63 #define INVALID std::numeric_limits<double>::max() 66 #define DEFAULT_RANGE 50.0 72 #define AVAILABLE_SSMS "TTC DRAC PET" 73 #define DEFAULT_THRESHOLD_TTC 3. // in [s.], events get logged if 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]) 74 #define DEFAULT_THRESHOLD_DRAC 3. // in [m/s^2], events get logged if 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]) 75 #define DEFAULT_THRESHOLD_PET 2. // in seconds, events get logged if 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*>&
176 for (std::set<MSDevice*>::iterator ii =
instances->begin(); ii !=
instances->end(); ++ii) {
195 oc.
addDescription(
"device.ssm.measures",
"SSM Device",
"Specifies which measures will be logged (as a space seperated sequence of IDs in ('TTC', 'DRAC', 'PET')).");
197 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.");
199 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).");
201 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.");
203 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.");
205 oc.
addDescription(
"device.ssm.geo",
"SSM Device",
"Whether to use coordinates of the original reference system in output (default is false).");
212 WRITE_WARNING(
"SSM Device for vehicle '" + v.
getID() +
"' will not be built. (SSMs not supported in MESO)");
216 std::string deviceID =
"ssm_" + v.
getID();
221 std::map<std::string, double> thresholds;
244 into.push_back(device);
252 egoID(_ego->
getID()),
253 foeID(_foe->
getID()),
257 remainingExtraTime(extraTime),
265 closingRequested(false) {
267 std::cout <<
"\n" <<
SIMTIME <<
" Constructing encounter of '" 274 std::cout <<
"\n" <<
SIMTIME <<
" Destroying encounter of '" 275 <<
egoID <<
"' and '" <<
foeID <<
"' (begin was " <<
begin <<
")" << std::endl;
282 Position conflictPoint,
double egoDistToConflict,
double foeDistToConflict,
double ttc,
double drac, std::pair<double, double> pet) {
284 std::cout << time <<
" Adding data point for encounter of '" <<
egoID <<
"' and '" <<
foeID <<
"':\n" 285 <<
"type=" << type <<
", egoDistToConflict=" << (egoDistToConflict ==
INVALID ?
"NA" :
toString(egoDistToConflict))
286 <<
", foeDistToConflict=" << (foeDistToConflict ==
INVALID ?
"NA" :
toString(foeDistToConflict))
350 conflictPoint(
Position::invalidPosition()),
355 egoEstimatedConflictEntryTime(
INVALID),
356 foeEstimatedConflictEntryTime(
INVALID),
357 egoEstimatedConflictExitTime(
INVALID),
358 foeEstimatedConflictExitTime(
INVALID),
359 egoConflictAreaLength(
INVALID),
360 foeConflictAreaLength(
INVALID),
361 egoLeftConflict(false),
362 foeLeftConflict(false),
385 std::cout <<
"\n" <<
SIMTIME <<
" Device '" <<
getID() <<
"' update()\n" 395 if (foes.size() > 0) {
396 std::cout <<
"Scanned surroundings: Found potential foes:\n";
397 for (FoeInfoMap::const_iterator i = foes.begin(); i != foes.end(); ++i) {
398 std::cout << i->first->getID() <<
" ";
400 std::cout << std::endl;
402 std::cout <<
"Scanned surroundings: No potential conflict could be identified." << std::endl;
418 std::cout <<
"\n" <<
SIMTIME <<
" Device '" <<
getID() <<
"' createEncounters()" << std::endl;
419 std::cout <<
"New foes:\n";
420 for (FoeInfoMap::const_iterator vi = foes.begin(); vi != foes.end(); ++vi) {
421 std::cout << vi->first->getID() <<
"\n";
423 std::cout << std::endl;
426 for (FoeInfoMap::const_iterator foe = foes.begin(); foe != foes.end(); ++foe) {
427 std::pair<MSLane*, MSLane*> conflictLanes;
434 assert(myOldestActiveEncounterBegin <= e->begin);
450 std::cout <<
"\n" <<
SIMTIME <<
" Device '" <<
getID() <<
"' processEncounters()" << std::endl;
451 std::cout <<
"Currently present foes:\n";
452 for (FoeInfoMap::const_iterator vi = foes.begin(); vi != foes.end(); ++vi) {
453 std::cout << vi->first->getID() <<
"\n";
455 std::cout << std::endl;
471 if (foes.find(e->
foe) != foes.end()) {
487 double eBegin = e->
begin;
511 std::cout <<
SIMTIME <<
" qualifiesAsConflict() for encounter of vehicles '" 542 std::cout <<
SIMTIME <<
" closeEncounter() of vehicles '" 544 <<
"' (was ranked as " << (wasConflict ?
"conflict" :
"non-conflict") <<
")" << std::endl;
554 std::cout <<
SIMTIME <<
" updateEncounter() of vehicles '" 574 std::cout <<
SIMTIME <<
" Encounter of vehicles '" 576 <<
"' does not imply any conflict." << std::endl;
629 std::cout <<
SIMTIME <<
" determineConflictPoint()" << std::endl;
654 std::cout <<
"No conflict point associated with encounter type " << type << std::endl;
660 std::cout <<
" Conflict at " << eInfo.
conflictPoint << std::endl;
673 std::cout <<
SIMTIME <<
" estimateConflictTimes() for ego '" << e->
egoID <<
"' and foe '" << e->
foeID <<
"'\n" 674 <<
" encounter type: " << eInfo.
type <<
"\n" 687 std::cout <<
" encouter type " << type <<
" -> no entry/exit times to be calculated." 728 std::cout <<
" Potential conflict type: " << (type ==
ENCOUNTER_TYPE_CROSSING ?
"CROSSING" :
"MERGING") <<
"\n" 758 std::stringstream ss;
759 ss <<
"SSM device of vehicle '" << e->
egoID <<
"' detected collision with vehicle '" << e->
foeID <<
"'";
764 std::cout <<
" -> ego is estimated leader at conflict entry." 772 std::cout <<
" -> foe is estimated leader at conflict entry." 787 std::cout <<
SIMTIME <<
" computeSSMs() for vehicles '" 817 std::stringstream ss;
818 ss <<
"'" << type <<
"'";
819 WRITE_WARNING(
"Unknown or undetermined encounter type at computeSSMs(): " + ss.str());
823 std::cout <<
"computeSSMs() for encounter of vehicles '" << e->
egoID <<
"' and '" << e->
foeID <<
"':\n" 835 if (e->
size() == 0) {
839 std::pair<double, double>&
pet = eInfo.
pet;
842 std::cout <<
SIMTIME <<
" determinePET() for encounter of vehicles '" << e->
egoID <<
"' and '" << e->
foeID <<
"'" 856 std::cout <<
"PET for crossing encounter already calculated as " << e->
PET.second
899 std::cout <<
"Unexpected branch in determinePET: Both passed conflict area in the same step." 915 std::cout <<
"Calculated PET = " << pet.second <<
" (at t=" << pet.first <<
")" 921 std::cout <<
"PET unappropriate for merging and pre-crossing situations. No calculation performed." 937 std::cout <<
SIMTIME <<
" determineTTCandDRAC() for encounter of vehicles '" << e->
egoID <<
"' and '" << e->
foeID <<
"' (type = " << eInfo.
type <<
")" 972 std::cout <<
" Conflict times with constant speed extrapolation for merging situation:\n " 973 <<
" egoEntryTime=" << (egoEntryTime ==
INVALID ?
"NA" :
toString(egoEntryTime))
974 <<
", egoExitTime=" << (egoExitTime ==
INVALID ?
"NA" :
toString(egoExitTime))
975 <<
", foeEntryTime=" << (foeEntryTime ==
INVALID ?
"NA" :
toString(foeEntryTime))
976 <<
", foeExitTime=" << (foeExitTime ==
INVALID ?
"NA" :
toString(foeExitTime))
986 std::cout <<
" No TTC and DRAC computed as one vehicle is stopped." << std::endl;
990 double leaderEntryTime =
MIN2(egoEntryTime, foeEntryTime);
991 double followerEntryTime =
MAX2(egoEntryTime, foeEntryTime);
992 double leaderExitTime = leaderEntryTime == egoEntryTime ? egoExitTime : foeExitTime;
999 if (leaderExitTime >= followerEntryTime) {
1002 ttc =
computeTTC(followerConflictDist, followerSpeed, 0.);
1007 drac =
computeDRAC(followerConflictDist, followerSpeed, 0.);
1012 std::cout <<
" Extrapolation predicts collision *at* merge point with TTC=" << ttc
1013 <<
", drac=" << drac << std::endl;
1020 double gapAfterMerge = followerConflictDist - leaderExitTime * followerSpeed;
1021 assert(gapAfterMerge >= 0);
1024 double ttcAfterMerge =
computeTTC(gapAfterMerge, followerSpeed, leaderSpeed);
1025 ttc = ttcAfterMerge ==
INVALID ?
INVALID : leaderExitTime + ttcAfterMerge;
1029 double g0 = followerConflictDist - leaderConflictDist - leaderLength;
1032 assert(leaderSpeed - followerSpeed > 0);
1037 drac =
computeDRAC(g0, followerSpeed, leaderSpeed);
1044 std::cout <<
" Extrapolation does not predict any collision." << std::endl;
1046 std::cout <<
" Extrapolation predicts collision *after* merge point with TTC=" 1048 <<
", drac=" << (drac ==
INVALID ?
"NA" :
toString(drac)) << std::endl;
1086 std::stringstream ss;
1087 ss <<
"'" << type <<
"'";
1088 WRITE_WARNING(
"Underspecified or unknown encounter type in MSDevice_SSM::determineTTCandDRAC(): " + ss.str());
1105 std::cout <<
"computeTTC() with gap=" << gap <<
", followerSpeed=" << followerSpeed <<
", leaderSpeed=" << leaderSpeed
1111 double dv = followerSpeed - leaderSpeed;
1122 #ifdef DEBUG_SSM_DRAC 1123 std::cout <<
"computeDRAC() with gap=" << gap <<
", followerSpeed=" << followerSpeed <<
", leaderSpeed=" << leaderSpeed
1129 double dv = followerSpeed - leaderSpeed;
1133 assert(followerSpeed > 0.);
1134 return 0.5 * dv * dv / gap;
1150 #ifdef DEBUG_SSM_DRAC 1151 std::cout <<
SIMTIME <<
"computeDRAC() with" 1152 <<
"\ndEntry1=" << dEntry1 <<
", dEntry2=" << dEntry2
1153 <<
", dExit1=" << dExit1 <<
", dExit2=" << dExit2
1154 <<
",\nv1=" << v1 <<
", v2=" << v2
1159 if (dExit1 <= 0. || dExit2 <= 0.) {
1161 #ifdef DEBUG_SSM_DRAC 1162 std::cout <<
"One already left conflict area -> drac == 0." << std::endl;
1166 if (dEntry1 <= 0. && dEntry2 <= 0.) {
1168 #ifdef DEBUG_SSM_DRAC 1169 std::cout <<
"Both entered conflict area but neither left. -> collision!" << std::endl;
1174 double drac = std::numeric_limits<double>::max();
1177 #ifdef DEBUG_SSM_DRAC 1178 std::cout <<
"Ego could break..." << std::endl;
1182 drac =
MIN2(drac, 2 * (v1 - dEntry1 / tExit2) / tExit2);
1183 #ifdef DEBUG_SSM_DRAC 1184 std::cout <<
" Foe expected to leave in " << tExit2 <<
"-> Ego needs drac=" << drac << std::endl;
1191 #ifdef DEBUG_SSM_DRAC 1192 std::cout <<
" Foe is expected stop on conflict area -> Ego needs drac=" << drac << std::endl;
1196 #ifdef DEBUG_SSM_DRAC 1197 std::cout <<
" Foe is expected stop before conflict area -> no drac computation for ego (will be done for foe if applicable)" << std::endl;
1205 #ifdef DEBUG_SSM_DRAC 1206 std::cout <<
"Foe could break..." << std::endl;
1210 #ifdef DEBUG_SSM_DRAC 1211 std::cout <<
" Ego expected to leave in " << tExit1 <<
"-> Foe needs drac=" << (2 * (v2 - dEntry2 / tExit1) / tExit1) << std::endl;
1213 drac =
MIN2(drac, 2 * (v2 - dEntry2 / tExit1) / tExit1);
1218 #ifdef DEBUG_SSM_DRAC 1219 std::cout <<
" Ego is expected stop on conflict area -> Foe needs drac=" <<
computeDRAC(dEntry2, v2, 0) << std::endl;
1224 #ifdef DEBUG_SSM_DRAC 1225 std::cout <<
" Ego is expected stop before conflict area -> no drac computation for foe (done for ego if applicable)" << std::endl;
1240 std::cout <<
SIMTIME <<
" checkConflictEntryAndExit() for encounter of vehicles '" << e->
egoID <<
"' and '" << e->
foeID <<
"'" << std::endl;
1253 prevEgoConflictEntryDist =
MAX2(prevEgoConflictEntryDist, 0.);
1254 prevFoeConflictEntryDist =
MAX2(prevFoeConflictEntryDist, 0.);
1255 prevEgoConflictExitDist =
MAX2(prevEgoConflictExitDist, 0.);
1256 prevFoeConflictExitDist =
MAX2(prevFoeConflictExitDist, 0.);
1326 std::cout <<
SIMTIME <<
" updatePassedEncounter() for vehicles '" 1335 std::cout <<
" Foe is out of range. Counting down extra time." 1352 std::cout <<
" This encounter wasn't classified as a potential conflict lately." << std::endl;
1360 std::cout <<
" Closing encounter." << std::endl;
1370 std::cout <<
" Encounter was previously classified as a follow/lead situation." << std::endl;
1379 std::cout <<
" Encounter was previously classified as a merging situation." << std::endl;
1394 std::cout <<
" Encounter was previously classified as a crossing situation of type " << lastPotentialConflictType <<
"." << std::endl;
1425 if ((!egoEnteredConflict) && !foeEnteredConflict) {
1429 eInfo.
type = lastPotentialConflictType;
1430 }
else if (egoEnteredConflict && !foeEnteredConflict) {
1432 }
else if ((!egoEnteredConflict) && foeEnteredConflict) {
1438 if ((!egoLeftConflict) && !foeLeftConflict) {
1442 }
else if (egoLeftConflict && !foeLeftConflict) {
1446 }
else if ((!egoLeftConflict) && foeLeftConflict) {
1462 std::cout <<
" Updated classification: " << eInfo.
type << std::endl;
1471 std::cout <<
"classifyEncounter() called." << std::endl;
1493 std::cout <<
" Ongoing crossing conflict will be traced by passedEncounter()." << std::endl;
1508 double foeDistToConflictLane;
1512 std::cout <<
"egoConflictLane: '" << (egoConflictLane == 0 ?
"NULL" : egoConflictLane->
getID()) <<
"'\n" 1513 <<
"foeConflictLane: '" << (foeConflictLane == 0 ?
"NULL" : foeConflictLane->
getID()) <<
"'" 1514 <<
"\nEgo's distance to conflict lane: " << egoDistToConflictLane
1515 <<
"\nFoe's distance to conflict lane: " << foeDistToConflictLane
1530 if (foeConflictLane == 0) {
1534 std::cout <<
"-> Encounter type: No conflict." << std::endl;
1536 }
else if (!egoConflictLane->isInternal()) {
1538 if (egoConflictLane == egoLane) {
1540 if (foeLane == egoLane) {
1550 std::cout <<
"-> Encounter type: Lead/follow-situation on non-internal lane '" << egoLane->
getID() <<
"'" << std::endl;
1557 std::cout <<
"-> Encounter type: " << type << std::endl;
1561 assert(egoDistToConflictLane <= 0);
1563 if (foeConflictLane == egoLane) {
1568 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' leads foe '" 1569 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'" 1577 std::cout <<
"-> Encounter type: " << type << std::endl;
1586 assert(&(foeLane->
getEdge()) == &(egoConflictLane->getEdge()));
1587 assert(foeDistToConflictLane <= 0);
1588 if (foeLane == egoConflictLane) {
1592 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' follows foe '" 1593 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'" 1601 std::cout <<
"-> Encounter type: " << type << std::endl;
1609 MSLink* egoEntryLink = egoConflictLane->getEntryLink();
1611 if (&(egoEntryLink->getViaLane()->getEdge()) == &(foeEntryLink->
getViaLane()->
getEdge())) {
1612 if (egoEntryLink != foeEntryLink) {
1616 std::cout <<
"-> Encounter type: " << type << std::endl;
1620 if (egoLane == egoConflictLane && foeLane != foeConflictLane) {
1625 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' leads foe '" 1626 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'" 1630 }
else if (egoLane != egoConflictLane && foeLane == foeConflictLane) {
1635 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' follows foe '" 1636 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'" 1644 assert(egoLane == egoConflictLane);
1645 assert(foeLane == foeConflictLane);
1646 if (egoLane == foeLane) {
1652 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' leads foe '" 1653 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'" 1661 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' follows foe '" 1662 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'" 1670 std::cout <<
" Lead/follow situation on consecutive internal lanes." << std::endl;
1672 MSLane* lane = egoEntryLink->getViaLane();
1674 #pragma warning(push) 1675 #pragma warning(disable: 4127) // do not warn about constant conditional expression 1679 #pragma warning(pop) 1683 if (egoLane == lane) {
1688 while (lane != foeLane) {
1694 egoConflictLane = lane;
1696 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' follows foe '" 1697 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'" 1702 }
else if (foeLane == lane) {
1707 while (lane != egoLane) {
1713 foeConflictLane = lane;
1715 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' leads foe '" 1716 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'" 1727 std::cout <<
"-> Encounter type: Lead/follow-situation on connection from '" << egoEntryLink->getLaneBefore()->getID()
1728 <<
"' to '" << egoEntryLink->getLane()->getID() <<
"'" << std::endl;
1735 const std::vector<MSLink*>& egoFoeLinks = egoEntryLink->getFoeLinks();
1736 const std::vector<MSLink*>& foeFoeLinks = foeEntryLink->
getFoeLinks();
1738 bool crossOrMerge = (find(egoFoeLinks.begin(), egoFoeLinks.end(), foeEntryLink) != egoFoeLinks.end()
1739 || find(foeFoeLinks.begin(), foeFoeLinks.end(), egoEntryLink) != foeFoeLinks.end());
1740 if (!crossOrMerge) {
1750 std::cout <<
"-> Encounter type: No conflict." << std::endl;
1753 }
else if (&(foeEntryLink->
getLane()->
getEdge()) == &(egoEntryLink->getLane()->getEdge())) {
1754 if (foeEntryLink->
getLane() == egoEntryLink->getLane()) {
1759 std::cout <<
"-> Encounter type: Merging situation of ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' and foe '" 1760 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'" 1768 std::cout <<
"-> Encounter type: No conflict: " << type << std::endl;
1774 assert(egoConflictLane->isInternal());
1775 assert(foeConflictLane->
getEdge().
getToJunction() == egoConflictLane->getEdge().getToJunction());
1782 egoConflictLane = egoConflictLane->getFirstInternalInConnection(offset);
1783 egoDistToConflictLane -= offset;
1785 foeDistToConflictLane -= offset;
1789 double egoDistToConflictFromJunctionEntry =
INVALID;
1790 double foeInternalLaneLengthsBeforeCrossing = 0.;
1791 while (foeConflictLane != 0 && foeConflictLane->
isInternal()) {
1792 egoDistToConflictFromJunctionEntry = egoEntryLink->getLengthsBeforeCrossing(foeConflictLane);
1793 if (egoDistToConflictFromJunctionEntry !=
INVALID) {
1798 foeInternalLaneLengthsBeforeCrossing += foeConflictLane->
getLength();
1801 assert(foeConflictLane != 0 && foeConflictLane->
isInternal());
1803 assert(egoDistToConflictFromJunctionEntry !=
INVALID);
1806 double foeDistToConflictFromJunctionEntry =
INVALID;
1807 double egoInternalLaneLengthsBeforeCrossing = 0.;
1808 foeDistToConflictFromJunctionEntry =
INVALID;
1809 while (egoConflictLane != 0 && egoConflictLane->isInternal()) {
1811 if (foeDistToConflictFromJunctionEntry !=
INVALID) {
1816 egoInternalLaneLengthsBeforeCrossing += egoConflictLane->getLength();
1818 egoConflictLane = egoConflictLane->getCanonicalSuccessorLane();
1819 assert(egoConflictLane != 0 && egoConflictLane->isInternal());
1821 assert(foeDistToConflictFromJunctionEntry !=
INVALID);
1833 Position egoEntryPos = egoEntryLink->getViaLane()->getShape().front();
1834 Position egoExitPos = egoEntryLink->getCorrespondingExitLink()->getInternalLaneBefore()->getShape().back();
1844 assert(angle <= 2 *
M_PI);
1848 assert(angle >= -
M_PI);
1849 assert(angle <=
M_PI);
1851 double crossingOrientation = (angle < 0) - (angle > 0);
1864 std::cout <<
" Determined exact conflict distances for crossing conflict." 1865 <<
"\n crossingOrientation=" << crossingOrientation
1868 <<
", relativeAngle=" << angle
1869 <<
" (foe from " << (crossingOrientation > 0 ?
"right)" :
"left)")
1870 <<
"\n resulting offset for conflict entry distance:" 1873 <<
"\n resulting entry distances:" 1888 std::cout <<
"real egoConflictLane: '" << (egoConflictLane == 0 ?
"NULL" : egoConflictLane->getID()) <<
"'\n" 1889 <<
"real foeConflictLane: '" << (foeConflictLane == 0 ?
"NULL" : foeConflictLane->
getID()) <<
"'\n" 1890 <<
"-> Encounter type: Crossing situation of ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' and foe '" 1891 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'" 1906 std::cout <<
SIMTIME <<
" findFoeConflictLane() for foe '" 1908 <<
"' (with egoConflictLane=" << (egoConflictLane == 0 ?
"NULL" : egoConflictLane->
getID())
1915 assert(foeLane->
isInternal() || *laneIter == foeLane);
1921 if (conflictJunction != 0) {
1922 std::cout <<
"Potential conflict on junction '" << conflictJunction->
getID()
1934 if (*laneIter == 0) {
1935 while (foeLane != 0 && foeLane->
isInternal()) {
1936 distToConflictLane += foeLane->
getLength();
1937 foeLane = foeLane->
getLinkCont()[0]->getViaLane();
1940 assert(laneIter == foeBestLanesEnd || *laneIter != 0);
1944 while (laneIter != foeBestLanesEnd && distToConflictLane <=
myRange) {
1946 assert(*laneIter == foeLane || foeLane == 0);
1947 foeLane = *laneIter;
1951 std::cout <<
"Found conflict lane for foe: '" << foeLane->
getID() <<
"'" << std::endl;
1957 distToConflictLane += foeLane->
getLength();
1961 if (laneIter == foeBestLanesEnd) {
1964 MSLane* nextNonInternalLane = *laneIter;
1971 std::cout <<
"Found conflict lane for foe: '" << foeLane->
getID() <<
"'" << std::endl;
1978 foeLane = nextNonInternalLane;
1987 std::cout <<
"\n" <<
SIMTIME <<
" Device '" <<
getID() <<
"' flushConflicts()" << std::endl;
2016 std::cout <<
SIMTIME <<
" writeOutConflict() of vehicles '" 2097 std::string res =
"";
2098 for (std::vector<double>::const_iterator i = v.begin(); i != v.end(); ++i) {
2099 res += (i == v.begin() ?
"" : sep) + (*i == NA ?
"NA" :
toString(*i));
2106 std::string res =
"";
2107 for (std::vector<double>::const_iterator i = v.begin(); i != v.end(); ++i) {
2108 res += (i == v.begin() ?
"" : sep) + (find(NAs.begin(), NAs.end(), *i) != NAs.end() ?
"NA" :
toString(*i));
2118 bool trajectories,
double range,
double extraTime,
bool useGeoCoords) :
2149 std::vector<std::string> measures;
2150 std::vector<double> threshVals;
2152 measures.push_back(i->first);
2153 threshVals.push_back(i->second);
2155 std::cout <<
"Initialized ssm device '" <<
id <<
"' with " 2175 #ifdef DEBUG_SSM_NOTIFICATIONS 2176 std::cout <<
"device '" <<
getID() <<
"' notifyEnter: reason=" << reason <<
" currentEdge=" << veh.
getLane()->
getEdge().
getID() <<
"\n";
2187 #ifdef DEBUG_SSM_NOTIFICATIONS 2188 std::cout <<
"device '" <<
getID() <<
"' notifyLeave: reason=" << reason <<
" currentEdge=" << veh.
getLane()->
getEdge().
getID() <<
"\n";
2198 double ,
double newSpeed) {
2199 #ifdef DEBUG_SSM_NOTIFICATIONS 2200 std::cout <<
"device '" <<
getID() <<
"' notifyMove: newSpeed=" << newSpeed <<
"\n";
2210 #ifdef DEBUG_SSM_SURROUNDING 2211 std::cout <<
SIMTIME <<
" Looking for surrounding vehicles for ego vehicle '" << veh.
getID()
2230 assert(*edgeIter != 0);
2234 std::vector<MSLane*>::const_iterator laneIter = egoBestLanes.begin();
2238 assert(lane->
isInternal() || lane == *laneIter);
2241 const MSLane* nextNonInternalLane = 0;
2249 double remainingDownstreamRange = range;
2251 double distToConflictLane = -pos;
2253 std::set<const MSJunction*> seenJunctions;
2261 #ifdef DEBUG_SSM_SURROUNDING 2262 std::cout <<
SIMTIME <<
" Vehicle '" << veh.
getID() <<
"' is on internal edge " << edge->
getID() <<
"'.\n" 2263 <<
"Previous edge of its route: '" << (*edgeIter)->getID() <<
"'" << std::endl;
2271 seenJunctions.insert(junction);
2277 for (ConstMSEdgeVector::const_iterator ei = incoming.begin(); ei != incoming.end(); ++ei) {
2278 if ((*ei)->isInternal()) {
2292 remainingDownstreamRange -= link->getInternalLengthsAfter();
2293 distToConflictLane += lane->
getLength() + link->getInternalLengthsAfter();
2297 lane = *(++laneIter);
2310 while (remainingDownstreamRange > 0.) {
2311 #ifdef DEBUG_SSM_SURROUNDING 2312 std::cout <<
SIMTIME <<
" Scanning downstream for vehicle '" << veh.
getID() <<
"' on lane '" << veh.
getLane()->
getID() <<
"', position=" << pos <<
".\n" 2313 <<
"Considering edge '" << edge->
getID() <<
"' Remaining downstream range = " << remainingDownstreamRange
2314 <<
"\nbestLanes=" <<
toString(egoBestLanes) <<
"\n" 2319 assert(pos == 0 || lane == veh.
getLane());
2320 if (pos + remainingDownstreamRange < lane->getLength()) {
2322 getUpstreamVehicles(edge, pos + remainingDownstreamRange, remainingDownstreamRange, distToConflictLane, lane, foeCollector, seenJunctions);
2330 remainingDownstreamRange -= lane->getLength() - pos;
2331 distToConflictLane += lane->getLength();
2336 assert(laneIter == egoBestLanes.end() || *laneIter != 0);
2339 if (laneIter != egoBestLanes.end()) {
2341 const MSJunction* junction = lane->getEdge().getToJunction();
2344 nextNonInternalLane = *laneIter;
2345 MSLink* link = lane->getLinkTo(nextNonInternalLane);
2351 if (seenJunctions.count(junction) == 0) {
2354 seenJunctions.insert(junction);
2357 for (ConstMSEdgeVector::const_iterator ei = incoming.begin(); ei != incoming.end(); ++ei) {
2361 getUpstreamVehicles(*ei, (*ei)->getLength(), range, distToConflictLane, lane, foeCollector, seenJunctions);
2365 remainingDownstreamRange -= linkLength;
2366 distToConflictLane += linkLength;
2367 #ifdef DEBUG_SSM_SURROUNDING 2368 std::cout <<
" Downstream Scan for vehicle '" << veh.
getID() <<
"' proceeded over junction '" << junction->
getID()
2369 <<
"',\n linkLength=" << linkLength <<
", remainingDownstreamRange=" << remainingDownstreamRange
2374 lane = nextNonInternalLane;
2375 edge = &(lane->getEdge());
2377 #ifdef DEBUG_SSM_SURROUNDING 2378 std::cout <<
" Downstream Scan for vehicle '" << veh.
getID() <<
"' stops at junction '" << junction->
getID()
2379 <<
"', which has already been scanned." 2391 foeCollector.erase(&veh);
2396 #ifdef DEBUG_SSM_SURROUNDING 2397 std::cout <<
SIMTIME <<
" getUpstreamVehicles() for edge '" << edge->
getID() <<
"'" 2398 <<
" pos = " << pos <<
" range = " << range
2399 <<
"\nFound vehicles:" 2406 const std::vector<MSLane*>& lanes = edge->
getLanes();
2408 for (std::vector<MSLane*>::const_iterator li = lanes.begin(); li != lanes.end(); ++li) {
2411 for (MSLane::VehCont::const_iterator vi = vehicles.begin(); vi != vehicles.end(); ++vi) {
2415 std::cout << veh->
getID() <<
"\n";
2420 foeCollector[veh] = c;
2427 std::cout << std::endl;
2443 if (seenJunctions.count(junction) == 0) {
2451 seenJunctions.insert(junction);
2455 for (ConstMSEdgeVector::const_iterator ei = incoming.begin(); ei != incoming.end(); ++ei) {
2456 if ((*ei)->isInternal()) {
2459 const MSEdge* inEdge = *ei;
2460 assert(inEdge != 0);
2462 if (distOnJunction >= range) {
2466 getUpstreamVehicles(inEdge, inEdge->
getLength(), range - distOnJunction, egoDistToConflictLane, egoConflictLane, foeCollector, seenJunctions);
2469 #ifdef DEBUG_SSM_SURROUNDING 2470 std::cout <<
" Downstream Scan for stops at junction '" << junction->
getID()
2471 <<
"', which has already been scanned." 2479 #ifdef DEBUG_SSM_SURROUNDING 2480 std::cout <<
SIMTIME <<
" getVehiclesOnJunction() for junction '" << junction->
getID() <<
"'" 2481 <<
"\nFound vehicles:" 2486 for (std::vector<MSLane*>::const_iterator li = lanes.begin(); li != lanes.end(); ++li) {
2492 for (MSLane::VehCont::const_iterator vi = vehicles.begin(); vi != vehicles.end(); ++vi) {
2496 foeCollector[*vi] = c;
2497 #ifdef DEBUG_SSM_SURROUNDING 2498 for (MSLane::VehCont::const_iterator vi = vehicles.begin(); vi != vehicles.end(); ++vi) {
2499 std::cout << (*vi)->getID() <<
"\n";
2515 for (MSLane::VehCont::const_iterator vi = vehicles2.begin(); vi != vehicles2.end(); ++vi) {
2519 foeCollector[*vi] = c;
2520 #ifdef DEBUG_SSM_SURROUNDING 2521 for (MSLane::VehCont::const_iterator vi = vehicles2.begin(); vi != vehicles2.end(); ++vi) {
2522 std::cout << (*vi)->getID() <<
"\n";
2530 #ifdef DEBUG_SSM_SURROUNDING 2531 std::cout << std::endl;
2549 std::string file = deviceID +
".xml";
2563 std::cout <<
"vehicle '" << v.
getID() <<
"' does not supply vehicle parameter 'device.ssm.file'. Using default of '" << file <<
"'\n";
2571 bool useGeo =
false;
2585 useGeo = oc.
getBool(
"device.ssm.geo");
2587 std::cout <<
"vehicle '" << v.
getID() <<
"' does not supply vehicle parameter 'device.ssm.geo'. Using default of '" << useGeo <<
"'\n";
2611 range = oc.
getFloat(
"device.ssm.range");
2613 std::cout <<
"vehicle '" << v.
getID() <<
"' does not supply vehicle parameter 'device.ssm.range'. Using default of '" << range <<
"'\n";
2637 extraTime = oc.
getFloat(
"device.ssm.extratime");
2639 std::cout <<
"vehicle '" << v.
getID() <<
"' does not supply vehicle parameter 'device.ssm.extratime'. Using default of '" << extraTime <<
"'\n";
2642 if (extraTime < 0.) {
2644 WRITE_WARNING(
"Negative (or no) value encountered for vehicle parameter 'device.ssm.extratime' in vehicle '" + v.
getID() +
"' using default value " +
toString(extraTime) +
" instead");
2653 bool trajectories =
false;
2667 trajectories = oc.
getBool(
"device.ssm.trajectories");
2669 std::cout <<
"vehicle '" << v.
getID() <<
"' does not supply vehicle parameter 'device.ssm.trajectories'. Using default of '" << trajectories <<
"'\n";
2672 return trajectories;
2681 std::string measures_str =
"";
2695 measures_str = oc.
getString(
"device.ssm.measures");
2696 std::cout <<
"vehicle '" << v.
getID() <<
"' does not supply vehicle parameter 'device.ssm.measures'. Using default of '" << measures_str <<
"'\n";
2700 if (measures_str ==
"") {
2701 WRITE_WARNING(
"No measures specified for ssm device of vehicle '" + v.
getID() +
"'. Registering all available SSMs.");
2705 std::vector<std::string> available = st.
getVector();
2707 std::vector<std::string> measures = st.
getVector();
2708 for (std::vector<std::string>::const_iterator i = measures.begin(); i != measures.end(); ++i) {
2709 if (std::find(available.begin(), available.end(), *i) == available.end()) {
2711 WRITE_ERROR(
"SSM identifier '" + *i +
"' is not supported. Aborting construction of SSM device '" + deviceID +
"'.");
2717 std::string thresholds_str =
"";
2731 thresholds_str = oc.
getString(
"device.ssm.thresholds");
2733 std::cout <<
"vehicle '" << v.
getID() <<
"' does not supply vehicle parameter 'device.ssm.thresholds'. Using default of '" << thresholds_str <<
"'\n";
2739 if (thresholds_str !=
"") {
2741 while (count < (
int)measures.size() && st.
hasNext()) {
2743 thresholds.insert(std::make_pair(measures[count], thresh));
2746 if (thresholds.size() < measures.size() || st.
hasNext()) {
2747 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.");
2752 for (std::vector<std::string>::const_iterator i = measures.begin(); i != measures.end(); ++i) {
2755 }
else if (*i ==
"DRAC") {
2757 }
else if (*i ==
"PET") {
2760 WRITE_ERROR(
"Unknown SSM identifier '" + (*i) +
"'. Aborting construction of ssm device.");
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 ...
ENCOUNTER_TYPE_MERGING_ADJACENT.
static const std::set< MSDevice * > & getInstances()
returns all currently existing SSM devices
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 ...
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...
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...
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.
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.
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)
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.
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...
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.
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()
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 equippedByDefaultAssignmentOptions(const OptionsCont &oc, const std::string &deviceName, SUMOVehicle &v)
Determines whether a vehicle should get a certain device.
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)
static std::set< MSDevice * > * instances
All currently existing SSM devices.
~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...
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
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.
An encounter is an episode involving two vehicles, which are closer to each other than some specified...
bool closeTag()
Closes the most recently opened tag.
#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