Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2002-2026 German Aerospace Center (DLR) and others.
4 : // This program and the accompanying materials are made available under the
5 : // terms of the Eclipse Public License 2.0 which is available at
6 : // https://www.eclipse.org/legal/epl-2.0/
7 : // This Source Code may also be made available under the following Secondary
8 : // Licenses when the conditions for such availability set forth in the Eclipse
9 : // Public License 2.0 are satisfied: GNU General Public License, version 2
10 : // or later which is available at
11 : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 : /****************************************************************************/
14 : /// @file MSLeaderInfo.cpp
15 : /// @author Jakob Erdmann
16 : /// @date Oct 2015
17 : ///
18 : // Information about vehicles ahead (may be multiple vehicles if
19 : // lateral-resolution is active)
20 : /****************************************************************************/
21 : #include <config.h>
22 :
23 : #include <cassert>
24 : #include <cmath>
25 : #include <utils/common/ToString.h>
26 : #include <microsim/MSGlobals.h>
27 : #include <microsim/MSVehicle.h>
28 : #include <microsim/lcmodels/MSAbstractLaneChangeModel.h>
29 : #include <microsim/MSNet.h>
30 : #include <microsim/MSLane.h>
31 : #include "MSLeaderInfo.h"
32 :
33 :
34 : // ===========================================================================
35 : // MSLeaderInfo member method definitions
36 : // ===========================================================================
37 2011030777 : MSLeaderInfo::MSLeaderInfo(const double laneWidth, const MSVehicle* ego, const double latOffset) :
38 2011030777 : myWidth(laneWidth),
39 2011030777 : myOffset(0),
40 2011030777 : myVehicles(MAX2(1, int(ceil(laneWidth / MSGlobals::gLateralResolution))), (MSVehicle*)nullptr),
41 2011030777 : myFreeSublanes((int)myVehicles.size()),
42 2011030777 : egoRightMost(-1),
43 2011030777 : egoLeftMost(-1),
44 2011030777 : myHasVehicles(false) {
45 2011030777 : if (ego != nullptr) {
46 260760229 : getSubLanes(ego, latOffset, egoRightMost, egoLeftMost);
47 : // filter out sublanes not of interest to ego
48 260760229 : myFreeSublanes -= egoRightMost;
49 260760229 : myFreeSublanes -= (int)myVehicles.size() - 1 - egoLeftMost;
50 : }
51 2011030777 : }
52 :
53 :
54 4469335448 : MSLeaderInfo::~MSLeaderInfo() { }
55 :
56 :
57 : int
58 1346151701 : MSLeaderInfo::addLeader(const MSVehicle* veh, bool beyond, double latOffset) {
59 1346151701 : if (veh == nullptr) {
60 0 : return myFreeSublanes;
61 : }
62 1346151701 : if (myVehicles.size() == 1) {
63 : // speedup for the simple case
64 713445493 : if (!beyond || myVehicles[0] == 0) {
65 713445493 : myVehicles[0] = veh;
66 713445493 : myFreeSublanes = 0;
67 713445493 : myHasVehicles = true;
68 : }
69 713445493 : return myFreeSublanes;
70 : }
71 : // map center-line based coordinates into [0, myWidth] coordinates
72 : int rightmost, leftmost;
73 632706208 : getSubLanes(veh, latOffset, rightmost, leftmost);
74 : //if (gDebugFlag1) std::cout << " addLeader veh=" << veh->getID() << " beyond=" << beyond << " latOffset=" << latOffset << " sublaneOffset=" << myOffset
75 : // << " rightmost=" << rightmost << " leftmost=" << leftmost
76 : // << " eRM=" << egoRightMost << " eLM=" << egoLeftMost
77 : // << " myFreeSublanes=" << myFreeSublanes << "\n";
78 2645292483 : for (int sublane = rightmost; sublane <= leftmost; ++sublane) {
79 19165846 : if ((egoRightMost < 0 || (egoRightMost <= sublane && sublane <= egoLeftMost))
80 2021653910 : && (!beyond || myVehicles[sublane] == 0)) {
81 1675936334 : if (myVehicles[sublane] == 0) {
82 1010686977 : myFreeSublanes--;
83 : }
84 1675936334 : myVehicles[sublane] = veh;
85 1675936334 : myHasVehicles = true;
86 : }
87 : }
88 632706208 : return myFreeSublanes;
89 : }
90 :
91 :
92 : void
93 397180 : MSLeaderInfo::clear() {
94 397180 : myVehicles.assign(myVehicles.size(), (MSVehicle*)nullptr);
95 397180 : myFreeSublanes = (int)myVehicles.size();
96 397180 : if (egoRightMost >= 0) {
97 0 : myFreeSublanes -= egoRightMost;
98 0 : myFreeSublanes -= (int)myVehicles.size() - 1 - egoLeftMost;
99 : }
100 397180 : }
101 :
102 :
103 : void
104 4824500428 : MSLeaderInfo::getSubLanes(const MSVehicle* veh, double latOffset, int& rightmost, int& leftmost) const {
105 4824500428 : if (myVehicles.size() == 1) {
106 : // speedup for the simple case
107 1035959363 : rightmost = 0;
108 1035959363 : leftmost = 0;
109 1035959363 : return;
110 : }
111 : // map center-line based coordinates into [0, myWidth] coordinates
112 3788541065 : const double vehCenter = veh->getLateralPositionOnLane() + 0.5 * myWidth + latOffset + myOffset * MSGlobals::gLateralResolution;
113 3788541065 : const double vehHalfWidth = 0.5 * veh->getVehicleType().getWidth();
114 3788541065 : double rightVehSide = vehCenter - vehHalfWidth;
115 3788541065 : double leftVehSide = vehCenter + vehHalfWidth;
116 : // Reserve some additional space if the vehicle is performing a maneuver continuation.
117 3788541065 : if (veh->getActionStepLength() != DELTA_T) {
118 232917545 : if (veh->getLaneChangeModel().getManeuverDist() < 0. || veh->getLaneChangeModel().getSpeedLat() < 0.) {
119 12859406 : const double maneuverDist = MIN2(veh->getVehicleType().getMaxSpeedLat() * veh->getActionStepLengthSecs(), -MIN2(0., veh->getLaneChangeModel().getManeuverDist()));
120 6429703 : rightVehSide -= maneuverDist;
121 : }
122 232917545 : if (veh->getLaneChangeModel().getManeuverDist() > 0. || veh->getLaneChangeModel().getSpeedLat() > 0.) {
123 17784576 : const double maneuverDist = MIN2(veh->getVehicleType().getMaxSpeedLat() * veh->getActionStepLengthSecs(), MAX2(0., veh->getLaneChangeModel().getManeuverDist()));
124 8892288 : leftVehSide += maneuverDist;
125 : }
126 : }
127 3788541065 : if (rightVehSide > myWidth || leftVehSide < 0) {
128 : // vehicle does not touch this lane
129 : // set the values so that an iteration
130 : // for (i = rightmost; i <= leftmost; i++) stops immediately
131 44282152 : rightmost = -1000;
132 44282152 : leftmost = -2000;
133 : } else {
134 3744258913 : rightmost = MAX2(0, (int)floor((rightVehSide + NUMERICAL_EPS) / MSGlobals::gLateralResolution));
135 7488434878 : leftmost = MIN2((int)myVehicles.size() - 1, (int)floor(MAX2(0.0, leftVehSide - NUMERICAL_EPS) / MSGlobals::gLateralResolution));
136 : }
137 : //if (veh->isSelected()) std::cout << SIMTIME << " veh=" << veh->getID()
138 : // << std::setprecision(2)
139 : // << " posLat=" << veh->getLateralPositionOnLane()
140 : // << " latOffset=" << latOffset
141 : // << " vehCenter=" << vehCenter
142 : // << " rightVehSide=" << rightVehSide
143 : // << " leftVehSide=" << leftVehSide
144 : // << " rightmost=" << rightmost
145 : // << " leftmost=" << leftmost
146 : // << " myOffset=" << myOffset
147 : // << std::setprecision(2)
148 : // << "\n";
149 : }
150 :
151 :
152 : void
153 455653430 : MSLeaderInfo::getSublaneBorders(int sublane, double latOffset, double& rightSide, double& leftSide) const {
154 : assert(sublane >= 0);
155 : assert(sublane < (int)myVehicles.size());
156 455653430 : const double res = MSGlobals::gLateralResolution > 0 ? MSGlobals::gLateralResolution : myWidth;
157 455653430 : rightSide = sublane * res + latOffset - myOffset * MSGlobals::gLateralResolution;
158 455653430 : leftSide = MIN2((sublane + 1) * res, myWidth) + latOffset - myOffset * MSGlobals::gLateralResolution;
159 455653430 : }
160 :
161 :
162 : const MSVehicle*
163 4452515899 : MSLeaderInfo::operator[](int sublane) const {
164 : assert(sublane >= 0);
165 : assert(sublane < (int)myVehicles.size());
166 4452515899 : return myVehicles[sublane];
167 : }
168 :
169 :
170 : std::string
171 0 : MSLeaderInfo::toString() const {
172 0 : std::ostringstream oss;
173 : oss.setf(std::ios::fixed, std::ios::floatfield);
174 : oss << std::setprecision(2);
175 0 : for (int i = 0; i < (int)myVehicles.size(); ++i) {
176 0 : oss << Named::getIDSecure(myVehicles[i]);
177 0 : if (i < (int)myVehicles.size() - 1) {
178 0 : oss << ", ";
179 : }
180 : }
181 0 : oss << " free=" << myFreeSublanes;
182 0 : return oss.str();
183 0 : }
184 :
185 :
186 : void
187 82484200 : MSLeaderInfo::setSublaneOffset(int offset) {
188 : assert(MSGlobals::gLateralResolution > 0);
189 82484200 : myOffset = offset;
190 82484200 : }
191 :
192 :
193 : bool
194 126720786 : MSLeaderInfo::hasStoppedVehicle() const {
195 126720786 : if (!myHasVehicles) {
196 : return false;
197 : }
198 565682133 : for (int i = 0; i < (int)myVehicles.size(); ++i) {
199 456493802 : if (myVehicles[i] != 0 && myVehicles[i]->isStopped()) {
200 : return true;
201 : }
202 : }
203 : return false;
204 : }
205 :
206 :
207 : bool
208 1952605 : MSLeaderInfo::hasVehicle(const MSVehicle* veh) const {
209 1952605 : if (!myHasVehicles) {
210 : return false;
211 : }
212 6286662 : for (int i = 0; i < (int)myVehicles.size(); ++i) {
213 5291308 : if (myVehicles[i] == veh) {
214 : return true;
215 : }
216 : }
217 : return false;
218 : }
219 :
220 : void
221 138623 : MSLeaderInfo::removeOpposite(const MSLane* lane) {
222 656368 : for (int i = 0; i < (int)myVehicles.size(); ++i) {
223 517745 : const MSVehicle* veh = myVehicles[i];
224 810527 : if (veh != 0 &&
225 292782 : (veh->getLaneChangeModel().isOpposite()
226 287384 : || &lane->getEdge() != &veh->getLane()->getEdge())) {
227 8268 : myVehicles[i] = nullptr;
228 : }
229 : }
230 138623 : }
231 :
232 :
233 : // ===========================================================================
234 : // MSLeaderDistanceInfo member method definitions
235 : // ===========================================================================
236 669809148 : MSLeaderDistanceInfo::MSLeaderDistanceInfo(const double laneWidth, const MSVehicle* ego, const double latOffset) :
237 : MSLeaderInfo(laneWidth, ego, latOffset),
238 669809148 : myDistances(myVehicles.size(), std::numeric_limits<double>::max()) {
239 669809148 : }
240 :
241 :
242 487943030 : MSLeaderDistanceInfo::MSLeaderDistanceInfo(const CLeaderDist& cLeaderDist, const double laneWidth) :
243 : MSLeaderInfo(laneWidth, nullptr, 0.),
244 487943030 : myDistances(1, cLeaderDist.second) {
245 : assert(myVehicles.size() == 1);
246 487943030 : myVehicles[0] = cLeaderDist.first;
247 487943030 : myHasVehicles = cLeaderDist.first != nullptr;
248 487943030 : }
249 :
250 1774494472 : MSLeaderDistanceInfo::~MSLeaderDistanceInfo() { }
251 :
252 :
253 : int
254 573250919 : MSLeaderDistanceInfo::addLeader(const MSVehicle* veh, double gap, double latOffset, int sublane) {
255 : //if (SIMTIME == 31 && gDebugFlag1 && veh != 0 && veh->getID() == "cars.8") {
256 : // std::cout << " BREAKPOINT\n";
257 : //}
258 573250919 : if (veh == nullptr) {
259 1225925 : return myFreeSublanes;
260 : }
261 572024994 : if (myVehicles.size() == 1) {
262 : // speedup for the simple case
263 : sublane = 0;
264 : }
265 572024994 : if (sublane >= 0 && sublane < (int)myVehicles.size()) {
266 : // sublane is already given
267 570410035 : if (gap < myDistances[sublane]) {
268 424190019 : if (myVehicles[sublane] == 0) {
269 420692085 : myFreeSublanes--;
270 : }
271 424190019 : myVehicles[sublane] = veh;
272 424190019 : myDistances[sublane] = gap;
273 424190019 : myHasVehicles = true;
274 : }
275 570410035 : return myFreeSublanes;
276 : }
277 : int rightmost, leftmost;
278 1614959 : getSubLanes(veh, latOffset, rightmost, leftmost);
279 : //if (gDebugFlag1) std::cout << " addLeader veh=" << veh->getID() << " gap=" << gap << " latOffset=" << latOffset << " sublaneOffset=" << myOffset
280 : // << " rightmost=" << rightmost << " leftmost=" << leftmost
281 : // << " eRM=" << egoRightMost << " eLM=" << egoLeftMost
282 : // << " myFreeSublanes=" << myFreeSublanes << "\n";
283 6182717 : for (int sublaneIdx = rightmost; sublaneIdx <= leftmost; ++sublaneIdx) {
284 582133 : if ((egoRightMost < 0 || (egoRightMost <= sublaneIdx && sublaneIdx <= egoLeftMost))
285 5053906 : && gap < myDistances[sublaneIdx]) {
286 1866434 : if (myVehicles[sublaneIdx] == 0) {
287 1636573 : myFreeSublanes--;
288 : }
289 1866434 : myVehicles[sublaneIdx] = veh;
290 1866434 : myDistances[sublaneIdx] = gap;
291 1866434 : myHasVehicles = true;
292 : }
293 : }
294 1614959 : return myFreeSublanes;
295 : }
296 :
297 :
298 : void
299 1247814 : MSLeaderDistanceInfo::addLeaders(MSLeaderDistanceInfo& other) {
300 : const int maxSubLane = MIN2(numSublanes(), other.numSublanes());
301 7276878 : for (int i = 0; i < maxSubLane; i++) {
302 6029064 : addLeader(other[i].first, other[i].second, 0, i);
303 : //if ((myDistances[i] > 0 && myDistances[i] > other.myDistances[i])
304 : // || (other.myDistances[i] < 0 && myDistances[i] < other.myDistances[i])) {
305 : // addLeader(other[i].first, other[i].second, 0, i);
306 : //}
307 : }
308 1247814 : }
309 :
310 :
311 : void
312 0 : MSLeaderDistanceInfo::clear() {
313 0 : MSLeaderInfo::clear();
314 0 : myDistances.assign(myVehicles.size(), std::numeric_limits<double>::max());
315 0 : }
316 :
317 :
318 : CLeaderDist
319 5148663878 : MSLeaderDistanceInfo::operator[](int sublane) const {
320 : assert(sublane >= 0);
321 : assert(sublane < (int)myVehicles.size());
322 5148663878 : return std::make_pair(myVehicles[sublane], myDistances[sublane]);
323 : }
324 :
325 :
326 : std::string
327 0 : MSLeaderDistanceInfo::toString() const {
328 0 : std::ostringstream oss;
329 : oss.setf(std::ios::fixed, std::ios::floatfield);
330 : oss << std::setprecision(2);
331 0 : for (int i = 0; i < (int)myVehicles.size(); ++i) {
332 0 : oss << Named::getIDSecure(myVehicles[i]) << ":";
333 0 : if (myVehicles[i] == 0) {
334 0 : oss << "inf";
335 : } else {
336 0 : oss << myDistances[i];
337 : }
338 0 : if (i < (int)myVehicles.size() - 1) {
339 0 : oss << ", ";
340 : }
341 : }
342 0 : oss << " free=" << myFreeSublanes;
343 0 : return oss.str();
344 0 : }
345 :
346 : void
347 448560 : MSLeaderDistanceInfo::fixOppositeGaps(bool isFollower) {
348 2219368 : for (int i = 0; i < (int)myVehicles.size(); ++i) {
349 1770808 : if (myVehicles[i] != nullptr) {
350 1291374 : if (myVehicles[i]->getLaneChangeModel().isOpposite()) {
351 601444 : myDistances[i] -= myVehicles[i]->getVehicleType().getLength();
352 689930 : } else if (isFollower && myDistances[i] > POSITION_EPS) {
353 : // can ignore oncoming followers once they are past
354 228687 : myVehicles[i] = nullptr;
355 228687 : myDistances[i] = -1;
356 : }
357 : }
358 : }
359 448560 : }
360 :
361 :
362 : void
363 88553 : MSLeaderDistanceInfo::patchGaps(double amount) {
364 446321 : for (int i = 0; i < (int)myVehicles.size(); ++i) {
365 357768 : if (myVehicles[i] != nullptr) {
366 323698 : myDistances[i] += amount;
367 : }
368 : }
369 88553 : }
370 :
371 : CLeaderDist
372 1365305 : MSLeaderDistanceInfo::getClosest() const {
373 : double minGap = -1;
374 : const MSVehicle* veh = nullptr;
375 1365305 : if (hasVehicles()) {
376 : minGap = std::numeric_limits<double>::max();
377 1680247 : for (int i = 0; i < (int)myVehicles.size(); ++i) {
378 992370 : if (myVehicles[i] != nullptr && myDistances[i] < minGap) {
379 : minGap = myDistances[i];
380 : veh = myVehicles[i];
381 : }
382 : }
383 : }
384 1365305 : return std::make_pair(veh, minGap);
385 : }
386 :
387 :
388 : void
389 13405123 : MSLeaderDistanceInfo::moveSamePosTo(const MSVehicle* ego, MSLeaderDistanceInfo& other) {
390 13405123 : const double pos = ego->getPositionOnLane();
391 70022855 : for (int i = 0; i < (int)myVehicles.size(); ++i) {
392 56617732 : if (myVehicles[i] != nullptr && myDistances[i] < 0 && myVehicles[i]->getPositionOnLane() == pos
393 57833134 : && &myVehicles[i]->getLane()->getEdge() == &ego->getLane()->getEdge()) {
394 1215207 : other.myVehicles[i] = myVehicles[i];
395 1215207 : other.myDistances[i] = myDistances[i];
396 1215207 : myVehicles[i] = nullptr;
397 1215207 : myDistances[i] = -1;
398 : }
399 : }
400 13405123 : }
401 :
402 :
403 : double
404 28785 : MSLeaderDistanceInfo::getMinDistToStopped() const {
405 : double result = std::numeric_limits<double>::max();
406 28785 : if (!myHasVehicles) {
407 : return result;
408 : }
409 143498 : for (int i = 0; i < (int)myVehicles.size(); ++i) {
410 114713 : if (myVehicles[i] != 0 && myVehicles[i]->isStopped()) {
411 56830 : result = MIN2(result, myDistances[i]);
412 : }
413 : }
414 : return result;
415 : }
416 :
417 :
418 : // ===========================================================================
419 : // MSCriticalFollowerDistanceInfo member method definitions
420 : // ===========================================================================
421 :
422 :
423 308907351 : MSCriticalFollowerDistanceInfo::MSCriticalFollowerDistanceInfo(const double laneWidth, const MSVehicle* ego, const double latOffset, const bool haveOppositeLeaders) :
424 : MSLeaderDistanceInfo(laneWidth, ego, latOffset),
425 617814702 : myMissingGaps(myVehicles.size(), -std::numeric_limits<double>::max()),
426 308907351 : myHaveOppositeLeaders(haveOppositeLeaders)
427 308907351 : { }
428 :
429 :
430 308907351 : MSCriticalFollowerDistanceInfo::~MSCriticalFollowerDistanceInfo() { }
431 :
432 :
433 : int
434 2924489539 : MSCriticalFollowerDistanceInfo::addFollower(const MSVehicle* veh, const MSVehicle* ego, double gap, double latOffset, int sublane) {
435 2924489539 : if (veh == nullptr) {
436 4107135 : return myFreeSublanes;
437 : }
438 2920382404 : const double requiredGap = (myHaveOppositeLeaders ? 0
439 2914744771 : : veh->getCarFollowModel().getSecureGap(veh, ego, veh->getSpeed(), ego->getSpeed(), ego->getCarFollowModel().getMaxDecel()));
440 2920382404 : const double missingGap = requiredGap - gap;
441 : /*
442 : if (ego->getID() == "disabled" || gDebugFlag1) {
443 : std::cout << " addFollower veh=" << veh->getID()
444 : << " ego=" << ego->getID()
445 : << " gap=" << gap
446 : << " reqGap=" << requiredGap
447 : << " missingGap=" << missingGap
448 : << " latOffset=" << latOffset
449 : << " sublane=" << sublane
450 : << "\n";
451 : if (sublane > 0) {
452 : std::cout
453 : << " dists[s]=" << myDistances[sublane]
454 : << " gaps[s]=" << myMissingGaps[sublane]
455 : << "\n";
456 : } else {
457 : std::cout << toString() << "\n";
458 : }
459 : }
460 : */
461 2920382404 : if (myVehicles.size() == 1) {
462 : // speedup for the simple case
463 : sublane = 0;
464 : }
465 2920382404 : if (sublane >= 0 && sublane < (int)myVehicles.size()) {
466 : // sublane is already given
467 : // overlapping vehicles are stored preferably
468 : // among those vehicles with missing gap, closer ones are preferred
469 208622519 : if ((missingGap > myMissingGaps[sublane]
470 91182903 : || (missingGap > 0 && gap < myDistances[sublane])
471 91178075 : || (gap < 0 && myDistances[sublane] > 0))
472 117444447 : && !(gap > 0 && myDistances[sublane] < 0)
473 326037924 : && !(myMissingGaps[sublane] > 0 && myDistances[sublane] < gap)
474 : ) {
475 117381896 : if (myVehicles[sublane] == 0) {
476 104594039 : myFreeSublanes--;
477 : }
478 117381896 : myVehicles[sublane] = veh;
479 117381896 : myDistances[sublane] = gap;
480 117381896 : myMissingGaps[sublane] = missingGap;
481 117381896 : myHasVehicles = true;
482 : }
483 208622519 : return myFreeSublanes;
484 : }
485 : int rightmost, leftmost;
486 2711759885 : getSubLanes(veh, latOffset, rightmost, leftmost);
487 12747352042 : for (int sublaneIdx = rightmost; sublaneIdx <= leftmost; ++sublaneIdx) {
488 1127166 : if ((egoRightMost < 0 || (egoRightMost <= sublaneIdx && sublaneIdx <= egoLeftMost))
489 : // overlapping vehicles are stored preferably
490 : // among those vehicles with missing gap, closer ones are preferred
491 10035519991 : && (missingGap > myMissingGaps[sublaneIdx]
492 54467834 : || (missingGap > 0 && gap < myDistances[sublaneIdx])
493 53109788 : || (gap < 0 && myDistances[sublaneIdx] > 0))
494 9982410215 : && !(gap > 0 && myDistances[sublaneIdx] < 0)
495 20017974380 : && !(myMissingGaps[sublaneIdx] > 0 && myDistances[sublaneIdx] < gap)
496 : ) {
497 9982364714 : if (myVehicles[sublaneIdx] == 0) {
498 740113254 : myFreeSublanes--;
499 : }
500 9982364714 : myVehicles[sublaneIdx] = veh;
501 9982364714 : myDistances[sublaneIdx] = gap;
502 9982364714 : myMissingGaps[sublaneIdx] = missingGap;
503 9982364714 : myHasVehicles = true;
504 : }
505 : }
506 2711759885 : return myFreeSublanes;
507 : }
508 :
509 :
510 : void
511 0 : MSCriticalFollowerDistanceInfo::clear() {
512 0 : MSLeaderDistanceInfo::clear();
513 0 : myMissingGaps.assign(myVehicles.size(), -std::numeric_limits<double>::max());
514 0 : }
515 :
516 :
517 : std::string
518 0 : MSCriticalFollowerDistanceInfo::toString() const {
519 0 : std::ostringstream oss;
520 : oss.setf(std::ios::fixed, std::ios::floatfield);
521 : oss << std::setprecision(2);
522 0 : for (int i = 0; i < (int)myVehicles.size(); ++i) {
523 0 : oss << Named::getIDSecure(myVehicles[i]) << ":";
524 0 : if (myVehicles[i] == 0) {
525 0 : oss << "inf:-inf";
526 : } else {
527 0 : oss << myDistances[i] << ":" << myMissingGaps[i];
528 : }
529 0 : if (i < (int)myVehicles.size() - 1) {
530 0 : oss << ", ";
531 : }
532 : }
533 0 : oss << " free=" << myFreeSublanes;
534 0 : return oss.str();
535 0 : }
536 :
537 :
538 : /****************************************************************************/
|