SUMO - Simulation of Urban MObility
MSLeaderInfo.cpp
Go to the documentation of this file.
1 /****************************************************************************/
7 // Information about vehicles ahead (may be multiple vehicles if
8 // lateral-resolution is active)
9 /****************************************************************************/
10 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
11 // Copyright (C) 2002-2017 DLR (http://www.dlr.de/) and contributors
12 /****************************************************************************/
13 //
14 // This file is part of SUMO.
15 // SUMO is free software: you can redistribute it and/or modify
16 // it under the terms of the GNU General Public License as published by
17 // the Free Software Foundation, either version 3 of the License, or
18 // (at your option) any later version.
19 //
20 /****************************************************************************/
21 
22 
23 // ===========================================================================
24 // included modules
25 // ===========================================================================
26 #ifdef _MSC_VER
27 #include <windows_config.h>
28 #else
29 #include <config.h>
30 #endif
31 
32 #include <cassert>
33 #include <cmath>
34 #include <utils/common/ToString.h>
35 #include <microsim/MSGlobals.h>
36 #include <microsim/MSVehicle.h>
37 #include <microsim/MSNet.h>
38 #include "MSLeaderInfo.h"
39 
40 
41 // ===========================================================================
42 // static member variables
43 // ===========================================================================
44 
45 
46 // ===========================================================================
47 // MSLeaderInfo member method definitions
48 // ===========================================================================
49 MSLeaderInfo::MSLeaderInfo(const MSLane* lane, const MSVehicle* ego, double latOffset) :
50  myWidth(lane->getWidth()),
51  myVehicles(MAX2(1, int(ceil(myWidth / MSGlobals::gLateralResolution))), (MSVehicle*)0),
52  myFreeSublanes((int)myVehicles.size()),
53  egoRightMost(-1),
54  egoLeftMost(-1),
55  myHasVehicles(false) {
56  if (ego != 0) {
57  getSubLanes(ego, latOffset, egoRightMost, egoLeftMost);
58  // filter out sublanes not of interest to ego
60  myFreeSublanes -= (int)myVehicles.size() - 1 - egoLeftMost;
61  }
62 }
63 
64 
66 
67 
68 int
69 MSLeaderInfo::addLeader(const MSVehicle* veh, bool beyond, double latOffset) {
70  if (veh == 0) {
71  return myFreeSublanes;
72  }
73  if (myVehicles.size() == 1) {
74  // speedup for the simple case
75  if (!beyond || myVehicles[0] == 0) {
76  myVehicles[0] = veh;
77  myFreeSublanes = 0;
78  myHasVehicles = true;
79  }
80  return myFreeSublanes;
81  }
82  // map center-line based coordinates into [0, myWidth] coordinates
83  int rightmost, leftmost;
84  getSubLanes(veh, latOffset, rightmost, leftmost);
85  //if (gDebugFlag1) std::cout << " addLeader veh=" << veh->getID() << " beyond=" << beyond << " latOffset=" << latOffset << " rightmost=" << rightmost << " leftmost=" << leftmost << " myFreeSublanes=" << myFreeSublanes << "\n";
86  for (int sublane = rightmost; sublane <= leftmost; ++sublane) {
87  if ((egoRightMost < 0 || (egoRightMost <= sublane && sublane <= egoLeftMost))
88  && (!beyond || myVehicles[sublane] == 0)) {
89  if (myVehicles[sublane] == 0) {
91  }
92  myVehicles[sublane] = veh;
93  myHasVehicles = true;
94  }
95  }
96  return myFreeSublanes;
97 }
98 
99 
100 void
102  myVehicles.assign(myVehicles.size(), (MSVehicle*)0);
103  myFreeSublanes = (int)myVehicles.size();
104  if (egoRightMost >= 0) {
106  myFreeSublanes -= (int)myVehicles.size() - 1 - egoLeftMost;
107  }
108 }
109 
110 
111 void
112 MSLeaderInfo::getSubLanes(const MSVehicle* veh, double latOffset, int& rightmost, int& leftmost) const {
113  if (myVehicles.size() == 1) {
114  // speedup for the simple case
115  rightmost = 0;
116  leftmost = 0;
117  return;
118  }
119  // map center-line based coordinates into [0, myWidth] coordinates
120  const double vehCenter = veh->getLateralPositionOnLane() + 0.5 * myWidth + latOffset;
121  const double vehHalfWidth = 0.5 * veh->getVehicleType().getWidth();
122  const double rightVehSide = MAX2(0., vehCenter - vehHalfWidth);
123  const double leftVehSide = MIN2(myWidth, vehCenter + vehHalfWidth);
124  rightmost = (int)floor((rightVehSide + NUMERICAL_EPS) / MSGlobals::gLateralResolution);
125  leftmost = MIN2((int)myVehicles.size() - 1, (int)floor((leftVehSide - NUMERICAL_EPS) / MSGlobals::gLateralResolution));
126  //if (veh->getID() == "Pepoli_11_41") std::cout << SIMTIME << " veh=" << veh->getID()
127  // << std::setprecision(10)
128  // << " posLat=" << veh->getLateralPositionOnLane()
129  // << " latOffset=" << latOffset
130  // << " rightVehSide=" << rightVehSide
131  // << " leftVehSide=" << leftVehSide
132  // << " rightmost=" << rightmost
133  // << " leftmost=" << leftmost
134  // << std::setprecision(2)
135  // << "\n";
136 }
137 
138 
139 void
140 MSLeaderInfo::getSublaneBorders(int sublane, double latOffset, double& rightSide, double& leftSide) const {
141  assert(sublane >= 0);
142  assert(sublane < (int)myVehicles.size());
143  rightSide = sublane * MSGlobals::gLateralResolution + latOffset;
144  leftSide = MIN2((sublane + 1) * MSGlobals::gLateralResolution, myWidth) + latOffset;
145 }
146 
147 
148 const MSVehicle*
149 MSLeaderInfo::operator[](int sublane) const {
150  assert(sublane >= 0);
151  assert(sublane < (int)myVehicles.size());
152  return myVehicles[sublane];
153 }
154 
155 
156 std::string
158  std::ostringstream oss;
159  oss.setf(std::ios::fixed , std::ios::floatfield);
160  oss << std::setprecision(2);
161  for (int i = 0; i < (int)myVehicles.size(); ++i) {
162  oss << Named::getIDSecure(myVehicles[i]);
163  if (i < (int)myVehicles.size() - 1) {
164  oss << ", ";
165  }
166  }
167  oss << " free=" << myFreeSublanes;
168  return oss.str();
169 }
170 
171 
172 bool
174  if (!myHasVehicles) {
175  return false;
176  }
177  for (int i = 0; i < (int)myVehicles.size(); ++i) {
178  if (myVehicles[0] != 0 && myVehicles[0]->isStopped()) {
179  return true;
180  }
181  }
182  return false;
183 }
184 
185 // ===========================================================================
186 // MSLeaderDistanceInfo member method definitions
187 // ===========================================================================
188 
189 
190 MSLeaderDistanceInfo::MSLeaderDistanceInfo(const MSLane* lane, const MSVehicle* ego, double latOffset) :
191  MSLeaderInfo(lane, ego, latOffset),
192  myDistances(myVehicles.size(), std::numeric_limits<double>::max()) {
193 }
194 
195 
197  MSLeaderInfo(dummy, 0, 0),
198  myDistances(1, cLeaderDist.second) {
199  assert(myVehicles.size() == 1);
200  myVehicles[0] = cLeaderDist.first;
201 }
202 
204 
205 
206 int
207 MSLeaderDistanceInfo::addLeader(const MSVehicle* veh, double gap, double latOffset, int sublane) {
208  //if (SIMTIME == 31 && gDebugFlag1 && veh != 0 && veh->getID() == "cars.8") {
209  // std::cout << " BREAKPOINT\n";
210  //}
211  if (veh == 0) {
212  return myFreeSublanes;
213  }
214  if (myVehicles.size() == 1) {
215  // speedup for the simple case
216  sublane = 0;
217  }
218  if (sublane >= 0 && sublane < (int)myVehicles.size()) {
219  // sublane is already given
220  if (gap < myDistances[sublane]) {
221  if (myVehicles[sublane] == 0) {
222  myFreeSublanes--;
223  }
224  myVehicles[sublane] = veh;
225  myDistances[sublane] = gap;
226  myHasVehicles = true;
227  }
228  return myFreeSublanes;
229  }
230  int rightmost, leftmost;
231  getSubLanes(veh, latOffset, rightmost, leftmost);
232  for (int sublane = rightmost; sublane <= leftmost; ++sublane) {
233  if ((egoRightMost < 0 || (egoRightMost <= sublane && sublane <= egoLeftMost))
234  && gap < myDistances[sublane]) {
235  if (myVehicles[sublane] == 0) {
236  myFreeSublanes--;
237  }
238  myVehicles[sublane] = veh;
239  myDistances[sublane] = gap;
240  myHasVehicles = true;
241  }
242  }
243  return myFreeSublanes;
244 }
245 
246 
247 void
251 }
252 
253 
256  assert(sublane >= 0);
257  assert(sublane < (int)myVehicles.size());
258  return std::make_pair(myVehicles[sublane], myDistances[sublane]);
259 }
260 
261 
262 std::string
264  std::ostringstream oss;
265  oss.setf(std::ios::fixed , std::ios::floatfield);
266  oss << std::setprecision(2);
267  for (int i = 0; i < (int)myVehicles.size(); ++i) {
268  oss << Named::getIDSecure(myVehicles[i]) << ":";
269  if (myVehicles[i] == 0) {
270  oss << "inf";
271  } else {
272  oss << myDistances[i];
273  }
274  if (i < (int)myVehicles.size() - 1) {
275  oss << ", ";
276  }
277  }
278  oss << " free=" << myFreeSublanes;
279  return oss.str();
280 }
281 
282 
283 // ===========================================================================
284 // MSCriticalFollowerDistanceInfo member method definitions
285 // ===========================================================================
286 
287 
289  MSLeaderDistanceInfo(lane, ego, latOffset),
290  myMissingGaps(myVehicles.size(), -std::numeric_limits<double>::max()) {
291 }
292 
293 
295 
296 
297 int
298 MSCriticalFollowerDistanceInfo::addFollower(const MSVehicle* veh, const MSVehicle* ego, double gap, double latOffset, int sublane) {
299  if (veh == 0) {
300  return myFreeSublanes;
301  }
302  const double requiredGap = veh->getCarFollowModel().getSecureGap(veh->getSpeed(), ego->getSpeed(), ego->getCarFollowModel().getMaxDecel());
303  const double missingGap = requiredGap - gap;
304  /*
305  if (ego->getID() == "disabled" || gDebugFlag1) {
306  std::cout << " addFollower veh=" << veh->getID()
307  << " ego=" << ego->getID()
308  << " gap=" << gap
309  << " reqGap=" << requiredGap
310  << " missingGap=" << missingGap
311  << " latOffset=" << latOffset
312  << " sublane=" << sublane
313  << "\n";
314  if (sublane > 0) {
315  std::cout
316  << " dists[s]=" << myDistances[sublane]
317  << " gaps[s]=" << myMissingGaps[sublane]
318  << "\n";
319  } else {
320  std::cout << toString() << "\n";
321  }
322  }
323  */
324  if (myVehicles.size() == 1) {
325  // speedup for the simple case
326  sublane = 0;
327  }
328  if (sublane >= 0 && sublane < (int)myVehicles.size()) {
329  // sublane is already given
330  // overlapping vehicles are stored preferably
331  if ((missingGap > myMissingGaps[sublane] || (gap < 0 && myDistances[sublane] > 0))
332  && !(gap > 0 && myDistances[sublane] < 0)) {
333  if (myVehicles[sublane] == 0) {
334  myFreeSublanes--;
335  }
336  myVehicles[sublane] = veh;
337  myDistances[sublane] = gap;
338  myMissingGaps[sublane] = missingGap;
339  myHasVehicles = true;
340  }
341  return myFreeSublanes;
342  }
343  int rightmost, leftmost;
344  getSubLanes(veh, latOffset, rightmost, leftmost);
345  for (int sublane = rightmost; sublane <= leftmost; ++sublane) {
346  if ((egoRightMost < 0 || (egoRightMost <= sublane && sublane <= egoLeftMost))
347  // overlapping vehicles are stored preferably
348  && (missingGap > myMissingGaps[sublane] || (gap < 0 && myDistances[sublane] > 0))
349  && !(gap > 0 && myDistances[sublane] < 0)) {
350  if (myVehicles[sublane] == 0) {
351  myFreeSublanes--;
352  }
353  myVehicles[sublane] = veh;
354  myDistances[sublane] = gap;
355  myMissingGaps[sublane] = missingGap;
356  myHasVehicles = true;
357  }
358  }
359  return myFreeSublanes;
360 }
361 
362 
363 void
367 }
368 
369 
370 std::string
372  std::ostringstream oss;
373  oss.setf(std::ios::fixed , std::ios::floatfield);
374  oss << std::setprecision(2);
375  for (int i = 0; i < (int)myVehicles.size(); ++i) {
376  oss << Named::getIDSecure(myVehicles[i]) << ":";
377  if (myVehicles[i] == 0) {
378  oss << "inf:-inf";
379  } else {
380  oss << myDistances[i] << ":" << myMissingGaps[i];
381  }
382  if (i < (int)myVehicles.size() - 1) {
383  oss << ", ";
384  }
385  }
386  oss << " free=" << myFreeSublanes;
387  return oss.str();
388 }
389 /****************************************************************************/
390 
static double gLateralResolution
Definition: MSGlobals.h:92
saves leader/follower vehicles and their distances relative to an ego vehicle
Definition: MSLeaderInfo.h:136
MSLeaderDistanceInfo(const MSLane *lane, const MSVehicle *ego, double latOffset)
Constructor.
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:83
virtual int addLeader(const MSVehicle *veh, bool beyond, double latOffset=0)
virtual std::string toString() const
print a debugging representation
void getSublaneBorders(int sublane, double latOffset, double &rightSide, double &leftSide) const
const MSCFModel & getCarFollowModel() const
Returns the vehicle&#39;s car following model definition.
Definition: MSVehicle.h:796
virtual ~MSCriticalFollowerDistanceInfo()
Destructor.
virtual std::string toString() const
print a debugging representation
int myFreeSublanes
the number of free sublanes
Definition: MSLeaderInfo.h:124
double getSecureGap(const double speed, const double leaderSpeed, const double leaderMaxDecel) const
Returns the minimum gap to reserve if the leader is braking at maximum (>=0)
Definition: MSCFModel.h:305
virtual void clear()
discard all information
T MAX2(T a, T b)
Definition: StdDefs.h:74
static std::string getIDSecure(const T *obj, const std::string &fallBack="NULL")
get an identifier for Named-like object which may be Null
Definition: Named.h:59
int egoRightMost
borders of the ego vehicle for filtering of free sublanes
Definition: MSLeaderInfo.h:127
double myWidth
the width of the lane to which this instance applies
Definition: MSLeaderInfo.h:117
bool hasStoppedVehicle() const
whether a stopped vehicle is leader
std::vector< double > myDistances
Definition: MSLeaderInfo.h:175
CLeaderDist operator[](int sublane) const
return the vehicle and its distance for the given sublane
virtual int addLeader(const MSVehicle *veh, double gap, double latOffset=0, int sublane=-1)
std::vector< double > myMissingGaps
Definition: MSLeaderInfo.h:225
virtual ~MSLeaderInfo()
Destructor.
#define max(a, b)
Definition: polyfonts.c:65
virtual void clear()
discard all information
const MSVehicle * operator[](int sublane) const
return the vehicle for the given sublane
double getMaxDecel() const
Get the vehicle type&#39;s maximal comfortable deceleration [m/s^2].
Definition: MSCFModel.h:212
void getSubLanes(const MSVehicle *veh, double latOffset, int &rightmost, int &leftmost) const
T MIN2(T a, T b)
Definition: StdDefs.h:68
void clear()
discard all information
virtual ~MSLeaderDistanceInfo()
Destructor.
double getWidth() const
Get the width which vehicles of this class shall have when being drawn.
std::vector< const MSVehicle * > myVehicles
Definition: MSLeaderInfo.h:119
bool myHasVehicles
Definition: MSLeaderInfo.h:130
std::pair< const MSVehicle *, double > CLeaderDist
Definition: MSLeaderInfo.h:42
int addFollower(const MSVehicle *veh, const MSVehicle *ego, double gap, double latOffset=0, int sublane=-1)
const MSVehicleType & getVehicleType() const
Returns the vehicle&#39;s type definition.
double getLateralPositionOnLane() const
Get the vehicle&#39;s lateral position on the lane.
Definition: MSVehicle.h:407
#define NUMERICAL_EPS
Definition: config.h:152
std::string toString() const
print a debugging representation
MSLeaderInfo(const MSLane *lane, const MSVehicle *ego=0, double latOffset=0)
Constructor.
Representation of a lane in the micro simulation.
Definition: MSLane.h:79
MSCriticalFollowerDistanceInfo(const MSLane *lane, const MSVehicle *ego, double latOffset)
Constructor.
double getSpeed() const
Returns the vehicle&#39;s current speed.
Definition: MSVehicle.h:443