68#define DEBUG_COND(ego) (ego!=nullptr && ego->isSelected())
69#define DEBUG_COND_FIND(ego) (ego.isSelected())
70#define DEBUG_COND_ENCOUNTER(e) (e->ego != nullptr && e->ego->isSelected() && e->foe != nullptr && e->foe->isSelected())
79#define AVAILABLE_SSMS "TTC DRAC PET BR SGAP TGAP PPET MDRAC"
80#define DEFAULT_THRESHOLD_TTC 3.
81#define DEFAULT_THRESHOLD_DRAC 3.
82#define DEFAULT_THRESHOLD_MDRAC 3.4
84#define DEFAULT_THRESHOLD_PET 2.
85#define DEFAULT_THRESHOLD_PPET 2.
87#define DEFAULT_THRESHOLD_BR 0.0
88#define DEFAULT_THRESHOLD_SGAP 0.2
89#define DEFAULT_THRESHOLD_TGAP 0.5
91#define DEFAULT_EXTRA_TIME 5.
108 out <<
"NOCONFLICT_AHEAD";
114 out <<
"FOLLOWING_FOLLOWER";
117 out <<
"FOLLOWING_LEADER";
120 out <<
"ON_ADJACENT_LANES";
126 out <<
"MERGING_LEADER";
129 out <<
"MERGING_FOLLOWER";
132 out <<
"MERGING_ADJACENT";
138 out <<
"CROSSING_LEADER";
141 out <<
"CROSSING_FOLLOWER";
144 out <<
"EGO_ENTERED_CONFLICT_AREA";
147 out <<
"FOE_ENTERED_CONFLICT_AREA";
150 out <<
"BOTH_ENTERED_CONFLICT_AREA";
153 out <<
"EGO_LEFT_CONFLICT_AREA";
156 out <<
"FOE_LEFT_CONFLICT_AREA";
159 out <<
"BOTH_LEFT_CONFLICT_AREA";
162 out <<
"FOLLOWING_PASSED";
165 out <<
"MERGING_PASSED";
175 out <<
"unknown type (" << int(type) <<
")";
186std::set<MSDevice_SSM*, ComparatorNumericalIdLess>*
MSDevice_SSM::myInstances =
new std::set<MSDevice_SSM*, ComparatorNumericalIdLess>();
193 ENCOUNTER_TYPE_FOLLOWING_LEADER, ENCOUNTER_TYPE_MERGING_FOLLOWER,
194 ENCOUNTER_TYPE_CROSSING_FOLLOWER, ENCOUNTER_TYPE_FOE_ENTERED_CONFLICT_AREA,
195 ENCOUNTER_TYPE_FOE_LEFT_CONFLICT_AREA
198 ENCOUNTER_TYPE_FOLLOWING_FOLLOWER, ENCOUNTER_TYPE_MERGING_LEADER,
199 ENCOUNTER_TYPE_CROSSING_LEADER, ENCOUNTER_TYPE_EGO_ENTERED_CONFLICT_AREA,
200 ENCOUNTER_TYPE_EGO_LEFT_CONFLICT_AREA
204const std::set<MSDevice_SSM*, ComparatorNumericalIdLess>&
214 device->resetEncounters();
215 device->flushConflicts(
true);
216 device->flushGlobalMeasures();
234 oc.
addDescription(
"device.ssm.measures",
"SSM Device",
TL(
"Specifies which measures will be logged (as a space or comma-separated sequence of IDs in ('TTC', 'DRAC', 'PET', 'PPET','MDRAC'))"));
236 oc.
addDescription(
"device.ssm.thresholds",
"SSM Device",
TL(
"Specifies space or comma-separated thresholds corresponding to the specified measures (see documentation and watch the order!). Only events exceeding the thresholds will be logged."));
238 oc.
addDescription(
"device.ssm.trajectories",
"SSM Device",
TL(
"Specifies whether trajectories will be logged (if false, only the extremal values and times are reported)."));
240 oc.
addDescription(
"device.ssm.range",
"SSM Device",
TL(
"Specifies the detection range in meters. For vehicles below this distance from the equipped vehicle, SSM values are traced."));
242 oc.
addDescription(
"device.ssm.extratime",
"SSM Device",
TL(
"Specifies the time in seconds to be logged after a conflict is over. Required >0 if PET is to be calculated for crossing conflicts."));
244 oc.
addDescription(
"device.ssm.mdrac.prt",
"SSM Device",
TL(
"Specifies the perception reaction time for MDRAC computation."));
246 oc.
addDescription(
"device.ssm.file",
"SSM Device",
TL(
"Give a global default filename for the SSM output"));
248 oc.
addDescription(
"device.ssm.geo",
"SSM Device",
TL(
"Whether to use coordinates of the original reference system in output"));
250 oc.
addDescription(
"device.ssm.write-positions",
"SSM Device",
TL(
"Whether to write positions (coordinates) for each timestep"));
252 oc.
addDescription(
"device.ssm.write-lane-positions",
"SSM Device",
TL(
"Whether to write lanes and their positions for each timestep"));
254 oc.
addDescription(
"device.ssm.exclude-conflict-types",
"SSM Device",
TL(
"Which conflicts will be excluded from the log according to the conflict type they have been classified (combination of values in 'ego', 'foe' , '', any numerical valid conflict type code). An empty value will log all and 'ego'/'foe' refer to a certain conflict type subset."));
263 std::ifstream strm(file.c_str());
265 throw ProcessError(
TLF(
"Could not load names of edges for filtering SSM device output from '%'.", file));
268 while (strm.good()) {
273 std::string edgeID = line.substr(5);
275 if (edge !=
nullptr) {
278 WRITE_WARNING(
"Unknown edge ID '" + edgeID +
"' in SSM device edge filter (" + file +
"): " + line);
282 std::string junctionID = line.substr(9);
284 if (junction !=
nullptr) {
289 WRITE_WARNING(
"Unknown junction ID '" + junctionID +
"' in SSM device edge filter (" + file +
"): " + line);
291 }
else if (line ==
"") {
293 WRITE_WARNING(
"Cannot interpret line in SSM device edge filter (" + file +
"): " + line);
303 WRITE_WARNINGF(
"SSM Device for vehicle '%' will not be built. (SSMs not supported in MESO)", v.
getID());
307 std::string deviceID =
"ssm_" + v.
getID();
312 std::map<std::string, double> thresholds;
337 std::vector<int> conflictTypeFilter;
344 MSDevice_SSM* device =
new MSDevice_SSM(v, deviceID, file, thresholds, trajectories, range, extraTime, useGeo, writePos, writeLanesPos, conflictTypeFilter);
345 into.push_back(device);
358 egoID(_ego->getID()),
359 foeID(_foe->getID()),
362 currentType(ENCOUNTER_TYPE_NOCONFLICT_AHEAD),
363 remainingExtraTime(extraTime),
373 closingRequested(false) {
374#ifdef DEBUG_ENCOUNTER
376 std::cout <<
"\n" <<
SIMTIME <<
" Constructing encounter of '" <<
ego->
getID() <<
"' and '" <<
foe->
getID() <<
"'" << std::endl;
382#ifdef DEBUG_ENCOUNTER
384 std::cout <<
"\n" <<
SIMTIME <<
" Destroying encounter of '" << egoID <<
"' and '" << foeID <<
"' (begin was " << begin <<
")" << std::endl;
393 Position conflictPoint,
double egoDistToConflict,
double foeDistToConflict,
double ttc,
double drac, std::pair<double, double> pet,
double ppet,
double mdrac) {
394#ifdef DEBUG_ENCOUNTER
396 std::cout << time <<
" Adding data point for encounter of '" << egoID <<
"' and '" << foeID <<
"':\n"
397 <<
"type=" << type <<
", egoDistToConflict=" << (egoDistToConflict ==
INVALID_DOUBLE ?
"NA" :
::toString(egoDistToConflict))
406 timeSpan.push_back(time);
407 typeSpan.push_back(type);
408 egoTrajectory.x.push_back(egoX);
409 egoTrajectory.lane.push_back(egoLane);
410 egoTrajectory.lanePos.push_back(egoLanePos);
411 egoTrajectory.v.push_back(egoV);
412 foeTrajectory.x.push_back(foeX);
413 foeTrajectory.lane.push_back(foeLane);
414 foeTrajectory.lanePos.push_back(foeLanePos);
415 foeTrajectory.v.push_back(foeV);
416 conflictPointSpan.push_back(conflictPoint);
417 egoDistsToConflict.push_back(egoDistToConflict);
418 foeDistsToConflict.push_back(foeDistToConflict);
420 TTCspan.push_back(ttc);
424 minTTC.pos = conflictPoint;
429 DRACspan.push_back(drac);
431 maxDRAC.value = drac;
433 maxDRAC.pos = conflictPoint;
439 PET.value = pet.second;
440 PET.time = pet.first;
441 PET.pos = conflictPoint;
445 PPETspan.push_back(ppet);
447 minPPET.value = ppet;
449 minPPET.pos = conflictPoint;
453 MDRACspan.push_back(mdrac);
455 maxMDRAC.value = mdrac;
456 maxMDRAC.time = time;
457 maxMDRAC.pos = conflictPoint;
458 maxMDRAC.type = type;
466 remainingExtraTime = value;
472 remainingExtraTime -= amount;
478 return remainingExtraTime;
513 std::cout <<
"\n" <<
SIMTIME <<
" Device '" <<
getID() <<
"' updateAndWriteOutput()\n"
514 <<
" Holder is off-road! Calling resetEncounters()."
527 std::cout <<
"\n" <<
SIMTIME <<
" Device '" <<
getID() <<
"' update()\n"
537 const MSEdge* egoEdge = &((*myHolderMS).getLane()->getEdge());
546 if (foes.size() > 0) {
547 std::cout <<
"Scanned surroundings: Found potential foes:\n";
548 for (FoeInfoMap::const_iterator i = foes.begin(); i != foes.end(); ++i) {
549 std::cout << i->first->getID() <<
" ";
551 std::cout << std::endl;
553 std::cout <<
"Scanned surroundings: No potential conflict could be identified." << std::endl;
590 double leaderSearchDist = 0;
591 std::pair<const MSVehicle*, double> leader(
nullptr, 0.);
599 if (leaderSearchDist > 0.) {
605 if (leader.first ==
nullptr || leader.second < 0) {
636 std::cout <<
"\n" <<
SIMTIME <<
" Device '" <<
getID() <<
"' createEncounters()" << std::endl;
637 std::cout <<
"New foes:\n";
638 for (FoeInfoMap::const_iterator vi = foes.begin(); vi != foes.end(); ++vi) {
639 std::cout << vi->first->getID() <<
"\n";
641 std::cout << std::endl;
645 for (FoeInfoMap::const_iterator foe = foes.begin(); foe != foes.end(); ++foe) {
652 assert(myOldestActiveEncounterBegin <= e->begin);
677 std::cout <<
"\n" <<
SIMTIME <<
" Device '" <<
getID() <<
"' processEncounters(forceClose = " << forceClose <<
")" << std::endl;
678 std::cout <<
"Currently present foes:\n";
679 for (FoeInfoMap::const_iterator vi = foes.begin(); vi != foes.end(); ++vi) {
680 std::cout << vi->first->getID() <<
"\n";
682 std::cout << std::endl;
698 if (foes.find(e->
foe) != foes.end()) {
710 std::cout <<
" Requesting encounter closure because both left conflict area of previous encounter but another encounter lies ahead." << std::endl;
724 std::cout <<
" Requesting encounter closure because..." << std::endl;
726 std::cout <<
" ... extra time elapsed." << std::endl;
727 }
else if (forceClose) {
728 std::cout <<
" ... closing was forced." << std::endl;
730 std::cout <<
" ... foe disappeared." << std::endl;
741 double eBegin = e->
begin;
766 std::cout <<
SIMTIME <<
" qualifiesAsConflict() for encounter of vehicles '"
792 assert(e->
size() > 0);
800 std::cout <<
SIMTIME <<
" closeEncounter() of vehicles '"
802 <<
"' (was ranked as " << (wasConflict ?
"conflict" :
"non-conflict") <<
")" << std::endl;
810 std::cout <<
"pastConflictsQueue of veh '" <<
myHolderMS->
getID() <<
"':\n";
818 std::cout <<
" Conflict with foe '" << c->foe <<
"' (time=" << c->begin <<
"-" << c->end <<
")\n";
820 if (c->begin < lastBegin) {
821 std::cout <<
" Queue corrupt...\n";
824 lastBegin = c->begin;
826 std::cout << std::endl;
839#ifdef DEBUG_ENCOUNTER
841 std::cout <<
SIMTIME <<
" updateEncounter() of vehicles '" << e->
egoID <<
"' and '" << e->
foeID <<
"'\n";
868#ifdef DEBUG_ENCOUNTER
870 std::cout <<
SIMTIME <<
" Encounter of vehicles '" << e->
egoID <<
"' and '" << e->
foeID <<
"' does not imply any conflict.\n";
901 if (e->
size() == 0) {
902#ifdef DEBUG_ENCOUNTER
904 std::cout <<
SIMTIME <<
" type when creating encounter: " << eInfo.
type <<
"\n";
947 std::cout <<
SIMTIME <<
" determineConflictPoint()" << std::endl;
957 assert(e->
size() > 0);
978 std::cout <<
"No conflict point associated with encounter type " << type << std::endl;
986 std::cout <<
" Conflict at " << eInfo.
conflictPoint << std::endl;
1001 std::cout <<
SIMTIME <<
" estimateConflictTimes() for ego '" << e->
egoID <<
"' and foe '" << e->
foeID <<
"'\n"
1002 <<
" encounter type: " << eInfo.
type <<
"\n"
1016 std::cout <<
" encouter type " << type <<
" -> no exit times to be calculated."
1028 std::cout <<
" encouter type " << type <<
" -> no entry/exit times to be calculated."
1124 std::cout <<
" -> ego is estimated leader at conflict entry."
1133 std::cout <<
" -> foe is estimated leader at conflict entry."
1149 std::cout <<
SIMTIME <<
" computeSSMs() for vehicles '"
1151 <<
"'" << std::endl;
1181 std::stringstream ss;
1182 ss <<
"'" << type <<
"'";
1183 WRITE_WARNING(
"Unknown or undetermined encounter type at computeSSMs(): " + ss.str());
1189 std::cout <<
"computeSSMs() for encounter of vehicles '" << e->
egoID <<
"' and '" << e->
foeID <<
"':\n"
1202 if (e->
size() == 0) {
1206 std::pair<double, double>& pet = eInfo.
pet;
1210 std::cout <<
SIMTIME <<
" determinePET() for encounter of vehicles '" << e->
egoID <<
"' and '" << e->
foeID <<
"'"
1225 std::cout <<
"PET for crossing encounter already calculated as " << e->
PET.
value
1268 std::cout <<
"determinePET: Both passed conflict area in the same step. Assume collision"
1283 std::cout <<
"Calculated PET = " << pet.second <<
" (at t=" << pet.first <<
")"
1290 std::cout <<
"PET unappropriate for merging and pre-crossing situations. No calculation performed."
1302 double& ttc = eInfo.
ttc;
1303 double& drac = eInfo.
drac;
1304 double& ppet = eInfo.
ppet;
1305 double& mdrac = eInfo.
mdrac;
1309 std::cout <<
SIMTIME <<
" determineTTCandDRAC() for encounter of vehicles '" << e->
egoID <<
"' and '" << e->
foeID <<
"' (type = " << eInfo.
type <<
")"
1358 std::cout <<
" Conflict times with constant speed extrapolation for merging situation:\n "
1374 std::cout <<
" No TTC and DRAC computed as one vehicle is stopped." << std::endl;
1379 double leaderEntryTime =
MIN2(egoEntryTime, foeEntryTime);
1380 double followerEntryTime =
MAX2(egoEntryTime, foeEntryTime);
1381 double leaderExitTime = leaderEntryTime == egoEntryTime ? egoExitTime : foeExitTime;
1389 ppet = followerEntryTime - leaderExitTime;
1392 if (leaderExitTime >= followerEntryTime) {
1395 ttc =
computeTTC(followerConflictDist, followerSpeed, 0.);
1400 drac =
computeDRAC(followerConflictDist, followerSpeed, 0.);
1408 std::cout <<
" Extrapolation predicts collision *at* merge point with TTC=" << ttc
1409 <<
", drac=" << drac << std::endl;
1416 double gapAfterMerge = followerConflictDist - leaderExitTime * followerSpeed;
1417 assert(gapAfterMerge >= 0);
1420 double ttcAfterMerge =
computeTTC(gapAfterMerge, followerSpeed, leaderSpeed);
1425 double g0 = followerConflictDist - leaderConflictDist - leaderLength;
1428 assert(leaderSpeed - followerSpeed > 0);
1433 drac =
computeDRAC(g0, followerSpeed, leaderSpeed);
1438 double g0 = followerConflictDist - leaderConflictDist - leaderLength;
1441 assert(leaderSpeed - followerSpeed > 0);
1454 std::cout <<
" Extrapolation does not predict any collision." << std::endl;
1456 std::cout <<
" Extrapolation predicts collision *after* merge point with TTC="
1489 ppet = entryTime - exitTime;
1518 ppet = entryTime - exitTime;
1529 std::stringstream ss;
1530 ss <<
"'" << type <<
"'";
1531 WRITE_WARNING(
"Underspecified or unknown encounter type in MSDevice_SSM::determineTTCandDRAC(): " + ss.str());
1551 std::cout <<
"computeTTC() with gap=" << gap <<
", followerSpeed=" << followerSpeed <<
", leaderSpeed=" << leaderSpeed
1557 double dv = followerSpeed - leaderSpeed;
1576 double dv = followerSpeed - leaderSpeed;
1580 assert(followerSpeed > 0.);
1581 return 0.5 * dv * dv / gap;
1594 double dv = followerSpeed - leaderSpeed;
1598 if (gap / dv == prt) {
1601 assert(followerSpeed > 0.);
1602 return 0.5 * dv / (gap / dv - prt);
1619#ifdef DEBUG_SSM_DRAC
1621 std::cout <<
SIMTIME <<
"computeDRAC() with"
1622 <<
"\ndEntry1=" << dEntry1 <<
", dEntry2=" << dEntry2
1623 <<
", dExit1=" << dExit1 <<
", dExit2=" << dExit2
1624 <<
",\nv1=" << v1 <<
", v2=" << v2
1629 if (dExit1 <= 0. || dExit2 <= 0.) {
1631#ifdef DEBUG_SSM_DRAC
1633 std::cout <<
"One already left conflict area -> drac == 0." << std::endl;
1638 if (dEntry1 <= 0. && dEntry2 <= 0.) {
1640#ifdef DEBUG_SSM_DRAC
1642 std::cout <<
"Both entered conflict area but neither left. -> collision!" << std::endl;
1648 double drac = std::numeric_limits<double>::max();
1651#ifdef DEBUG_SSM_DRAC
1653 std::cout <<
"Ego could break..." << std::endl;
1658 drac =
MIN2(drac, 2 * (v1 - dEntry1 / tExit2) / tExit2);
1659#ifdef DEBUG_SSM_DRAC
1661 std::cout <<
" Foe expected to leave in " << tExit2 <<
"-> Ego needs drac=" << drac << std::endl;
1669#ifdef DEBUG_SSM_DRAC
1671 std::cout <<
" Foe is expected stop on conflict area -> Ego needs drac=" << drac << std::endl;
1676#ifdef DEBUG_SSM_DRAC
1678 std::cout <<
" Foe is expected stop before conflict area -> no drac computation for ego (will be done for foe if applicable)" << std::endl;
1687#ifdef DEBUG_SSM_DRAC
1689 std::cout <<
"Foe could break..." << std::endl;
1694#ifdef DEBUG_SSM_DRAC
1696 std::cout <<
" Ego expected to leave in " << tExit1 <<
"-> Foe needs drac=" << (2 * (v2 - dEntry2 / tExit1) / tExit1) << std::endl;
1699 drac =
MIN2(drac, 2 * (v2 - dEntry2 / tExit1) / tExit1);
1704#ifdef DEBUG_SSM_DRAC
1706 std::cout <<
" Ego is expected stop on conflict area -> Foe needs drac=" <<
computeDRAC(dEntry2, v2, 0) << std::endl;
1712#ifdef DEBUG_SSM_DRAC
1714 std::cout <<
" Ego is expected stop before conflict area -> no drac computation for foe (done for ego if applicable)" << std::endl;
1735#ifdef DEBUG_ENCOUNTER
1737 std::cout <<
SIMTIME <<
" checkConflictEntryAndExit() for encounter of vehicles '" << e->
egoID <<
"' and '" << e->
foeID <<
"'"
1747 if (e->
size() == 0) {
1751 if (egoPastConflictExit) {
1752 if (foePastConflictExit) {
1754 }
else if (foePastConflictEntry) {
1759 }
else if (foePastConflictExit) {
1760 if (egoPastConflictEntry) {
1767 if (egoPastConflictEntry) {
1768 if (foePastConflictEntry) {
1773 }
else if (foePastConflictEntry) {
1801#ifdef DEBUG_ENCOUNTER
1817#ifdef DEBUG_ENCOUNTER
1835#ifdef DEBUG_ENCOUNTER
1853#ifdef DEBUG_ENCOUNTER
1870#ifdef DEBUG_ENCOUNTER
1872 std::cout <<
SIMTIME <<
" updatePassedEncounter() for vehicles '" << e->
egoID <<
"' and '" << e->
foeID <<
"'\n";
1876 if (foeInfo ==
nullptr) {
1879#ifdef DEBUG_ENCOUNTER
1895#ifdef DEBUG_ENCOUNTER
1897 std::cout <<
" This encounter wasn't classified as a potential conflict lately.\n";
1900 if (foeInfo ==
nullptr) {
1906 std::cout <<
" Requesting encounter closure because foeInfo==nullptr" << std::endl;
1910#ifdef DEBUG_ENCOUNTER
1912 std::cout <<
" Closing encounter.\n";
1922#ifdef DEBUG_ENCOUNTER
1924 std::cout <<
" Encounter was previously classified as a follow/lead situation.\n";
1933#ifdef DEBUG_ENCOUNTER
1935 std::cout <<
" Encounter was previously classified as a merging situation.\n";
1950#ifdef DEBUG_ENCOUNTER
1952 std::cout <<
" Encounter was previously classified as a crossing situation of type " << lastPotentialConflictType <<
".\n";
1970#ifdef DEBUG_ENCOUNTER
1984 if ((!egoEnteredConflict) && !foeEnteredConflict) {
1988 eInfo.
type = lastPotentialConflictType;
1989 }
else if (egoEnteredConflict && !foeEnteredConflict) {
1991 }
else if ((!egoEnteredConflict) && foeEnteredConflict) {
1997 if ((!egoLeftConflict) && !foeLeftConflict) {
2001 }
else if (egoLeftConflict && !foeLeftConflict) {
2005 }
else if ((!egoLeftConflict) && foeLeftConflict) {
2020#ifdef DEBUG_ENCOUNTER
2022 std::cout <<
" Updated classification: " << eInfo.
type <<
"\n";
2031#ifdef DEBUG_ENCOUNTER
2033 std::cout <<
"classifyEncounter() called.\n";
2036 if (foeInfo ==
nullptr) {
2055#ifdef DEBUG_ENCOUNTER
2057 std::cout <<
" Ongoing crossing conflict will be traced by passedEncounter().\n";
2073 double foeDistToConflictLane;
2076#ifdef DEBUG_ENCOUNTER
2078 std::cout <<
" egoConflictLane='" << (egoConflictLane == 0 ?
"NULL" : egoConflictLane->
getID()) <<
"'\n"
2079 <<
" foeConflictLane='" << (foeConflictLane == 0 ?
"NULL" : foeConflictLane->
getID()) <<
"'\n"
2080 <<
" egoDistToConflictLane=" << egoDistToConflictLane
2081 <<
" foeDistToConflictLane=" << foeDistToConflictLane
2096 if (foeConflictLane ==
nullptr) {
2099#ifdef DEBUG_ENCOUNTER
2101 std::cout <<
"-> Encounter type: No conflict.\n";
2106 if (egoConflictLane == egoLane) {
2110 if (foeLane == egoLane) {
2112 if (!egoOpposite && !foeOpposite) {
2120#ifdef DEBUG_ENCOUNTER
2122 std::cout <<
"-> Encounter type: Lead/follow-situation on non-internal lane '" << egoLane->
getID() <<
"'\n";
2125 }
else if (egoOpposite && foeOpposite) {
2133#ifdef DEBUG_ENCOUNTER
2135 std::cout <<
"-> Encounter type: Lead/follow-situation while both are driving in the opposite direction on non-internal lane '" << egoLane->
getID() <<
"'\n";
2156#ifdef DEBUG_ENCOUNTER
2158 std::cout <<
"-> Encounter type: oncoming on non-internal lane '" << egoLane->
getID() <<
"'\n";
2167#ifdef DEBUG_ENCOUNTER
2169 std::cout <<
"-> Encounter type: " << type << std::endl;
2174 if (!egoOpposite && !foeOpposite) {
2177 assert(egoDistToConflictLane <= 0);
2179 if (foeConflictLane == egoLane) {
2183#ifdef DEBUG_ENCOUNTER
2185 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' leads foe '"
2186 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2192#ifdef DEBUG_ENCOUNTER
2194 std::cout <<
"-> Encounter type: " << type << std::endl;
2199 }
else if (egoOpposite && foeOpposite) {
2211#ifdef DEBUG_ENCOUNTER
2213 std::cout <<
"-> Encounter type: Lead/follow-situation while both are driving in the opposite direction on non-internal lane '" << egoLane->
getID() <<
"'\n";
2237#ifdef DEBUG_ENCOUNTER
2239 std::cout <<
"-> Encounter type: oncoming on non-internal lane '" << egoLane->
getID() <<
"'\n";
2251 assert(foeDistToConflictLane <= 0);
2252 if (foeLane == egoConflictLane) {
2255#ifdef DEBUG_ENCOUNTER
2257 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' follows foe '"
2258 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2264#ifdef DEBUG_ENCOUNTER
2266 std::cout <<
"-> Encounter type: " << type << std::endl;
2278 if (egoEntryLink != foeEntryLink) {
2281#ifdef DEBUG_ENCOUNTER
2283 std::cout <<
"-> Encounter type: " << type << std::endl;
2288 if (egoLane == egoConflictLane && foeLane != foeConflictLane) {
2295#ifdef DEBUG_ENCOUNTER
2297 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' leads foe '"
2298 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2301 }
else if (egoLane != egoConflictLane && foeLane == foeConflictLane) {
2308#ifdef DEBUG_ENCOUNTER
2310 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' follows foe '"
2311 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2318#ifdef DEBUG_ENCOUNTER
2320 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' merges with foe '"
2321 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2329 if (egoLane != egoConflictLane || foeLane != foeConflictLane) {
2333 if (egoLane == foeLane) {
2338#ifdef DEBUG_ENCOUNTER
2340 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' leads foe '"
2341 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2348#ifdef DEBUG_ENCOUNTER
2350 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' follows foe '"
2351 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2358#ifdef DEBUG_ENCOUNTER
2360 std::cout <<
" Lead/follow situation on consecutive internal lanes." << std::endl;
2367 if (egoLane == lane) {
2372 while (lane != foeLane) {
2378 egoConflictLane = lane;
2379#ifdef DEBUG_ENCOUNTER
2381 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' follows foe '"
2382 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2387 }
else if (foeLane == lane) {
2392 while (lane != egoLane) {
2398 foeConflictLane = lane;
2399#ifdef DEBUG_ENCOUNTER
2401 std::cout <<
"-> Encounter type: Ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' leads foe '"
2402 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2412#ifdef DEBUG_ENCOUNTER
2414 std::cout <<
"-> Encounter type: Lead/follow-situation on connection from '" << egoEntryLink->
getLaneBefore()->
getID()
2415 <<
"' to '" << egoEntryLink->
getLane()->
getID() <<
"'" << std::endl;
2422 const std::vector<MSLink*>& egoFoeLinks = egoEntryLink->
getFoeLinks();
2423 const std::vector<MSLink*>& foeFoeLinks = foeEntryLink->
getFoeLinks();
2425 bool crossOrMerge = (find(egoFoeLinks.begin(), egoFoeLinks.end(), foeEntryLink) != egoFoeLinks.end()
2426 || std::find(foeFoeLinks.begin(), foeFoeLinks.end(), egoEntryLink) != foeFoeLinks.end());
2427 if (!crossOrMerge) {
2436#ifdef DEBUG_ENCOUNTER
2438 std::cout <<
"-> Encounter type: No conflict.\n";
2463#ifdef DEBUG_ENCOUNTER
2465 std::cout <<
"-> Encounter type: Merging situation of ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' and foe '"
2466 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2473#ifdef DEBUG_ENCOUNTER
2475 std::cout <<
"-> Encounter type: No conflict: " << type << std::endl;
2491 egoDistToConflictLane -= offset;
2493 foeDistToConflictLane -= offset;
2498 while (foeConflictLane !=
nullptr && foeConflictLane->
isInternal()) {
2507 egoDistToConflictFromJunctionEntry = 0;
2508 WRITE_WARNINGF(
TL(
"Cannot compute SSM due to bad internal lane geometry at junction '%'. Crossing point between traffic from links % and % not found."),
2515 assert(foeConflictLane !=
nullptr && foeConflictLane->
isInternal());
2522 while (egoConflictLane !=
nullptr && egoConflictLane->
isInternal()) {
2531 foeDistToConflictFromJunctionEntry = 0;
2532 WRITE_WARNINGF(
TL(
"Cannot compute SSM due to bad internal lane geometry at junction '%'. Crossing point between traffic from links % and % not found."),
2539 assert(egoConflictLane !=
nullptr && egoConflictLane->
isInternal());
2564 assert(angle <= 2 *
M_PI);
2568 assert(angle >= -
M_PI);
2569 assert(angle <=
M_PI);
2571 double crossingOrientation = (angle < 0) - (angle > 0);
2591#ifdef DEBUG_ENCOUNTER
2593 std::cout <<
" Determined exact conflict distances for crossing conflict."
2594 <<
"\n crossingOrientation=" << crossingOrientation
2597 <<
", relativeAngle=" << angle
2598 <<
" (foe from " << (crossingOrientation > 0 ?
"right)" :
"left)")
2599 <<
"\n resulting offset for conflict entry distance:"
2602 <<
"\n distToConflictLane:"
2603 <<
"\n ego=" << egoDistToConflictLane
2604 <<
", foe=" << foeDistToConflictLane
2605 <<
"\n distToConflictFromJunctionEntry:"
2606 <<
"\n ego=" << egoDistToConflictFromJunctionEntry
2607 <<
", foe=" << foeDistToConflictFromJunctionEntry
2608 <<
"\n resulting entry distances:"
2611 <<
"\n resulting exit distances:"
2616 std::cout <<
"real egoConflictLane: '" << (egoConflictLane == 0 ?
"NULL" : egoConflictLane->
getID()) <<
"'\n"
2617 <<
"real foeConflictLane: '" << (foeConflictLane == 0 ?
"NULL" : foeConflictLane->
getID()) <<
"'\n"
2618 <<
"-> Encounter type: Crossing situation of ego '" << e->
ego->
getID() <<
"' on lane '" << egoLane->
getID() <<
"' and foe '"
2619 << e->
foe->
getID() <<
"' on lane '" << foeLane->
getID() <<
"'"
2637 std::cout <<
SIMTIME <<
" findFoeConflictLane() for foe '"
2639 <<
"' (with egoConflictLane=" << (egoConflictLane == 0 ?
"NULL" : egoConflictLane->
getID())
2649#ifdef DEBUG_SSM_OPPOSITE
2669 return egoConflictLane;
2678 return egoConflictLane;
2688 assert(foeLane->
isInternal() || *laneIter == foeLane);
2695 if (conflictJunction != 0) {
2696 std::cout <<
"Potential conflict on junction '" << conflictJunction->
getID()
2702 if (egoConflictLane !=
nullptr && egoConflictLane->
isInternal() && egoConflictLane->
getLinkCont()[0]->getViaLane() == foeLane) {
2703 distToConflictLane += egoConflictLane->
getLength();
2711 if (*laneIter ==
nullptr) {
2712 while (foeLane !=
nullptr && foeLane->
isInternal()) {
2713 distToConflictLane += foeLane->
getLength();
2714 foeLane = foeLane->
getLinkCont()[0]->getViaLane();
2717 assert(laneIter == foeBestLanesEnd || *laneIter != 0);
2721 while (laneIter != foeBestLanesEnd && distToConflictLane <=
myRange) {
2723 assert(*laneIter == foeLane || foeLane == 0);
2724 foeLane = *laneIter;
2729 std::cout <<
"Found conflict lane for foe: '" << foeLane->
getID() <<
"'" << std::endl;
2736 distToConflictLane += foeLane->
getLength();
2740 if (laneIter == foeBestLanesEnd) {
2743 MSLane*
const nextNonInternalLane = *laneIter;
2747 assert(foeLane == 0 || foeLane->
isInternal());
2748 if (foeLane ==
nullptr) {
2749 foeLane = nextNonInternalLane;
2753 assert(foeLane != 0);
2756 std::cout <<
"Found conflict lane for foe: '" << foeLane->
getID() <<
"'" << std::endl;
2764 foeLane = nextNonInternalLane;
2785 std::vector<int> foundTypes;
2787 std::set_intersection(
2789 encounterTypes.begin(), encounterTypes.end(),
2790 std::back_inserter(foundTypes));
2791 write = foundTypes.size() == 0;
2809 std::cout <<
SIMTIME <<
" flushGlobalMeasures() of vehicle '"
2883 std::cout <<
SIMTIME <<
" writeOutConflict() of vehicles '"
3011 std::string res =
"";
3012 for (std::vector<double>::const_iterator i = v.begin(); i != v.end(); ++i) {
3013 res += (i == v.begin() ?
"" :
" ") + (*i == NA ?
"NA" :
::toString(*i));
3020 std::string res =
"";
3021 for (std::vector<double>::const_iterator i = v.begin(); i != v.end(); ++i) {
3022 res += (i == v.begin() ?
"" :
" ") + (find(NAs.begin(), NAs.end(), *i) != NAs.end() ?
"NA" :
::toString(*i));
3030 std::string res =
"";
3031 for (PositionVector::const_iterator i = v.begin(); i != v.end(); ++i) {
3046 return v == NA ?
"NA" :
toString(v);
3054 std::vector<int> conflictTypeFilter) :
3100 std::vector<std::string> measures;
3101 std::vector<double> threshVals;
3103 measures.push_back(i->first);
3104 threshVals.push_back(i->second);
3106 std::cout <<
"Initialized ssm device '" <<
id <<
"' with "
3129#ifdef DEBUG_SSM_NOTIFICATIONS
3145#ifdef DEBUG_SSM_NOTIFICATIONS
3159 double ,
double newSpeed) {
3160#ifdef DEBUG_SSM_NOTIFICATIONS
3163 std::cout <<
SIMTIME <<
"device '" <<
getID() <<
"' notifyMove: newSpeed=" << newSpeed <<
"\n";
3178#ifdef DEBUG_SSM_SURROUNDING
3182 std::cout <<
SIMTIME <<
" Looking for surrounding vehicles for ego vehicle '" << veh.
getID()
3208 std::vector<MSLane*>::const_iterator laneIter = egoBestLanes.begin();
3209 assert(lane->
isInternal() || lane == *laneIter || isOpposite);
3211 if (lane->
isInternal() && egoBestLanes[0] !=
nullptr) {
3216 for (
int i = 0; i < (int)egoBestLanes.size(); i++) {
3217 if (egoBestLanes[i] !=
nullptr && egoBestLanes[i]->getEdge().getOppositeEdge() !=
nullptr) {
3218 egoBestLanes[i] = egoBestLanes[i]->getEdge().getOppositeEdge()->getLanes().back();
3224 const MSLane* nextNonInternalLane =
nullptr;
3232 double remainingDownstreamRange = range;
3234 double distToConflictLane = isOpposite ? pos - veh.
getLane()->
getLength() : -pos;
3237 std::set<const MSLane*> seenLanes;
3238 std::set<const MSJunction*> routeJunctions;
3242 std::vector<UpstreamScanStartInfo> upstreamScanStartPositions;
3251#ifdef DEBUG_SSM_SURROUNDING
3253 std::cout <<
SIMTIME <<
" Vehicle '" << veh.
getID() <<
"' is on internal edge " << edge->
getID() <<
"'." << std::endl;
3263 routeJunctions.insert(junction);
3269 for (ConstMSEdgeVector::const_iterator ei = incoming.begin(); ei != incoming.end(); ++ei) {
3270 if ((*ei)->isInternal()) {
3289 lane = *(++laneIter);
3295 double startScanPos = std::min(pos + remainingDownstreamRange, edgeLength);
3296 upstreamScanStartPositions.push_back(
UpstreamScanStartInfo(edge, startScanPos, std::max(0., startScanPos - pos + range + veh.
getLength()), distToConflictLane, lane));
3305 while (remainingDownstreamRange > 0.) {
3307#ifdef DEBUG_SSM_SURROUNDING
3309 std::cout <<
SIMTIME <<
" Scanning downstream for vehicle '" << veh.
getID() <<
"' on lane '" << veh.
getLane()->
getID() <<
"', position=" << pos <<
".\n"
3310 <<
"Considering edge '" << edge->
getID() <<
"' Remaining downstream range = " << remainingDownstreamRange
3311 <<
"\nbestLanes=" <<
::toString(egoBestLanes) <<
"\n"
3317 assert(pos == 0 || lane == veh.
getLane());
3318 if (pos + remainingDownstreamRange < lane->getLength()) {
3321 upstreamScanStartPositions.push_back(
UpstreamScanStartInfo(edge, pos + remainingDownstreamRange, remainingDownstreamRange, distToConflictLane, lane));
3332 remainingDownstreamRange -= lane->
getLength() - pos;
3333 distToConflictLane += lane->
getLength();
3338 assert(laneIter == egoBestLanes.end() || *laneIter != 0);
3341 if (laneIter != egoBestLanes.end()) {
3352 nextNonInternalLane = *laneIter;
3354 if (isOpposite && link ==
nullptr) {
3355 link = nextNonInternalLane->
getLinkTo(lane);
3356 if (link ==
nullptr) {
3360 if (link ==
nullptr) {
3367 if (lane ==
nullptr) {
3369 lane = nextNonInternalLane;
3371 if (seenLanes.count(lane) == 0) {
3372 seenLanes.insert(lane);
3379 if (seenLanes.count(lane) == 0) {
3382 routeJunctions.insert(junction);
3388 for (ConstMSEdgeVector::const_iterator ei = outgoing.begin(); ei != outgoing.end(); ++ei) {
3392 upstreamScanStartPositions.push_back(
UpstreamScanStartInfo(*ei, (*ei)->getLength(), range, distToConflictLane, lane));
3396 for (ConstMSEdgeVector::const_iterator ei = incoming.begin(); ei != incoming.end(); ++ei) {
3400 upstreamScanStartPositions.push_back(
UpstreamScanStartInfo(*ei, (*ei)->getLength(), range, distToConflictLane, lane));
3406 remainingDownstreamRange -= linkLength;
3407 distToConflictLane += linkLength;
3408#ifdef DEBUG_SSM_SURROUNDING
3410 std::cout <<
" Downstream Scan for vehicle '" << veh.
getID() <<
"' proceeded over junction '" << junction->
getID()
3411 <<
"',\n linkLength=" << linkLength <<
", remainingDownstreamRange=" << remainingDownstreamRange
3417 lane = nextNonInternalLane;
3420#ifdef DEBUG_SSM_SURROUNDING
3422 std::cout <<
" Downstream Scan for vehicle '" << veh.
getID() <<
"' stops at lane '" << lane->
getID()
3423 <<
"', which has already been scanned."
3444#ifdef DEBUG_SSM_SURROUNDING
3446 for (std::pair<const MSVehicle*, FoeInfo*> foeInfo : foeCollector) {
3447 std::cout <<
" foe " << foeInfo.first->getID() <<
" conflict at " << foeInfo.second->egoConflictLane->getID() <<
" egoDist " << foeInfo.second->egoDistToConflictLane << std::endl;
3453 const auto& it = foeCollector.find(&veh);
3454 if (it != foeCollector.end()) {
3456 foeCollector.erase(it);
3464#ifdef DEBUG_SSM_SURROUNDING
3466 std::cout <<
SIMTIME <<
" getUpstreamVehicles() for edge '" << scanStart.
edge->
getID() <<
"'"
3468 <<
" pos = " << scanStart.
pos <<
" range = " << scanStart.
range
3472 if (scanStart.
range <= 0) {
3478 if (seenLanes.find(lane) != seenLanes.end()) {
3482 for (
MSVehicle*
const veh : lane->getVehiclesSecure()) {
3483 if (foeCollector.find(veh) != foeCollector.end()) {
3487 if (veh->getPositionOnLane() - veh->getLength() <= scanStart.
pos && veh->getPositionOnLane() >= scanStart.
pos - scanStart.
range) {
3488#ifdef DEBUG_SSM_SURROUNDING
3490 std::cout <<
"\t" << veh->getID() <<
"\n";
3496 foeCollector[veh] = c;
3500 lane->releaseVehicles();
3502#ifdef DEBUG_SSM_SURROUNDING
3504 std::cout <<
"\t" << lane->getID() <<
": Found " << foundCount <<
"\n";
3507 seenLanes.insert(lane);
3510#ifdef DEBUG_SSM_SURROUNDING
3512 std::cout << std::endl;
3520 if (scanStart.
range <= scanStart.
pos) {
3525 double remainingRange = scanStart.
range - scanStart.
pos;
3531 if (routeJunctions.find(junction) != routeJunctions.end()) {
3536 int incomingEdgeCount = 0;
3544 if (internalLane->getEdge().getSuccessors()[0]->getID() == scanStart.
edge->
getID()) {
3546 incomingEdgeCount++;
3551 if (incomingEdgeCount > 0) {
3553 if (inEdge->isInternal() || inEdge->isCrossing()) {
3557 for (
MSLane*
const lane : inEdge->getLanes()) {
3558 if (seenLanes.find(lane) != seenLanes.end()) {
3564#ifdef DEBUG_SSM_SURROUNDING
3572 if (distOnJunction >= remainingRange) {
3573#ifdef DEBUG_SSM_SURROUNDING
3588#ifdef DEBUG_SSM_SURROUNDING
3590 std::cout <<
SIMTIME <<
" getVehiclesOnJunction() for junction '" << junction->
getID()
3592 <<
"\nFound vehicles:"
3599 if (foeCollector.find(veh) != foeCollector.end()) {
3600 delete foeCollector[veh];
3605 foeCollector[veh] = c;
3606#ifdef DEBUG_SSM_SURROUNDING
3608 std::cout <<
"\t" << veh->getID() <<
" egoConflictLane=" <<
Named::getIDSecure(egoConflictLane) <<
"\n";
3615 if (seenLanes.find(egoJunctionLane) != seenLanes.end() || egoJunctionLane->
getEdge().
isCrossing()) {
3619 auto scanInternalLane = [&](
const MSLane * lane) {
3624 collectFoeInfos(vehicles);
3626 lane->releaseVehicles();
3630 if (lane->getCanonicalPredecessorLane()->isInternal()) {
3631 lane = lane->getCanonicalPredecessorLane();
3634 assert(!lane->getEntryLink()->fromInternalLane());
3639 collectFoeInfos(vehicles2);
3640 lane->releaseVehicles();
3645 if (lane->getLinkCont().size() > 1 && lane->getLinkCont()[0]->getViaLane() !=
nullptr) {
3647 lane = lane->getLinkCont()[0]->getViaLane();
3649 assert(lane->getLinkCont().size() == 0 || lane->getLinkCont()[0]->getViaLane() == 0);
3654 collectFoeInfos(vehicles2);
3655 lane->releaseVehicles();
3665 for (
MSLane* lane : foeLanes) {
3666 if (seenLanes.find(lane) != seenLanes.end()) {
3669 scanInternalLane(lane);
3670 seenLanes.insert(lane);
3673 scanInternalLane(egoJunctionLane);
3675#ifdef DEBUG_SSM_SURROUNDING
3677 std::cout << std::endl;
3697 std::string file = deviceID +
".xml";
3711 file = oc.
getString(
"device.ssm.file") ==
"" ? file : oc.
getString(
"device.ssm.file");
3713 WRITE_MESSAGEF(
TL(
"Vehicle '%' does not supply vehicle parameter 'device.ssm.file'. Using default of '%'."), v.
getID(), file);
3731 bool useGeo =
false;
3745 useGeo = oc.
getBool(
"device.ssm.geo");
3758 bool writePos =
false;
3772 writePos = oc.
getBool(
"device.ssm.write-positions");
3774 WRITE_MESSAGEF(
TL(
"Vehicle '%' does not supply vehicle parameter 'device.ssm.write-positions'. Using default of '%'."), v.
getID(),
toString(writePos));
3785 bool writeLanesPos =
false;
3799 writeLanesPos = oc.
getBool(
"device.ssm.write-lane-positions");
3801 WRITE_MESSAGEF(
TL(
"Vehicle '%' does not supply vehicle parameter 'device.ssm.write-positions'. Using default of '%'."), v.
getID(),
toString(writeLanesPos));
3805 return writeLanesPos;
3812 std::string typeString =
"";
3826 typeString = oc.
getString(
"device.ssm.exclude-conflict-types");
3828 WRITE_MESSAGEF(
TL(
"Vehicle '%' does not supply vehicle parameter 'device.ssm.exclude-conflict-types'. Using default of '%'."), v.
getID(), typeString);
3835 std::vector<std::string> found = st.
getVector();
3836 std::set<int> confirmed;
3837 for (std::vector<std::string>::const_iterator i = found.begin(); i != found.end(); ++i) {
3840 }
else if (*i ==
"ego") {
3843 confirmed.insert(std::stoi(*i));
3846 WRITE_ERRORF(
TL(
"SSM order filter '%' is not supported. Aborting construction of SSM device '%'."), *i, deviceID);
3850 conflictTypes.insert(conflictTypes.end(), confirmed.begin(), confirmed.end());
3872 range = oc.
getFloat(
"device.ssm.range");
3899 prt = oc.
getFloat(
"device.ssm.mdrac.prt");
3901 WRITE_MESSAGEF(
TL(
"Vehicle '%' does not supply vehicle parameter 'device.ssm.mdrac.prt'. Using default of '%'."), v.
getID(),
toString(prt));
3928 extraTime = oc.
getFloat(
"device.ssm.extratime");
3930 WRITE_MESSAGEF(
TL(
"Vehicle '%' does not supply vehicle parameter 'device.ssm.extratime'. Using default of '%'."), v.
getID(),
toString(extraTime));
3934 if (extraTime < 0.) {
3936 WRITE_WARNINGF(
TL(
"Negative (or no) value encountered for vehicle parameter 'device.ssm.extratime' in vehicle '%' using default value % instead."), v.
getID(),
::toString(extraTime));
3945 bool trajectories =
false;
3959 trajectories = oc.
getBool(
"device.ssm.trajectories");
3961 WRITE_MESSAGEF(
TL(
"Vehicle '%' does not supply vehicle parameter 'device.ssm.trajectories'. Using default of '%'."), v.
getID(),
toString(trajectories));
3965 return trajectories;
3974 std::string measures_str =
"";
3988 measures_str = oc.
getString(
"device.ssm.measures");
3990 WRITE_MESSAGEF(
TL(
"Vehicle '%' does not supply vehicle parameter 'device.ssm.measures'. Using default of '%'."), v.
getID(), measures_str);
3996 if (measures_str ==
"") {
3997 WRITE_WARNINGF(
"No measures specified for ssm device of vehicle '%'. Registering all available SSMs.", v.
getID());
4001 std::vector<std::string> available = st.
getVector();
4003 std::vector<std::string> measures = st.
getVector();
4004 for (std::vector<std::string>::const_iterator i = measures.begin(); i != measures.end(); ++i) {
4005 if (std::find(available.begin(), available.end(), *i) == available.end()) {
4007 WRITE_ERRORF(
TL(
"SSM identifier '%' is not supported. Aborting construction of SSM device '%'."), *i, deviceID);
4013 std::string thresholds_str =
"";
4027 thresholds_str = oc.
getString(
"device.ssm.thresholds");
4029 WRITE_MESSAGEF(
TL(
"Vehicle '%' does not supply vehicle parameter 'device.ssm.thresholds'. Using default of '%'."), v.
getID(), thresholds_str);
4036 if (thresholds_str !=
"") {
4038 while (count < (
int)measures.size() && st.
hasNext()) {
4040 thresholds.insert(std::make_pair(measures[count], thresh));
4043 if (thresholds.size() < measures.size() || st.
hasNext()) {
4044 WRITE_ERRORF(
TL(
"Given list of thresholds ('%') is not of the same size as the list of measures ('%').\nPlease specify exactly one threshold for each measure."), thresholds_str, measures_str);
4049 for (std::vector<std::string>::const_iterator i = measures.begin(); i != measures.end(); ++i) {
4052 }
else if (*i ==
"DRAC") {
4054 }
else if (*i ==
"MDRAC") {
4056 }
else if (*i ==
"PET") {
4058 }
else if (*i ==
"PPET") {
4060 }
else if (*i ==
"BR") {
4062 }
else if (*i ==
"SGAP") {
4064 }
else if (*i ==
"TGAP") {
4067 WRITE_ERROR(
"Unknown SSM identifier '" + (*i) +
"'. Aborting construction of ssm device.");
4093 if (key ==
"minTTC" ||
4095 key ==
"maxMDRAC" ||
4105 minTTC =
MIN2(minTTC, e->minTTC.value);
4106 minPET =
MIN2(minPET, e->PET.value);
4107 maxDRAC =
MAX2(maxDRAC, e->maxDRAC.value);
4108 maxMDRAC =
MAX2(maxMDRAC, e->maxMDRAC.value);
4109 minPPET =
MIN2(minPPET, e->minPPET.value);
4111 if (key ==
"minTTC") {
4113 }
else if (key ==
"maxDRAC") {
4115 }
else if (key ==
"maxMDRAC") {
4117 }
else if (key ==
"minPET") {
4119 }
else if (key ==
"minPPET") {
4140 if (
false || key ==
"foo") {
#define DEFAULT_THRESHOLD_SGAP
#define DEFAULT_THRESHOLD_BR
#define DEFAULT_THRESHOLD_TGAP
#define DEFAULT_THRESHOLD_PPET
#define DEFAULT_THRESHOLD_DRAC
#define DEFAULT_THRESHOLD_TTC
#define DEFAULT_EXTRA_TIME
#define DEFAULT_THRESHOLD_PET
#define DEFAULT_THRESHOLD_MDRAC
#define DEBUG_COND_ENCOUNTER(e)
std::ostream & operator<<(std::ostream &out, MSDevice_SSM::EncounterType type)
Nicer output for EncounterType enum.
#define DEBUG_COND_FIND(ego)
std::vector< const MSEdge * > ConstMSEdgeVector
#define WRITE_WARNINGF(...)
#define WRITE_MESSAGEF(...)
#define WRITE_ERRORF(...)
#define WRITE_WARNING(msg)
std::string time2string(SUMOTime t, bool humanReadable)
convert SUMOTime to string (independently of global format setting)
@ SVC_IGNORING
vehicles ignoring classes
int gPrecision
the precision for floating point outputs
const double INVALID_DOUBLE
invalid double
#define UNUSED_PARAMETER(x)
std::string joinToString(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=gPrecision)
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
static std::string checkForRelativity(const std::string &filename, const std::string &basePath)
Returns the path from a configuration so that it is accessable from the current working directory.
static const GeoConvHelper & getFinal()
the coordinate transformation for writing the location element and for tracking the original coordina...
void cartesian2geo(Position &cartesian) const
Converts the given cartesian (shifted) position to its geo (lat/long) representation.
The base class for microscopic and mesoscopic vehicles.
const MSRouteIterator & getCurrentRouteEdge() const
Returns an iterator pointing to the current edge in this vehicles route.
double getLength() const
Returns the vehicle's length.
const MSEdge * getEdge() const
Returns the edge the vehicle is currently at.
double getWidth() const
Returns the vehicle's width.
const MSRoute & getRoute() const
Returns the current route.
const MSVehicleType & getVehicleType() const
Returns the vehicle's type definition.
static double passingTime(const double lastPos, const double passedPos, const double currentPos, const double lastSpeed, const double currentSpeed)
Calculates the time at which the position passedPosition has been passed In case of a ballistic updat...
static double estimateArrivalTime(double dist, double speed, double maxSpeed, double accel)
Computes the time needed to travel a distance dist given an initial speed and constant acceleration....
An encounter is an episode involving two vehicles, which are closer to each other than some specified...
ConflictPointInfo minPPET
EncounterType currentType
double foeConflictEntryTime
Times when the foe vehicle entered/left the conflict area. Currently only applies for crossing situat...
std::vector< double > foeDistsToConflict
Evolution of the foe vehicle's distance to the conflict point.
std::vector< double > timeSpan
time points corresponding to the trajectories
std::vector< int > typeSpan
Evolution of the encounter classification (.
bool closingRequested
this flag is set by updateEncounter() or directly in processEncounters(), where encounters are closed...
std::vector< double > TTCspan
All values for TTC.
std::size_t size() const
Returns the number of trajectory points stored.
std::vector< double > MDRACspan
All values for MDRAC.
void resetExtraTime(double value)
resets remainingExtraTime to the given value
ConflictPointInfo maxMDRAC
PositionVector conflictPointSpan
Predicted location of the conflict: In case of MERGING and CROSSING: entry point to conflict area for...
ConflictPointInfo maxDRAC
double egoConflictExitTime
void countDownExtraTime(double amount)
decreases myRemaingExtraTime by given amount in seconds
Trajectory foeTrajectory
Trajectory of the foe vehicle.
std::vector< double > egoDistsToConflict
Evolution of the ego vehicle's distance to the conflict point.
Trajectory egoTrajectory
Trajectory of the ego vehicle.
double egoConflictEntryTime
Times when the ego vehicle entered/left the conflict area. Currently only applies for crossing situat...
Encounter(const MSVehicle *_ego, const MSVehicle *const _foe, double _begin, double extraTime)
Constructor.
double foeConflictExitTime
double getRemainingExtraTime() const
returns the remaining extra time
std::vector< double > PPETspan
All values for PPET.
void add(double time, EncounterType type, Position egoX, std::string egoLane, double egoLanePos, Position egoV, Position foeX, std::string foeLane, double foeLanePos, Position foeV, Position conflictPoint, double egoDistToConflict, double foeDistToConflict, double ttc, double drac, std::pair< double, double > pet, double ppet, double mdrac)
add a new data point and update encounter type
std::vector< double > DRACspan
All values for DRAC.
A device which collects info on the vehicle trip (mainly on departure and arrival)
std::map< const MSVehicle *, FoeInfo * > FoeInfoMap
double myExtraTime
Extra time in seconds to be logged after a conflict is over.
void generateOutput(OutputDevice *tripinfoOut) const
Finalizes output. Called on vehicle removal.
std::pair< std::pair< std::pair< double, Position >, double >, std::string > myMinTGAP
bool myComputeTTC
Flags for switching on / off comutation of different SSMs, derived from myMeasures.
PositionVector myGlobalMeasuresPositions
All values for positions (coordinates)
static std::set< std::string > myCreatedOutputFiles
remember which files were created already (don't duplicate xml root-elements)
bool mySaveTrajectories
This determines whether the whole trajectories of the vehicles (position, speed, ssms) shall be saved...
bool updateEncounter(Encounter *e, FoeInfo *foeInfo)
Updates the encounter (adds a new trajectory point).
static bool requestsTrajectories(const SUMOVehicle &v)
static bool getMeasuresAndThresholds(const SUMOVehicle &v, std::string deviceID, std::map< std::string, double > &thresholds)
std::string getParameter(const std::string &key) const
try to retrieve the given parameter from this device. Throw exception for unsupported key
EncounterType classifyEncounter(const FoeInfo *foeInfo, EncounterApproachInfo &eInfo) const
Classifies the current type of the encounter provided some information on the opponents.
void computeSSMs(EncounterApproachInfo &e) const
Compute current values of the logged SSMs (myMeasures) for the given encounter 'e' and update 'e' acc...
static void buildVehicleDevices(SUMOVehicle &v, std::vector< MSVehicleDevice * > &into)
Build devices for the given vehicle, if needed.
void writeOutConflict(Encounter *e)
EncounterType
Different types of encounters corresponding to relative positions of the vehicles....
@ ENCOUNTER_TYPE_EGO_ENTERED_CONFLICT_AREA
ENCOUNTER_TYPE_EGO_ENTERED_CONFLICT_AREA.
@ ENCOUNTER_TYPE_FOE_LEFT_CONFLICT_AREA
ENCOUNTER_TYPE_FOE_LEFT_CONFLICT_AREA.
@ ENCOUNTER_TYPE_MERGING
ENCOUNTER_TYPE_MERGING.
@ ENCOUNTER_TYPE_MERGING_FOLLOWER
ENCOUNTER_TYPE_MERGING_FOLLOWER.
@ ENCOUNTER_TYPE_FOLLOWING_FOLLOWER
ENCOUNTER_TYPE_FOLLOWING_FOLLOWER.
@ ENCOUNTER_TYPE_FOLLOWING
ENCOUNTER_TYPE_FOLLOWING.
@ ENCOUNTER_TYPE_MERGING_LEADER
ENCOUNTER_TYPE_MERGING_LEADER.
@ ENCOUNTER_TYPE_FOLLOWING_PASSED
ENCOUNTER_TYPE_FOLLOWING_PASSED.
@ ENCOUNTER_TYPE_FOLLOWING_LEADER
ENCOUNTER_TYPE_FOLLOWING_LEADER.
@ ENCOUNTER_TYPE_BOTH_LEFT_CONFLICT_AREA
ENCOUNTER_TYPE_BOTH_LEFT_CONFLICT_AREA.
@ ENCOUNTER_TYPE_FOE_ENTERED_CONFLICT_AREA
ENCOUNTER_TYPE_FOE_ENTERED_CONFLICT_AREA.
@ ENCOUNTER_TYPE_ONCOMING
@ ENCOUNTER_TYPE_MERGING_PASSED
ENCOUNTER_TYPE_FOLLOWING_PASSED.
@ ENCOUNTER_TYPE_ON_ADJACENT_LANES
ENCOUNTER_TYPE_ON_ADJACENT_LANES.
@ ENCOUNTER_TYPE_EGO_LEFT_CONFLICT_AREA
ENCOUNTER_TYPE_EGO_LEFT_CONFLICT_AREA.
@ ENCOUNTER_TYPE_BOTH_ENTERED_CONFLICT_AREA
ENCOUNTER_TYPE_BOTH_ENTERED_CONFLICT_AREA.
@ ENCOUNTER_TYPE_NOCONFLICT_AHEAD
ENCOUNTER_TYPE_NOCONFLICT_AHEAD.
@ ENCOUNTER_TYPE_COLLISION
ENCOUNTER_TYPE_COLLISION.
@ ENCOUNTER_TYPE_CROSSING
ENCOUNTER_TYPE_CROSSING.
@ ENCOUNTER_TYPE_CROSSING_FOLLOWER
ENCOUNTER_TYPE_CROSSING_FOLLOWER.
@ ENCOUNTER_TYPE_MERGING_ADJACENT
ENCOUNTER_TYPE_MERGING_ADJACENT.
@ ENCOUNTER_TYPE_CROSSING_LEADER
ENCOUNTER_TYPE_CROSSING_LEADER.
std::priority_queue< Encounter *, std::vector< Encounter * >, Encounter::compare > EncounterQueue
static std::string writeNA(double v, double NA=INVALID_DOUBLE)
static void initEdgeFilter()
initialize edge filter (once)
std::vector< double > myGlobalMeasuresLanesPositions
All values for positions on the lanes.
bool notifyMove(SUMOTrafficObject &veh, double oldPos, double newPos, double newSpeed)
Checks for waiting steps when the vehicle moves.
static void determineConflictPoint(EncounterApproachInfo &eInfo)
Calculates the (x,y)-coordinate for the eventually predicted conflict point and stores the result in ...
static double computeDRAC(double gap, double followerSpeed, double leaderSpeed)
Computes the DRAC (deceleration to avoid a collision) for a lead/follow situation as defined,...
EncounterQueue myPastConflicts
Past encounters that where qualified as conflicts and are not yet flushed to the output file.
static bool useGeoCoords(const SUMOVehicle &v)
void setParameter(const std::string &key, const std::string &value)
try to set the given parameter for this device. Throw exception for unsupported key
static double getMDRAC_PRT(const SUMOVehicle &v)
static bool myEdgeFilterInitialized
static const std::set< MSDevice_SSM *, ComparatorNumericalIdLess > & getInstances()
returns all currently existing SSM devices
void closeEncounter(Encounter *e)
Finalizes the encounter and calculates SSM values.
static std::string makeStringWithNAs(const std::vector< double > &v, const double NA)
make a string of a double vector and treat a special value as invalid ("NA")
static bool writePositions(const SUMOVehicle &v)
void determineTTCandDRACandPPETandMDRAC(EncounterApproachInfo &eInfo) const
Discriminates between different encounter types and correspondingly determines TTC and DRAC for those...
static double getDetectionRange(const SUMOVehicle &v)
static void cleanup()
Clean up remaining devices instances.
static void insertOptions(OptionsCont &oc)
Inserts MSDevice_SSM-options.
double myRange
Detection range. For vehicles closer than this distance from the ego vehicle, SSMs are traced.
const MSLane * findFoeConflictLane(const MSVehicle *foe, const MSLane *egoConflictLane, double &distToConflictLane) const
Computes the conflict lane for the foe.
std::vector< std::string > myGlobalMeasuresLaneIDs
All values for lanes.
std::vector< int > myDroppedConflictTypes
Which conflict types to exclude from the output.
static int myIssuedParameterWarnFlags
bitset storing info whether warning has already been issued about unset parameter (warn only once!...
bool notifyLeave(SUMOTrafficObject &veh, double lastPos, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Called whenever the holder leaves a lane.
std::vector< Encounter * > EncounterVector
static void getUpstreamVehicles(const UpstreamScanStartInfo &scanStart, FoeInfoMap &foeCollector, std::set< const MSLane * > &seenLanes, const std::set< const MSJunction * > &routeJunctions)
Collects all vehicles within range 'range' upstream of the position 'pos' on the edge 'edge' into foe...
void createEncounters(FoeInfoMap &foes)
Makes new encounters for all given vehicles (these should be the ones entering the device's range in ...
static const std::set< int > FOE_ENCOUNTERTYPES
bool qualifiesAsConflict(Encounter *e)
Tests if the SSM values exceed the threshold for qualification as conflict.
std::map< std::string, double > myThresholds
static std::string getOutputFilename(const SUMOVehicle &v, std::string deviceID)
void updateAndWriteOutput()
This is called once per time step in MSNet::writeOutput() and collects the surrounding vehicles,...
static double computeMDRAC(double gap, double followerSpeed, double leaderSpeed, double prt)
Computes the MDRAC (deceleration to avoid a collision) for a lead/follow situation as defined conside...
static std::set< MSDevice_SSM *, ComparatorNumericalIdLess > * myInstances
All currently existing SSM devices.
std::pair< std::pair< std::pair< double, Position >, double >, std::string > myMinSGAP
OutputDevice * myOutputFile
Output device.
static double getExtraTime(const SUMOVehicle &v)
EncounterVector myActiveEncounters
std::vector< double > myGlobalMeasuresTimeSpan
void computeGlobalMeasures()
Stores measures, that are not associated to a specific encounter as headways and brake rates.
static std::string encounterToString(EncounterType type)
double myOldestActiveEncounterBegin
begin time of the oldest active encounter
static void checkConflictEntryAndExit(EncounterApproachInfo &eInfo)
Checks whether ego or foe have entered or left the conflict area in the last step and eventually writ...
double computeTTC(double gap, double followerSpeed, double leaderSpeed) const
Computes the time to collision (in seconds) for two vehicles with a given initial gap under the assum...
void flushConflicts(bool all=false)
Writes out all past conflicts that have begun earlier than the oldest active encounter.
void determinePET(EncounterApproachInfo &eInfo) const
Discriminates between different encounter types and correspondingly determines the PET for those case...
static std::set< const MSEdge * > myEdgeFilter
spatial filter for SSM device output
MSDevice_SSM(SUMOVehicle &holder, const std::string &id, std::string outputFilename, std::map< std::string, double > thresholds, bool trajectories, double range, double extraTime, bool useGeoCoords, bool writePositions, bool writeLanesPositions, std::vector< int > conflictOrder)
Constructor.
static const std::set< int > EGO_ENCOUNTERTYPES
static void toGeo(Position &x)
convert SUMO-positions to geo coordinates (in place)
static void findSurroundingVehicles(const MSVehicle &veh, double range, FoeInfoMap &foeCollector)
Returns all vehicles, which are within the given range of the given vehicle.
bool myWritePositions
Wether to print the positions for all timesteps.
void resetEncounters()
Closes all current Encounters and moves conflicts to myPastConflicts,.
std::pair< std::pair< double, Position >, double > myMaxBR
Extremal values for the global measures (as <<<time, Position>, value>, [leaderID]>-pairs)
std::vector< double > myBRspan
All values for brake rate.
bool myFilterConflictTypes
Whether to exclude certain conflicts containing certain conflict types from the output.
bool myUseGeoCoords
Whether to use the original coordinate system for output.
bool myWriteLanesPositions
Wether to print the lanes and positions for all timesteps and conflicts.
@ SSM_WARN_CONFLICTFILTER
static bool filterByConflictType(const SUMOVehicle &v, std::string deviceID, std::vector< int > &conflictTypes)
~MSDevice_SSM()
Destructor.
double myMDRACPRT
perception reaction time for MDRAC
const std::string deviceName() const
return the name for this type of device
static bool myEdgeFilterActive
void flushGlobalMeasures()
Write out all non-encounter specific measures as headways and braking rates.
std::vector< double > myTGAPspan
All values for time gap.
static void getVehiclesOnJunction(const MSJunction *, const MSLane *egoJunctionLane, double egoDistToConflictLane, const MSLane *const egoConflictLane, FoeInfoMap &foeCollector, std::set< const MSLane * > &seenLanes)
Collects all vehicles on the junction into foeCollector.
static void estimateConflictTimes(EncounterApproachInfo &eInfo)
Estimates the time until conflict for the vehicles based on the distance to the conflict entry points...
bool notifyEnter(SUMOTrafficObject &veh, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Called whenever the holder enteres a lane.
void updatePassedEncounter(Encounter *e, FoeInfo *foeInfo, EncounterApproachInfo &eInfo)
Updates an encounter, which was classified as ENCOUNTER_TYPE_NOCONFLICT_AHEAD this may be the case be...
void processEncounters(FoeInfoMap &foes, bool forceClose=false)
Finds encounters for which the foe vehicle has disappeared from range. remainingExtraTime is decrease...
static bool writeLanesPositions(const SUMOVehicle &v)
std::vector< double > mySGAPspan
All values for space gap.
static void insertDefaultAssignmentOptions(const std::string &deviceName, const std::string &optionsTopic, OptionsCont &oc, const bool isPerson=false)
Adds common command options that allow to assign devices to vehicles.
static bool equippedByDefaultAssignmentOptions(const OptionsCont &oc, const std::string &deviceName, DEVICEHOLDER &v, bool outputOptionSet, const bool isPerson=false)
Determines whether a vehicle should get a certain device.
A road/street connecting two junctions.
bool isCrossing() const
return whether this edge is a pedestrian crossing
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
const MSEdge * getOppositeEdge() const
Returns the opposite direction edge if on exists else a nullptr.
const MSJunction * getToJunction() const
double getLength() const
return the length of the edge
const MSJunction * getFromJunction() const
bool isInternal() const
return whether this edge is an internal edge
static bool dictionary(const std::string &id, MSEdge *edge)
Inserts edge into the static dictionary Returns true if the key id isn't already in the dictionary....
The base class for an intersection.
virtual const std::vector< MSLane * > & getFoeInternalLanes(const MSLink *const) const
virtual const std::vector< MSLane * > getInternalLanes() const
Returns all internal lanes on the junction.
const ConstMSEdgeVector & getOutgoing() const
const ConstMSEdgeVector & getIncoming() const
Representation of a lane in the micro simulation.
const MSLink * getEntryLink() const
Returns the entry link if this is an internal lane, else nullptr.
const MSLink * getLinkTo(const MSLane *const) const
returns the link to the given lane or nullptr, if it is not connected
std::vector< MSVehicle * > VehCont
Container for vehicles.
const std::vector< IncomingLaneInfo > & getIncomingLanes() const
double getLength() const
Returns the lane's length.
const MSLane * getFirstInternalInConnection(double &offset) const
Returns 0 if the lane is not internal. Otherwise the first part of the connection (sequence of intern...
MSLane * getCanonicalSuccessorLane() const
virtual const PositionVector & getShape(bool) const
MSLane * getParallelOpposite() const
return the opposite direction lane of this lanes edge or nullptr
MSEdge & getEdge() const
Returns the lane's edge.
double getWidth() const
Returns the lane's width.
const std::vector< MSLink * > & getLinkCont() const
returns the container with all links !!!
const std::vector< const MSLane * > & getFoeLanes() const
const MSLane * getInternalLaneBefore() const
return myInternalLaneBefore (always 0 when compiled without internal lanes)
MSJunction * getJunction() const
MSLane * getLane() const
Returns the connected lane.
int getIndex() const
Returns the respond index (for visualization)
const MSLane * getLaneBefore() const
return the internalLaneBefore if it exists and the laneBefore otherwise
const std::vector< MSLink * > & getFoeLinks() const
bool isInternalJunctionLink() const
return whether the fromLane and the toLane of this link are internal lanes
MSLane * getViaLane() const
Returns the following inner lane.
double getInternalLengthsAfter() const
Returns the cumulative length of all internal lanes after this link.
double getLengthsBeforeCrossing(const MSLane *foeLane) const
Returns the sum of the lengths along internal lanes following this link to the crossing with the give...
const MSLink * getCorrespondingExitLink() const
returns the corresponding exit link for entryLinks to a junction.
Notification
Definition of a vehicle state.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
MSJunctionControl & getJunctionControl()
Returns the junctions control.
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
MSRouteIterator end() const
Returns the end of the list of edges to pass.
SUMOVehicle * getVehicle(const std::string &id) const
Returns the vehicle with the given id.
Abstract in-vehicle device.
SUMOVehicle & myHolder
The vehicle that stores the device.
Representation of a vehicle in the micro simulation.
bool isOnRoad() const
Returns the information whether the vehicle is on a road (is simulated)
MSAbstractLaneChangeModel & getLaneChangeModel()
Position getPositionAlongBestLanes(double offset) const
Return the (x,y)-position, which the vehicle would reach if it continued along its best continuation ...
double getMaxSpeedOnLane() const
Returns the maximal speed for the vehicle on its current lane (including speed factor and deviation,...
double getAcceleration() const
Returns the vehicle's acceleration in m/s (this is computed as the last step's mean acceleration in c...
Position getPosition(const double offset=0) const
Return current position (x/y, cartesian)
const std::vector< MSLane * > & getBestLanesContinuation() const
Returns the best sequence of lanes to continue the route starting at myLane.
double getBackPositionOnLane(const MSLane *lane) const
Get the vehicle's position relative to the given lane.
std::pair< const MSVehicle *const, double > getLeader(double dist=0) const
Returns the leader of the vehicle looking for a fixed distance.
const MSLane * getLane() const
Returns the lane the vehicle is on.
double getLastStepDist() const
Get the distance the vehicle covered in the previous timestep.
double getLateralPositionOnLane() const
Get the vehicle's lateral position on the lane.
double getSpeed() const
Returns the vehicle's current speed.
const MSCFModel & getCarFollowModel() const
Returns the vehicle's car following model definition.
double getPositionOnLane() const
Get the vehicle's position along the lane.
double getPreviousSpeed() const
Returns the vehicle's speed before the previous time step.
Position getVelocityVector() const
Returns the vehicle's direction in radians.
double getWidth() const
Get the width which vehicles of this class shall have when being drawn.
double getMinGap() const
Get the free space in front of vehicles of this class.
double getLength() const
Get vehicle's length [m].
const SUMOVTypeParameter & getParameter() const
static std::string getIDSecure(const T *obj, const std::string &fallBack="NULL")
get an identifier for Named-like object which may be Null
const std::string & getID() const
Returns the id.
T get(const std::string &id) const
Retrieves an item.
A storage for options typed value containers)
void addDescription(const std::string &name, const std::string &subtopic, const std::string &description)
Adds a description for an option.
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
bool isDefault(const std::string &name) const
Returns the information whether the named option has still the default value.
void doRegister(const std::string &name, Option *o)
Adds an option under the given name.
void addOptionSubTopic(const std::string &topic)
Adds an option subtopic.
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
static OptionsCont & getOptions()
Retrieves the options.
Static storage of an output device and its base (abstract) implementation.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
static OutputDevice & getDevice(const std::string &name, bool usePrefix=true)
Returns the described OutputDevice.
bool writeXMLHeader(const std::string &rootElement, const std::string &schemaFile, std::map< SumoXMLAttr, std::string > attrs=std::map< SumoXMLAttr, std::string >(), bool includeConfig=true)
Writes an XML header with optional configuration.
virtual const std::string getParameter(const std::string &key, const std::string defaultValue="") const
Returns the value for a given key.
bool knowsParameter(const std::string &key) const
Returns whether the parameter is known.
A point in 2D or 3D with translation and scaling methods.
static const Position INVALID
used to indicate that a position is valid
double distanceTo(const Position &p2) const
returns the euclidean distance in 3 dimension
double rotationAtOffset(double pos) const
Returns the rotation at the given length.
Representation of a vehicle, person, or container.
virtual bool isVehicle() const
Whether it is a vehicle.
virtual const MSVehicleType & getVehicleType() const =0
Returns the object's "vehicle" type.
virtual const MSLane * getLane() const =0
Returns the lane the object is currently at.
virtual const SUMOVehicleParameter & getParameter() const =0
Returns the vehicle's parameter (including departure definition)
virtual const MSEdge * getEdge() const =0
Returns the edge the object is currently at.
Representation of a vehicle.
virtual bool isOnRoad() const =0
Returns the information whether the vehicle is on a road (is simulated)
virtual const ConstMSEdgeVector::const_iterator & getCurrentRouteEdge() const =0
Returns an iterator pointing to the current edge in this vehicles route.
virtual const MSRoute & getRoute() const =0
Returns the current route.
std::vector< std::string > getVector()
return vector of strings
bool hasNext()
returns the information whether further substrings exist
std::string next()
returns the next substring when it exists. Otherwise the behaviour is undefined
static std::string urlDecode(const std::string &encoded)
decode url (stem from http://bogomip.net/blog/cpp-url-encoding-and-decoding/)
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter
static bool startsWith(const std::string &str, const std::string prefix)
Checks whether a given string starts with the prefix.
static bool toBool(const std::string &sData)
converts a string into the bool value described by it by calling the char-type converter
EncounterType type
Type of the conflict.
double time
time point of the conflict
double speed
speed of the reporting vehicle at the given time/position
Position pos
Predicted location of the conflict: In case of MERGING and CROSSING: entry point to conflict area for...
double value
value of the corresponding SSM
std::vector< std::string > lane
std::vector< double > lanePos
Structure to collect some info on the encounter needed during ssm calculation by various functions.
double egoConflictEntryDist
double egoConflictAreaLength
EncounterApproachInfo(Encounter *e)
double foeConflictAreaLength
double foeConflictExitDist
double egoConflictExitDist
double foeEstimatedConflictEntryTime
std::pair< double, double > pet
double foeEstimatedConflictExitTime
double egoEstimatedConflictExitTime
double foeConflictEntryDist
double egoEstimatedConflictEntryTime
const MSLane * egoConflictLane
double egoDistToConflictLane
Auxiliary structure used to handle upstream scanning start points Upstream scan has to be started aft...
double egoDistToConflictLane
const MSLane * egoConflictLane