80#define AVAILABLE_SSMS "TTC DRAC PET BR SGAP TGAP PPET MDRAC"
81#define DEFAULT_THRESHOLD_TTC 3.
82#define DEFAULT_THRESHOLD_DRAC 3.
83#define DEFAULT_THRESHOLD_MDRAC 3.4
85#define DEFAULT_THRESHOLD_PET 2.
86#define DEFAULT_THRESHOLD_PPET 2.
88#define DEFAULT_THRESHOLD_BR 0.0
89#define DEFAULT_THRESHOLD_SGAP 0.2
90#define DEFAULT_THRESHOLD_TGAP 0.5
92#define DEFAULT_EXTRA_TIME 5.
109 out <<
"NOCONFLICT_AHEAD";
115 out <<
"FOLLOWING_FOLLOWER";
118 out <<
"FOLLOWING_LEADER";
121 out <<
"ON_ADJACENT_LANES";
127 out <<
"MERGING_LEADER";
130 out <<
"MERGING_FOLLOWER";
133 out <<
"MERGING_ADJACENT";
139 out <<
"CROSSING_LEADER";
142 out <<
"CROSSING_FOLLOWER";
145 out <<
"EGO_ENTERED_CONFLICT_AREA";
148 out <<
"FOE_ENTERED_CONFLICT_AREA";
151 out <<
"BOTH_ENTERED_CONFLICT_AREA";
154 out <<
"EGO_LEFT_CONFLICT_AREA";
157 out <<
"FOE_LEFT_CONFLICT_AREA";
160 out <<
"BOTH_LEFT_CONFLICT_AREA";
163 out <<
"FOLLOWING_PASSED";
166 out <<
"MERGING_PASSED";
176 out <<
"unknown type (" << int(type) <<
")";
187std::set<MSDevice_SSM*, ComparatorNumericalIdLess>*
MSDevice_SSM::myInstances =
new std::set<MSDevice_SSM*, ComparatorNumericalIdLess>();
194 ENCOUNTER_TYPE_FOLLOWING_LEADER, ENCOUNTER_TYPE_MERGING_FOLLOWER,
195 ENCOUNTER_TYPE_CROSSING_FOLLOWER, ENCOUNTER_TYPE_FOE_ENTERED_CONFLICT_AREA,
196 ENCOUNTER_TYPE_FOE_LEFT_CONFLICT_AREA
199 ENCOUNTER_TYPE_FOLLOWING_FOLLOWER, ENCOUNTER_TYPE_MERGING_LEADER,
200 ENCOUNTER_TYPE_CROSSING_LEADER, ENCOUNTER_TYPE_EGO_ENTERED_CONFLICT_AREA,
201 ENCOUNTER_TYPE_EGO_LEFT_CONFLICT_AREA
205const std::set<MSDevice_SSM*, ComparatorNumericalIdLess>&
215 device->resetEncounters();
216 device->flushConflicts(
true);
217 device->flushGlobalMeasures();
238 oc.
addDescription(
"device.ssm.measures",
"SSM Device",
TL(
"Specifies which measures will be logged (as a space or comma-separated sequence of IDs in ('TTC', 'DRAC', 'PET', 'PPET', 'MDRAC'))"));
240 oc.
addDescription(
"device.ssm.thresholds",
"SSM Device",
TL(
"Specifies space or comma-separated thresholds corresponding to the specified measures (see documentation and watch the order!). Only events exceeding the thresholds will be logged."));
242 oc.
addDescription(
"device.ssm.trajectories",
"SSM Device",
TL(
"Specifies whether trajectories will be logged (if false, only the extremal values and times are reported)."));
244 oc.
addDescription(
"device.ssm.range",
"SSM Device",
TL(
"Specifies the detection range in meters. For vehicles below this distance from the equipped vehicle, SSM values are traced."));
246 oc.
addDescription(
"device.ssm.extratime",
"SSM Device",
TL(
"Specifies the time in seconds to be logged after a conflict is over. Required >0 if PET is to be calculated for crossing conflicts."));
248 oc.
addDescription(
"device.ssm.mdrac.prt",
"SSM Device",
TL(
"Specifies the perception reaction time for MDRAC computation."));
250 oc.
addDescription(
"device.ssm.file",
"SSM Device",
TL(
"Give a global default filename for the SSM output"));
252 oc.
addDescription(
"device.ssm.geo",
"SSM Device",
TL(
"Whether to use coordinates of the original reference system in output"));
254 oc.
addDescription(
"device.ssm.write-positions",
"SSM Device",
TL(
"Whether to write positions (coordinates) for each timestep"));
256 oc.
addDescription(
"device.ssm.write-lane-positions",
"SSM Device",
TL(
"Whether to write lanes and their positions for each timestep"));
258 oc.
addDescription(
"device.ssm.exclude-conflict-types",
"SSM Device",
TL(
"Which conflicts will be excluded from the log according to the conflict type they have been classified (combination of values in 'ego', 'foe' , '', any numerical valid conflict type code). An empty value will log all and 'ego'/'foe' refer to a certain conflict type subset."));
267 std::ifstream strm(file.c_str());
269 throw ProcessError(
TLF(
"Could not load names of edges for filtering SSM device output from '%'.", file));
272 while (strm.good()) {
277 std::string edgeID = line.substr(5);
279 if (edge !=
nullptr) {
282 WRITE_WARNING(
"Unknown edge ID '" + edgeID +
"' in SSM device edge filter (" + file +
"): " + line);
286 std::string junctionID = line.substr(9);
288 if (junction !=
nullptr) {
293 WRITE_WARNING(
"Unknown junction ID '" + junctionID +
"' in SSM device edge filter (" + file +
"): " + line);
295 }
else if (line ==
"") {
297 WRITE_WARNING(
"Cannot interpret line in SSM device edge filter (" + file +
"): " + line);
307 WRITE_WARNINGF(
"SSM Device for vehicle '%' will not be built. (SSMs not supported in MESO)", v.
getID());
311 std::string deviceID =
"ssm_" + v.
getID();
316 std::map<std::string, double> thresholds;
341 std::vector<int> conflictTypeFilter;
348 MSDevice_SSM* device =
new MSDevice_SSM(v, deviceID, file, thresholds, trajectories, range, extraTime, useGeo, writePos, writeLanesPos, conflictTypeFilter);
349 into.push_back(device);
362 egoID(_ego->getID()),
363 foeID(_foe->getID()),
366 currentType(ENCOUNTER_TYPE_NOCONFLICT_AHEAD),
367 remainingExtraTime(extraTime),
377 closingRequested(false) {
378#ifdef DEBUG_ENCOUNTER
379 if (DEBUG_COND_ENCOUNTER(
this)) {
380 std::cout <<
"\n" <<
SIMTIME <<
" Constructing encounter of '" <<
ego->
getID() <<
"' and '" <<
foe->
getID() <<
"'" << std::endl;
386#ifdef DEBUG_ENCOUNTER
387 if (DEBUG_COND_ENCOUNTER(
this)) {
388 std::cout <<
"\n" <<
SIMTIME <<
" Destroying encounter of '" << egoID <<
"' and '" << foeID <<
"' (begin was " << begin <<
")" << std::endl;
397 Position conflictPoint,
double egoDistToConflict,
double foeDistToConflict,
double ttc,
double drac, std::pair<double, double> pet,
double ppet,
double mdrac) {
398#ifdef DEBUG_ENCOUNTER
399 if (DEBUG_COND_ENCOUNTER(
this))
400 std::cout << time <<
" Adding data point for encounter of '" << egoID <<
"' and '" << foeID <<
"':\n"
401 <<
"type=" << type <<
", egoDistToConflict=" << (egoDistToConflict ==
INVALID_DOUBLE ?
"NA" :
::toString(egoDistToConflict))
410 timeSpan.push_back(time);
411 typeSpan.push_back(type);
412 egoTrajectory.x.push_back(egoX);
413 egoTrajectory.lane.push_back(egoLane);
414 egoTrajectory.lanePos.push_back(egoLanePos);
415 egoTrajectory.v.push_back(egoV);
416 foeTrajectory.x.push_back(foeX);
417 foeTrajectory.lane.push_back(foeLane);
418 foeTrajectory.lanePos.push_back(foeLanePos);
419 foeTrajectory.v.push_back(foeV);
420 conflictPointSpan.push_back(conflictPoint);
421 egoDistsToConflict.push_back(egoDistToConflict);
422 foeDistsToConflict.push_back(foeDistToConflict);
424 TTCspan.push_back(ttc);
428 minTTC.pos = conflictPoint;
433 DRACspan.push_back(drac);
435 maxDRAC.value = drac;
437 maxDRAC.pos = conflictPoint;
443 PET.value = pet.second;
444 PET.time = pet.first;
445 PET.pos = conflictPoint;
449 PPETspan.push_back(ppet);
451 minPPET.value = ppet;
453 minPPET.pos = conflictPoint;
457 MDRACspan.push_back(mdrac);
459 maxMDRAC.value = mdrac;
460 maxMDRAC.time = time;
461 maxMDRAC.pos = conflictPoint;
462 maxMDRAC.type = type;
470 remainingExtraTime = value;
476 remainingExtraTime -= amount;
482 return remainingExtraTime;
517 std::cout <<
"\n" <<
SIMTIME <<
" Device '" <<
getID() <<
"' updateAndWriteOutput()\n"
518 <<
" Holder is off-road! Calling resetEncounters()."
531 std::cout <<
"\n" <<
SIMTIME <<
" Device '" <<
getID() <<
"' update()\n"
541 const MSEdge* egoEdge = &((*myHolderMS).getLane()->getEdge());
550 if (foes.size() > 0) {
551 std::cout <<
"Scanned surroundings: Found potential foes:\n";
552 for (FoeInfoMap::const_iterator i = foes.begin(); i != foes.end(); ++i) {
553 std::cout << i->first->getID() <<
" ";
555 std::cout << std::endl;
557 std::cout <<
"Scanned surroundings: No potential conflict could be identified." << std::endl;
594 double leaderSearchDist = 0;
595 std::pair<const MSVehicle*, double> leader(
nullptr, 0.);
603 if (leaderSearchDist > 0.) {
609 if (leader.first ==
nullptr || leader.second < 0) {
640 std::cout <<
"\n" <<
SIMTIME <<
" Device '" <<
getID() <<
"' createEncounters()" << std::endl;
641 std::cout <<
"New foes:\n";
642 for (FoeInfoMap::const_iterator vi = foes.begin(); vi != foes.end(); ++vi) {
643 std::cout << vi->first->getID() <<
"\n";
645 std::cout << std::endl;
649 for (FoeInfoMap::const_iterator foe = foes.begin(); foe != foes.end(); ++foe) {
656 assert(myOldestActiveEncounterBegin <= e->begin);
681 std::cout <<
"\n" <<
SIMTIME <<
" Device '" <<
getID() <<
"' processEncounters(forceClose = " << forceClose <<
")" << std::endl;
682 std::cout <<
"Currently present foes:\n";
683 for (FoeInfoMap::const_iterator vi = foes.begin(); vi != foes.end(); ++vi) {
684 std::cout << vi->first->getID() <<
"\n";
686 std::cout << std::endl;
702 if (foes.find(e->
foe) != foes.end()) {
714 std::cout <<
" Requesting encounter closure because both left conflict area of previous encounter but another encounter lies ahead." << std::endl;
728 std::cout <<
" Requesting encounter closure because..." << std::endl;
730 std::cout <<
" ... extra time elapsed." << std::endl;
731 }
else if (forceClose) {
732 std::cout <<
" ... closing was forced." << std::endl;
734 std::cout <<
" ... foe disappeared." << std::endl;
745 double eBegin = e->
begin;
770 std::cout <<
SIMTIME <<
" qualifiesAsConflict() for encounter of vehicles '"
796 assert(e->
size() > 0);
804 std::cout <<
SIMTIME <<
" closeEncounter() of vehicles '"
806 <<
"' (was ranked as " << (wasConflict ?
"conflict" :
"non-conflict") <<
")" << std::endl;
814 std::cout <<
"pastConflictsQueue of veh '" <<
myHolderMS->
getID() <<
"':\n";
822 std::cout <<
" Conflict with foe '" << c->foe <<
"' (time=" << c->begin <<
"-" << c->end <<
")\n";
824 if (c->begin < lastBegin) {
825 std::cout <<
" Queue corrupt...\n";
828 lastBegin = c->begin;
830 std::cout << std::endl;
843#ifdef DEBUG_ENCOUNTER
844 if (DEBUG_COND_ENCOUNTER(e)) {
845 std::cout <<
SIMTIME <<
" updateEncounter() of vehicles '" << e->
egoID <<
"' and '" << e->
foeID <<
"'\n";
872#ifdef DEBUG_ENCOUNTER
873 if (DEBUG_COND_ENCOUNTER(e)) {
874 std::cout <<
SIMTIME <<
" Encounter of vehicles '" << e->
egoID <<
"' and '" << e->
foeID <<
"' does not imply any conflict.\n";
905 if (e->
size() == 0) {
906#ifdef DEBUG_ENCOUNTER
907 if (DEBUG_COND_ENCOUNTER(e)) {
908 std::cout <<
SIMTIME <<
" type when creating encounter: " << eInfo.
type <<
"\n";
951 std::cout <<
SIMTIME <<
" determineConflictPoint()" << std::endl;
961 if (e->
size() == 0) {
966 assert(e->
size() > 0);
987 std::cout <<
"No conflict point associated with encounter type " << type << std::endl;
995 std::cout <<
" Conflict at " << eInfo.
conflictPoint << std::endl;
1010 std::cout <<
SIMTIME <<
" estimateConflictTimes() for ego '" << e->
egoID <<
"' and foe '" << e->
foeID <<
"'\n"
1011 <<
" encounter type: " << eInfo.
type <<
"\n"
1025 std::cout <<
" encouter type " << type <<
" -> no exit times to be calculated."
1037 std::cout <<
" encouter type " << type <<
" -> no entry/exit times to be calculated."
1135 std::cout <<
" -> ego is estimated leader at conflict entry."
1146 std::cout <<
" -> foe is estimated leader at conflict entry."
1164 std::cout <<
SIMTIME <<
" computeSSMs() for vehicles '"
1166 <<
"'" << std::endl;
1196 std::stringstream ss;
1197 ss <<
"'" << type <<
"'";
1198 WRITE_WARNING(
"Unknown or undetermined encounter type at computeSSMs(): " + ss.str());
1204 std::cout <<
"computeSSMs() for encounter of vehicles '" << e->
egoID <<
"' and '" << e->
foeID <<
"':\n"
1217 if (e->
size() == 0) {
1221 std::pair<double, double>& pet = eInfo.
pet;
1225 std::cout <<
SIMTIME <<
" determinePET() for encounter of vehicles '" << e->
egoID <<
"' and '" << e->
foeID <<
"'"
1240 std::cout <<
"PET for crossing encounter already calculated as " << e->
PET.
value
1283 std::cout <<
"determinePET: Both passed conflict area in the same step. Assume collision"
1298 std::cout <<
"Calculated PET = " << pet.second <<
" (at t=" << pet.first <<
")"
1305 std::cout <<
"PET unappropriate for merging and pre-crossing situations. No calculation performed."
1317 double& ttc = eInfo.
ttc;
1318 double& drac = eInfo.
drac;
1319 double& ppet = eInfo.
ppet;
1320 double& mdrac = eInfo.
mdrac;
1324 std::cout <<
SIMTIME <<
" determineTTCandDRAC() for encounter of vehicles '" << e->
egoID <<
"' and '" << e->
foeID <<
"' (type = " << eInfo.
type <<
")"
1373 std::cout <<
" Conflict times with constant speed extrapolation for merging situation:\n "
1389 std::cout <<
" No TTC and DRAC computed as one vehicle is stopped." << std::endl;
1394 double leaderEntryTime =
MIN2(egoEntryTime, foeEntryTime);
1395 double followerEntryTime =
MAX2(egoEntryTime, foeEntryTime);
1396 double leaderExitTime = leaderEntryTime == egoEntryTime ? egoExitTime : foeExitTime;
1404 ppet = followerEntryTime - leaderExitTime;
1407 if (leaderExitTime >= followerEntryTime) {
1410 ttc =
computeTTC(followerConflictDist, followerSpeed, 0.);
1415 drac =
computeDRAC(followerConflictDist, followerSpeed, 0.);
1423 std::cout <<
" Extrapolation predicts collision *at* merge point with TTC=" << ttc
1424 <<
", drac=" << drac << std::endl;
1431 double gapAfterMerge = followerConflictDist - leaderExitTime * followerSpeed;
1432 assert(gapAfterMerge >= 0);
1435 double ttcAfterMerge =
computeTTC(gapAfterMerge, followerSpeed, leaderSpeed);
1440 double g0 = followerConflictDist - leaderConflictDist - leaderLength;
1443 assert(leaderSpeed - followerSpeed > 0);
1448 drac =
computeDRAC(g0, followerSpeed, leaderSpeed);
1453 double g0 = followerConflictDist - leaderConflictDist - leaderLength;
1456 assert(leaderSpeed - followerSpeed > 0);
1469 std::cout <<
" Extrapolation does not predict any collision." << std::endl;
1471 std::cout <<
" Extrapolation predicts collision *after* merge point with TTC="
1504 ppet = entryTime - exitTime;
1533 ppet = entryTime - exitTime;
1544 std::stringstream ss;
1545 ss <<
"'" << type <<
"'";
1546 WRITE_WARNING(
"Underspecified or unknown encounter type in MSDevice_SSM::determineTTCandDRAC(): " + ss.str());
1566 std::cout <<
"computeTTC() with gap=" << gap <<
", followerSpeed=" << followerSpeed <<
", leaderSpeed=" << leaderSpeed
1572 double dv = followerSpeed - leaderSpeed;
1591 double dv = followerSpeed - leaderSpeed;
1595 assert(followerSpeed > 0.);
1596 return 0.5 * dv * dv / gap;
1609 double dv = followerSpeed - leaderSpeed;
1613 if (gap / dv == prt) {
1616 assert(followerSpeed > 0.);
1617 return 0.5 * dv / (gap / dv - prt);
1634#ifdef DEBUG_SSM_DRAC
1636 std::cout <<
SIMTIME <<
"computeDRAC() with"
1637 <<
"\ndEntry1=" << dEntry1 <<
", dEntry2=" << dEntry2
1638 <<
", dExit1=" << dExit1 <<
", dExit2=" << dExit2
1639 <<
",\nv1=" << v1 <<
", v2=" << v2
1644 if (dExit1 <= 0. || dExit2 <= 0.) {
1646#ifdef DEBUG_SSM_DRAC
1648 std::cout <<
"One already left conflict area -> drac == 0." << std::endl;
1653 if (dEntry1 <= 0. && dEntry2 <= 0.) {
1655#ifdef DEBUG_SSM_DRAC
1657 std::cout <<
"Both entered conflict area but neither left. -> collision!" << std::endl;
1663 double drac = std::numeric_limits<double>::max();
1666#ifdef DEBUG_SSM_DRAC
1668 std::cout <<
"Ego could break..." << std::endl;
1673 drac =
MIN2(drac, 2 * (v1 - dEntry1 / tExit2) / tExit2);
1674#ifdef DEBUG_SSM_DRAC
1676 std::cout <<
" Foe expected to leave in " << tExit2 <<
"-> Ego needs drac=" << drac << std::endl;
1684#ifdef DEBUG_SSM_DRAC
1686 std::cout <<
" Foe is expected stop on conflict area -> Ego needs drac=" << drac << std::endl;
1691#ifdef DEBUG_SSM_DRAC
1693 std::cout <<
" Foe is expected stop before conflict area -> no drac computation for ego (will be done for foe if applicable)" << std::endl;
1702#ifdef DEBUG_SSM_DRAC
1704 std::cout <<
"Foe could break..." << std::endl;
1709#ifdef DEBUG_SSM_DRAC
1711 std::cout <<
" Ego expected to leave in " << tExit1 <<
"-> Foe needs drac=" << (2 * (v2 - dEntry2 / tExit1) / tExit1) << std::endl;
1714 drac =
MIN2(drac, 2 * (v2 - dEntry2 / tExit1) / tExit1);
1719#ifdef DEBUG_SSM_DRAC
1721 std::cout <<
" Ego is expected stop on conflict area -> Foe needs drac=" <<
computeDRAC(dEntry2, v2, 0) << std::endl;
1727#ifdef DEBUG_SSM_DRAC
1729 std::cout <<
" Ego is expected stop before conflict area -> no drac computation for foe (done for ego if applicable)" << std::endl;
1749#ifdef DEBUG_ENCOUNTER
1750 if (DEBUG_COND_ENCOUNTER(e)) {
1751 std::cout <<
SIMTIME <<
" checkConflictEntryAndExit() for encounter of vehicles '" << e->
egoID <<
"' and '" << e->
foeID <<
"'"
1761 if (e->
size() == 0) {
1765 if (egoPastConflictExit) {
1766 if (foePastConflictExit) {
1768 }
else if (foePastConflictEntry) {
1773 }
else if (foePastConflictExit) {
1774 if (egoPastConflictEntry) {
1781 if (egoPastConflictEntry) {
1782 if (foePastConflictEntry) {
1787 }
else if (foePastConflictEntry) {
1815#ifdef DEBUG_ENCOUNTER
1816 if (DEBUG_COND_ENCOUNTER(e)) {
1831#ifdef DEBUG_ENCOUNTER
1832 if (DEBUG_COND_ENCOUNTER(e)) {
1849#ifdef DEBUG_ENCOUNTER
1850 if (DEBUG_COND_ENCOUNTER(e)) {
1867#ifdef DEBUG_ENCOUNTER
1868 if (DEBUG_COND_ENCOUNTER(e)) {
1884#ifdef DEBUG_ENCOUNTER
1885 if (DEBUG_COND_ENCOUNTER(e)) {
1886 std::cout <<
SIMTIME <<
" updatePassedEncounter() for vehicles '" << e->
egoID <<
"' and '" << e->
foeID <<
"'\n";
1890 if (foeInfo ==
nullptr) {
1893#ifdef DEBUG_ENCOUNTER
1894 if (DEBUG_COND_ENCOUNTER(e)) std::cout <<
" Foe is out of range. Counting down extra time."
1909#ifdef DEBUG_ENCOUNTER
1910 if (DEBUG_COND_ENCOUNTER(e)) {
1911 std::cout <<
" This encounter wasn't classified as a potential conflict lately.\n";
1914 if (foeInfo ==
nullptr) {
1920 std::cout <<
" Requesting encounter closure because foeInfo==nullptr" << std::endl;
1924#ifdef DEBUG_ENCOUNTER
1925 if (DEBUG_COND_ENCOUNTER(e)) {
1926 std::cout <<
" Closing encounter.\n";
1936#ifdef DEBUG_ENCOUNTER
1937 if (DEBUG_COND_ENCOUNTER(e)) {
1938 std::cout <<
" Encounter was previously classified as a follow/lead situation.\n";
1947#ifdef DEBUG_ENCOUNTER
1948 if (DEBUG_COND_ENCOUNTER(e)) {
1949 std::cout <<
" Encounter was previously classified as a merging situation.\n";
1964#ifdef DEBUG_ENCOUNTER
1965 if (DEBUG_COND_ENCOUNTER(e)) {
1966 std::cout <<
" Encounter was previously classified as a crossing situation of type " << lastPotentialConflictType <<
".\n";
1984#ifdef DEBUG_ENCOUNTER
1985 if (DEBUG_COND_ENCOUNTER(e))
1998 if ((!egoEnteredConflict) && !foeEnteredConflict) {
2002 eInfo.
type = lastPotentialConflictType;
2003 }
else if (egoEnteredConflict && !foeEnteredConflict) {
2005 }
else if ((!egoEnteredConflict) && foeEnteredConflict) {
2011 if ((!egoLeftConflict) && !foeLeftConflict) {
2015 }
else if (egoLeftConflict && !foeLeftConflict) {
2019 }
else if ((!egoLeftConflict) && foeLeftConflict) {
2034#ifdef DEBUG_ENCOUNTER
2035 if (DEBUG_COND_ENCOUNTER(e)) {
2036 std::cout <<
" Updated classification: " << eInfo.
type <<
"\n";
2045#ifdef DEBUG_ENCOUNTER
2046 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2047 std::cout <<
"classifyEncounter() called.\n";
2050 if (foeInfo ==
nullptr) {
2069#ifdef DEBUG_ENCOUNTER
2070 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2071 std::cout <<
" Ongoing crossing conflict will be traced by passedEncounter().\n";
2087 double foeDistToConflictLane;
2090#ifdef DEBUG_ENCOUNTER
2091 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter))
2092 std::cout <<
" egoConflictLane='" << (egoConflictLane == 0 ?
"NULL" : egoConflictLane->
getID()) <<
"'\n"
2093 <<
" foeConflictLane='" << (foeConflictLane == 0 ?
"NULL" : foeConflictLane->
getID()) <<
"'\n"
2094 <<
" egoDistToConflictLane=" << egoDistToConflictLane
2095 <<
" foeDistToConflictLane=" << foeDistToConflictLane
2110 if (foeConflictLane ==
nullptr) {
2113#ifdef DEBUG_ENCOUNTER
2114 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2115 std::cout <<
"-> Encounter type: No conflict.\n";
2120 if (egoConflictLane == egoLane) {
2123#ifdef DEBUG_ENCOUNTER
2124 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2125 std::cout <<
"-> ego " << e->
ego->
getID() <<
" isOpposite " << egoOpposite <<
" foe " << e->
foe->
getID() <<
" isOpposite " << foeOpposite <<
" .\n";
2129 if (foeLane == egoLane) {
2131 if (!egoOpposite && !foeOpposite) {
2139#ifdef DEBUG_ENCOUNTER
2140 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2141 std::cout <<
"-> Encounter type: Lead/follow-situation on non-internal lane '" << egoLane->
getID() <<
"'\n";
2144 }
else if (egoOpposite && foeOpposite) {
2152#ifdef DEBUG_ENCOUNTER
2153 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2154 std::cout <<
"-> Encounter type: Lead/follow-situation while both are driving in the opposite direction on non-internal lane '" << egoLane->
getID() <<
"'\n";
2175#ifdef DEBUG_ENCOUNTER
2176 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2177 std::cout <<
"-> Encounter type: oncoming on non-internal lane '" << egoLane->
getID() <<
"'\n";
2185 if (foeOpposite != egoOpposite) {
2190#ifdef DEBUG_ENCOUNTER
2191 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2192 std::cout <<
"-> Encounter type: " << type << std::endl;
2197 if (!egoOpposite && !foeOpposite) {
2200 assert(egoDistToConflictLane <= 0);
2202 if (foeConflictLane == egoLane) {
2206#ifdef DEBUG_ENCOUNTER
2207 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter))
2208 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' leads foe '"
2209 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2215#ifdef DEBUG_ENCOUNTER
2216 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2217 std::cout <<
"-> Encounter type: " << type << std::endl;
2222 }
else if (egoOpposite && foeOpposite) {
2234#ifdef DEBUG_ENCOUNTER
2235 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2236 std::cout <<
"-> Encounter type: Lead/follow-situation while both are driving in the opposite direction on non-internal lane '" << egoLane->
getID() <<
"'\n";
2260#ifdef DEBUG_ENCOUNTER
2261 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2262 std::cout <<
"-> Encounter type: oncoming on non-internal lane '" << egoLane->
getID() <<
"'\n";
2274 assert(foeDistToConflictLane <= 0);
2275 if (foeLane == egoConflictLane) {
2278#ifdef DEBUG_ENCOUNTER
2279 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter))
2280 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' follows foe '"
2281 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2287#ifdef DEBUG_ENCOUNTER
2288 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2289 std::cout <<
"-> Encounter type: " << type << std::endl;
2303 if (((!egoOpposite && foeOpposite) || (egoOpposite && !foeOpposite)) && egoConflictLane == foeConflictLane) {
2305#ifdef DEBUG_ENCOUNTER
2306 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2308 std::cout <<
"-> egoConflictLane: " << egoConflictLane->
getID() <<
" foeConflictLane: " << foeConflictLane->
getID() <<
" egoOpposite " << egoOpposite <<
" foeOpposite " << foeOpposite << std::endl;
2312 if (foeLane == egoLane) {
2314 if (!egoOpposite && !foeOpposite) {
2322#ifdef DEBUG_ENCOUNTER
2323 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2324 std::cout <<
"-> Encounter type: Lead/follow-situation on non-internal lane '" << egoLane->
getID() <<
"'\n";
2327 }
else if (egoOpposite && foeOpposite) {
2335#ifdef DEBUG_ENCOUNTER
2336 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2337 std::cout <<
"-> Encounter type: Lead/follow-situation while both are driving in the opposite direction on non-internal lane '" << egoLane->
getID() <<
"'\n";
2358#ifdef DEBUG_ENCOUNTER
2359 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2360 std::cout <<
"-> Encounter type: oncoming on non-internal lane '" << egoLane->
getID() <<
"'\n";
2368 if (foeOpposite != egoOpposite) {
2373#ifdef DEBUG_ENCOUNTER
2374 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2375 std::cout <<
"-> Encounter type: " << type << std::endl;
2379 if (!egoOpposite && !foeOpposite) {
2381 assert(egoDistToConflictLane <= 0);
2383 if (foeConflictLane == egoLane) {
2387#ifdef DEBUG_ENCOUNTER
2388 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter))
2389 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' leads foe '"
2390 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2396#ifdef DEBUG_ENCOUNTER
2397 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2398 std::cout <<
"-> Encounter type: " << type << std::endl;
2402 }
else if (egoOpposite && foeOpposite) {
2414#ifdef DEBUG_ENCOUNTER
2415 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2416 std::cout <<
"-> Encounter type: Lead/follow-situation while both are driving in the opposite direction on non-internal lane '" << egoLane->
getID() <<
"'\n";
2440#ifdef DEBUG_ENCOUNTER
2441 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2442 std::cout <<
"-> Encounter type: oncoming on non-internal lane '" << egoLane->
getID() <<
"'\n";
2448 if (egoEntryLink != foeEntryLink) {
2451#ifdef DEBUG_ENCOUNTER
2452 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2453 std::cout <<
"-> Encounter type: " << type << std::endl;
2458 if (egoLane == egoConflictLane && foeLane != foeConflictLane) {
2465#ifdef DEBUG_ENCOUNTER
2466 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter))
2467 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' leads foe '"
2468 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2471 }
else if (egoLane != egoConflictLane && foeLane == foeConflictLane) {
2478#ifdef DEBUG_ENCOUNTER
2479 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter))
2480 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' follows foe '"
2481 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2488#ifdef DEBUG_ENCOUNTER
2489 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter))
2490 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' merges with foe '"
2491 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2499 if (egoLane != egoConflictLane || foeLane != foeConflictLane) {
2503 if (egoLane == foeLane) {
2508#ifdef DEBUG_ENCOUNTER
2509 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter))
2510 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' leads foe '"
2511 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2518#ifdef DEBUG_ENCOUNTER
2519 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter))
2520 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' follows foe '"
2521 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2528#ifdef DEBUG_ENCOUNTER
2529 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2530 std::cout <<
" Lead/follow situation on consecutive internal lanes." << std::endl;
2537 if (egoLane == lane) {
2542 while (lane != foeLane) {
2548 egoConflictLane = lane;
2549#ifdef DEBUG_ENCOUNTER
2550 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter))
2551 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' follows foe '"
2552 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2557 }
else if (foeLane == lane) {
2562 while (lane != egoLane) {
2568 foeConflictLane = lane;
2569#ifdef DEBUG_ENCOUNTER
2570 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter))
2571 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' leads foe '"
2572 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2582#ifdef DEBUG_ENCOUNTER
2583 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter))
2584 std::cout <<
"-> Encounter type: Lead/follow-situation on connection from '" << egoEntryLink->
getLaneBefore()->
getID()
2585 <<
"' to '" << egoEntryLink->
getLane()->
getID() <<
"'" << std::endl;
2592 const std::vector<MSLink*>& egoFoeLinks = egoEntryLink->
getFoeLinks();
2593 const std::vector<MSLink*>& foeFoeLinks = foeEntryLink->
getFoeLinks();
2595 bool crossOrMerge = (find(egoFoeLinks.begin(), egoFoeLinks.end(), foeEntryLink) != egoFoeLinks.end()
2596 || std::find(foeFoeLinks.begin(), foeFoeLinks.end(), egoEntryLink) != foeFoeLinks.end());
2597 if (!crossOrMerge) {
2606#ifdef DEBUG_ENCOUNTER
2607 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2608 std::cout <<
"-> Encounter type: No conflict.\n";
2633#ifdef DEBUG_ENCOUNTER
2634 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter))
2635 std::cout <<
"-> Encounter type: Merging situation of ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' and foe '"
2636 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2643#ifdef DEBUG_ENCOUNTER
2644 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2645 std::cout <<
"-> Encounter type: No conflict: " << type << std::endl;
2661 egoDistToConflictLane -= offset;
2663 foeDistToConflictLane -= offset;
2668 while (foeConflictLane !=
nullptr && foeConflictLane->
isInternal()) {
2677 egoDistToConflictFromJunctionEntry = 0;
2678 WRITE_WARNINGF(
TL(
"Cannot compute SSM due to bad internal lane geometry at junction '%'. Crossing point between traffic from links % and % not found."),
2685 assert(foeConflictLane !=
nullptr && foeConflictLane->
isInternal());
2692 while (egoConflictLane !=
nullptr && egoConflictLane->
isInternal()) {
2701 foeDistToConflictFromJunctionEntry = 0;
2702 WRITE_WARNINGF(
TL(
"Cannot compute SSM due to bad internal lane geometry at junction '%'. Crossing point between traffic from links % and % not found."),
2709 assert(egoConflictLane !=
nullptr && egoConflictLane->
isInternal());
2734 assert(angle <= 2 *
M_PI);
2738 assert(angle >= -
M_PI);
2739 assert(angle <=
M_PI);
2741 double crossingOrientation = (angle < 0) - (angle > 0);
2761#ifdef DEBUG_ENCOUNTER
2762 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2763 std::cout <<
" Determined exact conflict distances for crossing conflict."
2764 <<
"\n crossingOrientation=" << crossingOrientation
2767 <<
", relativeAngle=" << angle
2768 <<
" (foe from " << (crossingOrientation > 0 ?
"right)" :
"left)")
2769 <<
"\n resulting offset for conflict entry distance:"
2772 <<
"\n distToConflictLane:"
2773 <<
"\n ego=" << egoDistToConflictLane
2774 <<
", foe=" << foeDistToConflictLane
2775 <<
"\n distToConflictFromJunctionEntry:"
2776 <<
"\n ego=" << egoDistToConflictFromJunctionEntry
2777 <<
", foe=" << foeDistToConflictFromJunctionEntry
2778 <<
"\n resulting entry distances:"
2781 <<
"\n resulting exit distances:"
2786 std::cout <<
"real egoConflictLane: '" << (egoConflictLane == 0 ?
"NULL" : egoConflictLane->
getID()) <<
"'\n"
2787 <<
"real foeConflictLane: '" << (foeConflictLane == 0 ?
"NULL" : foeConflictLane->
getID()) <<
"'\n"
2788 <<
"-> Encounter type: Crossing situation of ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' and foe '"
2789 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2807 std::cout <<
SIMTIME <<
" findFoeConflictLane() for foe '"
2809 <<
"' (with egoConflictLane=" << (egoConflictLane == 0 ?
"NULL" : egoConflictLane->
getID())
2819#ifdef DEBUG_SSM_OPPOSITE
2839 return egoConflictLane;
2848 return egoConflictLane;
2858 assert(foeLane->
isInternal() || *laneIter == foeLane);
2865 if (conflictJunction != 0) {
2866 std::cout <<
"Potential conflict on junction '" << conflictJunction->
getID()
2872 if (egoConflictLane !=
nullptr && egoConflictLane->
isInternal() && egoConflictLane->
getLinkCont()[0]->getViaLane() == foeLane) {
2873 distToConflictLane += egoConflictLane->
getLength();
2881 if (*laneIter ==
nullptr) {
2882 while (foeLane !=
nullptr && foeLane->
isInternal()) {
2883 distToConflictLane += foeLane->
getLength();
2884 foeLane = foeLane->
getLinkCont()[0]->getViaLane();
2887 assert(laneIter == foeBestLanesEnd || *laneIter != 0);
2891 while (laneIter != foeBestLanesEnd && distToConflictLane <=
myRange) {
2893 assert(*laneIter == foeLane || foeLane == 0);
2894 foeLane = *laneIter;
2899 std::cout <<
"Found conflict lane for foe: '" << foeLane->
getID() <<
"'" << std::endl;
2906 distToConflictLane += foeLane->
getLength();
2910 if (laneIter == foeBestLanesEnd) {
2913 MSLane*
const nextNonInternalLane = *laneIter;
2915 if (link ==
nullptr) {
2921 assert(foeLane == 0 || foeLane->
isInternal());
2922 if (foeLane ==
nullptr) {
2923 foeLane = nextNonInternalLane;
2927 assert(foeLane != 0);
2930 std::cout <<
"Found conflict lane for foe: '" << foeLane->
getID() <<
"'" << std::endl;
2938 foeLane = nextNonInternalLane;
2959 std::vector<int> foundTypes;
2961 std::set_intersection(
2963 encounterTypes.begin(), encounterTypes.end(),
2964 std::back_inserter(foundTypes));
2965 write = foundTypes.size() == 0;
2983 std::cout <<
SIMTIME <<
" flushGlobalMeasures() of vehicle '"
3057 std::cout <<
SIMTIME <<
" writeOutConflict() of vehicles '"
3185 std::string res =
"";
3186 for (std::vector<double>::const_iterator i = v.begin(); i != v.end(); ++i) {
3187 res += (i == v.begin() ?
"" :
" ") + (*i == NA ?
"NA" :
::toString(*i));
3194 std::string res =
"";
3195 for (std::vector<double>::const_iterator i = v.begin(); i != v.end(); ++i) {
3196 res += (i == v.begin() ?
"" :
" ") + (find(NAs.begin(), NAs.end(), *i) != NAs.end() ?
"NA" :
::toString(*i));
3204 std::string res =
"";
3205 for (PositionVector::const_iterator i = v.begin(); i != v.end(); ++i) {
3220 return v == NA ?
"NA" :
toString(v);
3228 std::vector<int> conflictTypeFilter) :
3274 std::vector<std::string> measures;
3275 std::vector<double> threshVals;
3277 measures.push_back(i->first);
3278 threshVals.push_back(i->second);
3280 std::cout <<
"Initialized ssm device '" <<
id <<
"' with "
3303#ifdef DEBUG_SSM_NOTIFICATIONS
3319#ifdef DEBUG_SSM_NOTIFICATIONS
3333 double ,
double newSpeed) {
3334#ifdef DEBUG_SSM_NOTIFICATIONS
3337 std::cout <<
SIMTIME <<
"device '" <<
getID() <<
"' notifyMove: newSpeed=" << newSpeed <<
"\n";
3352#ifdef DEBUG_SSM_SURROUNDING
3356 std::cout <<
SIMTIME <<
" Looking for surrounding vehicles for ego vehicle '" << veh.
getID()
3382 std::vector<MSLane*>::const_iterator laneIter = egoBestLanes.begin();
3383 assert(lane->
isInternal() || lane == *laneIter || isOpposite);
3385 if (lane->
isInternal() && egoBestLanes[0] !=
nullptr) {
3390 for (
int i = 0; i < (int)egoBestLanes.size(); i++) {
3391 if (egoBestLanes[i] !=
nullptr && egoBestLanes[i]->getEdge().getOppositeEdge() !=
nullptr) {
3392 egoBestLanes[i] = egoBestLanes[i]->getEdge().getOppositeEdge()->getLanes().back();
3398 const MSLane* nextNonInternalLane =
nullptr;
3406 double remainingDownstreamRange = range;
3408 double distToConflictLane = isOpposite ? pos - veh.
getLane()->
getLength() : -pos;
3411 std::set<const MSLane*> seenLanes;
3412 std::set<const MSJunction*> routeJunctions;
3416 std::vector<UpstreamScanStartInfo> upstreamScanStartPositions;
3425#ifdef DEBUG_SSM_SURROUNDING
3427 std::cout <<
SIMTIME <<
" Vehicle '" << veh.
getID() <<
"' is on internal edge " << edge->
getID() <<
"'." << std::endl;
3437 routeJunctions.insert(junction);
3443 for (ConstMSEdgeVector::const_iterator ei = incoming.begin(); ei != incoming.end(); ++ei) {
3444 if ((*ei)->isInternal()) {
3463 lane = *(++laneIter);
3469 double startScanPos = std::min(pos + remainingDownstreamRange, edgeLength);
3470 upstreamScanStartPositions.push_back(
UpstreamScanStartInfo(edge, startScanPos, std::max(0., startScanPos - pos + range + veh.
getLength()), distToConflictLane, lane));
3479 while (remainingDownstreamRange > 0.) {
3481#ifdef DEBUG_SSM_SURROUNDING
3483 std::cout <<
SIMTIME <<
" Scanning downstream for vehicle '" << veh.
getID() <<
"' on lane '" << veh.
getLane()->
getID() <<
"', position=" << pos <<
".\n"
3484 <<
"Considering edge '" << edge->
getID() <<
"' Remaining downstream range = " << remainingDownstreamRange
3485 <<
"\nbestLanes=" <<
::toString(egoBestLanes) <<
"\n"
3491 assert(pos == 0 || lane == veh.
getLane());
3492 if (pos + remainingDownstreamRange < lane->getLength()) {
3495 upstreamScanStartPositions.push_back(
UpstreamScanStartInfo(edge, pos + remainingDownstreamRange, remainingDownstreamRange, distToConflictLane, lane));
3506 remainingDownstreamRange -= lane->
getLength() - pos;
3507 distToConflictLane += lane->
getLength();
3512 assert(laneIter == egoBestLanes.end() || *laneIter != 0);
3515 if (laneIter != egoBestLanes.end()) {
3526 nextNonInternalLane = *laneIter;
3528 if (isOpposite && link ==
nullptr) {
3529 link = nextNonInternalLane->
getLinkTo(lane);
3530 if (link ==
nullptr) {
3534 if (link ==
nullptr) {
3541 if (lane ==
nullptr) {
3543 lane = nextNonInternalLane;
3545 if (seenLanes.count(lane) == 0) {
3546 seenLanes.insert(lane);
3553 if (seenLanes.count(lane) == 0) {
3556 routeJunctions.insert(junction);
3562 for (ConstMSEdgeVector::const_iterator ei = outgoing.begin(); ei != outgoing.end(); ++ei) {
3566 upstreamScanStartPositions.push_back(
UpstreamScanStartInfo(*ei, (*ei)->getLength(), range, distToConflictLane, lane));
3570 for (ConstMSEdgeVector::const_iterator ei = incoming.begin(); ei != incoming.end(); ++ei) {
3574 upstreamScanStartPositions.push_back(
UpstreamScanStartInfo(*ei, (*ei)->getLength(), range, distToConflictLane, lane));
3580 remainingDownstreamRange -= linkLength;
3581 distToConflictLane += linkLength;
3582#ifdef DEBUG_SSM_SURROUNDING
3584 std::cout <<
" Downstream Scan for vehicle '" << veh.
getID() <<
"' proceeded over junction '" << junction->
getID()
3585 <<
"',\n linkLength=" << linkLength <<
", remainingDownstreamRange=" << remainingDownstreamRange
3591 lane = nextNonInternalLane;
3594#ifdef DEBUG_SSM_SURROUNDING
3596 std::cout <<
" Downstream Scan for vehicle '" << veh.
getID() <<
"' stops at lane '" << lane->
getID()
3597 <<
"', which has already been scanned."
3618#ifdef DEBUG_SSM_SURROUNDING
3620 for (std::pair<const MSVehicle*, FoeInfo*> foeInfo : foeCollector) {
3621 std::cout <<
" foe " << foeInfo.first->getID() <<
" conflict at " << foeInfo.second->egoConflictLane->getID() <<
" egoDist " << foeInfo.second->egoDistToConflictLane << std::endl;
3627 const auto& it = foeCollector.find(&veh);
3628 if (it != foeCollector.end()) {
3630 foeCollector.erase(it);
3638#ifdef DEBUG_SSM_SURROUNDING
3640 std::cout <<
SIMTIME <<
" getUpstreamVehicles() for edge '" << scanStart.
edge->
getID() <<
"'"
3642 <<
" pos = " << scanStart.
pos <<
" range = " << scanStart.
range
3646 if (scanStart.
range <= 0) {
3652 if (seenLanes.find(lane) != seenLanes.end()) {
3655#ifdef DEBUG_SSM_SURROUNDING
3658 for (
MSVehicle*
const veh : lane->getVehiclesSecure()) {
3659 if (foeCollector.find(veh) != foeCollector.end()) {
3663 if (veh->getPositionOnLane() - veh->getLength() <= scanStart.
pos && veh->getPositionOnLane() >= scanStart.
pos - scanStart.
range) {
3664#ifdef DEBUG_SSM_SURROUNDING
3666 std::cout <<
"\t" << veh->getID() <<
"\n";
3673 foeCollector[veh] = c;
3676 lane->releaseVehicles();
3678#ifdef DEBUG_SSM_SURROUNDING
3680 std::cout <<
"\t" << lane->getID() <<
": Found " << foundCount <<
"\n";
3683 seenLanes.insert(lane);
3686#ifdef DEBUG_SSM_SURROUNDING
3688 std::cout << std::endl;
3696 if (scanStart.
range <= scanStart.
pos) {
3701 double remainingRange = scanStart.
range - scanStart.
pos;
3707 if (routeJunctions.find(junction) != routeJunctions.end()) {
3712 int incomingEdgeCount = 0;
3720 if (internalLane->getEdge().getSuccessors()[0]->getID() == scanStart.
edge->
getID()) {
3722 incomingEdgeCount++;
3727 if (incomingEdgeCount > 0) {
3729 if (inEdge->isInternal() || inEdge->isCrossing()) {
3733 for (
MSLane*
const lane : inEdge->getLanes()) {
3734 if (seenLanes.find(lane) != seenLanes.end()) {
3740#ifdef DEBUG_SSM_SURROUNDING
3748 if (distOnJunction >= remainingRange) {
3749#ifdef DEBUG_SSM_SURROUNDING
3764#ifdef DEBUG_SSM_SURROUNDING
3766 std::cout <<
SIMTIME <<
" getVehiclesOnJunction() for junction '" << junction->
getID()
3768 <<
"\nFound vehicles:"
3775 if (foeCollector.find(veh) != foeCollector.end()) {
3776 delete foeCollector[veh];
3781 foeCollector[veh] = c;
3782#ifdef DEBUG_SSM_SURROUNDING
3784 std::cout <<
"\t" << veh->getID() <<
" egoConflictLane=" <<
Named::getIDSecure(egoConflictLane) <<
"\n";
3791 if (seenLanes.find(egoJunctionLane) != seenLanes.end() || egoJunctionLane->
getEdge().
isCrossing()) {
3795 auto scanInternalLane = [&](
const MSLane * lane) {
3800 collectFoeInfos(vehicles);
3802 lane->releaseVehicles();
3806 if (lane->getCanonicalPredecessorLane()->isInternal()) {
3807 lane = lane->getCanonicalPredecessorLane();
3810 assert(!lane->getEntryLink()->fromInternalLane());
3815 collectFoeInfos(vehicles2);
3816 lane->releaseVehicles();
3821 if (lane->getLinkCont().size() > 1 && lane->getLinkCont()[0]->getViaLane() !=
nullptr) {
3823 lane = lane->getLinkCont()[0]->getViaLane();
3825 assert(lane->getLinkCont().size() == 0 || lane->getLinkCont()[0]->getViaLane() == 0);
3830 collectFoeInfos(vehicles2);
3831 lane->releaseVehicles();
3841 for (
MSLane* lane : foeLanes) {
3842 if (seenLanes.find(lane) != seenLanes.end()) {
3845 scanInternalLane(lane);
3846 seenLanes.insert(lane);
3849 scanInternalLane(egoJunctionLane);
3851#ifdef DEBUG_SSM_SURROUNDING
3853 std::cout << std::endl;
3873 std::string file = deviceID +
".xml";
3887 file = oc.
getString(
"device.ssm.file") ==
"" ? file : oc.
getString(
"device.ssm.file");
3889 WRITE_MESSAGEF(
TL(
"Vehicle '%' does not supply vehicle parameter 'device.ssm.file'. Using default of '%'."), v.
getID(), file);
3907 bool useGeo =
false;
3921 useGeo = oc.
getBool(
"device.ssm.geo");
3934 bool writePos =
false;
3948 writePos = oc.
getBool(
"device.ssm.write-positions");
3950 WRITE_MESSAGEF(
TL(
"Vehicle '%' does not supply vehicle parameter 'device.ssm.write-positions'. Using default of '%'."), v.
getID(),
toString(writePos));
3961 bool writeLanesPos =
false;
3975 writeLanesPos = oc.
getBool(
"device.ssm.write-lane-positions");
3977 WRITE_MESSAGEF(
TL(
"Vehicle '%' does not supply vehicle parameter 'device.ssm.write-positions'. Using default of '%'."), v.
getID(),
toString(writeLanesPos));
3981 return writeLanesPos;
3988 std::string typeString =
"";
4002 typeString = oc.
getString(
"device.ssm.exclude-conflict-types");
4004 WRITE_MESSAGEF(
TL(
"Vehicle '%' does not supply vehicle parameter 'device.ssm.exclude-conflict-types'. Using default of '%'."), v.
getID(), typeString);
4011 std::vector<std::string> found = st.
getVector();
4012 std::set<int> confirmed;
4013 for (std::vector<std::string>::const_iterator i = found.begin(); i != found.end(); ++i) {
4016 }
else if (*i ==
"ego") {
4019 confirmed.insert(std::stoi(*i));
4022 WRITE_ERRORF(
TL(
"SSM order filter '%' is not supported. Aborting construction of SSM device '%'."), *i, deviceID);
4026 conflictTypes.insert(conflictTypes.end(), confirmed.begin(), confirmed.end());
4048 range = oc.
getFloat(
"device.ssm.range");
4075 prt = oc.
getFloat(
"device.ssm.mdrac.prt");
4077 WRITE_MESSAGEF(
TL(
"Vehicle '%' does not supply vehicle parameter 'device.ssm.mdrac.prt'. Using default of '%'."), v.
getID(),
toString(prt));
4104 extraTime = oc.
getFloat(
"device.ssm.extratime");
4106 WRITE_MESSAGEF(
TL(
"Vehicle '%' does not supply vehicle parameter 'device.ssm.extratime'. Using default of '%'."), v.
getID(),
toString(extraTime));
4110 if (extraTime < 0.) {
4112 WRITE_WARNINGF(
TL(
"Negative (or no) value encountered for vehicle parameter 'device.ssm.extratime' in vehicle '%' using default value % instead."), v.
getID(),
::toString(extraTime));
4121 bool trajectories =
false;
4135 trajectories = oc.
getBool(
"device.ssm.trajectories");
4137 WRITE_MESSAGEF(
TL(
"Vehicle '%' does not supply vehicle parameter 'device.ssm.trajectories'. Using default of '%'."), v.
getID(),
toString(trajectories));
4141 return trajectories;
4150 std::string measures_str =
"";
4164 measures_str = oc.
getString(
"device.ssm.measures");
4166 WRITE_MESSAGEF(
TL(
"Vehicle '%' does not supply vehicle parameter 'device.ssm.measures'. Using default of '%'."), v.
getID(), measures_str);
4172 if (measures_str ==
"") {
4173 WRITE_WARNINGF(
"No measures specified for ssm device of vehicle '%'. Registering all available SSMs.", v.
getID());
4177 std::vector<std::string> available = st.
getVector();
4179 std::vector<std::string> measures = st.
getVector();
4180 for (std::vector<std::string>::const_iterator i = measures.begin(); i != measures.end(); ++i) {
4181 if (std::find(available.begin(), available.end(), *i) == available.end()) {
4183 WRITE_ERRORF(
TL(
"SSM identifier '%' is not supported. Aborting construction of SSM device '%'."), *i, deviceID);
4189 std::string thresholds_str =
"";
4203 thresholds_str = oc.
getString(
"device.ssm.thresholds");
4205 WRITE_MESSAGEF(
TL(
"Vehicle '%' does not supply vehicle parameter 'device.ssm.thresholds'. Using default of '%'."), v.
getID(), thresholds_str);
4212 if (thresholds_str !=
"") {
4214 while (count < (
int)measures.size() && st.
hasNext()) {
4216 thresholds.insert(std::make_pair(measures[count], thresh));
4219 if (thresholds.size() < measures.size() || st.
hasNext()) {
4220 WRITE_ERRORF(
TL(
"Given list of thresholds ('%') is not of the same size as the list of measures ('%').\nPlease specify exactly one threshold for each measure."), thresholds_str, measures_str);
4225 for (std::vector<std::string>::const_iterator i = measures.begin(); i != measures.end(); ++i) {
4228 }
else if (*i ==
"DRAC") {
4230 }
else if (*i ==
"MDRAC") {
4232 }
else if (*i ==
"PET") {
4234 }
else if (*i ==
"PPET") {
4236 }
else if (*i ==
"BR") {
4238 }
else if (*i ==
"SGAP") {
4240 }
else if (*i ==
"TGAP") {
4243 WRITE_ERROR(
"Unknown SSM identifier '" + (*i) +
"'. Aborting construction of ssm device.");
4269 if (key ==
"minTTC" ||
4271 key ==
"maxMDRAC" ||
4281 minTTC =
MIN2(minTTC, e->minTTC.value);
4282 minPET =
MIN2(minPET, e->PET.value);
4283 maxDRAC =
MAX2(maxDRAC, e->maxDRAC.value);
4284 maxMDRAC =
MAX2(maxMDRAC, e->maxMDRAC.value);
4285 minPPET =
MIN2(minPPET, e->minPPET.value);
4287 if (key ==
"minTTC") {
4289 }
else if (key ==
"maxDRAC") {
4291 }
else if (key ==
"maxMDRAC") {
4293 }
else if (key ==
"minPET") {
4295 }
else if (key ==
"minPPET") {
4316 if (
false || key ==
"foo") {
#define DEFAULT_THRESHOLD_SGAP
#define DEFAULT_THRESHOLD_BR
#define DEFAULT_THRESHOLD_TGAP
#define DEFAULT_THRESHOLD_PPET
#define DEFAULT_THRESHOLD_DRAC
#define DEFAULT_THRESHOLD_TTC
#define DEFAULT_EXTRA_TIME
#define DEFAULT_THRESHOLD_PET
#define DEFAULT_THRESHOLD_MDRAC
std::ostream & operator<<(std::ostream &out, MSDevice_SSM::EncounterType type)
Nicer output for EncounterType enum.
std::vector< const MSEdge * > ConstMSEdgeVector
#define WRITE_WARNINGF(...)
#define WRITE_MESSAGEF(...)
#define WRITE_ERRORF(...)
#define WRITE_WARNING(msg)
std::string time2string(SUMOTime t, bool humanReadable)
convert SUMOTime to string (independently of global format setting)
@ SVC_IGNORING
vehicles ignoring classes
int gPrecision
the precision for floating point outputs
const double INVALID_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.
static const GeoConvHelper & getFinal()
the coordinate transformation for writing the location element and for tracking the original coordina...
void cartesian2geo(Position &cartesian) const
Converts the given cartesian (shifted) position to its geo (lat/long) representation.
The base class for microscopic and mesoscopic vehicles.
const MSRouteIterator & getCurrentRouteEdge() const
Returns an iterator pointing to the current edge in this vehicles route.
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 MSRoute & getRoute() const
Returns the current route.
const MSVehicleType & getVehicleType() const
Returns the vehicle's type definition.
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...
ConflictPointInfo minPPET
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.
std::vector< double > MDRACspan
All values for MDRAC.
void resetExtraTime(double value)
resets remainingExtraTime to the given value
ConflictPointInfo maxMDRAC
PositionVector conflictPointSpan
Predicted location of the conflict: In case of MERGING and CROSSING: entry point to conflict area for...
ConflictPointInfo maxDRAC
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 > PPETspan
All values for PPET.
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, double ppet, double mdrac)
add a new data point and update encounter type
std::vector< double > DRACspan
All values for DRAC.
A device which collects info on the vehicle trip (mainly on departure and arrival)
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 > myCreatedOutputFiles
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 std::string writeNA(double v, double NA=INVALID_DOUBLE)
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)
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 double getMDRAC_PRT(const SUMOVehicle &v)
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)
void determineTTCandDRACandPPETandMDRAC(EncounterApproachInfo &eInfo) const
Discriminates between different encounter types and correspondingly determines TTC and DRAC for those...
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.
std::vector< int > myDroppedConflictTypes
Which conflict types to exclude from the output.
static int myIssuedParameterWarnFlags
bitset storing info whether warning has already been issued about unset parameter (warn only once!...
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 ...
static const std::set< int > FOE_ENCOUNTERTYPES
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 double computeMDRAC(double gap, double followerSpeed, double leaderSpeed, double prt)
Computes the MDRAC (deceleration to avoid a collision) for a lead/follow situation as defined conside...
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
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, std::vector< int > conflictOrder)
Constructor.
static const std::set< int > EGO_ENCOUNTERTYPES
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.
bool myFilterConflictTypes
Whether to exclude certain conflicts containing certain conflict types from the output.
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.
@ SSM_WARN_CONFLICTFILTER
static bool filterByConflictType(const SUMOVehicle &v, std::string deviceID, std::vector< int > &conflictTypes)
~MSDevice_SSM()
Destructor.
double myMDRACPRT
perception reaction time for MDRAC
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 std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
const MSEdge * getOppositeEdge() const
Returns the opposite direction edge if on exists else a nullptr.
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
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....
The base class for an intersection.
virtual const std::vector< MSLane * > & getFoeInternalLanes(const MSLink *const) const
virtual const std::vector< MSLane * > getInternalLanes() const
Returns all internal lanes on the junction.
const ConstMSEdgeVector & getOutgoing() const
const ConstMSEdgeVector & getIncoming() const
Representation of a lane in the micro simulation.
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.
const std::vector< IncomingLaneInfo > & getIncomingLanes() const
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
virtual const PositionVector & getShape(bool) const
MSLane * getParallelOpposite() const
return the opposite direction lane of this lanes edge or nullptr
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 std::vector< const MSLane * > & getFoeLanes() const
const MSLane * getInternalLaneBefore() const
return myInternalLaneBefore (always 0 when compiled without internal lanes)
MSJunction * getJunction() const
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
const std::vector< MSLink * > & getFoeLinks() const
bool isInternalJunctionLink() const
return whether the fromLane and the toLane of this link are internal lanes
MSLane * getViaLane() const
Returns the following inner lane.
double getInternalLengthsAfter() const
Returns the cumulative length of all internal lanes after this link.
double getLengthsBeforeCrossing(const MSLane *foeLane) const
Returns the sum of the lengths along internal lanes following this link to the crossing with the give...
const MSLink * getCorrespondingExitLink() const
returns the corresponding exit link for entryLinks to a junction.
Notification
Definition of a vehicle state.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
MSJunctionControl & getJunctionControl()
Returns the junctions control.
MSVehicleControl & getVehicleControl()
Returns the vehicle 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.
const MSLane * getLane() const
Returns the lane the vehicle is on.
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.
const MSCFModel & getCarFollowModel() const
Returns the vehicle's car following model definition.
double getPositionOnLane() const
Get the vehicle's position along the lane.
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.
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)
bool isDefault(const std::string &name) const
Returns the information whether the named option has still the default value.
void doRegister(const std::string &name, Option *o)
Adds an option under the given name.
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 & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
static OutputDevice & getDevice(const std::string &name, bool usePrefix=true)
Returns the described OutputDevice.
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.
bool hasParameter(const std::string &key) const
Returns whether the parameter is set.
virtual const std::string getParameter(const std::string &key, const std::string defaultValue="") const
Returns the value for a given key.
A point in 2D or 3D with translation and scaling methods.
static const Position INVALID
used to indicate that a position is valid
double distanceTo(const Position &p2) const
returns the euclidean distance in 3 dimensions
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 MSLane * getLane() const =0
Returns the lane the object is currently at.
virtual const SUMOVehicleParameter & getParameter() const =0
Returns the vehicle's parameter (including departure definition)
virtual const MSEdge * getEdge() const =0
Returns the edge the object is currently at.
Representation of a vehicle.
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.
virtual const MSRoute & getRoute() const =0
Returns the current 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)
decode url (stem from http://bogomip.net/blog/cpp-url-encoding-and-decoding/)
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
double speed
speed of the reporting vehicle at the given time/position
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