51#define DEBUGCOND(PED) ((PED).myPerson->isSelected())
52#define DEBUGCOND2(LANE) ((LANE)->isSelected())
57 for (
int i = 0; i < (int)obs.size(); ++i) {
59 <<
"(" << obs[i].description
60 <<
" x=(" << obs[i].xBack <<
"," << obs[i].xFwd
61 <<
") s=" << obs[i].speed
116 myNumActivePedestrians(0),
124 WRITE_WARNINGF(
TL(
"Pedestrian vType '%' width % is larger than pedestrian.striping.stripe-width and this may cause collisions with vehicles."),
178 if (lane ==
nullptr) {
179 const char* error =
TL(
"Person '%' could not find sidewalk on edge '%', time=%.");
211 const MSLane* lane =
dynamic_cast<PState*
>(state)->myLane;
213 for (Pedestrians::iterator it = pedestrians.begin(); it != pedestrians.end(); ++it) {
215 pedestrians.erase(it);
225 double oncomingGap, std::vector<const MSPerson*>* collectBlockers) {
227 for (Pedestrians::const_iterator it_ped = pedestrians.begin(); it_ped != pedestrians.end(); ++it_ped) {
228 const PState& ped = **it_ped;
230 const double leaderBackDist = leaderFrontDist + ped.
getLength();
233 <<
" vehSide=" << vehSide
234 <<
" vehWidth=" << vehWidth
235 <<
" lBD=" << leaderBackDist
236 <<
" lFD=" << leaderFrontDist
239 if (leaderBackDist >= -vehWidth
240 && (leaderFrontDist < 0
248 if (collectBlockers ==
nullptr) {
251 collectBlockers->push_back(ped.
myPerson);
255 if (collectBlockers ==
nullptr) {
258 return collectBlockers->size() > 0;
283 for (Pedestrians::const_iterator it_ped = pedestrians.begin(); it_ped != pedestrians.end(); ++it_ped) {
284 const PState& ped = **it_ped;
287 double dist = ((relX2 - minPos) * (bidi ? -1 : 1)
289 const bool aheadOfVehicle = bidi ? ped.
myRelX < minPos : ped.
myRelX > minPos;
290 if (aheadOfVehicle && dist < result.second) {
293 const bool overlap = (center + halfWidth > minRight && center - halfWidth < maxLeft);
295 std::cout <<
" nextBlocking lane=" << lane->
getID() <<
" bidi=" << bidi
296 <<
" minPos=" << minPos <<
" minRight=" << minRight <<
" maxLeft=" << maxLeft
297 <<
" stopTime=" << stopTime
300 <<
" relX2=" << relX2
301 <<
" center=" << center
302 <<
" pedLeft=" << center + halfWidth
303 <<
" pedRight=" << center - halfWidth
304 <<
" overlap=" << overlap
309 result.second = dist;
336 if (from ==
nullptr || to ==
nullptr) {
338 }
else if (from->
getLinkTo(to) !=
nullptr) {
340 }
else if (to->
getLinkTo(from) !=
nullptr) {
358 for (
MSLink* link : lane->getLinkCont()) {
359 if (link->getWalkingAreaFoe() !=
nullptr) {
361 myWalkingAreaFoes[&link->getWalkingAreaFoe()->getEdge()].push_back(link->getLaneBefore());
364 if (link->getWalkingAreaFoeExit() !=
nullptr) {
366 myWalkingAreaFoes[&link->getWalkingAreaFoeExit()->getEdge()].push_back(link->getLaneBefore());
378 const MSLane* walkingArea = getSidewalk<MSEdge, MSLane>(edge);
382 std::vector<const MSLane*> lanes;
384 if (!in->isTazConnector()) {
385 lanes.push_back(getSidewalk<MSEdge, MSLane>(in));
386 if (lanes.back() ==
nullptr) {
387 throw ProcessError(
"Invalid connection from edge '" + in->getID() +
"' to walkingarea edge '" + edge->
getID() +
"'");
392 if (!out->isTazConnector()) {
393 lanes.push_back(getSidewalk<MSEdge, MSLane>(out));
394 if (lanes.back() ==
nullptr) {
395 throw ProcessError(
"Invalid connection from walkingarea edge '" + edge->
getID() +
"' to edge '" + out->getID() +
"'");
400 for (
int j = 0; j < (int)lanes.size(); ++j) {
401 for (
int k = 0; k < (int)lanes.size(); ++k) {
404 const MSLane*
const from = lanes[j];
405 const MSLane*
const to = lanes[k];
411 const double maxExtent = fromPos.
distanceTo2D(toPos) / 4;
412 const double extrapolateBy =
MIN2(maxExtent, walkingArea->
getWidth() / 2);
414 shape.push_back(fromPos);
415 if (extrapolateBy > POSITION_EPS) {
424 if (shape.size() < 2) {
428 assert(shape.size() == 2);
433 if (shape.size() >= 4 && shape.
length() < walkingArea->
getWidth()) {
434 const double aStart = shape.
angleAt2D(0);
435 const double aEnd = shape.
angleAt2D((
int)shape.size() - 2);
436 if (fabs(aStart - aEnd) <
DEG2RAD(10)) {
437 angleOverride = (aStart + aEnd) / 2;
458 std::vector<const MSLane*> lanes;
460 lanes.push_back(getSidewalk<MSEdge, MSLane>(pred));
463 lanes.push_back(getSidewalk<MSEdge, MSLane>(succ));
465 if (lanes.size() < 1) {
466 throw ProcessError(
TLF(
"Invalid walkingarea '%' does not allow continuation.", walkingArea->
getID()));
474 const MSLane* swBefore = getSidewalk<MSEdge, MSLane>(before);
475 const MSLane* swAfter = getSidewalk<MSEdge, MSLane>(after);
478 return &pathIt->second;
482 bool useBefore = swBefore !=
nullptr && std::find(preds.begin(), preds.end(), before) != preds.end();
483 bool useAfter = swAfter !=
nullptr && std::find(succs.begin(), succs.end(), after) != succs.end();
487 }
else if (succs.size() > 0) {
489 return getWalkingAreaPath(walkingArea, swBefore, getSidewalk<MSEdge, MSLane>(succs.front()));
491 }
else if (useAfter && preds.size() > 0) {
493 return getWalkingAreaPath(walkingArea, getSidewalk<MSEdge, MSLane>(preds.front()), swAfter);
504 return &pathIt->second;
508 if (preds.size() > 0) {
510 const auto pathIt2 =
myWalkingAreaPaths.find(std::make_pair(getSidewalk<MSEdge, MSLane>(pred), after));
512 return &pathIt2->second;
528 const MSLane* nextLane = nextRouteLane;
529 const MSLink* link =
nullptr;
535 if (nextRouteLane ==
nullptr && nextRouteEdge !=
nullptr) {
536 std::string error =
"Person '" + ped.
myPerson->
getID() +
"' could not find sidewalk on edge '" + nextRouteEdge->
getID() +
"', time="
540 nextRouteLane = nextRouteEdge->
getLanes().front();
546 if (nextRouteLane !=
nullptr) {
551 nextLane = currentLane->
getLinkCont()[0]->getViaLaneOrLane();
556 std::cout <<
" internal\n";
561 nextLane = currentLane->
getLinkCont()[0]->getLane();
566 std::cout <<
" crossing\n";
573 const double arrivalPos = (nextRouteEdge == ped.
myStage->
getRoute().back()
577 if (prevLane !=
nullptr) {
578 prohibited.push_back(&prevLane->
getEdge());
583 <<
" nre=" << nextRouteEdge->
getID()
584 <<
" nreDir=" << nextRouteEdgeDir
585 <<
" aPos=" << arrivalPos
586 <<
" crossingRoute=" <<
toString(crossingRoute)
589 if (crossingRoute.size() > 1) {
590 const MSEdge* nextEdge = crossingRoute[1];
591 nextLane = getSidewalk<MSEdge, MSLane>(crossingRoute[1], ped.
myPerson->
getVClass());
593 assert(nextLane != prevLane);
596 std::cout <<
" nextDir=" << nextDir <<
"\n";
605 link = oppositeWalkingArea->
getLinkTo(nextLane);
608 assert(link !=
nullptr);
612 <<
" no route from '" << (currentEdge ==
nullptr ?
"NULL" : currentEdge->
getID())
613 <<
"' to '" << (nextRouteEdge ==
nullptr ?
"NULL" : nextRouteEdge->
getID())
618 link = prevLane->
getLinkTo(nextRouteLane);
620 link = nextRouteLane->
getLinkTo(prevLane);
622 if (link !=
nullptr) {
627 +
"' from walkingArea '" + currentEdge->
getID()
628 +
"' to edge '" + nextRouteEdge->
getID() +
"', time=" +
631 nextLane = nextRouteLane;
634 }
else if (currentEdge == nextRouteEdge) {
636 nextDir = -ped.
myDir;
641 if (nextLane !=
nullptr) {
644 std::cout <<
" next walkingArea " << (nextDir ==
FORWARD ?
"forward" :
"backward") <<
"\n";
652 link = currentLane->
getLinkTo(nextRouteLane);
653 if (link !=
nullptr) {
655 std::cout <<
" direct forward\n";
660 link = nextRouteLane->
getLinkTo(currentLane);
661 if (link !=
nullptr) {
663 std::cout <<
" direct backward\n";
666 if (nextLane !=
nullptr) {
668 while (nextLane->
getLinkCont()[0]->getViaLaneOrLane()->isInternal()) {
669 nextLane = nextLane->
getLinkCont()[0]->getViaLaneOrLane();
675 if (nextLane ==
nullptr) {
677 nextLane = nextRouteLane;
679 std::cout <<
SIMTIME <<
" no next lane found for " << currentLane->
getID() <<
" dir=" << ped.
myDir <<
"\n";
683 +
"' from edge '" + currentEdge->
getID()
684 +
"' to edge '" + nextRouteEdge->
getID() +
"', time=" +
687 }
else if (nextLane->
getLength() <= POSITION_EPS) {
699 nextLane = nextRouteLane;
708 <<
" l=" << currentLane->
getID()
709 <<
" nl=" << (nextLane ==
nullptr ?
"NULL" : nextLane->
getID())
710 <<
" nrl=" << (nextRouteLane ==
nullptr ?
"NULL" : nextRouteLane->
getID())
713 <<
" pedDir=" << ped.
myDir
716 assert(nextLane != 0 || nextRouteLane == 0);
725 if (l->getLane()->getEdge().isWalkingArea()) {
731 const std::vector<MSLane::IncomingLaneInfo>& laneInfos = currentLane->
getIncomingLanes();
732 for (std::vector<MSLane::IncomingLaneInfo>::const_iterator it = laneInfos.begin(); it != laneInfos.end(); ++it) {
733 if ((*it).lane->getEdge().isWalkingArea()) {
734 link = (*it).viaLink;
745 const PState& ego = *pedestrians[egoIndex];
746 const int egoStripe = ego.
stripe();
748 std::vector<bool> haveBlocker(stripes,
false);
749 for (
int index = egoIndex + 1; index < (int)pedestrians.size(); index++) {
750 const PState& p = *pedestrians[index];
752 std::cout <<
SIMTIME <<
" ped=" << ego.
getID() <<
" cur=" << egoStripe <<
" checking neighbor " << p.
getID()
758 std::cout <<
" dist=" << ego.
distanceTo(o) << std::endl;
766 haveBlocker[p.
stripe()] =
true;
777 if (!haveBlocker[p.
stripe()]) {
796 int offset = (destStripes - origStripes) / 2;
798 offset += (destStripes - origStripes) % 2;
806 MSLane* lane,
const MSLane* nextLane,
int stripes,
int nextDir,
807 double currentLength,
int currentDir) {
808 if (nextLanesObs.count(nextLane) == 0) {
815 const int offset =
getStripeOffset(nextStripes, stripes, currentDir != nextDir && nextStripes > stripes);
826 if (nextStripes < stripes) {
828 for (
int ii = 0; ii < stripes; ++ii) {
829 if (ii < offset || ii >= nextStripes + offset) {
840 if ((stripes - nextStripes) % 2 != 0) {
843 nextDir = currentDir;
845 for (
int ii = 0; ii < (int)pedestrians.size(); ++ii) {
846 PState& p = *pedestrians[ii];
851 const double newY = relPos.
y() + lateral_offset;
862 sort(pedestrians.begin(), pedestrians.end(),
by_xpos_sorter(nextDir));
863 for (
int ii = 0; ii < (int)pedestrians.size(); ++ii) {
864 const PState& p = *pedestrians[ii];
870 if (nextDir != currentDir) {
875 const int stripe = p.
stripe(newY);
876 if (stripe >= 0 && stripe < stripes) {
880 if (otherStripe >= 0 && otherStripe < stripes) {
881 obs[otherStripe] = pObs;
896 nextLanesObs[nextLane] = obs;
898 return nextLanesObs[nextLane];
903 for (
int ii = 0; ii < (int)obs.size(); ++ii) {
907 o.
xFwd += currentLength;
908 o.
xBack += currentLength;
910 const double tmp = o.
xFwd;
911 o.
xFwd = currentLength + nextLength - o.
xBack;
912 o.
xBack = currentLength + nextLength - tmp;
916 const double tmp = o.
xFwd;
920 o.
xFwd -= nextLength;
921 o.
xBack -= nextLength;
931 if ((dir ==
FORWARD && x - width / 2. < obs[stripe].xBack) || (dir ==
BACKWARD && x + width / 2. > obs[stripe].xFwd)) {
932 obs[stripe] =
Obstacle(x, 0, type,
id, width);
940 const MSLane* lane = it_lane->first;
942 if (pedestrians.size() == 0) {
948 const double minY =
stripeWidth * - 0.5 + NUMERICAL_EPS;
953 std::set<const WalkingAreaPath*, walkingarea_path_sorter> paths;
954 for (Pedestrians::iterator it = pedestrians.begin(); it != pedestrians.end(); ++it) {
957 if (p->
myDir == dir) {
961 std::cout <<
SIMTIME <<
" debugging WalkingAreaPath from=" << debugPath->from->getID() <<
" to=" << debugPath->to->getID() <<
" minY=" << minY <<
" maxY=" << maxY <<
" latOffset=" << lateral_offset <<
"\n";
966 for (std::set<const WalkingAreaPath*, walkingarea_path_sorter>::iterator it = paths.begin(); it != paths.end(); ++it) {
970 transformedPeds.reserve(pedestrians.size());
971 for (Pedestrians::iterator it_p = pedestrians.begin(); it_p != pedestrians.end(); ++it_p) {
974 transformedPeds.push_back(p);
975 if (path == debugPath) std::cout <<
" ped=" << p->
myPerson->
getID() <<
" relX=" << p->
myRelX <<
" relY=" << p->
myRelY <<
" (untransformed), vecCoord="
980 transformedPeds.push_back(p);
981 if (path == debugPath) std::cout <<
" ped=" << p->
myPerson->
getID() <<
" relX=" << p->
myRelX <<
" relY=" << p->
myRelY <<
" (untransformed), vecCoord="
991 toDelete.push_back(tp);
992 transformedPeds.push_back(tp);
993 if (path == debugPath) std::cout <<
" ped=" << p->
myPerson->
getID() <<
" relX=" << p->
myRelX <<
" relY=" << p->
myRelY <<
" (semi-transformed), vecCoord="
998 const double newY = relPos.
y() + lateral_offset;
1007 toDelete.push_back(tp);
1008 transformedPeds.push_back(tp);
1009 if (path == debugPath) {
1010 std::cout <<
" ped=" << p->
myPerson->
getID() <<
" relX=" << relPos.
x() <<
" relY=" << newY <<
" (transformed), vecCoord=" << relPos <<
"\n";
1013 if (path == debugPath) {
1014 std::cout <<
" ped=" << p->
myPerson->
getID() <<
" relX=" << relPos.
x() <<
" relY=" << newY <<
" (invalid), vecCoord=" << relPos <<
"\n";
1024 for (
const MSLane* foeLane : itFoe->second) {
1032 relCenter.push_back(relFront);
1033 relCenter.push_back(relBack);
1035 relCorners.
add(relCenter[0]);
1036 relCorners.
add(relCenter[1]);
1038 relCorners.
add(relCenter[0]);
1039 relCorners.
add(relCenter[1]);
1043 const double xWidth = relCorners.
getWidth();
1044 const double vehYmin =
MAX2(minY - lateral_offset, relCorners.
ymin());
1045 const double vehYmax =
MIN2(maxY - lateral_offset, relCorners.
ymax());
1046 const double xCenter = relCorners.
getCenter().
x();
1047 Position yMinPos(xCenter, vehYmin);
1048 Position yMaxPos(xCenter, vehYmax);
1049 const bool addFront =
addVehicleFoe(veh, lane, yMinPos, dir * xWidth, 0, lateral_offset, minY, maxY, toDelete, transformedPeds);
1050 const bool addBack =
addVehicleFoe(veh, lane, yMaxPos, dir * xWidth, 0, lateral_offset, minY, maxY, toDelete, transformedPeds);
1051 if (path == debugPath) {
1052 std::cout <<
" veh=" << veh->
getID()
1053 <<
" corners=" << relCorners
1054 <<
" xWidth=" << xWidth
1055 <<
" ymin=" << relCorners.
ymin()
1056 <<
" ymax=" << relCorners.
ymax()
1057 <<
" vehYmin=" << vehYmin
1058 <<
" vehYmax=" << vehYmax
1061 if (addFront && addBack) {
1063 const double yDist = vehYmax - vehYmin;
1065 const double relDist = dist / yDist;
1066 Position between = (yMinPos * relDist) + (yMaxPos * (1 - relDist));
1067 if (path == debugPath) {
1068 std::cout <<
" vehBetween=" << veh->
getID() <<
" pos=" << between <<
"\n";
1070 addVehicleFoe(veh, lane, between, dir * xWidth,
stripeWidth, lateral_offset, minY, maxY, toDelete, transformedPeds);
1079 for (Pedestrians::iterator it_p = toDelete.begin(); it_p != toDelete.end(); ++it_p) {
1095 const double newY = relPos.
y() + lateral_offset;
1096 if (newY >= minY && newY <= maxY) {
1099 toDelete.push_back(tp);
1100 transformedPeds.push_back(tp);
1111 sort(pedestrians.begin(), pedestrians.end(),
by_xpos_sorter(dir));
1113 for (
int i = 0; i < (int)pedestrians.size(); i++) {
1114 PState*
const p = pedestrians[i];
1121 pedestrians.erase(pedestrians.begin() + i);
1124 if (p->
myLane !=
nullptr) {
1143 sort(pedestrians.begin(), pedestrians.end(),
by_xpos_sorter(dir));
1146 bool hasCrossingVehObs =
false;
1149 hasCrossingVehObs =
addCrossingVehs(lane, stripes, 0, dir, crossingVehs,
true);
1152 for (
int ii = 0; ii < (int)pedestrians.size(); ++ii) {
1153 PState& p = *pedestrians[ii];
1190 nextLanesObs, lane, nextLane, stripes,
1209 const double passingClearanceTime = 2;
1210 const double passingLength = p.
getLength() + passingClearanceTime * speed;
1221 && !link->
opened(currentTime -
DELTA_T, speed, speed, passingLength, p.
getImpatience(currentTime), speed, 0, 0,
nullptr, p.
ignoreRed(link), p.
myPerson)) {
1258 if (hasCrossingVehObs) {
1267 p.
walk(currentObs, currentTime);
1278 for (
int coll = 0; coll < ii; ++coll) {
1279 PState& c = *pedestrians[coll];
1286 +
"', lane='" + lane->
getID() +
"', time=" +
time2string(currentTime) +
".");
1299 bool hasCrossingVehObs =
false;
1304 if (linkLeaders.size() > 0) {
1305 for (MSLink::LinkLeaders::const_iterator it = linkLeaders.begin(); it != linkLeaders.end(); ++it) {
1307 const MSVehicle* veh = (*it).vehAndGap.first;
1308 if (veh !=
nullptr) {
1313 voBlock.
xBack = NUMERICAL_EPS;
1320 const double bGap = (prio
1322 : veh->
getSpeed() * distToCrossBeforeVeh);
1326 if ((*it).fromLeft()) {
1327 vehYmin = -(*it).vehAndGap.second + lateral_offset;
1331 vehYmax = crossing->
getWidth() + (*it).vehAndGap.second - lateral_offset;
1345 hasCrossingVehObs =
true;
1350 <<
" crossingVeh=" << veh->
getID()
1351 <<
" lane=" << crossing->
getID()
1353 <<
" latOffset=" << lateral_offset
1355 <<
" stripes=" << stripes
1356 <<
" dist=" << (*it).distToCrossing
1357 <<
" gap=" << (*it).vehAndGap.second
1358 <<
" brakeGap=" << bGap
1359 <<
" fromLeft=" << (*it).fromLeft()
1360 <<
" distToCrossBefore=" << distToCrossBeforeVeh
1361 <<
" ymin=" << vehYmin
1362 <<
" ymax=" << vehYmax
1370 if (hasCrossingVehObs) {
1373 bool allBlocked =
true;
1375 for (
int i = 0; i < (int)obs.size(); i++) {
1378 (dir ==
FORWARD && i >= reserved) ||
1379 (dir ==
BACKWARD && i < (
int)obs.size() - reserved))) {
1386 std::cout <<
SIMTIME <<
" crossing=" << crossing->
getID() <<
" allBlocked\n";
1390 o.xBack = NUMERICAL_EPS;
1392 o.xFwd = crossing->
getLength() - NUMERICAL_EPS;
1398 return hasCrossingVehObs;
1413 if (ped !=
nullptr) {
1434 const double vehNextSpeed =
MAX2(veh->
getSpeed(), 1.0);
1439 double vehXMaxCheck;
1440 double vehXMinCheck;
1444 vehXMin = vehFront - clearance;
1446 vehXMaxCheck = vehBack + NUMERICAL_EPS;
1450 vehXMinCheck = vehFront - clearance;
1453 vehXMax = vehFront + clearance;
1456 vehXMaxCheck = vehFront + clearance;
1460 vehXMinCheck = vehBack - NUMERICAL_EPS;
1464 std::cout <<
SIMTIME <<
" ped=" << pID <<
" veh=" << veh->
getID() <<
" check obstacle on lane=" << lane->
getID()
1466 <<
" vehXMin=" << vehXMin
1467 <<
" vehXMax=" << vehXMax
1468 <<
" vehXMinC=" << vehXMinCheck
1469 <<
" vehXMaxC=" << vehXMaxCheck
1473 <<
" vFront=" << vehFront
1474 <<
" vBack=" << vehBack
1477 if (vehXMaxCheck > minX && vehXMinCheck && vehXMinCheck <= maxX) {
1490 if (s == current && vehFront +
SAFETY_GAP < minX) {
1492 if (pRelY - pWidth < vehYmax &&
1493 pRelY + pWidth > vehYmin && dir ==
FORWARD) {
1495 std::cout <<
" ignoring vehicle '" << veh->
getID() <<
" on stripe " << s <<
" vehFrontSG=" << vehFront +
SAFETY_GAP <<
" minX=" << minX <<
"\n";
1506 std::cout <<
SIMTIME <<
" ped=" << pID <<
" veh=" << veh->
getID() <<
" obstacle on lane=" << lane->
getID()
1508 <<
" ymin=" << vehYmin
1509 <<
" ymax=" << vehYmax
1512 <<
" relY=" << pRelY
1513 <<
" current=" << current
1514 <<
" vo.xFwd=" << vo.
xFwd
1515 <<
" vo.xBack=" << vo.
xBack
1516 <<
" vFront=" << vehFront
1517 <<
" vBack=" << vehBack
1533 type(OBSTACLE_NONE),
1539 xFwd(ped.getMaxX()),
1540 xBack(ped.getMinX()),
1541 speed(ped.myDir * ped.mySpeed),
1542 type(ped.getOType()),
1543 description(ped.getID()) {
1551 return xBack <= o.
xBack;
1553 return xFwd >= o.
xFwd;
1565 myRelX(stage->getDepartPos()),
1566 myRelY(stage->getDepartPosLat()),
1570 myWaitingToEnter(true),
1572 myWalkingAreaPath(nullptr),
1575 myAngle(
std::numeric_limits<double>::max()) {
1578 assert(!route.empty());
1579 if (route.size() == 1) {
1585 if (route.front()->isWalkingArea()) {
1592 std::cout <<
" initialize dir for " <<
myPerson->
getID() <<
" forward=" << mayStartForward <<
" backward=" << mayStartBackward <<
"\n";
1594 if (mayStartForward && mayStartBackward) {
1598 if (crossingRoute.size() > 1) {
1600 const MSEdge* nextEdge = crossingRoute[1];
1606 std::cout <<
" crossingRoute=" <<
toString(crossingRoute) <<
"\n";
1648 myWaitingToEnter(false),
1650 myWalkingAreaPath(nullptr),
1653 myAngle(
std::numeric_limits<double>::max()) {
1661 myWalkingAreaPath(nullptr),
1663 myAngle(
std::numeric_limits<double>::max()) {
1664 if (in !=
nullptr) {
1666 std::string wapLaneFrom;
1667 std::string wapLaneTo;
1668 std::string nextLaneID;
1669 std::string nextLinkFrom;
1670 std::string nextLinkTo;
1675 >> wapLaneFrom >> wapLaneTo
1685 throw ProcessError(
"Unknown lane '" + laneID +
"' when loading walk for person '" +
myPerson->
getID() +
"' from state.");
1688 MSLane* nextLane =
nullptr;
1689 if (nextLaneID !=
"null") {
1691 if (nextLane ==
nullptr) {
1692 throw ProcessError(
"Unknown next lane '" + nextLaneID +
"' when loading walk for person '" +
myPerson->
getID() +
"' from state.");
1695 const MSLink* link =
nullptr;
1696 if (nextLinkFrom !=
"null") {
1699 if (from ==
nullptr) {
1700 throw ProcessError(
"Unknown link origin lane '" + nextLinkFrom +
"' when loading walk for person '" +
myPerson->
getID() +
"' from state.");
1702 if (to ==
nullptr) {
1703 throw ProcessError(
"Unknown link destination lane '" + nextLinkTo +
"' when loading walk for person '" +
myPerson->
getID() +
"' from state.");
1709 if (wapLaneFrom !=
"null") {
1712 if (from ==
nullptr) {
1713 throw ProcessError(
"Unknown walkingAreaPath origin lane '" + wapLaneFrom +
"' when loading walk for person '" +
myPerson->
getID() +
"' from state.");
1715 if (to ==
nullptr) {
1716 throw ProcessError(
"Unknown walkingAreaPath destination lane '" + wapLaneTo +
"' when loading walk for person '" +
myPerson->
getID() +
"' from state.");
1722 throw ProcessError(
"Unknown walkingAreaPath from lane '" + wapLaneFrom +
"' to lane '" + wapLaneTo +
"' when loading walk for person '" +
myPerson->
getID() +
"' from state.");
1730 std::string wapLaneFrom =
"null";
1731 std::string wapLaneTo =
"null";
1732 if (myWalkingAreaPath !=
nullptr) {
1733 wapLaneFrom = myWalkingAreaPath->from->getID();
1734 wapLaneTo = myWalkingAreaPath->to->getID();
1736 std::string nextLaneID =
"null";
1737 std::string nextLinkFrom =
"null";
1738 std::string nextLinkTo =
"null";
1739 if (myNLI.lane !=
nullptr) {
1740 nextLaneID = myNLI.lane->getID();
1742 if (myNLI.link !=
nullptr) {
1743 nextLinkFrom = myNLI.link->getLaneBefore()->getID();
1744 nextLinkTo = myNLI.link->getViaLaneOrLane()->getID();
1746 out <<
" " << myLane->getID()
1751 <<
" " << mySpeedLat
1752 <<
" " << myWaitingToEnter
1753 <<
" " << myWaitingTime
1754 <<
" " << wapLaneFrom
1756 <<
" " << myAmJammed
1757 <<
" " << nextLaneID
1758 <<
" " << nextLinkFrom
1759 <<
" " << nextLinkTo
1760 <<
" " << myNLI.dir;
1767 return myRelX - getLength();
1769 return myRelX - (includeMinGap ? getMinGap() : 0.);
1777 return myRelX + (includeMinGap ? getMinGap() : 0.);
1779 return myRelX + getLength();
1785 return myPerson->getVehicleType().getLength();
1791 return myPerson->getVehicleType().getMinGap();
1803 const int s = stripe(relY);
1807 if (offset > threshold) {
1809 }
else if (offset < -threshold) {
1834 if (myStage->getNextRouteEdge() ==
nullptr) {
1835 return myDir * (myStage->getArrivalPos() - myRelX) - POSITION_EPS - (
1836 (myWaitingTime >
DELTA_T && (myStage->getDestinationStop() ==
nullptr ||
1837 myStage->getDestinationStop()->getWaitingCapacity() > myStage->getDestinationStop()->getNumWaitingPersons()))
1840 const double length = myWalkingAreaPath ==
nullptr ? myLane->getLength() : myWalkingAreaPath->length;
1841 return myDir ==
FORWARD ? length - myRelX : myRelX;
1848 double dist = distToLaneEnd();
1850 std::cout <<
SIMTIME <<
" ped=" << myPerson->getID() <<
" myRelX=" << myRelX <<
" dist=" << dist <<
"\n";
1858 const int oldDir = myDir;
1859 const MSLane* oldLane = myLane;
1860 myLane = myNLI.lane;
1862 const bool normalLane = (myLane ==
nullptr || myLane->getEdge().getFunction() ==
SumoXMLEdgeFunc::NORMAL || &myLane->getEdge() == myStage->getNextRouteEdge());
1865 <<
" ped=" << myPerson->getID()
1866 <<
" moveToNextLane old=" << oldLane->
getID()
1867 <<
" new=" << (myLane ==
nullptr ?
"NULL" : myLane->getID())
1868 <<
" oldDir=" << oldDir
1869 <<
" newDir=" << myDir
1870 <<
" myRelX=" << myRelX
1874 if (myLane ==
nullptr) {
1875 myRelX = myStage->getArrivalPos();
1878 if (myStage->getRouteStep() == myStage->getRoute().end() - 1) {
1881 const bool arrived = myStage->moveToNextEdge(myPerson, currentTime, oldDir, normalLane ?
nullptr : &myLane->getEdge());
1887 myStage->activateEntryReminders(myPerson);
1888 assert(myNLI.lane != oldLane);
1890 std::cout <<
" nextLane=" << (myNLI.lane ==
nullptr ?
"NULL" : myNLI.lane->getID()) <<
"\n";
1892 if (myLane->getEdge().isWalkingArea()) {
1895 assert(myWalkingAreaPath->shape.size() >= 2);
1897 std::cout <<
" mWAPath shape=" << myWalkingAreaPath->shape <<
" length=" << myWalkingAreaPath->length <<
"\n";
1899 }
else if (myNLI.link !=
nullptr) {
1901 myLane = myNLI.lane;
1902 assert(!myLane->getEdge().isWalkingArea());
1903 myStage->moveToNextEdge(myPerson, currentTime, myDir, &myLane->getEdge());
1904 myWalkingAreaPath =
nullptr;
1910 const MSEdge* currRouteEdge = *myStage->getRouteStep();
1911 const MSEdge* nextRouteEdge = myStage->getNextRouteEdge();
1919 myStage->moveToNextEdge(myPerson, currentTime, oldDir,
nullptr);
1920 myLane = myNLI.lane;
1921 assert(myLane != 0);
1924 myWalkingAreaPath =
nullptr;
1926 throw ProcessError(
TLF(
"Disconnected walk for person '%'.", myPerson->getID()));
1930 myWalkingAreaPath =
nullptr;
1935 const double newLength = (myWalkingAreaPath ==
nullptr ? myLane->getLength() : myWalkingAreaPath->length);
1936 if (-dist > newLength) {
1943 myRelX = newLength + dist;
1948 std::cout <<
SIMTIME <<
" update myRelX ped=" << myPerson->getID()
1949 <<
" newLength=" << newLength
1951 <<
" myRelX=" << myRelX
1955 if (myDir != oldDir) {
1962 std::cout <<
SIMTIME <<
" transformY ped=" << myPerson->getID()
1964 <<
" newY=" << myRelY
1966 <<
" od=" << oldDir <<
" nd=" << myDir
1967 <<
" offset=" << offset <<
"\n";
1970 myAngle = std::numeric_limits<double>::max();
1981 (
int)floor(stripes * factor),
1987 const int stripes = (int)obs.size();
1988 const int sMax = stripes - 1;
1992 const double vMax = (myStage->getConfiguredSpeed() >= 0
1993 ? myStage->getConfiguredSpeed()
1994 : (myLane->isNormal() || myLane->isInternal()
1995 ? myLane->getVehicleMaxSpeed(myPerson)
1996 : myStage->getMaxSpeed(myPerson)));
1998 const int current = stripe();
1999 const int other = otherStripe();
2001 std::vector<double> distance(stripes);
2002 for (
int i = 0; i < stripes; ++i) {
2003 distance[i] = distanceTo(obs[i], obs[i].type ==
OBSTACLE_PED);
2006 std::vector<double> utility(stripes, 0);
2008 for (
int i = 0; i < stripes; ++i) {
2010 if (i == current && (!myWaitingToEnter || stripe() != stripe(myRelY))) {
2014 for (
int j = 0; j <= i; ++j) {
2019 for (
int j = i; j < stripes; ++j) {
2028 const bool onJunction = myLane->getEdge().isWalkingArea() || myLane->getEdge().isCrossing();
2031 for (
int i = 0; i < reserved; ++i) {
2035 for (
int i = sMax; i > sMax - reserved; --i) {
2040 for (
int i = 0; i < stripes; ++i) {
2041 if (obs[i].speed * myDir < 0) {
2044 utility[i - 1] -= 0.5;
2045 }
else if (myDir ==
BACKWARD && i < sMax) {
2046 utility[i + 1] -= 0.5;
2050 const double walkDist =
MAX2(0., distance[i]);
2052 const double expectedDist =
MIN2(vMax *
LOOKAHEAD_SAMEDIR, walkDist + obs[i].speed * myDir * lookAhead);
2053 if (expectedDist >= 0) {
2054 utility[i] += expectedDist;
2061 if (myDir ==
FORWARD && obs[0].speed < 0) {
2063 }
else if (myDir ==
BACKWARD && obs[sMax].speed > 0) {
2067 if (distance[current] > 0 && myWaitingTime == 0) {
2068 for (
int i = 0; i < stripes; ++i) {
2074 for (
int i = 0; i < stripes; ++i) {
2082 int chosen = current;
2083 for (
int i = 0; i < stripes; ++i) {
2089 const int next = (chosen == current ? current : (chosen < current ? current - 1 : current + 1));
2090 double xDist =
MIN3(distance[current], distance[other], distance[next]);
2091 if (next != chosen) {
2094 const int nextOther = chosen < current ? current - 2 : current + 2;
2095 xDist =
MIN2(xDist, distance[nextOther]);
2098 const double preferredGap = NUMERICAL_EPS;
2100 if (xSpeed < NUMERICAL_EPS) {
2104 std::cout <<
" xSpeedPotential=" << xSpeed <<
"\n";
2111 (xDist == distance[current] && obs[current].type >=
OBSTACLE_END)
2112 || (xDist == distance[other] && obs[other].type >=
OBSTACLE_END)
2113 || (xDist == distance[next] && obs[next].type >=
OBSTACLE_END))
2118 if (myWaitingTime > ((myLane->getEdge().isCrossing()
2120 || (myLane->getEdge().isWalkingArea() && obs[current].type ==
OBSTACLE_VEHICLE
2122 || (sMax == 0 && obs[0].speed * myDir < 0 && myWaitingTime >
jamTimeNarrow)
2133 }
else if (myAmJammed && stripe(myRelY) >= 0 && stripe(myRelY) <= sMax && xDist >=
MIN_STARTUP_DIST) {
2157 if (fabs(yDist) > NUMERICAL_EPS) {
2158 ySpeed = (yDist > 0 ?
2164 && stripe() == stripe(myRelY)
2166 && !(myLane->getEdge().isCrossing() || myLane->getEdge().isWalkingArea())) {
2168 int stepAsideDir = myDir;
2169 if (myLane->getEdge().getLanes().size() > 1 || current > sMax / 2) {
2175 ySpeed = stepAsideDir * vMax;
2181 <<
" ped=" << myPerson->getID()
2182 <<
" edge=" << myStage->getEdge()->getID()
2186 <<
" pvx=" << mySpeed
2187 <<
" cur=" << current
2188 <<
" cho=" << chosen
2192 <<
" dawdle=" << dawdle
2197 <<
" wTime=" << myStage->getWaitingTime(currentTime)
2198 <<
" jammed=" << myAmJammed
2201 for (
int i = 0; i < stripes; ++i) {
2203 std::cout <<
" util=" << utility[i] <<
" dist=" << distance[i] <<
" o=" << o.
description;
2205 std::cout <<
" xF=" << o.
xFwd <<
" xB=" << o.
xBack <<
" v=" << o.
speed;
2208 std::cout <<
" current";
2210 if (i == other && i != current) {
2211 std::cout <<
" other";
2214 std::cout <<
" chosen";
2217 std::cout <<
" next";
2225 mySpeedLat = ySpeed;
2228 myWaitingToEnter =
false;
2233 myAngle = std::numeric_limits<double>::max();
2239 return MAX2(0.,
MIN2(1., myPerson->getVehicleType().getImpatience()
2259 return myRemoteXYPos;
2261 if (myLane ==
nullptr) {
2265 const double lateral_offset = myRelY + (
stripeWidth - myLane->getWidth()) * 0.5;
2266 if (myWalkingAreaPath ==
nullptr) {
2281 return myWalkingAreaPath->shape.positionAtOffset(myRelX, lateral_offset);
2283 const double rotationOffset = myDir ==
FORWARD ? 0 :
DEG2RAD(180);
2284 return myWalkingAreaPath->shape.sidePositionAtAngle(myRelX, lateral_offset, myWalkingAreaPath->angleOverride + rotationOffset);
2292 if (myAngle != std::numeric_limits<double>::max()) {
2295 if (myLane ==
nullptr) {
2299 if (myWalkingAreaPath !=
nullptr && myWalkingAreaPath->angleOverride !=
INVALID_DOUBLE) {
2300 return myWalkingAreaPath->angleOverride;
2302 const PositionVector& shp = myWalkingAreaPath ==
nullptr ? myLane->getShape() : myWalkingAreaPath->shape;
2303 double geomX = myWalkingAreaPath ==
nullptr ? myLane->interpolateLanePosToGeometryPos(myRelX) : myRelX;
2306 angle += atan2(mySpeedLat,
MAX2(mySpeed, NUMERICAL_EPS));
2308 angle -= atan2(mySpeedLat,
MAX2(mySpeed, NUMERICAL_EPS));
2320 return myWaitingTime;
2332 return myNLI.lane ==
nullptr ? nullptr : &myNLI.lane->getEdge();
2339 int routeOffset = 0;
2340 bool laneOnRoute =
false;
2342 for (
const MSEdge* edge : myStage->getRoute()) {
2345 || edge->getFromJunction() == laneOnJunction) {
2352 throw ProcessError(
"Lane '" + lane->
getID() +
"' is not on the route of person '" + getID() +
"'.");
2355 if (lane->
getEdge().
isWalkingArea() && (myWalkingAreaPath ==
nullptr || myWalkingAreaPath->lane != lane)) {
2357 const MSEdge* prevEdge = myStage->getRoute()[routeOffset];
2358 const MSEdge* nextEdge = routeOffset + 1 < (int)myStage->getRoute().size() ? myStage->getRoute()[routeOffset + 1] :
nullptr;
2360 const double maxPos = guessed->
shape.
length() - NUMERICAL_EPS;
2361 if (lanePos > maxPos + POSITION_EPS || lanePos < -POSITION_EPS) {
2363 +
"' (fromLane='" + guessed->
from->
getID()
2364 +
"' toLane='" + guessed->
to->
getID() +
"') for person '" + getID() +
"' time=" +
time2string(t) +
".");
2367 lanePos =
MIN2(maxPos,
MAX2(NUMERICAL_EPS, lanePos));
2371 moveToXY(p, pos, lane, lanePos, lanePosLat, angle, routeOffset, newEdges, t);
2377 double lanePosLat,
double angle,
int routeOffset,
2380 assert(p == myPerson);
2381 assert(pm !=
nullptr);
2384 const double oldX = myRelX -
SPEED2DIST(mySpeed * myDir);
2385 const double tmp = myRelX;
2387 Position oldPos = getPosition(*myStage, t);
2393#ifdef DEBUG_MOVETOXY
2397 <<
" lane=" << lane->
getID()
2398 <<
" lanePos=" << lanePos
2399 <<
" lanePosLat=" << lanePosLat
2400 <<
" angle=" << angle
2401 <<
" routeOffset=" << routeOffset
2404 <<
" path=" << (myWalkingAreaPath ==
nullptr ?
"null" : (myWalkingAreaPath->from->getID() +
"->" + myWalkingAreaPath->to->getID())) <<
"\n";
2407 if (lane != myLane && myLane !=
nullptr) {
2411 if (lane !=
nullptr &&
2414 const MSEdge* old = myStage->getEdge();
2415 const MSLane* oldLane = myLane;
2416 if (lane != myLane) {
2420 if (edges.empty()) {
2422 myStage->setRouteIndex(myPerson, routeOffset);
2424 myStage->replaceRoute(myPerson, edges, routeOffset);
2427 myStage->moveToNextEdge(myPerson, t, myDir, &lane->
getEdge());
2433 if (myWalkingAreaPath ==
nullptr || myWalkingAreaPath->lane != lane) {
2435 myWalkingAreaPath =
guessPath(&lane->
getEdge(), old, myStage->getNextRouteEdge());
2436#ifdef DEBUG_MOVETOXY
2438 <<
" path=" << myWalkingAreaPath->from->getID() <<
"->" << myWalkingAreaPath->to->getID() <<
"\n";
2443 const Position relPos = myWalkingAreaPath->shape.transformToVectorCoordinates(pos);
2446 +
"' (fromLane='" + myWalkingAreaPath->from->getID()
2447 +
"' toLane='" + myWalkingAreaPath->to->getID() +
"') for person '" + getID() +
"' time=" +
time2string(t) +
".");
2448 myRemoteXYPos = pos;
2450 myRelX = relPos.
x();
2451 myRelY = lateral_offset + relPos.
y();
2454 myWalkingAreaPath =
nullptr;
2456 myRelY = lateral_offset - lanePosLat;
2460 if (myStage->getNextRouteEdge() !=
nullptr) {
2461 if (myStage->getEdge()->getToJunction() == myStage->getNextRouteEdge()->getFromJunction() ||
2462 myStage->getEdge()->getToJunction() == myStage->getNextRouteEdge()->getToJunction()) {
2469 if (angleDiff <= 90) {
2480 if (oldLane ==
nullptr || &oldLane->
getEdge() != &myLane->getEdge()) {
2481 const MSLane* sidewalk = getSidewalk<MSEdge, MSLane>(&myLane->getEdge(), p->
getVClass());
2484 myNLI =
getNextLane(*
this, sidewalk ==
nullptr ? myLane : sidewalk,
nullptr);
2485 myStage->activateEntryReminders(myPerson);
2486#ifdef DEBUG_MOVETOXY
2487 std::cout <<
" myNLI=" <<
Named::getIDSecure(myNLI.lane) <<
" link=" << (myNLI.link ==
nullptr ?
"NULL" : myNLI.link->getDescription()) <<
" dir=" << myNLI.dir <<
"\n";
2490#ifdef DEBUG_MOVETOXY
2491 std::cout <<
" newRelPos=" <<
Position(myRelX, myRelY) <<
" edge=" << myPerson->getEdge()->getID() <<
" newPos=" << myPerson->getPosition()
2492 <<
" oldAngle=" << oldAngle <<
" angleDiff=" << angleDiff <<
" newDir=" << myDir <<
"\n";
2494 if (oldLane == myLane) {
2502 myRemoteXYPos = pos;
2521 if (myWalkingAreaPath !=
nullptr) {
2522 return myWalkingAreaPath->length;
2531 const double maxX = getMaxX(includeMinGap);
2532 const double minX = getMinX(includeMinGap);
2536 if ((obs.
xFwd >= maxX && obs.
xBack <= maxX) || (obs.
xFwd <= maxX && obs.
xFwd >= minX)) {
2550 for (
int i = 0; i < (int)into.size(); ++i) {
2552 std::cout <<
" i=" << i <<
" maxX=" << getMaxX(
true) <<
" minX=" << getMinX(
true)
2553 <<
" into=" << into[i].description <<
" iDist=" << distanceTo(into[i], into[i].type ==
OBSTACLE_PED)
2554 <<
" obs2=" << obs2[i].description <<
" oDist=" << distanceTo(obs2[i], obs2[i].type ==
OBSTACLE_PED) <<
"\n";
2556 const double dO = distanceTo(obs2[i], obs2[i].type ==
OBSTACLE_PED);
2557 const double dI = distanceTo(into[i], into[i].type ==
OBSTACLE_PED);
2572 for (
int i = 0; i < (int)into.size(); ++i) {
2573 int i2 = i + offset;
2574 if (i2 >= 0 && i2 < (
int)obs2.size()) {
2576 if (obs2[i2].xBack < into[i].xBack) {
2580 if (obs2[i2].xFwd > into[i].xFwd) {
2593 if (ignoreRedTime >= 0) {
2596 std::cout <<
SIMTIME <<
" ignoreRedTime=" << ignoreRedTime <<
" redDuration=" << redDuration <<
"\n";
2598 return ignoreRedTime > redDuration;
2609 return myPerson->getID();
2614 return myPerson->getVehicleType().getWidth();
2620 return myPerson->hasInfluencer() && myPerson->getInfluencer().isRemoteControlled();
2628 myVehicle(veh), myXWidth(xWidth), myYWidth(yWidth) {
2632 myRelX = relX + xWidth / 2;
2638 return myVehicle->getID();
2648 return myXWidth > 0 ? myRelX - myXWidth : myRelX;
2653 return myXWidth > 0 ? myRelX : myRelX - myXWidth;
2662 std::set<MSPerson*> changedLane;
2663 myModel->moveInDirection(currentTime, changedLane,
FORWARD);
2664 myModel->moveInDirection(currentTime, changedLane,
BACKWARD);
2667 for (ActiveLanes::const_iterator it_lane = myModel->getActiveLanes().begin(); it_lane != myModel->getActiveLanes().end(); ++it_lane) {
2668 const MSLane* lane = it_lane->first;
2670 if (pedestrians.size() == 0) {
2675 for (
int ii = 0; ii < (int)pedestrians.size(); ++ii) {
2676 const PState& p = *pedestrians[ii];
std::vector< const MSEdge * > ConstMSEdgeVector
std::vector< MSEdge * > MSEdgeVector
std::pair< const MSPerson *, double > PersonDist
#define WRITE_WARNINGF(...)
#define WRITE_WARNING(msg)
std::string time2string(SUMOTime t)
convert SUMOTime to string
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
@ SVC_PEDESTRIAN
pedestrian
const std::string DEFAULT_PEDTYPE_ID
@ SUMO_ATTR_JM_DRIVE_AFTER_RED_TIME
bool gDebugFlag1
global utility flags for debugging
const double INVALID_DOUBLE
invalid double
#define UNUSED_PARAMETER(x)
const double SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
A class that stores a 2D geometrical boundary.
Position getCenter() const
Returns the center of the boundary.
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
double ymin() const
Returns minimum y-coordinate.
double getWidth() const
Returns the width of the boudary (x-axis)
void growWidth(double by)
Increases the width of the boundary (x-axis)
double ymax() const
Returns maximum y-coordinate.
static double naviDegree(const double angle)
static double fromNaviDegree(const double angle)
static double getMinAngleDiff(double angle1, double angle2)
Returns the minimum distance (clockwise/counter-clockwise) between both angles.
const MSVehicleType & getVehicleType() const
Returns the vehicle's type definition.
double brakeGap(const double speed) const
Returns the distance the vehicle needs to halt including driver's reaction time tau (i....
double getMaxDecel() const
Get the vehicle type's maximal comfortable deceleration [m/s^2].
A road/street connecting two junctions.
static const MSEdgeVector & getAllEdges()
Returns all edges with a numerical id.
bool isCrossing() const
return whether this edge is a pedestrian crossing
bool isWalkingArea() const
return whether this edge is walking area
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
bool isNormal() const
return whether this edge is an internal edge
const MSJunction * getToJunction() const
double getLength() const
return the length of the edge
const MSJunction * getFromJunction() const
bool isInternal() const
return whether this edge is an internal edge
const MSEdgeVector & getPredecessors() const
const MSEdgeVector & getSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges, restricted by vClass.
virtual void addEvent(Command *operation, SUMOTime execTimeStep=-1)
Adds an Event.
static bool gCheck4Accidents
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
The base class for an intersection.
AnyVehicleIterator is a structure, which manages the iteration through all vehicles on the lane,...
Representation of a lane in the micro simulation.
AnyVehicleIterator anyVehiclesEnd() const
end iterator for iterating over all vehicles touching this lane in downstream direction
int getVehicleNumberWithPartials() const
Returns the number of vehicles on this lane (including partial occupators)
const MSLink * getLinkTo(const MSLane *const) const
returns the link to the given lane or nullptr, if it is not connected
SVCPermissions getPermissions() const
Returns the vehicle class permissions for this lane.
const std::vector< IncomingLaneInfo > & getIncomingLanes() const
double getLength() const
Returns the lane's length.
const MSLane * getInternalFollowingLane(const MSLane *const) const
returns the internal lane leading to the given lane or nullptr, if there is none
MSLane * getCanonicalSuccessorLane() const
MSLane * getLogicalPredecessorLane() const
get the most likely precedecessor lane (sorted using by_connections_to_sorter). The result is cached ...
AnyVehicleIterator anyVehiclesUpstreamEnd() const
end iterator for iterating over all vehicles touching this lane in upstream direction
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
AnyVehicleIterator anyVehiclesUpstreamBegin() const
begin iterator for iterating over all vehicles touching this lane in upstream direction
AnyVehicleIterator anyVehiclesBegin() const
begin iterator for iterating over all vehicles touching this lane in downstream direction
MSLane * getBidiLane() const
retrieve bidirectional lane or nullptr
virtual const PositionVector & getShape(bool) const
MSEdge & getEdge() const
Returns the lane's edge.
double getWidth() const
Returns the lane's width.
const std::vector< MSLink * > & getLinkCont() const
returns the container with all links !!!
const Position geometryPositionAtOffset(double offset, double lateralOffset=0) const
SUMOTime getLastStateChange() const
MSLane * getLane() const
Returns the connected lane.
bool havePriority() const
Returns whether this link is a major link.
const LinkLeaders getLeaderInfo(const MSVehicle *ego, double dist, std::vector< const MSPerson * > *collectBlockers=0, bool isShadowLink=false) const
Returns all potential link leaders (vehicles on foeLanes) Valid during the planMove() phase.
static bool ignoreFoe(const SUMOTrafficObject *ego, const SUMOTrafficObject *foe)
std::vector< LinkLeader > LinkLeaders
MSLane * getViaLaneOrLane() const
return the via lane if it exists and the lane otherwise
bool opened(SUMOTime arrivalTime, double arrivalSpeed, double leaveSpeed, double vehicleLength, double impatience, double decel, SUMOTime waitingTime, double posLat=0, BlockingFoes *collectFoes=nullptr, bool ignoreRed=false, const SUMOTrafficObject *ego=nullptr) const
Returns the information whether the link may be passed.
const MSTrafficLightLogic * getTLLogic() const
Returns the TLS index.
bool haveRed() const
Returns whether this link is blocked by a red (or redyellow) traffic light.
The simulated network and simulation perfomer.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
MSEventControl * getBeginOfTimestepEvents()
Returns the event control for events executed at the begin of a time step.
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
bool hasPedestrianNetwork() const
return whether the network contains walkingareas and crossings
MSPedestrianRouter & getPedestrianRouter(const int rngIndex, const MSEdgeVector &prohibited=MSEdgeVector()) const
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
virtual MSTransportableControl & getPersonControl()
Returns the person control.
bool hasInternalLinks() const
return whether the network contains internal links
SUMOTime execute(SUMOTime currentTime)
Executes the command.
Container for pedestrian state and individual position update function.
virtual double getMaxX(const bool includeMinGap=true) const
return the maximum position on the lane
bool isJammed() const
whether the transportable is jammed
bool myAmJammed
whether the person is jammed
Position myRemoteXYPos
remote-controlled position
bool myWaitingToEnter
whether the pedestrian is waiting to start its walk
const WalkingAreaPath * myWalkingAreaPath
the current walkingAreaPath or 0
SUMOTime getWaitingTime(const MSStageMoving &stage, SUMOTime now) const
return the time the transportable spent standing
PState()
constructor for PStateVehicle
double myRelX
the advancement along the current lane
double distToLaneEnd() const
the absolute distance to the end of the lane in walking direction (or to the arrivalPos)
int myDir
the walking direction on the current lane (1 forward, -1 backward)
double myRelY
the orthogonal shift on the current lane
void mergeObstacles(Obstacles &into, const Obstacles &obs2)
replace obstacles in the first vector with obstacles from the second if they are closer to me
bool isRemoteControlled() const
whether the person is currently being controlled via TraCI
const MSEdge * getNextEdge(const MSStageMoving &stage) const
return the list of internal edges if the transportable is on an intersection
void walk(const Obstacles &obs, SUMOTime currentTime)
perform position update
virtual double getWidth() const
return the person width
double mySpeed
the current walking speed
void saveState(std::ostringstream &out)
Saves the current state into the given stream.
int getDirection(const MSStageMoving &stage, SUMOTime now) const
return the walking direction (FORWARD, BACKWARD)
bool ignoreRed(const MSLink *link) const
whether the pedestrian may ignore a red light
virtual double getMinX(const bool includeMinGap=true) const
return the minimum position on the lane
bool moveToNextLane(SUMOTime currentTime)
return whether this pedestrian has passed the end of the current lane and update myRelX if so
double mySpeedLat
the current lateral walking speed
double getMinGap() const
return the minimum gap of the pedestrian
void moveToXY(MSPerson *p, Position pos, MSLane *lane, double lanePos, double lanePosLat, double angle, int routeOffset, const ConstMSEdgeVector &edges, SUMOTime t)
try to move transportable to the given position
void moveTo(MSPerson *p, MSLane *lane, double lanePos, double lanePosLat, SUMOTime t)
try to move transportable to the given position
double getSpeed(const MSStageMoving &stage) const
return the current speed of the transportable
Position getPosition(const MSStageMoving &stage, SUMOTime now) const
return the network coordinate of the transportable
NextLaneInfo myNLI
information about the upcoming lane
const MSLane * myLane
the current lane of this pedestrian
double getAngle(const MSStageMoving &stage, SUMOTime now) const
return the direction in which the transportable faces in degrees
virtual const std::string & getID() const
return the person id
double getImpatience(SUMOTime now) const
returns the impatience
SUMOTime myWaitingTime
the consecutive time spent at speed 0
double distanceTo(const Obstacle &obs, const bool includeMinGap=true) const
const MSLane * getLane() const
whether the transportable is jammed
double getEdgePos(const MSStageMoving &stage, SUMOTime now) const
abstract methods inherited from PedestrianState
double getLength() const
return the length of the pedestrian
double getPathLength() const
return the total length of the current lane (in particular for on a walkingarea)
double getWidth() const
return the person width
double getMaxX(const bool includeMinGap=true) const
return the maximum position on the lane
double getMinX(const bool includeMinGap=true) const
return the minimum position on the lane
const std::string & getID() const
return the person id
PStateVehicle(const MSVehicle *veh, const MSLane *walkingarea, double relX, double relY, double xWidth, double yWidth)
sorts the persons by position on the lane. If dir is forward, higher x positions come first.
The pedestrian following model.
static const double MIN_STARTUP_DIST
static double RESERVE_FOR_ONCOMING_FACTOR
static MinNextLengths myMinNextLengths
static bool addVehicleFoe(const MSVehicle *veh, const MSLane *walkingarea, const Position &relPos, double xWidth, double yWidth, double lateral_offset, double minY, double maxY, Pedestrians &toDelete, Pedestrians &transformedPeds)
MSTransportableStateAdapter * loadState(MSTransportable *transportable, MSStageMoving *stage, std::istringstream &in)
load the state of the given transportable
static SUMOTime jamTimeCrossing
bool hasPedestrians(const MSLane *lane)
whether the given lane has pedestrians on it
void moveInDirection(SUMOTime currentTime, std::set< MSPerson * > &changedLane, int dir)
move all pedestrians forward and advance to the next lane if applicable
static void transformToCurrentLanePositions(Obstacles &o, int currentDir, int nextDir, double currentLength, double nextLength)
static int myWalkingAreaDetail
static const double LOOKAHEAD_SAMEDIR
static double RESERVE_FOR_ONCOMING_MAX
static double minGapToVehicle
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...
static void initWalkingAreaPaths(const MSNet *net)
std::vector< PState * > Pedestrians
ActiveLanes myActiveLanes
store of all lanes which have pedestrians on them
static const double LOOKAROUND_VEHICLES
static const double SQUEEZE
static SUMOTime jamTimeNarrow
static const WalkingAreaPath * getWalkingAreaPath(const MSEdge *walkingArea, const MSLane *before, const MSLane *after)
void arriveAndAdvance(Pedestrians &pedestrians, SUMOTime currentTime, std::set< MSPerson * > &changedLane, int dir)
handle arrivals and lane advancement
std::map< const MSLane *, double > MinNextLengths
static double RESERVE_FOR_ONCOMING_FACTOR_JUNCTIONS
static int getStripeOffset(int origStripes, int destStripes, bool addRemainder)
bool myAmActive
whether an event for pedestrian processing was added
static const WalkingAreaPath * guessPath(const MSEdge *walkingArea, const MSEdge *before, const MSEdge *after)
static int getReserved(int stripes, double factor)
void moveInDirectionOnLane(Pedestrians &pedestrians, const MSLane *lane, SUMOTime currentTime, std::set< MSPerson * > &changedLane, int dir, bool debug)
move pedestrians forward on one lane
static double stripeWidth
model parameters
static const double MAX_WAIT_TOLERANCE
static Obstacles getVehicleObstacles(const MSLane *lane, int dir, PState *ped=0)
retrieve vehicle obstacles on the given lane
static const double OBSTRUCTED_PENALTY
std::map< const MSLane *, Obstacles, lane_by_numid_sorter > NextLanesObstacles
static const MSLane * getNextWalkingArea(const MSLane *currentLane, const int dir, const MSLink *&link)
return the next walkingArea in the given direction
PersonDist nextBlocking(const MSLane *lane, double minPos, double minRight, double maxLeft, double stopTime=0, bool bidi=false)
returns the next pedestrian beyond minPos that is laterally between minRight and maxLeft or 0
MSTransportableStateAdapter * add(MSTransportable *transportable, MSStageMoving *stage, SUMOTime now)
register the given person as a pedestrian
static const double DIST_OVERLAP
static const WalkingAreaPath * getArbitraryPath(const MSEdge *walkingArea)
return an arbitrary path across the given walkingArea
static const double LATERAL_PENALTY
bool blockedAtDist(const SUMOTrafficObject *ego, const MSLane *lane, double vehSide, double vehWidth, double oncomingGap, std::vector< const MSPerson * > *collectBlockers)
whether a pedestrian is blocking the crossing of lane for the given vehicle bondaries
std::vector< Obstacle > Obstacles
void remove(MSTransportableStateAdapter *state)
remove the specified person from the pedestrian simulation
static const double DIST_BEHIND
bool usingInternalLanes()
whether movements on intersections are modelled /
MSPModel_Striping(const OptionsCont &oc, MSNet *net)
Constructor (it should not be necessary to construct more than one instance)
static bool usingInternalLanesStatic()
static Obstacles getNeighboringObstacles(const Pedestrians &pedestrians, int egoIndex, int stripes)
static Pedestrians noPedestrians
empty pedestrian vector
static bool myLegacyPosLat
static void addCloserObstacle(Obstacles &obs, double x, int stripe, int numStripes, const std::string &id, double width, int dir, ObstacleType type)
Pedestrians & getPedestrians(const MSLane *lane)
retrieves the pedestian vector for the given lane (may be empty)
static int numStripes(const MSLane *lane)
return the maximum number of pedestrians walking side by side
static const double OBSTRUCTION_THRESHOLD
static bool addCrossingVehs(const MSLane *crossing, int stripes, double lateral_offset, int dir, Obstacles &crossingVehs, bool prio)
add vehicles driving across
static int connectedDirection(const MSLane *from, const MSLane *to)
returns the direction in which these lanes are connectioned or 0 if they are not
static void DEBUG_PRINT(const Obstacles &obs)
static const double LATERAL_SPEED_FACTOR
static const double INAPPROPRIATE_PENALTY
void clearState()
Resets pedestrians when quick-loading state.
static const double ONCOMING_CONFLICT_PENALTY
int myNumActivePedestrians
the total number of active pedestrians
static const double LOOKAHEAD_ONCOMING
static std::map< const MSEdge *, std::vector< const MSLane * > > myWalkingAreaFoes
const Obstacles & getNextLaneObstacles(NextLanesObstacles &nextLanesObs, const MSLane *lane, const MSLane *nextLane, int stripes, int nextDir, double currentLength, int currentDir)
static const double DIST_FAR_AWAY
std::map< std::pair< const MSLane *, const MSLane * >, const WalkingAreaPath > WalkingAreaPaths
static WalkingAreaPaths myWalkingAreaPaths
store for walkinArea elements
static const int BACKWARD
static int canTraverse(int dir, const ConstMSEdgeVector &route)
static const double RANDOM_POS_LAT
magic value to encode randomized lateral offset for persons when starting a walk
static const double SIDEWALK_OFFSET
the offset for computing person positions when walking on edges without a sidewalk
static const int UNDEFINED_DIRECTION
static const double UNSPECIFIED_POS_LAT
the default lateral offset for persons when starting a walk
static const double SAFETY_GAP
const MSEdge * getDestination() const
returns the destination edge
virtual double getArrivalPos() const
MSStoppingPlace * getDestinationStop() const
returns the destination stop (if any)
Position getLanePosition(const MSLane *lane, double at, double offset) const
get position on lane at length at with orthogonal offset
virtual const MSEdge * getNextRouteEdge() const =0
static const MSLane * checkDepartLane(const MSEdge *edge, SUMOVehicleClass svc, int laneIndex, const std::string &id)
interpret custom depart lane
virtual bool moveToNextEdge(MSTransportable *transportable, SUMOTime currentTime, int prevDir, MSEdge *nextInternal=0)=0
move forward and return whether the transportable arrived
const std::vector< const MSEdge * > & getRoute() const
int getDepartLane() const
virtual double getMaxSpeed(const MSTransportable *const transportable=nullptr) const =0
the maximum speed of the transportable
int getNumWaitingPersons() const
get number of persons waiting at this stop
int getWaitingCapacity() const
get number of persons that can wait at this stop
MSPModel * getMovementModel()
Returns the default movement model for this kind of transportables.
void registerJammed()
register a jammed transportable
SUMOVehicleClass getVClass() const
Returns the object's access class.
bool isPerson() const
Whether it is a person.
Position getPosition(const double) const
Return current position (x/y, cartesian)
const MSVehicleType & getVehicleType() const
Returns the object's "vehicle" type.
MSStageType getCurrentStageType() const
the current stage type of the transportable
const MSEdge * getEdge() const
Returns the current edge.
double getMaxSpeed() const
Returns the maximum speed (the minimum of desired and physical maximum speed)
abstract base class for managing callbacks to retrieve various state information from the model
MSVehicleType * getVType(const std::string &id=DEFAULT_VTYPE_ID, SumoRNG *rng=nullptr, bool readOnly=false)
Returns the named vehicle type or a sample from the named distribution.
Representation of a vehicle in the micro simulation.
Position getPosition(const double offset=0) const
Return current position (x/y, cartesian)
double getBackPositionOnLane(const MSLane *lane) const
Get the vehicle's position relative to the given lane.
const MSLane * getLane() const
Returns the lane the vehicle is on.
double getLateralPositionOnLane() const
Get the vehicle's lateral position on the lane.
const Position getBackPosition() const
double getSpeed() const
Returns the vehicle's current speed.
const MSCFModel & getCarFollowModel() const
Returns the vehicle's car following model definition.
The car-following model and parameter.
double getWidth() const
Get the width which vehicles of this class shall have when being drawn.
double getLength() const
Get vehicle's length [m].
static std::string getIDSecure(const T *obj, const std::string &fallBack="NULL")
get an identifier for Named-like object which may be Null
const std::string & getID() const
Returns the id.
A storage for options typed value containers)
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
int getInt(const std::string &name) const
Returns the int-value of the named option (only for Option_Integer)
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
static OptionsCont & getOptions()
Retrieves the options.
double compute(const E *from, const E *to, double departPos, double arrivalPos, double speed, SUMOTime msTime, const N *onlyNode, std::vector< const E * > &into, bool allEdges=false)
Builds the route between the given edges using the minimum effort at the given time The definition of...
A point in 2D or 3D with translation and scaling methods.
static const Position INVALID
used to indicate that a position is valid
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
double x() const
Returns the x-position.
double angleTo2D(const Position &other) const
returns the angle in the plane of the vector pointing from here to the other position
double y() const
Returns the y-position.
double length() const
Returns the length.
double rotationAtOffset(double pos) const
Returns the rotation at the given length.
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
void move2side(double amount, double maxExtension=100)
move position vector to side using certain ammount
double angleAt2D(int pos) const
get angle in certain position of position vector
void extrapolate(const double val, const bool onlyFirst=false, const bool onlyLast=false)
extrapolate position vector
PositionVector bezier(int numPoints)
return a bezier interpolation
void push_back_noDoublePos(const Position &p)
insert in back a non double position
PositionVector reverse() const
reverse position vector
Position transformToVectorCoordinates(const Position &p, bool extend=false) const
return position p within the length-wise coordinate system defined by this position vector....
static double rand(SumoRNG *rng=nullptr)
Returns a random real number in [0, 1)
Representation of a vehicle, person, or container.
information regarding surround Pedestrians (and potentially other things)
double speed
speed relative to lane direction (positive means in the same direction)
double xFwd
maximal position on the current lane in forward direction
Obstacle(int dir, double dist=DIST_FAR_AWAY)
create No-Obstacle
bool closer(const Obstacle &o, int dir)
std::string description
the id / description of the obstacle
ObstacleType type
whether this obstacle denotes a border or a pedestrian
double xBack
maximal position on the current lane in backward direction
const PositionVector shape