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.write-na",
"SSM Device",
TL(
"Whether to write conflict outputs with no data as NA values or skip it"));
260 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."));
269 std::ifstream strm(file.c_str());
271 throw ProcessError(
TLF(
"Could not load names of edges for filtering SSM device output from '%'.", file));
274 while (strm.good()) {
279 std::string edgeID = line.substr(5);
281 if (edge !=
nullptr) {
284 WRITE_WARNING(
"Unknown edge ID '" + edgeID +
"' in SSM device edge filter (" + file +
"): " + line);
288 std::string junctionID = line.substr(9);
290 if (junction !=
nullptr) {
295 WRITE_WARNING(
"Unknown junction ID '" + junctionID +
"' in SSM device edge filter (" + file +
"): " + line);
297 }
else if (line ==
"") {
299 WRITE_WARNING(
"Cannot interpret line in SSM device edge filter (" + file +
"): " + line);
309 WRITE_WARNINGF(
"SSM Device for vehicle '%' will not be built. (SSMs not supported in MESO)", v.
getID());
313 std::string deviceID =
"ssm_" + v.
getID();
318 std::map<std::string, double> thresholds;
343 std::vector<int> conflictTypeFilter;
350 MSDevice_SSM* device =
new MSDevice_SSM(v, deviceID, file, thresholds, trajectories, range, extraTime, useGeo, writePos, writeLanesPos, conflictTypeFilter);
351 into.push_back(device);
364 egoID(_ego->getID()),
365 foeID(_foe->getID()),
368 currentType(ENCOUNTER_TYPE_NOCONFLICT_AHEAD),
369 remainingExtraTime(extraTime),
379 closingRequested(false) {
380#ifdef DEBUG_ENCOUNTER
381 if (DEBUG_COND_ENCOUNTER(
this)) {
382 std::cout <<
"\n" <<
SIMTIME <<
" Constructing encounter of '" <<
ego->
getID() <<
"' and '" <<
foe->
getID() <<
"'" << std::endl;
388#ifdef DEBUG_ENCOUNTER
389 if (DEBUG_COND_ENCOUNTER(
this)) {
390 std::cout <<
"\n" <<
SIMTIME <<
" Destroying encounter of '" << egoID <<
"' and '" << foeID <<
"' (begin was " << begin <<
")" << std::endl;
399 Position conflictPoint,
double egoDistToConflict,
double foeDistToConflict,
double ttc,
double drac, std::pair<double, double> pet,
double ppet,
double mdrac) {
400#ifdef DEBUG_ENCOUNTER
401 if (DEBUG_COND_ENCOUNTER(
this))
402 std::cout << time <<
" Adding data point for encounter of '" << egoID <<
"' and '" << foeID <<
"':\n"
403 <<
"type=" << type <<
", egoDistToConflict=" << (egoDistToConflict ==
INVALID_DOUBLE ?
"NA" :
::toString(egoDistToConflict))
412 timeSpan.push_back(time);
413 typeSpan.push_back(type);
414 egoTrajectory.x.push_back(egoX);
415 egoTrajectory.lane.push_back(egoLane);
416 egoTrajectory.lanePos.push_back(egoLanePos);
417 egoTrajectory.v.push_back(egoV);
418 foeTrajectory.x.push_back(foeX);
419 foeTrajectory.lane.push_back(foeLane);
420 foeTrajectory.lanePos.push_back(foeLanePos);
421 foeTrajectory.v.push_back(foeV);
422 conflictPointSpan.push_back(conflictPoint);
423 egoDistsToConflict.push_back(egoDistToConflict);
424 foeDistsToConflict.push_back(foeDistToConflict);
426 TTCspan.push_back(ttc);
430 minTTC.pos = conflictPoint;
435 DRACspan.push_back(drac);
437 maxDRAC.value = drac;
439 maxDRAC.pos = conflictPoint;
445 PET.value = pet.second;
446 PET.time = pet.first;
447 PET.pos = conflictPoint;
451 PPETspan.push_back(ppet);
453 minPPET.value = ppet;
455 minPPET.pos = conflictPoint;
459 MDRACspan.push_back(mdrac);
461 maxMDRAC.value = mdrac;
462 maxMDRAC.time = time;
463 maxMDRAC.pos = conflictPoint;
464 maxMDRAC.type = type;
472 remainingExtraTime = value;
478 remainingExtraTime -= amount;
484 return remainingExtraTime;
519 std::cout <<
"\n" <<
SIMTIME <<
" Device '" <<
getID() <<
"' updateAndWriteOutput()\n"
520 <<
" Holder is off-road! Calling resetEncounters()."
533 std::cout <<
"\n" <<
SIMTIME <<
" Device '" <<
getID() <<
"' update()\n"
543 const MSEdge* egoEdge = &((*myHolderMS).getLane()->getEdge());
552 if (foes.size() > 0) {
553 std::cout <<
"Scanned surroundings: Found potential foes:\n";
554 for (FoeInfoMap::const_iterator i = foes.begin(); i != foes.end(); ++i) {
555 std::cout << i->first->getID() <<
" ";
557 std::cout << std::endl;
559 std::cout <<
"Scanned surroundings: No potential conflict could be identified." << std::endl;
596 double leaderSearchDist = 0;
597 std::pair<const MSVehicle*, double> leader(
nullptr, 0.);
605 if (leaderSearchDist > 0.) {
611 if (leader.first ==
nullptr || leader.second < 0) {
642 std::cout <<
"\n" <<
SIMTIME <<
" Device '" <<
getID() <<
"' createEncounters()" << std::endl;
643 std::cout <<
"New foes:\n";
644 for (FoeInfoMap::const_iterator vi = foes.begin(); vi != foes.end(); ++vi) {
645 std::cout << vi->first->getID() <<
"\n";
647 std::cout << std::endl;
651 for (FoeInfoMap::const_iterator foe = foes.begin(); foe != foes.end(); ++foe) {
658 assert(myOldestActiveEncounterBegin <= e->begin);
683 std::cout <<
"\n" <<
SIMTIME <<
" Device '" <<
getID() <<
"' processEncounters(forceClose = " << forceClose <<
")" << std::endl;
684 std::cout <<
"Currently present foes:\n";
685 for (FoeInfoMap::const_iterator vi = foes.begin(); vi != foes.end(); ++vi) {
686 std::cout << vi->first->getID() <<
"\n";
688 std::cout << std::endl;
704 if (foes.find(e->
foe) != foes.end()) {
716 std::cout <<
" Requesting encounter closure because both left conflict area of previous encounter but another encounter lies ahead." << std::endl;
730 std::cout <<
" Requesting encounter closure because..." << std::endl;
732 std::cout <<
" ... extra time elapsed." << std::endl;
733 }
else if (forceClose) {
734 std::cout <<
" ... closing was forced." << std::endl;
736 std::cout <<
" ... foe disappeared." << std::endl;
747 double eBegin = e->
begin;
772 std::cout <<
SIMTIME <<
" qualifiesAsConflict() for encounter of vehicles '"
798 assert(e->
size() > 0);
806 std::cout <<
SIMTIME <<
" closeEncounter() of vehicles '"
808 <<
"' (was ranked as " << (wasConflict ?
"conflict" :
"non-conflict") <<
")" << std::endl;
816 std::cout <<
"pastConflictsQueue of veh '" <<
myHolderMS->
getID() <<
"':\n";
824 std::cout <<
" Conflict with foe '" << c->foe <<
"' (time=" << c->begin <<
"-" << c->end <<
")\n";
826 if (c->begin < lastBegin) {
827 std::cout <<
" Queue corrupt...\n";
830 lastBegin = c->begin;
832 std::cout << std::endl;
845#ifdef DEBUG_ENCOUNTER
846 if (DEBUG_COND_ENCOUNTER(e)) {
847 std::cout <<
SIMTIME <<
" updateEncounter() of vehicles '" << e->
egoID <<
"' and '" << e->
foeID <<
"'\n";
874#ifdef DEBUG_ENCOUNTER
875 if (DEBUG_COND_ENCOUNTER(e)) {
876 std::cout <<
SIMTIME <<
" Encounter of vehicles '" << e->
egoID <<
"' and '" << e->
foeID <<
"' does not imply any conflict.\n";
907 if (e->
size() == 0) {
908#ifdef DEBUG_ENCOUNTER
909 if (DEBUG_COND_ENCOUNTER(e)) {
910 std::cout <<
SIMTIME <<
" type when creating encounter: " << eInfo.
type <<
"\n";
953 std::cout <<
SIMTIME <<
" determineConflictPoint()" << std::endl;
963 if (e->
size() == 0) {
968 assert(e->
size() > 0);
989 std::cout <<
"No conflict point associated with encounter type " << type << std::endl;
997 std::cout <<
" Conflict at " << eInfo.
conflictPoint << std::endl;
1012 std::cout <<
SIMTIME <<
" estimateConflictTimes() for ego '" << e->
egoID <<
"' and foe '" << e->
foeID <<
"'\n"
1013 <<
" encounter type: " << eInfo.
type <<
"\n"
1027 std::cout <<
" encouter type " << type <<
" -> no exit times to be calculated."
1039 std::cout <<
" encouter type " << type <<
" -> no entry/exit times to be calculated."
1137 std::cout <<
" -> ego is estimated leader at conflict entry."
1148 std::cout <<
" -> foe is estimated leader at conflict entry."
1166 std::cout <<
SIMTIME <<
" computeSSMs() for vehicles '"
1168 <<
"'" << std::endl;
1198 std::stringstream ss;
1199 ss <<
"'" << type <<
"'";
1200 WRITE_WARNING(
"Unknown or undetermined encounter type at computeSSMs(): " + ss.str());
1206 std::cout <<
"computeSSMs() for encounter of vehicles '" << e->
egoID <<
"' and '" << e->
foeID <<
"':\n"
1219 if (e->
size() == 0) {
1223 std::pair<double, double>& pet = eInfo.
pet;
1227 std::cout <<
SIMTIME <<
" determinePET() for encounter of vehicles '" << e->
egoID <<
"' and '" << e->
foeID <<
"'"
1242 std::cout <<
"PET for crossing encounter already calculated as " << e->
PET.
value
1285 std::cout <<
"determinePET: Both passed conflict area in the same step. Assume collision"
1300 std::cout <<
"Calculated PET = " << pet.second <<
" (at t=" << pet.first <<
")"
1307 std::cout <<
"PET unappropriate for merging and pre-crossing situations. No calculation performed."
1319 double& ttc = eInfo.
ttc;
1320 double& drac = eInfo.
drac;
1321 double& ppet = eInfo.
ppet;
1322 double& mdrac = eInfo.
mdrac;
1326 std::cout <<
SIMTIME <<
" determineTTCandDRAC() for encounter of vehicles '" << e->
egoID <<
"' and '" << e->
foeID <<
"' (type = " << eInfo.
type <<
")"
1375 std::cout <<
" Conflict times with constant speed extrapolation for merging situation:\n "
1391 std::cout <<
" No TTC and DRAC computed as one vehicle is stopped." << std::endl;
1396 double leaderEntryTime =
MIN2(egoEntryTime, foeEntryTime);
1397 double followerEntryTime =
MAX2(egoEntryTime, foeEntryTime);
1398 double leaderExitTime = leaderEntryTime == egoEntryTime ? egoExitTime : foeExitTime;
1406 ppet = followerEntryTime - leaderExitTime;
1409 if (leaderExitTime >= followerEntryTime) {
1412 ttc =
computeTTC(followerConflictDist, followerSpeed, 0.);
1417 drac =
computeDRAC(followerConflictDist, followerSpeed, 0.);
1425 std::cout <<
" Extrapolation predicts collision *at* merge point with TTC=" << ttc
1426 <<
", drac=" << drac << std::endl;
1433 double gapAfterMerge = followerConflictDist - leaderExitTime * followerSpeed;
1434 assert(gapAfterMerge >= 0);
1437 double ttcAfterMerge =
computeTTC(gapAfterMerge, followerSpeed, leaderSpeed);
1442 double g0 = followerConflictDist - leaderConflictDist - leaderLength;
1445 assert(leaderSpeed - followerSpeed > 0);
1450 drac =
computeDRAC(g0, followerSpeed, leaderSpeed);
1455 double g0 = followerConflictDist - leaderConflictDist - leaderLength;
1458 assert(leaderSpeed - followerSpeed > 0);
1471 std::cout <<
" Extrapolation does not predict any collision." << std::endl;
1473 std::cout <<
" Extrapolation predicts collision *after* merge point with TTC="
1506 ppet = entryTime - exitTime;
1535 ppet = entryTime - exitTime;
1546 std::stringstream ss;
1547 ss <<
"'" << type <<
"'";
1548 WRITE_WARNING(
"Underspecified or unknown encounter type in MSDevice_SSM::determineTTCandDRAC(): " + ss.str());
1568 std::cout <<
"computeTTC() with gap=" << gap <<
", followerSpeed=" << followerSpeed <<
", leaderSpeed=" << leaderSpeed
1574 double dv = followerSpeed - leaderSpeed;
1593 double dv = followerSpeed - leaderSpeed;
1597 assert(followerSpeed > 0.);
1598 return 0.5 * dv * dv / gap;
1611 double dv = followerSpeed - leaderSpeed;
1615 if (gap / dv == prt) {
1618 assert(followerSpeed > 0.);
1619 return 0.5 * dv / (gap / dv - prt);
1636#ifdef DEBUG_SSM_DRAC
1638 std::cout <<
SIMTIME <<
"computeDRAC() with"
1639 <<
"\ndEntry1=" << dEntry1 <<
", dEntry2=" << dEntry2
1640 <<
", dExit1=" << dExit1 <<
", dExit2=" << dExit2
1641 <<
",\nv1=" << v1 <<
", v2=" << v2
1646 if (dExit1 <= 0. || dExit2 <= 0.) {
1648#ifdef DEBUG_SSM_DRAC
1650 std::cout <<
"One already left conflict area -> drac == 0." << std::endl;
1655 if (dEntry1 <= 0. && dEntry2 <= 0.) {
1657#ifdef DEBUG_SSM_DRAC
1659 std::cout <<
"Both entered conflict area but neither left. -> collision!" << std::endl;
1665 double drac = std::numeric_limits<double>::max();
1668#ifdef DEBUG_SSM_DRAC
1670 std::cout <<
"Ego could break..." << std::endl;
1675 drac =
MIN2(drac, 2 * (v1 - dEntry1 / tExit2) / tExit2);
1676#ifdef DEBUG_SSM_DRAC
1678 std::cout <<
" Foe expected to leave in " << tExit2 <<
"-> Ego needs drac=" << drac << std::endl;
1686#ifdef DEBUG_SSM_DRAC
1688 std::cout <<
" Foe is expected stop on conflict area -> Ego needs drac=" << drac << std::endl;
1693#ifdef DEBUG_SSM_DRAC
1695 std::cout <<
" Foe is expected stop before conflict area -> no drac computation for ego (will be done for foe if applicable)" << std::endl;
1704#ifdef DEBUG_SSM_DRAC
1706 std::cout <<
"Foe could break..." << std::endl;
1711#ifdef DEBUG_SSM_DRAC
1713 std::cout <<
" Ego expected to leave in " << tExit1 <<
"-> Foe needs drac=" << (2 * (v2 - dEntry2 / tExit1) / tExit1) << std::endl;
1716 drac =
MIN2(drac, 2 * (v2 - dEntry2 / tExit1) / tExit1);
1721#ifdef DEBUG_SSM_DRAC
1723 std::cout <<
" Ego is expected stop on conflict area -> Foe needs drac=" <<
computeDRAC(dEntry2, v2, 0) << std::endl;
1729#ifdef DEBUG_SSM_DRAC
1731 std::cout <<
" Ego is expected stop before conflict area -> no drac computation for foe (done for ego if applicable)" << std::endl;
1751#ifdef DEBUG_ENCOUNTER
1752 if (DEBUG_COND_ENCOUNTER(e)) {
1753 std::cout <<
SIMTIME <<
" checkConflictEntryAndExit() for encounter of vehicles '" << e->
egoID <<
"' and '" << e->
foeID <<
"'"
1763 if (e->
size() == 0) {
1767 if (egoPastConflictExit) {
1768 if (foePastConflictExit) {
1770 }
else if (foePastConflictEntry) {
1775 }
else if (foePastConflictExit) {
1776 if (egoPastConflictEntry) {
1783 if (egoPastConflictEntry) {
1784 if (foePastConflictEntry) {
1789 }
else if (foePastConflictEntry) {
1817#ifdef DEBUG_ENCOUNTER
1818 if (DEBUG_COND_ENCOUNTER(e)) {
1833#ifdef DEBUG_ENCOUNTER
1834 if (DEBUG_COND_ENCOUNTER(e)) {
1851#ifdef DEBUG_ENCOUNTER
1852 if (DEBUG_COND_ENCOUNTER(e)) {
1869#ifdef DEBUG_ENCOUNTER
1870 if (DEBUG_COND_ENCOUNTER(e)) {
1886#ifdef DEBUG_ENCOUNTER
1887 if (DEBUG_COND_ENCOUNTER(e)) {
1888 std::cout <<
SIMTIME <<
" updatePassedEncounter() for vehicles '" << e->
egoID <<
"' and '" << e->
foeID <<
"'\n";
1892 if (foeInfo ==
nullptr) {
1895#ifdef DEBUG_ENCOUNTER
1896 if (DEBUG_COND_ENCOUNTER(e)) std::cout <<
" Foe is out of range. Counting down extra time."
1911#ifdef DEBUG_ENCOUNTER
1912 if (DEBUG_COND_ENCOUNTER(e)) {
1913 std::cout <<
" This encounter wasn't classified as a potential conflict lately.\n";
1916 if (foeInfo ==
nullptr) {
1922 std::cout <<
" Requesting encounter closure because foeInfo==nullptr" << std::endl;
1926#ifdef DEBUG_ENCOUNTER
1927 if (DEBUG_COND_ENCOUNTER(e)) {
1928 std::cout <<
" Closing encounter.\n";
1938#ifdef DEBUG_ENCOUNTER
1939 if (DEBUG_COND_ENCOUNTER(e)) {
1940 std::cout <<
" Encounter was previously classified as a follow/lead situation.\n";
1949#ifdef DEBUG_ENCOUNTER
1950 if (DEBUG_COND_ENCOUNTER(e)) {
1951 std::cout <<
" Encounter was previously classified as a merging situation.\n";
1966#ifdef DEBUG_ENCOUNTER
1967 if (DEBUG_COND_ENCOUNTER(e)) {
1968 std::cout <<
" Encounter was previously classified as a crossing situation of type " << lastPotentialConflictType <<
".\n";
1986#ifdef DEBUG_ENCOUNTER
1987 if (DEBUG_COND_ENCOUNTER(e))
2000 if ((!egoEnteredConflict) && !foeEnteredConflict) {
2004 eInfo.
type = lastPotentialConflictType;
2005 }
else if (egoEnteredConflict && !foeEnteredConflict) {
2007 }
else if ((!egoEnteredConflict) && foeEnteredConflict) {
2013 if ((!egoLeftConflict) && !foeLeftConflict) {
2017 }
else if (egoLeftConflict && !foeLeftConflict) {
2021 }
else if ((!egoLeftConflict) && foeLeftConflict) {
2036#ifdef DEBUG_ENCOUNTER
2037 if (DEBUG_COND_ENCOUNTER(e)) {
2038 std::cout <<
" Updated classification: " << eInfo.
type <<
"\n";
2047#ifdef DEBUG_ENCOUNTER
2048 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2049 std::cout <<
"classifyEncounter() called.\n";
2052 if (foeInfo ==
nullptr) {
2071#ifdef DEBUG_ENCOUNTER
2072 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2073 std::cout <<
" Ongoing crossing conflict will be traced by passedEncounter().\n";
2089 double foeDistToConflictLane;
2092#ifdef DEBUG_ENCOUNTER
2093 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter))
2094 std::cout <<
" egoConflictLane='" << (egoConflictLane == 0 ?
"NULL" : egoConflictLane->
getID()) <<
"'\n"
2095 <<
" foeConflictLane='" << (foeConflictLane == 0 ?
"NULL" : foeConflictLane->
getID()) <<
"'\n"
2096 <<
" egoDistToConflictLane=" << egoDistToConflictLane
2097 <<
" foeDistToConflictLane=" << foeDistToConflictLane
2112 if (foeConflictLane ==
nullptr) {
2115#ifdef DEBUG_ENCOUNTER
2116 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2117 std::cout <<
"-> Encounter type: No conflict.\n";
2122 if (egoConflictLane == egoLane) {
2125#ifdef DEBUG_ENCOUNTER
2126 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2127 std::cout <<
"-> ego " << e->
ego->
getID() <<
" isOpposite " << egoOpposite <<
" foe " << e->
foe->
getID() <<
" isOpposite " << foeOpposite <<
" .\n";
2131 if (foeLane == egoLane) {
2133 if (!egoOpposite && !foeOpposite) {
2141#ifdef DEBUG_ENCOUNTER
2142 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2143 std::cout <<
"-> Encounter type: Lead/follow-situation on non-internal lane '" << egoLane->
getID() <<
"'\n";
2146 }
else if (egoOpposite && foeOpposite) {
2154#ifdef DEBUG_ENCOUNTER
2155 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2156 std::cout <<
"-> Encounter type: Lead/follow-situation while both are driving in the opposite direction on non-internal lane '" << egoLane->
getID() <<
"'\n";
2177#ifdef DEBUG_ENCOUNTER
2178 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2179 std::cout <<
"-> Encounter type: oncoming on non-internal lane '" << egoLane->
getID() <<
"'\n";
2187 if (foeOpposite != egoOpposite) {
2192#ifdef DEBUG_ENCOUNTER
2193 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2194 std::cout <<
"-> Encounter type: " << type << std::endl;
2199 if (!egoOpposite && !foeOpposite) {
2202 assert(egoDistToConflictLane <= 0);
2204 if (foeConflictLane == egoLane) {
2208#ifdef DEBUG_ENCOUNTER
2209 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter))
2210 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' leads foe '"
2211 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2217#ifdef DEBUG_ENCOUNTER
2218 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2219 std::cout <<
"-> Encounter type: " << type << std::endl;
2224 }
else if (egoOpposite && foeOpposite) {
2236#ifdef DEBUG_ENCOUNTER
2237 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2238 std::cout <<
"-> Encounter type: Lead/follow-situation while both are driving in the opposite direction on non-internal lane '" << egoLane->
getID() <<
"'\n";
2262#ifdef DEBUG_ENCOUNTER
2263 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2264 std::cout <<
"-> Encounter type: oncoming on non-internal lane '" << egoLane->
getID() <<
"'\n";
2276 assert(foeDistToConflictLane <= 0);
2277 if (foeLane == egoConflictLane) {
2280#ifdef DEBUG_ENCOUNTER
2281 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter))
2282 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' follows foe '"
2283 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2289#ifdef DEBUG_ENCOUNTER
2290 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2291 std::cout <<
"-> Encounter type: " << type << std::endl;
2305 if (((!egoOpposite && foeOpposite) || (egoOpposite && !foeOpposite)) && egoConflictLane == foeConflictLane) {
2307#ifdef DEBUG_ENCOUNTER
2308 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2310 std::cout <<
"-> egoConflictLane: " << egoConflictLane->
getID() <<
" foeConflictLane: " << foeConflictLane->
getID() <<
" egoOpposite " << egoOpposite <<
" foeOpposite " << foeOpposite << std::endl;
2314 if (foeLane == egoLane) {
2316 if (!egoOpposite && !foeOpposite) {
2324#ifdef DEBUG_ENCOUNTER
2325 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2326 std::cout <<
"-> Encounter type: Lead/follow-situation on non-internal lane '" << egoLane->
getID() <<
"'\n";
2329 }
else if (egoOpposite && foeOpposite) {
2337#ifdef DEBUG_ENCOUNTER
2338 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2339 std::cout <<
"-> Encounter type: Lead/follow-situation while both are driving in the opposite direction on non-internal lane '" << egoLane->
getID() <<
"'\n";
2360#ifdef DEBUG_ENCOUNTER
2361 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2362 std::cout <<
"-> Encounter type: oncoming on non-internal lane '" << egoLane->
getID() <<
"'\n";
2370 if (foeOpposite != egoOpposite) {
2375#ifdef DEBUG_ENCOUNTER
2376 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2377 std::cout <<
"-> Encounter type: " << type << std::endl;
2381 if (!egoOpposite && !foeOpposite) {
2383 assert(egoDistToConflictLane <= 0);
2385 if (foeConflictLane == egoLane) {
2389#ifdef DEBUG_ENCOUNTER
2390 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter))
2391 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' leads foe '"
2392 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2398#ifdef DEBUG_ENCOUNTER
2399 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2400 std::cout <<
"-> Encounter type: " << type << std::endl;
2404 }
else if (egoOpposite && foeOpposite) {
2416#ifdef DEBUG_ENCOUNTER
2417 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2418 std::cout <<
"-> Encounter type: Lead/follow-situation while both are driving in the opposite direction on non-internal lane '" << egoLane->
getID() <<
"'\n";
2442#ifdef DEBUG_ENCOUNTER
2443 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2444 std::cout <<
"-> Encounter type: oncoming on non-internal lane '" << egoLane->
getID() <<
"'\n";
2450 if (egoEntryLink != foeEntryLink) {
2453#ifdef DEBUG_ENCOUNTER
2454 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2455 std::cout <<
"-> Encounter type: " << type << std::endl;
2460 if (egoLane == egoConflictLane && foeLane != foeConflictLane) {
2467#ifdef DEBUG_ENCOUNTER
2468 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter))
2469 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' leads foe '"
2470 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2473 }
else if (egoLane != egoConflictLane && foeLane == foeConflictLane) {
2480#ifdef DEBUG_ENCOUNTER
2481 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter))
2482 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' follows foe '"
2483 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2490#ifdef DEBUG_ENCOUNTER
2491 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter))
2492 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' merges with foe '"
2493 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2501 if (egoLane != egoConflictLane || foeLane != foeConflictLane) {
2505 if (egoLane == foeLane) {
2510#ifdef DEBUG_ENCOUNTER
2511 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter))
2512 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' leads foe '"
2513 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2520#ifdef DEBUG_ENCOUNTER
2521 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter))
2522 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' follows foe '"
2523 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2530#ifdef DEBUG_ENCOUNTER
2531 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2532 std::cout <<
" Lead/follow situation on consecutive internal lanes." << std::endl;
2539 if (egoLane == lane) {
2544 while (lane != foeLane) {
2550 egoConflictLane = lane;
2551#ifdef DEBUG_ENCOUNTER
2552 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter))
2553 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' follows foe '"
2554 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2559 }
else if (foeLane == lane) {
2564 while (lane != egoLane) {
2570 foeConflictLane = lane;
2571#ifdef DEBUG_ENCOUNTER
2572 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter))
2573 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' leads foe '"
2574 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2584#ifdef DEBUG_ENCOUNTER
2585 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter))
2586 std::cout <<
"-> Encounter type: Lead/follow-situation on connection from '" << egoEntryLink->
getLaneBefore()->
getID()
2587 <<
"' to '" << egoEntryLink->
getLane()->
getID() <<
"'" << std::endl;
2594 const std::vector<MSLink*>& egoFoeLinks = egoEntryLink->
getFoeLinks();
2595 const std::vector<MSLink*>& foeFoeLinks = foeEntryLink->
getFoeLinks();
2597 bool crossOrMerge = (find(egoFoeLinks.begin(), egoFoeLinks.end(), foeEntryLink) != egoFoeLinks.end()
2598 || std::find(foeFoeLinks.begin(), foeFoeLinks.end(), egoEntryLink) != foeFoeLinks.end());
2599 if (!crossOrMerge) {
2608#ifdef DEBUG_ENCOUNTER
2609 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2610 std::cout <<
"-> Encounter type: No conflict.\n";
2635#ifdef DEBUG_ENCOUNTER
2636 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter))
2637 std::cout <<
"-> Encounter type: Merging situation of ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' and foe '"
2638 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2645#ifdef DEBUG_ENCOUNTER
2646 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2647 std::cout <<
"-> Encounter type: No conflict: " << type << std::endl;
2663 egoDistToConflictLane -= offset;
2665 foeDistToConflictLane -= offset;
2670 while (foeConflictLane !=
nullptr && foeConflictLane->
isInternal()) {
2679 egoDistToConflictFromJunctionEntry = 0;
2680 WRITE_WARNINGF(
TL(
"Cannot compute SSM due to bad internal lane geometry at junction '%'. Crossing point between traffic from links % and % not found."),
2687 assert(foeConflictLane !=
nullptr && foeConflictLane->
isInternal());
2694 while (egoConflictLane !=
nullptr && egoConflictLane->
isInternal()) {
2703 foeDistToConflictFromJunctionEntry = 0;
2704 WRITE_WARNINGF(
TL(
"Cannot compute SSM due to bad internal lane geometry at junction '%'. Crossing point between traffic from links % and % not found."),
2711 assert(egoConflictLane !=
nullptr && egoConflictLane->
isInternal());
2736 assert(angle <= 2 *
M_PI);
2740 assert(angle >= -
M_PI);
2741 assert(angle <=
M_PI);
2743 double crossingOrientation = (angle < 0) - (angle > 0);
2763#ifdef DEBUG_ENCOUNTER
2764 if (DEBUG_COND_ENCOUNTER(eInfo.
encounter)) {
2765 std::cout <<
" Determined exact conflict distances for crossing conflict."
2766 <<
"\n crossingOrientation=" << crossingOrientation
2769 <<
", relativeAngle=" << angle
2770 <<
" (foe from " << (crossingOrientation > 0 ?
"right)" :
"left)")
2771 <<
"\n resulting offset for conflict entry distance:"
2774 <<
"\n distToConflictLane:"
2775 <<
"\n ego=" << egoDistToConflictLane
2776 <<
", foe=" << foeDistToConflictLane
2777 <<
"\n distToConflictFromJunctionEntry:"
2778 <<
"\n ego=" << egoDistToConflictFromJunctionEntry
2779 <<
", foe=" << foeDistToConflictFromJunctionEntry
2780 <<
"\n resulting entry distances:"
2783 <<
"\n resulting exit distances:"
2788 std::cout <<
"real egoConflictLane: '" << (egoConflictLane == 0 ?
"NULL" : egoConflictLane->
getID()) <<
"'\n"
2789 <<
"real foeConflictLane: '" << (foeConflictLane == 0 ?
"NULL" : foeConflictLane->
getID()) <<
"'\n"
2790 <<
"-> Encounter type: Crossing situation of ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' and foe '"
2791 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2809 std::cout <<
SIMTIME <<
" findFoeConflictLane() for foe '"
2811 <<
"' (with egoConflictLane=" << (egoConflictLane == 0 ?
"NULL" : egoConflictLane->
getID())
2821#ifdef DEBUG_SSM_OPPOSITE
2841 return egoConflictLane;
2850 return egoConflictLane;
2860 assert(foeLane->
isInternal() || *laneIter == foeLane);
2867 if (conflictJunction != 0) {
2868 std::cout <<
"Potential conflict on junction '" << conflictJunction->
getID()
2874 if (egoConflictLane !=
nullptr && egoConflictLane->
isInternal() && egoConflictLane->
getLinkCont()[0]->getViaLane() == foeLane) {
2875 distToConflictLane += egoConflictLane->
getLength();
2883 if (*laneIter ==
nullptr) {
2884 while (foeLane !=
nullptr && foeLane->
isInternal()) {
2885 distToConflictLane += foeLane->
getLength();
2886 foeLane = foeLane->
getLinkCont()[0]->getViaLane();
2889 assert(laneIter == foeBestLanesEnd || *laneIter != 0);
2893 while (laneIter != foeBestLanesEnd && distToConflictLane <=
myRange) {
2895 assert(*laneIter == foeLane || foeLane == 0);
2896 foeLane = *laneIter;
2901 std::cout <<
"Found conflict lane for foe: '" << foeLane->
getID() <<
"'" << std::endl;
2908 distToConflictLane += foeLane->
getLength();
2912 if (laneIter == foeBestLanesEnd) {
2915 MSLane*
const nextNonInternalLane = *laneIter;
2917 if (link ==
nullptr) {
2923 assert(foeLane == 0 || foeLane->
isInternal());
2924 if (foeLane ==
nullptr) {
2925 foeLane = nextNonInternalLane;
2929 assert(foeLane != 0);
2932 std::cout <<
"Found conflict lane for foe: '" << foeLane->
getID() <<
"'" << std::endl;
2940 foeLane = nextNonInternalLane;
2961 std::vector<int> foundTypes;
2963 std::set_intersection(
2965 encounterTypes.begin(), encounterTypes.end(),
2966 std::back_inserter(foundTypes));
2967 write = foundTypes.size() == 0;
2985 std::cout <<
SIMTIME <<
" flushGlobalMeasures() of vehicle '"
3059 std::cout <<
SIMTIME <<
" writeOutConflict() of vehicles '"
3197 std::string res =
"";
3198 for (std::vector<double>::const_iterator i = v.begin(); i != v.end(); ++i) {
3199 res += (i == v.begin() ?
"" :
" ") + (*i == NA ?
"NA" :
::toString(*i));
3206 std::string res =
"";
3207 for (std::vector<double>::const_iterator i = v.begin(); i != v.end(); ++i) {
3208 res += (i == v.begin() ?
"" :
" ") + (find(NAs.begin(), NAs.end(), *i) != NAs.end() ?
"NA" :
::toString(*i));
3216 std::string res =
"";
3217 for (PositionVector::const_iterator i = v.begin(); i != v.end(); ++i) {
3232 return v == NA ?
"NA" :
toString(v);
3240 std::vector<int> conflictTypeFilter) :
3250 myWriteNA(holder.getBoolParam(
"device.ssm.write-na", true, true)),
3287 std::vector<std::string> measures;
3288 std::vector<double> threshVals;
3290 measures.push_back(i->first);
3291 threshVals.push_back(i->second);
3293 std::cout <<
"Initialized ssm device '" <<
id <<
"' with "
3316#ifdef DEBUG_SSM_NOTIFICATIONS
3332#ifdef DEBUG_SSM_NOTIFICATIONS
3346 double ,
double newSpeed) {
3347#ifdef DEBUG_SSM_NOTIFICATIONS
3350 std::cout <<
SIMTIME <<
"device '" <<
getID() <<
"' notifyMove: newSpeed=" << newSpeed <<
"\n";
3365#ifdef DEBUG_SSM_SURROUNDING
3369 std::cout <<
SIMTIME <<
" Looking for surrounding vehicles for ego vehicle '" << veh.
getID()
3395 std::vector<MSLane*>::const_iterator laneIter = egoBestLanes.begin();
3396 assert(lane->
isInternal() || lane == *laneIter || isOpposite);
3398 if (lane->
isInternal() && egoBestLanes[0] !=
nullptr) {
3403 for (
int i = 0; i < (int)egoBestLanes.size(); i++) {
3404 if (egoBestLanes[i] !=
nullptr && egoBestLanes[i]->getEdge().getOppositeEdge() !=
nullptr) {
3405 egoBestLanes[i] = egoBestLanes[i]->getEdge().getOppositeEdge()->getLanes().back();
3411 const MSLane* nextNonInternalLane =
nullptr;
3419 double remainingDownstreamRange = range;
3421 double distToConflictLane = isOpposite ? pos - veh.
getLane()->
getLength() : -pos;
3424 std::set<const MSLane*> seenLanes;
3425 std::set<const MSJunction*> routeJunctions;
3429 std::vector<UpstreamScanStartInfo> upstreamScanStartPositions;
3438#ifdef DEBUG_SSM_SURROUNDING
3440 std::cout <<
SIMTIME <<
" Vehicle '" << veh.
getID() <<
"' is on internal edge " << edge->
getID() <<
"'." << std::endl;
3450 routeJunctions.insert(junction);
3456 for (ConstMSEdgeVector::const_iterator ei = incoming.begin(); ei != incoming.end(); ++ei) {
3457 if ((*ei)->isInternal()) {
3476 lane = *(++laneIter);
3482 double startScanPos = std::min(pos + remainingDownstreamRange, edgeLength);
3483 upstreamScanStartPositions.push_back(
UpstreamScanStartInfo(edge, startScanPos, std::max(0., startScanPos - pos + range + veh.
getLength()), distToConflictLane, lane));
3492 while (remainingDownstreamRange > 0.) {
3494#ifdef DEBUG_SSM_SURROUNDING
3496 std::cout <<
SIMTIME <<
" Scanning downstream for vehicle '" << veh.
getID() <<
"' on lane '" << veh.
getLane()->
getID() <<
"', position=" << pos <<
".\n"
3497 <<
"Considering edge '" << edge->
getID() <<
"' Remaining downstream range = " << remainingDownstreamRange
3498 <<
"\nbestLanes=" <<
::toString(egoBestLanes) <<
"\n"
3504 assert(pos == 0 || lane == veh.
getLane());
3505 if (pos + remainingDownstreamRange < lane->getLength()) {
3508 upstreamScanStartPositions.push_back(
UpstreamScanStartInfo(edge, pos + remainingDownstreamRange, remainingDownstreamRange, distToConflictLane, lane));
3519 remainingDownstreamRange -= lane->
getLength() - pos;
3520 distToConflictLane += lane->
getLength();
3525 assert(laneIter == egoBestLanes.end() || *laneIter != 0);
3528 if (laneIter != egoBestLanes.end()) {
3539 nextNonInternalLane = *laneIter;
3541 if (isOpposite && link ==
nullptr) {
3542 link = nextNonInternalLane->
getLinkTo(lane);
3543 if (link ==
nullptr) {
3547 if (link ==
nullptr) {
3554 if (lane ==
nullptr) {
3556 lane = nextNonInternalLane;
3558 if (seenLanes.count(lane) == 0) {
3559 seenLanes.insert(lane);
3566 if (seenLanes.count(lane) == 0) {
3569 routeJunctions.insert(junction);
3575 for (ConstMSEdgeVector::const_iterator ei = outgoing.begin(); ei != outgoing.end(); ++ei) {
3579 upstreamScanStartPositions.push_back(
UpstreamScanStartInfo(*ei, (*ei)->getLength(), range, distToConflictLane, lane));
3583 for (ConstMSEdgeVector::const_iterator ei = incoming.begin(); ei != incoming.end(); ++ei) {
3587 upstreamScanStartPositions.push_back(
UpstreamScanStartInfo(*ei, (*ei)->getLength(), range, distToConflictLane, lane));
3593 remainingDownstreamRange -= linkLength;
3594 distToConflictLane += linkLength;
3595#ifdef DEBUG_SSM_SURROUNDING
3597 std::cout <<
" Downstream Scan for vehicle '" << veh.
getID() <<
"' proceeded over junction '" << junction->
getID()
3598 <<
"',\n linkLength=" << linkLength <<
", remainingDownstreamRange=" << remainingDownstreamRange
3604 lane = nextNonInternalLane;
3607#ifdef DEBUG_SSM_SURROUNDING
3609 std::cout <<
" Downstream Scan for vehicle '" << veh.
getID() <<
"' stops at lane '" << lane->
getID()
3610 <<
"', which has already been scanned."
3631#ifdef DEBUG_SSM_SURROUNDING
3633 for (std::pair<const MSVehicle*, FoeInfo*> foeInfo : foeCollector) {
3634 std::cout <<
" foe " << foeInfo.first->getID() <<
" conflict at " << foeInfo.second->egoConflictLane->getID() <<
" egoDist " << foeInfo.second->egoDistToConflictLane << std::endl;
3640 const auto& it = foeCollector.find(&veh);
3641 if (it != foeCollector.end()) {
3643 foeCollector.erase(it);
3651#ifdef DEBUG_SSM_SURROUNDING
3653 std::cout <<
SIMTIME <<
" getUpstreamVehicles() for edge '" << scanStart.
edge->
getID() <<
"'"
3655 <<
" pos = " << scanStart.
pos <<
" range = " << scanStart.
range
3659 if (scanStart.
range <= 0) {
3665 if (seenLanes.find(lane) != seenLanes.end()) {
3668#ifdef DEBUG_SSM_SURROUNDING
3671 for (
MSVehicle*
const veh : lane->getVehiclesSecure()) {
3672 if (foeCollector.find(veh) != foeCollector.end()) {
3676 if (veh->getPositionOnLane() - veh->getLength() <= scanStart.
pos && veh->getPositionOnLane() >= scanStart.
pos - scanStart.
range) {
3677#ifdef DEBUG_SSM_SURROUNDING
3679 std::cout <<
"\t" << veh->getID() <<
"\n";
3686 foeCollector[veh] = c;
3689 lane->releaseVehicles();
3691#ifdef DEBUG_SSM_SURROUNDING
3693 std::cout <<
"\t" << lane->getID() <<
": Found " << foundCount <<
"\n";
3696 seenLanes.insert(lane);
3699#ifdef DEBUG_SSM_SURROUNDING
3701 std::cout << std::endl;
3709 if (scanStart.
range <= scanStart.
pos) {
3714 double remainingRange = scanStart.
range - scanStart.
pos;
3720 if (routeJunctions.find(junction) != routeJunctions.end()) {
3725 int incomingEdgeCount = 0;
3733 if (internalLane->getEdge().getSuccessors()[0]->getID() == scanStart.
edge->
getID()) {
3735 incomingEdgeCount++;
3740 if (incomingEdgeCount > 0) {
3742 if (inEdge->isInternal() || inEdge->isCrossing()) {
3746 for (
MSLane*
const lane : inEdge->getLanes()) {
3747 if (seenLanes.find(lane) != seenLanes.end()) {
3753#ifdef DEBUG_SSM_SURROUNDING
3761 if (distOnJunction >= remainingRange) {
3762#ifdef DEBUG_SSM_SURROUNDING
3777#ifdef DEBUG_SSM_SURROUNDING
3779 std::cout <<
SIMTIME <<
" getVehiclesOnJunction() for junction '" << junction->
getID()
3781 <<
"\nFound vehicles:"
3788 if (foeCollector.find(veh) != foeCollector.end()) {
3789 delete foeCollector[veh];
3794 foeCollector[veh] = c;
3795#ifdef DEBUG_SSM_SURROUNDING
3797 std::cout <<
"\t" << veh->getID() <<
" egoConflictLane=" <<
Named::getIDSecure(egoConflictLane) <<
"\n";
3804 if (seenLanes.find(egoJunctionLane) != seenLanes.end() || egoJunctionLane->
getEdge().
isCrossing()) {
3808 auto scanInternalLane = [&](
const MSLane * lane) {
3813 collectFoeInfos(vehicles);
3815 lane->releaseVehicles();
3819 if (lane->getCanonicalPredecessorLane()->isInternal()) {
3820 lane = lane->getCanonicalPredecessorLane();
3823 assert(!lane->getEntryLink()->fromInternalLane());
3828 collectFoeInfos(vehicles2);
3829 lane->releaseVehicles();
3834 if (lane->getLinkCont().size() > 1 && lane->getLinkCont()[0]->getViaLane() !=
nullptr) {
3836 lane = lane->getLinkCont()[0]->getViaLane();
3838 assert(lane->getLinkCont().size() == 0 || lane->getLinkCont()[0]->getViaLane() == 0);
3843 collectFoeInfos(vehicles2);
3844 lane->releaseVehicles();
3854 for (
MSLane* lane : foeLanes) {
3855 if (seenLanes.find(lane) != seenLanes.end()) {
3858 scanInternalLane(lane);
3859 seenLanes.insert(lane);
3862 scanInternalLane(egoJunctionLane);
3864#ifdef DEBUG_SSM_SURROUNDING
3866 std::cout << std::endl;
3886 std::string file = deviceID +
".xml";
3900 file = oc.
getString(
"device.ssm.file") ==
"" ? file : oc.
getString(
"device.ssm.file");
3902 WRITE_MESSAGEF(
TL(
"Vehicle '%' does not supply vehicle parameter 'device.ssm.file'. Using default of '%'."), v.
getID(), file);
3920 bool useGeo =
false;
3934 useGeo = oc.
getBool(
"device.ssm.geo");
3947 bool writePos =
false;
3961 writePos = oc.
getBool(
"device.ssm.write-positions");
3963 WRITE_MESSAGEF(
TL(
"Vehicle '%' does not supply vehicle parameter 'device.ssm.write-positions'. Using default of '%'."), v.
getID(),
toString(writePos));
3974 bool writeLanesPos =
false;
3988 writeLanesPos = oc.
getBool(
"device.ssm.write-lane-positions");
3990 WRITE_MESSAGEF(
TL(
"Vehicle '%' does not supply vehicle parameter 'device.ssm.write-lane-positions'. Using default of '%'."), v.
getID(),
toString(writeLanesPos));
3994 return writeLanesPos;
4001 std::string typeString =
"";
4015 typeString = oc.
getString(
"device.ssm.exclude-conflict-types");
4017 WRITE_MESSAGEF(
TL(
"Vehicle '%' does not supply vehicle parameter 'device.ssm.exclude-conflict-types'. Using default of '%'."), v.
getID(), typeString);
4024 std::vector<std::string> found = st.
getVector();
4025 std::set<int> confirmed;
4026 for (std::vector<std::string>::const_iterator i = found.begin(); i != found.end(); ++i) {
4029 }
else if (*i ==
"ego") {
4031 }
else if (*i ==
"none") {
4034 confirmed.insert(std::stoi(*i));
4037 WRITE_ERRORF(
TL(
"SSM exclude-conflict-type '%' is not supported. Aborting construction of SSM device '%'."), *i, deviceID);
4041 conflictTypes.insert(conflictTypes.end(), confirmed.begin(), confirmed.end());
4063 range = oc.
getFloat(
"device.ssm.range");
4090 prt = oc.
getFloat(
"device.ssm.mdrac.prt");
4092 WRITE_MESSAGEF(
TL(
"Vehicle '%' does not supply vehicle parameter 'device.ssm.mdrac.prt'. Using default of '%'."), v.
getID(),
toString(prt));
4119 extraTime = oc.
getFloat(
"device.ssm.extratime");
4121 WRITE_MESSAGEF(
TL(
"Vehicle '%' does not supply vehicle parameter 'device.ssm.extratime'. Using default of '%'."), v.
getID(),
toString(extraTime));
4125 if (extraTime < 0.) {
4127 WRITE_WARNINGF(
TL(
"Negative (or no) value encountered for vehicle parameter 'device.ssm.extratime' in vehicle '%' using default value % instead."), v.
getID(),
::toString(extraTime));
4136 bool trajectories =
false;
4150 trajectories = oc.
getBool(
"device.ssm.trajectories");
4152 WRITE_MESSAGEF(
TL(
"Vehicle '%' does not supply vehicle parameter 'device.ssm.trajectories'. Using default of '%'."), v.
getID(),
toString(trajectories));
4156 return trajectories;
4165 std::string measures_str =
"";
4179 measures_str = oc.
getString(
"device.ssm.measures");
4181 WRITE_MESSAGEF(
TL(
"Vehicle '%' does not supply vehicle parameter 'device.ssm.measures'. Using default of '%'."), v.
getID(), measures_str);
4187 if (measures_str ==
"") {
4188 WRITE_WARNINGF(
"No measures specified for ssm device of vehicle '%'. Registering all available SSMs.", v.
getID());
4192 std::vector<std::string> available = st.
getVector();
4194 std::vector<std::string> measures = st.
getVector();
4195 for (std::vector<std::string>::const_iterator i = measures.begin(); i != measures.end(); ++i) {
4196 if (std::find(available.begin(), available.end(), *i) == available.end()) {
4198 WRITE_ERRORF(
TL(
"SSM identifier '%' is not supported. Aborting construction of SSM device '%'."), *i, deviceID);
4204 std::string thresholds_str =
"";
4218 thresholds_str = oc.
getString(
"device.ssm.thresholds");
4220 WRITE_MESSAGEF(
TL(
"Vehicle '%' does not supply vehicle parameter 'device.ssm.thresholds'. Using default of '%'."), v.
getID(), thresholds_str);
4227 if (thresholds_str !=
"") {
4229 while (count < (
int)measures.size() && st.
hasNext()) {
4231 thresholds.insert(std::make_pair(measures[count], thresh));
4234 if (thresholds.size() < measures.size() || st.
hasNext()) {
4235 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);
4240 for (std::vector<std::string>::const_iterator i = measures.begin(); i != measures.end(); ++i) {
4243 }
else if (*i ==
"DRAC") {
4245 }
else if (*i ==
"MDRAC") {
4247 }
else if (*i ==
"PET") {
4249 }
else if (*i ==
"PPET") {
4251 }
else if (*i ==
"BR") {
4253 }
else if (*i ==
"SGAP") {
4255 }
else if (*i ==
"TGAP") {
4258 WRITE_ERROR(
"Unknown SSM identifier '" + (*i) +
"'. Aborting construction of ssm device.");
4284 if (key ==
"minTTC" ||
4286 key ==
"maxMDRAC" ||
4296 minTTC =
MIN2(minTTC, e->minTTC.value);
4297 minPET =
MIN2(minPET, e->PET.value);
4298 maxDRAC =
MAX2(maxDRAC, e->maxDRAC.value);
4299 maxMDRAC =
MAX2(maxMDRAC, e->maxMDRAC.value);
4300 minPPET =
MIN2(minPPET, e->minPPET.value);
4302 if (key ==
"minTTC") {
4304 }
else if (key ==
"maxDRAC") {
4306 }
else if (key ==
"maxMDRAC") {
4308 }
else if (key ==
"minPET") {
4310 }
else if (key ==
"minPPET") {
4331 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
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)
bool myWriteNA
Wether to write measuers with NA entries.
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.
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.
std::pair< const MSVehicle *const, double > getLeader(double dist=0, bool considerFoes=true) const
Returns the leader of the vehicle looking for a fixed distance.
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 int toInt(const std::string &sData)
converts a string into the integer value described by it by calling the char-type converter,...
static bool isInt(const std::string &sData)
check if the given sData can be converted to int
static bool toBool(const std::string &sData)
converts a string into the bool value described by it by calling the char-type converter
#define UNUSED_PARAMETER(x)
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