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