void MELoop::checkCar(MEVehicle* veh) { const SUMOTime leaveTime = veh->getEventTime(); MESegment* const onSegment = veh->getSegment(); MESegment* const toSegment = nextSegment(onSegment, veh); const bool teleporting = (onSegment == 0); // is the vehicle currently teleporting? if (changeSegment(veh, leaveTime, toSegment, teleporting)) { return; } if (MSGlobals::gTimeToGridlock > 0 && veh->getWaitingTime() > MSGlobals::gTimeToGridlock && !veh->isStopped()) { teleportVehicle(veh, toSegment); return; } if (veh->getBlockTime() == SUMOTime_MAX) { veh->setBlockTime(leaveTime); } if (leaveTime < toSegment->getEntryBlockTime()) { // receiving segment has recently received another vehicle veh->setEventTime(toSegment->getEntryBlockTime()); } else if (toSegment->hasSpaceFor(veh, leaveTime) && !veh->mayProceed()) { // either the junction is blocked or the traffic light is red veh->setEventTime(leaveTime + MAX2(SUMOTime(1), myLinkRecheckInterval)); } else { SUMOTime newEventTime = MAX3(toSegment->getEventTime() + 1, leaveTime + 1, leaveTime + myFullRecheckInterval); if (MSGlobals::gTimeToGridlock > 0) { // if teleporting is enabled, make sure we look at the vehicle when the the gridlock-time is up newEventTime = MIN2(newEventTime, veh->getBlockTime() + MSGlobals::gTimeToGridlock + 1); } veh->setEventTime(newEventTime); } addLeaderCar(veh, onSegment->getLink(veh)); }
SUMOTime MESegment::newArrival(const MEVehicle* const v, SUMOReal newSpeed, SUMOTime currentTime) { // since speed is only an upper bound pos may be to optimistic const SUMOReal pos = MIN2(myLength, STEPS2TIME(currentTime - v->getLastEntryTime()) * v->getSpeed()); // traveltime may not be 0 return currentTime + MAX2(TIME2STEPS((myLength - pos) / newSpeed), SUMOTime(1)); }
// ------------ "actuated" algorithm methods SUMOTime MSActuatedTrafficLightLogic::duration(const double detectionGap) const { assert(getCurrentPhaseDef().isGreenPhase()); assert((int)myPhases.size() > myStep); const SUMOTime actDuration = MSNet::getInstance()->getCurrentTimeStep() - myPhases[myStep]->myLastSwitch; // ensure that minimum duration is kept SUMOTime newDuration = getCurrentPhaseDef().minDuration - actDuration; // try to let the last detected vehicle pass the intersection (duration must be positive) newDuration = MAX3(newDuration, TIME2STEPS(myDetectorGap - detectionGap), SUMOTime(1)); // cut the decimal places to ensure that phases always have integer duration if (newDuration % 1000 != 0) { const SUMOTime totalDur = newDuration + actDuration; newDuration = (totalDur / 1000 + 1) * 1000 - actDuration; } // ensure that the maximum duration is not exceeded newDuration = MIN2(newDuration, getCurrentPhaseDef().maxDuration - actDuration); return newDuration; }
void MSCalibrator::MSCalibrator_FileTriggeredChild::myStartElement(SumoXMLTag element, const SUMOSAXAttributes &attrs) throw(ProcessError) { if (element==SUMO_TAG_ROUTEDISTELEM) { bool ok = true; SUMOReal freq = attrs.getSUMORealReporting(SUMO_ATTR_PROB, "calibrator/routedistelem", myParent.getID().c_str(), ok); std::string routeStr = attrs.getStringReporting(SUMO_ATTR_ID, "calibrator/routedistelem", myParent.getID().c_str(), ok); if (ok) { const MSRoute* route = MSRoute::dictionary(routeStr); if (route == 0) { throw ProcessError("MSTriggeredSource " + myParent.getID() + ": Route '" + routeStr + "' does not exist."); } if (freq<0) { throw ProcessError("MSTriggeredSource " + myParent.getID() + ": Attribute \"probability\" is negative (must not)."); } // Attributes ok, add to routeDist myRouteDist.add(freq, route); } return; } // vehicle-type distributions if (element==SUMO_TAG_VTYPEDISTELEM) { // get the id, report an error if not given or empty... std::string id; if (!attrs.setIDFromAttributes("vtypedistelem", id)) { return; } bool ok = true; SUMOReal prob = attrs.getSUMORealReporting(SUMO_ATTR_PROB, "vtypedistelem", id.c_str(), ok); if (ok) { if (prob<=0) { MsgHandler::getErrorInstance()->inform("False probability while parsing calibrator '" + myParent.getID() + "' (" + toString(prob) + ")."); return; } MSVehicleType *vtype = MSNet::getInstance()->getVehicleControl().getVType(id); if (vtype==0) { MsgHandler::getErrorInstance()->inform("Unknown vtype-object '" + id + "'."); return; } myVTypeDist.add(prob, vtype); } } if (element==SUMO_TAG_FLOW) { bool ok = true; SUMOReal no = attrs.getSUMORealReporting(SUMO_ATTR_NO, "flow", myParent.getID().c_str(), ok); if (no<0) { MsgHandler::getErrorInstance()->inform("Negative flow in calibrator '" + myParent.getID() + "'."); return; } SUMOTime end = attrs.getOptSUMOTimeReporting(SUMO_ATTR_END, "flow", myParent.getID().c_str(), ok, -1); if (!ok) { return; } myFlow = (SUMOReal) no; if (end==-1||end>=MSNet::getInstance()->getCurrentTimeStep()) { if (myFlow>0) { buildAndScheduleFlowVehicle(); MSNet::getInstance()->getEmissionEvents().addEvent( new WrappingCommand<MSCalibrator::MSCalibrator_FileTriggeredChild>(this, &MSCalibrator::MSCalibrator_FileTriggeredChild::execute), (SUMOTime)(1. / (myFlow / 3600.))+MSNet::getInstance()->getCurrentTimeStep(), MSEventControl::ADAPT_AFTER_EXECUTION); myHaveInitialisedFlow = true; } } } // check whethe the correct tag is read if (element==SUMO_TAG_EMIT) { bool ok = true; SUMOTime depart = attrs.getSUMOTimeReporting(SUMO_ATTR_TIME, "emit", 0, ok); SUMOReal departSpeed = attrs.getOptSUMORealReporting(SUMO_ATTR_SPEED, "emit", myParent.getID().c_str(), ok, -1); if (!ok) { return; } if (depart<myBeginTime) { // do not process the vehicle if the emission time is before the simulation begin return; } SUMOVehicleParameter* pars = new SUMOVehicleParameter(); pars->repetitionNumber = -1; pars->repetitionOffset = -1; pars->depart = depart; pars->departSpeed = departSpeed; // check and assign id pars->id = attrs.getStringSecure(SUMO_ATTR_ID, ""); if (myVehicleControl.getVehicle(pars->id)!=0) { WRITE_WARNING("MSTriggeredSource " + myParent.getID()+ ": Vehicle " + pars->id + " already exists.\n Generating a default id."); pars->id = ""; } if (pars->id=="") { pars->id = myParent.getID() + "_" + toString(pars->depart) + "_" + toString(myRunningID++); if (myVehicleControl.getVehicle(pars->id)!=0) { WRITE_WARNING("MSTriggeredSource " + myParent.getID()+ ": Vehicle " + pars->id + " already exists.\n Continuing with next element."); return; } } // check and assign vehicle type pars->vtypeid = attrs.getStringReporting(SUMO_ATTR_TYPE, "calibrator/routedistelem", myParent.getID().c_str(), ok, ""); MSVehicleType* aVehType = MSNet::getInstance()->getVehicleControl().getVType(pars->vtypeid); if (aVehType == 0) { if (myVTypeDist.getOverallProb()!=0) { aVehType = myVTypeDist.get(); } if (aVehType==0) { aVehType = MSNet::getInstance()->getVehicleControl().getVType(); if (aVehType==0) { WRITE_WARNING("MSTriggeredSource " + myParent.getID()+ ": no valid vehicle type exists.\n Continuing with next element."); return; } } } // check and assign vehicle type pars->routeid = attrs.getStringReporting(SUMO_ATTR_ROUTE, "calibrator/routedistelem", myParent.getID().c_str(), ok, ""); const MSRoute *aEmitRoute = MSRoute::dictionary(pars->routeid); if (aEmitRoute==0) { if (myRouteDist.getOverallProb()!=0) { aEmitRoute = myRouteDist.get(); } if (aEmitRoute==0) { WRITE_WARNING("MSTriggeredSource " + myParent.getID()+ ": no valid route exsists."); WRITE_WARNING("Continuing with next element."); return; } } // build vehicle MSVehicle *veh = MSNet::getInstance()->getVehicleControl().buildVehicle(pars, aEmitRoute, aVehType); myParent.schedule(this, veh, pars->departSpeed); myHaveNext = true; myOffset = SUMOTime(pars->depart); } // check whethe the correct tag is read if (element==SUMO_TAG_RESET) { myVTypeDist.clear(); myRouteDist.clear(); } #if 0 #ifdef TM_CALIB if (element==SUMO_TAG_CALIB) { WRITE_WARNING("FOUND calib Tag!!!"); /* MSNet::getInstance()->getEmissionEvents().addEvent( new WrappingCommand<MSCalibrator::MSCalibrator_FileTriggeredChild>(this, &MSCalibrator::MSCalibrator_FileTriggeredChild::execute2), //MSNet::getInstance()->getCurrentTimeStep() + 5, 10, MSEventControl::ADAPT_AFTER_EXECUTION); */ } #endif //TM_CALIB #endif //0 }