Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' of github.com:eclipse-sumo/sumo into Netedit_dev
Browse files Browse the repository at this point in the history
palvarezlopez committed Jan 16, 2025
2 parents c221321 + 927af3e commit a170f73
Showing 526 changed files with 317,690 additions and 200,181 deletions.
2 changes: 1 addition & 1 deletion docs/web/docs/Demand/Shortest_or_Optimal_Path_Routing.md
Original file line number Diff line number Diff line change
@@ -50,7 +50,7 @@ the router using an XML-file. The syntax of a single trip definition is:
| fromLonLat | float, float | The network position from which to depart in geo-coordinates [note](#mapmatching) |
| toLonLat | float, float | The network position from which to depart in geo-coordinates [note](#mapmatching) |
| viaLonLat | float, float [float,float] | The network positions to pass along the way in geo-coordinates [note](#mapmatching) |
| speedFactor | float > 0 | Sets custom speedFactor (factor on road speed limit) and overrides the [speedFactor distribution](#speed_distributions) of the vehicle type |
| speedFactor | float > 0 | Sets custom speedFactor (factor on road speed limit) and overrides the [speedFactor distribution](../Definition_of_Vehicles%2C_Vehicle_Types%2C_and_Routes.md#speed_distributions) of the vehicle type |
| insertionChecks | string list | Sets the list of safety checks to perform during vehicle insertion. Possible values are: `all`, `none`, `collision`, `leaderGap`, `followerGap`, `junction`, `stop`, `arrivalSpeed`, `oncomingTrain`, `speedLimit`, `pedestrians`. default *all* |
| parkingBadges | string list | list of keywords to access restricted parking areas (the default empty list will still allow access to unrestricted parking areas) |

1 change: 1 addition & 0 deletions docs/web/docs/Netedit/index.md
Original file line number Diff line number Diff line change
@@ -233,6 +233,7 @@ Right clicking over an element will open a popup-menu with functions and operati
- [Converting an intersection into a roundabout](neteditUsageExamples.md#converting_an_intersection_into_a_roundabout)
- [Correcting road access permissions](neteditUsageExamples.md#correcting_road_access_permissions)
- [Creating bidirectional railway tracks](neteditUsageExamples.md#creating_bidirectional_railway_tracks)
- [Creating pedestrian infrastructure](neteditUsageExamples.md#building_pedestrian_infrastructure)
- [**+ many others**](neteditUsageExamples.md).

# Planned Features
17 changes: 17 additions & 0 deletions docs/web/docs/Netedit/neteditUsageExamples.md
Original file line number Diff line number Diff line change
@@ -250,3 +250,20 @@ There is also another solution in case you want to add special lanes to your edg
- explanation: This makes it so that the inside lanes in both directions are directly on top of each other
4. go to inspect mode and inspect the selection of edges
5. activate the 'isBidi' checkbox

## Building Pedestrian infrastructure

In order to [simulate pedestrians](../Simulation/Pedestrians.md), the network needs sidewalks (or footpaths), walkingareas and it will usually contain pedestrian crossings.
For pedestrian simulation to work, every lane of the network that is not meant for a shared-space simulation, should either disallow road vehicles or disallow pedestrian use.
Prohibiting pedestrians from walking on the road can be accomplished using the 'allow' attribute of lanes but will happen automatically when either

- edges are created and the 'add Sidwalk' option is active
- edges are created with a custom 'allow' value (i.e. 'pedestrian' or 'passenger')
- edge context menu function 'Lane operations/Add restricted Lane/Sidwealk' is applied to an edge or a selection of edges

Crossings can be created with 'crossing mode' by clicking on a junction and then clicking on one or more edges to be crossed and confirming with <kbd>ENTER</kbd>
!!! note
Crossings can only be created if the edges to be crossed have lanes that prohibit pedestrian use

Walkingareas are created automatically if the network contains at least one pedestrian crossing or if option **walkingareas** is set in the options screen (<kd>F10</kbd>, in the Pedestrians tab).
They will be created wherever footpaths or sidewalks are bordered by lanes that prohibit pedestrian use.
34 changes: 22 additions & 12 deletions src/guisim/GUITriggeredRerouter.cpp
Original file line number Diff line number Diff line change
@@ -238,9 +238,12 @@ GUITriggeredRerouter::GUITriggeredRerouter(const std::string& id, const MSEdgeVe
myShiftProbDistIndex(0) {
// add visualisation objects for edges which trigger the rerouter
for (MSEdgeVector::const_iterator it = edges.begin(); it != edges.end(); ++it) {
myEdgeVisualizations.push_back(new GUITriggeredRerouterEdge(dynamic_cast<GUIEdge*>(*it), this, REROUTER_TRIGGER_EDGE));
myEdgeVisualizations.push_back(new GUITriggeredRerouterEdge(dynamic_cast<GUIEdge*>(*it), this, REROUTER_TRIGGER_EDGE, -1, pos, radius));
rtree.addAdditionalGLObject(myEdgeVisualizations.back());
myBoundary.add(myEdgeVisualizations.back()->getCenteringBoundary());
if (pos != Position::INVALID) {
break;
}
}
}

@@ -382,25 +385,32 @@ GUITriggeredRerouter::shiftProbs() {
/* -------------------------------------------------------------------------
* GUITriggeredRerouterEdge - methods
* ----------------------------------------------------------------------- */
GUITriggeredRerouter::GUITriggeredRerouterEdge::GUITriggeredRerouterEdge(GUIEdge* edge, GUITriggeredRerouter* parent, RerouterEdgeType edgeType, int distIndex) :
GUITriggeredRerouter::GUITriggeredRerouterEdge::GUITriggeredRerouterEdge(GUIEdge* edge, GUITriggeredRerouter* parent, RerouterEdgeType edgeType, int distIndex,
const Position& pos, const double radius) :
GUIGlObject(GLO_REROUTER_EDGE, parent->getID() + ":" + edge->getID(), GUIIconSubSys::getIcon(GUIIcon::REROUTER)),
myParent(parent),
myEdge(edge),
myEdgeType(edgeType),
myDistIndex(distIndex) {
UNUSED_PARAMETER(radius); // it would be nice to have this in the visualization too
const std::vector<MSLane*>& lanes = edge->getLanes();
myFGPositions.reserve(lanes.size());
myFGRotations.reserve(lanes.size());
for (const MSLane* lane : lanes) {
if ((lane->getPermissions() & ~SVC_PEDESTRIAN) == 0) {
continue;
if (pos == Position::INVALID) {
for (const MSLane* lane : lanes) {
if ((lane->getPermissions() & ~SVC_PEDESTRIAN) == 0) {
continue;
}
const PositionVector& v = lane->getShape();
const double lanePos = edgeType == REROUTER_TRIGGER_EDGE ? MAX2(0.0, v.length() - 6) : MIN2(v.length(), 3.0);
myFGPositions.push_back(v.positionAtOffset(lanePos));
myFGRotations.push_back(-v.rotationDegreeAtOffset(lanePos));
myBoundary.add(myFGPositions.back());
myHalfWidths.push_back(lane->getWidth() * 0.5 * 0.875);
}
const PositionVector& v = lane->getShape();
const double pos = edgeType == REROUTER_TRIGGER_EDGE ? MAX2(0.0, v.length() - 6) : MIN2(v.length(), 3.0);
myFGPositions.push_back(v.positionAtOffset(pos));
myFGRotations.push_back(-v.rotationDegreeAtOffset(pos));
} else {
myFGPositions.push_back(pos);
myFGRotations.push_back(0);
myBoundary.add(myFGPositions.back());
myHalfWidths.push_back(lane->getWidth() * 0.5 * 0.875);
myHalfWidths.push_back(SUMO_const_halfLaneWidth * 0.875);
}
}

3 changes: 2 additions & 1 deletion src/guisim/GUITriggeredRerouter.h
Original file line number Diff line number Diff line change
@@ -130,7 +130,8 @@ class GUITriggeredRerouter
class GUITriggeredRerouterEdge : public GUIGlObject {

public:
GUITriggeredRerouterEdge(GUIEdge* edge, GUITriggeredRerouter* parent, RerouterEdgeType edgeType, int distIndex = -1);
GUITriggeredRerouterEdge(GUIEdge* edge, GUITriggeredRerouter* parent, RerouterEdgeType edgeType, int distIndex = -1,
const Position& pos = Position::INVALID, const double radius = std::numeric_limits<double>::max());

virtual ~GUITriggeredRerouterEdge();

14 changes: 11 additions & 3 deletions src/microsim/MSVehicle.cpp
Original file line number Diff line number Diff line change
@@ -1247,6 +1247,9 @@ MSVehicle::getPosition(const double offset) const {
}
}
if (isParking()) {
if (myInfluencer != nullptr && myInfluencer->getLastAccessTimeStep() > getNextStopParameter()->started) {
return myCachedPosition;
}
if (myStops.begin()->parkingarea != nullptr) {
return myStops.begin()->parkingarea->getVehiclePosition(*this);
} else {
@@ -4815,7 +4818,7 @@ MSVehicle::executeFractionalMove(double dist) {


void
MSVehicle::updateState(double vNext) {
MSVehicle::updateState(double vNext, bool parking) {
// update position and speed
double deltaPos; // positional change
if (MSGlobals::gSemiImplicitEulerUpdate) {
@@ -4865,12 +4868,14 @@ MSVehicle::updateState(double vNext) {
myState.myLastCoveredDist = deltaPos;
myNextTurn.first -= deltaPos;

myCachedPosition = Position::INVALID;
if (!parking) {
myCachedPosition = Position::INVALID;
}
}

void
MSVehicle::updateParkingState() {
updateState(0);
updateState(0, true);
// deboard while parked
if (myPersonDevice != nullptr) {
myPersonDevice->notifyMove(*this, getPositionOnLane(), getPositionOnLane(), 0);
@@ -5648,6 +5653,9 @@ MSVehicle::enterLaneAtInsertion(MSLane* enteredLane, double pos, double speed, d
// schedule action for the next timestep
myLastActionTime = MSNet::getInstance()->getCurrentTimeStep() + DELTA_T;
if (notification != MSMoveReminder::NOTIFICATION_TELEPORT) {
if (notification == MSMoveReminder::NOTIFICATION_PARKING && myInfluencer != nullptr) {
drawOutsideNetwork(false);
}
// set and activate the new lane's reminders, teleports already did that at enterLaneAtMove
for (std::vector< MSMoveReminder* >::const_iterator rem = enteredLane->getMoveReminders().begin(); rem != enteredLane->getMoveReminders().end(); ++rem) {
addReminder(*rem);
2 changes: 1 addition & 1 deletion src/microsim/MSVehicle.h
Original file line number Diff line number Diff line change
@@ -2109,7 +2109,7 @@ class MSVehicle : public MSBaseVehicle {
* acceleration a within the next time step is then a = (vNext - vCurrent)/TS )
* @param[in] vNext speed in the next time step
*/
void updateState(double vNext);
void updateState(double vNext, bool parking = false);


/// @brief decide whether the given link must be kept clear
25 changes: 18 additions & 7 deletions src/microsim/devices/MSRoutingEngine.cpp
Original file line number Diff line number Diff line change
@@ -182,13 +182,9 @@ SumoRNG*
MSRoutingEngine::getThreadRNG() {
if (myHaveRoutingThreads) {
auto it = myThreadRNGs.find(std::this_thread::get_id());
if (it != myThreadRNGs.end()) {
return it->second;
} else {
SumoRNG* rng = new SumoRNG("routing_" + toString(myThreadRNGs.size()));
myThreadRNGs[std::this_thread::get_id()] = rng;
return rng;
}
// created by InitTask
assert(it != myThreadRNGs.end());
return it->second;
}
return nullptr;
}
@@ -435,6 +431,10 @@ MSRoutingEngine::initRouter(SUMOVehicle* vehicle) {
}
}
myHaveRoutingThreads = true;
for (int i = 0; i < threadPool.size(); i++) {
threadPool.add(new InitTask(), i);
}
threadPool.waitAll();
}
#endif
#endif
@@ -639,6 +639,17 @@ MSRoutingEngine::RoutingTask::run(MFXWorkerThread* context) {
}
}
}

// ---------------------------------------------------------------------------
// MSRoutingEngine::InitTask-methods
// ---------------------------------------------------------------------------
void
MSRoutingEngine::InitTask::run(MFXWorkerThread* /*context*/) {
FXMutexLock lock(myRouteCacheMutex);
SumoRNG* rng = new SumoRNG("routing_" + toString(myThreadRNGs.size()));
myThreadRNGs[std::this_thread::get_id()] = rng;
}

#endif


13 changes: 13 additions & 0 deletions src/microsim/devices/MSRoutingEngine.h
Original file line number Diff line number Diff line change
@@ -172,6 +172,19 @@ class MSRoutingEngine {
/// @brief Invalidated assignment operator.
RoutingTask& operator=(const RoutingTask&) = delete;
};

/**
* @class InitTask
* @brief setup RNGs for each thread (with proper locking so we don't need
* locking later */
class InitTask : public MFXWorkerThread::Task {
public:
InitTask() {}
void run(MFXWorkerThread* context);
private:
/// @brief Invalidated assignment operator.
RoutingTask& operator=(const RoutingTask&) = delete;
};
#endif

/// @name Network state adaptation
17 changes: 9 additions & 8 deletions src/microsim/transportables/MSPModel_JuPedSim.cpp
Original file line number Diff line number Diff line change
@@ -390,6 +390,7 @@ MSPModel_JuPedSim::remove(MSTransportableStateAdapter* state) {
if (pstate->getLane() != nullptr) {
auto& peds = myActiveLanes[pstate->getLane()];
peds.erase(std::find(peds.begin(), peds.end(), pstate));
pstate->setLane(nullptr);
}
if (pstate->getStage() != nullptr) {
pstate->getStage()->setPState(nullptr); // we need to remove the old state reference to avoid double deletion
@@ -426,8 +427,8 @@ MSPModel_JuPedSim::execute(SUMOTime time) {
continue;
}

MSPerson* person = state->getPerson();
MSStageWalking* stage = dynamic_cast<MSStageWalking*>(person->getCurrentStage());
MSPerson* const person = state->getPerson();
MSStageWalking* const stage = dynamic_cast<MSStageWalking*>(person->getCurrentStage());
if (stage == nullptr) {
// It seems we kept the state for another stage but the new stage is not a walk.
// So let's remove the state because after the new stage we will be elsewhere and need to be reinserted for JuPedSim anyway.
@@ -450,6 +451,7 @@ MSPModel_JuPedSim::execute(SUMOTime time) {
Position newPosition(position.x, position.y);
ConstMSEdgeVector route = stage->getEdges();
const int routeIndex = (int)(stage->getRouteStep() - stage->getRoute().begin());
const double oldLanePos = state->getEdgePos(time);
ConstMSEdgeVector forwardRoute = ConstMSEdgeVector(route.begin() + routeIndex, route.end());
double bestDistance = std::numeric_limits<double>::max();
MSLane* candidateLane = nullptr;
@@ -462,9 +464,7 @@ MSPModel_JuPedSim::execute(SUMOTime time) {
if (candidateLane != state->getLane()) {
if (state->getLane() != nullptr) {
auto& peds = myActiveLanes[state->getLane()];
if (!peds.empty()) {
peds.erase(std::find(peds.begin(), peds.end(), state));
}
peds.erase(std::find(peds.begin(), peds.end(), state));
}
myActiveLanes[candidateLane].push_back(state);
state->setLane(candidateLane);
@@ -530,6 +530,7 @@ MSPModel_JuPedSim::execute(SUMOTime time) {
JPS_WaitingSetProxy_SetWaitingSetState(proxy, open ? JPS_WaitingSet_Inactive : JPS_WaitingSet_Active);
}
}
stage->activateMoveReminders(person, oldLanePos, state->getEdgePos(time), state->getSpeed(*stage));
// In the worst case during one SUMO step the person touches the waypoint radius and walks immediately into a different direction,
// but at some simstep it should have a maximum distance of v * delta_t / 2 to the waypoint circle.
const double slack = person->getMaxSpeed() * TS / 2. + POSITION_EPS;
@@ -1300,13 +1301,13 @@ MSPModel_JuPedSim::PState::~PState() {
}


void MSPModel_JuPedSim::PState::setPosition(double x, double y) {
void MSPModel_JuPedSim::PState::setPosition(const double x, const double y, const double z) {
if (myRemoteXYPos != Position::INVALID) {
mySpeed = myRemoteXYPos.distanceTo2D(Position(x, y)) / STEPS2TIME(DELTA_T);
mySpeed = myRemoteXYPos.distanceTo2D(Position(x, y, z)) / STEPS2TIME(DELTA_T);
} else {
mySpeed = 0.;
}
myRemoteXYPos.set(x, y);
myRemoteXYPos.set(x, y, z);
}


2 changes: 1 addition & 1 deletion src/microsim/transportables/MSPModel_JuPedSim.h
Original file line number Diff line number Diff line change
@@ -95,7 +95,7 @@ class MSPModel_JuPedSim : public MSPModel_Interacting {
inline Position getPosition(const MSStageMoving&, SUMOTime) const override {
return myRemoteXYPos;
}
void setPosition(double x, double y);
void setPosition(const double x, const double y, const double z = 0.);

inline void setAngle(double angle) {
myAngle = angle;
32 changes: 22 additions & 10 deletions src/microsim/transportables/MSStageWalking.cpp
Original file line number Diff line number Diff line change
@@ -393,16 +393,6 @@ MSStageWalking::moveToNextEdge(MSTransportable* person, SUMOTime currentTime, in
}


void
MSStageWalking::activateLeaveReminders(MSTransportable* person, const MSLane* lane, double lastPos, SUMOTime t, bool arrived) {
MSMoveReminder::Notification notification = arrived ? MSMoveReminder::NOTIFICATION_ARRIVED : MSMoveReminder::NOTIFICATION_JUNCTION;
for (MSMoveReminder* const rem : myMoveReminders) {
rem->updateDetector(*person, 0.0, lane->getLength(), myLastEdgeEntryTime, t, t, true);
rem->notifyLeave(*person, lastPos, notification);
}
}


void
MSStageWalking::activateEntryReminders(MSTransportable* person, const bool isDepart) {
const MSLane* const nextLane = getSidewalk<MSEdge, MSLane>(getEdge());
@@ -434,6 +424,28 @@ MSStageWalking::activateEntryReminders(MSTransportable* person, const bool isDep
}


void
MSStageWalking::activateMoveReminders(MSTransportable* person, double oldPos, double newPos, double newSpeed) {
for (std::vector<MSMoveReminder*>::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
if ((*rem)->notifyMove(*person, oldPos, newPos, newSpeed)) {
++rem;
} else {
rem = myMoveReminders.erase(rem);
}
}
}


void
MSStageWalking::activateLeaveReminders(MSTransportable* person, const MSLane* lane, double lastPos, SUMOTime t, bool arrived) {
MSMoveReminder::Notification notification = arrived ? MSMoveReminder::NOTIFICATION_ARRIVED : MSMoveReminder::NOTIFICATION_JUNCTION;
for (MSMoveReminder* const rem : myMoveReminders) {
rem->updateDetector(*person, 0.0, lane->getLength(), myLastEdgeEntryTime, t, t, true);
rem->notifyLeave(*person, lastPos, notification);
}
}


int
MSStageWalking::getRoutePosition() const {
return (int)(myRouteStep - myRoute.begin());
2 changes: 2 additions & 0 deletions src/microsim/transportables/MSStageWalking.h
Original file line number Diff line number Diff line change
@@ -117,6 +117,8 @@ class MSStageWalking : public MSStageMoving {

void activateEntryReminders(MSTransportable* person, const bool isDepart = false);

void activateMoveReminders(MSTransportable* person, double oldPos, double newPos, double newSpeed);

void activateLeaveReminders(MSTransportable* person, const MSLane* lane, double lastPos, SUMOTime t, bool arrived);

/// @brief accessors to be used by MSPModel
5 changes: 4 additions & 1 deletion src/microsim/trigger/MSTriggeredRerouter.cpp
Original file line number Diff line number Diff line change
@@ -105,6 +105,9 @@ MSTriggeredRerouter::MSTriggeredRerouter(const std::string& id,
}
const std::vector<std::string> vt = StringTokenizer(vTypes).getVector();
myVehicleTypes.insert(vt.begin(), vt.end());
if (myPosition == Position::INVALID) {
myPosition = edges.front()->getLanes()[0]->getShape()[0];
}
}


@@ -389,7 +392,7 @@ MSTriggeredRerouter::getCurrentReroute(SUMOTime time) const {

bool
MSTriggeredRerouter::notifyEnter(SUMOTrafficObject& tObject, MSMoveReminder::Notification reason, const MSLane* /* enteredLane */) {
if (myAmOptional) {
if (myAmOptional || myRadius != std::numeric_limits<double>::max()) {
return true;
}
return triggerRouting(tObject, reason);
Loading

0 comments on commit a170f73

Please sign in to comment.