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-2025 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;
711}
712
713
714void
721
722
723const std::vector<std::string>&
727
728
729const std::vector<std::string>&
733
734
735void
738 i.second.clear();
739 }
741 i.second.clear();
742 }
743}
744
745
748 try {
749 return c->getCurrentStateInterval();
750 } catch (ProcessError& e) {
751 throw TraCIException(e.what());
752 }
753}
754
755
756void
757Helper::findObjectShape(int domain, const std::string& id, PositionVector& shape) {
758 switch (domain) {
761 shape.push_back(stop->getLane().getShape().positionAtOffset(stop->getBeginLanePosition()));
762 shape.push_back(stop->getLane().getShape().positionAtOffset(stop->getEndLanePosition()));
763 break;
764 }
766 MSCalibrator* const calib = Calibrator::getCalibrator(id);
767 shape.push_back(calib->getLane()->getShape()[0]);
768 break;
769 }
772 shape.push_back(stop->getLane().getShape().positionAtOffset(stop->getBeginLanePosition()));
773 shape.push_back(stop->getLane().getShape().positionAtOffset(stop->getEndLanePosition()));
774 break;
775 }
777 Edge::storeShape(id, shape);
778 break;
780 InductionLoop::storeShape(id, shape);
781 break;
783 Junction::storeShape(id, shape);
784 break;
786 Lane::storeShape(id, shape);
787 break;
789 LaneArea::storeShape(id, shape);
790 break;
792 MSE3Collector* const det = MultiEntryExit::getDetector(id);
793 for (const MSCrossSection& cs : det->getEntries()) {
794 shape.push_back(cs.myLane->getShape().positionAtOffset(cs.myPosition));
795 }
796 for (const MSCrossSection& cs : det->getExits()) {
797 shape.push_back(cs.myLane->getShape().positionAtOffset(cs.myPosition));
798 }
799 break;
800 }
803 shape.push_back(stop->getLane().getShape().positionAtOffset(stop->getBeginLanePosition()));
804 shape.push_back(stop->getLane().getShape().positionAtOffset(stop->getEndLanePosition()));
805 break;
806 }
808 Person::storeShape(id, shape);
809 break;
811 POI::storeShape(id, shape);
812 break;
814 Polygon::storeShape(id, shape);
815 break;
817 Vehicle::storeShape(id, shape);
818 break;
819 default:
820 Simulation::storeShape(shape);
821 break;
822 }
823}
824
825
826void
827Helper::collectObjectIDsInRange(int domain, const PositionVector& shape, double range, std::set<std::string>& into) {
828 std::set<const Named*> objects;
829 collectObjectsInRange(domain, shape, range, objects);
830 for (const Named* obj : objects) {
831 into.insert(obj->getID());
832 }
833}
834
835
836void
837Helper::collectObjectsInRange(int domain, const PositionVector& shape, double range, std::set<const Named*>& into) {
838 const Boundary b = shape.getBoxBoundary().grow(range);
839 const float cmin[2] = {(float) b.xmin(), (float) b.ymin()};
840 const float cmax[2] = {(float) b.xmax(), (float) b.ymax()};
841 switch (domain) {
843 for (const auto& stop : MSNet::getInstance()->getStoppingPlaces(SUMO_TAG_BUS_STOP)) {
844 if (shape.distance2D(stop.second->getCenterPos()) <= range) {
845 into.insert(stop.second);
846 }
847 }
848 break;
851 if (shape.distance2D(stop.second->getCenterPos()) <= range) {
852 into.insert(stop.second);
853 }
854 }
855 break;
857 for (const auto& calib : MSCalibrator::getInstances()) {
858 if (shape.distance2D(calib.second->getLane()->getShape()[0]) <= range) {
859 into.insert(calib.second);
860 }
861 }
862 break;
864 InductionLoop::getTree()->Search(cmin, cmax, Named::StoringVisitor(into));
865 break;
867 Junction::getTree()->Search(cmin, cmax, Named::StoringVisitor(into));
868 break;
870 LaneArea::getTree()->Search(cmin, cmax, Named::StoringVisitor(into));
871 break;
873 for (const auto& stop : MSNet::getInstance()->getStoppingPlaces(SUMO_TAG_PARKING_AREA)) {
874 if (shape.distance2D(stop.second->getCenterPos()) <= range) {
875 into.insert(stop.second);
876 }
877 }
878 break;
879 }
881 POI::getTree()->Search(cmin, cmax, Named::StoringVisitor(into));
882 break;
884 Polygon::getTree()->Search(cmin, cmax, Named::StoringVisitor(into));
885 break;
890 if (myLaneTree == nullptr) {
893 }
894 MSLane::StoringVisitor lsv(into, shape, range, domain);
895 myLaneTree->Search(cmin, cmax, lsv);
896 }
897 break;
898 default:
899 throw TraCIException("Infeasible context domain (" + toString(domain) + ")");
900 break;
901 }
902}
903
904
905
906void
907Helper::applySubscriptionFilters(const Subscription& s, std::set<std::string>& objIDs) {
908#ifdef DEBUG_SURROUNDING
909 MSBaseVehicle* _veh = getVehicle(s.id);
910 std::cout << SIMTIME << " applySubscriptionFilters for vehicle '" << _veh->getID() << "' on lane '" << _veh->getLane()->getID() << "'"
911 << "\n on edge '" << _veh->getLane()->getEdge().getID() << "' (" << toString(_veh->getLane()->getEdge().getLanes()) << ")\n"
912 << "objIDs = " << toString(objIDs) << std::endl;
913#endif
914
915 if (s.activeFilters == 0) {
916 // No filters set
917 return;
918 }
919
920 MSVehicle* v = dynamic_cast<MSVehicle*>(getVehicle(s.id));
921
922 // Whether vehicles on opposite lanes shall be taken into account
923 const bool disregardOppositeDirection = (s.activeFilters & SUBS_FILTER_NOOPPOSITE) != 0;
924
925 // Check filter specification consistency
926 if (disregardOppositeDirection && (s.activeFilters & SUBS_FILTER_NO_RTREE) == 0) {
927 WRITE_WARNINGF(TL("Ignoring veh '%' no-opposite subscription filter for geographic range object collection. Consider using the 'lanes' filter."), v->getID())
928 }
929 // TODO: Treat case, where ego vehicle is currently on opposite lane
930
931 std::set<const SUMOTrafficObject*> vehs;
933 // Set defaults for upstream/downstream/lateral distances
934 double downstreamDist = s.range, upstreamDist = s.range, lateralDist = s.range;
936 // Specifies maximal downstream distance for vehicles in context subscription result
937 downstreamDist = s.filterDownstreamDist;
938 }
940 // Specifies maximal downstream distance for vehicles in context subscription result
941 upstreamDist = s.filterUpstreamDist;
942 }
944 // Specifies maximal lateral distance for vehicles in context subscription result
945 lateralDist = s.filterLateralDist;
946 }
947 if (v == nullptr) {
948 throw TraCIException("Subscription filter not yet implemented for meso vehicle");
949 }
950 if (!v->isOnRoad()) {
951 return;
952 }
953 const MSLane* vehLane = v->getLane();
954 if (vehLane == nullptr) {
955 return;
956 }
957 MSEdge* vehEdge = &vehLane->getEdge();
958 std::vector<int> filterLanes;
959 if ((s.activeFilters & SUBS_FILTER_LANES) == 0) {
960 // No lane indices are specified (but downstream and/or upstream distance)
961 // -> use only vehicle's current lane as origin for the searches
962 filterLanes = {0};
963 // Lane indices must be specified when leader/follower information is requested.
964 assert((s.activeFilters & SUBS_FILTER_LEAD_FOLLOW) == 0);
965 } else {
966 filterLanes = s.filterLanes;
967 }
968
969#ifdef DEBUG_SURROUNDING
970 std::cout << "Filter lanes: " << toString(filterLanes) << std::endl;
971 std::cout << "Downstream distance: " << downstreamDist << std::endl;
972 std::cout << "Upstream distance: " << upstreamDist << std::endl;
973 std::cout << "Lateral distance: " << lateralDist << std::endl;
974#endif
975
976 if ((s.activeFilters & SUBS_FILTER_MANEUVER) != 0) {
977 // Maneuver filters disables road net search for all surrounding vehicles
978 if ((s.activeFilters & SUBS_FILTER_LEAD_FOLLOW) != 0) {
979 // Return leader and follower on the specified lanes in context subscription result.
980 for (int offset : filterLanes) {
981 MSLane* lane = v->getLane()->getParallelLane(offset, false);
982 if (lane != nullptr) {
983 // this is a non-opposite lane
984 MSVehicle* leader = lane->getLeader(v, v->getPositionOnLane(), v->getBestLanesContinuation(lane), downstreamDist).first;
985 MSVehicle* follower = lane->getFollower(v, v->getPositionOnLane(), upstreamDist,
987 vehs.insert(vehs.end(), leader);
988 vehs.insert(vehs.end(), follower);
989
990#ifdef DEBUG_SURROUNDING
991 std::cout << "Lane at index " << offset << ": '" << lane->getID() << std::endl;
992 std::cout << "Leader: '" << (leader != nullptr ? leader->getID() : "NULL") << "'" << std::endl;
993 std::cout << "Follower: '" << (follower != nullptr ? follower->getID() : "NULL") << "'" << std::endl;
994#endif
995
996 } else if (!disregardOppositeDirection && offset > 0) { // TODO: offset<0 may indicate opposite query when vehicle is on opposite itself
997 // check whether ix points to an opposite lane
998 const MSEdge* opposite = vehEdge->getOppositeEdge();
999 if (opposite == nullptr) {
1000#ifdef DEBUG_SURROUNDING
1001 std::cout << "No lane at index " << offset << std::endl;
1002#endif
1003 // no opposite edge
1004 continue;
1005 }
1006 // Index of opposite lane at relative offset
1007 const int ix_opposite = (int)opposite->getLanes().size() - 1 - (vehLane->getIndex() + offset - (int)vehEdge->getLanes().size());
1008 if (ix_opposite < 0) {
1009#ifdef DEBUG_SURROUNDING
1010 std::cout << "No lane on opposite at index " << ix_opposite << std::endl;
1011#endif
1012 // no opposite edge
1013 continue;
1014 }
1015 lane = opposite->getLanes()[ix_opposite];
1016 // Search vehs along opposite lanes (swap upstream and downstream distance)
1017 // XXX transformations for curved geometries
1018 double posOnOpposite = MAX2(0., opposite->getLength() - v->getPositionOnLane());
1019 // Get leader on opposite
1020 vehs.insert(vehs.end(), lane->getFollower(v, posOnOpposite, downstreamDist, MSLane::MinorLinkMode::FOLLOW_NEVER).first);
1021 // Get follower (no search on consecutive lanes
1022 vehs.insert(vehs.end(), lane->getLeader(v, posOnOpposite - v->getLength(), std::vector<MSLane*>()).first);
1023 }
1024 }
1025 }
1026
1030 applySubscriptionFilterLanes(s, vehs, filterLanes, downstreamDist, upstreamDist, disregardOppositeDirection);
1031 }
1033 applySubscriptionFilterLateralDistance(s, vehs, downstreamDist, upstreamDist, lateralDist);
1034 }
1035 }
1036#ifdef DEBUG_SURROUNDING
1037 std::cout << SIMTIME << " applySubscriptionFilters() for veh '" << v->getID() << "'. Found the following vehicles:\n";
1038 for (auto veh : vehs) {
1039 debugPrint(veh);
1040 }
1041#endif
1042 } else if (s.activeFilters & SUBS_FILTER_LATERAL_DIST) {
1043 applySubscriptionFilterLateralDistance(s, vehs, downstreamDist, upstreamDist, lateralDist);
1044 } else {
1045 // No maneuver or lateral distance filters requested, but only lanes filter (directly, or indirectly by specifying downstream or upstream distance)
1046 applySubscriptionFilterLanes(s, vehs, filterLanes, downstreamDist, upstreamDist, disregardOppositeDirection);
1047 }
1048 // Write vehs IDs in objIDs
1049 for (const SUMOTrafficObject* veh : vehs) {
1050 if (veh != nullptr) {
1051 objIDs.insert(objIDs.end(), veh->getID());
1052 }
1053 }
1054 }
1055
1057 // Only return vehicles of the given vClass in context subscription result
1058 auto i = objIDs.begin();
1059 while (i != objIDs.end()) {
1060 MSBaseVehicle* veh = getVehicle(*i);
1061 if ((veh->getVehicleType().getVehicleClass() & s.filterVClasses) == 0) {
1062 i = objIDs.erase(i);
1063 } else {
1064 ++i;
1065 }
1066 }
1067 }
1069 // Only return vehicles of the given vType in context subscription result
1070 auto i = objIDs.begin();
1071 while (i != objIDs.end()) {
1072 MSBaseVehicle* veh = getVehicle(*i);
1073 if (s.filterVTypes.find(veh->getVehicleType().getID()) == s.filterVTypes.end()) {
1074 i = objIDs.erase(i);
1075 } else {
1076 ++i;
1077 }
1078 }
1079 }
1081 // Only return vehicles within field of vision in context subscription result
1083 }
1084}
1085
1086void
1087Helper::applySubscriptionFilterLanes(const Subscription& s, std::set<const SUMOTrafficObject*>& vehs, std::vector<int>& filterLanes, double downstreamDist,
1088 double upstreamDist, bool disregardOppositeDirection) {
1090 WRITE_WARNINGF(TL("Lanes filter is only feasible for context domain 'vehicle' (current is '%'), ignoring filter..."), toHex(s.contextDomain, 2));
1091 return;
1092 }
1093 assert(filterLanes.size() > 0);
1094 MSVehicle* v = dynamic_cast<MSVehicle*>(getVehicle(s.id));
1095 const MSLane* vehLane = v->getLane();
1096 MSEdge* vehEdge = &vehLane->getEdge();
1097 // This is to remember the lanes checked in the driving direction of the vehicle (their opposites can be added in a second pass)
1098 auto checkedLanesInDrivingDir = std::make_shared<LaneCoverageInfo>();
1099 for (int offset : filterLanes) {
1100 MSLane* lane = vehLane->getParallelLane(offset, false);
1101 if (lane != nullptr) {
1102#ifdef DEBUG_SURROUNDING
1103 std::cout << "Checking for surrounding vehicles starting on lane '" << lane->getID() << "' at index " << offset << std::endl;
1104#endif
1105 // Search vehs along this lane
1106 // (Coverage info is collected per origin lane since lanes reached from neighboring lanes may have different distances
1107 // and aborting at previously scanned when coming from a closer origin may prevent scanning of parts that should be included.)
1108 std::shared_ptr<LaneCoverageInfo> checkedLanes = std::make_shared<LaneCoverageInfo>();
1109 const std::set<MSVehicle*> new_vehs =
1110 lane->getSurroundingVehicles(v->getPositionOnLane(), downstreamDist, upstreamDist + v->getLength(), checkedLanes);
1111 vehs.insert(new_vehs.begin(), new_vehs.end());
1112 fuseLaneCoverage(checkedLanesInDrivingDir, checkedLanes);
1113 } else if (!disregardOppositeDirection && offset > 0) {
1114 // Check opposite edge, too
1115 assert(vehLane->getIndex() + offset >= (int)vehEdge->getLanes().size()); // index points beyond this edge
1116 const MSEdge* opposite = vehEdge->getOppositeEdge();
1117 if (opposite == nullptr) {
1118#ifdef DEBUG_SURROUNDING
1119 std::cout << "No opposite edge, thus no lane at index " << offset << std::endl;
1120#endif
1121 // no opposite edge
1122 continue;
1123 }
1124 // Index of opposite lane at relative offset
1125 const int ix_opposite = (int)opposite->getLanes().size() - 1 - (vehLane->getIndex() + offset - (int)vehEdge->getLanes().size());
1126 if (ix_opposite < 0) {
1127#ifdef DEBUG_SURROUNDING
1128 std::cout << "No lane on opposite at index " << ix_opposite << std::endl;
1129#endif
1130 // no opposite edge
1131 continue;
1132 }
1133 lane = opposite->getLanes()[ix_opposite];
1134 // Search vehs along opposite lanes (swap upstream and downstream distance)
1135 const std::set<MSVehicle*> new_vehs = lane->getSurroundingVehicles(lane->getLength() - v->getPositionOnLane(), upstreamDist + v->getLength(),
1136 downstreamDist, std::make_shared<LaneCoverageInfo>());
1137 vehs.insert(new_vehs.begin(), new_vehs.end());
1138 }
1139#ifdef DEBUG_SURROUNDING
1140 else {
1141 std::cout << "No lane at index " << offset << std::endl;
1142 }
1143#endif
1144
1145 if (!disregardOppositeDirection) {
1146 // If opposite should be checked, do this for each lane of the search tree in checkedLanesInDrivingDir
1147 // (For instance, some opposite lanes of these would not be obtained if the ego lane does not have an opposite.)
1148
1149 // Number of opposite lanes to be checked (assumes filterLanes.size()>0, see assertion above) determined as hypothetical offset
1150 // overlap into opposing edge from the vehicle's current lane.
1151 // TODO: offset<0 may indicate opposite query when vehicle is on opposite itself (-> use min_element(filterLanes...) instead, etc)
1152 const int nOpp = MAX2(0, (*std::max_element(filterLanes.begin(), filterLanes.end())) - ((int)vehEdge->getLanes().size() - 1 - vehLane->getIndex()));
1153 // Collect vehicles from opposite lanes
1154 if (nOpp > 0) {
1155 for (auto& laneCov : *checkedLanesInDrivingDir) {
1156 const MSLane* const l = laneCov.first;
1157 if (l == nullptr || l->getEdge().getOppositeEdge() == nullptr) {
1158 continue;
1159 }
1160 const MSEdge* opposite = l->getEdge().getOppositeEdge();
1161 const std::pair<double, double>& range = laneCov.second;
1162 auto leftMostOppositeLaneIt = opposite->getLanes().rbegin();
1163 for (auto oppositeLaneIt = leftMostOppositeLaneIt; oppositeLaneIt != opposite->getLanes().rend(); ++oppositeLaneIt) {
1164 if ((int)(oppositeLaneIt - leftMostOppositeLaneIt) == nOpp) {
1165 break;
1166 }
1167 // Add vehicles from corresponding range on opposite direction
1168 const MSLane* oppositeLane = *oppositeLaneIt;
1169 auto new_vehs = oppositeLane->getVehiclesInRange(l->getLength() - range.second, l->getLength() - range.first);
1170 vehs.insert(new_vehs.begin(), new_vehs.end());
1171 }
1172 }
1173 }
1174 }
1175#ifdef DEBUG_SURROUNDING
1176 std::cout << SIMTIME << " applySubscriptionFilterLanes() for veh '" << v->getID() << "', lane offset '" << offset << "'. Found the following vehicles so far:\n";
1177 for (auto veh : vehs) {
1178 debugPrint(veh);
1179 }
1180#endif
1181 }
1182}
1183
1184void
1185Helper::applySubscriptionFilterTurn(const Subscription& s, std::set<const SUMOTrafficObject*>& vehs) {
1187 WRITE_WARNINGF(TL("Turn filter is only feasible for context domain 'vehicle' (current is '%'), ignoring filter..."), toHex(s.contextDomain, 2));
1188 return;
1189 }
1190 // Get upcoming junctions and vialanes within downstream distance, where foe links exist or at least the link direction is not straight
1191 MSVehicle* v = dynamic_cast<MSVehicle*>(getVehicle(s.id));
1192 const MSLane* lane = v->getLane();
1193 std::vector<const MSLink*> links = lane->getUpcomingLinks(v->getPositionOnLane(), s.filterDownstreamDist, v->getBestLanesContinuation());
1194#ifdef DEBUG_SURROUNDING
1195 std::cout << "Applying turn filter for vehicle '" << v->getID() << "'\n Gathering foes ..." << std::endl;
1196#endif
1197 // Iterate through junctions and find approaching foes within foeDistToJunction.
1198 for (auto& l : links) {
1199#ifdef DEBUG_SURROUNDING
1200 std::cout << " On junction '" << l->getJunction()->getID() << "' (no. foe links = " << l->getFoeLinks().size() << "):" << std::endl;
1201#endif
1202 for (auto& foeLane : l->getFoeLanes()) {
1203 if (foeLane->getEdge().isCrossing()) {
1204#ifdef DEBUG_SURROUNDING
1205 std::cout << " skipping crossing foeLane '" << foeLane->getID() << "'" << std::endl;
1206#endif
1207 continue;
1208 }
1209#ifdef DEBUG_SURROUNDING
1210 std::cout << " foeLane '" << foeLane->getID() << "'" << std::endl;
1211#endif
1212 // Check vehicles approaching the entry link corresponding to this lane
1213 const MSLink* foeLink = foeLane->getEntryLink();
1214 for (auto& vi : foeLink->getApproaching()) {
1215 if (vi.second.dist <= s.filterFoeDistToJunction) {
1216#ifdef DEBUG_SURROUNDING
1217 std::cout << " Approaching foeLane entry link '" << vi.first->getID() << "'" << std::endl;
1218#endif
1219 vehs.insert(vehs.end(), dynamic_cast<const MSVehicle*>(vi.first));
1220 }
1221 }
1222 // add vehicles currently on the junction
1223 for (const MSVehicle* foe : foeLane->getVehiclesSecure()) {
1224#ifdef DEBUG_SURROUNDING
1225 std::cout << " On foeLane '" << foe->getID() << "'" << std::endl;
1226#endif
1227 vehs.insert(vehs.end(), foe);
1228 }
1229 foeLane->releaseVehicles();
1230 for (auto& laneInfo : foeLane->getIncomingLanes()) {
1231 const MSLane* foeLanePred = laneInfo.lane;
1232 if (foeLanePred->isInternal()) {
1233#ifdef DEBUG_SURROUNDING
1234 std::cout << " foeLanePred '" << foeLanePred->getID() << "'" << std::endl;
1235#endif
1236 for (const MSVehicle* foe : foeLanePred->getVehiclesSecure()) {
1237#ifdef DEBUG_SURROUNDING
1238 std::cout << " On foeLanePred '" << foe->getID() << "'" << std::endl;
1239#endif
1240 vehs.insert(vehs.end(), foe);
1241 }
1242 foeLanePred->releaseVehicles();
1243 }
1244 }
1245 }
1246 }
1247}
1248
1249void
1250Helper::applySubscriptionFilterFieldOfVision(const Subscription& s, std::set<std::string>& objIDs) {
1252 WRITE_WARNINGF(TL("Field of vision opening angle ('%') should be within interval (0, 360), ignoring filter..."), s.filterFieldOfVisionOpeningAngle);
1253 return;
1254 }
1255
1256 MSBaseVehicle* egoVehicle = getVehicle(s.id);
1257 Position egoPosition = egoVehicle->getPosition();
1258 double openingAngle = DEG2RAD(s.filterFieldOfVisionOpeningAngle);
1259
1260#ifdef DEBUG_SURROUNDING
1261 std::cout << "FOVFILTER: ego direction = " << toString(RAD2DEG(egoVehicle->getAngle())) << " (deg)" << std::endl;
1262#endif
1263
1264 auto i = objIDs.begin();
1265 while (i != objIDs.end()) {
1266 if (s.id.compare(*i) == 0) { // skip if this is the ego vehicle
1267 ++i;
1268 continue;
1269 }
1271 double angleEgoToVeh = egoPosition.angleTo2D(obj->getPosition());
1272 double alpha = GeomHelper::angleDiff(egoVehicle->getAngle(), angleEgoToVeh);
1273
1274#ifdef DEBUG_SURROUNDING
1275 const std::string objType = s.isVehicleToPersonContextSubscription() ? "person" : "veh";
1276 std::cout << "FOVFILTER: " << objType << " '" << *i << "' dist = " << toString(egoPosition.distanceTo2D(obj->getPosition())) << std::endl;
1277 std::cout << "FOVFILTER: " << objType << " '" << *i << "' alpha = " << toString(RAD2DEG(alpha)) << " (deg)" << std::endl;
1278#endif
1279
1280 if (abs(alpha) > openingAngle * 0.5) {
1281 i = objIDs.erase(i);
1282 } else {
1283 ++i;
1284 }
1285 }
1286}
1287
1288void
1289Helper::applySubscriptionFilterLateralDistance(const Subscription& s, std::set<const SUMOTrafficObject*>& vehs, double downstreamDist, double upstreamDist,
1290 double lateralDist) {
1291 // collect all vehicles within maximum range of interest to get an upper bound
1292 PositionVector vehShape;
1293 findObjectShape(s.commandId, s.id, vehShape);
1294 double range = MAX3(downstreamDist, upstreamDist, lateralDist);
1295 std::set<std::string> objIDs;
1296 collectObjectIDsInRange(s.contextDomain, vehShape, range, objIDs);
1297
1298#ifdef DEBUG_SURROUNDING
1299 std::cout << "FILTER_LATERAL_DIST: collected object IDs (range " << range << "):" << std::endl;
1300 for (std::string i : objIDs) {
1301 std::cout << i << std::endl;
1302 }
1303#endif
1304
1305 MSVehicle* v = dynamic_cast<MSVehicle*>(getVehicle(s.id));
1306#ifdef DEBUG_SURROUNDING
1307 std::cout << "FILTER_LATERAL_DIST: myLane is '" << v->getLane()->getID() << "', pos " << v->getPositionOnLane() << std::endl;
1308 std::cout << "FILTER_LATERAL_DIST: opposite lane is '" << v->getLane()->getParallelOpposite()->getID() << "'" << std::endl;
1309#endif
1310 double frontPosOnLane = v->getPositionOnLane();
1311 if (v->getLaneChangeModel().isOpposite()) {
1312 frontPosOnLane = v->getLane()->getOppositePos(frontPosOnLane);
1313 }
1314 // 1st pass: downstream (make sure that the whole length of the vehicle is included in the match)
1315 const double backPosOnLane = MAX2(0.0, frontPosOnLane - v->getVehicleType().getLength());
1316 applySubscriptionFilterLateralDistanceSinglePass(s, objIDs, vehs, v->getUpcomingLanesUntil(downstreamDist), backPosOnLane, v->getLateralPositionOnLane(),
1317 true);
1318 // 2nd pass: upstream
1319 applySubscriptionFilterLateralDistanceSinglePass(s, objIDs, vehs, v->getPastLanesUntil(upstreamDist), frontPosOnLane, v->getLateralPositionOnLane(), false);
1320}
1321
1322void
1324 std::set<const SUMOTrafficObject*>& vehs,
1325 const std::vector<const MSLane*>& lanes, double posOnLane, double posLat, bool isDownstream) {
1326 const double streamDist = isDownstream ? s.filterDownstreamDist : s.filterUpstreamDist;
1327 double distRemaining = streamDist;
1328 bool isFirstLane = true;
1329 PositionVector combinedShape;
1330 for (const MSLane* lane : lanes) {
1331#ifdef DEBUG_SURROUNDING
1332 std::cout << "FILTER_LATERAL_DIST: current lane " << (isDownstream ? "down" : "up") << " is '" << lane->getID() << "', length " << lane->getLength()
1333 << ", pos " << posOnLane << ", distRemaining " << distRemaining << std::endl;
1334#endif
1335 PositionVector laneShape = lane->getShape();
1336 if (isFirstLane) {
1337 isFirstLane = false;
1338 double geometryPos = lane->interpolateLanePosToGeometryPos(posOnLane);
1339 if (geometryPos <= POSITION_EPS) {
1340 if (!isDownstream) {
1341 continue;
1342 }
1343 } else {
1344 if (geometryPos >= laneShape.length() - POSITION_EPS) {
1345 laneShape = isDownstream ? PositionVector() : laneShape;
1346 } else {
1347 auto pair = laneShape.splitAt(geometryPos, false);
1348 laneShape = isDownstream ? pair.second : pair.first;
1349 }
1350 }
1351 }
1352 double laneLength = lane->interpolateGeometryPosToLanePos(laneShape.length());
1353 if (distRemaining - laneLength < 0.) {
1354 double geometryPos = lane->interpolateLanePosToGeometryPos(isDownstream ? distRemaining : laneLength - distRemaining);
1355 if (geometryPos > POSITION_EPS && geometryPos < laneShape.length() - POSITION_EPS) {
1356 auto pair = laneShape.splitAt(geometryPos, false);
1357 laneShape = isDownstream ? pair.first : pair.second;
1358 }
1359 }
1360 distRemaining -= laneLength;
1361 try {
1362 laneShape.move2side(-posLat);
1363 } catch (ProcessError&) {
1364 WRITE_WARNINGF(TL("addSubscriptionFilterLateralDistance could not determine shape of lane '%' with a lateral shift of %."),
1365 lane->getID(), toString(posLat));
1366 }
1367#ifdef DEBUG_SURROUNDING
1368 std::cout << " posLat=" << posLat << " laneShape=" << laneShape << "\n";
1369#endif
1370 if (isDownstream) {
1371 combinedShape.append(laneShape);
1372 } else {
1373 combinedShape.prepend(laneShape);
1374 }
1375 if (distRemaining <= POSITION_EPS) {
1376 break;
1377 }
1378 }
1379#ifdef DEBUG_SURROUNDING
1380 std::cout << " combinedShape=" << combinedShape << "\n";
1381#endif
1382 // check remaining objects' distances to the combined shape
1383 auto i = objIDs.begin();
1384 while (i != objIDs.end()) {
1386 double minPerpendicularDist = combinedShape.distance2D(obj->getPosition(), true);
1387#ifdef DEBUG_SURROUNDING
1388 std::cout << (isDownstream ? "DOWN" : "UP") << " obj " << obj->getID() << " perpendicular dist=" << minPerpendicularDist << " filterLateralDist=" << s.filterLateralDist << "\n";
1389#endif
1390 if ((minPerpendicularDist != GeomHelper::INVALID_OFFSET) && (minPerpendicularDist <= s.filterLateralDist)) {
1391 vehs.insert(obj);
1392 i = objIDs.erase(i);
1393 } else {
1394 ++i;
1395 }
1396 }
1397}
1398
1399void
1400Helper::setRemoteControlled(MSVehicle* v, Position xyPos, MSLane* l, double pos, double posLat, double angle,
1401 int edgeOffset, ConstMSEdgeVector route, SUMOTime t) {
1403 v->getInfluencer().setRemoteControlled(xyPos, l, pos, posLat, angle, edgeOffset, route, t);
1404}
1405
1406void
1407Helper::setRemoteControlled(MSPerson* p, Position xyPos, MSLane* l, double pos, double posLat, double angle,
1408 int edgeOffset, ConstMSEdgeVector route, SUMOTime t) {
1410 p->getInfluencer().setRemoteControlled(xyPos, l, pos, posLat, angle, edgeOffset, route, t);
1411}
1412
1413
1414int
1416 int numControlled = 0;
1417 for (auto& controlled : myRemoteControlledVehicles) {
1418 if (MSNet::getInstance()->getVehicleControl().getVehicle(controlled.first) != nullptr) {
1419 controlled.second->getInfluencer().postProcessRemoteControl(controlled.second);
1420 numControlled++;
1421 } else {
1422 WRITE_WARNINGF(TL("Vehicle '%' was removed though being controlled by TraCI"), controlled.first);
1423 }
1424 }
1426 for (auto& controlled : myRemoteControlledPersons) {
1427 if (MSNet::getInstance()->getPersonControl().get(controlled.first) != nullptr) {
1428 controlled.second->getInfluencer().postProcessRemoteControl(controlled.second);
1429 numControlled++;
1430 } else {
1431 WRITE_WARNINGF(TL("Person '%' was removed though being controlled by TraCI"), controlled.first);
1432 }
1433 }
1435 return numControlled;
1436}
1437
1438
1439bool
1440Helper::moveToXYMap(const Position& pos, double maxRouteDistance, bool mayLeaveNetwork, const std::string& origID, const double angle,
1441 double speed, const ConstMSEdgeVector& currentRoute, const int routePosition, const MSLane* currentLane, double currentLanePos, bool onRoad,
1442 SUMOVehicleClass vClass, double currentAngle, bool setLateralPos,
1443 double& bestDistance, MSLane** lane, double& lanePos, int& routeOffset, ConstMSEdgeVector& edges) {
1444 // collect edges around the vehicle/person
1445#ifdef DEBUG_MOVEXY
1446 std::cout << SIMTIME << " moveToXYMap pos=" << pos << " angle=" << angle << " vClass=" << toString(vClass) << "\n";
1447#endif
1448 const MSEdge* const currentRouteEdge = currentRoute[routePosition];
1449 std::set<const Named*> into;
1450 PositionVector shape;
1451 shape.push_back(pos);
1452 collectObjectsInRange(libsumo::CMD_GET_EDGE_VARIABLE, shape, maxRouteDistance, into);
1453 double maxDist = 0;
1454 std::map<MSLane*, LaneUtility, ComparatorNumericalIdLess> lane2utility;
1455 // compute utility for all candidate edges
1456 for (const Named* namedEdge : into) {
1457 const MSEdge* e = dynamic_cast<const MSEdge*>(namedEdge);
1458 if ((e->getPermissions() & vClass) != vClass) {
1459 continue;
1460 }
1461 const MSEdge* prevEdge = nullptr;
1462 const MSEdge* nextEdge = nullptr;
1463 bool onRoute = false;
1464 bool useCurrentAngle = false;
1465 // the next if/the clause sets "onRoute", "prevEdge", and "nextEdge", depending on
1466 // whether the currently seen edge is an internal one or a normal one
1467 if (e->isWalkingArea() || e->isCrossing()) {
1468 // find current intersection along the route
1469 const MSJunction* junction = e->getFromJunction();
1470 for (int i = routePosition; i < (int)currentRoute.size(); i++) {
1471 const MSEdge* cand = currentRoute[i];
1472 if (cand->getToJunction() == junction) {
1473 prevEdge = cand;
1474 if (i + 1 < (int)currentRoute.size()) {
1475 onRoute = true;
1476 nextEdge = currentRoute[i + 1];
1477 }
1478 break;
1479 }
1480 }
1481 if (!onRoute) {
1482 // search backward
1483 for (int i = routePosition - 1; i >= 0; i--) {
1484 const MSEdge* cand = currentRoute[i];
1485 if (cand->getToJunction() == junction) {
1486 onRoute = true;
1487 prevEdge = cand;
1488 nextEdge = currentRoute[i + 1];
1489 break;
1490 }
1491 }
1492 }
1493 if (prevEdge == nullptr) {
1494 // use arbitrary predecessor
1495 if (e->getPredecessors().size() > 0) {
1496 prevEdge = e->getPredecessors().front();
1497 } else if (e->getSuccessors().size() > 1) {
1498 for (MSEdge* e2 : e->getSuccessors()) {
1499 if (e2 != nextEdge) {
1500 prevEdge = e2;
1501 break;
1502 }
1503 }
1504 }
1505 }
1506 if (nextEdge == nullptr) {
1507 if (e->getSuccessors().size() > 0) {
1508 nextEdge = e->getSuccessors().front();
1509 } else if (e->getPredecessors().size() > 1) {
1510 for (MSEdge* e2 : e->getPredecessors()) {
1511 if (e2 != prevEdge) {
1512 nextEdge = e2;
1513 break;
1514 }
1515 }
1516 }
1517 }
1518#ifdef DEBUG_MOVEXY_ANGLE
1519 std::cout << "walkingarea/crossing:" << e->getID() << " prev:" << Named::getIDSecure(prevEdge) << " next:" << Named::getIDSecure(nextEdge)
1520 << " pred=" << toString(e->getPredecessors()) << " succ=" << toString(e->getSuccessors())
1521 << "\n";
1522#endif
1523 } else if (e->isNormal()) {
1524 // a normal edge
1525 //
1526 // check whether the currently seen edge is in the vehicle's route
1527 // - either the one it's on or one of the next edges
1528 ConstMSEdgeVector::const_iterator searchStart = currentRoute.begin() + routePosition;
1529 if (onRoad && currentLane->getEdge().isInternal()) {
1530 ++searchStart;
1531 }
1532 ConstMSEdgeVector::const_iterator edgePos = std::find(searchStart, currentRoute.end(), e);
1533 onRoute = edgePos != currentRoute.end(); // no? -> onRoute is false
1534 if (edgePos == currentRoute.end() - 1 && currentRouteEdge == e) {
1535 // onRoute is false as well if the vehicle is beyond the edge
1536 onRoute &= currentRouteEdge->getLength() > currentLanePos + SPEED2DIST(speed);
1537 }
1538 // save prior and next edges
1539 prevEdge = e;
1540 nextEdge = !onRoute || edgePos == currentRoute.end() - 1 ? nullptr : *(edgePos + 1);
1541#ifdef DEBUG_MOVEXY_ANGLE
1542 std::cout << "normal:" << e->getID() << " prev:" << Named::getIDSecure(prevEdge) << " next:" << Named::getIDSecure(nextEdge) << "\n";
1543#endif
1544 } else if (e->isInternal()) {
1545 // an internal edge
1546 // get the previous edge
1547 prevEdge = e;
1548 while (prevEdge != nullptr && prevEdge->isInternal()) {
1549 MSLane* l = prevEdge->getLanes()[0];
1551 prevEdge = l == nullptr ? nullptr : &l->getEdge();
1552 }
1553 // check whether the previous edge is on the route (was on the route)
1554 ConstMSEdgeVector::const_iterator prevEdgePos = std::find(currentRoute.begin() + routePosition, currentRoute.end(), prevEdge);
1555 nextEdge = e;
1556 while (nextEdge != nullptr && nextEdge->isInternal()) {
1557 nextEdge = nextEdge->getSuccessors()[0]; // should be only one for an internal edge
1558 }
1559 if (prevEdgePos != currentRoute.end() && (prevEdgePos + 1) != currentRoute.end()) {
1560 onRoute = *(prevEdgePos + 1) == nextEdge;
1561 } else {
1562 // we cannot make use of route information and should make
1563 // use of the current angle if the user did not supply an angle
1564 useCurrentAngle = angle == INVALID_DOUBLE_VALUE;
1565 }
1566#ifdef DEBUG_MOVEXY_ANGLE
1567 std::cout << "internal:" << e->getID() << " prev:" << Named::getIDSecure(prevEdge) << " next:" << Named::getIDSecure(nextEdge) << "\n";
1568#endif
1569 }
1570
1571
1572 // weight the lanes...
1573 const bool perpendicular = false;
1574 for (MSLane* const l : e->getLanes()) {
1575 if (!l->allowsVehicleClass(vClass)) {
1576 continue;
1577 }
1578 if (l->getShape().length() == 0) {
1579 // mapping to shapeless lanes is a bad idea
1580 continue;
1581 }
1582 double langle = 180.;
1583 double dist = FAR_AWAY;
1584 double perpendicularDist = FAR_AWAY;
1585 // add some slack to avoid issues from tiny gaps between consecutive lanes
1586 // except when simulating with high precision where the slack can throw of mapping
1587 const double slack = POSITION_EPS * TS;
1588 PositionVector laneShape = l->getShape();
1589 laneShape.extrapolate2D(slack);
1590 double off = laneShape.nearest_offset_to_point2D(pos, true);
1591 if (off != GeomHelper::INVALID_OFFSET) {
1592 perpendicularDist = laneShape.distance2D(pos, true);
1593 perpendicularDist = patchShapeDistance(l, pos, perpendicularDist, true);
1594 }
1595 off = l->getShape().nearest_offset_to_point2D(pos, perpendicular);
1596 if (off != GeomHelper::INVALID_OFFSET) {
1597 dist = l->getShape().distance2D(pos, perpendicular);
1598 dist = patchShapeDistance(l, pos, dist, perpendicular);
1599 langle = GeomHelper::naviDegree(l->getShape().rotationAtOffset(off));
1600 }
1601 // cannot trust lanePos on walkingArea
1602 bool sameEdge = onRoad && e == &currentLane->getEdge() && currentRouteEdge->getLength() > currentLanePos + SPEED2DIST(speed) && !e->isWalkingArea();
1603 /*
1604 const MSEdge* rNextEdge = nextEdge;
1605 while(rNextEdge==0&&lane->getEdge().getPurpose()==MSEdge::EDGEFUNCTION_INTERNAL) {
1606 MSLane* next = lane->getLinkCont()[0]->getLane();
1607 rNextEdge = next == 0 ? 0 : &next->getEdge();
1608 }
1609 */
1610 double dist2 = dist;
1611 if (mayLeaveNetwork && fabs(dist - perpendicularDist) > slack) {
1612 // ambiguous mapping. Don't trust this
1613 dist2 = FAR_AWAY;
1614 }
1615 const double angle2 = useCurrentAngle ? currentAngle : angle;
1616 const double angleDiff = (angle2 == INVALID_DOUBLE_VALUE || l->getEdge().isWalkingArea() ? 0 : GeomHelper::getMinAngleDiff(angle2, langle));
1617#ifdef DEBUG_MOVEXY_ANGLE
1618 std::cout << std::setprecision(gPrecision)
1619 << " candLane=" << l->getID() << " lAngle=" << langle << " lLength=" << l->getLength()
1620 << " angleDiff=" << angleDiff
1621 << " off=" << off
1622 << " pDist=" << perpendicularDist
1623 << " dist=" << dist
1624 << " dist2=" << dist2
1625 << "\n";
1626 std::cout << l->getID() << " param=" << l->getParameter(SUMO_PARAM_ORIGID, "") << " origID='" << origID << "\n";
1627#endif
1628
1629 bool origIDMatch = l->getParameter(SUMO_PARAM_ORIGID, l->getID()) == origID;
1630 if (origIDMatch && setLateralPos
1631 && perpendicularDist > l->getWidth() / 2) {
1632 origIDMatch = false;
1633 }
1634 lane2utility.emplace(l, LaneUtility(
1635 dist2, perpendicularDist, off, angleDiff,
1636 origIDMatch,
1637 onRoute, sameEdge, prevEdge, nextEdge));
1638 // update scaling value
1639 maxDist = MAX2(maxDist, MIN2(dist, SUMO_const_laneWidth));
1640
1641 }
1642 }
1643
1644 // get the best lane given the previously computed values
1645 double bestValue = 0;
1646 MSLane* bestLane = nullptr;
1647 for (const auto& it : lane2utility) {
1648 MSLane* const l = it.first;
1649 const LaneUtility& u = it.second;
1650 double distN = u.dist > 999 ? -10 : 1. - (u.dist / maxDist);
1651 double angleDiffN = 1. - (u.angleDiff / 180.);
1652 double idN = u.ID ? 1 : 0;
1653 double onRouteN = u.onRoute ? 1 : 0;
1654 double sameEdgeN = u.sameEdge ? MIN2(currentRouteEdge->getLength() / MAX2(NUMERICAL_EPS, speed), (double)1.) : 0;
1655 // distance is more important than angle because the vehicle might be driving in the opposite direction
1656 // 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)
1657 double value = (distN * .5 / TS
1658 + angleDiffN * 0.35 /*.5 */
1659 + idN * 1
1660 + onRouteN * 0.1
1661 + sameEdgeN * 0.1);
1662#ifdef DEBUG_MOVEXY
1663 std::cout << " x; l:" << l->getID() << " d:" << u.dist << " dN:" << distN << " aD:" << angleDiffN <<
1664 " ID:" << idN << " oRN:" << onRouteN << " sEN:" << sameEdgeN << " value:" << value << std::endl;
1665#endif
1666 if (value > bestValue || bestLane == nullptr) {
1667 bestValue = value;
1668 if (u.dist == FAR_AWAY) {
1669 bestLane = nullptr;
1670 } else {
1671 bestLane = l;
1672 }
1673 }
1674 }
1675 // no best lane found, return
1676 if (bestLane == nullptr) {
1677 return false;
1678 }
1679 const LaneUtility& u = lane2utility.find(bestLane)->second;
1680 bestDistance = u.dist;
1681 *lane = bestLane;
1682 lanePos = MAX2(0., MIN2(double((*lane)->getLength() - NUMERICAL_EPS),
1684 bestLane->getShape().nearest_offset_to_point25D(pos, false))));
1685 const MSEdge* prevEdge = u.prevEdge;
1686 if (u.onRoute) {
1687 ConstMSEdgeVector::const_iterator prevEdgePos = std::find(currentRoute.begin(), currentRoute.end(), prevEdge);
1688 routeOffset = (int)std::distance(currentRoute.begin(), prevEdgePos);
1689 //std::cout << SIMTIME << "moveToXYMap currLane=" << currentLane->getID() << " routeOffset=" << routeOffset << " edges=" << toString(edges) << " bestLane=" << bestLane->getID() << " prevEdge=" << prevEdge->getID() << "\n";
1690 } else {
1691 edges.push_back(u.prevEdge);
1692 /*
1693 if(bestLane->getEdge().getPurpose()!=MSEdge::EDGEFUNCTION_INTERNAL) {
1694 edges.push_back(&bestLane->getEdge());
1695 }
1696 */
1697 if (u.nextEdge != nullptr) {
1698 edges.push_back(u.nextEdge);
1699 }
1700 routeOffset = 0;
1701#ifdef DEBUG_MOVEXY_ANGLE
1702 std::cout << SIMTIME << " internal2: lane=" << bestLane->getID() << " prev=" << Named::getIDSecure(u.prevEdge) << " next=" << Named::getIDSecure(u.nextEdge) << "\n";
1703#endif
1704 }
1705 return true;
1706}
1707
1708
1709bool
1710Helper::findCloserLane(const MSEdge* edge, const Position& pos, SUMOVehicleClass vClass, double& bestDistance, MSLane** lane) {
1711 // TODO maybe there is a way to abort this early if the lane already found is good enough but simply
1712 // checking for bestDistance < POSITON_EPS gives ugly order dependencies (#7933), so think twice and profile first
1713 if (edge == nullptr) {
1714 return false;
1715 }
1716 bool newBest = false;
1717 for (MSLane* const candidateLane : edge->getLanes()) {
1718 if (!candidateLane->allowsVehicleClass(vClass)) {
1719 continue;
1720 }
1721 if (candidateLane->getShape().length() == 0) {
1722 // mapping to shapeless lanes is a bad idea
1723 continue;
1724 }
1725 double dist = candidateLane->getShape().distance2D(pos);
1726 dist = patchShapeDistance(candidateLane, pos, dist, false);
1727#ifdef DEBUG_MOVEXY
1728 std::cout << " b at lane " << candidateLane->getID() << " dist:" << dist << " best:" << bestDistance << std::endl;
1729#endif
1730 if (dist < bestDistance || (dist == bestDistance && candidateLane->getNumericalID() < (*lane)->getNumericalID())) {
1731 // is the new distance the best one? keep then...
1732 bestDistance = dist;
1733 *lane = candidateLane;
1734 newBest = true;
1735 }
1736 }
1737 if (edge->isInternal() && edge->getNumLanes() > 1) {
1738 // there is a parallel internal edge that isn't returned by getInternalFollowingEdge but is also usable for the same route
1739 for (const MSLane* const l : edge->getLanes()) {
1740 if (l->getIndex() == 0) {
1741 continue;
1742 }
1743 for (const MSLink* const link : l->getLinkCont()) {
1744 if (link->isInternalJunctionLink()) {
1745 if (findCloserLane(&link->getViaLane()->getEdge(), pos, vClass, bestDistance, lane)) {
1746 newBest = true;
1747 }
1748 }
1749 }
1750 }
1751 }
1752 return newBest;
1753}
1754
1755
1756bool
1757Helper::moveToXYMap_matchingRoutePosition(const Position& pos, const std::string& origID,
1758 const ConstMSEdgeVector& currentRoute, int routeIndex,
1759 SUMOVehicleClass vClass, bool setLateralPos,
1760 double& bestDistance, MSLane** lane, double& lanePos, int& routeOffset) {
1761#ifdef DEBUG_MOVEXY
1762 std::cout << SIMTIME << " moveToXYMap_matchingRoutePosition pos=" << pos << " vClass=" << toString(vClass) << "\n";
1763#endif
1764 //std::cout << "moveToXYMap_matchingRoutePosition pos=" << pos << "\n";
1765 routeOffset = 0;
1766 // routes may be looped which makes routeOffset ambiguous. We first try to
1767 // find the closest upcoming edge on the route and then look for closer passed edges
1768
1769 // look forward along the route
1770 const MSEdge* prev = nullptr;
1771 for (int i = routeIndex; i < (int)currentRoute.size(); ++i) {
1772 const MSEdge* cand = currentRoute[i];
1773 while (prev != nullptr) {
1774 // check internal edge(s)
1775 const MSEdge* internalCand = prev->getInternalFollowingEdge(cand, vClass);
1776#ifdef DEBUG_MOVEXY
1777 std::cout << SIMTIME << " prev=" << Named::getIDSecure(prev) << " cand=" << Named::getIDSecure(cand) << " internal=" << Named::getIDSecure(internalCand) << "\n";
1778#endif
1779 if (findCloserLane(internalCand, pos, vClass, bestDistance, lane)) {
1780 routeOffset = i - 1;
1781 }
1782 prev = internalCand;
1783 }
1784 if (findCloserLane(cand, pos, vClass, bestDistance, lane)) {
1785 routeOffset = i;
1786 }
1787 prev = cand;
1788 }
1789 // look backward along the route
1790 const MSEdge* next = currentRoute[routeIndex];
1791 for (int i = routeIndex; i >= 0; --i) {
1792 const MSEdge* cand = currentRoute[i];
1793 //std::cout << " next=" << next->getID() << " cand=" << cand->getID() << " i=" << i << " routeIndex=" << routeIndex << "\n";
1794 prev = cand;
1795 while (prev != nullptr) {
1796 // check internal edge(s)
1797 const MSEdge* internalCand = prev->getInternalFollowingEdge(next, vClass);
1798 if (findCloserLane(internalCand, pos, vClass, bestDistance, lane)) {
1799 routeOffset = i;
1800 }
1801 prev = internalCand;
1802 }
1803 if (findCloserLane(cand, pos, vClass, bestDistance, lane)) {
1804 routeOffset = i;
1805 }
1806 next = cand;
1807 }
1808 if (vClass == SVC_PEDESTRIAN) {
1809 // consider all crossings and walkingareas along the route
1810 std::map<const MSJunction*, int> routeJunctions;
1811 for (int i = 0; i < (int)currentRoute.size() - 1; ++i) {
1812 routeJunctions[currentRoute[i]->getToJunction()] = i;
1813 }
1814 std::set<const Named*> into;
1815 PositionVector shape;
1816 shape.push_back(pos);
1818 for (const Named* named : into) {
1819 const MSLane* cand = dynamic_cast<const MSLane*>(named);
1820 if ((cand->getEdge().isWalkingArea() || cand->getEdge().isCrossing())
1821 && routeJunctions.count(cand->getEdge().getToJunction()) != 0) {
1822 if (findCloserLane(&cand->getEdge(), pos, vClass, bestDistance, lane)) {
1823 routeOffset = routeJunctions[cand->getEdge().getToJunction()];
1824 }
1825 }
1826 }
1827 }
1828
1829 assert(lane != nullptr);
1830 // quit if no solution was found, reporting a failure
1831 if (lane == nullptr) {
1832#ifdef DEBUG_MOVEXY
1833 std::cout << " b failed - no best route lane" << std::endl;
1834#endif
1835 return false;
1836 }
1837
1838
1839 // position may be inaccurate; let's check the given index, too
1840 // @note: this is enabled for non-internal lanes only, as otherwise the position information may ambiguous
1841 if (!(*lane)->getEdge().isInternal()) {
1842 const std::vector<MSLane*>& lanes = (*lane)->getEdge().getLanes();
1843 for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
1844 if ((*i)->getParameter(SUMO_PARAM_ORIGID, (*i)->getID()) == origID) {
1845 if (setLateralPos) {
1846 // vehicle might end up on top of another lane with a big
1847 // lateral offset to the lane with origID.
1848 const double dist = (*i)->getShape().distance2D(pos); // get distance
1849 if (dist < (*i)->getWidth() / 2) {
1850 *lane = *i;
1851 break;
1852 }
1853 } else {
1854 *lane = *i;
1855 break;
1856 }
1857 }
1858 }
1859 }
1860 // check position, stuff, we should have the best lane along the route
1861 lanePos = MAX2(0., MIN2(double((*lane)->getLength() - NUMERICAL_EPS),
1862 (*lane)->interpolateGeometryPosToLanePos(
1863 (*lane)->getShape().nearest_offset_to_point25D(pos, false))));
1864 //std::cout << SIMTIME << " moveToXYMap_matchingRoutePosition vehicle=" << veh.getID() << " currLane=" << veh.getLane()->getID() << " routeOffset=" << routeOffset << " edges=" << toString(edges) << " lane=" << (*lane)->getID() << "\n";
1865#ifdef DEBUG_MOVEXY
1866 std::cout << " b ok lane " << (*lane)->getID() << " lanePos:" << lanePos << std::endl;
1867#endif
1868 return true;
1869}
1870
1871
1872double
1873Helper::patchShapeDistance(const MSLane* lane, const Position& pos, double dist, bool wasPerpendicular) {
1874 if (!lane->isWalkingArea() && (wasPerpendicular || lane->getShape().nearest_offset_to_point25D(pos, true) != GeomHelper::INVALID_OFFSET)) {
1875 dist = MAX2(0.0, dist - lane->getWidth() * 0.5);
1876 }
1877 return dist;
1878}
1879
1880
1881int
1883 int distType = 0;
1884 StoHelp::readCompound(data, 2, "Retrieval of distance requires two parameter as compound.");
1885 const int posType = data.readUnsignedByte();
1886 switch (posType) {
1888 roadPos.edgeID = data.readString();
1889 roadPos.pos = data.readDouble();
1890 roadPos.laneIndex = data.readUnsignedByte();
1891 break;
1892 }
1894 case libsumo::POSITION_3D: {
1895 pos.setx(data.readDouble());
1896 pos.sety(data.readDouble());
1897 if (posType == libsumo::POSITION_3D) {
1898 pos.setz(data.readDouble());
1899 }
1900 break;
1901 }
1902 default:
1903 throw TraCIException("Unknown position format used for distance request.");
1904 }
1905 distType = data.readUnsignedByte();
1906 if (distType != libsumo::REQUEST_DRIVINGDIST) {
1907 throw TraCIException("Only driving distance is supported.");
1908 }
1909 return posType;
1910}
1911
1912
1914 : VariableWrapper(handler), myResults(into), myContextResults(context), myActiveResults(&into) {
1915
1916}
1917
1918
1919void
1920Helper::SubscriptionWrapper::setContext(const std::string* const refID) {
1921 myActiveResults = refID == nullptr ? &myResults : &myContextResults[*refID];
1922}
1923
1924
1925void
1927 myActiveResults = &myResults;
1928 myResults.clear();
1929 myContextResults.clear();
1930}
1931
1932
1933bool
1934Helper::SubscriptionWrapper::wrapConnectionVector(const std::string& objID, const int variable, const std::vector<TraCIConnection>& value) {
1935 auto sl = std::make_shared<TraCIConnectionVectorWrapped>();
1936 sl->value = value;
1937 (*myActiveResults)[objID][variable] = sl;
1938 return true;
1939}
1940
1941
1942bool
1943Helper::SubscriptionWrapper::wrapDouble(const std::string& objID, const int variable, const double value) {
1944 (*myActiveResults)[objID][variable] = std::make_shared<TraCIDouble>(value);
1945 return true;
1946}
1947
1948
1949bool
1950Helper::SubscriptionWrapper::wrapInt(const std::string& objID, const int variable, const int value) {
1951 (*myActiveResults)[objID][variable] = std::make_shared<TraCIInt>(value);
1952 return true;
1953}
1954
1955
1956bool
1957Helper::SubscriptionWrapper::wrapString(const std::string& objID, const int variable, const std::string& value) {
1958 (*myActiveResults)[objID][variable] = std::make_shared<TraCIString>(value);
1959 return true;
1960}
1961
1962
1963bool
1964Helper::SubscriptionWrapper::wrapStringList(const std::string& objID, const int variable, const std::vector<std::string>& value) {
1965 auto sl = std::make_shared<TraCIStringList>();
1966 sl->value = value;
1967 (*myActiveResults)[objID][variable] = sl;
1968 return true;
1969}
1970
1971
1972bool
1973Helper::SubscriptionWrapper::wrapDoubleList(const std::string& objID, const int variable, const std::vector<double>& value) {
1974 auto sl = std::make_shared<TraCIDoubleList>();
1975 sl->value = value;
1976 (*myActiveResults)[objID][variable] = sl;
1977 return true;
1978}
1979
1980
1981bool
1982Helper::SubscriptionWrapper::wrapPosition(const std::string& objID, const int variable, const TraCIPosition& value) {
1983 (*myActiveResults)[objID][variable] = std::make_shared<TraCIPosition>(value);
1984 return true;
1985}
1986
1987
1988bool
1989Helper::SubscriptionWrapper::wrapPositionVector(const std::string& objID, const int variable, const TraCIPositionVector& value) {
1990 (*myActiveResults)[objID][variable] = std::make_shared<TraCIPositionVector>(value);
1991 return true;
1992}
1993
1994
1995bool
1996Helper::SubscriptionWrapper::wrapColor(const std::string& objID, const int variable, const TraCIColor& value) {
1997 (*myActiveResults)[objID][variable] = std::make_shared<TraCIColor>(value);
1998 return true;
1999}
2000
2001
2002bool
2003Helper::SubscriptionWrapper::wrapStringDoublePair(const std::string& objID, const int variable, const std::pair<std::string, double>& value) {
2004 (*myActiveResults)[objID][variable] = std::make_shared<TraCIRoadPosition>(value.first, value.second);
2005 return true;
2006}
2007
2008
2009bool
2010Helper::SubscriptionWrapper::wrapStringDoublePairList(const std::string& objID, const int variable, const std::vector<std::pair<std::string, double> >& value) {
2011 auto sl = std::make_shared<TraCIStringDoublePairList>();
2012 sl->value = value;
2013 (*myActiveResults)[objID][variable] = sl;
2014 return true;
2015}
2016
2017
2018bool
2019Helper::SubscriptionWrapper::wrapStringPair(const std::string& objID, const int variable, const std::pair<std::string, std::string>& value) {
2020 auto sl = std::make_shared<TraCIStringList>();
2021 sl->value.push_back(value.first);
2022 sl->value.push_back(value.second);
2023 (*myActiveResults)[objID][variable] = sl;
2024 return true;
2025}
2026
2027
2028bool
2029Helper::SubscriptionWrapper::wrapIntPair(const std::string& objID, const int variable, const std::pair<int, int>& value) {
2030 auto sl = std::make_shared<TraCIIntList>();
2031 sl->value.push_back(value.first);
2032 sl->value.push_back(value.second);
2033 (*myActiveResults)[objID][variable] = sl;
2034 return true;
2035}
2036
2037
2038bool
2039Helper::SubscriptionWrapper::wrapStage(const std::string& objID, const int variable, const TraCIStage& value) {
2040 (*myActiveResults)[objID][variable] = std::make_shared<TraCIStage>(value);
2041 return true;
2042}
2043
2044
2045bool
2046Helper::SubscriptionWrapper::wrapReservationVector(const std::string& objID, const int variable, const std::vector<libsumo::TraCIReservation>& value) {
2047 auto sl = std::make_shared<TraCIReservationVectorWrapped>();
2048 sl->value = value;
2049 (*myActiveResults)[objID][variable] = sl;
2050 return true;
2051}
2052
2053
2054bool
2055Helper::SubscriptionWrapper::wrapLogicVector(const std::string& objID, const int variable, const std::vector<libsumo::TraCILogic>& value) {
2056 auto sl = std::make_shared<TraCILogicVectorWrapped>();
2057 sl->value = value;
2058 (*myActiveResults)[objID][variable] = sl;
2059 return true;
2060}
2061
2062
2063bool
2064Helper::SubscriptionWrapper::wrapLinkVectorVector(const std::string& objID, const int variable, const std::vector<std::vector<libsumo::TraCILink> >& value) {
2065 auto sl = std::make_shared<TraCILinkVectorVectorWrapped>();
2066 sl->value = value;
2067 (*myActiveResults)[objID][variable] = sl;
2068 return true;
2069}
2070
2071
2072bool
2073Helper::SubscriptionWrapper::wrapSignalConstraintVector(const std::string& objID, const int variable, const std::vector<libsumo::TraCISignalConstraint>& value) {
2074 auto sl = std::make_shared<TraCISignalConstraintVectorWrapped>();
2075 sl->value = value;
2076 (*myActiveResults)[objID][variable] = sl;
2077 return true;
2078}
2079
2080
2081bool
2082Helper::SubscriptionWrapper::wrapJunctionFoeVector(const std::string& objID, const int variable, const std::vector<libsumo::TraCIJunctionFoe>& value) {
2083 auto sl = std::make_shared<TraCIJunctionFoeVectorWrapped>();
2084 sl->value = value;
2085 (*myActiveResults)[objID][variable] = sl;
2086 return true;
2087}
2088
2089
2090bool
2091Helper::SubscriptionWrapper::wrapNextStopDataVector(const std::string& objID, const int variable, const std::vector<libsumo::TraCINextStopData>& value) {
2092 auto sl = std::make_shared<TraCINextStopDataVectorWrapped>();
2093 sl->value = value;
2094 (*myActiveResults)[objID][variable] = sl;
2095 return true;
2096}
2097
2098
2099bool
2100Helper::SubscriptionWrapper::wrapVehicleDataVector(const std::string& objID, const int variable, const std::vector<libsumo::TraCIVehicleData>& value) {
2101 auto sl = std::make_shared<TraCIVehicleDataVectorWrapped>();
2102 sl->value = value;
2103 (*myActiveResults)[objID][variable] = sl;
2104 return true;
2105}
2106
2107
2108bool
2109Helper::SubscriptionWrapper::wrapBestLanesDataVector(const std::string& objID, const int variable, const std::vector<libsumo::TraCIBestLanesData>& value) {
2110 auto sl = std::make_shared<TraCIBestLanesDataVectorWrapped>();
2111 sl->value = value;
2112 (*myActiveResults)[objID][variable] = sl;
2113 return true;
2114}
2115
2116
2117bool
2118Helper::SubscriptionWrapper::wrapNextTLSDataVector(const std::string& objID, const int variable, const std::vector<libsumo::TraCINextTLSData>& value) {
2119 auto sl = std::make_shared<TraCINextTLSDataVectorWrapped>();
2120 sl->value = value;
2121 (*myActiveResults)[objID][variable] = sl;
2122 return true;
2123}
2124
2125
2126void
2127Helper::SubscriptionWrapper::empty(const std::string& objID) {
2128 (*myActiveResults)[objID]; // initiate the empty map to track the objectID for TRACI_ID_LIST context subscriptions
2129}
2130
2131
2132void
2133Helper::VehicleStateListener::vehicleStateChanged(const SUMOVehicle* const vehicle, MSNet::VehicleState to, const std::string& /*info*/) {
2134 myVehicleStateChanges[to].push_back(vehicle->getID());
2135}
2136
2137
2138void
2140 myTransportableStateChanges[to].push_back(transportable->getID());
2141}
2142
2143
2144}
2145
2146
2147/****************************************************************************/
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:74
#define LANE_RTREE_QUAL
Definition MSLane.h:1809
#define WRITE_WARNINGF(...)
Definition MsgHandler.h:288
#define TL(string)
Definition MsgHandler.h:305
void checkTimeBounds(const double time)
check the valid SUMOTime range of double input and throw an error if out of bounds
Definition SUMOTime.cpp:173
#define STEPS2TIME(x)
Definition SUMOTime.h:55
#define SPEED2DIST(x)
Definition SUMOTime.h:45
#define SIMSTEP
Definition SUMOTime.h:61
#define SUMOTime_MAX
Definition SUMOTime.h:34
#define TS
Definition SUMOTime.h:42
#define SIMTIME
Definition SUMOTime.h:62
#define TIME2STEPS(x)
Definition SUMOTime.h:57
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:26
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:56
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:46
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:77
bool isCrossing() const
return whether this edge is a pedestrian crossing
Definition MSEdge.h:273
SVCPermissions getPermissions() const
Returns the combined permissions of all lanes of this edge.
Definition MSEdge.h:649
bool isWalkingArea() const
return whether this edge is walking area
Definition MSEdge.h:287
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition MSEdge.h:168
const MSEdge * getOppositeEdge() const
Returns the opposite direction edge if on exists else a nullptr.
Definition MSEdge.cpp:1346
bool isNormal() const
return whether this edge is an internal edge
Definition MSEdge.h:263
const MSJunction * getToJunction() const
Definition MSEdge.h:418
double getLength() const
return the length of the edge
Definition MSEdge.h:685
const MSJunction * getFromJunction() const
Definition MSEdge.h:414
int getNumLanes() const
Definition MSEdge.h:172
bool isInternal() const
return whether this edge is an internal edge
Definition MSEdge.h:268
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:1053
const MSEdgeVector & getPredecessors() const
Definition MSEdge.h:409
const MSEdge * getInternalFollowingEdge(const MSEdge *followerAfterInternal, SUMOVehicleClass vClass) const
Definition MSEdge.cpp:906
const MSEdgeVector & getSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges, restricted by vClass.
Definition MSEdge.cpp:1264
The base class for an intersection.
Definition MSJunction.h:58
Representation of a lane in the micro simulation.
Definition MSLane.h:84
std::pair< MSVehicle *const, double > getFollower(const MSVehicle *ego, double egoPos, double dist, MinorLinkMode mLinkMode) const
Find follower vehicle for the given ego vehicle (which may be on the opposite direction lane)
Definition MSLane.cpp:4389
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:2839
void visit(const MSLane::StoringVisitor &cont) const
Callback for visiting the lane when traversing an RTree.
Definition MSLane.h:1339
static void fill(RTREE &into)
Fills the given RTree with lane instances.
Definition MSLane.cpp:2518
bool isWalkingArea() const
Definition MSLane.cpp:2626
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:4293
double getLength() const
Returns the lane's length.
Definition MSLane.h:611
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:4324
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:4241
bool allowsVehicleClass(SUMOVehicleClass vclass) const
Definition MSLane.h:930
int getIndex() const
Returns the lane's index.
Definition MSLane.h:647
double getOppositePos(double pos) const
return the corresponding position on the opposite lane
Definition MSLane.cpp:4384
MSLane * getLogicalPredecessorLane() const
get the most likely precedecessor lane (sorted using by_connections_to_sorter). The result is cached ...
Definition MSLane.cpp:3205
bool isInternal() const
Definition MSLane.cpp:2609
@ FOLLOW_ALWAYS
Definition MSLane.h:980
@ FOLLOW_NEVER
Definition MSLane.h:979
double interpolateGeometryPosToLanePos(double geometryPos) const
Definition MSLane.h:566
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:2908
virtual const VehCont & getVehiclesSecure() const
Returns the vehicles container; locks it for microsimulation.
Definition MSLane.h:483
virtual void releaseVehicles() const
Allows to use the container for microsimulation again.
Definition MSLane.h:513
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:4378
MSEdge & getEdge() const
Returns the lane's edge.
Definition MSLane.h:769
double getWidth() const
Returns the lane's width.
Definition MSLane.h:640
VehicleState
Definition of a vehicle state.
Definition MSNet.h:614
@ 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:186
MSTLLogicControl & getTLSControl()
Returns the tls logics control.
Definition MSNet.h:457
MSVehicleRouter & getRouterTT(int rngIndex, const Prohibitions &prohibited={}) const
Definition MSNet.cpp:1530
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:1403
void addVehicleStateListener(VehicleStateListener *listener)
Adds a vehicle states listener.
Definition MSNet.cpp:1268
void addTransportableStateListener(TransportableStateListener *listener)
Adds a transportable states listener.
Definition MSNet.cpp:1296
TransportableState
Definition of a transportable state.
Definition MSNet.h:691
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition MSNet.h:384
virtual MSTransportableControl & getPersonControl()
Returns the person control.
Definition MSNet.cpp:1200
const NamedObjectCont< MSStoppingPlace * > & getStoppingPlaces(SumoXMLTag category) const
Definition MSNet.cpp:1438
void setRemoteControlled(Position xyPos, MSLane *l, double pos, double posLat, double angle, int edgeOffset, const ConstMSEdgeVector &route, SUMOTime t)
Definition MSPerson.cpp:316
Influencer & getInfluencer()
Returns the velocity/lane influencer.
Definition MSPerson.cpp:291
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:311
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:90
Base class for objects which have an id.
Definition Named.h:54
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:67
const std::string & getID() const
Returns the id.
Definition Named.h:74
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:74
unsigned char alpha() const
Returns the alpha-amount of the color.
Definition RGBColor.cpp:92
unsigned char green() const
Returns the green-amount of the color.
Definition RGBColor.cpp:80
unsigned char blue() const
Returns the blue-amount of the color.
Definition RGBColor.cpp:86
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 edge the object is currently at.
Representation of a vehicle.
Definition SUMOVehicle.h:62
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:2029
bool wrapJunctionFoeVector(const std::string &objID, const int variable, const std::vector< TraCIJunctionFoe > &value)
Definition Helper.cpp:2082
bool wrapDouble(const std::string &objID, const int variable, const double value)
Definition Helper.cpp:1943
void empty(const std::string &objID)
Definition Helper.cpp:2127
bool wrapConnectionVector(const std::string &objID, const int variable, const std::vector< TraCIConnection > &value)
Definition Helper.cpp:1934
bool wrapStringDoublePairList(const std::string &objID, const int variable, const std::vector< std::pair< std::string, double > > &value)
Definition Helper.cpp:2010
bool wrapPositionVector(const std::string &objID, const int variable, const TraCIPositionVector &value)
Definition Helper.cpp:1989
bool wrapLinkVectorVector(const std::string &objID, const int variable, const std::vector< std::vector< TraCILink > > &value)
Definition Helper.cpp:2064
bool wrapSignalConstraintVector(const std::string &objID, const int variable, const std::vector< TraCISignalConstraint > &value)
Definition Helper.cpp:2073
bool wrapColor(const std::string &objID, const int variable, const TraCIColor &value)
Definition Helper.cpp:1996
bool wrapInt(const std::string &objID, const int variable, const int value)
Definition Helper.cpp:1950
bool wrapReservationVector(const std::string &objID, const int variable, const std::vector< TraCIReservation > &value)
Definition Helper.cpp:2046
bool wrapNextTLSDataVector(const std::string &objID, const int variable, const std::vector< TraCINextTLSData > &value)
Definition Helper.cpp:2118
bool wrapBestLanesDataVector(const std::string &objID, const int variable, const std::vector< TraCIBestLanesData > &value)
Definition Helper.cpp:2109
bool wrapStringList(const std::string &objID, const int variable, const std::vector< std::string > &value)
Definition Helper.cpp:1964
bool wrapPosition(const std::string &objID, const int variable, const TraCIPosition &value)
Definition Helper.cpp:1982
bool wrapString(const std::string &objID, const int variable, const std::string &value)
Definition Helper.cpp:1957
bool wrapLogicVector(const std::string &objID, const int variable, const std::vector< TraCILogic > &value)
Definition Helper.cpp:2055
bool wrapNextStopDataVector(const std::string &objID, const int variable, const std::vector< TraCINextStopData > &value)
Definition Helper.cpp:2091
bool wrapStage(const std::string &objID, const int variable, const TraCIStage &value)
Definition Helper.cpp:2039
bool wrapStringPair(const std::string &objID, const int variable, const std::pair< std::string, std::string > &value)
Definition Helper.cpp:2019
bool wrapStringDoublePair(const std::string &objID, const int variable, const std::pair< std::string, double > &value)
Definition Helper.cpp:2003
SubscriptionWrapper(VariableWrapper::SubscriptionHandler handler, SubscriptionResults &into, ContextSubscriptionResults &context)
Definition Helper.cpp:1913
bool wrapVehicleDataVector(const std::string &objID, const int variable, const std::vector< TraCIVehicleData > &value)
Definition Helper.cpp:2100
void setContext(const std::string *const refID)
Definition Helper.cpp:1920
bool wrapDoubleList(const std::string &objID, const int variable, const std::vector< double > &value)
Definition Helper.cpp:1973
void transportableStateChanged(const MSTransportable *const transportable, MSNet::TransportableState to, const std::string &info="")
Called if a transportable changes its state.
Definition Helper.cpp:2139
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:2133
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:1873
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:837
static MSCalibrator::AspiredState getCalibratorState(const MSCalibrator *c)
Definition Helper.cpp:747
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:1185
static void findObjectShape(int domain, const std::string &id, PositionVector &shape)
Definition Helper.cpp:757
static void clearStateChanges()
Definition Helper.cpp:736
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:1757
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:1882
static const std::vector< std::string > & getTransportableStateChanges(const MSNet::TransportableState state)
Definition Helper.cpp:730
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:1323
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:1250
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:715
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:1400
static int postProcessRemoteControl()
return number of remote-controlled entities
Definition Helper.cpp:1415
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:907
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:1440
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:1289
static const std::vector< std::string > & getVehicleStateChanges(const MSNet::VehicleState state)
Definition Helper.cpp:724
static void collectObjectIDsInRange(int domain, const PositionVector &shape, double range, std::set< std::string > &into)
Definition Helper.cpp:827
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:1087
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:1710
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:379
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:378
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:376
TRACI_CONST int CMD_SUBSCRIBE_EDGE_VARIABLE
A 2D or 3D-position, for 2D positions z == INVALID_DOUBLE_VALUE.
Definition TraCIDefs.h:179
A list of positions.
Definition TraCIDefs.h:240
std::vector< TraCIPosition > value
Definition TraCIDefs.h:250
An edgeId, position and laneIndex.
Definition TraCIDefs.h:201