30#include <jupedsim/jupedsim.h>
68 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) {
71 std::string model = oc.
getString(
"pedestrian.jupedsim.model");
72 if (model ==
"CollisionFreeSpeed") {
74 }
else if (model ==
"CollisionFreeSpeedV2") {
76 }
else if (model ==
"GeneralizedCentrifugalForce") {
78 }
else if (model ==
"SocialForce") {
89 (*myPythonScript) <<
"while simulation.agent_count() > 0 and simulation.iteration_count() < 160 * 100: simulation.iterate()\n";
109 JPS_Point orientation;
110 if (fabs(angle -
M_PI / 2) < NUMERICAL_EPS) {
111 orientation = JPS_Point{0., 1.};
112 }
else if (fabs(angle +
M_PI / 2) < NUMERICAL_EPS) {
113 orientation = JPS_Point{0., -1.};
115 orientation = JPS_Point{1., tan(angle)};
118 JPS_AgentId agentId = 0;
119 JPS_ErrorMessage message =
nullptr;
123 JPS_CollisionFreeSpeedModelAgentParameters agentParameters{};
124 agentParameters.position = {p.
x(), p.
y()};
126 agentParameters.stageId = state->
getStageId();
128 agentParameters.radius =
getRadius(type);
129 agentId = JPS_Simulation_AddCollisionFreeSpeedModelAgent(
myJPSSimulation, agentParameters, &message);
133 JPS_CollisionFreeSpeedModelV2AgentParameters agentParameters{};
134 agentParameters.position = {p.
x(), p.
y()};
136 agentParameters.stageId = state->
getStageId();
138 agentParameters.radius =
getRadius(type);
139 agentId = JPS_Simulation_AddCollisionFreeSpeedModelV2Agent(
myJPSSimulation, agentParameters, &message);
143 JPS_GeneralizedCentrifugalForceModelAgentParameters agentParameters{};
144 agentParameters.position = {p.
x(), p.
y()};
145 agentParameters.orientation = orientation;
147 agentParameters.stageId = state->
getStageId();
149 agentId = JPS_Simulation_AddGeneralizedCentrifugalForceModelAgent(
myJPSSimulation, agentParameters, &message);
153 JPS_SocialForceModelAgentParameters agentParameters{};
154 agentParameters.position = {p.
x(), p.
y()};
155 agentParameters.orientation = orientation;
157 agentParameters.stageId = state->
getStageId();
159 agentParameters.radius =
getRadius(type);
160 agentId = JPS_Simulation_AddSocialForceModelAgent(
myJPSSimulation, agentParameters, &message);
164 if (message !=
nullptr) {
166 JPS_ErrorMessage_Free(message);
175 JPS_ErrorMessage message =
nullptr;
176 if (predecessor != 0) {
177 const JPS_Transition transition = JPS_Transition_CreateFixedTransition(stage, &message);
178 if (message !=
nullptr) {
179 WRITE_WARNINGF(
TL(
"Error while creating fixed transition for person '%': %"), agentID, JPS_ErrorMessage_GetMessage(message));
180 JPS_ErrorMessage_Free(message);
183 JPS_JourneyDescription_SetTransitionForStage(journey, predecessor, transition, &message);
184 if (message !=
nullptr) {
185 WRITE_WARNINGF(
TL(
"Error while setting transition for person '%': %"), agentID, JPS_ErrorMessage_GetMessage(message));
186 JPS_ErrorMessage_Free(message);
189 JPS_Transition_Free(transition);
191 JPS_JourneyDescription_AddStage(journey, stage);
199 JPS_ErrorMessage message =
nullptr;
200 const Position& coords = std::get<1>(waypoint);
201 const JPS_StageId waypointId = JPS_Simulation_AddStageWaypoint(
myJPSSimulation, {coords.
x(), coords.
y()},
202 std::get<2>(waypoint), &message);
203 if (message !=
nullptr) {
204 WRITE_WARNINGF(
TL(
"Error while adding waypoint for person '%': %"), agentID, JPS_ErrorMessage_GetMessage(message));
205 JPS_ErrorMessage_Free(message);
208 const JPS_StageId waiting = std::get<0>(waypoint);
211 (*myPythonScript) <<
"journey.add(" << waiting <<
")\n";
212 if (predecessor != 0) {
213 (*myPythonScript) <<
"journey.set_transition_for_stage(" << predecessor <<
", jps.Transition.create_fixed_transition(" << waiting <<
"))\n";
216 if (!
addStage(journey, predecessor, agentID, waiting)) {
221 (*myPythonScript) <<
"ws = simulation.add_waypoint_stage((" << coords.
x() <<
"," << coords.
y() <<
"), " << std::get<2>(waypoint) <<
")\n"
223 if (predecessor != 0) {
224 (*myPythonScript) <<
"journey.set_transition_for_stage(" << predecessor <<
", jps.Transition.create_fixed_transition(ws))\n";
227 if (!
addStage(journey, predecessor, agentID, waypointId)) {
239 const MSLane*
const departureLane = getSidewalk<MSEdge, MSLane>(stage->
getRoute().front());
240 if (departureLane ==
nullptr) {
241 const char* error =
TL(
"Person '%' could not find sidewalk on edge '%', time=%.");
254 if (tazShape ==
nullptr) {
267 const double halfDepartureLaneWidth = departureLane->
getWidth() / 2.0;
270 departureRelativePositionY = 0.0;
273 departureRelativePositionY =
RandHelper::rand(-halfDepartureLaneWidth, halfDepartureLaneWidth);
278 std::vector<WaypointDesc> waypoints;
279 const MSEdge* prev =
nullptr;
281 const MSLane*
const lane = getSidewalk<MSEdge, MSLane>(e);
282 JPS_StageId waitingStage = 0;
283 if (prev !=
nullptr) {
295 const MSEdge* wa =
nullptr;
296 for (
const MSEdge*
const ce : crossingRoute) {
297 if (ce->isCrossing()) {
298 const MSLane*
const crossing = getSidewalk<MSEdge, MSLane>(ce);
300 if (waitingStage != 0 && wa !=
nullptr) {
302 waypoints.push_back({waitingStage, wa->
getLanes()[0]->getShape().getCentroid(), wa->
getWidth() / 2.});
304 const MSLane*
const prevLane = getSidewalk<MSEdge, MSLane>(prev);
307 if (crossing->
getShape().front().distanceSquaredTo(startPos) < crossing->
getShape().back().distanceSquaredTo(startPos)) {
313 throw ProcessError(
TLF(
"No waiting set for crossing at %.", ce->getID()));
316 if (ce->isWalkingArea()) {
322 waypoints.push_back({waitingStage, lane->
getShape().positionAtOffset(e->getLength() / 2.), lane->
getWidth() / 2.});
325 const JPS_StageId finalWait = std::get<0>(waypoints.back());
326 waypoints.pop_back();
327 if (!waypoints.empty()) {
328 waypoints.erase(waypoints.begin());
334 JPS_JourneyDescription journeyDesc = JPS_JourneyDescription_Create();
336 (*myPythonScript) <<
"\njourney = jps.JourneyDescription()\n";
338 JPS_StageId startingStage = 0;
339 JPS_StageId predecessor = 0;
340 for (
const auto& p : waypoints) {
342 JPS_JourneyDescription_Free(journeyDesc);
345 if (startingStage == 0) {
346 startingStage = std::get<0>(waypoints.front()) == 0 ? predecessor : std::get<0>(waypoints.front());
349 JPS_ErrorMessage message =
nullptr;
350 JPS_JourneyId journeyId = JPS_Simulation_AddJourney(
myJPSSimulation, journeyDesc, &message);
351 JPS_JourneyDescription_Free(journeyDesc);
352 if (message !=
nullptr) {
353 WRITE_WARNINGF(
TL(
"Error while adding a journey for person '%': %"), person->
getID(), JPS_ErrorMessage_GetMessage(message));
354 JPS_ErrorMessage_Free(message);
360 if (pstate->getPerson() == person) {
365 if (state ==
nullptr) {
366 state =
new PState(
static_cast<MSPerson*
>(person), stage, journeyId, startingStage, waypoints);
368 state->
setPosition(departurePosition.
x(), departurePosition.
y());
373 state->
reinit(stage, journeyId, startingStage, waypoints);
379 (*myPythonScript) <<
"journey_id = simulation.add_journey(journey)\n"
380 "simulation.add_agent(jps.CollisionFreeSpeedModelAgentParameters(journey_id=journey_id,stage_id="
381 << startingStage <<
",position=(" << departurePosition.
x() <<
"," << departurePosition.
y()
386 if (message !=
nullptr) {
387 WRITE_WARNINGF(
TL(
"Error while switching to a new journey for person '%': %"), person->
getID(), JPS_ErrorMessage_GetMessage(message));
388 JPS_ErrorMessage_Free(message);
399 if (pstate->
getLane() !=
nullptr) {
401 peds.erase(std::find(peds.begin(), peds.end(), pstate));
404 if (pstate->
getStage() !=
nullptr) {
414 JPS_ErrorMessage message =
nullptr;
415 for (
int i = 0; i < nbrIterations; ++i) {
419 WRITE_ERRORF(
TL(
"Error during iteration %: %"), i, JPS_ErrorMessage_GetMessage(message));
427 PState*
const state = *stateIt;
441 if (stage ==
nullptr) {
452 const JPS_Point position = JPS_Agent_GetPosition(agent);
456 const JPS_Point orientation = JPS_Agent_GetOrientation(agent);
457 state->
setAngle(atan2(orientation.y, orientation.x));
460 Position newPosition(position.x, position.y);
463 const double oldLanePos = state->
getEdgePos(time);
465 double bestDistance = std::numeric_limits<double>::max();
466 MSLane* candidateLane =
nullptr;
467 double candidateLaneLongitudinalPosition = 0.0;
470 forwardRoute, 0, person->
getVClass(),
true, bestDistance, &candidateLane, candidateLaneLongitudinalPosition, routeOffset);
473 if (candidateLane != state->
getLane()) {
474 if (state->
getLane() !=
nullptr) {
476 peds.erase(std::find(peds.begin(), peds.end(), state));
486 const bool arrived = stage->
moveToNextEdge(person, time, 1,
nullptr);
494 JPS_CollisionFreeSpeedModelState modelState = JPS_Agent_GetCollisionFreeSpeedModelState(agent,
nullptr);
495 if (newMaxSpeed != JPS_CollisionFreeSpeedModelState_GetV0(modelState)) {
496 JPS_CollisionFreeSpeedModelState_SetV0(modelState, newMaxSpeed);
501 JPS_CollisionFreeSpeedModelV2State modelState = JPS_Agent_GetCollisionFreeSpeedModelV2State(agent,
nullptr);
502 if (newMaxSpeed != JPS_CollisionFreeSpeedModelV2State_GetV0(modelState)) {
503 JPS_CollisionFreeSpeedModelV2State_SetV0(modelState, newMaxSpeed);
508 JPS_GeneralizedCentrifugalForceModelState modelState = JPS_Agent_GetGeneralizedCentrifugalForceModelState(agent,
nullptr);
509 if (newMaxSpeed != JPS_GeneralizedCentrifugalForceModelState_GetV0(modelState)) {
510 JPS_GeneralizedCentrifugalForceModelState_SetV0(modelState, newMaxSpeed);
515 JPS_SocialForceModelState modelState = JPS_Agent_GetSocialForceModelState(agent,
nullptr);
516 if (newMaxSpeed != JPS_SocialForceModelState_GetDesiredSpeed(modelState)) {
517 JPS_SocialForceModelState_SetDesiredSpeed(modelState, newMaxSpeed);
523 const double speed = person->
getSpeed();
524 for (
int offset = 0; offset < 2; offset++) {
526 if (waypoint !=
nullptr && std::get<0>(*waypoint) != 0) {
527 const JPS_StageId waitingStage = std::get<0>(*waypoint);
538 const double passingClearanceTime = person->
getFloatParam(
"pedestrian.timegap-crossing");
540 person->
getImpatience(), speed, 0, 0,
nullptr,
false, person);
541 const auto proxy = JPS_Simulation_GetWaitingSetProxy(
myJPSSimulation, waitingStage, &message);
542 JPS_WaitingSetProxy_SetWaitingSetState(proxy, open ? JPS_WaitingSet_Inactive : JPS_WaitingSet_Active);
548 const double slack = person->
getMaxSpeed() *
TS / 2. + POSITION_EPS;
554 const JPS_AgentId agentID = state->
getAgentId();
567 for (
const auto& area :
myAreas) {
568 const std::vector<JPS_Point>& areaBoundary = area->areaBoundary;
569 JPS_AgentIdIterator agentsInArea = JPS_Simulation_AgentsInPolygon(
myJPSSimulation, areaBoundary.data(), areaBoundary.size());
570 if (area->areaType ==
"vanishing_area") {
571 const SUMOTime period = area->params.count(
"period") > 0 ?
string2time(area->params.at(
"period")) : 1000;
572 const int nbrPeriodsCoveringTimestep = (int)ceil(
TS /
STEPS2TIME(period));
573 if (time - area->lastRemovalTime >= nbrPeriodsCoveringTimestep * period) {
574 for (
int k = 0; k < nbrPeriodsCoveringTimestep; k++) {
575 const JPS_AgentId agentID = JPS_AgentIdIterator_Next(agentsInArea);
577 auto lambda = [agentID](
const PState *
const p) {
578 return p->getAgentId() == agentID;
582 const PState*
const state = *iterator;
587 WRITE_MESSAGEF(
TL(
"Person '%' in vanishing area '%' was removed from the simulation."), person->
getID(), area->id);
591 area->lastRemovalTime = time;
598 for (JPS_AgentId agentID = JPS_AgentIdIterator_Next(agentsInArea); agentID != 0; agentID = JPS_AgentIdIterator_Next(agentsInArea)) {
599 if (area->params.count(
"speed") > 0) {
600 const JPS_Agent agent = JPS_Simulation_GetAgent(
myJPSSimulation, agentID,
nullptr);
604 JPS_CollisionFreeSpeedModelState modelState = JPS_Agent_GetCollisionFreeSpeedModelState(agent,
nullptr);
605 if (newMaxSpeed != JPS_CollisionFreeSpeedModelState_GetV0(modelState)) {
606 JPS_CollisionFreeSpeedModelState_SetV0(modelState, newMaxSpeed);
611 JPS_CollisionFreeSpeedModelV2State modelState = JPS_Agent_GetCollisionFreeSpeedModelV2State(agent,
nullptr);
612 if (newMaxSpeed != JPS_CollisionFreeSpeedModelV2State_GetV0(modelState)) {
613 JPS_CollisionFreeSpeedModelV2State_SetV0(modelState, newMaxSpeed);
618 JPS_GeneralizedCentrifugalForceModelState modelState = JPS_Agent_GetGeneralizedCentrifugalForceModelState(agent,
nullptr);
619 if (newMaxSpeed != JPS_GeneralizedCentrifugalForceModelState_GetV0(modelState)) {
620 JPS_GeneralizedCentrifugalForceModelState_SetV0(modelState, newMaxSpeed);
625 JPS_SocialForceModelState modelState = JPS_Agent_GetSocialForceModelState(agent,
nullptr);
626 if (newMaxSpeed != JPS_SocialForceModelState_GetDesiredSpeed(modelState)) {
627 JPS_SocialForceModelState_SetDesiredSpeed(modelState, newMaxSpeed);
635 JPS_AgentIdIterator_Free(agentsInArea);
640 std::vector<SUMOTrafficObject::NumericalID> allStoppedTrainIDs;
641 std::vector<const MSVehicle*> allStoppedTrains;
642 for (
const auto& stop : stoppingPlaces) {
643 std::vector<const SUMOVehicle*> stoppedTrains = stop.second->getStoppedVehicles();
645 allStoppedTrainIDs.push_back(train->getNumericalID());
646 allStoppedTrains.push_back(
dynamic_cast<const MSVehicle*
>(train));
651 if (!allStoppedTrainIDs.empty()) {
652 std::vector<GEOSGeometry*> carriagePolygons;
653 std::vector<GEOSGeometry*> rampPolygons;
654 for (
const MSVehicle* train : allStoppedTrains) {
655 if (train->getLeavingPersonNumber() > 0) {
659 const std::vector<MSTrainHelper::Carriage*>& carriages = trainHelper.
getCarriages();
661 Position dir = carriage->front - carriage->back;
670 carriageShape.push_back(carriage->front + perp * p);
671 carriageShape.push_back(carriage->back + perp * p);
672 carriageShape.push_back(carriage->back - perp * p);
673 carriageShape.push_back(carriage->front - perp * p);
678 for (
const Position& door : carriage->doorPositions) {
680 rampShape.push_back(door - perp * p + dir * d);
681 rampShape.push_back(door - perp * p - dir * d);
682 rampShape.push_back(door + perp * p - dir * d);
683 rampShape.push_back(door + perp * p + dir * d);
689 if (!carriagePolygons.empty()) {
690 GEOSGeometry* carriagesCollection = GEOSGeom_createCollection(GEOS_MULTIPOLYGON, carriagePolygons.data(), (
unsigned int)carriagePolygons.size());
691 GEOSGeometry* rampsCollection = GEOSGeom_createCollection(GEOS_MULTIPOLYGON, rampPolygons.data(), (
unsigned int)rampPolygons.size());
692 GEOSGeometry* carriagesAndRampsUnion = GEOSUnion(carriagesCollection, rampsCollection);
693 if (carriagesAndRampsUnion ==
nullptr) {
697#ifdef DEBUG_GEOMETRY_GENERATION
700 int nbrComponents = 0;
701 double maxArea = 0.0;
702 double totalArea = 0.0;
703 const GEOSGeometry* pedestrianNetworkWithTrainsAndRampsLargestComponent =
getLargestComponent(pedestrianNetworkWithTrainsAndRamps, nbrComponents, maxArea, totalArea);
704 if (nbrComponents > 1) {
705 WRITE_WARNINGF(
TL(
"While generating geometry % connected components were detected, %% of total pedestrian area is covered by the largest."),
706 nbrComponents, maxArea / totalArea * 100.0,
"%");
708#ifdef DEBUG_GEOMETRY_GENERATION
714 WRITE_WARNINGF(
TL(
"While switching to train geometry: %"), JPS_ErrorMessage_GetMessage(message));
718 GEOSGeom_destroy(pedestrianNetworkWithTrainsAndRamps);
720 GEOSGeom_destroy(rampsCollection);
721 GEOSGeom_destroy(carriagesCollection);
726 WRITE_WARNINGF(
TL(
"While switching to default geometry: %"), JPS_ErrorMessage_GetMessage(message));
733 JPS_ErrorMessage_Free(message);
754 GEOSGeometry* lineString = GEOSGeom_createLineString(coordinateSequence);
756 GEOSGeom_destroy(lineString);
757 return dilatedLineString;
764 if (shape.size() == 1) {
765 WRITE_WARNINGF(
TL(
"Polygon '%' at junction '%' will be skipped as it is just a point."), shapeID, junctionID);
769 if (shape.back() != shape.front()) {
770 shape.push_back(shape.front());
774 cleanShape.push_back(shape[0]);
776 for (
int i = 1; i < (int)shape.size(); i++) {
777 if (shape[i] != shape[i - 1]) {
778 cleanShape.push_back(shape[i]);
780 duplicates.push_back(shape[i]);
783 if (cleanShape.size() < shape.size()) {
784 WRITE_WARNINGF(
TL(
"Polygon '%' at junction '%' had some equal consecutive points removed: %"), shapeID, junctionID,
toString(duplicates, 9));
787 GEOSGeometry* linearRing = GEOSGeom_createLinearRing(coordinateSequence);
788 GEOSGeometry* polygon = GEOSGeom_createPolygon(linearRing,
nullptr, 0);
790 if (!GEOSisValid(polygon)) {
791 if (cleanShape.size() == 3) {
792 if (isInternalShape) {
793 WRITE_WARNINGF(
TL(
"Polygon '%' at junction '%' has been dilated as it is just a segment."), shapeID, junctionID);
795 WRITE_WARNINGF(
TL(
"Polygon '%' has been dilated as it is just a segment."), shapeID);
797 GEOSGeometry* lineString = GEOSGeom_createLineString(GEOSCoordSeq_clone(coordinateSequence));
798 GEOSGeom_destroy(polygon);
800 GEOSGeom_destroy(lineString);
802 if (isInternalShape) {
803 WRITE_WARNINGF(
TL(
"Polygon '%' at junction '%' has been replaced by its convex hull as it is not simple."), shapeID, junctionID);
804 GEOSGeometry* hull = GEOSConvexHull(polygon);
805 GEOSGeom_destroy(polygon);
808 WRITE_WARNINGF(
TL(
"Polygon '%' at junction '%' will be skipped as it is not simple."), shapeID, junctionID);
817 if (isInternalShape) {
827 std::vector<GEOSGeometry*> walkableAreas;
829 const MSLane*
const lane = getSidewalk<MSEdge, MSLane>(edge);
830 if (lane !=
nullptr) {
831 GEOSGeometry* dilatedLane =
nullptr;
832 if (edge->isWalkingArea()) {
834 }
else if (edge->isCrossing()) {
836 if (outlineShape !=
nullptr) {
839 if (dilatedLane !=
nullptr) {
840 walkableAreas.push_back(dilatedLane);
850 if (dilatedLane !=
nullptr) {
851 walkableAreas.push_back(dilatedLane);
856 const MSJunction*
const junction = junctionWithID.second;
857 int pedEdgeCount = 0;
858 bool hasWalkingArea =
false;
862 for (
const MSEdge*
const edge : edges) {
863 if (edge->isWalkingArea()) {
864 hasWalkingArea =
true;
867 if (getSidewalk<MSEdge, MSLane>(edge) !=
nullptr) {
871 if (hasWalkingArea) {
875 if (!hasWalkingArea && pedEdgeCount > 1) {
878 if (walkingAreaGeom !=
nullptr) {
879 walkableAreas.push_back(walkingAreaGeom);
885 std::vector<GEOSGeometry*> additionalObstacles;
887 if (polygonWithID.second->getShapeType() ==
"jupedsim.walkable_area" || polygonWithID.second->getShapeType() ==
"taz") {
888 GEOSGeometry* walkableArea =
createGeometryFromShape(polygonWithID.second->getShape(), std::string(
""), polygonWithID.first);
889 if (walkableArea !=
nullptr) {
890 walkableAreas.push_back(walkableArea);
893 }
else if (polygonWithID.second->getShapeType() ==
"jupedsim.obstacle") {
894 GEOSGeometry* additionalObstacle =
createGeometryFromShape(polygonWithID.second->getShape(), std::string(
""), polygonWithID.first);
895 if (additionalObstacle !=
nullptr) {
896 additionalObstacles.push_back(additionalObstacle);
902 GEOSGeometry* disjointWalkableAreas = GEOSGeom_createCollection(GEOS_MULTIPOLYGON, walkableAreas.data(), (
unsigned int)walkableAreas.size());
903#ifdef DEBUG_GEOMETRY_GENERATION
906 GEOSGeometry* initialWalkableAreas = GEOSUnaryUnion(disjointWalkableAreas);
907#ifdef DEBUG_GEOMETRY_GENERATION
908 dumpGeometry(initialWalkableAreas,
"initialWalkableAreas.wkt");
910 GEOSGeom_destroy(disjointWalkableAreas);
913 GEOSGeometry* disjointAdditionalObstacles = GEOSGeom_createCollection(GEOS_MULTIPOLYGON, additionalObstacles.data(), (
unsigned int)additionalObstacles.size());
914#ifdef DEBUG_GEOMETRY_GENERATION
917 GEOSGeometry* additionalObstaclesUnion = GEOSUnaryUnion(disjointAdditionalObstacles);
918#ifdef DEBUG_GEOMETRY_GENERATION
919 dumpGeometry(additionalObstaclesUnion,
"additionalObstaclesUnion.wkt");
921 GEOSGeometry* finalWalkableAreas = GEOSDifference(initialWalkableAreas, additionalObstaclesUnion);
922#ifdef DEBUG_GEOMETRY_GENERATION
923 dumpGeometry(finalWalkableAreas,
"finalWalkableAreas.wkt");
925 GEOSGeom_destroy(initialWalkableAreas);
926 GEOSGeom_destroy(additionalObstaclesUnion);
927 GEOSGeom_destroy(disjointAdditionalObstacles);
929 if (!GEOSisSimple(finalWalkableAreas)) {
930 throw ProcessError(
TL(
"Union of walkable areas minus union of obstacles is not a simple polygon."));
933 return finalWalkableAreas;
939 GEOSCoordSequence* coordinateSequence = GEOSCoordSeq_create((
unsigned int)shape.size(), 2);
940 for (
int i = 0; i < (int)shape.size(); i++) {
941 GEOSCoordSeq_setX(coordinateSequence, i, shape[i].x());
942 GEOSCoordSeq_setY(coordinateSequence, i, shape[i].y());
944 return coordinateSequence;
951 const GEOSCoordSequence* coordinateSequence = GEOSGeom_getCoordSeq(geometry);
952 unsigned int coordinateSequenceSize;
953 GEOSCoordSeq_getSize(coordinateSequence, &coordinateSequenceSize);
956 for (
unsigned int i = 0; i < coordinateSequenceSize; i++) {
957 GEOSCoordSeq_getX(coordinateSequence, i, &x);
958 GEOSCoordSeq_getY(coordinateSequence, i, &y);
959 coordinateVector.push_back(
Position(x, y));
961 return coordinateVector;
965std::vector<JPS_Point>
967 std::vector<JPS_Point> pointVector;
968 const GEOSCoordSequence* coordinateSequence = GEOSGeom_getCoordSeq(geometry);
969 unsigned int coordinateSequenceSize;
970 GEOSCoordSeq_getSize(coordinateSequence, &coordinateSequenceSize);
974 for (
unsigned int i = 0; i < coordinateSequenceSize - 1; i++) {
975 GEOSCoordSeq_getX(coordinateSequence, i, &x);
976 GEOSCoordSeq_getY(coordinateSequence, i, &y);
977 pointVector.push_back({x, y});
986 GEOSGeometry* linearRingAsPolygon = GEOSGeom_createPolygon(GEOSGeom_clone(linearRing),
nullptr, 0);
987 GEOSArea(linearRingAsPolygon, &area);
988 GEOSGeom_destroy(linearRingAsPolygon);
1001 const GEOSGeometry* exterior = GEOSGetExteriorRing(polygon);
1005 std::vector<PositionVector> holes;
1006 int nbrInteriorRings = GEOSGetNumInteriorRings(polygon);
1007 if (nbrInteriorRings != -1) {
1008 for (
int k = 0; k < nbrInteriorRings; k++) {
1009 const GEOSGeometry* linearRing = GEOSGetInteriorRingN(polygon, k);
1023 nbrComponents = GEOSGetNumGeometries(polygon);
1024 const GEOSGeometry* largestComponent =
nullptr;
1027 for (
int i = 0; i < nbrComponents; i++) {
1028 const GEOSGeometry* componentPolygon = GEOSGetGeometryN(polygon, i);
1030 GEOSArea(componentPolygon, &area);
1032 if (area > maxArea) {
1034 largestComponent = componentPolygon;
1037 return largestComponent;
1043 JPS_GeometryBuilder geometryBuilder = JPS_GeometryBuilder_Create();
1046 const GEOSGeometry* exterior = GEOSGetExteriorRing(polygon);
1048 JPS_GeometryBuilder_AddAccessibleArea(geometryBuilder, exteriorCoordinates.data(), exteriorCoordinates.size());
1051 int nbrInteriorRings = GEOSGetNumInteriorRings(polygon);
1052 if (nbrInteriorRings != -1) {
1053 for (
int k = 0; k < nbrInteriorRings; k++) {
1054 const GEOSGeometry* linearRing = GEOSGetInteriorRingN(polygon, k);
1058 JPS_GeometryBuilder_ExcludeFromAccessibleArea(geometryBuilder, holeCoordinates.data(), holeCoordinates.size());
1063 JPS_ErrorMessage message =
nullptr;
1064 JPS_Geometry geometry = JPS_GeometryBuilder_Build(geometryBuilder, &message);
1065 if (geometry ==
nullptr) {
1066 const std::string error =
TLF(
"Error while generating geometry: %", JPS_ErrorMessage_GetMessage(message));
1067 JPS_ErrorMessage_Free(message);
1070 JPS_GeometryBuilder_Free(geometryBuilder);
1077 GEOSGeometry* polygonGeoCoordinates =
nullptr;
1078 if (useGeoCoordinates) {
1079 const GEOSGeometry* exterior = GEOSGetExteriorRing(polygon);
1081 for (
Position& position : exteriorPoints) {
1084 const int nbrInteriorRings = GEOSGetNumInteriorRings(polygon);
1085 std::vector<GEOSGeometry*> holeRings;
1086 if (nbrInteriorRings != -1) {
1087 for (
int k = 0; k < nbrInteriorRings; k++) {
1088 const GEOSGeometry* linearRing = GEOSGetInteriorRingN(polygon, k);
1090 for (
Position& position : holePoints) {
1094 GEOSGeometry* holeRing = GEOSGeom_createLinearRing(holeRingCoords);
1095 holeRings.push_back(holeRing);
1099 GEOSGeometry* exteriorRing = GEOSGeom_createLinearRing(exteriorRingCoords);
1100 polygonGeoCoordinates = GEOSGeom_createPolygon(exteriorRing, holeRings.data(), nbrInteriorRings);
1102 std::ofstream dumpFile;
1103 dumpFile.open(filename);
1104 GEOSWKTWriter* writer = GEOSWKTWriter_create();
1106 char* wkt = GEOSWKTWriter_write(writer, polygonGeoCoordinates ==
nullptr ? polygon : polygonGeoCoordinates);
1107 dumpFile << wkt << std::endl;
1110 GEOSWKTWriter_destroy(writer);
1111 GEOSGeom_destroy(polygonGeoCoordinates);
1123 JPS_ErrorMessage message =
nullptr;
1124 JPS_StageId waitingStage = 0;
1128 const double offset = 2 * radius + POSITION_EPS;
1129 const double lonOffset = entry ? NUMERICAL_EPS : shape.
length() - NUMERICAL_EPS;
1132 for (
double latOff = offset; latOff < crossing->
getWidth() / 2. - offset; latOff += offset) {
1140 pv.push_back(crossing->
getIncomingLanes().front().lane->getShape().getCentroid());
1142 if (!entry && crossing->
getLinkCont().size() == 1 && crossing->
getLinkCont().front()->getLane()->isWalkingArea()) {
1143 pv.push_back(crossing->
getLinkCont().front()->getLane()->getShape().getCentroid());
1145 std::vector<JPS_Point> points;
1147 GEOSCoordSequence* seq = GEOSCoordSeq_create(1, 2);
1148 GEOSCoordSeq_setX(seq, 0, p.x());
1149 GEOSCoordSeq_setY(seq, 0, p.y());
1150 GEOSGeometry* point = GEOSGeom_createPoint(seq);
1152 points.push_back({p.x(), p.y()});
1154 WRITE_WARNINGF(
"Waiting point %,% is not in the geometry for % on '%'.", p.x(), p.y(), entry ?
"entry" :
"exit", crossing->
getID())
1156 GEOSGeom_destroy(point);
1158 waitingStage = JPS_Simulation_AddStageWaitingSet(
myJPSSimulation, points.data(), points.size(), &message);
1159 if (message !=
nullptr) {
1160 const std::string error =
TLF(
"Error while adding waiting set for % on '%': %",
1161 entry ?
"entry" :
"exit", crossing->
getID(), JPS_ErrorMessage_GetMessage(message));
1162 JPS_ErrorMessage_Free(message);
1165 const auto proxy = JPS_Simulation_GetWaitingSetProxy(
myJPSSimulation, waitingStage, &message);
1166 JPS_WaitingSetProxy_SetWaitingSetState(proxy, JPS_WaitingSet_Inactive);
1169 (*myPythonScript) <<
"ws = simulation.add_waiting_set_stage([";
1170 for (
const JPS_Point& p : points) {
1171 (*myPythonScript) <<
"(" << p.x <<
"," << p.y <<
"),";
1173 (*myPythonScript) <<
"])\nsimulation.get_stage(ws).state = jps.stages.WaitingSetState.INACTIVE\n";
1175 return waitingStage;
1181 initGEOS(
nullptr,
nullptr);
1184 int nbrComponents = 0;
1185 double maxArea = 0.0;
1186 double totalArea = 0.0;
1188 if (nbrComponents > 1) {
1189 WRITE_WARNINGF(
TL(
"While generating geometry % connected components were detected, %% of total pedestrian area is covered by the largest."),
1190 nbrComponents, maxArea / totalArea * 100.0,
"%");
1192#ifdef DEBUG_GEOMETRY_GENERATION
1195 const std::string filename = oc.
getString(
"pedestrian.jupedsim.wkt");
1196 if (!filename.empty()) {
1204 JPS_ErrorMessage message =
nullptr;
1206 double strengthGeometryRepulsion = oc.
getFloat(
"pedestrian.jupedsim.strength-geometry-repulsion");
1207 double rangeGeometryRepulsion = oc.
getFloat(
"pedestrian.jupedsim.range-geometry-repulsion");
1209 if (oc.
isDefault(
"pedestrian.jupedsim.strength-geometry-repulsion") && oc.
isDefault(
"pedestrian.jupedsim.range-geometry-repulsion")) {
1210 WRITE_MESSAGE(
TL(
"Adapting geometry repulsion default values for jupedsim timestep of 0.02."));
1211 strengthGeometryRepulsion = 35.;
1212 rangeGeometryRepulsion = 0.019;
1218 JPS_CollisionFreeSpeedModelBuilder modelBuilder = JPS_CollisionFreeSpeedModelBuilder_Create(
1219 oc.
getFloat(
"pedestrian.jupedsim.strength-neighbor-repulsion"),
1220 oc.
getFloat(
"pedestrian.jupedsim.range-neighbor-repulsion"),
1221 strengthGeometryRepulsion,
1222 rangeGeometryRepulsion);
1224 JPS_CollisionFreeSpeedModelBuilder_Free(modelBuilder);
1228 JPS_CollisionFreeSpeedModelV2Builder modelBuilder = JPS_CollisionFreeSpeedModelV2Builder_Create();
1230 JPS_CollisionFreeSpeedModelV2Builder_Free(modelBuilder);
1234 JPS_GeneralizedCentrifugalForceModelBuilder modelBuilder = JPS_GeneralizedCentrifugalForceModelBuilder_Create(
1235 oc.
getFloat(
"pedestrian.jupedsim.strength-neighbor-repulsion"),
1236 strengthGeometryRepulsion,
1244 JPS_GeneralizedCentrifugalForceModelBuilder_Free(modelBuilder);
1248 JPS_SocialForceModelBuilder modelBuilder = JPS_SocialForceModelBuilder_Create(120000.0, 240000.0);
1250 JPS_SocialForceModelBuilder_Free(modelBuilder);
1256 const std::string error =
TLF(
"Error creating the pedestrian model: %", JPS_ErrorMessage_GetMessage(message));
1257 JPS_ErrorMessage_Free(message);
1262 const std::string error =
TLF(
"Error creating the simulation: %", JPS_ErrorMessage_GetMessage(message));
1263 JPS_ErrorMessage_Free(message);
1273 (*myPythonScript) <<
"import jupedsim as jps\nimport shapely\n\n"
1274 "with open('" << filename <<
"') as f: geom = shapely.from_wkt(f.read())\n"
1275 "simulation = jps.Simulation(dt=" <<
STEPS2TIME(
myJPSDeltaT) <<
", model=jps.CollisionFreeSpeedModel(), geometry=geom,\n"
1276 "trajectory_writer=jps.SqliteTrajectoryWriter(output_file='out.sql'))\n";
1280 crossing.second.first =
addWaitingSet(crossing.first,
true);
1281 crossing.second.second =
addWaitingSet(crossing.first,
false);
1292 for (
auto areaIt =
myAreas.begin(); areaIt !=
myAreas.end(); ++areaIt) {
1293 if (poly->
getID() == (*areaIt)->id) {
1294 lastRemovalTime = (*areaIt)->lastRemovalTime;
1301 std::vector<JPS_Point> areaBoundary;
1303 areaBoundary.push_back({p.x(), p.y()});
1306 if (areaBoundary.back().x == areaBoundary.front().x && areaBoundary.back().y == areaBoundary.front().y) {
1307 areaBoundary.pop_back();
1320 JPS_JourneyId journeyId, JPS_StageId stageId,
1321 const std::vector<WaypointDesc>& waypoints) :
1323 myJourneyId(journeyId), myStageId(stageId), myWaypoints(waypoints), myAgentId(0) {
1330 const std::vector<WaypointDesc>& waypoints) {
1331 if (myStage !=
nullptr) {
1332 myStage->setPState(
nullptr);
1335 myJourneyId = journeyId;
1336 myStageId = stageId;
1337 myWaypoints = waypoints;
1351 myRemoteXYPos.set(x, y, z);
1362 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 precedecessor lane (sorted using by_connections_to_sorter). The result is cached ...
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_StageId getStageId() const
first stage of the journey
void setAngle(double angle)
void setLane(MSLane *lane)
JPS_AgentId getAgentId() const
void setStage(MSStageMoving *const stage)
void setAgentId(JPS_AgentId id)
const MSPModel_JuPedSim::WaypointDesc * getNextWaypoint(const int offset=0) const
bool advanceNextWaypoint()
void setLanePosition(double lanePosition)
const MSEdge * getNextEdge(const MSStageMoving &stage) const override
return the list of internal edges if the transportable is on an intersection
JPS_JourneyId getJourneyId() const
PState(MSPerson *person, MSStageMoving *stage, JPS_JourneyId journeyId, JPS_StageId stageId, const std::vector< WaypointDesc > &waypoints)
void reinit(MSStageMoving *stage, JPS_JourneyId journeyId, JPS_StageId stageId, const std::vector< WaypointDesc > &waypoints)
Position getPosition(const MSStageMoving &, SUMOTime) const override
return the network coordinate of the transportable
void setPosition(const double x, const double y, const double z=0.)
JPS_StageId addWaitingSet(const MSLane *const crossing, const bool entry)
OutputDevice * myPythonScript
MSTransportableStateAdapter * add(MSTransportable *person, MSStageMoving *stage, SUMOTime now) override
register the given person as a pedestrian
void removePolygonFromDrawing(const std::string &polygonId)
const GEOSGeometry * myGEOSPedestrianNetworkLargestComponent
The GEOS polygon representing the largest (by area) connected component of the pedestrian network.
void preparePolygonForDrawing(const GEOSGeometry *polygon, const std::string &polygonId, const RGBColor &color)
static const RGBColor PEDESTRIAN_NETWORK_CARRIAGES_AND_RAMPS_COLOR
MSPModel_JuPedSim(const OptionsCont &oc, MSNet *net)
static const double GEOS_MITRE_LIMIT
@ GeneralizedCentrifugalForce
const double myExitTolerance
Threshold to decide if a pedestrian has ended its journey or not.
std::vector< SUMOTrafficObject::NumericalID > myAllStoppedTrainIDs
Array of stopped trains, used to detect whether to add carriages and ramps to the geometry.
bool addStage(JPS_JourneyDescription journey, JPS_StageId &predecessor, const std::string &agentID, const JPS_StageId stage)
void registerArrived(const JPS_AgentId agentID)
static GEOSGeometry * createGeometryFromCenterLine(PositionVector centerLine, double width, int capStyle)
static PositionVector convertToSUMOPoints(const GEOSGeometry *geometry)
static const std::string PEDESTRIAN_NETWORK_CARRIAGES_AND_RAMPS_ID
static const RGBColor PEDESTRIAN_NETWORK_COLOR
JPS_Geometry myJPSGeometry
The JPS polygon representing the largest connected component of the pedestrian network.
static const std::string PEDESTRIAN_NETWORK_ID
bool addWaypoint(JPS_JourneyDescription journey, JPS_StageId &predecessor, const std::string &agentID, const WaypointDesc &waypoint)
static GEOSGeometry * createGeometryFromShape(PositionVector shape, std::string junctionID=std::string(""), std::string shapeID=std::string(""), bool isInternalShape=false)
static GEOSCoordSequence * convertToGEOSPoints(PositionVector shape)
JPS_Simulation myJPSSimulation
GEOSGeometry * myGEOSPedestrianNetwork
The GEOS polygon containing all computed connected components of the pedestrian network.
static void dumpGeometry(const GEOSGeometry *polygon, const std::string &filename, bool useGeoCoordinates=false)
bool myHaveAdditionalWalkableAreas
static std::vector< JPS_Point > convertToJPSPoints(const GEOSGeometry *geometry)
static JPS_Geometry buildJPSGeometryFromGEOSGeometry(const GEOSGeometry *polygon)
std::map< const MSLane *, std::pair< JPS_StageId, JPS_StageId >, ComparatorNumericalIdLess > myCrossingWaits
const SUMOTime myJPSDeltaT
Timestep used in the JuPedSim simulator.
MSNet *const myNetwork
The network on which the simulation runs.
std::map< JPS_StageId, const MSLane * > myCrossings
JPS_Geometry myJPSGeometryWithTrainsAndRamps
The JPS polygon representing the largest connected component plus carriages and ramps.
void polygonChanged(const SUMOPolygon *const poly, const bool added, const bool removed) override
static const double GEOS_MIN_AREA
std::tuple< JPS_StageId, Position, double > WaypointDesc
void initialize(const OptionsCont &oc)
GEOSGeometry * buildPedestrianNetwork(MSNet *network)
void remove(MSTransportableStateAdapter *state) override
remove the specified person from the pedestrian simulation
std::vector< std::unique_ptr< AreaData > > myAreas
Array of special areas.
static double getLinearRingArea(const GEOSGeometry *linearRing)
void clearState() override
Resets pedestrians when quick-loading state.
ShapeContainer & myShapeContainer
The shape container used to add polygons to the rendering pipeline.
std::vector< PState * > myPedestrianStates
JPS_OperationalModel myJPSOperationalModel
static const int GEOS_QUADRANT_SEGMENTS
static const std::vector< MSPModel_JuPedSim::PState * > noPedestrians
static const GEOSGeometry * getLargestComponent(const GEOSGeometry *polygon, int &nbrComponents, double &maxArea, double &totalArea)
static double getRadius(const MSVehicleType &vehType)
void tryPedestrianInsertion(PState *state, const Position &p)
SUMOTime execute(SUMOTime time)
static const double GEOS_BUFFERED_SEGMENT_WIDTH
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)
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).