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