67 #define DEBUG_COND(ego) (ego!=nullptr && ego->isSelected())
68 #define DEBUG_COND_FIND(ego) (ego.isSelected())
69 #define DEBUG_COND_ENCOUNTER(e) (e->ego != nullptr && e->ego->isSelected() && e->foe != nullptr && e->foe->isSelected())
75 #define DEFAULT_RANGE 50.0
81 #define AVAILABLE_SSMS "TTC DRAC PET BR SGAP TGAP"
83 #define DEFAULT_THRESHOLD_TTC 3.
84 #define DEFAULT_THRESHOLD_DRAC 3.
85 #define DEFAULT_THRESHOLD_PET 2.
87 #define DEFAULT_THRESHOLD_BR 0.0
88 #define DEFAULT_THRESHOLD_SGAP 0.2
89 #define DEFAULT_THRESHOLD_TGAP 0.5
91 #define DEFAULT_EXTRA_TIME 5.
108 out <<
"NOCONFLICT_AHEAD";
114 out <<
"FOLLOWING_FOLLOWER";
117 out <<
"FOLLOWING_LEADER";
120 out <<
"ON_ADJACENT_LANES";
126 out <<
"MERGING_LEADER";
129 out <<
"MERGING_FOLLOWER";
132 out <<
"MERGING_ADJACENT";
138 out <<
"CROSSING_LEADER";
141 out <<
"CROSSING_FOLLOWER";
144 out <<
"EGO_ENTERED_CONFLICT_AREA";
147 out <<
"FOE_ENTERED_CONFLICT_AREA";
150 out <<
"BOTH_ENTERED_CONFLICT_AREA";
153 out <<
"EGO_LEFT_CONFLICT_AREA";
156 out <<
"FOE_LEFT_CONFLICT_AREA";
159 out <<
"BOTH_LEFT_CONFLICT_AREA";
162 out <<
"FOLLOWING_PASSED";
165 out <<
"MERGING_PASSED";
175 out <<
"unknown type (" << int(type) <<
")";
186 std::set<MSDevice_SSM*, ComparatorNumericalIdLess>*
MSDevice_SSM::myInstances =
new std::set<MSDevice_SSM*, ComparatorNumericalIdLess>();
192 const std::set<MSDevice_SSM*, ComparatorNumericalIdLess>&
202 device->resetEncounters();
203 device->flushConflicts(
true);
204 device->flushGlobalMeasures();
220 oc.
doRegister(
"device.ssm.measures", Option::makeUnsetWithDefault<Option_String, std::string>(
""));
221 oc.
addDescription(
"device.ssm.measures",
"SSM Device",
"Specifies which measures will be logged (as a space separated sequence of IDs in ('TTC', 'DRAC', 'PET')).");
222 oc.
doRegister(
"device.ssm.thresholds", Option::makeUnsetWithDefault<Option_String, std::string>(
""));
223 oc.
addDescription(
"device.ssm.thresholds",
"SSM Device",
"Specifies thresholds corresponding to the specified measures (see documentation and watch the order!). Only events exceeding the thresholds will be logged.");
224 oc.
doRegister(
"device.ssm.trajectories", Option::makeUnsetWithDefault<Option_Bool, bool>(
false));
225 oc.
addDescription(
"device.ssm.trajectories",
"SSM Device",
"Specifies whether trajectories will be logged (if false, only the extremal values and times are reported, this is the default).");
227 oc.
addDescription(
"device.ssm.range",
"SSM Device",
"Specifies the detection range in meters (default is " + ::
toString(
DEFAULT_RANGE) +
"m.). For vehicles below this distance from the equipped vehicle, SSM values are traced.");
229 oc.
addDescription(
"device.ssm.extratime",
"SSM Device",
"Specifies the time in seconds to be logged after a conflict is over (default is " + ::
toString(
DEFAULT_EXTRA_TIME) +
"secs.). Required >0 if PET is to be calculated for crossing conflicts.");
230 oc.
doRegister(
"device.ssm.file", Option::makeUnsetWithDefault<Option_String, std::string>(
""));
231 oc.
addDescription(
"device.ssm.file",
"SSM Device",
"Give a global default filename for the SSM output.");
232 oc.
doRegister(
"device.ssm.geo", Option::makeUnsetWithDefault<Option_Bool, bool>(
false));
233 oc.
addDescription(
"device.ssm.geo",
"SSM Device",
"Whether to use coordinates of the original reference system in output (default is false).");
234 oc.
doRegister(
"device.ssm.write-positions", Option::makeUnsetWithDefault<Option_Bool, bool>(
false));
235 oc.
addDescription(
"device.ssm.write-positions",
"SSM Device",
"Whether to write positions (coordinates) for each timestep.");
236 oc.
doRegister(
"device.ssm.write-lane-positions", Option::makeUnsetWithDefault<Option_Bool, bool>(
false));
237 oc.
addDescription(
"device.ssm.write-lane-positions",
"SSM Device",
"Whether to write lanes and their positions for each timestep.");
246 std::ifstream strm(file.c_str());
248 throw ProcessError(
"Could not load names of edges for filtering SSM device output from '" + file +
"'.");
251 while (strm.good()) {
256 std::string edgeID = line.substr(5);
258 if (edge !=
nullptr) {
261 WRITE_WARNING(
"Unknown edge ID '" + edgeID +
"' in SSM device edge filter (" + file +
"): " + line);
265 std::string junctionID = line.substr(9);
267 if (junction !=
nullptr) {
272 WRITE_WARNING(
"Unknown junction ID '" + junctionID +
"' in SSM device edge filter (" + file +
"): " + line);
274 }
else if (line ==
"") {
276 WRITE_WARNING(
"Cannot interpret line in SSM device edge filter (" + file +
"): " + line);
286 WRITE_WARNING(
"SSM Device for vehicle '" + v.
getID() +
"' will not be built. (SSMs not supported in MESO)");
290 std::string deviceID =
"ssm_" + v.
getID();
295 std::map<std::string, double> thresholds;
321 MSDevice_SSM* device =
new MSDevice_SSM(v, deviceID, file, thresholds, trajectories, range, extraTime, useGeo, writePos, writeLanesPos);
322 into.push_back(device);
335 egoID(_ego->getID()),
336 foeID(_foe->getID()),
339 currentType(ENCOUNTER_TYPE_NOCONFLICT_AHEAD),
340 remainingExtraTime(extraTime),
348 closingRequested(false) {
349 #ifdef DEBUG_ENCOUNTER
351 std::cout <<
"\n" <<
SIMTIME <<
" Constructing encounter of '" <<
ego->
getID() <<
"' and '" <<
foe->
getID() <<
"'" << std::endl;
357 #ifdef DEBUG_ENCOUNTER
359 std::cout <<
"\n" <<
SIMTIME <<
" Destroying encounter of '" << egoID <<
"' and '" << foeID <<
"' (begin was " << begin <<
")" << std::endl;
368 Position conflictPoint,
double egoDistToConflict,
double foeDistToConflict,
double ttc,
double drac, std::pair<double, double> pet) {
369 #ifdef DEBUG_ENCOUNTER
371 std::cout << time <<
" Adding data point for encounter of '" << egoID <<
"' and '" << foeID <<
"':\n"
372 <<
"type=" << type <<
", egoDistToConflict=" << (egoDistToConflict ==
INVALID_DOUBLE ?
"NA" :
::toString(egoDistToConflict))
381 timeSpan.push_back(time);
382 typeSpan.push_back(type);
383 egoTrajectory.x.push_back(egoX);
384 egoTrajectory.lane.push_back(egoLane);
385 egoTrajectory.lanePos.push_back(egoLanePos);
386 egoTrajectory.v.push_back(egoV);
387 foeTrajectory.x.push_back(foeX);
388 foeTrajectory.lane.push_back(foeLane);
389 foeTrajectory.lanePos.push_back(foeLanePos);
390 foeTrajectory.v.push_back(foeV);
391 conflictPointSpan.push_back(conflictPoint);
392 egoDistsToConflict.push_back(egoDistToConflict);
393 foeDistsToConflict.push_back(foeDistToConflict);
395 TTCspan.push_back(ttc);
399 minTTC.pos = conflictPoint;
403 DRACspan.push_back(drac);
405 maxDRAC.value = drac;
407 maxDRAC.pos = conflictPoint;
412 PET.value = pet.second;
413 PET.time = pet.first;
414 PET.pos = conflictPoint;
422 remainingExtraTime = value;
428 remainingExtraTime -= amount;
434 return remainingExtraTime;
452 egoLeftConflict(false),
453 foeLeftConflict(false),
469 std::cout <<
"\n" <<
SIMTIME <<
" Device '" <<
getID() <<
"' updateAndWriteOutput()\n"
470 <<
" Holder is off-road! Calling resetEncounters()."
483 std::cout <<
"\n" <<
SIMTIME <<
" Device '" <<
getID() <<
"' update()\n"
493 const MSEdge* egoEdge = &((*myHolderMS).getLane()->getEdge());
502 if (foes.size() > 0) {
503 std::cout <<
"Scanned surroundings: Found potential foes:\n";
504 for (FoeInfoMap::const_iterator i = foes.begin(); i != foes.end(); ++i) {
505 std::cout << i->first->getID() <<
" ";
507 std::cout << std::endl;
509 std::cout <<
"Scanned surroundings: No potential conflict could be identified." << std::endl;
546 double leaderSearchDist = 0;
547 std::pair<const MSVehicle*, double> leader(
nullptr, 0.);
555 if (leaderSearchDist > 0.) {
561 if (leader.first ==
nullptr || leader.second < 0) {
592 std::cout <<
"\n" <<
SIMTIME <<
" Device '" <<
getID() <<
"' createEncounters()" << std::endl;
593 std::cout <<
"New foes:\n";
594 for (FoeInfoMap::const_iterator vi = foes.begin(); vi != foes.end(); ++vi) {
595 std::cout << vi->first->getID() <<
"\n";
597 std::cout << std::endl;
601 for (FoeInfoMap::const_iterator foe = foes.begin(); foe != foes.end(); ++foe) {
608 assert(myOldestActiveEncounterBegin <= e->begin);
631 std::cout <<
"\n" <<
SIMTIME <<
" Device '" <<
getID() <<
"' processEncounters(forceClose = " << forceClose <<
")" << std::endl;
632 std::cout <<
"Currently present foes:\n";
633 for (FoeInfoMap::const_iterator vi = foes.begin(); vi != foes.end(); ++vi) {
634 std::cout << vi->first->getID() <<
"\n";
636 std::cout << std::endl;
652 if (foes.find(e->
foe) != foes.end()) {
664 std::cout <<
" Requesting encounter closure because both left conflict area of previous encounter but another encounter lies ahead." << std::endl;
678 std::cout <<
" Requesting encounter closure because..." << std::endl;
680 std::cout <<
" ... extra time elapsed." << std::endl;
681 }
else if (forceClose) {
682 std::cout <<
" ... closing was forced." << std::endl;
684 std::cout <<
" ... foe disappeared." << std::endl;
695 double eBegin = e->
begin;
720 std::cout <<
SIMTIME <<
" qualifiesAsConflict() for encounter of vehicles '"
740 assert(e->
size() > 0);
748 std::cout <<
SIMTIME <<
" closeEncounter() of vehicles '"
750 <<
"' (was ranked as " << (wasConflict ?
"conflict" :
"non-conflict") <<
")" << std::endl;
758 std::cout <<
"pastConflictsQueue of veh '" <<
myHolderMS->
getID() <<
"':\n";
766 std::cout <<
" Conflict with foe '" << c->foe <<
"' (time=" << c->begin <<
"-" << c->end <<
")\n";
768 if (c->begin < lastBegin) {
769 std::cout <<
" Queue corrupt...\n";
772 lastBegin = c->begin;
774 std::cout << std::endl;
787 #ifdef DEBUG_ENCOUNTER
789 std::cout <<
SIMTIME <<
" updateEncounter() of vehicles '" << e->
egoID <<
"' and '" << e->
foeID <<
"'\n";
816 #ifdef DEBUG_ENCOUNTER
818 std::cout <<
SIMTIME <<
" Encounter of vehicles '" << e->
egoID <<
"' and '" << e->
foeID <<
"' does not imply any conflict.\n";
849 if (e->
size() == 0) {
850 #ifdef DEBUG_ENCOUNTER
852 std::cout <<
SIMTIME <<
" type when creating encounter: " << eInfo.
type <<
"\n";
895 std::cout <<
SIMTIME <<
" determineConflictPoint()" << std::endl;
905 assert(e->
size() > 0);
926 std::cout <<
"No conflict point associated with encounter type " << type << std::endl;
934 std::cout <<
" Conflict at " << eInfo.
conflictPoint << std::endl;
949 std::cout <<
SIMTIME <<
" estimateConflictTimes() for ego '" << e->
egoID <<
"' and foe '" << e->
foeID <<
"'\n"
950 <<
" encounter type: " << eInfo.
type <<
"\n"
962 std::cout <<
" encouter type " << type <<
" -> no exit times to be calculated."
974 std::cout <<
" encouter type " << type <<
" -> no entry/exit times to be calculated."
1061 std::cout <<
" -> ego is estimated leader at conflict entry."
1070 std::cout <<
" -> foe is estimated leader at conflict entry."
1086 std::cout <<
SIMTIME <<
" computeSSMs() for vehicles '"
1088 <<
"'" << std::endl;
1118 std::stringstream ss;
1119 ss <<
"'" << type <<
"'";
1120 WRITE_WARNING(
"Unknown or undetermined encounter type at computeSSMs(): " + ss.str());
1126 std::cout <<
"computeSSMs() for encounter of vehicles '" << e->
egoID <<
"' and '" << e->
foeID <<
"':\n"
1139 if (e->
size() == 0) {
1143 std::pair<double, double>& pet = eInfo.
pet;
1147 std::cout <<
SIMTIME <<
" determinePET() for encounter of vehicles '" << e->
egoID <<
"' and '" << e->
foeID <<
"'"
1162 std::cout <<
"PET for crossing encounter already calculated as " << e->
PET.
value
1205 std::cout <<
"determinePET: Both passed conflict area in the same step. Assume collision"
1220 std::cout <<
"Calculated PET = " << pet.second <<
" (at t=" << pet.first <<
")"
1227 std::cout <<
"PET unappropriate for merging and pre-crossing situations. No calculation performed."
1239 double& ttc = eInfo.
ttc;
1240 double& drac = eInfo.
drac;
1244 std::cout <<
SIMTIME <<
" determineTTCandDRAC() for encounter of vehicles '" << e->
egoID <<
"' and '" << e->
foeID <<
"' (type = " << eInfo.
type <<
")"
1287 std::cout <<
" Conflict times with constant speed extrapolation for merging situation:\n "
1302 std::cout <<
" No TTC and DRAC computed as one vehicle is stopped." << std::endl;
1307 double leaderEntryTime =
MIN2(egoEntryTime, foeEntryTime);
1308 double followerEntryTime =
MAX2(egoEntryTime, foeEntryTime);
1309 double leaderExitTime = leaderEntryTime == egoEntryTime ? egoExitTime : foeExitTime;
1316 if (leaderExitTime >= followerEntryTime) {
1319 ttc =
computeTTC(followerConflictDist, followerSpeed, 0.);
1324 drac =
computeDRAC(followerConflictDist, followerSpeed, 0.);
1330 std::cout <<
" Extrapolation predicts collision *at* merge point with TTC=" << ttc
1331 <<
", drac=" << drac << std::endl;
1338 double gapAfterMerge = followerConflictDist - leaderExitTime * followerSpeed;
1339 assert(gapAfterMerge >= 0);
1342 double ttcAfterMerge =
computeTTC(gapAfterMerge, followerSpeed, leaderSpeed);
1347 double g0 = followerConflictDist - leaderConflictDist - leaderLength;
1350 assert(leaderSpeed - followerSpeed > 0);
1355 drac =
computeDRAC(g0, followerSpeed, leaderSpeed);
1363 std::cout <<
" Extrapolation does not predict any collision." << std::endl;
1365 std::cout <<
" Extrapolation predicts collision *after* merge point with TTC="
1407 std::stringstream ss;
1408 ss <<
"'" << type <<
"'";
1409 WRITE_WARNING(
"Underspecified or unknown encounter type in MSDevice_SSM::determineTTCandDRAC(): " + ss.str());
1429 std::cout <<
"computeTTC() with gap=" << gap <<
", followerSpeed=" << followerSpeed <<
", leaderSpeed=" << leaderSpeed
1435 double dv = followerSpeed - leaderSpeed;
1454 double dv = followerSpeed - leaderSpeed;
1458 assert(followerSpeed > 0.);
1459 return 0.5 * dv * dv / gap;
1475 #ifdef DEBUG_SSM_DRAC
1477 std::cout <<
SIMTIME <<
"computeDRAC() with"
1478 <<
"\ndEntry1=" << dEntry1 <<
", dEntry2=" << dEntry2
1479 <<
", dExit1=" << dExit1 <<
", dExit2=" << dExit2
1480 <<
",\nv1=" << v1 <<
", v2=" << v2
1485 if (dExit1 <= 0. || dExit2 <= 0.) {
1487 #ifdef DEBUG_SSM_DRAC
1489 std::cout <<
"One already left conflict area -> drac == 0." << std::endl;
1494 if (dEntry1 <= 0. && dEntry2 <= 0.) {
1496 #ifdef DEBUG_SSM_DRAC
1498 std::cout <<
"Both entered conflict area but neither left. -> collision!" << std::endl;
1504 double drac = std::numeric_limits<double>::max();
1507 #ifdef DEBUG_SSM_DRAC
1509 std::cout <<
"Ego could break..." << std::endl;
1514 drac =
MIN2(drac, 2 * (v1 - dEntry1 / tExit2) / tExit2);
1515 #ifdef DEBUG_SSM_DRAC
1517 std::cout <<
" Foe expected to leave in " << tExit2 <<
"-> Ego needs drac=" << drac << std::endl;
1525 #ifdef DEBUG_SSM_DRAC
1527 std::cout <<
" Foe is expected stop on conflict area -> Ego needs drac=" << drac << std::endl;
1532 #ifdef DEBUG_SSM_DRAC
1534 std::cout <<
" Foe is expected stop before conflict area -> no drac computation for ego (will be done for foe if applicable)" << std::endl;
1543 #ifdef DEBUG_SSM_DRAC
1545 std::cout <<
"Foe could break..." << std::endl;
1550 #ifdef DEBUG_SSM_DRAC
1552 std::cout <<
" Ego expected to leave in " << tExit1 <<
"-> Foe needs drac=" << (2 * (v2 - dEntry2 / tExit1) / tExit1) << std::endl;
1555 drac =
MIN2(drac, 2 * (v2 - dEntry2 / tExit1) / tExit1);
1560 #ifdef DEBUG_SSM_DRAC
1562 std::cout <<
" Ego is expected stop on conflict area -> Foe needs drac=" <<
computeDRAC(dEntry2, v2, 0) << std::endl;
1568 #ifdef DEBUG_SSM_DRAC
1570 std::cout <<
" Ego is expected stop before conflict area -> no drac computation for foe (done for ego if applicable)" << std::endl;
1591 #ifdef DEBUG_ENCOUNTER
1593 std::cout <<
SIMTIME <<
" checkConflictEntryAndExit() for encounter of vehicles '" << e->
egoID <<
"' and '" << e->
foeID <<
"'"
1603 if (e->
size() == 0) {
1607 if (egoPastConflictExit) {
1608 if (foePastConflictExit) {
1610 }
else if (foePastConflictEntry) {
1615 }
else if (foePastConflictExit) {
1616 if (egoPastConflictEntry) {
1623 if (egoPastConflictEntry) {
1624 if (foePastConflictEntry) {
1629 }
else if (foePastConflictEntry) {
1657 #ifdef DEBUG_ENCOUNTER
1673 #ifdef DEBUG_ENCOUNTER
1691 #ifdef DEBUG_ENCOUNTER
1709 #ifdef DEBUG_ENCOUNTER
1726 #ifdef DEBUG_ENCOUNTER
1728 std::cout <<
SIMTIME <<
" updatePassedEncounter() for vehicles '" << e->
egoID <<
"' and '" << e->
foeID <<
"'\n";
1732 if (foeInfo ==
nullptr) {
1735 #ifdef DEBUG_ENCOUNTER
1751 #ifdef DEBUG_ENCOUNTER
1753 std::cout <<
" This encounter wasn't classified as a potential conflict lately.\n";
1756 if (foeInfo ==
nullptr) {
1762 std::cout <<
" Requesting encounter closure because foeInfo==nullptr" << std::endl;
1766 #ifdef DEBUG_ENCOUNTER
1768 std::cout <<
" Closing encounter.\n";
1778 #ifdef DEBUG_ENCOUNTER
1780 std::cout <<
" Encounter was previously classified as a follow/lead situation.\n";
1789 #ifdef DEBUG_ENCOUNTER
1791 std::cout <<
" Encounter was previously classified as a merging situation.\n";
1806 #ifdef DEBUG_ENCOUNTER
1808 std::cout <<
" Encounter was previously classified as a crossing situation of type " << lastPotentialConflictType <<
".\n";
1826 #ifdef DEBUG_ENCOUNTER
1841 if ((!egoEnteredConflict) && !foeEnteredConflict) {
1845 eInfo.
type = lastPotentialConflictType;
1846 }
else if (egoEnteredConflict && !foeEnteredConflict) {
1848 }
else if ((!egoEnteredConflict) && foeEnteredConflict) {
1854 if ((!egoLeftConflict) && !foeLeftConflict) {
1858 }
else if (egoLeftConflict && !foeLeftConflict) {
1862 }
else if ((!egoLeftConflict) && foeLeftConflict) {
1877 #ifdef DEBUG_ENCOUNTER
1879 std::cout <<
" Updated classification: " << eInfo.
type <<
"\n";
1888 #ifdef DEBUG_ENCOUNTER
1890 std::cout <<
"classifyEncounter() called.\n";
1893 if (foeInfo ==
nullptr) {
1912 #ifdef DEBUG_ENCOUNTER
1914 std::cout <<
" Ongoing crossing conflict will be traced by passedEncounter().\n";
1930 double foeDistToConflictLane;
1933 #ifdef DEBUG_ENCOUNTER
1935 std::cout <<
" egoConflictLane='" << (egoConflictLane == 0 ?
"NULL" : egoConflictLane->
getID()) <<
"'\n"
1936 <<
" foeConflictLane='" << (foeConflictLane == 0 ?
"NULL" : foeConflictLane->
getID()) <<
"'\n"
1937 <<
" egoDistToConflictLane=" << egoDistToConflictLane
1938 <<
" foeDistToConflictLane=" << foeDistToConflictLane
1953 if (foeConflictLane ==
nullptr) {
1956 #ifdef DEBUG_ENCOUNTER
1958 std::cout <<
"-> Encounter type: No conflict.\n";
1963 if (egoConflictLane == egoLane) {
1967 if (foeLane == egoLane) {
1969 if (!egoOpposite && !foeOpposite) {
1977 #ifdef DEBUG_ENCOUNTER
1979 std::cout <<
"-> Encounter type: Lead/follow-situation on non-internal lane '" << egoLane->
getID() <<
"'\n";
1982 }
else if (egoOpposite && foeOpposite) {
1990 #ifdef DEBUG_ENCOUNTER
1992 std::cout <<
"-> Encounter type: Lead/follow-situation while both are driving in the opposite direction on non-internal lane '" << egoLane->
getID() <<
"'\n";
2013 #ifdef DEBUG_ENCOUNTER
2015 std::cout <<
"-> Encounter type: oncoming on non-internal lane '" << egoLane->
getID() <<
"'\n";
2024 #ifdef DEBUG_ENCOUNTER
2026 std::cout <<
"-> Encounter type: " << type << std::endl;
2031 if (!egoOpposite && !foeOpposite) {
2034 assert(egoDistToConflictLane <= 0);
2036 if (foeConflictLane == egoLane) {
2040 #ifdef DEBUG_ENCOUNTER
2042 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' leads foe '"
2043 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2049 #ifdef DEBUG_ENCOUNTER
2051 std::cout <<
"-> Encounter type: " << type << std::endl;
2056 }
else if (egoOpposite && foeOpposite) {
2068 #ifdef DEBUG_ENCOUNTER
2070 std::cout <<
"-> Encounter type: Lead/follow-situation while both are driving in the opposite direction on non-internal lane '" << egoLane->
getID() <<
"'\n";
2094 #ifdef DEBUG_ENCOUNTER
2096 std::cout <<
"-> Encounter type: oncoming on non-internal lane '" << egoLane->
getID() <<
"'\n";
2108 assert(foeDistToConflictLane <= 0);
2109 if (foeLane == egoConflictLane) {
2112 #ifdef DEBUG_ENCOUNTER
2114 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' follows foe '"
2115 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2121 #ifdef DEBUG_ENCOUNTER
2123 std::cout <<
"-> Encounter type: " << type << std::endl;
2135 if (egoEntryLink != foeEntryLink) {
2138 #ifdef DEBUG_ENCOUNTER
2140 std::cout <<
"-> Encounter type: " << type << std::endl;
2145 if (egoLane == egoConflictLane && foeLane != foeConflictLane) {
2152 #ifdef DEBUG_ENCOUNTER
2154 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' leads foe '"
2155 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2158 }
else if (egoLane != egoConflictLane && foeLane == foeConflictLane) {
2165 #ifdef DEBUG_ENCOUNTER
2167 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' follows foe '"
2168 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2175 #ifdef DEBUG_ENCOUNTER
2177 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' merges with foe '"
2178 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2186 if (egoLane != egoConflictLane || foeLane != foeConflictLane) {
2190 if (egoLane == foeLane) {
2195 #ifdef DEBUG_ENCOUNTER
2197 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' leads foe '"
2198 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2205 #ifdef DEBUG_ENCOUNTER
2207 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' follows foe '"
2208 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2215 #ifdef DEBUG_ENCOUNTER
2217 std::cout <<
" Lead/follow situation on consecutive internal lanes." << std::endl;
2222 #pragma warning(push)
2223 #pragma warning(disable: 4127)
2227 #pragma warning(pop)
2231 if (egoLane == lane) {
2236 while (lane != foeLane) {
2242 egoConflictLane = lane;
2243 #ifdef DEBUG_ENCOUNTER
2245 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' follows foe '"
2246 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2251 }
else if (foeLane == lane) {
2256 while (lane != egoLane) {
2262 foeConflictLane = lane;
2263 #ifdef DEBUG_ENCOUNTER
2265 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' leads foe '"
2266 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2276 #ifdef DEBUG_ENCOUNTER
2278 std::cout <<
"-> Encounter type: Lead/follow-situation on connection from '" << egoEntryLink->
getLaneBefore()->
getID()
2279 <<
"' to '" << egoEntryLink->
getLane()->
getID() <<
"'" << std::endl;
2286 const std::vector<MSLink*>& egoFoeLinks = egoEntryLink->
getFoeLinks();
2287 const std::vector<MSLink*>& foeFoeLinks = foeEntryLink->
getFoeLinks();
2289 bool crossOrMerge = (find(egoFoeLinks.begin(), egoFoeLinks.end(), foeEntryLink) != egoFoeLinks.end()
2290 || std::find(foeFoeLinks.begin(), foeFoeLinks.end(), egoEntryLink) != foeFoeLinks.end());
2291 if (!crossOrMerge) {
2300 #ifdef DEBUG_ENCOUNTER
2302 std::cout <<
"-> Encounter type: No conflict.\n";
2327 #ifdef DEBUG_ENCOUNTER
2329 std::cout <<
"-> Encounter type: Merging situation of ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' and foe '"
2330 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2337 #ifdef DEBUG_ENCOUNTER
2339 std::cout <<
"-> Encounter type: No conflict: " << type << std::endl;
2355 egoDistToConflictLane -= offset;
2357 foeDistToConflictLane -= offset;
2362 double foeInternalLaneLengthsBeforeCrossing = 0.;
2363 while (foeConflictLane !=
nullptr && foeConflictLane->
isInternal()) {
2370 foeInternalLaneLengthsBeforeCrossing += foeConflictLane->
getLength();
2374 egoDistToConflictFromJunctionEntry = 0;
2375 WRITE_WARNINGF(
"Cannot compute SSM due to bad internal lane geometry at junction '%'. Crossing point between traffic from links % and % not found.",
2382 assert(foeConflictLane != 0 && foeConflictLane->
isInternal());
2388 double egoInternalLaneLengthsBeforeCrossing = 0.;
2390 while (egoConflictLane !=
nullptr && egoConflictLane->
isInternal()) {
2397 egoInternalLaneLengthsBeforeCrossing += egoConflictLane->
getLength();
2401 foeDistToConflictFromJunctionEntry = 0;
2402 WRITE_WARNINGF(
"Cannot compute SSM due to bad internal lane geometry at junction '%'. Crossing point between traffic from links % and % not found.",
2409 assert(egoConflictLane != 0 && egoConflictLane->
isInternal());
2434 assert(angle <= 2 *
M_PI);
2438 assert(angle >= -
M_PI);
2439 assert(angle <=
M_PI);
2441 double crossingOrientation = (angle < 0) - (angle > 0);
2461 #ifdef DEBUG_ENCOUNTER
2463 std::cout <<
" Determined exact conflict distances for crossing conflict."
2464 <<
"\n crossingOrientation=" << crossingOrientation
2467 <<
", relativeAngle=" << angle
2468 <<
" (foe from " << (crossingOrientation > 0 ?
"right)" :
"left)")
2469 <<
"\n resulting offset for conflict entry distance:"
2472 <<
"\n distToConflictLane:"
2473 <<
"\n ego=" << egoDistToConflictLane
2474 <<
", foe=" << foeDistToConflictLane
2475 <<
"\n distToConflictFromJunctionEntry:"
2476 <<
"\n ego=" << egoDistToConflictFromJunctionEntry
2477 <<
", foe=" << foeDistToConflictFromJunctionEntry
2478 <<
"\n resulting entry distances:"
2481 <<
"\n resulting exit distances:"
2486 std::cout <<
"real egoConflictLane: '" << (egoConflictLane == 0 ?
"NULL" : egoConflictLane->
getID()) <<
"'\n"
2487 <<
"real foeConflictLane: '" << (foeConflictLane == 0 ?
"NULL" : foeConflictLane->
getID()) <<
"'\n"
2488 <<
"-> Encounter type: Crossing situation of ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' and foe '"
2489 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2507 std::cout <<
SIMTIME <<
" findFoeConflictLane() for foe '"
2509 <<
"' (with egoConflictLane=" << (egoConflictLane == 0 ?
"NULL" : egoConflictLane->
getID())
2519 #ifdef DEBUG_SSM_OPPOSITE
2539 return egoConflictLane;
2548 return egoConflictLane;
2558 assert(foeLane->
isInternal() || *laneIter == foeLane);
2565 if (conflictJunction != 0) {
2566 std::cout <<
"Potential conflict on junction '" << conflictJunction->
getID()
2572 if (egoConflictLane !=
nullptr && egoConflictLane->
isInternal() && egoConflictLane->
getLinkCont()[0]->getViaLane() == foeLane) {
2573 distToConflictLane += egoConflictLane->
getLength();
2581 if (*laneIter ==
nullptr) {
2582 while (foeLane !=
nullptr && foeLane->
isInternal()) {
2583 distToConflictLane += foeLane->
getLength();
2584 foeLane = foeLane->
getLinkCont()[0]->getViaLane();
2587 assert(laneIter == foeBestLanesEnd || *laneIter != 0);
2591 while (laneIter != foeBestLanesEnd && distToConflictLane <=
myRange) {
2593 assert(*laneIter == foeLane || foeLane == 0);
2594 foeLane = *laneIter;
2599 std::cout <<
"Found conflict lane for foe: '" << foeLane->
getID() <<
"'" << std::endl;
2606 distToConflictLane += foeLane->
getLength();
2610 if (laneIter == foeBestLanesEnd) {
2613 MSLane*
const nextNonInternalLane = *laneIter;
2617 assert(foeLane == 0 || foeLane->
isInternal());
2618 if (foeLane ==
nullptr) {
2619 foeLane = nextNonInternalLane;
2623 assert(foeLane != 0);
2626 std::cout <<
"Found conflict lane for foe: '" << foeLane->
getID() <<
"'" << std::endl;
2634 foeLane = nextNonInternalLane;
2667 std::cout <<
SIMTIME <<
" flushGlobalMeasures() of vehicle '"
2741 std::cout <<
SIMTIME <<
" writeOutConflict() of vehicles '"
2830 std::string res =
"";
2831 for (std::vector<double>::const_iterator i = v.begin(); i != v.end(); ++i) {
2832 res += (i == v.begin() ?
"" :
" ") + (*i == NA ?
"NA" : ::
toString(*i));
2839 std::string res =
"";
2840 for (std::vector<double>::const_iterator i = v.begin(); i != v.end(); ++i) {
2841 res += (i == v.begin() ?
"" :
" ") + (find(NAs.begin(), NAs.end(), *i) != NAs.end() ?
"NA" :
::toString(*i));
2848 std::string res =
"";
2849 for (PositionVector::const_iterator i = v.begin(); i != v.end(); ++i) {
2871 myMinSGAP(std::make_pair(std::make_pair(-1,
Position(0., 0.)), std::numeric_limits<double>::max()),
""),
2872 myMinTGAP(std::make_pair(std::make_pair(-1,
Position(0., 0.)), std::numeric_limits<double>::max()),
"") {
2900 std::vector<std::string> measures;
2901 std::vector<double> threshVals;
2903 measures.push_back(i->first);
2904 threshVals.push_back(i->second);
2906 std::cout <<
"Initialized ssm device '" <<
id <<
"' with "
2929 #ifdef DEBUG_SSM_NOTIFICATIONS
2945 #ifdef DEBUG_SSM_NOTIFICATIONS
2959 double ,
double newSpeed) {
2960 #ifdef DEBUG_SSM_NOTIFICATIONS
2963 std::cout <<
SIMTIME <<
"device '" <<
getID() <<
"' notifyMove: newSpeed=" << newSpeed <<
"\n";
2978 #ifdef DEBUG_SSM_SURROUNDING
2982 std::cout <<
SIMTIME <<
" Looking for surrounding vehicles for ego vehicle '" << veh.
getID()
3005 for (
int i = 0; i < (int)egoBestLanes.size(); i++) {
3006 if (egoBestLanes[i] !=
nullptr && egoBestLanes[i]->getEdge().getOppositeEdge() !=
nullptr) {
3007 egoBestLanes[i] = egoBestLanes[i]->getEdge().getOppositeEdge()->getLanes().back();
3011 std::vector<MSLane*>::const_iterator laneIter = egoBestLanes.begin();
3016 assert(lane->
isInternal() || lane == *laneIter);
3019 const MSLane* nextNonInternalLane =
nullptr;
3027 double remainingDownstreamRange = range;
3029 double distToConflictLane = isOpposite ? pos - veh.
getLane()->
getLength() : -pos;
3032 std::set<const MSLane*> seenLanes;
3033 std::set<const MSJunction*> routeJunctions;
3037 std::vector<UpstreamScanStartInfo> upstreamScanStartPositions;
3046 #ifdef DEBUG_SSM_SURROUNDING
3048 std::cout <<
SIMTIME <<
" Vehicle '" << veh.
getID() <<
"' is on internal edge " << edge->
getID() <<
"'." << std::endl;
3058 routeJunctions.insert(junction);
3064 for (ConstMSEdgeVector::const_iterator ei = incoming.begin(); ei != incoming.end(); ++ei) {
3065 if ((*ei)->isInternal()) {
3084 lane = *(++laneIter);
3090 double startScanPos = std::min(pos + remainingDownstreamRange, edgeLength);
3091 upstreamScanStartPositions.push_back(
UpstreamScanStartInfo(edge, startScanPos, std::max(0., startScanPos - pos + range + veh.
getLength()), distToConflictLane, lane));
3100 while (remainingDownstreamRange > 0.) {
3102 #ifdef DEBUG_SSM_SURROUNDING
3104 std::cout <<
SIMTIME <<
" Scanning downstream for vehicle '" << veh.
getID() <<
"' on lane '" << veh.
getLane()->
getID() <<
"', position=" << pos <<
".\n"
3105 <<
"Considering edge '" << edge->
getID() <<
"' Remaining downstream range = " << remainingDownstreamRange
3106 <<
"\nbestLanes=" <<
::toString(egoBestLanes) <<
"\n"
3112 assert(pos == 0 || lane == veh.
getLane());
3113 if (pos + remainingDownstreamRange < lane->getLength()) {
3116 upstreamScanStartPositions.push_back(
UpstreamScanStartInfo(edge, pos + remainingDownstreamRange, remainingDownstreamRange, distToConflictLane, lane));
3127 remainingDownstreamRange -= lane->
getLength() - pos;
3128 distToConflictLane += lane->
getLength();
3133 assert(laneIter == egoBestLanes.end() || *laneIter != 0);
3136 if (laneIter != egoBestLanes.end()) {
3147 nextNonInternalLane = *laneIter;
3149 if (isOpposite && link ==
nullptr) {
3150 link = nextNonInternalLane->
getLinkTo(lane);
3151 if (link ==
nullptr) {
3155 if (link ==
nullptr) {
3162 if (lane ==
nullptr) {
3164 lane = nextNonInternalLane;
3166 if (seenLanes.count(lane) == 0) {
3167 seenLanes.insert(lane);
3174 if (seenLanes.count(lane) == 0) {
3177 routeJunctions.insert(junction);
3183 for (ConstMSEdgeVector::const_iterator ei = outgoing.begin(); ei != outgoing.end(); ++ei) {
3187 upstreamScanStartPositions.push_back(
UpstreamScanStartInfo(*ei, (*ei)->getLength(), range, distToConflictLane, lane));
3191 for (ConstMSEdgeVector::const_iterator ei = incoming.begin(); ei != incoming.end(); ++ei) {
3195 upstreamScanStartPositions.push_back(
UpstreamScanStartInfo(*ei, (*ei)->getLength(), range, distToConflictLane, lane));
3201 remainingDownstreamRange -= linkLength;
3202 distToConflictLane += linkLength;
3203 #ifdef DEBUG_SSM_SURROUNDING
3205 std::cout <<
" Downstream Scan for vehicle '" << veh.
getID() <<
"' proceeded over junction '" << junction->
getID()
3206 <<
"',\n linkLength=" << linkLength <<
", remainingDownstreamRange=" << remainingDownstreamRange
3212 lane = nextNonInternalLane;
3215 #ifdef DEBUG_SSM_SURROUNDING
3217 std::cout <<
" Downstream Scan for vehicle '" << veh.
getID() <<
"' stops at lane '" << lane->
getID()
3218 <<
"', which has already been scanned."
3239 #ifdef DEBUG_SSM_SURROUNDING
3241 for (std::pair<const MSVehicle*, FoeInfo*> foeInfo : foeCollector) {
3242 std::cout <<
" foe " << foeInfo.first->getID() <<
" conflict at " << foeInfo.second->egoConflictLane->getID() <<
" egoDist " << foeInfo.second->egoDistToConflictLane << std::endl;
3248 foeCollector.erase(&veh);
3254 #ifdef DEBUG_SSM_SURROUNDING
3256 std::cout <<
SIMTIME <<
" getUpstreamVehicles() for edge '" << scanStart.
edge->
getID() <<
"'"
3258 <<
" pos = " << scanStart.
pos <<
" range = " << scanStart.
range
3262 if (scanStart.
range <= 0) {
3268 if (seenLanes.find(lane) != seenLanes.end()) {
3272 for (
MSVehicle*
const veh : lane->getVehiclesSecure()) {
3273 if (foeCollector.find(veh) != foeCollector.end()) {
3277 if (veh->getPositionOnLane() - veh->getLength() <= scanStart.
pos && veh->getPositionOnLane() >= scanStart.
pos - scanStart.
range) {
3278 #ifdef DEBUG_SSM_SURROUNDING
3280 std::cout <<
"\t" << veh->getID() <<
"\n";
3286 foeCollector[veh] = c;
3290 lane->releaseVehicles();
3292 #ifdef DEBUG_SSM_SURROUNDING
3294 std::cout <<
"\t" << lane->getID() <<
": Found " << foundCount <<
"\n";
3297 seenLanes.insert(lane);
3300 #ifdef DEBUG_SSM_SURROUNDING
3302 std::cout << std::endl;
3310 if (scanStart.
range <= scanStart.
pos) {
3315 double remainingRange = scanStart.
range - scanStart.
pos;
3321 if (routeJunctions.find(junction) != routeJunctions.end()) {
3326 int incomingEdgeCount = 0;
3334 if (internalLane->getEdge().getSuccessors()[0]->getID() == scanStart.
edge->
getID()) {
3336 incomingEdgeCount++;
3341 if (incomingEdgeCount > 0) {
3343 if (inEdge->isInternal() || inEdge->isCrossing()) {
3347 for (
MSLane*
const lane : inEdge->getLanes()) {
3348 if (seenLanes.find(lane) != seenLanes.end()) {
3354 #ifdef DEBUG_SSM_SURROUNDING
3360 double distOnJunction = scanStart.
edge->
isInternal() ? 0. : inEdge->getInternalFollowingLengthTo(scanStart.
edge);
3361 if (distOnJunction >= remainingRange) {
3362 #ifdef DEBUG_SSM_SURROUNDING
3377 #ifdef DEBUG_SSM_SURROUNDING
3379 std::cout <<
SIMTIME <<
" getVehiclesOnJunction() for junction '" << junction->
getID()
3381 <<
"\nFound vehicles:"
3388 if (foeCollector.find(veh) != foeCollector.end()) {
3389 delete foeCollector[veh];
3394 foeCollector[veh] = c;
3395 #ifdef DEBUG_SSM_SURROUNDING
3397 std::cout <<
"\t" << veh->getID() <<
" egoConflictLane=" <<
Named::getIDSecure(egoConflictLane) <<
"\n";
3404 if (seenLanes.find(egoJunctionLane) != seenLanes.end() || egoJunctionLane->
getEdge().
isCrossing()) {
3408 auto scanInternalLane = [&](
const MSLane * lane) {
3413 collectFoeInfos(vehicles);
3415 lane->releaseVehicles();
3419 if (lane->getCanonicalPredecessorLane()->isInternal()) {
3420 lane = lane->getCanonicalPredecessorLane();
3423 assert(!lane->getEntryLink()->fromInternalLane());
3428 collectFoeInfos(vehicles2);
3429 lane->releaseVehicles();
3434 if (lane->getLinkCont().size() > 1 && lane->getLinkCont()[0]->getViaLane() !=
nullptr) {
3436 lane = lane->getLinkCont()[0]->getViaLane();
3438 assert(lane->getLinkCont().size() == 0 || lane->getLinkCont()[0]->getViaLane() == 0);
3443 collectFoeInfos(vehicles2);
3444 lane->releaseVehicles();
3454 for (
MSLane* lane : foeLanes) {
3455 if (seenLanes.find(lane) != seenLanes.end()) {
3458 scanInternalLane(lane);
3459 seenLanes.insert(lane);
3462 scanInternalLane(egoJunctionLane);
3464 #ifdef DEBUG_SSM_SURROUNDING
3466 std::cout << std::endl;
3486 std::string file = deviceID +
".xml";
3500 file = oc.
getString(
"device.ssm.file") ==
"" ? file : oc.
getString(
"device.ssm.file");
3502 WRITE_MESSAGE(
"vehicle '" + v.
getID() +
"' does not supply vehicle parameter 'device.ssm.file'. Using default of '" + file +
"'");
3520 bool useGeo =
false;
3534 useGeo = oc.
getBool(
"device.ssm.geo");
3536 WRITE_MESSAGE(
"vehicle '" + v.
getID() +
"' does not supply vehicle parameter 'device.ssm.geo'. Using default of '" +
toString(useGeo) +
"'");
3547 bool writePos =
false;
3561 writePos = oc.
getBool(
"device.ssm.write-positions");
3563 WRITE_MESSAGE(
"vehicle '" + v.
getID() +
"' does not supply vehicle parameter 'device.ssm.write-positions'. Using default of '" +
toString(writePos) +
"'");
3574 bool writeLanesPos =
false;
3588 writeLanesPos = oc.
getBool(
"device.ssm.write-lane-positions");
3590 WRITE_MESSAGE(
"vehicle '" + v.
getID() +
"' does not supply vehicle parameter 'device.ssm.write-positions'. Using default of '" +
toString(writeLanesPos) +
"'");
3594 return writeLanesPos;
3615 range = oc.
getFloat(
"device.ssm.range");
3617 WRITE_MESSAGE(
"vehicle '" + v.
getID() +
"' does not supply vehicle parameter 'device.ssm.range'. Using default of '" +
toString(range) +
"'");
3642 extraTime = oc.
getFloat(
"device.ssm.extratime");
3644 WRITE_MESSAGE(
"vehicle '" + v.
getID() +
"' does not supply vehicle parameter 'device.ssm.extratime'. Using default of '" +
toString(extraTime) +
"'");
3648 if (extraTime < 0.) {
3650 WRITE_WARNING(
"Negative (or no) value encountered for vehicle parameter 'device.ssm.extratime' in vehicle '" + v.
getID() +
"' using default value " + ::
toString(extraTime) +
" instead");
3659 bool trajectories =
false;
3673 trajectories = oc.
getBool(
"device.ssm.trajectories");
3675 WRITE_MESSAGE(
"vehicle '" + v.
getID() +
"' does not supply vehicle parameter 'device.ssm.trajectories'. Using default of '" +
toString(trajectories) +
"'");
3679 return trajectories;
3688 std::string measures_str =
"";
3702 measures_str = oc.
getString(
"device.ssm.measures");
3704 WRITE_MESSAGE(
"vehicle '" + v.
getID() +
"' does not supply vehicle parameter 'device.ssm.measures'. Using default of '" + measures_str +
"'");
3710 if (measures_str ==
"") {
3711 WRITE_WARNING(
"No measures specified for ssm device of vehicle '" + v.
getID() +
"'. Registering all available SSMs.");
3715 std::vector<std::string> available = st.
getVector();
3717 std::vector<std::string> measures = st.
getVector();
3718 for (std::vector<std::string>::const_iterator i = measures.begin(); i != measures.end(); ++i) {
3719 if (std::find(available.begin(), available.end(), *i) == available.end()) {
3721 WRITE_ERROR(
"SSM identifier '" + *i +
"' is not supported. Aborting construction of SSM device '" + deviceID +
"'.");
3727 std::string thresholds_str =
"";
3741 thresholds_str = oc.
getString(
"device.ssm.thresholds");
3743 WRITE_MESSAGE(
"vehicle '" + v.
getID() +
"' does not supply vehicle parameter 'device.ssm.thresholds'. Using default of '" + thresholds_str +
"'");
3750 if (thresholds_str !=
"") {
3752 while (count < (
int)measures.size() && st.
hasNext()) {
3754 thresholds.insert(std::make_pair(measures[count], thresh));
3757 if (thresholds.size() < measures.size() || st.
hasNext()) {
3758 WRITE_ERROR(
"Given list of thresholds ('" + thresholds_str +
"') is not of the same size as the list of measures ('" + measures_str +
"').\nPlease specify exactly one threshold for each measure.");
3763 for (std::vector<std::string>::const_iterator i = measures.begin(); i != measures.end(); ++i) {
3766 }
else if (*i ==
"DRAC") {
3768 }
else if (*i ==
"PET") {
3770 }
else if (*i ==
"BR") {
3772 }
else if (*i ==
"SGAP") {
3774 }
else if (*i ==
"TGAP") {
3777 WRITE_ERROR(
"Unknown SSM identifier '" + (*i) +
"'. Aborting construction of ssm device.");
3797 if (key ==
"minTTC" ||
3805 minTTC =
MIN2(minTTC, e->minTTC.value);
3806 minPET =
MIN2(minPET, e->PET.value);
3807 maxDRAC =
MAX2(maxDRAC, e->maxDRAC.value);
3809 if (key ==
"minTTC") {
3811 }
else if (key ==
"maxDRAC") {
3813 }
else if (key ==
"minPET") {
3834 if (
false || key ==
"foo") {
#define DEFAULT_THRESHOLD_SGAP
#define DEFAULT_THRESHOLD_BR
#define DEFAULT_THRESHOLD_TGAP
#define DEFAULT_THRESHOLD_DRAC
#define DEFAULT_THRESHOLD_TTC
#define DEFAULT_EXTRA_TIME
#define DEFAULT_THRESHOLD_PET
#define DEBUG_COND_ENCOUNTER(e)
std::ostream & operator<<(std::ostream &out, MSDevice_SSM::EncounterType type)
Nicer output for EncounterType enum.
#define DEBUG_COND_FIND(ego)
std::vector< const MSEdge * > ConstMSEdgeVector
#define WRITE_WARNINGF(...)
#define WRITE_MESSAGE(msg)
#define WRITE_WARNING(msg)
std::string time2string(SUMOTime t)
convert SUMOTime to string
int gPrecision
the precision for floating point outputs
const double INVALID_DOUBLE
#define UNUSED_PARAMETER(x)
std::string joinToString(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=gPrecision)
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
static std::string checkForRelativity(const std::string &filename, const std::string &basePath)
Returns the path from a configuration so that it is accessable from the current working directory.
void cartesian2geo(Position &cartesian) const
Converts the given cartesian (shifted) position to its geo (lat/long) representation.
static const GeoConvHelper & getFinal()
the coordinate transformation for writing the location element and for tracking the original coordina...
The base class for microscopic and mesoscopic vehicles.
double getLength() const
Returns the vehicle's length.
const MSEdge * getEdge() const
Returns the edge the vehicle is currently at.
double getWidth() const
Returns the vehicle's width.
const MSRouteIterator & getCurrentRouteEdge() const
Returns an iterator pointing to the current edge in this vehicles route.
const MSVehicleType & getVehicleType() const
Returns the vehicle's type definition.
const MSRoute & getRoute() const
Returns the current route.
static double passingTime(const double lastPos, const double passedPos, const double currentPos, const double lastSpeed, const double currentSpeed)
Calculates the time at which the position passedPosition has been passed In case of a ballistic updat...
static double estimateArrivalTime(double dist, double speed, double maxSpeed, double accel)
Computes the time needed to travel a distance dist given an initial speed and constant acceleration....
An encounter is an episode involving two vehicles, which are closer to each other than some specified...
EncounterType currentType
double foeConflictEntryTime
Times when the foe vehicle entered/left the conflict area. Currently only applies for crossing situat...
std::vector< double > foeDistsToConflict
Evolution of the foe vehicle's distance to the conflict point.
std::vector< double > timeSpan
time points corresponding to the trajectories
std::vector< int > typeSpan
Evolution of the encounter classification (.
bool closingRequested
this flag is set by updateEncounter() or directly in processEncounters(), where encounters are closed...
std::vector< double > TTCspan
All values for TTC.
std::size_t size() const
Returns the number of trajectory points stored.
void resetExtraTime(double value)
resets remainingExtraTime to the given value
PositionVector conflictPointSpan
Predicted location of the conflict: In case of MERGING and CROSSING: entry point to conflict area for...
ConflictPointInfo maxDRAC
void add(double time, EncounterType type, Position egoX, std::string egoLane, double egoLanePos, Position egoV, Position foeX, std::string foeLane, double foeLanePos, Position foeV, Position conflictPoint, double egoDistToConflict, double foeDistToConflict, double ttc, double drac, std::pair< double, double > pet)
add a new data point and update encounter type
double egoConflictExitTime
void countDownExtraTime(double amount)
decreases myRemaingExtraTime by given amount in seconds
Trajectory foeTrajectory
Trajectory of the foe vehicle.
std::vector< double > egoDistsToConflict
Evolution of the ego vehicle's distance to the conflict point.
Trajectory egoTrajectory
Trajectory of the ego vehicle.
double egoConflictEntryTime
Times when the ego vehicle entered/left the conflict area. Currently only applies for crossing situat...
Encounter(const MSVehicle *_ego, const MSVehicle *const _foe, double _begin, double extraTime)
Constructor.
double foeConflictExitTime
double getRemainingExtraTime() const
returns the remaining extra time
std::vector< double > DRACspan
All values for DRAC.
A device which collects info on the vehicle trip (mainly on departure and arrival)
MSDevice_SSM(SUMOVehicle &holder, const std::string &id, std::string outputFilename, std::map< std::string, double > thresholds, bool trajectories, double range, double extraTime, bool useGeoCoords, bool writePositions, bool writeLanesPositions)
Constructor.
std::map< const MSVehicle *, FoeInfo * > FoeInfoMap
double myExtraTime
Extra time in seconds to be logged after a conflict is over.
void generateOutput(OutputDevice *tripinfoOut) const
Finalizes output. Called on vehicle removal.
std::pair< std::pair< std::pair< double, Position >, double >, std::string > myMinTGAP
bool myComputeTTC
Flags for switching on / off comutation of different SSMs, derived from myMeasures.
PositionVector myGlobalMeasuresPositions
All values for positions (coordinates)
static std::set< std::string > createdOutputFiles
remember which files were created already (don't duplicate xml root-elements)
bool mySaveTrajectories
This determines whether the whole trajectories of the vehicles (position, speed, ssms) shall be saved...
bool updateEncounter(Encounter *e, FoeInfo *foeInfo)
Updates the encounter (adds a new trajectory point).
static bool requestsTrajectories(const SUMOVehicle &v)
static bool getMeasuresAndThresholds(const SUMOVehicle &v, std::string deviceID, std::map< std::string, double > &thresholds)
std::string getParameter(const std::string &key) const
try to retrieve the given parameter from this device. Throw exception for unsupported key
EncounterType classifyEncounter(const FoeInfo *foeInfo, EncounterApproachInfo &eInfo) const
Classifies the current type of the encounter provided some information on the opponents.
void computeSSMs(EncounterApproachInfo &e) const
Compute current values of the logged SSMs (myMeasures) for the given encounter 'e' and update 'e' acc...
static void buildVehicleDevices(SUMOVehicle &v, std::vector< MSVehicleDevice * > &into)
Build devices for the given vehicle, if needed.
void writeOutConflict(Encounter *e)
EncounterType
Different types of encounters corresponding to relative positions of the vehicles....
@ ENCOUNTER_TYPE_EGO_ENTERED_CONFLICT_AREA
ENCOUNTER_TYPE_EGO_ENTERED_CONFLICT_AREA.
@ ENCOUNTER_TYPE_FOE_LEFT_CONFLICT_AREA
ENCOUNTER_TYPE_FOE_LEFT_CONFLICT_AREA.
@ ENCOUNTER_TYPE_MERGING
ENCOUNTER_TYPE_MERGING.
@ ENCOUNTER_TYPE_MERGING_FOLLOWER
ENCOUNTER_TYPE_MERGING_FOLLOWER.
@ ENCOUNTER_TYPE_FOLLOWING_FOLLOWER
ENCOUNTER_TYPE_FOLLOWING_FOLLOWER.
@ ENCOUNTER_TYPE_FOLLOWING
ENCOUNTER_TYPE_FOLLOWING.
@ ENCOUNTER_TYPE_MERGING_LEADER
ENCOUNTER_TYPE_MERGING_LEADER.
@ ENCOUNTER_TYPE_FOLLOWING_PASSED
ENCOUNTER_TYPE_FOLLOWING_PASSED.
@ ENCOUNTER_TYPE_FOLLOWING_LEADER
ENCOUNTER_TYPE_FOLLOWING_LEADER.
@ ENCOUNTER_TYPE_BOTH_LEFT_CONFLICT_AREA
ENCOUNTER_TYPE_BOTH_LEFT_CONFLICT_AREA.
@ ENCOUNTER_TYPE_FOE_ENTERED_CONFLICT_AREA
ENCOUNTER_TYPE_FOE_ENTERED_CONFLICT_AREA.
@ ENCOUNTER_TYPE_ONCOMING
@ ENCOUNTER_TYPE_MERGING_PASSED
ENCOUNTER_TYPE_FOLLOWING_PASSED.
@ ENCOUNTER_TYPE_ON_ADJACENT_LANES
ENCOUNTER_TYPE_ON_ADJACENT_LANES.
@ ENCOUNTER_TYPE_EGO_LEFT_CONFLICT_AREA
ENCOUNTER_TYPE_EGO_LEFT_CONFLICT_AREA.
@ ENCOUNTER_TYPE_BOTH_ENTERED_CONFLICT_AREA
ENCOUNTER_TYPE_BOTH_ENTERED_CONFLICT_AREA.
@ ENCOUNTER_TYPE_NOCONFLICT_AHEAD
ENCOUNTER_TYPE_NOCONFLICT_AHEAD.
@ ENCOUNTER_TYPE_COLLISION
ENCOUNTER_TYPE_COLLISION.
@ ENCOUNTER_TYPE_CROSSING
ENCOUNTER_TYPE_CROSSING.
@ ENCOUNTER_TYPE_CROSSING_FOLLOWER
ENCOUNTER_TYPE_CROSSING_FOLLOWER.
@ ENCOUNTER_TYPE_MERGING_ADJACENT
ENCOUNTER_TYPE_MERGING_ADJACENT.
@ ENCOUNTER_TYPE_CROSSING_LEADER
ENCOUNTER_TYPE_CROSSING_LEADER.
std::priority_queue< Encounter *, std::vector< Encounter * >, Encounter::compare > EncounterQueue
static void initEdgeFilter()
initialize edge filter (once)
std::vector< double > myGlobalMeasuresLanesPositions
All values for positions on the lanes.
bool notifyMove(SUMOTrafficObject &veh, double oldPos, double newPos, double newSpeed)
Checks for waiting steps when the vehicle moves.
static void determineConflictPoint(EncounterApproachInfo &eInfo)
Calculates the (x,y)-coordinate for the eventually predicted conflict point and stores the result in ...
static double computeDRAC(double gap, double followerSpeed, double leaderSpeed)
Computes the DRAC (deceleration to avoid a collision) for a lead/follow situation as defined,...
EncounterQueue myPastConflicts
Past encounters that where qualified as conflicts and are not yet flushed to the output file.
static bool useGeoCoords(const SUMOVehicle &v)
static int issuedParameterWarnFlags
bitset storing info whether warning has already been issued about unset parameter (warn only once!...
void setParameter(const std::string &key, const std::string &value)
try to set the given parameter for this device. Throw exception for unsupported key
static bool myEdgeFilterInitialized
static const std::set< MSDevice_SSM *, ComparatorNumericalIdLess > & getInstances()
returns all currently existing SSM devices
void closeEncounter(Encounter *e)
Finalizes the encounter and calculates SSM values.
static std::string makeStringWithNAs(const std::vector< double > &v, const double NA)
make a string of a double vector and treat a special value as invalid ("NA")
static bool writePositions(const SUMOVehicle &v)
static double getDetectionRange(const SUMOVehicle &v)
static void cleanup()
Clean up remaining devices instances.
static void insertOptions(OptionsCont &oc)
Inserts MSDevice_SSM-options.
double myRange
Detection range. For vehicles closer than this distance from the ego vehicle, SSMs are traced.
const MSLane * findFoeConflictLane(const MSVehicle *foe, const MSLane *egoConflictLane, double &distToConflictLane) const
Computes the conflict lane for the foe.
std::vector< std::string > myGlobalMeasuresLaneIDs
All values for lanes.
bool notifyLeave(SUMOTrafficObject &veh, double lastPos, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Called whenever the holder leaves a lane.
std::vector< Encounter * > EncounterVector
static void getUpstreamVehicles(const UpstreamScanStartInfo &scanStart, FoeInfoMap &foeCollector, std::set< const MSLane * > &seenLanes, const std::set< const MSJunction * > &routeJunctions)
Collects all vehicles within range 'range' upstream of the position 'pos' on the edge 'edge' into foe...
void createEncounters(FoeInfoMap &foes)
Makes new encounters for all given vehicles (these should be the ones entering the device's range in ...
bool qualifiesAsConflict(Encounter *e)
Tests if the SSM values exceed the threshold for qualification as conflict.
std::map< std::string, double > myThresholds
static std::string getOutputFilename(const SUMOVehicle &v, std::string deviceID)
void updateAndWriteOutput()
This is called once per time step in MSNet::writeOutput() and collects the surrounding vehicles,...
static std::set< MSDevice_SSM *, ComparatorNumericalIdLess > * myInstances
All currently existing SSM devices.
std::pair< std::pair< std::pair< double, Position >, double >, std::string > myMinSGAP
OutputDevice * myOutputFile
Output device.
static double getExtraTime(const SUMOVehicle &v)
EncounterVector myActiveEncounters
std::vector< double > myGlobalMeasuresTimeSpan
void computeGlobalMeasures()
Stores measures, that are not associated to a specific encounter as headways and brake rates.
static std::string encounterToString(EncounterType type)
double myOldestActiveEncounterBegin
begin time of the oldest active encounter
static void checkConflictEntryAndExit(EncounterApproachInfo &eInfo)
Checks whether ego or foe have entered or left the conflict area in the last step and eventually writ...
double computeTTC(double gap, double followerSpeed, double leaderSpeed) const
Computes the time to collision (in seconds) for two vehicles with a given initial gap under the assum...
void flushConflicts(bool all=false)
Writes out all past conflicts that have begun earlier than the oldest active encounter.
void determinePET(EncounterApproachInfo &eInfo) const
Discriminates between different encounter types and correspondingly determines the PET for those case...
static std::set< const MSEdge * > myEdgeFilter
spatial filter for SSM device output
static void toGeo(Position &x)
convert SUMO-positions to geo coordinates (in place)
static void findSurroundingVehicles(const MSVehicle &veh, double range, FoeInfoMap &foeCollector)
Returns all vehicles, which are within the given range of the given vehicle.
bool myWritePositions
Wether to print the positions for all timesteps.
void resetEncounters()
Closes all current Encounters and moves conflicts to myPastConflicts,.
std::pair< std::pair< double, Position >, double > myMaxBR
Extremal values for the global measures (as <<<time, Position>, value>, [leaderID]>-pairs)
std::vector< double > myBRspan
All values for brake rate.
void determineTTCandDRAC(EncounterApproachInfo &eInfo) const
Discriminates between different encounter types and correspondingly determines TTC and DRAC for those...
bool myUseGeoCoords
Whether to use the original coordinate system for output.
bool myWriteLanesPositions
Wether to print the lanes and positions for all timesteps and conflicts.
~MSDevice_SSM()
Destructor.
const std::string deviceName() const
return the name for this type of device
static bool myEdgeFilterActive
void flushGlobalMeasures()
Write out all non-encounter specific measures as headways and braking rates.
std::vector< double > myTGAPspan
All values for time gap.
static void getVehiclesOnJunction(const MSJunction *, const MSLane *egoJunctionLane, double egoDistToConflictLane, const MSLane *const egoConflictLane, FoeInfoMap &foeCollector, std::set< const MSLane * > &seenLanes)
Collects all vehicles on the junction into foeCollector.
static void estimateConflictTimes(EncounterApproachInfo &eInfo)
Estimates the time until conflict for the vehicles based on the distance to the conflict entry points...
bool notifyEnter(SUMOTrafficObject &veh, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Called whenever the holder enteres a lane.
void updatePassedEncounter(Encounter *e, FoeInfo *foeInfo, EncounterApproachInfo &eInfo)
Updates an encounter, which was classified as ENCOUNTER_TYPE_NOCONFLICT_AHEAD this may be the case be...
void processEncounters(FoeInfoMap &foes, bool forceClose=false)
Finds encounters for which the foe vehicle has disappeared from range. remainingExtraTime is decrease...
static bool writeLanesPositions(const SUMOVehicle &v)
std::vector< double > mySGAPspan
All values for space gap.
static void insertDefaultAssignmentOptions(const std::string &deviceName, const std::string &optionsTopic, OptionsCont &oc, const bool isPerson=false)
Adds common command options that allow to assign devices to vehicles.
static bool equippedByDefaultAssignmentOptions(const OptionsCont &oc, const std::string &deviceName, DEVICEHOLDER &v, bool outputOptionSet, const bool isPerson=false)
Determines whether a vehicle should get a certain device.
A road/street connecting two junctions.
bool isCrossing() const
return whether this edge is a pedestrian crossing
const MSEdge * getOppositeEdge() const
Returns the opposite direction edge if on exists else a nullptr.
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
const MSJunction * getFromJunction() const
double getLength() const
return the length of the edge
bool isInternal() const
return whether this edge is an internal edge
static bool dictionary(const std::string &id, MSEdge *edge)
Inserts edge into the static dictionary Returns true if the key id isn't already in the dictionary....
const MSJunction * getToJunction() const
The base class for an intersection.
const ConstMSEdgeVector & getIncoming() const
const ConstMSEdgeVector & getOutgoing() const
virtual const std::vector< MSLane * > getInternalLanes() const
Returns all internal lanes on the junction.
virtual const std::vector< MSLane * > & getFoeInternalLanes(const MSLink *const) const
Representation of a lane in the micro simulation.
const std::vector< MSLink * > & getLinkCont() const
returns the container with all links !!!
const MSLink * getEntryLink() const
Returns the entry link if this is an internal lane, else nullptr.
const MSLink * getLinkTo(const MSLane *const) const
returns the link to the given lane or nullptr, if it is not connected
std::vector< MSVehicle * > VehCont
Container for vehicles.
double getLength() const
Returns the lane's length.
const MSLane * getFirstInternalInConnection(double &offset) const
Returns 0 if the lane is not internal. Otherwise the first part of the connection (sequence of intern...
MSLane * getCanonicalSuccessorLane() const
const std::vector< IncomingLaneInfo > & getIncomingLanes() const
MSEdge & getEdge() const
Returns the lane's edge.
const PositionVector & getShape() const
Returns this lane's shape.
MSLane * getParallelOpposite() const
return the opposite direction lane of this lanes edge or nullptr
double getWidth() const
Returns the lane's width.
MSLane * getViaLane() const
Returns the following inner lane.
MSLane * getLane() const
Returns the connected lane.
int getIndex() const
Returns the respond index (for visualization)
const MSLane * getLaneBefore() const
return the internalLaneBefore if it exists and the laneBefore otherwise
bool isInternalJunctionLink() const
return whether the fromLane and the toLane of this link are internal lanes
double getInternalLengthsAfter() const
Returns the cumulative length of all internal lanes after this link.
const std::vector< MSLink * > & getFoeLinks() const
const std::vector< const MSLane * > & getFoeLanes() const
double getLengthsBeforeCrossing(const MSLane *foeLane) const
Returns the sum of the lengths along internal lanes following this link to the crossing with the give...
MSJunction * getJunction() const
const MSLink * getCorrespondingExitLink() const
returns the corresponding exit link for entryLinks to a junction.
const MSLane * getInternalLaneBefore() const
return myInternalLaneBefore (always 0 when compiled without internal lanes)
Notification
Definition of a vehicle state.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
MSJunctionControl & getJunctionControl()
Returns the junctions control.
MSRouteIterator end() const
Returns the end of the list of edges to pass.
SUMOVehicle * getVehicle(const std::string &id) const
Returns the vehicle with the given id.
Abstract in-vehicle device.
SUMOVehicle & myHolder
The vehicle that stores the device.
Representation of a vehicle in the micro simulation.
bool isOnRoad() const
Returns the information whether the vehicle is on a road (is simulated)
MSAbstractLaneChangeModel & getLaneChangeModel()
Position getPositionAlongBestLanes(double offset) const
Return the (x,y)-position, which the vehicle would reach if it continued along its best continuation ...
double getMaxSpeedOnLane() const
Returns the maximal speed for the vehicle on its current lane (including speed factor and deviation,...
double getAcceleration() const
Returns the vehicle's acceleration in m/s (this is computed as the last step's mean acceleration in c...
Position getPosition(const double offset=0) const
Return current position (x/y, cartesian)
const std::vector< MSLane * > & getBestLanesContinuation() const
Returns the best sequence of lanes to continue the route starting at myLane.
double getBackPositionOnLane(const MSLane *lane) const
Get the vehicle's position relative to the given lane.
std::pair< const MSVehicle *const, double > getLeader(double dist=0) const
Returns the leader of the vehicle looking for a fixed distance.
double getLastStepDist() const
Get the distance the vehicle covered in the previous timestep.
double getLateralPositionOnLane() const
Get the vehicle's lateral position on the lane.
double getSpeed() const
Returns the vehicle's current speed.
double getPositionOnLane() const
Get the vehicle's position along the lane.
const MSLane * getLane() const
Returns the lane the vehicle is on.
const MSCFModel & getCarFollowModel() const
Returns the vehicle's car following model definition.
double getPreviousSpeed() const
Returns the vehicle's speed before the previous time step.
Position getVelocityVector() const
Returns the vehicle's direction in radians.
double getWidth() const
Get the width which vehicles of this class shall have when being drawn.
double getMinGap() const
Get the free space in front of vehicles of this class.
double getLength() const
Get vehicle's length [m].
const SUMOVTypeParameter & getParameter() const
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.
T get(const std::string &id) const
Retrieves an item.
A storage for options typed value containers)
void addDescription(const std::string &name, const std::string &subtopic, const std::string &description)
Adds a description for an option.
void doRegister(const std::string &name, Option *v)
Adds an option under the given name.
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
void addOptionSubTopic(const std::string &topic)
Adds an option subtopic.
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.
Static storage of an output device and its base (abstract) implementation.
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
bool writeXMLHeader(const std::string &rootElement, const std::string &schemaFile, std::map< SumoXMLAttr, std::string > attrs=std::map< SumoXMLAttr, std::string >(), bool includeConfig=true)
Writes an XML header with optional configuration.
static OutputDevice & getDevice(const std::string &name)
Returns the described OutputDevice.
virtual const std::string getParameter(const std::string &key, const std::string defaultValue="") const
Returns the value for a given key.
bool knowsParameter(const std::string &key) const
Returns whether the parameter is known.
A point in 2D or 3D with translation and scaling methods.
static const Position INVALID
used to indicate that a position is valid
double rotationAtOffset(double pos) const
Returns the rotation at the given length.
Representation of a vehicle, person, or container.
virtual bool isVehicle() const
Whether it is a vehicle.
virtual const MSVehicleType & getVehicleType() const =0
Returns the object's "vehicle" type.
virtual const SUMOVehicleParameter & getParameter() const =0
Returns the vehicle's parameter (including departure definition)
virtual const MSLane * getLane() const =0
Returns the lane the object is currently at.
virtual const MSEdge * getEdge() const =0
Returns the edge the object is currently at.
Representation of a vehicle.
virtual const MSRoute & getRoute() const =0
Returns the current route.
virtual bool isOnRoad() const =0
Returns the information whether the vehicle is on a road (is simulated)
virtual const ConstMSEdgeVector::const_iterator & getCurrentRouteEdge() const =0
Returns an iterator pointing to the current edge in this vehicles route.
std::vector< std::string > getVector()
return vector of strings
bool hasNext()
returns the information whether further substrings exist
std::string next()
returns the next substring when it exists. Otherwise the behaviour is undefined
static std::string urlDecode(const std::string &encoded)
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter
static bool startsWith(const std::string &str, const std::string prefix)
Checks whether a given string starts with the prefix.
static bool toBool(const std::string &sData)
converts a string into the bool value described by it by calling the char-type converter
EncounterType type
Type of the conflict.
double time
time point of the conflict
Position pos
Predicted location of the conflict: In case of MERGING and CROSSING: entry point to conflict area for...
double value
value of the corresponding SSM
std::vector< std::string > lane
std::vector< double > lanePos
Structure to collect some info on the encounter needed during ssm calculation by various functions.
double egoConflictEntryDist
double egoConflictAreaLength
EncounterApproachInfo(Encounter *e)
double foeConflictAreaLength
double foeConflictExitDist
double egoConflictExitDist
double foeEstimatedConflictEntryTime
std::pair< double, double > pet
double foeEstimatedConflictExitTime
double egoEstimatedConflictExitTime
double foeConflictEntryDist
double egoEstimatedConflictEntryTime
const MSLane * egoConflictLane
double egoDistToConflictLane
Auxiliary structure used to handle upstream scanning start points Upstream scan has to be started aft...
double egoDistToConflictLane
const MSLane * egoConflictLane