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; }
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 }
GUIParameterTableWindow* GUIEdge::getParameterWindow(GUIMainWindow& app, GUISUMOAbstractView& parent) { GUIParameterTableWindow* ret = 0; #ifdef HAVE_INTERNAL ret = new GUIParameterTableWindow(app, *this, 16); // add edge items ret->mkItem("length [m]", false, (*myLanes)[0]->getLength()); ret->mkItem("allowed speed [m/s]", false, getAllowedSpeed()); ret->mkItem("occupancy [%]", true, new FunctionBinding<GUIEdge, SUMOReal>(this, &GUIEdge::getBruttoOccupancy, 100.)); ret->mkItem("mean vehicle speed [m/s]", true, new FunctionBinding<GUIEdge, SUMOReal>(this, &GUIEdge::getMeanSpeed)); ret->mkItem("flow [veh/h/lane]", true, new FunctionBinding<GUIEdge, SUMOReal>(this, &GUIEdge::getFlow)); ret->mkItem("#vehicles", true, new CastingFunctionBinding<GUIEdge, SUMOReal, unsigned int>(this, &GUIEdge::getVehicleNo)); ret->mkItem("vehicle ids", false, getVehicleIDs()); // add segment items MESegment* segment = getSegmentAtPosition(parent.getPositionInformation()); ret->mkItem("segment index", false, segment->getIndex()); ret->mkItem("segment length [m]", false, segment->getLength()); ret->mkItem("segment allowed speed [m/s]", false, segment->getMaxSpeed()); ret->mkItem("segment jam threshold [%]", false, segment->getRelativeJamThreshold()); ret->mkItem("segment occupancy [%]", true, new FunctionBinding<MESegment, SUMOReal>(segment, &MESegment::getRelativeOccupancy)); ret->mkItem("segment mean vehicle speed [m/s]", true, new FunctionBinding<MESegment, SUMOReal>(segment, &MESegment::getMeanSpeed)); ret->mkItem("segment flow [veh/h/lane]", true, new FunctionBinding<MESegment, SUMOReal>(segment, &MESegment::getFlow)); ret->mkItem("segment #vehicles", true, new CastingFunctionBinding<MESegment, SUMOReal, size_t>(segment, &MESegment::getCarNumber)); ret->mkItem("segment leader leave time", true, new FunctionBinding<MESegment, SUMOReal>(segment, &MESegment::getEventTimeSeconds)); // close building ret->closeBuilding(); #else UNUSED_PARAMETER(app); UNUSED_PARAMETER(parent); #endif return ret; }
GUIParameterTableWindow* GUIEdge::getParameterWindow(GUIMainWindow& app, GUISUMOAbstractView& parent) { GUIParameterTableWindow* ret = 0; ret = new GUIParameterTableWindow(app, *this, 18); // add edge items ret->mkItem("length [m]", false, (*myLanes)[0]->getLength()); ret->mkItem("allowed speed [m/s]", false, getAllowedSpeed()); ret->mkItem("brutto occupancy [%]", true, new FunctionBinding<GUIEdge, SUMOReal>(this, &GUIEdge::getBruttoOccupancy, 100.)); ret->mkItem("mean vehicle speed [m/s]", true, new FunctionBinding<GUIEdge, SUMOReal>(this, &GUIEdge::getMeanSpeed)); ret->mkItem("flow [veh/h/lane]", true, new FunctionBinding<GUIEdge, SUMOReal>(this, &GUIEdge::getFlow)); ret->mkItem("routing speed [m/s]", true, new FunctionBinding<MSEdge, SUMOReal>(this, &MSEdge::getRoutingSpeed)); ret->mkItem("#vehicles", true, new CastingFunctionBinding<GUIEdge, SUMOReal, int>(this, &GUIEdge::getVehicleNo)); ret->mkItem("vehicle ids", false, getVehicleIDs()); // add segment items MESegment* segment = getSegmentAtPosition(parent.getPositionInformation()); ret->mkItem("segment index", false, segment->getIndex()); ret->mkItem("segment queues", false, segment->numQueues()); ret->mkItem("segment length [m]", false, segment->getLength()); ret->mkItem("segment allowed speed [m/s]", false, segment->getEdge().getSpeedLimit()); ret->mkItem("segment jam threshold [%]", false, segment->getRelativeJamThreshold() * 100); ret->mkItem("segment brutto occupancy [%]", true, new FunctionBinding<MESegment, SUMOReal>(segment, &MESegment::getRelativeOccupancy, 100)); ret->mkItem("segment mean vehicle speed [m/s]", true, new FunctionBinding<MESegment, SUMOReal>(segment, &MESegment::getMeanSpeed)); ret->mkItem("segment flow [veh/h/lane]", true, new FunctionBinding<MESegment, SUMOReal>(segment, &MESegment::getFlow)); ret->mkItem("segment #vehicles", true, new CastingFunctionBinding<MESegment, SUMOReal, int>(segment, &MESegment::getCarNumber)); ret->mkItem("segment leader leave time", true, new FunctionBinding<MESegment, SUMOReal>(segment, &MESegment::getEventTimeSeconds)); ret->mkItem("segment headway [s]", true, new FunctionBinding<MESegment, SUMOReal>(segment, &MESegment::getLastHeadwaySeconds)); // close building ret->closeBuilding(); return ret; }
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 } }
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 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(); } }
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(); }
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; } }