MESegment* MELoop::getSegmentForEdge(const MSEdge& e, SUMOReal pos) { MESegment* s = myEdges2FirstSegments[e.getNumericalID()]; if (pos > 0) { SUMOReal cpos = 0; while (s->getNextSegment() != 0 && cpos + s->getLength() < pos) { cpos += s->getLength(); s = s->getNextSegment(); } } return s; }
SUMOReal MSEdge::getCurrentTravelTime(SUMOReal minSpeed) const { assert(minSpeed > 0); if (!myAmDelayed) { return myEmptyTraveltime; } SUMOReal v = 0; #ifdef HAVE_INTERNAL if (MSGlobals::gUseMesoSim) { MESegment* first = MSGlobals::gMesoNet->getSegmentForEdge(*this); unsigned segments = 0; do { v += first->getMeanSpeed(); first = first->getNextSegment(); segments++; } while (first != 0); v /= (SUMOReal) segments; } else { #endif for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) { v += (*i)->getMeanSpeed(); } v /= (SUMOReal) myLanes->size(); #ifdef HAVE_INTERNAL } #endif return getLength() / MAX2(minSpeed, v); }
SUMOTime MSLaneSpeedTrigger::processCommand(bool move2next, SUMOTime currentTime) { UNUSED_PARAMETER(currentTime); std::vector<MSLane*>::iterator i; const SUMOReal speed = getCurrentSpeed(); for (i = myDestLanes.begin(); i != myDestLanes.end(); ++i) { #ifdef HAVE_INTERNAL if (MSGlobals::gUseMesoSim) { MESegment* first = MSGlobals::gMesoNet->getSegmentForEdge((*i)->getEdge()); while (first != 0) { first->setSpeed(speed, currentTime, -1); first = first->getNextSegment(); } continue; } #endif (*i)->setMaxSpeed(speed); } if (!move2next) { // changed from the gui return 0; } if (myCurrentEntry != myLoadedSpeeds.end()) { ++myCurrentEntry; } if (myCurrentEntry != myLoadedSpeeds.end()) { return ((*myCurrentEntry).first) - ((*(myCurrentEntry - 1)).first); } else { return 0; } }
MELoop::~MELoop() { for (std::vector<MESegment*>::const_iterator j = myEdges2FirstSegments.begin(); j != myEdges2FirstSegments.end(); ++j) { for (MESegment* s = *j; s != 0;) { MESegment* n = s->getNextSegment(); delete s; s = n; } } }
void NLDetectorBuilder::buildInductLoop(const std::string &id, const std::string &lane, SUMOReal pos, int splInterval, OutputDevice& device, bool friendlyPos) throw(InvalidArgument) { if (splInterval<0) { throw InvalidArgument("Negative sampling frequency (in e1-detector '" + id + "')."); } if (splInterval==0) { throw InvalidArgument("Sampling frequency must not be zero (in e1-detector '" + id + "')."); } // get and check the lane MSLane *clane = getLaneChecking(lane, id); if (pos<0) { pos = clane->getLength() + pos; } #ifdef HAVE_MESOSIM if (!MSGlobals::gUseMesoSim) { #endif // get and check the position pos = getPositionChecking(pos, clane, friendlyPos, id); // build the loop MSInductLoop *loop = createInductLoop(id, clane, pos); // add the file output myNet.getDetectorControl().add(loop, device, splInterval); #ifdef HAVE_MESOSIM } else { if (pos<0) { pos = clane->getLength() + pos; } MESegment *s = MSGlobals::gMesoNet->getSegmentForEdge(clane->getEdge()); MESegment *prev = s; SUMOReal cpos = 0; while (cpos+prev->getLength()<pos&&s!=0) { prev = s; cpos += s->getLength(); s = s->getNextSegment(); } SUMOReal rpos = pos-cpos;//-prev->getLength(); if (rpos>prev->getLength()||rpos<0) { if (friendlyPos) { rpos = prev->getLength() - (SUMOReal) 0.1; } else { throw InvalidArgument("The position of detector '" + id + "' lies beyond the lane's '" + lane + "' length."); } } MEInductLoop *loop = createMEInductLoop(id, prev, rpos); myNet.getDetectorControl().add(loop, device, splInterval); } #endif }
void MELoop::teleportVehicle(MEVehicle* veh, MESegment* const toSegment) { const SUMOTime leaveTime = veh->getEventTime(); MESegment* const onSegment = veh->getSegment(); const bool teleporting = (onSegment == 0); // is the vehicle already teleporting? // try to find a place on the current edge MESegment* teleSegment = toSegment->getNextSegment(); while (teleSegment != 0 && !teleSegment->hasSpaceFor(veh, leaveTime)) { // @caution the time to get to the next segment here is ignored XXX teleSegment = teleSegment->getNextSegment(); } if (teleSegment != 0) { if (!teleporting) { // we managed to teleport in a single jump WRITE_WARNING("Teleporting vehicle '" + veh->getID() + "'; waited too long, from edge '" + onSegment->getEdge().getID() + "':" + toString(onSegment->getIndex()) + " to edge '" + teleSegment->getEdge().getID() + "':" + toString(teleSegment->getIndex()) + ", time " + time2string(leaveTime) + "."); MSNet::getInstance()->getVehicleControl().registerTeleportJam(); } changeSegment(veh, leaveTime, teleSegment, true); teleSegment->setEntryBlockTime(leaveTime); // teleports should not block normal flow } else { // teleport across the current edge and try insertion later if (!teleporting) { // announce start of multi-step teleport, arrival will be announced in changeSegment() WRITE_WARNING("Teleporting vehicle '" + veh->getID() + "'; waited too long, from edge '" + onSegment->getEdge().getID() + "':" + toString(onSegment->getIndex()) + ", time " + time2string(leaveTime) + "."); MSNet::getInstance()->getVehicleControl().registerTeleportJam(); // remove from current segment onSegment->send(veh, 0, leaveTime); // mark veh as teleporting veh->setSegment(0, 0); } // @caution microsim uses current travel time teleport duration const SUMOTime teleArrival = leaveTime + TIME2STEPS(veh->getEdge()->getLength() / veh->getEdge()->getSpeedLimit()); const bool atDest = veh->moveRoutePointer(); if (atDest) { // teleporting to end of route changeSegment(veh, teleArrival, 0, true); } else { veh->setEventTime(teleArrival); addLeaderCar(veh, 0); // teleporting vehicles must react to rerouters getSegmentForEdge(*veh->getEdge())->addReminders(veh); veh->activateReminders(MSMoveReminder::NOTIFICATION_JUNCTION); } } }
bool MSEdge::insertVehicle(SUMOVehicle& v, SUMOTime time) const { // when vaporizing, no vehicles are inserted... if (isVaporizing()) { return false; } #ifdef HAVE_INTERNAL if (MSGlobals::gUseMesoSim) { const SUMOVehicleParameter& pars = v.getParameter(); 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) { result = segment->initialise(veh, time); segment = segment->getNextSegment(); } } else { result = segment->initialise(veh, time); } return result; } #else UNUSED_PARAMETER(time); #endif MSLane* insertionLane = getDepartLane(static_cast<MSVehicle&>(v)); return insertionLane != 0 && insertionLane->insertVehicle(static_cast<MSVehicle&>(v)); }
void GUIEdge::drawMesoVehicles(const GUIVisualizationSettings& s) const { GUIMEVehicleControl* vehicleControl = GUINet::getGUIInstance()->getGUIMEVehicleControl(); if (vehicleControl != 0) { // draw the meso vehicles vehicleControl->secureVehicles(); AbstractMutex::ScopedLocker locker(myLock); size_t laneIndex = 0; MESegment::Queue queue; for (std::vector<MSLane*>::const_iterator msl = myLanes->begin(); msl != myLanes->end(); ++msl, ++laneIndex) { GUILane* l = static_cast<GUILane*>(*msl); // go through the vehicles SUMOReal segmentOffset = 0; // offset at start of current segment for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != 0; segment = segment->getNextSegment()) { const SUMOReal length = segment->getLength(); if (laneIndex < segment->numQueues()) { // make a copy so we don't have to worry about synchronization queue = segment->getQueue(laneIndex); const size_t queueSize = queue.size(); SUMOReal vehiclePosition = segmentOffset + length; // draw vehicles beginning with the leader at the end of the segment SUMOReal xOff = 0; for (size_t i = 0; i < queueSize; ++i) { GUIMEVehicle* veh = static_cast<GUIMEVehicle*>(queue[queueSize - i - 1]); const SUMOReal vehLength = veh->getVehicleType().getLengthWithGap(); while (vehiclePosition < segmentOffset) { // if there is only a single queue for a // multi-lane edge shift vehicles and start // drawing again from the end of the segment vehiclePosition += length; xOff += 2; } const Position p = l->geometryPositionAtOffset(vehiclePosition); const SUMOReal angle = l->getShape().rotationAtOffset(l->interpolateLanePosToGeometryPos(vehiclePosition)); veh->setPositionAndAngle(p, angle); veh->drawGL(s); vehiclePosition -= vehLength; } } segmentOffset += length; } glPopMatrix(); } vehicleControl->releaseVehicles(); } }
void NLDetectorBuilder::buildInductLoop(const std::string& id, const std::string& lane, SUMOReal pos, int splInterval, const std::string& device, bool friendlyPos, bool splitByType) { checkSampleInterval(splInterval, SUMO_TAG_E1DETECTOR, id); // get and check the lane MSLane* clane = getLaneChecking(lane, SUMO_TAG_E1DETECTOR, id); if (!MSGlobals::gUseMesoSim) { // get and check the position pos = getPositionChecking(pos, clane, friendlyPos, id); // build the loop MSDetectorFileOutput* loop = createInductLoop(id, clane, pos, splitByType); // add the file output myNet.getDetectorControl().add(SUMO_TAG_INDUCTION_LOOP, loop, device, splInterval); } else { #ifdef HAVE_INTERNAL if (pos < 0) { pos = clane->getLength() + pos; } MESegment* s = MSGlobals::gMesoNet->getSegmentForEdge(clane->getEdge()); MESegment* prev = s; SUMOReal cpos = 0; while (cpos + prev->getLength() < pos && s != 0) { prev = s; cpos += s->getLength(); s = s->getNextSegment(); } SUMOReal rpos = pos - cpos; //-prev->getLength(); if (rpos > prev->getLength() || rpos < 0) { if (friendlyPos) { rpos = prev->getLength() - (SUMOReal) 0.1; } else { throw InvalidArgument("The position of detector '" + id + "' lies beyond the lane's '" + lane + "' length."); } } MEInductLoop* loop = createMEInductLoop(id, prev, rpos); myNet.getDetectorControl().add(SUMO_TAG_INDUCTION_LOOP, loop, device, splInterval); #endif } }
// =========================================================================== // method definitions // =========================================================================== MSRouteProbe::MSRouteProbe(const std::string& id, const MSEdge* edge, SUMOTime begin) : MSDetectorFileOutput(id), myCurrentRouteDistribution(0) { const std::string distID = id + "_" + toString(begin); myCurrentRouteDistribution = MSRoute::distDictionary(distID); if (myCurrentRouteDistribution == 0) { myCurrentRouteDistribution = new RandomDistributor<const MSRoute*>(MSRoute::getMaxRouteDistSize(), &MSRoute::releaseRoute); MSRoute::dictionary(distID, myCurrentRouteDistribution); } #ifdef HAVE_INTERNAL if (MSGlobals::gUseMesoSim) { MESegment* seg = MSGlobals::gMesoNet->getSegmentForEdge(*edge); while (seg != 0) { seg->addDetector(this); seg = seg->getNextSegment(); } return; } #endif for (std::vector<MSLane*>::const_iterator it = edge->getLanes().begin(); it != edge->getLanes().end(); ++it) { (*it)->addMoveReminder(this); } }
// =========================================================================== // method definitions // =========================================================================== MSRouteProbe::MSRouteProbe(const std::string& id, const MSEdge* edge, const std::string& distID, const std::string& lastID) : MSDetectorFileOutput(id), MSMoveReminder(id) { myCurrentRouteDistribution = std::make_pair(distID, MSRoute::distDictionary(distID)); if (myCurrentRouteDistribution.second == 0) { myCurrentRouteDistribution.second = new RandomDistributor<const MSRoute*>(); MSRoute::dictionary(distID, myCurrentRouteDistribution.second, false); } myLastRouteDistribution = std::make_pair(lastID, MSRoute::distDictionary(lastID)); #ifdef HAVE_INTERNAL if (MSGlobals::gUseMesoSim) { MESegment* seg = MSGlobals::gMesoNet->getSegmentForEdge(*edge); while (seg != 0) { seg->addDetector(this); seg = seg->getNextSegment(); } return; } #endif for (std::vector<MSLane*>::const_iterator it = edge->getLanes().begin(); it != edge->getLanes().end(); ++it) { (*it)->addMoveReminder(this); } }
bool GUIEdge::setMultiColor(const GUIColorer& c) const { const int activeScheme = c.getActive(); mySegmentColors.clear(); switch (activeScheme) { case 10: // alternating segments for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != 0; segment = segment->getNextSegment()) { mySegmentColors.push_back(c.getScheme().getColor(segment->getIndex() % 2)); } //std::cout << getID() << " scheme=" << c.getScheme().getName() << " schemeCols=" << c.getScheme().getColors().size() << " thresh=" << toString(c.getScheme().getThresholds()) << " segmentColors=" << mySegmentColors.size() << " [0]=" << mySegmentColors[0] << " [1]=" << mySegmentColors[1] << "\n"; return true; case 11: // by segment jammed state for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != 0; segment = segment->getNextSegment()) { mySegmentColors.push_back(c.getScheme().getColor(segment->free() ? 0 : 1)); } return true; case 12: // by segment occupancy for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != 0; segment = segment->getNextSegment()) { mySegmentColors.push_back(c.getScheme().getColor(segment->getRelativeOccupancy())); } return true; case 13: // by segment speed for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != 0; segment = segment->getNextSegment()) { mySegmentColors.push_back(c.getScheme().getColor(segment->getMeanSpeed())); } return true; case 14: // by segment flow for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != 0; segment = segment->getNextSegment()) { mySegmentColors.push_back(c.getScheme().getColor(3600 * segment->getCarNumber() * segment->getMeanSpeed() / segment->getLength())); } return true; case 15: // by segment relative speed for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != 0; segment = segment->getNextSegment()) { mySegmentColors.push_back(c.getScheme().getColor(segment->getMeanSpeed() / getAllowedSpeed())); } return true; default: return false; } }
MSRouteProbe::MSRouteProbe(const std::string &id, const MSEdge *edge, SUMOTime begin) throw() : Named(id), myCurrentRouteDistribution(0) { const std::string distID = id + "_" + toString(begin); myCurrentRouteDistribution = MSRoute::distDictionary(distID); if (myCurrentRouteDistribution == 0) { myCurrentRouteDistribution = new RandomDistributor<const MSRoute*>(); MSRoute::dictionary(distID, myCurrentRouteDistribution); } #ifdef HAVE_MESOSIM if (MSGlobals::gUseMesoSim) { MESegment *seg = MSGlobals::gMesoNet->getSegmentForEdge(*edge); while (seg!=0) { seg->setRouteProbe(this); seg = seg->getNextSegment(); } return; } #endif std::vector<MSLane*>::const_iterator it = edge->getLanes().begin(); myEntryReminder = new MSRouteProbe::EntryReminder(*it, *this); for (++it; it!=edge->getLanes().end(); ++it) { (*it)->addMoveReminder(myEntryReminder); } }
void MSStateHandler::saveState(const std::string& file, SUMOTime step) { OutputDevice& out = OutputDevice::getDevice(file); out.writeHeader<MSEdge>(SUMO_TAG_SNAPSHOT); out.writeAttr(SUMO_ATTR_VERSION, VERSION_STRING).writeAttr(SUMO_ATTR_TIME, step); MSRoute::dict_saveState(out); MSNet::getInstance()->getVehicleControl().saveState(out); if (MSGlobals::gUseMesoSim) { #ifdef HAVE_INTERNAL for (size_t i = 0; i < MSEdge::dictSize(); i++) { for (MESegment* s = MSGlobals::gMesoNet->getSegmentForEdge(*MSEdge::dictionary(i)); s != 0; s = s->getNextSegment()) { s->saveState(out); } } #endif } else { for (size_t i = 0; i < MSEdge::dictSize(); i++) { const std::vector<MSLane*>& lanes = MSEdge::dictionary(i)->getLanes(); for (std::vector<MSLane*>::const_iterator it = lanes.begin(); it != lanes.end(); ++it) { (*it)->saveState(out); } } } }
SUMOReal GUIEdge::getMeanSpeed() const { SUMOReal v = 0; SUMOReal no = 0; for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != 0; segment = segment->getNextSegment()) { SUMOReal vehNo = (SUMOReal) segment->getCarNumber(); v += vehNo * segment->getMeanSpeed(); no += vehNo; } if (no == 0) { return getSpeedLimit(); } return v / no; }
SUMOReal GUIEdge::getBruttoOccupancy() const { SUMOReal occ = 0; for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != 0; segment = segment->getNextSegment()) { occ += segment->getBruttoOccupancy(); } return occ / (*myLanes)[0]->getLength() / (SUMOReal)(myLanes->size()); }
SUMOReal GUIEdge::getFlow() const { SUMOReal flow = 0; for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != 0; segment = segment->getNextSegment()) { flow += (SUMOReal) segment->getCarNumber() * segment->getMeanSpeed(); } return 3600 * flow / (*myLanes)[0]->getLength(); }
std::string GUIEdge::getVehicleIDs() const { std::string result = " "; std::vector<const MEVehicle*> vehs; for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != 0; segment = segment->getNextSegment()) { std::vector<const MEVehicle*> segmentVehs = segment->getVehicles(); vehs.insert(vehs.end(), segmentVehs.begin(), segmentVehs.end()); } for (std::vector<const MEVehicle*>::const_iterator it = vehs.begin(); it != vehs.end(); it++) { result += (*it)->getID() + " "; } return result; }
unsigned int GUIEdge::getVehicleNo() const { size_t vehNo = 0; for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != 0; segment = segment->getNextSegment()) { vehNo += segment->getCarNumber(); } return (unsigned int)vehNo; }
void GUIEdge::drawMesoVehicles(const GUIVisualizationSettings& s) const { const GUIVisualizationTextSettings& nameSettings = s.vehicleName; const SUMOReal exaggeration = s.vehicleSize.getExaggeration(s); GUIMEVehicleControl* vehicleControl = GUINet::getGUIInstance()->getGUIMEVehicleControl(); if (vehicleControl != 0) { // draw the meso vehicles vehicleControl->secureVehicles(); size_t laneIndex = 0; MESegment::Queue queue; for (std::vector<MSLane*>::const_iterator msl = myLanes->begin(); msl != myLanes->end(); ++msl, ++laneIndex) { GUILane* l = static_cast<GUILane*>(*msl); // go through the vehicles SUMOReal segmentOffset = 0; // offset at start of current segment for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != 0; segment = segment->getNextSegment()) { const SUMOReal length = segment->getLength() * segment->getLengthGeometryFactor(); if (laneIndex < segment->numQueues()) { // make a copy so we don't have to worry about synchronization queue = segment->getQueue(laneIndex); const SUMOReal avgCarSize = segment->getBruttoOccupancy() / segment->getCarNumber(); const SUMOReal avgCarHalfSize = 0.5 * avgCarSize; const size_t queueSize = queue.size(); SUMOReal vehiclePosition = segmentOffset + length; // draw vehicles beginning with the leader at the end of the segment SUMOReal xOff = 0; for (size_t i = 0; i < queueSize; ++i) { MSBaseVehicle* veh = queue[queueSize - i - 1]; const SUMOReal vehLength = veh->getVehicleType().getLengthWithGap(); setVehicleColor(s, veh); while (vehiclePosition < segmentOffset) { // if there is only a single queue for a // multi-lane edge shift vehicles and start // drawing again from the end of the segment vehiclePosition += length; xOff += 2; } const Position p = l->geometryPositionAtOffset(vehiclePosition); const SUMOReal angle = -l->getShape().rotationDegreeAtOffset(l->interpolateLanePosToGeometryPos(vehiclePosition)); glPushMatrix(); glTranslated(p.x(), p.y(), 0); glRotated(angle, 0, 0, 1); glTranslated(xOff, 0, GLO_VEHICLE); glScaled(exaggeration, vehLength * exaggeration, 1); glBegin(GL_TRIANGLES); glVertex2d(0, 0); glVertex2d(0 - 1.25, 1); glVertex2d(0 + 1.25, 1); glEnd(); glPopMatrix(); if (nameSettings.show) { glPushMatrix(); glRotated(angle, 0, 0, 1); glTranslated(xOff, 0, 0); glRotated(-angle, 0, 0, 1); GLHelper::drawText(veh->getID(), l->geometryPositionAtOffset(vehiclePosition - 0.5 * vehLength), GLO_MAX, nameSettings.size / s.scale, nameSettings.color); glPopMatrix(); } vehiclePosition -= vehLength; } } segmentOffset += length; } glPopMatrix(); } vehicleControl->releaseVehicles(); } }
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)); }
SUMOReal MSEdge::getMeanSpeed() const { SUMOReal v = 0; SUMOReal no = 0; if (MSGlobals::gUseMesoSim) { for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != 0; segment = segment->getNextSegment()) { const SUMOReal vehNo = (SUMOReal) segment->getCarNumber(); v += vehNo * segment->getMeanSpeed(); no += vehNo; } if (no == 0) { return getLength() / myEmptyTraveltime; // may include tls-penalty } } else { for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) { const SUMOReal vehNo = (SUMOReal)(*i)->getVehicleNumber(); v += vehNo * (*i)->getMeanSpeed(); no += vehNo; } if (no == 0) { return getSpeedLimit(); } } return v / no; }
void GUIEdge::drawGL(const GUIVisualizationSettings& s) const { if (s.hideConnectors && myFunction == MSEdge::EDGEFUNCTION_CONNECTOR) { return; } if (MSGlobals::gUseMesoSim) { glPushName(getGlID()); } // draw the lanes for (LaneWrapperVector::const_iterator i = myLaneGeoms.begin(); i != myLaneGeoms.end(); ++i) { #ifdef HAVE_INTERNAL if (MSGlobals::gUseMesoSim) { setColor(s); } #endif (*i)->drawGL(s); } #ifdef HAVE_INTERNAL if (MSGlobals::gUseMesoSim) { const GUIVisualizationTextSettings& nameSettings = s.vehicleName; GUIMEVehicleControl* vehicleControl = GUINet::getGUIInstance()->getGUIMEVehicleControl(); if (vehicleControl != 0) { // draw the meso vehicles vehicleControl->secureVehicles(); size_t laneIndex = 0; MESegment::Queue queue; for (LaneWrapperVector::const_iterator l = myLaneGeoms.begin(); l != myLaneGeoms.end(); ++l, ++laneIndex) { const PositionVector& shape = (*l)->getShape(); const std::vector<SUMOReal>& shapeRotations = (*l)->getShapeRotations(); const std::vector<SUMOReal>& shapeLengths = (*l)->getShapeLengths(); const Position& laneBeg = shape[0]; glPushMatrix(); glTranslated(laneBeg.x(), laneBeg.y(), 0); glRotated(shapeRotations[0], 0, 0, 1); // go through the vehicles int shapeIndex = 0; SUMOReal shapeOffset = 0; // ofset at start of current shape SUMOReal segmentOffset = 0; // offset at start of current segment for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != 0; segment = segment->getNextSegment()) { const SUMOReal length = segment->getLength(); if (laneIndex < segment->numQueues()) { // make a copy so we don't have to worry about synchronization queue = segment->getQueue(laneIndex); const SUMOReal avgCarSize = segment->getOccupancy() / segment->getCarNumber(); const size_t queueSize = queue.size(); for (size_t i = 0; i < queueSize; i++) { MSBaseVehicle* veh = queue[queueSize - i - 1]; setVehicleColor(s, veh); SUMOReal vehiclePosition = segmentOffset + length - i * avgCarSize; SUMOReal xOff = 0.f; while (vehiclePosition < segmentOffset) { // if there is only a single queue for a // multi-lane edge shift vehicles and start // drawing again from the end of the segment vehiclePosition += length; xOff += 0.5f; } while (shapeIndex < (int)shapeRotations.size() - 1 && vehiclePosition > shapeOffset + shapeLengths[shapeIndex]) { glPopMatrix(); shapeOffset += shapeLengths[shapeIndex]; shapeIndex++; glPushMatrix(); glTranslated(shape[shapeIndex].x(), shape[shapeIndex].y(), 0); glRotated(shapeRotations[shapeIndex], 0, 0, 1); } glPushMatrix(); glTranslated(xOff, -(vehiclePosition - shapeOffset), GLO_VEHICLE); glPushMatrix(); glScaled(1, avgCarSize, 1); glBegin(GL_TRIANGLES); glVertex2d(0, 0); glVertex2d(0 - 1.25, 1); glVertex2d(0 + 1.25, 1); glEnd(); glPopMatrix(); glPopMatrix(); if (nameSettings.show) { GLHelper::drawText(veh->getID(), Position(xOff, -(vehiclePosition - shapeOffset)), GLO_MAX, nameSettings.size / s.scale, nameSettings.color, 0); } } } segmentOffset += length; } glPopMatrix(); } vehicleControl->releaseVehicles(); } glPopName(); } #endif // (optionally) draw the name and/or the street name const bool drawEdgeName = s.edgeName.show && myFunction == EDGEFUNCTION_NORMAL; const bool drawInternalEdgeName = s.internalEdgeName.show && myFunction != EDGEFUNCTION_NORMAL; const bool drawStreetName = s.streetName.show && myStreetName != ""; if (drawEdgeName || drawInternalEdgeName || drawStreetName) { GUILaneWrapper* lane1 = myLaneGeoms[0]; GUILaneWrapper* lane2 = myLaneGeoms[myLaneGeoms.size() - 1]; Position p = lane1->getShape().positionAtLengthPosition(lane1->getShape().length() / (SUMOReal) 2.); p.add(lane2->getShape().positionAtLengthPosition(lane2->getShape().length() / (SUMOReal) 2.)); p.mul(.5); SUMOReal angle = lane1->getShape().rotationDegreeAtLengthPosition(lane1->getShape().length() / (SUMOReal) 2.); angle += 90; if (angle > 90 && angle < 270) { angle -= 180; } if (drawEdgeName) { drawName(p, s.scale, s.edgeName, angle); } else if (drawInternalEdgeName) { drawName(p, s.scale, s.internalEdgeName, angle); } if (drawStreetName) { GLHelper::drawText(getStreetName(), p, GLO_MAX, s.streetName.size / s.scale, s.streetName.color, angle); } } myLock.lock(); for (std::set<MSPerson*>::const_iterator i = myPersons.begin(); i != myPersons.end(); ++i) { GUIPerson* person = dynamic_cast<GUIPerson*>(*i); assert(person != 0); person->drawGL(s); } myLock.unlock(); }
void MSXMLRawOut::writeEdge(OutputDevice& of, const MSEdge& edge, SUMOTime timestep) { //en bool dump = !MSGlobals::gOmitEmptyEdgesOnDump; if (!dump) { #ifdef HAVE_INTERNAL if (MSGlobals::gUseMesoSim) { MESegment* seg = MSGlobals::gMesoNet->getSegmentForEdge(edge); while (seg != 0) { if (seg->getCarNumber() != 0) { dump = true; break; } seg = seg->getNextSegment(); } } else { #endif const std::vector<MSLane*>& lanes = edge.getLanes(); for (std::vector<MSLane*>::const_iterator lane = lanes.begin(); lane != lanes.end(); ++lane) { if (((**lane).getVehicleNumber() != 0)) { dump = true; break; } } #ifdef HAVE_INTERNAL } #endif } //en const std::vector<MSPerson*>& persons = edge.getSortedPersons(timestep); if (dump || persons.size() > 0) { of.openTag("edge") << " id=\"" << edge.getID() << "\""; if (dump) { #ifdef HAVE_INTERNAL if (MSGlobals::gUseMesoSim) { MESegment* seg = MSGlobals::gMesoNet->getSegmentForEdge(edge); while (seg != 0) { seg->writeVehicles(of); seg = seg->getNextSegment(); } } else { #endif const std::vector<MSLane*>& lanes = edge.getLanes(); for (std::vector<MSLane*>::const_iterator lane = lanes.begin(); lane != lanes.end(); ++lane) { writeLane(of, **lane); } #ifdef HAVE_INTERNAL } #endif } // write persons for (std::vector<MSPerson*>::const_iterator it_p = persons.begin(); it_p != persons.end(); ++it_p) { of.openTag(SUMO_TAG_PERSON); of.writeAttr(SUMO_ATTR_ID, (*it_p)->getID()); of.writeAttr(SUMO_ATTR_POSITION, (*it_p)->getEdgePos()); of.writeAttr(SUMO_ATTR_ANGLE, (*it_p)->getAngle()); of.writeAttr("stage", (*it_p)->getCurrentStageDescription()); of.closeTag(); } of.closeTag(); } }
SUMOTime METriggeredCalibrator::execute(SUMOTime currentTime) { // get current simulation values (valid for the last simulation second) // XXX could we miss vehicle movements if this is called less often than every DELTA_T (default) ? mySegment->prepareDetectorForWriting(myEdgeMeanData); // check whether an adaptation value exists if (isCurrentStateActive(currentTime)) { // all happens in isCurrentStateActive() } else { myEdgeMeanData.reset(); // discard collected values if (!mySpeedIsDefault) { // if not, reset adaptation values mySegment->getEdge().setMaxSpeed(myDefaultSpeed); MESegment* first = MSGlobals::gMesoNet->getSegmentForEdge(mySegment->getEdge()); const SUMOReal jamThresh = OptionsCont::getOptions().getFloat("meso-jam-threshold"); while (first != 0) { first->setSpeed(myDefaultSpeed, currentTime, jamThresh); first = first->getNextSegment(); } mySpeedIsDefault = true; } if (myCurrentStateInterval == myIntervals.end()) { // keep calibrator alive but do not call again return TIME2STEPS(86400); } return myFrequency; } // we are active if (!myDidSpeedAdaption && myCurrentStateInterval->v >= 0 && myCurrentStateInterval->v != mySegment->getEdge().getSpeedLimit()) { mySegment->getEdge().setMaxSpeed(myCurrentStateInterval->v); MESegment* first = MSGlobals::gMesoNet->getSegmentForEdge(mySegment->getEdge()); while (first != 0) { first->setSpeed(myCurrentStateInterval->v, currentTime, -1); first = first->getNextSegment(); } mySpeedIsDefault = false; myDidSpeedAdaption = true; } // clear invalid jams bool hadInvalidJam = false; while (invalidJam()) { hadInvalidJam = true; if (!myHaveWarnedAboutClearingJam) { WRITE_WARNING("Clearing jam at calibrator '" + myID + "' at time " + time2string(currentTime)); } // remove one vehicle currently on the segment if (mySegment->vaporizeAnyCar(currentTime)) { myClearedInJam++; } else { if (!myHaveWarnedAboutClearingJam) { // this frequenly happens for very short edges WRITE_WARNING("Could not clear jam at calibrator '" + myID + "' at time " + time2string(currentTime)); } break; } myHaveWarnedAboutClearingJam = true; } if (myCurrentStateInterval->q >= 0) { // flow calibration starts here ... // compute the number of vehicles that should have passed the calibrator within the time // rom begin of the interval const SUMOReal totalHourFraction = STEPS2TIME(myCurrentStateInterval->end - myCurrentStateInterval->begin) / (SUMOReal) 3600.; const int totalWishedNum = (int)std::floor(myCurrentStateInterval->q * totalHourFraction + 0.5); // round to closest int int adaptedNum = passed() + myClearedInJam; if (!hadInvalidJam) { // only add vehicles if we do not have an invalid upstream jam to prevent spill-back const SUMOReal hourFraction = STEPS2TIME(currentTime - myCurrentStateInterval->begin + DELTA_T) / (SUMOReal) 3600.; const int wishedNum = (int)std::floor(myCurrentStateInterval->q * hourFraction + 0.5); // round to closest int // only the difference between inflow and aspiredFlow should be added, thus // we should not count vehicles vaporized from a jam here // if we have enough time left we can add missing vehicles later const int relaxedInsertion = (int)std::floor(STEPS2TIME(myCurrentStateInterval->end - currentTime) / 3); const int insertionSlack = MAX2(0, adaptedNum + relaxedInsertion - totalWishedNum); // increase number of vehicles //std::cout << "time:" << STEPS2TIME(currentTime) << " w:" << wishedNum << " s:" << insertionSlack << " before:" << adaptedNum; while (wishedNum > adaptedNum + insertionSlack && remainingVehicleCapacity() > maximumInflow()) { SUMOVehicleParameter* pars = myCurrentStateInterval->vehicleParameter; const MSRoute* route = myProbe != 0 ? myProbe->getRoute() : 0; if (route == 0) { route = MSRoute::dictionary(pars->routeid); } if (route == 0) { WRITE_WARNING("No valid routes in calibrator '" + myID + "'."); break; } if (!route->contains(myEdge)) { WRITE_WARNING("Route '" + route->getID() + "' in calibrator '" + myID + "' does not contain edge '" + myEdge->getID() + "'."); break; } MSVehicleType* vtype = MSNet::getInstance()->getVehicleControl().getVType(pars->vtypeid); assert(route != 0 && vtype != 0); // build the vehicle const SUMOTime depart = mySegment->getNextInsertionTime(currentTime); SUMOVehicleParameter* newPars = new SUMOVehicleParameter(*pars); newPars->id = myID + "." + toString(depart) + "." + toString(myInserted); newPars->depart = depart; newPars->routeid = route->getID(); MEVehicle* vehicle = static_cast<MEVehicle*>(MSNet::getInstance()->getVehicleControl().buildVehicle( newPars, route, vtype, false, false)); vehicle->setSegment(mySegment); // needed or vehicle will not be registered (XXX why?) vehicle->setEventTime(currentTime); // XXX superfluous? // move vehicle forward when the route does not begin at the calibrator's edge const MSEdge* myedge = &mySegment->getEdge(); bool atDest = false; while (vehicle->getEdge() != myedge) { // let the vehicle move to the next edge atDest = vehicle->moveRoutePointer(); } // insert vehicle into the net if (atDest || !tryEmit(mySegment, vehicle)) { //std::cout << "F "; MSNet::getInstance()->getVehicleControl().deleteVehicle(vehicle, true); break; } //std::cout << "I "; myInserted++; adaptedNum++; } } //std::cout << " after:" << adaptedNum << "\n"; // we only remove vehicles once we really have to while (totalWishedNum < adaptedNum) { if (!mySegment->vaporizeAnyCar(currentTime)) { // @bug: short edges may be jumped in a single step, giving us no chance to remove a vehicle break; } myRemoved++; adaptedNum--; } } if (myCurrentStateInterval->end <= currentTime + myFrequency) { writeXMLOutput(); } assert(!invalidJam()); return myFrequency; }