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