void MSVehicleControl::vehicleDeparted(const SUMOVehicle& v) { ++myRunningVehNo; myTotalDepartureDelay += STEPS2TIME(v.getDeparture() - STEPFLOOR(v.getParameter().depart)); MSNet::getInstance()->informVehicleStateListener(&v, MSNet::VEHICLE_STATE_DEPARTED); myMaxSpeedFactor = MAX2(myMaxSpeedFactor, v.getChosenSpeedFactor()); myMinDeceleration = MIN2(myMinDeceleration, v.getVehicleType().getCarFollowModel().getMaxDecel()); }
void MSVehicleControl::vehicleDeparted(const SUMOVehicle& v) { ++myRunningVehNo; myTotalDepartureDelay += STEPS2TIME(v.getDeparture() - STEPFLOOR(v.getParameter().depart)); MSNet::getInstance()->informVehicleStateListener(&v, MSNet::VEHICLE_STATE_DEPARTED); myMaxSpeedFactor = MAX2(myMaxSpeedFactor, v.getChosenSpeedFactor()); if ((v.getVClass() & (SVC_PEDESTRIAN | SVC_NON_ROAD)) == 0) { // only worry about deceleration of road users myMinDeceleration = MIN2(myMinDeceleration, v.getVehicleType().getCarFollowModel().getMaxDecel()); } }
bool MSEdge::insertVehicle(SUMOVehicle& v, SUMOTime time, const bool checkOnly, const bool forceCheck) const { // when vaporizing, no vehicles are inserted, but checking needs to be successful to trigger removal if (isVaporizing()) { return checkOnly; } if (isTaz() && checkOnly) { return true; } const SUMOVehicleParameter& pars = v.getParameter(); const MSVehicleType& type = v.getVehicleType(); if (pars.departSpeedProcedure == DEPART_SPEED_GIVEN && pars.departSpeed > getVehicleMaxSpeed(&v)) { if (type.getSpeedDeviation() > 0) { v.setChosenSpeedFactor(type.computeChosenSpeedDeviation(0, pars.departSpeed / (type.getSpeedFactor() * getSpeedLimit()))); if (v.getChosenSpeedFactor() > type.getSpeedFactor() * (2 * type.getSpeedDeviation() + 1)) { // only warn for significant deviation WRITE_WARNING("Choosing new speed factor " + toString(v.getChosenSpeedFactor()) + " for vehicle '" + pars.id + "' to match departure speed."); } } else { throw ProcessError("Departure speed for vehicle '" + pars.id + "' is too high for the departure edge '" + getID() + "'."); } } if (!checkOnly) { std::string msg; if (!v.hasValidRoute(msg)) { if (MSGlobals::gCheckRoutes) { throw ProcessError("Vehicle '" + v.getID() + "' has no valid route. " + msg); } else if (v.getEdge()->getPurpose() == MSEdge::EDGEFUNCTION_DISTRICT) { WRITE_WARNING("Removing vehicle '" + pars.id + "' which has no valid route."); MSNet::getInstance()->getInsertionControl().descheduleDeparture(&v); return false; } } } if (MSGlobals::gUseMesoSim) { SUMOReal pos = 0.0; switch (pars.departPosProcedure) { case DEPART_POS_GIVEN: if (pars.departPos >= 0.) { pos = pars.departPos; } else { pos = pars.departPos + getLength(); } if (pos < 0 || pos > getLength()) { WRITE_WARNING("Invalid departPos " + toString(pos) + " given for vehicle '" + v.getID() + "'. Inserting at lane end instead."); pos = getLength(); } break; case DEPART_POS_RANDOM: case DEPART_POS_RANDOM_FREE: pos = RandHelper::rand(getLength()); break; default: break; } bool result = false; MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this, pos); MEVehicle* veh = static_cast<MEVehicle*>(&v); if (pars.departPosProcedure == DEPART_POS_FREE) { while (segment != 0 && !result) { if (checkOnly) { result = segment->hasSpaceFor(veh, time, true); } else { result = segment->initialise(veh, time); } segment = segment->getNextSegment(); } } else { if (checkOnly) { result = segment->hasSpaceFor(veh, time, true); } else { result = segment->initialise(veh, time); } } return result; } if (checkOnly) { switch (v.getParameter().departLaneProcedure) { case DEPART_LANE_GIVEN: case DEPART_LANE_DEFAULT: case DEPART_LANE_FIRST_ALLOWED: { MSLane* insertionLane = getDepartLane(static_cast<MSVehicle&>(v)); if (insertionLane == 0) { WRITE_WARNING("could not insert vehicle '" + v.getID() + "' on any lane of edge '" + getID() + "', time=" + time2string(MSNet::getInstance()->getCurrentTimeStep())); return false; } const SUMOReal occupancy = insertionLane->getBruttoOccupancy(); return occupancy == (SUMOReal)0 || occupancy * myLength + v.getVehicleType().getLengthWithGap() <= myLength; } default: for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) { const SUMOReal occupancy = (*i)->getBruttoOccupancy(); if (occupancy == (SUMOReal)0 || occupancy * myLength + v.getVehicleType().getLengthWithGap() <= myLength) { return true; } } } return false; } MSLane* insertionLane = getDepartLane(static_cast<MSVehicle&>(v)); if (insertionLane == 0){ return false; } if (!forceCheck){ if (myLastFailedInsertionTime == time) { if (myFailedInsertionMemory.count(insertionLane->getIndex())){ // A vehicle was already rejected for the proposed insertionLane in this timestep return false; } } else { // last rejection occured in a previous timestep, clear cache myFailedInsertionMemory.clear(); } } bool success = insertionLane->insertVehicle(static_cast<MSVehicle&>(v)); if(!success){ myFailedInsertionMemory.insert(insertionLane->getIndex()); } return success; }