Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
libsumo/Vehicle.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2012-2023 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/****************************************************************************/
19// C++ Vehicle API
20/****************************************************************************/
21#include <config.h>
22
35#include <microsim/MSStop.h>
36#include <microsim/MSVehicle.h>
40#include <microsim/MSNet.h>
41#include <microsim/MSEdge.h>
42#include <microsim/MSLane.h>
47#include <mesosim/MEVehicle.h>
48#include <libsumo/TraCIDefs.h>
50#include "Helper.h"
51#include "Route.h"
52#include "Polygon.h"
53#include "Vehicle.h"
54
55#define CALL_MICRO_FUN(veh, fun, mesoResult) ((dynamic_cast<MSVehicle*>(veh) == nullptr ? (mesoResult) : dynamic_cast<MSVehicle*>(veh)->fun))
56
57
58// ===========================================================================
59// debug defines
60// ===========================================================================
61//#define DEBUG_NEIGHBORS
62//#define DEBUG_DYNAMIC_SHAPES
63//#define DEBUG_MOVEXY
64#define DEBUG_COND (veh->isSelected())
65
66
67
68namespace libsumo {
69// ===========================================================================
70// static member initializations
71// ===========================================================================
72SubscriptionResults Vehicle::mySubscriptionResults;
73ContextSubscriptionResults Vehicle::myContextSubscriptionResults;
74
75
76// ===========================================================================
77// static member definitions
78// ===========================================================================
79bool
80Vehicle::isVisible(const SUMOVehicle* veh) {
81 return veh->isOnRoad() || veh->isParking() || veh->wasRemoteControlled();
82}
83
84
85bool
86Vehicle::isOnInit(const std::string& vehID) {
88 return sumoVehicle == nullptr || sumoVehicle->getLane() == nullptr;
89}
90
91
92std::vector<std::string>
93Vehicle::getIDList() {
94 std::vector<std::string> ids;
96 for (MSVehicleControl::constVehIt i = c.loadedVehBegin(); i != c.loadedVehEnd(); ++i) {
97 if (isVisible((*i).second)) {
98 ids.push_back((*i).first);
99 }
100 }
101 return ids;
102}
103
104int
105Vehicle::getIDCount() {
106 return (int)getIDList().size();
107}
108
109
110double
111Vehicle::getSpeed(const std::string& vehID) {
112 MSBaseVehicle* veh = Helper::getVehicle(vehID);
113 return isVisible(veh) ? veh->getSpeed() : INVALID_DOUBLE_VALUE;
114}
115
116double
117Vehicle::getLateralSpeed(const std::string& vehID) {
118 MSBaseVehicle* veh = Helper::getVehicle(vehID);
119 return isVisible(veh) ? CALL_MICRO_FUN(veh, getLaneChangeModel().getSpeedLat(), 0) : INVALID_DOUBLE_VALUE;
120}
121
122
123double
124Vehicle::getAcceleration(const std::string& vehID) {
125 MSBaseVehicle* veh = Helper::getVehicle(vehID);
126 return isVisible(veh) ? CALL_MICRO_FUN(veh, getAcceleration(), 0) : INVALID_DOUBLE_VALUE;
127}
128
129
130double
131Vehicle::getSpeedWithoutTraCI(const std::string& vehID) {
132 MSBaseVehicle* veh = Helper::getVehicle(vehID);
133 return isVisible(veh) ? CALL_MICRO_FUN(veh, getSpeedWithoutTraciInfluence(), veh->getSpeed()) : INVALID_DOUBLE_VALUE;
134}
135
136
137TraCIPosition
138Vehicle::getPosition(const std::string& vehID, const bool includeZ) {
139 MSBaseVehicle* veh = Helper::getVehicle(vehID);
140 if (isVisible(veh)) {
141 return Helper::makeTraCIPosition(veh->getPosition(), includeZ);
142 }
143 return TraCIPosition();
144}
145
146
147TraCIPosition
148Vehicle::getPosition3D(const std::string& vehID) {
149 return getPosition(vehID, true);
150}
151
152
153double
154Vehicle::getAngle(const std::string& vehID) {
155 MSBaseVehicle* veh = Helper::getVehicle(vehID);
156 return isVisible(veh) ? GeomHelper::naviDegree(veh->getAngle()) : INVALID_DOUBLE_VALUE;
157}
158
159
160double
161Vehicle::getSlope(const std::string& vehID) {
162 MSBaseVehicle* veh = Helper::getVehicle(vehID);
163 return (veh->isOnRoad() || veh->isParking()) ? veh->getSlope() : INVALID_DOUBLE_VALUE;
164}
165
166
167std::string
168Vehicle::getRoadID(const std::string& vehID) {
169 MSBaseVehicle* veh = Helper::getVehicle(vehID);
170 return isVisible(veh) ? CALL_MICRO_FUN(veh, getLane()->getEdge().getID(), veh->getEdge()->getID()) : "";
171}
172
173
174std::string
175Vehicle::getLaneID(const std::string& vehID) {
176 MSBaseVehicle* veh = Helper::getVehicle(vehID);
177 return veh->isOnRoad() ? CALL_MICRO_FUN(veh, getLane()->getID(), "") : "";
178}
179
180
181int
182Vehicle::getLaneIndex(const std::string& vehID) {
183 MSBaseVehicle* veh = Helper::getVehicle(vehID);
184 return veh->isOnRoad() ? CALL_MICRO_FUN(veh, getLane()->getIndex(), INVALID_INT_VALUE) : INVALID_INT_VALUE;
185}
186
187
188std::string
189Vehicle::getTypeID(const std::string& vehID) {
190 return Helper::getVehicleType(vehID).getID();
191}
192
193
194std::string
195Vehicle::getRouteID(const std::string& vehID) {
196 return Helper::getVehicle(vehID)->getRoute().getID();
197}
198
199
200double
201Vehicle::getDeparture(const std::string& vehID) {
202 MSBaseVehicle* veh = Helper::getVehicle(vehID);
204}
205
206
207double
208Vehicle::getDepartDelay(const std::string& vehID) {
209 return STEPS2TIME(Helper::getVehicle(vehID)->getDepartDelay());
210}
211
212
213int
214Vehicle::getRouteIndex(const std::string& vehID) {
215 MSBaseVehicle* veh = Helper::getVehicle(vehID);
216 return veh->hasDeparted() ? veh->getRoutePosition() : INVALID_INT_VALUE;
217}
218
219
220TraCIColor
221Vehicle::getColor(const std::string& vehID) {
222 return Helper::makeTraCIColor(Helper::getVehicle(vehID)->getParameter().color);
223}
224
225double
226Vehicle::getLanePosition(const std::string& vehID) {
227 MSBaseVehicle* veh = Helper::getVehicle(vehID);
228 return veh->isOnRoad() ? veh->getPositionOnLane() : INVALID_DOUBLE_VALUE;
229}
230
231double
232Vehicle::getLateralLanePosition(const std::string& vehID) {
233 MSBaseVehicle* veh = Helper::getVehicle(vehID);
234 return veh->isOnRoad() ? CALL_MICRO_FUN(veh, getLateralPositionOnLane(), 0) : INVALID_DOUBLE_VALUE;
235}
236
237double
238Vehicle::getCO2Emission(const std::string& vehID) {
239 MSBaseVehicle* veh = Helper::getVehicle(vehID);
240 return isVisible(veh) ? veh->getEmissions<PollutantsInterface::CO2>() : INVALID_DOUBLE_VALUE;
241}
242
243double
244Vehicle::getCOEmission(const std::string& vehID) {
245 MSBaseVehicle* veh = Helper::getVehicle(vehID);
246 return isVisible(veh) ? veh->getEmissions<PollutantsInterface::CO>() : INVALID_DOUBLE_VALUE;
247}
248
249double
250Vehicle::getHCEmission(const std::string& vehID) {
251 MSBaseVehicle* veh = Helper::getVehicle(vehID);
252 return isVisible(veh) ? veh->getEmissions<PollutantsInterface::HC>() : INVALID_DOUBLE_VALUE;
253}
254
255double
256Vehicle::getPMxEmission(const std::string& vehID) {
257 MSBaseVehicle* veh = Helper::getVehicle(vehID);
258 return isVisible(veh) ? veh->getEmissions<PollutantsInterface::PM_X>() : INVALID_DOUBLE_VALUE;
259}
260
261double
262Vehicle::getNOxEmission(const std::string& vehID) {
263 MSBaseVehicle* veh = Helper::getVehicle(vehID);
264 return isVisible(veh) ? veh->getEmissions<PollutantsInterface::NO_X>() : INVALID_DOUBLE_VALUE;
265}
266
267double
268Vehicle::getFuelConsumption(const std::string& vehID) {
269 MSBaseVehicle* veh = Helper::getVehicle(vehID);
270 return isVisible(veh) ? veh->getEmissions<PollutantsInterface::FUEL>() : INVALID_DOUBLE_VALUE;
271}
272
273double
274Vehicle::getNoiseEmission(const std::string& vehID) {
275 MSBaseVehicle* veh = Helper::getVehicle(vehID);
276 return isVisible(veh) ? veh->getHarmonoise_NoiseEmissions() : INVALID_DOUBLE_VALUE;
277}
278
279double
280Vehicle::getElectricityConsumption(const std::string& vehID) {
281 MSBaseVehicle* veh = Helper::getVehicle(vehID);
282 return isVisible(veh) ? veh->getEmissions<PollutantsInterface::ELEC>() : INVALID_DOUBLE_VALUE;
283}
284
285int
286Vehicle::getPersonNumber(const std::string& vehID) {
287 return Helper::getVehicle(vehID)->getPersonNumber();
288}
289
290int
291Vehicle::getPersonCapacity(const std::string& vehID) {
293}
294
295
296double
297Vehicle::getBoardingDuration(const std::string& vehID) {
298 return STEPS2TIME(Helper::getVehicleType(vehID).getLoadingDuration(true));
299}
300
301
302std::vector<std::string>
303Vehicle::getPersonIDList(const std::string& vehID) {
304 return Helper::getVehicle(vehID)->getPersonIDList();
305}
306
307std::pair<std::string, double>
308Vehicle::getLeader(const std::string& vehID, double dist) {
309 MSBaseVehicle* veh = Helper::getVehicle(vehID);
310 if (veh->isOnRoad()) {
311 std::pair<const MSVehicle* const, double> leaderInfo = veh->getLeader(dist);
312 const std::string leaderID = leaderInfo.first != nullptr ? leaderInfo.first->getID() : "";
313 double gap = leaderInfo.second;
314 if (leaderInfo.first != nullptr
315 && leaderInfo.first->getLane() != nullptr
316 && leaderInfo.first->getLane()->isInternal()
317 && veh->getLane() != nullptr
318 && (!veh->getLane()->isInternal()
319 || (veh->getLane()->getLinkCont().front()->getIndex() != leaderInfo.first->getLane()->getLinkCont().front()->getIndex()))) {
320 // leader is a linkLeader (see MSLink::getLeaderInfo)
321 // avoid internal gap values which may be negative (or -inf)
322 gap = MAX2(0.0, gap);
323 }
324 return std::make_pair(leaderID, gap);
325 } else {
326 return std::make_pair("", -1);
327 }
328}
329
330
331std::pair<std::string, double>
332Vehicle::getFollower(const std::string& vehID, double dist) {
333 MSBaseVehicle* veh = Helper::getVehicle(vehID);
334 if (veh->isOnRoad()) {
335 std::pair<const MSVehicle* const, double> leaderInfo = veh->getFollower(dist);
336 return std::make_pair(
337 leaderInfo.first != nullptr ? leaderInfo.first->getID() : "",
338 leaderInfo.second);
339 } else {
340 return std::make_pair("", -1);
341 }
342}
343
344
345std::vector<TraCIJunctionFoe>
346Vehicle::getJunctionFoes(const std::string& vehID, double dist) {
347 std::vector<TraCIJunctionFoe> result;
348 MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
349 MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
350 if (veh == nullptr) {
351 WRITE_WARNING("getJunctionFoes not applicable for meso");
352 } else if (veh->isOnRoad()) {
353 if (dist == 0) {
354 dist = veh->getCarFollowModel().brakeGap(veh->getSpeed()) + veh->getVehicleType().getMinGap();
355 }
356 const std::vector<const MSLane*> internalLanes;
357 // distance to the end of the lane
358 double curDist = -veh->getPositionOnLane();
359 for (const MSLane* lane : veh->getUpcomingLanesUntil(dist)) {
360 curDist += lane->getLength();
361 if (lane->isInternal()) {
362 const MSLink* exitLink = lane->getLinkCont().front();
363 int foeIndex = 0;
364 const std::vector<MSLink::ConflictInfo>& conflicts = exitLink->getConflicts();
365 const MSJunctionLogic* logic = exitLink->getJunction()->getLogic();
366 for (const MSLane* foeLane : exitLink->getFoeLanes()) {
367 const MSLink::ConflictInfo& ci = conflicts[foeIndex];
369 continue;
370 }
371 const double distBehindCrossing = ci.lengthBehindCrossing;
372 const MSLink* foeExitLink = foeLane->getLinkCont().front();
373 const double distToCrossing = curDist - distBehindCrossing;
374 const double foeDistBehindCrossing = ci.getFoeLengthBehindCrossing(foeExitLink);
375 for (auto item : foeExitLink->getApproaching()) {
376 const SUMOVehicle* foe = item.first;
377 TraCIJunctionFoe jf;
378 jf.foeId = foe->getID();
379 jf.egoDist = distToCrossing;
380 // approach information is from the start of the previous step
381 // but the foe vehicle then moved within that steop
382 const double prevFoeDist = SPEED2DIST(MSGlobals::gSemiImplicitEulerUpdate
383 ? foe->getSpeed()
384 : (foe->getSpeed() + foe->getPreviousSpeed()) / 2);
385 jf.foeDist = item.second.dist - foeDistBehindCrossing - prevFoeDist;
386 jf.egoExitDist = jf.egoDist + ci.conflictSize;
387 jf.foeExitDist = jf.foeDist + ci.getFoeConflictSize(foeExitLink);
388 jf.egoLane = lane->getID();
389 jf.foeLane = foeLane->getID();
390 jf.egoResponse = logic->getResponseFor(exitLink->getIndex()).test(foeExitLink->getIndex());
391 jf.foeResponse = logic->getResponseFor(foeExitLink->getIndex()).test(exitLink->getIndex());
392 result.push_back(jf);
393 }
394 foeIndex++;
395 }
396 }
397 }
398 }
399 return result;
400}
401
402
403double
404Vehicle::getWaitingTime(const std::string& vehID) {
405 return STEPS2TIME(Helper::getVehicle(vehID)->getWaitingTime());
406}
407
408
409double
410Vehicle::getAccumulatedWaitingTime(const std::string& vehID) {
411 MSBaseVehicle* veh = Helper::getVehicle(vehID);
412 return CALL_MICRO_FUN(veh, getAccumulatedWaitingSeconds(), INVALID_DOUBLE_VALUE);
413}
414
415
416double
417Vehicle::getAdaptedTraveltime(const std::string& vehID, double time, const std::string& edgeID) {
418 MSEdge* edge = Helper::getEdge(edgeID);
419 double value = INVALID_DOUBLE_VALUE;
421 return value;
422}
423
424
425double
426Vehicle::getEffort(const std::string& vehID, double time, const std::string& edgeID) {
427 MSEdge* edge = Helper::getEdge(edgeID);
428 double value = INVALID_DOUBLE_VALUE;
430 return value;
431}
432
433
434bool
435Vehicle::isRouteValid(const std::string& vehID) {
436 std::string msg;
437 return Helper::getVehicle(vehID)->hasValidRoute(msg);
438}
439
440
441std::vector<std::string>
442Vehicle::getRoute(const std::string& vehID) {
443 std::vector<std::string> result;
444 MSBaseVehicle* veh = Helper::getVehicle(vehID);
445 const MSRoute& r = veh->getRoute();
446 for (MSRouteIterator i = r.begin(); i != r.end(); ++i) {
447 result.push_back((*i)->getID());
448 }
449 return result;
450}
451
452
453int
454Vehicle::getSignals(const std::string& vehID) {
455 MSBaseVehicle* veh = Helper::getVehicle(vehID);
456 return CALL_MICRO_FUN(veh, getSignals(), MSVehicle::VEH_SIGNAL_NONE);
457}
458
459
460std::vector<TraCIBestLanesData>
461Vehicle::getBestLanes(const std::string& vehID) {
462 std::vector<TraCIBestLanesData> result;
463 MSVehicle* veh = dynamic_cast<MSVehicle*>(Helper::getVehicle(vehID));
464 if (veh != nullptr && veh->isOnRoad()) {
465 for (const MSVehicle::LaneQ& lq : veh->getBestLanes()) {
466 TraCIBestLanesData bld;
467 bld.laneID = lq.lane->getID();
468 bld.length = lq.length;
469 bld.occupation = lq.nextOccupation;
470 bld.bestLaneOffset = lq.bestLaneOffset;
471 bld.allowsContinuation = lq.allowsContinuation;
472 for (const MSLane* const lane : lq.bestContinuations) {
473 if (lane != nullptr) {
474 bld.continuationLanes.push_back(lane->getID());
475 }
476 }
477 result.emplace_back(bld);
478 }
479 }
480 return result;
481}
482
483
484std::vector<TraCINextTLSData>
485Vehicle::getNextTLS(const std::string& vehID) {
486 std::vector<TraCINextTLSData> result;
487 MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
488 MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
489 if (!vehicle->isOnRoad()) {
490 return result;
491 }
492 if (veh != nullptr) {
493 const MSLane* lane = veh->getLane();
494 const std::vector<MSLane*>& bestLaneConts = veh->getBestLanesContinuation(lane);
495 double seen = lane->getLength() - veh->getPositionOnLane();
496 int view = 1;
497 std::vector<MSLink*>::const_iterator linkIt = MSLane::succLinkSec(*veh, view, *lane, bestLaneConts);
498 while (!lane->isLinkEnd(linkIt)) {
499 if (!lane->getEdge().isInternal()) {
500 if ((*linkIt)->isTLSControlled()) {
501 TraCINextTLSData ntd;
502 ntd.id = (*linkIt)->getTLLogic()->getID();
503 ntd.tlIndex = (*linkIt)->getTLIndex();
504 ntd.dist = seen;
505 ntd.state = (char)(*linkIt)->getState();
506 result.push_back(ntd);
507 }
508 }
509 lane = (*linkIt)->getViaLaneOrLane();
510 if (!lane->getEdge().isInternal()) {
511 view++;
512 }
513 seen += lane->getLength();
514 linkIt = MSLane::succLinkSec(*veh, view, *lane, bestLaneConts);
515 }
516 // consider edges beyond bestLanes
517 const int remainingEdges = (int)(veh->getRoute().end() - veh->getCurrentRouteEdge()) - view;
518 //std::cout << SIMTIME << "remainingEdges=" << remainingEdges << " seen=" << seen << " view=" << view << " best=" << toString(bestLaneConts) << "\n";
519 for (int i = 0; i < remainingEdges; i++) {
520 const MSEdge* prev = *(veh->getCurrentRouteEdge() + view + i - 1);
521 const MSEdge* next = *(veh->getCurrentRouteEdge() + view + i);
522 const std::vector<MSLane*>* allowed = prev->allowedLanes(*next, veh->getVClass());
523 if (allowed != nullptr && allowed->size() != 0) {
524 for (const MSLink* const link : allowed->front()->getLinkCont()) {
525 if (&link->getLane()->getEdge() == next) {
526 if (link->isTLSControlled()) {
527 TraCINextTLSData ntd;
528 ntd.id = link->getTLLogic()->getID();
529 ntd.tlIndex = link->getTLIndex();
530 ntd.dist = seen;
531 ntd.state = (char)link->getState();
532 result.push_back(ntd);
533 }
534 seen += allowed->front()->getLength();
535 }
536 }
537 } else {
538 // invalid route, cannot determine nextTLS
539 break;
540 }
541 }
542 } else {
543 WRITE_WARNING("getNextTLS not yet implemented for meso");
544 }
545 return result;
546}
547
548std::vector<TraCINextStopData>
549Vehicle::getNextStops(const std::string& vehID) {
550 return getStops(vehID, 0);
551}
552
553std::vector<libsumo::TraCIConnection>
554Vehicle::getNextLinks(const std::string& vehID) {
555 std::vector<libsumo::TraCIConnection> result;
556 MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
557 MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
558 if (!vehicle->isOnRoad()) {
559 return result;
560 }
561 if (veh != nullptr) {
562 const MSLane* lane = veh->getLane();
563 const std::vector<MSLane*>& bestLaneConts = veh->getBestLanesContinuation(lane);
564 int view = 1;
565 const SUMOTime currTime = MSNet::getInstance()->getCurrentTimeStep();
566 std::vector<MSLink*>::const_iterator linkIt = MSLane::succLinkSec(*veh, view, *lane, bestLaneConts);
567 while (!lane->isLinkEnd(linkIt)) {
568 if (!lane->getEdge().isInternal()) {
569 const MSLink* link = (*linkIt);
570 const std::string approachedLane = link->getLane() != nullptr ? link->getLane()->getID() : "";
571 const bool hasPrio = link->havePriority();
572 const double speed = MIN2(lane->getSpeedLimit(), link->getLane()->getSpeedLimit());
573 const bool isOpen = link->opened(currTime, speed, speed, SUMOVTypeParameter::getDefault().length,
575 const bool hasFoe = link->hasApproachingFoe(currTime, currTime, 0, SUMOVTypeParameter::getDefaultDecel());
576 const std::string approachedInternal = link->getViaLane() != nullptr ? link->getViaLane()->getID() : "";
577 const std::string state = SUMOXMLDefinitions::LinkStates.getString(link->getState());
578 const std::string direction = SUMOXMLDefinitions::LinkDirections.getString(link->getDirection());
579 const double length = link->getLength();
580 result.push_back(TraCIConnection(approachedLane, hasPrio, isOpen, hasFoe, approachedInternal, state, direction, length));
581 }
582 lane = (*linkIt)->getViaLaneOrLane();
583 if (!lane->getEdge().isInternal()) {
584 view++;
585 }
586 linkIt = MSLane::succLinkSec(*veh, view, *lane, bestLaneConts);
587 }
588 // consider edges beyond bestLanes
589 const int remainingEdges = (int)(veh->getRoute().end() - veh->getCurrentRouteEdge()) - view;
590 for (int i = 0; i < remainingEdges; i++) {
591 const MSEdge* prev = *(veh->getCurrentRouteEdge() + view + i - 1);
592 const MSEdge* next = *(veh->getCurrentRouteEdge() + view + i);
593 const std::vector<MSLane*>* allowed = prev->allowedLanes(*next, veh->getVClass());
594 if (allowed != nullptr && allowed->size() != 0) {
595 for (const MSLink* const link : allowed->front()->getLinkCont()) {
596 if (&link->getLane()->getEdge() == next) {
597 const std::string approachedLane = link->getLane() != nullptr ? link->getLane()->getID() : "";
598 const bool hasPrio = link->havePriority();
599 const double speed = MIN2(lane->getSpeedLimit(), link->getLane()->getSpeedLimit());
600 const bool isOpen = link->opened(currTime, speed, speed, SUMOVTypeParameter::getDefault().length,
602 const bool hasFoe = link->hasApproachingFoe(currTime, currTime, 0, SUMOVTypeParameter::getDefaultDecel());
603 const std::string approachedInternal = link->getViaLane() != nullptr ? link->getViaLane()->getID() : "";
604 const std::string state = SUMOXMLDefinitions::LinkStates.getString(link->getState());
605 const std::string direction = SUMOXMLDefinitions::LinkDirections.getString(link->getDirection());
606 const double length = link->getLength();
607 result.push_back(TraCIConnection(approachedLane, hasPrio, isOpen, hasFoe, approachedInternal, state, direction, length));
608 }
609 }
610 } else {
611 // invalid route, cannot determine nextTLS
612 break;
613 }
614 }
615 } else {
616 WRITE_WARNING("getNextLinks not yet implemented for meso");
617 }
618 return result;
619}
620
621std::vector<TraCINextStopData>
622Vehicle::getStops(const std::string& vehID, int limit) {
623 std::vector<TraCINextStopData> result;
624 MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
625 if (limit < 0) {
626 // return past stops up to the given limit
627 const std::vector<SUMOVehicleParameter::Stop>& pastStops = vehicle->getPastStops();
628 const int n = (int)pastStops.size();
629 for (int i = MAX2(0, n + limit); i < n; i++) {
630 result.push_back(Helper::buildStopData(pastStops[i]));
631 }
632 } else {
633 for (const MSStop& stop : vehicle->getStops()) {
634 if (!stop.pars.collision) {
635 TraCINextStopData nsd = Helper::buildStopData(stop.pars);
636 nsd.duration = STEPS2TIME(stop.duration);
637 result.push_back(nsd);
638 if (limit > 0 && (int)result.size() >= limit) {
639 break;
640 }
641 }
642 }
643 }
644 return result;
645}
646
647
648int
649Vehicle::getStopState(const std::string& vehID) {
650 MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
651 MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
652 if (veh == nullptr) {
653 WRITE_WARNING("getStopState not yet implemented for meso");
654 return 0;
655 }
656 int result = 0;
657 if (veh->isStopped()) {
658 const MSStop& stop = veh->getNextStop();
659 result = stop.getStateFlagsOld();
660 }
661 return result;
662}
663
664
665double
666Vehicle::getDistance(const std::string& vehID) {
667 MSBaseVehicle* veh = Helper::getVehicle(vehID);
668 if (veh->isOnRoad()) {
669 return veh->getOdometer();
670 } else {
672 }
673}
674
675
676double
677Vehicle::getDrivingDistance(const std::string& vehID, const std::string& edgeID, double position, int /* laneIndex */) {
678 MSBaseVehicle* veh = Helper::getVehicle(vehID);
679 MSVehicle* microVeh = dynamic_cast<MSVehicle*>(veh);
680 if (veh->isOnRoad()) {
681 const MSEdge* edge = microVeh != nullptr ? &veh->getLane()->getEdge() : veh->getEdge();
682 double distance = veh->getRoute().getDistanceBetween(veh->getPositionOnLane(), position,
683 edge, Helper::getEdge(edgeID), true, veh->getRoutePosition());
684 if (distance == std::numeric_limits<double>::max()) {
686 }
687 return distance;
688 } else {
690 }
691}
692
693
694double
695Vehicle::getDrivingDistance2D(const std::string& vehID, double x, double y) {
696 MSBaseVehicle* veh = Helper::getVehicle(vehID);
697 if (veh == nullptr) {
699 }
700 if (veh->isOnRoad()) {
701 std::pair<MSLane*, double> roadPos = Helper::convertCartesianToRoadMap(Position(x, y), veh->getVehicleType().getVehicleClass());
702 double distance = veh->getRoute().getDistanceBetween(veh->getPositionOnLane(), roadPos.second,
703 veh->getEdge(), &roadPos.first->getEdge(), true, veh->getRoutePosition());
704 if (distance == std::numeric_limits<double>::max()) {
706 }
707 return distance;
708 } else {
710 }
711}
712
713
714double
715Vehicle::getAllowedSpeed(const std::string& vehID) {
716 MSBaseVehicle* veh = Helper::getVehicle(vehID);
717 return veh->isOnRoad() ? CALL_MICRO_FUN(veh, getLane()->getVehicleMaxSpeed(veh), veh->getEdge()->getVehicleMaxSpeed(veh)) : INVALID_DOUBLE_VALUE;
718}
719
720
721double
722Vehicle::getSpeedFactor(const std::string& vehID) {
724}
725
726
727int
728Vehicle::getSpeedMode(const std::string& vehID) {
729 MSBaseVehicle* veh = Helper::getVehicle(vehID);
730 return CALL_MICRO_FUN(veh, getInfluencer().getSpeedMode(), INVALID_INT_VALUE);
731}
732
733
734int
735Vehicle::getLaneChangeMode(const std::string& vehID) {
736 MSBaseVehicle* veh = Helper::getVehicle(vehID);
737 return CALL_MICRO_FUN(veh, getInfluencer().getLaneChangeMode(), INVALID_INT_VALUE);
738}
739
740
741int
742Vehicle::getRoutingMode(const std::string& vehID) {
744}
745
746
747std::string
748Vehicle::getLine(const std::string& vehID) {
749 return Helper::getVehicle(vehID)->getParameter().line;
750}
751
752
753std::vector<std::string>
754Vehicle::getVia(const std::string& vehID) {
755 return Helper::getVehicle(vehID)->getParameter().via;
756}
757
758
759std::pair<int, int>
760Vehicle::getLaneChangeState(const std::string& vehID, int direction) {
761 MSBaseVehicle* veh = Helper::getVehicle(vehID);
762 auto undefined = std::make_pair((int)LCA_UNKNOWN, (int)LCA_UNKNOWN);
763 return veh->isOnRoad() ? CALL_MICRO_FUN(veh, getLaneChangeModel().getSavedState(direction), undefined) : undefined;
764}
765
766
767std::string
768Vehicle::getParameter(const std::string& vehID, const std::string& key) {
769 MSBaseVehicle* veh = Helper::getVehicle(vehID);
770 std::string error;
771 std::string result = veh->getPrefixedParameter(key, error);
772 if (error != "") {
773 throw TraCIException(error);
774 }
775 return result;
776}
777
778
780
781
782std::vector<std::pair<std::string, double> >
783Vehicle::getNeighbors(const std::string& vehID, const int mode) {
784 int dir = (1 & mode) != 0 ? -1 : 1;
785 bool queryLeaders = (2 & mode) != 0;
786 bool blockersOnly = (4 & mode) != 0;
787 MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
788 MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
789 std::vector<std::pair<std::string, double> > result;
790 if (veh == nullptr) {
791 return result;
792 }
793#ifdef DEBUG_NEIGHBORS
794 if (DEBUG_COND) {
795 std::cout << "getNeighbors() for veh '" << vehID << "': dir=" << dir
796 << ", queryLeaders=" << queryLeaders
797 << ", blockersOnly=" << blockersOnly << std::endl;
798 }
799#endif
800 if (veh->getLaneChangeModel().isOpposite()) {
801 // getParallelLane works relative to lane forward direction
802 dir *= -1;
803 }
804
805 MSLane* targetLane = veh->getLane()->getParallelLane(dir);
806 if (targetLane == nullptr) {
807 return result;
808 }
809 // need to recompute leaders and followers (#8119)
810 const bool opposite = &veh->getLane()->getEdge() != &targetLane->getEdge();
811 MSLeaderDistanceInfo neighbors(targetLane->getWidth(), nullptr, 0.);
812 if (queryLeaders) {
813 if (opposite) {
814 double pos = targetLane->getOppositePos(veh->getPositionOnLane());
815 neighbors = targetLane->getFollowersOnConsecutive(veh, pos, true);
816 } else {
817 targetLane->addLeaders(veh, veh->getPositionOnLane(), neighbors);
818 }
819 } else {
820 if (opposite) {
821 double pos = targetLane->getOppositePos(veh->getPositionOnLane());
822 targetLane->addLeaders(veh, pos, neighbors);
823 neighbors.fixOppositeGaps(true);
824 } else {
825 neighbors = targetLane->getFollowersOnConsecutive(veh, veh->getBackPositionOnLane(), true);
826 }
827 }
828 if (blockersOnly) {
829 // filter out vehicles that aren't blocking
830 MSLeaderDistanceInfo blockers(targetLane->getWidth(), nullptr, 0.);
831 for (int i = 0; i < neighbors.numSublanes(); i++) {
832 CLeaderDist n = neighbors[i];
833 if (n.first != nullptr) {
834 const MSVehicle* follower = veh;
835 const MSVehicle* leader = n.first;
836 if (!queryLeaders) {
837 std::swap(follower, leader);
838 }
839 const double secureGap = (follower->getCarFollowModel().getSecureGap(
840 follower, leader, follower->getSpeed(), leader->getSpeed(), leader->getCarFollowModel().getMaxDecel())
841 * follower->getLaneChangeModel().getSafetyFactor());
842 if (n.second < secureGap) {
843 blockers.addLeader(n.first, n.second, 0, i);
844 }
845 }
846 }
847 neighbors = blockers;
848 }
849
850 if (neighbors.hasVehicles()) {
851 for (int i = 0; i < neighbors.numSublanes(); i++) {
852 CLeaderDist n = neighbors[i];
853 if (n.first != nullptr &&
854 // avoid duplicates
855 (result.size() == 0 || result.back().first != n.first->getID())) {
856 result.push_back(std::make_pair(n.first->getID(), n.second));
857 }
858 }
859 }
860 return result;
861}
862
863
864double
865Vehicle::getFollowSpeed(const std::string& vehID, double speed, double gap, double leaderSpeed, double leaderMaxDecel, const std::string& leaderID) {
866 MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
867 MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
868 if (veh == nullptr) {
869 WRITE_ERROR("getFollowSpeed not applicable for meso");
871 }
872 MSVehicle* leader = dynamic_cast<MSVehicle*>(MSNet::getInstance()->getVehicleControl().getVehicle(leaderID));
873 return veh->getCarFollowModel().followSpeed(veh, speed, gap, leaderSpeed, leaderMaxDecel, leader, MSCFModel::CalcReason::FUTURE);
874}
875
876
877double
878Vehicle::getSecureGap(const std::string& vehID, double speed, double leaderSpeed, double leaderMaxDecel, const std::string& leaderID) {
879 MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
880 MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
881 if (veh == nullptr) {
882 WRITE_ERROR("getSecureGap not applicable for meso");
884 }
885 MSVehicle* leader = dynamic_cast<MSVehicle*>(MSNet::getInstance()->getVehicleControl().getVehicle(leaderID));
886 return veh->getCarFollowModel().getSecureGap(veh, leader, speed, leaderSpeed, leaderMaxDecel);
887}
888
889
890double
891Vehicle::getStopSpeed(const std::string& vehID, const double speed, double gap) {
892 MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
893 MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
894 if (veh == nullptr) {
895 WRITE_ERROR("getStopSpeed not applicable for meso");
897 }
898 return veh->getCarFollowModel().stopSpeed(veh, speed, gap, MSCFModel::CalcReason::FUTURE);
899}
900
901double
902Vehicle::getStopDelay(const std::string& vehID) {
903 return Helper::getVehicle(vehID)->getStopDelay();
904}
905
906
907double
908Vehicle::getImpatience(const std::string& vehID) {
909 return Helper::getVehicle(vehID)->getImpatience();
910}
911
912
913double
914Vehicle::getStopArrivalDelay(const std::string& vehID) {
915 double result = Helper::getVehicle(vehID)->getStopArrivalDelay();
916 if (result == INVALID_DOUBLE) {
918 } else {
919 return result;
920 }
921}
922
923double
924Vehicle::getTimeLoss(const std::string& vehID) {
925 return Helper::getVehicle(vehID)->getTimeLossSeconds();
926}
927
928std::vector<std::string>
929Vehicle::getTaxiFleet(int taxiState) {
930 std::vector<std::string> result;
931 for (MSDevice_Taxi* taxi : MSDevice_Taxi::getFleet()) {
932 if (taxi->getHolder().hasDeparted()) {
933 if (taxiState == -1
934 || (taxiState == 0 && taxi->getState() == 0)
935 || (taxiState != 0 && (taxi->getState() & taxiState) == taxiState)) {
936 result.push_back(taxi->getHolder().getID());
937 }
938 }
939 }
940 return result;
941}
942
943std::vector<std::string>
944Vehicle::getLoadedIDList() {
945 std::vector<std::string> ids;
947 for (MSVehicleControl::constVehIt i = c.loadedVehBegin(); i != c.loadedVehEnd(); ++i) {
948 ids.push_back(i->first);
949 }
950 return ids;
951}
952
953std::vector<std::string>
954Vehicle::getTeleportingIDList() {
955 std::vector<std::string> ids;
957 for (MSVehicleControl::constVehIt i = c.loadedVehBegin(); i != c.loadedVehEnd(); ++i) {
958 SUMOVehicle* veh = i->second;
959 if (veh->hasDeparted() && !isVisible(veh)) {
960 ids.push_back(veh->getID());
961 }
962 }
963 return ids;
964}
965
966std::string
967Vehicle::getEmissionClass(const std::string& vehID) {
968 return PollutantsInterface::getName(Helper::getVehicleType(vehID).getEmissionClass());
969}
970
971std::string
972Vehicle::getShapeClass(const std::string& vehID) {
973 return getVehicleShapeName(Helper::getVehicleType(vehID).getGuiShape());
974}
975
976
977double
978Vehicle::getLength(const std::string& vehID) {
979 return Helper::getVehicleType(vehID).getLength();
980}
981
982
983double
984Vehicle::getAccel(const std::string& vehID) {
986}
987
988
989double
990Vehicle::getDecel(const std::string& vehID) {
992}
993
994
995double Vehicle::getEmergencyDecel(const std::string& vehID) {
997}
998
999
1000double Vehicle::getApparentDecel(const std::string& vehID) {
1002}
1003
1004
1005double Vehicle::getActionStepLength(const std::string& vehID) {
1007}
1008
1009
1010double Vehicle::getLastActionTime(const std::string& vehID) {
1011 MSBaseVehicle* veh = Helper::getVehicle(vehID);
1012 MSVehicle* microVeh = dynamic_cast<MSVehicle*>(veh);
1013 if (microVeh != nullptr) {
1014 return STEPS2TIME(microVeh->getLastActionTime());
1015 } else {
1016 MEVehicle* mesoVeh = dynamic_cast<MEVehicle*>(veh);
1017 return STEPS2TIME(mesoVeh->getEventTime());
1018 }
1019}
1020
1021
1022double
1023Vehicle::getTau(const std::string& vehID) {
1025}
1026
1027
1028double
1029Vehicle::getImperfection(const std::string& vehID) {
1031}
1032
1033
1034double
1035Vehicle::getSpeedDeviation(const std::string& vehID) {
1037}
1038
1039
1040std::string
1041Vehicle::getVehicleClass(const std::string& vehID) {
1042 return toString(Helper::getVehicleType(vehID).getVehicleClass());
1043}
1044
1045
1046double
1047Vehicle::getMinGap(const std::string& vehID) {
1048 return Helper::getVehicleType(vehID).getMinGap();
1049}
1050
1051
1052double
1053Vehicle::getMinGapLat(const std::string& vehID) {
1054 try {
1055 return StringUtils::toDouble(getParameter(vehID, "laneChangeModel.minGapLat"));
1056 } catch (const TraCIException&) {
1057 // legacy behavior
1058 return Helper::getVehicleType(vehID).getMinGapLat();
1059 }
1060}
1061
1062
1063double
1064Vehicle::getMaxSpeed(const std::string& vehID) {
1065 return Helper::getVehicleType(vehID).getMaxSpeed();
1066}
1067
1068
1069double
1070Vehicle::getMaxSpeedLat(const std::string& vehID) {
1071 return Helper::getVehicleType(vehID).getMaxSpeedLat();
1072}
1073
1074
1075std::string
1076Vehicle::getLateralAlignment(const std::string& vehID) {
1077 return toString(Helper::getVehicleType(vehID).getPreferredLateralAlignment());
1078}
1079
1080
1081double
1082Vehicle::getWidth(const std::string& vehID) {
1083 return Helper::getVehicleType(vehID).getWidth();
1084}
1085
1086
1087double
1088Vehicle::getHeight(const std::string& vehID) {
1089 return Helper::getVehicleType(vehID).getHeight();
1090}
1091
1092
1093void
1094Vehicle::setStop(const std::string& vehID,
1095 const std::string& edgeID,
1096 double pos,
1097 int laneIndex,
1098 double duration,
1099 int flags,
1100 double startPos,
1101 double until) {
1102 MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
1104 pos, laneIndex, startPos, flags, duration, until);
1105 std::string error;
1106 if (!vehicle->addTraciStop(stopPars, error)) {
1107 throw TraCIException(error);
1108 }
1109}
1110
1111
1112void
1113Vehicle::replaceStop(const std::string& vehID,
1114 int nextStopIndex,
1115 const std::string& edgeID,
1116 double pos,
1117 int laneIndex,
1118 double duration,
1119 int flags,
1120 double startPos,
1121 double until,
1122 int teleport) {
1123 MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
1124 std::string error;
1125 if (edgeID == "") {
1126 // only remove stop
1127 const bool ok = vehicle->abortNextStop(nextStopIndex);
1128 if ((teleport & 2) != 0) {
1129 if (!vehicle->rerouteBetweenStops(nextStopIndex, "traci:replaceStop", (teleport & 1), error)) {
1130 throw TraCIException("Stop replacement failed for vehicle '" + vehID + "' (" + error + ").");
1131 }
1132 } else if (teleport != 0) {
1133 WRITE_WARNINGF(TL("Stop replacement parameter 'teleport=%' ignored for vehicle '%' when only removing stop."), toString(teleport), vehID);
1134 }
1135 if (!ok) {
1136 throw TraCIException("Stop replacement failed for vehicle '" + vehID + "' (invalid nextStopIndex).");
1137 }
1138 } else {
1140 pos, laneIndex, startPos, flags, duration, until);
1141
1142 if (!vehicle->replaceStop(nextStopIndex, stopPars, "traci:replaceStop", teleport != 0, error)) {
1143 throw TraCIException("Stop replacement failed for vehicle '" + vehID + "' (" + error + ").");
1144 }
1145 }
1146}
1147
1148
1149void
1150Vehicle::insertStop(const std::string& vehID,
1151 int nextStopIndex,
1152 const std::string& edgeID,
1153 double pos,
1154 int laneIndex,
1155 double duration,
1156 int flags,
1157 double startPos,
1158 double until,
1159 int teleport) {
1160 MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
1162 pos, laneIndex, startPos, flags, duration, until);
1163
1164 std::string error;
1165 if (!vehicle->insertStop(nextStopIndex, stopPars, "traci:insertStop", teleport != 0, error)) {
1166 throw TraCIException("Stop insertion failed for vehicle '" + vehID + "' (" + error + ").");
1167 }
1168}
1169
1170
1171std::string
1172Vehicle::getStopParameter(const std::string& vehID, int nextStopIndex, const std::string& param, bool customParam) {
1173 MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
1174 try {
1175 if (nextStopIndex >= (int)vehicle->getStops().size() || (nextStopIndex < 0 && -nextStopIndex > (int)vehicle->getPastStops().size())) {
1176 throw ProcessError("Invalid stop index " + toString(nextStopIndex)
1177 + " (has " + toString(vehicle->getPastStops().size()) + " past stops and " + toString(vehicle->getStops().size()) + " remaining stops)");
1178
1179 }
1180 const SUMOVehicleParameter::Stop& pars = (nextStopIndex >= 0
1181 ? vehicle->getStop(nextStopIndex).pars
1182 : vehicle->getPastStops()[vehicle->getPastStops().size() + nextStopIndex]);
1183 if (customParam) {
1184 // custom user parameter
1185 return pars.getParameter(param, "");
1186 }
1187
1188 if (param == toString(SUMO_ATTR_EDGE)) {
1189 return pars.edge;
1190 } else if (param == toString(SUMO_ATTR_LANE)) {
1192 } else if (param == toString(SUMO_ATTR_BUS_STOP)
1193 || param == toString(SUMO_ATTR_TRAIN_STOP)) {
1194 return pars.busstop;
1195 } else if (param == toString(SUMO_ATTR_CONTAINER_STOP)) {
1196 return pars.containerstop;
1197 } else if (param == toString(SUMO_ATTR_CHARGING_STATION)) {
1198 return pars.chargingStation;
1199 } else if (param == toString(SUMO_ATTR_PARKING_AREA)) {
1200 return pars.parkingarea;
1201 } else if (param == toString(SUMO_ATTR_STARTPOS)) {
1202 return toString(pars.startPos);
1203 } else if (param == toString(SUMO_ATTR_ENDPOS)) {
1204 return toString(pars.endPos);
1205 } else if (param == toString(SUMO_ATTR_POSITION_LAT)) {
1206 return toString(pars.posLat == INVALID_DOUBLE ? INVALID_DOUBLE_VALUE : pars.posLat);
1207 } else if (param == toString(SUMO_ATTR_ARRIVAL)) {
1208 return pars.arrival < 0 ? "-1" : time2string(pars.arrival);
1209 } else if (param == toString(SUMO_ATTR_DURATION)) {
1210 return pars.duration < 0 ? "-1" : time2string(pars.duration);
1211 } else if (param == toString(SUMO_ATTR_UNTIL)) {
1212 return pars.until < 0 ? "-1" : time2string(pars.until);
1213 } else if (param == toString(SUMO_ATTR_EXTENSION)) {
1214 return pars.extension < 0 ? "-1" : time2string(pars.extension);
1215 } else if (param == toString(SUMO_ATTR_INDEX)) {
1216 return toString(nextStopIndex + vehicle->getPastStops().size());
1217 } else if (param == toString(SUMO_ATTR_PARKING)) {
1218 return toString(pars.parking);
1219 } else if (param == toString(SUMO_ATTR_TRIGGERED)) {
1220 return joinToString(pars.getTriggers(), " ");
1221 } else if (param == toString(SUMO_ATTR_EXPECTED)) {
1222 return joinToString(pars.awaitedPersons, " ");
1223 } else if (param == toString(SUMO_ATTR_EXPECTED_CONTAINERS)) {
1224 return joinToString(pars.awaitedContainers, " ");
1225 } else if (param == toString(SUMO_ATTR_PERMITTED)) {
1226 return joinToString(pars.permitted, " ");
1227 } else if (param == toString(SUMO_ATTR_ACTTYPE)) {
1228 return pars.actType;
1229 } else if (param == toString(SUMO_ATTR_TRIP_ID)) {
1230 return pars.tripId;
1231 } else if (param == toString(SUMO_ATTR_SPLIT)) {
1232 return pars.split;
1233 } else if (param == toString(SUMO_ATTR_JOIN)) {
1234 return pars.join;
1235 } else if (param == toString(SUMO_ATTR_LINE)) {
1236 return pars.line;
1237 } else if (param == toString(SUMO_ATTR_SPEED)) {
1238 return toString(pars.speed);
1239 } else if (param == toString(SUMO_ATTR_STARTED)) {
1240 return pars.started < 0 ? "-1" : time2string(pars.started);
1241 } else if (param == toString(SUMO_ATTR_ENDED)) {
1242 return pars.ended < 0 ? "-1" : time2string(pars.ended);
1243 } else if (param == toString(SUMO_ATTR_ONDEMAND)) {
1244 return toString(pars.onDemand);
1245 } else {
1246 throw ProcessError(TLF("Unsupported parameter '%'", param));
1247 }
1248 } catch (ProcessError& e) {
1249 throw TraCIException("Could not get stop parameter for vehicle '" + vehID + "' (" + e.what() + ")");
1250 }
1251}
1252
1253
1254
1255void
1256Vehicle::setStopParameter(const std::string& vehID, int nextStopIndex,
1257 const std::string& param, const std::string& value,
1258 bool customParam) {
1259 MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
1260 try {
1261 MSStop& stop = vehicle->getStop(nextStopIndex);
1263 if (customParam) {
1264 pars.setParameter(param, value);
1265 return;
1266 }
1267 std::string error;
1268 if (param == toString(SUMO_ATTR_EDGE)
1269 || param == toString(SUMO_ATTR_BUS_STOP)
1270 || param == toString(SUMO_ATTR_TRAIN_STOP)
1273 || param == toString(SUMO_ATTR_PARKING_AREA)
1274 || param == toString(SUMO_ATTR_LANE)
1275 ) {
1276 int laneIndex = stop.lane->getIndex();
1277 int flags = pars.getFlags() & 3;
1278 std::string edgeOrStopID = value;
1279 if (param == toString(SUMO_ATTR_LANE)) {
1280 laneIndex = StringUtils::toInt(value);
1281 edgeOrStopID = pars.edge;
1282 } else if (param == toString(SUMO_ATTR_BUS_STOP)
1283 || param == toString(SUMO_ATTR_TRAIN_STOP)) {
1284 flags |= 8;
1285 } else if (param == toString(SUMO_ATTR_CONTAINER_STOP)) {
1286 flags |= 16;
1287 } else if (param == toString(SUMO_ATTR_CHARGING_STATION)) {
1288 flags |= 32;
1289 } else if (param == toString(SUMO_ATTR_PARKING_AREA)) {
1290 flags |= 64;
1291 }
1292 // special case: replace stop
1293 replaceStop(vehID, nextStopIndex, edgeOrStopID, pars.endPos, laneIndex, STEPS2TIME(pars.duration),
1294 flags, pars.startPos, STEPS2TIME(pars.until), 0);
1295
1296 } else if (param == toString(SUMO_ATTR_STARTPOS)) {
1297 pars.startPos = StringUtils::toDouble(value);
1299 } else if (param == toString(SUMO_ATTR_ENDPOS)) {
1300 pars.endPos = StringUtils::toDouble(value);
1302 } else if (param == toString(SUMO_ATTR_POSITION_LAT)) {
1303 pars.posLat = StringUtils::toDouble(value);
1305 } else if (param == toString(SUMO_ATTR_ARRIVAL)) {
1306 pars.arrival = string2time(value);
1308 } else if (param == toString(SUMO_ATTR_DURATION)) {
1309 pars.duration = string2time(value);
1311 // also update dynamic value
1312 stop.initPars(pars);
1313 } else if (param == toString(SUMO_ATTR_UNTIL)) {
1314 pars.until = string2time(value);
1316 } else if (param == toString(SUMO_ATTR_EXTENSION)) {
1317 pars.extension = string2time(value);
1319 } else if (param == toString(SUMO_ATTR_INDEX)) {
1320 throw TraCIException("Changing stop index is not supported");
1321 } else if (param == toString(SUMO_ATTR_PARKING)) {
1324 } else if (param == toString(SUMO_ATTR_TRIGGERED)) {
1325 if (pars.speed > 0 && value != "") {
1326 throw ProcessError(TLF("Waypoint (speed = %) at index % does not support triggers", pars.speed, nextStopIndex));
1327 }
1328 SUMOVehicleParameter::parseStopTriggers(StringTokenizer(value).getVector(), false, pars);
1330 // also update dynamic value
1331 stop.initPars(pars);
1332 } else if (param == toString(SUMO_ATTR_EXPECTED)) {
1333 pars.awaitedPersons = StringTokenizer(value).getSet();
1335 } else if (param == toString(SUMO_ATTR_EXPECTED_CONTAINERS)) {
1338 // also update dynamic value
1339 stop.initPars(pars);
1340 } else if (param == toString(SUMO_ATTR_PERMITTED)) {
1341 pars.permitted = StringTokenizer(value).getSet();
1343 } else if (param == toString(SUMO_ATTR_ACTTYPE)) {
1344 pars.actType = value;
1345 } else if (param == toString(SUMO_ATTR_TRIP_ID)) {
1346 pars.tripId = value;
1348 } else if (param == toString(SUMO_ATTR_SPLIT)) {
1349 pars.split = value;
1351 } else if (param == toString(SUMO_ATTR_JOIN)) {
1352 pars.join = value;
1354 } else if (param == toString(SUMO_ATTR_LINE)) {
1355 pars.line = value;
1357 } else if (param == toString(SUMO_ATTR_SPEED)) {
1358 const double speed = StringUtils::toDouble(value);
1359 if (speed > 0 && pars.getTriggers().size() > 0) {
1360 throw ProcessError(TLF("Triggered stop at index % cannot be changed into a waypoint by setting speed to %", nextStopIndex, speed));
1361 }
1362 pars.speed = speed;
1364 } else if (param == toString(SUMO_ATTR_STARTED)) {
1365 pars.started = string2time(value);
1367 } else if (param == toString(SUMO_ATTR_ENDED)) {
1368 pars.ended = string2time(value);
1370 } else if (param == toString(SUMO_ATTR_ONDEMAND)) {
1371 pars.onDemand = StringUtils::toBool(value);
1373 } else {
1374 throw ProcessError(TLF("Unsupported parameter '%'", param));
1375 }
1376 } catch (ProcessError& e) {
1377 throw TraCIException("Could not set stop parameter for vehicle '" + vehID + "' (" + e.what() + ")");
1378 }
1379}
1380
1381
1382void
1383Vehicle::rerouteParkingArea(const std::string& vehID, const std::string& parkingAreaID) {
1384 MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
1385 MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
1386 if (veh == nullptr) {
1387 WRITE_WARNING("rerouteParkingArea not yet implemented for meso");
1388 return;
1389 }
1390 std::string error;
1391 // Forward command to vehicle
1392 if (!veh->rerouteParkingArea(parkingAreaID, error)) {
1393 throw TraCIException(error);
1394 }
1395}
1396
1397void
1398Vehicle::resume(const std::string& vehID) {
1399 MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
1400 MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
1401 if (veh == nullptr) {
1402 WRITE_WARNING("resume not yet implemented for meso");
1403 return;
1404 }
1405 if (!veh->hasStops()) {
1406 throw TraCIException("Failed to resume vehicle '" + veh->getID() + "', it has no stops.");
1407 }
1408 if (!veh->resumeFromStopping()) {
1409 MSStop& sto = veh->getNextStop();
1410 std::ostringstream strs;
1411 strs << "reached: " << sto.reached;
1412 strs << ", duration:" << sto.duration;
1413 strs << ", edge:" << (*sto.edge)->getID();
1414 strs << ", startPos: " << sto.pars.startPos;
1415 std::string posStr = strs.str();
1416 throw TraCIException("Failed to resume from stopping for vehicle '" + veh->getID() + "', " + posStr);
1417 }
1418}
1419
1420
1421void
1422Vehicle::changeTarget(const std::string& vehID, const std::string& edgeID) {
1423 MSBaseVehicle* veh = Helper::getVehicle(vehID);
1424 const MSEdge* destEdge = MSEdge::dictionary(edgeID);
1425 const bool onInit = isOnInit(vehID);
1426 if (destEdge == nullptr) {
1427 throw TraCIException("Destination edge '" + edgeID + "' is not known.");
1428 }
1429 // build a new route between the vehicle's current edge and destination edge
1430 ConstMSEdgeVector newRoute;
1431 const MSEdge* currentEdge = *veh->getRerouteOrigin();
1433 currentEdge, destEdge, veh, MSNet::getInstance()->getCurrentTimeStep(), newRoute);
1434 // replace the vehicle's route by the new one (cost is updated by call to reroute())
1435 std::string errorMsg;
1436 if (!veh->replaceRouteEdges(newRoute, -1, 0, "traci:changeTarget", onInit, false, true, &errorMsg)) {
1437 throw TraCIException("Route replacement failed for vehicle '" + veh->getID() + "' (" + errorMsg + ").");
1438 }
1439 // route again to ensure usage of via/stops
1440 try {
1441 veh->reroute(MSNet::getInstance()->getCurrentTimeStep(), "traci:changeTarget",
1442 veh->getBaseInfluencer().getRouterTT(veh->getRNGIndex(), veh->getVClass()), onInit);
1443 } catch (ProcessError& e) {
1444 throw TraCIException(e.what());
1445 }
1446}
1447
1448
1449void
1450Vehicle::changeLane(const std::string& vehID, int laneIndex, double duration) {
1451 MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
1452 MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
1453 if (veh == nullptr) {
1454 WRITE_ERROR("changeLane not applicable for meso");
1455 return;
1456 }
1457
1458 std::vector<std::pair<SUMOTime, int> > laneTimeLine;
1459 laneTimeLine.push_back(std::make_pair(MSNet::getInstance()->getCurrentTimeStep(), laneIndex));
1460 laneTimeLine.push_back(std::make_pair(MSNet::getInstance()->getCurrentTimeStep() + TIME2STEPS(duration), laneIndex));
1461 veh->getInfluencer().setLaneTimeLine(laneTimeLine);
1462}
1463
1464void
1465Vehicle::changeLaneRelative(const std::string& vehID, int indexOffset, double duration) {
1466 MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
1467 MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
1468 if (veh == nullptr) {
1469 WRITE_ERROR("changeLaneRelative not applicable for meso");
1470 return;
1471 }
1472
1473 std::vector<std::pair<SUMOTime, int> > laneTimeLine;
1474 int laneIndex = veh->getLaneIndex() + indexOffset;
1475 if (laneIndex < 0 && !veh->getLaneChangeModel().isOpposite()) {
1476 if (veh->getLaneIndex() == -1) {
1477 WRITE_WARNINGF(TL("Ignoring changeLaneRelative for vehicle '%' that isn't on the road"), vehID);
1478 } else {
1479 WRITE_WARNINGF(TL("Ignoring indexOffset % for vehicle '%' on laneIndex %."), indexOffset, vehID, veh->getLaneIndex());
1480 }
1481 } else {
1482 laneTimeLine.push_back(std::make_pair(MSNet::getInstance()->getCurrentTimeStep(), laneIndex));
1483 laneTimeLine.push_back(std::make_pair(MSNet::getInstance()->getCurrentTimeStep() + TIME2STEPS(duration), laneIndex));
1484 veh->getInfluencer().setLaneTimeLine(laneTimeLine);
1485 }
1486}
1487
1488
1489void
1490Vehicle::changeSublane(const std::string& vehID, double latDist) {
1491 MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
1492 MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
1493 if (veh == nullptr) {
1494 WRITE_ERROR("changeSublane not applicable for meso");
1495 return;
1496 }
1497
1498 veh->getInfluencer().setSublaneChange(latDist);
1499}
1500
1501
1502void
1503Vehicle::add(const std::string& vehID,
1504 const std::string& routeID,
1505 const std::string& typeID,
1506 const std::string& depart,
1507 const std::string& departLane,
1508 const std::string& departPos,
1509 const std::string& departSpeed,
1510 const std::string& arrivalLane,
1511 const std::string& arrivalPos,
1512 const std::string& arrivalSpeed,
1513 const std::string& fromTaz,
1514 const std::string& toTaz,
1515 const std::string& line,
1516 int /*personCapacity*/,
1517 int personNumber) {
1519 if (veh != nullptr) {
1520 throw TraCIException("The vehicle '" + vehID + "' to add already exists.");
1521 }
1522
1523 SUMOVehicleParameter vehicleParams;
1524 vehicleParams.id = vehID;
1525 MSVehicleType* vehicleType = MSNet::getInstance()->getVehicleControl().getVType(typeID);
1526 if (!vehicleType) {
1527 throw TraCIException("Invalid type '" + typeID + "' for vehicle '" + vehID + "'.");
1528 }
1529 if (typeID != "DEFAULT_VEHTYPE") {
1530 vehicleParams.vtypeid = typeID;
1531 vehicleParams.parametersSet |= VEHPARS_VTYPE_SET;
1532 }
1533 ConstMSRoutePtr route = MSRoute::dictionary(routeID);
1534 if (!route) {
1535 if (routeID == "") {
1536 // assume, route was intentionally left blank because the caller
1537 // intends to control the vehicle remotely
1538 SUMOVehicleClass vclass = vehicleType->getVehicleClass();
1539 const std::string dummyRouteID = "DUMMY_ROUTE_" + SumoVehicleClassStrings.getString(vclass);
1540 route = MSRoute::dictionary(dummyRouteID);
1541 if (route == nullptr) {
1542 for (MSEdge* e : MSEdge::getAllEdges()) {
1543 if (e->getFunction() == SumoXMLEdgeFunc::NORMAL && (e->getPermissions() & vclass) == vclass) {
1544 std::vector<std::string> edges;
1545 edges.push_back(e->getID());
1546 libsumo::Route::add(dummyRouteID, edges);
1547 break;
1548 }
1549 }
1550 }
1551 route = MSRoute::dictionary(dummyRouteID);
1552 if (!route) {
1553 throw TraCIException("Could not build dummy route for vehicle class: '" + SumoVehicleClassStrings.getString(vehicleType->getVehicleClass()) + "'");
1554 }
1555 } else {
1556 throw TraCIException("Invalid route '" + routeID + "' for vehicle '" + vehID + "'.");
1557 }
1558 }
1559 // check if the route implies a trip
1560 if (route->getEdges().size() == 2) {
1561 const MSEdgeVector& succ = route->getEdges().front()->getSuccessors();
1562 if (std::find(succ.begin(), succ.end(), route->getEdges().back()) == succ.end()) {
1563 vehicleParams.parametersSet |= VEHPARS_FORCE_REROUTE;
1564 }
1565 }
1566 if (fromTaz != "" || toTaz != "") {
1567 vehicleParams.parametersSet |= VEHPARS_FORCE_REROUTE;
1568 }
1569 std::string error;
1570 if (!SUMOVehicleParameter::parseDepart(depart, "vehicle", vehID, vehicleParams.depart, vehicleParams.departProcedure, error)) {
1571 throw TraCIException(error);
1572 }
1573 if (vehicleParams.departProcedure == DepartDefinition::GIVEN && vehicleParams.depart < MSNet::getInstance()->getCurrentTimeStep()) {
1574 vehicleParams.depart = MSNet::getInstance()->getCurrentTimeStep();
1575 WRITE_WARNINGF(TL("Departure time for vehicle '%' is in the past; using current time instead."), vehID);
1576 } else if (vehicleParams.departProcedure == DepartDefinition::NOW) {
1577 vehicleParams.depart = MSNet::getInstance()->getCurrentTimeStep();
1578 }
1579 if (!SUMOVehicleParameter::parseDepartLane(departLane, "vehicle", vehID, vehicleParams.departLane, vehicleParams.departLaneProcedure, error)) {
1580 throw TraCIException(error);
1581 }
1582 if (!SUMOVehicleParameter::parseDepartPos(departPos, "vehicle", vehID, vehicleParams.departPos, vehicleParams.departPosProcedure, error)) {
1583 throw TraCIException(error);
1584 }
1585 if (!SUMOVehicleParameter::parseDepartSpeed(departSpeed, "vehicle", vehID, vehicleParams.departSpeed, vehicleParams.departSpeedProcedure, error)) {
1586 throw TraCIException(error);
1587 }
1588 if (!SUMOVehicleParameter::parseArrivalLane(arrivalLane, "vehicle", vehID, vehicleParams.arrivalLane, vehicleParams.arrivalLaneProcedure, error)) {
1589 throw TraCIException(error);
1590 }
1591 if (!SUMOVehicleParameter::parseArrivalPos(arrivalPos, "vehicle", vehID, vehicleParams.arrivalPos, vehicleParams.arrivalPosProcedure, error)) {
1592 throw TraCIException(error);
1593 }
1594 if (!SUMOVehicleParameter::parseArrivalSpeed(arrivalSpeed, "vehicle", vehID, vehicleParams.arrivalSpeed, vehicleParams.arrivalSpeedProcedure, error)) {
1595 throw TraCIException(error);
1596 }
1597 // mark non-default attributes
1598 if (departLane != "first") {
1599 vehicleParams.parametersSet |= VEHPARS_DEPARTLANE_SET;
1600 }
1601 if (departPos != "base") {
1602 vehicleParams.parametersSet |= VEHPARS_DEPARTPOS_SET;
1603 }
1604 if (departSpeed != "0") {
1605 vehicleParams.parametersSet |= VEHPARS_DEPARTSPEED_SET;
1606 }
1607 if (arrivalLane != "current") {
1608 vehicleParams.parametersSet |= VEHPARS_ARRIVALLANE_SET;
1609 }
1610 if (arrivalPos != "max") {
1611 vehicleParams.parametersSet |= VEHPARS_ARRIVALPOS_SET;
1612 }
1613 if (arrivalSpeed != "current") {
1614 vehicleParams.parametersSet |= VEHPARS_ARRIVALSPEED_SET;
1615 }
1616 if (fromTaz != "") {
1617 vehicleParams.parametersSet |= VEHPARS_FROM_TAZ_SET;
1618 }
1619 if (toTaz != "") {
1620 vehicleParams.parametersSet |= VEHPARS_TO_TAZ_SET;
1621 }
1622 if (line != "") {
1623 vehicleParams.parametersSet |= VEHPARS_LINE_SET;
1624 }
1625 if (personNumber != 0) {
1627 }
1628 // build vehicle
1629 vehicleParams.fromTaz = fromTaz;
1630 vehicleParams.toTaz = toTaz;
1631 vehicleParams.line = line;
1632 //vehicleParams.personCapacity = personCapacity;
1633 vehicleParams.personNumber = personNumber;
1634
1635 SUMOVehicleParameter* params = new SUMOVehicleParameter(vehicleParams);
1636 SUMOVehicle* vehicle = nullptr;
1637 try {
1638 vehicle = MSNet::getInstance()->getVehicleControl().buildVehicle(params, route, vehicleType, true, false);
1639 if (fromTaz == "" && !route->getEdges().front()->validateDepartSpeed(*vehicle)) {
1641 throw TraCIException("Departure speed for vehicle '" + vehID + "' is too high for the departure edge '" + route->getEdges().front()->getID() + "'.");
1642 }
1643 std::string msg;
1644 if (vehicle->getRouteValidity(true, true, &msg) != MSBaseVehicle::ROUTE_VALID) {
1646 throw TraCIException("Vehicle '" + vehID + "' has no valid route (" + msg + "). ");
1647 }
1648 MSNet::getInstance()->getVehicleControl().addVehicle(vehicleParams.id, vehicle);
1651 }
1652 } catch (ProcessError& e) {
1653 if (vehicle != nullptr) {
1655 }
1656 throw TraCIException(e.what());
1657 }
1658}
1659
1660
1661void
1662Vehicle::moveToXY(const std::string& vehID, const std::string& edgeID, const int laneIndex,
1663 const double x, const double y, double angle, const int keepRoute, double matchThreshold) {
1664 MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
1665 MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
1666 if (veh == nullptr) {
1667 WRITE_WARNING("moveToXY not yet implemented for meso");
1668 return;
1669 }
1670 const bool doKeepRoute = (keepRoute & 1) != 0 && veh->getID() != "VTD_EGO";
1671 const bool mayLeaveNetwork = (keepRoute & 2) != 0;
1672 const bool ignorePermissions = (keepRoute & 4) != 0;
1673 const bool setLateralPos = (MSGlobals::gLateralResolution > 0 || mayLeaveNetwork);
1674 SUMOVehicleClass vClass = ignorePermissions ? SVC_IGNORING : veh->getVClass();
1675 // process
1676 const std::string origID = edgeID + "_" + toString(laneIndex);
1677 // @todo add an interpretation layer for OSM derived origID values (without lane index)
1678 Position pos(x, y);
1679#ifdef DEBUG_MOVEXY
1680 const double origAngle = angle;
1681#endif
1682 // angle must be in [0,360] because it will be compared against those returned by naviDegree()
1683 // angle set to INVALID_DOUBLE_VALUE is ignored in the evaluated and later set to the angle of the matched lane
1684 if (angle != INVALID_DOUBLE_VALUE) {
1685 while (angle >= 360.) {
1686 angle -= 360.;
1687 }
1688 while (angle < 0.) {
1689 angle += 360.;
1690 }
1691 }
1692
1693 Position vehPos = veh->getPosition();
1694#ifdef DEBUG_MOVEXY
1695 std::cout << std::endl << SIMTIME << " moveToXY veh=" << veh->getID() << " vehPos=" << vehPos
1696 << " lane=" << Named::getIDSecure(veh->getLane()) << " lanePos=" << vehicle->getPositionOnLane() << std::endl;
1697 std::cout << " wantedPos=" << pos << " origID=" << origID << " laneIndex=" << laneIndex << " origAngle=" << origAngle << " angle=" << angle << " keepRoute=" << keepRoute << std::endl;
1698#endif
1699
1700 ConstMSEdgeVector edges;
1701 MSLane* lane = nullptr;
1702 double lanePos;
1703 double lanePosLat = 0;
1704 double bestDistance = std::numeric_limits<double>::max();
1705 int routeOffset = 0;
1706 bool found;
1707 double maxRouteDistance = matchThreshold;
1708 /* EGO vehicle is known to have a fixed route. @todo make this into a parameter of the TraCI call */
1709 if (doKeepRoute) {
1710 // case a): vehicle is on its earlier route
1711 // we additionally assume it is moving forward (SUMO-limit);
1712 // note that the route ("edges") is not changed in this case
1713
1715 veh->getRoute().getEdges(), veh->getRoutePosition(),
1716 vClass, setLateralPos,
1717 bestDistance, &lane, lanePos, routeOffset);
1718 // @note silenty ignoring mapping failure
1719 } else {
1720 double speed = pos.distanceTo2D(veh->getPosition()); // !!!veh->getSpeed();
1721 found = Helper::moveToXYMap(pos, maxRouteDistance, mayLeaveNetwork, origID, angle,
1722 speed, veh->getRoute().getEdges(), veh->getRoutePosition(), veh->getLane(), veh->getPositionOnLane(), veh->isOnRoad(),
1723 vClass, setLateralPos,
1724 bestDistance, &lane, lanePos, routeOffset, edges);
1725 }
1726 if ((found && bestDistance <= maxRouteDistance) || mayLeaveNetwork) {
1727 // optionally compute lateral offset
1728 pos.setz(veh->getPosition().z());
1729 if (found && setLateralPos) {
1730 const double perpDist = lane->getShape().distance2D(pos, false);
1731 if (perpDist != GeomHelper::INVALID_OFFSET) {
1732 lanePosLat = perpDist;
1733 if (!mayLeaveNetwork) {
1734 lanePosLat = MIN2(lanePosLat, 0.5 * (lane->getWidth() + veh->getVehicleType().getWidth() - MSGlobals::gLateralResolution));
1735 }
1736 // figure out whether the offset is to the left or to the right
1737 PositionVector tmp = lane->getShape();
1738 try {
1739 tmp.move2side(-lanePosLat); // moved to left
1740 } catch (ProcessError&) {
1741 WRITE_WARNINGF(TL("Could not determine position on lane '%' at lateral position %."), lane->getID(), toString(-lanePosLat));
1742 }
1743 //std::cout << " lane=" << lane->getID() << " posLat=" << lanePosLat << " shape=" << lane->getShape() << " tmp=" << tmp << " tmpDist=" << tmp.distance2D(pos) << "\n";
1744 if (tmp.distance2D(pos) > perpDist) {
1745 lanePosLat = -lanePosLat;
1746 }
1747 }
1748 pos.setz(lane->geometryPositionAtOffset(lanePos).z());
1749 }
1750 if (found && !mayLeaveNetwork && MSGlobals::gLateralResolution < 0) {
1751 // mapped position may differ from pos
1752 pos = lane->geometryPositionAtOffset(lanePos, -lanePosLat);
1753 }
1754 assert((found && lane != 0) || (!found && lane == 0));
1755 assert(!std::isnan(lanePos));
1756 if (angle == INVALID_DOUBLE_VALUE) {
1757 if (lane != nullptr) {
1758 angle = GeomHelper::naviDegree(lane->getShape().rotationAtOffset(lanePos));
1759 } else {
1760 // compute angle outside road network from old and new position
1761 angle = GeomHelper::naviDegree(veh->getPosition().angleTo2D(pos));
1762 }
1763 }
1764 // use the best we have
1765#ifdef DEBUG_MOVEXY
1766 std::cout << SIMTIME << " veh=" << vehID + " moveToXYResult lane='" << Named::getIDSecure(lane) << "' lanePos=" << lanePos << " lanePosLat=" << lanePosLat << "\n";
1767#endif
1768 Helper::setRemoteControlled(veh, pos, lane, lanePos, lanePosLat, angle, routeOffset, edges, MSNet::getInstance()->getCurrentTimeStep());
1769 if (!veh->isOnRoad()) {
1771 }
1772 } else {
1773 if (lane == nullptr) {
1774 throw TraCIException("Could not map vehicle '" + vehID + "', no road found within " + toString(maxRouteDistance) + "m.");
1775 } else {
1776 throw TraCIException("Could not map vehicle '" + vehID + "', distance to road is " + toString(bestDistance) + ".");
1777 }
1778 }
1779}
1780
1781void
1782Vehicle::slowDown(const std::string& vehID, double speed, double duration) {
1783 MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
1784 MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
1785 if (veh == nullptr) {
1786 WRITE_ERROR("slowDown not applicable for meso");
1787 return;
1788 }
1789
1790 std::vector<std::pair<SUMOTime, double> > speedTimeLine;
1791 speedTimeLine.push_back(std::make_pair(MSNet::getInstance()->getCurrentTimeStep(), veh->getSpeed()));
1792 speedTimeLine.push_back(std::make_pair(MSNet::getInstance()->getCurrentTimeStep() + TIME2STEPS(duration), speed));
1793 veh->getInfluencer().setSpeedTimeLine(speedTimeLine);
1794}
1795
1796void
1797Vehicle::openGap(const std::string& vehID, double newTimeHeadway, double newSpaceHeadway, double duration, double changeRate, double maxDecel, const std::string& referenceVehID) {
1798 MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
1799 MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
1800 if (veh == nullptr) {
1801 WRITE_ERROR("openGap not applicable for meso");
1802 return;
1803 }
1804
1805 MSVehicle* refVeh = nullptr;
1806 if (referenceVehID != "") {
1807 refVeh = dynamic_cast<MSVehicle*>(Helper::getVehicle(referenceVehID));
1808 }
1809 const double originalTau = veh->getVehicleType().getCarFollowModel().getHeadwayTime();
1810 if (newTimeHeadway == -1) {
1811 newTimeHeadway = originalTau;
1812 }
1813 if (originalTau > newTimeHeadway) {
1814 WRITE_WARNING("Ignoring openGap(). New time headway must not be smaller than the original.");
1815 return;
1816 }
1817 veh->getInfluencer().activateGapController(originalTau, newTimeHeadway, newSpaceHeadway, duration, changeRate, maxDecel, refVeh);
1818}
1819
1820void
1821Vehicle::deactivateGapControl(const std::string& vehID) {
1822 MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
1823 MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
1824 if (veh == nullptr) {
1825 WRITE_ERROR("deactivateGapControl not applicable for meso");
1826 return;
1827 }
1828
1829 if (veh->hasInfluencer()) {
1831 }
1832}
1833
1834void
1835Vehicle::requestToC(const std::string& vehID, double leadTime) {
1836 setParameter(vehID, "device.toc.requestToC", toString(leadTime));
1837}
1838
1839void
1840Vehicle::setSpeed(const std::string& vehID, double speed) {
1841 MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
1842 MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
1843 if (veh == nullptr) {
1844 WRITE_WARNING("setSpeed not yet implemented for meso");
1845 return;
1846 }
1847
1848 std::vector<std::pair<SUMOTime, double> > speedTimeLine;
1849 if (speed >= 0) {
1850 speedTimeLine.push_back(std::make_pair(MSNet::getInstance()->getCurrentTimeStep(), speed));
1851 speedTimeLine.push_back(std::make_pair(SUMOTime_MAX - DELTA_T, speed));
1852 }
1853 veh->getInfluencer().setSpeedTimeLine(speedTimeLine);
1854}
1855
1856void
1857Vehicle::setAcceleration(const std::string& vehID, double accel, double duration) {
1858 MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
1859 MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
1860 if (veh == nullptr) {
1861 WRITE_WARNING("setAcceleration not yet implemented for meso");
1862 return;
1863 }
1864
1865 double targetSpeed = std::max(veh->getSpeed() + accel * duration, 0.0);
1866 std::vector<std::pair<SUMOTime, double>> speedTimeLine;
1867 speedTimeLine.push_back(std::make_pair(MSNet::getInstance()->getCurrentTimeStep(), veh->getSpeed()));
1868 speedTimeLine.push_back(std::make_pair(MSNet::getInstance()->getCurrentTimeStep() + TIME2STEPS(duration), targetSpeed));
1869 veh->getInfluencer().setSpeedTimeLine(speedTimeLine);
1870}
1871
1872void
1873Vehicle::setPreviousSpeed(const std::string& vehID, double prevSpeed, double prevAcceleration) {
1874 MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
1875 MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
1876 if (veh == nullptr) {
1877 WRITE_WARNING("setPreviousSpeed not yet implemented for meso");
1878 return;
1879 }
1880 if (prevAcceleration == INVALID_DOUBLE_VALUE) {
1881 prevAcceleration = std::numeric_limits<double>::min();
1882 }
1883 veh->setPreviousSpeed(prevSpeed, prevAcceleration);
1884}
1885
1886void
1887Vehicle::setSpeedMode(const std::string& vehID, int speedMode) {
1888 MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
1889 MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
1890 if (veh == nullptr) {
1891 WRITE_WARNING("setSpeedMode not yet implemented for meso");
1892 return;
1893 }
1894
1895 veh->getInfluencer().setSpeedMode(speedMode);
1896}
1897
1898void
1899Vehicle::setLaneChangeMode(const std::string& vehID, int laneChangeMode) {
1900 MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
1901 MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
1902 if (veh == nullptr) {
1903 WRITE_ERROR("setLaneChangeMode not applicable for meso");
1904 return;
1905 }
1906
1907 veh->getInfluencer().setLaneChangeMode(laneChangeMode);
1908}
1909
1910void
1911Vehicle::setRoutingMode(const std::string& vehID, int routingMode) {
1913}
1914
1915void
1916Vehicle::setType(const std::string& vehID, const std::string& typeID) {
1917 MSVehicleType* vehicleType = MSNet::getInstance()->getVehicleControl().getVType(typeID);
1918 if (vehicleType == nullptr) {
1919 throw TraCIException("Vehicle type '" + typeID + "' is not known");
1920 }
1921 MSBaseVehicle* veh = Helper::getVehicle(vehID);
1922 veh->replaceVehicleType(vehicleType);
1923 MSVehicle* microVeh = dynamic_cast<MSVehicle*>(veh);
1924 if (microVeh != nullptr && microVeh->isOnRoad()) {
1925 microVeh->updateBestLanes(true);
1926 }
1927}
1928
1929void
1930Vehicle::setRouteID(const std::string& vehID, const std::string& routeID) {
1931 MSBaseVehicle* veh = Helper::getVehicle(vehID);
1933 if (r == nullptr) {
1934 throw TraCIException("The route '" + routeID + "' is not known.");
1935 }
1936 std::string msg;
1937 if (!veh->hasValidRoute(msg, r)) {
1938 WRITE_WARNINGF(TL("Invalid route replacement for vehicle '%'. %"), veh->getID(), msg);
1940 throw TraCIException("Route replacement failed for " + veh->getID());
1941 }
1942 }
1943
1944 std::string errorMsg;
1945 if (!veh->replaceRoute(r, "traci:setRouteID", veh->getLane() == nullptr, 0, true, true, &errorMsg)) {
1946 throw TraCIException("Route replacement failed for vehicle '" + veh->getID() + "' (" + errorMsg + ").");
1947 }
1948}
1949
1950void
1951Vehicle::setRoute(const std::string& vehID, const std::string& edgeID) {
1952 setRoute(vehID, std::vector<std::string>({edgeID}));
1953}
1954
1955
1956void
1957Vehicle::setRoute(const std::string& vehID, const std::vector<std::string>& edgeIDs) {
1958 MSBaseVehicle* veh = Helper::getVehicle(vehID);
1959 ConstMSEdgeVector edges;
1960 const bool onInit = veh->getLane() == nullptr;
1961 try {
1962 MSEdge::parseEdgesList(edgeIDs, edges, "<unknown>");
1963 if (edges.size() > 0 && edges.front()->isInternal()) {
1964 if (edges.size() == 1) {
1965 // avoid crashing due to lack of normal edges in route (#5390)
1966 edges.push_back(edges.back()->getLanes()[0]->getNextNormal());
1967 } else {
1968 // avoid internal edge in final route
1969 if (edges.front() == &veh->getLane()->getEdge()) {
1970 edges.erase(edges.begin());
1971 }
1972 }
1973 }
1974 } catch (ProcessError& e) {
1975 throw TraCIException("Invalid edge list for vehicle '" + veh->getID() + "' (" + e.what() + ")");
1976 }
1977 std::string errorMsg;
1978 if (!veh->replaceRouteEdges(edges, -1, 0, "traci:setRoute", onInit, true, true, &errorMsg)) {
1979 throw TraCIException("Route replacement failed for vehicle '" + veh->getID() + "' (" + errorMsg + ").");
1980 }
1981}
1982
1983
1984void
1985Vehicle::setLateralLanePosition(const std::string& vehID, double posLat) {
1986 MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
1987 MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
1988 if (veh != nullptr) {
1989 veh->setLateralPositionOnLane(posLat);
1990 } else {
1991 WRITE_ERROR("updateBestLanes not applicable for meso");
1992 }
1993}
1994
1995
1996void
1997Vehicle::updateBestLanes(const std::string& vehID) {
1998 MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
1999 MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
2000 if (veh == nullptr) {
2001 WRITE_ERROR("updateBestLanes not applicable for meso");
2002 return;
2003 }
2004 if (veh->isOnRoad()) {
2005 veh->updateBestLanes(true);
2006 }
2007}
2008
2009
2010void
2011Vehicle::setAdaptedTraveltime(const std::string& vehID, const std::string& edgeID,
2012 double time, double begSeconds, double endSeconds) {
2013 MSBaseVehicle* veh = Helper::getVehicle(vehID);
2014 MSEdge* edge = MSEdge::dictionary(edgeID);
2015 if (edge == nullptr) {
2016 throw TraCIException("Edge '" + edgeID + "' is not known.");
2017 }
2018 if (time != INVALID_DOUBLE_VALUE) {
2019 // add time
2020 if (begSeconds == 0 && endSeconds == std::numeric_limits<double>::max()) {
2021 // clean up old values before setting whole range
2022 while (veh->getWeightsStorage().knowsTravelTime(edge)) {
2024 }
2025 }
2026 veh->getWeightsStorage().addTravelTime(edge, begSeconds, endSeconds, time);
2027 } else {
2028 // remove time
2029 while (veh->getWeightsStorage().knowsTravelTime(edge)) {
2031 }
2032 }
2033}
2034
2035
2036void
2037Vehicle::setEffort(const std::string& vehID, const std::string& edgeID,
2038 double effort, double begSeconds, double endSeconds) {
2039 MSBaseVehicle* veh = Helper::getVehicle(vehID);
2040 MSEdge* edge = MSEdge::dictionary(edgeID);
2041 if (edge == nullptr) {
2042 throw TraCIException("Edge '" + edgeID + "' is not known.");
2043 }
2044 if (effort != INVALID_DOUBLE_VALUE) {
2045 // add effort
2046 if (begSeconds == 0 && endSeconds == std::numeric_limits<double>::max()) {
2047 // clean up old values before setting whole range
2048 while (veh->getWeightsStorage().knowsEffort(edge)) {
2049 veh->getWeightsStorage().removeEffort(edge);
2050 }
2051 }
2052 veh->getWeightsStorage().addEffort(edge, begSeconds, endSeconds, effort);
2053 } else {
2054 // remove effort
2055 while (veh->getWeightsStorage().knowsEffort(edge)) {
2056 veh->getWeightsStorage().removeEffort(edge);
2057 }
2058 }
2059}
2060
2061
2062void
2063Vehicle::rerouteTraveltime(const std::string& vehID, const bool currentTravelTimes) {
2064 MSBaseVehicle* veh = Helper::getVehicle(vehID);
2065 const int routingMode = veh->getBaseInfluencer().getRoutingMode();
2066 if (currentTravelTimes && routingMode == ROUTING_MODE_DEFAULT) {
2068 }
2069 veh->reroute(MSNet::getInstance()->getCurrentTimeStep(), "traci:rerouteTraveltime",
2070 veh->getBaseInfluencer().getRouterTT(veh->getRNGIndex(), veh->getVClass()), isOnInit(vehID));
2071 if (currentTravelTimes && routingMode == ROUTING_MODE_DEFAULT) {
2072 veh->getBaseInfluencer().setRoutingMode(routingMode);
2073 }
2074}
2075
2076
2077void
2078Vehicle::rerouteEffort(const std::string& vehID) {
2079 MSBaseVehicle* veh = Helper::getVehicle(vehID);
2080 veh->reroute(MSNet::getInstance()->getCurrentTimeStep(), "traci:rerouteEffort",
2081 MSNet::getInstance()->getRouterEffort(veh->getRNGIndex()), isOnInit(vehID));
2082}
2083
2084
2085void
2086Vehicle::setSignals(const std::string& vehID, int signals) {
2087 MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
2088 MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
2089 if (veh == nullptr) {
2090 WRITE_ERROR("setSignals not applicable for meso");
2091 return;
2092 }
2093
2094 // set influencer to make the change persistent
2095 veh->getInfluencer().setSignals(signals);
2096 // set them now so that getSignals returns the correct value
2097 veh->switchOffSignal(0x0fffffff);
2098 if (signals >= 0) {
2099 veh->switchOnSignal(signals);
2100 }
2101}
2102
2103
2104void
2105Vehicle::moveTo(const std::string& vehID, const std::string& laneID, double position, int reason) {
2106 MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
2107 MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
2108 if (veh == nullptr) {
2109 WRITE_WARNING("moveTo not yet implemented for meso");
2110 return;
2111 }
2112
2113 MSLane* l = MSLane::dictionary(laneID);
2114 if (l == nullptr) {
2115 throw TraCIException("Unknown lane '" + laneID + "'.");
2116 }
2117 if (veh->getLane() == l) {
2118 veh->setTentativeLaneAndPosition(l, position, veh->getLateralPositionOnLane());
2119 return;
2120 }
2121 MSEdge* destinationEdge = &l->getEdge();
2122 const MSEdge* destinationRouteEdge = destinationEdge->getNormalBefore();
2123 if (!veh->isOnRoad() && veh->getParameter().wasSet(VEHPARS_FORCE_REROUTE) && veh->getRoute().getEdges().size() == 2) {
2124 // it's a trip that wasn't routeted yet (likely because the vehicle was added in this step. Find a route now
2125 veh->reroute(MSNet::getInstance()->getCurrentTimeStep(), "traci:moveTo-tripInsertion",
2126 veh->getBaseInfluencer().getRouterTT(veh->getRNGIndex(), veh->getVClass()), true);
2127 }
2128 // find edge in the remaining route
2129 MSRouteIterator it = std::find(veh->getCurrentRouteEdge(), veh->getRoute().end(), destinationRouteEdge);
2130 if (it == veh->getRoute().end()) {
2131 // find edge in the edges that were already passed
2132 it = std::find(veh->getRoute().begin(), veh->getRoute().end(), destinationRouteEdge);
2133 }
2134 if (it == veh->getRoute().end() ||
2135 // internal edge must continue the route
2136 (destinationEdge->isInternal() &&
2137 ((it + 1) == veh->getRoute().end()
2138 || l->getNextNormal() != *(it + 1)))) {
2139 throw TraCIException("Lane '" + laneID + "' is not on the route of vehicle '" + vehID + "'.");
2140 }
2141 Position oldPos = vehicle->getPosition();
2143 if (veh->getLane() != nullptr) {
2144 // correct odometer which gets incremented via onRemovalFromNet->leaveLane
2145 veh->addToOdometer(-veh->getLane()->getLength());
2147 } else {
2148 veh->setTentativeLaneAndPosition(l, position);
2149 }
2150 const int oldRouteIndex = veh->getRoutePosition();
2151 const int newRouteIndex = (int)(it - veh->getRoute().begin());
2152 if (oldRouteIndex > newRouteIndex) {
2153 // more odometer correction needed
2154 veh->addToOdometer(-l->getLength());
2155 }
2156 veh->resetRoutePosition(newRouteIndex, veh->getParameter().departLaneProcedure);
2157 if (!veh->isOnRoad()) {
2159 }
2160 MSMoveReminder::Notification moveReminderReason;
2161 if (veh->hasDeparted()) {
2162 if (reason == MOVE_TELEPORT) {
2163 moveReminderReason = MSMoveReminder::NOTIFICATION_TELEPORT;
2164 } else if (reason == MOVE_NORMAL) {
2165 moveReminderReason = MSMoveReminder::NOTIFICATION_JUNCTION;
2166 } else if (reason == MOVE_AUTOMATIC) {
2167 Position newPos = l->geometryPositionAtOffset(position);
2168 const double dist = newPos.distanceTo2D(oldPos);
2169 if (dist < SPEED2DIST(veh->getMaxSpeed())) {
2170 moveReminderReason = MSMoveReminder::NOTIFICATION_JUNCTION;
2171 } else {
2172 moveReminderReason = MSMoveReminder::NOTIFICATION_TELEPORT;
2173 }
2174 } else {
2175 throw TraCIException("Invalid moveTo reason '" + toString(reason) + "' for vehicle '" + vehID + "'.");
2176 }
2177 } else {
2178 moveReminderReason = MSMoveReminder::NOTIFICATION_DEPARTED;
2179 }
2180 l->forceVehicleInsertion(veh, position, moveReminderReason);
2181}
2182
2183
2184void
2185Vehicle::setActionStepLength(const std::string& vehID, double actionStepLength, bool resetActionOffset) {
2186 if (actionStepLength < 0.0) {
2187 WRITE_ERROR("Invalid action step length (<0). Ignoring command setActionStepLength().");
2188 return;
2189 }
2190 MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
2191 MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
2192 if (veh == nullptr) {
2193 WRITE_ERROR("setActionStepLength not applicable for meso");
2194 return;
2195 }
2196
2197 if (actionStepLength == 0.) {
2198 veh->resetActionOffset();
2199 } else {
2200 veh->setActionStepLength(actionStepLength, resetActionOffset);
2201 }
2202}
2203
2204
2205void
2206Vehicle::setBoardingDuration(const std::string& vehID, double boardingDuration) {
2208}
2209
2210
2211void
2212Vehicle::setImpatience(const std::string& vehID, double impatience) {
2213 MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
2214 const double normalImpatience = vehicle->getImpatience();
2215 vehicle->getBaseInfluencer().setExtraImpatience(impatience - normalImpatience);
2216}
2217
2218
2219void
2220Vehicle::remove(const std::string& vehID, char reason) {
2221 MSBaseVehicle* veh = Helper::getVehicle(vehID);
2223 switch (reason) {
2224 case REMOVE_TELEPORT:
2225 // XXX semantics unclear
2226 // n = MSMoveReminder::NOTIFICATION_TELEPORT;
2228 break;
2229 case REMOVE_PARKING:
2230 // XXX semantics unclear
2231 // n = MSMoveReminder::NOTIFICATION_PARKING;
2233 break;
2234 case REMOVE_ARRIVED:
2236 break;
2237 case REMOVE_VAPORIZED:
2239 break;
2242 break;
2243 default:
2244 throw TraCIException("Unknown removal status.");
2245 }
2246 if (veh->hasDeparted()) {
2247 veh->onRemovalFromNet(n);
2248 MSVehicle* microVeh = dynamic_cast<MSVehicle*>(veh);
2249 if (microVeh != nullptr) {
2250 if (veh->getLane() != nullptr) {
2251 microVeh->getMutableLane()->removeVehicle(dynamic_cast<MSVehicle*>(veh), n);
2252 }
2254 }
2256 } else {
2259 }
2260}
2261
2262
2263void
2264Vehicle::setColor(const std::string& vehID, const TraCIColor& col) {
2266 p.color.set((unsigned char)col.r, (unsigned char)col.g, (unsigned char)col.b, (unsigned char)col.a);
2268}
2269
2270
2271void
2272Vehicle::setSpeedFactor(const std::string& vehID, double factor) {
2274}
2275
2276
2277void
2278Vehicle::setLine(const std::string& vehID, const std::string& line) {
2279 Helper::getVehicle(vehID)->getParameter().line = line;
2280}
2281
2282
2283void
2284Vehicle::setVia(const std::string& vehID, const std::vector<std::string>& via) {
2285 MSBaseVehicle* veh = Helper::getVehicle(vehID);
2286 try {
2287 // ensure edges exist
2288 ConstMSEdgeVector edges;
2289 MSEdge::parseEdgesList(via, edges, "<via-edges>");
2290 } catch (ProcessError& e) {
2291 throw TraCIException(e.what());
2292 }
2293 veh->getParameter().via = via;
2294}
2295
2296
2297void
2298Vehicle::setLength(const std::string& vehID, double length) {
2300}
2301
2302
2303void
2304Vehicle::setMaxSpeed(const std::string& vehID, double speed) {
2306}
2307
2308
2309void
2310Vehicle::setVehicleClass(const std::string& vehID, const std::string& clazz) {
2311 MSBaseVehicle* veh = Helper::getVehicle(vehID);
2313 MSVehicle* microVeh = dynamic_cast<MSVehicle*>(veh);
2314 if (microVeh != nullptr && microVeh->isOnRoad()) {
2315 microVeh->updateBestLanes(true);
2316 }
2317}
2318
2319
2320void
2321Vehicle::setShapeClass(const std::string& vehID, const std::string& clazz) {
2323}
2324
2325
2326void
2327Vehicle::setEmissionClass(const std::string& vehID, const std::string& clazz) {
2329}
2330
2331
2332void
2333Vehicle::setWidth(const std::string& vehID, double width) {
2335}
2336
2337
2338void
2339Vehicle::setHeight(const std::string& vehID, double height) {
2341}
2342
2343
2344void
2345Vehicle::setMinGap(const std::string& vehID, double minGap) {
2347}
2348
2349
2350void
2351Vehicle::setAccel(const std::string& vehID, double accel) {
2353}
2354
2355
2356void
2357Vehicle::setDecel(const std::string& vehID, double decel) {
2358 VehicleType::setDecel(Helper::getVehicle(vehID)->getSingularType().getID(), decel);
2359}
2360
2361
2362void
2363Vehicle::setEmergencyDecel(const std::string& vehID, double decel) {
2364 VehicleType::setEmergencyDecel(Helper::getVehicle(vehID)->getSingularType().getID(), decel);
2365}
2366
2367
2368void
2369Vehicle::setApparentDecel(const std::string& vehID, double decel) {
2371}
2372
2373
2374void
2375Vehicle::setImperfection(const std::string& vehID, double imperfection) {
2376 Helper::getVehicle(vehID)->getSingularType().setImperfection(imperfection);
2377}
2378
2379
2380void
2381Vehicle::setTau(const std::string& vehID, double tau) {
2383}
2384
2385
2386void
2387Vehicle::setMinGapLat(const std::string& vehID, double minGapLat) {
2388 try {
2389 setParameter(vehID, "laneChangeModel.minGapLat", toString(minGapLat));
2390 } catch (TraCIException&) {
2391 // legacy behavior
2392 Helper::getVehicle(vehID)->getSingularType().setMinGapLat(minGapLat);
2393 }
2394}
2395
2396
2397void
2398Vehicle::setMaxSpeedLat(const std::string& vehID, double speed) {
2400}
2401
2402
2403void
2404Vehicle::setLateralAlignment(const std::string& vehID, const std::string& latAlignment) {
2405 double lao;
2407 if (SUMOVTypeParameter::parseLatAlignment(latAlignment, lao, lad)) {
2409 } else {
2410 throw TraCIException("Unknown value '" + latAlignment + "' when setting latAlignment for vehID '" + vehID + "';\n must be one of (\"right\", \"center\", \"arbitrary\", \"nice\", \"compact\", \"left\" or a float)");
2411 }
2412}
2413
2414
2415void
2416Vehicle::setParameter(const std::string& vehID, const std::string& key, const std::string& value) {
2417 MSBaseVehicle* veh = Helper::getVehicle(vehID);
2418 MSVehicle* microVeh = dynamic_cast<MSVehicle*>(veh);
2419 if (StringUtils::startsWith(key, "device.")) {
2420 StringTokenizer tok(key, ".");
2421 if (tok.size() < 3) {
2422 throw TraCIException("Invalid device parameter '" + key + "' for vehicle '" + vehID + "'");
2423 }
2424 try {
2425 veh->setDeviceParameter(tok.get(1), key.substr(tok.get(0).size() + tok.get(1).size() + 2), value);
2426 } catch (InvalidArgument& e) {
2427 throw TraCIException("Vehicle '" + vehID + "' does not support device parameter '" + key + "' (" + e.what() + ").");
2428 }
2429 } else if (StringUtils::startsWith(key, "laneChangeModel.")) {
2430 if (microVeh == nullptr) {
2431 throw TraCIException("Meso Vehicle '" + vehID + "' does not support laneChangeModel parameters.");
2432 }
2433 const std::string attrName = key.substr(16);
2434 try {
2435 microVeh->getLaneChangeModel().setParameter(attrName, value);
2436 } catch (InvalidArgument& e) {
2437 throw TraCIException("Vehicle '" + vehID + "' does not support laneChangeModel parameter '" + key + "' (" + e.what() + ").");
2438 }
2439 } else if (StringUtils::startsWith(key, "carFollowModel.")) {
2440 if (microVeh == nullptr) {
2441 throw TraCIException("Meso Vehicle '" + vehID + "' does not support carFollowModel parameters.");
2442 }
2443 try {
2444 veh->setCarFollowModelParameter(key, value);
2445 } catch (InvalidArgument& e) {
2446 throw TraCIException("Vehicle '" + vehID + "' does not support carFollowModel parameter '" + key + "' (" + e.what() + ").");
2447 }
2448 } else if (StringUtils::startsWith(key, "junctionModel.")) {
2449 try {
2450 // use the whole key (including junctionModel prefix)
2451 veh->setJunctionModelParameter(key, value);
2452 } catch (InvalidArgument& e) {
2453 // error message includes id since it is also used for xml input
2454 throw TraCIException(e.what());
2455 }
2456 } else if (StringUtils::startsWith(key, "has.") && StringUtils::endsWith(key, ".device")) {
2457 StringTokenizer tok(key, ".");
2458 if (tok.size() != 3) {
2459 throw TraCIException("Invalid request for device status change. Expected format is 'has.DEVICENAME.device'");
2460 }
2461 const std::string deviceName = tok.get(1);
2462 bool create;
2463 try {
2464 create = StringUtils::toBool(value);
2465 } catch (BoolFormatException&) {
2466 throw TraCIException("Changing device status requires a 'true' or 'false'");
2467 }
2468 if (!create) {
2469 throw TraCIException("Device removal is not supported for device of type '" + deviceName + "'");
2470 }
2471 try {
2472 veh->createDevice(deviceName);
2473 } catch (InvalidArgument& e) {
2474 throw TraCIException("Cannot create vehicle device (" + std::string(e.what()) + ").");
2475 }
2476 } else {
2477 ((SUMOVehicleParameter&)veh->getParameter()).setParameter(key, value);
2478 }
2479}
2480
2481
2482void
2483Vehicle::highlight(const std::string& vehID, const TraCIColor& col, double size, const int alphaMax, const double duration, const int type) {
2484 // NOTE: Code is duplicated in large parts in POI.cpp
2485 MSBaseVehicle* veh = Helper::getVehicle(vehID);
2486
2487 // Center of the highlight circle
2488 Position center = veh->getPosition();
2489 const double l2 = veh->getLength() * 0.5;
2490 center.sub(cos(veh->getAngle())*l2, sin(veh->getAngle())*l2);
2491 // Size of the highlight circle
2492 if (size <= 0) {
2493 size = veh->getLength() * 0.7;
2494 }
2495 // Make polygon shape
2496 const unsigned int nPoints = 34;
2497 const PositionVector circlePV = GeomHelper::makeRing(size, size + 1., center, nPoints);
2498 TraCIPositionVector circle = Helper::makeTraCIPositionVector(circlePV);
2499
2500#ifdef DEBUG_DYNAMIC_SHAPES
2501 std::cout << SIMTIME << " Vehicle::highlight() for vehicle '" << vehID << "'\n"
2502 << " circle: " << circlePV << std::endl;
2503#endif
2504
2505 // Find a free polygon id
2506 int i = 0;
2507 std::string polyID = veh->getID() + "_hl" + toString(i);
2508 while (Polygon::exists(polyID)) {
2509 polyID = veh->getID() + "_hl" + toString(++i);
2510 }
2511 // Line width
2512 double lw = 0.;
2513 // Layer
2514 double lyr = 0.;
2515 if (MSNet::getInstance()->isGUINet()) {
2516 lyr = GLO_VEHICLE + 0.01;
2517 lyr += (type + 1) / 257.;
2518 }
2519 // Make Polygon
2520 Polygon::addHighlightPolygon(vehID, type, polyID, circle, col, true, "highlight", (int)lyr, lw);
2521
2522 // Animation time line
2523 double maxAttack = 1.0; // maximal fade-in time
2524 std::vector<double> timeSpan;
2525 if (duration > 0.) {
2526 timeSpan = {0, MIN2(maxAttack, duration / 3.), 2.*duration / 3., duration};
2527 }
2528 // Alpha time line
2529 std::vector<double> alphaSpan;
2530 if (alphaMax > 0.) {
2531 alphaSpan = {0., (double) alphaMax, (double)(alphaMax) / 3., 0.};
2532 }
2533 // Attach dynamics
2534 Polygon::addDynamics(polyID, vehID, timeSpan, alphaSpan, false, true);
2535}
2536
2537void
2538Vehicle::dispatchTaxi(const std::string& vehID, const std::vector<std::string>& reservations) {
2539 MSBaseVehicle* veh = Helper::getVehicle(vehID);
2540 MSDevice_Taxi* taxi = static_cast<MSDevice_Taxi*>(veh->getDevice(typeid(MSDevice_Taxi)));
2541 if (taxi == nullptr) {
2542 throw TraCIException("Vehicle '" + vehID + "' is not a taxi");
2543 }
2545 if (dispatcher == nullptr) {
2546 throw TraCIException("Cannot dispatch taxi because no reservations have been made");
2547 }
2548 MSDispatch_TraCI* traciDispatcher = dynamic_cast<MSDispatch_TraCI*>(dispatcher);
2549 if (traciDispatcher == nullptr) {
2550 throw TraCIException("device.taxi.dispatch-algorithm 'traci' has not been loaded");
2551 }
2552 if (reservations.size() == 0) {
2553 throw TraCIException("No reservations have been specified for vehicle '" + vehID + "'");
2554 }
2555 try {
2556 traciDispatcher->interpretDispatch(taxi, reservations);
2557 } catch (InvalidArgument& e) {
2558 throw TraCIException("Could not interpret reservations for vehicle '" + vehID + "' (" + e.what() + ").");
2559 }
2560}
2561
2563
2564
2565void
2566Vehicle::subscribeLeader(const std::string& vehID, double dist, double begin, double end) {
2567 subscribe(vehID, std::vector<int>({ libsumo::VAR_LEADER }), begin, end,
2568 libsumo::TraCIResults({ {libsumo::VAR_LEADER, std::make_shared<libsumo::TraCIDouble>(dist)} }));
2569}
2570
2571
2572void
2573Vehicle::addSubscriptionFilterLanes(const std::vector<int>& lanes, bool noOpposite, double downstreamDist, double upstreamDist) {
2575 if (s != nullptr) {
2576 s->filterLanes = lanes;
2577 }
2578 if (noOpposite) {
2579 addSubscriptionFilterNoOpposite();
2580 }
2581 if (downstreamDist != INVALID_DOUBLE_VALUE) {
2582 addSubscriptionFilterDownstreamDistance(downstreamDist);
2583 }
2584 if (upstreamDist != INVALID_DOUBLE_VALUE) {
2585 addSubscriptionFilterUpstreamDistance(upstreamDist);
2586 }
2587}
2588
2589
2590void
2591Vehicle::addSubscriptionFilterNoOpposite() {
2593}
2594
2595
2596void
2597Vehicle::addSubscriptionFilterDownstreamDistance(double dist) {
2599 if (s != nullptr) {
2600 s->filterDownstreamDist = dist;
2601 }
2602}
2603
2604
2605void
2606Vehicle::addSubscriptionFilterUpstreamDistance(double dist) {
2608 if (s != nullptr) {
2609 s->filterUpstreamDist = dist;
2610 }
2611}
2612
2613
2614void
2615Vehicle::addSubscriptionFilterCFManeuver(double downstreamDist, double upstreamDist) {
2616 addSubscriptionFilterLeadFollow(std::vector<int>({0}));
2617 if (downstreamDist != INVALID_DOUBLE_VALUE) {
2618 addSubscriptionFilterDownstreamDistance(downstreamDist);
2619 }
2620 if (upstreamDist != INVALID_DOUBLE_VALUE) {
2621 addSubscriptionFilterUpstreamDistance(upstreamDist);
2622 }
2623
2624}
2625
2626
2627void
2628Vehicle::addSubscriptionFilterLCManeuver(int direction, bool noOpposite, double downstreamDist, double upstreamDist) {
2629 std::vector<int> lanes;
2630 if (direction == INVALID_INT_VALUE) {
2631 // Using default: both directions
2632 lanes = std::vector<int>({-1, 0, 1});
2633 } else if (direction != -1 && direction != 1) {
2634 WRITE_WARNINGF(TL("Ignoring lane change subscription filter with non-neighboring lane offset direction=%."), direction);
2635 } else {
2636 lanes = std::vector<int>({0, direction});
2637 }
2638 addSubscriptionFilterLeadFollow(lanes);
2639 if (noOpposite) {
2640 addSubscriptionFilterNoOpposite();
2641 }
2642 if (downstreamDist != INVALID_DOUBLE_VALUE) {
2643 addSubscriptionFilterDownstreamDistance(downstreamDist);
2644 }
2645 if (upstreamDist != INVALID_DOUBLE_VALUE) {
2646 addSubscriptionFilterUpstreamDistance(upstreamDist);
2647 }
2648}
2649
2650
2651void
2652Vehicle::addSubscriptionFilterLeadFollow(const std::vector<int>& lanes) {
2654 addSubscriptionFilterLanes(lanes);
2655}
2656
2657
2658void
2659Vehicle::addSubscriptionFilterTurn(double downstreamDist, double foeDistToJunction) {
2661 if (downstreamDist != INVALID_DOUBLE_VALUE) {
2662 addSubscriptionFilterDownstreamDistance(downstreamDist);
2663 }
2664 if (foeDistToJunction != INVALID_DOUBLE_VALUE) {
2665 s->filterFoeDistToJunction = foeDistToJunction;
2666 }
2667}
2668
2669
2670void
2671Vehicle::addSubscriptionFilterVClass(const std::vector<std::string>& vClasses) {
2673 if (s != nullptr) {
2674 s->filterVClasses = parseVehicleClasses(vClasses);
2675 }
2676}
2677
2678
2679void
2680Vehicle::addSubscriptionFilterVType(const std::vector<std::string>& vTypes) {
2682 if (s != nullptr) {
2683 s->filterVTypes.insert(vTypes.begin(), vTypes.end());
2684 }
2685}
2686
2687
2688void
2689Vehicle::addSubscriptionFilterFieldOfVision(double openingAngle) {
2691 if (s != nullptr) {
2692 s->filterFieldOfVisionOpeningAngle = openingAngle;
2693 }
2694}
2695
2696
2697void
2698Vehicle::addSubscriptionFilterLateralDistance(double lateralDist, double downstreamDist, double upstreamDist) {
2700 if (s != nullptr) {
2701 s->filterLateralDist = lateralDist;
2702 }
2703 if (downstreamDist != INVALID_DOUBLE_VALUE) {
2704 addSubscriptionFilterDownstreamDistance(downstreamDist);
2705 }
2706 if (upstreamDist != INVALID_DOUBLE_VALUE) {
2707 addSubscriptionFilterUpstreamDistance(upstreamDist);
2708 }
2709}
2710
2711
2712void
2713Vehicle::storeShape(const std::string& id, PositionVector& shape) {
2714 shape.push_back(Helper::getVehicle(id)->getPosition());
2715}
2716
2717
2718std::shared_ptr<VariableWrapper>
2719Vehicle::makeWrapper() {
2720 return std::make_shared<Helper::SubscriptionWrapper>(handleVariable, mySubscriptionResults, myContextSubscriptionResults);
2721}
2722
2723
2724bool
2725Vehicle::handleVariable(const std::string& objID, const int variable, VariableWrapper* wrapper, tcpip::Storage* paramData) {
2726 switch (variable) {
2727 case TRACI_ID_LIST:
2728 return wrapper->wrapStringList(objID, variable, getIDList());
2729 case ID_COUNT:
2730 return wrapper->wrapInt(objID, variable, getIDCount());
2731 case VAR_POSITION:
2732 return wrapper->wrapPosition(objID, variable, getPosition(objID));
2733 case VAR_POSITION3D:
2734 return wrapper->wrapPosition(objID, variable, getPosition(objID, true));
2735 case VAR_ANGLE:
2736 return wrapper->wrapDouble(objID, variable, getAngle(objID));
2737 case VAR_SPEED:
2738 return wrapper->wrapDouble(objID, variable, getSpeed(objID));
2739 case VAR_SPEED_LAT:
2740 return wrapper->wrapDouble(objID, variable, getLateralSpeed(objID));
2741 case VAR_ROAD_ID:
2742 return wrapper->wrapString(objID, variable, getRoadID(objID));
2744 return wrapper->wrapDouble(objID, variable, getSpeedWithoutTraCI(objID));
2745 case VAR_SLOPE:
2746 return wrapper->wrapDouble(objID, variable, getSlope(objID));
2747 case VAR_LANE_ID:
2748 return wrapper->wrapString(objID, variable, getLaneID(objID));
2749 case VAR_LANE_INDEX:
2750 return wrapper->wrapInt(objID, variable, getLaneIndex(objID));
2751 case VAR_TYPE:
2752 return wrapper->wrapString(objID, variable, getTypeID(objID));
2753 case VAR_ROUTE_ID:
2754 return wrapper->wrapString(objID, variable, getRouteID(objID));
2755 case VAR_DEPARTURE:
2756 return wrapper->wrapDouble(objID, variable, getDeparture(objID));
2757 case VAR_DEPART_DELAY:
2758 return wrapper->wrapDouble(objID, variable, getDepartDelay(objID));
2759 case VAR_ROUTE_INDEX:
2760 return wrapper->wrapInt(objID, variable, getRouteIndex(objID));
2761 case VAR_COLOR:
2762 return wrapper->wrapColor(objID, variable, getColor(objID));
2763 case VAR_LANEPOSITION:
2764 return wrapper->wrapDouble(objID, variable, getLanePosition(objID));
2766 return wrapper->wrapDouble(objID, variable, getLateralLanePosition(objID));
2767 case VAR_CO2EMISSION:
2768 return wrapper->wrapDouble(objID, variable, getCO2Emission(objID));
2769 case VAR_COEMISSION:
2770 return wrapper->wrapDouble(objID, variable, getCOEmission(objID));
2771 case VAR_HCEMISSION:
2772 return wrapper->wrapDouble(objID, variable, getHCEmission(objID));
2773 case VAR_PMXEMISSION:
2774 return wrapper->wrapDouble(objID, variable, getPMxEmission(objID));
2775 case VAR_NOXEMISSION:
2776 return wrapper->wrapDouble(objID, variable, getNOxEmission(objID));
2778 return wrapper->wrapDouble(objID, variable, getFuelConsumption(objID));
2779 case VAR_NOISEEMISSION:
2780 return wrapper->wrapDouble(objID, variable, getNoiseEmission(objID));
2782 return wrapper->wrapDouble(objID, variable, getElectricityConsumption(objID));
2783 case VAR_PERSON_NUMBER:
2784 return wrapper->wrapInt(objID, variable, getPersonNumber(objID));
2786 return wrapper->wrapInt(objID, variable, getPersonCapacity(objID));
2788 return wrapper->wrapDouble(objID, variable, getBoardingDuration(objID));
2790 return wrapper->wrapStringList(objID, variable, getPersonIDList(objID));
2791 case VAR_WAITING_TIME:
2792 return wrapper->wrapDouble(objID, variable, getWaitingTime(objID));
2794 return wrapper->wrapDouble(objID, variable, getAccumulatedWaitingTime(objID));
2795 case VAR_ROUTE_VALID:
2796 return wrapper->wrapInt(objID, variable, isRouteValid(objID));
2797 case VAR_EDGES:
2798 return wrapper->wrapStringList(objID, variable, getRoute(objID));
2799 case VAR_SIGNALS:
2800 return wrapper->wrapInt(objID, variable, getSignals(objID));
2801 case VAR_STOPSTATE:
2802 return wrapper->wrapInt(objID, variable, getStopState(objID));
2803 case VAR_DISTANCE:
2804 return wrapper->wrapDouble(objID, variable, getDistance(objID));
2805 case VAR_ALLOWED_SPEED:
2806 return wrapper->wrapDouble(objID, variable, getAllowedSpeed(objID));
2807 case VAR_SPEED_FACTOR:
2808 return wrapper->wrapDouble(objID, variable, getSpeedFactor(objID));
2809 case VAR_SPEEDSETMODE:
2810 return wrapper->wrapInt(objID, variable, getSpeedMode(objID));
2812 return wrapper->wrapInt(objID, variable, getLaneChangeMode(objID));
2813 case VAR_ROUTING_MODE:
2814 return wrapper->wrapInt(objID, variable, getRoutingMode(objID));
2815 case VAR_LINE:
2816 return wrapper->wrapString(objID, variable, getLine(objID));
2817 case VAR_VIA:
2818 return wrapper->wrapStringList(objID, variable, getVia(objID));
2819 case VAR_ACCELERATION:
2820 return wrapper->wrapDouble(objID, variable, getAcceleration(objID));
2821 case VAR_LASTACTIONTIME:
2822 return wrapper->wrapDouble(objID, variable, getLastActionTime(objID));
2823 case VAR_STOP_DELAY:
2824 return wrapper->wrapDouble(objID, variable, getStopDelay(objID));
2825 case VAR_IMPATIENCE:
2826 return wrapper->wrapDouble(objID, variable, getImpatience(objID));
2828 return wrapper->wrapDouble(objID, variable, getStopArrivalDelay(objID));
2829 case VAR_TIMELOSS:
2830 return wrapper->wrapDouble(objID, variable, getTimeLoss(objID));
2831 case VAR_MINGAP_LAT:
2832 return wrapper->wrapDouble(objID, variable, getMinGapLat(objID));
2833 case VAR_LEADER: {
2834 paramData->readUnsignedByte();
2835 const double dist = paramData->readDouble();
2836 return wrapper->wrapStringDoublePair(objID, variable, getLeader(objID, dist));
2837 }
2838 case VAR_FOLLOWER: {
2839 paramData->readUnsignedByte();
2840 const double dist = paramData->readDouble();
2841 return wrapper->wrapStringDoublePair(objID, variable, getFollower(objID, dist));
2842 }
2843 case VAR_LOADED_LIST:
2844 return wrapper->wrapStringList(objID, variable, getLoadedIDList());
2846 return wrapper->wrapStringList(objID, variable, getTeleportingIDList());
2848 paramData->readUnsignedByte();
2849 return wrapper->wrapString(objID, variable, getParameter(objID, paramData->readString()));
2851 paramData->readUnsignedByte();
2852 return wrapper->wrapStringPair(objID, variable, getParameterWithKey(objID, paramData->readString()));
2853 case VAR_TAXI_FLEET:
2854 // we cannot use the general fall through here because we do not have an object id
2855 return false;
2856 default:
2857 return VehicleType::handleVariableWithID(objID, getTypeID(objID), variable, wrapper, paramData);
2858 }
2859}
2860
2861
2862}
2863
2864
2865/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
@ GLO_VEHICLE
a vehicle
std::vector< const MSEdge * > ConstMSEdgeVector
Definition MSEdge.h:74
std::vector< MSEdge * > MSEdgeVector
Definition MSEdge.h:73
std::pair< const MSVehicle *, double > CLeaderDist
ConstMSEdgeVector::const_iterator MSRouteIterator
Definition MSRoute.h:56
#define WRITE_WARNINGF(...)
Definition MsgHandler.h:271
#define WRITE_ERROR(msg)
Definition MsgHandler.h:279
#define WRITE_WARNING(msg)
Definition MsgHandler.h:270
#define TL(string)
Definition MsgHandler.h:287
#define TLF(string,...)
Definition MsgHandler.h:288
std::shared_ptr< const MSRoute > ConstMSRoutePtr
Definition Route.h:32
SUMOTime DELTA_T
Definition SUMOTime.cpp:38
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
Definition SUMOTime.cpp:46
std::string time2string(SUMOTime t, bool humanReadable)
convert SUMOTime to string (independently of global format setting)
Definition SUMOTime.cpp:69
#define STEPS2TIME(x)
Definition SUMOTime.h:55
#define SPEED2DIST(x)
Definition SUMOTime.h:45
#define SUMOTime_MAX
Definition SUMOTime.h:34
#define SIMTIME
Definition SUMOTime.h:62
#define TIME2STEPS(x)
Definition SUMOTime.h:57
LatAlignmentDefinition
Possible ways to choose the lateral alignment, i.e., how vehicles align themselves within their lane.
SUMOVehicleClass getVehicleClassID(const std::string &name)
Returns the class id of the abstract class given by its name.
SUMOVehicleShape getVehicleShapeID(const std::string &name)
Returns the class id of the shape class given by its name.
SVCPermissions parseVehicleClasses(const std::string &allowedS)
Parses the given definition of allowed vehicle classes into the given containers Deprecated classes g...
std::string getVehicleShapeName(SUMOVehicleShape id)
Returns the class name of the shape class given by its id.
StringBijection< SUMOVehicleClass > SumoVehicleClassStrings(sumoVehicleClassStringInitializer, SVC_CUSTOM2, false)
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
@ SVC_IGNORING
vehicles ignoring classes
const int STOP_ARRIVAL_SET
const int STOP_DURATION_SET
const int VEHPARS_COLOR_SET
const int STOP_POSLAT_SET
const int STOP_EXPECTED_SET
const int VEHPARS_TO_TAZ_SET
const int STOP_SPEED_SET
const int STOP_UNTIL_SET
const int STOP_LINE_SET
const int STOP_PARKING_SET
const int STOP_TRIP_ID_SET
const int VEHPARS_DEPARTPOS_SET
const int STOP_PERMITTED_SET
const int VEHPARS_ARRIVALLANE_SET
const int VEHPARS_DEPARTLANE_SET
const int STOP_SPLIT_SET
const int STOP_START_SET
const int VEHPARS_FROM_TAZ_SET
const int STOP_JOIN_SET
const int VEHPARS_ARRIVALSPEED_SET
const int STOP_EXTENSION_SET
const int VEHPARS_FORCE_REROUTE
const int STOP_ENDED_SET
const int STOP_TRIGGER_SET
const int STOP_ONDEMAND_SET
const int STOP_END_SET
const int VEHPARS_LINE_SET
const int STOP_STARTED_SET
const int VEHPARS_PERSON_NUMBER_SET
const int STOP_EXPECTED_CONTAINERS_SET
const int VEHPARS_DEPARTSPEED_SET
const int VEHPARS_VTYPE_SET
const int VEHPARS_ARRIVALPOS_SET
@ GIVEN
The time is given.
@ NOW
The vehicle is discarded if emission fails (not fully implemented yet)
@ CONTAINER_TRIGGERED
The departure is container triggered.
@ TRIGGERED
The departure is person triggered.
@ LCA_UNKNOWN
The action has not been determined.
@ SUMO_ATTR_STARTPOS
@ SUMO_ATTR_PARKING
@ SUMO_ATTR_EXTENSION
@ SUMO_ATTR_LANE
@ SUMO_ATTR_SPEED
@ SUMO_ATTR_STARTED
@ SUMO_ATTR_CONTAINER_STOP
@ SUMO_ATTR_PARKING_AREA
@ SUMO_ATTR_EDGE
@ SUMO_ATTR_BUS_STOP
@ SUMO_ATTR_TRAIN_STOP
@ SUMO_ATTR_ENDPOS
@ SUMO_ATTR_SPLIT
@ SUMO_ATTR_ACTTYPE
@ SUMO_ATTR_POSITION_LAT
@ SUMO_ATTR_EXPECTED
@ SUMO_ATTR_LINE
@ SUMO_ATTR_CHARGING_STATION
@ SUMO_ATTR_ENDED
@ SUMO_ATTR_ONDEMAND
@ SUMO_ATTR_INDEX
@ SUMO_ATTR_ARRIVAL
@ SUMO_ATTR_TRIP_ID
@ SUMO_ATTR_PERMITTED
@ SUMO_ATTR_JOIN
@ SUMO_ATTR_EXPECTED_CONTAINERS
@ SUMO_ATTR_UNTIL
@ SUMO_ATTR_TRIGGERED
@ SUMO_ATTR_DURATION
const double INVALID_DOUBLE
invalid double
Definition StdDefs.h:64
T MIN2(T a, T b)
Definition StdDefs.h:76
T MAX2(T a, T b)
Definition StdDefs.h:82
std::string joinToString(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=gPrecision)
Definition ToString.h:283
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:46
#define LIBSUMO_SUBSCRIPTION_IMPLEMENTATION(CLASS, DOM)
Definition TraCIDefs.h:76
#define LIBSUMO_GET_PARAMETER_WITH_KEY_IMPLEMENTATION(CLASS)
Definition TraCIDefs.h:123
std::vector< double > & getParameter()
Returns the parameters of this distribution.
static PositionVector makeRing(const double radius1, const double radius2, const Position &center, unsigned int nPoints)
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)
A vehicle from the mesoscopic point of view.
Definition MEVehicle.h:42
SUMOTime getEventTime() const
Returns the (planned) time at which the vehicle leaves its current segment.
Definition MEVehicle.h:200
virtual double getSafetyFactor() const
return factor for modifying the safety constraints of the car-following model
virtual void setParameter(const std::string &key, const std::string &value)
try to set the given parameter for this laneChangeModel. Throw exception for unsupported key
void setExtraImpatience(double value)
Sets routing behavior.
SUMOAbstractRouter< MSEdge, SUMOVehicle > & getRouterTT(const int rngIndex, SUMOVehicleClass svc) const
void setRoutingMode(int value)
Sets routing behavior.
int getRoutingMode() const
return the current routing mode
The base class for microscopic and mesoscopic vehicles.
double getMaxSpeed() const
Returns the maximum speed (the minimum of desired and technical maximum speed)
MSVehicleDevice * getDevice(const std::type_info &type) const
Returns a device of the given type if it exists, nullptr otherwise.
double getImpatience() const
Returns this vehicles impatience.
virtual ConstMSEdgeVector::const_iterator getRerouteOrigin() const
Returns the starting point for reroutes (usually the current edge)
void resetRoutePosition(int index, DepartLaneDefinition departLaneProcedure)
reset index of edge within route
bool replaceStop(int nextStopIndex, SUMOVehicleParameter::Stop stop, const std::string &info, bool teleport, std::string &errorMsg)
void setChosenSpeedFactor(const double factor)
Returns the precomputed factor by which the driver wants to be faster than the speed limit.
void setCarFollowModelParameter(const std::string &key, const std::string &value)
set individual carFollow model parameters (not type related)
virtual double getStopDelay() const
Returns the estimated public transport stop (departure) delay in seconds.
bool rerouteBetweenStops(int nextStopIndex, const std::string &info, bool teleport, std::string &errorMsg)
const SUMOVehicleParameter & getParameter() const
Returns the vehicle's parameter (including departure definition)
double getChosenSpeedFactor() const
Returns the precomputed factor by which the driver wants to be faster than the speed limit.
virtual BaseInfluencer & getBaseInfluencer()=0
Returns the velocity/lane influencer.
virtual double getTimeLossSeconds() const
Returns the time loss in seconds.
double getOdometer() const
Returns the distance that was already driven by this vehicle.
MSVehicleType & getSingularType()
Replaces the current vehicle type with a new one used by this vehicle only.
virtual void replaceVehicleType(MSVehicleType *type)
Replaces the current vehicle type by the one given.
const MSRouteIterator & getCurrentRouteEdge() const
Returns an iterator pointing to the current edge in this vehicles route.
bool hasValidRoute(std::string &msg, ConstMSRoutePtr route=0) const
Validates the current or given route.
virtual void onRemovalFromNet(const MSMoveReminder::Notification)
Called when the vehicle is removed from the network.
double getLength() const
Returns the vehicle's length.
bool isParking() const
Returns whether the vehicle is parking.
const MSEdge * getEdge() const
Returns the edge the vehicle is currently at.
double getHarmonoise_NoiseEmissions() const
Returns noise emissions of the current state.
int getPersonNumber() const
Returns the number of persons.
void setJunctionModelParameter(const std::string &key, const std::string &value)
set individual junction model paramete (not type related)
bool hasDeparted() const
Returns whether this vehicle has already departed.
MSStop & getNextStop()
const std::list< MSStop > & getStops() const
SUMOTime getDeparture() const
Returns this vehicle's real departure time.
void setDeviceParameter(const std::string &deviceName, const std::string &key, const std::string &value)
try to set the given parameter from any of the vehicles devices, raise InvalidArgument if no device p...
bool hasStops() const
Returns whether the vehicle has to stop somewhere.
void addToOdometer(double value)
Manipulate the odometer.
std::string getPrefixedParameter(const std::string &key, std::string &error) const
retrieve parameters of devices, models and the vehicle itself
SUMOVehicleClass getVClass() const
Returns the vehicle's access class.
virtual double getStopArrivalDelay() const
Returns the estimated public transport stop arrival delay in seconds.
MSStop & getStop(int nextStopIndex)
virtual std::pair< const MSVehicle *const, double > getFollower(double dist=0) const
Returns the follower of the vehicle looking for a fixed distance.
bool insertStop(int nextStopIndex, SUMOVehicleParameter::Stop stop, const std::string &info, bool teleport, std::string &errorMsg)
std::vector< std::string > getPersonIDList() const
Returns the list of persons.
const MSEdgeWeightsStorage & getWeightsStorage() const
Returns the vehicle's internal edge travel times/efforts container.
const std::vector< SUMOVehicleParameter::Stop > & getPastStops() const
virtual bool addTraciStop(SUMOVehicleParameter::Stop stop, std::string &errorMsg)
const MSRoute & getRoute() const
Returns the current route.
int getRoutePosition() const
return index of edge within route
double getEmissions() const
Returns emissions of the current state The value is always per 1s, so multiply by step length if nece...
virtual bool replaceRoute(ConstMSRoutePtr route, const std::string &info, bool onInit=false, int offset=0, bool addStops=true, bool removeStops=true, std::string *msgReturn=nullptr)
Replaces the current route by the given one.
virtual bool isOnRoad() const
Returns the information whether the vehicle is on a road (is simulated)
void reroute(SUMOTime t, const std::string &info, SUMOAbstractRouter< MSEdge, SUMOVehicle > &router, const bool onInit=false, const bool withTaz=false, const bool silent=false)
Performs a rerouting using the given router.
virtual std::pair< const MSVehicle *const, double > getLeader(double dist=0) const
Returns the leader of the vehicle looking for a fixed distance.
int getRNGIndex() const
const MSVehicleType & getVehicleType() const
Returns the vehicle's type definition.
void createDevice(const std::string &deviceName)
create device of the given type
bool isStopped() const
Returns whether the vehicle is at a stop.
bool abortNextStop(int nextStopIndex=0)
deletes the next stop at the given index if it exists
bool replaceRouteEdges(ConstMSEdgeVector &edges, double cost, double savings, const std::string &info, bool onInit=false, bool check=false, bool removeStops=true, std::string *msgReturn=nullptr)
Replaces the current route by the given edges.
double getEmergencyDecel() const
Get the vehicle type's maximal phisically possible deceleration [m/s^2].
Definition MSCFModel.h:272
@ FUTURE
the return value is used for calculating future speeds
Definition MSCFModel.h:81
virtual double getSecureGap(const MSVehicle *const veh, const MSVehicle *const, const double speed, const double leaderSpeed, const double leaderMaxDecel) const
Returns the minimum gap to reserve if the leader is braking at maximum (>=0)
double getApparentDecel() const
Get the vehicle type's apparent deceleration [m/s^2] (the one regarded by its followers.
Definition MSCFModel.h:280
double getMaxAccel() const
Get the vehicle type's maximum acceleration [m/s^2].
Definition MSCFModel.h:256
double brakeGap(const double speed) const
Returns the distance the vehicle needs to halt including driver's reaction time tau (i....
Definition MSCFModel.h:380
virtual double getImperfection() const
Get the driver's imperfection.
Definition MSCFModel.h:303
double getMaxDecel() const
Get the vehicle type's maximal comfortable deceleration [m/s^2].
Definition MSCFModel.h:264
virtual double followSpeed(const MSVehicle *const veh, double speed, double gap2pred, double predSpeed, double predMaxDecel, const MSVehicle *const pred=0, const CalcReason usage=CalcReason::CURRENT) const =0
Computes the vehicle's follow speed (no dawdling)
double stopSpeed(const MSVehicle *const veh, const double speed, double gap, const CalcReason usage=CalcReason::CURRENT) const
Computes the vehicle's safe speed for approaching a non-moving obstacle (no dawdling)
Definition MSCFModel.h:168
virtual double getHeadwayTime() const
Get the driver's desired headway [s].
Definition MSCFModel.h:311
A device which collects info on the vehicle trip (mainly on departure and arrival)
static const std::vector< MSDevice_Taxi * > & getFleet()
static MSDispatch * getDispatchAlgorithm()
A dispatch algorithm that services customers in reservation order and always sends the closest availa...
void interpretDispatch(MSDevice_Taxi *taxi, const std::vector< std::string > &reservationsIDs)
trigger taxi dispatch.
An algorithm that performs distpach for a taxi fleet.
Definition MSDispatch.h:102
A road/street connecting two junctions.
Definition MSEdge.h:77
static const MSEdgeVector & getAllEdges()
Returns all edges with a numerical id.
Definition MSEdge.cpp:984
static void parseEdgesList(const std::string &desc, ConstMSEdgeVector &into, const std::string &rid)
Parses the given string assuming it contains a list of edge ids divided by spaces.
Definition MSEdge.cpp:1008
const std::vector< MSLane * > * allowedLanes(const MSEdge &destination, SUMOVehicleClass vclass=SVC_IGNORING) const
Get the allowed lanes to reach the destination-edge.
Definition MSEdge.cpp:439
bool isInternal() const
return whether this edge is an internal edge
Definition MSEdge.h:265
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:945
double getVehicleMaxSpeed(const SUMOTrafficObject *const veh) const
Returns the maximum speed the vehicle may use on this edge.
Definition MSEdge.cpp:1068
const MSEdge * getNormalBefore() const
if this edge is an internal edge, return its first normal predecessor, otherwise the edge itself
Definition MSEdge.cpp:835
bool retrieveExistingTravelTime(const MSEdge *const e, const double t, double &value) const
Returns a travel time for an edge and time if stored.
bool knowsTravelTime(const MSEdge *const e) const
Returns the information whether any travel time is known for the given edge.
void addTravelTime(const MSEdge *const e, double begin, double end, double value)
Adds a travel time information for an edge and a time span.
void removeEffort(const MSEdge *const e)
Removes the effort information for an edge.
bool knowsEffort(const MSEdge *const e) const
Returns the information whether any effort is known for the given edge.
void addEffort(const MSEdge *const e, double begin, double end, double value)
Adds an effort information for an edge and a time span.
bool retrieveExistingEffort(const MSEdge *const e, const double t, double &value) const
Returns an effort for an edge and time if stored.
void removeTravelTime(const MSEdge *const e)
Removes the travel time information for an edge.
static bool gCheckRoutes
Definition MSGlobals.h:88
static double gLateralResolution
Definition MSGlobals.h:97
static bool gSemiImplicitEulerUpdate
Definition MSGlobals.h:53
void alreadyDeparted(SUMOVehicle *veh)
stops trying to emit the given vehicle (because it already departed)
void add(SUMOVehicle *veh)
Adds a single vehicle for departure.
virtual const MSJunctionLogic * getLogic() const
Definition MSJunction.h:143
virtual const MSLogicJunction::LinkBits & getResponseFor(int linkIndex) const
Returns the response for the given link.
Representation of a lane in the micro simulation.
Definition MSLane.h:84
MSLane * getParallelLane(int offset, bool includeOpposite=true) const
Returns the lane with the given offset parallel to this one or 0 if it does not exist.
Definition MSLane.cpp:2653
virtual MSVehicle * removeVehicle(MSVehicle *remVehicle, MSMoveReminder::Notification notification, bool notify=true)
Definition MSLane.cpp:2635
static std::vector< MSLink * >::const_iterator succLinkSec(const SUMOVehicle &veh, int nRouteSuccs, const MSLane &succLinkSource, const std::vector< MSLane * > &conts)
Definition MSLane.cpp:2511
void forceVehicleInsertion(MSVehicle *veh, double pos, MSMoveReminder::Notification notification, double posLat=0)
Inserts the given vehicle at the given position.
Definition MSLane.cpp:1295
double getSpeedLimit() const
Returns the lane's maximum allowed speed.
Definition MSLane.h:579
const MSEdge * getNextNormal() const
Returns the lane's follower if it is an internal lane, the edge of the lane otherwise.
Definition MSLane.cpp:2301
void addLeaders(const MSVehicle *vehicle, double vehPos, MSLeaderDistanceInfo &result, bool oppositeDirection=false)
get leaders for ego on the given lane
Definition MSLane.cpp:3925
double getLength() const
Returns the lane's length.
Definition MSLane.h:593
bool isLinkEnd(std::vector< MSLink * >::const_iterator &i) const
Definition MSLane.h:834
int getIndex() const
Returns the lane's index.
Definition MSLane.h:629
double getOppositePos(double pos) const
return the corresponding position on the opposite lane
Definition MSLane.cpp:4172
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition MSLane.cpp:2325
bool isInternal() const
Definition MSLane.cpp:2456
virtual const PositionVector & getShape(bool) const
Definition MSLane.h:293
MSEdge & getEdge() const
Returns the lane's edge.
Definition MSLane.h:745
MSLeaderDistanceInfo getFollowersOnConsecutive(const MSVehicle *ego, double backOffset, bool allSublanes, double searchDist=-1, MinorLinkMode mLinkMode=FOLLOW_ALWAYS) const
return the sublane followers with the largest missing rear gap among all predecessor lanes (within di...
Definition MSLane.cpp:3589
double getWidth() const
Returns the lane's width.
Definition MSLane.h:622
const std::vector< MSLink * > & getLinkCont() const
returns the container with all links !!!
Definition MSLane.h:707
const Position geometryPositionAtOffset(double offset, double lateralOffset=0) const
Definition MSLane.h:551
saves leader/follower vehicles and their distances relative to an ego vehicle
void fixOppositeGaps(bool isFollower)
subtract vehicle length from all gaps if the leader vehicle is driving in the opposite direction
virtual int addLeader(const MSVehicle *veh, double gap, double latOffset=0, int sublane=-1)
int numSublanes() const
bool hasVehicles() const
Notification
Definition of a vehicle state.
@ NOTIFICATION_VAPORIZED_TRACI
The vehicle got removed via TraCI.
@ NOTIFICATION_ARRIVED
The vehicle arrived at its destination (is deleted)
@ NOTIFICATION_TELEPORT_ARRIVED
The vehicle was teleported out of the net.
@ NOTIFICATION_DEPARTED
The vehicle has departed (was inserted into the network)
@ NOTIFICATION_JUNCTION
The vehicle arrived at a junction.
@ NOTIFICATION_TELEPORT
The vehicle is being teleported.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition MSNet.cpp:183
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition MSNet.h:322
MSInsertionControl & getInsertionControl()
Returns the insertion control.
Definition MSNet.h:433
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition MSNet.h:380
const ConstMSEdgeVector & getEdges() const
Definition MSRoute.h:124
MSRouteIterator end() const
Returns the end of the list of edges to pass.
Definition MSRoute.cpp:79
double getDistanceBetween(double fromPos, double toPos, const MSEdge *fromEdge, const MSEdge *toEdge, bool includeInternal=true, int routePosition=0) const
Compute the distance between 2 given edges on this route, including the length of internal lanes....
Definition MSRoute.cpp:311
static bool dictionary(const std::string &id, ConstMSRoutePtr route)
Adds a route to the dictionary.
Definition MSRoute.cpp:109
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition MSRoute.cpp:73
const MSLane * lane
The lane to stop at (microsim only)
Definition MSStop.h:50
void initPars(const SUMOVehicleParameter::Stop &stopPar)
initialize attributes from the given stop parameters
Definition MSStop.cpp:112
int getStateFlagsOld() const
return flags as used by Vehicle::getStopState
Definition MSStop.cpp:128
bool reached
Information whether the stop has been reached.
Definition MSStop.h:75
MSRouteIterator edge
The edge in the route to stop at.
Definition MSStop.h:48
SUMOTime duration
The stopping duration.
Definition MSStop.h:67
const SUMOVehicleParameter::Stop pars
The stop parameter.
Definition MSStop.h:65
void setLaneChangeMode(int value)
Sets lane changing behavior.
void deactivateGapController()
Deactivates the gap control.
void setSpeedMode(int speedMode)
Sets speed-constraining behaviors.
void setLaneTimeLine(const std::vector< std::pair< SUMOTime, int > > &laneTimeLine)
Sets a new lane timeline.
void setSublaneChange(double latDist)
Sets a new sublane-change request.
void setSignals(int signals)
Definition MSVehicle.h:1583
void setSpeedTimeLine(const std::vector< std::pair< SUMOTime, double > > &speedTimeLine)
Sets a new velocity timeline.
void activateGapController(double originalTau, double newTimeHeadway, double newSpaceHeadway, double duration, double changeRate, double maxDecel, MSVehicle *refVeh=nullptr)
Activates the gap control with the given parameters,.
The class responsible for building and deletion of vehicles.
virtual SUMOVehicle * buildVehicle(SUMOVehicleParameter *defs, ConstMSRoutePtr route, MSVehicleType *type, const bool ignoreStopErrors, const bool fromRouteFile=true, bool addRouteStops=true)
Builds a vehicle, increases the number of built vehicles.
void removePending()
Removes a vehicle after it has ended.
virtual void deleteVehicle(SUMOVehicle *v, bool discard=false)
Deletes the vehicle.
virtual bool addVehicle(const std::string &id, SUMOVehicle *v)
Tries to insert the vehicle into the internal vehicle container.
SUMOVehicle * getVehicle(const std::string &id) const
Returns the vehicle with the given id.
MSVehicleType * getVType(const std::string &id=DEFAULT_VTYPE_ID, SumoRNG *rng=nullptr, bool readOnly=false)
Returns the named vehicle type or a sample from the named distribution.
std::map< std::string, SUMOVehicle * >::const_iterator constVehIt
Definition of the internal vehicles map iterator.
void scheduleVehicleRemoval(SUMOVehicle *veh, bool checkDuplicate=false)
Removes a vehicle after it has ended.
constVehIt loadedVehBegin() const
Returns the begin of the internal vehicle map.
constVehIt loadedVehEnd() const
Returns the end of the internal vehicle map.
Representation of a vehicle in the micro simulation.
Definition MSVehicle.h:77
void updateBestLanes(bool forceRebuild=false, const MSLane *startLane=0)
computes the best lanes to use in order to continue the route
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:608
SUMOTime getLastActionTime() const
Returns the time of the vehicle's last action point.
Definition MSVehicle.h:544
void setTentativeLaneAndPosition(MSLane *lane, double pos, double posLat=0)
set tentative lane and position during insertion to ensure that all cfmodels work (some of them requi...
void setPreviousSpeed(double prevSpeed, double prevAcceleration)
Sets the influenced previous speed.
MSAbstractLaneChangeModel & getLaneChangeModel()
Position getPosition(const double offset=0) const
Return current position (x/y, cartesian)
const std::vector< MSLane * > & getBestLanesContinuation() const
Returns the best sequence of lanes to continue the route starting at myLane.
void onRemovalFromNet(const MSMoveReminder::Notification reason)
Called when the vehicle is removed from the network.
bool resumeFromStopping()
double getBackPositionOnLane(const MSLane *lane) const
Get the vehicle's position relative to the given lane.
Definition MSVehicle.h:401
void resetActionOffset(const SUMOTime timeUntilNextAction=0)
Resets the action offset for the vehicle.
bool rerouteParkingArea(const std::string &parkingAreaID, std::string &errorMsg)
void switchOffSignal(int signal)
Switches the given signal off.
Definition MSVehicle.h:1174
@ VEH_SIGNAL_NONE
Everything is switched off.
Definition MSVehicle.h:1111
const MSLane * getLane() const
Returns the lane the vehicle is on.
Definition MSVehicle.h:584
MSLane * getMutableLane() const
Returns the lane the vehicle is on Non const version indicates that something volatile is going on.
Definition MSVehicle.h:592
BaseInfluencer & getBaseInfluencer()
Returns the velocity/lane influencer.
Influencer & getInfluencer()
void setActionStepLength(double actionStepLength, bool resetActionOffset=true)
Sets the action steplength of the vehicle.
double getLateralPositionOnLane() const
Get the vehicle's lateral position on the lane.
Definition MSVehicle.h:416
double getSpeed() const
Returns the vehicle's current speed.
Definition MSVehicle.h:493
const std::vector< LaneQ > & getBestLanes() const
Returns the description of best lanes to use in order to continue the route.
const MSCFModel & getCarFollowModel() const
Returns the vehicle's car following model definition.
Definition MSVehicle.h:978
double getPositionOnLane() const
Get the vehicle's position along the lane.
Definition MSVehicle.h:377
bool hasInfluencer() const
whether the vehicle is individually influenced (via TraCI or special parameters)
Definition MSVehicle.h:1682
void setLateralPositionOnLane(double posLat)
Definition MSVehicle.h:420
void switchOnSignal(int signal)
Switches the given signal on.
Definition MSVehicle.h:1166
int getLaneIndex() const
The car-following model and parameter.
void setHeight(const double &height)
Set a new value for this type's height.
void setMaxSpeedLat(const double &maxSpeedLat)
Set a new value for this type's maximum lateral speed.
double getMinGapLat() const
Get the minimum lateral gap that vehicles of this type maintain.
double getWidth() const
Get the width which vehicles of this class shall have when being drawn.
SUMOVehicleClass getVehicleClass() const
Get this vehicle type's vehicle class.
void setEmissionClass(SUMOEmissionClass eclass)
Set a new value for this type's emission class.
double getMaxSpeed() const
Get vehicle's (technical) maximum speed [m/s].
int getPersonCapacity() const
Get this vehicle type's person capacity.
const std::string & getID() const
Returns the name of the vehicle type.
void setMinGapLat(const double &minGapLat)
Set a new value for this type's minimum lataral gap.
double getMinGap() const
Get the free space in front of vehicles of this class.
void setApparentDecel(double apparentDecel)
Set a new value for this type's apparent deceleration.
double getHeight() const
Get the height which vehicles of this class shall have when being drawn.
void setMaxSpeed(const double &maxSpeed)
Set a new value for this type's maximum speed.
const Distribution_Parameterized & getSpeedFactor() const
Returns this type's speed factor.
void setBoardingDuration(SUMOTime duration, bool isPerson=true)
Set a new value for this type's boardingDuration.
double getActionStepLengthSecs() const
Returns this type's default action step length in seconds.
void setLength(const double &length)
Set a new value for this type's length.
double getMaxSpeedLat() const
Get vehicle's maximum lateral speed [m/s].
void setVClass(SUMOVehicleClass vclass)
Set a new value for this type's vehicle class.
void setAccel(double accel)
Set a new value for this type's acceleration.
const MSCFModel & getCarFollowModel() const
Returns the vehicle type's car following model definition (const version)
void setWidth(const double &width)
Set a new value for this type's width.
void setImperfection(double imperfection)
Set a new value for this type's imperfection.
void setPreferredLateralAlignment(const LatAlignmentDefinition &latAlignment, double latAlignmentOffset=0.0)
Set vehicle's preferred lateral alignment.
void setTau(double tau)
Set a new value for this type's headway.
double getLength() const
Get vehicle's length [m].
void setMinGap(const double &minGap)
Set a new value for this type's minimum gap.
void setShape(SUMOVehicleShape shape)
Set a new value for this type's shape.
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
virtual const std::string getParameter(const std::string &key, const std::string defaultValue="") const
Returns the value for a given key.
virtual void setParameter(const std::string &key, const std::string &value)
Sets a parameter.
static std::string getName(const SUMOEmissionClass c)
Checks whether the string describes a known vehicle class.
static SUMOEmissionClass getClassByName(const std::string &eClass, const SUMOVehicleClass vc=SVC_IGNORING)
Checks whether the string describes a known vehicle class.
A point in 2D or 3D with translation and scaling methods.
Definition Position.h:37
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
Definition Position.h:254
void sub(double dx, double dy)
Subtracts the given position from this one.
Definition Position.h:145
void setz(double z)
set position z
Definition Position.h:80
double z() const
Returns the z-position.
Definition Position.h:65
double angleTo2D(const Position &other) const
returns the angle in the plane of the vector pointing from here to the other position
Definition Position.h:264
A list of positions.
double rotationAtOffset(double pos) const
Returns the rotation 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 move2side(double amount, double maxExtension=100)
move position vector to side using certain ammount
void set(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
assigns new values
Definition RGBColor.cpp:98
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...
virtual double getSlope() const =0
Returns the slope of the road at object's position in degrees.
virtual const MSLane * getLane() const =0
Returns the lane the object is currently at.
virtual double getPreviousSpeed() const =0
Returns the object's previous speed.
virtual double getSpeed() const =0
Returns the object's current speed.
virtual Position getPosition(const double offset=0) const =0
Return current position (x/y, cartesian)
virtual double getPositionOnLane() const =0
Get the object's position along the lane.
static double getDefaultDecel(const SUMOVehicleClass vc=SVC_IGNORING)
Returns the default deceleration for the given vehicle class This needs to be a function because the ...
static const SUMOVTypeParameter & getDefault()
return the default parameters, this is a function due to the http://www.parashift....
static bool parseLatAlignment(const std::string &val, double &lao, LatAlignmentDefinition &lad)
Parses and validates a given latAlignment value.
Representation of a vehicle.
Definition SUMOVehicle.h:62
virtual int getRouteValidity(bool update=true, bool silent=false, std::string *msgReturn=nullptr)=0
computes validity attributes for the current route
virtual bool wasRemoteControlled(SUMOTime lookBack=DELTA_T) const =0
Returns the information whether the vehicle is fully controlled via TraCI.
virtual bool hasDeparted() const =0
Returns whether this vehicle has departed.
virtual bool isOnRoad() const =0
Returns the information whether the vehicle is on a road (is simulated)
virtual bool isParking() const =0
Returns the information whether the vehicle is parked.
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 (used only in netedit)
ParkingType parking
whether the vehicle is removed from the net while stopping
std::string lane
The lane to stop at.
SUMOTime extension
The maximum time extension for boarding / loading.
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
double posLat
the lateral offset when stopping
bool onDemand
whether the stop may be skipped
std::string chargingStation
(Optional) charging station if one is assigned to the stop
std::vector< std::string > getTriggers() const
write trigger attribute
std::set< std::string > permitted
IDs of persons or containers that may board/load at this stop.
int parametersSet
Information for the output which parameter were set.
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)
SUMOTime ended
the time at which this stop was ended
double endPos
The stopping position end.
std::set< std::string > awaitedPersons
IDs of persons the vehicle has to wait for until departing.
std::set< std::string > awaitedContainers
IDs of containers the vehicle has to wait for until departing.
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
SUMOTime arrival
The (expected) time at which the vehicle reaches the stop.
SUMOTime duration
The stopping duration.
Structure representing possible vehicle parameter.
int parametersSet
Information for the router which parameter were set, TraCI may modify this (when changing color)
int departLane
(optional) The lane the vehicle shall depart from (index in edge)
ArrivalSpeedDefinition arrivalSpeedProcedure
Information how the vehicle's end speed shall be chosen.
double departSpeed
(optional) The initial speed of the vehicle
std::string vtypeid
The vehicle's type id.
std::vector< std::string > via
List of the via-edges the vehicle must visit.
static bool parseArrivalLane(const std::string &val, const std::string &element, const std::string &id, int &lane, ArrivalLaneDefinition &ald, std::string &error)
Validates a given arrivalLane value.
ArrivalLaneDefinition arrivalLaneProcedure
Information how the vehicle shall choose the lane to arrive on.
DepartLaneDefinition departLaneProcedure
Information how the vehicle shall choose the lane to depart from.
static bool parseDepartSpeed(const std::string &val, const std::string &element, const std::string &id, double &speed, DepartSpeedDefinition &dsd, std::string &error)
Validates a given departSpeed value.
static bool parseArrivalPos(const std::string &val, const std::string &element, const std::string &id, double &pos, ArrivalPosDefinition &apd, std::string &error)
Validates a given arrivalPos value.
int personNumber
The static number of persons in the vehicle when it departs (not including boarding persons)
static bool parseArrivalSpeed(const std::string &val, const std::string &element, const std::string &id, double &speed, ArrivalSpeedDefinition &asd, std::string &error)
Validates a given arrivalSpeed value.
double departPos
(optional) The position the vehicle shall depart from
DepartSpeedDefinition departSpeedProcedure
Information how the vehicle's initial speed shall be chosen.
RGBColor color
The vehicle's color, TraCI may change this.
double arrivalPos
(optional) The position the vehicle shall arrive on
static bool parseDepartLane(const std::string &val, const std::string &element, const std::string &id, int &lane, DepartLaneDefinition &dld, std::string &error)
Validates a given departLane value.
std::string id
The vehicle's id.
static bool parseDepart(const std::string &val, const std::string &element, const std::string &id, SUMOTime &depart, DepartDefinition &dd, std::string &error, const std::string &attr="departure")
Validates a given depart value.
bool wasSet(int what) const
Returns whether the given parameter was set.
ArrivalPosDefinition arrivalPosProcedure
Information how the vehicle shall choose the arrival position.
std::string toTaz
The vehicle's destination zone (district)
double arrivalSpeed
(optional) The final speed of the vehicle (not used yet)
DepartDefinition departProcedure
Information how the vehicle shall choose the depart time.
static bool parseDepartPos(const std::string &val, const std::string &element, const std::string &id, double &pos, DepartPosDefinition &dpd, std::string &error)
Validates a given departPos value.
std::string fromTaz
The vehicle's origin zone (district)
DepartPosDefinition departPosProcedure
Information how the vehicle shall choose the departure position.
std::string line
The vehicle's line (mainly for public transport)
static ParkingType parseParkingType(const std::string &value)
parses parking type value
static void parseStopTriggers(const std::vector< std::string > &triggers, bool expectTrigger, Stop &stop)
parses stop trigger values
static StringBijection< LinkState > LinkStates
link states
static int getIndexFromLane(const std::string laneID)
return lane index when given the lane ID
static StringBijection< LinkDirection > LinkDirections
link directions
const std::string & getString(const T key) const
std::set< std::string > getSet()
return set of strings
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter
static bool startsWith(const std::string &str, const std::string prefix)
Checks whether a given string starts with the prefix.
static bool endsWith(const std::string &str, const std::string suffix)
Checks whether a given string ends with the suffix.
static int toInt(const std::string &sData)
converts a string into the integer value described by it by calling the char-type converter,...
static bool toBool(const std::string &sData)
converts a string into the bool value described by it by calling the char-type converter
C++ TraCI client API implementation.
static MSEdge * getEdge(const std::string &edgeID)
Definition Helper.cpp:393
static TraCIPosition makeTraCIPosition(const Position &position, const bool includeZ=false)
Definition Helper.cpp:377
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:1725
static TraCIPositionVector makeTraCIPositionVector(const PositionVector &positionVector)
helper functions
Definition Helper.cpp:337
static MSBaseVehicle * getVehicle(const std::string &id)
Definition Helper.cpp:477
static TraCIColor makeTraCIColor(const RGBColor &color)
Definition Helper.cpp:360
static TraCINextStopData buildStopData(const SUMOVehicleParameter::Stop &stopPar)
Definition Helper.cpp:637
static void setRemoteControlled(MSVehicle *v, Position xyPos, MSLane *l, double pos, double posLat, double angle, int edgeOffset, ConstMSEdgeVector route, SUMOTime t)
Definition Helper.cpp:1377
static const MSVehicleType & getVehicleType(const std::string &vehicleID)
Definition Helper.cpp:512
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, bool setLateralPos, double &bestDistance, MSLane **lane, double &lanePos, int &routeOffset, ConstMSEdgeVector &edges)
Definition Helper.cpp:1417
static std::pair< MSLane *, double > convertCartesianToRoadMap(const Position &pos, const SUMOVehicleClass vClass)
Definition Helper.cpp:420
static SUMOVehicleParameter::Stop buildStopParameters(const std::string &edgeOrStoppingPlaceID, double pos, int laneIndex, double startPos, int flags, double duration, double until)
Definition Helper.cpp:537
static Subscription * addSubscriptionFilter(SubscriptionFilterType filter)
Definition Helper.cpp:210
virtual std::string readString()
Definition storage.cpp:180
virtual int readUnsignedByte()
Definition storage.cpp:155
virtual double readDouble()
Definition storage.cpp:362
#define CALL_MICRO_FUN(veh, fun, mesoResult)
#define DEBUG_COND
TRACI_CONST double INVALID_DOUBLE_VALUE
TRACI_CONST int VAR_LASTACTIONTIME
TRACI_CONST int VAR_EDGES
TRACI_CONST int VAR_NOXEMISSION
TRACI_CONST int VAR_LANECHANGE_MODE
TRACI_CONST int MOVE_AUTOMATIC
TRACI_CONST int LAST_STEP_PERSON_ID_LIST
TRACI_CONST int TRACI_ID_LIST
TRACI_CONST int VAR_IMPATIENCE
TRACI_CONST int VAR_TYPE
TRACI_CONST int VAR_DEPARTURE
TRACI_CONST int VAR_ROUTING_MODE
TRACI_CONST int VAR_WAITING_TIME
TRACI_CONST int VAR_LINE
std::map< std::string, libsumo::SubscriptionResults > ContextSubscriptionResults
Definition TraCIDefs.h:338
TRACI_CONST int VAR_ROAD_ID
TRACI_CONST int MOVE_NORMAL
TRACI_CONST int VAR_TIMELOSS
TRACI_CONST int VAR_SPEED_FACTOR
TRACI_CONST int VAR_STOP_ARRIVALDELAY
TRACI_CONST int VAR_SPEED_LAT
TRACI_CONST int VAR_ANGLE
TRACI_CONST int VAR_ALLOWED_SPEED
TRACI_CONST int VAR_LANE_INDEX
TRACI_CONST int VAR_PMXEMISSION
TRACI_CONST int VAR_SPEED_WITHOUT_TRACI
TRACI_CONST int VAR_BOARDING_DURATION
TRACI_CONST int MOVE_TELEPORT
TRACI_CONST int VAR_PERSON_NUMBER
TRACI_CONST int VAR_COEMISSION
TRACI_CONST int VAR_COLOR
TRACI_CONST int VAR_POSITION
TRACI_CONST int VAR_PERSON_CAPACITY
TRACI_CONST int VAR_LEADER
TRACI_CONST int VAR_CO2EMISSION
TRACI_CONST int VAR_TELEPORTING_LIST
TRACI_CONST int REMOVE_TELEPORT
TRACI_CONST int VAR_TAXI_FLEET
TRACI_CONST int VAR_ROUTE_VALID
TRACI_CONST int VAR_SPEEDSETMODE
TRACI_CONST int VAR_FUELCONSUMPTION
std::map< std::string, libsumo::TraCIResults > SubscriptionResults
{object->{variable->value}}
Definition TraCIDefs.h:337
TRACI_CONST int VAR_SLOPE
TRACI_CONST int VAR_HCEMISSION
TRACI_CONST int ID_COUNT
TRACI_CONST int VAR_PARAMETER
TRACI_CONST int VAR_LANEPOSITION
TRACI_CONST int REMOVE_PARKING
TRACI_CONST int VAR_LANE_ID
TRACI_CONST int VAR_NOISEEMISSION
TRACI_CONST int VAR_POSITION3D
TRACI_CONST int VAR_SPEED
TRACI_CONST int VAR_SIGNALS
TRACI_CONST int VAR_PARAMETER_WITH_KEY
TRACI_CONST int VAR_ACCUMULATED_WAITING_TIME
TRACI_CONST int VAR_MINGAP_LAT
TRACI_CONST int INVALID_INT_VALUE
TRACI_CONST int VAR_ROUTE_INDEX
TRACI_CONST int VAR_ACCELERATION
TRACI_CONST int VAR_ROUTE_ID
TRACI_CONST int REMOVE_ARRIVED
@ SUBS_FILTER_LEAD_FOLLOW
@ SUBS_FILTER_UPSTREAM_DIST
@ SUBS_FILTER_VTYPE
@ SUBS_FILTER_LANES
@ SUBS_FILTER_NOOPPOSITE
@ SUBS_FILTER_DOWNSTREAM_DIST
@ SUBS_FILTER_LATERAL_DIST
@ SUBS_FILTER_TURN
@ SUBS_FILTER_VCLASS
@ SUBS_FILTER_FIELD_OF_VISION
TRACI_CONST int ROUTING_MODE_DEFAULT
TRACI_CONST int VAR_LANEPOSITION_LAT
TRACI_CONST int VAR_STOP_DELAY
TRACI_CONST int REMOVE_TELEPORT_ARRIVED
TRACI_CONST int REMOVE_VAPORIZED
TRACI_CONST int VAR_STOPSTATE
TRACI_CONST int VAR_FOLLOWER
TRACI_CONST int VAR_LOADED_LIST
TRACI_CONST int VAR_DEPART_DELAY
std::map< int, std::shared_ptr< libsumo::TraCIResult > > TraCIResults
{variable->value}
Definition TraCIDefs.h:335
TRACI_CONST int VAR_DISTANCE
TRACI_CONST int ROUTING_MODE_AGGREGATED_CUSTOM
TRACI_CONST int VAR_ELECTRICITYCONSUMPTION
TRACI_CONST int VAR_VIA
@ key
the parser read a key of a value in an object
NLOHMANN_BASIC_JSON_TPL_DECLARATION void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL &j1, nlohmann::NLOHMANN_BASIC_JSON_TPL &j2) noexcept(//NOLINT(readability-inconsistent-declaration-parameter-name) is_nothrow_move_constructible< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value &&//NOLINT(misc-redundant-expression) is_nothrow_move_assignable< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value)
exchanges the values of two JSON objects
Definition json.hpp:21884
A structure representing the best lanes for continuing the current route starting at 'lane'.
Definition MSVehicle.h:869