Eclipse SUMO - Simulation of Urban MObility
libsumo/Person.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 // Copyright (C) 2017-2024 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
18 // C++ TraCI client API implementation
19 /****************************************************************************/
20 #include <config.h>
21 
24 #include <microsim/MSEdge.h>
25 #include <microsim/MSLane.h>
26 #include <microsim/MSNet.h>
35 #include <libsumo/TraCIConstants.h>
36 #include <utils/geom/GeomHelper.h>
38 #include <utils/common/SUMOTime.h>
42 #include "Helper.h"
43 #include "VehicleType.h"
44 #include "Person.h"
45 
46 #define FAR_AWAY 1000.0
47 
48 //#define DEBUG_MOVEXY
49 //#define DEBUG_MOVEXY_ANGLE
50 
51 namespace libsumo {
52 // ===========================================================================
53 // static member initializations
54 // ===========================================================================
55 SubscriptionResults Person::mySubscriptionResults;
56 ContextSubscriptionResults Person::myContextSubscriptionResults;
57 
58 
59 // ===========================================================================
60 // static member definitions
61 // ===========================================================================
62 std::vector<std::string>
63 Person::getIDList() {
65  std::vector<std::string> ids;
66  for (MSTransportableControl::constVehIt i = c.loadedBegin(); i != c.loadedEnd(); ++i) {
67  if (i->second->getCurrentStageType() != MSStageType::WAITING_FOR_DEPART) {
68  ids.push_back(i->first);
69  }
70  }
71  return ids;
72 }
73 
74 
75 int
76 Person::getIDCount() {
78 }
79 
80 
81 TraCIPosition
82 Person::getPosition(const std::string& personID, const bool includeZ) {
83  return Helper::makeTraCIPosition(getPerson(personID)->getPosition(), includeZ);
84 }
85 
86 
87 TraCIPosition
88 Person::getPosition3D(const std::string& personID) {
89  return Helper::makeTraCIPosition(getPerson(personID)->getPosition(), true);
90 }
91 
92 
93 double
94 Person::getAngle(const std::string& personID) {
95  return GeomHelper::naviDegree(getPerson(personID)->getAngle());
96 }
97 
98 
99 double
100 Person::getSlope(const std::string& personID) {
101  MSPerson* person = getPerson(personID);
102  const double ep = person->getEdgePos();
103  const MSLane* lane = getSidewalk<MSEdge, MSLane>(person->getEdge());
104  if (lane == nullptr) {
105  lane = person->getEdge()->getLanes()[0];
106  }
107  const double gp = lane->interpolateLanePosToGeometryPos(ep);
108  return lane->getShape().slopeDegreeAtOffset(gp);
109 }
110 
111 
112 double
113 Person::getSpeed(const std::string& personID) {
114  return getPerson(personID)->getSpeed();
115 }
116 
117 
118 std::string
119 Person::getRoadID(const std::string& personID) {
120  return getPerson(personID)->getEdge()->getID();
121 }
122 
123 
124 std::string
125 Person::getLaneID(const std::string& personID) {
126  return Named::getIDSecure(getPerson(personID)->getLane(), "");
127 }
128 
129 
130 double
131 Person::getLanePosition(const std::string& personID) {
132  return getPerson(personID)->getEdgePos();
133 }
134 
135 std::vector<TraCIReservation>
136 Person::getTaxiReservations(int onlyNew) {
137  std::vector<TraCIReservation> result;
139  if (dispatcher != nullptr) {
140  MSDispatch_TraCI* traciDispatcher = dynamic_cast<MSDispatch_TraCI*>(dispatcher);
141  if (traciDispatcher == nullptr) {
142  throw TraCIException("device.taxi.dispatch-algorithm 'traci' has not been loaded");
143  }
144  for (Reservation* res : dispatcher->getReservations()) {
145  if (filterReservation(onlyNew, res, result)) {
146  if (res->state == Reservation::NEW) {
147  res->state = Reservation::RETRIEVED;
148  }
149  }
150  }
151  const bool includeRunning = onlyNew == 0 || (onlyNew & (Reservation::ASSIGNED | Reservation::ONBOARD)) != 0;
152  if (includeRunning) {
153  for (const Reservation* res : dispatcher->getRunningReservations()) {
154  filterReservation(onlyNew, res, result);
155  }
156  }
157  }
158  std::sort(result.begin(), result.end(), reservation_by_id_sorter());
159  return result;
160 }
161 
162 int
163 Person::reservation_by_id_sorter::operator()(const TraCIReservation& r1, const TraCIReservation& r2) const {
164  return r1.id < r2.id;
165 }
166 
167 
168 std::string
169 Person::splitTaxiReservation(std::string reservationID, const std::vector<std::string>& personIDs) {
171  if (dispatcher != nullptr) {
172  MSDispatch_TraCI* traciDispatcher = dynamic_cast<MSDispatch_TraCI*>(dispatcher);
173  if (traciDispatcher != nullptr) {
174  return traciDispatcher->splitReservation(reservationID, personIDs);
175  }
176  }
177  throw TraCIException("device.taxi.dispatch-algorithm 'traci' has not been loaded");
178 }
179 
180 bool
181 Person::filterReservation(int onlyNew, const Reservation* res, std::vector<libsumo::TraCIReservation>& reservations) {
182  if (onlyNew != 0 && (onlyNew & res->state) == 0) {
183  return false;
184  }
185  std::vector<std::string> personIDs;
186  for (const MSTransportable* p : res->persons) {
187  personIDs.push_back(p->getID());
188  }
189  std::sort(personIDs.begin(), personIDs.end());
190  reservations.push_back(TraCIReservation(res->id,
191  personIDs,
192  res->group,
193  res->from->getID(),
194  res->to->getID(),
195  res->fromPos,
196  res->toPos,
197  STEPS2TIME(res->pickupTime),
199  res->state
200  ));
201  return true;
202 }
203 
204 
205 TraCIColor
206 Person::getColor(const std::string& personID) {
207  const RGBColor& col = getPerson(personID)->getParameter().color;
208  TraCIColor tcol;
209  tcol.r = col.red();
210  tcol.g = col.green();
211  tcol.b = col.blue();
212  tcol.a = col.alpha();
213  return tcol;
214 }
215 
216 
217 std::string
218 Person::getTypeID(const std::string& personID) {
219  return getPerson(personID)->getVehicleType().getID();
220 }
221 
222 
223 double
224 Person::getWaitingTime(const std::string& personID) {
225  return getPerson(personID)->getWaitingSeconds();
226 }
227 
228 
229 std::string
230 Person::getNextEdge(const std::string& personID) {
231  return getPerson(personID)->getNextEdge();
232 }
233 
234 
235 std::vector<std::string>
236 Person::getEdges(const std::string& personID, int nextStageIndex) {
237  MSTransportable* p = getPerson(personID);
238  if (nextStageIndex >= p->getNumRemainingStages()) {
239  throw TraCIException("The stage index must be lower than the number of remaining stages.");
240  }
241  if (nextStageIndex < (p->getNumRemainingStages() - p->getNumStages())) {
242  throw TraCIException("The negative stage index must refer to a valid previous stage.");
243  }
244  std::vector<std::string> edgeIDs;
245  for (auto& e : p->getNextStage(nextStageIndex)->getEdges()) {
246  if (e != nullptr) {
247  edgeIDs.push_back(e->getID());
248  }
249  }
250  return edgeIDs;
251 }
252 
253 
254 TraCIStage
255 Person::getStage(const std::string& personID, int nextStageIndex) {
256  MSTransportable* p = getPerson(personID);
257  TraCIStage result;
258  if (nextStageIndex >= p->getNumRemainingStages()) {
259  throw TraCIException("The stage index must be lower than the number of remaining stages.");
260  }
261  if (nextStageIndex < (p->getNumRemainingStages() - p->getNumStages())) {
262  throw TraCIException("The negative stage index " + toString(nextStageIndex) + " must refer to a valid previous stage.");
263  }
264  //stageType, arrivalPos, edges, destStop, vType, and description can be retrieved directly from the base Stage class.
265  MSStage* stage = p->getNextStage(nextStageIndex);
266  result.type = (int)stage->getStageType();
267  result.arrivalPos = stage->getArrivalPos();
268  for (auto e : stage->getEdges()) {
269  if (e != nullptr) {
270  result.edges.push_back(e->getID());
271  }
272  }
273  MSStoppingPlace* destinationStop = stage->getDestinationStop();
274  if (destinationStop != nullptr) {
275  result.destStop = destinationStop->getID();
276  }
277  result.description = stage->getStageDescription(p->isPerson());
278  result.length = stage->getDistance();
279  if (result.length == -1.) {
280  result.length = INVALID_DOUBLE_VALUE;
281  }
282  result.departPos = INVALID_DOUBLE_VALUE;
283  result.cost = INVALID_DOUBLE_VALUE;
284  result.depart = stage->getDeparted() >= 0 ? STEPS2TIME(stage->getDeparted()) : INVALID_DOUBLE_VALUE;
285  result.travelTime = INVALID_DOUBLE_VALUE;
286  if (stage->getArrived() >= 0) {
287  result.travelTime = STEPS2TIME(stage->getArrived() - stage->getDeparted());
288  } else if (stage->getDeparted() >= 0) {
289  result.travelTime = STEPS2TIME(SIMSTEP - stage->getDeparted());
290  }
291 
292  // Some stage type dependant attributes
293  switch (stage->getStageType()) {
294  case MSStageType::DRIVING: {
295  MSStageDriving* const drivingStage = static_cast<MSStageDriving*>(stage);
296  result.vType = drivingStage->getVehicleType();
297  result.intended = drivingStage->getIntendedVehicleID();
298  if (result.depart < 0 && drivingStage->getIntendedDepart() >= 0) {
299  result.depart = STEPS2TIME(drivingStage->getIntendedDepart());
300  }
301  const std::set<std::string> lines = drivingStage->getLines();
302  for (auto line = lines.begin(); line != lines.end(); line++) {
303  if (line != lines.begin()) {
304  result.line += " ";
305  }
306  result.line += *line;
307  }
308  break;
309  }
310  case MSStageType::WALKING: {
311  auto* walkingStage = (MSStageWalking*) stage;
312  result.departPos = walkingStage->getDepartPos();
313  break;
314  }
315  case MSStageType::WAITING: {
316  auto* waitingStage = (MSStageWaiting*) stage;
317  if (waitingStage->getDuration() > 0) {
318  result.travelTime = STEPS2TIME(waitingStage->getDuration());
319  }
320  break;
321  }
322  default:
323  break;
324  }
325  return result;
326 }
327 
328 
329 int
330 Person::getRemainingStages(const std::string& personID) {
331  return getPerson(personID)->getNumRemainingStages();
332 }
333 
334 
335 std::string
336 Person::getVehicle(const std::string& personID) {
337  const SUMOVehicle* veh = getPerson(personID)->getVehicle();
338  if (veh == nullptr) {
339  return "";
340  } else {
341  return veh->getID();
342  }
343 }
344 
345 
346 std::string
347 Person::getParameter(const std::string& personID, const std::string& param) {
348  return getPerson(personID)->getParameter().getParameter(param, "");
349 }
350 
351 
353 
354 
355 std::string
356 Person::getEmissionClass(const std::string& personID) {
357  return PollutantsInterface::getName(getPerson(personID)->getVehicleType().getEmissionClass());
358 }
359 
360 
361 std::string
362 Person::getShapeClass(const std::string& personID) {
363  return getVehicleShapeName(getPerson(personID)->getVehicleType().getGuiShape());
364 }
365 
366 
367 double
368 Person::getLength(const std::string& personID) {
369  return getPerson(personID)->getVehicleType().getLength();
370 }
371 
372 
373 double
374 Person::getSpeedFactor(const std::string& personID) {
375  return getPerson(personID)->getChosenSpeedFactor();
376 }
377 
378 
379 double
380 Person::getAccel(const std::string& personID) {
381  return getPerson(personID)->getVehicleType().getCarFollowModel().getMaxAccel();
382 }
383 
384 
385 double
386 Person::getDecel(const std::string& personID) {
387  return getPerson(personID)->getVehicleType().getCarFollowModel().getMaxDecel();
388 }
389 
390 
391 double Person::getEmergencyDecel(const std::string& personID) {
392  return getPerson(personID)->getVehicleType().getCarFollowModel().getEmergencyDecel();
393 }
394 
395 
396 double Person::getApparentDecel(const std::string& personID) {
397  return getPerson(personID)->getVehicleType().getCarFollowModel().getApparentDecel();
398 }
399 
400 
401 double Person::getActionStepLength(const std::string& personID) {
402  return getPerson(personID)->getVehicleType().getActionStepLengthSecs();
403 }
404 
405 
406 double
407 Person::getTau(const std::string& personID) {
408  return getPerson(personID)->getVehicleType().getCarFollowModel().getHeadwayTime();
409 }
410 
411 
412 double
413 Person::getImperfection(const std::string& personID) {
414  return getPerson(personID)->getVehicleType().getCarFollowModel().getImperfection();
415 }
416 
417 
418 double
419 Person::getSpeedDeviation(const std::string& personID) {
420  return getPerson(personID)->getVehicleType().getSpeedFactor().getParameter()[1];
421 }
422 
423 
424 std::string
425 Person::getVehicleClass(const std::string& personID) {
426  return toString(getPerson(personID)->getVehicleType().getVehicleClass());
427 }
428 
429 
430 double
431 Person::getMinGap(const std::string& personID) {
432  return getPerson(personID)->getVehicleType().getMinGap();
433 }
434 
435 
436 double
437 Person::getMinGapLat(const std::string& personID) {
438  return getPerson(personID)->getVehicleType().getMinGapLat();
439 }
440 
441 
442 double
443 Person::getMaxSpeed(const std::string& personID) {
444  return getPerson(personID)->getMaxSpeed();
445 }
446 
447 
448 double
449 Person::getMaxSpeedLat(const std::string& personID) {
450  return getPerson(personID)->getVehicleType().getMaxSpeedLat();
451 }
452 
453 
454 std::string
455 Person::getLateralAlignment(const std::string& personID) {
456  return toString(getPerson(personID)->getVehicleType().getPreferredLateralAlignment());
457 }
458 
459 
460 double
461 Person::getWidth(const std::string& personID) {
462  return getPerson(personID)->getVehicleType().getWidth();
463 }
464 
465 
466 double
467 Person::getHeight(const std::string& personID) {
468  return getPerson(personID)->getVehicleType().getHeight();
469 }
470 
471 
472 int
473 Person::getPersonCapacity(const std::string& personID) {
474  return getPerson(personID)->getVehicleType().getPersonCapacity();
475 }
476 
477 
478 double
479 Person::getBoardingDuration(const std::string& personID) {
480  return STEPS2TIME(getPerson(personID)->getVehicleType().getBoardingDuration(true));
481 }
482 
483 
484 double
485 Person::getImpatience(const std::string& personID) {
486  return getPerson(personID)->getImpatience();
487 }
488 
489 
490 void
491 Person::setSpeed(const std::string& personID, double speed) {
492  getPerson(personID)->setSpeed(speed);
493 }
494 
495 
496 void
497 Person::setType(const std::string& personID, const std::string& typeID) {
498  MSVehicleType* vehicleType = MSNet::getInstance()->getVehicleControl().getVType(typeID);
499  if (vehicleType == nullptr) {
500  throw TraCIException("The vehicle type '" + typeID + "' is not known.");
501  }
502  getPerson(personID)->replaceVehicleType(vehicleType);
503 }
504 
505 
506 void
507 Person::add(const std::string& personID, const std::string& edgeID, double pos, double departInSecs, const std::string typeID) {
508  MSTransportable* p;
509  try {
510  p = getPerson(personID);
511  } catch (TraCIException&) {
512  p = nullptr;
513  }
514 
515  if (p != nullptr) {
516  throw TraCIException("The person " + personID + " to add already exists.");
517  }
518 
519  SUMOTime depart = TIME2STEPS(departInSecs);
520  SUMOVehicleParameter vehicleParams;
521  vehicleParams.id = personID;
522 
523  MSVehicleType* vehicleType = MSNet::getInstance()->getVehicleControl().getVType(typeID);
524  if (!vehicleType) {
525  throw TraCIException("Invalid type '" + typeID + "' for person '" + personID + "'");
526  }
527 
528  const MSEdge* edge = MSEdge::dictionary(edgeID);
529  if (!edge) {
530  throw TraCIException("Invalid edge '" + edgeID + "' for person: '" + personID + "'");
531  }
532 
533  if (departInSecs < 0.) {
534  const int proc = (int) - departInSecs;
535  if (proc >= static_cast<int>(DepartDefinition::DEF_MAX)) {
536  throw TraCIException("Invalid departure time." + toString(depart) + " " + toString(proc));
537  }
538  vehicleParams.departProcedure = (DepartDefinition)proc;
539  vehicleParams.depart = MSNet::getInstance()->getCurrentTimeStep();
540  } else if (depart < MSNet::getInstance()->getCurrentTimeStep()) {
541  vehicleParams.depart = MSNet::getInstance()->getCurrentTimeStep();
542  WRITE_WARNINGF(TL("Departure time=% for person '%' is in the past; using current time=% instead."),
543  toString(departInSecs), personID, time2string(vehicleParams.depart));
544  } else {
545  vehicleParams.depart = depart;
546  }
547 
549  if (fabs(pos) > edge->getLength()) {
550  throw TraCIException("Invalid departure position.");
551  }
552  if (pos < 0) {
553  pos += edge->getLength();
554  }
555  vehicleParams.departPos = pos;
556 
557  SUMOVehicleParameter* params = new SUMOVehicleParameter(vehicleParams);
559  plan->push_back(new MSStageWaiting(edge, nullptr, 0, depart, pos, "awaiting departure", true));
560 
561  try {
562  MSTransportable* person = MSNet::getInstance()->getPersonControl().buildPerson(params, vehicleType, plan, nullptr);
564  } catch (ProcessError& e) {
565  delete params;
566  delete plan;
567  throw TraCIException(e.what());
568  }
569 }
570 
571 MSStage*
572 Person::convertTraCIStage(const TraCIStage& stage, const std::string personID) {
573  MSStoppingPlace* bs = nullptr;
574  if (!stage.destStop.empty()) {
575  bs = MSNet::getInstance()->getStoppingPlace(stage.destStop, SUMO_TAG_BUS_STOP);
576  if (bs == nullptr) {
578  if (bs == nullptr) {
579  throw TraCIException("Invalid stopping place id '" + stage.destStop + "' for person: '" + personID + "'");
580  } else {
581  // parkingArea is not a proper arrival place
582  bs = nullptr;
583  }
584  }
585  }
586  switch (stage.type) {
587  case STAGE_DRIVING: {
588  if (stage.edges.empty()) {
589  throw TraCIException("The stage should have at least one edge");
590  }
591  std::string toId = stage.edges.back();
592  MSEdge* to = MSEdge::dictionary(toId);
593  if (!to) {
594  throw TraCIException("Invalid edge '" + toId + "' for person: '" + personID + "'");
595  }
596  //std::string fromId = stage.edges.front();
597  //MSEdge* from = MSEdge::dictionary(fromId);
598  //if (!from) {
599  // throw TraCIException("Invalid edge '" + fromId + "' for person: '" + personID + "'");
600  //}
601  if (stage.line.empty()) {
602  throw TraCIException("Empty lines parameter for person: '" + personID + "'");
603  }
604  double arrivalPos = stage.arrivalPos;
605  if (arrivalPos == INVALID_DOUBLE_VALUE) {
606  if (bs != nullptr) {
607  arrivalPos = bs->getEndLanePosition();
608  } else {
609  arrivalPos = to->getLength();
610  }
611  }
612  return new MSStageDriving(nullptr, to, bs, arrivalPos, 0.0, StringTokenizer(stage.line).getVector());
613  }
614 
615  case STAGE_WALKING: {
616  MSTransportable* p = getPerson(personID);
617  ConstMSEdgeVector edges;
618  try {
619  MSEdge::parseEdgesList(stage.edges, edges, "<unknown>");
620  } catch (ProcessError& e) {
621  throw TraCIException(e.what());
622  }
623  if (edges.empty()) {
624  throw TraCIException("Empty edge list for walking stage of person '" + personID + "'.");
625  }
626  double arrivalPos = stage.arrivalPos;
627  if (fabs(arrivalPos) > edges.back()->getLength()) {
628  throw TraCIException("Invalid arrivalPos for walking stage of person '" + personID + "'.");
629  }
630  if (arrivalPos < 0) {
631  arrivalPos += edges.back()->getLength();
632  }
633  double speed = p->getMaxSpeed();
634  return new MSStageWalking(p->getID(), edges, bs, -1, speed, p->getArrivalPos(), arrivalPos, MSPModel::UNSPECIFIED_POS_LAT);
635  }
636 
637  case STAGE_WAITING: {
638  MSTransportable* p = getPerson(personID);
639  if (stage.travelTime < 0) {
640  throw TraCIException("Duration for person: '" + personID + "' must not be negative");
641  }
642  return new MSStageWaiting(p->getArrivalEdge(), nullptr, TIME2STEPS(stage.travelTime), 0, p->getArrivalPos(), stage.description, false);
643  }
644  default:
645  return nullptr;
646  }
647 }
648 
649 
650 void
651 Person::appendStage(const std::string& personID, const TraCIStage& stage) {
652  MSTransportable* p = getPerson(personID);
653  MSStage* personStage = convertTraCIStage(stage, personID);
654  p->appendStage(personStage);
655 }
656 
657 
658 void
659 Person::replaceStage(const std::string& personID, const int stageIndex, const TraCIStage& stage) {
660  MSTransportable* p = getPerson(personID);
661  if (stageIndex >= p->getNumRemainingStages()) {
662  throw TraCIException("Specified stage index: is not valid for person " + personID);
663  }
664  MSStage* personStage = convertTraCIStage(stage, personID);
665  // removing the current stage triggers abort+proceed so the replacement
666  // stage must be ready beforehand
667  p->appendStage(personStage, stageIndex + 1);
668  p->removeStage(stageIndex);
669 }
670 
671 
672 void
673 Person::appendDrivingStage(const std::string& personID, const std::string& toEdge, const std::string& lines, const std::string& stopID) {
674  MSTransportable* p = getPerson(personID);
675  const MSEdge* edge = MSEdge::dictionary(toEdge);
676  if (!edge) {
677  throw TraCIException("Invalid edge '" + toEdge + "' for person: '" + personID + "'");
678  }
679  if (lines.size() == 0) {
680  throw TraCIException("Empty lines parameter for person: '" + personID + "'");
681  }
682  MSStoppingPlace* bs = nullptr;
683  if (stopID != "") {
685  if (bs == nullptr) {
686  throw TraCIException("Invalid stopping place id '" + stopID + "' for person: '" + personID + "'");
687  }
688  }
689  p->appendStage(new MSStageDriving(nullptr, edge, bs, edge->getLength() - NUMERICAL_EPS, 0.0, StringTokenizer(lines).getVector()));
690 }
691 
692 
693 void
694 Person::appendWaitingStage(const std::string& personID, double duration, const std::string& description, const std::string& stopID) {
695  MSTransportable* p = getPerson(personID);
696  if (duration < 0) {
697  throw TraCIException("Duration for person: '" + personID + "' must not be negative");
698  }
699  MSStoppingPlace* bs = nullptr;
700  if (stopID != "") {
702  if (bs == nullptr) {
703  throw TraCIException("Invalid stopping place id '" + stopID + "' for person: '" + personID + "'");
704  }
705  }
706  p->appendStage(new MSStageWaiting(p->getArrivalEdge(), nullptr, TIME2STEPS(duration), 0, p->getArrivalPos(), description, false));
707 }
708 
709 
710 void
711 Person::appendWalkingStage(const std::string& personID, const std::vector<std::string>& edgeIDs, double arrivalPos, double duration, double speed, const std::string& stopID) {
712  MSTransportable* p = getPerson(personID);
713  ConstMSEdgeVector edges;
714  try {
715  MSEdge::parseEdgesList(edgeIDs, edges, "<unknown>");
716  } catch (ProcessError& e) {
717  throw TraCIException(e.what());
718  }
719  if (edges.empty()) {
720  throw TraCIException("Empty edge list for walking stage of person '" + personID + "'.");
721  }
722  if (fabs(arrivalPos) > edges.back()->getLength()) {
723  throw TraCIException("Invalid arrivalPos for walking stage of person '" + personID + "'.");
724  }
725  if (arrivalPos < 0) {
726  arrivalPos += edges.back()->getLength();
727  }
728  if (speed < 0) {
729  speed = p->getMaxSpeed();
730  }
731  MSStoppingPlace* bs = nullptr;
732  if (stopID != "") {
734  if (bs == nullptr) {
735  throw TraCIException("Invalid stopping place id '" + stopID + "' for person: '" + personID + "'");
736  }
737  }
738  p->appendStage(new MSStageWalking(p->getID(), edges, bs, TIME2STEPS(duration), speed, p->getArrivalPos(), arrivalPos, MSPModel::UNSPECIFIED_POS_LAT));
739 }
740 
741 
742 void
743 Person::removeStage(const std::string& personID, int nextStageIndex) {
744  MSTransportable* p = getPerson(personID);
745  if (nextStageIndex >= p->getNumRemainingStages()) {
746  throw TraCIException("The stage index must be lower than the number of remaining stages.");
747  }
748  if (nextStageIndex < 0) {
749  throw TraCIException("The stage index may not be negative.");
750  }
751  p->removeStage(nextStageIndex);
752 }
753 
754 
755 void
756 Person::rerouteTraveltime(const std::string& personID) {
757  MSPerson* p = getPerson(personID);
758  if (p->getNumRemainingStages() == 0) {
759  throw TraCIException("Person '" + personID + "' has no remaining stages.");
760  }
761  const MSEdge* from = p->getEdge();
762  double departPos = p->getEdgePos();
763  // reroute to the start of the next-non-walking stage
764  int firstIndex;
766  firstIndex = 0;
767  } else if (p->getCurrentStageType() == MSStageType::WAITING) {
768  if (p->getNumRemainingStages() < 2 || p->getStageType(1) != MSStageType::WALKING) {
769  throw TraCIException("Person '" + personID + "' cannot reroute after the current stop.");
770  }
771  firstIndex = 1;
772  } else {
773  throw TraCIException("Person '" + personID + "' cannot reroute in stage type '" + toString((int)p->getCurrentStageType()) + "'.");
774  }
775  int nextIndex = firstIndex + 1;
776  for (; nextIndex < p->getNumRemainingStages(); nextIndex++) {
777  if (p->getStageType(nextIndex) != MSStageType::WALKING) {
778  break;
779  }
780  }
781  MSStage* destStage = p->getNextStage(nextIndex - 1);
782  const MSEdge* to = destStage->getEdges().back();
783  double arrivalPos = destStage->getArrivalPos();
784  double speed = p->getMaxSpeed();
785  ConstMSEdgeVector newEdges;
786  MSNet::getInstance()->getPedestrianRouter(0).compute(from, to, departPos, arrivalPos, speed, 0, nullptr, newEdges);
787  if (newEdges.empty()) {
788  throw TraCIException("Could not find new route for person '" + personID + "'.");
789  }
790  ConstMSEdgeVector oldEdges = p->getNextStage(firstIndex)->getEdges();
791  assert(!oldEdges.empty());
792  if (oldEdges.front()->getFunction() != SumoXMLEdgeFunc::NORMAL) {
793  oldEdges.erase(oldEdges.begin());
794  }
795  //std::cout << " remainingStages=" << p->getNumRemainingStages() << " oldEdges=" << toString(oldEdges) << " newEdges=" << toString(newEdges) << " firstIndex=" << firstIndex << " nextIndex=" << nextIndex << "\n";
796  if (newEdges == oldEdges && (firstIndex + 1 == nextIndex)) {
797  return;
798  }
799  if (newEdges.front() != from) {
800  // @note: maybe this should be done automatically by the router
801  newEdges.insert(newEdges.begin(), from);
802  }
803  p->reroute(newEdges, departPos, firstIndex, nextIndex);
804 }
805 
806 
807 void
808 Person::moveTo(const std::string& personID, const std::string& laneID, double pos, double posLat) {
809  MSPerson* p = getPerson(personID);
810  MSLane* l = MSLane::dictionary(laneID);
811  if (l == nullptr) {
812  throw TraCIException("Unknown lane '" + laneID + "'.");
813  }
814  if (posLat == INVALID_DOUBLE_VALUE) {
815  posLat = 0;
816  } else if (fabs(posLat) >= (0.5 * (l->getWidth() + p->getVehicleType().getWidth()) + MSPModel::SIDEWALK_OFFSET)) {
817  // see MSPModel_Striping::moveToXY
818  throw TraCIException("Invalid lateral position " + toString(posLat) + " on lane '" + laneID + "'.");
819  }
820  switch (p->getStageType(0)) {
821  case MSStageType::WALKING: {
822  MSStageWalking* s = dynamic_cast<MSStageWalking*>(p->getCurrentStage());
823  assert(s != 0);
824  s->getPState()->moveTo(p, l, pos, posLat, SIMSTEP);
825  break;
826  }
827  default:
828  throw TraCIException("Command moveTo is not supported for person '" + personID + "' while " + p->getCurrentStageDescription() + ".");
829  }
830 }
831 
832 
833 void
834 Person::moveToXY(const std::string& personID, const std::string& edgeID, const double x, const double y, double angle, const int keepRoute, double matchThreshold) {
835  MSPerson* p = getPerson(personID);
836  const bool doKeepRoute = (keepRoute & 1) != 0;
837  const bool mayLeaveNetwork = (keepRoute & 2) != 0;
838  const bool ignorePermissions = (keepRoute & 4) != 0;
839  SUMOVehicleClass vClass = ignorePermissions ? SVC_IGNORING : p->getVClass();
840  Position pos(x, y);
841 #ifdef DEBUG_MOVEXY
842  const double origAngle = angle;
843 #endif
844  // angle must be in [0,360] because it will be compared against those returned by naviDegree()
845  // angle set to INVALID_DOUBLE_VALUE is ignored in the evaluated and later set to the angle of the matched lane
846  if (angle != INVALID_DOUBLE_VALUE) {
847  while (angle >= 360.) {
848  angle -= 360.;
849  }
850  while (angle < 0.) {
851  angle += 360.;
852  }
853  }
854  Position currentPos = p->getPosition();
855 #ifdef DEBUG_MOVEXY
856  std::cout << std::endl << "begin person " << p->getID() << " lanePos:" << p->getEdgePos() << " edge:" << Named::getIDSecure(p->getEdge()) << "\n";
857  std::cout << " want pos:" << pos << " edgeID:" << edgeID << " origAngle:" << origAngle << " angle:" << angle << " keepRoute:" << keepRoute << std::endl;
858 #endif
859 
860  ConstMSEdgeVector edges;
861  MSLane* lane = nullptr;
862  double lanePos;
863  double lanePosLat = 0;
864  double bestDistance = std::numeric_limits<double>::max();
865  int routeOffset = 0;
866  bool found = false;
867  double maxRouteDistance = matchThreshold;
868 
870  ev.push_back(p->getEdge());
871  int routeIndex = 0;
872  MSLane* currentLane = const_cast<MSLane*>(getSidewalk<MSEdge, MSLane>(p->getEdge()));
873  switch (p->getStageType(0)) {
874  case MSStageType::WALKING: {
875  MSStageWalking* s = dynamic_cast<MSStageWalking*>(p->getCurrentStage());
876  assert(s != 0);
877  ev = s->getEdges();
878  routeIndex = (int)(s->getRouteStep() - s->getRoute().begin());
879  }
880  break;
881  default:
882  break;
883  }
884  if (doKeepRoute) {
885  // case a): vehicle is on its earlier route
886  // we additionally assume it is moving forward (SUMO-limit);
887  // note that the route ("edges") is not changed in this case
888  found = Helper::moveToXYMap_matchingRoutePosition(pos, edgeID,
889  ev, routeIndex, vClass, true,
890  bestDistance, &lane, lanePos, routeOffset);
891  } else {
892  double speed = pos.distanceTo2D(p->getPosition()); // !!!veh->getSpeed();
893  found = Helper::moveToXYMap(pos, maxRouteDistance, mayLeaveNetwork, edgeID, angle,
894  speed, ev, routeIndex, currentLane, p->getEdgePos(), currentLane != nullptr,
895  vClass, true,
896  bestDistance, &lane, lanePos, routeOffset, edges);
897  if (edges.size() != 0 && ev.size() > 1) {
898  // try to rebuild the route
899  const MSEdge* origEdge = p->getEdge();
900  assert(lane != nullptr);
901  const MSJunction* originalTarget = nullptr;
902  if (origEdge->isNormal()) {
903  if (routeIndex == 0) {
904  if (origEdge->getToJunction() == ev[1]->getToJunction() || origEdge->getToJunction() == ev[1]->getFromJunction()) {
905  originalTarget = origEdge->getToJunction();
906  } else {
907  originalTarget = origEdge->getFromJunction();
908  }
909  } else {
910  if (origEdge->getToJunction() == ev[routeIndex - 1]->getToJunction() || origEdge->getToJunction() == ev[routeIndex - 1]->getFromJunction()) {
911  originalTarget = origEdge->getFromJunction();
912  } else {
913  originalTarget = origEdge->getToJunction();
914  }
915  }
916  } else {
917  originalTarget = origEdge->getToJunction();
918  assert(originalTarget == origEdge->getFromJunction());
919  }
920  const MSEdge* newEdge = edges[0];
921  if (edges[0]->getFromJunction() == originalTarget || edges[0]->getToJunction() == originalTarget) {
922  edges = ev;
923  edges[routeIndex] = newEdge;
924  }
925  }
926  }
927  if ((found && bestDistance <= maxRouteDistance) || mayLeaveNetwork) {
928  // compute lateral offset
929  if (found) {
930  const double perpDist = lane->getShape().distance2D(pos, false);
931  if (perpDist != GeomHelper::INVALID_OFFSET) {
932  lanePosLat = perpDist;
933  if (!mayLeaveNetwork) {
934  lanePosLat = MIN2(lanePosLat, 0.5 * (lane->getWidth() + p->getVehicleType().getWidth()));
935  }
936  // figure out whether the offset is to the left or to the right
937  PositionVector tmp = lane->getShape();
938  try {
939  tmp.move2side(-lanePosLat); // moved to left
940  } catch (ProcessError&) {
941  WRITE_WARNINGF(TL("Could not determine position on lane '%' at lateral position %."), lane->getID(), toString(-lanePosLat));
942  }
943  //std::cout << " lane=" << lane->getID() << " posLat=" << lanePosLat << " shape=" << lane->getShape() << " tmp=" << tmp << " tmpDist=" << tmp.distance2D(pos) << "\n";
944  if (tmp.distance2D(pos) > perpDist) {
945  lanePosLat = -lanePosLat;
946  }
947  }
948  }
949  if (found && !mayLeaveNetwork && MSGlobals::gLateralResolution < 0) {
950  // mapped position may differ from pos
951  pos = lane->geometryPositionAtOffset(lanePos, -lanePosLat);
952  }
953  assert((found && lane != 0) || (!found && lane == 0));
954  switch (p->getStageType(0)) {
955  case MSStageType::WALKING: {
956  if (angle == INVALID_DOUBLE_VALUE) {
957  // walking angle cannot be deduced from road angle so we always use the last pos
958  angle = GeomHelper::naviDegree(p->getPosition().angleTo2D(pos));
959  }
960  break;
961  }
963  case MSStageType::WAITING: {
964  if (p->getNumRemainingStages() <= 1 || p->getStageType(1) != MSStageType::WALKING) {
965  // insert walking stage after the current stage
966  ConstMSEdgeVector route({p->getEdge()});
967  const double departPos = p->getCurrentStage()->getArrivalPos();
968  p->appendStage(new MSStageWalking(p->getID(), route, nullptr, -1, -1, departPos, departPos, MSPModel::UNSPECIFIED_POS_LAT), 1);
969  }
970  // abort waiting stage and proceed to walking stage
971  p->removeStage(0);
972  assert(p->getStageType(0) == MSStageType::WALKING);
973  if (angle == INVALID_DOUBLE_VALUE) {
974  if (lane != nullptr && !lane->getEdge().isWalkingArea()) {
975  angle = GeomHelper::naviDegree(lane->getShape().rotationAtOffset(lanePos));
976  } else {
977  // compute angle outside road network or on walkingarea from old and new position
978  angle = GeomHelper::naviDegree(p->getPosition().angleTo2D(pos));
979  }
980  }
981  break;
982  }
983  default:
984  throw TraCIException("Command moveToXY is not supported for person '" + personID + "' while " + p->getCurrentStageDescription() + ".");
985  }
986  Helper::setRemoteControlled(p, pos, lane, lanePos, lanePosLat, angle, routeOffset, edges, MSNet::getInstance()->getCurrentTimeStep());
987  } else {
988  if (lane == nullptr) {
989  throw TraCIException("Could not map person '" + personID + "' no road found within " + toString(maxRouteDistance) + "m.");
990  } else {
991  throw TraCIException("Could not map person '" + personID + "' distance to road is " + toString(bestDistance) + ".");
992  }
993  }
994 }
995 
996 
999 void
1000 Person::setParameter(const std::string& personID, const std::string& key, const std::string& value) {
1001  MSTransportable* p = getPerson(personID);
1002  if (StringUtils::startsWith(key, "device.")) {
1003  throw TraCIException("Person '" + personID + "' does not support device parameters\n");
1004  } else if (StringUtils::startsWith(key, "laneChangeModel.")) {
1005  throw TraCIException("Person '" + personID + "' does not support laneChangeModel parameters\n");
1006  } else if (StringUtils::startsWith(key, "carFollowModel.")) {
1007  throw TraCIException("Person '" + personID + "' does not support carFollowModel parameters\n");
1008  } else if (StringUtils::startsWith(key, "junctionModel.")) {
1009  try {
1010  // use the whole key (including junctionModel prefix)
1011  p->setJunctionModelParameter(key, value);
1012  } catch (InvalidArgument& e) {
1013  // error message includes id since it is also used for xml input
1014  throw TraCIException(e.what());
1015  }
1016  } else if (StringUtils::startsWith(key, "has.") && StringUtils::endsWith(key, ".device")) {
1017  throw TraCIException("Person '" + personID + "' does not support chanigng device status\n");
1018  } else {
1019  ((SUMOVehicleParameter&)p->getParameter()).setParameter(key, value);
1020  }
1021 }
1022 
1023 
1024 void
1025 Person::setLength(const std::string& personID, double length) {
1026  getPerson(personID)->getSingularType().setLength(length);
1027 }
1028 
1029 
1030 void
1031 Person::setMaxSpeed(const std::string& personID, double speed) {
1032  getPerson(personID)->getSingularType().setMaxSpeed(speed);
1033 }
1034 
1035 
1036 void
1037 Person::setVehicleClass(const std::string& personID, const std::string& clazz) {
1038  getPerson(personID)->getSingularType().setVClass(getVehicleClassID(clazz));
1039 }
1040 
1041 
1042 void
1043 Person::setShapeClass(const std::string& personID, const std::string& clazz) {
1044  getPerson(personID)->getSingularType().setShape(getVehicleShapeID(clazz));
1045 }
1046 
1047 
1048 void
1049 Person::setEmissionClass(const std::string& personID, const std::string& clazz) {
1050  getPerson(personID)->getSingularType().setEmissionClass(PollutantsInterface::getClassByName(clazz));
1051 }
1052 
1053 
1054 void
1055 Person::setWidth(const std::string& personID, double width) {
1056  getPerson(personID)->getSingularType().setWidth(width);
1057 }
1058 
1059 
1060 void
1061 Person::setHeight(const std::string& personID, double height) {
1062  getPerson(personID)->getSingularType().setHeight(height);
1063 }
1064 
1065 
1066 void
1067 Person::setMinGap(const std::string& personID, double minGap) {
1068  getPerson(personID)->getSingularType().setMinGap(minGap);
1069 }
1070 
1071 
1072 void
1073 Person::setAccel(const std::string& personID, double accel) {
1074  getPerson(personID)->getSingularType().setAccel(accel);
1075 }
1076 
1077 
1078 void
1079 Person::setDecel(const std::string& personID, double decel) {
1080  getPerson(personID)->getSingularType().setDecel(decel);
1081 }
1082 
1083 
1084 void
1085 Person::setEmergencyDecel(const std::string& personID, double decel) {
1086  getPerson(personID)->getSingularType().setEmergencyDecel(decel);
1087 }
1088 
1089 
1090 void
1091 Person::setApparentDecel(const std::string& personID, double decel) {
1092  getPerson(personID)->getSingularType().setApparentDecel(decel);
1093 }
1094 
1095 
1096 void
1097 Person::setImperfection(const std::string& personID, double imperfection) {
1098  getPerson(personID)->getSingularType().setImperfection(imperfection);
1099 }
1100 
1101 
1102 void
1103 Person::setBoardingDuration(const std::string& personID, double boardingDuration) {
1104  Helper::getPerson(personID)->getSingularType().setBoardingDuration(TIME2STEPS(boardingDuration));
1105 }
1106 
1107 
1108 void
1109 Person::setImpatience(const std::string& personID, double impatience) {
1110  Helper::getVehicle(personID)->getSingularType().setImpatience(impatience);
1111 }
1112 
1113 
1114 
1115 void
1116 Person::setTau(const std::string& personID, double tau) {
1117  getPerson(personID)->getSingularType().setTau(tau);
1118 }
1119 
1120 
1121 void
1122 Person::setMinGapLat(const std::string& personID, double minGapLat) {
1123  getPerson(personID)->getSingularType().setMinGapLat(minGapLat);
1124 }
1125 
1126 
1127 void
1128 Person::setMaxSpeedLat(const std::string& personID, double speed) {
1129  getPerson(personID)->getSingularType().setMaxSpeedLat(speed);
1130 }
1131 
1132 
1133 void
1134 Person::setLateralAlignment(const std::string& personID, const std::string& latAlignment) {
1135  double lao;
1137  if (SUMOVTypeParameter::parseLatAlignment(latAlignment, lao, lad)) {
1138  getPerson(personID)->getSingularType().setPreferredLateralAlignment(lad, lao);
1139  } else {
1140  throw TraCIException("Unknown value '" + latAlignment + "' when setting latAlignment for person '" + personID + "';\n must be one of (\"right\", \"center\", \"arbitrary\", \"nice\", \"compact\", \"left\" or a float)");
1141  }
1142 }
1143 
1144 
1145 void
1146 Person::setSpeedFactor(const std::string& personID, double factor) {
1147  getPerson(personID)->setChosenSpeedFactor(factor);
1148 }
1149 
1150 
1151 void
1152 Person::setActionStepLength(const std::string& personID, double actionStepLength, bool resetActionOffset) {
1153  getPerson(personID)->getSingularType().setActionStepLength(SUMOVehicleParserHelper::processActionStepLength(actionStepLength), resetActionOffset);
1154 }
1155 
1156 void
1157 Person::remove(const std::string& personID, char /*reason*/) {
1158  MSPerson* person = getPerson(personID);
1159  // remove all stages after the current and then abort the current stage
1160  // (without adding a zero-length waiting stage)
1161  while (person->getNumRemainingStages() > 1) {
1162  person->removeStage(1);
1163  }
1164  person->removeStage(0, false);
1165 }
1166 
1167 void
1168 Person::setColor(const std::string& personID, const TraCIColor& c) {
1169  const SUMOVehicleParameter& p = getPerson(personID)->getParameter();
1170  p.color.set((unsigned char)c.r, (unsigned char)c.g, (unsigned char)c.b, (unsigned char)c.a);
1172 }
1173 
1174 
1176 
1177 
1178 MSPerson*
1179 Person::getPerson(const std::string& personID) {
1180  return Helper::getPerson(personID);
1181 }
1182 
1183 
1184 void
1185 Person::storeShape(const std::string& id, PositionVector& shape) {
1186  shape.push_back(getPerson(id)->getPosition());
1187 }
1188 
1189 
1190 std::shared_ptr<VariableWrapper>
1191 Person::makeWrapper() {
1192  return std::make_shared<Helper::SubscriptionWrapper>(handleVariable, mySubscriptionResults, myContextSubscriptionResults);
1193 }
1194 
1195 
1196 bool
1197 Person::handleVariable(const std::string& objID, const int variable, VariableWrapper* wrapper, tcpip::Storage* paramData) {
1198  switch (variable) {
1199  case TRACI_ID_LIST:
1200  return wrapper->wrapStringList(objID, variable, getIDList());
1201  case ID_COUNT:
1202  return wrapper->wrapInt(objID, variable, getIDCount());
1203  case VAR_POSITION:
1204  return wrapper->wrapPosition(objID, variable, getPosition(objID));
1205  case VAR_POSITION3D:
1206  return wrapper->wrapPosition(objID, variable, getPosition(objID, true));
1207  case VAR_ANGLE:
1208  return wrapper->wrapDouble(objID, variable, getAngle(objID));
1209  case VAR_SLOPE:
1210  return wrapper->wrapDouble(objID, variable, getSlope(objID));
1211  case VAR_SPEED:
1212  return wrapper->wrapDouble(objID, variable, getSpeed(objID));
1213  case VAR_ROAD_ID:
1214  return wrapper->wrapString(objID, variable, getRoadID(objID));
1215  case VAR_LANE_ID:
1216  return wrapper->wrapString(objID, variable, getLaneID(objID));
1217  case VAR_LANEPOSITION:
1218  return wrapper->wrapDouble(objID, variable, getLanePosition(objID));
1219  case VAR_COLOR:
1220  return wrapper->wrapColor(objID, variable, getColor(objID));
1221  case VAR_WAITING_TIME:
1222  return wrapper->wrapDouble(objID, variable, getWaitingTime(objID));
1223  case VAR_IMPATIENCE:
1224  return wrapper->wrapDouble(objID, variable, getImpatience(objID));
1225  case VAR_TYPE:
1226  return wrapper->wrapString(objID, variable, getTypeID(objID));
1227  case VAR_SPEED_FACTOR:
1228  return wrapper->wrapDouble(objID, variable, getSpeedFactor(objID));
1229  case VAR_NEXT_EDGE:
1230  return wrapper->wrapString(objID, variable, getNextEdge(objID));
1231  case VAR_STAGES_REMAINING:
1232  return wrapper->wrapInt(objID, variable, getRemainingStages(objID));
1233  case VAR_VEHICLE:
1234  return wrapper->wrapString(objID, variable, getVehicle(objID));
1235  case VAR_MAXSPEED:
1236  // integrate desiredMaxSpeed and individual speedFactor
1237  return wrapper->wrapDouble(objID, variable, getMaxSpeed(objID));
1239  paramData->readUnsignedByte();
1240  return wrapper->wrapString(objID, variable, getParameter(objID, paramData->readString()));
1242  paramData->readUnsignedByte();
1243  return wrapper->wrapStringPair(objID, variable, getParameterWithKey(objID, paramData->readString()));
1244  case VAR_TAXI_RESERVATIONS:
1245  // we cannot use the general fall through here because we do not have an object id
1246  return false;
1247  default:
1248  return libsumo::VehicleType::handleVariable(getTypeID(objID), variable, wrapper, paramData);
1249  }
1250 }
1251 
1252 
1253 }
1254 
1255 
1256 /****************************************************************************/
long long int SUMOTime
Definition: GUI.h:35
std::vector< const MSEdge * > ConstMSEdgeVector
Definition: MSEdge.h:74
#define WRITE_WARNINGF(...)
Definition: MsgHandler.h:296
#define TL(string)
Definition: MsgHandler.h:315
std::string time2string(SUMOTime t, bool humanReadable)
convert SUMOTime to string (independently of global format setting)
Definition: SUMOTime.cpp:69
#define STEPS2TIME(x)
Definition: SUMOTime.h:55
#define SIMSTEP
Definition: SUMOTime.h:61
#define TIME2STEPS(x)
Definition: SUMOTime.h:57
LatAlignmentDefinition
Possible ways to choose the lateral alignment, i.e., how vehicles align themselves within their lane.
SUMOVehicleClass getVehicleClassID(const std::string &name)
Returns the class id of the abstract class given by its name.
SUMOVehicleShape getVehicleShapeID(const std::string &name)
Returns the class id of the shape class given by its name.
std::string getVehicleShapeName(SUMOVehicleShape id)
Returns the class name of the shape class given by its id.
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
@ SVC_IGNORING
vehicles ignoring classes
const int VEHPARS_COLOR_SET
@ GIVEN
The position is given.
DepartDefinition
Possible ways to depart.
@ DEF_MAX
Tag for the last element in the enum for safe int casting.
@ SUMO_TAG_BUS_STOP
A bus stop.
@ SUMO_TAG_PARKING_AREA
A parking area.
T MIN2(T a, T b)
Definition: StdDefs.h:76
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
#define LIBSUMO_SUBSCRIPTION_IMPLEMENTATION(CLASS, DOM)
Definition: TraCIDefs.h:76
#define LIBSUMO_GET_PARAMETER_WITH_KEY_IMPLEMENTATION(CLASS)
Definition: TraCIDefs.h:123
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:191
MSVehicleType & getSingularType()
Replaces the current vehicle type with a new one used by this vehicle only.
static MSDispatch * getDispatchAlgorithm()
A dispatch algorithm that services customers in reservation order and always sends the closest availa...
std::string splitReservation(std::string resID, std::vector< std::string > personIDs)
split existing reservations and return the new reservation id
An algorithm that performs distpach for a taxi fleet.
Definition: MSDispatch.h:112
std::vector< Reservation * > getReservations()
retrieve all reservations
Definition: MSDispatch.cpp:226
virtual std::vector< const Reservation * > getRunningReservations()
retrieve all reservations that were already dispatched and are still active
Definition: MSDispatch.cpp:236
A road/street connecting two junctions.
Definition: MSEdge.h:77
bool isWalkingArea() const
return whether this edge is walking area
Definition: MSEdge.h:284
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:1046
bool isNormal() const
return whether this edge is an internal edge
Definition: MSEdge.h:260
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition: MSEdge.h:168
const MSJunction * getFromJunction() const
Definition: MSEdge.h:411
double getLength() const
return the length of the edge
Definition: MSEdge.h:662
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:983
const MSJunction * getToJunction() const
Definition: MSEdge.h:415
static double gLateralResolution
Definition: MSGlobals.h:97
The base class for an intersection.
Definition: MSJunction.h:58
Representation of a lane in the micro simulation.
Definition: MSLane.h:84
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition: MSLane.cpp:2355
MSEdge & getEdge() const
Returns the lane's edge.
Definition: MSLane.h:752
double interpolateLanePosToGeometryPos(double lanePos) const
Definition: MSLane.h:546
double getWidth() const
Returns the lane's width.
Definition: MSLane.h:627
const Position geometryPositionAtOffset(double offset, double lateralOffset=0) const
Definition: MSLane.h:552
virtual const PositionVector & getShape(bool) const
Definition: MSLane.h:294
MSPedestrianRouter & getPedestrianRouter(const int rngIndex, const MSEdgeVector &prohibited=MSEdgeVector()) const
Definition: MSNet.cpp:1494
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:182
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:378
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:320
MSStoppingPlace * getStoppingPlace(const std::string &id, const SumoXMLTag category) const
Returns the named stopping place of the given category.
Definition: MSNet.cpp:1364
virtual MSTransportableControl & getPersonControl()
Returns the person control.
Definition: MSNet.cpp:1173
static const double SIDEWALK_OFFSET
the offset for computing person positions when walking on edges without a sidewalk
Definition: MSPModel.h:127
static const double UNSPECIFIED_POS_LAT
the default lateral offset for persons when starting a walk
Definition: MSPModel.h:130
void reroute(const ConstMSEdgeVector &newEdges, double departPos, int firstIndex, int nextIndex)
set new walk and replace the stages with relative indices in the interval [firstIndex,...
Definition: MSPerson.cpp:246
const std::set< std::string > & getLines() const
SUMOTime getIntendedDepart() const
std::string getIntendedVehicleID() const
std::string getVehicleType() const
virtual ConstMSEdgeVector getEdges() const
the edges of the current stage
Definition: MSStage.cpp:113
virtual double getArrivalPos() const
Definition: MSStage.h:93
SUMOTime getDeparted() const
get departure time of stage
Definition: MSStage.cpp:128
virtual std::string getStageDescription(const bool isPerson) const =0
return (brief) string representation of the current stage
MSStoppingPlace * getDestinationStop() const
returns the destination stop (if any)
Definition: MSStage.h:84
SUMOTime getArrived() const
get arrival time of stage
Definition: MSStage.cpp:133
MSStageType getStageType() const
Definition: MSStage.h:126
virtual double getDistance() const =0
get travel distance in this stage
ConstMSEdgeVector getEdges() const
the edges of the current stage
const std::vector< const MSEdge * >::iterator getRouteStep() const
const std::vector< const MSEdge * > & getRoute() const
MSTransportableStateAdapter * getPState() const
Definition: MSStageMoving.h:49
A lane area vehicles can halt at.
double getEndLanePosition() const
Returns the end position of this stop.
std::map< std::string, MSTransportable * >::const_iterator constVehIt
Definition of the internal transportables map iterator.
constVehIt loadedBegin() const
Returns the begin of the internal transportables map.
int size() const
Returns the number of known transportables.
constVehIt loadedEnd() const
Returns the end of the internal transportables map.
virtual MSTransportable * buildPerson(const SUMOVehicleParameter *pars, MSVehicleType *vtype, MSTransportable::MSTransportablePlan *plan, SumoRNG *rng) const
Builds a new person.
bool add(MSTransportable *transportable)
Adds a single transportable, returns false if an id clash occurred.
virtual double getEdgePos() const
Return the position on the edge.
SUMOVehicleClass getVClass() const
Returns the object's access class.
const MSEdge * getArrivalEdge() const
returns the final arrival edge
std::string getCurrentStageDescription() const
Returns the current stage description as a string.
MSStageType getStageType(int next) const
the stage type for the nth next stage
void setJunctionModelParameter(const std::string &key, const std::string &value)
set individual junction model paramete (not type related)
MSStage * getNextStage(int offset) const
Return the next (or previous) stage denoted by the offset.
int getNumRemainingStages() const
Return the number of remaining stages (including the current)
const SUMOVehicleParameter & getParameter() const
Returns the vehicle's parameter (including departure definition)
void removeStage(int next, bool stayInSim=true)
removes the nth next stage
const MSVehicleType & getVehicleType() const
Returns the object's "vehicle" type.
bool isPerson() const
Whether it is a person.
Position getPosition(const double) const
Return current position (x/y, cartesian)
double getArrivalPos() const
returns the final arrival pos
int getNumStages() const
Return the total number stages in this person's plan.
MSStageType getCurrentStageType() const
the current stage type of the transportable
const MSEdge * getEdge() const
Returns the current edge.
MSStage * getCurrentStage() const
Return the current stage.
void appendStage(MSStage *stage, int next=-1)
Appends the given stage to the current plan.
MSVehicleType & getSingularType()
Replaces the current vehicle type with a new one used by this vehicle only.
std::vector< MSStage * > MSTransportablePlan
the structure holding the plan of a transportable
double getMaxSpeed() const
Returns the maximum speed (the minimum of desired and physical maximum speed)
virtual void moveTo(MSPerson *p, MSLane *lane, double lanePos, double lanePosLat, SUMOTime t)
try to move transportable to the given position
Definition: MSPModel.h:182
MSVehicleType * getVType(const std::string &id=DEFAULT_VTYPE_ID, SumoRNG *rng=nullptr, bool readOnly=false)
Returns the named vehicle type or a sample from the named distribution.
The car-following model and parameter.
Definition: MSVehicleType.h:63
double getWidth() const
Get the width which vehicles of this class shall have when being drawn.
void setBoardingDuration(SUMOTime duration, bool isPerson=true)
Set a new value for this type's boardingDuration.
void setImpatience(const double impatience)
Set a new value for this type's impatience.
static std::string getIDSecure(const T *obj, const std::string &fallBack="NULL")
get an identifier for Named-like object which may be Null
Definition: Named.h:67
const std::string & getID() const
Returns the id.
Definition: Named.h:74
double compute(const E *from, const E *to, double departPos, double arrivalPos, double speed, SUMOTime msTime, const N *onlyNode, std::vector< const E * > &into, bool allEdges=false)
Builds the route between the given edges using the minimum effort at the given time The definition of...
C++ TraCI client API implementation.
Definition: Person.h:33
static std::string getName(const SUMOEmissionClass c)
Checks whether the string describes a known vehicle class.
static SUMOEmissionClass getClassByName(const std::string &eClass, const SUMOVehicleClass vc=SVC_IGNORING)
Checks whether the string describes a known vehicle class.
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:37
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
Definition: Position.h:271
double angleTo2D(const Position &other) const
returns the angle in the plane of the vector pointing from here to the other position (in radians bet...
Definition: Position.h:281
A list of positions.
double rotationAtOffset(double pos) const
Returns the rotation at the given length.
double distance2D(const Position &p, bool perpendicular=false) const
closest 2D-distance to point p (or -1 if perpendicular is true and the point is beyond this vector)
void move2side(double amount, double maxExtension=100)
move position vector to side using certain amount
double slopeDegreeAtOffset(double pos) const
Returns the slope at the given length.
unsigned char red() const
Returns the red-amount of the color.
Definition: RGBColor.cpp:74
unsigned char alpha() const
Returns the alpha-amount of the color.
Definition: RGBColor.cpp:92
unsigned char green() const
Returns the green-amount of the color.
Definition: RGBColor.cpp:80
unsigned char blue() const
Returns the blue-amount of the color.
Definition: RGBColor.cpp:86
void set(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
assigns new values
Definition: RGBColor.cpp:98
static bool parseLatAlignment(const std::string &val, double &lao, LatAlignmentDefinition &lad)
Parses and validates a given latAlignment value.
Representation of a vehicle.
Definition: SUMOVehicle.h:60
Structure representing possible vehicle parameter.
int parametersSet
Information for the router which parameter were set, TraCI may modify this (when changing color)
double departPos
(optional) The position the vehicle shall depart from
RGBColor color
The vehicle's color, TraCI may change this.
std::string id
The vehicle's id.
DepartDefinition departProcedure
Information how the vehicle shall choose the depart time.
DepartPosDefinition departPosProcedure
Information how the vehicle shall choose the departure position.
static SUMOTime processActionStepLength(double given)
Checks and converts given value for the action step length from seconds to miliseconds assuring it be...
std::vector< std::string > getVector()
return vector of strings
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 TraCIPosition makeTraCIPosition(const Position &position, const bool includeZ=false)
Definition: Helper.cpp:377
static bool moveToXYMap_matchingRoutePosition(const Position &pos, const std::string &origID, const ConstMSEdgeVector &currentRoute, int routeIndex, SUMOVehicleClass vClass, bool setLateralPos, double &bestDistance, MSLane **lane, double &lanePos, int &routeOffset)
Definition: Helper.cpp:1725
static MSPerson * getPerson(const std::string &id)
Definition: Helper.cpp:491
static MSBaseVehicle * getVehicle(const std::string &id)
Definition: Helper.cpp:477
static void setRemoteControlled(MSVehicle *v, Position xyPos, MSLane *l, double pos, double posLat, double angle, int edgeOffset, ConstMSEdgeVector route, SUMOTime t)
Definition: Helper.cpp:1377
static bool moveToXYMap(const Position &pos, double maxRouteDistance, bool mayLeaveNetwork, const std::string &origID, const double angle, double speed, const ConstMSEdgeVector &currentRoute, const int routePosition, const MSLane *currentLane, double currentLanePos, bool onRoad, SUMOVehicleClass vClass, bool setLateralPos, double &bestDistance, MSLane **lane, double &lanePos, int &routeOffset, ConstMSEdgeVector &edges)
Definition: Helper.cpp:1417
virtual std::string readString()
Definition: storage.cpp:180
virtual int readUnsignedByte()
Definition: storage.cpp:155
TRACI_CONST double INVALID_DOUBLE_VALUE
TRACI_CONST int TRACI_ID_LIST
TRACI_CONST int VAR_IMPATIENCE
TRACI_CONST int VAR_TYPE
TRACI_CONST int VAR_VEHICLE
TRACI_CONST int VAR_WAITING_TIME
std::map< std::string, libsumo::SubscriptionResults > ContextSubscriptionResults
Definition: TraCIDefs.h:338
TRACI_CONST int VAR_ROAD_ID
TRACI_CONST int VAR_TAXI_RESERVATIONS
TRACI_CONST int VAR_SPEED_FACTOR
TRACI_CONST int VAR_ANGLE
TRACI_CONST int VAR_COLOR
TRACI_CONST int VAR_POSITION
TRACI_CONST int VAR_MAXSPEED
TRACI_CONST int STAGE_WAITING
std::map< std::string, libsumo::TraCIResults > SubscriptionResults
{object->{variable->value}}
Definition: TraCIDefs.h:337
TRACI_CONST int VAR_SLOPE
TRACI_CONST int ID_COUNT
TRACI_CONST int VAR_PARAMETER
TRACI_CONST int VAR_LANEPOSITION
TRACI_CONST int VAR_LANE_ID
TRACI_CONST int STAGE_WALKING
TRACI_CONST int VAR_POSITION3D
TRACI_CONST int VAR_SPEED
TRACI_CONST int VAR_PARAMETER_WITH_KEY
TRACI_CONST int VAR_NEXT_EDGE
TRACI_CONST int STAGE_DRIVING
TRACI_CONST int VAR_STAGES_REMAINING
SUMOTime pickupTime
Definition: MSDispatch.h:79
std::string id
Definition: MSDispatch.h:76
const MSEdge * to
Definition: MSDispatch.h:84
double fromPos
Definition: MSDispatch.h:82
const MSEdge * from
Definition: MSDispatch.h:81
SUMOTime reservationTime
Definition: MSDispatch.h:78
std::string group
Definition: MSDispatch.h:87
ReservationState state
Definition: MSDispatch.h:90
std::set< const MSTransportable * > persons
Definition: MSDispatch.h:77
double toPos
Definition: MSDispatch.h:85