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