70 myStopWatch(10), myRNG(
"JuPedSim"), myNetwork(net), myShapeContainer(net->getShapeContainer()), myJPSDeltaT(
string2time(oc.getString(
"pedestrian.jupedsim.step-length"))),
71 myExitTolerance(oc.getFloat(
"pedestrian.jupedsim.exit-tolerance")), myGEOSPedestrianNetworkLargestComponent(nullptr),
72 myHaveAdditionalWalkableAreas(false) {
75 if (
myJPSModel.find(
"Model") == std::string::npos) {
78 if (
myJPSModel ==
"CollisionFreeSpeedV2Model") {
83 std::string address = oc.
getString(
"pedestrian.jupedsim.address");
86 const char* pythonEnv = getenv(
"PYTHON");
87 const std::string python = (pythonEnv ==
nullptr) ?
"python" : pythonEnv;
88 const char* sumoHomeEnv = getenv(
"SUMO_HOME");
89 const std::string sumoHome = (sumoHomeEnv ==
nullptr) ?
"." : sumoHomeEnv;
90 command = python +
" " + sumoHome +
"/tools/jupedsim_grpc/servicer.py";
91 if (oc.
isSet(
"pedestrian.jupedsim.py")) {
92 command +=
" --debug " + oc.
getString(
"pedestrian.jupedsim.py");
95 for (
int i = 0; i < 2; i++) {
99 myJuPedSimServer = std::unique_ptr<bp::child>(
new bp::child(command +
" --port " + port));
100 address =
"localhost:" + port;
102 WRITE_WARNINGF(
TL(
"No boost process support, you will need to start the JuPedSim server manually using %."), command);
106 myGrpcChannel = grpc::CreateChannel(address, grpc::InsecureChannelCredentials());
107 if (
myGrpcChannel->WaitForConnected(std::chrono::system_clock::now() + std::chrono::seconds(5))) {
111 WRITE_WARNINGF(
TL(
"Could not connect to JuPedSim gRPC server on '%' (will retry on demand)."), address);
113 if (myJuPedSimServer ==
nullptr || myJuPedSimServer->running()) {
130 if (myJuPedSimServer !=
nullptr) {
131 myJuPedSimServer->terminate();
139#ifdef DEBUG_GRPC_TIMING
140 std::cout <<
myStopWatch[0].getTotal() / (1e6) <<
"ms, iteration: "
141 <<
myStopWatch[1].getTotal() / (1e6) <<
"ms, agent data retrieval: "
142 <<
myStopWatch[2].getTotal() / (1e6) <<
"ms, journey creation: "
143 <<
myStopWatch[3].getTotal() / (1e6) <<
"ms, insertion: "
144 <<
myStopWatch[4].getTotal() / (1e6) <<
"ms, removal: "
145 <<
myStopWatch[5].getTotal() / (1e6) <<
"ms, add waiting set: "
146 <<
myStopWatch[6].getTotal() / (1e6) <<
"ms, speed: "
147 <<
myStopWatch[7].getTotal() / (1e6) <<
"ms " << std::endl;
154#ifdef DEBUG_GRPC_TIMING
158 sumo_jupedsim_api::CreateAgentRequest agentRequest;
160 agentRequest.set_agent_model_class(
myJPSModel);
161 auto& agentParams = *agentRequest.mutable_agent_model_parameters()->mutable_fields();
162 agentParams[
"journey_id"].set_number_value(
static_cast<double>(state->
getJourneyId()));
163 agentParams[
"stage_id"].set_number_value(
static_cast<double>(state->
getStageId()));
165 if (
myJPSModel !=
"GeneralizedCentrifugalForceModel") {
166 agentParams[
"radius"].set_number_value(
getRadius(type));
168 google::protobuf::ListValue* position = agentParams[
"position"].mutable_list_value();
169 position->add_values()->set_number_value(p.
x());
170 position->add_values()->set_number_value(p.
y());
173 double orientation_x = 0.;
174 double orientation_y = 0.;
175 if (fabs(angle -
M_PI / 2) < NUMERICAL_EPS) {
177 }
else if (fabs(angle +
M_PI / 2) < NUMERICAL_EPS) {
181 orientation_y = tan(angle);
183 google::protobuf::ListValue* orientation = agentParams[
"orientation"].mutable_list_value();
184 orientation->add_values()->set_number_value(orientation_x);
185 orientation->add_values()->set_number_value(orientation_y);
187 grpc::ClientContext agentContext;
188 sumo_jupedsim_api::CreateAgentResponse agentResponse;
189 const grpc::Status agentStatus =
myGrpcStub->CreateAgent(&agentContext, agentRequest, &agentResponse);
190 if (agentStatus.ok()) {
195#ifdef DEBUG_GRPC_TIMING
205 const MSLane*
const lane = std::get<1>(waypoint);
206 Position& coords = std::get<2>(waypoint);
207 double& dist = std::get<3>(waypoint);
208 sumo_jupedsim_api::AddWaypointStageRequest waypointRequest;
209 if (finalStage ==
nullptr) {
219 return centerIt->second;
225 waypointRequest.mutable_point()->set_x(coords.
x());
226 waypointRequest.mutable_point()->set_y(coords.
y());
227 waypointRequest.set_distance(dist);
228 sumo_jupedsim_api::StageResponse waypointResponse =
callGrpc(&sumo_jupedsim_api::JuPedSimService::Stub::AddWaypointStage, waypointRequest,
229 TLF(
"Error while adding waypoint for person '%': ", agentID),
true);
230 if (waypointResponse.stage_id() != 0 && finalStage ==
nullptr) {
233 return waypointResponse.stage_id();
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);
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], {}, {}});
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, {}, {}});
335 const JPS_StageId finalWait = std::get<0>(waypoints.back());
336 waypoints.pop_back();
337 if (!waypoints.empty()) {
338 waypoints.erase(waypoints.begin());
340 waypoints.push_back({finalWait, getSidewalk<MSEdge, MSLane>(stage->
getDestination()), {}, {}});
342#ifdef DEBUG_GRPC_TIMING
345 sumo_jupedsim_api::AddJourneyRequest journeyRequest;
350 journeyRequest.add_stage_ids(waiting);
356 journeyRequest.add_stage_ids(waypoint);
357 if (startingStage == 0) {
358 startingStage = waiting != 0 ? waiting : waypoint;
361 const sumo_jupedsim_api::AddJourneyResponse journeyResponse =
callGrpc(&sumo_jupedsim_api::JuPedSimService::Stub::AddJourney, journeyRequest,
362 TLF(
"Error while adding journey for agent '%': ", person->
getID()));
363 const JPS_JourneyId journeyId = journeyResponse.journey_id();
364#ifdef DEBUG_GRPC_TIMING
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 sumo_jupedsim_api::SwitchAgentJourneyRequest switchRequest;
390 switchRequest.set_agent_id(state->
getAgentId());
391 switchRequest.set_journey_id(journeyId);
392 switchRequest.set_stage_id(startingStage);
393 callGrpc(&sumo_jupedsim_api::JuPedSimService::Stub::SwitchAgentJourney, switchRequest,
394 TLF(
"Error while switching journey for agent '%': ", person->
getID()));
403 if (pstate->
getLane() !=
nullptr) {
405 peds.erase(std::find(peds.begin(), peds.end(), pstate));
408 if (pstate->
getStage() !=
nullptr) {
417#ifdef DEBUG_GRPC_TIMING
420 sumo_jupedsim_api::IterateRequest iterateRequest;
422 callGrpc(&sumo_jupedsim_api::JuPedSimService::Stub::Iterate, iterateRequest,
TL(
"JuPedSim gRPC Iterate failed: "));
423#ifdef DEBUG_GRPC_TIMING
427#ifdef DEBUG_GRPC_TIMING
430 sumo_jupedsim_api::GetCorePropertiesOfAllAgentsRequest propertiesRequest;
431 sumo_jupedsim_api::GetCorePropertiesOfAllAgentsResponse propertiesResponse =
432 callGrpc(&sumo_jupedsim_api::JuPedSimService::Stub::GetCorePropertiesOfAllAgents, propertiesRequest,
TL(
"JuPedSim gRPC GetCorePropertiesOfAllAgents failed: "));
433 const auto& properties = propertiesResponse.properties();
434#ifdef DEBUG_GRPC_TIMING
439 PState*
const state = *stateIt;
453 if (stage ==
nullptr) {
463 const auto agentIt = properties.find(state->
getAgentId());
464 if (agentIt == properties.end()) {
468 const sumo_jupedsim_api::Point& pos = agentIt->second.position();
470 const sumo_jupedsim_api::Point& orientation = agentIt->second.orientation();
471 state->
setAngle(atan2(orientation.y(), orientation.x()));
474 Position newPosition(pos.x(), pos.y());
477 const double oldLanePos = state->
getEdgePos(time);
479 double bestDistance = std::numeric_limits<double>::max();
480 MSLane* candidateLane =
nullptr;
481 double candidateLaneLongitudinalPosition = 0.0;
484 forwardRoute, 0, person->
getVClass(),
true, bestDistance, &candidateLane, candidateLaneLongitudinalPosition, routeOffset);
487 if (candidateLane != state->
getLane()) {
488 if (state->
getLane() !=
nullptr) {
490 peds.erase(std::find(peds.begin(), peds.end(), state));
500 const bool arrived = stage->
moveToNextEdge(person, time, 1,
nullptr);
506 sumo_jupedsim_api::SetDesiredSpeedRequest desiredSpeedRequest;
507 auto speeds = desiredSpeedRequest.mutable_desired_speeds();
509#ifdef DEBUG_GRPC_TIMING
512 callGrpc(&sumo_jupedsim_api::JuPedSimService::Stub::SetDesiredSpeedOfAgents, desiredSpeedRequest,
513 TLF(
"Error while setting desired speed for %: ", person->
getID()));
514#ifdef DEBUG_GRPC_TIMING
518 const double speed = person->
getSpeed();
519 for (
int offset = 0; offset < 2; offset++) {
521 if (waypoint !=
nullptr && std::get<0>(*waypoint) != 0) {
522 const JPS_StageId waitingStage = std::get<0>(*waypoint);
524 const MSLane*
const crossing = crossingState.first;
534 const double passingClearanceTime = person->
getFloatParam(
"pedestrian.timegap-crossing");
536 person->
getImpatience(), speed, 0, 0,
nullptr,
false, person);
537 if (open != crossingState.second) {
538 sumo_jupedsim_api::SetWaitingSetStateRequest waitingSetStateRequest;
539 waitingSetStateRequest.set_stage_id(waitingStage);
540 waitingSetStateRequest.set_state(open ? sumo_jupedsim_api::INACTIVE : sumo_jupedsim_api::ACTIVE);
541 callGrpc(&sumo_jupedsim_api::JuPedSimService::Stub::SetWaitingSetState, waitingSetStateRequest,
542 TLF(
"Error while setting waiting status for %:", crossing->
getID()));
543 crossingState.second = open;
550 const double slack = person->
getMaxSpeed() *
TS / 2. + POSITION_EPS;
569 for (
const auto& area :
myAreas) {
570 sumo_jupedsim_api::GetAgentsInRegionRequest agentsRequest;
571 *agentsRequest.mutable_region() = area->areaBoundary;
572 const sumo_jupedsim_api::AgentIdsResponse agentsResponse =
callGrpc(&sumo_jupedsim_api::JuPedSimService::Stub::GetAgentsInRegion,
573 agentsRequest,
TL(
"Error while retrieving agents in area: "));
574 const int numAgents = agentsResponse.agent_ids_size();
575 if (numAgents == 0) {
578 if (area->areaType ==
"vanishing_area") {
579 const SUMOTime period = area->params.count(
"period") > 0 ?
string2time(area->params.at(
"period")) : 1000;
580 const int nbrPeriodsCoveringTimestep = (int)ceil(
TS /
STEPS2TIME(period));
581 if (time - area->lastRemovalTime >= nbrPeriodsCoveringTimestep * period) {
582 for (
int k = 0; k <
MIN2(nbrPeriodsCoveringTimestep, numAgents); k++) {
583 const JPS_AgentId agentID = agentsResponse.agent_ids(k);
584 auto lambda = [agentID](
const PState *
const p) {
585 return p->getAgentId() == agentID;
589 const PState*
const state = *iterator;
594 WRITE_MESSAGEF(
TL(
"Person '%' in vanishing area '%' was removed from the simulation."), person->
getID(), area->id);
598 area->lastRemovalTime = time;
604 if (area->params.count(
"speed") == 0) {
608 sumo_jupedsim_api::SetDesiredSpeedRequest desiredSpeedRequest;
609 auto speeds = desiredSpeedRequest.mutable_desired_speeds();
610 for (
int i = 0; i < numAgents; i++) {
611 (*speeds)[agentsResponse.agent_ids(i)] = newSpeed;
613 callGrpc(&sumo_jupedsim_api::JuPedSimService::Stub::SetDesiredSpeedOfAgents, desiredSpeedRequest,
614 TL(
"Error while setting desired speed for area: "));
620 std::vector<SUMOTrafficObject::NumericalID> allStoppedTrainIDs;
621 std::vector<const MSVehicle*> allStoppedTrains;
622 for (
const auto& stop : stoppingPlaces) {
623 std::vector<const SUMOVehicle*> stoppedTrains = stop.second->getStoppedVehicles();
625 allStoppedTrainIDs.push_back(train->getNumericalID());
626 allStoppedTrains.push_back(
dynamic_cast<const MSVehicle*
>(train));
631 if (!allStoppedTrainIDs.empty()) {
632 std::vector<GEOSGeometry*> carriagePolygons;
633 std::vector<GEOSGeometry*> rampPolygons;
634 for (
const MSVehicle* train : allStoppedTrains) {
635 if (train->getLeavingPersonNumber() > 0) {
639 const std::vector<MSTrainHelper::Carriage*>& carriages = trainHelper.
getCarriages();
641 Position dir = carriage->front - carriage->back;
650 carriageShape.push_back(carriage->front + perp * p);
651 carriageShape.push_back(carriage->back + perp * p);
652 carriageShape.push_back(carriage->back - perp * p);
653 carriageShape.push_back(carriage->front - perp * p);
658 for (
const Position& door : carriage->doorPositions) {
660 rampShape.push_back(door - perp * p + dir * d);
661 rampShape.push_back(door - perp * p - dir * d);
662 rampShape.push_back(door + perp * p - dir * d);
663 rampShape.push_back(door + perp * p + dir * d);
669 if (!carriagePolygons.empty()) {
670 GEOSGeometry* carriagesCollection = GEOSGeom_createCollection(GEOS_MULTIPOLYGON, carriagePolygons.data(), (
unsigned int)carriagePolygons.size());
671 GEOSGeometry* rampsCollection = GEOSGeom_createCollection(GEOS_MULTIPOLYGON, rampPolygons.data(), (
unsigned int)rampPolygons.size());
672 GEOSGeometry* carriagesAndRampsUnion = GEOSUnion(carriagesCollection, rampsCollection);
673 if (carriagesAndRampsUnion ==
nullptr) {
677#ifdef DEBUG_GEOMETRY_GENERATION
680 int nbrComponents = 0;
681 double maxArea = 0.0;
682 double totalArea = 0.0;
683 const GEOSGeometry* pedestrianNetworkWithTrainsAndRampsLargestComponent =
getLargestComponent(pedestrianNetworkWithTrainsAndRamps, nbrComponents, maxArea, totalArea);
684 if (nbrComponents > 1) {
685 WRITE_WARNINGF(
TL(
"While generating geometry % connected components were detected, %% of total pedestrian area is covered by the largest."),
686 nbrComponents, maxArea / totalArea * 100.0,
"%");
688#ifdef DEBUG_GEOMETRY_GENERATION
692 sumo_jupedsim_api::SwitchGeometryRequest switchRequest;
694 callGrpc(&sumo_jupedsim_api::JuPedSimService::Stub::SwitchGeometry, switchRequest,
TL(
"While switching to train geometry: "),
true);
697 GEOSGeom_destroy(pedestrianNetworkWithTrainsAndRamps);
699 GEOSGeom_destroy(rampsCollection);
700 GEOSGeom_destroy(carriagesCollection);
704 sumo_jupedsim_api::SwitchGeometryRequest switchRequest;
706 callGrpc(&sumo_jupedsim_api::JuPedSimService::Stub::SwitchGeometry, switchRequest,
TL(
"While switching to default geometry: "),
true);
720 sumo_jupedsim_api::RemoveAgentsRequest removeRequest;
721 removeRequest.add_agent_ids(agentID);
722#ifdef DEBUG_GRPC_TIMING
725 callGrpc(&sumo_jupedsim_api::JuPedSimService::Stub::RemoveAgents, removeRequest,
TL(
"Error while removing agent: "));
726#ifdef DEBUG_GRPC_TIMING
741 GEOSGeometry* lineString = GEOSGeom_createLineString(coordinateSequence);
743 GEOSGeom_destroy(lineString);
744 return dilatedLineString;
751 if (shape.size() == 1) {
752 WRITE_WARNINGF(
TL(
"Polygon '%' at junction '%' will be skipped as it is just a point."), shapeID, junctionID);
756 if (shape.back() != shape.front()) {
757 shape.push_back(shape.front());
761 cleanShape.push_back(shape[0]);
763 for (
int i = 1; i < (int)shape.size(); i++) {
764 if (shape[i] != shape[i - 1]) {
765 cleanShape.push_back(shape[i]);
767 duplicates.push_back(shape[i]);
770 if (cleanShape.size() < shape.size()) {
771 WRITE_WARNINGF(
TL(
"Polygon '%' at junction '%' had some equal consecutive points removed: %"), shapeID, junctionID,
toString(duplicates, 9));
774 GEOSGeometry* linearRing = GEOSGeom_createLinearRing(coordinateSequence);
775 GEOSGeometry* polygon = GEOSGeom_createPolygon(linearRing,
nullptr, 0);
777 if (!GEOSisValid(polygon)) {
778 if (cleanShape.size() == 3) {
779 if (isInternalShape) {
780 WRITE_WARNINGF(
TL(
"Polygon '%' at junction '%' has been dilated as it is just a segment."), shapeID, junctionID);
782 WRITE_WARNINGF(
TL(
"Polygon '%' has been dilated as it is just a segment."), shapeID);
784 GEOSGeometry* lineString = GEOSGeom_createLineString(GEOSCoordSeq_clone(coordinateSequence));
785 GEOSGeom_destroy(polygon);
787 GEOSGeom_destroy(lineString);
789 if (isInternalShape) {
790 WRITE_WARNINGF(
TL(
"Polygon '%' at junction '%' has been replaced by its convex hull as it is not simple."), shapeID, junctionID);
791 GEOSGeometry* hull = GEOSConvexHull(polygon);
792 GEOSGeom_destroy(polygon);
795 WRITE_WARNINGF(
TL(
"Polygon '%' at junction '%' will be skipped as it is not simple."), shapeID, junctionID);
804 if (isInternalShape) {
814 std::vector<GEOSGeometry*> walkableAreas;
816 const MSLane*
const lane = getSidewalk<MSEdge, MSLane>(edge);
817 if (lane !=
nullptr) {
818 GEOSGeometry* dilatedLane =
nullptr;
819 if (edge->isWalkingArea()) {
821 }
else if (edge->isCrossing()) {
823 if (outlineShape !=
nullptr) {
826 if (dilatedLane !=
nullptr) {
827 walkableAreas.push_back(dilatedLane);
837 if (dilatedLane !=
nullptr) {
838 walkableAreas.push_back(dilatedLane);
843 const MSJunction*
const junction = junctionWithID.second;
844 int pedEdgeCount = 0;
845 bool hasWalkingArea =
false;
849 for (
const MSEdge*
const edge : edges) {
850 if (edge->isWalkingArea()) {
851 hasWalkingArea =
true;
854 if (getSidewalk<MSEdge, MSLane>(edge) !=
nullptr) {
858 if (hasWalkingArea) {
862 if (!hasWalkingArea && pedEdgeCount > 1) {
865 if (walkingAreaGeom !=
nullptr) {
866 walkableAreas.push_back(walkingAreaGeom);
872 std::vector<GEOSGeometry*> additionalObstacles;
874 if (polygonWithID.second->getShapeType() ==
"jupedsim.walkable_area" || polygonWithID.second->getShapeType() ==
"taz") {
875 GEOSGeometry* walkableArea =
createGeometryFromShape(polygonWithID.second->getShape(), std::string(
""), polygonWithID.first);
876 if (walkableArea !=
nullptr) {
877 walkableAreas.push_back(walkableArea);
880 }
else if (polygonWithID.second->getShapeType() ==
"jupedsim.obstacle") {
881 GEOSGeometry* additionalObstacle =
createGeometryFromShape(polygonWithID.second->getShape(), std::string(
""), polygonWithID.first);
882 if (additionalObstacle !=
nullptr) {
883 additionalObstacles.push_back(additionalObstacle);
889 GEOSGeometry* disjointWalkableAreas = GEOSGeom_createCollection(GEOS_MULTIPOLYGON, walkableAreas.data(), (
unsigned int)walkableAreas.size());
890#ifdef DEBUG_GEOMETRY_GENERATION
893 GEOSGeometry* initialWalkableAreas = GEOSUnaryUnion(disjointWalkableAreas);
894#ifdef DEBUG_GEOMETRY_GENERATION
895 dumpGeometry(initialWalkableAreas,
"initialWalkableAreas.wkt");
897 GEOSGeom_destroy(disjointWalkableAreas);
900 GEOSGeometry* disjointAdditionalObstacles = GEOSGeom_createCollection(GEOS_MULTIPOLYGON, additionalObstacles.data(), (
unsigned int)additionalObstacles.size());
901#ifdef DEBUG_GEOMETRY_GENERATION
904 GEOSGeometry* additionalObstaclesUnion = GEOSUnaryUnion(disjointAdditionalObstacles);
905#ifdef DEBUG_GEOMETRY_GENERATION
906 dumpGeometry(additionalObstaclesUnion,
"additionalObstaclesUnion.wkt");
908 GEOSGeometry* finalWalkableAreas = GEOSDifference(initialWalkableAreas, additionalObstaclesUnion);
909#ifdef DEBUG_GEOMETRY_GENERATION
910 dumpGeometry(finalWalkableAreas,
"finalWalkableAreas.wkt");
912 GEOSGeom_destroy(initialWalkableAreas);
913 GEOSGeom_destroy(additionalObstaclesUnion);
914 GEOSGeom_destroy(disjointAdditionalObstacles);
916 if (!GEOSisSimple(finalWalkableAreas)) {
917 throw ProcessError(
TL(
"Union of walkable areas minus union of obstacles is not a simple polygon."));
920 return finalWalkableAreas;
926 GEOSCoordSequence* coordinateSequence = GEOSCoordSeq_create((
unsigned int)shape.size(), 2);
927 for (
int i = 0; i < (int)shape.size(); i++) {
928 GEOSCoordSeq_setX(coordinateSequence, i, shape[i].x());
929 GEOSCoordSeq_setY(coordinateSequence, i, shape[i].y());
931 return coordinateSequence;
938 const GEOSCoordSequence* coordinateSequence = GEOSGeom_getCoordSeq(geometry);
939 unsigned int coordinateSequenceSize;
940 GEOSCoordSeq_getSize(coordinateSequence, &coordinateSequenceSize);
943 for (
unsigned int i = 0; i < coordinateSequenceSize; i++) {
944 GEOSCoordSeq_getX(coordinateSequence, i, &x);
945 GEOSCoordSeq_getY(coordinateSequence, i, &y);
946 coordinateVector.push_back(
Position(x, y));
948 return coordinateVector;
954 const GEOSCoordSequence* coordinateSequence = GEOSGeom_getCoordSeq(geometry);
955 unsigned int coordinateSequenceSize;
956 GEOSCoordSeq_getSize(coordinateSequence, &coordinateSequenceSize);
960 for (
unsigned int i = 0; i < coordinateSequenceSize - 1; i++) {
961 GEOSCoordSeq_getX(coordinateSequence, i, &x);
962 GEOSCoordSeq_getY(coordinateSequence, i, &y);
963 sumo_jupedsim_api::Point* point = into->add_points();
973 GEOSGeometry* linearRingAsPolygon = GEOSGeom_createPolygon(GEOSGeom_clone(linearRing),
nullptr, 0);
974 GEOSArea(linearRingAsPolygon, &area);
975 GEOSGeom_destroy(linearRingAsPolygon);
988 const GEOSGeometry* exterior = GEOSGetExteriorRing(polygon);
992 std::vector<PositionVector> holes;
993 int nbrInteriorRings = GEOSGetNumInteriorRings(polygon);
994 if (nbrInteriorRings != -1) {
995 for (
int k = 0; k < nbrInteriorRings; k++) {
996 const GEOSGeometry* linearRing = GEOSGetInteriorRingN(polygon, k);
1010 nbrComponents = GEOSGetNumGeometries(polygon);
1011 const GEOSGeometry* largestComponent =
nullptr;
1014 for (
int i = 0; i < nbrComponents; i++) {
1015 const GEOSGeometry* componentPolygon = GEOSGetGeometryN(polygon, i);
1017 GEOSArea(componentPolygon, &area);
1019 if (area > maxArea) {
1021 largestComponent = componentPolygon;
1024 return largestComponent;
1030 sumo_jupedsim_api::CreateGeometryRequest geometryRequest;
1031 sumo_jupedsim_api::Polygon* boundary = geometryRequest.mutable_boundary();
1034 const GEOSGeometry* exterior = GEOSGetExteriorRing(polygon);
1038 int nbrInteriorRings = GEOSGetNumInteriorRings(polygon);
1039 if (nbrInteriorRings != -1) {
1040 for (
int k = 0; k < nbrInteriorRings; k++) {
1041 const GEOSGeometry* linearRing = GEOSGetInteriorRingN(polygon, k);
1044 sumo_jupedsim_api::Polygon* hole = geometryRequest.add_obstacles();
1049 grpc::ClientContext geometryContext;
1050 sumo_jupedsim_api::CreateGeometryResponse geometryResponse;
1051 const grpc::Status geometryStatus =
myGrpcStub->CreateGeometry(&geometryContext, geometryRequest, &geometryResponse);
1052 if (!geometryStatus.ok()) {
1053 WRITE_WARNINGF(
TL(
"JuPedSim gRPC CreateGeometry failed: %"), geometryStatus.error_message());
1057 return geometryResponse.geometry_id();
1062 GEOSGeometry* polygonGeoCoordinates =
nullptr;
1063 if (useGeoCoordinates) {
1064 const GEOSGeometry* exterior = GEOSGetExteriorRing(polygon);
1066 for (
Position& position : exteriorPoints) {
1069 const int nbrInteriorRings = GEOSGetNumInteriorRings(polygon);
1070 std::vector<GEOSGeometry*> holeRings;
1071 if (nbrInteriorRings != -1) {
1072 for (
int k = 0; k < nbrInteriorRings; k++) {
1073 const GEOSGeometry* linearRing = GEOSGetInteriorRingN(polygon, k);
1075 for (
Position& position : holePoints) {
1079 GEOSGeometry* holeRing = GEOSGeom_createLinearRing(holeRingCoords);
1080 holeRings.push_back(holeRing);
1084 GEOSGeometry* exteriorRing = GEOSGeom_createLinearRing(exteriorRingCoords);
1085 polygonGeoCoordinates = GEOSGeom_createPolygon(exteriorRing, holeRings.data(), nbrInteriorRings);
1087 std::ofstream dumpFile;
1088 dumpFile.open(filename);
1089 GEOSWKTWriter* writer = GEOSWKTWriter_create();
1091 char* wkt = GEOSWKTWriter_write(writer, polygonGeoCoordinates ==
nullptr ? polygon : polygonGeoCoordinates);
1092 dumpFile << wkt << std::endl;
1095 GEOSWKTWriter_destroy(writer);
1096 GEOSGeom_destroy(polygonGeoCoordinates);
1111 const double offset = 2 * radius + POSITION_EPS;
1112 const double lonOffset = entry ? NUMERICAL_EPS : shape.
length() - NUMERICAL_EPS;
1115 for (
double latOff = offset; latOff < crossing->
getWidth() / 2. - offset; latOff += offset) {
1123 pv.push_back(crossing->
getIncomingLanes().front().lane->getShape().getCentroid());
1125 if (!entry && crossing->
getLinkCont().size() == 1 && crossing->
getLinkCont().front()->getLane()->isWalkingArea()) {
1126 pv.push_back(crossing->
getLinkCont().front()->getLane()->getShape().getCentroid());
1129 sumo_jupedsim_api::AddWaitingSetStageRequest waitingSetRequest;
1131 GEOSCoordSequence* seq = GEOSCoordSeq_create(1, 2);
1132 GEOSCoordSeq_setX(seq, 0, p.x());
1133 GEOSCoordSeq_setY(seq, 0, p.y());
1134 GEOSGeometry* geosPoint = GEOSGeom_createPoint(seq);
1136 sumo_jupedsim_api::Point* point = waitingSetRequest.add_points();
1137 point->set_x(p.x());
1138 point->set_y(p.y());
1140 WRITE_WARNINGF(
"Waiting point %,% is not in the geometry for % on '%'.", p.x(), p.y(), entry ?
"entry" :
"exit", crossing->
getID())
1142 GEOSGeom_destroy(geosPoint);
1144#ifdef DEBUG_GRPC_TIMING
1147 auto waitingSetResponse =
callGrpc(&sumo_jupedsim_api::JuPedSimService::Stub::AddWaitingSetStage, waitingSetRequest,
1148 TLF(
"Error while adding waiting set for % on '%':", entry ?
"entry" :
"exit", crossing->
getID()));
1149#ifdef DEBUG_GRPC_TIMING
1152 JPS_StageId waitingStage = waitingSetResponse.stage_id();
1154 sumo_jupedsim_api::SetWaitingSetStateRequest waitingSetStateRequest;
1155 waitingSetStateRequest.set_stage_id(waitingStage);
1156 waitingSetStateRequest.set_state(sumo_jupedsim_api::INACTIVE);
1157 callGrpc(&sumo_jupedsim_api::JuPedSimService::Stub::SetWaitingSetState, waitingSetStateRequest,
1158 TLF(
"Error while setting waiting status for % on '%':", entry ?
"entry" :
"exit", crossing->
getID()));
1161 return waitingStage;
1167 initGEOS(
nullptr,
nullptr);
1170 int nbrComponents = 0;
1171 double maxArea = 0.0;
1172 double totalArea = 0.0;
1174 if (nbrComponents > 1) {
1175 WRITE_WARNINGF(
TL(
"While generating geometry % connected components were detected, %% of total pedestrian area is covered by the largest."),
1176 nbrComponents, maxArea / totalArea * 100.0,
"%");
1178#ifdef DEBUG_GEOMETRY_GENERATION
1181 const std::string filename = oc.
getString(
"pedestrian.jupedsim.wkt");
1182 if (!filename.empty()) {
1191 double strengthGeometryRepulsion = oc.
getFloat(
"pedestrian.jupedsim.strength-geometry-repulsion");
1192 double rangeGeometryRepulsion = oc.
getFloat(
"pedestrian.jupedsim.range-geometry-repulsion");
1194 if (oc.
isDefault(
"pedestrian.jupedsim.strength-geometry-repulsion") && oc.
isDefault(
"pedestrian.jupedsim.range-geometry-repulsion")) {
1195 WRITE_MESSAGE(
TL(
"Adapting geometry repulsion default values for jupedsim timestep of 0.02."));
1196 strengthGeometryRepulsion = 35.;
1197 rangeGeometryRepulsion = 0.019;
1200 sumo_jupedsim_api::CreateSimulationRequest simulationRequest;
1202 simulationRequest.set_model_class(
myJPSModel);
1206 auto& modelParams = *simulationRequest.mutable_model_parameters()->mutable_fields();
1207 if (
myJPSModel ==
"CollisionFreeSpeedModel") {
1208 modelParams[
"strength_neighbor_repulsion"].set_number_value(oc.
getFloat(
"pedestrian.jupedsim.strength-neighbor-repulsion"));
1209 modelParams[
"range_neighbor_repulsion"].set_number_value(oc.
getFloat(
"pedestrian.jupedsim.range-neighbor-repulsion"));
1210 modelParams[
"strength_geometry_repulsion"].set_number_value(strengthGeometryRepulsion);
1211 modelParams[
"range_geometry_repulsion"].set_number_value(rangeGeometryRepulsion);
1212 }
else if (
myJPSModel ==
"CollisionFreeSpeedModelV2") {
1214 }
else if (
myJPSModel ==
"GeneralizedCentrifugalForceModel") {
1215 modelParams[
"strength_neighbor_repulsion"].set_number_value(oc.
getFloat(
"pedestrian.jupedsim.strength-neighbor-repulsion"));
1216 modelParams[
"strength_geometry_repulsion"].set_number_value(strengthGeometryRepulsion);
1217 }
else if (
myJPSModel ==
"SocialForceModel") {
1218 modelParams[
"body_force"].set_number_value(120000.0);
1219 modelParams[
"friction"].set_number_value(240000.0);
1221 grpc::ClientContext simulationContext;
1222 sumo_jupedsim_api::CreateSimulationResponse simulationResponse;
1223 const grpc::Status simulationStatus =
myGrpcStub->CreateSimulation(&simulationContext, simulationRequest, &simulationResponse);
1224 if (simulationStatus.ok()) {
1227 throw ProcessError(
TLF(
"JuPedSim gRPC CreateSimulation failed: %", simulationStatus.error_message()));
1242 for (
auto areaIt =
myAreas.begin(); areaIt !=
myAreas.end(); ++areaIt) {
1243 if (poly->
getID() == (*areaIt)->id) {
1244 lastRemovalTime = (*areaIt)->lastRemovalTime;
1251 sumo_jupedsim_api::Polygon areaBoundary;
1253 sumo_jupedsim_api::Point* point = areaBoundary.add_points();
1254 point->set_x(p.x());
1255 point->set_y(p.y());
1273 const std::vector<WaypointDesc>& waypoints) :
1275 myJourneyId(journeyId), myStageId(stageId), myWaypoints(waypoints), myAgentId(0) {
1282 const std::vector<WaypointDesc>& waypoints) {
1283 if (myStage !=
nullptr) {
1284 myStage->setPState(
nullptr);
1287 myJourneyId = journeyId;
1288 myStageId = stageId;
1289 myWaypoints = waypoints;
1303 myRemoteXYPos.set(x, y, z);
1314 return offset < (int)myWaypoints.size() ? &myWaypoints[offset] :
nullptr;
std::vector< const MSEdge * > ConstMSEdgeVector
#define WRITE_WARNINGF(...)
#define WRITE_MESSAGEF(...)
#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
double getLength() const
return the length of the edge
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.
bool isWalkingArea() const
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_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.)
int64_t buildJPSGeometryFromGEOSGeometry(const GEOSGeometry *polygon)
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
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.
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
static const std::string PEDESTRIAN_NETWORK_ID
std::map< const MSLane *, JPS_StageId, ComparatorNumericalIdLess > myLaneCenters
static GEOSGeometry * createGeometryFromShape(PositionVector shape, std::string junctionID=std::string(""), std::string shapeID=std::string(""), bool isInternalShape=false)
static GEOSCoordSequence * convertToGEOSPoints(PositionVector shape)
int64_t myJPSGeometry
The JPS polygon representing the largest connected component of the pedestrian network.
GEOSGeometry * myGEOSPedestrianNetwork
The GEOS polygon containing all computed connected components of the pedestrian network.
static void convertToJPSPoints(const GEOSGeometry *geometry, sumo_jupedsim_api::Polygon *into)
static void dumpGeometry(const GEOSGeometry *polygon, const std::string &filename, bool useGeoCoordinates=false)
bool myHaveAdditionalWalkableAreas
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::shared_ptr< grpc::Channel > myGrpcChannel
void polygonChanged(const SUMOPolygon *const poly, const bool added, const bool removed) override
static const double GEOS_MIN_AREA
void initialize(const OptionsCont &oc)
GEOSGeometry * buildPedestrianNetwork(MSNet *network)
void remove(MSTransportableStateAdapter *state) override
remove the specified person from the pedestrian simulation
std::vector< StopWatch< std::chrono::nanoseconds > > myStopWatch
std::vector< std::unique_ptr< AreaData > > myAreas
Array of special areas.
static double getLinearRingArea(const GEOSGeometry *linearRing)
std::unique_ptr< sumo_jupedsim_api::JuPedSimService::Stub > myGrpcStub
SumoRNG myRNG
The random number generator for fluctuations on insertion.
std::tuple< JPS_StageId, const MSLane *, Position, double > WaypointDesc
void clearState() override
Resets pedestrians when quick-loading state.
Response callGrpc(grpc::Status(sumo_jupedsim_api::JuPedSimService::Stub::*method)(grpc::ClientContext *, const Request &, Response *), Request &request, const std::string &what, const bool warnOnly=false)
ShapeContainer & myShapeContainer
The shape container used to add polygons to the rendering pipeline.
std::vector< PState * > myPedestrianStates
JPS_StageId addWaitingSet(const MSLane *const crossing, const bool entry)
int64_t myJPSGeometryWithTrainsAndRamps
The JPS polygon representing the largest connected component plus carriages and ramps.
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)
JPS_StageId addWaypoint(const std::string &agentID, WaypointDesc &waypoint, const MSStageMoving *const finalStage)
void tryPedestrianInsertion(PState *state, const Position &p)
SUMOTime execute(SUMOTime time)
static const double GEOS_BUFFERED_SEGMENT_WIDTH
std::map< JPS_StageId, std::pair< const MSLane *, bool > > myCrossings
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)
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
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.
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.
Position getCentroid() const
Returns the centroid (closes the polygon if unclosed)
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)
static int getFreeSocketPort()
Returns an free port on the system.
#define UNUSED_PARAMETER(x)
Structure that keeps data related to vanishing areas (and other types of areas).