ADORe
ADORe is a modular open source software library and toolkit for decision making, planning, control and simulation of automated vehicles
ocroadbasedprediction.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 implementation and API
13  ********************************************************************************/
14 #pragma once
15 
18 #include <unordered_set>
19 #include <vector>
20 
21 namespace adore
22 {
23  namespace env
24  {
45  class OCRoadBasedPrediction: public OCPredictionStrategy<traffic::Participant>
46  {
47  private:
48  double t_max_utc_;
50  double lat_error_;
51  double lon_error_;
52  double v_max_;
53  double a_max_;
54  double a_min_;
56  double time_headway_;
57  double time_leeway_;
58  double delay_;
61  double width_ub_;
62  double width_lb_;
64  struct SearchState
65  {
66  public:
67  double s0_border_;
68  double s0_participant_;
71  double n0_lb_;
72  double n0_ub_;
73  double dn0_lb_;
74  double dn0_ub_;
75  };
76 
77  public:
78  void setAngleErrorMax(double value){angle_error_max_=value;}
79  void setTMaxUTC(double value){t_max_utc_=value;}
80  void setLatPrecision(double value){lat_precision_=value;}
81  void setLatError(double value){lat_error_=value;}
82  void setLonError(double value){lon_error_=value;}
83  void setVMax(double value){v_max_=value;}
84  void setAMax(double value){a_max_=value;}
85  void setAMin(double value){a_min_=value;}
86  void setTimeHeadway(double value){time_headway_=value;}
87  void setTimeLeeway(double value){time_leeway_=value;}
88  void setDelay(double value){delay_=value;}
91  void setWidthUB(double value){width_ub_=value;}
92  void setWidthLB(double value){width_lb_=value;}
94  :t_max_utc_(0.0),lat_precision_(0.2),lat_error_(0.0),lon_error_(0.0),
95  v_max_(9999.9),a_max_(0.0),a_min_(0.0),
96  time_headway_(2.0),
97  time_leeway_(1.0),
98  delay_(0.0),
99  width_ub_(10.0),
100  width_lb_(0.5),
101  trafficMap_(trafficMap),
103  lateral_predictions_(true){}
104  virtual bool predict(const traffic::Participant& p, OccupancyCylinderPredictionSet& set)const override
105  {
106  const double width = adore::mad::bound(width_lb_,p.getWidth(),width_ub_);
107  const double b = width*0.5 + lat_error_;
108  const double r = b+lat_precision_;
109  const double ds = 2.0 * std::sqrt(r*r-b*b);
110  const double t0 = p.getObservationTime();
111  const double t1 = (std::max)(t0,t_max_utc_);
112  const double v = std::sqrt(p.getVx()*p.getVx()+p.getVy()*p.getVy());
113  const double l = p.getLength() + 2.0*lon_error_;
114  const double k = (int)std::ceil(l/ds);
115  const double dx = std::cos(p.getYaw());
116  const double dy = std::sin(p.getYaw());
117  auto pos0 = p.getCenter();
120  RampPrediction ramp;
121  ramp.predict_s_tva(-l*0.5,v,a_min_,a_min_<0.0?0.0:v_max_,t0,0.1,t1,rear_end_s_tva);//lower bound: back of behicle with amin
122  ramp.predict_s_tva(+l*0.5,v,0.0,delay_,a_max_,a_max_<0.0?0.0:v_max_,t0,0.1,t1,front_end_s_tva);//upper bound: front of vehicle with amax
123  const double s1 = front_end_s_tva.limitHi() + 0.5*ds;
124 
125  //prediction for current shape and position
126  {
127  OccupancyCylinderPrediction prediction;
128  int predictionID = set.size();
130  center.getData()(0,0) = 0.0;
131  center.getData()(1,0) = pos0(0)-l*0.5*dx;
132  center.getData()(2,0) = pos0(1)-l*0.5*dy;
133  center.getData()(3,0) = pos0(2);
134  center.getData()(0,1) = l;
135  center.getData()(1,1) = pos0(0)+l*0.5*dx;
136  center.getData()(2,1) = pos0(1)+l*0.5*dy;
137  center.getData()(3,1) = pos0(2);
138  // if(center.getData().nc()<2)continue;
139  //create a new prediction for the encountered border
140  prediction.trackingID_ = p.getTrackingID();
141  prediction.v2xStationID_ = p.getStationID();
142  prediction.branchID_ = predictionID;
143  prediction.predecessorID_ = -1;
144  prediction.confidence_ = 1.0;
145  for(double s = ds*0.5;s<=l-ds*0.5;s+=ds)
146  {
147  auto pos = center.f(s);
148  double t0i,t1i;
149  //first time entering circle with front of vehicle
150  // t0i = front_end_s_tva.f(adore::mad::bound(front_end_s_tva.limitLo(),s-ds*0.5-0.5*l,front_end_s_tva.limitHi()))(0);
151  // t0i -= time_headway_;
152  t0i = t0;
153  //latest time exiting circle with back of vehicle
154  t1i = rear_end_s_tva.f(adore::mad::bound(rear_end_s_tva.limitLo(),s+ds*0.5-0.5*l,rear_end_s_tva.limitHi()))(0);
155  t1i += time_leeway_;
156  if(!std::isnan(r)&&!std::isnan(pos(0))&&!std::isnan(pos(1))&&!std::isnan(t0)&&!std::isnan(t1))
157  {
158  prediction.occupancy_.insert(adore::mad::OccupancyCylinder(r,pos(0),pos(1),t0i,t1i));
159  }
160  }
161  set.push_back(prediction);
162  }
163 
164 
165  //predict based on road-network
166  std::unordered_set<adore::env::BorderBased::BorderID,adore::env::BorderBased::BorderIDHasher> closed;
167  std::vector<SearchState> open;
168  //initialize open
169  for(auto itpair = trafficMap_->getParticipantToBorder().equal_range(p.getTrackingID());
170  itpair.first!=itpair.second;
171  itpair.first++)
172  {
173  auto it = itpair.first;
174  auto test_participantID = it->first;
175  auto borderID = it->second.first;
176  auto positioning = it->second.second;
177  if(test_participantID==p.getTrackingID() && positioning.anyInside())//start on border, if any point of vehicle is inside
178  {
179  //get the centerline of the lane
181  //compute the offset along the centerline
182  double min_tangential_distance, min_normal_distance;
183  double smin = center.getPositionOfPoint(p.center_(0),p.center_(1),1,2,min_tangential_distance,min_normal_distance);
184  if(min_tangential_distance<0.0 || 1.0<min_tangential_distance)continue;
185 
186  SearchState x;
187  // x.s0_border_ = positioning.s;
188  x.s0_border_ = smin;
189  x.s0_participant_ = 0.0;
190  x.predecessorID_ = -1;
191  x.borderID_ = borderID;
192 
193  //angle offset
194  //find two points on right border
195  // auto bright = trafficMap_->getBorderSet()->getBorder(borderID);
196  // if(bright==nullptr)continue;//no border found: prediction impossible
197  //compute orientation information:
198  // const double lah = adore::mad::bound(0.5,l*0.5,1.0);//look ahead/behind
199  const double lah = 1.0;//look ahead/behind
200  // if(positioning.s>=bright->m_path->limitHi()-0.1)continue;
201  const auto p0 = center.f_bounded(x.s0_border_-lah);
202  const auto p1 = center.f_bounded(x.s0_border_+lah);
203  const auto p = center.f_bounded(x.s0_border_);
204  double pdx = p1(0)-p0(0); //path delta x
205  double pdy = p1(1)-p0(1); //path delta y
206  const double lpdxy = std::sqrt(pdx*pdx+pdy*pdy);
207  pdx = pdx / lpdxy;
208  pdy = pdy / lpdxy;
209  if(lpdxy<0.01)continue;//very short border?
210  // const double rpdx = pdx*dx + pdy*dy;//path delta x rotated in vehicle coordinates
211  // const double rpdy = -pdx*dy + pdy*dx;//path delta y rotated in vehicle coordinates
212  const double rpx = (pos0(0)-p(0))*pdx + (pos0(1)-p(1))*pdy;
213  const double rpy = -(pos0(0)-p(0))*pdy + (pos0(1)-p(1))*pdx;
214  const double rpdx = dx*pdx + dy*pdy;//path delta x rotated in path coordinates
215  const double rpdy = -dx*pdy + dy*pdx;//path delta y rotated in path coordinates
216  if((std::abs)((std::atan2)(rpdy,rpdx))>angle_error_max_)continue;//orientation is wrong do not start on this border
217  double lateral_width = std::abs(rpdy*l*0.5+rpdx*b);//use orientation and width,length
218  x.n0_lb_ = adore::mad::bound(-p(3)*0.5,rpy - lateral_width,p(3)*0.5);
219  x.n0_ub_ = adore::mad::bound(-p(3)*0.5,rpy + lateral_width,p(3)*0.5);
220  x.dn0_lb_ = rpdy*v;
221  x.dn0_ub_ = rpdy*v;
222  std::cout<<"pos0=["<<pos0(0)-p(0)<<","<<pos0(1)-p(1)<<"]"<<std::endl;
223  std::cout<<"p0=["<<p0(0)-p(0)<<","<<p0(1)-p(1)<<"], p1=["<<p1(0)-p(0)<<","<<p1(1)-p(1)<<"]"<<std::endl;
224  std::cout<<"rp=["<<rpx<<","<<rpy<<"], rpd=["<<rpdx<<","<<rpdy<<"], dxy=["<<dx<<","<<dy<<"], v="<<v<<std::endl;
225  std::cout<<"n0=["<<x.n0_lb_<<","<<x.n0_ub_<<"], dn0=["<<x.dn0_lb_<<","<<x.dn0_ub_<<"]"<<std::endl;
226  std::cout<<"---"<<std::endl;
227 
228  open.push_back(x);
229  }
230  }
231  int branch_count = 0;
232  //process search states in open (depth first)
233  while(open.size()>0)
234  {
235  int predictionID = set.size();
236  SearchState x = open.back();
237  open.pop_back();
238  if(closed.find(x.borderID_)!=closed.end())continue;//do not explore twice
239  closed.insert(x.borderID_);
240  //find the center
242  //auto lane_width = trafficMap_->getBorderSet()->getLaneWidth(x.borderID_);
243  // if(center.getData().nc()<2)continue;
244  //create a new prediction for the encountered border
245  OccupancyCylinderPrediction prediction;
246  prediction.trackingID_ = p.getTrackingID();
247  prediction.v2xStationID_ = p.getStationID();
248  prediction.branchID_ = predictionID;
249  prediction.predecessorID_ = x.predecessorID_;
250  prediction.confidence_ = 1.0;
251  const double sx0 = x.s0_participant_;
252  const double dsmax = center.limitHi()-x.s0_border_;
253  const double sx1 = std::min(s1,sx0+dsmax);
254  const double s_max_border = center.limitHi();
255  if(center.getData().nc()>=2)for(double s = sx0;s<=sx1;s+=ds)
256  {
257  double t0i,t1i;
258  //first time entering circle with front of vehicle
259  t0i = front_end_s_tva.f(adore::mad::bound(front_end_s_tva.limitLo(),s-ds*0.5,front_end_s_tva.limitHi()))(0);
260  t0i = std::max(t0,t0i);
261  //latest time exiting circle with back of vehicle
262  t1i = rear_end_s_tva.f(adore::mad::bound(rear_end_s_tva.limitLo(),s+ds*0.5,rear_end_s_tva.limitHi()))(0);
263  const double si = s+x.s0_border_-x.s0_participant_;
264  const auto pos0 = center.f(si);
265  double dxi = center.dfidx(si,0);
266  double dyi = center.dfidx(si,1);
267  double scaledxyi = 1.0/std::sqrt(dxi*dxi+dyi*dyi);
268  dxi = dxi * scaledxyi;
269  dyi = dyi * scaledxyi;
270  const double widthi = pos0(3);
271  // maximum between the r_dynamic and r
272  double r_final = lane_width_predictions_?std::max(0.5*widthi,r):r;
273  double c_final = 0.0;
275  {
276  double dt = t1i-t0;//latest time arriving at that position
277  double alatmax = 2;
278  double n_ub = adore::mad::bound(-0.5*widthi,x.n0_ub_ + 0.5*alatmax*dt*dt + x.dn0_ub_*dt,0.5*widthi);
279  double n_lb = adore::mad::bound(-0.5*widthi,x.n0_lb_ - 0.5*alatmax*dt*dt + x.dn0_lb_*dt,0.5*widthi);
280  std::cout<<"n("<<dt<<")=["<<n_lb<<","<<n_ub<<"], di=["<<dxi<<","<<dyi<<"]"<<std::endl;
281  c_final = (n_ub+n_lb)*0.5;
282  r_final = std::abs(n_ub-n_lb)*0.5;
283  }
284  if(!std::isnan(r_final)&&!std::isnan(pos0(0))&&!std::isnan(pos0(1))&&!std::isnan(t0)&&!std::isnan(t1))
285  {
287  pos0(0) - dyi * c_final,
288  pos0(1) + dxi * c_final,
289  t0i-time_headway_,
290  t1i+time_leeway_));
291  }
292  }
293  set.push_back(prediction);
294 
295  if(sx1<s1)
296  {
297  //find all successors of the border and add them to the open list
298  auto border = trafficMap_->getBorderSet()->getBorder(x.borderID_);
299  for(auto it = trafficMap_->getBorderSet()->getSuccessors(border);
300  it.current()!=it.end();
301  it.current()++)
302  {
303  auto nextBorder = it.current()->second;
304  if(border->isContinuousPredecessorOf(nextBorder))
305  {
306  SearchState xnext;
307  xnext.s0_border_ = 0.0;
308  xnext.s0_participant_ = sx1;
309  xnext.predecessorID_ = predictionID;
310  xnext.borderID_ = nextBorder->m_id;
311  xnext.n0_lb_ = x.n0_lb_;
312  xnext.n0_ub_ = x.n0_ub_;
313  xnext.dn0_lb_ = x.dn0_lb_;
314  xnext.dn0_ub_ = x.dn0_ub_;
315  open.push_back(xnext);
316  }
317 
318  }
319  }
320  predictionID++;
321  branch_count++;
322  }
323 
324  return branch_count>0;
325  }
326 
327 
328  };
329  }
330 }
adore::mad::LLinearPiecewiseFunctionM< double, 4 > getCenterline(const BorderID &id)
get the linear piecewise description of the centerline:
Definition: borderset.h:647
itCoordinate2Border getSuccessors(Border *b)
get an interator pair for all borders which follow after b
Definition: borderset.h:996
Border * getBorder(const BorderID &id) const
retrieve a border by ID
Definition: borderset.h:628
Definition: occupancycylinderprediction.h:47
Definition: ocroadbasedprediction.h:46
void setAngleErrorMax(double value)
Definition: ocroadbasedprediction.h:78
double time_headway_
Definition: ocroadbasedprediction.h:56
void setVMax(double value)
Definition: ocroadbasedprediction.h:83
void setAMax(double value)
Definition: ocroadbasedprediction.h:84
double lat_error_
Definition: ocroadbasedprediction.h:50
double t_max_utc_
Definition: ocroadbasedprediction.h:48
double v_max_
Definition: ocroadbasedprediction.h:52
void setWidthLB(double value)
Definition: ocroadbasedprediction.h:92
double delay_
Definition: ocroadbasedprediction.h:58
void setAMin(double value)
Definition: ocroadbasedprediction.h:85
void setTimeHeadway(double value)
Definition: ocroadbasedprediction.h:86
OCRoadBasedPrediction(adore::env::traffic::TrafficMap *trafficMap)
Definition: ocroadbasedprediction.h:93
double a_min_
Definition: ocroadbasedprediction.h:54
void setLonError(double value)
Definition: ocroadbasedprediction.h:82
double lat_precision_
Definition: ocroadbasedprediction.h:49
void setLatError(double value)
Definition: ocroadbasedprediction.h:81
void setWidthUB(double value)
Definition: ocroadbasedprediction.h:91
void setLateralPredictions(bool value)
Definition: ocroadbasedprediction.h:90
void setDelay(double value)
Definition: ocroadbasedprediction.h:88
double angle_error_max_
Definition: ocroadbasedprediction.h:55
void setTimeLeeway(double value)
Definition: ocroadbasedprediction.h:87
double a_max_
Definition: ocroadbasedprediction.h:53
double width_lb_
Definition: ocroadbasedprediction.h:62
void setTMaxUTC(double value)
Definition: ocroadbasedprediction.h:79
double time_leeway_
Definition: ocroadbasedprediction.h:57
double lon_error_
Definition: ocroadbasedprediction.h:51
bool lateral_predictions_
Definition: ocroadbasedprediction.h:60
double width_ub_
Definition: ocroadbasedprediction.h:61
void setLatPrecision(double value)
Definition: ocroadbasedprediction.h:80
void setLaneWidthPredictions(bool value)
Definition: ocroadbasedprediction.h:89
adore::env::traffic::TrafficMap * trafficMap_
Definition: ocroadbasedprediction.h:63
virtual bool predict(const traffic::Participant &p, OccupancyCylinderPredictionSet &set) const override
Definition: ocroadbasedprediction.h:104
bool lane_width_predictions_
Definition: ocroadbasedprediction.h:59
Definition: velocityprediction.h:22
void predict_s_tva(double s0, double v0, double a0, double delay, double a1, double vbound, double t0, double dt, double t1, adore::mad::LLinearPiecewiseFunctionM< double, 3 > &result)
Definition: velocityprediction.h:24
Definition: trafficmap.h:36
adore::env::BorderBased::BorderSet * getBorderSet()
Get the border set.
Definition: trafficmap.h:63
const TParticipantToBorder & getParticipantToBorder() const
Get the participant to border map.
Definition: trafficmap.h:81
CT f_bounded(DT x)
Definition: alfunction.h:117
double getPositionOfPoint(T px, T py, int d1, int d2, T &d_tangential_min, T &d_normal_min)
Definition: llinearpiecewisefunction.h:955
virtual CT f(DT x) const override
Definition: llinearpiecewisefunction.h:251
virtual DT limitLo() const override
Definition: llinearpiecewisefunction.h:264
virtual T dfidx(DT x, int row)
Definition: llinearpiecewisefunction.h:400
adoreMatrix< T, n+1, 0 > & getData()
Definition: llinearpiecewisefunction.h:147
virtual DT limitHi() const override
Definition: llinearpiecewisefunction.h:259
void insert(const VolumeType &volume)
Definition: vectorbasedvolumetree.h:90
std::vector< OccupancyCylinderPrediction > OccupancyCylinderPredictionSet
Definition: occupancycylinderprediction.h:40
interval< T > atan2(interval< T > y, interval< T > x)
Definition: intervalarithmetic.h:234
interval< T > cos(interval< T > x)
Definition: intervalarithmetic.h:225
T bound(T lb, T value, T ub)
Definition: adoremath.h:569
T min(T a, T b, T c, T d)
Definition: adoremath.h:663
void set(T *data, T value, int size)
Definition: adoremath.h:39
interval< T > sin(interval< T > x)
Definition: intervalarithmetic.h:204
adoreMatrix< T, N, M > max(adoreMatrix< T, N, M > a, const adoreMatrix< T, N, M > &b)
Definition: adoremath.h:686
x
Definition: adore_set_goal.py:30
p0
Definition: adore_set_pose.py:32
r
Definition: adore_suppress_lanechanges.py:209
Definition: areaofeffectconverter.h:20
This struct identifies a Border by the coordinates of the starting and the end point.
Definition: borderid.h:31
T1 & current()
Definition: borderset.h:50
Definition: ocroadbasedprediction.h:65
double s0_border_
Definition: ocroadbasedprediction.h:67
int predecessorID_
Definition: ocroadbasedprediction.h:70
double n0_ub_
Definition: ocroadbasedprediction.h:72
double s0_participant_
Definition: ocroadbasedprediction.h:68
double n0_lb_
Definition: ocroadbasedprediction.h:71
double dn0_ub_
Definition: ocroadbasedprediction.h:74
double dn0_lb_
Definition: ocroadbasedprediction.h:73
adore::env::BorderBased::BorderID borderID_
Definition: ocroadbasedprediction.h:69
Definition: occupancycylinderprediction.h:27
int branchID_
Definition: occupancycylinderprediction.h:31
int trackingID_
Definition: occupancycylinderprediction.h:30
int v2xStationID_
Definition: occupancycylinderprediction.h:29
adore::mad::OccupancyCylinderTree occupancy_
Definition: occupancycylinderprediction.h:33
float confidence_
Definition: occupancycylinderprediction.h:34
int predecessorID_
Definition: occupancycylinderprediction.h:32
Struct for representing a participant in traffic.
Definition: participant.h:30
double getLength() const
Definition: participant.h:155
TTrackingID getTrackingID() const
Definition: participant.h:109
adoreMatrix< double, 3, 1 > center_
Definition: participant.h:98
double getObservationTime() const
Definition: participant.h:112
const adoreMatrix< double, 3, 1 > & getCenter() const
Definition: participant.h:124
double getYaw() const
Definition: participant.h:154
TV2XStationID getStationID() const
Definition: participant.h:110
double getWidth() const
Definition: participant.h:156
double getVy() const
Definition: participant.h:158
double getVx() const
Definition: participant.h:157
Definition: occupancycylinder.h:25