planar_dubins_3d.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018, The Regents of the University of California (Regents).
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above
13  * copyright notice, this list of conditions and the following
14  * disclaimer in the documentation and/or other materials provided
15  * with the distribution.
16  *
17  * 3. Neither the name of the copyright holder nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  *
33  * Please contact the author(s) of this library if you have any questions.
34  * Authors: David Fridovich-Keil ( dfk@eecs.berkeley.edu )
35  */
36 
38 //
39 // Class for planar Dubins dynamics with fixed speed.
40 // TODO: check state bounds when creating or modifying states.
41 //
43 
45 
46 #include <ros/ros.h>
47 
48 namespace fastrack {
49 namespace state {
50 
51 // Initialize static state space bounds.
52 PlanarDubins3D PlanarDubins3D::lower_ = PlanarDubins3D();
53 PlanarDubins3D PlanarDubins3D::upper_ = PlanarDubins3D();
54 
55 // Initialize static height z_.
57 
58 // Constructors.
59 PlanarDubins3D::PlanarDubins3D(const fastrack_msgs::State& msg)
60  : State(), x_(0.0), y_(0.0), theta_(0.0), v_(constants::kDefaultHeight) {
61  // Check dimensions.
62  if (msg.x.size() == StateDimension()) {
63  x_ = msg.x[0];
64  y_ = msg.x[1];
65  theta_ = msg.x[2];
66  } else if (msg.x.size() == StateDimension() + 1) {
67  x_ = msg.x[0];
68  y_ = msg.x[1];
69  theta_ = msg.x[2];
70  v_ = msg.x[3];
71  } else if (msg.x.size() == ConfigurationDimension()) {
72  x_ = msg.x[0];
73  y_ = msg.x[1];
74  } else {
75  throw std::runtime_error("PlanarDubins3D: msg dimension is incorrect: " +
76  std::to_string(msg.x.size()));
77  }
78 }
80  : State(), x_(0.0), y_(0.0), theta_(0.0), v_(constants::kDefaultHeight) {
81  // Check dimensions.
82  if (x.size() == ConfigurationDimension()) {
83  x_ = x(0);
84  y_ = x(1);
85  } else if (x.size() == StateDimension()) {
86  x_ = x(0);
87  y_ = x(1);
88  theta_ = x(2);
89  } else {
90  throw std::runtime_error("PlanarDubins3D: incorrect input dimension: " +
91  std::to_string(x.size()));
92  }
93 } // namespace state
94 
95 // Set non-configuration dimensions to match the given config derivative.
96 void PlanarDubins3D::SetConfigurationDot(const VectorXd& configuration_dot) {
97  if (configuration_dot.size() != ConfigurationDimension())
98  throw std::runtime_error("PlanarDubins3D: invalid configuration_dot dim: " +
99  std::to_string(configuration_dot.size()));
100 
101  v_ = configuration_dot.norm();
102  theta_ = std::atan2(configuration_dot(1), configuration_dot(0));
103 }
104 
105 // Static function to sample from the configuration space associated
106 // with this state space. Pass in the lower and upper bounds from
107 // which to sample.
109  const size_t kConfigurationSpaceDimension = 2;
110 
111  // Initialize a uniform random distribution in (0, 1).
112  std::uniform_real_distribution<double> unif(0.0, 1.0);
113 
114  // Extract lower/upper configuration bounds.
115  const VectorXd lower_config = PlanarDubins3D::GetConfigurationLower();
116  const VectorXd upper_config = PlanarDubins3D::GetConfigurationUpper();
117 
118  // Generate random sample.
119  VectorXd sample(kConfigurationSpaceDimension);
120  for (size_t ii = 0; ii < kConfigurationSpaceDimension; ii++)
121  sample(ii) =
122  lower_config(ii) + (upper_config(ii) - lower_config(ii)) * unif(rng_);
123 
124  return sample;
125 }
126 
127 // Sample from the state space itself.
128 // NOTE! Sets v_ to default value.
130  // Initialize a uniform random distribution in (0, 1).
131  std::uniform_real_distribution<double> unif(0.0, 1.0);
132 
133  // Generate random sample.
134  const double x = lower_.x_ + (upper_.x_ - lower_.x_) * unif(rng_);
135  const double y = lower_.y_ + (upper_.y_ - lower_.y_) * unif(rng_);
136  const double theta =
137  lower_.theta_ + (upper_.theta_ - lower_.theta_) * unif(rng_);
138 
139  return PlanarDubins3D(x, y, theta);
140 }
141 
142 // For a given configuration, what are the corresponding positions in
143 // position space that the system occupies.
144 // NOTE! For simplicity, this is a finite set. In future, this could
145 // be generalized to a collection of generic obstacles.
146 std::vector<Vector3d> PlanarDubins3D::OccupiedPositions() const {
147  return std::vector<Vector3d>({Position()});
148 }
149 
150 // Set bounds of the state space.
152  const PlanarDubins3D& upper) {
153  lower_ = lower;
154  upper_ = upper;
155 }
156 
157 // Set state space bounds from std vectors. Layout is assumed to be
158 // [x, y, theta].
159 void PlanarDubins3D::SetBounds(const std::vector<double>& lower,
160  const std::vector<double>& upper) {
161  // Check dimensions.
162  if (lower.size() != 3 || upper.size() != 3)
163  throw std::runtime_error("PlanarDubins3D: bad bound dimension.");
164 
165  lower_.x_ = lower[0];
166  lower_.y_ = lower[1];
167  lower_.theta_ = lower[2];
168 
169  upper_.x_ = upper[0];
170  upper_.y_ = upper[1];
171  upper_.theta_ = upper[2];
172 }
173 
174 // Convert from VectorXd. Assume State is [x, y, theta].
175 void PlanarDubins3D::FromVector(const VectorXd& x) {
176  if (x.size() == 3) {
177  x_ = x(0);
178  y_ = x(1);
179  theta_ = x(2);
180  return;
181  }
182 
183  ROS_ERROR("PlanarDubins3D: vector is of the wrong size.");
184 }
185 
186 // Convert to VectorXd. Assume State is [x, y, theta].
187 VectorXd PlanarDubins3D::ToVector() const {
188  VectorXd x(3);
189  x(0) = x_;
190  x(1) = y_;
191  x(2) = theta_;
192 
193  return x;
194 }
195 
196 // Convert from ROS message. Assume State is [x, y, theta], [x, y, theta, v], or
197 // configuration only.
198 void PlanarDubins3D::FromRos(const fastrack_msgs::State& msg) {
199  if (msg.x.size() == 3) {
200  // Message contains state, but not v.
201  x_ = msg.x[0];
202  y_ = msg.x[1];
203  theta_ = msg.x[2];
204  } else if (msg.x.size() == 4) {
205  // Message contains state and v.
206  x_ = msg.x[0];
207  y_ = msg.x[1];
208  theta_ = msg.x[2];
209  v_ = msg.x[3];
210  } else if (msg.x.size() == 3) {
211  // Message contains configuration only.
212  x_ = msg.x[0];
213  y_ = msg.x[1];
214  } else
215  throw std::runtime_error(
216  "PlanarDubins3D: msg is neither state nor configuration.");
217 }
218 
219 // Convert to ROS message. Format is [x, y, theta, v].
220 fastrack_msgs::State PlanarDubins3D::ToRos() const {
221  fastrack_msgs::State msg;
222  msg.x.push_back(x_);
223  msg.x.push_back(y_);
224  msg.x.push_back(theta_);
225  msg.x.push_back(v_);
226 
227  return msg;
228 }
229 
230 // Get bounds of state space.
233 
234 // Get bounds of configuration space.
236  return lower_.Configuration();
237 }
239  return upper_.Configuration();
240 }
241 
242 // Compound assignment operators.
244  x_ += rhs.x_;
245  y_ += rhs.y_;
246  theta_ += rhs.theta_;
247  return *this;
248 }
249 
251  x_ -= rhs.x_;
252  y_ -= rhs.y_;
253  theta_ -= rhs.theta_;
254  return *this;
255 }
256 
258  x_ *= s;
259  y_ *= s;
260  theta_ *= s;
261  return *this;
262 }
263 
265  x_ /= s;
266  y_ /= s;
267  theta_ *= s;
268  return *this;
269 }
270 
271 // Binary operators.
273  lhs += rhs;
274  return lhs;
275 }
276 
278  lhs -= rhs;
279  return lhs;
280 }
281 
283  lhs *= s;
284  return lhs;
285 }
286 
288  rhs *= s;
289  return rhs;
290 }
291 
293  lhs /= s;
294  return lhs;
295 }
296 
298  rhs /= s;
299  return rhs;
300 }
301 
302 } // namespace state
303 } // namespace fastrack
void SetConfigurationDot(const VectorXd &configuration_dot)
PlanarDubins3D & operator*=(double s)
fastrack_msgs::State ToRos() const
friend PlanarDubins3D operator+(PlanarDubins3D lhs, const PlanarDubins3D &rhs)
static constexpr double kDefaultHeight
Definition: types.h:79
PlanarDubins3D & operator/=(double s)
friend PlanarDubins3D operator/(PlanarDubins3D lhs, double s)
friend PlanarDubins3D operator-(PlanarDubins3D lhs, const PlanarDubins3D &rhs)
void FromVector(const VectorXd &x)
PlanarDubins3D & operator-=(const PlanarDubins3D &rhs)
static const PlanarDubins3D & GetLower()
Definition: box.h:53
static constexpr size_t StateDimension()
friend PlanarDubins3D operator*(PlanarDubins3D lhs, double s)
PlanarDubins3D & operator+=(const PlanarDubins3D &rhs)
static constexpr size_t ConfigurationDimension()
static std::default_random_engine rng_
Definition: state.h:89
static const PlanarDubins3D & GetUpper()
static PlanarDubins3D Sample()
void FromRos(const fastrack_msgs::State &msg)
static void SetBounds(const PlanarDubins3D &lower, const PlanarDubins3D &upper)
std::vector< Vector3d > OccupiedPositions() const


fastrack
Author(s): David Fridovich-Keil
autogenerated on Mon Aug 3 2020 21:28:37