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());
384 const MSLane* walkingArea = getSidewalk<MSEdge, MSLane>(edge);
388 std::vector<const MSLane*> lanes;
390 if (!in->isTazConnector()) {
391 lanes.push_back(getSidewalk<MSEdge, MSLane>(in));
392 if (lanes.back() ==
nullptr) {
393 throw ProcessError(
"Invalid connection from edge '" + in->getID() +
"' to walkingarea edge '" + edge->
getID() +
"'");
398 if (!out->isTazConnector()) {
399 lanes.push_back(getSidewalk<MSEdge, MSLane>(out));
400 if (lanes.back() ==
nullptr) {
401 throw ProcessError(
"Invalid connection from walkingarea edge '" + edge->
getID() +
"' to edge '" + out->getID() +
"'");
406 for (
int j = 0; j < (int)lanes.size(); ++j) {
407 for (
int k = 0; k < (int)lanes.size(); ++k) {
410 const MSLane*
const from = lanes[j];
411 const MSLane*
const to = lanes[k];
417 const double maxExtent = fromPos.
distanceTo2D(toPos) / 4;
418 const double extrapolateBy =
MIN2(maxExtent, walkingArea->
getWidth() / 2);
420 shape.push_back(fromPos);
421 if (extrapolateBy > POSITION_EPS) {
430 if (shape.size() < 2) {
434 assert(shape.size() == 2);
439 if (shape.size() >= 4 && shape.
length() < walkingArea->
getWidth()) {
440 const double aStart = shape.
angleAt2D(0);
441 const double aEnd = shape.
angleAt2D((
int)shape.size() - 2);
442 if (fabs(aStart - aEnd) <
DEG2RAD(10)) {
443 angleOverride = (aStart + aEnd) / 2;
451 into.insert(std::make_pair(std::make_pair(from, to), wap));
463 std::vector<const MSLane*> lanes;
465 lanes.push_back(getSidewalk<MSEdge, MSLane>(pred));
468 lanes.push_back(getSidewalk<MSEdge, MSLane>(succ));
470 if (lanes.size() < 1) {
471 throw ProcessError(
TLF(
"Invalid walkingarea '%' does not allow continuation.", walkingArea->
getID()));
479 const MSLane* swBefore = getSidewalk<MSEdge, MSLane>(before);
480 const MSLane* swAfter = getSidewalk<MSEdge, MSLane>(after);
483 return &pathIt->second;
487 bool useBefore = swBefore !=
nullptr && std::find(preds.begin(), preds.end(), before) != preds.end();
488 bool useAfter = swAfter !=
nullptr && std::find(succs.begin(), succs.end(), after) != succs.end();
492 }
else if (succs.size() > 0) {
494 return getWalkingAreaPath(walkingArea, swBefore, getSidewalk<MSEdge, MSLane>(succs.front()));
496 }
else if (useAfter && preds.size() > 0) {
498 return getWalkingAreaPath(walkingArea, getSidewalk<MSEdge, MSLane>(preds.front()), swAfter);
509 return &pathIt->second;
513 if (preds.size() > 0) {
515 const auto pathIt2 =
myWalkingAreaPaths.find(std::make_pair(getSidewalk<MSEdge, MSLane>(pred), after));
517 return &pathIt2->second;
533 const MSLane* nextLane = nextRouteLane;
534 const MSLink* link =
nullptr;
540 if (nextRouteLane ==
nullptr && nextRouteEdge !=
nullptr) {
541 std::string error =
"Person '" + ped.
myPerson->
getID() +
"' could not find sidewalk on edge '" + nextRouteEdge->
getID() +
"', time="
545 nextRouteLane = nextRouteEdge->
getLanes().front();
551 if (nextRouteLane !=
nullptr) {
556 nextLane = currentLane->
getLinkCont()[0]->getViaLaneOrLane();
561 std::cout <<
" internal\n";
566 nextLane = currentLane->
getLinkCont()[0]->getLane();
571 std::cout <<
" crossing\n";
578 const double arrivalPos = (nextRouteEdge == ped.
myStage->
getRoute().back()
582 if (prevLane !=
nullptr) {
583 prohibited.push_back(&prevLane->
getEdge());
588 <<
" nre=" << nextRouteEdge->
getID()
589 <<
" nreDir=" << nextRouteEdgeDir
590 <<
" aPos=" << arrivalPos
591 <<
" crossingRoute=" <<
toString(crossingRoute)
594 if (crossingRoute.size() > 1) {
595 const MSEdge* nextEdge = crossingRoute[1];
596 nextLane = getSidewalk<MSEdge, MSLane>(crossingRoute[1], ped.
myPerson->
getVClass());
598 assert(nextLane != prevLane);
601 std::cout <<
" nextDir=" << nextDir <<
"\n";
610 link = oppositeWalkingArea->
getLinkTo(nextLane);
613 assert(link !=
nullptr);
617 <<
" no route from '" << (currentEdge ==
nullptr ?
"NULL" : currentEdge->
getID())
618 <<
"' to '" << (nextRouteEdge ==
nullptr ?
"NULL" : nextRouteEdge->
getID())
623 link = prevLane->
getLinkTo(nextRouteLane);
625 link = nextRouteLane->
getLinkTo(prevLane);
627 if (link !=
nullptr) {
632 +
"' from walkingArea '" + currentEdge->
getID()
633 +
"' to edge '" + nextRouteEdge->
getID() +
"', time=" +
636 nextLane = nextRouteLane;
639 }
else if (currentEdge == nextRouteEdge) {
641 nextDir = -ped.
myDir;
646 if (nextLane !=
nullptr) {
649 std::cout <<
" next walkingArea " << (nextDir ==
FORWARD ?
"forward" :
"backward") <<
"\n";
657 link = currentLane->
getLinkTo(nextRouteLane);
658 if (link !=
nullptr) {
660 std::cout <<
" direct forward\n";
665 link = nextRouteLane->
getLinkTo(currentLane);
666 if (link !=
nullptr) {
668 std::cout <<
" direct backward\n";
671 if (nextLane !=
nullptr) {
673 while (nextLane->
getLinkCont()[0]->getViaLaneOrLane()->isInternal()) {
674 nextLane = nextLane->
getLinkCont()[0]->getViaLaneOrLane();
680 if (nextLane ==
nullptr) {
682 nextLane = nextRouteLane;
684 std::cout <<
SIMTIME <<
" no next lane found for " << currentLane->
getID() <<
" dir=" << ped.
myDir <<
"\n";
688 +
"' from edge '" + currentEdge->
getID()
689 +
"' to edge '" + nextRouteEdge->
getID() +
"', time=" +
692 }
else if (nextLane->
getLength() <= POSITION_EPS) {
704 nextLane = nextRouteLane;
713 <<
" l=" << currentLane->
getID()
714 <<
" nl=" << (nextLane ==
nullptr ?
"NULL" : nextLane->
getID())
715 <<
" nrl=" << (nextRouteLane ==
nullptr ?
"NULL" : nextRouteLane->
getID())
718 <<
" pedDir=" << ped.
myDir
721 assert(nextLane != 0 || nextRouteLane == 0);
730 if (l->getLane()->getEdge().isWalkingArea()) {
736 const std::vector<MSLane::IncomingLaneInfo>& laneInfos = currentLane->
getIncomingLanes();
737 for (std::vector<MSLane::IncomingLaneInfo>::const_iterator it = laneInfos.begin(); it != laneInfos.end(); ++it) {
738 if ((*it).lane->getEdge().isWalkingArea()) {
739 link = (*it).viaLink;
750 const PState& ego = *pedestrians[egoIndex];
751 const int egoStripe = ego.
stripe();
753 std::vector<bool> haveBlocker(stripes,
false);
754 for (
int index = egoIndex + 1; index < (int)pedestrians.size(); index++) {
755 const PState& p = *pedestrians[index];
757 std::cout <<
SIMTIME <<
" ped=" << ego.
getID() <<
" cur=" << egoStripe <<
" checking neighbor " << p.
getID()
763 std::cout <<
" dist=" << ego.
distanceTo(o) << std::endl;
771 haveBlocker[p.
stripe()] =
true;
782 if (!haveBlocker[p.
stripe()]) {
801 int offset = (destStripes - origStripes) / 2;
803 offset += (destStripes - origStripes) % 2;
811 MSLane* lane,
const MSLane* nextLane,
int stripes,
int nextDir,
812 double currentLength,
int currentDir) {
813 if (nextLanesObs.count(nextLane) == 0) {
820 const int offset =
getStripeOffset(nextStripes, stripes, currentDir != nextDir && nextStripes > stripes);
831 if (nextStripes < stripes) {
833 for (
int ii = 0; ii < stripes; ++ii) {
834 if (ii < offset || ii >= nextStripes + offset) {
845 if ((stripes - nextStripes) % 2 != 0) {
848 nextDir = currentDir;
850 for (
int ii = 0; ii < (int)pedestrians.size(); ++ii) {
851 PState& p = *pedestrians[ii];
856 const double newY = relPos.
y() + lateral_offset;
867 sort(pedestrians.begin(), pedestrians.end(),
by_xpos_sorter(nextDir));
868 for (
int ii = 0; ii < (int)pedestrians.size(); ++ii) {
869 const PState& p = *pedestrians[ii];
875 if (nextDir != currentDir) {
880 const int stripe = p.
stripe(newY);
881 if (stripe >= 0 && stripe < stripes) {
885 if (otherStripe >= 0 && otherStripe < stripes) {
886 obs[otherStripe] = pObs;
901 nextLanesObs[nextLane] = obs;
903 return nextLanesObs[nextLane];
908 for (
int ii = 0; ii < (int)obs.size(); ++ii) {
912 o.
xFwd += currentLength;
913 o.
xBack += currentLength;
915 const double tmp = o.
xFwd;
916 o.
xFwd = currentLength + nextLength - o.
xBack;
917 o.
xBack = currentLength + nextLength - tmp;
921 const double tmp = o.
xFwd;
925 o.
xFwd -= nextLength;
926 o.
xBack -= nextLength;
936 if ((dir ==
FORWARD && x - width / 2. < obs[stripe].xBack) || (dir ==
BACKWARD && x + width / 2. > obs[stripe].xFwd)) {
937 obs[stripe] =
Obstacle(x, 0, type,
id, width);
945 const MSLane* lane = it_lane->first;
947 if (pedestrians.size() == 0) {
953 const double minY =
stripeWidth * - 0.5 + NUMERICAL_EPS;
958 std::set<const WalkingAreaPath*, walkingarea_path_sorter> paths;
959 for (Pedestrians::iterator it = pedestrians.begin(); it != pedestrians.end(); ++it) {
962 if (p->
myDir == dir) {
966 std::cout <<
SIMTIME <<
" debugging WalkingAreaPath from=" << debugPath->
from->
getID() <<
" to=" << debugPath->to->getID() <<
" minY=" << minY <<
" maxY=" << maxY <<
" latOffset=" << lateral_offset <<
"\n";
971 for (std::set<const WalkingAreaPath*, walkingarea_path_sorter>::iterator it = paths.begin(); it != paths.end(); ++it) {
975 transformedPeds.reserve(pedestrians.size());
976 for (Pedestrians::iterator it_p = pedestrians.begin(); it_p != pedestrians.end(); ++it_p) {
979 transformedPeds.push_back(p);
980 if (path == debugPath) std::cout <<
" ped=" << p->
myPerson->
getID() <<
" relX=" << p->
myRelX <<
" relY=" << p->
myRelY <<
" (untransformed), vecCoord="
985 transformedPeds.push_back(p);
986 if (path == debugPath) std::cout <<
" ped=" << p->
myPerson->
getID() <<
" relX=" << p->
myRelX <<
" relY=" << p->
myRelY <<
" (untransformed), vecCoord="
996 toDelete.push_back(tp);
997 transformedPeds.push_back(tp);
998 if (path == debugPath) std::cout <<
" ped=" << p->
myPerson->
getID() <<
" relX=" << p->
myRelX <<
" relY=" << p->
myRelY <<
" (semi-transformed), vecCoord="
1003 const double newY = relPos.
y() + lateral_offset;
1012 toDelete.push_back(tp);
1013 transformedPeds.push_back(tp);
1014 if (path == debugPath) {
1015 std::cout <<
" ped=" << p->
myPerson->
getID() <<
" relX=" << relPos.
x() <<
" relY=" << newY <<
" (transformed), vecCoord=" << relPos <<
"\n";
1018 if (path == debugPath) {
1019 std::cout <<
" ped=" << p->
myPerson->
getID() <<
" relX=" << relPos.
x() <<
" relY=" << newY <<
" (invalid), vecCoord=" << relPos <<
"\n";
1029 for (
const MSLane* foeLane : itFoe->second) {
1030 for (
auto itVeh = foeLane->anyVehiclesBegin(); itVeh != foeLane->anyVehiclesEnd(); ++itVeh) {
1037 relCenter.push_back(relFront);
1038 relCenter.push_back(relBack);
1040 relCorners.
add(relCenter[0]);
1041 relCorners.
add(relCenter[1]);
1043 relCorners.
add(relCenter[0]);
1044 relCorners.
add(relCenter[1]);
1048 const double xWidth = relCorners.
getWidth();
1049 const double vehYmin =
MAX2(minY - lateral_offset, relCorners.
ymin());
1050 const double vehYmax =
MIN2(maxY - lateral_offset, relCorners.
ymax());
1051 const double xCenter = relCorners.
getCenter().
x();
1052 Position yMinPos(xCenter, vehYmin);
1053 Position yMaxPos(xCenter, vehYmax);
1054 const bool addFront =
addVehicleFoe(veh, lane, yMinPos, dir * xWidth, 0, lateral_offset, minY, maxY, toDelete, transformedPeds);
1055 const bool addBack =
addVehicleFoe(veh, lane, yMaxPos, dir * xWidth, 0, lateral_offset, minY, maxY, toDelete, transformedPeds);
1056 if (path == debugPath) {
1057 std::cout <<
" veh=" << veh->
getID()
1058 <<
" corners=" << relCorners
1059 <<
" xWidth=" << xWidth
1060 <<
" ymin=" << relCorners.
ymin()
1061 <<
" ymax=" << relCorners.
ymax()
1062 <<
" vehYmin=" << vehYmin
1063 <<
" vehYmax=" << vehYmax
1066 if (addFront && addBack) {
1068 const double yDist = vehYmax - vehYmin;
1070 const double relDist = dist / yDist;
1071 Position between = (yMinPos * relDist) + (yMaxPos * (1 - relDist));
1072 if (path == debugPath) {
1073 std::cout <<
" vehBetween=" << veh->
getID() <<
" pos=" << between <<
"\n";
1075 addVehicleFoe(veh, lane, between, dir * xWidth,
stripeWidth, lateral_offset, minY, maxY, toDelete, transformedPeds);
1084 for (Pedestrians::iterator it_p = toDelete.begin(); it_p != toDelete.end(); ++it_p) {
1100 const double newY = relPos.
y() + lateral_offset;
1101 if (newY >= minY && newY <= maxY) {
1104 toDelete.push_back(tp);
1105 transformedPeds.push_back(tp);
1116 sort(pedestrians.begin(), pedestrians.end(),
by_xpos_sorter(dir));
1118 for (
int i = 0; i < (int)pedestrians.size(); i++) {
1119 PState*
const p = pedestrians[i];
1126 pedestrians.erase(pedestrians.begin() + i);
1129 if (p->
myLane !=
nullptr) {
1148 sort(pedestrians.begin(), pedestrians.end(),
by_xpos_sorter(dir));
1151 bool hasCrossingVehObs =
false;
1154 hasCrossingVehObs =
addCrossingVehs(lane, stripes, 0, dir, crossingVehs,
true);
1157 for (
int ii = 0; ii < (int)pedestrians.size(); ++ii) {
1158 PState& p = *pedestrians[ii];
1195 nextLanesObs, lane, nextLane, stripes,
1214 const double passingClearanceTime = 2;
1215 const double passingLength = p.
getLength() + passingClearanceTime * speed;
1226 && !link->
opened(currentTime -
DELTA_T, speed, speed, passingLength, p.
getImpatience(currentTime), speed, 0, 0,
nullptr, p.
ignoreRed(link), p.
myPerson)) {
1263 if (hasCrossingVehObs) {
1272 p.
walk(currentObs, currentTime);
1283 for (
int coll = 0; coll < ii; ++coll) {
1284 PState& c = *pedestrians[coll];
1291 +
"', lane='" + lane->
getID() +
"', time=" +
time2string(currentTime) +
".");
1304 bool hasCrossingVehObs =
false;
1309 if (linkLeaders.size() > 0) {
1310 for (MSLink::LinkLeaders::const_iterator it = linkLeaders.begin(); it != linkLeaders.end(); ++it) {
1312 const MSVehicle* veh = (*it).vehAndGap.first;
1313 if (veh !=
nullptr) {
1318 voBlock.
xBack = NUMERICAL_EPS;
1325 const double bGap = (prio
1327 : veh->
getSpeed() * distToCrossBeforeVeh);
1331 if ((*it).fromLeft()) {
1332 vehYmin = -(*it).vehAndGap.second + lateral_offset;
1336 vehYmax = crossing->
getWidth() + (*it).vehAndGap.second - lateral_offset;
1350 hasCrossingVehObs =
true;
1355 <<
" crossingVeh=" << veh->
getID()
1356 <<
" lane=" << crossing->
getID()
1358 <<
" latOffset=" << lateral_offset
1360 <<
" stripes=" << stripes
1361 <<
" dist=" << (*it).distToCrossing
1362 <<
" gap=" << (*it).vehAndGap.second
1363 <<
" brakeGap=" << bGap
1364 <<
" fromLeft=" << (*it).fromLeft()
1365 <<
" distToCrossBefore=" << distToCrossBeforeVeh
1366 <<
" ymin=" << vehYmin
1367 <<
" ymax=" << vehYmax
1375 if (hasCrossingVehObs) {
1378 bool allBlocked =
true;
1380 for (
int i = 0; i < (int)obs.size(); i++) {
1383 (dir ==
FORWARD && i >= reserved) ||
1384 (dir ==
BACKWARD && i < (
int)obs.size() - reserved))) {
1391 std::cout <<
SIMTIME <<
" crossing=" << crossing->
getID() <<
" allBlocked\n";
1395 o.xBack = NUMERICAL_EPS;
1397 o.xFwd = crossing->
getLength() - NUMERICAL_EPS;
1403 return hasCrossingVehObs;
1418 if (ped !=
nullptr) {
1439 const double vehNextSpeed =
MAX2(veh->
getSpeed(), 1.0);
1444 double vehXMaxCheck;
1445 double vehXMinCheck;
1449 vehXMin = vehFront - clearance;
1451 vehXMaxCheck = vehBack + NUMERICAL_EPS;
1455 vehXMinCheck = vehFront - clearance;
1458 vehXMax = vehFront + clearance;
1461 vehXMaxCheck = vehFront + clearance;
1465 vehXMinCheck = vehBack - NUMERICAL_EPS;
1469 std::cout <<
SIMTIME <<
" ped=" << pID <<
" veh=" << veh->
getID() <<
" check obstacle on lane=" << lane->
getID()
1471 <<
" vehXMin=" << vehXMin
1472 <<
" vehXMax=" << vehXMax
1473 <<
" vehXMinC=" << vehXMinCheck
1474 <<
" vehXMaxC=" << vehXMaxCheck
1478 <<
" vFront=" << vehFront
1479 <<
" vBack=" << vehBack
1482 if (vehXMaxCheck > minX && vehXMinCheck && vehXMinCheck <= maxX) {
1495 if (s == current && vehFront +
SAFETY_GAP < minX) {
1497 if (pRelY - pWidth < vehYmax &&
1498 pRelY + pWidth > vehYmin && dir ==
FORWARD) {
1500 std::cout <<
" ignoring vehicle '" << veh->
getID() <<
" on stripe " << s <<
" vehFrontSG=" << vehFront +
SAFETY_GAP <<
" minX=" << minX <<
"\n";
1511 std::cout <<
SIMTIME <<
" ped=" << pID <<
" veh=" << veh->
getID() <<
" obstacle on lane=" << lane->
getID()
1513 <<
" ymin=" << vehYmin
1514 <<
" ymax=" << vehYmax
1517 <<
" relY=" << pRelY
1518 <<
" current=" << current
1519 <<
" vo.xFwd=" << vo.xFwd
1520 <<
" vo.xBack=" << vo.xBack
1521 <<
" vFront=" << vehFront
1522 <<
" vBack=" << vehBack
1538 type(OBSTACLE_NONE),
1544 xFwd(ped.getMaxX()),
1545 xBack(ped.getMinX()),
1546 speed(ped.myDir * ped.mySpeed),
1547 type(ped.getOType()),
1548 description(ped.getID()) {
1556 return xBack <= o.
xBack;
1558 return xFwd >= o.
xFwd;
1570 myRelX(stage->getDepartPos()),
1571 myRelY(stage->getDepartPosLat()),
1575 myWaitingToEnter(true),
1577 myWalkingAreaPath(nullptr),
1580 myAngle(
std::numeric_limits<double>::max()) {
1583 assert(!route.empty());
1584 if (route.size() == 1) {
1590 if (route.front()->isWalkingArea()) {
1597 std::cout <<
" initialize dir for " <<
myPerson->
getID() <<
" forward=" << mayStartForward <<
" backward=" << mayStartBackward <<
"\n";
1599 if (mayStartForward && mayStartBackward) {
1603 if (crossingRoute.size() > 1) {
1605 const MSEdge* nextEdge = crossingRoute[1];
1611 std::cout <<
" crossingRoute=" <<
toString(crossingRoute) <<
"\n";
1653 myWaitingToEnter(false),
1655 myWalkingAreaPath(nullptr),
1658 myAngle(
std::numeric_limits<double>::max()) {
1666 myWalkingAreaPath(nullptr),
1668 myAngle(
std::numeric_limits<double>::max()) {
1669 if (in !=
nullptr) {
1671 std::string wapLaneFrom;
1672 std::string wapLaneTo;
1673 std::string nextLaneID;
1674 std::string nextLinkFrom;
1675 std::string nextLinkTo;
1680 >> wapLaneFrom >> wapLaneTo
1690 throw ProcessError(
"Unknown lane '" + laneID +
"' when loading walk for person '" +
myPerson->
getID() +
"' from state.");
1693 MSLane* nextLane =
nullptr;
1694 if (nextLaneID !=
"null") {
1696 if (nextLane ==
nullptr) {
1697 throw ProcessError(
"Unknown next lane '" + nextLaneID +
"' when loading walk for person '" +
myPerson->
getID() +
"' from state.");
1700 const MSLink* link =
nullptr;
1701 if (nextLinkFrom !=
"null") {
1704 if (from ==
nullptr) {
1705 throw ProcessError(
"Unknown link origin lane '" + nextLinkFrom +
"' when loading walk for person '" +
myPerson->
getID() +
"' from state.");
1707 if (to ==
nullptr) {
1708 throw ProcessError(
"Unknown link destination lane '" + nextLinkTo +
"' when loading walk for person '" +
myPerson->
getID() +
"' from state.");
1714 if (wapLaneFrom !=
"null") {
1717 if (from ==
nullptr) {
1718 throw ProcessError(
"Unknown walkingAreaPath origin lane '" + wapLaneFrom +
"' when loading walk for person '" +
myPerson->
getID() +
"' from state.");
1720 if (to ==
nullptr) {
1721 throw ProcessError(
"Unknown walkingAreaPath destination lane '" + wapLaneTo +
"' when loading walk for person '" +
myPerson->
getID() +
"' from state.");
1727 throw ProcessError(
"Unknown walkingAreaPath from lane '" + wapLaneFrom +
"' to lane '" + wapLaneTo +
"' when loading walk for person '" +
myPerson->
getID() +
"' from state.");
1735 std::string wapLaneFrom =
"null";
1736 std::string wapLaneTo =
"null";
1737 if (myWalkingAreaPath !=
nullptr) {
1738 wapLaneFrom = myWalkingAreaPath->from->getID();
1739 wapLaneTo = myWalkingAreaPath->to->getID();
1741 std::string nextLaneID =
"null";
1742 std::string nextLinkFrom =
"null";
1743 std::string nextLinkTo =
"null";
1744 if (myNLI.lane !=
nullptr) {
1745 nextLaneID = myNLI.lane->getID();
1747 if (myNLI.link !=
nullptr) {
1748 nextLinkFrom = myNLI.link->getLaneBefore()->getID();
1749 nextLinkTo = myNLI.link->getViaLaneOrLane()->getID();
1751 out <<
" " << myLane->getID()
1756 <<
" " << mySpeedLat
1757 <<
" " << myWaitingToEnter
1758 <<
" " << myWaitingTime
1759 <<
" " << wapLaneFrom
1761 <<
" " << myAmJammed
1762 <<
" " << nextLaneID
1763 <<
" " << nextLinkFrom
1764 <<
" " << nextLinkTo
1765 <<
" " << myNLI.dir;
1772 return myRelX - getLength();
1774 return myRelX - (includeMinGap ? getMinGap() : 0.);
1782 return myRelX + (includeMinGap ? getMinGap() : 0.);
1784 return myRelX + getLength();
1790 return myPerson->getVehicleType().getLength();
1796 return myPerson->getVehicleType().getMinGap();
1808 const int s = stripe(relY);
1812 if (offset > threshold) {
1814 }
else if (offset < -threshold) {
1839 if (myStage->getNextRouteEdge() ==
nullptr) {
1840 return myDir * (myStage->getArrivalPos() - myRelX) - POSITION_EPS - (
1841 (myWaitingTime >
DELTA_T && (myStage->getDestinationStop() ==
nullptr ||
1842 myStage->getDestinationStop()->getWaitingCapacity() > myStage->getDestinationStop()->getNumWaitingPersons()))
1845 const double length = myWalkingAreaPath ==
nullptr ? myLane->getLength() : myWalkingAreaPath->length;
1846 return myDir ==
FORWARD ? length - myRelX : myRelX;
1853 double dist = distToLaneEnd();
1855 std::cout <<
SIMTIME <<
" ped=" << myPerson->getID() <<
" myRelX=" << myRelX <<
" dist=" << dist <<
"\n";
1863 const int oldDir = myDir;
1864 const MSLane* oldLane = myLane;
1865 myLane = myNLI.lane;
1867 const bool normalLane = (myLane ==
nullptr || myLane->getEdge().getFunction() ==
SumoXMLEdgeFunc::NORMAL || &myLane->getEdge() == myStage->getNextRouteEdge());
1870 <<
" ped=" << myPerson->
getID()
1871 <<
" moveToNextLane old=" << oldLane->
getID()
1872 <<
" new=" << (myLane ==
nullptr ?
"NULL" : myLane->getID())
1873 <<
" oldDir=" << oldDir
1874 <<
" newDir=" << myDir
1875 <<
" myRelX=" << myRelX
1879 if (myLane ==
nullptr) {
1880 myRelX = myStage->getArrivalPos();
1883 if (myStage->getRouteStep() == myStage->getRoute().end() - 1) {
1886 const bool arrived = myStage->moveToNextEdge(myPerson, currentTime, oldDir, normalLane ?
nullptr : &myLane->getEdge());
1892 myStage->activateEntryReminders(myPerson);
1893 assert(myNLI.lane != oldLane);
1895 std::cout <<
" nextLane=" << (myNLI.lane ==
nullptr ?
"NULL" : myNLI.lane->getID()) <<
"\n";
1897 if (myLane->getEdge().isWalkingArea()) {
1900 assert(myWalkingAreaPath->shape.size() >= 2);
1902 std::cout <<
" mWAPath shape=" << myWalkingAreaPath->shape <<
" length=" << myWalkingAreaPath->length <<
"\n";
1904 }
else if (myNLI.link !=
nullptr) {
1906 myLane = myNLI.lane;
1907 assert(!myLane->getEdge().isWalkingArea());
1908 myStage->moveToNextEdge(myPerson, currentTime, myDir, &myLane->getEdge());
1909 myWalkingAreaPath =
nullptr;
1915 const MSEdge* currRouteEdge = *myStage->getRouteStep();
1916 const MSEdge* nextRouteEdge = myStage->getNextRouteEdge();
1924 myStage->moveToNextEdge(myPerson, currentTime, oldDir,
nullptr);
1925 myLane = myNLI.lane;
1926 assert(myLane != 0);
1929 myWalkingAreaPath =
nullptr;
1931 throw ProcessError(
TLF(
"Disconnected walk for person '%'.", myPerson->getID()));
1935 myWalkingAreaPath =
nullptr;
1940 const double newLength = (myWalkingAreaPath ==
nullptr ? myLane->getLength() : myWalkingAreaPath->length);
1941 if (-dist > newLength) {
1948 myRelX = newLength + dist;
1953 std::cout <<
SIMTIME <<
" update myRelX ped=" << myPerson->getID()
1954 <<
" newLength=" << newLength
1956 <<
" myRelX=" << myRelX
1960 if (myDir != oldDir) {
1967 std::cout <<
SIMTIME <<
" transformY ped=" << myPerson->getID()
1969 <<
" newY=" << myRelY
1971 <<
" od=" << oldDir <<
" nd=" << myDir
1972 <<
" offset=" << offset <<
"\n";
1975 myAngle = std::numeric_limits<double>::max();
1986 (
int)floor(stripes * factor),
1992 const int stripes = (int)obs.size();
1993 const int sMax = stripes - 1;
1997 const double vMax = (myStage->getConfiguredSpeed() >= 0
1998 ? myStage->getConfiguredSpeed()
1999 : (myLane->isNormal() || myLane->isInternal()
2000 ? myLane->getVehicleMaxSpeed(myPerson)
2001 : myStage->getMaxSpeed(myPerson)));
2003 const int current = stripe();
2004 const int other = otherStripe();
2006 std::vector<double> distance(stripes);
2007 for (
int i = 0; i < stripes; ++i) {
2008 distance[i] = distanceTo(obs[i], obs[i].type ==
OBSTACLE_PED);
2011 std::vector<double> utility(stripes, 0);
2013 for (
int i = 0; i < stripes; ++i) {
2015 if (i == current && (!myWaitingToEnter || stripe() != stripe(myRelY))) {
2019 for (
int j = 0; j <= i; ++j) {
2024 for (
int j = i; j < stripes; ++j) {
2033 const bool onJunction = myLane->getEdge().isWalkingArea() || myLane->getEdge().isCrossing();
2036 for (
int i = 0; i < reserved; ++i) {
2040 for (
int i = sMax; i > sMax - reserved; --i) {
2045 for (
int i = 0; i < stripes; ++i) {
2046 if (obs[i].speed * myDir < 0) {
2049 utility[i - 1] -= 0.5;
2050 }
else if (myDir ==
BACKWARD && i < sMax) {
2051 utility[i + 1] -= 0.5;
2055 const double walkDist =
MAX2(0., distance[i]);
2057 const double expectedDist =
MIN2(vMax *
LOOKAHEAD_SAMEDIR, walkDist + obs[i].speed * myDir * lookAhead);
2058 if (expectedDist >= 0) {
2059 utility[i] += expectedDist;
2066 if (myDir ==
FORWARD && obs[0].speed < 0) {
2068 }
else if (myDir ==
BACKWARD && obs[sMax].speed > 0) {
2072 if (distance[current] > 0 && myWaitingTime == 0) {
2073 for (
int i = 0; i < stripes; ++i) {
2079 for (
int i = 0; i < stripes; ++i) {
2087 int chosen = current;
2088 for (
int i = 0; i < stripes; ++i) {
2094 const int next = (chosen == current ? current : (chosen < current ? current - 1 : current + 1));
2095 double xDist =
MIN3(distance[current], distance[other], distance[next]);
2096 if (next != chosen) {
2099 const int nextOther = chosen < current ? current - 2 : current + 2;
2100 xDist =
MIN2(xDist, distance[nextOther]);
2103 const double preferredGap = NUMERICAL_EPS;
2105 if (xSpeed < NUMERICAL_EPS) {
2109 std::cout <<
" xSpeedPotential=" << xSpeed <<
"\n";
2116 (xDist == distance[current] && obs[current].type >=
OBSTACLE_END)
2117 || (xDist == distance[other] && obs[other].type >=
OBSTACLE_END)
2118 || (xDist == distance[next] && obs[next].type >=
OBSTACLE_END))
2123 if (myWaitingTime > ((myLane->getEdge().isCrossing()
2125 || (myLane->getEdge().isWalkingArea() && obs[current].type ==
OBSTACLE_VEHICLE
2127 || (sMax == 0 && obs[0].speed * myDir < 0 && myWaitingTime >
jamTimeNarrow)
2138 }
else if (myAmJammed && stripe(myRelY) >= 0 && stripe(myRelY) <= sMax && xDist >=
MIN_STARTUP_DIST) {
2162 if (fabs(yDist) > NUMERICAL_EPS) {
2163 ySpeed = (yDist > 0 ?
2169 && stripe() == stripe(myRelY)
2171 && !(myLane->getEdge().isCrossing() || myLane->getEdge().isWalkingArea())) {
2173 int stepAsideDir = myDir;
2174 if (myLane->getEdge().getLanes().size() > 1 || current > sMax / 2) {
2180 ySpeed = stepAsideDir * vMax;
2186 <<
" ped=" << myPerson->getID()
2187 <<
" edge=" << myStage->getEdge()->getID()
2191 <<
" pvx=" << mySpeed
2192 <<
" cur=" << current
2193 <<
" cho=" << chosen
2197 <<
" dawdle=" << dawdle
2202 <<
" wTime=" << myStage->getWaitingTime(currentTime)
2203 <<
" jammed=" << myAmJammed
2206 for (
int i = 0; i < stripes; ++i) {
2208 std::cout <<
" util=" << utility[i] <<
" dist=" << distance[i] <<
" o=" << o.
description;
2210 std::cout <<
" xF=" << o.
xFwd <<
" xB=" << o.
xBack <<
" v=" << o.
speed;
2213 std::cout <<
" current";
2215 if (i == other && i != current) {
2216 std::cout <<
" other";
2219 std::cout <<
" chosen";
2222 std::cout <<
" next";
2230 mySpeedLat = ySpeed;
2233 myWaitingToEnter =
false;
2238 myAngle = std::numeric_limits<double>::max();
2244 return MAX2(0.,
MIN2(1., myPerson->getVehicleType().getImpatience()
2264 return myRemoteXYPos;
2266 if (myLane ==
nullptr) {
2270 const double lateral_offset = myRelY + (
stripeWidth - myLane->getWidth()) * 0.5;
2271 if (myWalkingAreaPath ==
nullptr) {
2286 return myWalkingAreaPath->shape.positionAtOffset(myRelX, lateral_offset);
2288 const double rotationOffset = myDir ==
FORWARD ? 0 :
DEG2RAD(180);
2289 return myWalkingAreaPath->shape.sidePositionAtAngle(myRelX, lateral_offset, myWalkingAreaPath->angleOverride + rotationOffset);
2297 if (myAngle != std::numeric_limits<double>::max()) {
2300 if (myLane ==
nullptr) {
2304 if (myWalkingAreaPath !=
nullptr && myWalkingAreaPath->angleOverride !=
INVALID_DOUBLE) {
2305 return myWalkingAreaPath->angleOverride;
2307 const PositionVector& shp = myWalkingAreaPath ==
nullptr ? myLane->getShape() : myWalkingAreaPath->shape;
2308 double geomX = myWalkingAreaPath ==
nullptr ? myLane->interpolateLanePosToGeometryPos(myRelX) : myRelX;
2311 angle += atan2(mySpeedLat,
MAX2(mySpeed, NUMERICAL_EPS));
2313 angle -= atan2(mySpeedLat,
MAX2(mySpeed, NUMERICAL_EPS));
2325 return myWaitingTime;
2337 return myNLI.lane ==
nullptr ? nullptr : &myNLI.lane->getEdge();
2344 int routeOffset = 0;
2345 bool laneOnRoute =
false;
2347 for (
const MSEdge* edge : myStage->getRoute()) {
2350 || edge->getFromJunction() == laneOnJunction) {
2357 throw ProcessError(
"Lane '" + lane->
getID() +
"' is not on the route of person '" + getID() +
"'.");
2360 if (lane->
getEdge().
isWalkingArea() && (myWalkingAreaPath ==
nullptr || myWalkingAreaPath->lane != lane)) {
2362 const MSEdge* prevEdge = myStage->getRoute()[routeOffset];
2363 const MSEdge* nextEdge = routeOffset + 1 < (int)myStage->getRoute().size() ? myStage->getRoute()[routeOffset + 1] :
nullptr;
2365 const double maxPos = guessed->
shape.
length() - NUMERICAL_EPS;
2366 if (lanePos > maxPos + POSITION_EPS || lanePos < -POSITION_EPS) {
2368 +
"' (fromLane='" + guessed->
from->
getID()
2369 +
"' toLane='" + guessed->
to->
getID() +
"') for person '" + getID() +
"' time=" +
time2string(t) +
".");
2372 lanePos =
MIN2(maxPos,
MAX2(NUMERICAL_EPS, lanePos));
2376 moveToXY(p, pos, lane, lanePos, lanePosLat, angle, routeOffset, newEdges, t);
2382 double lanePosLat,
double angle,
int routeOffset,
2385 assert(p == myPerson);
2386 assert(pm !=
nullptr);
2389 const double oldX = myRelX -
SPEED2DIST(mySpeed * myDir);
2390 const double tmp = myRelX;
2392 Position oldPos = getPosition(*myStage, t);
2398#ifdef DEBUG_MOVETOXY
2402 <<
" lane=" << lane->
getID()
2403 <<
" lanePos=" << lanePos
2404 <<
" lanePosLat=" << lanePosLat
2405 <<
" angle=" << angle
2406 <<
" routeOffset=" << routeOffset
2409 <<
" path=" << (myWalkingAreaPath ==
nullptr ?
"null" : (myWalkingAreaPath->from->getID() +
"->" + myWalkingAreaPath->to->getID())) <<
"\n";
2412 if (lane != myLane && myLane !=
nullptr) {
2416 if (lane !=
nullptr &&
2419 const MSEdge* old = myStage->getEdge();
2420 const MSLane* oldLane = myLane;
2421 if (lane != myLane) {
2425 if (edges.empty()) {
2427 myStage->setRouteIndex(myPerson, routeOffset);
2429 myStage->replaceRoute(myPerson, edges, routeOffset);
2432 myStage->moveToNextEdge(myPerson, t, myDir, &lane->
getEdge());
2438 if (myWalkingAreaPath ==
nullptr || myWalkingAreaPath->lane != lane) {
2440 myWalkingAreaPath =
guessPath(&lane->
getEdge(), old, myStage->getNextRouteEdge());
2441#ifdef DEBUG_MOVETOXY
2443 <<
" path=" << myWalkingAreaPath->from->getID() <<
"->" << myWalkingAreaPath->to->getID() <<
"\n";
2448 const Position relPos = myWalkingAreaPath->shape.transformToVectorCoordinates(pos);
2451 +
"' (fromLane='" + myWalkingAreaPath->from->getID()
2452 +
"' toLane='" + myWalkingAreaPath->to->getID() +
"') for person '" + getID() +
"' time=" +
time2string(t) +
".");
2453 myRemoteXYPos = pos;
2455 myRelX = relPos.
x();
2456 myRelY = lateral_offset + relPos.
y();
2459 myWalkingAreaPath =
nullptr;
2461 myRelY = lateral_offset - lanePosLat;
2465 if (myStage->getNextRouteEdge() !=
nullptr) {
2466 if (myStage->getEdge()->getToJunction() == myStage->getNextRouteEdge()->getFromJunction() ||
2467 myStage->getEdge()->getToJunction() == myStage->getNextRouteEdge()->getToJunction()) {
2474 if (angleDiff <= 90) {
2485 if (oldLane ==
nullptr || &oldLane->
getEdge() != &myLane->getEdge()) {
2486 const MSLane* sidewalk = getSidewalk<MSEdge, MSLane>(&myLane->getEdge(), p->
getVClass());
2489 myNLI =
getNextLane(*
this, sidewalk ==
nullptr ? myLane : sidewalk,
nullptr);
2490 myStage->activateEntryReminders(myPerson);
2491#ifdef DEBUG_MOVETOXY
2492 std::cout <<
" myNLI=" <<
Named::getIDSecure(myNLI.lane) <<
" link=" << (myNLI.link ==
nullptr ?
"NULL" : myNLI.link->getDescription()) <<
" dir=" << myNLI.
dir <<
"\n";
2495#ifdef DEBUG_MOVETOXY
2496 std::cout <<
" newRelPos=" <<
Position(myRelX, myRelY) <<
" edge=" << myPerson->getEdge()->getID() <<
" newPos=" << myPerson->getPosition()
2497 <<
" oldAngle=" << oldAngle <<
" angleDiff=" << angleDiff <<
" newDir=" << myDir <<
"\n";
2499 if (oldLane == myLane) {
2507 myRemoteXYPos = pos;
2526 if (myWalkingAreaPath !=
nullptr) {
2527 return myWalkingAreaPath->length;
2536 const double maxX = getMaxX(includeMinGap);
2537 const double minX = getMinX(includeMinGap);
2541 if ((obs.
xFwd >= maxX && obs.
xBack <= maxX) || (obs.
xFwd <= maxX && obs.
xFwd >= minX)) {
2555 for (
int i = 0; i < (int)into.size(); ++i) {
2557 std::cout <<
" i=" << i <<
" maxX=" << getMaxX(
true) <<
" minX=" << getMinX(
true)
2558 <<
" into=" << into[i].description <<
" iDist=" << distanceTo(into[i], into[i].type ==
OBSTACLE_PED)
2559 <<
" obs2=" << obs2[i].description <<
" oDist=" << distanceTo(obs2[i], obs2[i].type ==
OBSTACLE_PED) <<
"\n";
2561 const double dO = distanceTo(obs2[i], obs2[i].type ==
OBSTACLE_PED);
2562 const double dI = distanceTo(into[i], into[i].type ==
OBSTACLE_PED);
2577 for (
int i = 0; i < (int)into.size(); ++i) {
2578 int i2 = i + offset;
2579 if (i2 >= 0 && i2 < (
int)obs2.size()) {
2581 if (obs2[i2].xBack < into[i].xBack) {
2585 if (obs2[i2].xFwd > into[i].xFwd) {
2598 if (ignoreRedTime >= 0) {
2601 std::cout <<
SIMTIME <<
" ignoreRedTime=" << ignoreRedTime <<
" redDuration=" << redDuration <<
"\n";
2603 return ignoreRedTime > redDuration;
2614 return myPerson->getID();
2619 return myPerson->getVehicleType().getWidth();
2625 return myPerson->hasInfluencer() && myPerson->getInfluencer().isRemoteControlled();
2633 myVehicle(veh), myXWidth(xWidth), myYWidth(yWidth) {
2637 myRelX = relX + xWidth / 2;
2643 return myVehicle->
getID();
2653 return myXWidth > 0 ? myRelX - myXWidth : myRelX;
2658 return myXWidth > 0 ? myRelX : myRelX - myXWidth;
2667 std::set<MSPerson*> changedLane;
2668 myModel->moveInDirection(currentTime, changedLane,
FORWARD);
2669 myModel->moveInDirection(currentTime, changedLane,
BACKWARD);
2672 for (ActiveLanes::const_iterator it_lane = myModel->getActiveLanes().begin(); it_lane != myModel->getActiveLanes().end(); ++it_lane) {
2673 const MSLane* lane = it_lane->first;
2675 if (pedestrians.size() == 0) {
2680 for (
int ii = 0; ii < (int)pedestrians.size(); ++ii) {
2681 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)
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
std::string time2string(SUMOTime t, bool humanReadable)
convert SUMOTime to string (independently of global format setting)
@ 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)
static void insertWalkArePaths(const MSEdge *edge, WalkingAreaPaths &into)
creates and inserts all paths into the given map
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