51#define DEBUGCOND(PED) ((PED).getPerson()->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
124 WRITE_WARNINGF(
TL(
"Pedestrian vType '%' width % is larger than pedestrian.striping.stripe-width and this may cause collisions with vehicles."),
174 if (lane ==
nullptr) {
175 const char* error =
TL(
"Person '%' could not find sidewalk on edge '%', time=%.");
213 if (from ==
nullptr || to ==
nullptr) {
215 }
else if (from->
getLinkTo(to) !=
nullptr) {
217 }
else if (to->
getLinkTo(from) !=
nullptr) {
235 for (
MSLink* link : lane->getLinkCont()) {
236 if (link->getWalkingAreaFoe() !=
nullptr) {
238 myWalkingAreaFoes[&link->getWalkingAreaFoe()->getEdge()].push_back(link->getLaneBefore());
241 if (link->getWalkingAreaFoeExit() !=
nullptr) {
243 myWalkingAreaFoes[&link->getWalkingAreaFoeExit()->getEdge()].push_back(link->getLaneBefore());
261 const MSLane* walkingArea = getSidewalk<MSEdge, MSLane>(edge);
265 std::vector<const MSLane*> lanes;
267 if (!in->isTazConnector()) {
268 lanes.push_back(getSidewalk<MSEdge, MSLane>(in));
269 if (lanes.back() ==
nullptr) {
270 throw ProcessError(
"Invalid connection from edge '" + in->getID() +
"' to walkingarea edge '" + edge->
getID() +
"'");
275 if (!out->isTazConnector()) {
276 lanes.push_back(getSidewalk<MSEdge, MSLane>(out));
277 if (lanes.back() ==
nullptr) {
278 throw ProcessError(
"Invalid connection from walkingarea edge '" + edge->
getID() +
"' to edge '" + out->getID() +
"'");
283 for (
int j = 0; j < (int)lanes.size(); ++j) {
284 for (
int k = 0; k < (int)lanes.size(); ++k) {
287 const MSLane*
const from = lanes[j];
288 const MSLane*
const to = lanes[k];
294 const double maxExtent = fromPos.
distanceTo2D(toPos) / 4;
295 const double extrapolateBy =
MIN2(maxExtent, walkingArea->
getWidth() / 2);
297 shape.push_back(fromPos);
298 if (extrapolateBy > POSITION_EPS) {
307 if (shape.size() < 2) {
311 assert(shape.size() == 2);
316 if (shape.size() >= 4 && shape.
length() < walkingArea->
getWidth()) {
317 const double aStart = shape.
angleAt2D(0);
318 const double aEnd = shape.
angleAt2D((
int)shape.size() - 2);
319 if (fabs(aStart - aEnd) <
DEG2RAD(10)) {
320 angleOverride = (aStart + aEnd) / 2;
328 into.insert(std::make_pair(std::make_pair(from, to), wap));
340 std::vector<const MSLane*> lanes;
342 lanes.push_back(getSidewalk<MSEdge, MSLane>(pred));
345 lanes.push_back(getSidewalk<MSEdge, MSLane>(succ));
347 if (lanes.size() < 1) {
348 throw ProcessError(
TLF(
"Invalid walkingarea '%' does not allow continuation.", walkingArea->
getID()));
356 const MSLane* swBefore = getSidewalk<MSEdge, MSLane>(before);
357 const MSLane* swAfter = getSidewalk<MSEdge, MSLane>(after);
360 return &pathIt->second;
364 bool useBefore = swBefore !=
nullptr && std::find(preds.begin(), preds.end(), before) != preds.end();
365 bool useAfter = swAfter !=
nullptr && std::find(succs.begin(), succs.end(), after) != succs.end();
369 }
else if (succs.size() > 0) {
371 return getWalkingAreaPath(walkingArea, swBefore, getSidewalk<MSEdge, MSLane>(succs.front()));
373 }
else if (useAfter && preds.size() > 0) {
375 return getWalkingAreaPath(walkingArea, getSidewalk<MSEdge, MSLane>(preds.front()), swAfter);
386 return &pathIt->second;
390 if (preds.size() > 0) {
392 const auto pathIt2 =
myWalkingAreaPaths.find(std::make_pair(getSidewalk<MSEdge, MSLane>(pred), after));
394 return &pathIt2->second;
410 const MSLane* nextLane = nextRouteLane;
411 const MSLink* link =
nullptr;
417 if (nextRouteLane ==
nullptr && nextRouteEdge !=
nullptr) {
418 std::string error =
"Person '" + ped.
getPerson()->
getID() +
"' could not find sidewalk on edge '" + nextRouteEdge->
getID() +
"', time="
422 nextRouteLane = nextRouteEdge->
getLanes().front();
428 if (nextRouteLane !=
nullptr) {
433 nextLane = currentLane->
getLinkCont()[0]->getViaLaneOrLane();
438 std::cout <<
" internal\n";
443 nextLane = currentLane->
getLinkCont()[0]->getLane();
448 std::cout <<
" crossing\n";
458 const double arrivalPos = (nextRouteEdge == ped.
getStage()->
getRoute().back()
462 if (prevLane !=
nullptr) {
463 prohibited[&prevLane->
getEdge()].end = std::numeric_limits<double>::max();
470 <<
" nre=" << nextRouteEdge->
getID()
471 <<
" nreDir=" << nextRouteEdgeDir
472 <<
" aPos=" << arrivalPos
473 <<
" crossingRoute=" <<
toString(crossingRoute)
476 if (crossingRoute.size() > 1) {
477 const MSEdge* nextEdge = crossingRoute[1];
478 nextLane = getSidewalk<MSEdge, MSLane>(crossingRoute[1], ped.
getPerson()->
getVClass());
480 assert(nextLane != prevLane);
483 std::cout <<
" nextDir=" << nextDir <<
"\n";
492 link = oppositeWalkingArea->
getLinkTo(nextLane);
495 assert(link !=
nullptr);
502 <<
" no route from '" << (currentEdge ==
nullptr ?
"NULL" : currentEdge->
getID())
503 <<
"' to '" << (nextRouteEdge ==
nullptr ?
"NULL" : nextRouteEdge->
getID())
508 link = prevLane->
getLinkTo(nextRouteLane);
510 link = nextRouteLane->
getLinkTo(prevLane);
512 if (link !=
nullptr) {
517 +
"' from walkingArea '" + currentEdge->
getID()
518 +
"' to edge '" + nextRouteEdge->
getID() +
"', time=" +
521 nextLane = nextRouteLane;
524 }
else if (currentEdge == nextRouteEdge) {
531 if (nextLane !=
nullptr) {
534 std::cout <<
" next walkingArea " << (nextDir ==
FORWARD ?
"forward" :
"backward") <<
"\n";
553 std::cout <<
" nextEdge=" << nextRouteEdge->
getID() <<
" passedFwd=" << passedFwd <<
" passedBwd=" << passedBwd <<
" futureRoute=" <<
toString(futureRoute) <<
" nextDir=" << nextDir <<
"\n";
559 link = currentLane->
getLinkTo(nextRouteLane);
560 if (link !=
nullptr) {
562 std::cout <<
" direct forward\n";
567 link = nextRouteLane->
getLinkTo(currentLane);
568 if (link !=
nullptr) {
570 std::cout <<
" direct backward\n";
573 if (nextLane !=
nullptr) {
575 while (nextLane->
getLinkCont()[0]->getViaLaneOrLane()->isInternal()) {
576 nextLane = nextLane->
getLinkCont()[0]->getViaLaneOrLane();
582 if (nextLane ==
nullptr) {
584 nextLane = nextRouteLane;
586 std::cout <<
SIMTIME <<
" no next lane found for " << currentLane->
getID() <<
" dir=" << ped.
getDirection() <<
"\n";
590 +
"' from edge '" + currentEdge->
getID()
591 +
"' to edge '" + nextRouteEdge->
getID() +
"', time=" +
594 }
else if (nextLane->
getLength() <= POSITION_EPS) {
606 nextLane = nextRouteLane;
615 <<
" l=" << currentLane->
getID()
616 <<
" nl=" << (nextLane ==
nullptr ?
"NULL" : nextLane->
getID())
617 <<
" nrl=" << (nextRouteLane ==
nullptr ?
"NULL" : nextRouteLane->
getID())
623 assert(nextLane != 0 || nextRouteLane == 0);
632 if (l->getLane()->isWalkingArea()) {
638 const std::vector<MSLane::IncomingLaneInfo>& laneInfos = currentLane->
getIncomingLanes();
639 for (std::vector<MSLane::IncomingLaneInfo>::const_iterator it = laneInfos.begin(); it != laneInfos.end(); ++it) {
640 if ((*it).lane->isWalkingArea()) {
641 link = (*it).viaLink;
652 const PState& ego = *
static_cast<PState*
>(pedestrians[egoIndex]);
653 const int egoStripe = ego.
stripe();
655 std::vector<bool> haveBlocker(stripes,
false);
656 for (
int index = egoIndex + 1; index < (int)pedestrians.size(); index++) {
657 const PState& p = *
static_cast<PState*
>(pedestrians[index]);
659 std::cout <<
SIMTIME <<
" ped=" << ego.
getID() <<
" cur=" << egoStripe <<
" checking neighbor " << p.
getID()
665 std::cout <<
" dist=" << ego.
distanceTo(o) << std::endl;
673 haveBlocker[p.
stripe()] =
true;
684 if (!haveBlocker[p.
stripe()]) {
703 int offset = (destStripes - origStripes) / 2;
705 offset += (destStripes - origStripes) % 2;
713 MSLane* lane,
const MSLane* nextLane,
int stripes,
int nextDir,
714 double currentLength,
int currentDir) {
715 if (nextLanesObs.count(nextLane) == 0) {
722 const int offset =
getStripeOffset(nextStripes, stripes, currentDir != nextDir && nextStripes > stripes);
733 if (nextStripes < stripes) {
735 for (
int ii = 0; ii < stripes; ++ii) {
736 if (ii < offset || ii >= nextStripes + offset) {
747 if ((stripes - nextStripes) % 2 != 0) {
750 nextDir = currentDir;
752 for (
int ii = 0; ii < (int)pedestrians.size(); ++ii) {
753 const PState& p = *
static_cast<PState*
>(pedestrians[ii]);
762 const double newY = relPos.
y() + lateral_offset;
773 sort(pedestrians.begin(), pedestrians.end(),
by_xpos_sorter(nextDir));
774 for (
int ii = 0; ii < (int)pedestrians.size(); ++ii) {
775 const PState& p = *
static_cast<PState*
>(pedestrians[ii]);
781 if (nextDir != currentDir) {
786 const int stripe = p.
stripe(newY);
787 if (stripe >= 0 && stripe < stripes) {
791 if (otherStripe >= 0 && otherStripe < stripes) {
792 obs[otherStripe] = pObs;
799 addCrossingVehs(nextLane, stripes, offset, nextDir, obs, prio, currentDir != nextDir);
807 nextLanesObs[nextLane] = obs;
809 return nextLanesObs[nextLane];
817 o.xFwd += currentLength;
818 o.xBack += currentLength;
820 const double tmp = o.xFwd;
821 o.xFwd = currentLength + nextLength - o.xBack;
822 o.xBack = currentLength + nextLength - tmp;
826 const double tmp = o.xFwd;
830 o.xFwd -= nextLength;
831 o.xBack -= nextLength;
841 if ((dir ==
FORWARD && x - width / 2. < obs[stripe].xBack) || (dir ==
BACKWARD && x + width / 2. > obs[stripe].xFwd)) {
842 obs[stripe] =
Obstacle(x, 0, type,
id, width);
850 const MSLane* lane = it_lane->first;
852 if (pedestrians.size() == 0) {
858 const double minY =
stripeWidth * - 0.5 + NUMERICAL_EPS;
863 std::set<const WalkingAreaPath*, walkingarea_path_sorter> paths;
864 for (Pedestrians::iterator it = pedestrians.begin(); it != pedestrians.end(); ++it) {
871 std::cout <<
SIMTIME <<
" debugging WalkingAreaPath from=" << debugPath->
from->
getID() <<
" to=" << debugPath->to->getID() <<
" minY=" << minY <<
" maxY=" << maxY <<
" latOffset=" << lateral_offset <<
"\n";
876 for (std::set<const WalkingAreaPath*, walkingarea_path_sorter>::iterator it = paths.begin(); it != paths.end(); ++it) {
880 transformedPeds.reserve(pedestrians.size());
881 for (Pedestrians::iterator it_p = pedestrians.begin(); it_p != pedestrians.end(); ++it_p) {
884 transformedPeds.push_back(p);
885 if (path == debugPath) std::cout <<
" ped=" << p->
getPerson()->
getID() <<
" relX=" << p->
getEdgePos(0) <<
" relY=" << p->
getPosLat() <<
" (untransformed), vecCoord="
890 transformedPeds.push_back(p);
891 if (path == debugPath) std::cout <<
" ped=" << p->
getPerson()->
getID() <<
" relX=" << p->
getEdgePos(0) <<
" relY=" << p->
getPosLat() <<
" (untransformed), vecCoord="
897 toDelete.push_back(tp);
898 transformedPeds.push_back(tp);
899 if (path == debugPath) std::cout <<
" ped=" << p->
getPerson()->
getID() <<
" relX=" << p->
getEdgePos(0) <<
" relY=" << p->
getPosLat() <<
" (semi-transformed), vecCoord="
904 const double newY = relPos.
y() + lateral_offset;
907 tp->
reset(relPos.
x(), newY);
908 toDelete.push_back(tp);
909 transformedPeds.push_back(tp);
910 if (path == debugPath) {
911 std::cout <<
" ped=" << p->
getPerson()->
getID() <<
" relX=" << relPos.
x() <<
" relY=" << newY <<
" (transformed), vecCoord=" << relPos <<
"\n";
914 if (path == debugPath) {
915 std::cout <<
" ped=" << p->
getPerson()->
getID() <<
" relX=" << relPos.
x() <<
" relY=" << newY <<
" (invalid), vecCoord=" << relPos <<
"\n";
925 for (
const MSLane* foeLane : itFoe->second) {
926 for (
auto itVeh = foeLane->anyVehiclesBegin(); itVeh != foeLane->anyVehiclesEnd(); ++itVeh) {
933 WRITE_WARNINGF(
"Could not vehicle '%' front position % onto walkingarea '%' path=%, time=%.",
937 WRITE_WARNINGF(
"Could not vehicle '%' back position % onto walkingarea '%' path=%, time=%.",
941 relCenter.push_back(relFront);
942 relCenter.push_back(relBack);
944 relCorners.
add(relCenter[0]);
945 relCorners.
add(relCenter[1]);
947 relCorners.
add(relCenter[0]);
948 relCorners.
add(relCenter[1]);
952 const double xWidth = relCorners.
getWidth();
953 const double vehYmin =
MAX2(minY - lateral_offset, relCorners.
ymin());
954 const double vehYmax =
MIN2(maxY - lateral_offset, relCorners.
ymax());
955 const double xCenter = relCorners.
getCenter().
x();
958 const bool addFront =
addVehicleFoe(veh, lane, yMinPos, dir * xWidth, 0, lateral_offset, minY, maxY, toDelete, transformedPeds);
959 const bool addBack =
addVehicleFoe(veh, lane, yMaxPos, dir * xWidth, 0, lateral_offset, minY, maxY, toDelete, transformedPeds);
960 if (path == debugPath) {
961 std::cout <<
" veh=" << veh->
getID()
962 <<
" corners=" << relCorners
963 <<
" xWidth=" << xWidth
964 <<
" ymin=" << relCorners.
ymin()
965 <<
" ymax=" << relCorners.
ymax()
966 <<
" vehYmin=" << vehYmin
967 <<
" vehYmax=" << vehYmax
970 if (addFront && addBack) {
972 const double yDist = vehYmax - vehYmin;
974 const double relDist = dist / yDist;
975 Position between = (yMinPos * relDist) + (yMaxPos * (1 - relDist));
976 if (path == debugPath) {
977 std::cout <<
" vehBetween=" << veh->
getID() <<
" pos=" << between <<
"\n";
979 addVehicleFoe(veh, lane, between, dir * xWidth,
stripeWidth, lateral_offset, minY, maxY, toDelete, transformedPeds);
988 for (Pedestrians::iterator it_p = toDelete.begin(); it_p != toDelete.end(); ++it_p) {
1004 const double newY = relPos.
y() + lateral_offset;
1005 if (newY >= minY && newY <= maxY) {
1008 toDelete.push_back(tp);
1009 transformedPeds.push_back(tp);
1020 sort(pedestrians.begin(), pedestrians.end(),
by_xpos_sorter(dir));
1022 for (
int i = 0; i < (int)pedestrians.size(); i++) {
1023 PState*
const p =
static_cast<PState*
>(pedestrians[i]);
1030 pedestrians.erase(pedestrians.begin() + i);
1033 if (p->
getLane() !=
nullptr) {
1052 sort(pedestrians.begin(), pedestrians.end(),
by_xpos_sorter(dir));
1055 bool hasCrossingVehObs =
false;
1058 hasCrossingVehObs =
addCrossingVehs(lane, stripes, 0, dir, crossingVehs,
true,
false);
1061 for (
int ii = 0; ii < (int)pedestrians.size(); ++ii) {
1105 nextLanesObs, lane, nextLane, stripes,
1135 && (!link->
opened(currentTime -
DELTA_T, speed, speed, passingLength, p.
getImpatience(), speed, 0, 0,
nullptr, p.
ignoreRed(link), p.
getPerson())
1178 if (hasCrossingVehObs) {
1198 for (
int coll = 0; coll < ii; ++coll) {
1206 +
"', lane='" + lane->
getID() +
"', time=" +
time2string(currentTime) +
".");
1236 bool hasCrossingVehObs =
false;
1241 if (linkLeaders.size() > 0) {
1242 for (MSLink::LinkLeaders::const_iterator it = linkLeaders.begin(); it != linkLeaders.end(); ++it) {
1244 const MSVehicle* veh = (*it).vehAndGap.first;
1245 if (veh !=
nullptr) {
1250 voBlock.
xBack = NUMERICAL_EPS;
1257 const double bGap = (prio
1259 : veh->
getSpeed() * distToCrossBeforeVeh);
1263 if ((*it).fromLeft()) {
1264 vehYmin = -(*it).vehAndGap.second + lateral_offset;
1268 vehYmax = crossing->
getWidth() + (*it).vehAndGap.second - lateral_offset;
1282 hasCrossingVehObs =
true;
1287 for (
int i = 0; i < (int)obs.size(); i++) {
1288 obs[i] = tmp[obs.size() - 1 - i];
1293 <<
" crossingVeh=" << veh->
getID()
1294 <<
" lane=" << crossing->
getID()
1296 <<
" latOffset=" << lateral_offset
1298 <<
" flipY=" << flipY
1299 <<
" stripes=" << stripes
1300 <<
" dist=" << (*it).distToCrossing
1301 <<
" gap=" << (*it).vehAndGap.second
1302 <<
" brakeGap=" << bGap
1303 <<
" fromLeft=" << (*it).fromLeft()
1304 <<
" distToCrossBefore=" << distToCrossBeforeVeh
1305 <<
" ymin=" << vehYmin
1306 <<
" ymax=" << vehYmax
1314 if (hasCrossingVehObs) {
1317 bool allBlocked =
true;
1319 for (
int i = 0; i < (int)obs.size(); i++) {
1322 (dir ==
FORWARD && i >= reserved) ||
1323 (dir ==
BACKWARD && i < (
int)obs.size() - reserved))) {
1330 std::cout <<
SIMTIME <<
" crossing=" << crossing->
getID() <<
" allBlocked\n";
1334 o.xBack = NUMERICAL_EPS;
1336 o.xFwd = crossing->
getLength() - NUMERICAL_EPS;
1342 return hasCrossingVehObs;
1357 if (ped !=
nullptr) {
1383 double vehXMaxCheck;
1384 double vehXMinCheck;
1388 vehXMin = vehFront - clearance;
1390 vehXMaxCheck = vehBack + NUMERICAL_EPS;
1394 vehXMinCheck = vehFront - clearance;
1397 vehXMax = vehFront + clearance;
1400 vehXMaxCheck = vehFront + clearance;
1404 vehXMinCheck = vehBack - NUMERICAL_EPS;
1408 std::cout <<
SIMTIME <<
" ped=" << pID <<
" veh=" << veh->
getID() <<
" check obstacle on lane=" << lane->
getID()
1410 <<
" vehXMin=" << vehXMin
1411 <<
" vehXMax=" << vehXMax
1412 <<
" vehXMinC=" << vehXMinCheck
1413 <<
" vehXMaxC=" << vehXMaxCheck
1417 <<
" vFront=" << vehFront
1418 <<
" vBack=" << vehBack
1421 if (vehXMaxCheck > minX && vehXMinCheck && vehXMinCheck <= maxX) {
1434 if (s == current && vehFront +
SAFETY_GAP < minX) {
1436 if (pRelY - pWidth < vehYmax &&
1437 pRelY + pWidth > vehYmin && dir ==
FORWARD) {
1439 std::cout <<
" ignoring vehicle '" << veh->
getID() <<
" on stripe " << s <<
" vehFrontSG=" << vehFront +
SAFETY_GAP <<
" minX=" << minX <<
"\n";
1450 std::cout <<
SIMTIME <<
" ped=" << pID <<
" veh=" << veh->
getID() <<
" obstacle on lane=" << lane->
getID()
1452 <<
" ymin=" << vehYmin
1453 <<
" ymax=" << vehYmax
1456 <<
" relY=" << pRelY
1457 <<
" current=" << current
1458 <<
" vo.xFwd=" << vo.xFwd
1459 <<
" vo.xBack=" << vo.xBack
1460 <<
" vFront=" << vehFront
1461 <<
" vBack=" << vehBack
1477 type(OBSTACLE_NONE),
1483 xFwd(ped.getMaxX()),
1484 xBack(ped.getMinX()),
1485 speed(ped.getDirection() * ped.getSpeed(*ped.getStage())),
1486 type(ped.getOType()),
1487 description(ped.getID()) {
1498 return xBack <= o.
xBack;
1500 return xFwd >= o.
xFwd;
1510 myWalkingAreaPath(nullptr) {
1513 assert(!route.empty());
1515 if (route.size() == 1) {
1520 if (route.front()->isWalkingArea()) {
1529 std::cout <<
" initialize dir for " <<
myPerson->
getID() <<
" forward=" << mayStartForward <<
" backward=" << mayStartBackward <<
"\n";
1531 if (mayStartForward && mayStartBackward) {
1536 if (crossingRoute.size() > 1) {
1538 const MSEdge* nextEdge = crossingRoute[1];
1544 std::cout <<
" crossingRoute=" <<
toString(crossingRoute) <<
"\n";
1546 }
else if (!mayStartForward && !mayStartBackward) {
1547 int lastDisconnect = passedFwd >= passedBwd ? passedFwd : passedBwd;
1549 if (route.size() > 2) {
1550 dLoc =
TLF(
" between edge '%' and edge '%'", route[lastDisconnect - 1]->
getID(), route[lastDisconnect]->
getID());
1552 WRITE_WARNINGF(
TL(
"Person '%' walking from edge '%' to edge '%' has a disconnect%, time=%."),
1587 myWalkingAreaPath(nullptr) {
1588 if (in !=
nullptr) {
1590 std::string wapLaneFrom;
1591 std::string wapLaneTo;
1592 std::string nextLaneID;
1593 std::string nextLinkFrom;
1594 std::string nextLinkTo;
1599 >> wapLaneFrom >> wapLaneTo
1609 throw ProcessError(
"Unknown lane '" + laneID +
"' when loading walk for person '" +
myPerson->
getID() +
"' from state.");
1612 MSLane* nextLane =
nullptr;
1613 if (nextLaneID !=
"null") {
1615 if (nextLane ==
nullptr) {
1616 throw ProcessError(
"Unknown next lane '" + nextLaneID +
"' when loading walk for person '" +
myPerson->
getID() +
"' from state.");
1619 const MSLink* link =
nullptr;
1620 if (nextLinkFrom !=
"null") {
1623 if (from ==
nullptr) {
1624 throw ProcessError(
"Unknown link origin lane '" + nextLinkFrom +
"' when loading walk for person '" +
myPerson->
getID() +
"' from state.");
1626 if (to ==
nullptr) {
1627 throw ProcessError(
"Unknown link destination lane '" + nextLinkTo +
"' when loading walk for person '" +
myPerson->
getID() +
"' from state.");
1633 if (wapLaneFrom !=
"null") {
1636 if (from ==
nullptr) {
1637 throw ProcessError(
"Unknown walkingAreaPath origin lane '" + wapLaneFrom +
"' when loading walk for person '" +
myPerson->
getID() +
"' from state.");
1639 if (to ==
nullptr) {
1640 throw ProcessError(
"Unknown walkingAreaPath destination lane '" + wapLaneTo +
"' when loading walk for person '" +
myPerson->
getID() +
"' from state.");
1646 throw ProcessError(
"Unknown walkingAreaPath from lane '" + wapLaneFrom +
"' to lane '" + wapLaneTo +
"' when loading walk for person '" +
myPerson->
getID() +
"' from state.");
1659 std::string wapLaneFrom =
"null";
1660 std::string wapLaneTo =
"null";
1661 if (myWalkingAreaPath !=
nullptr) {
1662 wapLaneFrom = myWalkingAreaPath->from->
getID();
1663 wapLaneTo = myWalkingAreaPath->to->getID();
1665 std::string nextLaneID =
"null";
1666 std::string nextLinkFrom =
"null";
1667 std::string nextLinkTo =
"null";
1668 if (myNLI.lane !=
nullptr) {
1669 nextLaneID = myNLI.lane->getID();
1671 if (myNLI.link !=
nullptr) {
1672 nextLinkFrom = myNLI.link->getLaneBefore()->getID();
1673 nextLinkTo = myNLI.link->getViaLaneOrLane()->getID();
1675 out <<
" " << myLane->getID()
1680 <<
" " << mySpeedLat
1681 <<
" " << myWaitingToEnter
1682 <<
" " << myWaitingTime
1683 <<
" " << wapLaneFrom
1685 <<
" " << myAmJammed
1686 <<
" " << nextLaneID
1687 <<
" " << nextLinkFrom
1688 <<
" " << nextLinkTo
1689 <<
" " << myNLI.dir;
1696 return myEdgePos - getLength();
1698 return myEdgePos - (includeMinGap ? getMinGap() : 0.);
1706 return myEdgePos + (includeMinGap ? getMinGap() : 0.);
1708 return myEdgePos + getLength();
1714 return myPerson->getVehicleType().getLength();
1720 return myPerson->getVehicleType().getMinGap();
1732 const int s = stripe(relY);
1736 if (offset > threshold) {
1738 }
else if (offset < -threshold) {
1763 if (myStage->getNextRouteEdge() ==
nullptr) {
1764 return myDir * (myStage->getArrivalPos() - myEdgePos) - POSITION_EPS - (
1765 (myWaitingTime >
DELTA_T && (myStage->getDestinationStop() ==
nullptr ||
1766 myStage->getDestinationStop()->getWaitingCapacity() > myStage->getDestinationStop()->getNumWaitingPersons()))
1769 const double length = myWalkingAreaPath ==
nullptr ? myLane->getLength() : myWalkingAreaPath->length;
1770 return myDir ==
FORWARD ? length - myEdgePos : myEdgePos;
1777 double dist = distToLaneEnd();
1779 std::cout <<
SIMTIME <<
" ped=" << myPerson->getID() <<
" myEdgePos=" << myEdgePos <<
" dist=" << dist <<
"\n";
1787 const int oldDir = myDir;
1788 const MSLane* oldLane = myLane;
1789 myLane = myNLI.lane;
1791 const bool normalLane = (myLane ==
nullptr || myLane->getEdge().getFunction() ==
SumoXMLEdgeFunc::NORMAL || &myLane->getEdge() == myStage->getNextRouteEdge());
1794 <<
" ped=" << myPerson->
getID()
1795 <<
" moveToNextLane old=" << oldLane->
getID()
1796 <<
" new=" << (myLane ==
nullptr ?
"NULL" : myLane->getID())
1797 <<
" oldDir=" << oldDir
1798 <<
" newDir=" << myDir
1799 <<
" myEdgePos=" << myEdgePos
1803 if (myLane ==
nullptr) {
1804 myEdgePos = myStage->getArrivalPos();
1807 if (myStage->getRouteStep() == myStage->getRoute().end() - 1) {
1810 const bool arrived = myStage->moveToNextEdge(myPerson, currentTime, oldDir, normalLane ?
nullptr : &myLane->getEdge());
1816 myStage->activateEntryReminders(myPerson);
1817 assert(myNLI.lane != oldLane);
1819 std::cout <<
" nextLane=" << (myNLI.lane ==
nullptr ?
"NULL" : myNLI.lane->getID()) <<
"\n";
1821 if (myLane->isWalkingArea()) {
1824 assert(myWalkingAreaPath->shape.size() >= 2);
1826 std::cout <<
" mWAPath shape=" << myWalkingAreaPath->shape <<
" length=" << myWalkingAreaPath->length <<
"\n";
1828 }
else if (myNLI.link !=
nullptr) {
1830 myLane = myNLI.lane;
1831 assert(!myLane->isWalkingArea());
1832 myStage->moveToNextEdge(myPerson, currentTime, myDir, &myLane->getEdge());
1833 myWalkingAreaPath =
nullptr;
1839 const MSEdge* currRouteEdge = *myStage->getRouteStep();
1840 const MSEdge* nextRouteEdge = myStage->getNextRouteEdge();
1848 myStage->moveToNextEdge(myPerson, currentTime, oldDir,
nullptr);
1849 myLane = myNLI.lane;
1850 assert(myLane != 0);
1853 myWalkingAreaPath =
nullptr;
1855 throw ProcessError(
TLF(
"Disconnected walk for person '%'.", myPerson->getID()));
1859 myWalkingAreaPath =
nullptr;
1864 const double newLength = (myWalkingAreaPath ==
nullptr ? myLane->getLength() : myWalkingAreaPath->length);
1865 if (-dist > newLength) {
1872 myEdgePos = newLength + dist;
1877 std::cout <<
SIMTIME <<
" update myEdgePos ped=" << myPerson->getID()
1878 <<
" newLength=" << newLength
1880 <<
" myEdgePos=" << myEdgePos
1884 if (myDir != oldDir) {
1891 std::cout <<
SIMTIME <<
" transformY ped=" << myPerson->getID()
1893 <<
" newY=" << myPosLat
1895 <<
" od=" << oldDir <<
" nd=" << myDir
1896 <<
" offset=" << offset <<
"\n";
1899 myAngle = std::numeric_limits<double>::max();
1910 (
int)floor(stripes * factor),
1916 const int stripes = (int)obs.size();
1917 const int sMax = stripes - 1;
1921 const double vMax = (myStage->getConfiguredSpeed() >= 0
1922 ? myStage->getConfiguredSpeed()
1924 ? myLane->getVehicleMaxSpeed(myPerson)
1925 : myStage->getMaxSpeed(myPerson)));
1927 const int current = stripe();
1928 const int other = otherStripe();
1930 std::vector<double> distance(stripes);
1931 for (
int i = 0; i < stripes; ++i) {
1932 distance[i] = distanceTo(obs[i], obs[i].type ==
OBSTACLE_PED);
1935 std::vector<double> utility(stripes, 0);
1937 for (
int i = 0; i < stripes; ++i) {
1939 if (i == current && (!isWaitingToEnter() || stripe() != stripe(myPosLat))) {
1943 for (
int j = 0; j <= i; ++j) {
1948 for (
int j = i; j < stripes; ++j) {
1957 const bool onJunction = myLane->isWalkingArea() || myLane->isCrossing();
1960 for (
int i = 0; i < reserved; ++i) {
1964 for (
int i = sMax; i > sMax - reserved; --i) {
1969 for (
int i = 0; i < stripes; ++i) {
1970 if (obs[i].speed * myDir < 0) {
1973 utility[i - 1] -= 0.5;
1974 }
else if (myDir ==
BACKWARD && i < sMax) {
1975 utility[i + 1] -= 0.5;
1979 const double walkDist =
MAX2(0., distance[i]);
1981 const double expectedDist =
MIN2(vMax *
LOOKAHEAD_SAMEDIR, walkDist + obs[i].speed * myDir * lookAhead);
1982 if (expectedDist >= 0) {
1983 utility[i] += expectedDist;
1990 if (myDir ==
FORWARD && obs[0].speed < 0) {
1992 }
else if (myDir ==
BACKWARD && obs[sMax].speed > 0) {
1996 if (distance[current] > 0 && myWaitingTime == 0) {
1997 for (
int i = 0; i < stripes; ++i) {
2003 for (
int i = 0; i < stripes; ++i) {
2011 int chosen = current;
2012 for (
int i = 0; i < stripes; ++i) {
2018 const int next = (chosen == current ? current : (chosen < current ? current - 1 : current + 1));
2019 double xDist =
MIN3(distance[current], distance[other], distance[next]);
2020 if (next != chosen) {
2023 const int nextOther = chosen < current ? current - 2 : current + 2;
2024 xDist =
MIN2(xDist, distance[nextOther]);
2027 const double preferredGap = NUMERICAL_EPS;
2029 if (xSpeed < NUMERICAL_EPS) {
2033 std::cout <<
" xSpeedPotential=" << xSpeed <<
"\n";
2040 (xDist == distance[current] && obs[current].type >=
OBSTACLE_END)
2041 || (xDist == distance[other] && obs[other].type >=
OBSTACLE_END)
2042 || (xDist == distance[next] && obs[next].type >=
OBSTACLE_END))
2050 <<
" vehWait=" <<
STEPS2TIME(obs[current].vehicle ? obs[current].vehicle->getWaitingTime() : 0)
2053 if (myWaitingTime > ((myLane->isCrossing()
2055 || (myLane->isWalkingArea() && obs[current].vehicle !=
nullptr && obs[current].vehicle->getWaitingTime() >
jamTimeCrossing
2057 || (sMax == 0 && obs[0].speed * myDir < 0 && myWaitingTime >
jamTimeNarrow)
2068 }
else if (myAmJammed && stripe(myPosLat) >= 0 && stripe(myPosLat) <= sMax && xDist >=
MIN_STARTUP_DIST) {
2092 if (fabs(yDist) > NUMERICAL_EPS) {
2093 ySpeed = (yDist > 0 ?
2099 && stripe() == stripe(myPosLat)
2101 && !(myLane->isCrossing() || myLane->isWalkingArea())) {
2103 int stepAsideDir = myDir;
2104 if (myLane->getEdge().getLanes().size() > 1 || current > sMax / 2) {
2110 ySpeed = stepAsideDir * vMax;
2116 <<
" ped=" << myPerson->getID()
2117 <<
" edge=" << myStage->getEdge()->getID()
2118 <<
" x=" << myEdgePos
2119 <<
" y=" << myPosLat
2121 <<
" pvx=" << mySpeed
2122 <<
" cur=" << current
2123 <<
" cho=" << chosen
2127 <<
" dawdle=" << dawdle
2132 <<
" wTime=" << myStage->getWaitingTime()
2133 <<
" jammed=" << myAmJammed
2136 for (
int i = 0; i < stripes; ++i) {
2138 std::cout <<
" util=" << utility[i] <<
" dist=" << distance[i] <<
" o=" << o.
description;
2140 std::cout <<
" xF=" << o.
xFwd <<
" xB=" << o.
xBack <<
" v=" << o.
speed;
2143 std::cout <<
" current";
2145 if (i == other && i != current) {
2146 std::cout <<
" other";
2149 std::cout <<
" chosen";
2152 std::cout <<
" next";
2160 mySpeedLat = ySpeed;
2163 myWaitingToEnter =
false;
2167 myTotalWaitingTime +=
DELTA_T;
2169 myAngle = std::numeric_limits<double>::max();
2175 return MAX2(0.,
MIN2(1., myPerson->getVehicleType().getImpatience()
2183 return myRemoteXYPos;
2185 if (myLane ==
nullptr) {
2189 const double lateral_offset = -getLatOffset();
2190 if (myWalkingAreaPath ==
nullptr) {
2205 return myWalkingAreaPath->shape.positionAtOffset(myEdgePos, lateral_offset);
2207 const double rotationOffset = myDir ==
FORWARD ? 0 :
DEG2RAD(180);
2208 return myWalkingAreaPath->shape.sidePositionAtAngle(myEdgePos, lateral_offset, myWalkingAreaPath->angleOverride + rotationOffset);
2216 if (myAngle != std::numeric_limits<double>::max()) {
2219 if (myLane ==
nullptr) {
2223 if (myWalkingAreaPath !=
nullptr && myWalkingAreaPath->angleOverride !=
INVALID_DOUBLE) {
2224 return myWalkingAreaPath->angleOverride;
2226 const PositionVector& shp = myWalkingAreaPath ==
nullptr ? myLane->getShape() : myWalkingAreaPath->shape;
2227 double geomX = myWalkingAreaPath ==
nullptr ? myLane->interpolateLanePosToGeometryPos(myEdgePos) : myEdgePos;
2230 angle += atan2(mySpeedLat,
MAX2(mySpeed, NUMERICAL_EPS));
2232 angle -= atan2(mySpeedLat,
MAX2(mySpeed, NUMERICAL_EPS));
2244 return myNLI.lane ==
nullptr ? nullptr : &myNLI.lane->getEdge();
2250 return myNLI.lane !=
nullptr && myNLI.lane->
isCrossing() ? myNLI.lane :
nullptr;
2256 myEdgePos = pathLength - myEdgePos;
2257 myPosLat = usableWidth - myPosLat;
2258 myDir = -myWalkingAreaPath->dir;
2259 mySpeedLat = -mySpeedLat;
2265 myEdgePos = edgePos;
2276 int routeOffset = 0;
2277 bool laneOnRoute =
false;
2279 for (
const MSEdge* edge : myStage->getRoute()) {
2282 || edge->getFromJunction() == laneOnJunction) {
2289 throw ProcessError(
"Lane '" + lane->
getID() +
"' is not on the route of person '" + getID() +
"'.");
2292 if (lane->
isWalkingArea() && (myWalkingAreaPath ==
nullptr || myWalkingAreaPath->lane != lane)) {
2294 const MSEdge* prevEdge = myStage->getRoute()[routeOffset];
2295 const MSEdge* nextEdge = routeOffset + 1 < (int)myStage->getRoute().size() ? myStage->getRoute()[routeOffset + 1] :
nullptr;
2297 const double maxPos = guessed->
shape.
length() - NUMERICAL_EPS;
2298 if (lanePos > maxPos + POSITION_EPS || lanePos < -POSITION_EPS) {
2300 +
"' (fromLane='" + guessed->
from->
getID()
2301 +
"' toLane='" + guessed->
to->
getID() +
"') for person '" + getID() +
"' time=" +
time2string(t) +
".");
2304 lanePos =
MIN2(maxPos,
MAX2(NUMERICAL_EPS, lanePos));
2308 moveToXY(p, pos, lane, lanePos, lanePosLat, angle, routeOffset, newEdges, t);
2314 double lanePosLat,
double angle,
int routeOffset,
2317 assert(p == myPerson);
2318 assert(pm !=
nullptr);
2321 const double oldX = myEdgePos -
SPEED2DIST(mySpeed * myDir);
2322 const double tmp = myEdgePos;
2324 Position oldPos = getPosition(*myStage, t);
2330#ifdef DEBUG_MOVETOXY
2334 <<
" lane=" << lane->
getID()
2335 <<
" lanePos=" << lanePos
2336 <<
" lanePosLat=" << lanePosLat
2337 <<
" angle=" << angle
2338 <<
" routeOffset=" << routeOffset
2341 <<
" path=" << (myWalkingAreaPath ==
nullptr ?
"null" : (myWalkingAreaPath->from->getID() +
"->" + myWalkingAreaPath->to->getID())) <<
"\n";
2344 if (lane != myLane && myLane !=
nullptr && lane !=
nullptr) {
2348 if (lane !=
nullptr &&
2351 const MSEdge* old = myStage->getEdge();
2352 const MSLane* oldLane = myLane;
2353 if (lane != myLane) {
2357 if (edges.empty()) {
2359 myStage->setRouteIndex(myPerson, routeOffset);
2361 myStage->replaceRoute(myPerson, edges, routeOffset);
2364 myStage->moveToNextEdge(myPerson, t, myDir, &lane->
getEdge());
2370 if (myWalkingAreaPath ==
nullptr || myWalkingAreaPath->lane != lane) {
2372 myWalkingAreaPath =
guessPath(&lane->
getEdge(), old, myStage->getNextRouteEdge());
2373#ifdef DEBUG_MOVETOXY
2375 <<
" path=" << myWalkingAreaPath->from->getID() <<
"->" << myWalkingAreaPath->to->getID() <<
"\n";
2380 const Position relPos = myWalkingAreaPath->shape.transformToVectorCoordinates(pos);
2383 +
"' (fromLane='" + myWalkingAreaPath->from->getID()
2384 +
"' toLane='" + myWalkingAreaPath->to->getID() +
"') for person '" + getID() +
"' time=" +
time2string(t) +
".");
2385 myRemoteXYPos = pos;
2387 myEdgePos = relPos.
x();
2388 myPosLat = lateral_offset + relPos.
y();
2391 myWalkingAreaPath =
nullptr;
2392 myEdgePos = lanePos;
2393 myPosLat = lateral_offset - lanePosLat;
2398 if (myStage->getNextRouteEdge() !=
nullptr) {
2399 if (myStage->getEdge()->getToJunction() == myStage->getNextRouteEdge()->getFromJunction() ||
2400 myStage->getEdge()->getToJunction() == myStage->getNextRouteEdge()->getToJunction()) {
2407 if (angleDiff <= 90) {
2418 if (oldLane ==
nullptr || &oldLane->
getEdge() != &myLane->getEdge()) {
2419 const MSLane* sidewalk = getSidewalk<MSEdge, MSLane>(&myLane->getEdge(), p->
getVClass());
2422 myNLI =
getNextLane(*
this, sidewalk ==
nullptr ? myLane : sidewalk,
nullptr);
2423 myStage->activateEntryReminders(myPerson);
2424#ifdef DEBUG_MOVETOXY
2425 std::cout <<
" myNLI=" <<
Named::getIDSecure(myNLI.lane) <<
" link=" << (myNLI.link ==
nullptr ?
"NULL" : myNLI.link->getDescription()) <<
" dir=" << myNLI.
dir <<
"\n";
2428#ifdef DEBUG_MOVETOXY
2429 std::cout <<
" newRelPos=" <<
Position(myEdgePos, myPosLat) <<
" edge=" << myPerson->getEdge()->getID()
2430 <<
" newPos=" << myPerson->getPosition()
2431 <<
" latOffset=" << getLatOffset()
2432 <<
" oldAngle=" << oldAngle <<
" angleDiff=" << angleDiff <<
" newDir=" << myDir <<
"\n";
2434 if (oldLane == myLane) {
2435 mySpeed =
DIST2SPEED(fabs(oldX - myEdgePos));
2442 myRemoteXYPos = pos;
2451 if (myWalkingAreaPath !=
nullptr) {
2452 return myWalkingAreaPath->length;
2461 const double maxX = getMaxX(includeMinGap);
2462 const double minX = getMinX(includeMinGap);
2466 if ((obs.
xFwd >= maxX && obs.
xBack <= maxX) || (obs.
xFwd <= maxX && obs.
xFwd >= minX)) {
2480 for (
int i = 0; i < (int)into.size(); ++i) {
2482 std::cout <<
" i=" << i <<
" maxX=" << getMaxX(
true) <<
" minX=" << getMinX(
true)
2483 <<
" into=" << into[i].description <<
" iDist=" << distanceTo(into[i], into[i].type ==
OBSTACLE_PED)
2484 <<
" obs2=" << obs2[i].description <<
" oDist=" << distanceTo(obs2[i], obs2[i].type ==
OBSTACLE_PED) <<
"\n";
2486 const double dO = distanceTo(obs2[i], obs2[i].type ==
OBSTACLE_PED);
2487 const double dI = distanceTo(into[i], into[i].type ==
OBSTACLE_PED);
2502 for (
int i = 0; i < (int)into.size(); ++i) {
2503 int i2 = i + offset;
2504 if (i2 >= 0 && i2 < (
int)obs2.size()) {
2506 if (obs2[i2].xBack < into[i].xBack) {
2510 if (obs2[i2].xFwd > into[i].xFwd) {
2523 if (ignoreRedTime >= 0) {
2526 std::cout <<
SIMTIME <<
" ignoreRedTime=" << ignoreRedTime <<
" redDuration=" << redDuration <<
"\n";
2528 return ignoreRedTime > redDuration;
2543 if (ignoreYellowTime >= 0) {
2546 std::cout <<
SIMTIME <<
" ignoreYellowTime=" << ignoreYellowTime <<
" yellowDuration=" << yellowDuration <<
"\n";
2548 return ignoreYellowTime < yellowDuration;
2559 return myPerson->getVehicleType().getWidth();
2565 return myPerson->hasInfluencer() && myPerson->getInfluencer().isRemoteControlled();
2573 myVehicle(veh), myXWidth(xWidth), myYWidth(yWidth) {
2583 return myVehicle->
getID();
2593 return myXWidth > 0 ? myEdgePos - myXWidth : myEdgePos;
2598 return myXWidth > 0 ? myEdgePos : myEdgePos - myXWidth;
2607 std::set<MSPerson*> changedLane;
2608 myModel->moveInDirection(currentTime, changedLane,
FORWARD);
2609 myModel->moveInDirection(currentTime, changedLane,
BACKWARD);
2612 for (ActiveLanes::const_iterator it_lane = myModel->getActiveLanes().begin(); it_lane != myModel->getActiveLanes().end(); ++it_lane) {
2613 const MSLane* lane = it_lane->first;
2615 if (pedestrians.size() == 0) {
2620 for (
int ii = 0; ii < (int)pedestrians.size(); ++ii) {
2621 const PState& p = *pedestrians[ii];
std::vector< const MSEdge * > ConstMSEdgeVector
std::vector< MSEdge * > MSEdgeVector
#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)
const std::string DEFAULT_PEDTYPE_ID
@ SVC_PEDESTRIAN
pedestrian
@ SUMO_ATTR_JM_DRIVE_AFTER_RED_TIME
@ SUMO_ATTR_JM_DRIVE_AFTER_YELLOW_TIME
bool gDebugFlag1
global utility flags for debugging
const double INVALID_DOUBLE
invalid double
std::pair< int, double > MMVersion
(M)ajor/(M)inor version for written networks and default version for loading
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
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
bool isWalkingArea() const
SVCPermissions getPermissions() const
Returns the vehicle class permissions for this lane.
const std::vector< IncomingLaneInfo > & getIncomingLanes() const
bool isPriorityCrossing() 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
double getVehicleMaxSpeed(const SUMOTrafficObject *const veh) const
Returns the lane's maximum speed, given a vehicle's speed limit adaptation.
MSLane * getCanonicalSuccessorLane() const
void requireCollisionCheck()
require another collision check due to relevant changes in the simulation
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 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, double dist=-1) const
Returns the information whether the link may be passed.
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.
std::vector< LinkLeader > LinkLeaders
MSLane * getViaLaneOrLane() const
return the via lane if it exists and the lane otherwise
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.
MMVersion getNetworkVersion() const
return the network version
MSPedestrianRouter & getPedestrianRouter(int rngIndex, const Prohibitions &prohibited={}) const
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
virtual MSTransportableControl & getPersonControl()
Returns the person control.
std::vector< MSPModel_InteractingState * > Pedestrians
Pedestrians & getPedestrians(const MSLane *lane)
retrieves the pedestrian vector for the given lane (may be empty)
ActiveLanes myActiveLanes
store of all lanes which have pedestrians on them
bool myAmActive
whether an event for pedestrian processing was added
static bool usingInternalLanesStatic()
int myNumActivePedestrians
the total number of active pedestrians
void registerActive()
increase the number of active pedestrians
virtual void remove(MSTransportableStateAdapter *state)
remove the specified person from the pedestrian simulation
static void unregisterCrossingApproach(const MSPModel_InteractingState &ped, const MSLane *crossing)
unregister pedestrian approach with the junction model
Container for pedestrian state and individual position update function.
SUMOTime myWaitingTime
the consecutive time spent at speed 0
MSPerson * myPerson
the person who is being represented
MSStageMoving * getStage() const
return the current stage
int myDir
the walking direction on the current lane (1 forward, -1 backward)
double myEdgePos
the advancement along the current lane
double getEdgePos(SUMOTime) const
abstract methods inherited from MSTransportableStateAdapter
MSPerson * getPerson() const
return the represented person
virtual const std::string & getID() const
return ID of the person (or sometimes vehicle) being represented
const Position & getRemotePosition() const
return the remote position if being controlled by TraCI or JuPedSim
const MSLane * myLane
the current lane of this pedestrian
double mySpeed
the current walking speed
MSStageMoving * myStage
the current stage of this pedestrian
double myPosLat
the orthogonal shift on the current lane
double mySpeedLat
the current lateral walking speed
bool isWaitingToEnter() const
whether the person still waits to entere the network
bool myWaitingToEnter
whether the pedestrian is waiting to start its walk
const MSLane * getLane() const
the current lane of the transportable
int getDirection() const
return the walking direction (FORWARD, BACKWARD, UNDEFINED_DIRECTION)
bool myAmJammed
whether the person is jammed
double getSpeed(const MSStageMoving &) const
return the current speed of the transportable
bool isJammed() const
whether the transportable is jammed
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
const WalkingAreaPath * myWalkingAreaPath
the current walkingAreaPath or 0
PState()
constructor for PStateVehicle
double distToLaneEnd() const
the absolute distance to the end of the lane in walking direction (or to the arrivalPos)
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
const MSLane * getNextCrossing() const
placeholder function for the accessing the next crossing
virtual double getWidth() const
return the person width
void saveState(std::ostringstream &out)
Saves the current state into the given stream.
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
void reverse(const double pathLength, const double usableWidth)
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
Position getPosition(const MSStageMoving &stage, SUMOTime now) const
return the network coordinate of the transportable
NextLaneInfo myNLI
information about the upcoming lane
double getAngle(const MSStageMoving &stage, SUMOTime now) const
return the current orientation in degrees
void reset(const double edgePos, const double latPos)
double getImpatience() const
returns the impatience
double distanceTo(const Obstacle &obs, const bool includeMinGap=true) const
bool stopForYellow(const MSLink *link) const
whether the pedestrian should stop at a yellow light
double getLength() const
return the length of the pedestrian
void walk(const Obstacles &obs)
perform position update
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 ID of the person (or sometimes vehicle) being represented
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 movement model using stripes on sidewalks.
static const double MIN_STARTUP_DIST
the minimum distance to the next obstacle in order to start walking after stopped
static void registerCrossingApproach(const PState &ped, const MSLane *crossing, const MSLane *beforeWA)
register pedestrian approach with the junction model
static double RESERVE_FOR_ONCOMING_FACTOR
fraction of the leftmost lanes to reserve for oncoming traffic
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 double posLatConversion(const double posLat, const double laneWidth)
Convert the striping to the vehicle lateral position and vice versa.
static SUMOTime jamTimeCrossing
void moveInDirection(SUMOTime currentTime, std::set< MSPerson * > &changedLane, int dir)
move all pedestrians forward and advance to the next lane if applicable
static bool USE_NET_SPEEDS
whether to use speed limits embedded in the network
static void transformToCurrentLanePositions(Obstacles &o, int currentDir, int nextDir, double currentLength, double nextLength)
static int myWalkingAreaDetail
intermediate points to smooth out lanes within the walkingarea
static const double LOOKAHEAD_SAMEDIR
the distance (in seconds) to look ahead for changing stripes
static double RESERVE_FOR_ONCOMING_MAX
std::map< const MSLane *, Obstacles, ComparatorNumericalIdLess > NextLanesObstacles
static double minGapToVehicle
the safety buffer to vehicles
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 const double LOOKAHEAD_ONCOMING_DIST
the distance (in m) to look ahead for obstacles on a subsequent edge
static void initWalkingAreaPaths(const MSNet *net)
static bool addCrossingVehs(const MSLane *crossing, int stripes, double lateral_offset, int dir, Obstacles &crossingVehs, bool prio, bool flipY)
add vehicles driving across
static const double LOOKAROUND_VEHICLES
the distance (in m) to look around for vehicles
static const double SQUEEZE
the factor by which pedestrian width is reduced when sqeezing past each other
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)
static const WalkingAreaPath * guessPath(const MSEdge *walkingArea, const MSEdge *before, const MSEdge *after)
static int getReserved(int stripes, double factor)
static SUMOTime jamTime
the time threshold before becoming jammed
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 jamFactor
the factor on speed when jammed
static double stripeWidth
model parameters
static const double MAX_WAIT_TOLERANCE
the time pedestrians take to reach maximum impatience
static Obstacles getVehicleObstacles(const MSLane *lane, int dir, PState *ped=0)
retrieve vehicle obstacles on the given lane
static const double OBSTRUCTED_PENALTY
the utility penalty for obstructed (physically blocking me) stripes (corresponds to meters)
static const MSLane * getNextWalkingArea(const MSLane *currentLane, const int dir, const MSLink *&link)
return the next walkingArea in the given direction
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
the utility penalty for moving sideways (corresponds to meters)
std::vector< Obstacle > Obstacles
static const double DIST_BEHIND
MSPModel_Striping(const OptionsCont &oc, MSNet *net)
Constructor (it should not be necessary to construct more than one instance)
static Obstacles getNeighboringObstacles(const Pedestrians &pedestrians, int egoIndex, int stripes)
static bool myLegacyPosLat
use old style departPosLat interpretation
static void addCloserObstacle(Obstacles &obs, double x, int stripe, int numStripes, const std::string &id, double width, int dir, ObstacleType type)
static double dawdling
the factor for random slow-down
static int numStripes(const MSLane *lane)
return the maximum number of pedestrians walking side by side
static const double OBSTRUCTION_THRESHOLD
the minimum utility that indicates obstruction
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
the fraction of forward speed to be used for lateral movemenk
static const double INAPPROPRIATE_PENALTY
the utility penalty for inappropriate (reserved for oncoming traffic or may violate my min gap) strip...
static const double ONCOMING_CONFLICT_PENALTY
the utility penalty for oncoming conflicts on stripes (corresponds to meters)
static const double LOOKAHEAD_ONCOMING
the distance (in seconds) to look ahead for changing stripes (regarding oncoming pedestrians)
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, int &passedEdges)
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
double getTimegapCrossing() const
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 int getRoutePosition() const
return index of current edge within route
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
const std::vector< const MSEdge * > & getRoute() const
int getDepartLane() const
double getConfiguredSpeed() const
Returns the configured speed in this stage.
virtual bool moveToNextEdge(MSTransportable *transportable, SUMOTime currentTime, int prevDir, MSEdge *nextInternal=nullptr, const bool isReplay=false)=0
move forward and return whether the transportable arrived
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
bool checkPersonCapacity() const
MSPModel * getMovementModel()
Returns the default movement model for this kind of transportables.
void registerJammed()
register a jammed transportable
Position getPosition(const double) const override
Return current position (x/y, cartesian)
SUMOVehicleClass getVClass() const override
Returns the object's access class.
const SUMOVTypeParameter & getVTypeParameter() const override
Returns the object's "vehicle" type parameter.
bool isPerson() const override
Whether it is a person.
MSStageType getCurrentStageType() const
the current stage type of the transportable
const MSVehicleType & getVehicleType() const override
Returns the object's "vehicle" type.
const MSEdge * getEdge() const override
Returns the current edge.
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.
SUMOTime getWaitingTime(const bool accumulated=false) const
Returns the SUMOTime waited (speed was lesser than 0.1m/s)
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, const SUMOVTypeParameter &pars, std::vector< const E * > &into, bool allEdges=false) const
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 (in radians bet...
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 amount
double angleAt2D(int pos) const
get angle in certain position of position vector (in radians between -M_PI and M_PI)
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)
std::map< const E *, RouterProhibition > Prohibitions
#define UNUSED_PARAMETER(x)
int dir
the direction on the next lane
const MSLink * link
the link from the current lane to the next lane
const MSLane * lane
the next lane to be used
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
const SUMOVehicle * vehicle
a pointer to the vehicle if this obstacle is one
ObstacleType type
whether this obstacle denotes a border, a vehicle or a pedestrian
double xBack
maximal position on the current lane in backward direction
const PositionVector shape