void MSLCM_DK2004::informBlocker(MSAbstractLaneChangeModel::MSLCMessager& msgPass, int& blocked, int dir, const std::pair<MSVehicle*, SUMOReal>& neighLead, const std::pair<MSVehicle*, SUMOReal>& neighFollow) { if ((blocked & LCA_BLOCKED_BY_FOLLOWER) != 0) { assert(neighFollow.first != 0); MSVehicle* nv = neighFollow.first; SUMOReal decelGap = neighFollow.second + SPEED2DIST(myVehicle.getSpeed()) * (SUMOReal) 2.0 - MAX2(nv->getSpeed() - (SUMOReal) ACCEL2DIST(nv->getCarFollowModel().getMaxDecel()) * (SUMOReal) 2.0, (SUMOReal) 0); if (neighFollow.second > 0 && decelGap > 0 && decelGap >= nv->getCarFollowModel().getSecureGap(nv->getSpeed(), myVehicle.getSpeed(), myVehicle.getCarFollowModel().getMaxDecel())) { SUMOReal vsafe = myCarFollowModel.followSpeed(&myVehicle, myVehicle.getSpeed(), neighFollow.second, neighFollow.first->getSpeed(), neighFollow.first->getCarFollowModel().getMaxDecel()); msgPass.informNeighFollower(new Info(vsafe, dir | LCA_AMBLOCKINGFOLLOWER), &myVehicle); } else { SUMOReal vsafe = neighFollow.second <= 0 ? 0 : myCarFollowModel.followSpeed(&myVehicle, myVehicle.getSpeed(), neighFollow.second, neighFollow.first->getSpeed(), neighFollow.first->getCarFollowModel().getMaxDecel()); msgPass.informNeighFollower(new Info(vsafe, dir | LCA_AMBLOCKINGFOLLOWER_DONTBRAKE), &myVehicle); } } if ((blocked & LCA_BLOCKED_BY_LEADER) != 0) { if (neighLead.first != 0 && neighLead.second > 0) { msgPass.informNeighLeader(new Info(0, dir | LCA_AMBLOCKINGLEADER), &myVehicle); } } }
SUMOReal MSLCM_LC2013::informLeader(MSAbstractLaneChangeModel::MSLCMessager& msgPass, int blocked, int dir, const std::pair<MSVehicle*, SUMOReal>& neighLead, SUMOReal remainingSeconds) { SUMOReal plannedSpeed = MIN2(myVehicle.getSpeed(), myVehicle.getCarFollowModel().stopSpeed(&myVehicle, myVehicle.getSpeed(), myLeftSpace - myLeadingBlockerLength)); for (std::vector<SUMOReal>::const_iterator i = myVSafes.begin(); i != myVSafes.end(); ++i) { SUMOReal v = (*i); if (v >= myVehicle.getSpeed() - ACCEL2SPEED(myVehicle.getCarFollowModel().getMaxDecel())) { plannedSpeed = MIN2(plannedSpeed, v); } } if ((blocked & LCA_BLOCKED_BY_LEADER) != 0) { assert(neighLead.first != 0); MSVehicle* nv = neighLead.first; // decide whether we want to overtake the leader or follow it const SUMOReal dv = plannedSpeed - nv->getSpeed(); const SUMOReal overtakeDist = (neighLead.second // drive to back of follower + nv->getVehicleType().getLengthWithGap() // drive to front of follower + myVehicle.getVehicleType().getLength() // ego back reaches follower front + nv->getCarFollowModel().getSecureGap( // save gap to follower nv->getSpeed(), myVehicle.getSpeed(), myVehicle.getCarFollowModel().getMaxDecel())); if (dv < 0 // overtaking on the right on an uncongested highway is forbidden (noOvertakeLCLeft) || (dir == LCA_MLEFT && !myVehicle.congested()) // not enough space to overtake? || myLeftSpace < overtakeDist // not enough time to overtake? || dv * remainingSeconds < overtakeDist) { // cannot overtake msgPass.informNeighLeader(new Info(-1, dir | LCA_AMBLOCKINGLEADER), &myVehicle); // slow down smoothly to follow leader const SUMOReal targetSpeed = myCarFollowModel.followSpeed( &myVehicle, myVehicle.getSpeed(), neighLead.second, nv->getSpeed(), nv->getCarFollowModel().getMaxDecel()); if (targetSpeed < myVehicle.getSpeed()) { // slow down smoothly to follow leader const SUMOReal decel = ACCEL2SPEED(MIN2(myVehicle.getCarFollowModel().getMaxDecel(), MAX2(MIN_FALLBEHIND, (myVehicle.getSpeed() - targetSpeed) / remainingSeconds))); const SUMOReal nextSpeed = MIN2(plannedSpeed, myVehicle.getSpeed() - decel); myVSafes.push_back(nextSpeed); return nextSpeed; } else { // leader is fast enough anyway myVSafes.push_back(targetSpeed); return plannedSpeed; } } else { // overtaking, leader should not accelerate msgPass.informNeighLeader(new Info(nv->getSpeed(), dir | LCA_AMBLOCKINGLEADER), &myVehicle); return -1; } } else if (neighLead.first != 0) { // (remainUnblocked) // we are not blocked now. make sure we stay far enough from the leader MSVehicle* nv = neighLead.first; const SUMOReal nextNVSpeed = nv->getSpeed() - HELP_OVERTAKE; // conservative const SUMOReal dv = SPEED2DIST(myVehicle.getSpeed() - nextNVSpeed); const SUMOReal targetSpeed = myCarFollowModel.followSpeed( &myVehicle, myVehicle.getSpeed(), neighLead.second - dv, nextNVSpeed, nv->getCarFollowModel().getMaxDecel()); myVSafes.push_back(targetSpeed); return MIN2(targetSpeed, plannedSpeed); } else { // not overtaking return plannedSpeed; } }