Eclipse SUMO - Simulation of Urban MObility
MSPModel_Striping.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2014-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
16 // The pedestrian following model (prototype)
17 /****************************************************************************/
18 
19 // ===========================================================================
20 // included modules
21 // ===========================================================================
22 #include <config.h>
23 
24 #include <cmath>
25 #include <algorithm>
27 #include <utils/geom/GeomHelper.h>
30 #include <microsim/MSNet.h>
31 #include <microsim/MSEdge.h>
33 #include <microsim/MSLane.h>
34 #include <microsim/MSJunction.h>
35 #include <microsim/MSGlobals.h>
37 #include "MSPModel_Striping.h"
38 
39 
40 // ===========================================================================
41 // DEBUGGING HELPERS
42 // ===========================================================================
43 //
44 #define DEBUGID1 ""
45 #define DEBUGID2 ""
46 //#define DEBUGCOND(PED) (false)
47 //#define DEBUGCOND(PED) ((PED).myPerson->getID() == DEBUGID1 || (PED).myPerson->getID() == DEBUGID2)
48 #define DEBUGCOND(PED) ((PED).myPerson->isSelected())
49 #define DEBUGCOND2(LANE) ((LANE)->isSelected())
50 //#define LOG_ALL 1
51 
53  for (int i = 0; i < (int)obs.size(); ++i) {
54  std::cout
55  << "(" << obs[i].description
56  << " x=(" << obs[i].xBack << "," << obs[i].xFwd
57  << ") s=" << obs[i].speed
58  << ") ";
59  }
60  std::cout << "\n";
61 }
62 
63 // ===========================================================================
64 // named (internal) constants
65 // ===========================================================================
66 
67 // distances are comparable with lower values being "more important"
68 const double MSPModel_Striping::DIST_FAR_AWAY(10000);
69 const double MSPModel_Striping::DIST_BEHIND(1000);
70 const double MSPModel_Striping::DIST_OVERLAP(-1);
71 
72 // ===========================================================================
73 // static members
74 // ===========================================================================
75 
77 std::map<const MSEdge*, std::vector<const MSLane*> > MSPModel_Striping::myWalkingAreaFoes;
80 
81 // model parameters (static to simplify access from class PState
86 const double MSPModel_Striping::LOOKAHEAD_SAMEDIR(4.0); // seconds
87 const double MSPModel_Striping::LOOKAHEAD_ONCOMING(10.0); // seconds
88 const double MSPModel_Striping::LOOKAROUND_VEHICLES(60.0); // meters
89 const double MSPModel_Striping::LATERAL_PENALTY(-1.); // meters
90 const double MSPModel_Striping::OBSTRUCTED_PENALTY(-300000.); // meters
91 const double MSPModel_Striping::INAPPROPRIATE_PENALTY(-20000.); // meters
92 const double MSPModel_Striping::ONCOMING_CONFLICT_PENALTY(-1000.); // meters
93 const double MSPModel_Striping::OBSTRUCTION_THRESHOLD(MSPModel_Striping::OBSTRUCTED_PENALTY * 0.5); // despite obstruction, additional utility may have been added
94 const double MSPModel_Striping::SQUEEZE(0.7);
97 const double MSPModel_Striping::MAX_WAIT_TOLERANCE(120.); // seconds
99 const double MSPModel_Striping::MIN_STARTUP_DIST(0.4); // meters
100 
101 #define MINGAP_TO_VEHICLE 0.25
102 
103 
104 // ===========================================================================
105 // MSPModel_Striping method definitions
106 // ===========================================================================
107 
109  myNumActivePedestrians(0),
110  myAmActive(false) {
112  // configurable parameters
113  stripeWidth = oc.getFloat("pedestrian.striping.stripe-width");
114  dawdling = oc.getFloat("pedestrian.striping.dawdling");
115 
116  jamTime = string2time(oc.getString("pedestrian.striping.jamtime"));
117  if (jamTime <= 0) {
119  }
120  jamTimeCrossing = string2time(oc.getString("pedestrian.striping.jamtime.crossing"));
121  if (jamTimeCrossing <= 0) {
123  }
124 }
125 
126 
128 }
129 
130 
133  MSNet* net = MSNet::getInstance();
134  if (!myAmActive) {
136  myAmActive = true;
137  }
139  const MSLane* lane = getSidewalk<MSEdge, MSLane>(person->getEdge());
140  if (lane == nullptr) {
141  std::string error = "Person '" + person->getID() + "' could not find sidewalk on edge '" + person->getEdge()->getID() + "', time="
142  + time2string(net->getCurrentTimeStep()) + ".";
143  if (OptionsCont::getOptions().getBool("ignore-route-errors")) {
144  WRITE_WARNING(error);
145  return nullptr;
146  } else {
147  throw ProcessError(error);
148  }
149  }
150  PState* ped = new PState(person, stage, lane);
151  myActiveLanes[lane].push_back(ped);
153  return ped;
154 }
155 
156 
157 void
159  PState* ped = dynamic_cast<PState*>(pState);
160  assert(ped != 0);
161  myActiveLanes[lane].push_back(ped);
162 }
163 
164 
165 void
167  const MSLane* lane = dynamic_cast<PState*>(state)->myLane;
168  Pedestrians& pedestrians = myActiveLanes[lane];
169  for (Pedestrians::iterator it = pedestrians.begin(); it != pedestrians.end(); ++it) {
170  if (*it == state) {
171  pedestrians.erase(it);
172  return;
173  }
174  }
175 }
176 
177 
178 bool
179 MSPModel_Striping::blockedAtDist(const MSLane* lane, double vehSide, double vehWidth,
180  double oncomingGap, std::vector<const MSPerson*>* collectBlockers) {
181  const Pedestrians& pedestrians = getPedestrians(lane);
182  for (Pedestrians::const_iterator it_ped = pedestrians.begin(); it_ped != pedestrians.end(); ++it_ped) {
183  const PState& ped = **it_ped;
184  const double leaderFrontDist = (ped.myDir == FORWARD ? vehSide - ped.myRelX : ped.myRelX - vehSide);
185  const double leaderBackDist = leaderFrontDist + ped.getLength();
186  if DEBUGCOND(ped) {
187  std::cout << SIMTIME << " lane=" << lane->getID() << " dir=" << ped.myDir << " pX=" << ped.myRelX << " pL=" << ped.getLength()
188  << " vehSide=" << vehSide
189  << " vehWidth=" << vehWidth
190  << " lBD=" << leaderBackDist
191  << " lFD=" << leaderFrontDist
192  << "\n";
193  }
194  if (leaderBackDist >= -vehWidth
195  && (leaderFrontDist < 0
196  // give right of way to (close) approaching pedestrians unless they are standing
197  || (leaderFrontDist <= oncomingGap && ped.myWaitingTime < TIME2STEPS(2.0)))) {
198  // found one pedestrian that is not completely past the crossing point
199  //std::cout << SIMTIME << " blocking pedestrian foeLane=" << lane->getID() << " ped=" << ped.myPerson->getID() << " dir=" << ped.myDir << " pX=" << ped.myRelX << " pL=" << ped.getLength() << " fDTC=" << distToCrossing << " lBD=" << leaderBackDist << "\n";
200  if (collectBlockers == nullptr) {
201  return true;
202  } else {
203  collectBlockers->push_back(ped.myPerson);
204  }
205  }
206  }
207  if (collectBlockers == nullptr) {
208  return false;
209  } else {
210  return collectBlockers->size() > 0;
211  }
212 }
213 
214 
215 bool
217  return getPedestrians(lane).size() > 0;
218 }
219 
220 
221 bool
223  return usingInternalLanesStatic();
224 }
225 
226 bool
229 }
230 
232 MSPModel_Striping::nextBlocking(const MSLane* lane, double minPos, double minRight, double maxLeft, double stopTime) {
233  PersonDist result((const MSPerson*)nullptr, -1);
234  double closest = std::numeric_limits<double>::max();
235  const Pedestrians& pedestrians = getPedestrians(lane);
236  for (Pedestrians::const_iterator it_ped = pedestrians.begin(); it_ped != pedestrians.end(); ++it_ped) {
237  const PState& ped = **it_ped;
238  // account for distance covered by oncoming pedestrians
239  double relX2 = ped.myRelX - (ped.myDir == FORWARD ? 0 : stopTime * ped.myPerson->getVehicleType().getMaxSpeed());
240  if (ped.myRelX > minPos && (result.first == 0 || closest > relX2)) {
241  const double center = lane->getWidth() - (ped.myRelY + stripeWidth * 0.5);
242  const double halfWidth = 0.5 * ped.myPerson->getVehicleType().getWidth();
243  const bool overlap = (center + halfWidth > minRight && center - halfWidth < maxLeft);
244  if DEBUGCOND(ped) {
245  std::cout << " nextBlocking lane=" << lane->getID()
246  << " minPos=" << minPos << " minRight=" << minRight << " maxLeft=" << maxLeft
247  << " stopTime=" << stopTime
248  << " pedY=" << ped.myRelY
249  << " pedX=" << ped.myRelX
250  << " relX2=" << relX2
251  << " center=" << center
252  << " pedLeft=" << center + halfWidth
253  << " pedRight=" << center - halfWidth
254  << " overlap=" << overlap
255  << "\n";
256  }
257  if (overlap) {
258  closest = relX2;
259  result.first = ped.myPerson;
260  result.second = relX2 - minPos - (ped.myDir == FORWARD ? ped.myPerson->getVehicleType().getLength() : 0);
261  }
262  }
263  }
264  return result;
265 }
266 
267 
270  ActiveLanes::iterator it = myActiveLanes.find(lane);
271  if (it != myActiveLanes.end()) {
272  //std::cout << " found lane=" << lane->getID() << " n=" << it->second.size() << "\n";
273  return (it->second);
274  } else {
275  return noPedestrians;
276  }
277 }
278 
279 
280 void
282  myActiveLanes.clear();
284  myWalkingAreaPaths.clear(); // need to recompute when lane pointers change
285  myWalkingAreaFoes.clear();
286  myMinNextLengths.clear();
287 }
288 
289 
290 int
292  return MAX2(1, (int)floor(lane->getWidth() / stripeWidth));
293 }
294 
295 int
297  if (from == nullptr || to == nullptr) {
298  return UNDEFINED_DIRECTION;
299  } else if (MSLinkContHelper::getConnectingLink(*from, *to)) {
300  return FORWARD;
301  } else if (MSLinkContHelper::getConnectingLink(*to, *from)) {
302  return BACKWARD;
303  } else {
304  return UNDEFINED_DIRECTION;
305  }
306 }
307 
308 
309 void
311  if (myWalkingAreaPaths.size() > 0) {
312  return;
313  }
314  // collect vehicle lanes that cross walkingareas
315  for (MSEdgeVector::const_iterator i = MSEdge::getAllEdges().begin(); i != MSEdge::getAllEdges().end(); ++i) {
316  const MSEdge* edge = *i;
317  if (!edge->isWalkingArea() && !edge->isCrossing()) {
318  for (MSLane* lane : edge->getLanes()) {
319  for (MSLink* link : lane->getLinkCont()) {
320  if (link->getWalkingAreaFoe() != nullptr) {
321  // link is an exit link
322  myWalkingAreaFoes[&link->getWalkingAreaFoe()->getEdge()].push_back(link->getLaneBefore());
323  //std::cout << " wa=" << link->getWalkingAreaFoe()->getEdge().getID() << " foe=" << link->getLaneBefore()->getID() << "\n";
324  }
325  if (link->getWalkingAreaFoeExit() != nullptr) {
326  // link is an exit link
327  myWalkingAreaFoes[&link->getWalkingAreaFoeExit()->getEdge()].push_back(link->getLaneBefore());
328  //std::cout << " wa=" << link->getWalkingAreaFoeExit()->getEdge().getID() << " foe=" << link->getLaneBefore()->getID() << "\n";
329  }
330  }
331  }
332  }
333  }
334 
335  // build walkingareaPaths
336  for (MSEdgeVector::const_iterator i = MSEdge::getAllEdges().begin(); i != MSEdge::getAllEdges().end(); ++i) {
337  const MSEdge* edge = *i;
338  if (edge->isWalkingArea()) {
339  const MSLane* walkingArea = getSidewalk<MSEdge, MSLane>(edge);
340  myMinNextLengths[walkingArea] = walkingArea->getLength();
341  // build all possible paths across this walkingArea
342  // gather all incident lanes
343  std::vector<const MSLane*> lanes;
344  const MSEdgeVector& incoming = edge->getPredecessors();
345  for (int j = 0; j < (int)incoming.size(); ++j) {
346  lanes.push_back(getSidewalk<MSEdge, MSLane>(incoming[j]));
347  }
348  const MSEdgeVector& outgoing = edge->getSuccessors();
349  for (int j = 0; j < (int)outgoing.size(); ++j) {
350  lanes.push_back(getSidewalk<MSEdge, MSLane>(outgoing[j]));
351  }
352  // build all combinations
353  for (int j = 0; j < (int)lanes.size(); ++j) {
354  for (int k = 0; k < (int)lanes.size(); ++k) {
355  if (j != k) {
356  // build the walkingArea
357  const MSLane* from = lanes[j];
358  const MSLane* to = lanes[k];
359  const int fromDir = MSLinkContHelper::getConnectingLink(*from, *walkingArea) != nullptr ? FORWARD : BACKWARD;
360  const int toDir = MSLinkContHelper::getConnectingLink(*walkingArea, *to) != nullptr ? FORWARD : BACKWARD;
361  PositionVector shape;
362  Position fromPos = from->getShape()[fromDir == FORWARD ? -1 : 0];
363  Position toPos = to->getShape()[toDir == FORWARD ? 0 : -1];
364  const double maxExtent = fromPos.distanceTo2D(toPos) / 4; // prevent sharp corners
365  const double extrapolateBy = MIN2(maxExtent, walkingArea->getWidth() / 2);
366  // assemble shape
367  shape.push_back(fromPos);
368  if (extrapolateBy > POSITION_EPS) {
369  PositionVector fromShp = from->getShape();
370  fromShp.extrapolate(extrapolateBy);
371  shape.push_back_noDoublePos(fromDir == FORWARD ? fromShp.back() : fromShp.front());
372  PositionVector nextShp = to->getShape();
373  nextShp.extrapolate(extrapolateBy);
374  shape.push_back_noDoublePos(toDir == FORWARD ? nextShp.front() : nextShp.back());
375  }
376  shape.push_back_noDoublePos(toPos);
377  if (shape.size() < 2) {
378  PositionVector fromShp = from->getShape();
379  fromShp.extrapolate(1.5 * POSITION_EPS); // noDoublePos requires a difference of POSITION_EPS in at least one coordinate
380  shape.push_back_noDoublePos(fromDir == FORWARD ? fromShp.back() : fromShp.front());
381  assert(shape.size() == 2);
382  }
383  if (fromDir == BACKWARD) {
384  // will be walking backward on walkingArea
385  shape = shape.reverse();
386  }
387  WalkingAreaPath wap = WalkingAreaPath(from, walkingArea, to, shape);
388  myWalkingAreaPaths[std::make_pair(from, to)] = wap;
389  myMinNextLengths[walkingArea] = MIN2(myMinNextLengths[walkingArea], wap.length);
390  }
391  }
392  }
393  }
394  }
395 }
396 
397 
400  assert(walkingArea->isWalkingArea());
401  std::vector<const MSLane*> lanes;
402  const MSEdgeVector& incoming = walkingArea->getPredecessors();
403  for (int j = 0; j < (int)incoming.size(); ++j) {
404  lanes.push_back(getSidewalk<MSEdge, MSLane>(incoming[j]));
405  }
406  const MSEdgeVector& outgoing = walkingArea->getSuccessors();
407  for (int j = 0; j < (int)outgoing.size(); ++j) {
408  lanes.push_back(getSidewalk<MSEdge, MSLane>(outgoing[j]));
409  }
410  if (lanes.size() < 1) {
411  throw ProcessError("Invalid walkingarea '" + walkingArea->getID() + "' does not allow continuation.");
412  }
413  return &myWalkingAreaPaths[std::make_pair(lanes.front(), lanes.back())];
414 }
415 
416 
418 MSPModel_Striping::getNextLane(const PState& ped, const MSLane* currentLane, const MSLane* prevLane) {
419  const MSEdge* currentEdge = &currentLane->getEdge();
420  const MSJunction* junction = ped.myDir == FORWARD ? currentEdge->getToJunction() : currentEdge->getFromJunction();
421  const MSEdge* nextRouteEdge = ped.myStage->getNextRouteEdge();
422  const MSLane* nextRouteLane = getSidewalk<MSEdge, MSLane>(nextRouteEdge);
423  // result values
424  const MSLane* nextLane = nextRouteLane;
425  MSLink* link = nullptr;
426  int nextDir = UNDEFINED_DIRECTION;
427 
428  if (nextRouteLane == nullptr && nextRouteEdge != nullptr) {
429  std::string error = "Person '" + ped.myPerson->getID() + "' could not find sidewalk on edge '" + nextRouteEdge->getID() + "', time="
430  + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".";
431  if (OptionsCont::getOptions().getBool("ignore-route-errors")) {
432  WRITE_WARNING(error);
433  nextRouteLane = nextRouteEdge->getLanes().front();
434  } else {
435  throw ProcessError(error);
436  }
437  }
438 
439  if (nextRouteLane != nullptr) {
440  if (currentEdge->isInternal()) {
441  assert(junction == currentEdge->getFromJunction());
442  nextDir = junction == nextRouteEdge->getFromJunction() ? FORWARD : BACKWARD;
443  if (nextDir == FORWARD) {
444  nextLane = currentLane->getLinkCont()[0]->getViaLaneOrLane();
445  } else {
446  nextLane = currentLane->getLogicalPredecessorLane();
447  }
448  if DEBUGCOND(ped) {
449  std::cout << " internal\n";
450  }
451  } else if (currentEdge->isCrossing()) {
452  nextDir = ped.myDir;
453  if (ped.myDir == FORWARD) {
454  nextLane = currentLane->getLinkCont()[0]->getLane();
455  } else {
456  nextLane = currentLane->getLogicalPredecessorLane();
457  }
458  if DEBUGCOND(ped) {
459  std::cout << " crossing\n";
460  }
461  } else if (currentEdge->isWalkingArea()) {
462  ConstMSEdgeVector crossingRoute;
463  // departPos can be 0 because the direction of the walkingArea does not matter
464  // for the arrivalPos, we need to make sure that the route does not deviate across other junctions
465  const int nextRouteEdgeDir = nextRouteEdge->getFromJunction() == junction ? FORWARD : BACKWARD;
466  const double arrivalPos = (nextRouteEdge == ped.myStage->getRoute().back()
467  ? ped.myStage->getArrivalPos()
468  : (nextRouteEdgeDir == FORWARD ? 0 : nextRouteEdge->getLength()));
469  MSEdgeVector prohibited;
470  if (prevLane != nullptr) {
471  prohibited.push_back(&prevLane->getEdge());
472  }
473  MSNet::getInstance()->getPedestrianRouter(prohibited).compute(currentEdge, nextRouteEdge, 0, arrivalPos, ped.myStage->getMaxSpeed(ped.myPerson), 0, junction, crossingRoute, true);
474  if DEBUGCOND(ped) {
475  std::cout
476  << " nre=" << nextRouteEdge->getID()
477  << " nreDir=" << nextRouteEdgeDir
478  << " aPos=" << arrivalPos
479  << " crossingRoute=" << toString(crossingRoute)
480  << "\n";
481  }
482  if (crossingRoute.size() > 1) {
483  const MSEdge* nextEdge = crossingRoute[1];
484  nextLane = getSidewalk<MSEdge, MSLane>(crossingRoute[1]);
485  assert((nextEdge->getFromJunction() == junction || nextEdge->getToJunction() == junction));
486  assert(nextLane != prevLane);
487  nextDir = connectedDirection(currentLane, nextLane);
488  if DEBUGCOND(ped) {
489  std::cout << " nextDir=" << nextDir << "\n";
490  }
491  assert(nextDir != UNDEFINED_DIRECTION);
492  if (nextDir == FORWARD) {
493  link = MSLinkContHelper::getConnectingLink(*currentLane, *nextLane);
494  } else {
495  link = MSLinkContHelper::getConnectingLink(*nextLane, *currentLane);
496  if (nextEdge->isCrossing() && link->getTLLogic() == nullptr) {
497  const MSLane* oppositeWalkingArea = nextLane->getLogicalPredecessorLane();
498  link = MSLinkContHelper::getConnectingLink(*oppositeWalkingArea, *nextLane);
499  }
500  }
501  assert(link != 0);
502  } else {
503  if DEBUGCOND(ped) {
504  std::cout << SIMTIME
505  << " no route from '" << (currentEdge == nullptr ? "NULL" : currentEdge->getID())
506  << "' to '" << (nextRouteEdge == nullptr ? "NULL" : nextRouteEdge->getID())
507  << "\n";
508  }
509  WRITE_WARNING("Person '" + ped.myPerson->getID() + "' could not find route across junction '" + junction->getID()
510  + "' from walkingArea '" + currentEdge->getID()
511  + "' to edge '" + nextRouteEdge->getID() + "', time=" +
512  time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
513  // error indicated by nextDir == UNDEFINED_DIRECTION
514  nextLane = nextRouteLane;
515  }
516  } else if (currentEdge == nextRouteEdge) {
517  // strange loop in this route. No need to use walkingArea
518  nextDir = -ped.myDir;
519  } else {
520  // normal edge. by default use next / previous walking area
521  nextDir = ped.myDir;
522  nextLane = getNextWalkingArea(currentLane, ped.myDir, link);
523  if (nextLane != nullptr) {
524  // walking area found
525  if DEBUGCOND(ped) {
526  std::cout << " next walkingArea " << (nextDir == FORWARD ? "forward" : "backward") << "\n";
527  }
528  } else {
529  // walk forward by default
530  nextDir = junction == nextRouteEdge->getToJunction() ? BACKWARD : FORWARD;
531  // try to use a direct link as fallback
532  // direct links only exist if built explicitly. They are used to model tl-controlled links if there are no crossings
533  if (ped.myDir == FORWARD) {
534  link = MSLinkContHelper::getConnectingLink(*currentLane, *nextRouteLane);
535  if (link != nullptr) {
536  if DEBUGCOND(ped) {
537  std::cout << " direct forward\n";
538  }
539  nextLane = MSLinkContHelper::getInternalFollowingLane(currentLane, nextRouteLane);
540  }
541  } else {
542  link = MSLinkContHelper::getConnectingLink(*nextRouteLane, *currentLane);
543  if (link != nullptr) {
544  if DEBUGCOND(ped) {
545  std::cout << " direct backward\n";
546  }
547  nextLane = MSLinkContHelper::getInternalFollowingLane(nextRouteLane, currentLane);
548  if (nextLane != nullptr) {
549  // advance to the end of consecutive internal lanes
550  while (nextLane->getLinkCont()[0]->getViaLaneOrLane()->isInternal()) {
551  nextLane = nextLane->getLinkCont()[0]->getViaLaneOrLane();
552  }
553  }
554  }
555  }
556  }
557  if (nextLane == nullptr) {
558  // no internal lane found
559  nextLane = nextRouteLane;
560  if DEBUGCOND(ped) {
561  std::cout << SIMTIME << " no next lane found for " << currentLane->getID() << " dir=" << ped.myDir << "\n";
562  }
563  if (usingInternalLanesStatic() && currentLane->getLinkCont().size() > 0 && MSNet::getInstance()->hasPedestrianNetwork()) {
564  WRITE_WARNING("Person '" + ped.myPerson->getID() + "' could not find route across junction '" + junction->getID()
565  + "' from edge '" + currentEdge->getID()
566  + "' to edge '" + nextRouteEdge->getID() + "', time=" +
567  time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
568  }
569  } else if (nextLane->getLength() <= POSITION_EPS) {
570  // internal lane too short
571  // most often this is due to a zero-size junction. However, if
572  // the person needs to pass a crossing we cannot skip ahead
573  if ((nextLane->getCanonicalSuccessorLane() == nullptr
574  || !nextLane->getCanonicalSuccessorLane()->getEdge().isCrossing())
575  && (nextLane->getLogicalPredecessorLane() == nullptr ||
576  !nextLane->getLogicalPredecessorLane()->getEdge().isCrossing())) {
577  //WRITE_WARNING("Person '" + ped.getID()
578  // + "' skips short lane '" + nextLane->getID()
579  // + "' length=" + toString(nextLane->getLength())
580  // + " time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
581  nextLane = nextRouteLane;
582  nextDir = nextRouteEdge->getFromJunction() == junction ? FORWARD : BACKWARD;
583  }
584  }
585  }
586  }
587  if DEBUGCOND(ped) {
588  std::cout << SIMTIME
589  << " p=" << ped.myPerson->getID()
590  << " l=" << currentLane->getID()
591  << " nl=" << (nextLane == nullptr ? "NULL" : nextLane->getID())
592  << " nrl=" << (nextRouteLane == nullptr ? "NULL" : nextRouteLane->getID())
593  << " d=" << nextDir
594  << " link=" << (link == nullptr ? "NULL" : link->getViaLaneOrLane()->getID())
595  << " pedDir=" << ped.myDir
596  << "\n";
597  }
598  assert(nextLane != 0 || nextRouteLane == 0);
599  return NextLaneInfo(nextLane, link, nextDir);
600 }
601 
602 
603 const MSLane*
604 MSPModel_Striping::getNextWalkingArea(const MSLane* currentLane, const int dir, MSLink*& link) {
605  if (dir == FORWARD) {
606  const MSLinkCont& links = currentLane->getLinkCont();
607  for (MSLinkCont::const_iterator it = links.begin(); it != links.end(); ++it) {
608  if ((*it)->getLane()->getEdge().isWalkingArea()) {
609  link = *it;
610  return (*it)->getLane();
611  }
612  }
613  } else {
614  const std::vector<MSLane::IncomingLaneInfo>& laneInfos = currentLane->getIncomingLanes();
615  for (std::vector<MSLane::IncomingLaneInfo>::const_iterator it = laneInfos.begin(); it != laneInfos.end(); ++it) {
616  if ((*it).lane->getEdge().isWalkingArea()) {
617  link = (*it).viaLink;
618  return (*it).lane;
619  }
620  }
621  }
622  return nullptr;
623 }
624 
625 
627 MSPModel_Striping::getNeighboringObstacles(const Pedestrians& pedestrians, int egoIndex, int stripes) {
628  const PState& ego = *pedestrians[egoIndex];
629  Obstacles obs(stripes, Obstacle(ego.myDir));
630  std::vector<bool> haveBlocker(stripes, false);
631  for (int index = egoIndex + 1; index < (int)pedestrians.size(); index++) {
632  const PState& p = *pedestrians[index];
633  if DEBUGCOND(ego) {
634  std::cout << SIMTIME << " ped=" << ego.myPerson->getID() << " checking neighbor " << p.myPerson->getID();
635  }
636  if (!p.myWaitingToEnter) {
637  const Obstacle o(p);
638  if DEBUGCOND(ego) {
639  std::cout << " dist=" << ego.distanceTo(o) << std::endl;
640  }
641  if (ego.distanceTo(o) == DIST_BEHIND) {
642  break;
643  }
644  if (ego.distanceTo(o) == DIST_OVERLAP) {
645  obs[p.stripe()] = o;
646  obs[p.otherStripe()] = o;
647  haveBlocker[p.stripe()] = true;
648  haveBlocker[p.otherStripe()] = true;
649  }
650  if (!haveBlocker[p.stripe()]) {
651  obs[p.stripe()] = o;
652  }
653  if (!haveBlocker[p.otherStripe()]) {
654  obs[p.otherStripe()] = o;
655  }
656  }
657  }
658  if DEBUGCOND(ego) {
659  std::cout << SIMTIME << " ped=" << ego.myPerson->getID() << " neighObs=";
660  DEBUG_PRINT(obs);
661  }
662  return obs;
663 }
664 
665 
666 int
667 MSPModel_Striping::getStripeOffset(int origStripes, int destStripes, bool addRemainder) {
668  int offset = (destStripes - origStripes) / 2;
669  if (addRemainder) {
670  offset += (destStripes - origStripes) % 2;
671  }
672  return offset;
673 }
674 
675 
678  MSLane* lane, const MSLane* nextLane, int stripes, int nextDir,
679  double currentLength, int currentDir) {
680  if (nextLanesObs.count(nextLane) == 0) {
681  const double nextLength = nextLane->getEdge().isWalkingArea() ? myMinNextLengths[nextLane] : nextLane->getLength();
682  // figure out the which pedestrians are ahead on the next lane
683  const int nextStripes = numStripes(nextLane);
684  // do not move past the end of the next lane in a single step
685  Obstacles obs(stripes, Obstacle(nextDir == FORWARD ? nextLength : 0, 0, OBSTACLE_NEXTEND, "nextEnd", 0));
686 
687  const int offset = getStripeOffset(nextStripes, stripes, currentDir != nextDir && nextStripes > stripes);
688  //std::cout << SIMTIME << " getNextLaneObstacles"
689  // << " nextLane=" << nextLane->getID()
690  // << " nextLength=" << nextLength
691  // << " nextDir=" << nextDir
692  // << " currentLength=" << currentLength
693  // << " currentDir=" << currentDir
694  // << " stripes=" << stripes
695  // << " nextStripes=" << nextStripes
696  // << " offset=" << offset
697  // << "\n";
698  if (nextStripes < stripes) {
699  // some stripes do not continue
700  for (int ii = 0; ii < stripes; ++ii) {
701  if (ii < offset || ii >= nextStripes + offset) {
702  obs[ii] = Obstacle(nextDir == FORWARD ? 0 : nextLength, 0, OBSTACLE_END, "stripeEnd", 0);
703  }
704  }
705  }
706  Pedestrians& pedestrians = getPedestrians(nextLane);
707  if (nextLane->getEdge().isWalkingArea()) {
708  transformToCurrentLanePositions(obs, currentDir, nextDir, currentLength, nextLength);
709  // complex transformation into the coordinate system of the current lane
710  // (pedestrians on next lane may walk at arbitrary angles relative to the current lane)
711  double lateral_offset = (lane->getWidth() - stripeWidth) * 0.5;
712  if ((stripes - nextStripes) % 2 != 0) {
713  lateral_offset += 0.5 * stripeWidth;
714  }
715  nextDir = currentDir;
716  // transform pedestrians into the current coordinate system
717  for (int ii = 0; ii < (int)pedestrians.size(); ++ii) {
718  PState& p = *pedestrians[ii];
719  if (p.myWaitingToEnter || p.myAmJammed) {
720  continue;
721  }
722  Position relPos = lane->getShape().transformToVectorCoordinates(p.getPosition(*p.myStage, -1), true);
723  const double newY = relPos.y() + lateral_offset;
724  //if (p.myPerson->getID() == "ped200") std::cout << " ped=" << p.myPerson->getID() << " relX=" << relPos.x() << " relY=" << newY << " latOff=" << lateral_offset << " s=" << p.stripe(newY) << " os=" << p.otherStripe(newY) << "\n";
725  if ((currentDir == FORWARD && relPos.x() >= lane->getLength()) || (currentDir == BACKWARD && relPos.x() < 0)) {
726  addCloserObstacle(obs, relPos.x(), p.stripe(newY), stripes, p.myPerson->getID(), p.myPerson->getVehicleType().getWidth(), currentDir, OBSTACLE_PED);
727  addCloserObstacle(obs, relPos.x(), p.otherStripe(newY), stripes, p.myPerson->getID(), p.myPerson->getVehicleType().getWidth(), currentDir, OBSTACLE_PED);
728  }
729  }
730  } else {
731  // simple transformation into the coordinate system of the current lane
732  // (only need to worry about currentDir and nextDir)
733  // XXX consider waitingToEnter on nextLane
734  sort(pedestrians.begin(), pedestrians.end(), by_xpos_sorter(nextDir));
735  for (int ii = 0; ii < (int)pedestrians.size(); ++ii) {
736  const PState& p = *pedestrians[ii];
737  if (p.myWaitingToEnter || p.myAmJammed) {
738  continue;
739  }
740  double newY = p.myRelY;
741  Obstacle pObs(p);
742  if (nextDir != currentDir) {
743  newY = (nextStripes - 1) * stripeWidth - newY;
744  pObs.speed *= -1;
745  }
746  newY += offset * stripeWidth;
747  const int stripe = p.stripe(newY);
748  if (stripe >= 0 && stripe < stripes) {
749  obs[stripe] = pObs;
750  }
751  const int otherStripe = p.otherStripe(newY);
752  if (otherStripe >= 0 && otherStripe < stripes) {
753  obs[otherStripe] = pObs;
754  }
755  }
756  if (nextLane->getEdge().isCrossing()) {
757  // add vehicle obstacles
758  const MSLink* crossingEntryLink = nextLane->getIncomingLanes().front().viaLink;
759  const bool prio = crossingEntryLink->havePriority() || crossingEntryLink->getTLLogic() != nullptr;
760  addCrossingVehs(nextLane, stripes, offset, nextDir, obs, prio);
761  }
762  if (nextLane->getVehicleNumberWithPartials() > 0) {
763  Obstacles vehObs = getVehicleObstacles(nextLane, nextDir);
764  PState::mergeObstacles(obs, vehObs, nextDir, offset);
765  }
766  transformToCurrentLanePositions(obs, currentDir, nextDir, currentLength, nextLength);
767  }
768  nextLanesObs[nextLane] = obs;
769  }
770  return nextLanesObs[nextLane];
771 }
772 
773 void
774 MSPModel_Striping::transformToCurrentLanePositions(Obstacles& obs, int currentDir, int nextDir, double currentLength, double nextLength) {
775  for (int ii = 0; ii < (int)obs.size(); ++ii) {
776  Obstacle& o = obs[ii];
777  if (currentDir == FORWARD) {
778  if (nextDir == FORWARD) {
779  o.xFwd += currentLength;
780  o.xBack += currentLength;
781  } else {
782  const double tmp = o.xFwd;
783  o.xFwd = currentLength + nextLength - o.xBack;
784  o.xBack = currentLength + nextLength - tmp;
785  }
786  } else {
787  if (nextDir == FORWARD) {
788  const double tmp = o.xFwd;
789  o.xFwd = -o.xBack;
790  o.xBack = -tmp;
791  } else {
792  o.xFwd -= nextLength;
793  o.xBack -= nextLength;
794  }
795  }
796  }
797 }
798 
799 
800 void
801 MSPModel_Striping::addCloserObstacle(Obstacles& obs, double x, int stripe, int numStripes, const std::string& id, double width, int dir, ObstacleType type) {
802  if (stripe >= 0 && stripe < numStripes) {
803  if ((dir == FORWARD && x - width / 2. < obs[stripe].xBack) || (dir == BACKWARD && x + width / 2. > obs[stripe].xFwd)) {
804  obs[stripe] = Obstacle(x, 0, type, id, width);
805  }
806  }
807 }
808 
809 void
810 MSPModel_Striping::moveInDirection(SUMOTime currentTime, std::set<MSPerson*>& changedLane, int dir) {
811  for (ActiveLanes::iterator it_lane = myActiveLanes.begin(); it_lane != myActiveLanes.end(); ++it_lane) {
812  const MSLane* lane = it_lane->first;
813  Pedestrians& pedestrians = it_lane->second;
814  if (pedestrians.size() == 0) {
815  continue;
816  }
817  //std::cout << SIMTIME << ">>> lane=" << lane->getID() << " numPeds=" << pedestrians.size() << "\n";
818  if (lane->getEdge().isWalkingArea()) {
819  const double lateral_offset = (lane->getWidth() - stripeWidth) * 0.5;
820  const double minY = stripeWidth * - 0.5 + NUMERICAL_EPS;
821  const double maxY = stripeWidth * (numStripes(lane) - 0.5) - NUMERICAL_EPS;
822  const WalkingAreaPath* debugPath = nullptr;
823  // need to handle each walkingAreaPath separately and transform
824  // coordinates beforehand
825  std::set<const WalkingAreaPath*, walkingarea_path_sorter> paths;
826  for (Pedestrians::iterator it = pedestrians.begin(); it != pedestrians.end(); ++it) {
827  const PState* p = *it;
828  assert(p->myWalkingAreaPath != 0);
829  if (p->myDir == dir) {
830  paths.insert(p->myWalkingAreaPath);
831  if DEBUGCOND(*p) {
832  debugPath = p->myWalkingAreaPath;
833  std::cout << SIMTIME << " debugging WalkingAreaPath from=" << debugPath->from->getID() << " to=" << debugPath->to->getID() << "\n";
834  }
835  }
836  }
837  for (std::set<const WalkingAreaPath*, walkingarea_path_sorter>::iterator it = paths.begin(); it != paths.end(); ++it) {
838  const WalkingAreaPath* path = *it;
839  Pedestrians toDelete;
840  Pedestrians transformedPeds;
841  transformedPeds.reserve(pedestrians.size());
842  for (Pedestrians::iterator it_p = pedestrians.begin(); it_p != pedestrians.end(); ++it_p) {
843  PState* p = *it_p;
844  if (p->myWalkingAreaPath == path
845  // opposite direction is already in the correct coordinate system
846  || (p->myWalkingAreaPath->from == path->to && p->myWalkingAreaPath->to == path->from)) {
847  transformedPeds.push_back(p);
848  if (path == debugPath) std::cout << " ped=" << p->myPerson->getID() << " relX=" << p->myRelX << " relY=" << p->myRelY << " (untransformed), vecCoord="
849  << path->shape.transformToVectorCoordinates(p->getPosition(*p->myStage, -1)) << "\n";
850  } else {
851  const Position relPos = path->shape.transformToVectorCoordinates(p->getPosition(*p->myStage, -1));
852  const double newY = relPos.y() + lateral_offset;
853  if (relPos != Position::INVALID && newY >= minY && newY <= maxY) {
854  PState* tp = new PState(*p);
855  tp->myRelX = relPos.x();
856  tp->myRelY = newY;
857  // only an obstacle, speed may be orthogonal to dir
858  tp->myDir = !dir;
859  tp->mySpeed = 0;
860  toDelete.push_back(tp);
861  transformedPeds.push_back(tp);
862  if (path == debugPath) {
863  std::cout << " ped=" << p->myPerson->getID() << " relX=" << relPos.x() << " relY=" << newY << " (transformed), vecCoord=" << relPos << "\n";
864  }
865  } else {
866  if (path == debugPath) {
867  std::cout << " ped=" << p->myPerson->getID() << " relX=" << relPos.x() << " relY=" << newY << " (invalid), vecCoord=" << relPos << "\n";
868  }
869  }
870  }
871  }
872  auto itFoe = myWalkingAreaFoes.find(&lane->getEdge());
873  if (itFoe != myWalkingAreaFoes.end()) {
874  // add vehicle foes on paths which cross this walkingarea
875  // translate the vehicle into a number of dummy-pedestrians
876  // that occupy the same space
877  for (const MSLane* foeLane : itFoe->second) {
878  for (auto itVeh = foeLane->anyVehiclesBegin(); itVeh != foeLane->anyVehiclesEnd(); ++itVeh) {
879  const MSVehicle* veh = *itVeh;
880  const Position relPos = path->shape.transformToVectorCoordinates(veh->getPosition());
881  const Position relPos2 = path->shape.transformToVectorCoordinates(veh->getBackPosition());
882  //std::cout << " pos=" << veh->getPosition() << " back=" << veh->getBackPosition() << " relPos=" << relPos << " relPos2=" << relPos2 << " shape=" << path->shape << "\n";
883  if (addVehicleFoe(veh, lane, relPos, lateral_offset, minY, maxY, toDelete, transformedPeds)
884  && addVehicleFoe(veh, lane, relPos2, lateral_offset, minY, maxY, toDelete, transformedPeds)) {
885  // add in-between positions
886  const double length = veh->getVehicleType().getLength();
887  for (double dist = stripeWidth; dist < length; dist += stripeWidth) {
888  const double relDist = dist / length;
889  Position between = (relPos * relDist) + (relPos2 * (1 - relDist));
890  addVehicleFoe(veh, lane, between, lateral_offset, minY, maxY, toDelete, transformedPeds);
891  }
892  }
893  }
894  }
895  }
896  moveInDirectionOnLane(transformedPeds, lane, currentTime, changedLane, dir);
897  arriveAndAdvance(pedestrians, currentTime, changedLane, dir);
898  // clean up
899  for (Pedestrians::iterator it_p = toDelete.begin(); it_p != toDelete.end(); ++it_p) {
900  delete *it_p;
901  }
902  }
903  } else {
904  moveInDirectionOnLane(pedestrians, lane, currentTime, changedLane, dir);
905  arriveAndAdvance(pedestrians, currentTime, changedLane, dir);
906  }
907  }
908 }
909 
910 
911 bool
912 MSPModel_Striping::addVehicleFoe(const MSVehicle* veh, const MSLane* walkingarea, const Position& relPos, double lateral_offset,
913  double minY, double maxY, Pedestrians& toDelete, Pedestrians& transformedPeds) {
914  if (relPos != Position::INVALID) {
915  const double newY = relPos.y() + lateral_offset;
916  if (newY >= minY && newY <= maxY) {
917  PState* tp = new PStateVehicle(veh, walkingarea, relPos.x(), newY);
918  //std::cout << SIMTIME << " addVehicleFoe=" << veh->getID() << " rx=" << relPos.x() << " ry=" << newY << " s=" << tp->stripe() << " o=" << tp->otherStripe() << "\n";
919  toDelete.push_back(tp);
920  transformedPeds.push_back(tp);
921  }
922  return true;
923  } else {
924  return false;
925  }
926 }
927 
928 void
929 MSPModel_Striping::arriveAndAdvance(Pedestrians& pedestrians, SUMOTime currentTime, std::set<MSPerson*>& changedLane, int dir) {
930  // advance to the next lane / arrive at destination
931  sort(pedestrians.begin(), pedestrians.end(), by_xpos_sorter(dir));
932  // can't use iterators because we do concurrent modification
933  for (int i = 0; i < (int)pedestrians.size(); i++) {
934  PState* const p = pedestrians[i];
935  if (p->myDir == dir && p->distToLaneEnd() < 0) {
936  // moveToNextLane may trigger re-insertion (for consecutive
937  // walks) so erase must be called first
938  pedestrians.erase(pedestrians.begin() + i);
939  i--;
940  p->moveToNextLane(currentTime);
941  if (p->myLane != nullptr) {
942  changedLane.insert(p->myPerson);
943  myActiveLanes[p->myLane].push_back(p);
944  } else {
945  // end walking stage and destroy PState
946  p->myStage->moveToNextEdge(p->myPerson, currentTime);
948  }
949  }
950  }
951 }
952 
953 
954 void
955 MSPModel_Striping::moveInDirectionOnLane(Pedestrians& pedestrians, const MSLane* lane, SUMOTime currentTime, std::set<MSPerson*>& changedLane, int dir) {
956  const int stripes = numStripes(lane);
957  //std::cout << " laneWidth=" << lane->getWidth() << " stripeWidth=" << stripeWidth << " stripes=" << stripes << "\n";
958  Obstacles obs(stripes, Obstacle(dir)); // continously updated
959  NextLanesObstacles nextLanesObs; // continously updated
960  sort(pedestrians.begin(), pedestrians.end(), by_xpos_sorter(dir));
961 
962  Obstacles crossingVehs(stripes, Obstacle(dir));
963  bool hasCrossingVehObs = false;
964  if (lane->getEdge().isCrossing()) {
965  // assume that vehicles will brake when already on the crossing
966  hasCrossingVehObs = addCrossingVehs(lane, stripes, 0, dir, crossingVehs, true);
967  }
968 
969  for (int ii = 0; ii < (int)pedestrians.size(); ++ii) {
970  PState& p = *pedestrians[ii];
971  //std::cout << SIMTIME << "CHECKING" << p.myPerson->getID() << "\n";
972  Obstacles currentObs = obs;
973  if (p.myDir != dir || changedLane.count(p.myPerson) != 0) {
974  if (!p.myWaitingToEnter) {
975  //if DEBUGCOND(p) {
976  // std::cout << " obs=" << p.myPerson->getID() << " y=" << p.myRelY << " stripe=" << p.stripe() << " oStripe=" << p.otherStripe() << "\n";
977  //}
978  Obstacle o(p);
979  if (p.myDir != dir && p.mySpeed == 0) {
980  // ensure recognition of oncoming
981  o.speed = (p.myDir == FORWARD ? 0.1 : -0.1);
982  }
983  obs[p.stripe()] = o;
984  obs[p.otherStripe()] = o;
985  }
986  continue;
987  }
988  if DEBUGCOND(p) {
989  std::cout << SIMTIME << " ped=" << p.myPerson->getID() << " currentObs=";
990  gDebugFlag1 = true;
991  DEBUG_PRINT(currentObs);
992  }
993  const MSLane* nextLane = p.myNLI.lane;
994  const MSLink* link = p.myNLI.link;
995  const double dist = p.distToLaneEnd();
996  const double speed = p.myStage->getMaxSpeed(p.myPerson);
997  if (nextLane != nullptr && dist <= LOOKAHEAD_ONCOMING) {
998  const double currentLength = (p.myWalkingAreaPath == nullptr ? lane->getLength() : p.myWalkingAreaPath->length);
999  const Obstacles& nextObs = getNextLaneObstacles(
1000  nextLanesObs, lane, nextLane, stripes,
1001  p.myNLI.dir, currentLength, dir);
1002 
1003  if DEBUGCOND(p) {
1004  std::cout << SIMTIME << " ped=" << p.myPerson->getID() << " nextObs=";
1005  DEBUG_PRINT(nextObs);
1006  }
1007  p.mergeObstacles(currentObs, nextObs);
1008  }
1009  if DEBUGCOND(p) {
1010  std::cout << SIMTIME << " ped=" << p.myPerson->getID() << " obsWithNext=";
1011  DEBUG_PRINT(currentObs);
1012  }
1013  p.mergeObstacles(currentObs, getNeighboringObstacles(pedestrians, ii, stripes));
1014  if DEBUGCOND(p) {
1015  std::cout << SIMTIME << " ped=" << p.myPerson->getID() << " obsWithNeigh=";
1016  DEBUG_PRINT(currentObs);
1017  }
1018  // time gap to pass the intersection ahead of a vehicle.
1019  const double passingClearanceTime = 2;
1020  const double passingLength = p.getLength() + passingClearanceTime * speed;
1021  // check link state
1022  if DEBUGCOND(p) {
1023  gDebugFlag1 = true;
1024  std::cout << " link=" << (link == nullptr ? "NULL" : link->getViaLaneOrLane()->getID())
1025  << " dist=" << dist << " d2=" << dist - p.getMinGap() << " la=" << LOOKAHEAD_SAMEDIR* speed
1026  << " opened=" << (link == nullptr ? "NULL" : toString(link->opened(currentTime - DELTA_T, speed, speed, passingLength, p.getImpatience(currentTime), speed, 0, 0, nullptr, p.ignoreRed(link)))) << "\n";
1027  gDebugFlag1 = false;
1028  }
1029  if (link != nullptr
1030  // only check close before junction, @todo we should take deceleration into account here
1031  && dist - p.getMinGap() < LOOKAHEAD_SAMEDIR * speed
1032  // persons move before vehicles so we subtract DELTA_TO because they cannot rely on vehicles having passed the intersection in the current time step
1033  && !link->opened(currentTime - DELTA_T, speed, speed, passingLength, p.getImpatience(currentTime), speed, 0, 0, nullptr, p.ignoreRed(link))) {
1034  // prevent movement passed a closed link
1035  Obstacles closedLink(stripes, Obstacle(p.myRelX + dir * (dist + NUMERICAL_EPS), 0, OBSTACLE_LINKCLOSED, "closedLink_" + link->getViaLaneOrLane()->getID(), 0));
1036  p.mergeObstacles(currentObs, closedLink);
1037  if DEBUGCOND(p) {
1038  std::cout << SIMTIME << " ped=" << p.myPerson->getID() << " obsWithTLS=";
1039  DEBUG_PRINT(currentObs);
1040  }
1041  // consider rerouting over another crossing
1042  if (p.myWalkingAreaPath != nullptr) {
1043  // @todo actually another path would be needed starting at the current position
1045  }
1046  }
1047  if (&lane->getEdge() == p.myStage->getDestination() && p.myStage->getDestinationStop() != nullptr) {
1048  Obstacles arrival(stripes, Obstacle(p.myStage->getArrivalPos() + dir * p.getMinGap(), 0, OBSTACLE_ARRIVALPOS, "arrival", 0));
1049  p.mergeObstacles(currentObs, arrival);
1050  }
1051 
1052  if (lane->getVehicleNumberWithPartials() > 0) {
1053  // react to vehicles on the same lane
1054  // @todo: improve efficiency by using the same iterator for all pedestrians on this lane
1055  Obstacles vehObs = getVehicleObstacles(lane, dir, &p);
1056  p.mergeObstacles(currentObs, vehObs);
1057  if DEBUGCOND(p) {
1058  std::cout << SIMTIME << " ped=" << p.myPerson->getID() << " obsWithVehs=";
1059  DEBUG_PRINT(currentObs);
1060  }
1061  }
1062  if (hasCrossingVehObs) {
1063  p.mergeObstacles(currentObs, crossingVehs);
1064  if DEBUGCOND(p) {
1065  std::cout << SIMTIME << " ped=" << p.myPerson->getID() << " obsWithVehs2=";
1066  DEBUG_PRINT(currentObs);
1067  }
1068  }
1069 
1070  // walk, taking into account all obstacles
1071  p.walk(currentObs, currentTime);
1072  gDebugFlag1 = false;
1073  if (!p.myWaitingToEnter && !p.myAmJammed) {
1074  Obstacle o(p);
1075  obs[p.stripe()] = o;
1076  obs[p.otherStripe()] = o;
1077  if (MSGlobals::gCheck4Accidents && p.myWalkingAreaPath == nullptr && !p.myAmJammed) {
1078  for (int coll = 0; coll < ii; ++coll) {
1079  PState& c = *pedestrians[coll];
1080  if (!c.myWaitingToEnter && c.myWalkingAreaPath == nullptr && !c.myAmJammed) {
1081  if (c.stripe() == p.stripe() || p.stripe() == c.otherStripe() || p.otherStripe() == c.stripe() || p.otherStripe() == c.otherStripe()) {
1082  Obstacle cObs(c);
1083  // we check only for real collisions, no min gap violations
1084  if (p.distanceTo(cObs, false) == DIST_OVERLAP) {
1085  WRITE_WARNING("Collision of person '" + p.myPerson->getID() + "' and person '" + c.myPerson->getID()
1086  + "', lane='" + lane->getID() + "', time=" + time2string(currentTime) + ".");
1087  }
1088  }
1089  }
1090  }
1091  }
1092  }
1093  //std::cout << SIMTIME << p.myPerson->getID() << " lane=" << lane->getID() << " x=" << p.myRelX << "\n";
1094  }
1095 }
1096 
1097 bool
1098 MSPModel_Striping::addCrossingVehs(const MSLane* crossing, int stripes, double lateral_offset, int dir, Obstacles& obs, bool prio) {
1099  bool hasCrossingVehObs = false;
1100  const MSLink* crossingExitLink = crossing->getLinkCont().front();
1101  gDebugFlag1 = DEBUGCOND2(crossing);
1102  const MSLink::LinkLeaders linkLeaders = crossingExitLink->getLeaderInfo(nullptr, crossing->getLength());
1103  gDebugFlag1 = false;
1104  if (linkLeaders.size() > 0) {
1105  for (MSLink::LinkLeaders::const_iterator it = linkLeaders.begin(); it != linkLeaders.end(); ++it) {
1106  // the vehicle to enter the junction first has priority
1107  const MSVehicle* veh = (*it).vehAndGap.first;
1108  if (veh != nullptr) {
1109  Obstacle vo((*it).distToCrossing, 0, OBSTACLE_VEHICLE, veh->getID(), veh->getVehicleType().getWidth() + 2 * MINGAP_TO_VEHICLE);
1110  // block entry to the crossing in walking direction but allow leaving it
1111  Obstacle voBlock = vo;
1112  if (dir == FORWARD) {
1113  voBlock.xBack = NUMERICAL_EPS;
1114  } else {
1115  voBlock.xFwd = crossing->getLength() - NUMERICAL_EPS;
1116  }
1117  // when approaching a priority crossings, vehicles must be able
1118  // to brake, otherwise the person must be able to cross in time
1119  const double distToCrossBeforeVeh = (dir == FORWARD ? vo.xFwd : crossing->getLength() - vo.xBack);
1120  const double bGap = (prio
1121  ? veh->getCarFollowModel().brakeGap(veh->getSpeed(), veh->getCarFollowModel().getMaxDecel(), 0)
1122  : veh->getSpeed() * distToCrossBeforeVeh); // walking 1m/s
1123  double vehYmin;
1124  double vehYmax;
1125  // relY increases from left to right (the other way around from vehicles)
1126  if ((*it).fromLeft) {
1127  vehYmin = -(*it).vehAndGap.second + lateral_offset; // vehicle back
1128  vehYmax = vehYmin + veh->getVehicleType().getLength() + bGap + MINGAP_TO_VEHICLE;
1129  vehYmin -= MINGAP_TO_VEHICLE;
1130  } else {
1131  vehYmax = crossing->getWidth() + (*it).vehAndGap.second - lateral_offset; // vehicle back
1132  vehYmin = vehYmax - veh->getVehicleType().getLength() - bGap - MINGAP_TO_VEHICLE;
1133  vehYmax += MINGAP_TO_VEHICLE;
1134 
1135  }
1136  for (int s = MAX2(0, PState::stripe(vehYmin)); s < MIN2(PState::stripe(vehYmax), stripes); ++s) {
1137  if ((dir == FORWARD && obs[s].xBack > vo.xBack)
1138  || (dir == BACKWARD && obs[s].xFwd < vo.xFwd)) {
1139  if (!prio && veh->getSpeed() > SUMO_const_haltingSpeed) {
1140  // do not enter the crossing
1141  obs[s] = voBlock;
1142  } else {
1143  obs[s] = vo;
1144  }
1145  hasCrossingVehObs = true;
1146  }
1147  }
1148  if (DEBUGCOND2(crossing)) {
1149  std::cout << SIMTIME
1150  << " crossingVeh=" << veh->getID()
1151  << " lane=" << crossing->getID()
1152  << " prio=" << prio
1153  << " latOffset=" << lateral_offset
1154  << " dir=" << dir
1155  << " stripes=" << stripes
1156  << " dist=" << (*it).distToCrossing
1157  << " gap=" << (*it).vehAndGap.second
1158  << " brakeGap=" << bGap
1159  << " fromLeft=" << (*it).fromLeft
1160  << " distToCrossBefore=" << distToCrossBeforeVeh
1161  << " ymin=" << vehYmin
1162  << " ymax=" << vehYmax
1163  << " smin=" << PState::stripe(vehYmin)
1164  << " smax=" << PState::stripe(vehYmax)
1165  << "\n";
1166  DEBUG_PRINT(obs);
1167  }
1168  }
1169  }
1170  }
1171  return hasCrossingVehObs;
1172 }
1173 
1174 
1177  const int stripes = numStripes(lane);
1178  Obstacles vehObs(stripes, Obstacle(dir));
1179  int current = -1;
1180  double minX = 0.;
1181  double maxX = 0.;
1182  double pRelY = -1.;
1183  double pWidth = 0.;
1184  std::string pID;
1185  bool debug = DEBUGCOND2(lane);
1186  if (ped != nullptr) {
1187  current = ped->stripe();
1188  minX = ped->getMinX();
1189  maxX = ped->getMaxX();
1190  pRelY = ped->myRelY;
1191  pWidth = ped->myPerson->getVehicleType().getWidth();
1192  pID = ped->myPerson->getID();
1193  debug = DEBUGCOND(*ped);
1194  } else if (dir == BACKWARD) {
1195  // checking vehicles on the next lane. Use entry point as reference
1196  minX = lane->getLength();
1197  maxX = lane->getLength();
1198  }
1199  MSLane::AnyVehicleIterator begin = (dir == FORWARD ? lane->anyVehiclesUpstreamBegin() : lane->anyVehiclesBegin());
1200  MSLane::AnyVehicleIterator end = (dir == FORWARD ? lane->anyVehiclesUpstreamEnd() : lane->anyVehiclesEnd());
1201  for (MSLane::AnyVehicleIterator it = begin; it != end; ++it) {
1202  const MSVehicle* veh = *it;
1203  const double vehBack = veh->getBackPositionOnLane(lane);
1204  const double vehFront = vehBack + veh->getVehicleType().getLength();
1205  // ensure that vehicles are not blocked
1206  const double vehNextSpeed = MAX2(veh->getSpeed(), 1.0);
1207  const double clearance = SAFETY_GAP + vehNextSpeed * LOOKAHEAD_SAMEDIR;
1208  if ((dir == FORWARD && vehFront + clearance > minX && vehBack <= maxX + LOOKAHEAD_SAMEDIR)
1209  || (dir == BACKWARD && vehBack < maxX && vehFront >= minX - LOOKAROUND_VEHICLES)) {
1210  Obstacle vo(vehBack, veh->getSpeed(), OBSTACLE_VEHICLE, veh->getID(), 0);
1211  // moving vehicles block space along their path
1212  vo.xFwd += veh->getVehicleType().getLength() + clearance;
1213  vo.xBack -= SAFETY_GAP;
1214  // relY increases from left to right (the other way around from vehicles)
1215  // XXX lateral offset for partial vehicles
1216  const double vehYmax = 0.5 * (lane->getWidth() + veh->getVehicleType().getWidth() - stripeWidth) - veh->getLateralPositionOnLane();
1217  const double vehYmin = vehYmax - veh->getVehicleType().getWidth();
1218  for (int s = MAX2(0, PState::stripe(vehYmin)); s < MIN2(PState::stripe(vehYmax) + 1, stripes); ++s) {
1219  Obstacle prior = vehObs[s];
1220  vehObs[s] = vo;
1221  if (s == current && vehFront + SAFETY_GAP < minX) {
1222  // ignore if aleady overlapping while vehicle is still behind
1223  if (pRelY - pWidth < vehYmax &&
1224  pRelY + pWidth > vehYmin && dir == FORWARD) {
1225  if (debug) {
1226  std::cout << " ignoring vehicle '" << veh->getID() << " on stripe " << s << " vehFrontSG=" << vehFront + SAFETY_GAP << " minX=" << minX << "\n";
1227  }
1228  if (dir == FORWARD) {
1229  vehObs[s] = prior;
1230  } else {
1231  vehObs[s].xFwd = MIN2(vo.xFwd, vehFront + SAFETY_GAP);
1232  }
1233  }
1234  }
1235  }
1236  if (debug) {
1237  std::cout << SIMTIME << " ped=" << pID << " veh=" << veh->getID() << " obstacle on lane=" << lane->getID()
1238  << "\n"
1239  << " ymin=" << vehYmin
1240  << " ymax=" << vehYmax
1241  << " smin=" << PState::stripe(vehYmin)
1242  << " smax=" << PState::stripe(vehYmax)
1243  << " relY=" << pRelY
1244  << " current=" << current
1245  << " vo.xFwd=" << vo.xFwd
1246  << " vo.xBack=" << vo.xBack
1247  << "\n";
1248  }
1249  }
1250  }
1251  return vehObs;
1252 }
1253 
1254 
1255 // ===========================================================================
1256 // MSPModel_Striping::Obstacle method definitions
1257 // ===========================================================================
1259  xFwd(dir * dist), // by default, far away when seen in dir
1260  xBack(dir * dist), // by default, far away when seen in dir
1261  speed(0),
1262  type(OBSTACLE_NONE),
1263  description("") {
1264 }
1265 
1266 
1268  xFwd(ped.getMaxX()),
1269  xBack(ped.getMinX()),
1270  speed(ped.myDir * ped.mySpeed),
1271  type(OBSTACLE_PED),
1272  description(ped.getID()) {
1273  assert(!ped.myWaitingToEnter);
1274 }
1275 
1276 
1277 // ===========================================================================
1278 // MSPModel_Striping::PState method definitions
1279 // ===========================================================================
1280 
1281 
1283  myPerson(person),
1284  myStage(stage),
1285  myLane(lane),
1286  myRelX(stage->getDepartPos()),
1287  myRelY(stage->getDepartPosLat()),
1288  myDir(FORWARD),
1289  mySpeed(0),
1290  myWaitingToEnter(true),
1291  myWaitingTime(0),
1292  myWalkingAreaPath(nullptr),
1293  myAmJammed(false),
1294  myRemoteXYPos(Position::INVALID),
1295  myAngle(std::numeric_limits<double>::max()) {
1296  const MSEdge* currentEdge = &lane->getEdge();
1297  const ConstMSEdgeVector& route = myStage->getRoute();
1298  assert(!route.empty());
1299  if (route.size() == 1) {
1300  // only a single edge, move towards end pos
1302  } else if (route.front()->getFunction() != EDGEFUNC_NORMAL) {
1303  // start on an intersection
1304  myDir = FORWARD;
1305  if (route.front()->isWalkingArea()) {
1306  myWalkingAreaPath = getArbitraryPath(route.front());
1307  }
1308  } else {
1309  const bool mayStartForward = canTraverse(FORWARD, route) != UNDEFINED_DIRECTION;
1310  const bool mayStartBackward = canTraverse(BACKWARD, route) != UNDEFINED_DIRECTION;
1311  if DEBUGCOND(*this) {
1312  std::cout << " initialize dir for " << myPerson->getID() << " forward=" << mayStartForward << " backward=" << mayStartBackward << "\n";
1313  }
1314  if (mayStartForward && mayStartBackward) {
1315  // figure out the best direction via routing
1316  ConstMSEdgeVector crossingRoute;
1317  MSNet::getInstance()->getPedestrianRouter().compute(currentEdge, route.back(), myRelX, myStage->getArrivalPos(), myStage->getMaxSpeed(person), 0, nullptr, crossingRoute, true);
1318  if (crossingRoute.size() > 1) {
1319  // route found
1320  const MSEdge* nextEdge = crossingRoute[1];
1321  if (nextEdge->getFromJunction() == currentEdge->getFromJunction() || nextEdge->getToJunction() == currentEdge->getFromJunction()) {
1322  myDir = BACKWARD;
1323  }
1324  }
1325  if DEBUGCOND(*this) {
1326  std::cout << " crossingRoute=" << toString(crossingRoute) << "\n";
1327  }
1328  } else {
1329  myDir = !mayStartBackward ? FORWARD : BACKWARD;
1330  }
1331  }
1332  if (lane->getVehicleNumberWithPartials() > 0 && myRelY == 0) {
1333  // better start next to the road if nothing was specified
1334  myRelY -= stripeWidth;
1335  }
1336  if (myDir == FORWARD) {
1337  // start at the right side of the sidewalk
1338  myRelY = stripeWidth * (numStripes(lane) - 1) - myRelY;
1339  }
1340  if DEBUGCOND(*this) {
1341  std::cout << " added new pedestrian " << myPerson->getID() << " on " << lane->getID() << " myRelX=" << myRelX << " myRelY=" << myRelY << " dir=" << myDir << " route=" << toString(myStage->getRoute()) << "\n";
1342  }
1343 
1344  myNLI = getNextLane(*this, lane, nullptr);
1345 }
1346 
1348  myPerson(nullptr),
1349  myStage(nullptr),
1350  myLane(nullptr),
1351  myRelX(0),
1352  myRelY(0),
1353  myDir(UNDEFINED_DIRECTION),
1354  mySpeed(0),
1355  myWaitingToEnter(false),
1356  myWaitingTime(0),
1357  myWalkingAreaPath(nullptr),
1358  myAmJammed(false),
1359  myRemoteXYPos(Position::INVALID),
1360  myAngle(std::numeric_limits<double>::max()) {
1361 }
1362 
1363 
1364 double
1365 MSPModel_Striping::PState::getMinX(const bool includeMinGap) const {
1366  // @todo speed should have an influence here because faster persons need more space
1367  if (myDir == FORWARD) {
1368  return myRelX - getLength();
1369  }
1370  return myRelX - (includeMinGap ? getMinGap() : 0.);
1371 }
1372 
1373 
1374 double
1375 MSPModel_Striping::PState::getMaxX(const bool includeMinGap) const {
1376  // @todo speed should have an influence here because faster persons need more space
1377  if (myDir == FORWARD) {
1378  return myRelX + (includeMinGap ? getMinGap() : 0.);
1379  }
1380  return myRelX + getLength();
1381 }
1382 
1383 
1384 double
1386  return myPerson->getVehicleType().getLength();
1387 }
1388 
1389 
1390 double
1392  return myPerson->getVehicleType().getMinGap();
1393 }
1394 
1395 
1396 int
1398  return (int)floor(relY / stripeWidth + 0.5);
1399 }
1400 
1401 
1402 int
1404  const int s = stripe(relY);
1405  const double offset = relY - s * stripeWidth;
1406  const double threshold = MAX2(NUMERICAL_EPS, stripeWidth - SQUEEZE * getWidth());
1407  int result;
1408  if (offset > threshold) {
1409  result = s + 1;
1410  } else if (offset < -threshold) {
1411  result = s - 1;
1412  } else {
1413  result = s;
1414  }
1415  //std::cout.setf(std::ios::fixed , std::ios::floatfield);
1416  //std::cout << std::setprecision(5);
1417  //if DEBUGCOND(*this) std::cout << " otherStripe " << myPerson->getID() << " offset=" << offset << " threshold=" << threshold << " rawResult=" << result << "\n";
1418  return result;
1419 }
1420 
1421 int
1423  return MIN2(MAX2(0, stripe(myRelY)), numStripes(myLane) - 1);
1424 }
1425 
1426 
1427 int
1429  return MIN2(MAX2(0, otherStripe(myRelY)), numStripes(myLane) - 1);
1430 }
1431 
1432 
1433 double
1435  if (myStage->getNextRouteEdge() == nullptr) {
1436  return myDir * (myStage->getArrivalPos() - myRelX) - POSITION_EPS;
1437  } else {
1438  const double length = myWalkingAreaPath == nullptr ? myLane->getLength() : myWalkingAreaPath->length;
1439  return myDir == FORWARD ? length - myRelX : myRelX;
1440  }
1441 }
1442 
1443 
1444 bool
1446  double dist = distToLaneEnd();
1447  if (DEBUGCOND(*this)) {
1448  std::cout << SIMTIME << " ped=" << myPerson->getID() << " myRelX=" << myRelX << " dist=" << dist << "\n";
1449  }
1450  if (dist <= 0) {
1451  //if (ped.myPerson->getID() == DEBUG1) {
1452  // std::cout << SIMTIME << " addToLane x=" << ped.myRelX << " newDir=" << newDir << " newLane=" << newLane->getID() << " walkingAreaShape=" << walkingAreaShape << "\n";
1453  //}
1454  //std::cout << " changing to " << newLane->getID() << " myRelY=" << ped.myRelY << " oldStripes=" << numStripes(myLane) << " newStripes=" << numStripes(newLane);
1455  //std::cout << " newY=" << ped.myRelY << " myDir=" << ped.myDir << " newDir=" << newDir;
1456  const int oldDir = myDir;
1457  const MSLane* oldLane = myLane;
1458  myLane = myNLI.lane;
1459  myDir = myNLI.dir;
1460  const bool normalLane = (myLane == nullptr || myLane->getEdge().getFunction() == EDGEFUNC_NORMAL || &myLane->getEdge() == myStage->getNextRouteEdge());
1461  if DEBUGCOND(*this) {
1462  std::cout << SIMTIME
1463  << " ped=" << myPerson->getID()
1464  << " moveToNextLane old=" << oldLane->getID()
1465  << " new=" << (myLane == nullptr ? "NULL" : myLane->getID())
1466  << " oldDir=" << oldDir
1467  << " newDir=" << myDir
1468  << " myRelX=" << myRelX
1469  << " dist=" << dist
1470  << "\n";
1471  }
1472  if (myLane == nullptr) {
1473  myRelX = myStage->getArrivalPos();
1474  }
1475  // moveToNextEdge might destroy the person and thus mess up the heap. Better check first
1476  if (myStage->getRouteStep() == myStage->getRoute().end() - 1) {
1477  myLane = nullptr;
1478  } else {
1479  const bool arrived = myStage->moveToNextEdge(myPerson, currentTime, normalLane ? nullptr : &myLane->getEdge());
1480  UNUSED_PARAMETER(arrived);
1481  assert(!arrived);
1482  assert(myDir != UNDEFINED_DIRECTION);
1483  myNLI = getNextLane(*this, myLane, oldLane);
1484  assert(myNLI.lane != oldLane); // do not turn around
1485  if DEBUGCOND(*this) {
1486  std::cout << " nextLane=" << (myNLI.lane == nullptr ? "NULL" : myNLI.lane->getID()) << "\n";
1487  }
1488  if (myLane->getEdge().isWalkingArea()) {
1489  if (myNLI.dir != UNDEFINED_DIRECTION) {
1490  myWalkingAreaPath = &myWalkingAreaPaths[std::make_pair(oldLane, myNLI.lane)];
1491  assert(myWalkingAreaPath->from != 0);
1492  assert(myWalkingAreaPath->to != 0);
1493  assert(myWalkingAreaPath->shape.size() >= 2);
1494  if DEBUGCOND(*this) {
1495  std::cout << " mWAPath shape=" << myWalkingAreaPath->shape << " length=" << myWalkingAreaPath->length << "\n";
1496  }
1497  } else {
1498  // disconnnected route. move to the next edge
1499  if (OptionsCont::getOptions().getBool("ignore-route-errors")) {
1500  // try to determine direction from topology, otherwise maintain current direction
1501  const MSEdge* currRouteEdge = myStage->getRouteEdge();
1502  const MSEdge* nextRouteEdge = myStage->getNextRouteEdge();
1503  if ((nextRouteEdge->getToJunction() == currRouteEdge->getFromJunction())
1504  || nextRouteEdge->getToJunction() == currRouteEdge->getToJunction()) {
1505  myDir = BACKWARD;
1506  } else if ((nextRouteEdge->getFromJunction() == currRouteEdge->getFromJunction())
1507  || nextRouteEdge->getFromJunction() == currRouteEdge->getToJunction()) {
1508  myDir = FORWARD;
1509  }
1510  myStage->moveToNextEdge(myPerson, currentTime, nullptr);
1511  myLane = myNLI.lane;
1512  assert(myLane != 0);
1513  assert(myLane->getEdge().getFunction() == EDGEFUNC_NORMAL);
1514  myNLI = getNextLane(*this, myLane, oldLane);
1515  myWalkingAreaPath = nullptr;
1516  } else {
1517  throw ProcessError("Disconnected walk for person '" + myPerson->getID() + "'.");
1518  }
1519  }
1520  } else {
1521  myWalkingAreaPath = nullptr;
1522  }
1523  // adapt x to fit onto the new lane
1524  // (make sure we do not move past the end of the new lane since that
1525  // lane was not checked for obstacles)
1526  const double newLength = (myWalkingAreaPath == nullptr ? myLane->getLength() : myWalkingAreaPath->length);
1527  if (-dist > newLength) {
1528  assert(OptionsCont::getOptions().getBool("ignore-route-errors"));
1529  // should not happen because the end of myLane should have been an obstacle as well
1530  // (only when the route is broken)
1531  dist = -newLength;
1532  }
1533  if (myDir == BACKWARD) {
1534  myRelX = newLength + dist;
1535  } else {
1536  myRelX = -dist;
1537  }
1538  if DEBUGCOND(*this) {
1539  std::cout << SIMTIME << " update myRelX ped=" << myPerson->getID()
1540  << " newLength=" << newLength
1541  << " dist=" << dist
1542  << " myRelX=" << myRelX
1543  << "\n";
1544  }
1545  // adjust to change in direction
1546  if (myDir != oldDir) {
1547  myRelY = (numStripes(oldLane) - 1) * stripeWidth - myRelY;
1548  }
1549  // adjust to differences in sidewalk width
1550  const int offset = getStripeOffset(numStripes(oldLane), numStripes(myLane), oldDir != myDir && numStripes(myLane) < numStripes(oldLane));
1551  myRelY += offset * stripeWidth;
1552  if DEBUGCOND(*this) {
1553  std::cout << SIMTIME << " transformY ped=" << myPerson->getID()
1554  << " newLane=" << Named::getIDSecure(myLane)
1555  << " newY=" << myRelY
1556  << " os=" << numStripes(oldLane) << " ns=" << numStripes(myLane)
1557  << " od=" << oldDir << " nd=" << myDir
1558  << " offset=" << offset << "\n";
1559  }
1560  }
1561  return true;
1562  } else {
1563  return false;
1564  }
1565 }
1566 
1567 
1568 void
1570  myAngle = std::numeric_limits<double>::max(); // set on first access or via remote control
1571  const int stripes = (int)obs.size();
1572  const int sMax = stripes - 1;
1573  assert(stripes == numStripes(myLane));
1574  const double vMax = myStage->getMaxSpeed(myPerson);
1575  // ultimate goal is to choose the prefered stripe (chosen)
1576  const int current = stripe();
1577  const int other = otherStripe();
1578  // compute distances
1579  std::vector<double> distance(stripes);
1580  for (int i = 0; i < stripes; ++i) {
1581  distance[i] = distanceTo(obs[i], obs[i].type == OBSTACLE_PED);
1582  }
1583  // compute utility for all stripes
1584  std::vector<double> utility(stripes, 0);
1585  // forbid stripes which are blocked and also all stripes behind them
1586  for (int i = 0; i < stripes; ++i) {
1587  if (distance[i] == DIST_OVERLAP) {
1588  if (i == current && (!myWaitingToEnter || stripe() != stripe(myRelY))) {
1589  utility[i] += OBSTRUCTED_PENALTY;
1590  }
1591  if (i < current) {
1592  for (int j = 0; j <= i; ++j) {
1593  utility[j] += OBSTRUCTED_PENALTY;
1594  }
1595  }
1596  if (i > current) {
1597  for (int j = i; j < stripes; ++j) {
1598  utility[j] += OBSTRUCTED_PENALTY;
1599  }
1600  }
1601  }
1602  }
1603  // forbid a portion of the leftmost stripes (in walking direction).
1604  // lanes with stripes less than 1 / RESERVE_FOR_ONCOMING_FACTOR
1605  // may still deadlock in heavy pedestrian traffic
1606  const bool onJunction = myLane->getEdge().isWalkingArea() || myLane->getEdge().isCrossing();
1607  const int reserved = (int)floor(stripes * (onJunction ? RESERVE_FOR_ONCOMING_FACTOR_JUNCTIONS : RESERVE_FOR_ONCOMING_FACTOR));
1608  if (myDir == FORWARD) {
1609  for (int i = 0; i < reserved; ++i) {
1610  utility[i] += INAPPROPRIATE_PENALTY * (i == current ? 0.5 : 1);
1611  }
1612  } else {
1613  for (int i = sMax; i > sMax - reserved; --i) {
1614  utility[i] += INAPPROPRIATE_PENALTY * (i == current ? 0.5 : 1);
1615  }
1616  }
1617  // adapt utility based on obstacles
1618  for (int i = 0; i < stripes; ++i) {
1619  if (obs[i].speed * myDir < 0) {
1620  // penalize evasion to the left
1621  if (myDir == FORWARD && i > 0) {
1622  utility[i - 1] -= 0.5;
1623  } else if (myDir == BACKWARD && i < sMax) {
1624  utility[i + 1] -= 0.5;
1625  }
1626  }
1627  // compute expected distance achievable by staying on this stripe for a time horizon
1628  const double walkDist = MAX2(0., distance[i]); // disregard special distance flags
1629  const double lookAhead = obs[i].speed * myDir >= 0 ? LOOKAHEAD_SAMEDIR : LOOKAHEAD_ONCOMING;
1630  const double expectedDist = MIN2(vMax * LOOKAHEAD_SAMEDIR, walkDist + obs[i].speed * myDir * lookAhead);
1631  if (DEBUGCOND(*this)) {
1632  std::cout << " util=" << utility[i] << " exp=" << expectedDist << " dist=" << distance[i] << "\n";
1633  }
1634  if (expectedDist >= 0) {
1635  utility[i] += expectedDist;
1636  } else {
1637  // let only the distance count
1638  utility[i] += ONCOMING_CONFLICT_PENALTY + distance[i];
1639  }
1640  }
1641  // discourage use of the leftmost lane (in walking direction) if there are oncoming
1642  if (myDir == FORWARD && obs[0].speed < 0) {
1643  utility[0] += ONCOMING_CONFLICT_PENALTY;
1644  } else if (myDir == BACKWARD && obs[sMax].speed > 0) {
1645  utility[sMax] += ONCOMING_CONFLICT_PENALTY;
1646  }
1647  // penalize lateral movement (if the current stripe permits walking)
1648  if (distance[current] > 0 && myWaitingTime == 0) {
1649  for (int i = 0; i < stripes; ++i) {
1650  utility[i] += abs(i - current) * LATERAL_PENALTY;
1651  }
1652  }
1653 
1654  // select best stripe
1655  int chosen = current;
1656  for (int i = 0; i < stripes; ++i) {
1657  if (utility[chosen] < utility[i]) {
1658  chosen = i;
1659  }
1660  }
1661  // compute speed components along both axes
1662  const int next = (chosen == current ? current : (chosen < current ? current - 1 : current + 1));
1663  double xDist = MIN3(distance[current], distance[other], distance[next]);
1664  if (next != chosen) {
1665  // ensure that we do not collide with an obstacle in the stripe beyond
1666  // next as this might become the 'other' stripe in the next step
1667  const int nextOther = chosen < current ? current - 2 : current + 2;
1668  xDist = MIN2(xDist, distance[nextOther]);
1669  }
1670  // XXX preferred gap differs between approaching a standing obstacle or a moving obstacle
1671  const double preferredGap = NUMERICAL_EPS;
1672  double xSpeed = MIN2(vMax, MAX2(0., DIST2SPEED(xDist - preferredGap)));
1673  if (xSpeed < NUMERICAL_EPS) {
1674  xSpeed = 0.;
1675  }
1676  if (DEBUGCOND(*this)) {
1677  std::cout << " xSpeedPotential=" << xSpeed << "\n";
1678  }
1679  // avoid tiny steps
1680  // XXX pressure from behind?
1681  if (mySpeed == 0 && xDist < MIN_STARTUP_DIST &&
1682  // unless walking towards a short lane
1683  !(
1684  (xDist == distance[current] && obs[current].type >= OBSTACLE_END)
1685  || (xDist == distance[other] && obs[other].type >= OBSTACLE_END)
1686  || (xDist == distance[next] && obs[next].type >= OBSTACLE_END))
1687  ) {
1688  xSpeed = 0;
1689  }
1690  if (xSpeed == 0) {
1691  if (myWaitingTime > (myLane->getEdge().isCrossing() ? jamTimeCrossing : jamTime) || myAmJammed) {
1692  // squeeze slowly through the crowd ignoring others
1693  if (!myAmJammed) {
1695  WRITE_WARNING("Person '" + myPerson->getID()
1696  + "' is jammed on edge '" + myStage->getEdge()->getID()
1697  + "', time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
1698  myAmJammed = true;
1699  }
1700  xSpeed = vMax / 4;
1701  }
1702  } else if (stripe(myRelY) >= 0 && stripe(myRelY) <= sMax) {
1703  myAmJammed = false;
1704  }
1705  // dawdling
1706  const double dawdle = MIN2(xSpeed, RandHelper::rand() * vMax * dawdling);
1707  xSpeed -= dawdle;
1708 
1709  // XXX ensure that diagonal speed <= vMax
1710  // avoid deadlocks on narrow sidewalks
1711  //if (oncoming && xSpeed == 0 && myStage->getWaitingTime(currentTime) > TIME2STEPS(ONCOMIN_PATIENCE)) {
1712  // if DEBUGCOND(*this) std::cout << " stepping asside to resolve oncoming deadlock\n";
1713  // xSpeed = POSITION_EPS; // reset myWaitingTime
1714  // if (myDir == FORWARD && chosen < sMax) {
1715  // chosen += 1;
1716  // } else if (myDir == BACKWARD && chosen > 0) {
1717  // chosen -= 1;
1718  // }
1719  //}
1720  const double maxYSpeed = MIN2(MAX2(vMax * LATERAL_SPEED_FACTOR, vMax - xSpeed), stripeWidth);
1721  double ySpeed = 0;
1722  double yDist = 0;
1723  if (utility[next] > OBSTRUCTION_THRESHOLD && utility[chosen] > OBSTRUCTION_THRESHOLD) {
1724  // don't move laterally if the stripes are blocked
1725  yDist = (chosen * stripeWidth) - myRelY;
1726  if (fabs(yDist) > NUMERICAL_EPS) {
1727  ySpeed = (yDist > 0 ?
1728  MIN2(maxYSpeed, DIST2SPEED(yDist)) :
1729  MAX2(-maxYSpeed, DIST2SPEED(yDist)));
1730  }
1731  } else if (utility[next] <= OBSTRUCTION_THRESHOLD && obs[next].type == OBSTACLE_VEHICLE
1732  // still on the road
1733  && stripe() == stripe(myRelY)
1734  // only when the vehicle is moving on the same lane
1735  && !myLane->getEdge().isCrossing()) {
1736  // step aside to let the vehicle pass
1737  myRelY += myDir * vMax;
1738  }
1739  // DEBUG
1740  if DEBUGCOND(*this) {
1741  std::cout << SIMTIME
1742  << " ped=" << myPerson->getID()
1743  << " edge=" << myStage->getEdge()->getID()
1744  << " x=" << myRelX
1745  << " y=" << myRelY
1746  << " d=" << myDir
1747  << " pvx=" << mySpeed
1748  << " cur=" << current
1749  << " cho=" << chosen
1750  << " oth=" << other
1751  << " nxt=" << next
1752  << " vx=" << xSpeed
1753  << " dawdle=" << dawdle
1754  << " vy=" << ySpeed
1755  << " xd=" << xDist
1756  << " yd=" << yDist
1757  << " vMax=" << myStage->getMaxSpeed(myPerson)
1758  << " wTime=" << myStage->getWaitingTime(currentTime)
1759  << " jammed=" << myAmJammed
1760  << "\n distance=" << toString(distance)
1761  << "\n utility=" << toString(utility)
1762  << "\n";
1763  DEBUG_PRINT(obs);
1764  }
1765  myRelX += SPEED2DIST(xSpeed * myDir);
1766  myRelY += SPEED2DIST(ySpeed);
1767  mySpeed = xSpeed;
1768  if (xSpeed >= SUMO_const_haltingSpeed) {
1769  myWaitingToEnter = false;
1770  myWaitingTime = 0;
1771  } else {
1772  myWaitingTime += DELTA_T;
1773  }
1774 }
1775 
1776 
1777 double
1779  return MAX2(0., MIN2(1., myPerson->getVehicleType().getImpatience()
1780  + STEPS2TIME(myStage->getWaitingTime(now)) / MAX_WAIT_TOLERANCE));
1781 }
1782 
1783 
1784 double
1786  return myRelX;
1787 }
1788 
1789 
1790 Position
1792  if (myLane == nullptr) {
1793  // pedestrian has already finished
1794  return Position::INVALID;
1795  }
1796  const double lateral_offset = myRelY + (stripeWidth - myLane->getWidth()) * 0.5;
1797  if (myWalkingAreaPath == nullptr) {
1798  return stage.getLanePosition(myLane, myRelX, lateral_offset);
1799  } else {
1800  //if DEBUGCOND(*this) {
1801  // std::cout << SIMTIME
1802  // << " getPosition (walkingArea)"
1803  // << " p=" << myPerson->getID()
1804  // << " x=" << myRelX
1805  // << " y=" << myRelY
1806  // << " latOffset=" << lateral_offset
1807  // << " shape=" << myWalkingAreaPath->shape
1808  // << " pos=" << myWalkingAreaPath->shape.positionAtOffset(myRelX, lateral_offset)
1809  // << "\n";
1810  //}
1811  return myWalkingAreaPath->shape.positionAtOffset(myRelX, lateral_offset);
1812  }
1813 }
1814 
1815 
1816 double
1818  if (myAngle != std::numeric_limits<double>::max()) {
1819  return myAngle;
1820  }
1821  if (myLane == nullptr) {
1822  // pedestrian has already finished
1823  return 0;
1824  }
1825  const PositionVector& shp = myWalkingAreaPath == nullptr ? myLane->getShape() : myWalkingAreaPath->shape;
1826  double angle = shp.rotationAtOffset(myRelX) + (myDir == MSPModel::BACKWARD ? M_PI : 0);
1827  if (angle > M_PI) {
1828  angle -= 2 * M_PI;
1829  }
1830  myAngle = angle;
1831  return angle;
1832 }
1833 
1834 
1835 SUMOTime
1837  return myWaitingTime;
1838 }
1839 
1840 
1841 double
1843  return mySpeed;
1844 }
1845 
1846 
1847 const MSEdge*
1849  return myNLI.lane == nullptr ? nullptr : &myNLI.lane->getEdge();
1850 }
1851 
1852 void
1854  double lanePosLat, double angle, int routeOffset,
1855  const ConstMSEdgeVector& edges, SUMOTime t) {
1856  UNUSED_PARAMETER(p);
1857  assert(p == myPerson);
1858  myAngle = angle;
1859  myAngle = GeomHelper::fromNaviDegree(angle);
1860  /*
1861  std::cout << " MSPModel_Striping::PState::moveToXY"
1862  << " pos=" << pos
1863  << " lane=" << lane->getID()
1864  << " lanePos=" << lanePos
1865  << " lanePosLat=" << lanePosLat
1866  << " angle=" << angle
1867  << " routeOffset=" << routeOffset
1868  << " myRelX=" << myRelX << " myRelY=" << myRelY;
1869  */
1870  //std::cout << " newX=" << myRelX << " newY=" << myRelY << "\n";
1871  if (lane != nullptr) {
1872  myRemoteXYPos = Position::INVALID;
1873  const MSLane* sidewalk = getSidewalk<MSEdge, MSLane>(&lane->getEdge());
1874  if (lane != sidewalk) {
1875  MSPModel_Striping* pm = dynamic_cast<MSPModel_Striping*>(MSPModel::getModel());
1876  assert(pm != 0);
1877  // add a new active lane
1878  pm->remove(this);
1879  pm->add(this, lane);
1880  }
1881  if (edges.empty()) {
1882  // map within route
1883  myStage->setRouteIndex(myPerson, routeOffset);
1884  if (lane->getEdge().isInternal()) {
1885  myStage->moveToNextEdge(myPerson, t, &lane->getEdge());
1886  }
1887  } else {
1888  // map to new edge
1889  }
1890  myLane = lane;
1891  myRelX = lanePos;
1892  myRelY = (myLane->getWidth() - stripeWidth) * 0.5 - lanePosLat;
1893  } else {
1894  // map outside the network
1895  myRemoteXYPos = pos;
1896  }
1897 
1898 }
1899 
1900 
1901 
1902 double
1903 MSPModel_Striping::PState::distanceTo(const Obstacle& obs, const bool includeMinGap) const {
1904  // check for overlap
1905  const double maxX = getMaxX(includeMinGap);
1906  const double minX = getMinX(includeMinGap);
1907  //if (DEBUGCOND(*this)) {
1908  // std::cout << std::setprecision(2) << " distanceTo=" << obs.description << " maxX=" << maxX << " minX=" << minX << " obs.xFwd=" << obs.xFwd << " obs.xBack=" << obs.xBack << "\n";
1909  //}
1910  if ((obs.xFwd >= maxX && obs.xBack <= maxX) || (obs.xFwd <= maxX && obs.xFwd >= minX)) {
1911  // avoid blocking by itself on looped route
1912  return (obs.type == OBSTACLE_PED && obs.description == myPerson->getID()) ? DIST_FAR_AWAY : DIST_OVERLAP;
1913  }
1914  if (myDir == FORWARD) {
1915  return obs.xFwd < minX ? DIST_BEHIND : obs.xBack - maxX;
1916  } else {
1917  return obs.xBack > maxX ? DIST_BEHIND : minX - obs.xFwd;
1918  }
1919 }
1920 
1921 
1922 void
1924  for (int i = 0; i < (int)into.size(); ++i) {
1925  if (gDebugFlag1) {
1926  std::cout << " i=" << i << " maxX=" << getMaxX(true) << " minX=" << getMinX(true)
1927  << " into=" << into[i].description << " iDist=" << distanceTo(into[i], into[i].type == OBSTACLE_PED)
1928  << " obs2=" << obs2[i].description << " oDist=" << distanceTo(obs2[i], obs2[i].type == OBSTACLE_PED) << "\n";
1929  }
1930  const double dO = distanceTo(obs2[i], obs2[i].type == OBSTACLE_PED);
1931  const double dI = distanceTo(into[i], into[i].type == OBSTACLE_PED);
1932  if (dO < dI) {
1933  into[i] = obs2[i];
1934  } else if (dO == dI
1935  && into[i].type != OBSTACLE_PED
1936  && into[i].type != OBSTACLE_VEHICLE
1937  && (obs2[i].type == OBSTACLE_PED ||
1938  obs2[i].type == OBSTACLE_VEHICLE)) {
1939  into[i] = obs2[i];
1940  }
1941  }
1942 }
1943 
1944 void
1945 MSPModel_Striping::PState::mergeObstacles(Obstacles& into, const Obstacles& obs2, int dir, int offset) {
1946  for (int i = 0; i < (int)into.size(); ++i) {
1947  int i2 = i + offset;
1948  if (i2 >= 0 && i2 < (int)obs2.size()) {
1949  if (dir == FORWARD) {
1950  if (obs2[i2].xBack < into[i].xBack) {
1951  into[i] = obs2[i2];
1952  }
1953  } else {
1954  if (obs2[i2].xFwd > into[i].xFwd) {
1955  into[i] = obs2[i2];
1956  }
1957  }
1958  }
1959  }
1960 }
1961 
1962 
1963 bool
1965  if (link->haveRed()) {
1966  const double ignoreRedTime = myPerson->getVehicleType().getParameter().getJMParam(SUMO_ATTR_JM_DRIVE_AFTER_RED_TIME, -1);
1967  if (ignoreRedTime >= 0) {
1968  const double redDuration = STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep() - link->getLastStateChange());
1969  if (DEBUGCOND(*this)) {
1970  std::cout << SIMTIME << " ignoreRedTime=" << ignoreRedTime << " redDuration=" << redDuration << "\n";
1971  }
1972  return ignoreRedTime > redDuration;
1973  } else {
1974  return false;
1975  }
1976  } else {
1977  return false;
1978  }
1979 }
1980 
1981 const std::string&
1983  return myPerson->getID();
1984 }
1985 
1986 double
1988  return myPerson->getVehicleType().getWidth();
1989 }
1990 
1991 // ===========================================================================
1992 // MSPModel_Striping::PStateVehicle method definitions
1993 // ===========================================================================
1994 
1995 MSPModel_Striping::PStateVehicle::PStateVehicle(const MSVehicle* veh, const MSLane* walkingarea, double relX, double relY):
1996  myVehicle(veh) {
1997  myLane = walkingarea; // to ensure correct limits when calling otherStripe()
1998  myRelX = relX;
1999  myRelY = relY;
2000 }
2001 
2002 const std::string&
2004  return myVehicle->getID();
2005 }
2006 
2007 double
2009  return myVehicle->getVehicleType().getWidth();
2010 }
2011 
2012 double
2013 MSPModel_Striping::PStateVehicle::getMinX(const bool /*includeMinGap*/) const {
2014  return myRelX - myVehicle->getVehicleType().getWidth() / 2 - SAFETY_GAP ;
2015 }
2016 
2017 double
2018 MSPModel_Striping::PStateVehicle::getMaxX(const bool /*includeMinGap*/) const {
2019  return myRelX + myVehicle->getVehicleType().getWidth() / 2 + SAFETY_GAP;
2020 }
2021 
2022 // ===========================================================================
2023 // MSPModel_Striping::MovePedestrians method definitions
2024 // ===========================================================================
2025 
2026 SUMOTime
2028  std::set<MSPerson*> changedLane;
2029  myModel->moveInDirection(currentTime, changedLane, FORWARD);
2030  myModel->moveInDirection(currentTime, changedLane, BACKWARD);
2031  // DEBUG
2032 #ifdef LOG_ALL
2033  for (ActiveLanes::const_iterator it_lane = myModel->getActiveLanes().begin(); it_lane != myModel->getActiveLanes().end(); ++it_lane) {
2034  const MSLane* lane = it_lane->first;
2035  Pedestrians pedestrians = it_lane->second;
2036  if (pedestrians.size() == 0) {
2037  continue;
2038  }
2039  sort(pedestrians.begin(), pedestrians.end(), by_xpos_sorter(FORWARD));
2040  std::cout << SIMTIME << " lane=" << lane->getID();
2041  for (int ii = 0; ii < (int)pedestrians.size(); ++ii) {
2042  const PState& p = *pedestrians[ii];
2043  std::cout << " (" << p.myPerson->getID() << " " << p.myRelX << "," << p.myRelY << " " << p.myDir << ")";
2044  }
2045  std::cout << "\n";
2046  }
2047 #endif
2048  return DELTA_T;
2049 }
2050 
MSPModel_Striping::PState::myLane
const MSLane * myLane
the current lane of this pedestrian
Definition: MSPModel_Striping.h:289
MSPModel_Striping::PState
Container for pedestrian state and individual position update function.
Definition: MSPModel_Striping.h:265
MSPModel_Striping::LOOKAROUND_VEHICLES
static const double LOOKAROUND_VEHICLES
Definition: MSPModel_Striping.h:113
UNUSED_PARAMETER
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:32
MSNet::hasInternalLinks
bool hasInternalLinks() const
return whether the network contains internal links
Definition: MSNet.h:642
MSPModel_Striping::WalkingAreaPath::to
const MSLane * to
Definition: MSPModel_Striping.h:237
SPEED2DIST
#define SPEED2DIST(x)
Definition: SUMOTime.h:47
MSPModel_Striping::SQUEEZE
static const double SQUEEZE
Definition: MSPModel_Striping.h:131
MSCFModel::brakeGap
double brakeGap(const double speed) const
Returns the distance the vehicle needs to halt including driver's reaction time tau (i....
Definition: MSCFModel.h:313
MSEdge::getSuccessors
const MSEdgeVector & getSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges, restricted by vClass.
Definition: MSEdge.cpp:998
MSPModel_Striping::NextLaneInfo::link
const MSLink * link
Definition: MSPModel_Striping.h:188
MIN2
T MIN2(T a, T b)
Definition: StdDefs.h:74
MSCFModel::getMaxDecel
double getMaxDecel() const
Get the vehicle type's maximal comfortable deceleration [m/s^2].
Definition: MSCFModel.h:218
MSEventControl::addEvent
virtual void addEvent(Command *operation, SUMOTime execTimeStep=-1)
Adds an Event.
Definition: MSEventControl.cpp:53
MSPModel_Striping::MIN_STARTUP_DIST
static const double MIN_STARTUP_DIST
Definition: MSPModel_Striping.h:144
WRITE_WARNING
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:239
DIST2SPEED
#define DIST2SPEED(x)
Definition: SUMOTime.h:49
MSPModel::canTraverse
static int canTraverse(int dir, const ConstMSEdgeVector &route)
Definition: MSPModel.cpp:92
MSNet.h
MSPModel::BACKWARD
static const int BACKWARD
Definition: MSPModel.h:104
MSLane
Representation of a lane in the micro simulation.
Definition: MSLane.h:83
MSPModel_Striping::myAmActive
bool myAmActive
whether an event for pedestrian processing was added
Definition: MSPModel_Striping.h:492
MSPModel_Striping::MovePedestrians
Definition: MSPModel_Striping.h:383
MSPModel_Striping::PState::myWalkingAreaPath
WalkingAreaPath * myWalkingAreaPath
the current walkingAreaPath or 0
Definition: MSPModel_Striping.h:305
PedestrianRouter::compute
double compute(const E *from, const E *to, double departPos, double arrivalPos, double speed, SUMOTime msTime, const N *onlyNode, std::vector< const E * > &into, bool allEdges=false)
Builds the route between the given edges using the minimum effort at the given time The definition of...
Definition: PedestrianRouter.h:85
MSJunction
The base class for an intersection.
Definition: MSJunction.h:61
MSPModel_Striping::PState::myStage
MSPerson::MSPersonStage_Walking * myStage
Definition: MSPModel_Striping.h:287
MSLane::anyVehiclesUpstreamBegin
AnyVehicleIterator anyVehiclesUpstreamBegin() const
begin iterator for iterating over all vehicles touching this lane in upstream direction
Definition: MSLane.h:446
MSPModel_Striping::DIST_BEHIND
static const double DIST_BEHIND
Definition: MSPModel_Striping.h:151
DELTA_T
SUMOTime DELTA_T
Definition: SUMOTime.cpp:35
NUMERICAL_EPS
#define NUMERICAL_EPS
Definition: config.h:145
MSTransportable::Stage::getLanePosition
Position getLanePosition(const MSLane *lane, double at, double offset) const
get position on lane at length at with orthogonal offset
Definition: MSTransportable.cpp:129
MSLane::getCanonicalSuccessorLane
MSLane * getCanonicalSuccessorLane() const
Definition: MSLane.cpp:2598
MSPModel_Striping::LOOKAHEAD_ONCOMING
static const double LOOKAHEAD_ONCOMING
Definition: MSPModel_Striping.h:111
Position::INVALID
static const Position INVALID
used to indicate that a position is valid
Definition: Position.h:285
OptionsCont.h
MSPModel_Striping::getArbitraryPath
static WalkingAreaPath * getArbitraryPath(const MSEdge *walkingArea)
return an arbitrary path across the given walkingArea
Definition: MSPModel_Striping.cpp:399
MSPModel_Striping::jamTimeCrossing
static SUMOTime jamTimeCrossing
Definition: MSPModel_Striping.h:106
MSNet::getBeginOfTimestepEvents
MSEventControl * getBeginOfTimestepEvents()
Returns the event control for events executed at the begin of a time step.
Definition: MSNet.h:430
MSPModel_Striping::WalkingAreaPath::from
const MSLane * from
Definition: MSPModel_Striping.h:234
MINGAP_TO_VEHICLE
#define MINGAP_TO_VEHICLE
Definition: MSPModel_Striping.cpp:101
MSPModel_Striping::numStripes
static int numStripes(const MSLane *lane)
return the maximum number of pedestrians walking side by side
Definition: MSPModel_Striping.cpp:291
MSNet
The simulated network and simulation perfomer.
Definition: MSNet.h:92
MSPModel_Striping::getNeighboringObstacles
static Obstacles getNeighboringObstacles(const Pedestrians &pedestrians, int egoIndex, int stripes)
Definition: MSPModel_Striping.cpp:627
MSVehicle::getBackPosition
const Position getBackPosition() const
Definition: MSVehicle.cpp:1495
MSPModel_Striping::PState::getWidth
virtual double getWidth() const
return the person width
Definition: MSPModel_Striping.cpp:1987
MSPModel_Striping::PState::getID
virtual const std::string & getID() const
return the person id
Definition: MSPModel_Striping.cpp:1982
MSPModel_Striping::PState::getMinGap
double getMinGap() const
return the minimum gap of the pedestrian
Definition: MSPModel_Striping.cpp:1391
MSPerson
Definition: MSPerson.h:64
MSPModel_Striping::getNextWalkingArea
static const MSLane * getNextWalkingArea(const MSLane *currentLane, const int dir, MSLink *&link)
return the next walkingArea in the given direction
Definition: MSPModel_Striping.cpp:604
MSPModel::SAFETY_GAP
static const double SAFETY_GAP
Definition: MSPModel.h:108
MSPModel_Striping::PState::ignoreRed
bool ignoreRed(const MSLink *link) const
whether the pedestrian may ignore a red light
Definition: MSPModel_Striping.cpp:1964
OptionsCont::getString
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
Definition: OptionsCont.cpp:202
MSPModel_Striping::connectedDirection
static int connectedDirection(const MSLane *from, const MSLane *to)
returns the direction in which these lanes are connectioned or 0 if they are not
Definition: MSPModel_Striping.cpp:296
SUMOTime
long long int SUMOTime
Definition: SUMOTime.h:35
ConstMSEdgeVector
std::vector< const MSEdge * > ConstMSEdgeVector
Definition: MSEdge.h:73
MSPModel_Striping::PStateVehicle::getID
const std::string & getID() const
return the person id
Definition: MSPModel_Striping.cpp:2003
MSPModel_Striping::~MSPModel_Striping
~MSPModel_Striping()
Definition: MSPModel_Striping.cpp:127
OptionsCont::getBool
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
Definition: OptionsCont.cpp:223
OptionsCont::getOptions
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:58
MSPModel_Striping::PState::myPerson
MSPerson * myPerson
Definition: MSPModel_Striping.h:285
MSPModel_Striping::OBSTACLE_LINKCLOSED
Definition: MSPModel_Striping.h:199
MSPModel_Striping::PState::getMaxX
virtual double getMaxX(const bool includeMinGap=true) const
return the maximum position on the lane
Definition: MSPModel_Striping.cpp:1375
MSPModel_Striping::usingInternalLanesStatic
static bool usingInternalLanesStatic()
Definition: MSPModel_Striping.cpp:227
PositionVector::extrapolate
void extrapolate(const double val, const bool onlyFirst=false, const bool onlyLast=false)
extrapolate position vector
Definition: PositionVector.cpp:1025
MSEdge.h
MSPModel_Striping::PState::mySpeed
double mySpeed
the current walking speed
Definition: MSPModel_Striping.h:297
MSPModel_Striping::remove
void remove(PedestrianState *state)
remove the specified person from the pedestrian simulation
Definition: MSPModel_Striping.cpp:166
MSPModel_Striping::PState::getLength
double getLength() const
return the length of the pedestrian
Definition: MSPModel_Striping.cpp:1385
MSPModel_Striping
The pedestrian following model.
Definition: MSPModel_Striping.h:51
MSPModel_Striping::OBSTRUCTION_THRESHOLD
static const double OBSTRUCTION_THRESHOLD
Definition: MSPModel_Striping.h:128
MSPModel_Striping::LATERAL_PENALTY
static const double LATERAL_PENALTY
Definition: MSPModel_Striping.h:116
PositionVector
A list of positions.
Definition: PositionVector.h:46
MSEdge::getLength
double getLength() const
return the length of the edge
Definition: MSEdge.h:582
MSPModel_Striping::OBSTACLE_VEHICLE
Definition: MSPModel_Striping.h:196
MSVehicle::getCarFollowModel
const MSCFModel & getCarFollowModel() const
Returns the vehicle's car following model definition.
Definition: MSVehicle.h:894
MSTransportableControl::registerJammed
void registerJammed()
register a jammed transportable
Definition: MSTransportableControl.h:171
MSPModel_Striping::usingInternalLanes
bool usingInternalLanes()
whether movements on intersections are modelled /
Definition: MSPModel_Striping.cpp:222
MSTransportable::getCurrentStageType
StageType getCurrentStageType() const
the current stage type of the transportable
Definition: MSTransportable.h:658
SUMO_const_haltingSpeed
const double SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
Definition: StdDefs.h:61
MSLane::getIncomingLanes
const std::vector< IncomingLaneInfo > & getIncomingLanes() const
Definition: MSLane.h:819
MSPModel_Striping::moveInDirection
void moveInDirection(SUMOTime currentTime, std::set< MSPerson * > &changedLane, int dir)
move all pedestrians forward and advance to the next lane if applicable
Definition: MSPModel_Striping.cpp:810
MSTransportable::Stage::getDestination
const MSEdge * getDestination() const
returns the destination edge
Definition: MSTransportable.cpp:58
MSPModel_Striping::getPedestrians
Pedestrians & getPedestrians(const MSLane *lane)
retrieves the pedestian vector for the given lane (may be empty)
Definition: MSPModel_Striping.cpp:269
MSPModel_Striping::PState::mergeObstacles
void mergeObstacles(Obstacles &into, const Obstacles &obs2)
replace obstacles in the first vector with obstacles from the second if they are closer to me
Definition: MSPModel_Striping.cpp:1923
INVALID
#define INVALID
Definition: MSDevice_SSM.cpp:70
MSVehicle::getLateralPositionOnLane
double getLateralPositionOnLane() const
Get the vehicle's lateral position on the lane.
Definition: MSVehicle.h:434
MSPModel_Striping::Obstacle::speed
double speed
speed relative to lane direction (positive means in the same direction)
Definition: MSPModel_Striping.h:218
MSPModel_Striping::WalkingAreaPaths
std::map< std::pair< const MSLane *, const MSLane * >, WalkingAreaPath > WalkingAreaPaths
Definition: MSPModel_Striping.h:169
PedestrianState
abstract base class for managing callbacks to retrieve various state information from the model
Definition: MSPModel.h:128
MSPModel_Striping::PState::moveToNextLane
bool moveToNextLane(SUMOTime currentTime)
return whether this pedestrian has passed the end of the current lane and update myRelX if so
Definition: MSPModel_Striping.cpp:1445
MAX2
T MAX2(T a, T b)
Definition: StdDefs.h:80
MSEdge::isInternal
bool isInternal() const
return whether this edge is an internal edge
Definition: MSEdge.h:233
MSPModel_Striping::PState::moveToXY
void moveToXY(MSPerson *p, Position pos, MSLane *lane, double lanePos, double lanePosLat, double angle, int routeOffset, const ConstMSEdgeVector &edges, SUMOTime t)
try to move person to the given position
Definition: MSPModel_Striping.cpp:1853
MSPModel_Striping::nextBlocking
PersonDist nextBlocking(const MSLane *lane, double minPos, double minRight, double maxLeft, double stopTime=0)
returns the next pedestrian beyond minPos that is laterally between minRight and maxLeft or 0
Definition: MSPModel_Striping.cpp:232
MSVehicle::getPosition
Position getPosition(const double offset=0) const
Return current position (x/y, cartesian)
Definition: MSVehicle.cpp:1280
MSPModel_Striping::addCrossingVehs
static bool addCrossingVehs(const MSLane *crossing, int stripes, double lateral_offset, int dir, Obstacles &crossingVehs, bool prio)
add vehicles driving across
Definition: MSPModel_Striping.cpp:1098
MSPModel_Striping::OBSTACLE_END
Definition: MSPModel_Striping.h:197
MSPModel_Striping::myWalkingAreaPaths
static WalkingAreaPaths myWalkingAreaPaths
store for walkinArea elements
Definition: MSPModel_Striping.h:495
MSPModel_Striping::PState::myAmJammed
bool myAmJammed
whether the person is jammed
Definition: MSPModel_Striping.h:307
MSEdge::getFromJunction
const MSJunction * getFromJunction() const
Definition: MSEdge.h:357
MSTransportable::getEdge
const MSEdge * getEdge() const
Returns the current edge.
Definition: MSTransportable.h:628
RandHelper::rand
static double rand(std::mt19937 *rng=0)
Returns a random real number in [0, 1)
Definition: RandHelper.h:60
MSEdge::isCrossing
bool isCrossing() const
return whether this edge is a pedestrian crossing
Definition: MSEdge.h:238
SIMTIME
#define SIMTIME
Definition: SUMOTime.h:64
MSPModel_Striping::DIST_OVERLAP
static const double DIST_OVERLAP
Definition: MSPModel_Striping.h:152
PositionVector::push_back_noDoublePos
void push_back_noDoublePos(const Position &p)
insert in back a non double position
Definition: PositionVector.cpp:1258
MSPModel_Striping::PStateVehicle::getMinX
double getMinX(const bool includeMinGap=true) const
return the minimum position on the lane
Definition: MSPModel_Striping.cpp:2013
PositionVector::transformToVectorCoordinates
Position transformToVectorCoordinates(const Position &p, bool extend=false) const
return position p within the length-wise coordinate system defined by this position vector....
Definition: PositionVector.cpp:882
PersonDist
std::pair< const MSPerson *, double > PersonDist
Definition: MSPModel.h:38
MSPModel_Striping::noPedestrians
static Pedestrians noPedestrians
empty pedestrian vector
Definition: MSPModel_Striping.h:500
MSPModel_Striping::PState::walk
void walk(const Obstacles &obs, SUMOTime currentTime)
perform position update
Definition: MSPModel_Striping.cpp:1569
MSPModel_Striping::PState::myNLI
NextLaneInfo myNLI
information about the upcoming lane
Definition: MSPModel_Striping.h:303
MSPModel_Striping::RESERVE_FOR_ONCOMING_FACTOR_JUNCTIONS
static const double RESERVE_FOR_ONCOMING_FACTOR_JUNCTIONS
Definition: MSPModel_Striping.h:135
MSGlobals::gCheck4Accidents
static bool gCheck4Accidents
Definition: MSGlobals.h:76
DEBUGCOND2
#define DEBUGCOND2(LANE)
Definition: MSPModel_Striping.cpp:49
MSVehicleType::getWidth
double getWidth() const
Get the width which vehicles of this class shall have when being drawn.
Definition: MSVehicleType.h:247
MSPModel_Striping::getVehicleObstacles
static Obstacles getVehicleObstacles(const MSLane *lane, int dir, PState *ped=0)
retrieve vehicle obstacles on the given lane
Definition: MSPModel_Striping.cpp:1176
MSPModel_Striping::OBSTACLE_ARRIVALPOS
Definition: MSPModel_Striping.h:200
MSTransportableControl.h
TIME2STEPS
#define TIME2STEPS(x)
Definition: SUMOTime.h:59
MSJunction.h
MSLane::getVehicleNumberWithPartials
int getVehicleNumberWithPartials() const
Returns the number of vehicles on this lane (including partial occupators)
Definition: MSLane.h:409
PedestrianRouter.h
MSPModel_Striping::WalkingAreaPath::shape
PositionVector shape
Definition: MSPModel_Striping.h:239
MSPModel_Striping::PState::myRelX
double myRelX
the advancement along the current lane
Definition: MSPModel_Striping.h:291
MSNet::getCurrentTimeStep
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:284
MSPModel_Striping::ObstacleType
ObstacleType
Definition: MSPModel_Striping.h:193
STEPS2TIME
#define STEPS2TIME(x)
Definition: SUMOTime.h:57
MSPModel_Striping::PState::distToLaneEnd
double distToLaneEnd() const
the absolute distance to the end of the lane in walking direction (or to the arrivalPos)
Definition: MSPModel_Striping.cpp:1434
MSPModel_Striping::arriveAndAdvance
void arriveAndAdvance(Pedestrians &pedestrians, SUMOTime currentTime, std::set< MSPerson * > &changedLane, int dir)
handle arrivals and lane advancement
Definition: MSPModel_Striping.cpp:929
MSPModel_Striping::OBSTRUCTED_PENALTY
static const double OBSTRUCTED_PENALTY
Definition: MSPModel_Striping.h:119
MSLane::getLength
double getLength() const
Returns the lane's length.
Definition: MSLane.h:541
MSPModel_Striping::PState::getPosition
Position getPosition(const MSPerson::MSPersonStage_Walking &stage, SUMOTime now) const
return the network coordinate of the person
Definition: MSPModel_Striping.cpp:1791
MSPModel_Striping::PState::getSpeed
double getSpeed(const MSPerson::MSPersonStage_Walking &stage) const
return the current speed of the person
Definition: MSPModel_Striping.cpp:1842
ProcessError
Definition: UtilExceptions.h:40
MSPerson::MSPersonStage_Walking::getMaxSpeed
double getMaxSpeed(const MSTransportable *const person) const
accessors to be used by MSPModel
Definition: MSPerson.cpp:379
MSPModel_Striping::Obstacle::xFwd
double xFwd
maximal position on the current lane in forward direction
Definition: MSPModel_Striping.h:211
Position
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:39
Position::x
double x() const
Returns the x-position.
Definition: Position.h:57
MSPModel_Striping::getStripeOffset
static int getStripeOffset(int origStripes, int destStripes, bool addRemainder)
Definition: MSPModel_Striping.cpp:667
time2string
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:65
MSGlobals.h
MSPModel_Striping::OBSTACLE_NEXTEND
Definition: MSPModel_Striping.h:198
MSPModel_Striping::NextLanesObstacles
std::map< const MSLane *, Obstacles, lane_by_numid_sorter > NextLanesObstacles
Definition: MSPModel_Striping.h:168
OptionsCont
A storage for options typed value containers)
Definition: OptionsCont.h:90
MSEdge
A road/street connecting two junctions.
Definition: MSEdge.h:76
MSPModel_Striping::PState::myRelY
double myRelY
the orthogonal shift on the current lane
Definition: MSPModel_Striping.h:293
MSEdge::getToJunction
const MSJunction * getToJunction() const
Definition: MSEdge.h:361
MSPModel_Striping::PState::otherStripe
int otherStripe() const
Definition: MSPModel_Striping.cpp:1428
MSBaseVehicle::getVehicleType
const MSVehicleType & getVehicleType() const
Returns the vehicle's type definition.
Definition: MSBaseVehicle.h:118
EDGEFUNC_NORMAL
Definition: SUMOXMLDefinitions.h:1076
MSPModel_Striping::dawdling
static double dawdling
Definition: MSPModel_Striping.h:102
MSPModel_Striping::NextLaneInfo
Definition: MSPModel_Striping.h:172
MSLane::getLinkCont
const MSLinkCont & getLinkCont() const
returns the container with all links !!!
Definition: MSLane.cpp:2099
MSPModel_Striping::PState::myDir
int myDir
the walking direction on the current lane (1 forward, -1 backward)
Definition: MSPModel_Striping.h:295
MSPModel_Striping::MovePedestrians::execute
SUMOTime execute(SUMOTime currentTime)
Executes the command.
Definition: MSPModel_Striping.cpp:2027
MSLane::anyVehiclesEnd
AnyVehicleIterator anyVehiclesEnd() const
end iterator for iterating over all vehicles touching this lane in downstream direction
Definition: MSLane.h:440
MSPModel_Striping::getNextLaneObstacles
const Obstacles & getNextLaneObstacles(NextLanesObstacles &nextLanesObs, const MSLane *lane, const MSLane *nextLane, int stripes, int nextDir, double currentLength, int currentDir)
Definition: MSPModel_Striping.cpp:677
MSPModel_Striping::cleanupHelper
void cleanupHelper()
remove state at simulation end
Definition: MSPModel_Striping.cpp:281
MSPModel_Striping::PState::stripe
int stripe() const
Definition: MSPModel_Striping.cpp:1422
string2time
SUMOTime string2time(const std::string &r)
Definition: SUMOTime.cpp:42
MSPModel_Striping::Obstacle::xBack
double xBack
maximal position on the current lane in backward direction
Definition: MSPModel_Striping.h:216
MSPerson::MSPersonStage_Walking::getArrivalPos
double getArrivalPos() const
Definition: MSPerson.h:161
MSPModel_Striping::transformToCurrentLanePositions
static void transformToCurrentLanePositions(Obstacles &o, int currentDir, int nextDir, double currentLength, double nextLength)
Definition: MSPModel_Striping.cpp:774
MSLane::getLogicalPredecessorLane
MSLane * getLogicalPredecessorLane() const
get the most likely precedecessor lane (sorted using by_connections_to_sorter). The result is cached ...
Definition: MSLane.cpp:2532
MSPModel_Striping::PState::getEdgePos
double getEdgePos(const MSPerson::MSPersonStage_Walking &stage, SUMOTime now) const
abstract methods inherited from PedestrianState
Definition: MSPModel_Striping.cpp:1785
MSPModel::myModel
static MSPModel * myModel
Definition: MSPModel.h:122
MSGlobals::gUsingInternalLanes
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
Definition: MSGlobals.h:69
MSLane::getEdge
MSEdge & getEdge() const
Returns the lane's edge.
Definition: MSLane.h:670
MSPModel_Striping::MinNextLengths
std::map< const MSLane *, double > MinNextLengths
Definition: MSPModel_Striping.h:170
Position::distanceTo2D
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
Definition: Position.h:244
MSPModel_Striping::PState::myWaitingTime
SUMOTime myWaitingTime
the consecutive time spent at speed 0
Definition: MSPModel_Striping.h:301
MSPModel_Striping::ONCOMING_CONFLICT_PENALTY
static const double ONCOMING_CONFLICT_PENALTY
Definition: MSPModel_Striping.h:125
MSPModel_Striping::Obstacle
information regarding surround Pedestrians (and potentially other things)
Definition: MSPModel_Striping.h:204
MSEdge::isWalkingArea
bool isWalkingArea() const
return whether this edge is walking area
Definition: MSEdge.h:252
OptionsCont::getFloat
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
Definition: OptionsCont.cpp:209
DEBUGCOND
#define DEBUGCOND(PED)
Definition: MSPModel_Striping.cpp:48
toString
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:48
MSPModel::FORWARD
static const int FORWARD
Definition: MSPModel.h:100
MSPModel_Striping::myWalkingAreaFoes
static std::map< const MSEdge *, std::vector< const MSLane * > > myWalkingAreaFoes
Definition: MSPModel_Striping.h:496
MSLane::getShape
const PositionVector & getShape() const
Returns this lane's shape.
Definition: MSLane.h:478
MSPModel_Striping::WalkingAreaPath::length
double length
Definition: MSPModel_Striping.h:240
MSNet::getInstance
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:168
Position::y
double y() const
Returns the y-position.
Definition: Position.h:62
MSNet::getPersonControl
virtual MSTransportableControl & getPersonControl()
Returns the person control.
Definition: MSNet.cpp:798
MSPModel_Striping::LOOKAHEAD_SAMEDIR
static const double LOOKAHEAD_SAMEDIR
Definition: MSPModel_Striping.h:109
MSPModel_Striping::RESERVE_FOR_ONCOMING_FACTOR
static const double RESERVE_FOR_ONCOMING_FACTOR
Definition: MSPModel_Striping.h:134
MSPModel_Striping::OBSTACLE_PED
Definition: MSPModel_Striping.h:195
M_PI
#define M_PI
Definition: odrSpiral.cpp:40
MSPModel_Striping::add
PedestrianState * add(MSPerson *person, MSPerson::MSPersonStage_Walking *stage, SUMOTime now)
register the given person as a pedestrian
Definition: MSPModel_Striping.cpp:132
MSPerson::MSPersonStage_Walking::moveToNextEdge
bool moveToNextEdge(MSPerson *person, SUMOTime currentTime, MSEdge *nextInternal=nullptr)
move forward and return whether the person arrived
Definition: MSPerson.cpp:328
MSPerson::MSPersonStage_Walking::getRoute
const ConstMSEdgeVector & getRoute() const
Definition: MSPerson.h:175
PositionVector::reverse
PositionVector reverse() const
reverse position vector
Definition: PositionVector.cpp:1069
PositionVector::rotationAtOffset
double rotationAtOffset(double pos) const
Returns the rotation at the given length.
Definition: PositionVector.cpp:286
MSTransportable::getVehicleType
const MSVehicleType & getVehicleType() const
Returns the vehicle's type.
Definition: MSTransportable.h:607
MSVehicleType::getLength
double getLength() const
Get vehicle's length [m].
Definition: MSVehicleType.h:110
MSPModel_Striping::PState::distanceTo
double distanceTo(const Obstacle &obs, const bool includeMinGap=true) const
Definition: MSPModel_Striping.cpp:1903
MSPModel_Striping::PState::getNextEdge
const MSEdge * getNextEdge(const MSPerson::MSPersonStage_Walking &stage) const
return the list of internal edges if the pedestrian is on an intersection
Definition: MSPModel_Striping.cpp:1848
GeomHelper::fromNaviDegree
static double fromNaviDegree(const double angle)
Definition: GeomHelper.cpp:211
MSPModel_Striping::hasPedestrians
bool hasPedestrians(const MSLane *lane)
whether the given lane has pedestrians on it
Definition: MSPModel_Striping.cpp:216
MSPModel::UNDEFINED_DIRECTION
static const int UNDEFINED_DIRECTION
Definition: MSPModel.h:105
MSLane::anyVehiclesUpstreamEnd
AnyVehicleIterator anyVehiclesUpstreamEnd() const
end iterator for iterating over all vehicles touching this lane in upstream direction
Definition: MSLane.h:452
MSPModel_Striping::Obstacle::type
ObstacleType type
whether this obstacle denotes a border or a pedestrian
Definition: MSPModel_Striping.h:220
MSEdgeVector
std::vector< MSEdge * > MSEdgeVector
Definition: MSEdge.h:72
MSPModel_Striping::Obstacles
std::vector< Obstacle > Obstacles
Definition: MSPModel_Striping.h:167
MSPModel_Striping::DIST_FAR_AWAY
static const double DIST_FAR_AWAY
Definition: MSPModel_Striping.h:150
MSPModel_Striping::Pedestrians
std::vector< PState * > Pedestrians
Definition: MSPModel_Striping.h:164
MSPModel_Striping::INAPPROPRIATE_PENALTY
static const double INAPPROPRIATE_PENALTY
Definition: MSPModel_Striping.h:122
MSPerson::MSPersonStage_Walking
Definition: MSPerson.h:71
MSTransportable::getID
const std::string & getID() const
returns the id of the transportable
Definition: MSTransportable.cpp:694
MSPModel_Striping::blockedAtDist
bool blockedAtDist(const MSLane *lane, double vehSide, double vehWidth, double oncomingGap, std::vector< const MSPerson * > *collectBlockers)
whether a pedestrian is blocking the crossing of lane for the given vehicle bondaries
Definition: MSPModel_Striping.cpp:179
MSPModel_Striping::PState::myWaitingToEnter
bool myWaitingToEnter
whether the pedestrian is waiting to start its walk
Definition: MSPModel_Striping.h:299
SUMO_ATTR_JM_DRIVE_AFTER_RED_TIME
Definition: SUMOXMLDefinitions.h:613
MSPModel_Striping::PStateVehicle::getMaxX
double getMaxX(const bool includeMinGap=true) const
return the maximum position on the lane
Definition: MSPModel_Striping.cpp:2018
MSBaseVehicle::getID
const std::string & getID() const
Returns the name of the vehicle.
Definition: MSBaseVehicle.cpp:137
MSPModel_Striping::stripeWidth
static double stripeWidth
model parameters
Definition: MSPModel_Striping.h:99
MSEdge::getLanes
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition: MSEdge.h:165
MSVehicle::getBackPositionOnLane
double getBackPositionOnLane(const MSLane *lane) const
Get the vehicle's position relative to the given lane.
Definition: MSVehicle.cpp:3993
MSPModel_Striping::Obstacle::description
std::string description
the id / description of the obstacle
Definition: MSPModel_Striping.h:222
MSVehicleType::getMaxSpeed
double getMaxSpeed() const
Get vehicle's maximum speed [m/s].
Definition: MSVehicleType.h:162
MSPModel_Striping::PStateVehicle::PStateVehicle
PStateVehicle(const MSVehicle *veh, const MSLane *walkingarea, double relX, double relY)
Definition: MSPModel_Striping.cpp:1995
MSLane::getWidth
double getWidth() const
Returns the lane's width.
Definition: MSLane.h:557
MSPModel::getModel
static MSPModel * getModel()
Definition: MSPModel.cpp:59
MSPModel_Striping::Obstacle::Obstacle
Obstacle(int dir, double dist=DIST_FAR_AWAY)
create No-Obstacle
Definition: MSPModel_Striping.cpp:1258
MSPModel_Striping::PState::getMinX
virtual double getMinX(const bool includeMinGap=true) const
return the minimum position on the lane
Definition: MSPModel_Striping.cpp:1365
config.h
MSPModel_Striping::addCloserObstacle
static void addCloserObstacle(Obstacles &obs, double x, int stripe, int numStripes, const std::string &id, double width, int dir, ObstacleType type)
Definition: MSPModel_Striping.cpp:801
Named::getIDSecure
static std::string getIDSecure(const T *obj, const std::string &fallBack="NULL")
get an identifier for Named-like object which may be Null
Definition: Named.h:70
MSPModel_Striping::jamTime
static SUMOTime jamTime
Definition: MSPModel_Striping.h:105
GeomHelper.h
MSTransportable::MOVING_WITHOUT_VEHICLE
Definition: MSTransportable.h:64
gDebugFlag1
bool gDebugFlag1
global utility flags for debugging
Definition: StdDefs.cpp:33
MSVehicle::getSpeed
double getSpeed() const
Returns the vehicle's current speed.
Definition: MSVehicle.h:477
RandHelper.h
MSTransportable::Stage::getDestinationStop
MSStoppingPlace * getDestinationStop() const
returns the destination stop (if any)
Definition: MSTransportable.h:86
MSPModel_Striping::myNumActivePedestrians
int myNumActivePedestrians
the total number of active pedestrians
Definition: MSPModel_Striping.h:486
MSPModel_Striping::PState::getWaitingTime
SUMOTime getWaitingTime(const MSPerson::MSPersonStage_Walking &stage, SUMOTime now) const
return the time the person spent standing
Definition: MSPModel_Striping.cpp:1836
SUMOTime_MAX
#define SUMOTime_MAX
Definition: SUMOTime.h:36
MSEventControl.h
MSLane.h
MSPModel_Striping::myActiveLanes
ActiveLanes myActiveLanes
store of all lanes which have pedestrians on them
Definition: MSPModel_Striping.h:489
MSPModel_Striping::MSPModel_Striping
MSPModel_Striping(const OptionsCont &oc, MSNet *net)
Constructor (it should not be necessary to construct more than one instance)
Definition: MSPModel_Striping.cpp:108
MSPModel_Striping::MAX_WAIT_TOLERANCE
static const double MAX_WAIT_TOLERANCE
Definition: MSPModel_Striping.h:138
MSPModel_Striping::PStateVehicle::getWidth
double getWidth() const
return the person width
Definition: MSPModel_Striping.cpp:2008
MSPModel_Striping::moveInDirectionOnLane
void moveInDirectionOnLane(Pedestrians &pedestrians, const MSLane *lane, SUMOTime currentTime, std::set< MSPerson * > &changedLane, int dir)
move pedestrians forward on one lane
Definition: MSPModel_Striping.cpp:955
MSPModel_Striping::PStateVehicle
Definition: MSPModel_Striping.h:371
MSPModel_Striping.h
MSPModel_Striping::by_xpos_sorter
sorts the persons by position on the lane. If dir is forward, higher x positions come first.
Definition: MSPModel_Striping.h:396
MSEdge::getAllEdges
static const MSEdgeVector & getAllEdges()
Returns all edges with a numerical id.
Definition: MSEdge.cpp:837
MSNet::hasPedestrianNetwork
bool hasPedestrianNetwork() const
return whether the network contains walkingareas and crossings
Definition: MSNet.h:652
MSPModel_Striping::DEBUG_PRINT
static void DEBUG_PRINT(const Obstacles &obs)
Definition: MSPModel_Striping.cpp:52
MIN3
T MIN3(T a, T b, T c)
Definition: StdDefs.h:87
Named::getID
const std::string & getID() const
Returns the id.
Definition: Named.h:77
POSITION_EPS
#define POSITION_EPS
Definition: config.h:169
MSPerson::MSPersonStage_Walking::getNextRouteEdge
const MSEdge * getNextRouteEdge() const
Definition: MSPerson.h:172
MSPModel_Striping::myMinNextLengths
static MinNextLengths myMinNextLengths
Definition: MSPModel_Striping.h:497
MSLane::AnyVehicleIterator
AnyVehicleIterator is a structure, which manages the iteration through all vehicles on the lane,...
Definition: MSLane.h:110
MSPModel_Striping::WalkingAreaPath
Definition: MSPModel_Striping.h:225
MSPModel_Striping::NextLaneInfo::lane
const MSLane * lane
Definition: MSPModel_Striping.h:186
MSPModel_Striping::NextLaneInfo::dir
int dir
Definition: MSPModel_Striping.h:190
MSPModel_Striping::PState::getAngle
double getAngle(const MSPerson::MSPersonStage_Walking &stage, SUMOTime now) const
return the direction in which the person faces in degrees
Definition: MSPModel_Striping.cpp:1817
MSPModel_Striping::getNextLane
static NextLaneInfo getNextLane(const PState &ped, const MSLane *currentLane, const MSLane *prevLane)
computes the successor lane for the given pedestrian and sets the link as well as the direction to us...
Definition: MSPModel_Striping.cpp:418
MSNet::getPedestrianRouter
MSPedestrianRouter & getPedestrianRouter(const MSEdgeVector &prohibited=MSEdgeVector()) const
Definition: MSNet.cpp:985
MSPModel_Striping::addVehicleFoe
static bool addVehicleFoe(const MSVehicle *veh, const MSLane *walkingarea, const Position &relPos, double lateral_offset, double minY, double maxY, Pedestrians &toDelete, Pedestrians &transformedPeds)
Definition: MSPModel_Striping.cpp:912
MSPModel_Striping::initWalkingAreaPaths
static void initWalkingAreaPaths(const MSNet *net)
Definition: MSPModel_Striping.cpp:310
MSLane::anyVehiclesBegin
AnyVehicleIterator anyVehiclesBegin() const
begin iterator for iterating over all vehicles touching this lane in downstream direction
Definition: MSLane.h:434
MSPModel_Striping::LATERAL_SPEED_FACTOR
static const double LATERAL_SPEED_FACTOR
Definition: MSPModel_Striping.h:141
MSPModel_Striping::PState::PState
PState()
constructor for PStateVehicle
Definition: MSPModel_Striping.cpp:1347
MSEdge::getPredecessors
const MSEdgeVector & getPredecessors() const
Definition: MSEdge.h:352
MSVehicle
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:80
MSPModel_Striping::PState::getImpatience
double getImpatience(SUMOTime now) const
returns the impatience
Definition: MSPModel_Striping.cpp:1778