Example #1
0
 @SuppressWarnings("static-method")
 private boolean checkNextLinkSemantics(
     Link currentLink, Id<Link> nextLinkId, QLinkInternalI nextQLink, QVehicle veh) {
   if (nextQLink == null) {
     // throw new IllegalStateException
     log.warn(
         "The link id "
             + nextLinkId
             + " is not available in the simulation network, but vehicle "
             + veh.getId()
             + " plans to travel on that link from link "
             + veh.getCurrentLink().getId());
     return false;
   }
   if (currentLink.getToNode() != nextQLink.getLink().getFromNode()) {
     // throw new RuntimeException
     log.warn(
         "Cannot move vehicle "
             + veh.getId()
             + " from link "
             + currentLink.getId()
             + " to link "
             + nextQLink.getLink().getId());
     return false;
   }
   return true;
 }
Example #2
0
 private void moveLink(final QLinkInternalI link, final double now) {
   if (link instanceof QLinkLanesImpl) {
     // This cannot be moved to QLinkLanesImpl since we want to be able to serve other lanes if one
     // lane is blocked.
     // kai, feb'12
     // yyyy but somehow I think this should be solved "under the hood" in QLinkLanesImpl.  kai,
     // sep'13
     // zzzz the above yyyy solution would get really ugly with the current interface and the code
     // in the
     // else {} branch: link.isNotOfferingVehicle():boolean would return sequentially the state of
     // the single
     // lanes. Each call would have side effects on a state machine within QLinkLanesImpl.
     // Proposal: think
     // about a better interface first, then solve under the hood. dg, mar'14
     for (QLaneI lane : ((QLinkLanesImpl) link).getToNodeQueueLanes()) {
       while (!lane.isNotOfferingVehicle()) {
         QVehicle veh = lane.getFirstVehicle();
         Id<Link> nextLink = veh.getDriver().chooseNextLinkId();
         if (!(lane.hasGreenForToLink(nextLink) && moveVehicleOverNode(veh, lane, now))) {
           break;
         }
       }
     }
   } else {
     while (!link.isNotOfferingVehicle()) {
       QVehicle veh = link.getFirstVehicle();
       if (!moveVehicleOverNode(veh, link, now)) {
         break;
       }
     }
   }
 }
Example #3
0
  /**
   * @return <code>true</code> if the vehicle was successfully moved over the node, <code>false
   *     </code> otherwise (e.g. in case where the next link is jammed)
   */
  private boolean moveVehicleOverNode(
      final QVehicle veh, final QInternalI fromLaneBuffer, final double now) {
    Id<Link> nextLinkId = veh.getDriver().chooseNextLinkId();
    Link currentLink = veh.getCurrentLink();

    if ((!fromLaneBuffer.hasGreenForToLink(nextLinkId))) {
      // there is no longer a stuck check for red links. This means that
      // in case of an infinite red time the simulation will not stop automatically because
      // vehicles waiting in front of the red signal will never reach their destination. dg, mar'14
      return false;
    }

    if (nextLinkId == null) {
      log.error(
          "Agent has no or wrong route! agentId="
              + veh.getDriver().getId()
              + " currentLink="
              + currentLink.getId().toString()
              + ". The agent is removed from the simulation.");
      moveVehicleFromInlinkToAbort(veh, fromLaneBuffer, now);
      return true;
    }

    QLinkInternalI nextQueueLink = network.getNetsimLinks().get(nextLinkId);
    if (!checkNextLinkSemantics(currentLink, nextLinkId, nextQueueLink, veh)) {
      moveVehicleFromInlinkToAbort(veh, fromLaneBuffer, now);
      return true;
    }

    if (nextQueueLink.isAcceptingFromUpstream()) {
      moveVehicleFromInlinkToOutlink(veh, fromLaneBuffer, nextQueueLink);
      return true;
    }

    if (vehicleIsStuck(fromLaneBuffer, now)) {
      /* We just push the vehicle further after stucktime is over, regardless
       * of if there is space on the next link or not.. optionally we let them
       * die here, we have a config setting for that!
       */
      if (network.simEngine.getMobsim().getScenario().getConfig().qsim().isRemoveStuckVehicles()) {
        moveVehicleFromInlinkToAbort(veh, fromLaneBuffer, now);
        return false;
      } else {
        moveVehicleFromInlinkToOutlink(veh, fromLaneBuffer, nextQueueLink);
        return true;
        // (yyyy why is this returning `true'?  Since this is a fix to avoid gridlock, this should
        // proceed in small steps.
        // kai, feb'12)
      }
    }

    return false;
  }
  private void moveLinks() {
    boolean remainsActive;
    lockLinks = true;
    QLinkInternalI link;
    ListIterator<QLinkInternalI> simLinks = this.linksList.listIterator();
    while (simLinks.hasNext()) {
      link = simLinks.next();

      remainsActive = link.doSimStep(time);

      if (!remainsActive) simLinks.remove();
    }
    lockLinks = false;
  }
Example #5
0
  /**
   * Moves vehicles from the inlinks' buffer to the outlinks where possible.<br>
   * The inLinks are randomly chosen, and for each link all vehicles in the buffer are moved to
   * their desired outLink as long as there is space. If the front most vehicle in a buffer cannot
   * move across the node because there is no free space on its destination link, the work on this
   * inLink is finished and the next inLink's buffer is handled (this means, that at the node, all
   * links have only like one lane, and there are no separate lanes for the different outLinks. Thus
   * if the front most vehicle cannot drive further, all other vehicles behind must wait, too, even
   * if their links would be free).
   *
   * @param now The current time in seconds from midnight.
   * @return Whether the QNode stays active or not.
   */
  /*package*/ boolean doSimStep(final double now) {

    int inLinksCounter = 0;
    double inLinksCapSum = 0.0;
    // Check all incoming links for buffered agents
    for (QLinkInternalI link : this.inLinksArrayCache) {
      if (!link.isNotOfferingVehicle()) {
        this.tempLinks[inLinksCounter] = link;
        inLinksCounter++;
        inLinksCapSum += link.getLink().getCapacity(now);
      }
    }

    if (inLinksCounter == 0) {
      this.active.set(false);
      return false; // Nothing to do
    }

    // randomize based on capacity
    for (int auxCounter = 0; auxCounter < inLinksCounter; auxCounter++) {
      double rndNum = random.nextDouble() * inLinksCapSum;
      double selCap = 0.0;
      for (int i = 0; i < inLinksCounter; i++) {
        QLinkInternalI link = this.tempLinks[i];
        if (link != null) {
          selCap += link.getLink().getCapacity(now);
          if (selCap >= rndNum) {
            inLinksCapSum -= link.getLink().getCapacity(now);
            this.tempLinks[i] = null;
            this.moveLink(link, now);
            break;
          }
        }
      }
    }

    return true;
  }
Example #6
0
 private static void moveVehicleFromInlinkToOutlink(
     final QVehicle veh, final QInternalI fromLane, QLinkInternalI nextQueueLink) {
   fromLane.popFirstVehicle();
   veh.getDriver().notifyMoveOverNode(nextQueueLink.getLink().getId());
   nextQueueLink.addFromUpstream(veh);
 }