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