ADORe
ADORe is a modular open source software library and toolkit for decision making, planning, control and simulation of automated vehicles
independentlanechangegeometry.h
Go to the documentation of this file.
1 /********************************************************************************
2  * Copyright (C) 2017-2020 German Aerospace Center (DLR).
3  * Eclipse ADORe, Automated Driving Open Research https://eclipse.org/adore
4  *
5  * This program and the accompanying materials are made available under the
6  * terms of the Eclipse Public License 2.0 which is available at
7  * http://www.eclipse.org/legal/epl-2.0.
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  * Daniel Heß - initial API and implementation
13  * Thomas Lobig
14  ********************************************************************************/
15 #pragma once
19 
20 namespace adore
21 {
22 namespace env
23 {
24 namespace BorderBased
25 {
34 {
35  private:
38  bool valid_;
41  public:
56 
57  public:
58  void setSmoothness(double value)
59  {
60  baseline_.setSmoothness(value);
61  }
62  void setMaximumNavCostIncrease(double value)
63  {
65  }
66  void setLookAhead(double value)
67  {
68  baseline_.setLookAhead(value);
69  lcb_.setLookAhead(value+100.0);
70  }
71  void setLookBehind(double value)
72  {
73  baseline_.setLookBehind(value);
74  lcb_.setLookBehind(value+100.0);
75 
76  }
77  bool isValid()const{return valid_;}
78  double getProgressGateOpen()const{return progressGateOpen_;}
82  {
84  }
86  {
88  }
90  {
92  }
94  {
96  }
97  IndependentLaneChangeGeometry(bool lc_direction_left,BorderSet* borderSet,BorderCostMap* borderCostMap)
98  :lcb_(lc_direction_left,borderSet,borderCostMap),borderSet_(borderSet),borderCostMap_(borderCostMap),valid_(false)
99  {
100  maximum_navcost_increase_ = 1000.0;
101  }
110  template<typename Iterator>
111  void update(double position_on_current,Iterator current_lf, Iterator first_lf, Iterator last_lf)
112  {
113  valid_ = false;
114  separatingBorders_.clear();
115  sourceOuterBorders_.clear();
116  targetOuterBorders_.clear();
117  navigationCostBorders_.clear();
118  //compute set of borders relevant for lane change
120  //lcb_.setConinueOnIncreasingCost(false);
121  lcb_.update(position_on_current,current_lf,first_lf,last_lf);
122  if(!lcb_.isValid())return;
123  //assemple border sequences from relevant borders
124  if(!collectSeparatingBorders())return;
125  if(!collectSourceOuterBorders())return;
126  if(!collectTargetOuterBorders())return;
127  if(!collectNavigationCostBorders())return;
128  //fit baseline
130  if(!baseline_.isValid())return;
135  //compute progress for gate interval
136  if(!computeGateInterval_v2())return;
137  //some checks
138  if(!sanityTest())return;
140  valid_ = true;
141  }
142 
147  bool sanityTest()
148  {
149  if(getMaximumTargetLaneWidth()<1.5)return false;
150  return true;
151  }
152 
157  {
158  double width = 0.0;
159  const double sign = lcb_.isLCDirectionLeft()?1.0:-1.0;
160  for(double s=baseline_.position_fct_.limitLo();s<baseline_.position_fct_.limitHi();s+=1.0)
161  {
162  const double outside = offsetTargetOuterBorders_(s);
163  const double inside = offsetSeparatingBorders_(s);
164  width = std::max(width,sign*(outside-inside));
165  }
166  return width;
167  }
168 
175  {
176  if(lcb_.gate_source_borders_.size()==0)return false;
177  if(lcb_.gate_target_borders_.size()==0)return false;
178  Coordinate start_coord = lcb_.isLCDirectionLeft()
179  ?lcb_.gate_target_borders_[0]->m_id.m_first
180  :lcb_.gate_source_borders_[0]->m_id.m_first;
181  Coordinate end_coord = lcb_.isLCDirectionLeft()
182  ?lcb_.gate_target_borders_.back()->m_id.m_last
183  :lcb_.gate_source_borders_.back()->m_id.m_last;
184  double n=0;//not required
185  progressGateOpen_ = baseline_.position_fct_.getClosestParameter(start_coord.m_X,start_coord.m_Y,1,2,n);
187  return true;
188  }
189 
195  {
196  if(lcb_.gate_source_borders_.size()==0)return false;
197  if(lcb_.gate_target_borders_.size()==0)return false;
198  double min_separation = 0.5;
199  bool gate_open_found = false;
201  {
202  if((std::abs)(offsetSeparatingBorders_(s)-offsetTargetOuterBorders_(s))>min_separation)
203  {
204  progressGateOpen_ = s;
205  gate_open_found = true;
206  break;
207  }
208  }
209  Coordinate end_coord = lcb_.isLCDirectionLeft()
210  ?lcb_.gate_target_borders_.back()->m_id.m_last
211  :lcb_.gate_source_borders_.back()->m_id.m_last;
212  double n=0;//not required
214  return gate_open_found;
215  }
216 
217 
218 
223  {
224 
225  //collect known navigation cost points
226  std::vector<adoreMatrix<double,3,1>> navcost_vector;
228  {
229  auto c = borderCostMap_->find(rb->m_id);
230  if(c==borderCostMap_->end())return false;
231  adoreMatrix<double,3,1> value;
232  value(0) = c->second.getDistanceToGoal();
233  value(1) = rb->m_id.m_first.m_X;
234  value(2) = rb->m_id.m_first.m_Y;
235  navcost_vector.push_back(value);
236  }
237  {
238  Border* rb = *navigationCostBorders_.rbegin();
239  auto c = borderCostMap_->find(rb->m_id);
240  if(c==borderCostMap_->end())return false;
241  adoreMatrix<double,3,1> value;
242  value(0) = std::max(0.0,c->second.getDistanceToGoal()-rb->getLength());
243  value(1) = rb->m_id.m_last.m_X;
244  value(2) = rb->m_id.m_last.m_Y;
245  navcost_vector.push_back(value);
246  }
247 
248  //project navigation cost points to baseline
249  std::vector<double> svalues;
250  std::vector<double> cvalues;
253  for(auto& value:navcost_vector)
254  {
255  double tmp=0;//not required
256  double s = baseline_.position_fct_.getClosestParameter(value(1),value(2),1,2,tmp);
257  double c;//cost
258  if(s==baseline_.position_fct_.limitLo())//potentially located before interval start
259  {
260  double dx = value(1)-xstart(0);
261  double dy = value(2)-xstart(1);
262  double d = std::sqrt(dx*dx+dy*dy);
263  c = std::max(0.0,value(0) - d);
264  }
265  else if(s==baseline_.position_fct_.limitHi())//potentially located after interval end
266  {
267  double dx = value(1)-xend(0);
268  double dy = value(2)-xend(1);
269  double d = std::sqrt(dx*dx+dy*dy);
270  c = std::max(0.0,value(0) + d);
271  }
272  else
273  {
274  c = value(0);
275  }
276  if( svalues.size()>0 && s<svalues[svalues.size()-1])continue;
277  else if( svalues.size()>0 && s==svalues[svalues.size()-1])
278  {
279  if(c<cvalues[cvalues.size()-1])
280  {
281  svalues[svalues.size()-1] = s;
282  cvalues[svalues.size()-1] = c;
283  }
284  }
285  else
286  {
287  svalues.push_back(s);
288  cvalues.push_back(c);
289  }
290  }
291  if(svalues.size()>0)
292  {
293  navigationCost_fct_.setData(dlib::zeros_matrix<double>(2, svalues.size()));
294  for(int i=0;i<svalues.size();i++)
295  {
296  navigationCost_fct_.getData()(0,i) = svalues[i];
297  navigationCost_fct_.getData()(1,i) = cvalues[i];
298  }
299  return true;
300  }
301  else
302  {
303  navigationCost_fct_.setData(dlib::zeros_matrix<double>(2, 2));
306  navigationCost_fct_.getData()(1,0) = 1e10;
307  navigationCost_fct_.getData()(1,1) = 1e10;
308  return true;
309  }
310 
311  }
312 
322  {
323  if(lcb_.isLCDirectionLeft())
324  {
325  for(Border* rb:lcb_.upstream_borders_)
326  {
327  Border* lb = borderSet_->getLeftNeighbor(rb);
328  if(!lb)return false;
329  separatingBorders_.push_back(lb);
330  }
332  {
333  separatingBorders_.push_back(rb);
334  }
336  {
337  separatingBorders_.push_back(rb);
338  }
339  }
340  else
341  {
342  for(Border* rb:lcb_.upstream_borders_)
343  {
344  separatingBorders_.push_back(rb);
345  }
347  {
348  separatingBorders_.push_back(rb);
349  }
351  {
352  Border* lb = borderSet_->getLeftNeighbor(rb);
353  if(!lb)return false;
354  separatingBorders_.push_back(lb);
355  }
356  }
357  return true;
358  }
364  {
365  if(lcb_.isLCDirectionLeft())
366  {
367  for(Border* rb:lcb_.upstream_borders_)
368  {
369  Border* lb = borderSet_->getLeftNeighbor(rb);
370  if(!lb)return false;
371  targetOuterBorders_.push_back(lb);
372  }
374  {
375  Border* lb = borderSet_->getLeftNeighbor(rb);
376  if(!lb)return false;
377  targetOuterBorders_.push_back(lb);
378  }
380  {
381  Border* lb = borderSet_->getLeftNeighbor(rb);
382  if(!lb)return false;
383  targetOuterBorders_.push_back(lb);
384  }
385  }
386  else
387  {
388  for(Border* rb:lcb_.upstream_borders_)
389  {
390  targetOuterBorders_.push_back(rb);
391  }
393  {
394  targetOuterBorders_.push_back(rb);
395  }
397  {
398  targetOuterBorders_.push_back(rb);
399  }
400  }
401  return true;
402  }
408  {
409  if(lcb_.isLCDirectionLeft())
410  {
411  for(Border* rb:lcb_.upstream_borders_)
412  {
413  sourceOuterBorders_.push_back(rb);
414  }
416  {
417  sourceOuterBorders_.push_back(rb);
418  }
420  {
421  sourceOuterBorders_.push_back(rb);
422  }
423  }
424  else
425  {
426  for(Border* rb:lcb_.upstream_borders_)
427  {
428  Border* lb = borderSet_->getLeftNeighbor(rb);
429  if(!lb)return false;
430  sourceOuterBorders_.push_back(lb);
431  }
433  {
434  Border* lb = borderSet_->getLeftNeighbor(rb);
435  if(!lb)return false;
436  sourceOuterBorders_.push_back(lb);
437  }
439  {
440  Border* lb = borderSet_->getLeftNeighbor(rb);
441  if(!lb)return false;
442  sourceOuterBorders_.push_back(lb);
443  }
444  }
445  return true;
446  }
452  {
453  if(lcb_.isLCDirectionLeft())
454  {
456  {
457  navigationCostBorders_.push_back(rb);
458  }
460  {
461  navigationCostBorders_.push_back(rb);
462  }
463  }
464  else
465  {
467  {
468  navigationCostBorders_.push_back(rb);
469  }
471  {
472  navigationCostBorders_.push_back(rb);
473  }
474  }
475  return true;
476  }
477 };
478 }
479 }
480 }
A local, non-linear, smooth road coordinate system generated from a sequence of borders.
Definition: baseline.h:31
int defineOffset(BorderSequence &borderSequence, function_type_scalar *offset, double maximum_offset=10.0)
define a function, which represents the offset from baseline to the neighboring function
Definition: baseline.h:199
void update(BorderSequence &borderSequence, double soffset)
compute fit for borderSequence
Definition: baseline.h:125
void setSmoothness(double value)
Definition: baseline.h:112
void setLookBehind(double value)
Definition: baseline.h:117
void setLookAhead(double value)
Definition: baseline.h:116
function_type_xyz position_fct_
Definition: baseline.h:66
bool isValid() const
Definition: baseline.h:113
Definition: bordercostmap.h:31
A class which augments a vector of Border* with some sampling features.
Definition: bordersequence.h:28
efficiently store borders in boost R-tree
Definition: borderset.h:99
Border * getLeftNeighbor(Border *b)
Get left neighbor of a border.
Definition: borderset.h:1252
A class for computation of the geometric information required to perform lane changes....
Definition: independentlanechangegeometry.h:34
function_type_scalar speedLimit_fct_
Definition: independentlanechangegeometry.h:53
IndependentLaneChangeGeometry(bool lc_direction_left, BorderSet *borderSet, BorderCostMap *borderCostMap)
Definition: independentlanechangegeometry.h:97
double maximum_navcost_increase_
Definition: independentlanechangegeometry.h:55
LaneChangeBorders lcb_
Definition: independentlanechangegeometry.h:46
function_type_scalar & getLeftOffsetFct()
Definition: independentlanechangegeometry.h:81
bool computeGateInterval()
compute gate open and close in the domain of the baseline function
Definition: independentlanechangegeometry.h:174
double getProgressGateOpen() const
Definition: independentlanechangegeometry.h:78
function_type_scalar & getRightOffsetFct()
Definition: independentlanechangegeometry.h:85
void setLookAhead(double value)
Definition: independentlanechangegeometry.h:66
bool isValid() const
Definition: independentlanechangegeometry.h:77
BorderCostMap * borderCostMap_
Definition: independentlanechangegeometry.h:37
double progressGateClosed_
Definition: independentlanechangegeometry.h:40
BorderSequence separatingBorders_
Definition: independentlanechangegeometry.h:42
bool sanityTest()
a set of tests making sure that lane change geometry is drivable in real conditions
Definition: independentlanechangegeometry.h:147
bool valid_
Definition: independentlanechangegeometry.h:38
BorderSet * borderSet_
Definition: independentlanechangegeometry.h:36
double getMaximumTargetLaneWidth()
returns the maximum width of the lane change
Definition: independentlanechangegeometry.h:156
bool collectSeparatingBorders()
collects points describing the inner, separating border The separating borders are defined as a seque...
Definition: independentlanechangegeometry.h:321
bool collectNavigationCostBorders()
collects points describing the navigation cost reference borders
Definition: independentlanechangegeometry.h:451
void update(double position_on_current, Iterator current_lf, Iterator first_lf, Iterator last_lf)
constructs a lane change geometry if a gate is available
Definition: independentlanechangegeometry.h:111
function_type_scalar navigationCost_fct_
Definition: independentlanechangegeometry.h:52
function_type_scalar & getOffsetTargetOuterBordersFct()
Definition: independentlanechangegeometry.h:93
BorderSequence navigationCostBorders_
Definition: independentlanechangegeometry.h:45
bool computeNavigationCostFunction()
projects navigation cost of borders in navigationCostBorders_ unto baseline
Definition: independentlanechangegeometry.h:222
bool collectTargetOuterBorders()
collects points describing the target-side outer border
Definition: independentlanechangegeometry.h:363
bool collectSourceOuterBorders()
collects points describing the source-side outer border
Definition: independentlanechangegeometry.h:407
function_type_scalar & getOffsetSourceOuterBordersFct()
Definition: independentlanechangegeometry.h:89
BorderSequence targetOuterBorders_
Definition: independentlanechangegeometry.h:44
bool navigationCost_fcn_available_
Definition: independentlanechangegeometry.h:54
double getProgressGateClosed() const
Definition: independentlanechangegeometry.h:79
double progressGateOpen_
Definition: independentlanechangegeometry.h:39
function_type_scalar offsetSeparatingBorders_
Definition: independentlanechangegeometry.h:49
Baseline baseline_
Definition: independentlanechangegeometry.h:47
void setSmoothness(double value)
Definition: independentlanechangegeometry.h:58
function_type_scalar offsetSourceOuterBorders_
Definition: independentlanechangegeometry.h:50
BorderSequence sourceOuterBorders_
Definition: independentlanechangegeometry.h:43
function_type_scalar offsetTargetOuterBorders_
Definition: independentlanechangegeometry.h:51
void setLookBehind(double value)
Definition: independentlanechangegeometry.h:71
bool isNavigationCostFcnAvailable() const
Definition: independentlanechangegeometry.h:80
bool computeGateInterval_v2()
compute gate open and close in the domain of the baseline function. this version uses offset function...
Definition: independentlanechangegeometry.h:194
void setMaximumNavCostIncrease(double value)
Definition: independentlanechangegeometry.h:62
Selects Borders from BorderSet required for LaneChangeView construction.
Definition: lanechangeborders.h:30
void setLookAhead(double value)
Definition: lanechangeborders.h:85
std::vector< Border * > gate_target_borders_
Definition: lanechangeborders.h:44
void update(double position_on_current, Iterator current_lf, Iterator first_lf, Iterator last_lf)
collects all borders relevant for lane change view in object-variable vectors
Definition: lanechangeborders.h:127
bool isLCDirectionLeft()
Definition: lanechangeborders.h:57
std::vector< Border * > gate_source_borders_
Definition: lanechangeborders.h:45
bool isValid()
Definition: lanechangeborders.h:61
double getNavCostIncrease()
Definition: lanechangeborders.h:101
std::vector< Border * > upstream_borders_
Definition: lanechangeborders.h:47
std::vector< Border * > downstream_borders_
Definition: lanechangeborders.h:46
double getDistanceToCurrent()
Definition: lanechangeborders.h:77
void setConinueOnIncreasingCost(bool value)
Definition: lanechangeborders.h:97
void setLookBehind(double value)
Definition: lanechangeborders.h:93
void setData(const adoreMatrix< T, n+1, 0 > &data)
Definition: llinearpiecewisefunction.h:580
double getClosestParameter(T px, T py, int d1, int d2, T &n_min) const
Definition: llinearpiecewisefunction.h:1014
virtual DT limitLo() const override
Definition: llinearpiecewisefunction.h:264
adoreMatrix< T, n+1, 0 > & getData()
Definition: llinearpiecewisefunction.h:147
virtual DT limitHi() const override
Definition: llinearpiecewisefunction.h:259
adore::mad::LLinearPiecewiseFunctionM< double, 1 > function_type_scalar
Definition: linearfunctiontypedefs.h:24
adoreMatrix< T, N, M > max(adoreMatrix< T, N, M > a, const adoreMatrix< T, N, M > &b)
Definition: adoremath.h:686
Definition: areaofeffectconverter.h:20
Coordinate m_last
Definition: borderid.h:32
The border struct contains data of the smallest.
Definition: border.h:62
double getLength()
Get the length of the border.
Definition: border.h:703
BorderID m_id
Definition: border.h:68
This struct represents 3-dimensional coordines.
Definition: coordinate.h:34
double m_Y
Definition: coordinate.h:35
double m_X
Definition: coordinate.h:35