Nav2 Navigation Stack - jazzy  jazzy
ROS 2 Navigation Stack
motion_models.hpp
1 // Copyright (c) 2022 Samsung Research America, @artofnothingness Alexey Budyakov
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef NAV2_MPPI_CONTROLLER__MOTION_MODELS_HPP_
16 #define NAV2_MPPI_CONTROLLER__MOTION_MODELS_HPP_
17 
18 #include <cstdint>
19 #include <string>
20 
21 #include "nav2_mppi_controller/models/control_sequence.hpp"
22 #include "nav2_mppi_controller/models/state.hpp"
23 #include "nav2_mppi_controller/models/constraints.hpp"
24 
25 // xtensor creates warnings that needs to be ignored as we are building with -Werror
26 #pragma GCC diagnostic push
27 #pragma GCC diagnostic ignored "-Warray-bounds"
28 #pragma GCC diagnostic ignored "-Wstringop-overflow"
29 #include <xtensor/xmath.hpp>
30 #include <xtensor/xmasked_view.hpp>
31 #include <xtensor/xview.hpp>
32 #include <xtensor/xnoalias.hpp>
33 #pragma GCC diagnostic pop
34 
35 #include "nav2_mppi_controller/tools/parameters_handler.hpp"
36 
37 namespace mppi
38 {
39 
45 {
46 public:
50  MotionModel() = default;
51 
55  virtual ~MotionModel() = default;
56 
62  void initialize(const models::ControlConstraints & control_constraints, float model_dt)
63  {
64  control_constraints_ = control_constraints;
65  model_dt_ = model_dt;
66  }
67 
72  virtual void predict(models::State & state)
73  {
74  // Previously completed via tensor views, but found to be 10x slower
75  // using namespace xt::placeholders; // NOLINT
76  // xt::noalias(xt::view(state.vx, xt::all(), xt::range(1, _))) =
77  // xt::noalias(xt::view(state.cvx, xt::all(), xt::range(0, -1)));
78  // xt::noalias(xt::view(state.wz, xt::all(), xt::range(1, _))) =
79  // xt::noalias(xt::view(state.cwz, xt::all(), xt::range(0, -1)));
80  // if (isHolonomic()) {
81  // xt::noalias(xt::view(state.vy, xt::all(), xt::range(1, _))) =
82  // xt::noalias(xt::view(state.cvy, xt::all(), xt::range(0, -1)));
83  // }
84 
85  const bool is_holo = isHolonomic();
86  float max_delta_vx = model_dt_ * control_constraints_.ax_max;
87  float min_delta_vx = model_dt_ * control_constraints_.ax_min;
88  float max_delta_vy = model_dt_ * control_constraints_.ay_max;
89  float min_delta_vy = model_dt_ * control_constraints_.ay_min;
90  float max_delta_wz = model_dt_ * control_constraints_.az_max;
91  for (unsigned int i = 0; i != state.vx.shape(0); i++) {
92  float vx_last = state.vx(i, 0);
93  float vy_last = state.vy(i, 0);
94  float wz_last = state.wz(i, 0);
95  for (unsigned int j = 1; j != state.vx.shape(1); j++) {
96  float & cvx_curr = state.cvx(i, j - 1);
97  if (vx_last > 0) {
98  cvx_curr = std::clamp(cvx_curr, vx_last + min_delta_vx, vx_last + max_delta_vx);
99  } else {
100  cvx_curr = std::clamp(cvx_curr, vx_last - max_delta_vx, vx_last - min_delta_vx);
101  }
102  state.vx(i, j) = cvx_curr;
103  vx_last = cvx_curr;
104 
105  float & cwz_curr = state.cwz(i, j - 1);
106  cwz_curr = std::clamp(cwz_curr, wz_last - max_delta_wz, wz_last + max_delta_wz);
107  state.wz(i, j) = cwz_curr;
108  wz_last = cwz_curr;
109 
110  if (is_holo) {
111  float & cvy_curr = state.cvy(i, j - 1);
112  if (vy_last > 0) {
113  cvy_curr = std::clamp(cvy_curr, vy_last + min_delta_vy, vy_last + max_delta_vy);
114  } else {
115  cvy_curr = std::clamp(cvy_curr, vy_last - max_delta_vy, vy_last - min_delta_vy);
116  }
117  state.vy(i, j) = cvy_curr;
118  vy_last = cvy_curr;
119  }
120  }
121  }
122  }
123 
128  virtual bool isHolonomic() = 0;
129 
134  virtual void applyConstraints(models::ControlSequence & /*control_sequence*/) {}
135 
136 protected:
137  float model_dt_{0.0};
138  models::ControlConstraints control_constraints_{0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
139  0.0f, 0.0f};
140 };
141 
147 {
148 public:
152  explicit AckermannMotionModel(ParametersHandler * param_handler, const std::string & name)
153  {
154  auto getParam = param_handler->getParamGetter(name + ".AckermannConstraints");
155  getParam(min_turning_r_, "min_turning_r", 0.2);
156  }
157 
162  bool isHolonomic() override
163  {
164  return false;
165  }
166 
171  void applyConstraints(models::ControlSequence & control_sequence) override
172  {
173  auto & vx = control_sequence.vx;
174  auto & wz = control_sequence.wz;
175 
176  auto view = xt::masked_view(wz, (xt::fabs(vx) / xt::fabs(wz)) < min_turning_r_);
177  view = xt::sign(wz) * xt::fabs(vx) / min_turning_r_;
178  }
179 
184  float getMinTurningRadius() {return min_turning_r_;}
185 
186 private:
187  float min_turning_r_{0};
188 };
189 
195 {
196 public:
200  DiffDriveMotionModel() = default;
201 
206  bool isHolonomic() override
207  {
208  return false;
209  }
210 };
211 
217 {
218 public:
222  OmniMotionModel() = default;
223 
228  bool isHolonomic() override
229  {
230  return true;
231  }
232 };
233 
234 } // namespace mppi
235 
236 #endif // NAV2_MPPI_CONTROLLER__MOTION_MODELS_HPP_
Ackermann motion model.
float getMinTurningRadius()
Get minimum turning radius of ackermann drive.
void applyConstraints(models::ControlSequence &control_sequence) override
Apply hard vehicle constraints to a control sequence.
bool isHolonomic() override
Whether the motion model is holonomic, using Y axis.
AckermannMotionModel(ParametersHandler *param_handler, const std::string &name)
Constructor for mppi::AckermannMotionModel.
Differential drive motion model.
DiffDriveMotionModel()=default
Constructor for mppi::DiffDriveMotionModel.
bool isHolonomic() override
Whether the motion model is holonomic, using Y axis.
Abstract motion model for modeling a vehicle.
void initialize(const models::ControlConstraints &control_constraints, float model_dt)
Initialize motion model on bringup and set required variables.
virtual void predict(models::State &state)
With input velocities, find the vehicle's output velocities.
virtual void applyConstraints(models::ControlSequence &)
Apply hard vehicle constraints to a control sequence.
MotionModel()=default
Constructor for mppi::MotionModel.
virtual bool isHolonomic()=0
Whether the motion model is holonomic, using Y axis.
virtual ~MotionModel()=default
Destructor for mppi::MotionModel.
Omnidirectional motion model.
OmniMotionModel()=default
Constructor for mppi::OmniMotionModel.
bool isHolonomic() override
Whether the motion model is holonomic, using Y axis.
Handles getting parameters and dynamic parmaeter changes.
auto getParamGetter(const std::string &ns)
Get an object to retreive parameters.
Constraints on control.
Definition: constraints.hpp:26
A control sequence over time (e.g. trajectory)
State information: velocities, controls, poses, speed.
Definition: state.hpp:36