cc_dubins_state_space.cpp
Go to the documentation of this file.
1 /*********************************************************************
2 * Copyright (c) 2017 Robert Bosch GmbH.
3 * All rights reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 * *********************************************************************/
17 
18 #include <algorithm>
19 #include <cmath>
20 
23 
24 using namespace std;
25 
26 namespace steering
27 {
28 
29 CC_Dubins_State_Space::CC_Dubins_State_Space(double kappa, double sigma, double discretization, bool forwards)
30  : HC_CC_State_Space(kappa, sigma, discretization)
31  , forwards_(forwards)
32  , cc00_dubins_state_space_(kappa, sigma, discretization, forwards)
33  , cc0pm_dubins_state_space_(kappa, sigma, discretization, forwards)
34  , ccpm0_dubins_state_space_(kappa, sigma, discretization, forwards)
35  , ccpmpm_dubins_state_space_(kappa, sigma, discretization, forwards)
36 {
37 }
38 
39 vector<pair<State, Control>> CC_Dubins_State_Space::predict_state(const State &state, bool forwards) const
40 {
41  vector<pair<State, Control>> states_controls;
42 
43  // no prediction required
44  if ((fabs(state.kappa) < get_epsilon()) || ((kappa_ - fabs(state.kappa)) < get_epsilon()))
45  {
46  pair<State, Control> state_control;
47  state_control.first = state;
48  state_control.second.delta_s = 0.0;
49  state_control.second.kappa = state.kappa;
50  state_control.second.sigma = 0.0;
51  states_controls.push_back(state_control);
52  return states_controls;
53  }
54 
55  states_controls.reserve(2);
56  double sgn_kappa = sgn(state.kappa);
57  pair<State, Control> state_control1, state_control2;
58 
59  // assign controls
60  if (forwards)
61  {
62  state_control1.second.delta_s = (kappa_ - sgn_kappa * state.kappa) / sigma_;
63  state_control1.second.kappa = state.kappa;
64  state_control1.second.sigma = sgn_kappa * sigma_;
65  states_controls.push_back(state_control1);
66 
67  state_control2.second.delta_s = sgn_kappa * state.kappa / sigma_;
68  state_control2.second.kappa = state.kappa;
69  state_control2.second.sigma = -sgn_kappa * sigma_;
70  states_controls.push_back(state_control2);
71  }
72  else
73  {
74  state_control1.second.delta_s = -(kappa_ - sgn_kappa * state.kappa) / sigma_;
75  state_control1.second.kappa = state.kappa;
76  state_control1.second.sigma = sgn_kappa * sigma_;
77  states_controls.push_back(state_control1);
78 
79  state_control2.second.delta_s = -sgn_kappa * state.kappa / sigma_;
80  state_control2.second.kappa = state.kappa;
81  state_control2.second.sigma = -sgn_kappa * sigma_;
82  states_controls.push_back(state_control2);
83  }
84 
85  // predict states with controls
86  for (auto &state_control : states_controls)
87  {
88  double d = sgn(state_control.second.delta_s);
89  double abs_delta_s = fabs(state_control.second.delta_s);
90  double sigma = state_control.second.sigma;
91  end_of_clothoid(state.x, state.y, state.theta, state.kappa, sigma, d, abs_delta_s, &state_control.first.x,
92  &state_control.first.y, &state_control.first.theta, &state_control.first.kappa);
93  }
94  return states_controls;
95 }
96 
97 double CC_Dubins_State_Space::get_distance(const State &state1, const State &state2) const
98 {
99  vector<pair<State, Control>> start_states_controls = this->predict_state(state1, forwards_);
100  vector<pair<State, Control>> end_states_controls = this->predict_state(state2, !forwards_);
101  vector<double> distances;
102  distances.reserve(16);
103 
104  // compute the path length for all predicted start and end states
105  for (const auto &start_state_control : start_states_controls)
106  {
107  State start_state = start_state_control.first;
108  Control start_control = start_state_control.second;
109  for (const auto &end_state_control : end_states_controls)
110  {
111  State end_state = end_state_control.first;
112  Control end_control = end_state_control.second;
113  // check if start and goal state are equal
114  if (state_equal(start_state, end_state))
115  {
116  Control control = subtract_control(start_control, end_control);
117  distances.push_back(fabs(control.delta_s));
118  }
119  // call appropriate state space
120  else
121  {
122  double distance = 0.0;
123  if (fabs(start_state.kappa) < get_epsilon())
124  {
125  if (fabs(end_state.kappa) < get_epsilon())
126  distance += cc00_dubins_state_space_.get_distance(start_state, end_state);
127  else
128  distance += cc0pm_dubins_state_space_.get_distance(start_state, end_state);
129  }
130  else
131  {
132  if (fabs(end_state.kappa) < get_epsilon())
133  distance += ccpm0_dubins_state_space_.get_distance(start_state, end_state);
134  else
135  distance += ccpmpm_dubins_state_space_.get_distance(start_state, end_state);
136  }
137  // adjust controls by intial and final control
138  if (fabs(start_control.delta_s) > get_epsilon())
139  distance += fabs(start_control.delta_s);
140  if (fabs(end_control.delta_s) > get_epsilon())
141  distance += fabs(end_control.delta_s);
142  distances.push_back(distance);
143  }
144  }
145  }
146  return *min_element(distances.begin(), distances.end());
147 }
148 
149 vector<Control> CC_Dubins_State_Space::get_controls(const State &state1, const State &state2) const
150 {
151  vector<pair<State, Control>> start_states_controls = this->predict_state(state1, forwards_);
152  vector<pair<State, Control>> end_states_controls = this->predict_state(state2, !forwards_);
153  vector<pair<vector<Control>, double>> cc_dubins_controls_distance_pairs;
154  cc_dubins_controls_distance_pairs.reserve(16);
155 
156  // compute the path for all predicted start and end states
157  for (const auto &start_state_control : start_states_controls)
158  {
159  State start_state = start_state_control.first;
160  Control start_control = start_state_control.second;
161  for (const auto &end_state_control : end_states_controls)
162  {
163  State end_state = end_state_control.first;
164  Control end_control = end_state_control.second;
165  vector<Control> cc_dubins_controls;
166  // check if start and goal state are equal
167  if (state_equal(start_state, end_state))
168  {
169  Control control = subtract_control(start_control, end_control);
170  cc_dubins_controls.push_back(control);
171  }
172  // call the appropriate state space
173  else
174  {
175  if (fabs(start_state.kappa) < get_epsilon())
176  {
177  if (fabs(end_state.kappa) < get_epsilon())
178  cc_dubins_controls = cc00_dubins_state_space_.get_controls(start_state, end_state);
179  else
180  cc_dubins_controls = cc0pm_dubins_state_space_.get_controls(start_state, end_state);
181  }
182  else
183  {
184  if (fabs(end_state.kappa) < get_epsilon())
185  cc_dubins_controls = ccpm0_dubins_state_space_.get_controls(start_state, end_state);
186  else
187  cc_dubins_controls = ccpmpm_dubins_state_space_.get_controls(start_state, end_state);
188  }
189  // adjust controls by intial and final control
190  if (fabs(start_control.delta_s) > get_epsilon())
191  {
192  cc_dubins_controls.insert(cc_dubins_controls.begin(), start_control);
193  }
194  if (fabs(end_control.delta_s) > get_epsilon())
195  {
196  reverse_control(end_control);
197  cc_dubins_controls.insert(cc_dubins_controls.end(), end_control);
198  }
199  }
200 
201  // compute the path length
202  double distance = 0.0;
203  for (const auto &control : cc_dubins_controls)
204  distance += fabs(control.delta_s);
205 
206  // push back
207  pair<vector<Control>, double> cc_dubins_controls_distance_pair;
208  cc_dubins_controls_distance_pair.first = cc_dubins_controls;
209  cc_dubins_controls_distance_pair.second = distance;
210  cc_dubins_controls_distance_pairs.push_back(cc_dubins_controls_distance_pair);
211  }
212  }
213 
214  // sort the controls with respect to path length
215  sort(cc_dubins_controls_distance_pairs.begin(), cc_dubins_controls_distance_pairs.end(),
216  [](const pair<vector<Control>, double> &i, const pair<vector<Control>, double> &j) {
217  return i.second < j.second;
218  });
219 
220  return cc_dubins_controls_distance_pairs[0].first;
221 }
222 
223 } // namespace steering
steering::State
Description of a kinematic car's state.
Definition: steering_functions.hpp:44
steering::CC00_Dubins_State_Space::get_controls
std::vector< Control > get_controls(const State &state1, const State &state2) const
Returns controls of the shortest path from state1 to state2.
Definition: cc00_dubins_state_space.cpp:496
steering::CC0pm_Dubins_State_Space::get_distance
double get_distance(const State &state1, const State &state2) const
Returns shortest path length from state1 to state2.
Definition: cc0pm_dubins_state_space.cpp:508
steering::HC_CC_State_Space::sigma_
double sigma_
Definition: hc_cc_state_space.hpp:95
steering::State::theta
double theta
Orientation of the robot.
Definition: steering_functions.hpp:70
steering::CCpmpm_Dubins_State_Space::get_distance
double get_distance(const State &state1, const State &state2) const
Returns shortest path length from state1 to state2.
Definition: ccpmpm_dubins_state_space.cpp:653
steering::CC_Dubins_State_Space::cc00_dubins_state_space_
CC00_Dubins_State_Space cc00_dubins_state_space_
Required state spaces.
Definition: cc_dubins_state_space.hpp:89
steering::State::kappa
double kappa
Curvature at position (x,y)
Definition: steering_functions.hpp:73
steering::CC0pm_Dubins_State_Space::get_controls
std::vector< Control > get_controls(const State &state1, const State &state2) const
Returns controls of the shortest path from state1 to state2.
Definition: cc0pm_dubins_state_space.cpp:516
steering::CCpm0_Dubins_State_Space::get_distance
double get_distance(const State &state1, const State &state2) const
Returns shortest path length from state1 to state2.
Definition: ccpm0_dubins_state_space.cpp:507
steering::State::y
double y
Position in y of the robot.
Definition: steering_functions.hpp:67
steering::CC_Dubins_State_Space::get_distance
double get_distance(const State &state1, const State &state2) const
Returns shortest path length from state1 to state2.
Definition: cc_dubins_state_space.cpp:97
steering::Control
Description of a path segment with its corresponding control inputs.
Definition: steering_functions.hpp:82
steering::state_equal
bool state_equal(const State &state1, const State &state2)
Checks whether two states are equal.
Definition: paths.cpp:263
steering::CCpm0_Dubins_State_Space::get_controls
std::vector< Control > get_controls(const State &state1, const State &state2) const
Returns controls of the shortest path from state1 to state2.
Definition: ccpm0_dubins_state_space.cpp:515
steering::CC_Dubins_State_Space::predict_state
std::vector< std::pair< State, Control > > predict_state(const State &state, bool forwards) const
Predicts a state forwards or backwards to zero and max. curvature.
Definition: cc_dubins_state_space.cpp:39
steering::reverse_control
void reverse_control(Control &control)
Reverses a control.
Definition: paths.cpp:274
steering::State::x
double x
Position in x of the robot.
Definition: steering_functions.hpp:64
steering::CC_Dubins_State_Space::ccpmpm_dubins_state_space_
CCpmpm_Dubins_State_Space ccpmpm_dubins_state_space_
Definition: cc_dubins_state_space.hpp:92
steering::CC_Dubins_State_Space::ccpm0_dubins_state_space_
CCpm0_Dubins_State_Space ccpm0_dubins_state_space_
Definition: cc_dubins_state_space.hpp:91
steering::HC_CC_State_Space::kappa_
double kappa_
Curvature, sharpness of clothoid.
Definition: hc_cc_state_space.hpp:95
distance
double distance(double x0, double y0, double x1, double y1)
steering::Control::delta_s
double delta_s
Signed arc length of a segment.
Definition: steering_functions.hpp:85
steering::HC_CC_State_Space
Definition: hc_cc_state_space.hpp:45
steering::CCpmpm_Dubins_State_Space::get_controls
std::vector< Control > get_controls(const State &state1, const State &state2) const
Returns controls of the shortest path from state1 to state2.
Definition: ccpmpm_dubins_state_space.cpp:661
steering::CC00_Dubins_State_Space::get_distance
double get_distance(const State &state1, const State &state2) const
Returns shortest path length from state1 to state2.
Definition: cc00_dubins_state_space.cpp:488
steering::end_of_clothoid
void end_of_clothoid(double x_i, double y_i, double theta_i, double kappa_i, double sigma, double direction, double length, double *x_f, double *y_f, double *theta_f, double *kappa_f)
Computation of the end point on a clothoid x_i, y_i, theta_i, kappa_i: initial configuration sigma: s...
Definition: utilities.cpp:176
steering::get_epsilon
double get_epsilon()
Return value of epsilon.
Definition: utilities.cpp:57
steering::CC_Dubins_State_Space::cc0pm_dubins_state_space_
CC0pm_Dubins_State_Space cc0pm_dubins_state_space_
Definition: cc_dubins_state_space.hpp:90
plot_states.d
d
Definition: plot_states.py:107
std
plot_states.kappa
kappa
Definition: plot_states.py:106
steering
Definition: dubins_state_space.hpp:70
steering::CC_Dubins_State_Space::forwards_
bool forwards_
Driving direction.
Definition: cc_dubins_state_space.hpp:86
steering::sgn
double sgn(double x)
Return sign of a number.
Definition: utilities.cpp:62
cc_dubins_state_space.hpp
steering::subtract_control
Control subtract_control(const Control &control1, const Control &control2)
Subtracts control2 from control1.
Definition: paths.cpp:281
steering::CC_Dubins_State_Space::get_controls
std::vector< Control > get_controls(const State &state1, const State &state2) const
Returns controls of the shortest path from state1 to state2.
Definition: cc_dubins_state_space.cpp:149
utilities.hpp


steering_functions
Author(s): Holger Banzhaf
autogenerated on Mon Dec 11 2023 03:27:43