Пример #1
0
 private float getAcceleration(StreetMobilityInfo smi, StreetMobilityInfo nextCar) {
   float accel;
   if (nextCar == null) return smi.acceleration;
   accel =
       (float)
           (2
                   * (smi.getRemainingDist() - nextCar.getRemainingDist() - smi.getCarSpacing())
                   / smi.stepTime
               - 2 * (smi.currSpeed - nextCar.currSpeed));
   if (accel > smi.acceleration) return smi.acceleration;
   else return accel;
 }
Пример #2
0
  public StreetMobilityInfo getClosestCarInfo(StreetMobilityInfo smi, Integer id) {
    StreetMobilityInfo returnValue = null;
    LaneChangeInfo lci = (LaneChangeInfo) laneChangers.get(id);
    if (lci == null) return null; // this is wrong "currentlane"
    lci.nextCar = getNextCar(smi.current.getLanes(smi)[lci.nextLane], smi);
    if (lci.nextCar == null) return null;
    //		float spacing = (float)smi.getCarSpacing()-1; // floating point imprecision here...
    if (lci.nextCar.getRemainingDist() + RoadSegment.CAR_LENGTH + RoadSegment.SPACE
        > smi.getRemainingDist()) throw new RuntimeException("Wrong next car!");

    if (smi.nextCar == null || smi.nextCar.getRemainingDist() < lci.nextCar.getRemainingDist())
      returnValue = lci.nextCar;
    else returnValue = smi.nextCar;

    if (smi.getRemainingDist() <= returnValue.getRemainingDist())
      throw new RuntimeException("Wrong car picked!");
    return returnValue;
  }
Пример #3
0
  /**
   * According to the following criterium: acc' (M') - acc (M) > p [ acc (B) + acc (B') - acc' (B) -
   * acc' (B') ] + athr
   *
   * @param smi
   * @return
   */
  public boolean incentiveToChange(StreetMobilityInfo smi) {

    float accMPrime, accM, accB = 0, accBPrime, accPrimeB = 0, accPrimeBPrime;

    // no need to change lanes
    if (smi.nextCar == null || smi.nextCar.currSpeed > smi.currSpeed) {
      return false;
    }

    int currentLane = smi.current.getLane(smi.currentLane);

    // get available lanes
    LinkedList lanes[] = smi.current.getLanes(smi);
    int laneNumber = -1;

    for (int i = 0; i < 2; i++) {
      if (i == 0 && safeLeft) laneNumber = currentLane - 1;
      else if (i == 1 && safeRight) laneNumber = currentLane + 1;
      else continue;

      ListIterator li = lanes[laneNumber].listIterator();
      StreetMobilityInfo back = null, front = null;
      while (li.hasNext()) {
        back = (StreetMobilityInfo) li.next();
        // is there room behind?
        if (back.getRemainingDist() > smi.getRemainingDist()) {

          // set next car info
          if (li.hasPrevious()) front = back.nextCar;
          break;
        }
      }

      // use acceleration over next second
      accM = getAcceleration(smi, smi.nextCar);
      if (accM < 0) accM = 0;
      accMPrime = getAcceleration(smi, front);
      if (accMPrime < 0) accM = 0;
      // before going further, see if there's any advantage at all
      if (accMPrime - accM > ACC_THRESHOLD) {
        if (back == null) return true; // no worries if there is no one back there

        int index = smi.currentLane.indexOf(smi) + 1;
        StreetMobilityInfo currentBack = null;
        if (index < smi.currentLane.size())
          currentBack = (StreetMobilityInfo) smi.currentLane.get(index);
        if (currentBack != null) {
          accB = getAcceleration(currentBack, smi);
          accPrimeB = getAcceleration(currentBack, smi.nextCar);
        }

        accBPrime = getAcceleration(back, front);
        accPrimeBPrime = getAcceleration(back, smi);

        // finally, we can tell if there is enough incentive
        float incentive =
            POLITENESS * (accB + accBPrime - accPrimeB - accPrimeBPrime) + ACC_THRESHOLD;
        if (accMPrime - accM > incentive) return true;
      } else if (i == 0) safeLeft = false; // indicate no incentive to go into left lane
    }

    return false;
  }
Пример #4
0
  private boolean canChangeToLane(LinkedList list, StreetMobilityInfo smi) {
    ListIterator li = list.listIterator();
    StreetMobilityInfo back = null;
    while (li.hasNext()) {
      back = (StreetMobilityInfo) li.next();
      // is it safe to the side?
      if (back.getRemainingDist() + smi.getCarSpacing() > smi.getRemainingDist()) return false;
      // is there a car behind?
      if (back.getRemainingDist() > smi.getRemainingDist()) {
        // make sure there is room in front, too.
        if (back.nextCar != null
                && back.getRemainingDist() - back.nextCar.getRemainingDist()
                    < smi.getCarSpacing() // is there room between cars?
            || back.getRemainingDist() - smi.getCarSpacing() <= smi.getRemainingDist()) {
          return false;
        }
        // case where node is near end of segment
        if (back.nextCar == null && smi.getRemainingDist() < smi.getCarSpacing()) {
          // get back car from next road
          int index = smi.current.getLane(list);
          LinkedList lanes[];
          if (smi.nextEnd.distance(smi.nextRS.getEndPoint()) == 0) lanes = smi.nextRS.carsToEnd;
          else lanes = smi.nextRS.carsToEnd;
          if (lanes.length > index) { // there is another lane like this one
            if (lanes[index].size() > 0) {
              StreetMobilityInfo last = (StreetMobilityInfo) lanes[index].getLast();
              if (last.current.length - last.getRemainingDist() + smi.getRemainingDist()
                  < smi.getCarSpacing()) return false; // too little space
            }
          } else { // lane will end, don't try to change
            return false;
          }
        }
        break;
      }
    }
    if (back == null) return true; // no cars in lane
    // all cars in lane are in front of the current car
    else if (smi.getRemainingDist() > back.getRemainingDist()) {
      // is it too close?
      if (smi.getRemainingDist() - back.getRemainingDist() < smi.getCarSpacing()) {
        return false;
      }

    } else { // is it safe behind?
      float backSpeed = back.currSpeed;
      if (backSpeed > smi.currSpeed) { // will back car have to decelerate?
        double dist = back.getRemainingDist() - smi.getRemainingDist();
        double time = dist / (0.5 * (backSpeed - smi.currSpeed));
        if ((backSpeed - smi.currSpeed) / (2 * time) < B_SAVE) return true;
      } else return true;
    }
    return false;
  }