SUMOReal MSLCM_LC2013::_patchSpeed(const SUMOReal min, const SUMOReal wanted, const SUMOReal max, const MSCFModel& cfModel) { int state = myOwnState; // letting vehicles merge in at the end of the lane in case of counter-lane change, step#2 SUMOReal MAGIC_offset = 1.; // if we want to change and have a blocking leader and there is enough room for him in front of us if (myLeadingBlockerLength != 0) { SUMOReal space = myLeftSpace - myLeadingBlockerLength - MAGIC_offset - myVehicle.getVehicleType().getMinGap(); if (space > 0) { // compute speed for decelerating towards a place which allows the blocking leader to merge in in front SUMOReal safe = cfModel.stopSpeed(&myVehicle, myVehicle.getSpeed(), space); // if we are approaching this place if (safe < wanted) { // return this speed as the speed to use return MAX2(min, safe); } } } SUMOReal nVSafe = wanted; bool gotOne = false; for (std::vector<SUMOReal>::const_iterator i = myVSafes.begin(); i != myVSafes.end(); ++i) { SUMOReal v = (*i); if (v >= min && v <= max) { nVSafe = MIN2(v, nVSafe); gotOne = true; } else { } } if (gotOne && !myDontBrake) { return nVSafe; } // check whether the vehicle is blocked if ((state & LCA_WANTS_LANECHANGE) != 0 && (state & LCA_BLOCKED) != 0) { if ((state & LCA_STRATEGIC) != 0) { // necessary decelerations are controlled via vSafe. If there are // none it means we should speed up return (max + wanted) / (SUMOReal) 2.0; } else if ((state & LCA_COOPERATIVE) != 0) { // only minor adjustments in speed should be done if ((state & LCA_BLOCKED_BY_LEADER) != 0) { return (min + wanted) / (SUMOReal) 2.0; } if ((state & LCA_BLOCKED_BY_FOLLOWER) != 0) { return (max + wanted) / (SUMOReal) 2.0; } } } // accelerate if being a blocking leader or blocking follower not able to brake // (and does not have to change lanes) if ((state & LCA_AMBLOCKINGLEADER) != 0) { return (max + wanted) / (SUMOReal) 2.0; } if ((state & LCA_AMBLOCKINGFOLLOWER_DONTBRAKE) != 0) { } if (myVehicle.getLane()->getEdge().getLanes().size() == 1) { // remove chaning information if on a road with a single lane changed(); } return wanted; }
SUMOReal MSLCM_DK2004::patchSpeed(const SUMOReal min, const SUMOReal wanted, const SUMOReal max, const MSCFModel& cfModel) { #ifdef DEBUG_VEHICLE_GUI_SELECTION if (gSelected.isSelected(GLO_VEHICLE, static_cast<const GUIVehicle*>(&myVehicle)->getGlID())) { int bla = 0; } #endif int state = myOwnState; myOwnState = 0; // letting vehicles merge in at the end of the lane in case of counter-lane change, step#2 SUMOReal MAGIC_offset = 1.; // if we want to change and have a blocking leader and there is enough room for him in front of us if (myLeadingBlockerLength != 0) { SUMOReal space = myLeftSpace - myLeadingBlockerLength - MAGIC_offset - myVehicle.getVehicleType().getMinGap(); if (space > 0) { // compute speed for decelerating towards a place which allows the blocking leader to merge in in front SUMOReal safe = cfModel.stopSpeed(&myVehicle, space); // if we are approaching this place if (safe < wanted) { // return this speed as the speed to use return MAX2(min, safe); } } } // just to make sure to be notified about lane chaning end if (myVehicle.getLane()->getEdge().getLanes().size() == 1) { // remove chaning information if on a road with a single lane changed(); return wanted; } SUMOReal nVSafe = wanted; bool gotOne = false; for (std::vector<SUMOReal>::const_iterator i = myVSafes.begin(); i != myVSafes.end(); ++i) { SUMOReal v = (*i); if (v >= min && v <= max) { nVSafe = MIN2(v, nVSafe); gotOne = true; } } // check whether the vehicle is blocked if ((state & LCA_WANTS_LANECHANGE) != 0) { if (gotOne && !myDontBrake) { return nVSafe; } // check whether the vehicle maybe has to be swapped with one of // the blocking vehicles if ((state & LCA_BLOCKED) != 0) { if ((state & LCA_BLOCKED_BY_LEADER) != 0) { // if interacting with leader and not too slow return (min + wanted) / (SUMOReal) 2.0; } if ((state & LCA_BLOCKED_BY_FOLLOWER) != 0) { return (max + wanted) / (SUMOReal) 2.0; } return (min + wanted) / (SUMOReal) 2.0; } } // decelerate if being a blocking follower // (and does not have to change lanes) if ((state & LCA_AMBLOCKINGFOLLOWER) != 0) { if (fabs(max - myVehicle.getCarFollowModel().maxNextSpeed(myVehicle.getSpeed())) < 0.001 && min == 0) { // !!! was standing return 0; } return (min + wanted) / (SUMOReal) 2.0; } if ((state & LCA_AMBACKBLOCKER) != 0) { if (max <= myVehicle.getCarFollowModel().maxNextSpeed(myVehicle.getSpeed()) && min == 0) { // !!! was standing return min; } } if ((state & LCA_AMBACKBLOCKER_STANDING) != 0) { return min; } // accelerate if being a blocking leader or blocking follower not able to brake // (and does not have to change lanes) if ((state & LCA_AMBLOCKINGLEADER) != 0) { return (max + wanted) / (SUMOReal) 2.0; } if ((state & LCA_AMBLOCKINGFOLLOWER_DONTBRAKE) != 0) { if (max <= myVehicle.getCarFollowModel().maxNextSpeed(myVehicle.getSpeed()) && min == 0) { // !!! was standing return wanted; } return (min + wanted) / (SUMOReal) 2.0; } return wanted; }