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-2022 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 /****************************************************************************/
18 // C++ Vehicle API
19 /****************************************************************************/
20 #include <config.h>
21 
22 #include <foreign/tcpip/storage.h>
23 #include <utils/geom/GeomHelper.h>
34 #include <microsim/MSStop.h>
35 #include <microsim/MSVehicle.h>
37 #include <microsim/MSVehicleType.h>
39 #include <microsim/MSNet.h>
40 #include <microsim/MSEdge.h>
41 #include <microsim/MSLane.h>
42 #include <microsim/MSParkingArea.h>
45 #include <mesosim/MEVehicle.h>
46 #include <libsumo/TraCIDefs.h>
47 #include <libsumo/TraCIConstants.h>
48 #include "Helper.h"
49 #include "Route.h"
50 #include "Polygon.h"
51 #include "Vehicle.h"
52 
53 #define CALL_MICRO_FUN(veh, fun, mesoResult) ((dynamic_cast<MSVehicle*>(veh) == nullptr ? (mesoResult) : dynamic_cast<MSVehicle*>(veh)->fun))
54 
55 
56 // ===========================================================================
57 // debug defines
58 // ===========================================================================
59 //#define DEBUG_NEIGHBORS
60 //#define DEBUG_DYNAMIC_SHAPES
61 //#define DEBUG_MOVEXY
62 #define DEBUG_COND (veh->isSelected())
63 
64 
65 
66 namespace libsumo {
67 // ===========================================================================
68 // static member initializations
69 // ===========================================================================
70 SubscriptionResults Vehicle::mySubscriptionResults;
71 ContextSubscriptionResults Vehicle::myContextSubscriptionResults;
72 
73 
74 // ===========================================================================
75 // static member definitions
76 // ===========================================================================
77 bool
78 Vehicle::isVisible(const SUMOVehicle* veh) {
79  return veh->isOnRoad() || veh->isParking() || veh->wasRemoteControlled();
80 }
81 
82 
83 bool
84 Vehicle::isOnInit(const std::string& vehID) {
86  return sumoVehicle == nullptr || sumoVehicle->getLane() == nullptr;
87 }
88 
89 
90 std::vector<std::string>
91 Vehicle::getIDList() {
92  std::vector<std::string> ids;
94  for (MSVehicleControl::constVehIt i = c.loadedVehBegin(); i != c.loadedVehEnd(); ++i) {
95  if (isVisible((*i).second)) {
96  ids.push_back((*i).first);
97  }
98  }
99  return ids;
100 }
101 
102 int
103 Vehicle::getIDCount() {
104  return (int)getIDList().size();
105 }
106 
107 
108 double
109 Vehicle::getSpeed(const std::string& vehID) {
110  MSBaseVehicle* veh = Helper::getVehicle(vehID);
111  return isVisible(veh) ? veh->getSpeed() : INVALID_DOUBLE_VALUE;
112 }
113 
114 double
115 Vehicle::getLateralSpeed(const std::string& vehID) {
116  MSBaseVehicle* veh = Helper::getVehicle(vehID);
117  return isVisible(veh) ? CALL_MICRO_FUN(veh, getLaneChangeModel().getSpeedLat(), 0) : INVALID_DOUBLE_VALUE;
118 }
119 
120 
121 double
122 Vehicle::getAcceleration(const std::string& vehID) {
123  MSBaseVehicle* veh = Helper::getVehicle(vehID);
124  return isVisible(veh) ? CALL_MICRO_FUN(veh, getAcceleration(), 0) : INVALID_DOUBLE_VALUE;
125 }
126 
127 
128 double
129 Vehicle::getSpeedWithoutTraCI(const std::string& vehID) {
130  MSBaseVehicle* veh = Helper::getVehicle(vehID);
131  return isVisible(veh) ? CALL_MICRO_FUN(veh, getSpeedWithoutTraciInfluence(), veh->getSpeed()) : INVALID_DOUBLE_VALUE;
132 }
133 
134 
135 TraCIPosition
136 Vehicle::getPosition(const std::string& vehID, const bool includeZ) {
137  MSBaseVehicle* veh = Helper::getVehicle(vehID);
138  if (isVisible(veh)) {
139  return Helper::makeTraCIPosition(veh->getPosition(), includeZ);
140  }
141  return TraCIPosition();
142 }
143 
144 
145 TraCIPosition
146 Vehicle::getPosition3D(const std::string& vehID) {
147  return getPosition(vehID, true);
148 }
149 
150 
151 double
152 Vehicle::getAngle(const std::string& vehID) {
153  MSBaseVehicle* veh = Helper::getVehicle(vehID);
154  return isVisible(veh) ? GeomHelper::naviDegree(veh->getAngle()) : INVALID_DOUBLE_VALUE;
155 }
156 
157 
158 double
159 Vehicle::getSlope(const std::string& vehID) {
160  MSBaseVehicle* veh = Helper::getVehicle(vehID);
161  return (veh->isOnRoad() || veh->isParking()) ? veh->getSlope() : INVALID_DOUBLE_VALUE;
162 }
163 
164 
165 std::string
166 Vehicle::getRoadID(const std::string& vehID) {
167  MSBaseVehicle* veh = Helper::getVehicle(vehID);
168  return isVisible(veh) ? CALL_MICRO_FUN(veh, getLane()->getEdge().getID(), veh->getEdge()->getID()) : "";
169 }
170 
171 
172 std::string
173 Vehicle::getLaneID(const std::string& vehID) {
174  MSBaseVehicle* veh = Helper::getVehicle(vehID);
175  return veh->isOnRoad() ? CALL_MICRO_FUN(veh, getLane()->getID(), "") : "";
176 }
177 
178 
179 int
180 Vehicle::getLaneIndex(const std::string& vehID) {
181  MSBaseVehicle* veh = Helper::getVehicle(vehID);
182  return veh->isOnRoad() ? CALL_MICRO_FUN(veh, getLane()->getIndex(), INVALID_INT_VALUE) : INVALID_INT_VALUE;
183 }
184 
185 
186 std::string
187 Vehicle::getTypeID(const std::string& vehID) {
188  return Helper::getVehicleType(vehID).getID();
189 }
190 
191 
192 std::string
193 Vehicle::getRouteID(const std::string& vehID) {
194  return Helper::getVehicle(vehID)->getRoute().getID();
195 }
196 
197 
198 int
199 Vehicle::getRouteIndex(const std::string& vehID) {
200  MSBaseVehicle* veh = Helper::getVehicle(vehID);
201  return veh->hasDeparted() ? veh->getRoutePosition() : INVALID_INT_VALUE;
202 }
203 
204 
205 TraCIColor
206 Vehicle::getColor(const std::string& vehID) {
207  return Helper::makeTraCIColor(Helper::getVehicle(vehID)->getParameter().color);
208 }
209 
210 double
211 Vehicle::getLanePosition(const std::string& vehID) {
212  MSBaseVehicle* veh = Helper::getVehicle(vehID);
213  return veh->isOnRoad() ? veh->getPositionOnLane() : INVALID_DOUBLE_VALUE;
214 }
215 
216 double
217 Vehicle::getLateralLanePosition(const std::string& vehID) {
218  MSBaseVehicle* veh = Helper::getVehicle(vehID);
219  return veh->isOnRoad() ? CALL_MICRO_FUN(veh, getLateralPositionOnLane(), 0) : INVALID_DOUBLE_VALUE;
220 }
221 
222 double
223 Vehicle::getCO2Emission(const std::string& vehID) {
224  MSBaseVehicle* veh = Helper::getVehicle(vehID);
225  return isVisible(veh) ? veh->getCO2Emissions() : INVALID_DOUBLE_VALUE;
226 }
227 
228 double
229 Vehicle::getCOEmission(const std::string& vehID) {
230  MSBaseVehicle* veh = Helper::getVehicle(vehID);
231  return isVisible(veh) ? veh->getCOEmissions() : INVALID_DOUBLE_VALUE;
232 }
233 
234 double
235 Vehicle::getHCEmission(const std::string& vehID) {
236  MSBaseVehicle* veh = Helper::getVehicle(vehID);
237  return isVisible(veh) ? veh->getHCEmissions() : INVALID_DOUBLE_VALUE;
238 }
239 
240 double
241 Vehicle::getPMxEmission(const std::string& vehID) {
242  MSBaseVehicle* veh = Helper::getVehicle(vehID);
243  return isVisible(veh) ? veh->getPMxEmissions() : INVALID_DOUBLE_VALUE;
244 }
245 
246 double
247 Vehicle::getNOxEmission(const std::string& vehID) {
248  MSBaseVehicle* veh = Helper::getVehicle(vehID);
249  return isVisible(veh) ? veh->getNOxEmissions() : INVALID_DOUBLE_VALUE;
250 }
251 
252 double
253 Vehicle::getFuelConsumption(const std::string& vehID) {
254  MSBaseVehicle* veh = Helper::getVehicle(vehID);
255  return isVisible(veh) ? veh->getFuelConsumption() : INVALID_DOUBLE_VALUE;
256 }
257 
258 double
259 Vehicle::getNoiseEmission(const std::string& vehID) {
260  MSBaseVehicle* veh = Helper::getVehicle(vehID);
261  return isVisible(veh) ? veh->getHarmonoise_NoiseEmissions() : INVALID_DOUBLE_VALUE;
262 }
263 
264 double
265 Vehicle::getElectricityConsumption(const std::string& vehID) {
266  MSBaseVehicle* veh = Helper::getVehicle(vehID);
267  return isVisible(veh) ? veh->getElectricityConsumption() : INVALID_DOUBLE_VALUE;
268 }
269 
270 int
271 Vehicle::getPersonNumber(const std::string& vehID) {
272  return Helper::getVehicle(vehID)->getPersonNumber();
273 }
274 
275 int
276 Vehicle::getPersonCapacity(const std::string& vehID) {
278 }
279 
280 std::vector<std::string>
281 Vehicle::getPersonIDList(const std::string& vehID) {
282  return Helper::getVehicle(vehID)->getPersonIDList();
283 }
284 
285 std::pair<std::string, double>
286 Vehicle::getLeader(const std::string& vehID, double dist) {
287  MSBaseVehicle* veh = Helper::getVehicle(vehID);
288  if (veh->isOnRoad()) {
289  std::pair<const MSVehicle* const, double> leaderInfo = veh->getLeader(dist);
290  const std::string leaderID = leaderInfo.first != nullptr ? leaderInfo.first->getID() : "";
291  double gap = leaderInfo.second;
292  if (leaderInfo.first != nullptr
293  && leaderInfo.first->getLane() != nullptr
294  && leaderInfo.first->getLane()->isInternal()
295  && veh->getLane() != nullptr
296  && (!veh->getLane()->isInternal()
297  || (veh->getLane()->getLinkCont().front()->getIndex() != leaderInfo.first->getLane()->getLinkCont().front()->getIndex()))) {
298  // leader is a linkLeader (see MSLink::getLeaderInfo)
299  // avoid internal gap values which may be negative (or -inf)
300  gap = MAX2(0.0, gap);
301  }
302  return std::make_pair(leaderID, gap);
303  } else {
304  return std::make_pair("", -1);
305  }
306 }
307 
308 
309 std::pair<std::string, double>
310 Vehicle::getFollower(const std::string& vehID, double dist) {
311  MSBaseVehicle* veh = Helper::getVehicle(vehID);
312  if (veh->isOnRoad()) {
313  std::pair<const MSVehicle* const, double> leaderInfo = veh->getFollower(dist);
314  return std::make_pair(
315  leaderInfo.first != nullptr ? leaderInfo.first->getID() : "",
316  leaderInfo.second);
317  } else {
318  return std::make_pair("", -1);
319  }
320 }
321 
322 
323 double
324 Vehicle::getWaitingTime(const std::string& vehID) {
325  return STEPS2TIME(Helper::getVehicle(vehID)->getWaitingTime());
326 }
327 
328 
329 double
330 Vehicle::getAccumulatedWaitingTime(const std::string& vehID) {
331  MSBaseVehicle* veh = Helper::getVehicle(vehID);
332  return CALL_MICRO_FUN(veh, getAccumulatedWaitingSeconds(), INVALID_DOUBLE_VALUE);
333 }
334 
335 
336 double
337 Vehicle::getAdaptedTraveltime(const std::string& vehID, double time, const std::string& edgeID) {
338  MSEdge* edge = Helper::getEdge(edgeID);
339  double value = INVALID_DOUBLE_VALUE;
341  return value;
342 }
343 
344 
345 double
346 Vehicle::getEffort(const std::string& vehID, double time, const std::string& edgeID) {
347  MSEdge* edge = Helper::getEdge(edgeID);
348  double value = INVALID_DOUBLE_VALUE;
349  Helper::getVehicle(vehID)->getWeightsStorage().retrieveExistingEffort(edge, time, value);
350  return value;
351 }
352 
353 
354 bool
355 Vehicle::isRouteValid(const std::string& vehID) {
356  std::string msg;
357  return Helper::getVehicle(vehID)->hasValidRoute(msg);
358 }
359 
360 
361 std::vector<std::string>
362 Vehicle::getRoute(const std::string& vehID) {
363  std::vector<std::string> result;
364  MSBaseVehicle* veh = Helper::getVehicle(vehID);
365  const MSRoute& r = veh->getRoute();
366  for (MSRouteIterator i = r.begin(); i != r.end(); ++i) {
367  result.push_back((*i)->getID());
368  }
369  return result;
370 }
371 
372 
373 int
374 Vehicle::getSignals(const std::string& vehID) {
375  MSBaseVehicle* veh = Helper::getVehicle(vehID);
376  return CALL_MICRO_FUN(veh, getSignals(), MSVehicle::VEH_SIGNAL_NONE);
377 }
378 
379 
380 std::vector<TraCIBestLanesData>
381 Vehicle::getBestLanes(const std::string& vehID) {
382  std::vector<TraCIBestLanesData> result;
383  MSVehicle* veh = dynamic_cast<MSVehicle*>(Helper::getVehicle(vehID));
384  if (veh != nullptr && veh->isOnRoad()) {
385  for (const MSVehicle::LaneQ& lq : veh->getBestLanes()) {
386  TraCIBestLanesData bld;
387  bld.laneID = lq.lane->getID();
388  bld.length = lq.length;
389  bld.occupation = lq.nextOccupation;
390  bld.bestLaneOffset = lq.bestLaneOffset;
391  bld.allowsContinuation = lq.allowsContinuation;
392  for (const MSLane* const lane : lq.bestContinuations) {
393  if (lane != nullptr) {
394  bld.continuationLanes.push_back(lane->getID());
395  }
396  }
397  result.emplace_back(bld);
398  }
399  }
400  return result;
401 }
402 
403 
404 std::vector<TraCINextTLSData>
405 Vehicle::getNextTLS(const std::string& vehID) {
406  std::vector<TraCINextTLSData> result;
407  MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
408  MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
409  if (!vehicle->isOnRoad()) {
410  return result;
411  }
412  if (veh != nullptr) {
413  const MSLane* lane = veh->getLane();
414  const std::vector<MSLane*>& bestLaneConts = veh->getBestLanesContinuation(lane);
415  double seen = lane->getLength() - veh->getPositionOnLane();
416  int view = 1;
417  std::vector<MSLink*>::const_iterator linkIt = MSLane::succLinkSec(*veh, view, *lane, bestLaneConts);
418  while (!lane->isLinkEnd(linkIt)) {
419  if (!lane->getEdge().isInternal()) {
420  if ((*linkIt)->isTLSControlled()) {
421  TraCINextTLSData ntd;
422  ntd.id = (*linkIt)->getTLLogic()->getID();
423  ntd.tlIndex = (*linkIt)->getTLIndex();
424  ntd.dist = seen;
425  ntd.state = (char)(*linkIt)->getState();
426  result.push_back(ntd);
427  }
428  }
429  lane = (*linkIt)->getViaLaneOrLane();
430  if (!lane->getEdge().isInternal()) {
431  view++;
432  }
433  seen += lane->getLength();
434  linkIt = MSLane::succLinkSec(*veh, view, *lane, bestLaneConts);
435  }
436  // consider edges beyond bestLanes
437  const int remainingEdges = (int)(veh->getRoute().end() - veh->getCurrentRouteEdge()) - view;
438  //std::cout << SIMTIME << "remainingEdges=" << remainingEdges << " seen=" << seen << " view=" << view << " best=" << toString(bestLaneConts) << "\n";
439  for (int i = 0; i < remainingEdges; i++) {
440  const MSEdge* prev = *(veh->getCurrentRouteEdge() + view + i - 1);
441  const MSEdge* next = *(veh->getCurrentRouteEdge() + view + i);
442  const std::vector<MSLane*>* allowed = prev->allowedLanes(*next, veh->getVClass());
443  if (allowed != nullptr && allowed->size() != 0) {
444  for (const MSLink* const link : allowed->front()->getLinkCont()) {
445  if (&link->getLane()->getEdge() == next) {
446  if (link->isTLSControlled()) {
447  TraCINextTLSData ntd;
448  ntd.id = link->getTLLogic()->getID();
449  ntd.tlIndex = link->getTLIndex();
450  ntd.dist = seen;
451  ntd.state = (char)link->getState();
452  result.push_back(ntd);
453  }
454  seen += allowed->front()->getLength();
455  }
456  }
457  } else {
458  // invalid route, cannot determine nextTLS
459  break;
460  }
461  }
462  } else {
463  WRITE_WARNING("getNextTLS not yet implemented for meso");
464  }
465  return result;
466 }
467 
468 std::vector<TraCINextStopData>
469 Vehicle::getNextStops(const std::string& vehID) {
470  return getStops(vehID, 0);
471 }
472 
473 std::vector<TraCINextStopData>
474 Vehicle::getStops(const std::string& vehID, int limit) {
475  std::vector<TraCINextStopData> result;
476  MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
477  if (limit < 0) {
478  // return past stops up to the given limit
479  const std::vector<SUMOVehicleParameter::Stop>& pastStops = vehicle->getPastStops();
480  const int n = (int)pastStops.size();
481  for (int i = MAX2(0, n + limit); i < n; i++) {
482  result.push_back(Helper::buildStopData(pastStops[i]));
483  }
484  } else {
485  for (const MSStop& stop : vehicle->getStops()) {
486  if (!stop.collision) {
487  TraCINextStopData nsd = Helper::buildStopData(stop.pars);
488  nsd.duration = STEPS2TIME(stop.duration);
489  result.push_back(nsd);
490  if (limit > 0 && (int)result.size() >= limit) {
491  break;
492  }
493  }
494  }
495  }
496  return result;
497 }
498 
499 
500 int
501 Vehicle::getStopState(const std::string& vehID) {
502  MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
503  MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
504  if (veh == nullptr) {
505  WRITE_WARNING("getStopState not yet implemented for meso");
506  return 0;
507  }
508  int result = 0;
509  if (veh->isStopped()) {
510  const MSStop& stop = veh->getNextStop();
511  result = ((stop.reached ? 1 : 0) +
512  (stop.pars.parking ? 2 : 0) +
513  (stop.pars.triggered ? 4 : 0) +
514  (stop.pars.containerTriggered ? 8 : 0) +
515  (stop.busstop != nullptr ? 16 : 0) +
516  (stop.containerstop != nullptr ? 32 : 0) +
517  (stop.chargingStation != nullptr ? 64 : 0) +
518  (stop.parkingarea != nullptr ? 128 : 0));
519  }
520  return result;
521 }
522 
523 
524 double
525 Vehicle::getDistance(const std::string& vehID) {
526  MSBaseVehicle* veh = Helper::getVehicle(vehID);
527  if (veh->isOnRoad()) {
528  return veh->getOdometer();
529  } else {
530  return INVALID_DOUBLE_VALUE;
531  }
532 }
533 
534 
535 double
536 Vehicle::getDrivingDistance(const std::string& vehID, const std::string& edgeID, double position, int /* laneIndex */) {
537  MSBaseVehicle* veh = Helper::getVehicle(vehID);
538  MSVehicle* microVeh = dynamic_cast<MSVehicle*>(veh);
539  if (veh->isOnRoad()) {
540  const MSEdge* edge = microVeh != nullptr ? &veh->getLane()->getEdge() : veh->getEdge();
541  double distance = veh->getRoute().getDistanceBetween(veh->getPositionOnLane(), position,
542  edge, Helper::getEdge(edgeID), true, veh->getRoutePosition());
543  if (distance == std::numeric_limits<double>::max()) {
544  return INVALID_DOUBLE_VALUE;
545  }
546  return distance;
547  } else {
548  return INVALID_DOUBLE_VALUE;
549  }
550 }
551 
552 
553 double
554 Vehicle::getDrivingDistance2D(const std::string& vehID, double x, double y) {
555  MSBaseVehicle* veh = Helper::getVehicle(vehID);
556  if (veh == nullptr) {
557  return INVALID_DOUBLE_VALUE;
558  }
559  if (veh->isOnRoad()) {
560  std::pair<MSLane*, double> roadPos = Helper::convertCartesianToRoadMap(Position(x, y), veh->getVehicleType().getVehicleClass());
561  double distance = veh->getRoute().getDistanceBetween(veh->getPositionOnLane(), roadPos.second,
562  veh->getEdge(), &roadPos.first->getEdge(), true, veh->getRoutePosition());
563  if (distance == std::numeric_limits<double>::max()) {
564  return INVALID_DOUBLE_VALUE;
565  }
566  return distance;
567  } else {
568  return INVALID_DOUBLE_VALUE;
569  }
570 }
571 
572 
573 double
574 Vehicle::getAllowedSpeed(const std::string& vehID) {
575  MSBaseVehicle* veh = Helper::getVehicle(vehID);
576  return veh->isOnRoad() ? CALL_MICRO_FUN(veh, getLane()->getVehicleMaxSpeed(veh), veh->getEdge()->getVehicleMaxSpeed(veh)) : INVALID_DOUBLE_VALUE;
577 }
578 
579 
580 double
581 Vehicle::getSpeedFactor(const std::string& vehID) {
582  return Helper::getVehicle(vehID)->getChosenSpeedFactor();
583 }
584 
585 
586 int
587 Vehicle::getSpeedMode(const std::string& vehID) {
588  MSBaseVehicle* veh = Helper::getVehicle(vehID);
589  return CALL_MICRO_FUN(veh, getInfluencer().getSpeedMode(), INVALID_INT_VALUE);
590 }
591 
592 
593 int
594 Vehicle::getLaneChangeMode(const std::string& vehID) {
595  MSBaseVehicle* veh = Helper::getVehicle(vehID);
596  return CALL_MICRO_FUN(veh, getInfluencer().getLaneChangeMode(), INVALID_INT_VALUE);
597 }
598 
599 
600 int
601 Vehicle::getRoutingMode(const std::string& vehID) {
603 }
604 
605 
606 std::string
607 Vehicle::getLine(const std::string& vehID) {
608  return Helper::getVehicle(vehID)->getParameter().line;
609 }
610 
611 
612 std::vector<std::string>
613 Vehicle::getVia(const std::string& vehID) {
614  return Helper::getVehicle(vehID)->getParameter().via;
615 }
616 
617 
618 std::pair<int, int>
619 Vehicle::getLaneChangeState(const std::string& vehID, int direction) {
620  MSBaseVehicle* veh = Helper::getVehicle(vehID);
621  auto undefined = std::make_pair((int)LCA_UNKNOWN, (int)LCA_UNKNOWN);
622  return veh->isOnRoad() ? CALL_MICRO_FUN(veh, getLaneChangeModel().getSavedState(direction), undefined) : undefined;
623 }
624 
625 
626 std::string
627 Vehicle::getParameter(const std::string& vehID, const std::string& key) {
628  MSBaseVehicle* veh = Helper::getVehicle(vehID);
629  std::string error;
630  std::string result = veh->getPrefixedParameter(key, error);
631  if (error != "") {
632  throw TraCIException(error);
633  }
634  return result;
635 }
636 
637 
639 
640 
641 std::vector<std::pair<std::string, double> >
642 Vehicle::getNeighbors(const std::string& vehID, const int mode) {
643  int dir = (1 & mode) != 0 ? -1 : 1;
644  bool queryLeaders = (2 & mode) != 0;
645  bool blockersOnly = (4 & mode) != 0;
646  MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
647  MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
648  std::vector<std::pair<std::string, double> > result;
649  if (veh == nullptr) {
650  return result;
651  }
652 #ifdef DEBUG_NEIGHBORS
653  if (DEBUG_COND) {
654  std::cout << "getNeighbors() for veh '" << vehID << "': dir=" << dir
655  << ", queryLeaders=" << queryLeaders
656  << ", blockersOnly=" << blockersOnly << std::endl;
657  }
658 #endif
659  if (veh->getLaneChangeModel().isOpposite()) {
660  // getParallelLane works relative to lane forward direction
661  dir *= -1;
662  }
663 
664  MSLane* targetLane = veh->getLane()->getParallelLane(dir);
665  if (targetLane == nullptr) {
666  return result;
667  }
668  // need to recompute leaders and followers (#8119)
669  const bool opposite = &veh->getLane()->getEdge() != &targetLane->getEdge();
670  MSLeaderDistanceInfo neighbors(targetLane, nullptr, 0);
671  if (queryLeaders) {
672  if (opposite) {
673  double pos = targetLane->getOppositePos(veh->getPositionOnLane());
674  neighbors = targetLane->getFollowersOnConsecutive(veh, pos, true);
675  } else {
676  targetLane->addLeaders(veh, veh->getPositionOnLane(), neighbors);
677  }
678  } else {
679  if (opposite) {
680  double pos = targetLane->getOppositePos(veh->getPositionOnLane());
681  targetLane->addLeaders(veh, pos, neighbors);
682  neighbors.fixOppositeGaps(true);
683  } else {
684  neighbors = targetLane->getFollowersOnConsecutive(veh, veh->getBackPositionOnLane(), true);
685  }
686  }
687  if (blockersOnly) {
688  // filter out vehicles that aren't blocking
689  MSLeaderDistanceInfo blockers(targetLane, nullptr, 0);
690  for (int i = 0; i < neighbors.numSublanes(); i++) {
691  CLeaderDist n = neighbors[i];
692  if (n.first != nullptr) {
693  const MSVehicle* follower = veh;
694  const MSVehicle* leader = n.first;
695  if (!queryLeaders) {
696  std::swap(follower, leader);
697  }
698  const double secureGap = (follower->getCarFollowModel().getSecureGap(
699  follower, leader, follower->getSpeed(), leader->getSpeed(), leader->getCarFollowModel().getMaxDecel())
700  * follower->getLaneChangeModel().getSafetyFactor());
701  if (n.second < secureGap) {
702  blockers.addLeader(n.first, n.second, 0, i);
703  }
704  }
705  }
706  neighbors = blockers;
707  }
708 
709  if (neighbors.hasVehicles()) {
710  for (int i = 0; i < neighbors.numSublanes(); i++) {
711  CLeaderDist n = neighbors[i];
712  if (n.first != nullptr &&
713  // avoid duplicates
714  (result.size() == 0 || result.back().first != n.first->getID())) {
715  result.push_back(std::make_pair(n.first->getID(), n.second));
716  }
717  }
718  }
719  return result;
720 }
721 
722 
723 double
724 Vehicle::getFollowSpeed(const std::string& vehID, double speed, double gap, double leaderSpeed, double leaderMaxDecel, const std::string& leaderID) {
725  MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
726  MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
727  if (veh == nullptr) {
728  WRITE_ERROR("getFollowSpeed not applicable for meso");
729  return INVALID_DOUBLE_VALUE;
730  }
731  MSVehicle* leader = dynamic_cast<MSVehicle*>(MSNet::getInstance()->getVehicleControl().getVehicle(leaderID));
732  return veh->getCarFollowModel().followSpeed(veh, speed, gap, leaderSpeed, leaderMaxDecel, leader);
733 }
734 
735 
736 double
737 Vehicle::getSecureGap(const std::string& vehID, double speed, double leaderSpeed, double leaderMaxDecel, const std::string& leaderID) {
738  MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
739  MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
740  if (veh == nullptr) {
741  WRITE_ERROR("getSecureGap not applicable for meso");
742  return INVALID_DOUBLE_VALUE;
743  }
744  MSVehicle* leader = dynamic_cast<MSVehicle*>(MSNet::getInstance()->getVehicleControl().getVehicle(leaderID));
745  return veh->getCarFollowModel().getSecureGap(veh, leader, speed, leaderSpeed, leaderMaxDecel);
746 }
747 
748 
749 double
750 Vehicle::getStopSpeed(const std::string& vehID, const double speed, double gap) {
751  MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
752  MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
753  if (veh == nullptr) {
754  WRITE_ERROR("getStopSpeed not applicable for meso");
755  return INVALID_DOUBLE_VALUE;
756  }
757  return veh->getCarFollowModel().stopSpeed(veh, speed, gap);
758 }
759 
760 double
761 Vehicle::getStopDelay(const std::string& vehID) {
762  return Helper::getVehicle(vehID)->getStopDelay();
763 }
764 
765 double
766 Vehicle::getStopArrivalDelay(const std::string& vehID) {
767  double result = Helper::getVehicle(vehID)->getStopArrivalDelay();
768  if (result == INVALID_DOUBLE) {
769  return INVALID_DOUBLE_VALUE;
770  } else {
771  return result;
772  }
773 }
774 
775 double
776 Vehicle::getTimeLoss(const std::string& vehID) {
777  return Helper::getVehicle(vehID)->getTimeLossSeconds();
778 }
779 
780 std::vector<std::string>
781 Vehicle::getTaxiFleet(int taxiState) {
782  std::vector<std::string> result;
783  for (MSDevice_Taxi* taxi : MSDevice_Taxi::getFleet()) {
784  if (taxi->getHolder().hasDeparted()) {
785  if (taxiState == -1
786  || (taxiState == 0 && taxi->getState() == 0)
787  || (taxiState != 0 && (taxi->getState() & taxiState) == taxiState)) {
788  result.push_back(taxi->getHolder().getID());
789  }
790  }
791  }
792  return result;
793 }
794 
795 std::string
796 Vehicle::getEmissionClass(const std::string& vehID) {
797  return PollutantsInterface::getName(Helper::getVehicleType(vehID).getEmissionClass());
798 }
799 
800 std::string
801 Vehicle::getShapeClass(const std::string& vehID) {
802  return getVehicleShapeName(Helper::getVehicleType(vehID).getGuiShape());
803 }
804 
805 
806 double
807 Vehicle::getLength(const std::string& vehID) {
808  return Helper::getVehicleType(vehID).getLength();
809 }
810 
811 
812 double
813 Vehicle::getAccel(const std::string& vehID) {
815 }
816 
817 
818 double
819 Vehicle::getDecel(const std::string& vehID) {
821 }
822 
823 
824 double Vehicle::getEmergencyDecel(const std::string& vehID) {
826 }
827 
828 
829 double Vehicle::getApparentDecel(const std::string& vehID) {
831 }
832 
833 
834 double Vehicle::getActionStepLength(const std::string& vehID) {
836 }
837 
838 
839 double Vehicle::getLastActionTime(const std::string& vehID) {
840  MSBaseVehicle* veh = Helper::getVehicle(vehID);
841  MSVehicle* microVeh = dynamic_cast<MSVehicle*>(veh);
842  if (microVeh != nullptr) {
843  return STEPS2TIME(microVeh->getLastActionTime());
844  } else {
845  MEVehicle* mesoVeh = dynamic_cast<MEVehicle*>(veh);
846  return STEPS2TIME(mesoVeh->getEventTime());
847  }
848 }
849 
850 
851 double
852 Vehicle::getTau(const std::string& vehID) {
854 }
855 
856 
857 double
858 Vehicle::getImperfection(const std::string& vehID) {
860 }
861 
862 
863 double
864 Vehicle::getSpeedDeviation(const std::string& vehID) {
866 }
867 
868 
869 std::string
870 Vehicle::getVehicleClass(const std::string& vehID) {
871  return toString(Helper::getVehicleType(vehID).getVehicleClass());
872 }
873 
874 
875 double
876 Vehicle::getMinGap(const std::string& vehID) {
877  return Helper::getVehicleType(vehID).getMinGap();
878 }
879 
880 
881 double
882 Vehicle::getMinGapLat(const std::string& vehID) {
883  try {
884  return StringUtils::toDouble(getParameter(vehID, "laneChangeModel.minGapLat"));
885  } catch (const TraCIException&) {
886  // legacy behavior
887  return Helper::getVehicleType(vehID).getMinGapLat();
888  }
889 }
890 
891 
892 double
893 Vehicle::getMaxSpeed(const std::string& vehID) {
894  return Helper::getVehicleType(vehID).getMaxSpeed();
895 }
896 
897 
898 double
899 Vehicle::getMaxSpeedLat(const std::string& vehID) {
900  return Helper::getVehicleType(vehID).getMaxSpeedLat();
901 }
902 
903 
904 std::string
905 Vehicle::getLateralAlignment(const std::string& vehID) {
906  return toString(Helper::getVehicleType(vehID).getPreferredLateralAlignment());
907 }
908 
909 
910 double
911 Vehicle::getWidth(const std::string& vehID) {
912  return Helper::getVehicleType(vehID).getWidth();
913 }
914 
915 
916 double
917 Vehicle::getHeight(const std::string& vehID) {
918  return Helper::getVehicleType(vehID).getHeight();
919 }
920 
921 
922 void
923 Vehicle::setStop(const std::string& vehID,
924  const std::string& edgeID,
925  double pos,
926  int laneIndex,
927  double duration,
928  int flags,
929  double startPos,
930  double until) {
931  MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
933  pos, laneIndex, startPos, flags, duration, until);
934  std::string error;
935  if (!vehicle->addTraciStop(stopPars, error)) {
936  throw TraCIException(error);
937  }
938 }
939 
940 
941 void
942 Vehicle::replaceStop(const std::string& vehID,
943  int nextStopIndex,
944  const std::string& edgeID,
945  double pos,
946  int laneIndex,
947  double duration,
948  int flags,
949  double startPos,
950  double until,
951  int teleport) {
952  MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
953  if (edgeID == "") {
954  // only remove stop
955  const bool ok = vehicle->abortNextStop(nextStopIndex);
956  if (teleport != 0) {
957  WRITE_WARNING("Stop replacement parameter 'teleport=" + toString(teleport) + "' ignored for vehicle '" + vehID + "' when only removing stop.");
958  }
959  if (!ok) {
960  throw TraCIException("Stop replacement failed for vehicle '" + vehID + "' (invalid nextStopIndex).");
961  }
962  } else {
964  pos, laneIndex, startPos, flags, duration, until);
965 
966  std::string error;
967  if (!vehicle->replaceStop(nextStopIndex, stopPars, "traci:replaceStop", teleport != 0, error)) {
968  throw TraCIException("Stop replacement failed for vehicle '" + vehID + "' (" + error + ").");
969  }
970  }
971 }
972 
973 
974 void
975 Vehicle::rerouteParkingArea(const std::string& vehID, const std::string& parkingAreaID) {
976  MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
977  MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
978  if (veh == nullptr) {
979  WRITE_WARNING("rerouteParkingArea not yet implemented for meso");
980  return;
981  }
982  std::string error;
983  // Forward command to vehicle
984  if (!veh->rerouteParkingArea(parkingAreaID, error)) {
985  throw TraCIException(error);
986  }
987 }
988 
989 void
990 Vehicle::resume(const std::string& vehID) {
991  MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
992  MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
993  if (veh == nullptr) {
994  WRITE_WARNING("resume not yet implemented for meso");
995  return;
996  }
997  if (!veh->hasStops()) {
998  throw TraCIException("Failed to resume vehicle '" + veh->getID() + "', it has no stops.");
999  }
1000  if (!veh->resumeFromStopping()) {
1001  MSStop& sto = veh->getNextStop();
1002  std::ostringstream strs;
1003  strs << "reached: " << sto.reached;
1004  strs << ", duration:" << sto.duration;
1005  strs << ", edge:" << (*sto.edge)->getID();
1006  strs << ", startPos: " << sto.pars.startPos;
1007  std::string posStr = strs.str();
1008  throw TraCIException("Failed to resume from stopping for vehicle '" + veh->getID() + "', " + posStr);
1009  }
1010 }
1011 
1012 
1013 void
1014 Vehicle::changeTarget(const std::string& vehID, const std::string& edgeID) {
1015  MSBaseVehicle* veh = Helper::getVehicle(vehID);
1016  const MSEdge* destEdge = MSEdge::dictionary(edgeID);
1017  const bool onInit = isOnInit(vehID);
1018  if (destEdge == nullptr) {
1019  throw TraCIException("Destination edge '" + edgeID + "' is not known.");
1020  }
1021  // build a new route between the vehicle's current edge and destination edge
1022  ConstMSEdgeVector newRoute;
1023  const MSEdge* currentEdge = veh->getRerouteOrigin();
1025  currentEdge, destEdge, veh, MSNet::getInstance()->getCurrentTimeStep(), newRoute);
1026  // replace the vehicle's route by the new one (cost is updated by call to reroute())
1027  std::string errorMsg;
1028  if (!veh->replaceRouteEdges(newRoute, -1, 0, "traci:changeTarget", onInit, false, true, &errorMsg)) {
1029  throw TraCIException("Route replacement failed for vehicle '" + veh->getID() + "' (" + errorMsg + ").");
1030  }
1031  // route again to ensure usage of via/stops
1032  try {
1033  veh->reroute(MSNet::getInstance()->getCurrentTimeStep(), "traci:changeTarget",
1034  veh->getBaseInfluencer().getRouterTT(veh->getRNGIndex(), veh->getVClass()), onInit);
1035  } catch (ProcessError& e) {
1036  throw TraCIException(e.what());
1037  }
1038 }
1039 
1040 
1041 void
1042 Vehicle::changeLane(const std::string& vehID, int laneIndex, double duration) {
1043  MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
1044  MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
1045  if (veh == nullptr) {
1046  WRITE_ERROR("changeLane not applicable for meso");
1047  return;
1048  }
1049 
1050  std::vector<std::pair<SUMOTime, int> > laneTimeLine;
1051  laneTimeLine.push_back(std::make_pair(MSNet::getInstance()->getCurrentTimeStep(), laneIndex));
1052  laneTimeLine.push_back(std::make_pair(MSNet::getInstance()->getCurrentTimeStep() + TIME2STEPS(duration), laneIndex));
1053  veh->getInfluencer().setLaneTimeLine(laneTimeLine);
1054 }
1055 
1056 void
1057 Vehicle::changeLaneRelative(const std::string& vehID, int indexOffset, double duration) {
1058  MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
1059  MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
1060  if (veh == nullptr) {
1061  WRITE_ERROR("changeLaneRelative not applicable for meso");
1062  return;
1063  }
1064 
1065  std::vector<std::pair<SUMOTime, int> > laneTimeLine;
1066  int laneIndex = veh->getLaneIndex() + indexOffset;
1067  if (laneIndex < 0 && !veh->getLaneChangeModel().isOpposite()) {
1068  if (veh->getLaneIndex() == -1) {
1069  WRITE_WARNING("Ignoring changeLaneRelative for vehicle '" + vehID + "' that isn't on the road");
1070  } else {
1071  WRITE_WARNING("Ignoring indexOffset " + toString(indexOffset) + " for vehicle '" + vehID + "' on laneIndex " + toString(veh->getLaneIndex()));
1072  }
1073  } else {
1074  laneTimeLine.push_back(std::make_pair(MSNet::getInstance()->getCurrentTimeStep(), laneIndex));
1075  laneTimeLine.push_back(std::make_pair(MSNet::getInstance()->getCurrentTimeStep() + TIME2STEPS(duration), laneIndex));
1076  veh->getInfluencer().setLaneTimeLine(laneTimeLine);
1077  }
1078 }
1079 
1080 
1081 void
1082 Vehicle::changeSublane(const std::string& vehID, double latDist) {
1083  MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
1084  MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
1085  if (veh == nullptr) {
1086  WRITE_ERROR("changeSublane not applicable for meso");
1087  return;
1088  }
1089 
1090  veh->getInfluencer().setSublaneChange(latDist);
1091 }
1092 
1093 
1094 void
1095 Vehicle::add(const std::string& vehID,
1096  const std::string& routeID,
1097  const std::string& typeID,
1098  const std::string& depart,
1099  const std::string& departLane,
1100  const std::string& departPos,
1101  const std::string& departSpeed,
1102  const std::string& arrivalLane,
1103  const std::string& arrivalPos,
1104  const std::string& arrivalSpeed,
1105  const std::string& fromTaz,
1106  const std::string& toTaz,
1107  const std::string& line,
1108  int /*personCapacity*/,
1109  int personNumber) {
1111  if (veh != nullptr) {
1112  throw TraCIException("The vehicle '" + vehID + "' to add already exists.");
1113  }
1114 
1115  SUMOVehicleParameter vehicleParams;
1116  vehicleParams.id = vehID;
1117  MSVehicleType* vehicleType = MSNet::getInstance()->getVehicleControl().getVType(typeID);
1118  if (!vehicleType) {
1119  throw TraCIException("Invalid type '" + typeID + "' for vehicle '" + vehID + "'.");
1120  }
1121  const MSRoute* route = MSRoute::dictionary(routeID);
1122  if (!route) {
1123  if (routeID == "") {
1124  // assume, route was intentionally left blank because the caller
1125  // intends to control the vehicle remotely
1126  SUMOVehicleClass vclass = vehicleType->getVehicleClass();
1127  const std::string dummyRouteID = "DUMMY_ROUTE_" + SumoVehicleClassStrings.getString(vclass);
1128  route = MSRoute::dictionary(dummyRouteID);
1129  if (route == nullptr) {
1130  for (MSEdge* e : MSEdge::getAllEdges()) {
1131  if (e->getFunction() == SumoXMLEdgeFunc::NORMAL && (e->getPermissions() & vclass) == vclass) {
1132  std::vector<std::string> edges;
1133  edges.push_back(e->getID());
1134  libsumo::Route::add(dummyRouteID, edges);
1135  break;
1136  }
1137  }
1138  }
1139  route = MSRoute::dictionary(dummyRouteID);
1140  if (!route) {
1141  throw TraCIException("Could not build dummy route for vehicle class: '" + SumoVehicleClassStrings.getString(vehicleType->getVehicleClass()) + "'");
1142  }
1143  } else {
1144  throw TraCIException("Invalid route '" + routeID + "' for vehicle '" + vehID + "'.");
1145  }
1146  }
1147  // check if the route implies a trip
1148  if (route->getEdges().size() == 2) {
1149  const MSEdgeVector& succ = route->getEdges().front()->getSuccessors();
1150  if (std::find(succ.begin(), succ.end(), route->getEdges().back()) == succ.end()) {
1151  vehicleParams.parametersSet |= VEHPARS_FORCE_REROUTE;
1152  }
1153  }
1154  if (fromTaz != "" || toTaz != "") {
1155  vehicleParams.parametersSet |= VEHPARS_FORCE_REROUTE;
1156  }
1157  std::string error;
1158  if (!SUMOVehicleParameter::parseDepart(depart, "vehicle", vehID, vehicleParams.depart, vehicleParams.departProcedure, error)) {
1159  throw TraCIException(error);
1160  }
1161  if (vehicleParams.departProcedure == DEPART_GIVEN && vehicleParams.depart < MSNet::getInstance()->getCurrentTimeStep()) {
1162  vehicleParams.depart = MSNet::getInstance()->getCurrentTimeStep();
1163  WRITE_WARNING("Departure time for vehicle '" + vehID + "' is in the past; using current time instead.");
1164  } else if (vehicleParams.departProcedure == DEPART_NOW) {
1165  vehicleParams.depart = MSNet::getInstance()->getCurrentTimeStep();
1166  }
1167  if (!SUMOVehicleParameter::parseDepartLane(departLane, "vehicle", vehID, vehicleParams.departLane, vehicleParams.departLaneProcedure, error)) {
1168  throw TraCIException(error);
1169  }
1170  if (!SUMOVehicleParameter::parseDepartPos(departPos, "vehicle", vehID, vehicleParams.departPos, vehicleParams.departPosProcedure, error)) {
1171  throw TraCIException(error);
1172  }
1173  if (!SUMOVehicleParameter::parseDepartSpeed(departSpeed, "vehicle", vehID, vehicleParams.departSpeed, vehicleParams.departSpeedProcedure, error)) {
1174  throw TraCIException(error);
1175  }
1176  if (!SUMOVehicleParameter::parseArrivalLane(arrivalLane, "vehicle", vehID, vehicleParams.arrivalLane, vehicleParams.arrivalLaneProcedure, error)) {
1177  throw TraCIException(error);
1178  }
1179  if (!SUMOVehicleParameter::parseArrivalPos(arrivalPos, "vehicle", vehID, vehicleParams.arrivalPos, vehicleParams.arrivalPosProcedure, error)) {
1180  throw TraCIException(error);
1181  }
1182  if (!SUMOVehicleParameter::parseArrivalSpeed(arrivalSpeed, "vehicle", vehID, vehicleParams.arrivalSpeed, vehicleParams.arrivalSpeedProcedure, error)) {
1183  throw TraCIException(error);
1184  }
1185  vehicleParams.fromTaz = fromTaz;
1186  vehicleParams.toTaz = toTaz;
1187  vehicleParams.line = line;
1188  //vehicleParams.personCapacity = personCapacity;
1189  vehicleParams.personNumber = personNumber;
1190 
1191  SUMOVehicleParameter* params = new SUMOVehicleParameter(vehicleParams);
1192  SUMOVehicle* vehicle = nullptr;
1193  try {
1194  vehicle = MSNet::getInstance()->getVehicleControl().buildVehicle(params, route, vehicleType, true, false);
1195  if (fromTaz == "" && !route->getEdges().front()->validateDepartSpeed(*vehicle)) {
1197  throw TraCIException("Departure speed for vehicle '" + vehID + "' is too high for the departure edge '" + route->getEdges().front()->getID() + "'.");
1198  }
1199  std::string msg;
1200  if (vehicle->getRouteValidity(true, true, &msg) != MSBaseVehicle::ROUTE_VALID) {
1202  throw TraCIException("Vehicle '" + vehID + "' has no valid route (" + msg + "). ");
1203  }
1204  MSNet::getInstance()->getVehicleControl().addVehicle(vehicleParams.id, vehicle);
1205  if (vehicleParams.departProcedure != DEPART_TRIGGERED && vehicleParams.departProcedure != DEPART_CONTAINER_TRIGGERED) {
1207  }
1208  } catch (ProcessError& e) {
1209  if (vehicle != nullptr) {
1211  }
1212  throw TraCIException(e.what());
1213  }
1214 }
1215 
1216 
1217 void
1218 Vehicle::moveToXY(const std::string& vehID, const std::string& edgeID, const int laneIndex,
1219  const double x, const double y, double angle, const int keepRoute, double matchThreshold) {
1220  MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
1221  MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
1222  if (veh == nullptr) {
1223  WRITE_WARNING("moveToXY not yet implemented for meso");
1224  return;
1225  }
1226  const bool doKeepRoute = (keepRoute & 1) != 0 && veh->getID() != "VTD_EGO";
1227  const bool mayLeaveNetwork = (keepRoute & 2) != 0;
1228  const bool ignorePermissions = (keepRoute & 4) != 0;
1229  const bool setLateralPos = (MSGlobals::gLateralResolution > 0 || mayLeaveNetwork);
1230  SUMOVehicleClass vClass = ignorePermissions ? SVC_IGNORING : veh->getVClass();
1231  // process
1232  const std::string origID = edgeID + "_" + toString(laneIndex);
1233  // @todo add an interpretation layer for OSM derived origID values (without lane index)
1234  Position pos(x, y);
1235 #ifdef DEBUG_MOVEXY
1236  const double origAngle = angle;
1237 #endif
1238  // angle must be in [0,360] because it will be compared against those returned by naviDegree()
1239  // angle set to INVALID_DOUBLE_VALUE is ignored in the evaluated and later set to the angle of the matched lane
1240  if (angle != INVALID_DOUBLE_VALUE) {
1241  while (angle >= 360.) {
1242  angle -= 360.;
1243  }
1244  while (angle < 0.) {
1245  angle += 360.;
1246  }
1247  }
1248 
1249  Position vehPos = veh->getPosition();
1250 #ifdef DEBUG_MOVEXY
1251  std::cout << std::endl << SIMTIME << " moveToXY veh=" << veh->getID() << " vehPos=" << vehPos << " lane=" << Named::getIDSecure(veh->getLane()) << std::endl;
1252  std::cout << " wantedPos=" << pos << " origID=" << origID << " laneIndex=" << laneIndex << " origAngle=" << origAngle << " angle=" << angle << " keepRoute=" << keepRoute << std::endl;
1253 #endif
1254 
1255  ConstMSEdgeVector edges;
1256  MSLane* lane = nullptr;
1257  double lanePos;
1258  double lanePosLat = 0;
1259  double bestDistance = std::numeric_limits<double>::max();
1260  int routeOffset = 0;
1261  bool found;
1262  double maxRouteDistance = matchThreshold;
1263  /* EGO vehicle is known to have a fixed route. @todo make this into a parameter of the TraCI call */
1264  if (doKeepRoute) {
1265  // case a): vehicle is on its earlier route
1266  // we additionally assume it is moving forward (SUMO-limit);
1267  // note that the route ("edges") is not changed in this case
1268 
1269  found = Helper::moveToXYMap_matchingRoutePosition(pos, origID,
1270  veh->getRoute().getEdges(), (int)(veh->getCurrentRouteEdge() - veh->getRoute().begin()),
1271  vClass, setLateralPos,
1272  bestDistance, &lane, lanePos, routeOffset);
1273  // @note silenty ignoring mapping failure
1274  } else {
1275  double speed = pos.distanceTo2D(veh->getPosition()); // !!!veh->getSpeed();
1276  found = Helper::moveToXYMap(pos, maxRouteDistance, mayLeaveNetwork, origID, angle,
1277  speed, veh->getRoute().getEdges(), veh->getRoutePosition(), veh->getLane(), veh->getPositionOnLane(), veh->isOnRoad(),
1278  vClass, setLateralPos,
1279  bestDistance, &lane, lanePos, routeOffset, edges);
1280  }
1281  if ((found && bestDistance <= maxRouteDistance) || mayLeaveNetwork) {
1282  // optionally compute lateral offset
1283  pos.setz(veh->getPosition().z());
1284  if (found && setLateralPos) {
1285  const double perpDist = lane->getShape().distance2D(pos, false);
1286  if (perpDist != GeomHelper::INVALID_OFFSET) {
1287  lanePosLat = perpDist;
1288  if (!mayLeaveNetwork) {
1289  lanePosLat = MIN2(lanePosLat, 0.5 * (lane->getWidth() + veh->getVehicleType().getWidth() - MSGlobals::gLateralResolution));
1290  }
1291  // figure out whether the offset is to the left or to the right
1292  PositionVector tmp = lane->getShape();
1293  try {
1294  tmp.move2side(-lanePosLat); // moved to left
1295  } catch (ProcessError&) {
1296  WRITE_WARNING("Could not determine position on lane '" + lane->getID() + "' at lateral position " + toString(-lanePosLat) + ".");
1297  }
1298  //std::cout << " lane=" << lane->getID() << " posLat=" << lanePosLat << " shape=" << lane->getShape() << " tmp=" << tmp << " tmpDist=" << tmp.distance2D(pos) << "\n";
1299  if (tmp.distance2D(pos) > perpDist) {
1300  lanePosLat = -lanePosLat;
1301  }
1302  }
1303  pos.setz(lane->geometryPositionAtOffset(lanePos).z());
1304  }
1305  if (found && !mayLeaveNetwork && MSGlobals::gLateralResolution < 0) {
1306  // mapped position may differ from pos
1307  pos = lane->geometryPositionAtOffset(lanePos, -lanePosLat);
1308  }
1309  assert((found && lane != 0) || (!found && lane == 0));
1310  assert(!ISNAN(lanePos));
1311  if (angle == INVALID_DOUBLE_VALUE) {
1312  if (lane != nullptr) {
1313  angle = GeomHelper::naviDegree(lane->getShape().rotationAtOffset(lanePos));
1314  } else {
1315  // compute angle outside road network from old and new position
1316  angle = GeomHelper::naviDegree(veh->getPosition().angleTo2D(pos));
1317  }
1318  }
1319  // use the best we have
1320 #ifdef DEBUG_MOVEXY
1321  std::cout << SIMTIME << " veh=" << vehID + " moveToXYResult lane='" << Named::getIDSecure(lane) << "' lanePos=" << lanePos << " lanePosLat=" << lanePosLat << "\n";
1322 #endif
1323  Helper::setRemoteControlled(veh, pos, lane, lanePos, lanePosLat, angle, routeOffset, edges, MSNet::getInstance()->getCurrentTimeStep());
1324  if (!veh->isOnRoad()) {
1326  }
1327  } else {
1328  if (lane == nullptr) {
1329  throw TraCIException("Could not map vehicle '" + vehID + "', no road found within " + toString(maxRouteDistance) + "m.");
1330  } else {
1331  throw TraCIException("Could not map vehicle '" + vehID + "', distance to road is " + toString(bestDistance) + ".");
1332  }
1333  }
1334 }
1335 
1336 void
1337 Vehicle::slowDown(const std::string& vehID, double speed, double duration) {
1338  MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
1339  MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
1340  if (veh == nullptr) {
1341  WRITE_ERROR("slowDown not applicable for meso");
1342  return;
1343  }
1344 
1345  std::vector<std::pair<SUMOTime, double> > speedTimeLine;
1346  speedTimeLine.push_back(std::make_pair(MSNet::getInstance()->getCurrentTimeStep(), veh->getSpeed()));
1347  speedTimeLine.push_back(std::make_pair(MSNet::getInstance()->getCurrentTimeStep() + TIME2STEPS(duration), speed));
1348  veh->getInfluencer().setSpeedTimeLine(speedTimeLine);
1349 }
1350 
1351 void
1352 Vehicle::openGap(const std::string& vehID, double newTimeHeadway, double newSpaceHeadway, double duration, double changeRate, double maxDecel, const std::string& referenceVehID) {
1353  MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
1354  MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
1355  if (veh == nullptr) {
1356  WRITE_ERROR("openGap not applicable for meso");
1357  return;
1358  }
1359 
1360  MSVehicle* refVeh = nullptr;
1361  if (referenceVehID != "") {
1362  refVeh = dynamic_cast<MSVehicle*>(Helper::getVehicle(referenceVehID));
1363  }
1364  const double originalTau = veh->getVehicleType().getCarFollowModel().getHeadwayTime();
1365  if (newTimeHeadway == -1) {
1366  newTimeHeadway = originalTau;
1367  }
1368  if (originalTau > newTimeHeadway) {
1369  WRITE_WARNING("Ignoring openGap(). New time headway must not be smaller than the original.");
1370  return;
1371  }
1372  veh->getInfluencer().activateGapController(originalTau, newTimeHeadway, newSpaceHeadway, duration, changeRate, maxDecel, refVeh);
1373 }
1374 
1375 void
1376 Vehicle::deactivateGapControl(const std::string& vehID) {
1377  MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
1378  MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
1379  if (veh == nullptr) {
1380  WRITE_ERROR("deactivateGapControl not applicable for meso");
1381  return;
1382  }
1383 
1384  if (veh->hasInfluencer()) {
1386  }
1387 }
1388 
1389 void
1390 Vehicle::requestToC(const std::string& vehID, double leadTime) {
1391  setParameter(vehID, "device.toc.requestToC", toString(leadTime));
1392 }
1393 
1394 void
1395 Vehicle::setSpeed(const std::string& vehID, double speed) {
1396  MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
1397  MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
1398  if (veh == nullptr) {
1399  WRITE_WARNING("setSpeed not yet implemented for meso");
1400  return;
1401  }
1402 
1403  std::vector<std::pair<SUMOTime, double> > speedTimeLine;
1404  if (speed >= 0) {
1405  speedTimeLine.push_back(std::make_pair(MSNet::getInstance()->getCurrentTimeStep(), speed));
1406  speedTimeLine.push_back(std::make_pair(SUMOTime_MAX - DELTA_T, speed));
1407  }
1408  veh->getInfluencer().setSpeedTimeLine(speedTimeLine);
1409 }
1410 
1411 void
1412 Vehicle::setPreviousSpeed(const std::string& vehID, double prevspeed) {
1413  MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
1414  MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
1415  if (veh == nullptr) {
1416  WRITE_WARNING("setPreviousSpeed not yet implemented for meso");
1417  return;
1418  }
1419 
1420  veh->setPreviousSpeed(prevspeed);
1421 }
1422 
1423 void
1424 Vehicle::setSpeedMode(const std::string& vehID, int speedMode) {
1425  MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
1426  MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
1427  if (veh == nullptr) {
1428  WRITE_WARNING("setSpeedMode not yet implemented for meso");
1429  return;
1430  }
1431 
1432  veh->getInfluencer().setSpeedMode(speedMode);
1433 }
1434 
1435 void
1436 Vehicle::setLaneChangeMode(const std::string& vehID, int laneChangeMode) {
1437  MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
1438  MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
1439  if (veh == nullptr) {
1440  WRITE_ERROR("setLaneChangeMode not applicable for meso");
1441  return;
1442  }
1443 
1444  veh->getInfluencer().setLaneChangeMode(laneChangeMode);
1445 }
1446 
1447 void
1448 Vehicle::setRoutingMode(const std::string& vehID, int routingMode) {
1449  Helper::getVehicle(vehID)->getBaseInfluencer().setRoutingMode(routingMode);
1450 }
1451 
1452 void
1453 Vehicle::setType(const std::string& vehID, const std::string& typeID) {
1454  MSVehicleType* vehicleType = MSNet::getInstance()->getVehicleControl().getVType(typeID);
1455  if (vehicleType == nullptr) {
1456  throw TraCIException("Vehicle type '" + typeID + "' is not known");
1457  }
1458  Helper::getVehicle(vehID)->replaceVehicleType(vehicleType);
1459 }
1460 
1461 void
1462 Vehicle::setRouteID(const std::string& vehID, const std::string& routeID) {
1463  MSBaseVehicle* veh = Helper::getVehicle(vehID);
1464  const MSRoute* r = MSRoute::dictionary(routeID);
1465  if (r == nullptr) {
1466  throw TraCIException("The route '" + routeID + "' is not known.");
1467  }
1468  std::string msg;
1469  if (!veh->hasValidRoute(msg, r)) {
1470  WRITE_WARNING("Invalid route replacement for vehicle '" + veh->getID() + "'. " + msg);
1472  throw TraCIException("Route replacement failed for " + veh->getID());
1473  }
1474  }
1475 
1476  std::string errorMsg;
1477  if (!veh->replaceRoute(r, "traci:setRouteID", veh->getLane() == nullptr, 0, true, true, &errorMsg)) {
1478  throw TraCIException("Route replacement failed for vehicle '" + veh->getID() + "' (" + errorMsg + ").");
1479  }
1480 }
1481 
1482 void
1483 Vehicle::setRoute(const std::string& vehID, const std::string& edgeID) {
1484  setRoute(vehID, std::vector<std::string>({edgeID}));
1485 }
1486 
1487 void
1488 Vehicle::setRoute(const std::string& vehID, const std::vector<std::string>& edgeIDs) {
1489  MSBaseVehicle* veh = Helper::getVehicle(vehID);
1490  ConstMSEdgeVector edges;
1491  const bool onInit = veh->getLane() == nullptr;
1492  try {
1493  MSEdge::parseEdgesList(edgeIDs, edges, "<unknown>");
1494  if (edges.size() > 0 && edges.front()->isInternal()) {
1495  if (edges.size() == 1) {
1496  // avoid crashing due to lack of normal edges in route (#5390)
1497  edges.push_back(edges.back()->getLanes()[0]->getNextNormal());
1498  } else {
1499  // avoid internal edge in final route
1500  if (edges.front() == &veh->getLane()->getEdge()) {
1501  edges.erase(edges.begin());
1502  }
1503  }
1504  }
1505  } catch (ProcessError& e) {
1506  throw TraCIException("Invalid edge list for vehicle '" + veh->getID() + "' (" + e.what() + ")");
1507  }
1508  std::string errorMsg;
1509  if (!veh->replaceRouteEdges(edges, -1, 0, "traci:setRoute", onInit, true, true, &errorMsg)) {
1510  throw TraCIException("Route replacement failed for vehicle '" + veh->getID() + "' (" + errorMsg + ").");
1511  }
1512 }
1513 
1514 void
1515 Vehicle::updateBestLanes(const std::string& vehID) {
1516  MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
1517  MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
1518  if (veh == nullptr) {
1519  WRITE_ERROR("updateBestLanes not applicable for meso");
1520  return;
1521  }
1522 
1523  veh->updateBestLanes(true);
1524 }
1525 
1526 
1527 void
1528 Vehicle::setAdaptedTraveltime(const std::string& vehID, const std::string& edgeID,
1529  double time, double begSeconds, double endSeconds) {
1530  MSBaseVehicle* veh = Helper::getVehicle(vehID);
1531  MSEdge* edge = MSEdge::dictionary(edgeID);
1532  if (edge == nullptr) {
1533  throw TraCIException("Edge '" + edgeID + "' is not known.");
1534  }
1535  if (time != INVALID_DOUBLE_VALUE) {
1536  // add time
1537  if (begSeconds == 0 && endSeconds == std::numeric_limits<double>::max()) {
1538  // clean up old values before setting whole range
1539  while (veh->getWeightsStorage().knowsTravelTime(edge)) {
1540  veh->getWeightsStorage().removeTravelTime(edge);
1541  }
1542  }
1543  veh->getWeightsStorage().addTravelTime(edge, begSeconds, endSeconds, time);
1544  } else {
1545  // remove time
1546  while (veh->getWeightsStorage().knowsTravelTime(edge)) {
1547  veh->getWeightsStorage().removeTravelTime(edge);
1548  }
1549  }
1550 }
1551 
1552 
1553 void
1554 Vehicle::setEffort(const std::string& vehID, const std::string& edgeID,
1555  double effort, double begSeconds, double endSeconds) {
1556  MSBaseVehicle* veh = Helper::getVehicle(vehID);
1557  MSEdge* edge = MSEdge::dictionary(edgeID);
1558  if (edge == nullptr) {
1559  throw TraCIException("Edge '" + edgeID + "' is not known.");
1560  }
1561  if (effort != INVALID_DOUBLE_VALUE) {
1562  // add effort
1563  if (begSeconds == 0 && endSeconds == std::numeric_limits<double>::max()) {
1564  // clean up old values before setting whole range
1565  while (veh->getWeightsStorage().knowsEffort(edge)) {
1566  veh->getWeightsStorage().removeEffort(edge);
1567  }
1568  }
1569  veh->getWeightsStorage().addEffort(edge, begSeconds, endSeconds, effort);
1570  } else {
1571  // remove effort
1572  while (veh->getWeightsStorage().knowsEffort(edge)) {
1573  veh->getWeightsStorage().removeEffort(edge);
1574  }
1575  }
1576 }
1577 
1578 
1579 void
1580 Vehicle::rerouteTraveltime(const std::string& vehID, const bool currentTravelTimes) {
1581  UNUSED_PARAMETER(currentTravelTimes); // !!! see #5943
1582  MSBaseVehicle* veh = Helper::getVehicle(vehID);
1583  veh->reroute(MSNet::getInstance()->getCurrentTimeStep(), "traci:rerouteTraveltime",
1584  veh->getBaseInfluencer().getRouterTT(veh->getRNGIndex(), veh->getVClass()), isOnInit(vehID));
1585 }
1586 
1587 
1588 void
1589 Vehicle::rerouteEffort(const std::string& vehID) {
1590  MSBaseVehicle* veh = Helper::getVehicle(vehID);
1591  veh->reroute(MSNet::getInstance()->getCurrentTimeStep(), "traci:rerouteEffort",
1592  MSNet::getInstance()->getRouterEffort(veh->getRNGIndex()), isOnInit(vehID));
1593 }
1594 
1595 
1596 void
1597 Vehicle::setSignals(const std::string& vehID, int signals) {
1598  MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
1599  MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
1600  if (veh == nullptr) {
1601  WRITE_ERROR("setSignals not applicable for meso");
1602  return;
1603  }
1604 
1605  // set influencer to make the change persistent
1606  veh->getInfluencer().setSignals(signals);
1607  // set them now so that getSignals returns the correct value
1608  veh->switchOffSignal(0x0fffffff);
1609  if (signals >= 0) {
1610  veh->switchOnSignal(signals);
1611  }
1612 }
1613 
1614 
1615 void
1616 Vehicle::moveTo(const std::string& vehID, const std::string& laneID, double position, int reason) {
1617  MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
1618  MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
1619  if (veh == nullptr) {
1620  WRITE_WARNING("moveTo not yet implemented for meso");
1621  return;
1622  }
1623 
1624  MSLane* l = MSLane::dictionary(laneID);
1625  if (l == nullptr) {
1626  throw TraCIException("Unknown lane '" + laneID + "'.");
1627  }
1628  if (veh->getLane() == l) {
1629  veh->setTentativeLaneAndPosition(l, position, veh->getLateralPositionOnLane());
1630  return;
1631  }
1632  MSEdge* destinationEdge = &l->getEdge();
1633  const MSEdge* destinationRouteEdge = destinationEdge->getNormalBefore();
1634  if (!veh->isOnRoad() && veh->getParameter().wasSet(VEHPARS_FORCE_REROUTE) && veh->getRoute().getEdges().size() == 2) {
1635  // it's a trip that wasn't routeted yet (likely because the vehicle was added in this step. Find a route now
1636  veh->reroute(MSNet::getInstance()->getCurrentTimeStep(), "traci:moveTo-tripInsertion",
1637  veh->getBaseInfluencer().getRouterTT(veh->getRNGIndex(), veh->getVClass()), true);
1638  }
1639  // find edge in the remaining route
1640  MSRouteIterator it = std::find(veh->getCurrentRouteEdge(), veh->getRoute().end(), destinationRouteEdge);
1641  if (it == veh->getRoute().end()) {
1642  // find edge in the edges that were already passed
1643  it = std::find(veh->getRoute().begin(), veh->getRoute().end(), destinationRouteEdge);
1644  }
1645  if (it == veh->getRoute().end() ||
1646  // internal edge must continue the route
1647  (destinationEdge->isInternal() &&
1648  ((it + 1) == veh->getRoute().end()
1649  || l->getNextNormal() != *(it + 1)))) {
1650  throw TraCIException("Lane '" + laneID + "' is not on the route of vehicle '" + vehID + "'.");
1651  }
1652  Position oldPos = vehicle->getPosition();
1654  if (veh->getLane() != nullptr) {
1655  // correct odometer which gets incremented via onRemovalFromNet->leaveLane
1656  veh->addToOdometer(-veh->getLane()->getLength());
1658  } else {
1659  veh->setTentativeLaneAndPosition(l, position);
1660  }
1661  const int oldRouteIndex = veh->getRoutePosition();
1662  const int newRouteIndex = (int)(it - veh->getRoute().begin());
1663  if (oldRouteIndex > newRouteIndex) {
1664  // more odometer correction needed
1665  veh->addToOdometer(-l->getLength());
1666  }
1667  veh->resetRoutePosition(newRouteIndex, veh->getParameter().departLaneProcedure);
1668  if (!veh->isOnRoad()) {
1670  }
1671  MSMoveReminder::Notification moveReminderReason;
1672  if (veh->hasDeparted()) {
1673  if (reason == MOVE_TELEPORT) {
1674  moveReminderReason = MSMoveReminder::NOTIFICATION_TELEPORT;
1675  } else if (reason == MOVE_NORMAL) {
1676  moveReminderReason = MSMoveReminder::NOTIFICATION_JUNCTION;
1677  } else if (reason == MOVE_AUTOMATIC) {
1678  Position newPos = l->geometryPositionAtOffset(position);
1679  const double dist = newPos.distanceTo2D(oldPos);
1680  if (dist < SPEED2DIST(veh->getMaxSpeed())) {
1681  moveReminderReason = MSMoveReminder::NOTIFICATION_JUNCTION;
1682  } else {
1683  moveReminderReason = MSMoveReminder::NOTIFICATION_TELEPORT;
1684  }
1685  } else {
1686  throw TraCIException("Invalid moveTo reason '" + toString(reason) + "' for vehicle '" + vehID + "'.");
1687  }
1688  } else {
1689  moveReminderReason = MSMoveReminder::NOTIFICATION_DEPARTED;
1690  }
1691  l->forceVehicleInsertion(veh, position, moveReminderReason);
1692 }
1693 
1694 
1695 void
1696 Vehicle::setActionStepLength(const std::string& vehID, double actionStepLength, bool resetActionOffset) {
1697  if (actionStepLength < 0.0) {
1698  WRITE_ERROR("Invalid action step length (<0). Ignoring command setActionStepLength().");
1699  return;
1700  }
1701  MSBaseVehicle* vehicle = Helper::getVehicle(vehID);
1702  MSVehicle* veh = dynamic_cast<MSVehicle*>(vehicle);
1703  if (veh == nullptr) {
1704  WRITE_ERROR("setActionStepLength not applicable for meso");
1705  return;
1706  }
1707 
1708  if (actionStepLength == 0.) {
1709  veh->resetActionOffset();
1710  } else {
1711  veh->setActionStepLength(actionStepLength, resetActionOffset);
1712  }
1713 }
1714 
1715 
1716 void
1717 Vehicle::remove(const std::string& vehID, char reason) {
1718  MSBaseVehicle* veh = Helper::getVehicle(vehID);
1720  switch (reason) {
1721  case REMOVE_TELEPORT:
1722  // XXX semantics unclear
1723  // n = MSMoveReminder::NOTIFICATION_TELEPORT;
1725  break;
1726  case REMOVE_PARKING:
1727  // XXX semantics unclear
1728  // n = MSMoveReminder::NOTIFICATION_PARKING;
1730  break;
1731  case REMOVE_ARRIVED:
1733  break;
1734  case REMOVE_VAPORIZED:
1736  break;
1739  break;
1740  default:
1741  throw TraCIException("Unknown removal status.");
1742  }
1743  if (veh->hasDeparted()) {
1744  veh->onRemovalFromNet(n);
1745  MSVehicle* microVeh = dynamic_cast<MSVehicle*>(veh);
1746  if (microVeh != nullptr) {
1747  if (veh->getLane() != nullptr) {
1748  microVeh->getMutableLane()->removeVehicle(dynamic_cast<MSVehicle*>(veh), n);
1749  }
1751  }
1753  } else {
1756  }
1757 }
1758 
1759 
1760 void
1761 Vehicle::setColor(const std::string& vehID, const TraCIColor& col) {
1763  p.color.set((unsigned char)col.r, (unsigned char)col.g, (unsigned char)col.b, (unsigned char)col.a);
1765 }
1766 
1767 
1768 void
1769 Vehicle::setSpeedFactor(const std::string& vehID, double factor) {
1770  Helper::getVehicle(vehID)->setChosenSpeedFactor(factor);
1771 }
1772 
1773 
1774 void
1775 Vehicle::setLine(const std::string& vehID, const std::string& line) {
1776  Helper::getVehicle(vehID)->getParameter().line = line;
1777 }
1778 
1779 
1780 void
1781 Vehicle::setVia(const std::string& vehID, const std::vector<std::string>& via) {
1782  MSBaseVehicle* veh = Helper::getVehicle(vehID);
1783  try {
1784  // ensure edges exist
1785  ConstMSEdgeVector edges;
1786  MSEdge::parseEdgesList(via, edges, "<via-edges>");
1787  } catch (ProcessError& e) {
1788  throw TraCIException(e.what());
1789  }
1790  veh->getParameter().via = via;
1791 }
1792 
1793 
1794 void
1795 Vehicle::setLength(const std::string& vehID, double length) {
1796  Helper::getVehicle(vehID)->getSingularType().setLength(length);
1797 }
1798 
1799 
1800 void
1801 Vehicle::setMaxSpeed(const std::string& vehID, double speed) {
1803 }
1804 
1805 
1806 void
1807 Vehicle::setVehicleClass(const std::string& vehID, const std::string& clazz) {
1809 }
1810 
1811 
1812 void
1813 Vehicle::setShapeClass(const std::string& vehID, const std::string& clazz) {
1815 }
1816 
1817 
1818 void
1819 Vehicle::setEmissionClass(const std::string& vehID, const std::string& clazz) {
1821 }
1822 
1823 
1824 void
1825 Vehicle::setWidth(const std::string& vehID, double width) {
1826  Helper::getVehicle(vehID)->getSingularType().setWidth(width);
1827 }
1828 
1829 
1830 void
1831 Vehicle::setHeight(const std::string& vehID, double height) {
1832  Helper::getVehicle(vehID)->getSingularType().setHeight(height);
1833 }
1834 
1835 
1836 void
1837 Vehicle::setMinGap(const std::string& vehID, double minGap) {
1838  Helper::getVehicle(vehID)->getSingularType().setMinGap(minGap);
1839 }
1840 
1841 
1842 void
1843 Vehicle::setAccel(const std::string& vehID, double accel) {
1844  Helper::getVehicle(vehID)->getSingularType().setAccel(accel);
1845 }
1846 
1847 
1848 void
1849 Vehicle::setDecel(const std::string& vehID, double decel) {
1850  VehicleType::setDecel(Helper::getVehicle(vehID)->getSingularType().getID(), decel);
1851 }
1852 
1853 
1854 void
1855 Vehicle::setEmergencyDecel(const std::string& vehID, double decel) {
1856  VehicleType::setEmergencyDecel(Helper::getVehicle(vehID)->getSingularType().getID(), decel);
1857 }
1858 
1859 
1860 void
1861 Vehicle::setApparentDecel(const std::string& vehID, double decel) {
1863 }
1864 
1865 
1866 void
1867 Vehicle::setImperfection(const std::string& vehID, double imperfection) {
1868  Helper::getVehicle(vehID)->getSingularType().setImperfection(imperfection);
1869 }
1870 
1871 
1872 void
1873 Vehicle::setTau(const std::string& vehID, double tau) {
1874  Helper::getVehicle(vehID)->getSingularType().setTau(tau);
1875 }
1876 
1877 
1878 void
1879 Vehicle::setMinGapLat(const std::string& vehID, double minGapLat) {
1880  try {
1881  setParameter(vehID, "laneChangeModel.minGapLat", toString(minGapLat));
1882  } catch (TraCIException&) {
1883  // legacy behavior
1884  Helper::getVehicle(vehID)->getSingularType().setMinGapLat(minGapLat);
1885  }
1886 }
1887 
1888 
1889 void
1890 Vehicle::setMaxSpeedLat(const std::string& vehID, double speed) {
1892 }
1893 
1894 
1895 void
1896 Vehicle::setLateralAlignment(const std::string& vehID, const std::string& latAlignment) {
1897  double lao;
1899  if (SUMOVTypeParameter::parseLatAlignment(latAlignment, lao, lad)) {
1901  } else {
1902  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)");
1903  }
1904 }
1905 
1906 
1907 void
1908 Vehicle::setParameter(const std::string& vehID, const std::string& key, const std::string& value) {
1909  MSBaseVehicle* veh = Helper::getVehicle(vehID);
1910  MSVehicle* microVeh = dynamic_cast<MSVehicle*>(veh);
1911  if (StringUtils::startsWith(key, "device.")) {
1912  StringTokenizer tok(key, ".");
1913  if (tok.size() < 3) {
1914  throw TraCIException("Invalid device parameter '" + key + "' for vehicle '" + vehID + "'");
1915  }
1916  try {
1917  veh->setDeviceParameter(tok.get(1), key.substr(tok.get(0).size() + tok.get(1).size() + 2), value);
1918  } catch (InvalidArgument& e) {
1919  throw TraCIException("Vehicle '" + vehID + "' does not support device parameter '" + key + "' (" + e.what() + ").");
1920  }
1921  } else if (StringUtils::startsWith(key, "laneChangeModel.")) {
1922  if (microVeh == nullptr) {
1923  throw TraCIException("Meso Vehicle '" + vehID + "' does not support laneChangeModel parameters.");
1924  }
1925  const std::string attrName = key.substr(16);
1926  try {
1927  microVeh->getLaneChangeModel().setParameter(attrName, value);
1928  } catch (InvalidArgument& e) {
1929  throw TraCIException("Vehicle '" + vehID + "' does not support laneChangeModel parameter '" + key + "' (" + e.what() + ").");
1930  }
1931  } else if (StringUtils::startsWith(key, "carFollowModel.")) {
1932  if (microVeh == nullptr) {
1933  throw TraCIException("Meso Vehicle '" + vehID + "' does not support carFollowModel parameters.");
1934  }
1935  const std::string attrName = key.substr(15);
1936  try {
1937  microVeh->getCarFollowModel().setParameter(microVeh, attrName, value);
1938  } catch (InvalidArgument& e) {
1939  throw TraCIException("Vehicle '" + vehID + "' does not support carFollowModel parameter '" + key + "' (" + e.what() + ").");
1940  }
1941  } else if (StringUtils::startsWith(key, "junctionModel.")) {
1942  try {
1943  // use the whole key (including junctionModel prefix)
1944  veh->setJunctionModelParameter(key, value);
1945  } catch (InvalidArgument& e) {
1946  // error message includes id since it is also used for xml input
1947  throw TraCIException(e.what());
1948  }
1949  } else if (StringUtils::startsWith(key, "has.") && StringUtils::endsWith(key, ".device")) {
1950  StringTokenizer tok(key, ".");
1951  if (tok.size() != 3) {
1952  throw TraCIException("Invalid request for device status change. Expected format is 'has.DEVICENAME.device'");
1953  }
1954  const std::string deviceName = tok.get(1);
1955  bool create;
1956  try {
1957  create = StringUtils::toBool(value);
1958  } catch (BoolFormatException&) {
1959  throw TraCIException("Changing device status requires a 'true' or 'false'");
1960  }
1961  if (!create) {
1962  throw TraCIException("Device removal is not supported for device of type '" + deviceName + "'");
1963  }
1964  try {
1965  veh->createDevice(deviceName);
1966  } catch (InvalidArgument& e) {
1967  throw TraCIException("Cannot create vehicle device (" + std::string(e.what()) + ").");
1968  }
1969  } else {
1970  ((SUMOVehicleParameter&)veh->getParameter()).setParameter(key, value);
1971  }
1972 }
1973 
1974 
1975 void
1976 Vehicle::highlight(const std::string& vehID, const TraCIColor& col, double size, const int alphaMax, const double duration, const int type) {
1977  // NOTE: Code is duplicated in large parts in POI.cpp
1978  MSBaseVehicle* veh = Helper::getVehicle(vehID);
1979 
1980  // Center of the highlight circle
1981  Position center = veh->getPosition();
1982  const double l2 = veh->getLength() * 0.5;
1983  center.sub(cos(veh->getAngle())*l2, sin(veh->getAngle())*l2);
1984  // Size of the highlight circle
1985  if (size <= 0) {
1986  size = veh->getLength() * 0.7;
1987  }
1988  // Make polygon shape
1989  const unsigned int nPoints = 34;
1990  const PositionVector circlePV = GeomHelper::makeRing(size, size + 1., center, nPoints);
1991  TraCIPositionVector circle = Helper::makeTraCIPositionVector(circlePV);
1992 
1993 #ifdef DEBUG_DYNAMIC_SHAPES
1994  std::cout << SIMTIME << " Vehicle::highlight() for vehicle '" << vehID << "'\n"
1995  << " circle: " << circlePV << std::endl;
1996 #endif
1997 
1998  // Find a free polygon id
1999  int i = 0;
2000  std::string polyID = veh->getID() + "_hl" + toString(i);
2001  while (Polygon::exists(polyID)) {
2002  polyID = veh->getID() + "_hl" + toString(++i);
2003  }
2004  // Line width
2005  double lw = 0.;
2006  // Layer
2007  double lyr = 0.;
2008  if (MSNet::getInstance()->isGUINet()) {
2009  lyr = GLO_VEHICLE + 0.01;
2010  lyr += (type + 1) / 257.;
2011  }
2012  // Make Polygon
2013  Polygon::addHighlightPolygon(vehID, type, polyID, circle, col, true, "highlight", (int)lyr, lw);
2014 
2015  // Animation time line
2016  double maxAttack = 1.0; // maximal fade-in time
2017  std::vector<double> timeSpan;
2018  if (duration > 0.) {
2019  timeSpan = {0, MIN2(maxAttack, duration / 3.), 2.*duration / 3., duration};
2020  }
2021  // Alpha time line
2022  std::vector<double> alphaSpan;
2023  if (alphaMax > 0.) {
2024  alphaSpan = {0., (double) alphaMax, (double)(alphaMax) / 3., 0.};
2025  }
2026  // Attach dynamics
2027  Polygon::addDynamics(polyID, vehID, timeSpan, alphaSpan, false, true);
2028 }
2029 
2030 void
2031 Vehicle::dispatchTaxi(const std::string& vehID, const std::vector<std::string>& reservations) {
2032  MSBaseVehicle* veh = Helper::getVehicle(vehID);
2033  MSDevice_Taxi* taxi = static_cast<MSDevice_Taxi*>(veh->getDevice(typeid(MSDevice_Taxi)));
2034  if (taxi == nullptr) {
2035  throw TraCIException("Vehicle '" + vehID + "' is not a taxi");
2036  }
2038  if (dispatcher == nullptr) {
2039  throw TraCIException("Cannot dispatch taxi because no reservations have been made");
2040  }
2041  MSDispatch_TraCI* traciDispatcher = dynamic_cast<MSDispatch_TraCI*>(dispatcher);
2042  if (traciDispatcher == nullptr) {
2043  throw TraCIException("device.taxi.dispatch-algorithm 'traci' has not been loaded");
2044  }
2045  if (reservations.size() == 0) {
2046  throw TraCIException("No reservations have been specified for vehicle '" + vehID + "'");
2047  }
2048  try {
2049  traciDispatcher->interpretDispatch(taxi, reservations);
2050  } catch (InvalidArgument& e) {
2051  throw TraCIException("Could not interpret reservations for vehicle '" + vehID + "' (" + e.what() + ").");
2052  }
2053 }
2054 
2056 
2057 
2058 void
2059 Vehicle::subscribeLeader(const std::string& vehID, double dist, double begin, double end) {
2060  subscribe(vehID, std::vector<int>({ libsumo::VAR_LEADER }), begin, end,
2061  libsumo::TraCIResults({ {libsumo::VAR_LEADER, std::make_shared<libsumo::TraCIDouble>(dist)} }));
2062 }
2063 
2064 
2065 void
2066 Vehicle::addSubscriptionFilterLanes(const std::vector<int>& lanes, bool noOpposite, double downstreamDist, double upstreamDist) {
2068  if (s != nullptr) {
2069  s->filterLanes = lanes;
2070  }
2071  if (noOpposite) {
2072  addSubscriptionFilterNoOpposite();
2073  }
2074  if (downstreamDist != INVALID_DOUBLE_VALUE) {
2075  addSubscriptionFilterDownstreamDistance(downstreamDist);
2076  }
2077  if (upstreamDist != INVALID_DOUBLE_VALUE) {
2078  addSubscriptionFilterUpstreamDistance(upstreamDist);
2079  }
2080 }
2081 
2082 
2083 void
2084 Vehicle::addSubscriptionFilterNoOpposite() {
2086 }
2087 
2088 
2089 void
2090 Vehicle::addSubscriptionFilterDownstreamDistance(double dist) {
2092  if (s != nullptr) {
2093  s->filterDownstreamDist = dist;
2094  }
2095 }
2096 
2097 
2098 void
2099 Vehicle::addSubscriptionFilterUpstreamDistance(double dist) {
2101  if (s != nullptr) {
2102  s->filterUpstreamDist = dist;
2103  }
2104 }
2105 
2106 
2107 void
2108 Vehicle::addSubscriptionFilterCFManeuver(double downstreamDist, double upstreamDist) {
2109  addSubscriptionFilterLeadFollow(std::vector<int>({0}));
2110  if (downstreamDist != INVALID_DOUBLE_VALUE) {
2111  addSubscriptionFilterDownstreamDistance(downstreamDist);
2112  }
2113  if (upstreamDist != INVALID_DOUBLE_VALUE) {
2114  addSubscriptionFilterUpstreamDistance(upstreamDist);
2115  }
2116 
2117 }
2118 
2119 
2120 void
2121 Vehicle::addSubscriptionFilterLCManeuver(int direction, bool noOpposite, double downstreamDist, double upstreamDist) {
2122  std::vector<int> lanes;
2123  if (direction == INVALID_INT_VALUE) {
2124  // Using default: both directions
2125  lanes = std::vector<int>({-1, 0, 1});
2126  } else if (direction != -1 && direction != 1) {
2127  WRITE_WARNING("Ignoring lane change subscription filter with non-neighboring lane offset direction=" +
2128  toString(direction) + ".");
2129  } else {
2130  lanes = std::vector<int>({0, direction});
2131  }
2132  addSubscriptionFilterLeadFollow(lanes);
2133  if (noOpposite) {
2134  addSubscriptionFilterNoOpposite();
2135  }
2136  if (downstreamDist != INVALID_DOUBLE_VALUE) {
2137  addSubscriptionFilterDownstreamDistance(downstreamDist);
2138  }
2139  if (upstreamDist != INVALID_DOUBLE_VALUE) {
2140  addSubscriptionFilterUpstreamDistance(upstreamDist);
2141  }
2142 }
2143 
2144 
2145 void
2146 Vehicle::addSubscriptionFilterLeadFollow(const std::vector<int>& lanes) {
2148  addSubscriptionFilterLanes(lanes);
2149 }
2150 
2151 
2152 void
2153 Vehicle::addSubscriptionFilterTurn(double downstreamDist, double foeDistToJunction) {
2155  if (downstreamDist != INVALID_DOUBLE_VALUE) {
2156  addSubscriptionFilterDownstreamDistance(downstreamDist);
2157  }
2158  if (foeDistToJunction != INVALID_DOUBLE_VALUE) {
2159  s->filterFoeDistToJunction = foeDistToJunction;
2160  }
2161 }
2162 
2163 
2164 void
2165 Vehicle::addSubscriptionFilterVClass(const std::vector<std::string>& vClasses) {
2167  if (s != nullptr) {
2168  s->filterVClasses = parseVehicleClasses(vClasses);
2169  }
2170 }
2171 
2172 
2173 void
2174 Vehicle::addSubscriptionFilterVType(const std::vector<std::string>& vTypes) {
2176  if (s != nullptr) {
2177  s->filterVTypes.insert(vTypes.begin(), vTypes.end());
2178  }
2179 }
2180 
2181 
2182 void
2183 Vehicle::addSubscriptionFilterFieldOfVision(double openingAngle) {
2185  if (s != nullptr) {
2186  s->filterFieldOfVisionOpeningAngle = openingAngle;
2187  }
2188 }
2189 
2190 
2191 void
2192 Vehicle::addSubscriptionFilterLateralDistance(double lateralDist, double downstreamDist, double upstreamDist) {
2194  if (s != nullptr) {
2195  s->filterLateralDist = lateralDist;
2196  }
2197  if (downstreamDist != INVALID_DOUBLE_VALUE) {
2198  addSubscriptionFilterDownstreamDistance(downstreamDist);
2199  }
2200  if (upstreamDist != INVALID_DOUBLE_VALUE) {
2201  addSubscriptionFilterUpstreamDistance(upstreamDist);
2202  }
2203 }
2204 
2205 
2206 void
2207 Vehicle::storeShape(const std::string& id, PositionVector& shape) {
2208  shape.push_back(Helper::getVehicle(id)->getPosition());
2209 }
2210 
2211 
2212 std::shared_ptr<VariableWrapper>
2213 Vehicle::makeWrapper() {
2214  return std::make_shared<Helper::SubscriptionWrapper>(handleVariable, mySubscriptionResults, myContextSubscriptionResults);
2215 }
2216 
2217 
2218 bool
2219 Vehicle::handleVariable(const std::string& objID, const int variable, VariableWrapper* wrapper, tcpip::Storage* paramData) {
2220  switch (variable) {
2221  case TRACI_ID_LIST:
2222  return wrapper->wrapStringList(objID, variable, getIDList());
2223  case ID_COUNT:
2224  return wrapper->wrapInt(objID, variable, getIDCount());
2225  case VAR_POSITION:
2226  return wrapper->wrapPosition(objID, variable, getPosition(objID));
2227  case VAR_POSITION3D:
2228  return wrapper->wrapPosition(objID, variable, getPosition(objID, true));
2229  case VAR_ANGLE:
2230  return wrapper->wrapDouble(objID, variable, getAngle(objID));
2231  case VAR_SPEED:
2232  return wrapper->wrapDouble(objID, variable, getSpeed(objID));
2233  case VAR_SPEED_LAT:
2234  return wrapper->wrapDouble(objID, variable, getLateralSpeed(objID));
2235  case VAR_ROAD_ID:
2236  return wrapper->wrapString(objID, variable, getRoadID(objID));
2238  return wrapper->wrapDouble(objID, variable, getSpeedWithoutTraCI(objID));
2239  case VAR_SLOPE:
2240  return wrapper->wrapDouble(objID, variable, getSlope(objID));
2241  case VAR_LANE_ID:
2242  return wrapper->wrapString(objID, variable, getLaneID(objID));
2243  case VAR_LANE_INDEX:
2244  return wrapper->wrapInt(objID, variable, getLaneIndex(objID));
2245  case VAR_TYPE:
2246  return wrapper->wrapString(objID, variable, getTypeID(objID));
2247  case VAR_ROUTE_ID:
2248  return wrapper->wrapString(objID, variable, getRouteID(objID));
2249  case VAR_ROUTE_INDEX:
2250  return wrapper->wrapInt(objID, variable, getRouteIndex(objID));
2251  case VAR_COLOR:
2252  return wrapper->wrapColor(objID, variable, getColor(objID));
2253  case VAR_LANEPOSITION:
2254  return wrapper->wrapDouble(objID, variable, getLanePosition(objID));
2255  case VAR_LANEPOSITION_LAT:
2256  return wrapper->wrapDouble(objID, variable, getLateralLanePosition(objID));
2257  case VAR_CO2EMISSION:
2258  return wrapper->wrapDouble(objID, variable, getCO2Emission(objID));
2259  case VAR_COEMISSION:
2260  return wrapper->wrapDouble(objID, variable, getCOEmission(objID));
2261  case VAR_HCEMISSION:
2262  return wrapper->wrapDouble(objID, variable, getHCEmission(objID));
2263  case VAR_PMXEMISSION:
2264  return wrapper->wrapDouble(objID, variable, getPMxEmission(objID));
2265  case VAR_NOXEMISSION:
2266  return wrapper->wrapDouble(objID, variable, getNOxEmission(objID));
2267  case VAR_FUELCONSUMPTION:
2268  return wrapper->wrapDouble(objID, variable, getFuelConsumption(objID));
2269  case VAR_NOISEEMISSION:
2270  return wrapper->wrapDouble(objID, variable, getNoiseEmission(objID));
2272  return wrapper->wrapDouble(objID, variable, getElectricityConsumption(objID));
2273  case VAR_PERSON_NUMBER:
2274  return wrapper->wrapInt(objID, variable, getPersonNumber(objID));
2275  case VAR_PERSON_CAPACITY:
2276  return wrapper->wrapInt(objID, variable, getPersonCapacity(objID));
2278  return wrapper->wrapStringList(objID, variable, getPersonIDList(objID));
2279  case VAR_WAITING_TIME:
2280  return wrapper->wrapDouble(objID, variable, getWaitingTime(objID));
2282  return wrapper->wrapDouble(objID, variable, getAccumulatedWaitingTime(objID));
2283  case VAR_ROUTE_VALID:
2284  return wrapper->wrapInt(objID, variable, isRouteValid(objID));
2285  case VAR_EDGES:
2286  return wrapper->wrapStringList(objID, variable, getRoute(objID));
2287  case VAR_SIGNALS:
2288  return wrapper->wrapInt(objID, variable, getSignals(objID));
2289  case VAR_STOPSTATE:
2290  return wrapper->wrapInt(objID, variable, getStopState(objID));
2291  case VAR_DISTANCE:
2292  return wrapper->wrapDouble(objID, variable, getDistance(objID));
2293  case VAR_ALLOWED_SPEED:
2294  return wrapper->wrapDouble(objID, variable, getAllowedSpeed(objID));
2295  case VAR_SPEED_FACTOR:
2296  return wrapper->wrapDouble(objID, variable, getSpeedFactor(objID));
2297  case VAR_SPEEDSETMODE:
2298  return wrapper->wrapInt(objID, variable, getSpeedMode(objID));
2299  case VAR_LANECHANGE_MODE:
2300  return wrapper->wrapInt(objID, variable, getLaneChangeMode(objID));
2301  case VAR_ROUTING_MODE:
2302  return wrapper->wrapInt(objID, variable, getRoutingMode(objID));
2303  case VAR_LINE:
2304  return wrapper->wrapString(objID, variable, getLine(objID));
2305  case VAR_VIA:
2306  return wrapper->wrapStringList(objID, variable, getVia(objID));
2307  case VAR_ACCELERATION:
2308  return wrapper->wrapDouble(objID, variable, getAcceleration(objID));
2309  case VAR_LASTACTIONTIME:
2310  return wrapper->wrapDouble(objID, variable, getLastActionTime(objID));
2311  case VAR_STOP_DELAY:
2312  return wrapper->wrapDouble(objID, variable, getStopDelay(objID));
2313  case VAR_STOP_ARRIVALDELAY:
2314  return wrapper->wrapDouble(objID, variable, getStopArrivalDelay(objID));
2315  case VAR_TIMELOSS:
2316  return wrapper->wrapDouble(objID, variable, getTimeLoss(objID));
2317  case VAR_MINGAP_LAT:
2318  return wrapper->wrapDouble(objID, variable, getMinGapLat(objID));
2319  case VAR_LEADER: {
2320  paramData->readUnsignedByte();
2321  const double dist = paramData->readDouble();
2322  return wrapper->wrapStringDoublePair(objID, variable, getLeader(objID, dist));
2323  }
2324  case VAR_FOLLOWER: {
2325  paramData->readUnsignedByte();
2326  const double dist = paramData->readDouble();
2327  return wrapper->wrapStringDoublePair(objID, variable, getFollower(objID, dist));
2328  }
2330  paramData->readUnsignedByte();
2331  return wrapper->wrapString(objID, variable, getParameter(objID, paramData->readString()));
2333  paramData->readUnsignedByte();
2334  return wrapper->wrapStringPair(objID, variable, getParameterWithKey(objID, paramData->readString()));
2335  case VAR_TAXI_FLEET:
2336  // we cannot use the general fall through here because we do not have an object id
2337  return false;
2338  default:
2339  return VehicleType::handleVariableWithID(objID, getTypeID(objID), variable, wrapper, paramData);
2340  }
2341 }
2342 
2343 
2344 }
2345 
2346 
2347 /****************************************************************************/
@ 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:32
ConstMSEdgeVector::const_iterator MSRouteIterator
Definition: MSRoute.h:54
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:288
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:280
SUMOTime DELTA_T
Definition: SUMOTime.cpp:37
#define STEPS2TIME(x)
Definition: SUMOTime.h:53
#define SPEED2DIST(x)
Definition: SUMOTime.h:43
#define SUMOTime_MAX
Definition: SUMOTime.h:33
#define SIMTIME
Definition: SUMOTime.h:60
#define TIME2STEPS(x)
Definition: SUMOTime.h:55
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.
StringBijection< SUMOVehicleClass > SumoVehicleClassStrings(sumoVehicleClassStringInitializer, SVC_CUSTOM2, false)
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.
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
@ SVC_IGNORING
vehicles ignoring classes
const int VEHPARS_COLOR_SET
const int VEHPARS_FORCE_REROUTE
@ DEPART_GIVEN
The time is given.
@ DEPART_CONTAINER_TRIGGERED
The departure is container triggered.
@ DEPART_TRIGGERED
The departure is person triggered.
@ DEPART_NOW
The vehicle is discarded if emission fails (not fully implemented yet)
@ LCA_UNKNOWN
The action has not been determined.
const double INVALID_DOUBLE
Definition: StdDefs.h:63
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:30
T MIN2(T a, T b)
Definition: StdDefs.h:74
T ISNAN(T a)
Definition: StdDefs.h:115
T MAX2(T a, T b)
Definition: StdDefs.h:80
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
#define LIBSUMO_SUBSCRIPTION_IMPLEMENTATION(CLASS, DOMAIN)
Definition: TraCIDefs.h:69
#define LIBSUMO_GET_PARAMETER_WITH_KEY_IMPLEMENTATION(CLASS)
Definition: TraCIDefs.h:115
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 his current cell.
Definition: MEVehicle.h:221
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:51
double getMaxSpeed() const
Returns the maximum speed.
MSVehicleDevice * getDevice(const std::type_info &type) const
Returns a device of the given type if it exists or 0.
void resetRoutePosition(int index, DepartLaneDefinition departLaneProcedure)
reset index of edge within route
virtual BaseInfluencer & getBaseInfluencer()=0
Returns the velocity/lane influencer.
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.
const std::list< MSStop > & getStops() const
const SUMOVehicleParameter & getParameter() const
Returns the vehicle's parameter (including departure definition)
double getFuelConsumption() const
Returns fuel consumption of the current state.
double getCO2Emissions() const
Returns CO2 emission of the current state.
virtual std::pair< const MSVehicle *const, double > getFollower(double dist=0) const
Returns the follower of the vehicle looking for a fixed distance.
double getChosenSpeedFactor() const
Returns the precomputed factor by which the driver wants to be faster than the speed limit.
double getElectricityConsumption() const
Returns electricity consumption of the current state.
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.
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.
bool hasValidRoute(std::string &msg, const MSRoute *route=0) const
Validates the current or given route.
int getPersonNumber() const
Returns the number of persons.
virtual std::pair< const MSVehicle *const, double > getLeader(double dist=0) const
Returns the leader of the vehicle looking for a fixed distance.
void setJunctionModelParameter(const std::string &key, const std::string &value)
set individual junction model paramete (not type related)
double getNOxEmissions() const
Returns NOx emission of the current state.
double getPMxEmissions() const
Returns PMx emission of the current state.
bool hasDeparted() const
Returns whether this vehicle has already departed.
MSStop & getNextStop()
double getCOEmissions() const
Returns CO emission of the current state.
virtual const MSEdge * getRerouteOrigin() const
Returns the starting point for reroutes (usually the current edge)
const MSRouteIterator & getCurrentRouteEdge() const
Returns an iterator pointing to the current edge in this vehicles route.
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...
const MSVehicleType & getVehicleType() const
Returns the vehicle's type definition.
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.
virtual bool replaceRoute(const MSRoute *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.
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.
double getHCEmissions() const
Returns HC emission of the current state.
virtual bool addTraciStop(SUMOVehicleParameter::Stop stop, std::string &errorMsg)
int getRoutePosition() const
return index of edge within route
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.
const std::vector< SUMOVehicleParameter::Stop > & getPastStops() const
const MSRoute & getRoute() const
Returns the current route.
int getRNGIndex() const
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.
virtual double getSecureGap(const MSVehicle *const, 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.h:351
double stopSpeed(const MSVehicle *const veh, const double speed, double gap) const
Computes the vehicle's safe speed for approaching a non-moving obstacle (no dawdling)
Definition: MSCFModel.h:146
double getEmergencyDecel() const
Get the vehicle type's maximal phisically possible deceleration [m/s^2].
Definition: MSCFModel.h:247
virtual double followSpeed(const MSVehicle *const veh, double speed, double gap2pred, double predSpeed, double predMaxDecel, const MSVehicle *const pred=0) const =0
Computes the vehicle's follow speed (no dawdling)
double getApparentDecel() const
Get the vehicle type's apparent deceleration [m/s^2] (the one regarded by its followers.
Definition: MSCFModel.h:255
double getMaxAccel() const
Get the vehicle type's maximum acceleration [m/s^2].
Definition: MSCFModel.h:231
virtual double getImperfection() const
Get the driver's imperfection.
Definition: MSCFModel.h:272
double getMaxDecel() const
Get the vehicle type's maximal comfortable deceleration [m/s^2].
Definition: MSCFModel.h:239
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:613
virtual double getHeadwayTime() const
Get the driver's desired headway [s].
Definition: MSCFModel.h:280
A device which collects info on the vehicle trip (mainly on departure and arrival)
Definition: MSDevice_Taxi.h:48
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:918
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:942
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:408
bool isInternal() const
return whether this edge is an internal edge
Definition: MSEdge.h:262
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:885
double getVehicleMaxSpeed(const SUMOTrafficObject *const veh) const
Returns the maximum speed the vehicle may use on this edge.
Definition: MSEdge.cpp:1002
const MSEdge * getNormalBefore() const
if this edge is an internal edge, return its first normal predecessor, otherwise the edge itself
Definition: MSEdge.cpp:794
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:82
static double gLateralResolution
Definition: MSGlobals.h:88
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.
Representation of a lane in the micro simulation.
Definition: MSLane.h:82
const std::vector< MSLink * > & getLinkCont() const
returns the container with all links !!!
Definition: MSLane.h:641
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:2300
virtual MSVehicle * removeVehicle(MSVehicle *remVehicle, MSMoveReminder::Notification notification, bool notify=true)
Definition: MSLane.cpp:2282
static std::vector< MSLink * >::const_iterator succLinkSec(const SUMOVehicle &veh, int nRouteSuccs, const MSLane &succLinkSource, const std::vector< MSLane * > &conts)
Definition: MSLane.cpp:2165
void forceVehicleInsertion(MSVehicle *veh, double pos, MSMoveReminder::Notification notification, double posLat=0)
Inserts the given vehicle at the given position.
Definition: MSLane.cpp:1102
const MSEdge * getNextNormal() const
Returns the lane's follower if it is an internal lane, the edge of the lane otherwise.
Definition: MSLane.cpp:1967
void addLeaders(const MSVehicle *vehicle, double vehPos, MSLeaderDistanceInfo &result, bool oppositeDirection=false)
get leaders for ego on the given lane
Definition: MSLane.cpp:3571
double getLength() const
Returns the lane's length.
Definition: MSLane.h:541
bool isLinkEnd(std::vector< MSLink * >::const_iterator &i) const
Definition: MSLane.h:763
double getOppositePos(double pos) const
return the corresponding position on the opposite lane
Definition: MSLane.cpp:3817
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition: MSLane.cpp:1991
MSLeaderDistanceInfo getFollowersOnConsecutive(const MSVehicle *ego, double backOffset, bool allSublanes, double searchDist=-1, bool ignoreMinorLinks=false) const
return the sublane followers with the largest missing rear gap among all predecessor lanes (within di...
Definition: MSLane.cpp:3275
bool isInternal() const
Definition: MSLane.cpp:2122
MSEdge & getEdge() const
Returns the lane's edge.
Definition: MSLane.h:674
const PositionVector & getShape() const
Returns this lane's shape.
Definition: MSLane.h:478
double getWidth() const
Returns the lane's width.
Definition: MSLane.h:556
const Position geometryPositionAtOffset(double offset, double lateralOffset=0) const
Definition: MSLane.h:505
saves leader/follower vehicles and their distances relative to an ego vehicle
Definition: MSLeaderInfo.h:133
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:85
bool hasVehicles() const
Definition: MSLeaderInfo.h:93
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:174
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:376
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:318
MSInsertionControl & getInsertionControl()
Returns the insertion control.
Definition: MSNet.h:429
MSRouteIterator end() const
Returns the end of the list of edges to pass.
Definition: MSRoute.cpp:75
static bool dictionary(const std::string &id, const MSRoute *route)
Adds a route to the dictionary.
Definition: MSRoute.cpp:113
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:291
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition: MSRoute.cpp:69
const ConstMSEdgeVector & getEdges() const
Definition: MSRoute.h:120
Definition: MSStop.h:44
MSStoppingPlace * containerstop
(Optional) container stop if one is assigned to the stop
Definition: MSStop.h:56
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
MSParkingArea * parkingarea
(Optional) parkingArea if one is assigned to the stop
Definition: MSStop.h:58
MSStoppingPlace * chargingStation
(Optional) charging station if one is assigned to the stop
Definition: MSStop.h:60
SUMOTime duration
The stopping duration.
Definition: MSStop.h:67
const SUMOVehicleParameter::Stop pars
The stop parameter.
Definition: MSStop.h:65
MSStoppingPlace * busstop
(Optional) bus stop if one is assigned to the stop
Definition: MSStop.h:54
void setLaneChangeMode(int value)
Sets lane changing behavior.
Definition: MSVehicle.cpp:778
void deactivateGapController()
Deactivates the gap control.
Definition: MSVehicle.cpp:406
void setSpeedMode(int speedMode)
Sets speed-constraining behaviors.
Definition: MSVehicle.cpp:767
void setLaneTimeLine(const std::vector< std::pair< SUMOTime, int > > &laneTimeLine)
Sets a new lane timeline.
Definition: MSVehicle.cpp:413
void setSublaneChange(double latDist)
Sets a new sublane-change request.
Definition: MSVehicle.cpp:427
void setSignals(int signals)
Definition: MSVehicle.h:1534
void setSpeedTimeLine(const std::vector< std::pair< SUMOTime, double > > &speedTimeLine)
Sets a new velocity timeline.
Definition: MSVehicle.cpp:392
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:398
The class responsible for building and deletion of vehicles.
std::map< std::string, SUMOVehicle * >::const_iterator constVehIt
Definition of the internal vehicles map iterator.
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.
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.
virtual SUMOVehicle * buildVehicle(SUMOVehicleParameter *defs, const MSRoute *route, MSVehicleType *type, const bool ignoreStopErrors, const bool fromRouteFile=true)
Builds a vehicle, increases the number of built vehicles.
constVehIt loadedVehEnd() const
Returns the end of the internal vehicle map.
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:75
void updateBestLanes(bool forceRebuild=false, const MSLane *startLane=0)
computes the best lanes to use in order to continue the route
Definition: MSVehicle.cpp:5069
bool isOnRoad() const
Returns the information whether the vehicle is on a road (is simulated)
Definition: MSVehicle.h:574
SUMOTime getLastActionTime() const
Returns the time of the vehicle's last action point.
Definition: MSVehicle.h:512
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:5878
void setPreviousSpeed(double prevspeed)
Sets the influenced previous speed.
Definition: MSVehicle.cpp:6756
MSAbstractLaneChangeModel & getLaneChangeModel()
Definition: MSVehicle.cpp:5051
MSLane * getMutableLane() const
Returns the lane the vehicle is on Non const version indicates that something volatile is going on.
Definition: MSVehicle.h:560
Position getPosition(const double offset=0) const
Return current position (x/y, cartesian)
Definition: MSVehicle.cpp:1142
const std::vector< MSLane * > & getBestLanesContinuation() const
Returns the best sequence of lanes to continue the route starting at myLane.
Definition: MSVehicle.cpp:5497
void onRemovalFromNet(const MSMoveReminder::Notification reason)
Called when the vehicle is removed from the network.
Definition: MSVehicle.cpp:978
bool resumeFromStopping()
Definition: MSVehicle.cpp:6329
double getBackPositionOnLane(const MSLane *lane) const
Get the vehicle's position relative to the given lane.
Definition: MSVehicle.h:396
void resetActionOffset(const SUMOTime timeUntilNextAction=0)
Resets the action offset for the vehicle.
Definition: MSVehicle.cpp:1916
bool rerouteParkingArea(const std::string &parkingAreaID, std::string &errorMsg)
Definition: MSVehicle.cpp:6215
void switchOffSignal(int signal)
Switches the given signal off.
Definition: MSVehicle.h:1129
@ VEH_SIGNAL_NONE
Everything is switched off.
Definition: MSVehicle.h:1066
BaseInfluencer & getBaseInfluencer()
Returns the velocity/lane influencer.
Definition: MSVehicle.cpp:6397
Influencer & getInfluencer()
Definition: MSVehicle.cpp:6389
void setActionStepLength(double actionStepLength, bool resetActionOffset=true)
Sets the action steplength of the vehicle.
Definition: MSVehicle.cpp:1307
double getLateralPositionOnLane() const
Get the vehicle's lateral position on the lane.
Definition: MSVehicle.h:411
double getSpeed() const
Returns the vehicle's current speed.
Definition: MSVehicle.h:462
const std::vector< LaneQ > & getBestLanes() const
Returns the description of best lanes to use in order to continue the route.
Definition: MSVehicle.cpp:5063
double getPositionOnLane() const
Get the vehicle's position along the lane.
Definition: MSVehicle.h:372
const MSLane * getLane() const
Returns the lane the vehicle is on.
Definition: MSVehicle.h:552
const MSCFModel & getCarFollowModel() const
Returns the vehicle's car following model definition.
Definition: MSVehicle.h:917
bool hasInfluencer() const
whether the vehicle is individually influenced (via TraCI or special parameters)
Definition: MSVehicle.h:1633
void switchOnSignal(int signal)
Switches the given signal on.
Definition: MSVehicle.h:1121
int getLaneIndex() const
Definition: MSVehicle.cpp:5872
The car-following model and parameter.
Definition: MSVehicleType.h:62
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 maximum speed [m/s].
int getPersonCapacity() const
Get this vehicle type's person capacity.
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.
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.
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.
const Distribution_Parameterized & getSpeedFactor() const
Returns this type's speed factor.
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.
const std::string & getID() const
Returns the name of the vehicle type.
Definition: MSVehicleType.h:90
double getLength() const
Get vehicle's length [m].
const MSCFModel & getCarFollowModel() const
Returns the vehicle type's car following model definition (const version)
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:252
void sub(double dx, double dy)
Substracts 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:262
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 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 const MSLane * getLane() const =0
Returns the lane the object is currently at.
virtual double getPositionOnLane() const =0
Get the object's position along the lane.
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:60
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 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)
double startPos
The stopping position start.
bool triggered
whether an arriving person lets the vehicle continue
bool parking
whether the vehicle is removed from the net while stopping
bool containerTriggered
whether an arriving container lets the vehicle continue
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 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 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.
Definition: Vehicle.h:34
static MSEdge * getEdge(const std::string &edgeID)
Definition: Helper.cpp:394
static TraCIPosition makeTraCIPosition(const Position &position, const bool includeZ=false)
Definition: Helper.cpp:378
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:1659
static TraCIPositionVector makeTraCIPositionVector(const PositionVector &positionVector)
helper functions
Definition: Helper.cpp:338
static MSBaseVehicle * getVehicle(const std::string &id)
Definition: Helper.cpp:475
static TraCIColor makeTraCIColor(const RGBColor &color)
Definition: Helper.cpp:361
static TraCINextStopData buildStopData(const SUMOVehicleParameter::Stop &stopPar)
Definition: Helper.cpp:625
static void setRemoteControlled(MSVehicle *v, Position xyPos, MSLane *l, double pos, double posLat, double angle, int edgeOffset, ConstMSEdgeVector route, SUMOTime t)
Definition: Helper.cpp:1333
static const MSVehicleType & getVehicleType(const std::string &vehicleID)
Definition: Helper.cpp:510
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:1369
static std::pair< MSLane *, double > convertCartesianToRoadMap(const Position &pos, const SUMOVehicleClass vClass)
Definition: Helper.cpp:421
static SUMOVehicleParameter::Stop buildStopParameters(const std::string &edgeOrStoppingPlaceID, double pos, int laneIndex, double startPos, int flags, double duration, double until)
Definition: Helper.cpp:525
static Subscription * addSubscriptionFilter(SubscriptionFilterType filter)
Definition: Helper.cpp:240
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_ROUTING_MODE
TRACI_CONST int VAR_WAITING_TIME
TRACI_CONST int VAR_LINE
std::map< std::string, libsumo::SubscriptionResults > ContextSubscriptionResults
Definition: TraCIDefs.h:279
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 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 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:278
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 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
std::map< int, std::shared_ptr< libsumo::TraCIResult > > TraCIResults
{variable->value}
Definition: TraCIDefs.h:276
TRACI_CONST int VAR_DISTANCE
TRACI_CONST int VAR_ELECTRICITYCONSUMPTION
TRACI_CONST int VAR_VIA
A structure representing the best lanes for continuing the current route starting at 'lane'.
Definition: MSVehicle.h:811