analytical_kinematic_box_quadrotor_decoupled_6d.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 // Defines the AnalyticalKinematicBoxQuadrotorDecoupled6D class, which inherits
40 // from the ValueFunction base class. This class assumes Kinematic planner
41 // dynamics and QuadrotorDecoupled6D tracker dynamics, and uses a Box tracking
42 // error bound.
43 //
45 
48 
49 namespace fastrack {
50 namespace value {
51 
53 
54 // Load parameters.
56  const ros::NodeHandle& n) {
57  ros::NodeHandle nl(n);
58 
59  // Set dynamics parameters.
60  QuadrotorControl qc_lower, qc_upper;
61  qc_lower.yaw_rate = 0.0;
62  qc_upper.yaw_rate = 0.0;
63 
64  if (!nl.getParam("tracker/upper/pitch", qc_upper.pitch)) return false;
65  if (!nl.getParam("tracker/upper/roll", qc_upper.roll)) return false;
66  if (!nl.getParam("tracker/upper/thrust", qc_upper.thrust)) return false;
67  if (!nl.getParam("tracker/lower/thrust", qc_lower.thrust)) return false;
68  qc_lower.pitch = -qc_upper.pitch;
69  qc_lower.roll = -qc_upper.roll;
70 
71  tracker_dynamics_.Initialize(QuadrotorControlBoundBox(qc_lower, qc_upper));
72 
73  VectorXd max_planner_speed(3);
74  if (!nl.getParam("planner/vx", max_planner_speed(0))) return false;
75  if (!nl.getParam("planner/vy", max_planner_speed(1))) return false;
76  if (!nl.getParam("planner/vz", max_planner_speed(2))) return false;
77 
78  planner_dynamics_.Initialize(
79  VectorBoundBox(-max_planner_speed, max_planner_speed));
80 
81  // Set relative dynamics.
82  relative_dynamics_.reset(new QuadrotorDecoupled6DRelKinematics<QuadrotorControlBoundBox>);
83 
84  // Compute maximum acceleration. Make sure all elements are positive.
85  const auto x_dot_max = tracker_dynamics_.Evaluate(
86  PositionVelocity(Vector3d::Zero(), Vector3d::Zero()), qc_upper);
87 
88  max_acc_ = x_dot_max.Velocity();
89  max_acc_(0) = std::abs(max_acc_(0));
90  max_acc_(1) = std::abs(max_acc_(1));
91  max_acc_(2) = std::abs(max_acc_(2));
92 
93  // Velocity/acceleration disturbance bounds.
94  if (!nl.getParam("disturbance/velocity/x", vel_dist_(0))) return false;
95  if (!nl.getParam("disturbance/velocity/y", vel_dist_(1))) return false;
96  if (!nl.getParam("disturbance/velocity/z", vel_dist_(2))) return false;
97  if (!nl.getParam("disturbance/acceleration/x", acc_dist_(0))) return false;
98  if (!nl.getParam("disturbance/acceleration/y", acc_dist_(1))) return false;
99  if (!nl.getParam("disturbance/acceleration/z", acc_dist_(2))) return false;
100 
101  // Position/velocity expansion.
102  if (!nl.getParam("expansion/velocity/x", vel_exp_(0))) return false;
103  if (!nl.getParam("expansion/velocity/y", vel_exp_(1))) return false;
104  if (!nl.getParam("expansion/velocity/z", vel_exp_(2))) return false;
105  pos_exp_ = vel_exp_.cwiseProduct(2.0 * max_planner_speed + 0.5 * vel_exp_)
106  .cwiseQuotient(max_acc_ - acc_dist_);
107 
108  // Generate the tracking error bound.
109  bound_.x = pos_exp_(0) + (max_planner_speed(0) + vel_dist_(0)) *
110  (max_planner_speed(0) + vel_dist_(0)) /
111  (max_acc_(0) - acc_dist_(0));
112  bound_.y = pos_exp_(1) + (max_planner_speed(1) + vel_dist_(1)) *
113  (max_planner_speed(1) + vel_dist_(1)) /
114  (max_acc_(1) - acc_dist_(1));
115  bound_.z = pos_exp_(2) + (max_planner_speed(2) + vel_dist_(2)) *
116  (max_planner_speed(2) + vel_dist_(2)) /
117  (max_acc_(2) - acc_dist_(2));
118 
119  return true;
120 }
121 
122 // Register callbacks.
124  const ros::NodeHandle& n) {
125  return true;
126 }
127 
128 // Evaluate the value function at tracker/planner states.
130  const PositionVelocity& tracker_x,
131  const PositionVelocity& planner_x) const {
132  // Get relative state.
133  const PositionVelocityRelPositionVelocity relative_x(tracker_x, planner_x);
134  const Vector3d& rx_position = relative_x.State().Position();
135  const Vector3d& rx_velocity = relative_x.State().Velocity();
136 
137  // Get the maximum allowable control in each subsystem.
138  const auto& control_bound =
139  static_cast<const VectorBoundBox&>(planner_dynamics_.GetControlBound());
140  const auto& max_planner_u = control_bound.Max();
141 
142  // Value is the maximum of values in each 2D subsystem.
143  double value = -std::numeric_limits<double>::infinity();
144  for (size_t ii = 0; ii < 3; ii++) {
145  const double x = rx_position(ii);
146  const double v = rx_velocity(ii);
147  const double v_p = max_planner_u(ii);
148 
149  // Value surface A: + for x "below" convex acceleration parabola.
150  const double value_A = -x - pos_exp_(ii) +
151  (0.5 * (v - v_p) * (v - v_p) - v_p * v_p) /
152  (max_acc_(ii) - acc_dist_(ii));
153 
154  // Value surface B: + for x "above" concave braking parabola.
155  const double value_B = x + pos_exp_(ii) -
156  (-0.5 * (v + v_p) * (v + v_p) + v_p * v_p) /
157  (max_acc_(ii) - acc_dist_(ii));
158 
159  // Value function is the maximum of the above two surfaces.
160  value = std::max(value, std::max(value_A, value_B));
161  }
162 
163  return value;
164 }
165 
166 // Compute the value function gradient at a pair of tracker/planner states.s
167 std::unique_ptr<RelativeState<PositionVelocity, PositionVelocity>>
169  const PositionVelocity& tracker_x,
170  const PositionVelocity& planner_x) const {
171  // Get relative state.
172  const PositionVelocityRelPositionVelocity relative_x(tracker_x, planner_x);
173  const Vector3d& rx_position = relative_x.State().Position();
174  const Vector3d& rx_velocity = relative_x.State().Velocity();
175 
176  // Get the maximum allowable control in each subsystem.
177  const auto& control_bound =
178  static_cast<const VectorBoundBox&>(planner_dynamics_.GetControlBound());
179  const auto& max_planner_u = control_bound.Max();
180 
181  // Loop through each subsystem and populate grad in position/velocity dims.
182  Vector3d pos_grad, vel_grad;
183  for (size_t ii = 0; ii < 3; ii++) {
184  const double x = rx_position(ii);
185  const double v = rx_velocity(ii);
186  const double v_p = max_planner_u(ii);
187 
188  // Value surface A: + for x "below" convex acceleration parabola.
189  const double value_A = -x - pos_exp_(ii) +
190  (0.5 * (v - v_p) * (v - v_p) - v_p * v_p) /
191  (max_acc_(ii) - acc_dist_(ii));
192 
193  // Value surface B: + for x "above" concave braking parabola.
194  const double value_B = x + pos_exp_(ii) -
195  (-0.5 * (v + v_p) * (v + v_p) + v_p * v_p) /
196  (max_acc_(ii) - acc_dist_(ii));
197 
198  // Check which side we're on. If on A side, grad points toward -pos,
199  // if on B side, grad points toward +pos.
200  if (value_A > value_B) {
201  pos_grad(ii) = -1.0;
202  vel_grad(ii) = (v - v_p) / (max_acc_(ii) - acc_dist_(ii));
203  } else {
204  pos_grad(ii) = 1.0;
205  vel_grad(ii) = (v + v_p) / (max_acc_(ii) - acc_dist_(ii));
206  }
207  }
208 
209  return std::unique_ptr<RelativeState<PositionVelocity, PositionVelocity>>(
210  new PositionVelocityRelPositionVelocity(pos_grad, vel_grad));
211 }
212 
213 // Priority of the optimal control at the given vehicle and planner states.
214 // This is a number between 0 and 1, where 1 means the final control signal
215 // should be exactly the optimal control signal computed by this
216 // value function.
218  const PositionVelocity& tracker_x,
219  const PositionVelocity& planner_x) const {
220  // Get value at this relative state.
221  const double value = Value(tracker_x, planner_x);
222 
223  // HACK! The threshold should probably be externally set via config.
224  const double relative_high = 0.20; // 20% of max inside value
225  const double relative_low = 0.05; // 5% of max inside value
226 
227  // TODO! Make sure this is actually the maximum value.
228  const double max_value = std::max(bound_.x, std::max(bound_.y, bound_.z));
229  const double value_high = relative_high * max_value;
230  const double value_low = relative_low * max_value;
231 
232  const double priority =
233  1.0 -
234  std::max(0.0,
235  std::min((value - value_low) / (value_high - value_low), 1.0));
236 
237  return priority;
238 }
239 
240 } // namespace value
241 } // namespace fastrack
double Value(const PositionVelocity &vehicle_x, const PositionVelocity &planner_x) const
Definition: box.h:53
double Priority(const PositionVelocity &vehicle_x, const PositionVelocity &planner_x) const
std::unique_ptr< RelativeState< PositionVelocity, PositionVelocity > > Gradient(const PositionVelocity &vehicle_x, const PositionVelocity &planner_x) const


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