30#include <jupedsim/jupedsim.h>
68 myRNG(
"JuPedSim_legacy"), myNetwork(net), myShapeContainer(net->getShapeContainer()), myJPSDeltaT(
string2time(oc.getString(
"pedestrian.jupedsim.step-length"))),
69 myExitTolerance(oc.getFloat(
"pedestrian.jupedsim.exit-tolerance")), myGEOSPedestrianNetworkLargestComponent(nullptr),
70 myHaveAdditionalWalkableAreas(false) {
72 const std::string model = oc.
getString(
"pedestrian.jupedsim.model");
73 if (model ==
"CollisionFreeSpeed" || model ==
"CollisionFreeSpeedModel") {
75 }
else if (model ==
"CollisionFreeSpeedV2" || model ==
"CollisionFreeSpeedModelV2") {
77 }
else if (model ==
"GeneralizedCentrifugalForce" || model ==
"GeneralizedCentrifugalForceModel") {
79 }
else if (model ==
"SocialForce" || model ==
"SocialForceModel") {
92 (*myPythonScript) <<
"while simulation.agent_count() > 0 and simulation.iteration_count() < 160 * 100: simulation.iterate()\n";
112 JPS_Point orientation;
113 if (fabs(angle -
M_PI / 2) < NUMERICAL_EPS) {
114 orientation = JPS_Point{0., 1.};
115 }
else if (fabs(angle +
M_PI / 2) < NUMERICAL_EPS) {
116 orientation = JPS_Point{0., -1.};
118 orientation = JPS_Point{1., tan(angle)};
121 JPS_AgentId agentId = 0;
122 JPS_ErrorMessage message =
nullptr;
126 JPS_CollisionFreeSpeedModelAgentParameters agentParameters{};
127 agentParameters.position = {p.
x(), p.
y()};
129 agentParameters.stageId = state->
getStageId();
131 agentParameters.radius =
getRadius(type);
132 agentId = JPS_Simulation_AddCollisionFreeSpeedModelAgent(
myJPSSimulation, agentParameters, &message);
136 JPS_CollisionFreeSpeedModelV2AgentParameters agentParameters{};
137 agentParameters.position = {p.
x(), p.
y()};
139 agentParameters.stageId = state->
getStageId();
141 agentParameters.radius =
getRadius(type);
142 agentId = JPS_Simulation_AddCollisionFreeSpeedModelV2Agent(
myJPSSimulation, agentParameters, &message);
146 JPS_GeneralizedCentrifugalForceModelAgentParameters agentParameters{};
147 agentParameters.position = {p.
x(), p.
y()};
148 agentParameters.orientation = orientation;
150 agentParameters.stageId = state->
getStageId();
152 agentId = JPS_Simulation_AddGeneralizedCentrifugalForceModelAgent(
myJPSSimulation, agentParameters, &message);
156 JPS_SocialForceModelAgentParameters agentParameters{};
157 agentParameters.position = {p.
x(), p.
y()};
158 agentParameters.orientation = orientation;
160 agentParameters.stageId = state->
getStageId();
162 agentParameters.radius =
getRadius(type);
163 agentId = JPS_Simulation_AddSocialForceModelAgent(
myJPSSimulation, agentParameters, &message);
167 if (message !=
nullptr) {
169 JPS_ErrorMessage_Free(message);
178 JPS_ErrorMessage message =
nullptr;
179 if (predecessor != 0) {
180 const JPS_Transition transition = JPS_Transition_CreateFixedTransition(stage, &message);
181 if (message !=
nullptr) {
182 WRITE_WARNINGF(
TL(
"Error while creating fixed transition for person '%': %"), agentID, JPS_ErrorMessage_GetMessage(message));
183 JPS_ErrorMessage_Free(message);
186 JPS_JourneyDescription_SetTransitionForStage(journey, predecessor, transition, &message);
187 if (message !=
nullptr) {
188 WRITE_WARNINGF(
TL(
"Error while setting transition for person '%': %"), agentID, JPS_ErrorMessage_GetMessage(message));
189 JPS_ErrorMessage_Free(message);
192 JPS_Transition_Free(transition);
194 JPS_JourneyDescription_AddStage(journey, stage);
202 JPS_ErrorMessage message =
nullptr;
203 const Position& coords = std::get<1>(waypoint);
204 const JPS_StageId waypointId = JPS_Simulation_AddStageWaypoint(
myJPSSimulation, {coords.
x(), coords.
y()},
205 std::get<2>(waypoint), &message);
206 if (message !=
nullptr) {
207 WRITE_WARNINGF(
TL(
"Error while adding waypoint for person '%': %"), agentID, JPS_ErrorMessage_GetMessage(message));
208 JPS_ErrorMessage_Free(message);
211 const JPS_StageId waiting = std::get<0>(waypoint);
214 (*myPythonScript) <<
"journey.add(" << waiting <<
")\n";
215 if (predecessor != 0) {
216 (*myPythonScript) <<
"journey.set_transition_for_stage(" << predecessor <<
", jps.Transition.create_fixed_transition(" << waiting <<
"))\n";
219 if (!
addStage(journey, predecessor, agentID, waiting)) {
224 (*myPythonScript) <<
"ws = simulation.add_waypoint_stage((" << coords.
x() <<
"," << coords.
y() <<
"), " << std::get<2>(waypoint) <<
")\n"
226 if (predecessor != 0) {
227 (*myPythonScript) <<
"journey.set_transition_for_stage(" << predecessor <<
", jps.Transition.create_fixed_transition(ws))\n";
230 if (!
addStage(journey, predecessor, agentID, waypointId)) {
242 const MSLane*
const departureLane = getSidewalk<MSEdge, MSLane>(stage->
getRoute().front());
243 if (departureLane ==
nullptr) {
244 const char* error =
TL(
"Person '%' could not find sidewalk on edge '%', time=%.");
257 if (tazShape ==
nullptr) {
270 const double halfDepartureLaneWidth = departureLane->
getWidth() / 2.0;
273 departureRelativePositionY = 0.0;
276 departureRelativePositionY =
RandHelper::rand(-halfDepartureLaneWidth, halfDepartureLaneWidth, &
myRNG);
281 std::vector<WaypointDesc> waypoints;
282 const MSEdge* prev =
nullptr;
284 const MSLane*
const lane = getSidewalk<MSEdge, MSLane>(e);
285 JPS_StageId waitingStage = 0;
286 if (prev !=
nullptr) {
298 const MSEdge* wa =
nullptr;
299 for (
const MSEdge*
const ce : crossingRoute) {
300 if (ce->isCrossing()) {
301 const MSLane*
const crossing = getSidewalk<MSEdge, MSLane>(ce);
304 if (waitingStage != 0 && wa !=
nullptr) {
306 waypoints.push_back({waitingStage, wa->
getLanes()[0]->getShape().getCentroid(), wa->
getWidth() / 2.});
308 const MSLane*
const prevLane = getSidewalk<MSEdge, MSLane>(prev);
311 if (crossing->
getShape().front().distanceSquaredTo(startPos) < crossing->
getShape().back().distanceSquaredTo(startPos)) {
312 if (crossingWait->second.first == 0) {
315 waitingStage = crossingWait->second.first;
317 if (crossingWait->second.second == 0) {
318 crossingWait->second.second =
addWaitingSet(crossing,
false);
320 waitingStage = crossingWait->second.second;
323 throw ProcessError(
TLF(
"No waiting set for crossing at %.", ce->getID()));
326 if (ce->isWalkingArea()) {
332 waypoints.push_back({waitingStage, lane->
getShape().positionAtOffset(e->getLength() / 2.), lane->
getWidth() / 2.});
335 const JPS_StageId finalWait = std::get<0>(waypoints.back());
336 waypoints.pop_back();
337 if (!waypoints.empty()) {
338 waypoints.erase(waypoints.begin());
344 JPS_JourneyDescription journeyDesc = JPS_JourneyDescription_Create();
346 (*myPythonScript) <<
"\njourney = jps.JourneyDescription()\n";
348 JPS_StageId startingStage = 0;
349 JPS_StageId predecessor = 0;
350 for (
const auto& p : waypoints) {
352 JPS_JourneyDescription_Free(journeyDesc);
355 if (startingStage == 0) {
356 startingStage = std::get<0>(waypoints.front()) == 0 ? predecessor : std::get<0>(waypoints.front());
359 JPS_ErrorMessage message =
nullptr;
360 JPS_JourneyId journeyId = JPS_Simulation_AddJourney(
myJPSSimulation, journeyDesc, &message);
361 JPS_JourneyDescription_Free(journeyDesc);
362 if (message !=
nullptr) {
363 WRITE_WARNINGF(
TL(
"Error while adding a journey for person '%': %"), person->
getID(), JPS_ErrorMessage_GetMessage(message));
364 JPS_ErrorMessage_Free(message);
370 if (pstate->getPerson() == person) {
375 if (state ==
nullptr) {
376 state =
new PState(
static_cast<MSPerson*
>(person), stage, journeyId, startingStage, waypoints);
378 state->
setPosition(departurePosition.
x(), departurePosition.
y());
383 state->
reinit(stage, journeyId, startingStage, waypoints);
389 (*myPythonScript) <<
"journey_id = simulation.add_journey(journey)\n"
390 "simulation.add_agent(jps.CollisionFreeSpeedModelAgentParameters(journey_id=journey_id,stage_id="
391 << startingStage <<
",position=(" << departurePosition.
x() <<
"," << departurePosition.
y()
396 if (message !=
nullptr) {
397 WRITE_WARNINGF(
TL(
"Error while switching to a new journey for person '%': %"), person->
getID(), JPS_ErrorMessage_GetMessage(message));
398 JPS_ErrorMessage_Free(message);
409 if (pstate->
getLane() !=
nullptr) {
411 peds.erase(std::find(peds.begin(), peds.end(), pstate));
414 if (pstate->
getStage() !=
nullptr) {
424 JPS_ErrorMessage message =
nullptr;
425 for (
int i = 0; i < nbrIterations; ++i) {
429 WRITE_ERRORF(
TL(
"Error during iteration %: %"), i, JPS_ErrorMessage_GetMessage(message));
437 PState*
const state = *stateIt;
451 if (stage ==
nullptr) {
462 const JPS_Point position = JPS_Agent_GetPosition(agent);
466 const JPS_Point orientation = JPS_Agent_GetOrientation(agent);
467 state->
setAngle(atan2(orientation.y, orientation.x));
470 Position newPosition(position.x, position.y);
473 const double oldLanePos = state->
getEdgePos(time);
475 double bestDistance = std::numeric_limits<double>::max();
476 MSLane* candidateLane =
nullptr;
477 double candidateLaneLongitudinalPosition = 0.0;
480 forwardRoute, 0, person->
getVClass(),
true, bestDistance, &candidateLane, candidateLaneLongitudinalPosition, routeOffset);
483 if (candidateLane != state->
getLane()) {
484 if (state->
getLane() !=
nullptr) {
486 peds.erase(std::find(peds.begin(), peds.end(), state));
496 const bool arrived = stage->
moveToNextEdge(person, time, 1,
nullptr);
504 JPS_CollisionFreeSpeedModelState modelState = JPS_Agent_GetCollisionFreeSpeedModelState(agent,
nullptr);
505 if (newMaxSpeed != JPS_CollisionFreeSpeedModelState_GetV0(modelState)) {
506 JPS_CollisionFreeSpeedModelState_SetV0(modelState, newMaxSpeed);
511 JPS_CollisionFreeSpeedModelV2State modelState = JPS_Agent_GetCollisionFreeSpeedModelV2State(agent,
nullptr);
512 if (newMaxSpeed != JPS_CollisionFreeSpeedModelV2State_GetV0(modelState)) {
513 JPS_CollisionFreeSpeedModelV2State_SetV0(modelState, newMaxSpeed);
518 JPS_GeneralizedCentrifugalForceModelState modelState = JPS_Agent_GetGeneralizedCentrifugalForceModelState(agent,
nullptr);
519 if (newMaxSpeed != JPS_GeneralizedCentrifugalForceModelState_GetV0(modelState)) {
520 JPS_GeneralizedCentrifugalForceModelState_SetV0(modelState, newMaxSpeed);
525 JPS_SocialForceModelState modelState = JPS_Agent_GetSocialForceModelState(agent,
nullptr);
526 if (newMaxSpeed != JPS_SocialForceModelState_GetDesiredSpeed(modelState)) {
527 JPS_SocialForceModelState_SetDesiredSpeed(modelState, newMaxSpeed);
533 const double speed = person->
getSpeed();
534 for (
int offset = 0; offset < 2; offset++) {
536 if (waypoint !=
nullptr && std::get<0>(*waypoint) != 0) {
537 const JPS_StageId waitingStage = std::get<0>(*waypoint);
548 const double passingClearanceTime = person->
getFloatParam(
"pedestrian.timegap-crossing");
550 person->
getImpatience(), speed, 0, 0,
nullptr,
false, person);
551 const auto proxy = JPS_Simulation_GetWaitingSetProxy(
myJPSSimulation, waitingStage, &message);
552 JPS_WaitingSetProxy_SetWaitingSetState(proxy, open ? JPS_WaitingSet_Inactive : JPS_WaitingSet_Active);
558 const double slack = person->
getMaxSpeed() *
TS / 2. + POSITION_EPS;
564 const JPS_AgentId agentID = state->
getAgentId();
577 for (
const auto& area :
myAreas) {
578 const std::vector<JPS_Point>& areaBoundary = area->areaBoundary;
579 JPS_AgentIdIterator agentsInArea = JPS_Simulation_AgentsInPolygon(
myJPSSimulation, areaBoundary.data(), areaBoundary.size());
580 if (area->areaType ==
"vanishing_area") {
581 const SUMOTime period = area->params.count(
"period") > 0 ?
string2time(area->params.at(
"period")) : 1000;
582 const int nbrPeriodsCoveringTimestep = (int)ceil(
TS /
STEPS2TIME(period));
583 if (time - area->lastRemovalTime >= nbrPeriodsCoveringTimestep * period) {
584 for (
int k = 0; k < nbrPeriodsCoveringTimestep; k++) {
585 const JPS_AgentId agentID = JPS_AgentIdIterator_Next(agentsInArea);
587 auto lambda = [agentID](
const PState *
const p) {
588 return p->getAgentId() == agentID;
592 const PState*
const state = *iterator;
597 WRITE_MESSAGEF(
TL(
"Person '%' in vanishing area '%' was removed from the simulation."), person->
getID(), area->id);
601 area->lastRemovalTime = time;
608 for (JPS_AgentId agentID = JPS_AgentIdIterator_Next(agentsInArea); agentID != 0; agentID = JPS_AgentIdIterator_Next(agentsInArea)) {
609 if (area->params.count(
"speed") > 0) {
610 const JPS_Agent agent = JPS_Simulation_GetAgent(
myJPSSimulation, agentID,
nullptr);
614 JPS_CollisionFreeSpeedModelState modelState = JPS_Agent_GetCollisionFreeSpeedModelState(agent,
nullptr);
615 if (newMaxSpeed != JPS_CollisionFreeSpeedModelState_GetV0(modelState)) {
616 JPS_CollisionFreeSpeedModelState_SetV0(modelState, newMaxSpeed);
621 JPS_CollisionFreeSpeedModelV2State modelState = JPS_Agent_GetCollisionFreeSpeedModelV2State(agent,
nullptr);
622 if (newMaxSpeed != JPS_CollisionFreeSpeedModelV2State_GetV0(modelState)) {
623 JPS_CollisionFreeSpeedModelV2State_SetV0(modelState, newMaxSpeed);
628 JPS_GeneralizedCentrifugalForceModelState modelState = JPS_Agent_GetGeneralizedCentrifugalForceModelState(agent,
nullptr);
629 if (newMaxSpeed != JPS_GeneralizedCentrifugalForceModelState_GetV0(modelState)) {
630 JPS_GeneralizedCentrifugalForceModelState_SetV0(modelState, newMaxSpeed);
635 JPS_SocialForceModelState modelState = JPS_Agent_GetSocialForceModelState(agent,
nullptr);
636 if (newMaxSpeed != JPS_SocialForceModelState_GetDesiredSpeed(modelState)) {
637 JPS_SocialForceModelState_SetDesiredSpeed(modelState, newMaxSpeed);
645 JPS_AgentIdIterator_Free(agentsInArea);
650 std::vector<SUMOTrafficObject::NumericalID> allStoppedTrainIDs;
651 std::vector<const MSVehicle*> allStoppedTrains;
652 for (
const auto& stop : stoppingPlaces) {
653 std::vector<const SUMOVehicle*> stoppedTrains = stop.second->getStoppedVehicles();
655 allStoppedTrainIDs.push_back(train->getNumericalID());
656 allStoppedTrains.push_back(
dynamic_cast<const MSVehicle*
>(train));
661 if (!allStoppedTrainIDs.empty()) {
662 std::vector<GEOSGeometry*> carriagePolygons;
663 std::vector<GEOSGeometry*> rampPolygons;
664 for (
const MSVehicle* train : allStoppedTrains) {
665 if (train->getLeavingPersonNumber() > 0) {
669 const std::vector<MSTrainHelper::Carriage*>& carriages = trainHelper.
getCarriages();
671 Position dir = carriage->front - carriage->back;
680 carriageShape.push_back(carriage->front + perp * p);
681 carriageShape.push_back(carriage->back + perp * p);
682 carriageShape.push_back(carriage->back - perp * p);
683 carriageShape.push_back(carriage->front - perp * p);
688 for (
const Position& door : carriage->doorPositions) {
690 rampShape.push_back(door - perp * p + dir * d);
691 rampShape.push_back(door - perp * p - dir * d);
692 rampShape.push_back(door + perp * p - dir * d);
693 rampShape.push_back(door + perp * p + dir * d);
699 if (!carriagePolygons.empty()) {
700 GEOSGeometry* carriagesCollection = GEOSGeom_createCollection(GEOS_MULTIPOLYGON, carriagePolygons.data(), (
unsigned int)carriagePolygons.size());
701 GEOSGeometry* rampsCollection = GEOSGeom_createCollection(GEOS_MULTIPOLYGON, rampPolygons.data(), (
unsigned int)rampPolygons.size());
702 GEOSGeometry* carriagesAndRampsUnion = GEOSUnion(carriagesCollection, rampsCollection);
703 if (carriagesAndRampsUnion ==
nullptr) {
707#ifdef DEBUG_GEOMETRY_GENERATION
710 int nbrComponents = 0;
711 double maxArea = 0.0;
712 double totalArea = 0.0;
713 const GEOSGeometry* pedestrianNetworkWithTrainsAndRampsLargestComponent =
getLargestComponent(pedestrianNetworkWithTrainsAndRamps, nbrComponents, maxArea, totalArea);
714 if (nbrComponents > 1) {
715 WRITE_WARNINGF(
TL(
"While generating geometry % connected components were detected, %% of total pedestrian area is covered by the largest."),
716 nbrComponents, maxArea / totalArea * 100.0,
"%");
718#ifdef DEBUG_GEOMETRY_GENERATION
724 WRITE_WARNINGF(
TL(
"While switching to train geometry: %"), JPS_ErrorMessage_GetMessage(message));
728 GEOSGeom_destroy(pedestrianNetworkWithTrainsAndRamps);
730 GEOSGeom_destroy(rampsCollection);
731 GEOSGeom_destroy(carriagesCollection);
737 WRITE_WARNINGF(
TL(
"While switching to default geometry: %"), JPS_ErrorMessage_GetMessage(message));
746 JPS_ErrorMessage_Free(message);
767 GEOSGeometry* lineString = GEOSGeom_createLineString(coordinateSequence);
769 GEOSGeom_destroy(lineString);
770 return dilatedLineString;
777 if (shape.size() == 1) {
778 WRITE_WARNINGF(
TL(
"Polygon '%' at junction '%' will be skipped as it is just a point."), shapeID, junctionID);
782 if (shape.back() != shape.front()) {
783 shape.push_back(shape.front());
787 cleanShape.push_back(shape[0]);
789 for (
int i = 1; i < (int)shape.size(); i++) {
790 if (shape[i] != shape[i - 1]) {
791 cleanShape.push_back(shape[i]);
793 duplicates.push_back(shape[i]);
796 if (cleanShape.size() < shape.size()) {
797 WRITE_WARNINGF(
TL(
"Polygon '%' at junction '%' had some equal consecutive points removed: %"), shapeID, junctionID,
toString(duplicates, 9));
800 GEOSGeometry* linearRing = GEOSGeom_createLinearRing(coordinateSequence);
801 GEOSGeometry* polygon = GEOSGeom_createPolygon(linearRing,
nullptr, 0);
803 if (!GEOSisValid(polygon)) {
804 if (cleanShape.size() == 3) {
805 if (isInternalShape) {
806 WRITE_WARNINGF(
TL(
"Polygon '%' at junction '%' has been dilated as it is just a segment."), shapeID, junctionID);
808 WRITE_WARNINGF(
TL(
"Polygon '%' has been dilated as it is just a segment."), shapeID);
810 GEOSGeometry* lineString = GEOSGeom_createLineString(GEOSCoordSeq_clone(coordinateSequence));
811 GEOSGeom_destroy(polygon);
813 GEOSGeom_destroy(lineString);
815 if (isInternalShape) {
816 WRITE_WARNINGF(
TL(
"Polygon '%' at junction '%' has been replaced by its convex hull as it is not simple."), shapeID, junctionID);
817 GEOSGeometry* hull = GEOSConvexHull(polygon);
818 GEOSGeom_destroy(polygon);
821 WRITE_WARNINGF(
TL(
"Polygon '%' at junction '%' will be skipped as it is not simple."), shapeID, junctionID);
830 if (isInternalShape) {
840 std::vector<GEOSGeometry*> walkableAreas;
842 const MSLane*
const lane = getSidewalk<MSEdge, MSLane>(edge);
843 if (lane !=
nullptr) {
844 GEOSGeometry* dilatedLane =
nullptr;
845 if (edge->isWalkingArea()) {
847 }
else if (edge->isCrossing()) {
849 if (outlineShape !=
nullptr) {
852 if (dilatedLane !=
nullptr) {
853 walkableAreas.push_back(dilatedLane);
863 if (dilatedLane !=
nullptr) {
864 walkableAreas.push_back(dilatedLane);
869 const MSJunction*
const junction = junctionWithID.second;
870 int pedEdgeCount = 0;
871 bool hasWalkingArea =
false;
875 for (
const MSEdge*
const edge : edges) {
876 if (edge->isWalkingArea()) {
877 hasWalkingArea =
true;
880 if (getSidewalk<MSEdge, MSLane>(edge) !=
nullptr) {
884 if (hasWalkingArea) {
888 if (!hasWalkingArea && pedEdgeCount > 1) {
891 if (walkingAreaGeom !=
nullptr) {
892 walkableAreas.push_back(walkingAreaGeom);
898 std::vector<GEOSGeometry*> additionalObstacles;
900 if (polygonWithID.second->getShapeType() ==
"jupedsim.walkable_area" || polygonWithID.second->getShapeType() ==
"taz") {
901 GEOSGeometry* walkableArea =
createGeometryFromShape(polygonWithID.second->getShape(), std::string(
""), polygonWithID.first);
902 if (walkableArea !=
nullptr) {
903 walkableAreas.push_back(walkableArea);
906 }
else if (polygonWithID.second->getShapeType() ==
"jupedsim.obstacle") {
907 GEOSGeometry* additionalObstacle =
createGeometryFromShape(polygonWithID.second->getShape(), std::string(
""), polygonWithID.first);
908 if (additionalObstacle !=
nullptr) {
909 additionalObstacles.push_back(additionalObstacle);
915 GEOSGeometry* disjointWalkableAreas = GEOSGeom_createCollection(GEOS_MULTIPOLYGON, walkableAreas.data(), (
unsigned int)walkableAreas.size());
916#ifdef DEBUG_GEOMETRY_GENERATION
919 GEOSGeometry* initialWalkableAreas = GEOSUnaryUnion(disjointWalkableAreas);
920#ifdef DEBUG_GEOMETRY_GENERATION
921 dumpGeometry(initialWalkableAreas,
"initialWalkableAreas.wkt");
923 GEOSGeom_destroy(disjointWalkableAreas);
926 GEOSGeometry* disjointAdditionalObstacles = GEOSGeom_createCollection(GEOS_MULTIPOLYGON, additionalObstacles.data(), (
unsigned int)additionalObstacles.size());
927#ifdef DEBUG_GEOMETRY_GENERATION
930 GEOSGeometry* additionalObstaclesUnion = GEOSUnaryUnion(disjointAdditionalObstacles);
931#ifdef DEBUG_GEOMETRY_GENERATION
932 dumpGeometry(additionalObstaclesUnion,
"additionalObstaclesUnion.wkt");
934 GEOSGeometry* finalWalkableAreas = GEOSDifference(initialWalkableAreas, additionalObstaclesUnion);
935#ifdef DEBUG_GEOMETRY_GENERATION
936 dumpGeometry(finalWalkableAreas,
"finalWalkableAreas.wkt");
938 GEOSGeom_destroy(initialWalkableAreas);
939 GEOSGeom_destroy(additionalObstaclesUnion);
940 GEOSGeom_destroy(disjointAdditionalObstacles);
942 if (!GEOSisSimple(finalWalkableAreas)) {
943 throw ProcessError(
TL(
"Union of walkable areas minus union of obstacles is not a simple polygon."));
946 return finalWalkableAreas;
952 GEOSCoordSequence* coordinateSequence = GEOSCoordSeq_create((
unsigned int)shape.size(), 2);
953 for (
int i = 0; i < (int)shape.size(); i++) {
954 GEOSCoordSeq_setX(coordinateSequence, i, shape[i].x());
955 GEOSCoordSeq_setY(coordinateSequence, i, shape[i].y());
957 return coordinateSequence;
964 const GEOSCoordSequence* coordinateSequence = GEOSGeom_getCoordSeq(geometry);
965 unsigned int coordinateSequenceSize;
966 GEOSCoordSeq_getSize(coordinateSequence, &coordinateSequenceSize);
969 for (
unsigned int i = 0; i < coordinateSequenceSize; i++) {
970 GEOSCoordSeq_getX(coordinateSequence, i, &x);
971 GEOSCoordSeq_getY(coordinateSequence, i, &y);
972 coordinateVector.push_back(
Position(x, y));
974 return coordinateVector;
978std::vector<JPS_Point>
980 std::vector<JPS_Point> pointVector;
981 const GEOSCoordSequence* coordinateSequence = GEOSGeom_getCoordSeq(geometry);
982 unsigned int coordinateSequenceSize;
983 GEOSCoordSeq_getSize(coordinateSequence, &coordinateSequenceSize);
987 for (
unsigned int i = 0; i < coordinateSequenceSize - 1; i++) {
988 GEOSCoordSeq_getX(coordinateSequence, i, &x);
989 GEOSCoordSeq_getY(coordinateSequence, i, &y);
990 pointVector.push_back({x, y});
999 GEOSGeometry* linearRingAsPolygon = GEOSGeom_createPolygon(GEOSGeom_clone(linearRing),
nullptr, 0);
1000 GEOSArea(linearRingAsPolygon, &area);
1001 GEOSGeom_destroy(linearRingAsPolygon);
1014 const GEOSGeometry* exterior = GEOSGetExteriorRing(polygon);
1018 std::vector<PositionVector> holes;
1019 int nbrInteriorRings = GEOSGetNumInteriorRings(polygon);
1020 if (nbrInteriorRings != -1) {
1021 for (
int k = 0; k < nbrInteriorRings; k++) {
1022 const GEOSGeometry* linearRing = GEOSGetInteriorRingN(polygon, k);
1036 nbrComponents = GEOSGetNumGeometries(polygon);
1037 const GEOSGeometry* largestComponent =
nullptr;
1040 for (
int i = 0; i < nbrComponents; i++) {
1041 const GEOSGeometry* componentPolygon = GEOSGetGeometryN(polygon, i);
1043 GEOSArea(componentPolygon, &area);
1045 if (area > maxArea) {
1047 largestComponent = componentPolygon;
1050 return largestComponent;
1056 JPS_GeometryBuilder geometryBuilder = JPS_GeometryBuilder_Create();
1059 const GEOSGeometry* exterior = GEOSGetExteriorRing(polygon);
1061 JPS_GeometryBuilder_AddAccessibleArea(geometryBuilder, exteriorCoordinates.data(), exteriorCoordinates.size());
1064 int nbrInteriorRings = GEOSGetNumInteriorRings(polygon);
1065 if (nbrInteriorRings != -1) {
1066 for (
int k = 0; k < nbrInteriorRings; k++) {
1067 const GEOSGeometry* linearRing = GEOSGetInteriorRingN(polygon, k);
1071 JPS_GeometryBuilder_ExcludeFromAccessibleArea(geometryBuilder, holeCoordinates.data(), holeCoordinates.size());
1076 JPS_ErrorMessage message =
nullptr;
1077 JPS_Geometry geometry = JPS_GeometryBuilder_Build(geometryBuilder, &message);
1078 if (geometry ==
nullptr) {
1079 const std::string error =
TLF(
"Error while generating geometry: %", JPS_ErrorMessage_GetMessage(message));
1080 JPS_ErrorMessage_Free(message);
1083 JPS_GeometryBuilder_Free(geometryBuilder);
1090 GEOSGeometry* polygonGeoCoordinates =
nullptr;
1091 if (useGeoCoordinates) {
1092 const GEOSGeometry* exterior = GEOSGetExteriorRing(polygon);
1094 for (
Position& position : exteriorPoints) {
1097 const int nbrInteriorRings = GEOSGetNumInteriorRings(polygon);
1098 std::vector<GEOSGeometry*> holeRings;
1099 if (nbrInteriorRings != -1) {
1100 for (
int k = 0; k < nbrInteriorRings; k++) {
1101 const GEOSGeometry* linearRing = GEOSGetInteriorRingN(polygon, k);
1103 for (
Position& position : holePoints) {
1107 GEOSGeometry* holeRing = GEOSGeom_createLinearRing(holeRingCoords);
1108 holeRings.push_back(holeRing);
1112 GEOSGeometry* exteriorRing = GEOSGeom_createLinearRing(exteriorRingCoords);
1113 polygonGeoCoordinates = GEOSGeom_createPolygon(exteriorRing, holeRings.data(), nbrInteriorRings);
1115 std::ofstream dumpFile;
1116 dumpFile.open(filename);
1117 GEOSWKTWriter* writer = GEOSWKTWriter_create();
1119 char* wkt = GEOSWKTWriter_write(writer, polygonGeoCoordinates ==
nullptr ? polygon : polygonGeoCoordinates);
1120 dumpFile << wkt << std::endl;
1123 GEOSWKTWriter_destroy(writer);
1124 GEOSGeom_destroy(polygonGeoCoordinates);
1136 JPS_ErrorMessage message =
nullptr;
1137 JPS_StageId waitingStage = 0;
1141 const double offset = 2 * radius + POSITION_EPS;
1142 const double lonOffset = entry ? NUMERICAL_EPS : shape.
length() - NUMERICAL_EPS;
1145 for (
double latOff = offset; latOff < crossing->
getWidth() / 2. - offset; latOff += offset) {
1153 pv.push_back(crossing->
getIncomingLanes().front().lane->getShape().getCentroid());
1155 if (!entry && crossing->
getLinkCont().size() == 1 && crossing->
getLinkCont().front()->getLane()->isWalkingArea()) {
1156 pv.push_back(crossing->
getLinkCont().front()->getLane()->getShape().getCentroid());
1158 std::vector<JPS_Point> points;
1160 GEOSCoordSequence* seq = GEOSCoordSeq_create(1, 2);
1161 GEOSCoordSeq_setX(seq, 0, p.x());
1162 GEOSCoordSeq_setY(seq, 0, p.y());
1163 GEOSGeometry* point = GEOSGeom_createPoint(seq);
1165 points.push_back({p.x(), p.y()});
1167 WRITE_WARNINGF(
"Waiting point %,% is not in the geometry for % on '%'.", p.x(), p.y(), entry ?
"entry" :
"exit", crossing->
getID())
1169 GEOSGeom_destroy(point);
1171 waitingStage = JPS_Simulation_AddStageWaitingSet(
myJPSSimulation, points.data(), points.size(), &message);
1172 if (message !=
nullptr) {
1173 const std::string error =
TLF(
"Error while adding waiting set for % on '%': %",
1174 entry ?
"entry" :
"exit", crossing->
getID(), JPS_ErrorMessage_GetMessage(message));
1175 JPS_ErrorMessage_Free(message);
1178 const auto proxy = JPS_Simulation_GetWaitingSetProxy(
myJPSSimulation, waitingStage, &message);
1179 JPS_WaitingSetProxy_SetWaitingSetState(proxy, JPS_WaitingSet_Inactive);
1182 (*myPythonScript) <<
"ws = simulation.add_waiting_set_stage([";
1183 for (
const JPS_Point& p : points) {
1184 (*myPythonScript) <<
"(" << p.x <<
"," << p.y <<
"),";
1186 (*myPythonScript) <<
"])\nsimulation.get_stage(ws).state = jps.stages.WaitingSetState.INACTIVE\n";
1188 return waitingStage;
1194 initGEOS(
nullptr,
nullptr);
1197 int nbrComponents = 0;
1198 double maxArea = 0.0;
1199 double totalArea = 0.0;
1201 if (nbrComponents > 1) {
1202 WRITE_WARNINGF(
TL(
"While generating geometry % connected components were detected, %% of total pedestrian area is covered by the largest."),
1203 nbrComponents, maxArea / totalArea * 100.0,
"%");
1205#ifdef DEBUG_GEOMETRY_GENERATION
1208 const std::string filename = oc.
getString(
"pedestrian.jupedsim.wkt");
1209 if (!filename.empty()) {
1217 JPS_ErrorMessage message =
nullptr;
1219 double strengthGeometryRepulsion = oc.
getFloat(
"pedestrian.jupedsim.strength-geometry-repulsion");
1220 double rangeGeometryRepulsion = oc.
getFloat(
"pedestrian.jupedsim.range-geometry-repulsion");
1222 if (oc.
isDefault(
"pedestrian.jupedsim.strength-geometry-repulsion") && oc.
isDefault(
"pedestrian.jupedsim.range-geometry-repulsion")) {
1223 WRITE_MESSAGE(
TL(
"Adapting geometry repulsion default values for jupedsim timestep of 0.02."));
1224 strengthGeometryRepulsion = 35.;
1225 rangeGeometryRepulsion = 0.019;
1231 JPS_CollisionFreeSpeedModelBuilder modelBuilder = JPS_CollisionFreeSpeedModelBuilder_Create(
1232 oc.
getFloat(
"pedestrian.jupedsim.strength-neighbor-repulsion"),
1233 oc.
getFloat(
"pedestrian.jupedsim.range-neighbor-repulsion"),
1234 strengthGeometryRepulsion,
1235 rangeGeometryRepulsion);
1237 JPS_CollisionFreeSpeedModelBuilder_Free(modelBuilder);
1241 JPS_CollisionFreeSpeedModelV2Builder modelBuilder = JPS_CollisionFreeSpeedModelV2Builder_Create();
1243 JPS_CollisionFreeSpeedModelV2Builder_Free(modelBuilder);
1247 JPS_GeneralizedCentrifugalForceModelBuilder modelBuilder = JPS_GeneralizedCentrifugalForceModelBuilder_Create(
1248 oc.
getFloat(
"pedestrian.jupedsim.strength-neighbor-repulsion"),
1249 strengthGeometryRepulsion,
1257 JPS_GeneralizedCentrifugalForceModelBuilder_Free(modelBuilder);
1261 JPS_SocialForceModelBuilder modelBuilder = JPS_SocialForceModelBuilder_Create(120000.0, 240000.0);
1263 JPS_SocialForceModelBuilder_Free(modelBuilder);
1269 const std::string error =
TLF(
"Error creating the pedestrian model: %", JPS_ErrorMessage_GetMessage(message));
1270 JPS_ErrorMessage_Free(message);
1275 const std::string error =
TLF(
"Error creating the simulation: %", JPS_ErrorMessage_GetMessage(message));
1276 JPS_ErrorMessage_Free(message);
1286 (*myPythonScript) <<
"import jupedsim as jps\nimport shapely\n\n"
1287 "with open('" << filename <<
"') as f: geom = shapely.from_wkt(f.read())\n"
1288 "simulation = jps.Simulation(dt=" <<
STEPS2TIME(
myJPSDeltaT) <<
", model=jps.CollisionFreeSpeedModel(), geometry=geom,\n"
1289 "trajectory_writer=jps.SqliteTrajectoryWriter(output_file='out.sql'))\n";
1300 for (
auto areaIt =
myAreas.begin(); areaIt !=
myAreas.end(); ++areaIt) {
1301 if (poly->
getID() == (*areaIt)->id) {
1302 lastRemovalTime = (*areaIt)->lastRemovalTime;
1309 std::vector<JPS_Point> areaBoundary;
1311 areaBoundary.push_back({p.x(), p.y()});
1314 if (areaBoundary.back().x == areaBoundary.front().x && areaBoundary.back().y == areaBoundary.front().y) {
1315 areaBoundary.pop_back();
1328 JPS_JourneyId journeyId, JPS_StageId stageId,
1329 const std::vector<WaypointDesc>& waypoints) :
1331 myJourneyId(journeyId), myStageId(stageId), myWaypoints(waypoints), myAgentId(0) {
1338 const std::vector<WaypointDesc>& waypoints) {
1339 if (myStage !=
nullptr) {
1340 myStage->setPState(
nullptr);
1343 myJourneyId = journeyId;
1344 myStageId = stageId;
1345 myWaypoints = waypoints;
1359 myRemoteXYPos.set(x, y, z);
1370 return offset < (int)myWaypoints.size() ? &myWaypoints[offset] :
nullptr;
std::vector< const MSEdge * > ConstMSEdgeVector
#define WRITE_WARNINGF(...)
#define WRITE_MESSAGEF(...)
#define WRITE_ERRORF(...)
#define WRITE_MESSAGE(msg)
#define WRITE_WARNING(msg)
#define PROGRESS_DONE_MESSAGE()
#define PROGRESS_BEGIN_MESSAGE(msg)
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
std::string time2string(SUMOTime t, bool humanReadable)
convert SUMOTime to string (independently of global format setting)
const std::string DEFAULT_PEDTYPE_ID
@ RANDOM_LOCATION
The position may be chosen freely in a polygon defined by a taz.
@ SUMO_TAG_BUS_STOP
A bus stop.
const double SUMO_const_laneWidth
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
A class that stores a 2D geometrical boundary.
double ymin() const
Returns minimum y-coordinate.
double xmin() const
Returns minimum x-coordinate.
double ymax() const
Returns maximum y-coordinate.
double xmax() const
Returns maximum x-coordinate.
static const GeoConvHelper & getFinal()
the coordinate transformation for writing the location element and for tracking the original coordina...
void cartesian2geo(Position &cartesian) const
Converts the given cartesian (shifted) position to its geo (lat/long) representation.
const MSEdgeVector & getEdges() const
Returns loaded edges.
A road/street connecting two junctions.
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
bool isNormal() const
return whether this edge is an internal edge
const MSJunction * getToJunction() const
const MSJunction * getFromJunction() const
bool isTazConnector() const
double getWidth() const
Returns the edges's width (sum over all lanes)
virtual void addEvent(Command *operation, SUMOTime execTimeStep=-1)
Adds an Event.
The base class for an intersection.
const ConstMSEdgeVector & getOutgoing() const
const PositionVector & getShape() const
Returns this junction's shape.
const ConstMSEdgeVector & getIncoming() const
Representation of a lane in the micro simulation.
const MSLink * getLinkTo(const MSLane *const) const
returns the link to the given lane or nullptr, if it is not connected
double getSpeedLimit() const
Returns the lane's maximum allowed speed.
const std::vector< IncomingLaneInfo > & getIncomingLanes() const
MSLane * getLogicalPredecessorLane() const
get the most likely predecessor lane (sorted using by_connections_to_sorter). The result is cached in...
virtual const PositionVector & getShape(bool) const
MSEdge & getEdge() const
Returns the lane's edge.
const PositionVector * getOutlineShape() const
double getWidth() const
Returns the lane's width.
const std::vector< MSLink * > & getLinkCont() const
returns the container with all links !!!
bool opened(SUMOTime arrivalTime, double arrivalSpeed, double leaveSpeed, double vehicleLength, double impatience, double decel, SUMOTime waitingTime, double posLat=0, BlockingFoes *collectFoes=nullptr, bool ignoreRed=false, const SUMOTrafficObject *ego=nullptr, double dist=-1) const
Returns the information whether the link may be passed.
const MSTrafficLightLogic * getTLLogic() const
Returns the TLS index.
The simulated network and simulation perfomer.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
MSEventControl * getBeginOfTimestepEvents()
Returns the event control for events executed at the begin of a time step.
MSJunctionControl & getJunctionControl()
Returns the junctions control.
MSPedestrianRouter & getPedestrianRouter(int rngIndex, const Prohibitions &prohibited={}) const
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
ShapeContainer & getShapeContainer()
Returns the shapes container.
MSEdgeControl & getEdgeControl()
Returns the edge control.
const NamedObjectCont< MSStoppingPlace * > & getStoppingPlaces(SumoXMLTag category) const
ActiveLanes myActiveLanes
store of all lanes which have pedestrians on them
int myNumActivePedestrians
the total number of active pedestrians
Container for pedestrian state and individual position update function.
MSStageMoving * getStage() const
return the current stage
int myDir
the walking direction on the current lane (1 forward, -1 backward)
virtual double getAngle(const MSStageMoving &, SUMOTime) const
return the current orientation in degrees
double getEdgePos(SUMOTime) const
abstract methods inherited from MSTransportableStateAdapter
MSPerson * getPerson() const
return the represented person
bool isWaitingToEnter() const
whether the person still waits to entere the network
const MSLane * getLane() const
the current lane of the transportable
double getSpeed() const
return the current speed of the transportable, we need to be able to do this for vehicles as well,...
Holds pedestrian state and performs updates.
JPS_AgentId getAgentId() const
JPS_JourneyId getJourneyId() const
void setAngle(double angle)
void reinit(MSStageMoving *stage, JPS_JourneyId journeyId, JPS_StageId stageId, const std::vector< WaypointDesc > &waypoints)
const MSPModel_JuPedSim_legacy::WaypointDesc * getNextWaypoint(const int offset=0) const
const MSEdge * getNextEdge(const MSStageMoving &stage) const override
return the list of internal edges if the transportable is on an intersection
void setStage(MSStageMoving *const stage)
void setAgentId(JPS_AgentId id)
void setPosition(const double x, const double y, const double z=0.)
JPS_StageId getStageId() const
first stage of the journey
bool advanceNextWaypoint()
void setLanePosition(double lanePosition)
Position getPosition(const MSStageMoving &, SUMOTime) const override
return the network coordinate of the transportable
PState(MSPerson *person, MSStageMoving *stage, JPS_JourneyId journeyId, JPS_StageId stageId, const std::vector< WaypointDesc > &waypoints)
void setLane(MSLane *lane)
void polygonChanged(const SUMOPolygon *const poly, const bool added, const bool removed) override
SUMOTime execute(SUMOTime time)
JPS_Geometry myJPSGeometryWithTrainsAndRamps
The JPS polygon representing the largest connected component plus carriages and ramps.
JPS_Geometry myJPSGeometry
The JPS polygon representing the largest connected component of the pedestrian network.
static const RGBColor PEDESTRIAN_NETWORK_CARRIAGES_AND_RAMPS_COLOR
static const double GEOS_MITRE_LIMIT
void initialize(const OptionsCont &oc)
void clearState() override
Resets pedestrians when quick-loading state.
static JPS_Geometry buildJPSGeometryFromGEOSGeometry(const GEOSGeometry *polygon)
static GEOSCoordSequence * convertToGEOSPoints(PositionVector shape)
static PositionVector convertToSUMOPoints(const GEOSGeometry *geometry)
static double getRadius(const MSVehicleType &vehType)
static const double GEOS_BUFFERED_SEGMENT_WIDTH
GEOSGeometry * buildPedestrianNetwork(MSNet *network)
static const int GEOS_QUADRANT_SEGMENTS
void registerArrived(const JPS_AgentId agentID)
static void dumpGeometry(const GEOSGeometry *polygon, const std::string &filename, bool useGeoCoordinates=false)
void preparePolygonForDrawing(const GEOSGeometry *polygon, const std::string &polygonId, const RGBColor &color)
std::map< const MSLane *, std::pair< JPS_StageId, JPS_StageId >, ComparatorNumericalIdLess > myCrossingWaits
const SUMOTime myJPSDeltaT
Timestep used in the JuPedSim simulator.
bool addWaypoint(JPS_JourneyDescription journey, JPS_StageId &predecessor, const std::string &agentID, const WaypointDesc &waypoint)
GEOSGeometry * myGEOSPedestrianNetwork
The GEOS polygon containing all computed connected components of the pedestrian network.
JPS_StageId addWaitingSet(const MSLane *const crossing, const bool entry)
MSNet *const myNetwork
The network on which the simulation runs.
void removePolygonFromDrawing(const std::string &polygonId)
~MSPModel_JuPedSim_legacy()
JPS_OperationalModel myJPSOperationalModel
static const GEOSGeometry * getLargestComponent(const GEOSGeometry *polygon, int &nbrComponents, double &maxArea, double &totalArea)
JPS_Simulation myJPSSimulation
static const std::vector< MSPModel_JuPedSim_legacy::PState * > noPedestrians
void tryPedestrianInsertion(PState *state, const Position &p)
static GEOSGeometry * createGeometryFromCenterLine(PositionVector centerLine, double width, int capStyle)
MSTransportableStateAdapter * add(MSTransportable *person, MSStageMoving *stage, SUMOTime now) override
register the given person as a pedestrian
MSPModel_JuPedSim_legacy(const OptionsCont &oc, MSNet *net)
static std::vector< JPS_Point > convertToJPSPoints(const GEOSGeometry *geometry)
ShapeContainer & myShapeContainer
The shape container used to add polygons to the rendering pipeline.
OutputDevice * myPythonScript
@ GeneralizedCentrifugalForce
std::vector< std::unique_ptr< AreaData > > myAreas
Array of special areas.
void remove(MSTransportableStateAdapter *state) override
remove the specified person from the pedestrian simulation
bool addStage(JPS_JourneyDescription journey, JPS_StageId &predecessor, const std::string &agentID, const JPS_StageId stage)
static double getLinearRingArea(const GEOSGeometry *linearRing)
std::vector< SUMOTrafficObject::NumericalID > myAllStoppedTrainIDs
Array of stopped trains, used to detect whether to add carriages and ramps to the geometry.
static const std::string PEDESTRIAN_NETWORK_CARRIAGES_AND_RAMPS_ID
static GEOSGeometry * createGeometryFromShape(PositionVector shape, std::string junctionID=std::string(""), std::string shapeID=std::string(""), bool isInternalShape=false)
std::vector< PState * > myPedestrianStates
SumoRNG myRNG
The random number generator for fluctuations on insertion.
static const std::string PEDESTRIAN_NETWORK_ID
const double myExitTolerance
Threshold to decide if a pedestrian has ended its journey or not.
std::map< JPS_StageId, const MSLane * > myCrossings
const GEOSGeometry * myGEOSPedestrianNetworkLargestComponent
The GEOS polygon representing the largest (by area) connected component of the pedestrian network.
static const RGBColor PEDESTRIAN_NETWORK_COLOR
std::tuple< JPS_StageId, Position, double > WaypointDesc
static const double GEOS_MIN_AREA
bool myHaveAdditionalWalkableAreas
static const int BACKWARD
static const double RANDOM_POS_LAT
magic value to encode randomized lateral offset for persons when starting a walk
static const int UNDEFINED_DIRECTION
static const double UNSPECIFIED_POS_LAT
the default lateral offset for persons when starting a walk
double getImpatience() const
const MSEdge * getDestination() const
returns the destination edge
virtual double getArrivalPos() const
virtual const MSEdge * getEdge() const
Returns the current edge.
virtual const MSEdge * getNextRouteEdge() const =0
ConstMSEdgeVector getEdges() const
the edges of the current stage
const std::vector< const MSEdge * > & getRoute() const
void setPState(MSTransportableStateAdapter *pstate)
double getDepartPosLat() const
const MSEdge * getEdge() const
Returns the current edge.
double getDepartPos() const
const std::vector< constMSEdge * >::iterator getRouteStep() const
virtual bool moveToNextEdge(MSTransportable *transportable, SUMOTime currentTime, int prevDir, MSEdge *nextInternal=nullptr, const bool isReplay=false)=0
move forward and return whether the transportable arrived
virtual double getMaxSpeed(const MSTransportable *const transportable=nullptr) const =0
the maximum speed of the transportable
bool moveToNextEdge(MSTransportable *person, SUMOTime currentTime, int prevDir, MSEdge *nextInternal=nullptr, const bool isReplay=false)
move forward and return whether the person arrived
void activateMoveReminders(MSTransportable *person, double oldPos, double newPos, double newSpeed)
void activateEntryReminders(MSTransportable *person, const bool isDepart=false)
add the move reminders for the current lane on entry
A class that helps computing positions of a train's carriages and additional structures.
void computeDoorPositions()
compute door positions on demand and fills the carriage structures
const std::vector< Carriage * > & getCarriages() const
double getHalfWidth() const
virtual double getSpeed() const override
the current speed of the transportable
MSStage * getNextStage(int offset) const
Return the next (or previous) stage denoted by the offset.
int getNumRemainingStages() const
Return the number of remaining stages (including the current)
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)
const SUMOVTypeParameter & getVTypeParameter() const override
Returns the object's "vehicle" type parameter.
int getCurrentStageIndex() const
Return the index of the current stage.
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.
const MSEdge * getEdge() const override
Returns the current edge.
abstract base class for managing callbacks to retrieve various state information from the model
Representation of a vehicle in the micro simulation.
The car-following model and parameter.
double getWidth() const
Get the width which vehicles of this class shall have when being drawn.
double getLength() const
Get vehicle's length [m].
const std::string & getID() const
Returns the id.
T get(const std::string &id) const
Retrieves an item.
A storage for options typed value containers)
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
bool isDefault(const std::string &name) const
Returns the information whether the named option has still the default value.
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
static OptionsCont & getOptions()
Retrieves the options.
static OutputDevice & getDeviceByOption(const std::string &name)
Returns the device described by the option.
void setPrecision(int precision=gPrecision)
Sets the precision or resets it to default.
static bool createDeviceByOption(const std::string &optionName, const std::string &rootElement="", const std::string &schemaFile="", const int maximumDepth=2)
Creates the device using the output definition stored in the named option.
double getDouble(const std::string &key, const double defaultValue) const
Returns the value for a given key converted to a double.
virtual const std::string getParameter(const std::string &key, const std::string defaultValue="") const
Returns the value for a given key.
const Parameterised::Map & getParametersMap() const
Returns the inner key/value map.
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...
A point in 2D or 3D with translation and scaling methods.
void setx(double x)
set position x
static const Position INVALID
used to indicate that a position is valid
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
void norm2D()
Normalizes the given vector.
double x() const
Returns the x-position.
double length2D() const
Computes the length of the given vector neglecting the z coordinate.
void sety(double y)
set position y
double y() const
Returns the y-position.
double length() const
Returns the length.
double rotationAtOffset(double pos) const
Returns the rotation at the given length.
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
void move2side(double amount, double maxExtension=100)
move position vector to side using certain amount
Boundary getBoxBoundary() const
Returns a boundary enclosing this list of lines.
void extrapolate2D(const double val, const bool onlyFirst=false)
extrapolate position vector in two dimensions (Z is ignored)
bool around(const Position &p, double offset=0) const
Returns the information whether the position vector describes a polygon lying around the given point.
static double rand(SumoRNG *rng=nullptr)
Returns a random real number in [0, 1)
static void initRandGlobal(SumoRNG *which=nullptr)
Reads the given random number options and initialises the random number generator in accordance.
const PositionVector & getShape() const
Returns the shape of the polygon.
virtual void setHoles(const std::vector< PositionVector > &holes)
Sets the holes of the polygon.
double getFloatParam(const std::string ¶mName, const bool required=false, const double deflt=INVALID_DOUBLE, bool checkDist=true) const
Retrieve a floating point parameter for the traffic object.
Structure representing possible vehicle parameter.
double maxPlatformDistance
the maximum distance between platform and train
double carriageDoorWidth
the width of the carriage doors
Representation of a vehicle.
DepartPosDefinition departPosProcedure
Information how the vehicle shall choose the departure position.
void addShapeListener(ShapeListener *listener)
virtual bool removePolygon(const std::string &id, bool useLock=true)
Removes a polygon from the container.
const Polygons & getPolygons() const
Returns all polygons.
virtual bool addPolygon(const std::string &id, const std::string &type, const RGBColor &color, double layer, double angle, const std::string &imgFile, const PositionVector &shape, bool geo, bool fill, double lineWidth, bool ignorePruning=false, const std::string &name=Shape::DEFAULT_NAME)
Builds a polygon using the given values and adds it to the container.
const std::string & getShapeType() const
Returns the (abstract) type of the Shape.
std::vector< std::string > getVector()
return vector of strings
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter
static bool moveToXYMap_matchingRoutePosition(const Position &pos, const std::string &origID, const ConstMSEdgeVector ¤tRoute, int routeIndex, SUMOVehicleClass vClass, bool setLateralPos, double &bestDistance, MSLane **lane, double &lanePos, int &routeOffset)
#define UNUSED_PARAMETER(x)
Structure that keeps data related to vanishing areas (and other types of areas).