// =========================================================================== // method definitions // =========================================================================== GUILaneWrapper::GUILaneWrapper(GUIGlObjectStorage &idStorage, MSLane &lane, const Position2DVector &shape) throw() : GUIGlObject(idStorage, "lane:"+lane.getID()), myLane(lane), myShape(shape) { SUMOReal x1 = shape[0].x(); SUMOReal y1 = shape[0].y(); SUMOReal x2 = shape[-1].x(); SUMOReal y2 = shape[-1].y(); SUMOReal length = myLane.getLength(); // also the virtual length is set in here myVisLength = sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2)); // check maximum speed if (myAllMaxSpeed<lane.getMaxSpeed()) { myAllMaxSpeed = lane.getMaxSpeed(); } // myShapeRotations.reserve(myShape.size()-1); myShapeLengths.reserve(myShape.size()-1); int e = (int) myShape.size() - 1; for (int i=0; i<e; ++i) { const Position2D &f = myShape[i]; const Position2D &s = myShape[i+1]; myShapeLengths.push_back(f.distanceTo(s)); myShapeRotations.push_back((SUMOReal) atan2((s.x()-f.x()), (f.y()-s.y()))*(SUMOReal) 180.0/(SUMOReal) PI); } }
void GUIVehicle::drawAction_drawLinkItems(const GUIVisualizationSettings& s) const { glTranslated(0, 0, getType() + .2); // draw on top of cars for (DriveItemVector::const_iterator i = myLFLinkLanes.begin(); i != myLFLinkLanes.end(); ++i) { if ((*i).myLink == nullptr) { continue; } MSLink* link = (*i).myLink; MSLane* via = link->getViaLaneOrLane(); if (via != nullptr) { Position p = via->getShape()[0]; if ((*i).mySetRequest) { glColor3d(0, .8, 0); } else { glColor3d(.8, 0, 0); } const SUMOTime leaveTime = (*i).myLink->getLeaveTime( (*i).myArrivalTime, (*i).myArrivalSpeed, (*i).getLeaveSpeed(), getVehicleType().getLength()); drawLinkItem(p, (*i).myArrivalTime, leaveTime, s.vehicleName.size / s.scale); // the time slot that ego vehicle uses when checking opened may // differ from the one it requests in setApproaching MSLink::ApproachingVehicleInformation avi = (*i).myLink->getApproaching(this); assert(avi.arrivalTime == (*i).myArrivalTime && avi.leavingTime == leaveTime); UNUSED_PARAMETER(avi); // only used for assertion } } glTranslated(0, 0, getType() - .2); // draw on top of cars }
void MSEdge::recalcCache() { if (myLanes->empty()) { return; } myLength = myLanes->front()->getLength(); myEmptyTraveltime = myLength / MAX2(getSpeedLimit(), NUMERICAL_EPS); if (MSGlobals::gMesoTLSPenalty > 0 || MSGlobals::gMesoMinorPenalty > 0) { // add tls penalties to the minimum travel time SUMOTime minPenalty = -1; for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) { MSLane* l = *i; const MSLinkCont& lc = l->getLinkCont(); for (MSLinkCont::const_iterator j = lc.begin(); j != lc.end(); ++j) { MSLink* link = *j; SUMOTime linkPenalty = link->getMesoTLSPenalty() + (link->havePriority() ? 0 : MSGlobals::gMesoMinorPenalty); if (minPenalty == -1) { minPenalty = linkPenalty; } else { minPenalty = MIN2(minPenalty, linkPenalty); } } } if (minPenalty > 0) { myEmptyTraveltime += STEPS2TIME(minPenalty); } } }
void MSRailSignal::collectConflictLinks(MSLane* toLane, double length, std::vector<MSLane*>& backwardBlock, std::vector<MSLink*>& conflictLinks, LaneSet& visited, bool checkFoes) { while (toLane != nullptr) { //std::cout << "collectConflictLinks " << getID() << " toLane=" << toLane->getID() << " length=" << length // << " backward=" << toString(backwardBlock) // << " conflictLinks=" << conflictLinks.size() // << " visited=" << visited.size() // << " checkFoes=" << checkFoes // << "\n"; const auto& incomingLaneInfos = toLane->getIncomingLanes(); MSLane* orig = toLane; toLane = nullptr; for (const auto& ili : incomingLaneInfos) { if (ili.viaLink->getDirection() == LINKDIR_TURN) { continue; } if (visited.count(ili.lane) != 0) { continue; } if (ili.viaLink->getTLLogic() != nullptr) { conflictLinks.push_back(ili.viaLink); continue; } backwardBlock.push_back(ili.lane); visited.insert(ili.lane); length += orig->getLength(); if (length > MAX_BLOCK_LENGTH) { if (myNumWarnings < MAX_SIGNAL_WARNINGS) { WRITE_WARNING("incoming conflict block after rail signal junction '" + getID() + "' exceeds maximum length (stopped searching after lane '" + orig->getID() + "' (length=" + toString(length) + "m)."); } myNumWarnings++; return; } if (toLane == nullptr) { toLane = ili.lane; } else { collectConflictLinks(ili.lane, length, backwardBlock, conflictLinks, visited, false); } } if (checkFoes && orig->isInternal()) { // check for crossed tracks MSLink* link = orig->getIncomingLanes().front().viaLink; if (link->getDirection() != LINKDIR_TURN) { for (const MSLane* foeConst : link->getFoeLanes()) { MSLane* foe = const_cast<MSLane*>(foeConst); if (visited.count(foe) == 0) { backwardBlock.push_back(foe); visited.insert(foe); collectConflictLinks(foe, length, backwardBlock, conflictLinks, visited, false); } } } } } }
void MSEdge::closeBuilding() { myAllowed[0] = new std::vector<MSLane*>(); for (std::vector<MSLane*>::iterator i = myLanes->begin(); i != myLanes->end(); ++i) { myAllowed[0]->push_back(*i); const MSLinkCont& lc = (*i)->getLinkCont(); for (MSLinkCont::const_iterator j = lc.begin(); j != lc.end(); ++j) { MSLane* toL = (*j)->getLane(); if (toL != 0) { MSEdge& to = toL->getEdge(); // if (std::find(mySuccessors.begin(), mySuccessors.end(), &to) == mySuccessors.end()) { mySuccessors.push_back(&to); } if (std::find(to.myPredeccesors.begin(), to.myPredeccesors.end(), this) == to.myPredeccesors.end()) { to.myPredeccesors.push_back(this); } // if (myAllowed.find(&to) == myAllowed.end()) { myAllowed[&to] = new std::vector<MSLane*>(); } myAllowed[&to]->push_back(*i); } #ifdef HAVE_INTERNAL_LANES toL = (*j)->getViaLane(); if (toL != 0) { MSEdge& to = toL->getEdge(); to.myPredeccesors.push_back(this); } #endif } } std::sort(mySuccessors.begin(), mySuccessors.end(), by_id_sorter()); rebuildAllowedLanes(); }
void NLTriggerBuilder::parseAndBuildCalibrator(MSNet& net, const SUMOSAXAttributes& attrs, const std::string& base) { bool ok = true; // get the id, throw if not given or empty... std::string id = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok); if (!ok) { throw ProcessError(); } // get the file name to read further definitions from MSLane* lane = getLane(attrs, "calibrator", id); const SUMOReal pos = getPosition(attrs, lane, "calibrator", id); const SUMOTime freq = attrs.getOptSUMOTimeReporting(SUMO_ATTR_FREQUENCY, id.c_str(), ok, DELTA_T); // !!! no error handling std::string file = getFileName(attrs, base, true); std::string outfile = attrs.getOpt<std::string>(SUMO_ATTR_OUTPUT, 0, ok, ""); if (MSGlobals::gUseMesoSim) { #ifdef HAVE_INTERNAL METriggeredCalibrator* trigger = buildMECalibrator(net, id, &lane->getEdge(), pos, file, outfile, freq); if (file == "") { trigger->registerParent(SUMO_TAG_CALIBRATOR, myHandler); } #endif } else { MSCalibrator* trigger = buildCalibrator(net, id, &lane->getEdge(), pos, file, outfile, freq); if (file == "") { trigger->registerParent(SUMO_TAG_CALIBRATOR, myHandler); } } }
std::pair<MSVehicle* const, SUMOReal> MSLaneChanger::getRealLeader(const ChangerIt& target) const { // get the leading vehicle on the lane to change to MSVehicle* neighLead = target->lead; // check whether the hopped vehicle got the leader if (target->hoppedVeh != 0) { SUMOReal hoppedPos = target->hoppedVeh->getPositionOnLane(); if (hoppedPos > veh(myCandi)->getPositionOnLane() && (neighLead == 0 || neighLead->getPositionOnLane() > hoppedPos)) { neighLead = target->hoppedVeh; } } if (neighLead == 0) { MSLane* targetLane = target->lane; MSVehicle* predP = targetLane->getPartialOccupator(); if (predP != 0) { return std::pair<MSVehicle*, SUMOReal>(predP, targetLane->getPartialOccupatorEnd() - veh(myCandi)->getPositionOnLane() - veh(myCandi)->getVehicleType().getMinGap()); } const std::vector<MSLane*>& bestLaneConts = veh(myCandi)->getBestLanesContinuation(myCandi->lane); SUMOReal seen = myCandi->lane->getLength() - veh(myCandi)->getPositionOnLane(); SUMOReal speed = veh(myCandi)->getSpeed(); SUMOReal dist = veh(myCandi)->getCarFollowModel().brakeGap(speed) + veh(myCandi)->getVehicleType().getMinGap(); if (seen > dist) { return std::pair<MSVehicle* const, SUMOReal>(static_cast<MSVehicle*>(0), -1); } return target->lane->getLeaderOnConsecutive(dist, seen, speed, *veh(myCandi), bestLaneConts); } else { MSVehicle* candi = veh(myCandi); return std::pair<MSVehicle* const, SUMOReal>(neighLead, neighLead->getPositionOnLane() - neighLead->getVehicleType().getLength() - candi->getPositionOnLane() - candi->getVehicleType().getMinGap()); } }
bool MSLaneChangerSublane::startChangeSublane(MSVehicle* vehicle, ChangerIt& from, SUMOReal latDist) { //gDebugFlag4 = vehicle->getID() == "Togliatti_80_26"; // 1) update vehicles lateral position according to latDist and target lane vehicle->myState.myPosLat += latDist; vehicle->myCachedPosition = Position::INVALID; // 2) distinguish several cases // a) vehicle moves completely within the same lane // b) vehicle intersects another lane // - vehicle must be moved to the lane where it's midpoint is (either old or new) // - shadow vehicle must be created/moved to the other lane if the vehicle intersects it // 3) updated dens of all lanes that hold the vehicle or its shadow const int direction = vehicle->getLateralPositionOnLane() < 0 ? -1 : 1; ChangerIt to = from; if (mayChange(direction)) { to = from + direction; } else { /// XXX assert(false); } const bool changedToNewLane = to != from && fabs(vehicle->getLateralPositionOnLane()) > 0.5 * vehicle->getLane()->getWidth() && mayChange(direction); if (changedToNewLane) { vehicle->myState.myPosLat -= direction * 0.5 * (from->lane->getWidth() + to->lane->getWidth()); to->lane->myTmpVehicles.insert(to->lane->myTmpVehicles.begin(), vehicle); to->dens += vehicle->getVehicleType().getLengthWithGap(); vehicle->getLaneChangeModel().startLaneChangeManeuver(from->lane, to->lane, direction); to->ahead.addLeader(vehicle, false, 0); } else { registerUnchanged(vehicle); from->ahead.addLeader(vehicle, false, 0); } MSLane* oldShadowLane = vehicle->getLaneChangeModel().getShadowLane(); vehicle->getLaneChangeModel().updateShadowLane(); MSLane* shadowLane = vehicle->getLaneChangeModel().getShadowLane(); if (shadowLane != 0 && shadowLane != oldShadowLane) { assert(to != from); const SUMOReal latOffset = vehicle->getLane()->getRightSideOnEdge() - shadowLane->getRightSideOnEdge(); (myChanger.begin() + shadowLane->getIndex())->ahead.addLeader(vehicle, false, latOffset); } if (gDebugFlag4) std::cout << SIMTIME << " startChangeSublane shadowLane" << " old=" << Named::getIDSecure(oldShadowLane) << " new=" << Named::getIDSecure(vehicle->getLaneChangeModel().getShadowLane()) << "\n"; // compute new angle of the vehicle from the x- and y-distances travelled within last time step // (should happen last because primaryLaneChanged() also triggers angle computation) // this part of the angle comes from the orientation of our current lane SUMOReal laneAngle = vehicle->getLane()->getShape().rotationAtOffset(vehicle->getLane()->interpolateLanePosToGeometryPos(vehicle->getPositionOnLane())) ; // this part of the angle comes from the vehicle's lateral movement SUMOReal changeAngle = 0; // avoid flicker if (fabs(latDist) > NUMERICAL_EPS) { // avoid extreme angles by using vehicle length as a proxy for turning radius changeAngle = atan2(latDist, SPEED2DIST(MAX2(vehicle->getVehicleType().getLength(), vehicle->getSpeed()))); } vehicle->setAngle(laneAngle + changeAngle); return changedToNewLane; }
void NLHandler::addPOI(const SUMOSAXAttributes& attrs) { bool ok = true; const SUMOReal INVALID_POSITION(-1000000); std::string id = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok); SUMOReal x = attrs.getOpt<SUMOReal>(SUMO_ATTR_X, id.c_str(), ok, INVALID_POSITION); SUMOReal y = attrs.getOpt<SUMOReal>(SUMO_ATTR_Y, id.c_str(), ok, INVALID_POSITION); SUMOReal lon = attrs.getOpt<SUMOReal>(SUMO_ATTR_LON, id.c_str(), ok, INVALID_POSITION); SUMOReal lat = attrs.getOpt<SUMOReal>(SUMO_ATTR_LAT, id.c_str(), ok, INVALID_POSITION); SUMOReal lanePos = attrs.getOpt<SUMOReal>(SUMO_ATTR_POSITION, id.c_str(), ok, INVALID_POSITION); SUMOReal layer = attrs.getOpt<SUMOReal>(SUMO_ATTR_LAYER, id.c_str(), ok, (SUMOReal)GLO_POI); std::string type = attrs.getOpt<std::string>(SUMO_ATTR_TYPE, id.c_str(), ok, ""); std::string laneID = attrs.getOpt<std::string>(SUMO_ATTR_LANE, id.c_str(), ok, ""); RGBColor color = attrs.hasAttribute(SUMO_ATTR_COLOR) ? attrs.get<RGBColor>(SUMO_ATTR_COLOR, id.c_str(), ok) : RGBColor::RED; SUMOReal angle = attrs.getOpt<SUMOReal>(SUMO_ATTR_ANGLE, id.c_str(), ok, Shape::DEFAULT_ANGLE); std::string imgFile = attrs.getOpt<std::string>(SUMO_ATTR_IMGFILE, id.c_str(), ok, Shape::DEFAULT_IMG_FILE); if (imgFile != "" && !FileHelpers::isAbsolute(imgFile)) { imgFile = FileHelpers::getConfigurationRelative(getFileName(), imgFile); } SUMOReal width = attrs.getOpt<SUMOReal>(SUMO_ATTR_WIDTH, id.c_str(), ok, Shape::DEFAULT_IMG_WIDTH); SUMOReal height = attrs.getOpt<SUMOReal>(SUMO_ATTR_HEIGHT, id.c_str(), ok, Shape::DEFAULT_IMG_HEIGHT); if (!ok) { return; } Position pos(x, y); if (x == INVALID_POSITION || y == INVALID_POSITION) { // try computing x,y from lane,pos if (laneID != "") { MSLane* lane = MSLane::dictionary(laneID); if (lane == 0) { WRITE_ERROR("Lane '" + laneID + "' to place a poi '" + id + "'on is not known."); return; } if (lanePos < 0) { lanePos = lane->getLength() + lanePos; } pos = lane->geometryPositionAtOffset(lanePos); } else { // try computing x,y from lon,lat if (lat == INVALID_POSITION || lon == INVALID_POSITION) { WRITE_ERROR("Either (x,y), (lon,lat) or (lane,pos) must be specified for poi '" + id + "'."); return; } else if (!GeoConvHelper::getFinal().usingGeoProjection()) { WRITE_ERROR("(lon, lat) is specified for poi '" + id + "' but no geo-conversion is specified for the network."); return; } pos.set(lon, lat); GeoConvHelper::getFinal().x2cartesian_const(pos); } } if (!myNet.getShapeContainer().addPOI(id, type, color, layer, angle, imgFile, pos, width, height)) { WRITE_ERROR("PoI '" + id + "' already exists."); } }
void NLSucceedingLaneBuilder::closeSuccLane() throw(InvalidArgument) { MSLane *current = MSLane::dictionary(myCurrentLane); if (current==0) { throw InvalidArgument("Trying to close connections of an unknown lane ('" + myCurrentLane + "')."); } MSLinkCont *cont = new MSLinkCont(); cont->reserve(mySuccLanes->size()); copy(mySuccLanes->begin(), mySuccLanes->end(), back_inserter(*cont)); current->initialize(cont); mySuccLanes->clear(); }
// =========================================================================== // method definitions // =========================================================================== MSParkingArea::MSParkingArea(const std::string& id, const std::vector<std::string>& lines, MSLane& lane, double begPos, double endPos, unsigned int capacity, double width, double length, double angle, const std::string& name) : MSStoppingPlace(id, lines, lane, begPos, endPos, name), myCapacity(capacity), myWidth(width), myLength(length), myAngle(angle) { // initialize unspecified defaults if (myWidth == 0) { myWidth = SUMO_const_laneWidth; } if (myLength == 0) { myLength = getSpaceDim(); } const double offset = MSNet::getInstance()->lefthand() ? -1 : 1; myShape = lane.getShape().getSubpart( lane.interpolateLanePosToGeometryPos(begPos), lane.interpolateLanePosToGeometryPos(endPos)); myShape.move2side((lane.getWidth() / 2. + myWidth / 2.) * offset); // Initialize space occupancies if there is a road-side capacity // The overall number of lots is fixed and each lot accepts one vehicle regardless of size if (myCapacity > 0) { for (int i = 1; i <= myCapacity; ++i) { mySpaceOccupancies[i] = LotSpaceDefinition(); mySpaceOccupancies[i].index = i; mySpaceOccupancies[i].vehicle = 0; mySpaceOccupancies[i].myWidth = myWidth; mySpaceOccupancies[i].myLength = myLength; mySpaceOccupancies[i].myEndPos = myBegPos + getSpaceDim() * i; const Position& f = myShape.positionAtOffset(getSpaceDim() * (i - 1)); const Position& s = myShape.positionAtOffset(getSpaceDim() * (i)); double lot_angle = ((double) atan2((s.x() - f.x()), (f.y() - s.y())) * (double) 180.0 / (double) M_PI) + myAngle; mySpaceOccupancies[i].myRotation = lot_angle; if (myAngle == 0) { // parking parallel to the road mySpaceOccupancies[i].myPosition = s; } else { // angled parking mySpaceOccupancies[i].myPosition = (f + s) * 0.5; } } } computeLastFreePos(); }
bool MSLaneChanger::continueChange(MSVehicle* vehicle, ChangerIt& from) { MSAbstractLaneChangeModel& lcm = vehicle->getLaneChangeModel(); const int direction = lcm.getLaneChangeDirection(); const bool pastMidpoint = lcm.updateCompletion(); vehicle->myState.myPosLat += lcm.getLateralSpeed(); vehicle->myCachedPosition = Position::INVALID; ChangerIt shadow; if (pastMidpoint) { ChangerIt to = from + direction; MSLane* source = myCandi->lane; MSLane* target = to->lane; vehicle->myState.myPosLat -= direction * 0.5 * (source->getWidth() + target->getWidth()); lcm.primaryLaneChanged(source, target, direction); to->lane->myTmpVehicles.insert(to->lane->myTmpVehicles.begin(), vehicle); to->dens += vehicle->getVehicleType().getLengthWithGap(); to->hoppedVeh = vehicle; shadow = from; } else { from->lane->myTmpVehicles.insert(from->lane->myTmpVehicles.begin(), vehicle); from->dens += vehicle->getVehicleType().getLengthWithGap(); from->hoppedVeh = vehicle; shadow = from + lcm.getShadowDirection(); } if (!lcm.isChangingLanes()) { vehicle->myState.myPosLat = 0; lcm.endLaneChangeManeuver(); } lcm.updateShadowLane(); if (lcm.getShadowLane() != 0) { // set as hoppedVeh on the shadow lane so it is found as leader on both lanes shadow->hoppedVeh = vehicle; } vehicle->myAngle = vehicle->computeAngle(); #ifdef DEBUG_CONTINUE_CHANGE if(DEBUG_COND){ std::cout << SIMTIME << " continueChange veh=" << vehicle->getID() << " from=" << Named::getIDSecure(from->lane) << " dir=" << direction << " pastMidpoint=" << pastMidpoint << " posLat=" << vehicle->getLateralPositionOnLane() //<< " completion=" << lcm.getLaneChangeCompletion() << " shadowLane=" << Named::getIDSecure(lcm.getShadowLane()) << " shadowHopped=" << Named::getIDSecure(shadow->lane) << "\n"; } #endif return pastMidpoint; }
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 }
// =========================================================================== // method definitions // =========================================================================== MSCalibrator::MSCalibrator(const std::string& id, const MSEdge* const edge, MSLane* lane, const double pos, const std::string& aXMLFilename, const std::string& outputFilename, const SUMOTime freq, const double length, const MSRouteProbe* probe, bool addLaneMeanData) : MSTrigger(id), MSRouteHandler(aXMLFilename, true), myEdge(edge), myLane(lane), myPos(pos), myProbe(probe), myEdgeMeanData(nullptr, length, false, nullptr), myCurrentStateInterval(myIntervals.begin()), myOutput(nullptr), myFrequency(freq), myRemoved(0), myInserted(0), myClearedInJam(0), mySpeedIsDefault(true), myDidSpeedAdaption(false), myDidInit(false), myDefaultSpeed(myLane == nullptr ? myEdge->getSpeedLimit() : myLane->getSpeedLimit()), myHaveWarnedAboutClearingJam(false), myAmActive(false) { if (outputFilename != "") { myOutput = &OutputDevice::getDevice(outputFilename); myOutput->writeXMLHeader("calibratorstats", "calibratorstats_file.xsd"); } if (aXMLFilename != "") { XMLSubSys::runParser(*this, aXMLFilename); if (!myDidInit) { init(); } } if (addLaneMeanData) { // disabled for METriggeredCalibrator for (int i = 0; i < (int)myEdge->getLanes().size(); ++i) { MSLane* lane = myEdge->getLanes()[i]; if (myLane == nullptr || myLane == lane) { //std::cout << " cali=" << getID() << " myLane=" << Named::getIDSecure(myLane) << " checkLane=" << i << "\n"; MSMeanData_Net::MSLaneMeanDataValues* laneData = new MSMeanData_Net::MSLaneMeanDataValues(lane, lane->getLength(), true, nullptr); laneData->setDescription("meandata_calibrator_" + lane->getID()); LeftoverReminders.push_back(laneData); myLaneMeanData.push_back(laneData); VehicleRemover* remover = new VehicleRemover(lane, (int)i, this); LeftoverReminders.push_back(remover); myVehicleRemovers.push_back(remover); } } } }
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)); }
Position2D NLGeomShapeBuilder::getPointPosition(SUMOReal x, SUMOReal y, const std::string &laneID, SUMOReal posOnLane) const throw(InvalidArgument) { if (x!=INVALID_POSITION&&y!=INVALID_POSITION) { return Position2D(x,y); } MSLane *lane = MSLane::dictionary(laneID); if (lane==0) { throw InvalidArgument("Lane '" + laneID + "' to place a poi on is not known."); } if (posOnLane<0) { posOnLane = lane->getLength() + posOnLane; } return lane->getShape().positionAtLengthPosition(posOnLane); }
// =========================================================================== // method definitions // =========================================================================== GUIContainerStop::GUIContainerStop(const std::string& id, const std::vector<std::string>& lines, MSLane& lane, SUMOReal frompos, SUMOReal topos) : MSStoppingPlace(id, lines, lane, frompos, topos), GUIGlObject_AbstractAdd("containerStop", GLO_TRIGGER, id) { myFGShape = lane.getShape(); myFGShape.move2side((SUMOReal) 1.65); myFGShape = myFGShape.getSubpart(frompos, topos); myFGShapeRotations.reserve(myFGShape.size() - 1); myFGShapeLengths.reserve(myFGShape.size() - 1); int e = (int) myFGShape.size() - 1; for (int i = 0; i < e; ++i) { const Position& f = myFGShape[i]; const Position& s = myFGShape[i + 1]; myFGShapeLengths.push_back(f.distanceTo(s)); myFGShapeRotations.push_back((SUMOReal) atan2((s.x() - f.x()), (f.y() - s.y())) * (SUMOReal) 180.0 / (SUMOReal) PI); } PositionVector tmp = myFGShape; tmp.move2side(1.5); myFGSignPos = tmp.getLineCenter(); myFGSignRot = 0; if (tmp.length() != 0) { myFGSignRot = myFGShape.rotationDegreeAtOffset(SUMOReal((myFGShape.length() / 2.))); myFGSignRot -= 90; } }
std::pair<MSVehicle * const, SUMOReal> MSLane::getFollowerOnConsecutive(SUMOReal dist, SUMOReal seen, SUMOReal leaderSpeed, SUMOReal backOffset) const { // ok, a vehicle has not noticed the lane about itself; // iterate as long as necessary to search for an approaching one std::set<MSLane*> visited; std::vector<std::pair<MSVehicle *, SUMOReal> > possible; std::vector<MSLane::IncomingLaneInfo> newFound; std::vector<MSLane::IncomingLaneInfo> toExamine = myIncomingLanes; while (toExamine.size()!=0) { for (std::vector<MSLane::IncomingLaneInfo>::iterator i=toExamine.begin(); i!=toExamine.end(); ++i) { /* if ((*i).viaLink->getState()==MSLink::LINKSTATE_TL_RED) { continue; } */ MSLane *next = (*i).lane; if (next->getFirstVehicle()!=0) { MSVehicle * v = (MSVehicle*) next->getFirstVehicle(); SUMOReal agap = (*i).length - v->getPositionOnLane() + backOffset; if (!v->getCarFollowModel().hasSafeGap(v->getCarFollowModel().maxNextSpeed(v->getSpeed()), agap, leaderSpeed, v->getLane().getMaxSpeed())) { possible.push_back(std::make_pair(v, (*i).length-v->getPositionOnLane()+seen)); } } else { if ((*i).length+seen<dist) { const std::vector<MSLane::IncomingLaneInfo> &followers = next->getIncomingLanes(); for (std::vector<MSLane::IncomingLaneInfo>::const_iterator j=followers.begin(); j!=followers.end(); ++j) { if (visited.find((*j).lane)==visited.end()) { visited.insert((*j).lane); MSLane::IncomingLaneInfo ili; ili.lane = (*j).lane; ili.length = (*j).length + (*i).length; ili.viaLink = (*j).viaLink; newFound.push_back(ili); } } } } } toExamine.clear(); swap(newFound, toExamine); } if (possible.size()==0) { return std::pair<MSVehicle * const, SUMOReal>(0, -1); } sort(possible.begin(), possible.end(), by_second_sorter()); return *(possible.begin()); }
void MSFullExport::writeLane(OutputDevice& of, const MSLane& lane) { of.openTag("lane").writeAttr("id", lane.getID()).writeAttr("CO", lane.getCOEmissions()).writeAttr("CO2", lane.getCO2Emissions()); of.writeAttr("NOx", lane.getNOxEmissions()).writeAttr("PMx", lane.getPMxEmissions()).writeAttr("HC", lane.getHCEmissions()); of.writeAttr("noise", lane.getHarmonoise_NoiseEmissions()).writeAttr("fuel", lane.getFuelConsumption()).writeAttr("maxspeed", lane.getSpeedLimit()); of.writeAttr("meanspeed", lane.getMeanSpeed() * 3.6).writeAttr("occupancy", lane.getNettoOccupancy()).writeAttr("vehicle_count", lane.getVehicleNumber()); of.closeTag(); }
void MSVehicleTransfer::loadState(const SUMOSAXAttributes& attrs, const SUMOTime offset, MSVehicleControl& vc) { MSVehicle* veh = dynamic_cast<MSVehicle*>(vc.getVehicle(attrs.getString(SUMO_ATTR_ID))); if (veh == 0) { // deleted return; } SUMOTime proceedTime = (SUMOTime)attrs.getLong(SUMO_ATTR_DEPART); MSLane* parkingLane = attrs.hasAttribute(SUMO_ATTR_PARKING) ? MSLane::dictionary(attrs.getString(SUMO_ATTR_PARKING)) : 0; myVehicles.push_back(VehicleInformation(-1, veh, proceedTime - offset, parkingLane != 0)); if (parkingLane != 0) { parkingLane->addParking(veh); veh->setTentativeLaneAndPosition(parkingLane, veh->getPositionOnLane()); veh->processNextStop(veh->getSpeed()); } MSNet::getInstance()->getInsertionControl().alreadyDeparted(veh); }
std::pair<MSVehicle* const, SUMOReal> MSLaneChanger::getRealThisLeader(const ChangerIt& target) const { // get the leading vehicle on the lane to change to MSVehicle* leader = target->lead; if (leader == 0) { MSLane* targetLane = target->lane; MSVehicle* predP = targetLane->getPartialOccupator(); if (predP != 0) { return std::pair<MSVehicle*, SUMOReal>(predP, targetLane->getPartialOccupatorEnd() - veh(myCandi)->getPositionOnLane()); } const std::vector<MSLane*>& bestLaneConts = veh(myCandi)->getBestLanesContinuation(); MSLinkCont::const_iterator link = targetLane->succLinkSec(*veh(myCandi), 1, *targetLane, bestLaneConts); if (targetLane->isLinkEnd(link)) { return std::pair<MSVehicle*, SUMOReal>(static_cast<MSVehicle*>(0), -1); } MSLane* nextLane = (*link)->getLane(); if (nextLane == 0) { return std::pair<MSVehicle*, SUMOReal>(static_cast<MSVehicle*>(0), -1); } leader = nextLane->getLastVehicle(); if (leader == 0) { return std::pair<MSVehicle*, SUMOReal>(static_cast<MSVehicle*>(0), -1); } SUMOReal gap = leader->getPositionOnLane() - leader->getVehicleType().getLength() + (myCandi->lane->getLength() - veh(myCandi)->getPositionOnLane() - veh(myCandi)->getVehicleType().getMinGap()); // !!! recheck return std::pair<MSVehicle* const, SUMOReal>(leader, MAX2((SUMOReal) 0, gap)); } else { MSVehicle* candi = veh(myCandi); SUMOReal gap = leader->getPositionOnLane() - leader->getVehicleType().getLength() - candi->getPositionOnLane() - candi->getVehicleType().getMinGap(); return std::pair<MSVehicle* const, SUMOReal>(leader, MAX2((SUMOReal) 0, gap)); } }
void MSLaneChangerSublane::updateChanger(bool vehHasChanged) { MSLaneChanger::updateChanger(vehHasChanged); if (!vehHasChanged) { MSVehicle* lead = myCandi->lead; //std::cout << SIMTIME << " updateChanger lane=" << myCandi->lane->getID() << " lead=" << Named::getIDSecure(lead) << "\n"; myCandi->ahead.addLeader(lead, false, 0); MSLane* shadowLane = lead->getLaneChangeModel().getShadowLane(); if (shadowLane != 0) { const SUMOReal latOffset = lead->getLane()->getRightSideOnEdge() - shadowLane->getRightSideOnEdge(); //std::cout << SIMTIME << " updateChanger shadowLane=" << shadowLane->getID() << " lead=" << Named::getIDSecure(lead) << "\n"; (myChanger.begin() + shadowLane->getIndex())->ahead.addLeader(lead, false, latOffset); } } //std::cout << SIMTIME << " updateChanger: lane=" << myCandi->lane->getID() << " lead=" << Named::getIDSecure(myCandi->lead) << " ahead=" << myCandi->ahead.toString() << " vehHasChanged=" << vehHasChanged << "\n"; //for (ChangerIt ce = myChanger.begin(); ce != myChanger.end(); ++ce) { // std::cout << " lane=" << ce->lane->getID() << " vehicles=" << toString(ce->lane->myVehicles) << "\n"; //} }
void MSEdge::closeBuilding() { myAllowed[0] = new std::vector<MSLane*>(); for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) { myAllowed[0]->push_back(*i); const MSLinkCont& lc = (*i)->getLinkCont(); for (MSLinkCont::const_iterator j = lc.begin(); j != lc.end(); ++j) { (*j)->initParallelLinks(); MSLane* toL = (*j)->getLane(); if (toL != 0) { MSEdge& to = toL->getEdge(); // if (std::find(mySuccessors.begin(), mySuccessors.end(), &to) == mySuccessors.end()) { mySuccessors.push_back(&to); } if (std::find(to.myPredecessors.begin(), to.myPredecessors.end(), this) == to.myPredecessors.end()) { to.myPredecessors.push_back(this); } // if (myAllowed.find(&to) == myAllowed.end()) { myAllowed[&to] = new std::vector<MSLane*>(); } myAllowed[&to]->push_back(*i); } #ifdef HAVE_INTERNAL_LANES toL = (*j)->getViaLane(); if (toL != 0) { MSEdge& to = toL->getEdge(); if (std::find(to.myPredecessors.begin(), to.myPredecessors.end(), this) == to.myPredecessors.end()) { to.myPredecessors.push_back(this); } } #endif } } std::sort(mySuccessors.begin(), mySuccessors.end(), by_id_sorter()); rebuildAllowedLanes(); recalcCache(); // segment building depends on the finished list of successors (for multi-queue) if (MSGlobals::gUseMesoSim && !myLanes->empty()) { MSGlobals::gMesoNet->buildSegmentsFor(*this, OptionsCont::getOptions()); } }
const MSEdge* MSEdge::getInternalFollowingEdge(const MSEdge* followerAfterInternal) const { //@todo to be optimized for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) { MSLane* l = *i; const MSLinkCont& lc = l->getLinkCont(); for (MSLinkCont::const_iterator j = lc.begin(); j != lc.end(); ++j) { MSLink* link = *j; if (&link->getLane()->getEdge() == followerAfterInternal) { if (link->getViaLane() != 0) { return &link->getViaLane()->getEdge(); } else { return 0; // network without internal links } } } } return 0; }
void MSAgentbasedTrafficLightLogic::init(NLDetectorBuilder& nb) { MSTrafficLightLogic::init(nb); SUMOReal det_offset = TplConvert::_2SUMOReal(getParameter("detector_offset", DEFAULT_DETECTOR_OFFSET).c_str()); LaneVectorVector::const_iterator i2; LaneVector::const_iterator i; // build the detectors for (i2 = myLanes.begin(); i2 != myLanes.end(); ++i2) { const LaneVector& lanes = *i2; for (i = lanes.begin(); i != lanes.end(); i++) { MSLane* lane = (*i); // Build the lane state detetcor and set it into the container std::string id = "TL_" + myID + "_" + myProgramID + "_E2OverLanesDetectorStartingAt_" + lane->getID(); if (myE2Detectors.find(lane) == myE2Detectors.end()) { MSDetectorFileOutput* det = nb.buildMultiLaneE2Det(id, DU_TL_CONTROL, lane, 0, det_offset, /*haltingTimeThreshold!!!*/ 1, /*haltingSpeedThreshold!!!*/(SUMOReal)(5.0 / 3.6), /*jamDistThreshold!!!*/ 10); myE2Detectors[lane] = static_cast<MS_E2_ZS_CollectorOverLanes*>(det); } } } // initialise the duration unsigned int tCycleIst = 0; // the actual cycletime unsigned int tCycleMin = 0; // the minimum cycle time unsigned int tDeltaGreen = 0; // the difference between the actual cycle time and the required cycle time /// Calculation of starting values for (unsigned int actStep = 0; actStep != myPhases.size(); actStep++) { unsigned int dur = (unsigned int) myPhases[actStep]->duration; tCycleIst = tCycleIst + dur; if (myPhases[actStep]->isGreenPhase()) { unsigned int mindur = (unsigned int) myPhases[actStep]->minDuration; tCycleMin = tCycleMin + mindur; } else { tCycleMin = tCycleMin + dur; } } if (tCycle < tCycleMin) { tCycle = tCycleMin; } if (tCycleIst < tCycle) { tDeltaGreen = tCycle - tCycleIst; lengthenCycleTime(tDeltaGreen); } if (tCycleIst > tCycle) { tDeltaGreen = tCycleIst - tCycle; cutCycleTime(tDeltaGreen); } }
bool TraCIServerAPI_Lane::processSet(TraCIServer& server, tcpip::Storage& inputStorage, tcpip::Storage& outputStorage) { std::string warning = ""; // additional description for response // variable int variable = inputStorage.readUnsignedByte(); if (variable != VAR_MAXSPEED && variable != VAR_LENGTH && variable != LANE_ALLOWED && variable != LANE_DISALLOWED) { return server.writeErrorStatusCmd(CMD_SET_LANE_VARIABLE, "Change Lane State: unsupported variable specified", outputStorage); } // id std::string id = inputStorage.readString(); MSLane* l = MSLane::dictionary(id); if (l == 0) { return server.writeErrorStatusCmd(CMD_SET_LANE_VARIABLE, "Lane '" + id + "' is not known", outputStorage); } // process switch (variable) { case VAR_MAXSPEED: { double value = 0; if (!server.readTypeCheckingDouble(inputStorage, value)) { return server.writeErrorStatusCmd(CMD_SET_LANE_VARIABLE, "The speed must be given as a double.", outputStorage); } l->setMaxSpeed(value); } break; case VAR_LENGTH: { double value = 0; if (!server.readTypeCheckingDouble(inputStorage, value)) { return server.writeErrorStatusCmd(CMD_SET_LANE_VARIABLE, "The length must be given as a double.", outputStorage); } l->setLength(value); } break; case LANE_ALLOWED: { std::vector<std::string> classes; if (!server.readTypeCheckingStringList(inputStorage, classes)) { return server.writeErrorStatusCmd(CMD_SET_LANE_VARIABLE, "Allowed classes must be given as a list of strings.", outputStorage); } l->setPermissions(parseVehicleClasses(classes)); l->getEdge().rebuildAllowedLanes(); } break; case LANE_DISALLOWED: { std::vector<std::string> classes; if (!server.readTypeCheckingStringList(inputStorage, classes)) { return server.writeErrorStatusCmd(CMD_SET_LANE_VARIABLE, "Not allowed classes must be given as a list of strings.", outputStorage); } l->setPermissions(~parseVehicleClasses(classes)); // negation yields allowed l->getEdge().rebuildAllowedLanes(); } break; default: break; } server.writeStatusCmd(CMD_SET_LANE_VARIABLE, RTYPE_OK, warning, outputStorage); return true; }
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 MSActuatedTrafficLightLogic::init(NLDetectorBuilder& nb) { MSTrafficLightLogic::init(nb); assert(myLanes.size() > 0); // change values for setting the loops and lanestate-detectors, here //SUMOTime inductLoopInterval = 1; // LaneVectorVector::const_iterator i2; LaneVector::const_iterator i; // build the induct loops double maxDetectorGap = 0; for (i2 = myLanes.begin(); i2 != myLanes.end(); ++i2) { const LaneVector& lanes = *i2; for (i = lanes.begin(); i != lanes.end(); i++) { MSLane* lane = (*i); if (noVehicles(lane->getPermissions())) { // do not build detectors on green verges or sidewalks continue; } double length = lane->getLength(); double speed = lane->getSpeedLimit(); double inductLoopPosition = myDetectorGap * speed; // check whether the lane is long enough double ilpos = length - inductLoopPosition; if (ilpos < 0) { ilpos = 0; } // Build the induct loop and set it into the container std::string id = "TLS" + myID + "_" + myProgramID + "_InductLoopOn_" + lane->getID(); if (myInductLoops.find(lane) == myInductLoops.end()) { myInductLoops[lane] = nb.createInductLoop(id, lane, ilpos, myVehicleTypes, myShowDetectors); MSNet::getInstance()->getDetectorControl().add(SUMO_TAG_INDUCTION_LOOP, myInductLoops[lane], myFile, myFreq); } maxDetectorGap = MAX2(maxDetectorGap, length - ilpos); } } // warn if the minGap is insufficient to clear vehicles between stop line and detector SUMOTime minMinDur = getMinimumMinDuration(); if (floor(floor(maxDetectorGap / DEFAULT_LENGTH_WITH_GAP) * myPassingTime) > STEPS2TIME(minMinDur)) { WRITE_WARNING("At actuated tlLogic '" + getID() + "', minDur " + time2string(minMinDur) + " is too short for a detector gap of " + toString(maxDetectorGap) + "m."); } }
const std::vector<MSLane*> MSLogicJunction::getInternalLanes() const { // Besides the lanes im myInternal lanes, which are only the last parts of the connections, // this collects all lanes on the junction std::vector<MSLane*> allInternalLanes; for (std::vector<MSLane*>::const_iterator i = myInternalLanes.begin(); i != myInternalLanes.end(); ++i) { MSLane* l = *i; while (l != nullptr) { allInternalLanes.push_back(l); const std::vector<MSLane::IncomingLaneInfo> incoming = l->getIncomingLanes(); if (incoming.size() == 0) { break; } assert(l->getIncomingLanes().size() == 1); l = l->getIncomingLanes()[0].lane; if (!l->isInternal()) { break; } } } return allInternalLanes; }
void NLDetectorBuilder::buildMsgDetector(const std::string &id, const std::string &lane, SUMOReal pos, int splInterval, const std::string &msg, OutputDevice& device, bool friendlyPos) throw(InvalidArgument) { if (splInterval<0) { throw InvalidArgument("Negative sampling frequency (in e4-detector '" + id + "')."); } if (splInterval==0) { throw InvalidArgument("Sampling frequency must not be zero (in e4-detector '" + id + "')."); } if (msg == "") { throw InvalidArgument("No Message given (in e4-detector '" + id + "')."); } MSLane *clane = getLaneChecking(lane, id); if (pos<0) { pos = clane->getLength() + pos; } pos = getPositionChecking(pos, clane, friendlyPos, id); MSMsgInductLoop *msgloop = createMsgInductLoop(id, msg, clane, pos); myNet.getDetectorControl().add(msgloop, device, splInterval); }