bool MSTriggeredRerouter::notifyEnter(SUMOVehicle& veh, MSMoveReminder::Notification reason) { if (reason == MSMoveReminder::NOTIFICATION_LANE_CHANGE) { return false; } // check whether the vehicle shall be rerouted SUMOTime time = MSNet::getInstance()->getCurrentTimeStep(); if (!hasCurrentReroute(time, veh)) { return false; } SUMOReal prob = myAmInUserMode ? myUserProbability : myProbability; if (RandHelper::rand() > prob) { return false; } // get vehicle params const MSRoute& route = veh.getRoute(); const MSEdge* lastEdge = route.getLastEdge(); // get rerouting params const MSTriggeredRerouter::RerouteInterval& rerouteDef = getCurrentReroute(time, veh); const MSRoute* newRoute = rerouteDef.routeProbs.getOverallProb() > 0 ? rerouteDef.routeProbs.get() : 0; // we will use the route if given rather than calling our own dijsktra... if (newRoute != 0) { veh.replaceRoute(newRoute); return false; } const MSEdge* newEdge = lastEdge; // ok, try using a new destination const bool destUnreachable = std::find(rerouteDef.closed.begin(), rerouteDef.closed.end(), lastEdge) != rerouteDef.closed.end(); // if we have a closingReroute, only assign new destinations to vehicles which cannot reach their original destination if (rerouteDef.closed.size() == 0 || destUnreachable) { newEdge = rerouteDef.edgeProbs.getOverallProb() > 0 ? rerouteDef.edgeProbs.get() : route.getLastEdge(); if (newEdge == &mySpecialDest_terminateRoute) { newEdge = veh.getEdge(); } else if (newEdge == &mySpecialDest_keepDestination || newEdge == lastEdge) { if (destUnreachable) { WRITE_WARNING("Cannot keep destination for vehicle '" + veh.getID() + "' due to closed edges. Terminating route."); newEdge = veh.getEdge(); } else { newEdge = lastEdge; } } else if (newEdge == 0) { assert(false); // this should never happen newEdge = veh.getEdge(); } } // we have a new destination, let's replace the vehicle route std::vector<const MSEdge*> edges; MSNet::getInstance()->getRouterTT(rerouteDef.closed).compute( veh.getEdge(), newEdge, &veh, MSNet::getInstance()->getCurrentTimeStep(), edges); veh.replaceRouteEdges(edges); return false; }
bool MSDevice_Vehroutes::notifyLeave(SUMOVehicle& veh, SUMOReal /*lastPos*/, MSMoveReminder::Notification reason) { if (mySaveExits && reason != NOTIFICATION_LANE_CHANGE) { if (reason != NOTIFICATION_TELEPORT && myLastSavedAt == veh.getEdge()) { // need to check this for internal lanes myExits.back() = MSNet::getInstance()->getCurrentTimeStep(); } else if (myLastSavedAt != veh.getEdge()) { myExits.push_back(MSNet::getInstance()->getCurrentTimeStep()); myLastSavedAt = veh.getEdge(); } } return mySaveExits; }
bool MSDevice_BTreceiver::notifyEnter(SUMOVehicle& veh, Notification reason) { if (reason == MSMoveReminder::NOTIFICATION_DEPARTED && sVehicles.find(veh.getID()) == sVehicles.end()) { sVehicles[veh.getID()] = new VehicleInformation(veh.getID(), myRange); sVehicles[veh.getID()]->route.push_back(veh.getEdge()); } if (reason == MSMoveReminder::NOTIFICATION_TELEPORT && sVehicles.find(veh.getID()) != sVehicles.end()) { sVehicles[veh.getID()]->amOnNet = true; } if (reason == MSMoveReminder::NOTIFICATION_TELEPORT || reason == MSMoveReminder::NOTIFICATION_JUNCTION) { sVehicles[veh.getID()]->route.push_back(veh.getEdge()); } const MSVehicle& v = static_cast<MSVehicle&>(veh); sVehicles[veh.getID()]->updates.push_back(MSDevice_BTsender::VehicleState(veh.getSpeed(), veh.getPosition(), v.getLane()->getID(), veh.getPositionOnLane(), v.getRoutePosition())); return true; }
bool MSDevice_Container::notifyMove(SUMOVehicle& veh, SUMOReal /*oldPos*/, SUMOReal /*newPos*/, SUMOReal /*newSpeed*/) { if (myStopped) { // if veh is not anymore at the stop if (!veh.isStopped()) { for (std::vector<MSTransportable*>::iterator i = myContainers.begin(); i != myContainers.end(); ++i) { (*i)->setDeparted(MSNet::getInstance()->getCurrentTimeStep()); } myStopped = false; } } else { if (veh.isStopped()) { for (std::vector<MSTransportable*>::iterator i = myContainers.begin(); i != myContainers.end();) { MSTransportable* container = *i; if (&(container->getDestination()) == veh.getEdge()) { if (!container->proceed(MSNet::getInstance(), MSNet::getInstance()->getCurrentTimeStep())) { MSNet::getInstance()->getContainerControl().erase(container); } i = myContainers.erase(i); } else { ++i; } } myStopped = true; } } return true; }
bool MSDevice_Person::notifyMove(SUMOVehicle& veh, SUMOReal /*oldPos*/, SUMOReal /*newPos*/, SUMOReal /*newSpeed*/) { if (myStopped) { if (!veh.isStopped()) { for (std::vector<MSTransportable*>::iterator i = myPersons.begin(); i != myPersons.end(); ++i) { (*i)->setDeparted(MSNet::getInstance()->getCurrentTimeStep()); } myStopped = false; } } else { if (veh.isStopped()) { for (std::vector<MSTransportable*>::iterator i = myPersons.begin(); i != myPersons.end();) { MSTransportable* person = *i; if (&(person->getDestination()) == veh.getEdge()) { if (!person->proceed(MSNet::getInstance(), MSNet::getInstance()->getCurrentTimeStep())) { MSNet::getInstance()->getPersonControl().erase(person); } i = myPersons.erase(i); } else { ++i; } } myStopped = true; } } return true; }
bool MSDevice_Container::notifyLeave(SUMOVehicle& veh, SUMOReal /*lastPos*/, MSMoveReminder::Notification reason) { if (reason >= MSMoveReminder::NOTIFICATION_ARRIVED) { for (std::vector<MSTransportable*>::iterator i = myContainers.begin(); i != myContainers.end(); ++i) { MSTransportable* container = *i; if (&(container->getDestination()) != veh.getEdge()) { WRITE_WARNING("Teleporting container '" + container->getID() + "' from vehicle destination edge '" + veh.getEdge()->getID() + "' to intended destination edge '" + container->getDestination().getID() + "'"); } if (!container->proceed(MSNet::getInstance(), MSNet::getInstance()->getCurrentTimeStep())) { MSNet::getInstance()->getContainerControl().erase(container); }; } } return true; }
void MSDevice_Tripinfo::notifyMoveInternal(const SUMOVehicle& veh, const double /* frontOnLane */, const double timeOnLane, const double /* meanSpeedFrontOnLane */, const double meanSpeedVehicleOnLane, const double /* travelledDistanceFrontOnLane */, const double /* travelledDistanceVehicleOnLane */, const double /* meanLengthOnLane */) { // called by meso const MEVehicle* mesoVeh = dynamic_cast<const MEVehicle*>(&veh); assert(mesoVeh); const double vmax = veh.getEdge()->getVehicleMaxSpeed(&veh); if (vmax > 0) { myMesoTimeLoss += TIME2STEPS(timeOnLane * (vmax - meanSpeedVehicleOnLane) / vmax); } myWaitingTime += veh.getWaitingTime(); myStoppingTime += TIME2STEPS(mesoVeh->getCurrentStoppingTimeSeconds()); }
bool MSEdge::insertVehicle(SUMOVehicle& v, SUMOTime time, const bool checkOnly) const { // when vaporizing, no vehicles are inserted, but checking needs to be successful to trigger removal if (isVaporizing()) { return checkOnly; } const SUMOVehicleParameter& pars = v.getParameter(); const MSVehicleType& type = v.getVehicleType(); if (pars.departSpeedProcedure == DEPART_SPEED_GIVEN && pars.departSpeed > getVehicleMaxSpeed(&v)) { if (type.getSpeedDeviation() > 0 && pars.departSpeed <= type.getSpeedFactor() * getSpeedLimit() * (2 * type.getSpeedDeviation() + 1.)) { WRITE_WARNING("Choosing new speed factor for vehicle '" + pars.id + "' to match departure speed."); v.setChosenSpeedFactor(type.computeChosenSpeedDeviation(0, pars.departSpeed / (type.getSpeedFactor() * getSpeedLimit()))); } else { throw ProcessError("Departure speed for vehicle '" + pars.id + "' is too high for the departure edge '" + getID() + "'."); } } if (checkOnly && v.getEdge()->getPurpose() == MSEdge::EDGEFUNCTION_DISTRICT) { return true; } 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: { const SUMOReal occupancy = getDepartLane(static_cast<MSVehicle&>(v))->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)); return insertionLane != 0 && insertionLane->insertVehicle(static_cast<MSVehicle&>(v)); }
bool MSDevice_Example::notifyLeave(SUMOVehicle& veh, SUMOReal /*lastPos*/, MSMoveReminder::Notification reason) { std::cout << "device '" << getID() << "' notifyLeave: reason=" << reason << " currentEdge=" << veh.getEdge()->getID() << "\n"; return true; // keep the device }