SUMO - Simulation of Urban MObility
MSPModel_Striping.cpp
Go to the documentation of this file.
1 /****************************************************************************/
8 // The pedestrian following model (prototype)
9 /****************************************************************************/
10 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
11 // Copyright (C) 2014-2017 DLR (http://www.dlr.de/) and contributors
12 /****************************************************************************/
13 //
14 // This file is part of SUMO.
15 // SUMO is free software: you can redistribute it and/or modify
16 // it under the terms of the GNU General Public License as published by
17 // the Free Software Foundation, either version 3 of the License, or
18 // (at your option) any later version.
19 //
20 /****************************************************************************/
21 
22 // ===========================================================================
23 // included modules
24 // ===========================================================================
25 #ifdef _MSC_VER
26 #include <windows_config.h>
27 #else
28 #include <config.h>
29 #endif
30 
31 #include <math.h>
32 #include <algorithm>
34 #include <utils/geom/GeomHelper.h>
36 #include <microsim/MSNet.h>
37 #include <microsim/MSEdge.h>
38 #include <microsim/MSLane.h>
39 #include <microsim/MSJunction.h>
40 #include <microsim/MSGlobals.h>
42 #include "MSPModel_Striping.h"
43 
44 
45 // ===========================================================================
46 // DEBUGGING HELPERS
47 // ===========================================================================
48 //
49 #define DEBUG1 ""
50 #define DEBUG2 ""
51 #define DEBUGCOND(PEDID) (PEDID == DEBUG1 || PEDID == DEBUG2)
52 //#define LOG_ALL 1
53 
55  for (int i = 0; i < (int)obs.size(); ++i) {
56  std::cout
57  << "(" << obs[i].description
58  << " x=(" << obs[i].xBack << "," << obs[i].xFwd
59  << ") s=" << obs[i].speed
60  << ") ";
61  }
62  std::cout << "\n";
63 }
64 
65 // ===========================================================================
66 // named (internal) constants
67 // ===========================================================================
68 
69 // distances are comparable with lower values being "more important"
73 
74 // ===========================================================================
75 // static members
76 // ===========================================================================
77 
80 
81 
82 // model parameters (static to simplify access from class PState
87 const SUMOReal MSPModel_Striping::LOOKAHEAD_ONCOMING(10.0); // seconds
88 const SUMOReal MSPModel_Striping::LATERAL_PENALTY(-1.); // meters
89 const SUMOReal MSPModel_Striping::OBSTRUCTED_PENALTY(-300000.); // meters
90 const SUMOReal MSPModel_Striping::INAPPROPRIATE_PENALTY(-20000.); // meters
92 const SUMOReal MSPModel_Striping::OBSTRUCTION_THRESHOLD(MSPModel_Striping::OBSTRUCTED_PENALTY * 0.5); // despite obstruction, additional utility may have been added
97 const SUMOReal MSPModel_Striping::MAX_WAIT_TOLERANCE(120.); // seconds
100 
101 
102 // ===========================================================================
103 // MSPModel_Striping method definitions
104 // ===========================================================================
105 
108  myCommand = new MovePedestrians(this);
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 }
120 
121 
123 }
124 
125 
129  const MSLane* lane = getSidewalk<MSEdge, MSLane>(person->getEdge());
130  PState* ped = new PState(person, stage, lane);
131  myActiveLanes[lane].push_back(ped);
133  return ped;
134 }
135 
136 
137 void
139  const MSLane* lane = dynamic_cast<PState*>(state)->myLane;
140  Pedestrians& pedestrians = myActiveLanes[lane];
141  for (Pedestrians::iterator it = pedestrians.begin(); it != pedestrians.end(); ++it) {
142  if (*it == state) {
143  delete state;
144  pedestrians.erase(it);
145  return;
146  }
147  }
148 }
149 
150 
151 bool
152 MSPModel_Striping::blockedAtDist(const MSLane* lane, SUMOReal distToCrossing, std::vector<const MSPerson*>* collectBlockers) {
153  const Pedestrians& pedestrians = getPedestrians(lane);
154  for (Pedestrians::const_iterator it_ped = pedestrians.begin(); it_ped != pedestrians.end(); ++it_ped) {
155  const PState& ped = **it_ped;
156  const SUMOReal halfVehicleWidth = 1.0; // @note could get the actual value from the vehicle
157  const SUMOReal leaderBackDist = (ped.myDir == FORWARD
158  ? distToCrossing - (ped.myRelX - ped.getLength() - MSPModel::SAFETY_GAP - halfVehicleWidth)
159  : (ped.myRelX + ped.getLength() + MSPModel::SAFETY_GAP + halfVehicleWidth) - distToCrossing);
160  //std::cout << SIMTIME << " foe=" << foeLane->getID() << " dir=" << p.myDir << " pX=" << ped.myRelX << " pL=" << ped.getLength() << " fDTC=" << distToCrossing << " lBD=" << leaderBackDist << "\n";
161  if (leaderBackDist >= 0 && leaderBackDist <= BLOCKER_LOOKAHEAD) {
162  // found one pedestrian that is not completely past the crossing point
163  //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";
164  if (collectBlockers == 0) {
165  return true;
166  } else {
167  collectBlockers->push_back(ped.myPerson);
168  }
169  }
170  }
171  if (collectBlockers == 0) {
172  return false;
173  } else {
174  return collectBlockers->size() > 0;
175  }
176 }
177 
178 
181  ActiveLanes::iterator it = myActiveLanes.find(lane);
182  if (it != myActiveLanes.end()) {
183  //std::cout << " found lane=" << lane->getID() << " n=" << it->second.size() << "\n";
184  return (it->second);
185  } else {
186  return noPedestrians;
187  }
188 }
189 
190 
191 void
193  for (ActiveLanes::iterator it_lane = myActiveLanes.begin(); it_lane != myActiveLanes.end(); ++it_lane) {
194  for (Pedestrians::iterator it_p = it_lane->second.begin(); it_p != it_lane->second.end(); ++it_p) {
195  delete *it_p;
196  }
197  }
198  myActiveLanes.clear();
200  myWalkingAreaPaths.clear(); // need to recompute when lane pointers change
201 }
202 
203 
204 int
206  return (int)floor(lane->getWidth() / stripeWidth);
207 }
208 
209 int
211  if (from == 0 || to == 0) {
212  return UNDEFINED_DIRECTION;
213  } else if (MSLinkContHelper::getConnectingLink(*from, *to)) {
214  return FORWARD;
215  } else if (MSLinkContHelper::getConnectingLink(*to, *from)) {
216  return BACKWARD;
217  } else {
218  return UNDEFINED_DIRECTION;
219  }
220 }
221 
222 
223 void
225  if (myWalkingAreaPaths.size() > 0) {
226  return;
227  }
228  for (MSEdgeVector::const_iterator i = MSEdge::getAllEdges().begin(); i != MSEdge::getAllEdges().end(); ++i) {
229  const MSEdge* edge = *i;
230  if (edge->isWalkingArea()) {
231  const MSLane* walkingArea = getSidewalk<MSEdge, MSLane>(edge);
232  // build all possible paths across this walkingArea
233  // gather all incident lanes
234  std::vector<const MSLane*> lanes;
235  const MSEdgeVector& incoming = edge->getPredecessors();
236  for (int j = 0; j < (int)incoming.size(); ++j) {
237  lanes.push_back(getSidewalk<MSEdge, MSLane>(incoming[j]));
238  }
239  const MSEdgeVector& outgoing = edge->getSuccessors();
240  for (int j = 0; j < (int)outgoing.size(); ++j) {
241  lanes.push_back(getSidewalk<MSEdge, MSLane>(outgoing[j]));
242  }
243  // build all combinations
244  for (int j = 0; j < (int)lanes.size(); ++j) {
245  for (int k = 0; k < (int)lanes.size(); ++k) {
246  if (j != k) {
247  // build the walkingArea
248  const MSLane* from = lanes[j];
249  const MSLane* to = lanes[k];
250  const int fromDir = MSLinkContHelper::getConnectingLink(*from, *walkingArea) != 0 ? FORWARD : BACKWARD;
251  const int toDir = MSLinkContHelper::getConnectingLink(*walkingArea, *to) != 0 ? FORWARD : BACKWARD;
252  PositionVector shape;
253  Position fromPos = from->getShape()[fromDir == FORWARD ? -1 : 0];
254  Position toPos = to->getShape()[toDir == FORWARD ? 0 : -1];
255  const SUMOReal maxExtent = fromPos.distanceTo2D(toPos) / 4; // prevent sharp corners
256  const SUMOReal extrapolateBy = MIN2(maxExtent, walkingArea->getWidth() / 2);
257  // assemble shape
258  shape.push_back(fromPos);
259  if (extrapolateBy > POSITION_EPS) {
260  PositionVector fromShp = from->getShape();
261  fromShp.extrapolate(extrapolateBy);
262  shape.push_back_noDoublePos(fromDir == FORWARD ? fromShp.back() : fromShp.front());
263  PositionVector nextShp = to->getShape();
264  nextShp.extrapolate(extrapolateBy);
265  shape.push_back_noDoublePos(toDir == FORWARD ? nextShp.front() : nextShp.back());
266  }
267  shape.push_back_noDoublePos(toPos);
268  if (shape.size() < 2) {
269  PositionVector fromShp = from->getShape();
270  fromShp.extrapolate(1.5 * POSITION_EPS); // noDoublePos requires a difference of POSITION_EPS in at least one coordinate
271  shape.push_back_noDoublePos(fromDir == FORWARD ? fromShp.back() : fromShp.front());
272  assert(shape.size() == 2);
273  }
274  if (fromDir == BACKWARD) {
275  // will be walking backward on walkingArea
276  shape = shape.reverse();
277  }
278  myWalkingAreaPaths[std::make_pair(from, to)] = WalkingAreaPath(from, walkingArea, to, shape);
279  }
280  }
281  }
282  }
283  }
284 }
285 
286 
288 MSPModel_Striping::getNextLane(const PState& ped, const MSLane* currentLane, const MSLane* prevLane) {
289  const MSEdge* currentEdge = &currentLane->getEdge();
290  const MSJunction* junction = ped.myDir == FORWARD ? currentEdge->getToJunction() : currentEdge->getFromJunction();
291  const MSEdge* nextRouteEdge = ped.myStage->getNextRouteEdge();
292  const MSLane* nextRouteLane = getSidewalk<MSEdge, MSLane>(nextRouteEdge);
293  // result values
294  const MSLane* nextLane = nextRouteLane;
295  MSLink* link = 0;
296  int nextDir = UNDEFINED_DIRECTION;
297 
298  if (nextRouteLane != 0) {
299  if (currentEdge->isInternal()) {
300  assert(junction == currentEdge->getFromJunction());
301  nextDir = junction == nextRouteEdge->getFromJunction() ? FORWARD : BACKWARD;
302  if DEBUGCOND(ped.myPerson->getID()) {
303  std::cout << " internal\n";
304  }
305  } else if (currentEdge->isCrossing()) {
306  nextDir = ped.myDir;
307  if (ped.myDir == FORWARD) {
308  nextLane = currentLane->getLinkCont()[0]->getLane();
309  } else {
310  nextLane = currentLane->getLogicalPredecessorLane();
311  }
312  if DEBUGCOND(ped.myPerson->getID()) {
313  std::cout << " crossing\n";
314  }
315  } else if (currentEdge->isWalkingArea()) {
316  ConstMSEdgeVector crossingRoute;
317  // departPos can be 0 because the direction of the walkingArea does not matter
318  // for the arrivalPos, we need to make sure that the route does not deviate across other junctions
319  const int nextRouteEdgeDir = nextRouteEdge->getFromJunction() == junction ? FORWARD : BACKWARD;
320  const SUMOReal arrivalPos = (nextRouteEdge == ped.myStage->getRoute().back()
321  ? ped.myStage->getArrivalPos()
322  : (nextRouteEdgeDir == FORWARD ? 0 : nextRouteEdge->getLength()));
323  MSEdgeVector prohibited;
324  prohibited.push_back(&prevLane->getEdge());
325  MSNet::getInstance()->getPedestrianRouter(prohibited).compute(currentEdge, nextRouteEdge, 0, arrivalPos, ped.myStage->getMaxSpeed(), 0, junction, crossingRoute, true);
326  if DEBUGCOND(ped.myPerson->getID()) {
327  std::cout
328  << " nre=" << nextRouteEdge->getID()
329  << " nreDir=" << nextRouteEdgeDir
330  << " aPos=" << arrivalPos
331  << " crossingRoute=" << toString(crossingRoute)
332  << "\n";
333  }
334  if (crossingRoute.size() > 1) {
335  const MSEdge* nextEdge = crossingRoute[1];
336  nextLane = getSidewalk<MSEdge, MSLane>(crossingRoute[1]);
337  assert((nextEdge->getFromJunction() == junction || nextEdge->getToJunction() == junction));
338  assert(nextLane != prevLane);
339  nextDir = connectedDirection(currentLane, nextLane);
340  if DEBUGCOND(ped.myPerson->getID()) {
341  std::cout << " nextDir=" << nextDir << "\n";
342  }
343  assert(nextDir != UNDEFINED_DIRECTION);
344  if (nextDir == FORWARD) {
345  link = MSLinkContHelper::getConnectingLink(*currentLane, *nextLane);
346  } else if (nextEdge->isCrossing()) {
347  const MSLane* oppositeWalkingArea = nextLane->getLogicalPredecessorLane();
348  link = MSLinkContHelper::getConnectingLink(*oppositeWalkingArea, *nextLane);
349  } else {
350  link = MSLinkContHelper::getConnectingLink(*nextLane, *currentLane);
351  }
352  assert(link != 0);
353  } else {
354  if DEBUGCOND(ped.myPerson->getID()) {
355  std::cout << SIMTIME
356  << " no route from '" << (currentEdge == 0 ? "NULL" : currentEdge->getID())
357  << "' to '" << (nextRouteEdge == 0 ? "NULL" : nextRouteEdge->getID())
358  << "\n";
359  }
360  WRITE_WARNING("Pedestrian '" + ped.myPerson->getID() + "' could not find route across junction '" + junction->getID() + "', time=" +
361  time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
362  // error indicated by nextDir == UNDEFINED_DIRECTION
363  }
364  } else if (currentEdge == nextRouteEdge) {
365  // strange loop in this route. No need to use walkingArea
366  nextDir = -ped.myDir;
367  } else {
368  // normal edge. by default use next / previous walking area
369  nextDir = ped.myDir;
370  nextLane = getNextWalkingArea(currentLane, ped.myDir, link);
371  if (nextLane != 0) {
372  // walking area found
373  if DEBUGCOND(ped.myPerson->getID()) {
374  std::cout << " next walkingArea " << (nextDir == FORWARD ? "forward" : "backward") << "\n";
375  }
376  } else {
377  // walk forward by default
378  nextDir = junction == nextRouteEdge->getToJunction() ? BACKWARD : FORWARD;
379  // try to use a direct link as fallback
380  // direct links only exist if built explicitly. They are used to model tl-controlled links if there are no crossings
381  if (ped.myDir == FORWARD) {
382  link = MSLinkContHelper::getConnectingLink(*currentLane, *nextRouteLane);
383 #ifdef HAVE_INTERNAL_LANES
384  if (link != 0) {
385  if DEBUGCOND(ped.myPerson->getID()) {
386  std::cout << " direct forward\n";
387  }
388  nextLane = MSLinkContHelper::getInternalFollowingLane(currentLane, nextRouteLane);
389  }
390 #endif
391  } else {
392  link = MSLinkContHelper::getConnectingLink(*nextRouteLane, *currentLane);
393 #ifdef HAVE_INTERNAL_LANES
394  if (link != 0) {
395  if DEBUGCOND(ped.myPerson->getID()) {
396  std::cout << " direct backward\n";
397  }
398  nextLane = MSLinkContHelper::getInternalFollowingLane(nextRouteLane, currentLane);
399  }
400 #endif
401  }
402  }
403  if (nextLane == 0) {
404  // no internal lane found
405  nextLane = nextRouteLane;
406  if DEBUGCOND(ped.myPerson->getID()) {
407  std::cout << SIMTIME << " no next lane found for " << currentLane->getID() << " dir=" << ped.myDir << "\n";
408  }
409  } else if (nextLane->getLength() <= POSITION_EPS) {
410  // internal lane too short
411  nextLane = nextRouteLane;
412  }
413  }
414  }
415  if DEBUGCOND(ped.myPerson->getID()) {
416  std::cout << SIMTIME
417  << " p=" << ped.myPerson->getID()
418  << " l=" << currentLane->getID()
419  << " nl=" << (nextLane == 0 ? "NULL" : nextLane->getID())
420  << " nrl=" << (nextRouteLane == 0 ? "NULL" : nextRouteLane->getID())
421  << " d=" << nextDir
422  << " link=" << (link == 0 ? "NULL" : link->getViaLaneOrLane()->getID())
423  << " pedDir=" << ped.myDir
424  << "\n";
425  }
426  return NextLaneInfo(nextLane, link, nextDir);
427 }
428 
429 
430 const MSLane*
431 MSPModel_Striping::getNextWalkingArea(const MSLane* currentLane, const int dir, MSLink*& link) {
432  if (dir == FORWARD) {
433  const MSLinkCont& links = currentLane->getLinkCont();
434  for (MSLinkCont::const_iterator it = links.begin(); it != links.end(); ++it) {
435  if ((*it)->getLane()->getEdge().isWalkingArea()) {
436  link = *it;
437  return (*it)->getLane();
438  }
439  }
440  } else {
441  const std::vector<MSLane::IncomingLaneInfo>& laneInfos = currentLane->getIncomingLanes();
442  for (std::vector<MSLane::IncomingLaneInfo>::const_iterator it = laneInfos.begin(); it != laneInfos.end(); ++it) {
443  if ((*it).lane->getEdge().isWalkingArea()) {
444  link = (*it).viaLink;
445  return (*it).lane;
446  }
447  }
448  }
449  return 0;
450 }
451 
452 
454 MSPModel_Striping::getNeighboringObstacles(const Pedestrians& pedestrians, int egoIndex, int stripes) {
455  const PState& ego = *pedestrians[egoIndex];
456  Obstacles obs(stripes, Obstacle(ego.myDir));
457  std::vector<bool> haveBlocker(stripes, false);
458  for (int index = egoIndex + 1; index < (int)pedestrians.size(); index++) {
459  const PState& p = *pedestrians[index];
460  if DEBUGCOND(ego.myPerson->getID()) {
461  std::cout << SIMTIME << " ped=" << ego.myPerson->getID() << " checking neighbor " << p.myPerson->getID();
462  }
463  if (!p.myWaitingToEnter) {
464  const Obstacle o(p);
465  if DEBUGCOND(ego.myPerson->getID()) {
466  std::cout << " dist=" << ego.distanceTo(o) << std::endl;
467  }
468  if (ego.distanceTo(o) == DIST_BEHIND) {
469  break;
470  }
471  if (ego.distanceTo(o) == DIST_OVERLAP) {
472  obs[p.stripe()] = o;
473  obs[p.otherStripe()] = o;
474  haveBlocker[p.stripe()] = true;
475  haveBlocker[p.otherStripe()] = true;
476  }
477  if (!haveBlocker[p.stripe()]) {
478  obs[p.stripe()] = o;
479  }
480  if (!haveBlocker[p.otherStripe()]) {
481  obs[p.otherStripe()] = o;
482  }
483  }
484  }
485  if DEBUGCOND(ego.myPerson->getID()) {
486  std::cout << SIMTIME << " ped=" << ego.myPerson->getID() << " neighObs=";
487  DEBUG_PRINT(obs);
488  }
489  return obs;
490 }
491 
492 
493 int
494 MSPModel_Striping::getStripeOffset(int origStripes, int destStripes, bool addRemainder) {
495  int offset = (destStripes - origStripes) / 2;
496  if (addRemainder) {
497  offset += (destStripes - origStripes) % 2;
498  }
499  return offset;
500 }
501 
502 
505  MSLane* lane, const MSLane* nextLane, int stripes, SUMOReal nextLength, int nextDir,
506  SUMOReal currentLength, int currentDir) {
507  if (nextLanesObs.count(nextLane) == 0) {
508 
509  // figure out the which pedestrians are ahead on the next lane
510  const int nextStripes = numStripes(nextLane);
511  // do not move past the end of the next lane in a single step
512  Obstacles obs(stripes, Obstacle(nextDir == FORWARD ? nextLength : 0, 0, "nextEnd", 0, true));
513 
514  const int offset = getStripeOffset(nextStripes, stripes, currentDir != nextDir && nextStripes > stripes);
515  //std::cout << SIMTIME << " getNextLaneObstacles"
516  // << " nextLane=" << nextLane->getID()
517  // << " nextLength=" << nextLength
518  // << " nextDir=" << nextDir
519  // << " currentLength=" << currentLength
520  // << " currentDir=" << currentDir
521  // << " stripes=" << stripes
522  // << " nextStripes=" << nextStripes
523  // << " offset=" << offset
524  // << "\n";
525  if (nextStripes < stripes) {
526  // some stripes do not continue
527  for (int ii = 0; ii < stripes; ++ii) {
528  if (ii < offset || ii >= nextStripes + offset) {
529  obs[ii] = Obstacle(nextDir == FORWARD ? 0 : nextLength, 0, "stripeEnd", 0, true);
530  }
531  }
532  }
533  Pedestrians& pedestrians = getPedestrians(nextLane);
534  if (nextLane->getEdge().isWalkingArea()) {
535  transformToCurrentLanePositions(obs, currentDir, nextDir, currentLength, nextLength);
536  // complex transformation into the coordinate system of the current lane
537  // (pedestrians on next lane may walk at arbitrary angles relative to the current lane)
538  SUMOReal lateral_offset = (lane->getWidth() - stripeWidth) * 0.5;
539  if ((stripes - nextStripes) % 2 != 0) {
540  lateral_offset += 0.5 * stripeWidth;
541  }
542  nextDir = currentDir;
543  // transform pedestrians into the current coordinate system
544  for (int ii = 0; ii < (int)pedestrians.size(); ++ii) {
545  PState& p = *pedestrians[ii];
546  if (p.myWaitingToEnter || p.myAmJammed) {
547  continue;
548  }
549  Position relPos = lane->getShape().transformToVectorCoordinates(p.getPosition(*p.myStage, -1), true);
550  const SUMOReal newY = relPos.y() + lateral_offset;
551  //std::cout << " ped=" << p.myPerson->getID() << " relX=" << relPos.x() << " relY=" << newY << " latOff=" << lateral_offset << " s=" << p.stripe(newY) << " os=" << p.otherStripe(newY) << "\n";
552  addCloserObstacle(obs, relPos.x(), p.stripe(newY), stripes, p.myPerson->getID(), p.myPerson->getVehicleType().getWidth(), currentDir);
553  addCloserObstacle(obs, relPos.x(), p.otherStripe(newY), stripes, p.myPerson->getID(), p.myPerson->getVehicleType().getWidth(), currentDir);
554  }
555  } else {
556  // simple transformation into the coordinate system of the current lane
557  // (only need to worry about currentDir and nextDir)
558  // XXX consider waitingToEnter on nextLane
559  sort(pedestrians.begin(), pedestrians.end(), by_xpos_sorter(nextDir));
560  for (int ii = 0; ii < (int)pedestrians.size(); ++ii) {
561  const PState& p = *pedestrians[ii];
562  if (p.myWaitingToEnter || p.myAmJammed) {
563  continue;
564  }
565  SUMOReal newY = p.myRelY;
566  Obstacle pObs(p);
567  if (nextDir != currentDir) {
568  newY = (nextStripes - 1) * stripeWidth - newY;
569  pObs.speed *= -1;
570  }
571  newY += offset * stripeWidth;
572  const int stripe = p.stripe(newY);
573  if (stripe >= 0 && stripe < stripes) {
574  obs[stripe] = pObs;
575  }
576  const int otherStripe = p.otherStripe(newY);
577  if (otherStripe >= 0 && otherStripe < stripes) {
578  obs[otherStripe] = pObs;
579  }
580  }
581  transformToCurrentLanePositions(obs, currentDir, nextDir, currentLength, nextLength);
582  }
583  nextLanesObs[nextLane] = obs;
584  }
585  return nextLanesObs[nextLane];
586 }
587 
588 void
589 MSPModel_Striping::transformToCurrentLanePositions(Obstacles& obs, int currentDir, int nextDir, SUMOReal currentLength, SUMOReal nextLength) {
590  for (int ii = 0; ii < (int)obs.size(); ++ii) {
591  Obstacle& o = obs[ii];
592  if (currentDir == FORWARD) {
593  if (nextDir == FORWARD) {
594  o.xFwd += currentLength;
595  o.xBack += currentLength;
596  } else {
597  const SUMOReal tmp = o.xFwd;
598  o.xFwd = currentLength + nextLength - o.xBack;
599  o.xBack = currentLength + nextLength - tmp;
600  }
601  } else {
602  if (nextDir == FORWARD) {
603  const SUMOReal tmp = o.xFwd;
604  o.xFwd = -o.xBack;
605  o.xBack = -tmp;
606  } else {
607  o.xFwd -= nextLength;
608  o.xBack -= nextLength;
609  }
610  }
611  }
612 }
613 
614 
615 void
616 MSPModel_Striping::addCloserObstacle(Obstacles& obs, SUMOReal x, int stripe, int numStripes, const std::string& id, SUMOReal width, int dir) {
617  if (stripe >= 0 && stripe < numStripes) {
618  if ((dir == FORWARD && x - width / 2. < obs[stripe].xBack) || (dir == BACKWARD && x + width / 2. > obs[stripe].xFwd)) {
619  obs[stripe] = Obstacle(x, 0, id, width);
620  }
621  }
622 }
623 
624 void
625 MSPModel_Striping::moveInDirection(SUMOTime currentTime, std::set<MSPerson*>& changedLane, int dir) {
626  for (ActiveLanes::iterator it_lane = myActiveLanes.begin(); it_lane != myActiveLanes.end(); ++it_lane) {
627  const MSLane* lane = it_lane->first;
628  Pedestrians& pedestrians = it_lane->second;
629  //std::cout << SIMTIME << ">>> lane=" << lane->getID() << " numPeds=" << pedestrians.size() << "\n";
630  if (lane->getEdge().isWalkingArea()) {
631  const SUMOReal lateral_offset = (lane->getWidth() - stripeWidth) * 0.5;
632  const SUMOReal minY = stripeWidth * - 0.5 + NUMERICAL_EPS;
633  const SUMOReal maxY = stripeWidth * (numStripes(lane) - 0.5) - NUMERICAL_EPS;
634  const WalkingAreaPath* debugPath = 0;
635  // need to handle each walkingAreaPath seperately and transform
636  // coordinates beforehand
637  std::set<const WalkingAreaPath*, walkingarea_path_sorter> paths;
638  for (Pedestrians::iterator it = pedestrians.begin(); it != pedestrians.end(); ++it) {
639  const PState* p = *it;
640  assert(p->myWalkingAreaPath != 0);
641  if (p->myDir == dir) {
642  paths.insert(p->myWalkingAreaPath);
643  if DEBUGCOND(p->myPerson->getID()) {
644  debugPath = p->myWalkingAreaPath;
645  std::cout << SIMTIME << " debugging WalkingAreaPath from=" << debugPath->from->getID() << " to=" << debugPath->to->getID() << "\n";
646  }
647  }
648  }
649  for (std::set<const WalkingAreaPath*, walkingarea_path_sorter>::iterator it = paths.begin(); it != paths.end(); ++it) {
650  const WalkingAreaPath* path = *it;
651  Pedestrians toDelete;
652  Pedestrians transformedPeds;
653  transformedPeds.reserve(pedestrians.size());
654  for (Pedestrians::iterator it_p = pedestrians.begin(); it_p != pedestrians.end(); ++it_p) {
655  PState* p = *it_p;
656  if (p->myWalkingAreaPath == path
657  // opposite direction is already in the correct coordinate system
658  || (p->myWalkingAreaPath->from == path->to && p->myWalkingAreaPath->to == path->from)) {
659  transformedPeds.push_back(p);
660  if (path == debugPath) std::cout << " ped=" << p->myPerson->getID() << " relX=" << p->myRelX << " relY=" << p->myRelY << " (untransformed), vecCoord="
661  << path->shape.transformToVectorCoordinates(p->getPosition(*p->myStage, -1)) << "\n";
662  } else {
663  const Position relPos = path->shape.transformToVectorCoordinates(p->getPosition(*p->myStage, -1));
664  const SUMOReal newY = relPos.y() + lateral_offset;
665  if (relPos != Position::INVALID && newY >= minY && newY <= maxY) {
666  PState* tp = new PState(*p);
667  tp->myRelX = relPos.x();
668  tp->myRelY = newY;
669  // only an obstacle, speed may be orthogonal to dir
670  tp->myDir = !dir;
671  tp->mySpeed = 0;
672  toDelete.push_back(tp);
673  transformedPeds.push_back(tp);
674  if (path == debugPath) {
675  std::cout << " ped=" << p->myPerson->getID() << " relX=" << relPos.x() << " relY=" << newY << " (transformed), vecCoord=" << relPos << "\n";
676  }
677  } else {
678  if (path == debugPath) {
679  std::cout << " ped=" << p->myPerson->getID() << " relX=" << relPos.x() << " relY=" << newY << " (invalid), vecCoord=" << relPos << "\n";
680  }
681  }
682  }
683  }
684  moveInDirectionOnLane(transformedPeds, lane, currentTime, changedLane, dir);
685  arriveAndAdvance(pedestrians, currentTime, changedLane, dir);
686  // clean up
687  for (Pedestrians::iterator it_p = toDelete.begin(); it_p != toDelete.end(); ++it_p) {
688  delete *it_p;
689  }
690  }
691  } else {
692  moveInDirectionOnLane(pedestrians, lane, currentTime, changedLane, dir);
693  arriveAndAdvance(pedestrians, currentTime, changedLane, dir);
694  }
695  }
696 }
697 
698 
699 void
700 MSPModel_Striping::arriveAndAdvance(Pedestrians& pedestrians, SUMOTime currentTime, std::set<MSPerson*>& changedLane, int dir) {
701  // advance to the next lane / arrive at destination
702  sort(pedestrians.begin(), pedestrians.end(), by_xpos_sorter(dir));
703  // can't use iterators because we do concurrent modification
704  for (int i = 0; i < (int)pedestrians.size(); i++) {
705  PState* const p = pedestrians[i];
706  if (p->myDir == dir && p->distToLaneEnd() < 0) {
707  // moveToNextLane may trigger re-insertion (for consecutive
708  // walks) so erase must be called first
709  pedestrians.erase(pedestrians.begin() + i);
710  i--;
711  p->moveToNextLane(currentTime);
712  if (p->myLane != 0) {
713  changedLane.insert(p->myPerson);
714  myActiveLanes[p->myLane].push_back(p);
715  } else {
716  delete p;
718  }
719  }
720  }
721 }
722 
723 
724 void
725 MSPModel_Striping::moveInDirectionOnLane(Pedestrians& pedestrians, const MSLane* lane, SUMOTime currentTime, std::set<MSPerson*>& changedLane, int dir) {
726  const int stripes = numStripes(lane);
727  Obstacles obs(stripes, Obstacle(dir)); // continously updated
728  NextLanesObstacles nextLanesObs; // continously updated
729  sort(pedestrians.begin(), pedestrians.end(), by_xpos_sorter(dir));
730  for (int ii = 0; ii < (int)pedestrians.size(); ++ii) {
731  PState& p = *pedestrians[ii];
732  //std::cout << SIMTIME << "CHECKING" << p.myPerson->getID() << "\n";
733  Obstacles currentObs = obs;
734  if (p.myDir != dir || changedLane.count(p.myPerson) != 0) {
735  if (!p.myWaitingToEnter) {
736  //if DEBUGCOND(p.myPerson->getID()) {
737  // std::cout << " obs=" << p.myPerson->getID() << " y=" << p.myRelY << " stripe=" << p.stripe() << " oStripe=" << p.otherStripe() << "\n";
738  //}
739  Obstacle o(p);
740  if (p.myDir != dir && p.mySpeed == 0) {
741  // ensure recognition of oncoming
742  o.speed = (p.myDir == FORWARD ? 0.1 : -0.1);
743  }
744  obs[p.stripe()] = o;
745  obs[p.otherStripe()] = o;
746  }
747  continue;
748  }
749  if DEBUGCOND(p.myPerson->getID()) {
750  std::cout << SIMTIME << " ped=" << p.myPerson->getID() << " currentObs=";
751  gDebugFlag1 = true;
752  DEBUG_PRINT(currentObs);
753  }
754  const MSLane* nextLane = p.myNLI.lane;
755  const MSLink* link = p.myNLI.link;
756  const SUMOReal dist = p.distToLaneEnd();
757  const SUMOReal speed = p.myStage->getMaxSpeed();
758  if (nextLane != 0 && dist <= LOOKAHEAD_ONCOMING) {
759  const SUMOReal currentLength = (p.myWalkingAreaPath == 0 ? lane->getLength() : p.myWalkingAreaPath->length);
760  const SUMOReal nextLength = nextLane->getLength(); // XXX what to do if nextLane is a walkingArea?
761  const Obstacles& nextObs = getNextLaneObstacles(
762  nextLanesObs, lane, nextLane, stripes,
763  nextLength, p.myNLI.dir,
764  currentLength, dir);
765 
766  if DEBUGCOND(p.myPerson->getID()) {
767  std::cout << SIMTIME << " ped=" << p.myPerson->getID() << " nextObs=";
768  DEBUG_PRINT(nextObs);
769  }
770  p.mergeObstacles(currentObs, nextObs);
771  }
772  if DEBUGCOND(p.myPerson->getID()) {
773  std::cout << SIMTIME << " ped=" << p.myPerson->getID() << " obsWithNext=";
774  DEBUG_PRINT(currentObs);
775  }
776  p.mergeObstacles(currentObs, getNeighboringObstacles(pedestrians, ii, stripes));
777  if DEBUGCOND(p.myPerson->getID()) {
778  std::cout << SIMTIME << " ped=" << p.myPerson->getID() << " obsWithNeigh=";
779  DEBUG_PRINT(currentObs);
780  }
781  // check link state
782  if (link != 0
783  // only check close before junction, @todo we should take deceleration into account here
784  && dist - p.getMinGap() < LOOKAHEAD_SAMEDIR * speed
785  && (!link->opened(currentTime, speed, speed, p.getLength(), p.getImpatience(currentTime), speed, 0)
786  // @todo check for presence of vehicles blocking the path
787  )) {
788  // prevent movement passed a closed link
789  Obstacles closedLink(stripes, Obstacle(p.myRelX + dir * (dist + NUMERICAL_EPS), 0, "closedLink", 0, true));
790  p.mergeObstacles(currentObs, closedLink);
791  if DEBUGCOND(p.myPerson->getID()) {
792  std::cout << SIMTIME << " ped=" << p.myPerson->getID() << " obsWitTLS=";
793  DEBUG_PRINT(currentObs);
794  }
795  // consider rerouting over another crossing
796  if (p.myWalkingAreaPath != 0) {
797  // @todo actually another path would be needed starting at the current position
799  }
800  }
801  if (&lane->getEdge() == &p.myStage->getDestination() && p.myStage->getDestinationStop() != 0) {
802  Obstacles arrival(stripes, Obstacle(p.myStage->getArrivalPos() + dir * p.getMinGap(), 0, "arrival", 0, true));
803  p.mergeObstacles(currentObs, arrival);
804  }
805  p.walk(currentObs, currentTime);
806  gDebugFlag1 = false;
807  if (!p.myWaitingToEnter && !p.myAmJammed) {
808  Obstacle o(p);
809  obs[p.stripe()] = o;
810  obs[p.otherStripe()] = o;
812  for (int coll = 0; coll < ii; ++coll) {
813  PState& c = *pedestrians[coll];
814  if (!c.myWaitingToEnter && c.myWalkingAreaPath == 0 && !c.myAmJammed) {
815  if (c.stripe() == p.stripe() || p.stripe() == c.otherStripe() || p.otherStripe() == c.stripe() || p.otherStripe() == c.otherStripe()) {
816  Obstacle cObs(c);
817  // we check only for real collisions, no min gap violations
818  if (p.distanceTo(cObs, false) == DIST_OVERLAP) {
819  WRITE_WARNING("Collision of person '" + p.myPerson->getID() + "' and person '" + c.myPerson->getID()
820  + "', lane='" + lane->getID() + "', time=" + time2string(currentTime) + ".");
821  }
822  }
823  }
824  }
825  }
826  }
827  //std::cout << SIMTIME << p.myPerson->getID() << " lane=" << lane->getID() << " x=" << p.myRelX << "\n";
828  }
829 }
830 
831 
832 // ===========================================================================
833 // MSPModel_Striping::Obstacle method definitions
834 // ===========================================================================
836  xFwd(dir * dist), // by default, far away when seen in dir
837  xBack(dir * dist), // by default, far away when seen in dir
838  speed(0),
839  description(""),
840  border(false) {
841 }
842 
843 
845  description(ped.myPerson->getID()) {
846  assert(!ped.myWaitingToEnter);
847  xFwd = ped.getMaxX();
848  xBack = ped.getMinX();
849  speed = ped.myDir * ped.mySpeed;
850  border = false;
851 }
852 
853 
854 // ===========================================================================
855 // MSPModel_Striping::PState method definitions
856 // ===========================================================================
857 
858 
860  myPerson(person),
861  myStage(stage),
862  myLane(lane),
863  myRelX(stage->getDepartPos()),
864  myRelY(stage->getDepartPosLat()),
865  myDir(FORWARD),
866  mySpeed(0),
867  myWaitingToEnter(true),
868  myWaitingTime(0),
869  myWalkingAreaPath(0),
870  myAmJammed(false) {
871  const MSEdge* currentEdge = &lane->getEdge();
872  assert(!currentEdge->isWalkingArea());
873  const ConstMSEdgeVector& route = myStage->getRoute();
874  if (route.size() == 1) {
875  // only a single edge, move towards end pos
877  } else {
878  const bool mayStartForward = canTraverse(FORWARD, route);
879  const bool mayStartBackward = canTraverse(BACKWARD, route);
880  if DEBUGCOND(myPerson->getID()) {
881  std::cout << " initialize dir for " << myPerson->getID() << " forward=" << mayStartForward << " backward=" << mayStartBackward << "\n";
882  }
883  if (mayStartForward && mayStartBackward) {
884  // figure out the best direction via routing
885  ConstMSEdgeVector crossingRoute;
886  MSNet::getInstance()->getPedestrianRouter().compute(currentEdge, route.back(), myRelX, myStage->getArrivalPos(), myStage->getMaxSpeed(), 0, 0, crossingRoute, true);
887  if (crossingRoute.size() > 1) {
888  // route found
889  const MSEdge* nextEdge = crossingRoute[1];
890  if (nextEdge->getFromJunction() == currentEdge->getFromJunction() || nextEdge->getToJunction() == currentEdge->getFromJunction()) {
891  myDir = BACKWARD;
892  }
893  }
894  if DEBUGCOND(myPerson->getID()) {
895  std::cout << " crossingRoute=" << toString(crossingRoute) << "\n";
896  }
897  } else {
898  myDir = !mayStartBackward ? FORWARD : BACKWARD;
899  }
900  }
901  if (myDir == FORWARD) {
902  // start at the right side of the sidewalk
903  myRelY = stripeWidth * (numStripes(lane) - 1) - myRelY;
904  }
905  if DEBUGCOND(myPerson->getID()) {
906  std::cout << " added new pedestrian " << myPerson->getID() << " on " << lane->getID() << " myRelX=" << myRelX << " myRelY=" << myRelY << " dir=" << myDir << " route=" << toString(myStage->getRoute()) << "\n";
907  }
908 
909  myNLI = getNextLane(*this, lane, 0);
910 }
911 
912 
913 SUMOReal
914 MSPModel_Striping::PState::getMinX(const bool includeMinGap) const {
915  // @todo speed should have an influence here because faster persons need more space
916  if (myDir == FORWARD) {
917  return myRelX - getLength();
918  }
919  return myRelX - (includeMinGap ? getMinGap() : 0.);
920 }
921 
922 
923 SUMOReal
924 MSPModel_Striping::PState::getMaxX(const bool includeMinGap) const {
925  // @todo speed should have an influence here because faster persons need more space
926  if (myDir == FORWARD) {
927  return myRelX + (includeMinGap ? getMinGap() : 0.);
928  }
929  return myRelX + getLength();
930 }
931 
932 
933 SUMOReal
935  return myPerson->getVehicleType().getLength();
936 }
937 
938 
939 SUMOReal
941  return myPerson->getVehicleType().getMinGap();
942 }
943 
944 
945 int
947  return (int)floor(relY / stripeWidth + 0.5);
948 }
949 
950 
951 int
953  const int s = stripe(relY);
954  const SUMOReal offset = relY - s * stripeWidth;
955  const SUMOReal threshold = MAX2(NUMERICAL_EPS, stripeWidth - SQUEEZE * myPerson->getVehicleType().getWidth());
956  int result;
957  if (offset > threshold) {
958  result = s + 1;
959  } else if (offset < -threshold) {
960  result = s - 1;
961  } else {
962  result = s;
963  }
964  //std::cout.setf(std::ios::fixed , std::ios::floatfield);
965  //std::cout << std::setprecision(5);
966  //if DEBUGCOND(myPerson->getID()) std::cout << " otherStripe " << myPerson->getID() << " offset=" << offset << " threshold=" << threshold << " rawResult=" << result << "\n";
967  return result;
968 }
969 
970 int
972  return MIN2(MAX2(0, stripe(myRelY)), numStripes(myLane) - 1);
973 }
974 
975 
976 int
978  return MIN2(MAX2(0, otherStripe(myRelY)), numStripes(myLane) - 1);
979 }
980 
981 
982 SUMOReal
984  if (myStage->getNextRouteEdge() == 0) {
985  return myDir * (myStage->getArrivalPos() - myRelX) - POSITION_EPS;
986  } else {
988  return myDir == FORWARD ? length - myRelX : myRelX;
989  }
990 }
991 
992 
993 bool
995  SUMOReal dist = distToLaneEnd();
996  if (myPerson->getID() == DEBUG1) {
997  std::cout << SIMTIME << " myRelX=" << myRelX << " dist=" << dist << "\n";
998  }
999  if (dist <= 0) {
1000  //if (ped.myPerson->getID() == DEBUG1) {
1001  // std::cout << SIMTIME << " addToLane x=" << ped.myRelX << " newDir=" << newDir << " newLane=" << newLane->getID() << " walkingAreaShape=" << walkingAreaShape << "\n";
1002  //}
1003  //std::cout << " changing to " << newLane->getID() << " myRelY=" << ped.myRelY << " oldStripes=" << numStripes(myLane) << " newStripes=" << numStripes(newLane);
1004  //std::cout << " newY=" << ped.myRelY << " myDir=" << ped.myDir << " newDir=" << newDir;
1005  const int oldDir = myDir;
1006  const MSLane* oldLane = myLane;
1007  myLane = myNLI.lane;
1008  myDir = myNLI.dir;
1009  const bool normalLane = (myLane == 0 || myLane->getEdge().getPurpose() == MSEdge::EDGEFUNCTION_NORMAL);
1010  if DEBUGCOND(myPerson->getID()) {
1011  std::cout << SIMTIME
1012  << " ped=" << myPerson->getID()
1013  << " moveToNextLane old=" << oldLane->getID()
1014  << " new=" << (myLane == 0 ? "NULL" : myLane->getID())
1015  << " oldDir=" << oldDir
1016  << " newDir=" << myDir
1017  << " myRelX=" << myRelX
1018  << " dist=" << dist
1019  << "\n";
1020  }
1021  if (myLane == 0) {
1023  }
1024  myStage->moveToNextEdge(myPerson, currentTime, normalLane ? 0 : &myLane->getEdge());
1025  if (myLane != 0) {
1026  assert(myDir != UNDEFINED_DIRECTION);
1027  myNLI = getNextLane(*this, myLane, oldLane);
1028  assert(myNLI.lane != oldLane); // do not turn around
1029  if DEBUGCOND(myPerson->getID()) {
1030  std::cout << " nextLane=" << (myNLI.lane == 0 ? "NULL" : myNLI.lane->getID()) << "\n";
1031  }
1032  if (myLane->getEdge().isWalkingArea()) {
1033  if (myNLI.dir != UNDEFINED_DIRECTION) {
1034  myWalkingAreaPath = &myWalkingAreaPaths[std::make_pair(oldLane, myNLI.lane)];
1035  assert(myWalkingAreaPath->from != 0);
1036  assert(myWalkingAreaPath->to != 0);
1037  assert(myWalkingAreaPath->shape.size() >= 2);
1038  if DEBUGCOND(myPerson->getID()) {
1039  std::cout << " mWAPath shape=" << myWalkingAreaPath->shape << " length=" << myWalkingAreaPath->length << "\n";
1040  }
1041  } else {
1042  // disconnnected route. move to the next edge (arbitrariliy, maintaining current direction)
1043  if (OptionsCont::getOptions().getBool("ignore-route-errors")) {
1044  myStage->moveToNextEdge(myPerson, currentTime, 0);
1045  myLane = myNLI.lane;
1046  assert(myLane != 0);
1048  myNLI = getNextLane(*this, myLane, oldLane);
1049  myWalkingAreaPath = 0;
1050  } else {
1051  throw ProcessError("Disconnected walk for person '" + myPerson->getID() + "'.");
1052  }
1053  }
1054  } else {
1055  myWalkingAreaPath = 0;
1056  }
1057  // adapt x to fit onto the new lane
1058  // (make sure we do not move past the end of the new lane since that
1059  // lane was not checked for obstacles)
1060  const SUMOReal newLength = (myWalkingAreaPath == 0 ? myLane->getLength() : myWalkingAreaPath->length);
1061  if (-dist > newLength) {
1062  dist = -newLength;
1063  // should not happen because the end of myLane should have been an obstacle as well
1064  assert(false);
1065  }
1066  if (myDir == BACKWARD) {
1067  myRelX = newLength + dist;
1068  } else {
1069  myRelX = -dist;
1070  }
1071  if DEBUGCOND(myPerson->getID()) {
1072  std::cout << SIMTIME << " update myRelX ped=" << myPerson->getID()
1073  << " newLength=" << newLength
1074  << " dist=" << dist
1075  << " myRelX=" << myRelX
1076  << "\n";
1077  }
1078  // adjust to change in direction
1079  if (myDir != oldDir) {
1080  myRelY = (numStripes(oldLane) - 1) * stripeWidth - myRelY;
1081  }
1082  // adjust to differences in sidewalk width
1083  const int offset = getStripeOffset(numStripes(oldLane), numStripes(myLane), oldDir != myDir && numStripes(myLane) < numStripes(oldLane));
1084  myRelY += offset * stripeWidth;
1085  if DEBUGCOND(myPerson->getID()) {
1086  std::cout << SIMTIME << " transformY ped=" << myPerson->getID()
1087  << " newLane=" << Named::getIDSecure(myLane)
1088  << " newY=" << myRelY
1089  << " os=" << numStripes(oldLane) << " ns=" << numStripes(myLane)
1090  << " od=" << oldDir << " nd=" << myDir
1091  << " offset=" << offset << "\n";
1092  }
1093  }
1094  return true;
1095  } else {
1096  return false;
1097  }
1098 }
1099 
1100 
1101 void
1103  const int stripes = (int)obs.size();
1104  const int sMax = stripes - 1;
1105  assert(stripes == numStripes(myLane));
1106  const SUMOReal vMax = myStage->getMaxSpeed();
1107  // ultimate goal is to choose the prefered stripe (chosen)
1108  const int current = stripe();
1109  const int other = otherStripe();
1110  // compute distances
1111  std::vector<SUMOReal> distance(stripes);
1112  for (int i = 0; i < stripes; ++i) {
1113  distance[i] = distanceTo(obs[i], !obs[i].border);
1114  }
1115  // compute utility for all stripes
1116  std::vector<SUMOReal> utility(stripes, 0);
1117  // forbid stripes which are blocked and also all stripes behind them
1118  for (int i = 0; i < stripes; ++i) {
1119  if (distance[i] == DIST_OVERLAP) {
1120  if (i == current && !myWaitingToEnter) {
1121  utility[i] += OBSTRUCTED_PENALTY;
1122  }
1123  if (i < current) {
1124  for (int j = 0; j <= i; ++j) {
1125  utility[j] += OBSTRUCTED_PENALTY;
1126  }
1127  }
1128  if (i > current) {
1129  for (int j = i; j < stripes; ++j) {
1130  utility[j] += OBSTRUCTED_PENALTY;
1131  }
1132  }
1133  }
1134  }
1135  // forbid a portion of the leftmost stripes (in walking direction).
1136  // lanes with stripes less than 1 / RESERVE_FOR_ONCOMING_FACTOR
1137  // may still deadlock in heavy pedestrian traffic
1138  const bool onJunction = myLane->getEdge().isWalkingArea() || myLane->getEdge().isCrossing();
1139  const int reserved = (int)floor(stripes * (onJunction ? RESERVE_FOR_ONCOMING_FACTOR_JUNCTIONS : RESERVE_FOR_ONCOMING_FACTOR));
1140  if (myDir == FORWARD) {
1141  for (int i = 0; i < reserved; ++i) {
1142  utility[i] += INAPPROPRIATE_PENALTY * (i == current ? 0.5 : 1);
1143  }
1144  } else {
1145  for (int i = sMax; i > sMax - reserved; --i) {
1146  utility[i] += INAPPROPRIATE_PENALTY * (i == current ? 0.5 : 1);
1147  }
1148  }
1149  // adapt utility based on obstacles
1150  for (int i = 0; i < stripes; ++i) {
1151  if (obs[i].speed < 0) {
1152  // penalize evasion to the left
1153  if (myDir == FORWARD && i > 0) {
1154  utility[i - 1] -= 0.5;
1155  } else if (myDir == BACKWARD && i < sMax) {
1156  utility[i + 1] -= 0.5;
1157  }
1158  }
1159  // compute expected distance achievable by staying on this stripe for a time horizon
1160  const SUMOReal walkDist = MAX2((SUMOReal)0, distance[i]); // disregard special distance flags
1161  const SUMOReal lookAhead = obs[i].speed * myDir >= 0 ? LOOKAHEAD_SAMEDIR : LOOKAHEAD_ONCOMING;
1162  const SUMOReal expectedDist = MIN2(vMax * LOOKAHEAD_SAMEDIR, walkDist + obs[i].speed * myDir * lookAhead);
1163  if (DEBUGCOND(myPerson->getID())) {
1164  std::cout << " util=" << utility[i] << " exp=" << expectedDist << " dist=" << distance[i] << "\n";
1165  }
1166  if (expectedDist >= 0) {
1167  utility[i] += expectedDist;
1168  } else {
1169  // let only the distance count
1170  utility[i] += ONCOMING_CONFLICT_PENALTY + distance[i];
1171  }
1172  }
1173  // discourage use of the leftmost lane (in walking direction) if there are oncoming
1174  if (myDir == FORWARD && obs[0].speed < 0) {
1175  utility[0] += ONCOMING_CONFLICT_PENALTY;
1176  } else if (myDir == BACKWARD && obs[sMax].speed > 0) {
1177  utility[sMax] += ONCOMING_CONFLICT_PENALTY;
1178  }
1179  // penalize lateral movement (if the current stripe permits walking)
1180  if (distance[current] > 0 && myWaitingTime == 0) {
1181  for (int i = 0; i < stripes; ++i) {
1182  utility[i] += abs(i - current) * LATERAL_PENALTY;
1183  }
1184  }
1185 
1186  // select best stripe
1187  int chosen = current;
1188  for (int i = 0; i < stripes; ++i) {
1189  if (utility[chosen] < utility[i]) {
1190  chosen = i;
1191  }
1192  }
1193  // compute speed components along both axes
1194  const int next = (chosen == current ? current : (chosen < current ? current - 1 : current + 1));
1195  const SUMOReal xDist = MIN3(distance[current], distance[other], distance[next]);
1196  // XXX preferred gap differs between approaching a standing obstacle or a moving obstacle
1197  const SUMOReal preferredGap = NUMERICAL_EPS;
1198  SUMOReal xSpeed = MIN2(vMax, MAX2((SUMOReal)0, DIST2SPEED(xDist - preferredGap)));
1199  if (xSpeed < NUMERICAL_EPS) {
1200  xSpeed = 0.;
1201  }
1202  if (DEBUGCOND(myPerson->getID())) {
1203  std::cout << " xSpeedPotential=" << xSpeed << "\n";
1204  }
1205  // avoid tiny steps
1206  // XXX pressure from behind?
1207  if (mySpeed == 0 && xDist < MIN_STARTUP_DIST &&
1208  // unless walking towards a short lane
1209  !(
1210  (xDist == distance[current] && obs[current].border)
1211  || (xDist == distance[other] && obs[other].border)
1212  || (xDist == distance[next] && obs[next].border))
1213  ) {
1214  xSpeed = 0;
1215  }
1216  if (xSpeed == 0) {
1217  if (myWaitingTime > jamTime || myAmJammed) {
1218  // squeeze slowly through the crowd ignoring others
1219  if (!myAmJammed) {
1221  WRITE_WARNING("Person '" + myPerson->getID()
1222  + "' is jammed on edge '" + myStage->getEdge()->getID()
1223  + "', time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
1224  myAmJammed = true;
1225  }
1226  xSpeed = vMax / 4;
1227  }
1228  } else if (stripe(myRelY) >= 0 && stripe(myRelY) <= sMax) {
1229  myAmJammed = false;
1230  }
1231  // dawdling
1232  const SUMOReal dawdle = MIN2(xSpeed, RandHelper::rand() * vMax * dawdling);
1233 
1234  // XXX ensure that diagonal speed <= vMax
1235  // avoid deadlocks on narrow sidewalks
1236  //if (oncoming && xSpeed == 0 && myStage->getWaitingTime(currentTime) > TIME2STEPS(ONCOMIN_PATIENCE)) {
1237  // if DEBUGCOND(myPerson->getID()) std::cout << " stepping asside to resolve oncoming deadlock\n";
1238  // xSpeed = POSITION_EPS; // reset myWaitingTime
1239  // if (myDir == FORWARD && chosen < sMax) {
1240  // chosen += 1;
1241  // } else if (myDir == BACKWARD && chosen > 0) {
1242  // chosen -= 1;
1243  // }
1244  //}
1245  const SUMOReal maxYSpeed = MIN2(MAX2(vMax * LATERAL_SPEED_FACTOR, vMax - xSpeed), stripeWidth);
1246  SUMOReal ySpeed = 0;
1247  SUMOReal yDist = 0;
1248  if (utility[next] > OBSTRUCTION_THRESHOLD && utility[chosen] > OBSTRUCTION_THRESHOLD) {
1249  // don't move laterally if the stripes are blocked
1250  yDist = (chosen * stripeWidth) - myRelY;
1251  if (fabs(yDist) > NUMERICAL_EPS) {
1252  ySpeed = (yDist > 0 ?
1253  MIN2(maxYSpeed, DIST2SPEED(yDist)) :
1254  MAX2(-maxYSpeed, DIST2SPEED(yDist)));
1255  }
1256  }
1257  // DEBUG
1258  if DEBUGCOND(myPerson->getID()) {
1259  std::cout << SIMTIME
1260  << " ped=" << myPerson->getID()
1261  << " edge=" << myStage->getEdge()->getID()
1262  << " x=" << myRelX
1263  << " y=" << myRelY
1264  << " d=" << myDir
1265  << " pvx=" << mySpeed
1266  << " cur=" << current
1267  << " cho=" << chosen
1268  << " oth=" << other
1269  << " nxt=" << next
1270  << " vx=" << xSpeed
1271  << " dawdle=" << dawdle
1272  << " vy=" << ySpeed
1273  << " xd=" << xDist
1274  << " yd=" << yDist
1275  << " vMax=" << myStage->getMaxSpeed()
1276  << " wTime=" << myStage->getWaitingTime(currentTime)
1277  << " jammed=" << myAmJammed
1278  << "\n distance=" << toString(distance)
1279  << "\n utility=" << toString(utility)
1280  << "\n";
1281  DEBUG_PRINT(obs);
1282  }
1283  myRelX += SPEED2DIST(xSpeed * myDir);
1284  myRelY += SPEED2DIST(ySpeed);
1285  mySpeed = xSpeed;
1286  if (xSpeed >= SUMO_const_haltingSpeed) {
1287  myWaitingToEnter = false;
1288  myWaitingTime = 0;
1289  } else {
1291  }
1292 }
1293 
1294 
1295 SUMOReal
1297  return MAX2((SUMOReal)0, MIN2(SUMOReal(1),
1300 }
1301 
1302 
1303 SUMOReal
1305  return myRelX;
1306 }
1307 
1308 
1309 Position
1311  if (myLane == 0) {
1312  // pedestrian has already finished
1313  return Position::INVALID;
1314  }
1315  const SUMOReal lateral_offset = myRelY + (stripeWidth - myLane->getWidth()) * 0.5;
1316  if (myWalkingAreaPath == 0) {
1317  return stage.getLanePosition(myLane, myRelX, lateral_offset);
1318  } else {
1319  //if DEBUGCOND(myPerson->getID()) {
1320  // std::cout << SIMTIME
1321  // << " getPosition (walkingArea)"
1322  // << " p=" << myPerson->getID()
1323  // << " x=" << myRelX
1324  // << " y=" << myRelY
1325  // << " latOffset=" << lateral_offset
1326  // << " shape=" << myWalkingAreaPath->shape
1327  // << " pos=" << myWalkingAreaPath->shape.positionAtOffset(myRelX, lateral_offset)
1328  // << "\n";
1329  //}
1330  return myWalkingAreaPath->shape.positionAtOffset(myRelX, lateral_offset);
1331  }
1332 }
1333 
1334 
1335 SUMOReal
1337  if (myLane == 0) {
1338  // pedestrian has already finished
1339  return 0;
1340  }
1342  SUMOReal angle = shp.rotationAtOffset(myRelX) + (myDir == MSPModel::BACKWARD ? M_PI : 0);
1343  if (angle > M_PI) {
1344  angle -= 2 * M_PI;
1345  }
1346  return angle;
1347 }
1348 
1349 
1350 SUMOTime
1352  return myWaitingTime;
1353 }
1354 
1355 
1356 SUMOReal
1358  return mySpeed;
1359 }
1360 
1361 
1362 const MSEdge*
1364  return myNLI.lane == 0 ? 0 : &myNLI.lane->getEdge();
1365 }
1366 
1367 
1368 SUMOReal
1369 MSPModel_Striping::PState::distanceTo(const Obstacle& obs, const bool includeMinGap) const {
1370  // check for overlap
1371  const SUMOReal maxX = getMaxX(includeMinGap);
1372  const SUMOReal minX = getMinX(includeMinGap);
1373  //if (DEBUGCOND(myPerson->getID())) {
1374  // std::cout << std::setprecision(2) << " distanceTo=" << obs.description << " maxX=" << maxX << " minX=" << minX << " obs.xFwd=" << obs.xFwd << " obs.xBack=" << obs.xBack << "\n";
1375  //}
1376  if ((obs.xFwd >= maxX && obs.xBack <= maxX) || (obs.xFwd <= maxX && obs.xFwd >= minX)) {
1377  return DIST_OVERLAP;
1378  }
1379  if (myDir == FORWARD) {
1380  return obs.xFwd < minX ? DIST_BEHIND : obs.xBack - maxX;
1381  } else {
1382  return obs.xBack > maxX ? DIST_BEHIND : minX - obs.xFwd;
1383  }
1384 }
1385 
1386 
1387 void
1389  for (int i = 0; i < (int)into.size(); ++i) {
1390  if (gDebugFlag1) {
1391  std::cout << " i=" << i << " intoDist=" << distanceTo(into[i]) << " obs2Dist=" << distanceTo(obs2[i]) << "\n";
1392  }
1393  if (distanceTo(obs2[i]) < distanceTo(into[i])) {
1394  into[i] = obs2[i];
1395  }
1396  }
1397 }
1398 
1399 
1400 
1401 // ===========================================================================
1402 // MSPModel_Striping::MovePedestrians method definitions
1403 // ===========================================================================
1404 //
1405 
1406 SUMOTime
1408  std::set<MSPerson*> changedLane;
1409  myModel->moveInDirection(currentTime, changedLane, FORWARD);
1410  myModel->moveInDirection(currentTime, changedLane, BACKWARD);
1411  // DEBUG
1412 #ifdef LOG_ALL
1413  for (ActiveLanes::const_iterator it_lane = myModel->getActiveLanes().begin(); it_lane != myModel->getActiveLanes().end(); ++it_lane) {
1414  const MSLane* lane = it_lane->first;
1415  Pedestrians pedestrians = it_lane->second;
1416  if (pedestrians.size() == 0) {
1417  continue;
1418  }
1419  sort(pedestrians.begin(), pedestrians.end(), by_xpos_sorter(FORWARD));
1420  std::cout << SIMTIME << " lane=" << lane->getID();
1421  for (int ii = 0; ii < (int)pedestrians.size(); ++ii) {
1422  const PState& p = *pedestrians[ii];
1423  std::cout << " (" << p.myPerson->getID() << " " << p.myRelX << "," << p.myRelY << " " << p.myDir << ")";
1424  }
1425  std::cout << "\n";
1426  }
1427 #endif
1428  return DELTA_T;
1429 }
1430 
const Obstacles & getNextLaneObstacles(NextLanesObstacles &nextLanesObs, const MSLane *lane, const MSLane *nextLane, int stripes, SUMOReal nextLength, int nextDir, SUMOReal currentLength, int currentDir)
bool gDebugFlag1
global utility flags for debugging
Definition: StdDefs.cpp:37
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...
#define DIST2SPEED(x)
Definition: SUMOTime.h:57
bool blockedAtDist(const MSLane *lane, SUMOReal distToCrossing, std::vector< const MSPerson * > *collectBlockers)
whether a pedestrian is blocking the crossing of lane at offset distToCrossing
MSEdge & getEdge() const
Returns the lane&#39;s edge.
Definition: MSLane.h:571
static const SUMOReal OBSTRUCTED_PENALTY
long long int SUMOTime
Definition: SUMOTime.h:43
static const SUMOReal SAFETY_GAP
Definition: MSPModel.h:81
SUMOReal rotationAtOffset(SUMOReal pos) const
Returns the rotation at the given length.
const MSEdge * getNextRouteEdge() const
Definition: MSPerson.h:167
#define SPEED2DIST(x)
Definition: SUMOTime.h:55
SUMOReal distToLaneEnd() const
the absolute distance to the end of the lane in walking direction (or to the arrivalPos) ...
MSPerson::MSPersonStage_Walking * myStage
static SUMOReal stripeWidth
model parameters
static int numStripes(const MSLane *lane)
return the maximum number of pedestrians walking side by side
static Obstacles getNeighboringObstacles(const Pedestrians &pedestrians, int egoIndex, int stripes)
sorts the persons by position on the lane. If dir is forward, higher x positions come first...
SUMOReal mySpeed
the current walking speed
bool compute(const E *from, const E *to, SUMOReal departPos, SUMOReal arrivalPos, SUMOReal 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...
static const MSLane * getNextWalkingArea(const MSLane *currentLane, const int dir, MSLink *&link)
return the next walkingArea in the given direction
#define DEBUG1
static int connectedDirection(const MSLane *from, const MSLane *to)
returns the direction in which these lanes are connectioned or 0 if they are not
WalkingAreaPath * myWalkingAreaPath
the current walkingAreaPath or 0
#define M_PI
Definition: angles.h:37
information regarding surround Pedestrians (and potentially other things)
SUMOReal getLength() const
Returns the lane&#39;s length.
Definition: MSLane.h:480
The base class for an intersection.
Definition: MSJunction.h:64
SUMOReal distanceTo(const Obstacle &obs, const bool includeMinGap=true) const
const MSStoppingPlace * getDestinationStop() const
returns the destination stop (if any)
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
bool isWalkingArea() const
return whether this edge is walking area
Definition: MSEdge.h:264
PState(MSPerson *person, MSPerson::MSPersonStage_Walking *stage, const MSLane *lane)
static const int FORWARD
Definition: MSPModel.h:73
static SUMOReal rand()
Returns a random real number in [0, 1)
Definition: RandHelper.h:62
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:60
SUMOReal getLength() const
Get vehicle&#39;s length [m].
SUMOReal getImpatience() const
Returns this type&#39;s impatience.
MSPedestrianRouterDijkstra & getPedestrianRouter(const MSEdgeVector &prohibited=MSEdgeVector()) const
Definition: MSNet.cpp:934
SUMOReal getWidth() const
Returns the lane&#39;s width.
Definition: MSLane.h:496
static const SUMOReal ONCOMING_CONFLICT_PENALTY
void registerJammed()
register a jammed transportable
#define DEBUGCOND(PEDID)
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:159
T MAX2(T a, T b)
Definition: StdDefs.h:70
void remove(PedestrianState *state)
remove the specified person from the pedestrian simulation
SUMOTime DELTA_T
Definition: SUMOTime.cpp:40
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:59
const std::string & getID() const
returns the id of the transportable
SUMOReal getFloat(const std::string &name) const
Returns the SUMOReal-value of the named option (only for Option_Float)
std::vector< const MSEdge * > ConstMSEdgeVector
Definition: MSEdge.h:78
std::map< std::pair< const MSLane *, const MSLane * >, WalkingAreaPath > WalkingAreaPaths
bool moveToNextLane(SUMOTime currentTime)
return whether this pedestrian has passed the end of the current lane and update myRelX if so ...
static void addCloserObstacle(Obstacles &obs, SUMOReal x, int stripe, int numStripes, const std::string &id, SUMOReal width, int dir)
static MSPModel * myModel
Definition: MSPModel.h:90
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:255
static WalkingAreaPaths myWalkingAreaPaths
store for walkinArea elements
static const SUMOReal DIST_OVERLAP
SUMOReal x() const
Returns the x-position.
Definition: Position.h:63
#define abs(a)
Definition: polyfonts.c:67
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
The simulated network and simulation perfomer.
Definition: MSNet.h:94
bool myAmJammed
whether the person is jammed
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:69
#define SIMTIME
Definition: SUMOTime.h:70
const MSEdge * getEdge() const
Returns the current edge.
Definition: MSPerson.cpp:84
static Pedestrians noPedestrians
empty pedestrian vector
static bool gCheck4Accidents
Definition: MSGlobals.h:80
static const SUMOReal RESERVE_FOR_ONCOMING_FACTOR
PositionVector reverse() const
reverse position vector
void moveInDirection(SUMOTime currentTime, std::set< MSPerson * > &changedLane, int dir)
move all pedestrians forward and advance to the next lane if applicable
void mergeObstacles(Obstacles &into, const Obstacles &obs2)
replace obstacles in the first vector with obstacles from the second if they are closer to me ...
static void transformToCurrentLanePositions(Obstacles &o, int currentDir, int nextDir, SUMOReal currentLength, SUMOReal nextLength)
NextLaneInfo myNLI
information about the upcoming lane
const MSEdge & getDestination() const
returns the destination edge
static const SUMOReal SQUEEZE
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
SUMOReal getMinX(const bool includeMinGap=true) const
return the minimum position on the lane
const std::string & getID() const
Returns the id.
Definition: Named.h:66
A road/street connecting two junctions.
Definition: MSEdge.h:80
Pedestrians & getPedestrians(const MSLane *lane)
retrieves the pedestian vector for the given lane (may be empty)
Position getLanePosition(const MSLane *lane, SUMOReal at, SUMOReal offset) const
get position on lane at length at with orthogonal offset
static const SUMOReal LOOKAHEAD_SAMEDIR
static const int UNDEFINED_DIRECTION
Definition: MSPModel.h:78
SUMOReal getLength() const
return the length of the edge
Definition: MSEdge.h:580
void arriveAndAdvance(Pedestrians &pedestrians, SUMOTime currentTime, std::set< MSPerson * > &changedLane, int dir)
handle arrivals and lane advancement
const MSVehicleType & getVehicleType() const
MSLane * getLogicalPredecessorLane() const
get the most likely precedecessor lane (sorted using by_connections_to_sorter). The result is cached ...
Definition: MSLane.cpp:1994
bool moveToNextEdge(MSPerson *person, SUMOTime currentTime, MSEdge *nextInternal=0)
move forward and return whether the person arrived
Definition: MSPerson.cpp:211
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:55
const MSEdge * getEdge() const
Returns the current edge.
static const SUMOReal LATERAL_SPEED_FACTOR
SUMOTime execute(SUMOTime currentTime)
Executes the command.
const MSEdgeVector & getPredecessors() const
Returns the edge at the given position from the list of reachable edges.
Definition: MSEdge.h:364
SUMOReal getMinGap() const
Get the free space in front of vehicles of this class.
virtual MSTransportableControl & getPersonControl()
Returns the person control.
Definition: MSNet.cpp:710
void walk(const Obstacles &obs, SUMOTime currentTime)
perform position update
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:46
static const SUMOReal LOOKAHEAD_ONCOMING
static int getStripeOffset(int origStripes, int destStripes, bool addRemainder)
const ConstMSEdgeVector & getRoute() const
Definition: MSPerson.h:170
static const SUMOReal INAPPROPRIATE_PENALTY
SUMOReal xFwd
maximal position on the current lane in forward direction
static const SUMOReal OBSTRUCTION_THRESHOLD
A list of positions.
StageType getCurrentStageType() const
the current stage type of the transportable
static const SUMOReal DIST_BEHIND
MSEventControl * getBeginOfTimestepEvents()
Returns the event control for events executed at the begin of a time step.
Definition: MSNet.h:401
SUMOReal getLength() const
return the length of the pedestrian
SUMOTime getWaitingTime(const MSPerson::MSPersonStage_Walking &stage, SUMOTime now) const
return the time the person spent standing
#define STEPS2TIME(x)
Definition: SUMOTime.h:65
Position positionAtOffset(SUMOReal pos, SUMOReal lateralOffset=0) const
Returns the position at the given length.
SUMOTime string2time(const std::string &r)
Definition: SUMOTime.cpp:47
T MIN2(T a, T b)
Definition: StdDefs.h:64
#define POSITION_EPS
Definition: config.h:182
Position getPosition(const MSPerson::MSPersonStage_Walking &stage, SUMOTime now) const
return the network coordinate of the person
std::map< const MSLane *, Obstacles, lane_by_numid_sorter > NextLanesObstacles
SUMOReal getAngle(const MSPerson::MSPersonStage_Walking &stage, SUMOTime now) const
return the direction in which the person faces in degrees
SUMOTime myWaitingTime
the consecutive time spent at speed 0
bool isInternal() const
return whether this edge is an internal edge
Definition: MSEdge.h:254
int myDir
the walking direction on the current lane (1 forward, -1 backward)
SUMOTime getWaitingTime(SUMOTime now) const
the time this transportable spent waiting
Definition: MSPerson.cpp:118
virtual SUMOTime addEvent(Command *operation, SUMOTime execTimeStep, AdaptType type)
Adds an Event.
SUMOReal getEdgePos(const MSPerson::MSPersonStage_Walking &stage, SUMOTime now) const
abstract methods inherited from PedestrianState
static const SUMOReal RESERVE_FOR_ONCOMING_FACTOR_JUNCTIONS
SUMOReal getSpeed(const MSPerson::MSPersonStage_Walking &stage) const
return the current speed of the person
void cleanupHelper()
remove state at simulation end
PedestrianState * add(MSPerson *person, MSPerson::MSPersonStage_Walking *stage, SUMOTime now)
register the given person as a pedestrian
bool border
whether this obstacle denotes a border or a pedestrian
static const SUMOReal MIN_STARTUP_DIST
abstract base class for managing callbacks to retrieve various state information from the model ...
Definition: MSPModel.h:96
Obstacle(int dir, SUMOReal dist=DIST_FAR_AWAY)
create No-Obstacle
SUMOReal getArrivalPos() const
Definition: MSPerson.h:160
SUMOReal getWidth() const
Get the width which vehicles of this class shall have when being drawn.
EdgeBasicFunction getPurpose() const
Returns the edge type (EdgeBasicFunction)
Definition: MSEdge.h:249
SUMOReal getImpatience(SUMOTime now) const
returns the impatience
std::vector< PState * > Pedestrians
#define SUMOTime_MAX
Definition: SUMOTime.h:44
bool myWaitingToEnter
whether the pedestrian is waiting to start its walk
static const MSEdgeVector & getAllEdges()
Returns all edges with a numerical id.
Definition: MSEdge.cpp:726
The edge is a normal street.
Definition: MSEdge.h:93
SUMOReal y() const
Returns the y-position.
Definition: Position.h:68
A storage for options typed value containers)
Definition: OptionsCont.h:99
Container for pedestrian state and individual position update function.
const SUMOReal SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
Definition: StdDefs.h:56
std::vector< Obstacle > Obstacles
SUMOReal getMaxX(const bool includeMinGap=true) const
return the maximum position on the lane
static const SUMOReal BLOCKER_LOOKAHEAD
SUMOReal xBack
maximal position on the current lane in backward direction
static const int BACKWARD
Definition: MSPModel.h:77
const PositionVector & getShape() const
Returns this lane&#39;s shape.
Definition: MSLane.h:427
SUMOReal distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
Definition: Position.h:250
static const SUMOReal DIST_FAR_AWAY
Patch the time in a way that it is at least as high as the simulation begin time. ...
#define SUMOReal
Definition: config.h:208
const MSEdge * getNextEdge(const MSPerson::MSPersonStage_Walking &stage) const
return the list of internal edges if the pedestrian is on an intersection
SUMOReal myRelY
the orthogonal shift on the current lane
static const SUMOReal MAX_WAIT_TOLERANCE
bool isCrossing() const
return whether this edge is a pedestrian crossing
Definition: MSEdge.h:259
SUMOReal myRelX
the advancement along the current lane
const MSJunction * getFromJunction() const
Definition: MSEdge.h:369
const MSEdgeVector & getSuccessors() const
Returns the following edges.
Definition: MSEdge.h:339
T MIN3(T a, T b, T c)
Definition: StdDefs.h:77
MovePedestrians * myCommand
the MovePedestrians command that is registered
SUMOReal getMinGap() const
return the minimum gap of the pedestrian
#define NUMERICAL_EPS
Definition: config.h:158
void push_back_noDoublePos(const Position &p)
insert in back a non double position
static void DEBUG_PRINT(const Obstacles &obs)
const MSLinkCont & getLinkCont() const
returns the container with all links !!!
Definition: MSLane.cpp:1545
static SUMOReal dawdling
std::vector< MSEdge * > MSEdgeVector
Definition: MSEdge.h:77
static SUMOTime jamTime
int myNumActivePedestrians
the total number of active pedestrians
SUMOReal speed
speed relative to lane direction (positive means in the same direction)
const std::vector< IncomingLaneInfo > & getIncomingLanes() const
Definition: MSLane.h:708
std::string description
the id / description of the obstacle
SUMOReal getMaxSpeed() const
accessors to be used by MSPModel
Definition: MSPerson.h:149
static void initWalkingAreaPaths(const MSNet *net)
MSPModel_Striping(const OptionsCont &oc, MSNet *net)
Constructor (it should not be necessary to construct more than one instance)
Representation of a lane in the micro simulation.
Definition: MSLane.h:79
ActiveLanes myActiveLanes
store of all lanes which have pedestrians on them
const MSLane * myLane
the current lane of this pedestrian
static const SUMOReal LATERAL_PENALTY
void moveInDirectionOnLane(Pedestrians &pedestrians, const MSLane *lane, SUMOTime currentTime, std::set< MSPerson * > &changedLane, int dir)
move pedestrians forward on one lane
void extrapolate(const SUMOReal val, const bool onlyFirst=false)
extrapolate position vector
static const Position INVALID
used to indicate that a position is valid
Definition: Position.h:278
Position transformToVectorCoordinates(const Position &p, bool extend=false) const
return position p within the length-wise coordinate system defined by this position vector...
const MSJunction * getToJunction() const
Definition: MSEdge.h:373
static bool canTraverse(int dir, const ConstMSEdgeVector &route)
return whether the route may traversed with the given starting direction
Definition: MSPModel.cpp:91