Nav2 Navigation Stack - rolling  main
ROS 2 Navigation Stack
motion_models.hpp
1 // Copyright (c) 2022 Samsung Research America, @artofnothingness Alexey Budyakov
2 // Copyright (c) 2025 Open Navigation LLC
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 
16 #ifndef NAV2_MPPI_CONTROLLER__MOTION_MODELS_HPP_
17 #define NAV2_MPPI_CONTROLLER__MOTION_MODELS_HPP_
18 
19 #include <Eigen/Dense>
20 
21 #include <cstdint>
22 #include <string>
23 #include <algorithm>
24 
25 #include "nav2_mppi_controller/models/control_sequence.hpp"
26 #include "nav2_mppi_controller/models/state.hpp"
27 #include "nav2_mppi_controller/models/constraints.hpp"
28 
29 #include "nav2_mppi_controller/tools/parameters_handler.hpp"
30 
31 namespace mppi
32 {
33 
34 // Forward declaration of utils method, since utils.hpp can't be included here due
35 // to recursive inclusion.
36 namespace utils
37 {
38 float clamp(const float lower_bound, const float upper_bound, const float input);
39 }
40 
46 {
47 public:
51  MotionModel() = default;
52 
56  virtual ~MotionModel() = default;
57 
63  void initialize(const models::ControlConstraints & control_constraints, float model_dt)
64  {
65  control_constraints_ = control_constraints;
66  model_dt_ = model_dt;
67  }
68 
73  virtual void predict(models::State & state)
74  {
75  const bool is_holo = isHolonomic();
76  float max_delta_vx = model_dt_ * control_constraints_.ax_max;
77  float min_delta_vx = model_dt_ * control_constraints_.ax_min;
78  float max_delta_vy = model_dt_ * control_constraints_.ay_max;
79  float min_delta_vy = model_dt_ * control_constraints_.ay_min;
80  float max_delta_wz = model_dt_ * control_constraints_.az_max;
81 
82  unsigned int n_cols = state.vx.cols();
83 
84  for (unsigned int i = 1; i < n_cols; i++) {
85  auto lower_bound_vx = (state.vx.col(i - 1) >
86  0).select(state.vx.col(i - 1) + min_delta_vx,
87  state.vx.col(i - 1) - max_delta_vx);
88  auto upper_bound_vx = (state.vx.col(i - 1) >
89  0).select(state.vx.col(i - 1) + max_delta_vx,
90  state.vx.col(i - 1) - min_delta_vx);
91 
92  state.cvx.col(i - 1) = state.cvx.col(i - 1)
93  .cwiseMax(lower_bound_vx)
94  .cwiseMin(upper_bound_vx);
95  state.vx.col(i) = state.cvx.col(i - 1);
96 
97  state.cwz.col(i - 1) = state.cwz.col(i - 1)
98  .cwiseMax(state.wz.col(i - 1) - max_delta_wz)
99  .cwiseMin(state.wz.col(i - 1) + max_delta_wz);
100  state.wz.col(i) = state.cwz.col(i - 1);
101 
102  if (is_holo) {
103  auto lower_bound_vy = (state.vy.col(i - 1) >
104  0).select(state.vy.col(i - 1) + min_delta_vy,
105  state.vy.col(i - 1) - max_delta_vy);
106  auto upper_bound_vy = (state.vy.col(i - 1) >
107  0).select(state.vy.col(i - 1) + max_delta_vy,
108  state.vy.col(i - 1) - min_delta_vy);
109  state.cvy.col(i - 1) = state.cvy.col(i - 1)
110  .cwiseMax(lower_bound_vy)
111  .cwiseMin(upper_bound_vy);
112  state.vy.col(i) = state.cvy.col(i - 1);
113  }
114  }
115  }
116 
121  virtual bool isHolonomic() = 0;
122 
127  virtual void applyConstraints(models::ControlSequence & /*control_sequence*/) {}
128 
129 protected:
130  float model_dt_{0.0};
131  models::ControlConstraints control_constraints_{0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
132  0.0f, 0.0f};
133 };
134 
140 {
141 public:
145  explicit AckermannMotionModel(ParametersHandler * param_handler, const std::string & name)
146  {
147  auto getParam = param_handler->getParamGetter(name + ".AckermannConstraints");
148  getParam(min_turning_r_, "min_turning_r", 0.2);
149  }
150 
155  bool isHolonomic() override
156  {
157  return false;
158  }
159 
164  void applyConstraints(models::ControlSequence & control_sequence) override
165  {
166  const auto wz_constrained = control_sequence.vx.abs() / min_turning_r_;
167  control_sequence.wz = control_sequence.wz
168  .max((-wz_constrained))
169  .min(wz_constrained);
170  }
171 
176  float getMinTurningRadius() {return min_turning_r_;}
177 
178 private:
179  float min_turning_r_{0};
180 };
181 
187 {
188 public:
192  DiffDriveMotionModel() = default;
193 
198  bool isHolonomic() override
199  {
200  return false;
201  }
202 };
203 
209 {
210 public:
214  OmniMotionModel() = default;
215 
220  bool isHolonomic() override
221  {
222  return true;
223  }
224 };
225 
226 } // namespace mppi
227 
228 #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 parameter changes.
auto getParamGetter(const std::string &ns)
Get an object to retrieve 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:32