Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
Helper.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2017-2026 German Aerospace Center (DLR) and others.
4// This program and the accompanying materials are made available under the
5// terms of the Eclipse Public License 2.0 which is available at
6// https://www.eclipse.org/legal/epl-2.0/
7// This Source Code may also be made available under the following Secondary
8// Licenses when the conditions for such availability set forth in the Eclipse
9// Public License 2.0 are satisfied: GNU General Public License, version 2
10// or later which is available at
11// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13/****************************************************************************/
20// C++ TraCI client API implementation
21/****************************************************************************/
22#include <config.h>
23
24#include <cstring>
27#include <microsim/MSNet.h>
31#include <microsim/MSEdge.h>
32#include <microsim/MSLane.h>
33#include <microsim/MSLink.h>
35#include <microsim/MSVehicle.h>
42#include <libsumo/TraCIDefs.h>
43#include <libsumo/BusStop.h>
44#include <libsumo/Calibrator.h>
46#include <libsumo/Edge.h>
47#ifdef HAVE_LIBSUMOGUI
48#include <libsumo/GUI.h>
49#endif
51#include <libsumo/Junction.h>
52#include <libsumo/Lane.h>
53#include <libsumo/LaneArea.h>
54#include <libsumo/MeanData.h>
57#include <libsumo/ParkingArea.h>
58#include <libsumo/Person.h>
59#include <libsumo/POI.h>
60#include <libsumo/Polygon.h>
61#include <libsumo/Rerouter.h>
62#include <libsumo/Route.h>
63#include <libsumo/RouteProbe.h>
64#include <libsumo/Simulation.h>
67#include <libsumo/Vehicle.h>
68#include <libsumo/VehicleType.h>
70#include "Helper.h"
71
72#define FAR_AWAY 1000.0
73
74//#define DEBUG_MOVEXY
75//#define DEBUG_MOVEXY_ANGLE
76//#define DEBUG_SURROUNDING
77
78namespace libsumo {
79// ===========================================================================
80// static member initializations
81// ===========================================================================
82std::vector<Subscription> Helper::mySubscriptions;
83Subscription* Helper::myLastContextSubscription = nullptr;
84std::map<int, std::shared_ptr<VariableWrapper> > Helper::myWrapper;
85Helper::VehicleStateListener Helper::myVehicleStateListener;
86Helper::TransportableStateListener Helper::myTransportableStateListener;
88std::map<std::string, MSVehicle*> Helper::myRemoteControlledVehicles;
89std::map<std::string, MSPerson*> Helper::myRemoteControlledPersons;
90
91
92// ===========================================================================
93// static member definitions
94// ===========================================================================
95
96void
98 if (veh != nullptr) {
99 if (veh->isVehicle()) {
100 std::cout << " '" << veh->getID() << "' on lane '" << ((SUMOVehicle*)veh)->getLane()->getID() << "'\n";
101 } else {
102 std::cout << " '" << veh->getID() << "' on edge '" << veh->getEdge()->getID() << "'\n";
103 }
104 }
105}
106
107
108void
109Helper::subscribe(const int commandId, const std::string& id, const std::vector<int>& variables,
110 const double beginTime, const double endTime, const libsumo::TraCIResults& params,
111 const int contextDomain, const double range) {
113 if (variables.empty()) {
114 for (std::vector<libsumo::Subscription>::iterator j = mySubscriptions.begin(); j != mySubscriptions.end();) {
115 if (j->id == id && j->commandId == commandId && j->contextDomain == contextDomain) {
116 j = mySubscriptions.erase(j);
117 } else {
118 ++j;
119 }
120 }
121 return;
122 }
123 std::vector<std::shared_ptr<tcpip::Storage> > parameters;
124 for (const int var : variables) {
125 const auto& p = params.find(var);
126 if (p == params.end()) {
127 parameters.push_back(std::make_shared<tcpip::Storage>());
128 } else {
129 parameters.push_back(libsumo::StorageHelper::toStorage(*p->second));
130 }
131 }
132 const SUMOTime begin = beginTime == INVALID_DOUBLE_VALUE ? 0 : TIME2STEPS(beginTime);
133 const SUMOTime end = endTime == INVALID_DOUBLE_VALUE || endTime > STEPS2TIME(SUMOTime_MAX) ? SUMOTime_MAX : TIME2STEPS(endTime);
134 libsumo::Subscription s(commandId, id, variables, parameters, begin, end, contextDomain, range);
135 if (commandId == libsumo::CMD_SUBSCRIBE_SIM_CONTEXT) {
136 s.range = std::numeric_limits<double>::max();
137 }
138 if (s.variables.size() == 1 && s.variables.front() == -1) {
139 if (contextDomain == 0) {
141 // default for vehicles is edge id and lane position
143 s.parameters.push_back(std::make_shared<tcpip::Storage>());
144 } else if (commandId == libsumo::CMD_SUBSCRIBE_EDGE_VARIABLE ||
149 // default for detectors, edges and lanes is vehicle number
151 } else {
152 // for all others id list
154 }
155 } else {
156 s.variables.clear();
157 s.parameters.clear();
158 }
159 }
161 libsumo::Subscription* modifiedSubscription = nullptr;
162 needNewSubscription(s, mySubscriptions, modifiedSubscription);
163 if (modifiedSubscription->isVehicleToVehicleContextSubscription()
164 || modifiedSubscription->isVehicleToPersonContextSubscription()) {
165 // Set last modified vehicle context subscription active for filter modifications
166 myLastContextSubscription = modifiedSubscription;
167 }
168}
169
170
171void
173 for (auto& wrapper : myWrapper) {
174 wrapper.second->clear();
175 }
176 for (std::vector<libsumo::Subscription>::iterator i = mySubscriptions.begin(); i != mySubscriptions.end();) {
177 const libsumo::Subscription& s = *i;
178 const bool isArrivedVehicle = (s.commandId == CMD_SUBSCRIBE_VEHICLE_VARIABLE || s.commandId == CMD_SUBSCRIBE_VEHICLE_CONTEXT)
181 && MSNet::getInstance()->getPersonControl().get(s.id) == nullptr;
182 if (s.endTime < t || isArrivedVehicle || isArrivedPerson) {
183 i = mySubscriptions.erase(i);
184 continue;
185 }
186 ++i;
187 }
188 for (const libsumo::Subscription& s : mySubscriptions) {
189 if (s.beginTime <= t) {
191 }
192 }
193}
194
195
196bool
197Helper::needNewSubscription(libsumo::Subscription& s, std::vector<Subscription>& subscriptions, libsumo::Subscription*& modifiedSubscription) {
198 for (libsumo::Subscription& o : subscriptions) {
199 if (s.commandId == o.commandId && s.id == o.id &&
200 s.beginTime == o.beginTime && s.endTime == o.endTime &&
201 s.contextDomain == o.contextDomain && s.range == o.range) {
202 std::vector<std::shared_ptr<tcpip::Storage> >::const_iterator k = s.parameters.begin();
203 for (const int v : s.variables) {
204 const int offset = (int)(std::find(o.variables.begin(), o.variables.end(), v) - o.variables.begin());
205 if (offset == (int)o.variables.size() || o.parameters[offset]->size() != (*k)->size() || !std::equal((*k)->begin(), (*k)->end(), o.parameters[offset]->begin())) {
206 o.variables.push_back(v);
207 o.parameters.push_back(*k);
208 }
209 ++k;
210 }
211 modifiedSubscription = &o;
212 return false;
213 }
214 }
215 subscriptions.push_back(s);
216 modifiedSubscription = &subscriptions.back();
217 return true;
218}
219
220
221void
226
227
230 if (myLastContextSubscription != nullptr) {
232 } else {
233 // The following code relies on the fact that the filter is 2^(filterType-1),
234 // see Subscription.h and the corresponding TraCIConstants.h.
235 // It is only for getting similar error messages with libsumo and traci.
236 int index = (int)filter;
237 int filterType = 0;
238 if (index != 0) {
239 ++filterType;
240 while (index >>= 1) {
241 ++filterType;
242 }
243 }
244 throw TraCIException("No previous vehicle context subscription exists to apply filter type " + toHex(filterType, 2));
245 }
247}
248
249
250void
252 const int getCommandId = s.contextDomain > 0 ? s.contextDomain : s.commandId - 0x30;
253 std::set<std::string> objIDs;
254 if (s.contextDomain > 0) {
255 if ((s.activeFilters & SUBS_FILTER_NO_RTREE) == 0) {
256 PositionVector shape;
257 findObjectShape(s.commandId, s.id, shape);
258 collectObjectIDsInRange(s.contextDomain, shape, s.range, objIDs);
259 }
260 applySubscriptionFilters(s, objIDs);
261 } else {
262 objIDs.insert(s.id);
263 }
264 if (myWrapper.empty()) {
265 myWrapper[libsumo::CMD_GET_BUSSTOP_VARIABLE] = BusStop::makeWrapper();
266 myWrapper[libsumo::CMD_GET_CALIBRATOR_VARIABLE] = Calibrator::makeWrapper();
267 myWrapper[libsumo::CMD_GET_CHARGINGSTATION_VARIABLE] = ChargingStation::makeWrapper();
268 myWrapper[libsumo::CMD_GET_EDGE_VARIABLE] = Edge::makeWrapper();
269#ifdef HAVE_LIBSUMOGUI
270 myWrapper[libsumo::CMD_GET_GUI_VARIABLE] = GUI::makeWrapper();
271#endif
272 myWrapper[libsumo::CMD_GET_INDUCTIONLOOP_VARIABLE] = InductionLoop::makeWrapper();
273 myWrapper[libsumo::CMD_GET_JUNCTION_VARIABLE] = Junction::makeWrapper();
274 myWrapper[libsumo::CMD_GET_LANE_VARIABLE] = Lane::makeWrapper();
275 myWrapper[libsumo::CMD_GET_LANEAREA_VARIABLE] = LaneArea::makeWrapper();
276 myWrapper[libsumo::CMD_GET_MEANDATA_VARIABLE] = MeanData::makeWrapper();
277 myWrapper[libsumo::CMD_GET_MULTIENTRYEXIT_VARIABLE] = MultiEntryExit::makeWrapper();
278 myWrapper[libsumo::CMD_GET_OVERHEADWIRE_VARIABLE] = OverheadWire::makeWrapper();
279 myWrapper[libsumo::CMD_GET_PARKINGAREA_VARIABLE] = ParkingArea::makeWrapper();
280 myWrapper[libsumo::CMD_GET_PERSON_VARIABLE] = Person::makeWrapper();
281 myWrapper[libsumo::CMD_GET_POI_VARIABLE] = POI::makeWrapper();
282 myWrapper[libsumo::CMD_GET_POLYGON_VARIABLE] = Polygon::makeWrapper();
283 myWrapper[libsumo::CMD_GET_REROUTER_VARIABLE] = Rerouter::makeWrapper();
284 myWrapper[libsumo::CMD_GET_ROUTE_VARIABLE] = Route::makeWrapper();
285 myWrapper[libsumo::CMD_GET_ROUTEPROBE_VARIABLE] = RouteProbe::makeWrapper();
286 myWrapper[libsumo::CMD_GET_SIM_VARIABLE] = Simulation::makeWrapper();
287 myWrapper[libsumo::CMD_GET_TL_VARIABLE] = TrafficLight::makeWrapper();
288 myWrapper[libsumo::CMD_GET_VARIABLESPEEDSIGN_VARIABLE] = VariableSpeedSign::makeWrapper();
289 myWrapper[libsumo::CMD_GET_VEHICLE_VARIABLE] = Vehicle::makeWrapper();
290 myWrapper[libsumo::CMD_GET_VEHICLETYPE_VARIABLE] = VehicleType::makeWrapper();
291 }
292 auto wrapper = myWrapper.find(getCommandId);
293 if (wrapper == myWrapper.end()) {
294 throw TraCIException("Unsupported command " + toHex(getCommandId, 2) + " specified");
295 }
296 std::shared_ptr<VariableWrapper> handler = wrapper->second;
297 VariableWrapper* container = handler.get();
298 if (s.contextDomain > 0) {
299 auto containerWrapper = myWrapper.find(s.commandId + 0x20);
300 if (containerWrapper == myWrapper.end()) {
301 throw TraCIException("Unsupported domain " + toHex(s.commandId + 0x20, 2) + " specified");
302 }
303 container = containerWrapper->second.get();
304 container->setContext(&s.id);
305 } else {
306 container->setContext(nullptr);
307 }
308 for (const std::string& objID : objIDs) {
309 if (!s.variables.empty()) {
310 std::vector<std::shared_ptr<tcpip::Storage> >::const_iterator k = s.parameters.begin();
311 for (const int variable : s.variables) {
312 if (s.contextDomain > 0 && variable == libsumo::TRACI_ID_LIST) {
313 container->empty(objID);
314 } else {
315 (*k)->resetPos();
316 try {
317 if (!handler->handle(objID, variable, container, k->get())) {
318 throw TraCIException("Unsupported variable " + toHex(variable, 2) + " specified");
319 }
320 } catch (const std::invalid_argument&) {
321 throw TraCIException("Unsupported variable " + toHex(variable, 2) + " specified");
322 }
323 ++k;
324 }
325 }
326 } else if (s.contextDomain > 0) {
327 // default for contexts is an empty map (similar to id list)
328 container->empty(objID);
329 }
330 }
331}
332
333
334void
335Helper::fuseLaneCoverage(std::shared_ptr<LaneCoverageInfo> aggregatedLaneCoverage, const std::shared_ptr<LaneCoverageInfo> newLaneCoverage) {
336 for (auto& p : *newLaneCoverage) {
337 const MSLane* lane = p.first;
338 if (aggregatedLaneCoverage->find(lane) == aggregatedLaneCoverage->end()) {
339 // Lane has no coverage in aggregatedLaneCoverage, yet
340 (*aggregatedLaneCoverage)[lane] = (*newLaneCoverage)[lane];
341 } else {
342 // Lane is covered in aggregatedLaneCoverage as well
343 std::pair<double, double>& range1 = (*aggregatedLaneCoverage)[lane];
344 std::pair<double, double>& range2 = (*newLaneCoverage)[lane];
345 std::pair<double, double> hull = std::make_pair(MIN2(range1.first, range2.first), MAX2(range1.second, range2.second));
346 (*aggregatedLaneCoverage)[lane] = hull;
347 }
348 }
349}
350
351
355 for (int i = 0; i < (int)positionVector.size(); ++i) {
356 tp.value.push_back(makeTraCIPosition(positionVector[i]));
357 }
358 return tp;
359}
360
361
365 for (const TraCIPosition& pos : vector.value) {
366 if (std::isnan(pos.x) || std::isnan(pos.y)) {
367 throw libsumo::TraCIException("NaN-Value in shape.");
368 }
369 pv.push_back(Position(pos.x, pos.y));
370 }
371 return pv;
372}
373
374
377 TraCIColor tc;
378 tc.a = color.alpha();
379 tc.b = color.blue();
380 tc.g = color.green();
381 tc.r = color.red();
382 return tc;
383}
384
385
388 return RGBColor((unsigned char)c.r, (unsigned char)c.g, (unsigned char)c.b, (unsigned char)c.a);
389}
390
391
393Helper::makeTraCIPosition(const Position& position, const bool includeZ) {
395 p.x = position.x();
396 p.y = position.y();
397 p.z = includeZ ? position.z() : INVALID_DOUBLE_VALUE;
398 return p;
399}
400
401
404 return Position(tpos.x, tpos.y, tpos.z);
405}
406
407
408MSEdge*
409Helper::getEdge(const std::string& edgeID) {
410 MSEdge* edge = MSEdge::dictionary(edgeID);
411 if (edge == nullptr) {
412 throw TraCIException("Referenced edge '" + edgeID + "' is not known.");
413 }
414 return edge;
415}
416
417
418const MSLane*
419Helper::getLaneChecking(const std::string& edgeID, int laneIndex, double pos) {
420 const MSEdge* edge = MSEdge::dictionary(edgeID);
421 if (edge == nullptr) {
422 throw TraCIException("Unknown edge " + edgeID);
423 }
424 if (laneIndex < 0 || laneIndex >= (int)edge->getLanes().size()) {
425 throw TraCIException("Invalid lane index for " + edgeID);
426 }
427 const MSLane* lane = edge->getLanes()[laneIndex];
428 if (pos < 0 || pos > lane->getLength()) {
429 throw TraCIException("Position on lane invalid");
430 }
431 return lane;
432}
433
434
435std::pair<MSLane*, double>
437 const PositionVector shape({ pos });
438 std::pair<MSLane*, double> result(nullptr, -1);
439 double range = 1000.;
440 const Boundary& netBounds = GeoConvHelper::getFinal().getConvBoundary();
441 const double maxRange = MAX2(1001., netBounds.getWidth() + netBounds.getHeight() + netBounds.distanceTo2D(pos));
442 while (range < maxRange) {
443 std::set<const Named*> lanes;
445 double minDistance = std::numeric_limits<double>::max();
446 for (const Named* named : lanes) {
447 MSLane* lane = const_cast<MSLane*>(dynamic_cast<const MSLane*>(named));
448 if (lane->allowsVehicleClass(vClass)) {
449 // @todo this may be a place where 3D is required but 2D is used
450 double newDistance = lane->getShape().distance2D(pos);
451 newDistance = patchShapeDistance(lane, pos, newDistance, false);
452 if (newDistance < minDistance ||
453 (newDistance == minDistance
454 && result.first != nullptr
455 && lane->getID() < result.first->getID())) {
456 minDistance = newDistance;
457 result.first = lane;
458 }
459 }
460 }
461 if (minDistance < std::numeric_limits<double>::max()) {
462 result.second = result.first->interpolateGeometryPosToLanePos(result.first->getShape().nearest_offset_to_point2D(pos, false));
463 break;
464 }
465 range *= 2;
466 }
467 return result;
468}
469
470
471double
472Helper::getDrivingDistance(std::pair<const MSLane*, double>& roadPos1, std::pair<const MSLane*, double>& roadPos2) {
473 if (roadPos1.first == roadPos2.first && roadPos1.second <= roadPos2.second) {
474 // same edge
475 return roadPos2.second - roadPos1.second;
476 }
477 double distance = 0.0;
478 ConstMSEdgeVector newRoute;
479 while (roadPos2.first->isInternal() && roadPos2.first != roadPos1.first) {
480 distance += roadPos2.second;
481 roadPos2.first = roadPos2.first->getLogicalPredecessorLane();
482 roadPos2.second = roadPos2.first->getLength();
483 }
484 MSNet::getInstance()->getRouterTT(0).compute(&roadPos1.first->getEdge(), &roadPos2.first->getEdge(), nullptr, SIMSTEP, newRoute, true);
485 if (newRoute.empty()) {
487 }
488 MSRoute route("", newRoute, false, nullptr, StopParVector());
489 return distance + route.getDistanceBetween(roadPos1.second, roadPos2.second, roadPos1.first, roadPos2.first);
490}
491
492
494Helper::getVehicle(const std::string& id) {
496 if (sumoVehicle == nullptr) {
497 throw TraCIException("Vehicle '" + id + "' is not known.");
498 }
499 MSBaseVehicle* v = dynamic_cast<MSBaseVehicle*>(sumoVehicle);
500 if (v == nullptr) {
501 throw TraCIException("Vehicle '" + id + "' is not a proper vehicle.");
502 }
503 return v;
504}
505
506
508Helper::getPerson(const std::string& personID) {
510 MSPerson* p = dynamic_cast<MSPerson*>(c.get(personID));
511 if (p == nullptr) {
512 throw TraCIException("Person '" + personID + "' is not known");
513 }
514 return p;
515}
516
518Helper::getTrafficObject(int domain, const std::string& id) {
519 if (domain == CMD_GET_VEHICLE_VARIABLE) {
520 return getVehicle(id);
521 } else if (domain == CMD_GET_PERSON_VARIABLE) {
522 return getPerson(id);
523 } else {
524 throw TraCIException("Cannot retrieve traffic object for domain " + toString(domain));
525 }
526}
527
528const MSVehicleType&
529Helper::getVehicleType(const std::string& vehicleID) {
530 return getVehicle(vehicleID)->getVehicleType();
531}
532
533
535Helper::getTLS(const std::string& id) {
536 if (!MSNet::getInstance()->getTLSControl().knows(id)) {
537 throw TraCIException("Traffic light '" + id + "' is not known");
538 }
539 return MSNet::getInstance()->getTLSControl().get(id);
540}
541
542
544Helper::getStoppingPlace(const std::string& id, const SumoXMLTag type) {
546 if (s == nullptr) {
547 throw TraCIException(toString(type) + " '" + id + "' is not known");
548 }
549 return s;
550}
551
552
554Helper::buildStopParameters(const std::string& edgeOrStoppingPlaceID,
555 double pos, int laneIndex, double startPos, int flags, double duration, double until) {
557 try {
558 checkTimeBounds(duration);
559 checkTimeBounds(until);
560 } catch (ProcessError&) {
561 throw TraCIException("Duration or until parameter exceed the time value range.");
562 }
563 newStop.duration = duration == INVALID_DOUBLE_VALUE ? SUMOTime_MAX : TIME2STEPS(duration);
564 newStop.until = until == INVALID_DOUBLE_VALUE ? -1 : TIME2STEPS(until);
565 newStop.index = STOP_INDEX_FIT;
566 if (newStop.duration >= 0) {
568 }
569 if (newStop.until >= 0) {
570 newStop.parametersSet |= STOP_UNTIL_SET;
571 }
572 if ((flags & 1) != 0) {
575 }
576 if ((flags & 2) != 0) {
577 newStop.triggered = true;
579 }
580 if ((flags & 4) != 0) {
581 newStop.containerTriggered = true;
583 }
584
585 SumoXMLTag stoppingPlaceType = SUMO_TAG_NOTHING;
586 if ((flags & 8) != 0) {
587 stoppingPlaceType = SUMO_TAG_BUS_STOP;
588 }
589 if ((flags & 16) != 0) {
590 stoppingPlaceType = SUMO_TAG_CONTAINER_STOP;
591 }
592 if ((flags & 32) != 0) {
593 stoppingPlaceType = SUMO_TAG_CHARGING_STATION;
594 }
595 if ((flags & 64) != 0) {
596 stoppingPlaceType = SUMO_TAG_PARKING_AREA;
597 }
598 if ((flags & 128) != 0) {
599 stoppingPlaceType = SUMO_TAG_OVERHEAD_WIRE_SEGMENT;
600 }
601
602 if (stoppingPlaceType != SUMO_TAG_NOTHING) {
603 MSStoppingPlace* bs = MSNet::getInstance()->getStoppingPlace(edgeOrStoppingPlaceID, stoppingPlaceType);
604 if (bs == nullptr) {
605 throw TraCIException("The " + toString(stoppingPlaceType) + " '" + edgeOrStoppingPlaceID + "' is not known");
606 }
607 newStop.lane = bs->getLane().getID();
608 newStop.edge = bs->getLane().getEdge().getID();
609 newStop.endPos = bs->getEndLanePosition();
610 newStop.startPos = bs->getBeginLanePosition();
611 switch (stoppingPlaceType) {
613 newStop.busstop = edgeOrStoppingPlaceID;
614 break;
616 newStop.containerstop = edgeOrStoppingPlaceID;
617 break;
619 newStop.chargingStation = edgeOrStoppingPlaceID;
620 break;
622 newStop.parkingarea = edgeOrStoppingPlaceID;
623 break;
625 newStop.overheadWireSegment = edgeOrStoppingPlaceID;
626 break;
627 default:
628 throw TraCIException("Unknown stopping place type '" + toString(stoppingPlaceType) + "'.");
629 }
630 } else {
631 if (startPos == INVALID_DOUBLE_VALUE) {
632 startPos = MAX2(0.0, pos - POSITION_EPS);
633 }
634 if (startPos < 0.) {
635 throw TraCIException("Position on lane must not be negative.");
636 }
637 if (pos < startPos) {
638 throw TraCIException("End position on lane must be after start position.");
639 }
640 // get the actual lane that is referenced by laneIndex
641 MSEdge* road = MSEdge::dictionary(edgeOrStoppingPlaceID);
642 if (road == nullptr) {
643 throw TraCIException("Edge '" + edgeOrStoppingPlaceID + "' is not known.");
644 }
645 const std::vector<MSLane*>& allLanes = road->getLanes();
646 if ((laneIndex < 0) || laneIndex >= (int)(allLanes.size())) {
647 throw TraCIException("No lane with index '" + toString(laneIndex) + "' on edge '" + edgeOrStoppingPlaceID + "'.");
648 }
649 newStop.lane = allLanes[laneIndex]->getID();
650 newStop.edge = allLanes[laneIndex]->getEdge().getID();
651 newStop.endPos = pos;
652 newStop.startPos = startPos;
654 }
655 return newStop;
656}
657
658
661 std::string stoppingPlaceID = "";
662 if (stopPar.busstop != "") {
663 stoppingPlaceID = stopPar.busstop;
664 }
665 if (stopPar.containerstop != "") {
666 stoppingPlaceID = stopPar.containerstop;
667 }
668 if (stopPar.parkingarea != "") {
669 stoppingPlaceID = stopPar.parkingarea;
670 }
671 if (stopPar.chargingStation != "") {
672 stoppingPlaceID = stopPar.chargingStation;
673 }
674 if (stopPar.overheadWireSegment != "") {
675 stoppingPlaceID = stopPar.overheadWireSegment;
676 }
677
678 return TraCINextStopData(stopPar.lane,
679 stopPar.startPos,
680 stopPar.endPos,
681 stoppingPlaceID,
682 stopPar.getFlags(),
683 // negative duration is permitted to indicate that a vehicle cannot
684 // re-enter traffic after parking
685 stopPar.duration != -1 ? STEPS2TIME(stopPar.duration) : INVALID_DOUBLE_VALUE,
686 stopPar.until >= 0 ? STEPS2TIME(stopPar.until) : INVALID_DOUBLE_VALUE,
687 stopPar.arrival >= 0 ? STEPS2TIME(stopPar.arrival) : INVALID_DOUBLE_VALUE,
688 stopPar.started >= 0 ? STEPS2TIME(stopPar.started) : INVALID_DOUBLE_VALUE,
689 stopPar.ended >= 0 ? STEPS2TIME(stopPar.ended) : INVALID_DOUBLE_VALUE,
690 stopPar.split,
691 stopPar.join,
692 stopPar.actType,
693 stopPar.tripId,
694 stopPar.line,
695 stopPar.speed);
696}
697
698
699void
701 // clean up NamedRTrees
702 InductionLoop::cleanup();
703 Junction::cleanup();
704 LaneArea::cleanup();
705 POI::cleanup();
706 Polygon::cleanup();
709 delete myLaneTree;
710 myLaneTree = nullptr;
713}
714
715
716void
723
724
725const std::vector<std::string>&
729
730
731const std::vector<std::string>&
735
736
737void
740 i.second.clear();
741 }
743 i.second.clear();
744 }
745}
746
747
750 try {
751 return c->getCurrentStateInterval();
752 } catch (ProcessError& e) {
753 throw TraCIException(e.what());
754 }
755}
756
757
758void
759Helper::findObjectShape(int domain, const std::string& id, PositionVector& shape) {
760 switch (domain) {
763 shape.push_back(stop->getLane().getShape().positionAtOffset(stop->getBeginLanePosition()));
764 shape.push_back(stop->getLane().getShape().positionAtOffset(stop->getEndLanePosition()));
765 break;
766 }
768 MSCalibrator* const calib = Calibrator::getCalibrator(id);
769 shape.push_back(calib->getLane()->getShape()[0]);
770 break;
771 }
774 shape.push_back(stop->getLane().getShape().positionAtOffset(stop->getBeginLanePosition()));
775 shape.push_back(stop->getLane().getShape().positionAtOffset(stop->getEndLanePosition()));
776 break;
777 }
779 Edge::storeShape(id, shape);
780 break;
782 InductionLoop::storeShape(id, shape);
783 break;
785 Junction::storeShape(id, shape);
786 break;
788 Lane::storeShape(id, shape);
789 break;
791 LaneArea::storeShape(id, shape);
792 break;
794 MSE3Collector* const det = MultiEntryExit::getDetector(id);
795 for (const MSCrossSection& cs : det->getEntries()) {
796 shape.push_back(cs.myLane->getShape().positionAtOffset(cs.myPosition));
797 }
798 for (const MSCrossSection& cs : det->getExits()) {
799 shape.push_back(cs.myLane->getShape().positionAtOffset(cs.myPosition));
800 }
801 break;
802 }
805 shape.push_back(stop->getLane().getShape().positionAtOffset(stop->getBeginLanePosition()));
806 shape.push_back(stop->getLane().getShape().positionAtOffset(stop->getEndLanePosition()));
807 break;
808 }
810 Person::storeShape(id, shape);
811 break;
813 POI::storeShape(id, shape);
814 break;
816 Polygon::storeShape(id, shape);
817 break;
819 Vehicle::storeShape(id, shape);
820 break;
821 default:
822 Simulation::storeShape(shape);
823 break;
824 }
825}
826
827
828void
829Helper::collectObjectIDsInRange(int domain, const PositionVector& shape, double range, std::set<std::string>& into) {
830 std::set<const Named*> objects;
831 collectObjectsInRange(domain, shape, range, objects);
832 for (const Named* obj : objects) {
833 into.insert(obj->getID());
834 }
835}
836
837
838void
839Helper::collectObjectsInRange(int domain, const PositionVector& shape, double range, std::set<const Named*>& into) {
840 const Boundary b = shape.getBoxBoundary().grow(range);
841 const float cmin[2] = {(float) b.xmin(), (float) b.ymin()};
842 const float cmax[2] = {(float) b.xmax(), (float) b.ymax()};
843 switch (domain) {
845 for (const auto& stop : MSNet::getInstance()->getStoppingPlaces(SUMO_TAG_BUS_STOP)) {
846 if (shape.distance2D(stop.second->getCenterPos()) <= range) {
847 into.insert(stop.second);
848 }
849 }
850 break;
853 if (shape.distance2D(stop.second->getCenterPos()) <= range) {
854 into.insert(stop.second);
855 }
856 }
857 break;
859 for (const auto& calib : MSCalibrator::getInstances()) {
860 if (shape.distance2D(calib.second->getLane()->getShape()[0]) <= range) {
861 into.insert(calib.second);
862 }
863 }
864 break;
866 InductionLoop::getTree()->Search(cmin, cmax, Named::StoringVisitor(into));
867 break;
869 Junction::getTree()->Search(cmin, cmax, Named::StoringVisitor(into));
870 break;
872 LaneArea::getTree()->Search(cmin, cmax, Named::StoringVisitor(into));
873 break;
875 for (const auto& stop : MSNet::getInstance()->getStoppingPlaces(SUMO_TAG_PARKING_AREA)) {
876 if (shape.distance2D(stop.second->getCenterPos()) <= range) {
877 into.insert(stop.second);
878 }
879 }
880 break;
881 }
883 POI::getTree()->Search(cmin, cmax, Named::StoringVisitor(into));
884 break;
886 Polygon::getTree()->Search(cmin, cmax, Named::StoringVisitor(into));
887 break;
892 if (myLaneTree == nullptr) {
895 }
896 MSLane::StoringVisitor lsv(into, shape, range, domain);
897 myLaneTree->Search(cmin, cmax, lsv);
898 }
899 break;
900 default:
901 throw TraCIException("Infeasible context domain (" + toString(domain) + ")");
902 break;
903 }
904}
905
906
907
908void
909Helper::applySubscriptionFilters(const Subscription& s, std::set<std::string>& objIDs) {
910#ifdef DEBUG_SURROUNDING
911 MSBaseVehicle* _veh = getVehicle(s.id);
912 std::cout << SIMTIME << " applySubscriptionFilters for vehicle '" << _veh->getID() << "' on lane '" << _veh->getLane()->getID() << "'"
913 << "\n on edge '" << _veh->getLane()->getEdge().getID() << "' (" << toString(_veh->getLane()->getEdge().getLanes()) << ")\n"
914 << "objIDs = " << toString(objIDs) << std::endl;
915#endif
916
917 if (s.activeFilters == 0) {
918 // No filters set
919 return;
920 }
921
922 MSVehicle* v = dynamic_cast<MSVehicle*>(getVehicle(s.id));
923
924 // Whether vehicles on opposite lanes shall be taken into account
925 const bool disregardOppositeDirection = (s.activeFilters & SUBS_FILTER_NOOPPOSITE) != 0;
926
927 // Check filter specification consistency
928 if (disregardOppositeDirection && (s.activeFilters & SUBS_FILTER_NO_RTREE) == 0) {
929 WRITE_WARNINGF(TL("Ignoring veh '%' no-opposite subscription filter for geographic range object collection. Consider using the 'lanes' filter."), v->getID())
930 }
931 // TODO: Treat case, where ego vehicle is currently on opposite lane
932
933 std::set<const SUMOTrafficObject*> vehs;
935 // Set defaults for upstream/downstream/lateral distances
936 double downstreamDist = s.range, upstreamDist = s.range, lateralDist = s.range;
938 // Specifies maximal downstream distance for vehicles in context subscription result
939 downstreamDist = s.filterDownstreamDist;
940 }
942 // Specifies maximal downstream distance for vehicles in context subscription result
943 upstreamDist = s.filterUpstreamDist;
944 }
946 // Specifies maximal lateral distance for vehicles in context subscription result
947 lateralDist = s.filterLateralDist;
948 }
949 if (v == nullptr) {
950 throw TraCIException("Subscription filter not yet implemented for meso vehicle");
951 }
952 if (!v->isOnRoad()) {
953 return;
954 }
955 const MSLane* vehLane = v->getLane();
956 if (vehLane == nullptr) {
957 return;
958 }
959 MSEdge* vehEdge = &vehLane->getEdge();
960 std::vector<int> filterLanes;
961 if ((s.activeFilters & SUBS_FILTER_LANES) == 0) {
962 // No lane indices are specified (but downstream and/or upstream distance)
963 // -> use only vehicle's current lane as origin for the searches
964 filterLanes = {0};
965 // Lane indices must be specified when leader/follower information is requested.
966 assert((s.activeFilters & SUBS_FILTER_LEAD_FOLLOW) == 0);
967 } else {
968 filterLanes = s.filterLanes;
969 }
970
971#ifdef DEBUG_SURROUNDING
972 std::cout << "Filter lanes: " << toString(filterLanes) << std::endl;
973 std::cout << "Downstream distance: " << downstreamDist << std::endl;
974 std::cout << "Upstream distance: " << upstreamDist << std::endl;
975 std::cout << "Lateral distance: " << lateralDist << std::endl;
976#endif
977
978 if ((s.activeFilters & SUBS_FILTER_MANEUVER) != 0) {
979 // Maneuver filters disables road net search for all surrounding vehicles
980 if ((s.activeFilters & SUBS_FILTER_LEAD_FOLLOW) != 0) {
981 // Return leader and follower on the specified lanes in context subscription result.
982 for (int offset : filterLanes) {
983 MSLane* lane = v->getLane()->getParallelLane(offset, false);
984 if (lane != nullptr) {
985 // this is a non-opposite lane
986 MSVehicle* leader = lane->getLeader(v, v->getPositionOnLane(), v->getBestLanesContinuation(lane), downstreamDist).first;
987 MSVehicle* follower = lane->getFollower(v, v->getPositionOnLane(), upstreamDist,
989 vehs.insert(vehs.end(), leader);
990 vehs.insert(vehs.end(), follower);
991
992#ifdef DEBUG_SURROUNDING
993 std::cout << "Lane at index " << offset << ": '" << lane->getID() << std::endl;
994 std::cout << "Leader: '" << (leader != nullptr ? leader->getID() : "NULL") << "'" << std::endl;
995 std::cout << "Follower: '" << (follower != nullptr ? follower->getID() : "NULL") << "'" << std::endl;
996#endif
997
998 } else if (!disregardOppositeDirection && offset > 0) { // TODO: offset<0 may indicate opposite query when vehicle is on opposite itself
999 // check whether ix points to an opposite lane
1000 const MSEdge* opposite = vehEdge->getOppositeEdge();
1001 if (opposite == nullptr) {
1002#ifdef DEBUG_SURROUNDING
1003 std::cout << "No lane at index " << offset << std::endl;
1004#endif
1005 // no opposite edge
1006 continue;
1007 }
1008 // Index of opposite lane at relative offset
1009 const int ix_opposite = (int)opposite->getLanes().size() - 1 - (vehLane->getIndex() + offset - (int)vehEdge->getLanes().size());
1010 if (ix_opposite < 0) {
1011#ifdef DEBUG_SURROUNDING
1012 std::cout << "No lane on opposite at index " << ix_opposite << std::endl;
1013#endif
1014 // no opposite edge
1015 continue;
1016 }
1017 lane = opposite->getLanes()[ix_opposite];
1018 // Search vehs along opposite lanes (swap upstream and downstream distance)
1019 // XXX transformations for curved geometries
1020 double posOnOpposite = MAX2(0., opposite->getLength() - v->getPositionOnLane());
1021 // Get leader on opposite
1022 vehs.insert(vehs.end(), lane->getFollower(v, posOnOpposite, downstreamDist, MSLane::MinorLinkMode::FOLLOW_NEVER).first);
1023 // Get follower (no search on consecutive lanes
1024 vehs.insert(vehs.end(), lane->getLeader(v, posOnOpposite - v->getLength(), std::vector<MSLane*>()).first);
1025 }
1026 }
1027 }
1028
1032 applySubscriptionFilterLanes(s, vehs, filterLanes, downstreamDist, upstreamDist, disregardOppositeDirection);
1033 }
1035 applySubscriptionFilterLateralDistance(s, vehs, downstreamDist, upstreamDist, lateralDist);
1036 }
1037 }
1038#ifdef DEBUG_SURROUNDING
1039 std::cout << SIMTIME << " applySubscriptionFilters() for veh '" << v->getID() << "'. Found the following vehicles:\n";
1040 for (auto veh : vehs) {
1041 debugPrint(veh);
1042 }
1043#endif
1044 } else if (s.activeFilters & SUBS_FILTER_LATERAL_DIST) {
1045 applySubscriptionFilterLateralDistance(s, vehs, downstreamDist, upstreamDist, lateralDist);
1046 } else {
1047 // No maneuver or lateral distance filters requested, but only lanes filter (directly, or indirectly by specifying downstream or upstream distance)
1048 applySubscriptionFilterLanes(s, vehs, filterLanes, downstreamDist, upstreamDist, disregardOppositeDirection);
1049 }
1050 // Write vehs IDs in objIDs
1051 for (const SUMOTrafficObject* veh : vehs) {
1052 if (veh != nullptr) {
1053 objIDs.insert(objIDs.end(), veh->getID());
1054 }
1055 }
1056 }
1057
1059 // Only return vehicles of the given vClass in context subscription result
1060 auto i = objIDs.begin();
1061 while (i != objIDs.end()) {
1062 MSBaseVehicle* veh = getVehicle(*i);
1063 if ((veh->getVehicleType().getVehicleClass() & s.filterVClasses) == 0) {
1064 i = objIDs.erase(i);
1065 } else {
1066 ++i;
1067 }
1068 }
1069 }
1071 // Only return vehicles of the given vType in context subscription result
1072 auto i = objIDs.begin();
1073 while (i != objIDs.end()) {
1074 MSBaseVehicle* veh = getVehicle(*i);
1075 if (s.filterVTypes.find(veh->getVehicleType().getID()) == s.filterVTypes.end()) {
1076 i = objIDs.erase(i);
1077 } else {
1078 ++i;
1079 }
1080 }
1081 }
1083 // Only return vehicles within field of vision in context subscription result
1085 }
1086}
1087
1088void
1089Helper::applySubscriptionFilterLanes(const Subscription& s, std::set<const SUMOTrafficObject*>& vehs, std::vector<int>& filterLanes, double downstreamDist,
1090 double upstreamDist, bool disregardOppositeDirection) {
1092 WRITE_WARNINGF(TL("Lanes filter is only feasible for context domain 'vehicle' (current is '%'), ignoring filter..."), toHex(s.contextDomain, 2));
1093 return;
1094 }
1095 assert(filterLanes.size() > 0);
1096 MSVehicle* v = dynamic_cast<MSVehicle*>(getVehicle(s.id));
1097 const MSLane* vehLane = v->getLane();
1098 MSEdge* vehEdge = &vehLane->getEdge();
1099 // This is to remember the lanes checked in the driving direction of the vehicle (their opposites can be added in a second pass)
1100 auto checkedLanesInDrivingDir = std::make_shared<LaneCoverageInfo>();
1101 for (int offset : filterLanes) {
1102 MSLane* lane = vehLane->getParallelLane(offset, false);
1103 if (lane != nullptr) {
1104#ifdef DEBUG_SURROUNDING
1105 std::cout << "Checking for surrounding vehicles starting on lane '" << lane->getID() << "' at index " << offset << std::endl;
1106#endif
1107 // Search vehs along this lane
1108 // (Coverage info is collected per origin lane since lanes reached from neighboring lanes may have different distances
1109 // and aborting at previously scanned when coming from a closer origin may prevent scanning of parts that should be included.)
1110 std::shared_ptr<LaneCoverageInfo> checkedLanes = std::make_shared<LaneCoverageInfo>();
1111 const std::set<MSVehicle*> new_vehs =
1112 lane->getSurroundingVehicles(v->getPositionOnLane(), downstreamDist, upstreamDist + v->getLength(), checkedLanes);
1113 vehs.insert(new_vehs.begin(), new_vehs.end());
1114 fuseLaneCoverage(checkedLanesInDrivingDir, checkedLanes);
1115 } else if (!disregardOppositeDirection && offset > 0) {
1116 // Check opposite edge, too
1117 assert(vehLane->getIndex() + offset >= (int)vehEdge->getLanes().size()); // index points beyond this edge
1118 const MSEdge* opposite = vehEdge->getOppositeEdge();
1119 if (opposite == nullptr) {
1120#ifdef DEBUG_SURROUNDING
1121 std::cout << "No opposite edge, thus no lane at index " << offset << std::endl;
1122#endif
1123 // no opposite edge
1124 continue;
1125 }
1126 // Index of opposite lane at relative offset
1127 const int ix_opposite = (int)opposite->getLanes().size() - 1 - (vehLane->getIndex() + offset - (int)vehEdge->getLanes().size());
1128 if (ix_opposite < 0) {
1129#ifdef DEBUG_SURROUNDING
1130 std::cout << "No lane on opposite at index " << ix_opposite << std::endl;
1131#endif
1132 // no opposite edge
1133 continue;
1134 }
1135 lane = opposite->getLanes()[ix_opposite];
1136 // Search vehs along opposite lanes (swap upstream and downstream distance)
1137 const std::set<MSVehicle*> new_vehs = lane->getSurroundingVehicles(lane->getLength() - v->getPositionOnLane(), upstreamDist + v->getLength(),
1138 downstreamDist, std::make_shared<LaneCoverageInfo>());
1139 vehs.insert(new_vehs.begin(), new_vehs.end());
1140 }
1141#ifdef DEBUG_SURROUNDING
1142 else {
1143 std::cout << "No lane at index " << offset << std::endl;
1144 }
1145#endif
1146
1147 if (!disregardOppositeDirection) {
1148 // If opposite should be checked, do this for each lane of the search tree in checkedLanesInDrivingDir
1149 // (For instance, some opposite lanes of these would not be obtained if the ego lane does not have an opposite.)
1150
1151 // Number of opposite lanes to be checked (assumes filterLanes.size()>0, see assertion above) determined as hypothetical offset
1152 // overlap into opposing edge from the vehicle's current lane.
1153 // TODO: offset<0 may indicate opposite query when vehicle is on opposite itself (-> use min_element(filterLanes...) instead, etc)
1154 const int nOpp = MAX2(0, (*std::max_element(filterLanes.begin(), filterLanes.end())) - ((int)vehEdge->getLanes().size() - 1 - vehLane->getIndex()));
1155 // Collect vehicles from opposite lanes
1156 if (nOpp > 0) {
1157 for (auto& laneCov : *checkedLanesInDrivingDir) {
1158 const MSLane* const l = laneCov.first;
1159 if (l == nullptr || l->getEdge().getOppositeEdge() == nullptr) {
1160 continue;
1161 }
1162 const MSEdge* opposite = l->getEdge().getOppositeEdge();
1163 const std::pair<double, double>& range = laneCov.second;
1164 auto leftMostOppositeLaneIt = opposite->getLanes().rbegin();
1165 for (auto oppositeLaneIt = leftMostOppositeLaneIt; oppositeLaneIt != opposite->getLanes().rend(); ++oppositeLaneIt) {
1166 if ((int)(oppositeLaneIt - leftMostOppositeLaneIt) == nOpp) {
1167 break;
1168 }
1169 // Add vehicles from corresponding range on opposite direction
1170 const MSLane* oppositeLane = *oppositeLaneIt;
1171 auto new_vehs = oppositeLane->getVehiclesInRange(l->getLength() - range.second, l->getLength() - range.first);
1172 vehs.insert(new_vehs.begin(), new_vehs.end());
1173 }
1174 }
1175 }
1176 }
1177#ifdef DEBUG_SURROUNDING
1178 std::cout << SIMTIME << " applySubscriptionFilterLanes() for veh '" << v->getID() << "', lane offset '" << offset << "'. Found the following vehicles so far:\n";
1179 for (auto veh : vehs) {
1180 debugPrint(veh);
1181 }
1182#endif
1183 }
1184}
1185
1186void
1187Helper::applySubscriptionFilterTurn(const Subscription& s, std::set<const SUMOTrafficObject*>& vehs) {
1189 WRITE_WARNINGF(TL("Turn filter is only feasible for context domain 'vehicle' (current is '%'), ignoring filter..."), toHex(s.contextDomain, 2));
1190 return;
1191 }
1192 // Get upcoming junctions and vialanes within downstream distance, where foe links exist or at least the link direction is not straight
1193 MSVehicle* v = dynamic_cast<MSVehicle*>(getVehicle(s.id));
1194 const MSLane* lane = v->getLane();
1195 std::vector<const MSLink*> links = lane->getUpcomingLinks(v->getPositionOnLane(), s.filterDownstreamDist, v->getBestLanesContinuation());
1196#ifdef DEBUG_SURROUNDING
1197 std::cout << "Applying turn filter for vehicle '" << v->getID() << "'\n Gathering foes ..." << std::endl;
1198#endif
1199 // Iterate through junctions and find approaching foes within foeDistToJunction.
1200 for (auto& l : links) {
1201#ifdef DEBUG_SURROUNDING
1202 std::cout << " On junction '" << l->getJunction()->getID() << "' (no. foe links = " << l->getFoeLinks().size() << "):" << std::endl;
1203#endif
1204 for (auto& foeLane : l->getFoeLanes()) {
1205 if (foeLane->isCrossing()) {
1206#ifdef DEBUG_SURROUNDING
1207 std::cout << " skipping crossing foeLane '" << foeLane->getID() << "'" << std::endl;
1208#endif
1209 continue;
1210 }
1211#ifdef DEBUG_SURROUNDING
1212 std::cout << " foeLane '" << foeLane->getID() << "'" << std::endl;
1213#endif
1214 // Check vehicles approaching the entry link corresponding to this lane
1215 const MSLink* foeLink = foeLane->getEntryLink();
1216 for (auto& vi : foeLink->getApproaching()) {
1217 if (vi.second.dist <= s.filterFoeDistToJunction) {
1218#ifdef DEBUG_SURROUNDING
1219 std::cout << " Approaching foeLane entry link '" << vi.first->getID() << "'" << std::endl;
1220#endif
1221 vehs.insert(vehs.end(), dynamic_cast<const MSVehicle*>(vi.first));
1222 }
1223 }
1224 // add vehicles currently on the junction
1225 for (const MSVehicle* foe : foeLane->getVehiclesSecure()) {
1226#ifdef DEBUG_SURROUNDING
1227 std::cout << " On foeLane '" << foe->getID() << "'" << std::endl;
1228#endif
1229 vehs.insert(vehs.end(), foe);
1230 }
1231 foeLane->releaseVehicles();
1232 for (auto& laneInfo : foeLane->getIncomingLanes()) {
1233 const MSLane* foeLanePred = laneInfo.lane;
1234 if (foeLanePred->isInternal()) {
1235#ifdef DEBUG_SURROUNDING
1236 std::cout << " foeLanePred '" << foeLanePred->getID() << "'" << std::endl;
1237#endif
1238 for (const MSVehicle* foe : foeLanePred->getVehiclesSecure()) {
1239#ifdef DEBUG_SURROUNDING
1240 std::cout << " On foeLanePred '" << foe->getID() << "'" << std::endl;
1241#endif
1242 vehs.insert(vehs.end(), foe);
1243 }
1244 foeLanePred->releaseVehicles();
1245 }
1246 }
1247 }
1248 }
1249}
1250
1251void
1252Helper::applySubscriptionFilterFieldOfVision(const Subscription& s, std::set<std::string>& objIDs) {
1254 WRITE_WARNINGF(TL("Field of vision opening angle ('%') should be within interval (0, 360), ignoring filter..."), s.filterFieldOfVisionOpeningAngle);
1255 return;
1256 }
1257
1258 MSBaseVehicle* egoVehicle = getVehicle(s.id);
1259 Position egoPosition = egoVehicle->getPosition();
1260 double openingAngle = DEG2RAD(s.filterFieldOfVisionOpeningAngle);
1261
1262#ifdef DEBUG_SURROUNDING
1263 std::cout << "FOVFILTER: ego direction = " << toString(RAD2DEG(egoVehicle->getAngle())) << " (deg)" << std::endl;
1264#endif
1265
1266 auto i = objIDs.begin();
1267 while (i != objIDs.end()) {
1268 if (s.id.compare(*i) == 0) { // skip if this is the ego vehicle
1269 ++i;
1270 continue;
1271 }
1273 double angleEgoToVeh = egoPosition.angleTo2D(obj->getPosition());
1274 double alpha = GeomHelper::angleDiff(egoVehicle->getAngle(), angleEgoToVeh);
1275
1276#ifdef DEBUG_SURROUNDING
1277 const std::string objType = s.isVehicleToPersonContextSubscription() ? "person" : "veh";
1278 std::cout << "FOVFILTER: " << objType << " '" << *i << "' dist = " << toString(egoPosition.distanceTo2D(obj->getPosition())) << std::endl;
1279 std::cout << "FOVFILTER: " << objType << " '" << *i << "' alpha = " << toString(RAD2DEG(alpha)) << " (deg)" << std::endl;
1280#endif
1281
1282 if (abs(alpha) > openingAngle * 0.5) {
1283 i = objIDs.erase(i);
1284 } else {
1285 ++i;
1286 }
1287 }
1288}
1289
1290void
1291Helper::applySubscriptionFilterLateralDistance(const Subscription& s, std::set<const SUMOTrafficObject*>& vehs, double downstreamDist, double upstreamDist,
1292 double lateralDist) {
1293 // collect all vehicles within maximum range of interest to get an upper bound
1294 PositionVector vehShape;
1295 findObjectShape(s.commandId, s.id, vehShape);
1296 double range = MAX3(downstreamDist, upstreamDist, lateralDist);
1297 std::set<std::string> objIDs;
1298 collectObjectIDsInRange(s.contextDomain, vehShape, range, objIDs);
1299
1300#ifdef DEBUG_SURROUNDING
1301 std::cout << "FILTER_LATERAL_DIST: collected object IDs (range " << range << "):" << std::endl;
1302 for (std::string i : objIDs) {
1303 std::cout << i << std::endl;
1304 }
1305#endif
1306
1307 MSVehicle* v = dynamic_cast<MSVehicle*>(getVehicle(s.id));
1308#ifdef DEBUG_SURROUNDING
1309 std::cout << "FILTER_LATERAL_DIST: myLane is '" << v->getLane()->getID() << "', pos " << v->getPositionOnLane() << std::endl;
1310 std::cout << "FILTER_LATERAL_DIST: opposite lane is '" << v->getLane()->getParallelOpposite()->getID() << "'" << std::endl;
1311#endif
1312 double frontPosOnLane = v->getPositionOnLane();
1313 if (v->getLaneChangeModel().isOpposite()) {
1314 frontPosOnLane = v->getLane()->getOppositePos(frontPosOnLane);
1315 }
1316 // 1st pass: downstream (make sure that the whole length of the vehicle is included in the match)
1317 const double backPosOnLane = MAX2(0.0, frontPosOnLane - v->getVehicleType().getLength());
1318 applySubscriptionFilterLateralDistanceSinglePass(s, objIDs, vehs, v->getUpcomingLanesUntil(downstreamDist), backPosOnLane, v->getLateralPositionOnLane(),
1319 true);
1320 // 2nd pass: upstream
1321 applySubscriptionFilterLateralDistanceSinglePass(s, objIDs, vehs, v->getPastLanesUntil(upstreamDist), frontPosOnLane, v->getLateralPositionOnLane(), false);
1322}
1323
1324void
1326 std::set<const SUMOTrafficObject*>& vehs,
1327 const std::vector<const MSLane*>& lanes, double posOnLane, double posLat, bool isDownstream) {
1328 const double streamDist = isDownstream ? s.filterDownstreamDist : s.filterUpstreamDist;
1329 double distRemaining = streamDist;
1330 bool isFirstLane = true;
1331 PositionVector combinedShape;
1332 for (const MSLane* lane : lanes) {
1333#ifdef DEBUG_SURROUNDING
1334 std::cout << "FILTER_LATERAL_DIST: current lane " << (isDownstream ? "down" : "up") << " is '" << lane->getID() << "', length " << lane->getLength()
1335 << ", pos " << posOnLane << ", distRemaining " << distRemaining << std::endl;
1336#endif
1337 PositionVector laneShape = lane->getShape();
1338 if (isFirstLane) {
1339 isFirstLane = false;
1340 double geometryPos = lane->interpolateLanePosToGeometryPos(posOnLane);
1341 if (geometryPos <= POSITION_EPS) {
1342 if (!isDownstream) {
1343 continue;
1344 }
1345 } else {
1346 if (geometryPos >= laneShape.length() - POSITION_EPS) {
1347 laneShape = isDownstream ? PositionVector() : laneShape;
1348 } else {
1349 auto pair = laneShape.splitAt(geometryPos, false);
1350 laneShape = isDownstream ? pair.second : pair.first;
1351 }
1352 }
1353 }
1354 double laneLength = lane->interpolateGeometryPosToLanePos(laneShape.length());
1355 if (distRemaining - laneLength < 0.) {
1356 double geometryPos = lane->interpolateLanePosToGeometryPos(isDownstream ? distRemaining : laneLength - distRemaining);
1357 if (geometryPos > POSITION_EPS && geometryPos < laneShape.length() - POSITION_EPS) {
1358 auto pair = laneShape.splitAt(geometryPos, false);
1359 laneShape = isDownstream ? pair.first : pair.second;
1360 }
1361 }
1362 distRemaining -= laneLength;
1363 try {
1364 laneShape.move2side(-posLat);
1365 } catch (ProcessError&) {
1366 WRITE_WARNINGF(TL("addSubscriptionFilterLateralDistance could not determine shape of lane '%' with a lateral shift of %."),
1367 lane->getID(), toString(posLat));
1368 }
1369#ifdef DEBUG_SURROUNDING
1370 std::cout << " posLat=" << posLat << " laneShape=" << laneShape << "\n";
1371#endif
1372 if (isDownstream) {
1373 combinedShape.append(laneShape);
1374 } else {
1375 combinedShape.prepend(laneShape);
1376 }
1377 if (distRemaining <= POSITION_EPS) {
1378 break;
1379 }
1380 }
1381#ifdef DEBUG_SURROUNDING
1382 std::cout << " combinedShape=" << combinedShape << "\n";
1383#endif
1384 // check remaining objects' distances to the combined shape
1385 auto i = objIDs.begin();
1386 while (i != objIDs.end()) {
1388 double minPerpendicularDist = combinedShape.distance2D(obj->getPosition(), true);
1389#ifdef DEBUG_SURROUNDING
1390 std::cout << (isDownstream ? "DOWN" : "UP") << " obj " << obj->getID() << " perpendicular dist=" << minPerpendicularDist << " filterLateralDist=" << s.filterLateralDist << "\n";
1391#endif
1392 if ((minPerpendicularDist != GeomHelper::INVALID_OFFSET) && (minPerpendicularDist <= s.filterLateralDist)) {
1393 vehs.insert(obj);
1394 i = objIDs.erase(i);
1395 } else {
1396 ++i;
1397 }
1398 }
1399}
1400
1401void
1402Helper::setRemoteControlled(MSVehicle* v, Position xyPos, MSLane* l, double pos, double posLat, double angle,
1403 int edgeOffset, ConstMSEdgeVector route, SUMOTime t) {
1405 v->getInfluencer().setRemoteControlled(xyPos, l, pos, posLat, angle, edgeOffset, route, t);
1406}
1407
1408void
1409Helper::setRemoteControlled(MSPerson* p, Position xyPos, MSLane* l, double pos, double posLat, double angle,
1410 int edgeOffset, ConstMSEdgeVector route, SUMOTime t) {
1412 p->getInfluencer().setRemoteControlled(xyPos, l, pos, posLat, angle, edgeOffset, route, t);
1413}
1414
1415
1416int
1418 int numControlled = 0;
1419 for (auto& controlled : myRemoteControlledVehicles) {
1420 if (MSNet::getInstance()->getVehicleControl().getVehicle(controlled.first) != nullptr) {
1421 controlled.second->getInfluencer().postProcessRemoteControl(controlled.second);
1422 numControlled++;
1423 } else {
1424 WRITE_WARNINGF(TL("Vehicle '%' was removed though being controlled by TraCI"), controlled.first);
1425 }
1426 }
1428 for (auto& controlled : myRemoteControlledPersons) {
1429 if (MSNet::getInstance()->getPersonControl().get(controlled.first) != nullptr) {
1430 controlled.second->getInfluencer().postProcessRemoteControl(controlled.second);
1431 numControlled++;
1432 } else {
1433 WRITE_WARNINGF(TL("Person '%' was removed though being controlled by TraCI"), controlled.first);
1434 }
1435 }
1437 return numControlled;
1438}
1439
1440
1441bool
1442Helper::moveToXYMap(const Position& pos, double maxRouteDistance, bool mayLeaveNetwork, const std::string& origID, const double angle,
1443 double speed, const ConstMSEdgeVector& currentRoute, const int routePosition, const MSLane* currentLane, double currentLanePos, bool onRoad,
1444 SUMOVehicleClass vClass, double currentAngle, bool setLateralPos,
1445 double& bestDistance, MSLane** lane, double& lanePos, int& routeOffset, ConstMSEdgeVector& edges) {
1446 // collect edges around the vehicle/person
1447#ifdef DEBUG_MOVEXY
1448 std::cout << SIMTIME << " moveToXYMap pos=" << pos << " angle=" << angle << " vClass=" << toString(vClass) << "\n";
1449#endif
1450 const MSEdge* const currentRouteEdge = currentRoute[routePosition];
1451 std::set<const Named*> into;
1452 PositionVector shape;
1453 shape.push_back(pos);
1454 collectObjectsInRange(libsumo::CMD_GET_EDGE_VARIABLE, shape, maxRouteDistance, into);
1455 double maxDist = 0;
1456 std::map<MSLane*, LaneUtility, ComparatorNumericalIdLess> lane2utility;
1457 // compute utility for all candidate edges
1458 for (const Named* namedEdge : into) {
1459 const MSEdge* e = dynamic_cast<const MSEdge*>(namedEdge);
1460 if ((e->getPermissions() & vClass) != vClass) {
1461 continue;
1462 }
1463 const MSEdge* prevEdge = nullptr;
1464 const MSEdge* nextEdge = nullptr;
1465 bool onRoute = false;
1466 bool useCurrentAngle = false;
1467 // the next if/the clause sets "onRoute", "prevEdge", and "nextEdge", depending on
1468 // whether the currently seen edge is an internal one or a normal one
1469 if (e->isWalkingArea() || e->isCrossing()) {
1470 // find current intersection along the route
1471 const MSJunction* junction = e->getFromJunction();
1472 for (int i = routePosition; i < (int)currentRoute.size(); i++) {
1473 const MSEdge* cand = currentRoute[i];
1474 if (cand->getToJunction() == junction) {
1475 prevEdge = cand;
1476 if (i + 1 < (int)currentRoute.size()) {
1477 onRoute = true;
1478 nextEdge = currentRoute[i + 1];
1479 }
1480 break;
1481 }
1482 }
1483 if (!onRoute) {
1484 // search backward
1485 for (int i = routePosition - 1; i >= 0; i--) {
1486 const MSEdge* cand = currentRoute[i];
1487 if (cand->getToJunction() == junction) {
1488 onRoute = true;
1489 prevEdge = cand;
1490 nextEdge = currentRoute[i + 1];
1491 break;
1492 }
1493 }
1494 }
1495 if (prevEdge == nullptr) {
1496 // use arbitrary predecessor
1497 if (e->getPredecessors().size() > 0) {
1498 prevEdge = e->getPredecessors().front();
1499 } else if (e->getSuccessors().size() > 1) {
1500 for (MSEdge* e2 : e->getSuccessors()) {
1501 if (e2 != nextEdge) {
1502 prevEdge = e2;
1503 break;
1504 }
1505 }
1506 }
1507 }
1508 if (nextEdge == nullptr) {
1509 if (e->getSuccessors().size() > 0) {
1510 nextEdge = e->getSuccessors().front();
1511 } else if (e->getPredecessors().size() > 1) {
1512 for (MSEdge* e2 : e->getPredecessors()) {
1513 if (e2 != prevEdge) {
1514 nextEdge = e2;
1515 break;
1516 }
1517 }
1518 }
1519 }
1520#ifdef DEBUG_MOVEXY_ANGLE
1521 std::cout << "walkingarea/crossing:" << e->getID() << " prev:" << Named::getIDSecure(prevEdge) << " next:" << Named::getIDSecure(nextEdge)
1522 << " pred=" << toString(e->getPredecessors()) << " succ=" << toString(e->getSuccessors())
1523 << "\n";
1524#endif
1525 } else if (e->isNormal()) {
1526 // a normal edge
1527 //
1528 // check whether the currently seen edge is in the vehicle's route
1529 // - either the one it's on or one of the next edges
1530 ConstMSEdgeVector::const_iterator searchStart = currentRoute.begin() + routePosition;
1531 if (onRoad && currentLane->getEdge().isInternal()) {
1532 ++searchStart;
1533 }
1534 ConstMSEdgeVector::const_iterator edgePos = std::find(searchStart, currentRoute.end(), e);
1535 onRoute = edgePos != currentRoute.end(); // no? -> onRoute is false
1536 if (edgePos == currentRoute.end() - 1 && currentRouteEdge == e) {
1537 // onRoute is false as well if the vehicle is beyond the edge
1538 onRoute &= currentRouteEdge->getLength() > currentLanePos + SPEED2DIST(speed);
1539 }
1540 // save prior and next edges
1541 prevEdge = e;
1542 nextEdge = !onRoute || edgePos == currentRoute.end() - 1 ? nullptr : *(edgePos + 1);
1543#ifdef DEBUG_MOVEXY_ANGLE
1544 std::cout << "normal:" << e->getID() << " prev:" << Named::getIDSecure(prevEdge) << " next:" << Named::getIDSecure(nextEdge) << "\n";
1545#endif
1546 } else if (e->isInternal()) {
1547 // an internal edge
1548 // get the previous edge
1549 prevEdge = e;
1550 while (prevEdge != nullptr && prevEdge->isInternal()) {
1551 MSLane* l = prevEdge->getLanes()[0];
1553 prevEdge = l == nullptr ? nullptr : &l->getEdge();
1554 }
1555 // check whether the previous edge is on the route (was on the route)
1556 ConstMSEdgeVector::const_iterator prevEdgePos = std::find(currentRoute.begin() + routePosition, currentRoute.end(), prevEdge);
1557 nextEdge = e;
1558 while (nextEdge != nullptr && nextEdge->isInternal()) {
1559 nextEdge = nextEdge->getSuccessors()[0]; // should be only one for an internal edge
1560 }
1561 if (prevEdgePos != currentRoute.end() && (prevEdgePos + 1) != currentRoute.end()) {
1562 onRoute = *(prevEdgePos + 1) == nextEdge;
1563 } else {
1564 // we cannot make use of route information and should make
1565 // use of the current angle if the user did not supply an angle
1566 useCurrentAngle = angle == INVALID_DOUBLE_VALUE;
1567 }
1568#ifdef DEBUG_MOVEXY_ANGLE
1569 std::cout << "internal:" << e->getID() << " prev:" << Named::getIDSecure(prevEdge) << " next:" << Named::getIDSecure(nextEdge) << "\n";
1570#endif
1571 }
1572
1573
1574 // weight the lanes...
1575 const bool perpendicular = false;
1576 for (MSLane* const l : e->getLanes()) {
1577 if (!l->allowsVehicleClass(vClass)) {
1578 continue;
1579 }
1580 if (l->getShape().length() == 0) {
1581 // mapping to shapeless lanes is a bad idea
1582 continue;
1583 }
1584 double langle = 180.;
1585 double dist = FAR_AWAY;
1586 double perpendicularDist = FAR_AWAY;
1587 // add some slack to avoid issues from tiny gaps between consecutive lanes
1588 // except when simulating with high precision where the slack can throw of mapping
1589 const double slack = POSITION_EPS * TS;
1590 PositionVector laneShape = l->getShape();
1591 laneShape.extrapolate2D(slack);
1592 double off = laneShape.nearest_offset_to_point2D(pos, true);
1593 if (off != GeomHelper::INVALID_OFFSET) {
1594 perpendicularDist = laneShape.distance2D(pos, true);
1595 perpendicularDist = patchShapeDistance(l, pos, perpendicularDist, true);
1596 }
1597 off = l->getShape().nearest_offset_to_point2D(pos, perpendicular);
1598 if (off != GeomHelper::INVALID_OFFSET) {
1599 dist = l->getShape().distance2D(pos, perpendicular);
1600 dist = patchShapeDistance(l, pos, dist, perpendicular);
1601 langle = GeomHelper::naviDegree(l->getShape().rotationAtOffset(off));
1602 }
1603 // cannot trust lanePos on walkingArea
1604 bool sameEdge = onRoad && e == &currentLane->getEdge() && currentRouteEdge->getLength() > currentLanePos + SPEED2DIST(speed) && !e->isWalkingArea();
1605 /*
1606 const MSEdge* rNextEdge = nextEdge;
1607 while(rNextEdge==0&&lane->getEdge().getPurpose()==MSEdge::EDGEFUNCTION_INTERNAL) {
1608 MSLane* next = lane->getLinkCont()[0]->getLane();
1609 rNextEdge = next == 0 ? 0 : &next->getEdge();
1610 }
1611 */
1612 double dist2 = dist;
1613 if (mayLeaveNetwork && fabs(dist - perpendicularDist) > slack) {
1614 // ambiguous mapping. Don't trust this
1615 dist2 = FAR_AWAY;
1616 }
1617 const double angle2 = useCurrentAngle ? currentAngle : angle;
1618 const double angleDiff = (angle2 == INVALID_DOUBLE_VALUE || l->isWalkingArea() ? 0 : GeomHelper::getMinAngleDiff(angle2, langle));
1619#ifdef DEBUG_MOVEXY_ANGLE
1620 std::cout << std::setprecision(gPrecision)
1621 << " candLane=" << l->getID() << " lAngle=" << langle << " lLength=" << l->getLength()
1622 << " angleDiff=" << angleDiff
1623 << " off=" << off
1624 << " pDist=" << perpendicularDist
1625 << " dist=" << dist
1626 << " dist2=" << dist2
1627 << "\n";
1628 std::cout << l->getID() << " param=" << l->getParameter(SUMO_PARAM_ORIGID, "") << " origID='" << origID << "\n";
1629#endif
1630
1631 bool origIDMatch = l->getParameter(SUMO_PARAM_ORIGID, l->getID()) == origID;
1632 if (origIDMatch && setLateralPos
1633 && perpendicularDist > l->getWidth() / 2) {
1634 origIDMatch = false;
1635 }
1636 lane2utility.emplace(l, LaneUtility(
1637 dist2, perpendicularDist, off, angleDiff,
1638 origIDMatch,
1639 onRoute, sameEdge, prevEdge, nextEdge));
1640 // update scaling value
1641 maxDist = MAX2(maxDist, MIN2(dist, SUMO_const_laneWidth));
1642
1643 }
1644 }
1645
1646 // get the best lane given the previously computed values
1647 double bestValue = 0;
1648 MSLane* bestLane = nullptr;
1649 for (const auto& it : lane2utility) {
1650 MSLane* const l = it.first;
1651 const LaneUtility& u = it.second;
1652 double distN = u.dist > 999 ? -10 : 1. - (u.dist / maxDist);
1653 double angleDiffN = 1. - (u.angleDiff / 180.);
1654 double idN = u.ID ? 1 : 0;
1655 double onRouteN = u.onRoute ? 1 : 0;
1656 double sameEdgeN = u.sameEdge ? MIN2(currentRouteEdge->getLength() / MAX2(NUMERICAL_EPS, speed), (double)1.) : 0;
1657 // distance is more important than angle because the vehicle might be driving in the opposite direction
1658 // also, distance becomes increasingly more important with lower step lengths (because position errors from one step to the next can result in large acceleration/speed errors)
1659 double value = (distN * .5 / TS
1660 + angleDiffN * 0.35 /*.5 */
1661 + idN * 1
1662 + onRouteN * 0.1
1663 + sameEdgeN * 0.1);
1664#ifdef DEBUG_MOVEXY
1665 std::cout << " x; l:" << l->getID() << " d:" << u.dist << " dN:" << distN << " aD:" << angleDiffN <<
1666 " ID:" << idN << " oRN:" << onRouteN << " sEN:" << sameEdgeN << " value:" << value << std::endl;
1667#endif
1668 if (value > bestValue || bestLane == nullptr) {
1669 bestValue = value;
1670 if (u.dist == FAR_AWAY) {
1671 bestLane = nullptr;
1672 } else {
1673 bestLane = l;
1674 }
1675 }
1676 }
1677 // no best lane found, return
1678 if (bestLane == nullptr) {
1679 return false;
1680 }
1681 const LaneUtility& u = lane2utility.find(bestLane)->second;
1682 bestDistance = u.dist;
1683 *lane = bestLane;
1684 lanePos = MAX2(0., MIN2(double((*lane)->getLength() - NUMERICAL_EPS),
1686 bestLane->getShape().nearest_offset_to_point25D(pos, false))));
1687 const MSEdge* prevEdge = u.prevEdge;
1688 if (u.onRoute) {
1689 ConstMSEdgeVector::const_iterator prevEdgePos = std::find(currentRoute.begin(), currentRoute.end(), prevEdge);
1690 routeOffset = (int)std::distance(currentRoute.begin(), prevEdgePos);
1691 //std::cout << SIMTIME << "moveToXYMap currLane=" << currentLane->getID() << " routeOffset=" << routeOffset << " edges=" << toString(edges) << " bestLane=" << bestLane->getID() << " prevEdge=" << prevEdge->getID() << "\n";
1692 } else {
1693 edges.push_back(u.prevEdge);
1694 /*
1695 if(bestLane->getEdge().getPurpose()!=MSEdge::EDGEFUNCTION_INTERNAL) {
1696 edges.push_back(&bestLane->getEdge());
1697 }
1698 */
1699 if (u.nextEdge != nullptr) {
1700 edges.push_back(u.nextEdge);
1701 }
1702 routeOffset = 0;
1703#ifdef DEBUG_MOVEXY_ANGLE
1704 std::cout << SIMTIME << " internal2: lane=" << bestLane->getID() << " prev=" << Named::getIDSecure(u.prevEdge) << " next=" << Named::getIDSecure(u.nextEdge) << "\n";
1705#endif
1706 }
1707 return true;
1708}
1709
1710
1711bool
1712Helper::findCloserLane(const MSEdge* edge, const Position& pos, SUMOVehicleClass vClass, double& bestDistance, MSLane** lane) {
1713 // TODO maybe there is a way to abort this early if the lane already found is good enough but simply
1714 // checking for bestDistance < POSITON_EPS gives ugly order dependencies (#7933), so think twice and profile first
1715 if (edge == nullptr) {
1716 return false;
1717 }
1718 bool newBest = false;
1719 for (MSLane* const candidateLane : edge->getLanes()) {
1720 if (!candidateLane->allowsVehicleClass(vClass)) {
1721 continue;
1722 }
1723 if (candidateLane->getShape().length() == 0) {
1724 // mapping to shapeless lanes is a bad idea
1725 continue;
1726 }
1727 double dist = candidateLane->getShape().distance2D(pos);
1728 dist = patchShapeDistance(candidateLane, pos, dist, false);
1729#ifdef DEBUG_MOVEXY
1730 std::cout << " b at lane " << candidateLane->getID() << " dist:" << dist << " best:" << bestDistance << std::endl;
1731#endif
1732 if (dist < bestDistance || (dist == bestDistance && candidateLane->getNumericalID() < (*lane)->getNumericalID())) {
1733 // is the new distance the best one? keep then...
1734 bestDistance = dist;
1735 *lane = candidateLane;
1736 newBest = true;
1737 }
1738 }
1739 if (edge->isInternal() && edge->getNumLanes() > 1) {
1740 // there is a parallel internal edge that isn't returned by getInternalFollowingEdge but is also usable for the same route
1741 for (const MSLane* const l : edge->getLanes()) {
1742 if (l->getIndex() == 0) {
1743 continue;
1744 }
1745 for (const MSLink* const link : l->getLinkCont()) {
1746 if (link->isInternalJunctionLink()) {
1747 if (findCloserLane(&link->getViaLane()->getEdge(), pos, vClass, bestDistance, lane)) {
1748 newBest = true;
1749 }
1750 }
1751 }
1752 }
1753 }
1754 return newBest;
1755}
1756
1757
1758bool
1759Helper::moveToXYMap_matchingRoutePosition(const Position& pos, const std::string& origID,
1760 const ConstMSEdgeVector& currentRoute, int routeIndex,
1761 SUMOVehicleClass vClass, bool setLateralPos,
1762 double& bestDistance, MSLane** lane, double& lanePos, int& routeOffset) {
1763#ifdef DEBUG_MOVEXY
1764 std::cout << SIMTIME << " moveToXYMap_matchingRoutePosition pos=" << pos << " vClass=" << toString(vClass) << "\n";
1765#endif
1766 //std::cout << "moveToXYMap_matchingRoutePosition pos=" << pos << "\n";
1767 routeOffset = 0;
1768 // routes may be looped which makes routeOffset ambiguous. We first try to
1769 // find the closest upcoming edge on the route and then look for closer passed edges
1770
1771 // look forward along the route
1772 const MSEdge* prev = nullptr;
1773 for (int i = routeIndex; i < (int)currentRoute.size(); ++i) {
1774 const MSEdge* cand = currentRoute[i];
1775 while (prev != nullptr) {
1776 // check internal edge(s)
1777 const MSEdge* internalCand = prev->getInternalFollowingEdge(cand, vClass);
1778#ifdef DEBUG_MOVEXY
1779 std::cout << SIMTIME << " prev=" << Named::getIDSecure(prev) << " cand=" << Named::getIDSecure(cand) << " internal=" << Named::getIDSecure(internalCand) << "\n";
1780#endif
1781 if (findCloserLane(internalCand, pos, vClass, bestDistance, lane)) {
1782 routeOffset = i - 1;
1783 }
1784 prev = internalCand;
1785 }
1786 if (findCloserLane(cand, pos, vClass, bestDistance, lane)) {
1787 routeOffset = i;
1788 }
1789 prev = cand;
1790 }
1791 // look backward along the route
1792 const MSEdge* next = currentRoute[routeIndex];
1793 for (int i = routeIndex; i >= 0; --i) {
1794 const MSEdge* cand = currentRoute[i];
1795 //std::cout << " next=" << next->getID() << " cand=" << cand->getID() << " i=" << i << " routeIndex=" << routeIndex << "\n";
1796 prev = cand;
1797 while (prev != nullptr) {
1798 // check internal edge(s)
1799 const MSEdge* internalCand = prev->getInternalFollowingEdge(next, vClass);
1800 if (findCloserLane(internalCand, pos, vClass, bestDistance, lane)) {
1801 routeOffset = i;
1802 }
1803 prev = internalCand;
1804 }
1805 if (findCloserLane(cand, pos, vClass, bestDistance, lane)) {
1806 routeOffset = i;
1807 }
1808 next = cand;
1809 }
1810 if (vClass == SVC_PEDESTRIAN) {
1811 // consider all crossings and walkingareas along the route
1812 std::map<const MSJunction*, int> routeJunctions;
1813 for (int i = 0; i < (int)currentRoute.size() - 1; ++i) {
1814 routeJunctions[currentRoute[i]->getToJunction()] = i;
1815 }
1816 std::set<const Named*> into;
1817 PositionVector shape;
1818 shape.push_back(pos);
1820 for (const Named* named : into) {
1821 const MSLane* cand = dynamic_cast<const MSLane*>(named);
1822 if ((cand->isWalkingArea() || cand->isCrossing())
1823 && routeJunctions.count(cand->getEdge().getToJunction()) != 0) {
1824 if (findCloserLane(&cand->getEdge(), pos, vClass, bestDistance, lane)) {
1825 routeOffset = routeJunctions[cand->getEdge().getToJunction()];
1826 }
1827 }
1828 }
1829 }
1830
1831 assert(lane != nullptr);
1832 // quit if no solution was found, reporting a failure
1833 if (*lane == nullptr) {
1834#ifdef DEBUG_MOVEXY
1835 std::cout << " b failed - no best route lane" << std::endl;
1836#endif
1837 return false;
1838 }
1839
1840
1841 // position may be inaccurate; let's check the given index, too
1842 // @note: this is enabled for non-internal lanes only, as otherwise the position information may ambiguous
1843 if (!(*lane)->getEdge().isInternal()) {
1844 const std::vector<MSLane*>& lanes = (*lane)->getEdge().getLanes();
1845 for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
1846 if ((*i)->getParameter(SUMO_PARAM_ORIGID, (*i)->getID()) == origID) {
1847 if (setLateralPos) {
1848 // vehicle might end up on top of another lane with a big
1849 // lateral offset to the lane with origID.
1850 const double dist = (*i)->getShape().distance2D(pos); // get distance
1851 if (dist < (*i)->getWidth() / 2) {
1852 *lane = *i;
1853 break;
1854 }
1855 } else {
1856 *lane = *i;
1857 break;
1858 }
1859 }
1860 }
1861 }
1862 // check position, stuff, we should have the best lane along the route
1863 lanePos = MAX2(0., MIN2(double((*lane)->getLength() - NUMERICAL_EPS),
1864 (*lane)->interpolateGeometryPosToLanePos(
1865 (*lane)->getShape().nearest_offset_to_point25D(pos, false))));
1866 //std::cout << SIMTIME << " moveToXYMap_matchingRoutePosition vehicle=" << veh.getID() << " currLane=" << veh.getLane()->getID() << " routeOffset=" << routeOffset << " edges=" << toString(edges) << " lane=" << (*lane)->getID() << "\n";
1867#ifdef DEBUG_MOVEXY
1868 std::cout << " b ok lane " << (*lane)->getID() << " lanePos:" << lanePos << std::endl;
1869#endif
1870 return true;
1871}
1872
1873
1874double
1875Helper::patchShapeDistance(const MSLane* lane, const Position& pos, double dist, bool wasPerpendicular) {
1876 if (!lane->isWalkingArea() && (wasPerpendicular || lane->getShape().nearest_offset_to_point25D(pos, true) != GeomHelper::INVALID_OFFSET)) {
1877 dist = MAX2(0.0, dist - lane->getWidth() * 0.5);
1878 }
1879 return dist;
1880}
1881
1882
1883int
1885 int distType = 0;
1886 StoHelp::readCompound(data, 2, "Retrieval of distance requires two parameter as compound.");
1887 const int posType = data.readUnsignedByte();
1888 switch (posType) {
1890 roadPos.edgeID = data.readString();
1891 roadPos.pos = data.readDouble();
1892 roadPos.laneIndex = data.readUnsignedByte();
1893 break;
1894 }
1896 case libsumo::POSITION_3D: {
1897 pos.setx(data.readDouble());
1898 pos.sety(data.readDouble());
1899 if (posType == libsumo::POSITION_3D) {
1900 pos.setz(data.readDouble());
1901 }
1902 break;
1903 }
1904 default:
1905 throw TraCIException("Unknown position format used for distance request.");
1906 }
1907 distType = data.readUnsignedByte();
1908 if (distType != libsumo::REQUEST_DRIVINGDIST) {
1909 throw TraCIException("Only driving distance is supported.");
1910 }
1911 return posType;
1912}
1913
1914
1916 : VariableWrapper(handler), myResults(into), myContextResults(context), myActiveResults(&into) {
1917
1918}
1919
1920
1921void
1922Helper::SubscriptionWrapper::setContext(const std::string* const refID) {
1923 myActiveResults = refID == nullptr ? &myResults : &myContextResults[*refID];
1924}
1925
1926
1927void
1929 myActiveResults = &myResults;
1930 myResults.clear();
1931 myContextResults.clear();
1932}
1933
1934
1935bool
1936Helper::SubscriptionWrapper::wrapConnectionVector(const std::string& objID, const int variable, const std::vector<TraCIConnection>& value) {
1937 auto sl = std::make_shared<TraCIConnectionVectorWrapped>();
1938 sl->value = value;
1939 (*myActiveResults)[objID][variable] = sl;
1940 return true;
1941}
1942
1943
1944bool
1945Helper::SubscriptionWrapper::wrapDouble(const std::string& objID, const int variable, const double value) {
1946 (*myActiveResults)[objID][variable] = std::make_shared<TraCIDouble>(value);
1947 return true;
1948}
1949
1950
1951bool
1952Helper::SubscriptionWrapper::wrapInt(const std::string& objID, const int variable, const int value) {
1953 (*myActiveResults)[objID][variable] = std::make_shared<TraCIInt>(value);
1954 return true;
1955}
1956
1957
1958bool
1959Helper::SubscriptionWrapper::wrapString(const std::string& objID, const int variable, const std::string& value) {
1960 (*myActiveResults)[objID][variable] = std::make_shared<TraCIString>(value);
1961 return true;
1962}
1963
1964
1965bool
1966Helper::SubscriptionWrapper::wrapStringList(const std::string& objID, const int variable, const std::vector<std::string>& value) {
1967 auto sl = std::make_shared<TraCIStringList>();
1968 sl->value = value;
1969 (*myActiveResults)[objID][variable] = sl;
1970 return true;
1971}
1972
1973
1974bool
1975Helper::SubscriptionWrapper::wrapDoubleList(const std::string& objID, const int variable, const std::vector<double>& value) {
1976 auto sl = std::make_shared<TraCIDoubleList>();
1977 sl->value = value;
1978 (*myActiveResults)[objID][variable] = sl;
1979 return true;
1980}
1981
1982
1983bool
1984Helper::SubscriptionWrapper::wrapPosition(const std::string& objID, const int variable, const TraCIPosition& value) {
1985 (*myActiveResults)[objID][variable] = std::make_shared<TraCIPosition>(value);
1986 return true;
1987}
1988
1989
1990bool
1991Helper::SubscriptionWrapper::wrapPositionVector(const std::string& objID, const int variable, const TraCIPositionVector& value) {
1992 (*myActiveResults)[objID][variable] = std::make_shared<TraCIPositionVector>(value);
1993 return true;
1994}
1995
1996
1997bool
1998Helper::SubscriptionWrapper::wrapColor(const std::string& objID, const int variable, const TraCIColor& value) {
1999 (*myActiveResults)[objID][variable] = std::make_shared<TraCIColor>(value);
2000 return true;
2001}
2002
2003
2004bool
2005Helper::SubscriptionWrapper::wrapStringDoublePair(const std::string& objID, const int variable, const std::pair<std::string, double>& value) {
2006 (*myActiveResults)[objID][variable] = std::make_shared<TraCIRoadPosition>(value.first, value.second);
2007 return true;
2008}
2009
2010
2011bool
2012Helper::SubscriptionWrapper::wrapStringDoublePairList(const std::string& objID, const int variable, const std::vector<std::pair<std::string, double> >& value) {
2013 auto sl = std::make_shared<TraCIStringDoublePairList>();
2014 sl->value = value;
2015 (*myActiveResults)[objID][variable] = sl;
2016 return true;
2017}
2018
2019
2020bool
2021Helper::SubscriptionWrapper::wrapStringPair(const std::string& objID, const int variable, const std::pair<std::string, std::string>& value) {
2022 auto sl = std::make_shared<TraCIStringList>();
2023 sl->value.push_back(value.first);
2024 sl->value.push_back(value.second);
2025 (*myActiveResults)[objID][variable] = sl;
2026 return true;
2027}
2028
2029
2030bool
2031Helper::SubscriptionWrapper::wrapIntPair(const std::string& objID, const int variable, const std::pair<int, int>& value) {
2032 auto sl = std::make_shared<TraCIIntList>();
2033 sl->value.push_back(value.first);
2034 sl->value.push_back(value.second);
2035 (*myActiveResults)[objID][variable] = sl;
2036 return true;
2037}
2038
2039
2040bool
2041Helper::SubscriptionWrapper::wrapStage(const std::string& objID, const int variable, const TraCIStage& value) {
2042 (*myActiveResults)[objID][variable] = std::make_shared<TraCIStage>(value);
2043 return true;
2044}
2045
2046
2047bool
2048Helper::SubscriptionWrapper::wrapReservationVector(const std::string& objID, const int variable, const std::vector<libsumo::TraCIReservation>& value) {
2049 auto sl = std::make_shared<TraCIReservationVectorWrapped>();
2050 sl->value = value;
2051 (*myActiveResults)[objID][variable] = sl;
2052 return true;
2053}
2054
2055
2056bool
2057Helper::SubscriptionWrapper::wrapLogicVector(const std::string& objID, const int variable, const std::vector<libsumo::TraCILogic>& value) {
2058 auto sl = std::make_shared<TraCILogicVectorWrapped>();
2059 sl->value = value;
2060 (*myActiveResults)[objID][variable] = sl;
2061 return true;
2062}
2063
2064
2065bool
2066Helper::SubscriptionWrapper::wrapLinkVectorVector(const std::string& objID, const int variable, const std::vector<std::vector<libsumo::TraCILink> >& value) {
2067 auto sl = std::make_shared<TraCILinkVectorVectorWrapped>();
2068 sl->value = value;
2069 (*myActiveResults)[objID][variable] = sl;
2070 return true;
2071}
2072
2073
2074bool
2075Helper::SubscriptionWrapper::wrapSignalConstraintVector(const std::string& objID, const int variable, const std::vector<libsumo::TraCISignalConstraint>& value) {
2076 auto sl = std::make_shared<TraCISignalConstraintVectorWrapped>();
2077 sl->value = value;
2078 (*myActiveResults)[objID][variable] = sl;
2079 return true;
2080}
2081
2082
2083bool
2084Helper::SubscriptionWrapper::wrapJunctionFoeVector(const std::string& objID, const int variable, const std::vector<libsumo::TraCIJunctionFoe>& value) {
2085 auto sl = std::make_shared<TraCIJunctionFoeVectorWrapped>();
2086 sl->value = value;
2087 (*myActiveResults)[objID][variable] = sl;
2088 return true;
2089}
2090
2091
2092bool
2093Helper::SubscriptionWrapper::wrapNextStopDataVector(const std::string& objID, const int variable, const std::vector<libsumo::TraCINextStopData>& value) {
2094 auto sl = std::make_shared<TraCINextStopDataVectorWrapped>();
2095 sl->value = value;
2096 (*myActiveResults)[objID][variable] = sl;
2097 return true;
2098}
2099
2100
2101bool
2102Helper::SubscriptionWrapper::wrapVehicleDataVector(const std::string& objID, const int variable, const std::vector<libsumo::TraCIVehicleData>& value) {
2103 auto sl = std::make_shared<TraCIVehicleDataVectorWrapped>();
2104 sl->value = value;
2105 (*myActiveResults)[objID][variable] = sl;
2106 return true;
2107}
2108
2109
2110bool
2111Helper::SubscriptionWrapper::wrapBestLanesDataVector(const std::string& objID, const int variable, const std::vector<libsumo::TraCIBestLanesData>& value) {
2112 auto sl = std::make_shared<TraCIBestLanesDataVectorWrapped>();
2113 sl->value = value;
2114 (*myActiveResults)[objID][variable] = sl;
2115 return true;
2116}
2117
2118
2119bool
2120Helper::SubscriptionWrapper::wrapNextTLSDataVector(const std::string& objID, const int variable, const std::vector<libsumo::TraCINextTLSData>& value) {
2121 auto sl = std::make_shared<TraCINextTLSDataVectorWrapped>();
2122 sl->value = value;
2123 (*myActiveResults)[objID][variable] = sl;
2124 return true;
2125}
2126
2127
2128void
2129Helper::SubscriptionWrapper::empty(const std::string& objID) {
2130 (*myActiveResults)[objID]; // initiate the empty map to track the objectID for TRACI_ID_LIST context subscriptions
2131}
2132
2133
2134void
2135Helper::VehicleStateListener::vehicleStateChanged(const SUMOVehicle* const vehicle, MSNet::VehicleState to, const std::string& /*info*/) {
2136 myVehicleStateChanges[to].push_back(vehicle->getID());
2137}
2138
2139
2140void
2142 myTransportableStateChanges[to].push_back(transportable->getID());
2143}
2144
2145
2146}
2147
2148
2149/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
#define DEG2RAD(x)
Definition GeomHelper.h:35
#define RAD2DEG(x)
Definition GeomHelper.h:36
#define FAR_AWAY
Definition Helper.cpp:72
std::vector< const MSEdge * > ConstMSEdgeVector
Definition MSEdge.h:75
#define LANE_RTREE_QUAL
Definition MSLane.h:1844
#define WRITE_WARNINGF(...)
Definition MsgHandler.h:287
#define TL(string)
Definition MsgHandler.h:304
void checkTimeBounds(const double time)
check the valid SUMOTime range of double input and throw an error if out of bounds
Definition SUMOTime.cpp:188
#define STEPS2TIME(x)
Definition SUMOTime.h:58
#define SPEED2DIST(x)
Definition SUMOTime.h:48
#define SIMSTEP
Definition SUMOTime.h:69
constexpr SUMOTime TIME2STEPS(double x)
Definition SUMOTime.h:60
#define SUMOTime_MAX
Definition SUMOTime.h:34
#define TS
Definition SUMOTime.h:45
#define SIMTIME
Definition SUMOTime.h:70
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
@ SVC_PEDESTRIAN
pedestrian
const int STOP_DURATION_SET
const int STOP_UNTIL_SET
const int STOP_PARKING_SET
std::vector< SUMOVehicleParameter::Stop > StopParVector
const int STOP_START_SET
const int STOP_CONTAINER_TRIGGER_SET
const int STOP_INDEX_FIT
const int STOP_TRIGGER_SET
const int STOP_END_SET
const std::string SUMO_PARAM_ORIGID
SumoXMLTag
Numbers representing SUMO-XML - element names.
@ SUMO_TAG_CHARGING_STATION
A Charging Station.
@ SUMO_TAG_NOTHING
invalid tag, must be the last one
@ SUMO_TAG_CONTAINER_STOP
A container stop.
@ SUMO_TAG_BUS_STOP
A bus stop.
@ SUMO_TAG_PARKING_AREA
A parking area.
@ SUMO_TAG_OVERHEAD_WIRE_SEGMENT
An overhead wire segment.
int gPrecision
the precision for floating point outputs
Definition StdDefs.cpp:27
const double SUMO_const_laneWidth
Definition StdDefs.h:52
T MIN2(T a, T b)
Definition StdDefs.h:80
T MAX2(T a, T b)
Definition StdDefs.h:86
T MAX3(T a, T b, T c)
Definition StdDefs.h:100
std::string toHex(const T i, std::streamsize numDigits=0)
Definition ToString.h:89
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:57
A class that stores a 2D geometrical boundary.
Definition Boundary.h:39
double ymin() const
Returns minimum y-coordinate.
Definition Boundary.cpp:127
double xmin() const
Returns minimum x-coordinate.
Definition Boundary.cpp:115
Boundary & grow(double by)
extends the boundary by the given amount
Definition Boundary.cpp:340
double distanceTo2D(const Position &p) const
returns the euclidean distance in the x-y-plane
Definition Boundary.cpp:262
double getHeight() const
Returns the height of the boundary (y-axis)
Definition Boundary.cpp:157
double getWidth() const
Returns the width of the boudary (x-axis)
Definition Boundary.cpp:151
double ymax() const
Returns maximum y-coordinate.
Definition Boundary.cpp:133
double xmax() const
Returns maximum x-coordinate.
Definition Boundary.cpp:121
static const GeoConvHelper & getFinal()
the coordinate transformation for writing the location element and for tracking the original coordina...
const Boundary & getConvBoundary() const
Returns the converted boundary.
static const double INVALID_OFFSET
a value to signify offsets outside the range of [0, Line.length()]
Definition GeomHelper.h:50
static double naviDegree(const double angle)
static double angleDiff(const double angle1, const double angle2)
Returns the difference of the second angle to the first angle in radiants.
static double getMinAngleDiff(double angle1, double angle2)
Returns the minimum distance (clockwise/counter-clockwise) between both angles.
The base class for microscopic and mesoscopic vehicles.
double getLength() const
Returns the vehicle's length.
const MSVehicleType & getVehicleType() const
Returns the vehicle's type definition.
Calibrates the flow on a segment to a specified one.
const MSLane * getLane() const
AspiredState getCurrentStateInterval() const
static const std::map< std::string, MSCalibrator * > & getInstances()
return all calibrator instances
A simple description of a position on a lane (crossing of a lane)
A detector of vehicles passing an area between entry/exit points.
const CrossSectionVector & getEntries() const
Returns the entry cross sections.
const CrossSectionVector & getExits() const
Returns the exit cross sections.
A road/street connecting two junctions.
Definition MSEdge.h:78
bool isCrossing() const
return whether this edge is a pedestrian crossing
Definition MSEdge.h:275
SVCPermissions getPermissions() const
Returns the combined permissions of all lanes of this edge.
Definition MSEdge.h:659
bool isWalkingArea() const
return whether this edge is walking area
Definition MSEdge.h:289
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition MSEdge.h:169
const MSEdge * getOppositeEdge() const
Returns the opposite direction edge if on exists else a nullptr.
Definition MSEdge.cpp:1423
bool isNormal() const
return whether this edge is an internal edge
Definition MSEdge.h:265
const MSJunction * getToJunction() const
Definition MSEdge.h:428
double getLength() const
return the length of the edge
Definition MSEdge.h:695
const MSJunction * getFromJunction() const
Definition MSEdge.h:424
int getNumLanes() const
Definition MSEdge.h:173
bool isInternal() const
return whether this edge is an internal edge
Definition MSEdge.h:270
static bool dictionary(const std::string &id, MSEdge *edge)
Inserts edge into the static dictionary Returns true if the key id isn't already in the dictionary....
Definition MSEdge.cpp:1117
const MSEdgeVector & getPredecessors() const
Definition MSEdge.h:419
const MSEdge * getInternalFollowingEdge(const MSEdge *followerAfterInternal, SUMOVehicleClass vClass) const
Definition MSEdge.cpp:970
const MSEdgeVector & getSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges, restricted by vClass.
Definition MSEdge.cpp:1342
The base class for an intersection.
Definition MSJunction.h:58
Representation of a lane in the micro simulation.
Definition MSLane.h:84
MSLane * getParallelLane(int offset, bool includeOpposite=true) const
Returns the lane with the given offset parallel to this one or 0 if it does not exist.
Definition MSLane.cpp:2905
std::pair< MSVehicle *const, double > getFollower(const MSVehicle *ego, double egoPos, double dist, MinorLinkMode mLinkMode, bool maxSearchDist=false) const
Find follower vehicle for the given ego vehicle (which may be on the opposite direction lane)
Definition MSLane.cpp:4482
void visit(const MSLane::StoringVisitor &cont) const
Callback for visiting the lane when traversing an RTree.
Definition MSLane.h:1368
static void fill(RTREE &into)
Fills the given RTree with lane instances.
Definition MSLane.cpp:2578
bool isWalkingArea() const
Definition MSLane.cpp:2693
std::set< MSVehicle * > getVehiclesInRange(const double a, const double b) const
Returns all vehicles on the lane overlapping with the interval [a,b].
Definition MSLane.cpp:4386
double getLength() const
Returns the lane's length.
Definition MSLane.h:632
std::vector< const MSLink * > getUpcomingLinks(double pos, double range, const std::vector< MSLane * > &contLanes) const
Returns all upcoming links within given range along the given (non-internal) continuation lanes measu...
Definition MSLane.cpp:4417
std::set< MSVehicle * > getSurroundingVehicles(double startPos, double downstreamDist, double upstreamDist, std::shared_ptr< LaneCoverageInfo > checkedLanes) const
Returns all vehicles closer than downstreamDist along the road network starting on the given position...
Definition MSLane.cpp:4334
bool allowsVehicleClass(SUMOVehicleClass vclass) const
Definition MSLane.h:959
int getIndex() const
Returns the lane's index.
Definition MSLane.h:668
double getOppositePos(double pos) const
return the corresponding position on the opposite lane
Definition MSLane.cpp:4477
MSLane * getLogicalPredecessorLane() const
get the most likely predecessor lane (sorted using by_connections_to_sorter). The result is cached in...
Definition MSLane.cpp:3271
bool isCrossing() const
Definition MSLane.cpp:2681
bool isInternal() const
Definition MSLane.cpp:2669
@ FOLLOW_ALWAYS
Definition MSLane.h:1009
@ FOLLOW_NEVER
Definition MSLane.h:1008
double interpolateGeometryPosToLanePos(double geometryPos) const
Definition MSLane.h:567
std::pair< MSVehicle *const, double > getLeader(const MSVehicle *veh, const double vehPos, const std::vector< MSLane * > &bestLaneConts, double dist=-1, bool checkTmpVehicles=false) const
Returns the immediate leader of veh and the distance to veh starting on this lane.
Definition MSLane.cpp:2974
virtual const VehCont & getVehiclesSecure() const
Returns the vehicles container; locks it for microsimulation.
Definition MSLane.h:484
virtual void releaseVehicles() const
Allows to use the container for microsimulation again.
Definition MSLane.h:514
virtual const PositionVector & getShape(bool) const
Definition MSLane.h:294
MSLane * getParallelOpposite() const
return the opposite direction lane of this lanes edge or nullptr
Definition MSLane.cpp:4471
MSEdge & getEdge() const
Returns the lane's edge.
Definition MSLane.h:790
double getWidth() const
Returns the lane's width.
Definition MSLane.h:661
VehicleState
Definition of a vehicle state.
Definition MSNet.h:636
@ ARRIVED
The vehicle arrived at his destination (is deleted)
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition MSNet.cpp:201
MSTLLogicControl & getTLSControl()
Returns the tls logics control.
Definition MSNet.h:475
MSVehicleRouter & getRouterTT(int rngIndex, const Prohibitions &prohibited={}) const
Definition MSNet.cpp:1659
static bool hasInstance()
Returns whether the network was already constructed.
Definition MSNet.h:158
MSStoppingPlace * getStoppingPlace(const std::string &id, const SumoXMLTag category) const
Returns the named stopping place of the given category.
Definition MSNet.cpp:1527
void addVehicleStateListener(VehicleStateListener *listener)
Adds a vehicle states listener.
Definition MSNet.cpp:1385
void addTransportableStateListener(TransportableStateListener *listener)
Adds a transportable states listener.
Definition MSNet.cpp:1413
TransportableState
Definition of a transportable state.
Definition MSNet.h:713
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition MSNet.h:402
virtual MSTransportableControl & getPersonControl()
Returns the person control.
Definition MSNet.cpp:1317
const NamedObjectCont< MSStoppingPlace * > & getStoppingPlaces(SumoXMLTag category) const
Definition MSNet.cpp:1578
void setRemoteControlled(Position xyPos, MSLane *l, double pos, double posLat, double angle, int edgeOffset, const ConstMSEdgeVector &route, SUMOTime t)
Definition MSPerson.cpp:344
Influencer & getInfluencer()
Returns the velocity/lane influencer.
Definition MSPerson.cpp:319
double getDistanceBetween(double fromPos, double toPos, const MSLane *fromLane, const MSLane *toLane, int routePosition=0) const
Compute the distance between 2 given edges on this route, optionally including the length of internal...
Definition MSRoute.cpp:323
A lane area vehicles can halt at.
double getBeginLanePosition() const
Returns the begin position of this stop.
double getEndLanePosition() const
Returns the end position of this stop.
const MSLane & getLane() const
Returns the lane this stop is located at.
Storage for all programs of a single tls.
TLSLogicVariants & get(const std::string &id) const
Returns the variants of a named tls.
MSTransportable * get(const std::string &id) const
Returns the named transportable, if existing.
void setRemoteControlled(Position xyPos, MSLane *l, double pos, double posLat, double angle, int edgeOffset, const ConstMSEdgeVector &route, SUMOTime t)
SUMOVehicle * getVehicle(const std::string &id) const
Returns the vehicle with the given id.
Representation of a vehicle in the micro simulation.
Definition MSVehicle.h:77
const std::vector< const MSLane * > getUpcomingLanesUntil(double distance) const
Returns the upcoming (best followed by default 0) sequence of lanes to continue the route starting at...
bool isOnRoad() const
Returns the information whether the vehicle is on a road (is simulated)
Definition MSVehicle.h:605
MSAbstractLaneChangeModel & getLaneChangeModel()
const std::vector< MSLane * > & getBestLanesContinuation() const
Returns the best sequence of lanes to continue the route starting at myLane.
const std::vector< const MSLane * > getPastLanesUntil(double distance) const
Returns the sequence of past lanes (right-most on edge) based on the route starting at the current la...
const MSLane * getLane() const
Returns the lane the vehicle is on.
Definition MSVehicle.h:581
Influencer & getInfluencer()
double getLateralPositionOnLane() const
Get the vehicle's lateral position on the lane.
Definition MSVehicle.h:413
double getPositionOnLane() const
Get the vehicle's position along the lane.
Definition MSVehicle.h:374
The car-following model and parameter.
SUMOVehicleClass getVehicleClass() const
Get this vehicle type's vehicle class.
const std::string & getID() const
Returns the name of the vehicle type.
double getLength() const
Get vehicle's length [m].
Allows to store the object; used as context while traveling the rtree in TraCI.
Definition Named.h:89
Base class for objects which have an id.
Definition Named.h:53
static std::string getIDSecure(const T *obj, const std::string &fallBack="NULL")
get an identifier for Named-like object which may be Null
Definition Named.h:66
const std::string & getID() const
Returns the id.
Definition Named.h:73
A point in 2D or 3D with translation and scaling methods.
Definition Position.h:37
void setx(double x)
set position x
Definition Position.h:67
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
Definition Position.h:273
double x() const
Returns the x-position.
Definition Position.h:52
void setz(double z)
set position z
Definition Position.h:77
double z() const
Returns the z-position.
Definition Position.h:62
double angleTo2D(const Position &other) const
returns the angle in the plane of the vector pointing from here to the other position (in radians bet...
Definition Position.h:283
void sety(double y)
set position y
Definition Position.h:72
double y() const
Returns the y-position.
Definition Position.h:57
A list of positions.
void append(const PositionVector &v, double sameThreshold=2.0)
double length() const
Returns the length.
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
double distance2D(const Position &p, bool perpendicular=false) const
closest 2D-distance to point p (or -1 if perpendicular is true and the point is beyond this vector)
void prepend(const PositionVector &v, double sameThreshold=2.0)
double nearest_offset_to_point2D(const Position &p, bool perpendicular=true) const
return the nearest offest to point 2D
std::pair< PositionVector, PositionVector > splitAt(double where, bool use2D=false) const
Returns the two lists made when this list vector is splitted at the given point.
void move2side(double amount, double maxExtension=100)
move position vector to side using certain amount
Boundary getBoxBoundary() const
Returns a boundary enclosing this list of lines.
void extrapolate2D(const double val, const bool onlyFirst=false)
extrapolate position vector in two dimensions (Z is ignored)
double nearest_offset_to_point25D(const Position &p, bool perpendicular=true) const
return the nearest offest to point 2D projected onto the 3D geometry
unsigned char red() const
Returns the red-amount of the color.
Definition RGBColor.cpp:78
unsigned char alpha() const
Returns the alpha-amount of the color.
Definition RGBColor.cpp:96
unsigned char green() const
Returns the green-amount of the color.
Definition RGBColor.cpp:84
unsigned char blue() const
Returns the blue-amount of the color.
Definition RGBColor.cpp:90
virtual bool compute(const E *from, const E *to, const V *const vehicle, SUMOTime msTime, std::vector< const E * > &into, bool silent=false)=0
Builds the route between the given edges using the minimum effort at the given time The definition of...
Representation of a vehicle, person, or container.
virtual bool isVehicle() const
Whether it is a vehicle.
virtual const MSLane * getLane() const =0
Returns the lane the object is currently at.
virtual Position getPosition(const double offset=0) const =0
Return current position (x/y, cartesian)
virtual const MSEdge * getEdge() const =0
Returns the (normal) route edge the object is currently at.
Representation of a vehicle.
Definition SUMOVehicle.h:63
virtual double getAngle() const =0
Get the vehicle's angle.
Definition of vehicle stop (position and duration)
int getFlags() const
return flags as per Vehicle::getStops
SUMOTime started
the time at which this stop was reached
std::string edge
The edge to stop at.
ParkingType parking
whether the vehicle is removed from the net while stopping
std::string lane
The lane to stop at.
double speed
the speed at which this stop counts as reached (waypoint mode)
std::string parkingarea
(Optional) parking area if one is assigned to the stop
std::string split
the id of the vehicle (train portion) that splits of upon reaching this stop
double startPos
The stopping position start.
std::string line
the new line id of the trip within a cyclical public transport route
std::string chargingStation
(Optional) charging station if one is assigned to the stop
std::string overheadWireSegment
(Optional) overhead line segment if one is assigned to the stop
int parametersSet
Information for the output which parameter were set.
int index
at which position in the stops list
std::string join
the id of the vehicle (train portion) to which this vehicle shall be joined
SUMOTime until
The time at which the vehicle may continue its journey.
std::string actType
act Type (only used by Persons) (used by netedit)
bool triggered
whether an arriving person lets the vehicle continue
SUMOTime ended
the time at which this stop was ended
double endPos
The stopping position end.
std::string busstop
(Optional) bus stop if one is assigned to the stop
std::string tripId
id of the trip within a cyclical public transport route
std::string containerstop
(Optional) container stop if one is assigned to the stop
bool containerTriggered
whether an arriving container lets the vehicle continue
SUMOTime arrival
The (expected) time at which the vehicle reaches the stop.
SUMOTime duration
The stopping duration.
const MSEdge * nextEdge
Definition Helper.h:210
const MSEdge * prevEdge
Definition Helper.h:209
bool wrapIntPair(const std::string &objID, const int variable, const std::pair< int, int > &value)
Definition Helper.cpp:2031
bool wrapJunctionFoeVector(const std::string &objID, const int variable, const std::vector< TraCIJunctionFoe > &value)
Definition Helper.cpp:2084
bool wrapDouble(const std::string &objID, const int variable, const double value)
Definition Helper.cpp:1945
void empty(const std::string &objID)
Definition Helper.cpp:2129
bool wrapConnectionVector(const std::string &objID, const int variable, const std::vector< TraCIConnection > &value)
Definition Helper.cpp:1936
bool wrapStringDoublePairList(const std::string &objID, const int variable, const std::vector< std::pair< std::string, double > > &value)
Definition Helper.cpp:2012
bool wrapPositionVector(const std::string &objID, const int variable, const TraCIPositionVector &value)
Definition Helper.cpp:1991
bool wrapLinkVectorVector(const std::string &objID, const int variable, const std::vector< std::vector< TraCILink > > &value)
Definition Helper.cpp:2066
bool wrapSignalConstraintVector(const std::string &objID, const int variable, const std::vector< TraCISignalConstraint > &value)
Definition Helper.cpp:2075
bool wrapColor(const std::string &objID, const int variable, const TraCIColor &value)
Definition Helper.cpp:1998
bool wrapInt(const std::string &objID, const int variable, const int value)
Definition Helper.cpp:1952
bool wrapReservationVector(const std::string &objID, const int variable, const std::vector< TraCIReservation > &value)
Definition Helper.cpp:2048
bool wrapNextTLSDataVector(const std::string &objID, const int variable, const std::vector< TraCINextTLSData > &value)
Definition Helper.cpp:2120
bool wrapBestLanesDataVector(const std::string &objID, const int variable, const std::vector< TraCIBestLanesData > &value)
Definition Helper.cpp:2111
bool wrapStringList(const std::string &objID, const int variable, const std::vector< std::string > &value)
Definition Helper.cpp:1966
bool wrapPosition(const std::string &objID, const int variable, const TraCIPosition &value)
Definition Helper.cpp:1984
bool wrapString(const std::string &objID, const int variable, const std::string &value)
Definition Helper.cpp:1959
bool wrapLogicVector(const std::string &objID, const int variable, const std::vector< TraCILogic > &value)
Definition Helper.cpp:2057
bool wrapNextStopDataVector(const std::string &objID, const int variable, const std::vector< TraCINextStopData > &value)
Definition Helper.cpp:2093
bool wrapStage(const std::string &objID, const int variable, const TraCIStage &value)
Definition Helper.cpp:2041
bool wrapStringPair(const std::string &objID, const int variable, const std::pair< std::string, std::string > &value)
Definition Helper.cpp:2021
bool wrapStringDoublePair(const std::string &objID, const int variable, const std::pair< std::string, double > &value)
Definition Helper.cpp:2005
SubscriptionWrapper(VariableWrapper::SubscriptionHandler handler, SubscriptionResults &into, ContextSubscriptionResults &context)
Definition Helper.cpp:1915
bool wrapVehicleDataVector(const std::string &objID, const int variable, const std::vector< TraCIVehicleData > &value)
Definition Helper.cpp:2102
void setContext(const std::string *const refID)
Definition Helper.cpp:1922
bool wrapDoubleList(const std::string &objID, const int variable, const std::vector< double > &value)
Definition Helper.cpp:1975
void transportableStateChanged(const MSTransportable *const transportable, MSNet::TransportableState to, const std::string &info="")
Called if a transportable changes its state.
Definition Helper.cpp:2141
std::map< MSNet::TransportableState, std::vector< std::string > > myTransportableStateChanges
Changes in the states of simulated transportables.
Definition Helper.h:276
std::map< MSNet::VehicleState, std::vector< std::string > > myVehicleStateChanges
Changes in the states of simulated vehicles.
Definition Helper.h:269
void vehicleStateChanged(const SUMOVehicle *const vehicle, MSNet::VehicleState to, const std::string &info="")
Called if a vehicle changes its state.
Definition Helper.cpp:2135
static Position makePosition(const TraCIPosition &position)
Definition Helper.cpp:403
static MSEdge * getEdge(const std::string &edgeID)
Definition Helper.cpp:409
static double patchShapeDistance(const MSLane *lane, const Position &pos, double dist, bool wasPerpendicular)
return the distance of pos from the area covered by this lane
Definition Helper.cpp:1875
static void cleanup()
Definition Helper.cpp:700
static double getDrivingDistance(std::pair< const MSLane *, double > &roadPos1, std::pair< const MSLane *, double > &roadPos2)
Definition Helper.cpp:472
static void collectObjectsInRange(int domain, const PositionVector &shape, double range, std::set< const Named * > &into)
Definition Helper.cpp:839
static MSCalibrator::AspiredState getCalibratorState(const MSCalibrator *c)
Definition Helper.cpp:749
static TraCIPosition makeTraCIPosition(const Position &position, const bool includeZ=false)
Definition Helper.cpp:393
static LANE_RTREE_QUAL * myLaneTree
A lookup tree of lanes.
Definition Helper.h:295
static void applySubscriptionFilterTurn(const Subscription &s, std::set< const SUMOTrafficObject * > &vehs)
Apply the subscription filter "turn": Gather upcoming junctions and vialanes within downstream distan...
Definition Helper.cpp:1187
static void findObjectShape(int domain, const std::string &id, PositionVector &shape)
Definition Helper.cpp:759
static void clearStateChanges()
Definition Helper.cpp:738
static PositionVector makePositionVector(const TraCIPositionVector &vector)
Definition Helper.cpp:363
static void fuseLaneCoverage(std::shared_ptr< LaneCoverageInfo > aggregatedLaneCoverage, const std::shared_ptr< LaneCoverageInfo > newLaneCoverage)
Adds lane coverage information from newLaneCoverage into aggregatedLaneCoverage.
Definition Helper.cpp:335
static bool moveToXYMap_matchingRoutePosition(const Position &pos, const std::string &origID, const ConstMSEdgeVector &currentRoute, int routeIndex, SUMOVehicleClass vClass, bool setLateralPos, double &bestDistance, MSLane **lane, double &lanePos, int &routeOffset)
Definition Helper.cpp:1759
static void debugPrint(const SUMOTrafficObject *veh)
Definition Helper.cpp:97
static MSPerson * getPerson(const std::string &id)
Definition Helper.cpp:508
static void subscribe(const int commandId, const std::string &id, const std::vector< int > &variables, const double beginTime, const double endTime, const libsumo::TraCIResults &params, const int contextDomain=0, const double range=0.)
Definition Helper.cpp:109
static TraCIPositionVector makeTraCIPositionVector(const PositionVector &positionVector)
helper functions
Definition Helper.cpp:353
static int readDistanceRequest(tcpip::Storage &data, TraCIRoadPosition &roadPos, Position &pos)
Definition Helper.cpp:1884
static const std::vector< std::string > & getTransportableStateChanges(const MSNet::TransportableState state)
Definition Helper.cpp:732
static std::map< int, std::shared_ptr< VariableWrapper > > myWrapper
Map of commandIds -> their executors; applicable if the executor applies to the method footprint.
Definition Helper.h:286
static void clearSubscriptions()
Definition Helper.cpp:222
static MSBaseVehicle * getVehicle(const std::string &id)
Definition Helper.cpp:494
static void applySubscriptionFilterLateralDistanceSinglePass(const Subscription &s, std::set< std::string > &objIDs, std::set< const SUMOTrafficObject * > &vehs, const std::vector< const MSLane * > &lanes, double posOnLane, double posLat, bool isDownstream)
Definition Helper.cpp:1325
static MSStoppingPlace * getStoppingPlace(const std::string &id, const SumoXMLTag type)
Definition Helper.cpp:544
static TraCIColor makeTraCIColor(const RGBColor &color)
Definition Helper.cpp:376
static void applySubscriptionFilterFieldOfVision(const Subscription &s, std::set< std::string > &objIDs)
Definition Helper.cpp:1252
static Subscription * myLastContextSubscription
The last context subscription.
Definition Helper.h:283
static TraCINextStopData buildStopData(const SUMOVehicleParameter::Stop &stopPar)
Definition Helper.cpp:660
static void registerStateListener()
Definition Helper.cpp:717
static TransportableStateListener myTransportableStateListener
Changes in the states of simulated transportables.
Definition Helper.h:292
static void setRemoteControlled(MSVehicle *v, Position xyPos, MSLane *l, double pos, double posLat, double angle, int edgeOffset, ConstMSEdgeVector route, SUMOTime t)
Definition Helper.cpp:1402
static int postProcessRemoteControl()
return number of remote-controlled entities
Definition Helper.cpp:1417
static void applySubscriptionFilters(const Subscription &s, std::set< std::string > &objIDs)
Filter the given ID-Set (which was obtained from an R-Tree search) according to the filters set by th...
Definition Helper.cpp:909
static std::map< std::string, MSVehicle * > myRemoteControlledVehicles
Definition Helper.h:297
static const MSVehicleType & getVehicleType(const std::string &vehicleID)
Definition Helper.cpp:529
static bool moveToXYMap(const Position &pos, double maxRouteDistance, bool mayLeaveNetwork, const std::string &origID, const double angle, double speed, const ConstMSEdgeVector &currentRoute, const int routePosition, const MSLane *currentLane, double currentLanePos, bool onRoad, SUMOVehicleClass vClass, double currentAngle, bool setLateralPos, double &bestDistance, MSLane **lane, double &lanePos, int &routeOffset, ConstMSEdgeVector &edges)
Definition Helper.cpp:1442
static std::pair< MSLane *, double > convertCartesianToRoadMap(const Position &pos, const SUMOVehicleClass vClass)
Definition Helper.cpp:436
static MSTLLogicControl::TLSLogicVariants & getTLS(const std::string &id)
Definition Helper.cpp:535
static SUMOTrafficObject * getTrafficObject(int domain, const std::string &id)
Definition Helper.cpp:518
static VehicleStateListener myVehicleStateListener
Changes in the states of simulated vehicles.
Definition Helper.h:289
static std::vector< Subscription > mySubscriptions
The list of known, still valid subscriptions.
Definition Helper.h:280
static SUMOVehicleParameter::Stop buildStopParameters(const std::string &edgeOrStoppingPlaceID, double pos, int laneIndex, double startPos, int flags, double duration, double until)
Definition Helper.cpp:554
static void handleSingleSubscription(const Subscription &s)
Definition Helper.cpp:251
static void applySubscriptionFilterLateralDistance(const Subscription &s, std::set< const SUMOTrafficObject * > &vehs, double downstreamDist, double upstreamDist, double lateralDist)
Apply the subscription filter "lateral distance": Only return vehicles within the given lateral dista...
Definition Helper.cpp:1291
static const std::vector< std::string > & getVehicleStateChanges(const MSNet::VehicleState state)
Definition Helper.cpp:726
static void collectObjectIDsInRange(int domain, const PositionVector &shape, double range, std::set< std::string > &into)
Definition Helper.cpp:829
static void handleSubscriptions(const SUMOTime t)
Definition Helper.cpp:172
static Subscription * addSubscriptionFilter(SubscriptionFilterType filter)
Definition Helper.cpp:229
static const MSLane * getLaneChecking(const std::string &edgeID, int laneIndex, double pos)
Definition Helper.cpp:419
static RGBColor makeRGBColor(const TraCIColor &color)
Definition Helper.cpp:387
static void applySubscriptionFilterLanes(const Subscription &s, std::set< const SUMOTrafficObject * > &vehs, std::vector< int > &filterLanes, double downstreamDist, double upstreamDist, bool disregardOppositeDirection)
Apply the subscription filter "lanes": Only return vehicles on list of lanes relative to ego vehicle....
Definition Helper.cpp:1089
static std::map< std::string, MSPerson * > myRemoteControlledPersons
Definition Helper.h:298
static bool needNewSubscription(libsumo::Subscription &s, std::vector< Subscription > &subscriptions, libsumo::Subscription *&modifiedSubscription)
Definition Helper.cpp:197
static bool findCloserLane(const MSEdge *edge, const Position &pos, SUMOVehicleClass vClass, double &bestDistance, MSLane **lane)
Definition Helper.cpp:1712
static int readCompound(tcpip::Storage &ret, int expectedSize=-1, const std::string &error="")
static std::shared_ptr< tcpip::Storage > toStorage(const TraCIResult &v)
Representation of a subscription.
double filterUpstreamDist
Upstream distance specified by the upstream distance filter.
int commandId
commandIdArg The command id of the subscription
std::set< std::string > filterVTypes
vTypes specified by the vTypes filter
double filterFieldOfVisionOpeningAngle
Opening angle (in deg) specified by the field of vision filter.
std::vector< int > filterLanes
lanes specified by the lanes filter
std::string id
The id of the object that is subscribed.
SUMOTime endTime
The end time of the subscription.
int contextDomain
The domain ID of the context.
double filterFoeDistToJunction
Foe distance to junction specified by the turn filter.
bool isVehicleToVehicleContextSubscription() const
SUMOTime beginTime
The begin time of the subscription.
std::vector< int > variables
The subscribed variables.
SVCPermissions filterVClasses
vClasses specified by the vClasses filter,
bool isVehicleToPersonContextSubscription() const
double filterDownstreamDist
Downstream distance specified by the downstream distance filter.
double filterLateralDist
Lateral distance specified by the lateral distance filter.
int activeFilters
Active filters for the subscription (bitset,.
double range
The range of the context.
std::vector< std::shared_ptr< tcpip::Storage > > parameters
The parameters for the subscribed variables.
An error which allows to continue.
Definition TraCIDefs.h:145
virtual void empty(const std::string &)
bool(* SubscriptionHandler)(const std::string &objID, const int variable, VariableWrapper *wrapper, tcpip::Storage *paramData)
Definition of a method to be called for serving an associated commandID.
virtual void setContext(const std::string *const)
virtual std::string readString()
Definition storage.cpp:180
virtual int readUnsignedByte()
Definition storage.cpp:155
virtual double readDouble()
Definition storage.cpp:362
TRACI_CONST double INVALID_DOUBLE_VALUE
TRACI_CONST int LAST_STEP_VEHICLE_NUMBER
TRACI_CONST int POSITION_3D
TRACI_CONST int CMD_GET_CHARGINGSTATION_VARIABLE
TRACI_CONST int POSITION_ROADMAP
TRACI_CONST int CMD_SUBSCRIBE_EDGE_CONTEXT
TRACI_CONST int CMD_SUBSCRIBE_LANE_CONTEXT
TRACI_CONST int TRACI_ID_LIST
TRACI_CONST int CMD_GET_PARKINGAREA_VARIABLE
TRACI_CONST int CMD_GET_POI_VARIABLE
TRACI_CONST int CMD_GET_TL_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_VEHICLE_CONTEXT
std::map< std::string, libsumo::SubscriptionResults > ContextSubscriptionResults
Definition TraCIDefs.h:384
TRACI_CONST int CMD_GET_REROUTER_VARIABLE
TRACI_CONST int VAR_ROAD_ID
TRACI_CONST int CMD_GET_VEHICLE_VARIABLE
TRACI_CONST int CMD_GET_EDGE_VARIABLE
TRACI_CONST int CMD_GET_CALIBRATOR_VARIABLE
TRACI_CONST int CMD_GET_PERSON_VARIABLE
TRACI_CONST int CMD_GET_ROUTEPROBE_VARIABLE
TRACI_CONST int CMD_GET_LANEAREA_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_BUSSTOP_CONTEXT
TRACI_CONST int POSITION_2D
TRACI_CONST int CMD_GET_BUSSTOP_VARIABLE
TRACI_CONST int CMD_GET_ROUTE_VARIABLE
TRACI_CONST int CMD_GET_MEANDATA_VARIABLE
TRACI_CONST int CMD_GET_JUNCTION_VARIABLE
std::map< std::string, libsumo::TraCIResults > SubscriptionResults
{object->{variable->value}}
Definition TraCIDefs.h:383
TRACI_CONST int CMD_GET_VARIABLESPEEDSIGN_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_CALIBRATOR_CONTEXT
TRACI_CONST int VAR_LANEPOSITION
TRACI_CONST int CMD_GET_SIM_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_PERSON_CONTEXT
TRACI_CONST int CMD_GET_VEHICLETYPE_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_CHARGINGSTATION_CONTEXT
TRACI_CONST int CMD_SUBSCRIBE_POLYGON_CONTEXT
TRACI_CONST int REQUEST_DRIVINGDIST
TRACI_CONST int CMD_GET_LANE_VARIABLE
TRACI_CONST int CMD_GET_GUI_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_PARKINGAREA_CONTEXT
TRACI_CONST int CMD_GET_POLYGON_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_MULTIENTRYEXIT_CONTEXT
TRACI_CONST int CMD_SUBSCRIBE_VEHICLE_VARIABLE
TRACI_CONST int CMD_GET_MULTIENTRYEXIT_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_INDUCTIONLOOP_CONTEXT
SubscriptionFilterType
Filter types for context subscriptions.
@ SUBS_FILTER_LEAD_FOLLOW
@ SUBS_FILTER_UPSTREAM_DIST
@ SUBS_FILTER_VTYPE
@ SUBS_FILTER_NO_RTREE
@ SUBS_FILTER_LANES
@ SUBS_FILTER_NOOPPOSITE
@ SUBS_FILTER_DOWNSTREAM_DIST
@ SUBS_FILTER_LATERAL_DIST
@ SUBS_FILTER_TURN
@ SUBS_FILTER_VCLASS
@ SUBS_FILTER_MANEUVER
@ SUBS_FILTER_FIELD_OF_VISION
TRACI_CONST int CMD_SUBSCRIBE_LANEAREA_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_POI_CONTEXT
TRACI_CONST int CMD_SUBSCRIBE_INDUCTIONLOOP_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_SIM_CONTEXT
TRACI_CONST int CMD_SUBSCRIBE_MULTIENTRYEXIT_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_LANE_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_PERSON_VARIABLE
TRACI_CONST int CMD_GET_INDUCTIONLOOP_VARIABLE
TRACI_CONST int CMD_GET_OVERHEADWIRE_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_LANEAREA_CONTEXT
TRACI_CONST int CMD_SUBSCRIBE_JUNCTION_CONTEXT
std::map< int, std::shared_ptr< libsumo::TraCIResult > > TraCIResults
{variable->value}
Definition TraCIDefs.h:381
TRACI_CONST int CMD_SUBSCRIBE_EDGE_VARIABLE
A 2D or 3D-position, for 2D positions z == INVALID_DOUBLE_VALUE.
Definition TraCIDefs.h:184
A list of positions.
Definition TraCIDefs.h:245
std::vector< TraCIPosition > value
Definition TraCIDefs.h:255
An edgeId, position and laneIndex.
Definition TraCIDefs.h:206