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) <<
")";
169 const std::set<MSDevice_SSM*>&
178 for (std::set<MSDevice_SSM*>::iterator ii =
instances->begin(); ii !=
instances->end(); ++ii) {
179 (*ii)->resetEncounters();
180 (*ii)->flushConflicts(
true);
181 (*ii)->flushGlobalMeasures();
197 oc.
doRegister(
"device.ssm.measures", Option::makeUnsetWithDefault<Option_String, std::string>(
""));
198 oc.
addDescription(
"device.ssm.measures",
"SSM Device",
"Specifies which measures will be logged (as a space separated sequence of IDs in ('TTC', 'DRAC', 'PET')).");
199 oc.
doRegister(
"device.ssm.thresholds", Option::makeUnsetWithDefault<Option_String, std::string>(
""));
200 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.");
201 oc.
doRegister(
"device.ssm.trajectories", Option::makeUnsetWithDefault<Option_Bool, bool>(
false));
202 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).");
204 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.");
206 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.");
207 oc.
doRegister(
"device.ssm.file", Option::makeUnsetWithDefault<Option_String, std::string>(
""));
208 oc.
addDescription(
"device.ssm.file",
"SSM Device",
"Give a global default filename for the SSM output.");
209 oc.
doRegister(
"device.ssm.geo", Option::makeUnsetWithDefault<Option_Bool, bool>(
false));
210 oc.
addDescription(
"device.ssm.geo",
"SSM Device",
"Whether to use coordinates of the original reference system in output (default is false).");
217 WRITE_WARNING(
"SSM Device for vehicle '" + v.
getID() +
"' will not be built. (SSMs not supported in MESO)");
221 std::string deviceID =
"ssm_" + v.
getID();
226 std::map<std::string, double> thresholds;
249 into.push_back(device);
257 egoID(_ego->
getID()),
258 foeID(_foe->
getID()),
262 remainingExtraTime(extraTime),
270 closingRequested(false) {
272 std::cout <<
"\n" <<
SIMTIME <<
" Constructing encounter of '" 279 std::cout <<
"\n" <<
SIMTIME <<
" Destroying encounter of '" 280 <<
egoID <<
"' and '" <<
foeID <<
"' (begin was " <<
begin <<
")" << std::endl;
287 Position conflictPoint,
double egoDistToConflict,
double foeDistToConflict,
double ttc,
double drac, std::pair<double, double> pet) {
289 std::cout << time <<
" Adding data point for encounter of '" <<
egoID <<
"' and '" <<
foeID <<
"':\n" 290 <<
"type=" << type <<
", egoDistToConflict=" << (egoDistToConflict ==
INVALID ?
"NA" :
toString(egoDistToConflict))
291 <<
", foeDistToConflict=" << (foeDistToConflict ==
INVALID ?
"NA" :
toString(foeDistToConflict))
355 conflictPoint(
Position::invalidPosition()),
360 egoEstimatedConflictEntryTime(
INVALID),
361 foeEstimatedConflictEntryTime(
INVALID),
362 egoEstimatedConflictExitTime(
INVALID),
363 foeEstimatedConflictExitTime(
INVALID),
364 egoConflictAreaLength(
INVALID),
365 foeConflictAreaLength(
INVALID),
366 egoLeftConflict(false),
367 foeLeftConflict(false),
390 std::cout <<
"\n" <<
SIMTIME <<
" Device '" <<
getID() <<
"' update()\n" 400 if (foes.size() > 0) {
401 std::cout <<
"Scanned surroundings: Found potential foes:\n";
402 for (FoeInfoMap::const_iterator i = foes.begin(); i != foes.end(); ++i) {
403 std::cout << i->first->getID() <<
" ";
405 std::cout << std::endl;
407 std::cout <<
"Scanned surroundings: No potential conflict could be identified." << std::endl;
437 double leaderSearchDist = 0;
438 std::pair<const MSVehicle*, double> leader(
nullptr, 0.);
446 if (leaderSearchDist > 0.) {
451 if (leader.first ==
nullptr) {
454 double sgap = leader.second + leader.first->getVehicleType().getMinGap();
466 const double tgap = (leader.second + leader.first->getVehicleType().getMinGap()) /
myHolderMS->
getSpeed();
481 std::cout <<
"\n" <<
SIMTIME <<
" Device '" <<
getID() <<
"' createEncounters()" << std::endl;
482 std::cout <<
"New foes:\n";
483 for (FoeInfoMap::const_iterator vi = foes.begin(); vi != foes.end(); ++vi) {
484 std::cout << vi->first->getID() <<
"\n";
486 std::cout << std::endl;
489 for (FoeInfoMap::const_iterator foe = foes.begin(); foe != foes.end(); ++foe) {
490 std::pair<MSLane*, MSLane*> conflictLanes;
497 assert(myOldestActiveEncounterBegin <= e->begin);
513 std::cout <<
"\n" <<
SIMTIME <<
" Device '" <<
getID() <<
"' processEncounters()" << std::endl;
514 std::cout <<
"Currently present foes:\n";
515 for (FoeInfoMap::const_iterator vi = foes.begin(); vi != foes.end(); ++vi) {
516 std::cout << vi->first->getID() <<
"\n";
518 std::cout << std::endl;
534 if (foes.find(e->
foe) != foes.end()) {
550 double eBegin = e->
begin;
574 std::cout <<
SIMTIME <<
" qualifiesAsConflict() for encounter of vehicles '" 605 std::cout <<
SIMTIME <<
" closeEncounter() of vehicles '" 607 <<
"' (was ranked as " << (wasConflict ?
"conflict" :
"non-conflict") <<
")" << std::endl;
617 std::cout <<
SIMTIME <<
" updateEncounter() of vehicles '" 637 std::cout <<
SIMTIME <<
" Encounter of vehicles '" 639 <<
"' does not imply any conflict." << std::endl;
692 std::cout <<
SIMTIME <<
" determineConflictPoint()" << std::endl;
717 std::cout <<
"No conflict point associated with encounter type " << type << std::endl;
723 std::cout <<
" Conflict at " << eInfo.
conflictPoint << std::endl;
736 std::cout <<
SIMTIME <<
" estimateConflictTimes() for ego '" << e->
egoID <<
"' and foe '" << e->
foeID <<
"'\n" 737 <<
" encounter type: " << eInfo.
type <<
"\n" 750 std::cout <<
" encouter type " << type <<
" -> no entry/exit times to be calculated." 791 std::cout <<
" Potential conflict type: " << (type ==
ENCOUNTER_TYPE_CROSSING ?
"CROSSING" :
"MERGING") <<
"\n" 821 std::stringstream ss;
822 ss <<
"SSM device of vehicle '" << e->
egoID <<
"' detected collision with vehicle '" << e->
foeID <<
"'";
827 std::cout <<
" -> ego is estimated leader at conflict entry." 835 std::cout <<
" -> foe is estimated leader at conflict entry." 850 std::cout <<
SIMTIME <<
" computeSSMs() for vehicles '" 880 std::stringstream ss;
881 ss <<
"'" << type <<
"'";
882 WRITE_WARNING(
"Unknown or undetermined encounter type at computeSSMs(): " + ss.str());
886 std::cout <<
"computeSSMs() for encounter of vehicles '" << e->
egoID <<
"' and '" << e->
foeID <<
"':\n" 898 if (e->
size() == 0) {
902 std::pair<double, double>&
pet = eInfo.
pet;
905 std::cout <<
SIMTIME <<
" determinePET() for encounter of vehicles '" << e->
egoID <<
"' and '" << e->
foeID <<
"'" 919 std::cout <<
"PET for crossing encounter already calculated as " << e->
PET.
value 962 std::cout <<
"Unexpected branch in determinePET: Both passed conflict area in the same step." 978 std::cout <<
"Calculated PET = " << pet.second <<
" (at t=" << pet.first <<
")" 984 std::cout <<
"PET unappropriate for merging and pre-crossing situations. No calculation performed." 1000 std::cout <<
SIMTIME <<
" determineTTCandDRAC() for encounter of vehicles '" << e->
egoID <<
"' and '" << e->
foeID <<
"' (type = " << eInfo.
type <<
")" 1035 std::cout <<
" Conflict times with constant speed extrapolation for merging situation:\n " 1036 <<
" egoEntryTime=" << (egoEntryTime ==
INVALID ?
"NA" :
toString(egoEntryTime))
1037 <<
", egoExitTime=" << (egoExitTime ==
INVALID ?
"NA" :
toString(egoExitTime))
1038 <<
", foeEntryTime=" << (foeEntryTime ==
INVALID ?
"NA" :
toString(foeEntryTime))
1039 <<
", foeExitTime=" << (foeExitTime ==
INVALID ?
"NA" :
toString(foeExitTime))
1049 std::cout <<
" No TTC and DRAC computed as one vehicle is stopped." << std::endl;
1053 double leaderEntryTime =
MIN2(egoEntryTime, foeEntryTime);
1054 double followerEntryTime =
MAX2(egoEntryTime, foeEntryTime);
1055 double leaderExitTime = leaderEntryTime == egoEntryTime ? egoExitTime : foeExitTime;
1062 if (leaderExitTime >= followerEntryTime) {
1065 ttc =
computeTTC(followerConflictDist, followerSpeed, 0.);
1070 drac =
computeDRAC(followerConflictDist, followerSpeed, 0.);
1075 std::cout <<
" Extrapolation predicts collision *at* merge point with TTC=" << ttc
1076 <<
", drac=" << drac << std::endl;
1083 double gapAfterMerge = followerConflictDist - leaderExitTime * followerSpeed;
1084 assert(gapAfterMerge >= 0);
1087 double ttcAfterMerge =
computeTTC(gapAfterMerge, followerSpeed, leaderSpeed);
1088 ttc = ttcAfterMerge ==
INVALID ?
INVALID : leaderExitTime + ttcAfterMerge;
1092 double g0 = followerConflictDist - leaderConflictDist - leaderLength;
1095 assert(leaderSpeed - followerSpeed > 0);
1100 drac =
computeDRAC(g0, followerSpeed, leaderSpeed);
1107 std::cout <<
" Extrapolation does not predict any collision." << std::endl;
1109 std::cout <<
" Extrapolation predicts collision *after* merge point with TTC=" 1111 <<
", drac=" << (drac ==
INVALID ?
"NA" :
toString(drac)) << std::endl;
1149 std::stringstream ss;
1150 ss <<
"'" << type <<
"'";
1151 WRITE_WARNING(
"Underspecified or unknown encounter type in MSDevice_SSM::determineTTCandDRAC(): " + ss.str());
1168 std::cout <<
"computeTTC() with gap=" << gap <<
", followerSpeed=" << followerSpeed <<
", leaderSpeed=" << leaderSpeed
1174 double dv = followerSpeed - leaderSpeed;
1185 #ifdef DEBUG_SSM_DRAC 1186 std::cout <<
"computeDRAC() with gap=" << gap <<
", followerSpeed=" << followerSpeed <<
", leaderSpeed=" << leaderSpeed
1192 double dv = followerSpeed - leaderSpeed;
1196 assert(followerSpeed > 0.);
1197 return 0.5 * dv * dv / gap;
1213 #ifdef DEBUG_SSM_DRAC 1214 std::cout <<
SIMTIME <<
"computeDRAC() with" 1215 <<
"\ndEntry1=" << dEntry1 <<
", dEntry2=" << dEntry2
1216 <<
", dExit1=" << dExit1 <<
", dExit2=" << dExit2
1217 <<
",\nv1=" << v1 <<
", v2=" << v2
1222 if (dExit1 <= 0. || dExit2 <= 0.) {
1224 #ifdef DEBUG_SSM_DRAC 1225 std::cout <<
"One already left conflict area -> drac == 0." << std::endl;
1229 if (dEntry1 <= 0. && dEntry2 <= 0.) {
1231 #ifdef DEBUG_SSM_DRAC 1232 std::cout <<
"Both entered conflict area but neither left. -> collision!" << std::endl;
1237 double drac = std::numeric_limits<double>::max();
1240 #ifdef DEBUG_SSM_DRAC 1241 std::cout <<
"Ego could break..." << std::endl;
1245 drac =
MIN2(drac, 2 * (v1 - dEntry1 / tExit2) / tExit2);
1246 #ifdef DEBUG_SSM_DRAC 1247 std::cout <<
" Foe expected to leave in " << tExit2 <<
"-> Ego needs drac=" << drac << std::endl;
1254 #ifdef DEBUG_SSM_DRAC 1255 std::cout <<
" Foe is expected stop on conflict area -> Ego needs drac=" << drac << std::endl;
1259 #ifdef DEBUG_SSM_DRAC 1260 std::cout <<
" Foe is expected stop before conflict area -> no drac computation for ego (will be done for foe if applicable)" << std::endl;
1268 #ifdef DEBUG_SSM_DRAC 1269 std::cout <<
"Foe could break..." << std::endl;
1273 #ifdef DEBUG_SSM_DRAC 1274 std::cout <<
" Ego expected to leave in " << tExit1 <<
"-> Foe needs drac=" << (2 * (v2 - dEntry2 / tExit1) / tExit1) << std::endl;
1276 drac =
MIN2(drac, 2 * (v2 - dEntry2 / tExit1) / tExit1);
1281 #ifdef DEBUG_SSM_DRAC 1282 std::cout <<
" Ego is expected stop on conflict area -> Foe needs drac=" <<
computeDRAC(dEntry2, v2, 0) << std::endl;
1287 #ifdef DEBUG_SSM_DRAC 1288 std::cout <<
" Ego is expected stop before conflict area -> no drac computation for foe (done for ego if applicable)" << std::endl;
1303 std::cout <<
SIMTIME <<
" checkConflictEntryAndExit() for encounter of vehicles '" << e->
egoID <<
"' and '" << e->
foeID <<
"'" << std::endl;
1316 prevEgoConflictEntryDist =
MAX2(prevEgoConflictEntryDist, 0.);
1317 prevFoeConflictEntryDist =
MAX2(prevFoeConflictEntryDist, 0.);
1318 prevEgoConflictExitDist =
MAX2(prevEgoConflictExitDist, 0.);
1319 prevFoeConflictExitDist =
MAX2(prevFoeConflictExitDist, 0.);
1389 std::cout <<
SIMTIME <<
" updatePassedEncounter() for vehicles '" 1394 if (foeInfo ==
nullptr) {
1398 std::cout <<
" Foe is out of range. Counting down extra time." 1415 std::cout <<
" This encounter wasn't classified as a potential conflict lately." << std::endl;
1417 if (foeInfo ==
nullptr) {
1423 std::cout <<
" Closing encounter." << std::endl;
1433 std::cout <<
" Encounter was previously classified as a follow/lead situation." << std::endl;
1442 std::cout <<
" Encounter was previously classified as a merging situation." << std::endl;
1457 std::cout <<
" Encounter was previously classified as a crossing situation of type " << lastPotentialConflictType <<
"." << std::endl;
1488 if ((!egoEnteredConflict) && !foeEnteredConflict) {
1492 eInfo.
type = lastPotentialConflictType;
1493 }
else if (egoEnteredConflict && !foeEnteredConflict) {
1495 }
else if ((!egoEnteredConflict) && foeEnteredConflict) {
1501 if ((!egoLeftConflict) && !foeLeftConflict) {
1505 }
else if (egoLeftConflict && !foeLeftConflict) {
1509 }
else if ((!egoLeftConflict) && foeLeftConflict) {
1525 std::cout <<
" Updated classification: " << eInfo.
type << std::endl;
1534 std::cout <<
"classifyEncounter() called." << std::endl;
1536 if (foeInfo ==
nullptr) {
1556 std::cout <<
" Ongoing crossing conflict will be traced by passedEncounter()." << std::endl;
1571 double foeDistToConflictLane;
1575 std::cout <<
"egoConflictLane: '" << (egoConflictLane == 0 ?
"NULL" : egoConflictLane->
getID()) <<
"'\n" 1576 <<
"foeConflictLane: '" << (foeConflictLane == 0 ?
"NULL" : foeConflictLane->
getID()) <<
"'" 1577 <<
"\nEgo's distance to conflict lane: " << egoDistToConflictLane
1578 <<
"\nFoe's distance to conflict lane: " << foeDistToConflictLane
1593 if (foeConflictLane ==
nullptr) {
1597 std::cout <<
"-> Encounter type: No conflict." << std::endl;
1599 }
else if (!egoConflictLane->isInternal()) {
1601 if (egoConflictLane == egoLane) {
1603 if (foeLane == egoLane) {
1613 std::cout <<
"-> Encounter type: Lead/follow-situation on non-internal lane '" << egoLane->
getID() <<
"'" << std::endl;
1620 std::cout <<
"-> Encounter type: " << type << std::endl;
1624 assert(egoDistToConflictLane <= 0);
1626 if (foeConflictLane == egoLane) {
1631 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' leads foe '" 1632 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'" 1640 std::cout <<
"-> Encounter type: " << type << std::endl;
1649 assert(&(foeLane->
getEdge()) == &(egoConflictLane->getEdge()));
1650 assert(foeDistToConflictLane <= 0);
1651 if (foeLane == egoConflictLane) {
1655 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' follows foe '" 1656 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'" 1664 std::cout <<
"-> Encounter type: " << type << std::endl;
1672 MSLink* egoEntryLink = egoConflictLane->getEntryLink();
1674 if (&(egoEntryLink->getViaLane()->getEdge()) == &(foeEntryLink->
getViaLane()->
getEdge())) {
1675 if (egoEntryLink != foeEntryLink) {
1679 std::cout <<
"-> Encounter type: " << type << std::endl;
1683 if (egoLane == egoConflictLane && foeLane != foeConflictLane) {
1688 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' leads foe '" 1689 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'" 1693 }
else if (egoLane != egoConflictLane && foeLane == foeConflictLane) {
1698 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' follows foe '" 1699 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'" 1707 assert(egoLane == egoConflictLane);
1708 assert(foeLane == foeConflictLane);
1709 if (egoLane == foeLane) {
1715 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' leads foe '" 1716 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'" 1724 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' follows foe '" 1725 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'" 1733 std::cout <<
" Lead/follow situation on consecutive internal lanes." << std::endl;
1735 MSLane* lane = egoEntryLink->getViaLane();
1737 #pragma warning(push) 1738 #pragma warning(disable: 4127) // do not warn about constant conditional expression 1742 #pragma warning(pop) 1746 if (egoLane == lane) {
1751 while (lane != foeLane) {
1757 egoConflictLane = lane;
1759 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' follows foe '" 1760 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'" 1765 }
else if (foeLane == lane) {
1770 while (lane != egoLane) {
1776 foeConflictLane = lane;
1778 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' leads foe '" 1779 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'" 1790 std::cout <<
"-> Encounter type: Lead/follow-situation on connection from '" << egoEntryLink->getLaneBefore()->getID()
1791 <<
"' to '" << egoEntryLink->getLane()->getID() <<
"'" << std::endl;
1798 const std::vector<MSLink*>& egoFoeLinks = egoEntryLink->getFoeLinks();
1799 const std::vector<MSLink*>& foeFoeLinks = foeEntryLink->
getFoeLinks();
1801 bool crossOrMerge = (find(egoFoeLinks.begin(), egoFoeLinks.end(), foeEntryLink) != egoFoeLinks.end()
1802 || find(foeFoeLinks.begin(), foeFoeLinks.end(), egoEntryLink) != foeFoeLinks.end());
1803 if (!crossOrMerge) {
1813 std::cout <<
"-> Encounter type: No conflict." << std::endl;
1816 }
else if (&(foeEntryLink->
getLane()->
getEdge()) == &(egoEntryLink->getLane()->getEdge())) {
1817 if (foeEntryLink->
getLane() == egoEntryLink->getLane()) {
1822 std::cout <<
"-> Encounter type: Merging situation of ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' and foe '" 1823 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'" 1831 std::cout <<
"-> Encounter type: No conflict: " << type << std::endl;
1837 assert(egoConflictLane->isInternal());
1838 assert(foeConflictLane->
getEdge().
getToJunction() == egoConflictLane->getEdge().getToJunction());
1845 egoConflictLane = egoConflictLane->getFirstInternalInConnection(offset);
1846 egoDistToConflictLane -= offset;
1848 foeDistToConflictLane -= offset;
1852 double egoDistToConflictFromJunctionEntry =
INVALID;
1853 double foeInternalLaneLengthsBeforeCrossing = 0.;
1854 while (foeConflictLane !=
nullptr && foeConflictLane->
isInternal()) {
1855 egoDistToConflictFromJunctionEntry = egoEntryLink->getLengthsBeforeCrossing(foeConflictLane);
1856 if (egoDistToConflictFromJunctionEntry !=
INVALID) {
1861 foeInternalLaneLengthsBeforeCrossing += foeConflictLane->
getLength();
1864 assert(foeConflictLane != 0 && foeConflictLane->
isInternal());
1866 assert(egoDistToConflictFromJunctionEntry !=
INVALID);
1869 double foeDistToConflictFromJunctionEntry =
INVALID;
1870 double egoInternalLaneLengthsBeforeCrossing = 0.;
1871 foeDistToConflictFromJunctionEntry =
INVALID;
1872 while (egoConflictLane !=
nullptr && egoConflictLane->isInternal()) {
1874 if (foeDistToConflictFromJunctionEntry !=
INVALID) {
1879 egoInternalLaneLengthsBeforeCrossing += egoConflictLane->getLength();
1881 egoConflictLane = egoConflictLane->getCanonicalSuccessorLane();
1882 assert(egoConflictLane != 0 && egoConflictLane->isInternal());
1884 assert(foeDistToConflictFromJunctionEntry !=
INVALID);
1896 Position egoEntryPos = egoEntryLink->getViaLane()->getShape().front();
1897 Position egoExitPos = egoEntryLink->getCorrespondingExitLink()->getInternalLaneBefore()->getShape().back();
1907 assert(angle <= 2 *
M_PI);
1911 assert(angle >= -
M_PI);
1912 assert(angle <=
M_PI);
1914 double crossingOrientation = (angle < 0) - (angle > 0);
1927 std::cout <<
" Determined exact conflict distances for crossing conflict." 1928 <<
"\n crossingOrientation=" << crossingOrientation
1931 <<
", relativeAngle=" << angle
1932 <<
" (foe from " << (crossingOrientation > 0 ?
"right)" :
"left)")
1933 <<
"\n resulting offset for conflict entry distance:" 1936 <<
"\n resulting entry distances:" 1951 std::cout <<
"real egoConflictLane: '" << (egoConflictLane == 0 ?
"NULL" : egoConflictLane->getID()) <<
"'\n" 1952 <<
"real foeConflictLane: '" << (foeConflictLane == 0 ?
"NULL" : foeConflictLane->
getID()) <<
"'\n" 1953 <<
"-> Encounter type: Crossing situation of ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' and foe '" 1954 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'" 1969 std::cout <<
SIMTIME <<
" findFoeConflictLane() for foe '" 1971 <<
"' (with egoConflictLane=" << (egoConflictLane == 0 ?
"NULL" : egoConflictLane->
getID())
1978 assert(foeLane->
isInternal() || *laneIter == foeLane);
1984 if (conflictJunction != 0) {
1985 std::cout <<
"Potential conflict on junction '" << conflictJunction->
getID()
1997 if (*laneIter ==
nullptr) {
1998 while (foeLane !=
nullptr && foeLane->
isInternal()) {
1999 distToConflictLane += foeLane->
getLength();
2000 foeLane = foeLane->
getLinkCont()[0]->getViaLane();
2003 assert(laneIter == foeBestLanesEnd || *laneIter != 0);
2007 while (laneIter != foeBestLanesEnd && distToConflictLane <=
myRange) {
2009 assert(*laneIter == foeLane || foeLane == 0);
2010 foeLane = *laneIter;
2014 std::cout <<
"Found conflict lane for foe: '" << foeLane->
getID() <<
"'" << std::endl;
2020 distToConflictLane += foeLane->
getLength();
2024 if (laneIter == foeBestLanesEnd) {
2027 MSLane* nextNonInternalLane = *laneIter;
2031 assert(foeLane == 0 || foeLane->
isInternal());
2032 if (foeLane ==
nullptr) {
2033 foeLane = nextNonInternalLane;
2037 assert(foeLane != 0);
2039 std::cout <<
"Found conflict lane for foe: '" << foeLane->
getID() <<
"'" << std::endl;
2046 foeLane = nextNonInternalLane;
2055 std::cout <<
"\n" <<
SIMTIME <<
" Device '" <<
getID() <<
"' flushConflicts()" << std::endl;
2073 std::cout <<
SIMTIME <<
" flushGlobalMeasures() of vehicle '" 2137 std::cout <<
SIMTIME <<
" writeOutConflict() of vehicles '" 2218 std::string res =
"";
2219 for (std::vector<double>::const_iterator i = v.begin(); i != v.end(); ++i) {
2220 res += (i == v.begin() ?
"" : sep) + (*i == NA ?
"NA" :
toString(*i));
2227 std::string res =
"";
2228 for (std::vector<double>::const_iterator i = v.begin(); i != v.end(); ++i) {
2229 res += (i == v.begin() ?
"" : sep) + (find(NAs.begin(), NAs.end(), *i) != NAs.end() ?
"NA" :
toString(*i));
2239 bool trajectories,
double range,
double extraTime,
bool useGeoCoords) :
2248 myMinSGAP(std::make_pair(std::make_pair(-1,
Position(0., 0.)), std::numeric_limits<double>::max()),
""),
2249 myMinTGAP(std::make_pair(std::make_pair(-1,
Position(0., 0.)), std::numeric_limits<double>::max()),
"") {
2276 std::vector<std::string> measures;
2277 std::vector<double> threshVals;
2279 measures.push_back(i->first);
2280 threshVals.push_back(i->second);
2282 std::cout <<
"Initialized ssm device '" <<
id <<
"' with " 2303 #ifdef DEBUG_SSM_NOTIFICATIONS 2304 std::cout <<
"device '" <<
getID() <<
"' notifyEnter: reason=" << reason <<
" currentEdge=" << veh.
getLane()->
getEdge().
getID() <<
"\n";
2315 #ifdef DEBUG_SSM_NOTIFICATIONS 2316 std::cout <<
"device '" <<
getID() <<
"' notifyLeave: reason=" << reason <<
" currentEdge=" << veh.
getLane()->
getEdge().
getID() <<
"\n";
2326 double ,
double newSpeed) {
2327 #ifdef DEBUG_SSM_NOTIFICATIONS 2328 std::cout <<
"device '" <<
getID() <<
"' notifyMove: newSpeed=" << newSpeed <<
"\n";
2338 #ifdef DEBUG_SSM_SURROUNDING 2339 std::cout <<
SIMTIME <<
" Looking for surrounding vehicles for ego vehicle '" << veh.
getID()
2362 std::vector<MSLane*>::const_iterator laneIter = egoBestLanes.begin();
2366 assert(lane->
isInternal() || lane == *laneIter);
2369 const MSLane* nextNonInternalLane =
nullptr;
2377 double remainingDownstreamRange = range;
2379 double distToConflictLane = -pos;
2381 std::set<const MSJunction*> seenJunctions;
2389 #ifdef DEBUG_SSM_SURROUNDING 2390 std::cout <<
SIMTIME <<
" Vehicle '" << veh.
getID() <<
"' is on internal edge " << edge->
getID() <<
"'." << std::endl;
2399 seenJunctions.insert(junction);
2405 for (ConstMSEdgeVector::const_iterator ei = incoming.begin(); ei != incoming.end(); ++ei) {
2406 if ((*ei)->isInternal()) {
2420 remainingDownstreamRange -= link->getInternalLengthsAfter();
2421 distToConflictLane += lane->
getLength() + link->getInternalLengthsAfter();
2425 lane = *(++laneIter);
2438 while (remainingDownstreamRange > 0.) {
2439 #ifdef DEBUG_SSM_SURROUNDING 2440 std::cout <<
SIMTIME <<
" Scanning downstream for vehicle '" << veh.
getID() <<
"' on lane '" << veh.
getLane()->
getID() <<
"', position=" << pos <<
".\n" 2441 <<
"Considering edge '" << edge->
getID() <<
"' Remaining downstream range = " << remainingDownstreamRange
2442 <<
"\nbestLanes=" <<
toString(egoBestLanes) <<
"\n" 2447 assert(pos == 0 || lane == veh.
getLane());
2448 if (pos + remainingDownstreamRange < lane->getLength()) {
2450 getUpstreamVehicles(edge, pos + remainingDownstreamRange, remainingDownstreamRange, distToConflictLane, lane, foeCollector, seenJunctions);
2458 remainingDownstreamRange -= lane->getLength() - pos;
2459 distToConflictLane += lane->getLength();
2464 assert(laneIter == egoBestLanes.end() || *laneIter != 0);
2467 if (laneIter != egoBestLanes.end()) {
2469 const MSJunction* junction = lane->getEdge().getToJunction();
2472 nextNonInternalLane = *laneIter;
2473 MSLink* link = lane->getLinkTo(nextNonInternalLane);
2474 assert(link != 0 || link->
getLength() == 0.);
2478 if (lane ==
nullptr) {
2480 lane = nextNonInternalLane;
2481 edge = &(lane->getEdge());
2482 if (seenJunctions.count(junction) == 0) {
2483 seenJunctions.insert(junction);
2490 if (seenJunctions.count(junction) == 0) {
2493 seenJunctions.insert(junction);
2496 for (ConstMSEdgeVector::const_iterator ei = incoming.begin(); ei != incoming.end(); ++ei) {
2500 getUpstreamVehicles(*ei, (*ei)->getLength(), range, distToConflictLane, lane, foeCollector, seenJunctions);
2504 remainingDownstreamRange -= linkLength;
2505 distToConflictLane += linkLength;
2506 #ifdef DEBUG_SSM_SURROUNDING 2507 std::cout <<
" Downstream Scan for vehicle '" << veh.
getID() <<
"' proceeded over junction '" << junction->
getID()
2508 <<
"',\n linkLength=" << linkLength <<
", remainingDownstreamRange=" << remainingDownstreamRange
2513 lane = nextNonInternalLane;
2514 edge = &(lane->getEdge());
2516 #ifdef DEBUG_SSM_SURROUNDING 2517 std::cout <<
" Downstream Scan for vehicle '" << veh.
getID() <<
"' stops at junction '" << junction->
getID()
2518 <<
"', which has already been scanned." 2530 foeCollector.erase(&veh);
2535 #ifdef DEBUG_SSM_SURROUNDING 2536 std::cout <<
SIMTIME <<
" getUpstreamVehicles() for edge '" << edge->
getID() <<
"'" 2537 <<
" pos = " << pos <<
" range = " << range
2538 <<
"\nFound vehicles:" 2545 const std::vector<MSLane*>& lanes = edge->
getLanes();
2547 for (std::vector<MSLane*>::const_iterator li = lanes.begin(); li != lanes.end(); ++li) {
2550 for (MSLane::VehCont::const_iterator vi = vehicles.begin(); vi != vehicles.end(); ++vi) {
2552 if (foeCollector.find(veh) != foeCollector.end()) {
2558 std::cout << veh->
getID() <<
"\n";
2563 foeCollector[veh] = c;
2570 std::cout << std::endl;
2586 if (seenJunctions.count(junction) == 0) {
2594 seenJunctions.insert(junction);
2598 for (ConstMSEdgeVector::const_iterator ei = incoming.begin(); ei != incoming.end(); ++ei) {
2599 if ((*ei)->isInternal()) {
2602 const MSEdge* inEdge = *ei;
2603 assert(inEdge != 0);
2605 if (distOnJunction >= range) {
2609 getUpstreamVehicles(inEdge, inEdge->
getLength(), range - distOnJunction, egoDistToConflictLane, egoConflictLane, foeCollector, seenJunctions);
2612 #ifdef DEBUG_SSM_SURROUNDING 2613 std::cout <<
" Downstream Scan for stops at junction '" << junction->
getID()
2614 <<
"', which has already been scanned." 2622 #ifdef DEBUG_SSM_SURROUNDING 2623 std::cout <<
SIMTIME <<
" getVehiclesOnJunction() for junction '" << junction->
getID() <<
"'" 2624 <<
"\nFound vehicles:" 2629 for (std::vector<MSLane*>::const_iterator li = lanes.begin(); li != lanes.end(); ++li) {
2635 for (MSLane::VehCont::const_iterator vi = vehicles.begin(); vi != vehicles.end(); ++vi) {
2639 foeCollector[*vi] = c;
2640 #ifdef DEBUG_SSM_SURROUNDING 2641 for (MSLane::VehCont::const_iterator vi = vehicles.begin(); vi != vehicles.end(); ++vi) {
2642 std::cout << (*vi)->getID() <<
"\n";
2658 for (MSLane::VehCont::const_iterator vi = vehicles2.begin(); vi != vehicles2.end(); ++vi) {
2662 foeCollector[*vi] = c;
2663 #ifdef DEBUG_SSM_SURROUNDING 2664 for (MSLane::VehCont::const_iterator vi = vehicles2.begin(); vi != vehicles2.end(); ++vi) {
2665 std::cout << (*vi)->getID() <<
"\n";
2673 #ifdef DEBUG_SSM_SURROUNDING 2674 std::cout << std::endl;
2693 std::string file = deviceID +
".xml";
2707 file = oc.
getString(
"device.ssm.file") ==
"" ? file : oc.
getString(
"device.ssm.file");
2709 std::cout <<
"vehicle '" << v.
getID() <<
"' does not supply vehicle parameter 'device.ssm.file'. Using default of '" << file <<
"'\n";
2719 bool useGeo =
false;
2733 useGeo = oc.
getBool(
"device.ssm.geo");
2735 std::cout <<
"vehicle '" << v.
getID() <<
"' does not supply vehicle parameter 'device.ssm.geo'. Using default of '" <<
toString(useGeo) <<
"'\n";
2760 range = oc.
getFloat(
"device.ssm.range");
2762 std::cout <<
"vehicle '" << v.
getID() <<
"' does not supply vehicle parameter 'device.ssm.range'. Using default of '" << range <<
"'\n";
2787 extraTime = oc.
getFloat(
"device.ssm.extratime");
2789 std::cout <<
"vehicle '" << v.
getID() <<
"' does not supply vehicle parameter 'device.ssm.extratime'. Using default of '" << extraTime <<
"'\n";
2793 if (extraTime < 0.) {
2795 WRITE_WARNING(
"Negative (or no) value encountered for vehicle parameter 'device.ssm.extratime' in vehicle '" + v.
getID() +
"' using default value " +
toString(extraTime) +
" instead");
2804 bool trajectories =
false;
2818 trajectories = oc.
getBool(
"device.ssm.trajectories");
2820 std::cout <<
"vehicle '" << v.
getID() <<
"' does not supply vehicle parameter 'device.ssm.trajectories'. Using default of '" <<
toString(trajectories) <<
"'\n";
2824 return trajectories;
2833 std::string measures_str =
"";
2847 measures_str = oc.
getString(
"device.ssm.measures");
2849 std::cout <<
"vehicle '" << v.
getID() <<
"' does not supply vehicle parameter 'device.ssm.measures'. Using default of '" << measures_str <<
"'\n";
2855 if (measures_str ==
"") {
2856 WRITE_WARNING(
"No measures specified for ssm device of vehicle '" + v.
getID() +
"'. Registering all available SSMs.");
2860 std::vector<std::string> available = st.
getVector();
2862 std::vector<std::string> measures = st.
getVector();
2863 for (std::vector<std::string>::const_iterator i = measures.begin(); i != measures.end(); ++i) {
2864 if (std::find(available.begin(), available.end(), *i) == available.end()) {
2866 WRITE_ERROR(
"SSM identifier '" + *i +
"' is not supported. Aborting construction of SSM device '" + deviceID +
"'.");
2872 std::string thresholds_str =
"";
2886 thresholds_str = oc.
getString(
"device.ssm.thresholds");
2888 std::cout <<
"vehicle '" << v.
getID() <<
"' does not supply vehicle parameter 'device.ssm.thresholds'. Using default of '" << thresholds_str <<
"'\n";
2895 if (thresholds_str !=
"") {
2897 while (count < (
int)measures.size() && st.
hasNext()) {
2899 thresholds.insert(std::make_pair(measures[count], thresh));
2902 if (thresholds.size() < measures.size() || st.
hasNext()) {
2903 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.");
2908 for (std::vector<std::string>::const_iterator i = measures.begin(); i != measures.end(); ++i) {
2911 }
else if (*i ==
"DRAC") {
2913 }
else if (*i ==
"PET") {
2915 }
else if (*i ==
"BR") {
2917 }
else if (*i ==
"SGAP") {
2919 }
else if (*i ==
"TGAP") {
2922 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...
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.
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.
SUMOVehicle & myHolder
The vehicle that stores the device.
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.
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...
#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...
static bool toBool(const std::string &sData)
converts a string into the bool value described by it by calling the char-type converter ...
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)
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
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...
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter ...
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.
static int issuedParameterWarnFlags
bitset storing info whether warning has already been issued about unset parameter (warn only once!) ...
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
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.
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...
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.
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
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.
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.
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)
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.
Abstract in-vehicle device.
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
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)
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
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.
static void buildVehicleDevices(SUMOVehicle &v, std::vector< MSVehicleDevice *> &into)
Build devices for the given vehicle, if needed.
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