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