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