57 #define INVALID std::numeric_limits<double>::max() 60 #define DEFAULT_RANGE 50.0 66 #define AVAILABLE_SSMS "TTC DRAC PET BR SGAP TGAP" 68 #define DEFAULT_THRESHOLD_TTC 3. // in [s.], events get logged if time to collision is below threshold (1.5s. is an appropriate criticality threshold according to Van der Horst, A. R. A. (1991). Time-to-collision as a Cue for Decision-making in Braking [also see Guido et al. 2011]) 69 #define DEFAULT_THRESHOLD_DRAC 3. // in [m/s^2], events get logged if "deceleration to avoid a crash" is above threshold (3.4s. is an appropriate criticality threshold according to American Association of State Highway and Transportation Officials (2004). A Policy on Geometric Design of Highways and Streets [also see Guido et al. 2011]) 70 #define DEFAULT_THRESHOLD_PET 2. // in seconds, events get logged if post encroachment time is below threshold 72 #define DEFAULT_THRESHOLD_BR 0.0 // in [m/s^2], events get logged if brake rate is above threshold 73 #define DEFAULT_THRESHOLD_SGAP 0.2 // in [m.], events get logged if the space headway is below threshold. 74 #define DEFAULT_THRESHOLD_TGAP 0.5 // in [m.], events get logged if the time headway is below threshold. 76 #define DEFAULT_EXTRA_TIME 5. // in seconds, events get logged for extra time even if encounter is over 88 out <<
"NOCONFLICT_AHEAD";
94 out <<
"FOLLOWING_FOLLOWER";
97 out <<
"FOLLOWING_LEADER";
100 out <<
"ON_ADJACENT_LANES";
106 out <<
"MERGING_LEADER";
109 out <<
"MERGING_FOLLOWER";
112 out <<
"MERGING_ADJACENT";
118 out <<
"CROSSING_LEADER";
121 out <<
"CROSSING_FOLLOWER";
124 out <<
"EGO_ENTERED_CONFLICT_AREA";
127 out <<
"FOE_ENTERED_CONFLICT_AREA";
130 out <<
"BOTH_ENTERED_CONFLICT_AREA";
133 out <<
"EGO_LEFT_CONFLICT_AREA";
136 out <<
"FOE_LEFT_CONFLICT_AREA";
139 out <<
"BOTH_LEFT_CONFLICT_AREA";
142 out <<
"FOLLOWING_PASSED";
145 out <<
"MERGING_PASSED";
152 out <<
"unknown type (" << int(type) <<
")";
167 const std::set<MSDevice_SSM*>&
176 for (std::set<MSDevice_SSM*>::iterator ii =
instances->begin(); ii !=
instances->end(); ++ii) {
177 (*ii)->resetEncounters();
178 (*ii)->flushConflicts(
true);
179 (*ii)->flushGlobalMeasures();
196 oc.
addDescription(
"device.ssm.measures",
"SSM Device",
"Specifies which measures will be logged (as a space seperated sequence of IDs in ('TTC', 'DRAC', 'PET')).");
198 oc.
addDescription(
"device.ssm.thresholds",
"SSM Device",
"Specifies thresholds corresponding to the specified measures (see documentation and watch the order!). Only events exceeding the thresholds will be logged.");
200 oc.
addDescription(
"device.ssm.trajectories",
"SSM Device",
"Specifies whether trajectories will be logged (if false, only the extremal values and times are reported, this is the default).");
202 oc.
addDescription(
"device.ssm.range",
"SSM Device",
"Specifies the detection range in meters (default is " +
toString(
DEFAULT_RANGE) +
"m.). For vehicles below this distance from the equipped vehicle, SSM values are traced.");
204 oc.
addDescription(
"device.ssm.extratime",
"SSM Device",
"Specifies the time in seconds to be logged after a conflict is over (default is " +
toString(
DEFAULT_EXTRA_TIME) +
"secs.). Required >0 if PET is to be calculated for crossing conflicts.");
206 oc.
addDescription(
"device.ssm.geo",
"SSM Device",
"Whether to use coordinates of the original reference system in output (default is false).");
213 WRITE_WARNING(
"SSM Device for vehicle '" + v.
getID() +
"' will not be built. (SSMs not supported in MESO)");
217 std::string deviceID =
"ssm_" + v.
getID();
222 std::map<std::string, double> thresholds;
245 into.push_back(device);
253 egoID(_ego->
getID()),
254 foeID(_foe->
getID()),
258 remainingExtraTime(extraTime),
266 closingRequested(false) {
268 std::cout <<
"\n" <<
SIMTIME <<
" Constructing encounter of '" 275 std::cout <<
"\n" <<
SIMTIME <<
" Destroying encounter of '" 276 <<
egoID <<
"' and '" <<
foeID <<
"' (begin was " <<
begin <<
")" << std::endl;
283 Position conflictPoint,
double egoDistToConflict,
double foeDistToConflict,
double ttc,
double drac, std::pair<double, double> pet) {
285 std::cout << time <<
" Adding data point for encounter of '" <<
egoID <<
"' and '" <<
foeID <<
"':\n" 286 <<
"type=" << type <<
", egoDistToConflict=" << (egoDistToConflict ==
INVALID ?
"NA" :
toString(egoDistToConflict))
287 <<
", foeDistToConflict=" << (foeDistToConflict ==
INVALID ?
"NA" :
toString(foeDistToConflict))
351 conflictPoint(
Position::invalidPosition()),
356 egoEstimatedConflictEntryTime(
INVALID),
357 foeEstimatedConflictEntryTime(
INVALID),
358 egoEstimatedConflictExitTime(
INVALID),
359 foeEstimatedConflictExitTime(
INVALID),
360 egoConflictAreaLength(
INVALID),
361 foeConflictAreaLength(
INVALID),
362 egoLeftConflict(false),
363 foeLeftConflict(false),
386 std::cout <<
"\n" <<
SIMTIME <<
" Device '" <<
getID() <<
"' update()\n" 396 if (foes.size() > 0) {
397 std::cout <<
"Scanned surroundings: Found potential foes:\n";
398 for (FoeInfoMap::const_iterator i = foes.begin(); i != foes.end(); ++i) {
399 std::cout << i->first->getID() <<
" ";
401 std::cout << std::endl;
403 std::cout <<
"Scanned surroundings: No potential conflict could be identified." << std::endl;
433 double leaderSearchDist = 0;
434 std::pair<const MSVehicle*, double> leader(
nullptr, 0.);
442 if (leaderSearchDist > 0.) {
447 if (leader.first ==
nullptr) {
450 double sgap = leader.second + leader.first->getVehicleType().getMinGap();
459 if (leader.first ==
nullptr) {
462 double tgap = (leader.second + leader.first->getVehicleType().getMinGap()) /
myHolderMS->
getSpeed();
476 std::cout <<
"\n" <<
SIMTIME <<
" Device '" <<
getID() <<
"' createEncounters()" << std::endl;
477 std::cout <<
"New foes:\n";
478 for (FoeInfoMap::const_iterator vi = foes.begin(); vi != foes.end(); ++vi) {
479 std::cout << vi->first->getID() <<
"\n";
481 std::cout << std::endl;
484 for (FoeInfoMap::const_iterator foe = foes.begin(); foe != foes.end(); ++foe) {
485 std::pair<MSLane*, MSLane*> conflictLanes;
492 assert(myOldestActiveEncounterBegin <= e->begin);
508 std::cout <<
"\n" <<
SIMTIME <<
" Device '" <<
getID() <<
"' processEncounters()" << std::endl;
509 std::cout <<
"Currently present foes:\n";
510 for (FoeInfoMap::const_iterator vi = foes.begin(); vi != foes.end(); ++vi) {
511 std::cout << vi->first->getID() <<
"\n";
513 std::cout << std::endl;
529 if (foes.find(e->
foe) != foes.end()) {
545 double eBegin = e->
begin;
569 std::cout <<
SIMTIME <<
" qualifiesAsConflict() for encounter of vehicles '" 600 std::cout <<
SIMTIME <<
" closeEncounter() of vehicles '" 602 <<
"' (was ranked as " << (wasConflict ?
"conflict" :
"non-conflict") <<
")" << std::endl;
612 std::cout <<
SIMTIME <<
" updateEncounter() of vehicles '" 632 std::cout <<
SIMTIME <<
" Encounter of vehicles '" 634 <<
"' does not imply any conflict." << std::endl;
687 std::cout <<
SIMTIME <<
" determineConflictPoint()" << std::endl;
712 std::cout <<
"No conflict point associated with encounter type " << type << std::endl;
718 std::cout <<
" Conflict at " << eInfo.
conflictPoint << std::endl;
731 std::cout <<
SIMTIME <<
" estimateConflictTimes() for ego '" << e->
egoID <<
"' and foe '" << e->
foeID <<
"'\n" 732 <<
" encounter type: " << eInfo.
type <<
"\n" 745 std::cout <<
" encouter type " << type <<
" -> no entry/exit times to be calculated." 786 std::cout <<
" Potential conflict type: " << (type ==
ENCOUNTER_TYPE_CROSSING ?
"CROSSING" :
"MERGING") <<
"\n" 816 std::stringstream ss;
817 ss <<
"SSM device of vehicle '" << e->
egoID <<
"' detected collision with vehicle '" << e->
foeID <<
"'";
822 std::cout <<
" -> ego is estimated leader at conflict entry." 830 std::cout <<
" -> foe is estimated leader at conflict entry." 845 std::cout <<
SIMTIME <<
" computeSSMs() for vehicles '" 875 std::stringstream ss;
876 ss <<
"'" << type <<
"'";
877 WRITE_WARNING(
"Unknown or undetermined encounter type at computeSSMs(): " + ss.str());
881 std::cout <<
"computeSSMs() for encounter of vehicles '" << e->
egoID <<
"' and '" << e->
foeID <<
"':\n" 893 if (e->
size() == 0) {
897 std::pair<double, double>&
pet = eInfo.
pet;
900 std::cout <<
SIMTIME <<
" determinePET() for encounter of vehicles '" << e->
egoID <<
"' and '" << e->
foeID <<
"'" 914 std::cout <<
"PET for crossing encounter already calculated as " << e->
PET.
value 957 std::cout <<
"Unexpected branch in determinePET: Both passed conflict area in the same step." 973 std::cout <<
"Calculated PET = " << pet.second <<
" (at t=" << pet.first <<
")" 979 std::cout <<
"PET unappropriate for merging and pre-crossing situations. No calculation performed." 995 std::cout <<
SIMTIME <<
" determineTTCandDRAC() for encounter of vehicles '" << e->
egoID <<
"' and '" << e->
foeID <<
"' (type = " << eInfo.
type <<
")" 1030 std::cout <<
" Conflict times with constant speed extrapolation for merging situation:\n " 1031 <<
" egoEntryTime=" << (egoEntryTime ==
INVALID ?
"NA" :
toString(egoEntryTime))
1032 <<
", egoExitTime=" << (egoExitTime ==
INVALID ?
"NA" :
toString(egoExitTime))
1033 <<
", foeEntryTime=" << (foeEntryTime ==
INVALID ?
"NA" :
toString(foeEntryTime))
1034 <<
", foeExitTime=" << (foeExitTime ==
INVALID ?
"NA" :
toString(foeExitTime))
1044 std::cout <<
" No TTC and DRAC computed as one vehicle is stopped." << std::endl;
1048 double leaderEntryTime =
MIN2(egoEntryTime, foeEntryTime);
1049 double followerEntryTime =
MAX2(egoEntryTime, foeEntryTime);
1050 double leaderExitTime = leaderEntryTime == egoEntryTime ? egoExitTime : foeExitTime;
1057 if (leaderExitTime >= followerEntryTime) {
1060 ttc =
computeTTC(followerConflictDist, followerSpeed, 0.);
1065 drac =
computeDRAC(followerConflictDist, followerSpeed, 0.);
1070 std::cout <<
" Extrapolation predicts collision *at* merge point with TTC=" << ttc
1071 <<
", drac=" << drac << std::endl;
1078 double gapAfterMerge = followerConflictDist - leaderExitTime * followerSpeed;
1079 assert(gapAfterMerge >= 0);
1082 double ttcAfterMerge =
computeTTC(gapAfterMerge, followerSpeed, leaderSpeed);
1083 ttc = ttcAfterMerge ==
INVALID ?
INVALID : leaderExitTime + ttcAfterMerge;
1087 double g0 = followerConflictDist - leaderConflictDist - leaderLength;
1090 assert(leaderSpeed - followerSpeed > 0);
1095 drac =
computeDRAC(g0, followerSpeed, leaderSpeed);
1102 std::cout <<
" Extrapolation does not predict any collision." << std::endl;
1104 std::cout <<
" Extrapolation predicts collision *after* merge point with TTC=" 1106 <<
", drac=" << (drac ==
INVALID ?
"NA" :
toString(drac)) << std::endl;
1144 std::stringstream ss;
1145 ss <<
"'" << type <<
"'";
1146 WRITE_WARNING(
"Underspecified or unknown encounter type in MSDevice_SSM::determineTTCandDRAC(): " + ss.str());
1163 std::cout <<
"computeTTC() with gap=" << gap <<
", followerSpeed=" << followerSpeed <<
", leaderSpeed=" << leaderSpeed
1169 double dv = followerSpeed - leaderSpeed;
1180 #ifdef DEBUG_SSM_DRAC 1181 std::cout <<
"computeDRAC() with gap=" << gap <<
", followerSpeed=" << followerSpeed <<
", leaderSpeed=" << leaderSpeed
1187 double dv = followerSpeed - leaderSpeed;
1191 assert(followerSpeed > 0.);
1192 return 0.5 * dv * dv / gap;
1208 #ifdef DEBUG_SSM_DRAC 1209 std::cout <<
SIMTIME <<
"computeDRAC() with" 1210 <<
"\ndEntry1=" << dEntry1 <<
", dEntry2=" << dEntry2
1211 <<
", dExit1=" << dExit1 <<
", dExit2=" << dExit2
1212 <<
",\nv1=" << v1 <<
", v2=" << v2
1217 if (dExit1 <= 0. || dExit2 <= 0.) {
1219 #ifdef DEBUG_SSM_DRAC 1220 std::cout <<
"One already left conflict area -> drac == 0." << std::endl;
1224 if (dEntry1 <= 0. && dEntry2 <= 0.) {
1226 #ifdef DEBUG_SSM_DRAC 1227 std::cout <<
"Both entered conflict area but neither left. -> collision!" << std::endl;
1232 double drac = std::numeric_limits<double>::max();
1235 #ifdef DEBUG_SSM_DRAC 1236 std::cout <<
"Ego could break..." << std::endl;
1240 drac =
MIN2(drac, 2 * (v1 - dEntry1 / tExit2) / tExit2);
1241 #ifdef DEBUG_SSM_DRAC 1242 std::cout <<
" Foe expected to leave in " << tExit2 <<
"-> Ego needs drac=" << drac << std::endl;
1249 #ifdef DEBUG_SSM_DRAC 1250 std::cout <<
" Foe is expected stop on conflict area -> Ego needs drac=" << drac << std::endl;
1254 #ifdef DEBUG_SSM_DRAC 1255 std::cout <<
" Foe is expected stop before conflict area -> no drac computation for ego (will be done for foe if applicable)" << std::endl;
1263 #ifdef DEBUG_SSM_DRAC 1264 std::cout <<
"Foe could break..." << std::endl;
1268 #ifdef DEBUG_SSM_DRAC 1269 std::cout <<
" Ego expected to leave in " << tExit1 <<
"-> Foe needs drac=" << (2 * (v2 - dEntry2 / tExit1) / tExit1) << std::endl;
1271 drac =
MIN2(drac, 2 * (v2 - dEntry2 / tExit1) / tExit1);
1276 #ifdef DEBUG_SSM_DRAC 1277 std::cout <<
" Ego is expected stop on conflict area -> Foe needs drac=" <<
computeDRAC(dEntry2, v2, 0) << std::endl;
1282 #ifdef DEBUG_SSM_DRAC 1283 std::cout <<
" Ego is expected stop before conflict area -> no drac computation for foe (done for ego if applicable)" << std::endl;
1298 std::cout <<
SIMTIME <<
" checkConflictEntryAndExit() for encounter of vehicles '" << e->
egoID <<
"' and '" << e->
foeID <<
"'" << std::endl;
1311 prevEgoConflictEntryDist =
MAX2(prevEgoConflictEntryDist, 0.);
1312 prevFoeConflictEntryDist =
MAX2(prevFoeConflictEntryDist, 0.);
1313 prevEgoConflictExitDist =
MAX2(prevEgoConflictExitDist, 0.);
1314 prevFoeConflictExitDist =
MAX2(prevFoeConflictExitDist, 0.);
1384 std::cout <<
SIMTIME <<
" updatePassedEncounter() for vehicles '" 1393 std::cout <<
" Foe is out of range. Counting down extra time." 1410 std::cout <<
" This encounter wasn't classified as a potential conflict lately." << std::endl;
1418 std::cout <<
" Closing encounter." << std::endl;
1428 std::cout <<
" Encounter was previously classified as a follow/lead situation." << std::endl;
1437 std::cout <<
" Encounter was previously classified as a merging situation." << std::endl;
1452 std::cout <<
" Encounter was previously classified as a crossing situation of type " << lastPotentialConflictType <<
"." << std::endl;
1483 if ((!egoEnteredConflict) && !foeEnteredConflict) {
1487 eInfo.
type = lastPotentialConflictType;
1488 }
else if (egoEnteredConflict && !foeEnteredConflict) {
1490 }
else if ((!egoEnteredConflict) && foeEnteredConflict) {
1496 if ((!egoLeftConflict) && !foeLeftConflict) {
1500 }
else if (egoLeftConflict && !foeLeftConflict) {
1504 }
else if ((!egoLeftConflict) && foeLeftConflict) {
1520 std::cout <<
" Updated classification: " << eInfo.
type << std::endl;
1529 std::cout <<
"classifyEncounter() called." << std::endl;
1551 std::cout <<
" Ongoing crossing conflict will be traced by passedEncounter()." << std::endl;
1566 double foeDistToConflictLane;
1570 std::cout <<
"egoConflictLane: '" << (egoConflictLane == 0 ?
"NULL" : egoConflictLane->
getID()) <<
"'\n" 1571 <<
"foeConflictLane: '" << (foeConflictLane == 0 ?
"NULL" : foeConflictLane->
getID()) <<
"'" 1572 <<
"\nEgo's distance to conflict lane: " << egoDistToConflictLane
1573 <<
"\nFoe's distance to conflict lane: " << foeDistToConflictLane
1588 if (foeConflictLane == 0) {
1592 std::cout <<
"-> Encounter type: No conflict." << std::endl;
1594 }
else if (!egoConflictLane->isInternal()) {
1596 if (egoConflictLane == egoLane) {
1598 if (foeLane == egoLane) {
1608 std::cout <<
"-> Encounter type: Lead/follow-situation on non-internal lane '" << egoLane->
getID() <<
"'" << std::endl;
1615 std::cout <<
"-> Encounter type: " << type << std::endl;
1619 assert(egoDistToConflictLane <= 0);
1621 if (foeConflictLane == egoLane) {
1626 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' leads foe '" 1627 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'" 1635 std::cout <<
"-> Encounter type: " << type << std::endl;
1644 assert(&(foeLane->
getEdge()) == &(egoConflictLane->getEdge()));
1645 assert(foeDistToConflictLane <= 0);
1646 if (foeLane == egoConflictLane) {
1650 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' follows foe '" 1651 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'" 1659 std::cout <<
"-> Encounter type: " << type << std::endl;
1667 MSLink* egoEntryLink = egoConflictLane->getEntryLink();
1669 if (&(egoEntryLink->getViaLane()->getEdge()) == &(foeEntryLink->
getViaLane()->
getEdge())) {
1670 if (egoEntryLink != foeEntryLink) {
1674 std::cout <<
"-> Encounter type: " << type << std::endl;
1678 if (egoLane == egoConflictLane && foeLane != foeConflictLane) {
1683 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' leads foe '" 1684 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'" 1688 }
else if (egoLane != egoConflictLane && foeLane == foeConflictLane) {
1693 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' follows foe '" 1694 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'" 1702 assert(egoLane == egoConflictLane);
1703 assert(foeLane == foeConflictLane);
1704 if (egoLane == foeLane) {
1710 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' leads foe '" 1711 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'" 1719 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' follows foe '" 1720 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'" 1728 std::cout <<
" Lead/follow situation on consecutive internal lanes." << std::endl;
1730 MSLane* lane = egoEntryLink->getViaLane();
1732 #pragma warning(push) 1733 #pragma warning(disable: 4127) // do not warn about constant conditional expression 1737 #pragma warning(pop) 1741 if (egoLane == lane) {
1746 while (lane != foeLane) {
1752 egoConflictLane = lane;
1754 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' follows foe '" 1755 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'" 1760 }
else if (foeLane == lane) {
1765 while (lane != egoLane) {
1771 foeConflictLane = lane;
1773 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' leads foe '" 1774 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'" 1785 std::cout <<
"-> Encounter type: Lead/follow-situation on connection from '" << egoEntryLink->getLaneBefore()->getID()
1786 <<
"' to '" << egoEntryLink->getLane()->getID() <<
"'" << std::endl;
1793 const std::vector<MSLink*>& egoFoeLinks = egoEntryLink->getFoeLinks();
1794 const std::vector<MSLink*>& foeFoeLinks = foeEntryLink->
getFoeLinks();
1796 bool crossOrMerge = (find(egoFoeLinks.begin(), egoFoeLinks.end(), foeEntryLink) != egoFoeLinks.end()
1797 || find(foeFoeLinks.begin(), foeFoeLinks.end(), egoEntryLink) != foeFoeLinks.end());
1798 if (!crossOrMerge) {
1808 std::cout <<
"-> Encounter type: No conflict." << std::endl;
1811 }
else if (&(foeEntryLink->
getLane()->
getEdge()) == &(egoEntryLink->getLane()->getEdge())) {
1812 if (foeEntryLink->
getLane() == egoEntryLink->getLane()) {
1817 std::cout <<
"-> Encounter type: Merging situation of ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' and foe '" 1818 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'" 1826 std::cout <<
"-> Encounter type: No conflict: " << type << std::endl;
1832 assert(egoConflictLane->isInternal());
1833 assert(foeConflictLane->
getEdge().
getToJunction() == egoConflictLane->getEdge().getToJunction());
1840 egoConflictLane = egoConflictLane->getFirstInternalInConnection(offset);
1841 egoDistToConflictLane -= offset;
1843 foeDistToConflictLane -= offset;
1847 double egoDistToConflictFromJunctionEntry =
INVALID;
1848 double foeInternalLaneLengthsBeforeCrossing = 0.;
1849 while (foeConflictLane != 0 && foeConflictLane->
isInternal()) {
1850 egoDistToConflictFromJunctionEntry = egoEntryLink->getLengthsBeforeCrossing(foeConflictLane);
1851 if (egoDistToConflictFromJunctionEntry !=
INVALID) {
1856 foeInternalLaneLengthsBeforeCrossing += foeConflictLane->
getLength();
1859 assert(foeConflictLane != 0 && foeConflictLane->
isInternal());
1861 assert(egoDistToConflictFromJunctionEntry !=
INVALID);
1864 double foeDistToConflictFromJunctionEntry =
INVALID;
1865 double egoInternalLaneLengthsBeforeCrossing = 0.;
1866 foeDistToConflictFromJunctionEntry =
INVALID;
1867 while (egoConflictLane != 0 && egoConflictLane->isInternal()) {
1869 if (foeDistToConflictFromJunctionEntry !=
INVALID) {
1874 egoInternalLaneLengthsBeforeCrossing += egoConflictLane->getLength();
1876 egoConflictLane = egoConflictLane->getCanonicalSuccessorLane();
1877 assert(egoConflictLane != 0 && egoConflictLane->isInternal());
1879 assert(foeDistToConflictFromJunctionEntry !=
INVALID);
1891 Position egoEntryPos = egoEntryLink->getViaLane()->getShape().front();
1892 Position egoExitPos = egoEntryLink->getCorrespondingExitLink()->getInternalLaneBefore()->getShape().back();
1902 assert(angle <= 2 *
M_PI);
1906 assert(angle >= -
M_PI);
1907 assert(angle <=
M_PI);
1909 double crossingOrientation = (angle < 0) - (angle > 0);
1922 std::cout <<
" Determined exact conflict distances for crossing conflict." 1923 <<
"\n crossingOrientation=" << crossingOrientation
1926 <<
", relativeAngle=" << angle
1927 <<
" (foe from " << (crossingOrientation > 0 ?
"right)" :
"left)")
1928 <<
"\n resulting offset for conflict entry distance:" 1931 <<
"\n resulting entry distances:" 1946 std::cout <<
"real egoConflictLane: '" << (egoConflictLane == 0 ?
"NULL" : egoConflictLane->getID()) <<
"'\n" 1947 <<
"real foeConflictLane: '" << (foeConflictLane == 0 ?
"NULL" : foeConflictLane->
getID()) <<
"'\n" 1948 <<
"-> Encounter type: Crossing situation of ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' and foe '" 1949 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'" 1964 std::cout <<
SIMTIME <<
" findFoeConflictLane() for foe '" 1966 <<
"' (with egoConflictLane=" << (egoConflictLane == 0 ?
"NULL" : egoConflictLane->
getID())
1973 assert(foeLane->
isInternal() || *laneIter == foeLane);
1979 if (conflictJunction != 0) {
1980 std::cout <<
"Potential conflict on junction '" << conflictJunction->
getID()
1992 if (*laneIter == 0) {
1993 while (foeLane != 0 && foeLane->
isInternal()) {
1994 distToConflictLane += foeLane->
getLength();
1995 foeLane = foeLane->
getLinkCont()[0]->getViaLane();
1998 assert(laneIter == foeBestLanesEnd || *laneIter != 0);
2002 while (laneIter != foeBestLanesEnd && distToConflictLane <=
myRange) {
2004 assert(*laneIter == foeLane || foeLane == 0);
2005 foeLane = *laneIter;
2009 std::cout <<
"Found conflict lane for foe: '" << foeLane->
getID() <<
"'" << std::endl;
2015 distToConflictLane += foeLane->
getLength();
2019 if (laneIter == foeBestLanesEnd) {
2022 MSLane* nextNonInternalLane = *laneIter;
2026 assert(foeLane == 0 || foeLane->
isInternal());
2028 foeLane = nextNonInternalLane;
2032 assert(foeLane != 0);
2034 std::cout <<
"Found conflict lane for foe: '" << foeLane->
getID() <<
"'" << std::endl;
2041 foeLane = nextNonInternalLane;
2050 std::cout <<
"\n" <<
SIMTIME <<
" Device '" <<
getID() <<
"' flushConflicts()" << std::endl;
2068 std::cout <<
SIMTIME <<
" flushGlobalMeasures() of vehicle '" 2132 std::cout <<
SIMTIME <<
" writeOutConflict() of vehicles '" 2213 std::string res =
"";
2214 for (std::vector<double>::const_iterator i = v.begin(); i != v.end(); ++i) {
2215 res += (i == v.begin() ?
"" : sep) + (*i == NA ?
"NA" :
toString(*i));
2222 std::string res =
"";
2223 for (std::vector<double>::const_iterator i = v.begin(); i != v.end(); ++i) {
2224 res += (i == v.begin() ?
"" : sep) + (find(NAs.begin(), NAs.end(), *i) != NAs.end() ?
"NA" :
toString(*i));
2234 bool trajectories,
double range,
double extraTime,
bool useGeoCoords) :
2243 myMinSGAP(std::make_pair(std::make_pair(-1,
Position(0., 0.)), std::numeric_limits<double>::max()),
""),
2244 myMinTGAP(std::make_pair(std::make_pair(-1,
Position(0., 0.)), std::numeric_limits<double>::max()),
"") {
2271 std::vector<std::string> measures;
2272 std::vector<double> threshVals;
2274 measures.push_back(i->first);
2275 threshVals.push_back(i->second);
2277 std::cout <<
"Initialized ssm device '" <<
id <<
"' with " 2298 #ifdef DEBUG_SSM_NOTIFICATIONS 2299 std::cout <<
"device '" <<
getID() <<
"' notifyEnter: reason=" << reason <<
" currentEdge=" << veh.
getLane()->
getEdge().
getID() <<
"\n";
2310 #ifdef DEBUG_SSM_NOTIFICATIONS 2311 std::cout <<
"device '" <<
getID() <<
"' notifyLeave: reason=" << reason <<
" currentEdge=" << veh.
getLane()->
getEdge().
getID() <<
"\n";
2321 double ,
double newSpeed) {
2322 #ifdef DEBUG_SSM_NOTIFICATIONS 2323 std::cout <<
"device '" <<
getID() <<
"' notifyMove: newSpeed=" << newSpeed <<
"\n";
2333 #ifdef DEBUG_SSM_SURROUNDING 2334 std::cout <<
SIMTIME <<
" Looking for surrounding vehicles for ego vehicle '" << veh.
getID()
2353 assert(*edgeIter != 0);
2357 std::vector<MSLane*>::const_iterator laneIter = egoBestLanes.begin();
2361 assert(lane->
isInternal() || lane == *laneIter);
2364 const MSLane* nextNonInternalLane = 0;
2372 double remainingDownstreamRange = range;
2374 double distToConflictLane = -pos;
2376 std::set<const MSJunction*> seenJunctions;
2384 #ifdef DEBUG_SSM_SURROUNDING 2385 std::cout <<
SIMTIME <<
" Vehicle '" << veh.
getID() <<
"' is on internal edge " << edge->
getID() <<
"'.\n" 2386 <<
"Previous edge of its route: '" << (*edgeIter)->getID() <<
"'" << std::endl;
2394 seenJunctions.insert(junction);
2400 for (ConstMSEdgeVector::const_iterator ei = incoming.begin(); ei != incoming.end(); ++ei) {
2401 if ((*ei)->isInternal()) {
2415 remainingDownstreamRange -= link->getInternalLengthsAfter();
2416 distToConflictLane += lane->
getLength() + link->getInternalLengthsAfter();
2420 lane = *(++laneIter);
2433 while (remainingDownstreamRange > 0.) {
2434 #ifdef DEBUG_SSM_SURROUNDING 2435 std::cout <<
SIMTIME <<
" Scanning downstream for vehicle '" << veh.
getID() <<
"' on lane '" << veh.
getLane()->
getID() <<
"', position=" << pos <<
".\n" 2436 <<
"Considering edge '" << edge->
getID() <<
"' Remaining downstream range = " << remainingDownstreamRange
2437 <<
"\nbestLanes=" <<
toString(egoBestLanes) <<
"\n" 2442 assert(pos == 0 || lane == veh.
getLane());
2443 if (pos + remainingDownstreamRange < lane->getLength()) {
2445 getUpstreamVehicles(edge, pos + remainingDownstreamRange, remainingDownstreamRange, distToConflictLane, lane, foeCollector, seenJunctions);
2453 remainingDownstreamRange -= lane->getLength() - pos;
2454 distToConflictLane += lane->getLength();
2459 assert(laneIter == egoBestLanes.end() || *laneIter != 0);
2462 if (laneIter != egoBestLanes.end()) {
2464 const MSJunction* junction = lane->getEdge().getToJunction();
2467 nextNonInternalLane = *laneIter;
2468 MSLink* link = lane->getLinkTo(nextNonInternalLane);
2469 assert(link != 0 || link->
getLength() == 0.);
2475 lane = nextNonInternalLane;
2476 edge = &(lane->getEdge());
2477 if (seenJunctions.count(junction) == 0) {
2478 seenJunctions.insert(junction);
2485 if (seenJunctions.count(junction) == 0) {
2488 seenJunctions.insert(junction);
2491 for (ConstMSEdgeVector::const_iterator ei = incoming.begin(); ei != incoming.end(); ++ei) {
2495 getUpstreamVehicles(*ei, (*ei)->getLength(), range, distToConflictLane, lane, foeCollector, seenJunctions);
2499 remainingDownstreamRange -= linkLength;
2500 distToConflictLane += linkLength;
2501 #ifdef DEBUG_SSM_SURROUNDING 2502 std::cout <<
" Downstream Scan for vehicle '" << veh.
getID() <<
"' proceeded over junction '" << junction->
getID()
2503 <<
"',\n linkLength=" << linkLength <<
", remainingDownstreamRange=" << remainingDownstreamRange
2508 lane = nextNonInternalLane;
2509 edge = &(lane->getEdge());
2511 #ifdef DEBUG_SSM_SURROUNDING 2512 std::cout <<
" Downstream Scan for vehicle '" << veh.
getID() <<
"' stops at junction '" << junction->
getID()
2513 <<
"', which has already been scanned." 2525 foeCollector.erase(&veh);
2530 #ifdef DEBUG_SSM_SURROUNDING 2531 std::cout <<
SIMTIME <<
" getUpstreamVehicles() for edge '" << edge->
getID() <<
"'" 2532 <<
" pos = " << pos <<
" range = " << range
2533 <<
"\nFound vehicles:" 2540 const std::vector<MSLane*>& lanes = edge->
getLanes();
2542 for (std::vector<MSLane*>::const_iterator li = lanes.begin(); li != lanes.end(); ++li) {
2545 for (MSLane::VehCont::const_iterator vi = vehicles.begin(); vi != vehicles.end(); ++vi) {
2549 std::cout << veh->
getID() <<
"\n";
2554 foeCollector[veh] = c;
2561 std::cout << std::endl;
2577 if (seenJunctions.count(junction) == 0) {
2585 seenJunctions.insert(junction);
2589 for (ConstMSEdgeVector::const_iterator ei = incoming.begin(); ei != incoming.end(); ++ei) {
2590 if ((*ei)->isInternal()) {
2593 const MSEdge* inEdge = *ei;
2594 assert(inEdge != 0);
2596 if (distOnJunction >= range) {
2600 getUpstreamVehicles(inEdge, inEdge->
getLength(), range - distOnJunction, egoDistToConflictLane, egoConflictLane, foeCollector, seenJunctions);
2603 #ifdef DEBUG_SSM_SURROUNDING 2604 std::cout <<
" Downstream Scan for stops at junction '" << junction->
getID()
2605 <<
"', which has already been scanned." 2613 #ifdef DEBUG_SSM_SURROUNDING 2614 std::cout <<
SIMTIME <<
" getVehiclesOnJunction() for junction '" << junction->
getID() <<
"'" 2615 <<
"\nFound vehicles:" 2620 for (std::vector<MSLane*>::const_iterator li = lanes.begin(); li != lanes.end(); ++li) {
2626 for (MSLane::VehCont::const_iterator vi = vehicles.begin(); vi != vehicles.end(); ++vi) {
2630 foeCollector[*vi] = c;
2631 #ifdef DEBUG_SSM_SURROUNDING 2632 for (MSLane::VehCont::const_iterator vi = vehicles.begin(); vi != vehicles.end(); ++vi) {
2633 std::cout << (*vi)->getID() <<
"\n";
2649 for (MSLane::VehCont::const_iterator vi = vehicles2.begin(); vi != vehicles2.end(); ++vi) {
2653 foeCollector[*vi] = c;
2654 #ifdef DEBUG_SSM_SURROUNDING 2655 for (MSLane::VehCont::const_iterator vi = vehicles2.begin(); vi != vehicles2.end(); ++vi) {
2656 std::cout << (*vi)->getID() <<
"\n";
2664 #ifdef DEBUG_SSM_SURROUNDING 2665 std::cout << std::endl;
2683 std::string file = deviceID +
".xml";
2697 std::cout <<
"vehicle '" << v.
getID() <<
"' does not supply vehicle parameter 'device.ssm.file'. Using default of '" << file <<
"'\n";
2705 bool useGeo =
false;
2719 useGeo = oc.
getBool(
"device.ssm.geo");
2721 std::cout <<
"vehicle '" << v.
getID() <<
"' does not supply vehicle parameter 'device.ssm.geo'. Using default of '" << useGeo <<
"'\n";
2745 range = oc.
getFloat(
"device.ssm.range");
2747 std::cout <<
"vehicle '" << v.
getID() <<
"' does not supply vehicle parameter 'device.ssm.range'. Using default of '" << range <<
"'\n";
2771 extraTime = oc.
getFloat(
"device.ssm.extratime");
2773 std::cout <<
"vehicle '" << v.
getID() <<
"' does not supply vehicle parameter 'device.ssm.extratime'. Using default of '" << extraTime <<
"'\n";
2776 if (extraTime < 0.) {
2778 WRITE_WARNING(
"Negative (or no) value encountered for vehicle parameter 'device.ssm.extratime' in vehicle '" + v.
getID() +
"' using default value " +
toString(extraTime) +
" instead");
2787 bool trajectories =
false;
2801 trajectories = oc.
getBool(
"device.ssm.trajectories");
2803 std::cout <<
"vehicle '" << v.
getID() <<
"' does not supply vehicle parameter 'device.ssm.trajectories'. Using default of '" << trajectories <<
"'\n";
2806 return trajectories;
2815 std::string measures_str =
"";
2829 measures_str = oc.
getString(
"device.ssm.measures");
2830 std::cout <<
"vehicle '" << v.
getID() <<
"' does not supply vehicle parameter 'device.ssm.measures'. Using default of '" << measures_str <<
"'\n";
2834 if (measures_str ==
"") {
2835 WRITE_WARNING(
"No measures specified for ssm device of vehicle '" + v.
getID() +
"'. Registering all available SSMs.");
2839 std::vector<std::string> available = st.
getVector();
2841 std::vector<std::string> measures = st.
getVector();
2842 for (std::vector<std::string>::const_iterator i = measures.begin(); i != measures.end(); ++i) {
2843 if (std::find(available.begin(), available.end(), *i) == available.end()) {
2845 WRITE_ERROR(
"SSM identifier '" + *i +
"' is not supported. Aborting construction of SSM device '" + deviceID +
"'.");
2851 std::string thresholds_str =
"";
2865 thresholds_str = oc.
getString(
"device.ssm.thresholds");
2867 std::cout <<
"vehicle '" << v.
getID() <<
"' does not supply vehicle parameter 'device.ssm.thresholds'. Using default of '" << thresholds_str <<
"'\n";
2873 if (thresholds_str !=
"") {
2875 while (count < (
int)measures.size() && st.
hasNext()) {
2877 thresholds.insert(std::make_pair(measures[count], thresh));
2880 if (thresholds.size() < measures.size() || st.
hasNext()) {
2881 WRITE_ERROR(
"Given list of thresholds ('" + thresholds_str +
"') is not of the same size as the list of measures ('" + measures_str +
"').\nPlease specify exactly one threshold for each measure.");
2886 for (std::vector<std::string>::const_iterator i = measures.begin(); i != measures.end(); ++i) {
2889 }
else if (*i ==
"DRAC") {
2891 }
else if (*i ==
"PET") {
2893 }
else if (*i ==
"BR") {
2895 }
else if (*i ==
"SGAP") {
2897 }
else if (*i ==
"TGAP") {
2900 WRITE_ERROR(
"Unknown SSM identifier '" + (*i) +
"'. Aborting construction of ssm device.");
#define DEFAULT_THRESHOLD_BR
double foeConflictAreaLength
bool myUseGeoCoords
Whether to use the original coordinate system for output.
void doRegister(const std::string &name, Option *v)
Adds an option under the given name.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
static void determineConflictPoint(EncounterApproachInfo &eInfo)
Calculates the (x,y)-coordinate for the eventually predicted conflict point and stores the result in ...
std::vector< double > myBRspan
All values for brake rate.
ENCOUNTER_TYPE_MERGING_ADJACENT.
double getLength() const
Returns the vehicle's length.
MSEdge & getEdge() const
Returns the lane's edge.
static void getVehiclesOnJunction(const MSJunction *, double egoDistToConflictLane, const MSLane *const egoConflictLane, FoeInfoMap &foeCollector)
Collects all vehicles on the junction into foeCollector.
Representation of a vehicle in the micro simulation.
double getPreviousSpeed() const
Returns the vehicle's speed before the previous time step.
void createEncounters(FoeInfoMap &foes)
Makes new encounters for all given vehicles (these should be the ones entering the device's range in ...
static std::set< MSDevice_SSM * > * instances
All currently existing SSM devices.
bool notifyLeave(SUMOVehicle &veh, double lastPos, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Called whenever the holder leaves a lane.
MSLane * getLane() const
Returns the connected lane.
Position getVelocityVector() const
Returns the vehicle's direction in radians.
ConflictPointInfo maxDRAC
static void cleanup()
Clean up remaining devices instances.
EncounterType
Different types of encounters corresponding to relative positions of the vehicles. The name describes the type from the ego perspective.
MSLane * getLane() const
Returns the lane the vehicle is on.
PositionVector conflictPointSpan
Predicted location of the conflict: In case of MERGING and CROSSING: entry point to conflict area for...
static bool _2bool(const E *const data)
converts a 0-terminated char-type array into the boolean value described by it
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...
static void insertOptions(OptionsCont &oc)
Inserts MSDevice_SSM-options.
SUMOVehicle & myHolder
The vehicle that stores the device.
int gPrecision
the precision for floating point outputs
double egoConflictEntryTime
Times when the ego vehicle entered/left the conflict area. Currently only applies for crossing situat...
void determinePET(EncounterApproachInfo &eInfo) const
Discriminates between different encounter types and correspondingly determines the PET for those case...
std::pair< const MSVehicle *const, double > getLeader(double dist=0) const
Returns the leader of the vehicle looking for a fixed distance.
A device which collects info on the vehicle trip (mainly on departure and arrival) ...
void determineTTCandDRAC(EncounterApproachInfo &eInfo) const
Discriminates between different encounter types and correspondingly determines TTC and DRAC for those...
std::pair< std::pair< double, Position >, double > myMaxBR
Extremal values for the global measures (as <<<time, Position>, value>, [leaderID]>-pairs) ...
The base class for an intersection.
double getPositionOnLane() const
Get the vehicle's position along the lane.
EncounterVector myActiveEncounters
double foeEstimatedConflictExitTime
MSLink * getCorrespondingExitLink() const
returns the corresponding exit link for entryLinks to a junction.
SUMOVehicle * getVehicle(const std::string &id) const
Returns the vehicle with the given id.
Notification
Definition of a vehicle state.
ENCOUNTER_TYPE_FOLLOWING_PASSED.
virtual MSLane * getLane() const =0
Returns the lane the vehicle is on.
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...
EncounterType classifyEncounter(const FoeInfo *foeInfo, EncounterApproachInfo &eInfo) const
Classifies the current type of the encounter provided some information on the opponents.
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
std::vector< double > myGlobalMeasuresTimeSpan
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
double getLength() const
Returns the lane's length.
virtual const VehCont & getVehiclesSecure() const
Returns the vehicles container; locks it for microsimulation.
const PositionVector & getShape() const
Returns this lane's shape.
void closeEncounter(Encounter *e)
Finalizes the encounter and calculates SSM values.
MSLink * getLinkTo(const MSLane *) const
returns the link to the given lane or 0, if it is not connected
Position getPosition(const double offset=0) const
Return current position (x/y, cartesian)
double rotationAtOffset(double pos) const
Returns the rotation at the given length.
static double getDetectionRange(const SUMOVehicle &v)
ENCOUNTER_TYPE_COLLISION.
static void toGeo(Position &x)
convert SUMO-positions to geo coordinates (in place)
std::vector< double > TTCspan
All values for TTC.
ENCOUNTER_TYPE_EGO_ENTERED_CONFLICT_AREA.
Position pos
Predicted location of the conflict: In case of MERGING and CROSSING: entry point to conflict area for...
std::vector< const MSEdge * > ConstMSEdgeVector
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
const std::string & getID() const
Returns the id.
#define DEFAULT_THRESHOLD_PET
double getInternalLengthsAfter() const
Returns the cumulative length of all internal lanes after this link.
double getLength() const
return the length of the edge
double time
time point of the conflict
double foeEstimatedConflictEntryTime
const MSJunction * getToJunction() const
void updateEncounter(Encounter *e, FoeInfo *foeInfo)
Updates the encounter (adds a new trajectory point) and deletes the foeInfo.
void generateOutput() const
Finalizes output. Called on vehicle removal.
void resetExtraTime(double value)
resets remainingExtraTime to the given value
double egoConflictEntryDist
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)
Constructor.
ENCOUNTER_TYPE_CROSSING_FOLLOWER.
double getWidth() const
Returns the lane's width.
#define UNUSED_PARAMETER(x)
double egoConflictExitTime
ENCOUNTER_TYPE_BOTH_ENTERED_CONFLICT_AREA.
Position getPositionAlongBestLanes(double offset) const
Return the (x,y)-position, which the vehicle would reach if it continued along its best continuation ...
#define WRITE_WARNING(msg)
MSLane * getCanonicalSuccessorLane() const
static OptionsCont & getOptions()
Retrieves the options.
std::vector< double > mySGAPspan
All values for space gap.
static bool requestsTrajectories(const SUMOVehicle &v)
Encounter(const MSVehicle *_ego, const MSVehicle *const _foe, double _begin, double extraTime)
Constructor.
double egoDistToConflictLane
ENCOUNTER_TYPE_CROSSING_LEADER.
double getMaxSpeedOnLane() const
Returns the maximal speed for the vehicle on its current lane (including speed factor and deviation...
EncounterType currentType
EncounterApproachInfo(Encounter *e)
std::vector< double > DRACspan
All values for DRAC.
ENCOUNTER_TYPE_FOLLOWING_LEADER.
void cartesian2geo(Position &cartesian) const
Converts the given cartesian (shifted) position to its geo (lat/long) representation.
double foeConflictExitTime
A road/street connecting two junctions.
bool isOnRoad() const
Returns the information whether the vehicle is on a road (is simulated)
ENCOUNTER_TYPE_MERGING_FOLLOWER.
const MSCFModel & getCarFollowModel() const
Returns the vehicle's car following model definition.
std::size_t size() const
Returns the number of trajectory points stored.
static bool getMeasuresAndThresholds(const SUMOVehicle &v, std::string deviceID, std::map< std::string, double > &thresholds)
ENCOUNTER_TYPE_BOTH_LEFT_CONFLICT_AREA.
double egoConflictExitDist
MSLink * getEntryLink() const
Returns the entry link if this is an internal lane, else 0.
bool knowsParameter(const std::string &key) const
Returns whether the parameter is known.
MSLane * getViaLane() const
Returns the following inner lane.
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
std::vector< double > myTGAPspan
All values for time gap.
#define DEFAULT_THRESHOLD_TGAP
Representation of a vehicle.
static double computeDRAC(double gap, double followerSpeed, double leaderSpeed)
Computes the DRAC (deceleration to avoid a collision) for a lead/follow situation as defined...
void processEncounters(FoeInfoMap &foes, bool forceClose=false)
Finds encounters for which the foe vehicle has disappeared from range. remainingExtraTime is decrease...
#define DEFAULT_THRESHOLD_DRAC
A point in 2D or 3D with translation and scaling methods.
bool myComputeTTC
Flags for switching on / off comutation of different SSMs, derived from myMeasures.
OutputDevice * myOutputFile
Output device.
ENCOUNTER_TYPE_FOE_LEFT_CONFLICT_AREA.
void resetEncounters()
Closes all current Encounters and moves conflicts to myPastConflicts,.
const std::vector< MSLane * > & getBestLanesContinuation() const
Returns the best sequence of lanes to continue the route starting at myLane.
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
double getRemainingExtraTime() const
returns the remaining extra time
double myRange
Detection range. For vehicles closer than this distance from the ego vehicle, SSMs are traced...
std::vector< double > egoDistsToConflict
Evolution of the ego vehicle's distance to the conflict point.
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
ENCOUNTER_TYPE_FOLLOWING_FOLLOWER.
ENCOUNTER_TYPE_NOCONFLICT_AHEAD.
#define DEFAULT_EXTRA_TIME
static void getUpstreamVehicles(const MSEdge *edge, double pos, double range, double egoDistToConflictLane, const MSLane *const egoConflictLane, FoeInfoMap &foeCollector, std::set< const MSJunction *> seenJunctions)
Collects all vehicles within range 'range' upstream of the position 'pos' on the edge 'edge' into foe...
bool notifyEnter(SUMOVehicle &veh, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Called whenever the holder enteres a lane.
void computeSSMs(EncounterApproachInfo &e) const
Compute current values of the logged SSMs (myMeasures) for the given encounter 'e' and update 'e' acc...
double egoEstimatedConflictExitTime
const ConstMSEdgeVector & getIncoming() const
bool qualifiesAsConflict(Encounter *e)
Tests if the SSM values exceed the threshold for qualification as conflict.
const MSLane * getInternalLaneBefore() const
return myInternalLaneBefore (always 0 when compiled without internal lanes)
static void checkConflictEntryAndExit(EncounterApproachInfo &eInfo)
Checks whether ego or foe have entered or left the conflict area in the last step and eventually writ...
ENCOUNTER_TYPE_MERGING_LEADER.
static void insertDefaultAssignmentOptions(const std::string &deviceName, const std::string &optionsTopic, OptionsCont &oc)
Adds common command options that allow to assign devices to vehicles.
double getLengthsBeforeCrossing(const MSLane *foeLane) const
Returns the sum of the lengths along internal lanes following this link to the crossing with the give...
std::ostream & operator<<(std::ostream &out, MSDevice_SSM::EncounterType type)
Nicer output for EncounterType enum.
std::pair< std::pair< std::pair< double, Position >, double >, std::string > myMinTGAP
ENCOUNTER_TYPE_FOE_ENTERED_CONFLICT_AREA.
void addOptionSubTopic(const std::string &topic)
Adds an option subtopic.
virtual bool isOnRoad() const =0
Returns the information whether the vehicle is on a road (is simulated)
void updateAndWriteOutput()
This is called once per time step in MSNet::writeOutput() and collects the surrounding vehicles...
void flushGlobalMeasures()
Write out all non-encounter specific measures as headways and braking rates.
static const std::set< MSDevice_SSM * > & getInstances()
returns all currently existing SSM devices
const MSLane * findFoeConflictLane(const MSVehicle *foe, const MSLane *egoConflictLane, double &distToConflictLane) const
Computes the conflict lane for the foe.
EncounterType type
Type of the conflict.
double myOldestActiveEncounterBegin
begin time of the oldest active encounter
bool isInternal() const
return whether this edge is an internal edge
virtual const std::vector< MSLane * > getInternalLanes() const
Returns all internal lanes on the junction.
ENCOUNTER_TYPE_FOLLOWING.
bool mySaveTrajectories
This determines whether the whole trajectories of the vehicles (position, speed, ssms) shall be saved...
const SUMOVTypeParameter & getParameter() const
static std::string getOutputFilename(const SUMOVehicle &v, std::string deviceID)
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
std::vector< MSVehicle * > VehCont
Container for vehicles.
double getLength() const
Returns the length of this link.
static double getExtraTime(const SUMOVehicle &v)
void flushConflicts(bool all=false)
Writes out all past conflicts that have begun earlier than the oldest active encounter.
static std::string makeStringWithNAs(std::vector< double > v, double NA, std::string sep=" ")
make a string of a double vector and treat a special value as invalid ("NA")
double getLateralPositionOnLane() const
Get the vehicle's lateral position on the lane.
std::vector< double > foeDistsToConflict
Evolution of the foe vehicle's distance to the conflict point.
bool closingRequested
this flag is set by updateEncounter() or directly in processEncounters(), where encounters are closed...
std::vector< std::string > getVector()
#define DEFAULT_THRESHOLD_SGAP
Abstract in-vehicle device.
ENCOUNTER_TYPE_FOLLOWING_PASSED.
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...
std::vector< Encounter * > EncounterVector
double getWidth() const
Get the width which vehicles of this class shall have when being drawn.
static bool useGeoCoords(const SUMOVehicle &v)
const std::vector< MSLink * > & getFoeLinks() const
void countDownExtraTime(double amount)
decreases myRemaingExtraTime by given amount in seconds
double foeConflictEntryTime
Times when the foe vehicle entered/left the conflict area. Currently only applies for crossing situat...
const MSVehicleType & getVehicleType() const
Returns the vehicle's type definition.
std::map< const MSVehicle *, FoeInfo * > FoeInfoMap
const MSLane * egoConflictLane
Trajectory egoTrajectory
Trajectory of the ego vehicle.
const MSLane * getFirstInternalInConnection(double &offset) const
Returns 0 if the lane is not internal. Otherwise the first part of the connection (sequence of intern...
static OutputDevice & getDevice(const std::string &name)
Returns the described OutputDevice.
virtual const SUMOVehicleParameter & getParameter() const =0
Returns the vehicle's parameter (including departure definition)
~MSDevice_SSM()
Destructor.
const MSJunction * getFromJunction() const
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...
void computeGlobalMeasures()
Stores measures, that are not associated to a specific encounter as headways and brake rates...
double getAcceleration() const
Returns the vehicle's acceleration in m/s (this is computed as the last step's mean acceleration in c...
Structure to collect some info on the encounter needed during ssm calculation by various functions...
std::vector< double > timeSpan
time points corresponding to the trajectories
A storage for options typed value containers)
static double _2double(const E *const data)
converts a char-type array into the double value described by it
const std::string getParameter(const std::string &key, const std::string &defaultValue="") const
Returns the value for a given key.
double getInternalFollowingLengthTo(const MSEdge *followerAfterInternal) const
returns the length of all internal edges on the junction until reaching the non-internal edge followe...
ENCOUNTER_TYPE_EGO_LEFT_CONFLICT_AREA.
static const GeoConvHelper & getFinal()
the coordinate transformation for writing the location element and for tracking the original coordina...
std::pair< double, double > pet
double getLength() const
Get vehicle's length [m].
double egoEstimatedConflictEntryTime
std::map< std::string, double > myThresholds
double foeConflictExitDist
static bool equippedByDefaultAssignmentOptions(const OptionsCont &oc, const std::string &deviceName, SUMOVehicle &v, bool outputOptionSet)
Determines whether a vehicle should get a certain device.
std::pair< std::pair< std::pair< double, Position >, double >, std::string > myMinSGAP
double getBackPositionOnLane(const MSLane *lane) const
Get the vehicle's position relative to the given lane.
double getLastStepDist() const
Get the distance the vehicle covered in the previous timestep.
Static storage of an output device and its base (abstract) implementation.
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
An encounter is an episode involving two vehicles, which are closer to each other than some specified...
#define DEFAULT_THRESHOLD_TTC
double myExtraTime
Extra time in seconds to be logged after a conflict is over.
std::vector< int > typeSpan
Evolution of the encounter classification (.
double remainingExtraTime
Remaining extra time (decreases after an encounter ended)
ENCOUNTER_TYPE_ON_ADJACENT_LANES.
void addDescription(const std::string &name, const std::string &subtopic, const std::string &description)
Adds a description for an option.
const MSLinkCont & getLinkCont() const
returns the container with all links !!!
static void estimateConflictTimes(EncounterApproachInfo &eInfo)
Estimates the time until conflict for the vehicles based on the distance to the conflict entry points...
double getSpeed() const
Returns the vehicle's current speed.
double foeConflictEntryDist
void writeOutConflict(Encounter *e)
const MSRouteIterator & getCurrentRouteEdge() const
Returns an iterator pointing to the current edge in this vehicles route.
virtual void releaseVehicles() const
Allows to use the container for microsimulation again.
bool notifyMove(SUMOVehicle &veh, double oldPos, double newPos, double newSpeed)
Checks for waiting steps when the vehicle moves.
const std::string & getID() const
Returns the name of the vehicle.
static std::set< std::string > createdOutputFiles
remember which files were created already (don't duplicate xml root-elements)
Representation of a lane in the micro simulation.
virtual const std::string & getID() const =0
Get the vehicle's ID.
std::string joinToString(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=gPrecision)
EncounterQueue myPastConflicts
Past encounters that where qualified as conflicts and are not yet flushed to the output file...
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
double egoConflictAreaLength
double value
value of the corresponding SSM
static void buildVehicleDevices(SUMOVehicle &v, std::vector< MSDevice *> &into)
Build devices for the given vehicle, if needed.
double getWidth() const
Returns the vehicle's width.
Trajectory foeTrajectory
Trajectory of the foe vehicle.
static void findSurroundingVehicles(const MSVehicle &veh, double range, FoeInfoMap &foeCollector)
Returns all vehicles, which are within the given range of the given vehicle.
virtual const MSVehicleType & getVehicleType() const =0
Returns the vehicle's type.
std::priority_queue< Encounter *, std::vector< Encounter * >, Encounter::compare > EncounterQueue
void add(double time, EncounterType type, Position egoX, Position egoV, Position foeX, Position foeV, Position conflictPoint, double egoDistToConflict, double foeDistToConflict, double ttc, double drac, std::pair< double, double > pet)
add a new data point and update encounter type