16 #include "nav2_mppi_controller/optimizer.hpp"
26 #include "nav2_core/controller_exceptions.hpp"
27 #include "nav2_costmap_2d/costmap_filters/filter_values.hpp"
28 #include "nav2_ros_common/node_utils.hpp"
29 #include "nav2_ros_common/tf2_factories.hpp"
35 nav2::LifecycleNode::WeakPtr parent,
const std::string & name,
36 std::shared_ptr<nav2_costmap_2d::Costmap2DROS> costmap_ros,
37 nav2::TransformBuffer::SharedPtr tf_buffer,
42 costmap_ros_ = costmap_ros;
43 costmap_ = costmap_ros_->getCostmap();
44 parameters_handler_ = param_handler;
45 tf_buffer_ = tf_buffer;
47 auto node = parent_.lock();
52 critic_manager_.
on_configure(parent_, name_, costmap_ros_, parameters_handler_);
56 nav2::declare_parameter_if_not_declared(
57 node, name_ +
".TrajectoryValidator.plugin",
58 rclcpp::ParameterValue(
"mppi::DefaultOptimalTrajectoryValidator"));
59 std::string validator_plugin_type = nav2::get_plugin_type_param(
60 node, name_ +
".TrajectoryValidator");
61 validator_loader_ = std::make_unique<pluginlib::ClassLoader<OptimalTrajectoryValidator>>(
62 "nav2_mppi_controller",
"mppi::OptimalTrajectoryValidator");
63 trajectory_validator_ = validator_loader_->createUniqueInstance(validator_plugin_type);
64 trajectory_validator_->initialize(
65 parent_, name_ +
".TrajectoryValidator",
66 costmap_ros_, parameters_handler_, tf_buffer, settings_);
67 RCLCPP_INFO(
logger_,
"Loaded trajectory validator plugin: %s", validator_plugin_type.c_str());
79 std::string motion_model_name;
86 auto kinematic_guard = [
this](
87 const rclcpp::Parameter & param,
88 rcl_interfaces::msg::SetParametersResult & result) {
90 result.successful =
false;
91 if (!result.reason.empty()) {
92 result.reason +=
"\n";
94 result.reason +=
"Rejected dynamic update to '" + param.get_name() +
95 "': speed limit is active. Clear the speed limit first.";
99 const std::vector<std::string> kinematic_params = {
100 "vx_max",
"vx_min",
"vy_max",
"wz_max"};
101 for (
const auto & p : kinematic_params) {
102 parameters_handler_->
addPreCallback(name_ +
"." + p, kinematic_guard);
105 getParam(s.model_dt,
"model_dt", 0.05f);
106 getParam(s.model_delay_vx,
"model_delay_vx", 0.0f);
107 getParam(s.model_delay_vy,
"model_delay_vy", 0.0f);
108 getParam(s.model_delay_wz,
"model_delay_wz", 0.0f);
109 getParam(s.clamp_raw_controls,
"clamp_raw_controls",
false);
110 getParam(s.time_steps,
"time_steps", 56);
111 getParam(s.batch_size,
"batch_size", 1000);
112 getParam(s.iteration_count,
"iteration_count", 1);
113 getParam(s.temperature,
"temperature", 0.3f);
114 getParam(s.gamma,
"gamma", 0.015f);
115 getParam(s.base_constraints.vx_max,
"vx_max", 0.5f);
116 getParam(s.base_constraints.vx_min,
"vx_min", -0.35f);
117 getParam(s.base_constraints.vy,
"vy_max", 0.5f);
118 getParam(s.base_constraints.wz,
"wz_max", 1.9f);
119 getParam(s.base_constraints.ax_max,
"ax_max", 3.0f);
120 getParam(s.base_constraints.ax_min,
"ax_min", -3.0f);
121 getParam(s.base_constraints.ay_max,
"ay_max", 3.0f);
122 getParam(s.base_constraints.ay_min,
"ay_min", -3.0f);
123 getParam(s.base_constraints.az_max,
"az_max", 3.5f);
124 getParam(s.sampling_std.vx,
"vx_std", 0.2f);
125 getParam(s.sampling_std.vy,
"vy_std", 0.2f);
126 getParam(s.sampling_std.wz,
"wz_std", 0.4f);
127 getParam(s.retry_attempt_limit,
"retry_attempt_limit", 1);
128 getParam(s.open_loop,
"open_loop",
false);
129 getParam(s.sgf_order,
"sgf_order", 2);
130 if (s.sgf_order < 1 || s.sgf_order > 2) {
131 RCLCPP_WARN(
logger_,
"sgf_order must be 1 or 2, defaulting to 2");
135 s.base_constraints.ax_max = fabs(s.base_constraints.ax_max);
136 if (s.base_constraints.ax_min > 0.0) {
137 s.base_constraints.ax_min = -1.0 * s.base_constraints.ax_min;
140 "Sign of the parameter ax_min is incorrect, consider setting it negative.");
143 if (s.base_constraints.ay_min > 0.0) {
144 s.base_constraints.ay_min = -1.0 * s.base_constraints.ay_min;
147 "Sign of the parameter ay_min is incorrect, consider setting it negative.");
150 getParam(motion_model_name,
"motion_model", std::string(
"diff_drive"));
152 s.constraints = s.base_constraints;
157 double controller_frequency;
158 getParentParam(controller_frequency,
"controller_frequency", 0.0, ParameterType::Static);
159 s.controller_period =
static_cast<float>(1.0 / controller_frequency);
165 constexpr
double eps = 1e-6;
167 if ((controller_period + eps) < settings_.model_dt) {
170 "Controller period is less then model dt, consider setting it equal");
171 }
else if (abs(controller_period - settings_.model_dt) < eps) {
174 "Controller period is equal to model dt. Control sequence "
176 settings_.shift_control_sequence =
true;
179 "Controller period more then model dt, set it equal to model dt");
185 state_.
reset(settings_.batch_size, settings_.time_steps);
186 control_sequence_.reset(settings_.time_steps);
187 control_history_[0] = {0.0f, 0.0f, 0.0f};
188 control_history_[1] = {0.0f, 0.0f, 0.0f};
189 control_history_[2] = {0.0f, 0.0f, 0.0f};
190 control_history_[3] = {0.0f, 0.0f, 0.0f};
192 last_command_vel_ = geometry_msgs::msg::Twist();
194 if (reset_dynamic_speed_limits) {
195 settings_.constraints = settings_.base_constraints;
198 costs_.setZero(settings_.batch_size);
199 generated_trajectories_.
reset(settings_.batch_size, settings_.time_steps);
202 motion_model_->setConstraints(settings_.constraints, settings_.model_dt,
203 settings_.model_delay_vx, settings_.model_delay_vy, settings_.model_delay_wz,
204 settings_.clamp_raw_controls);
205 motion_model_->clearCommandHistory();
206 trajectory_validator_->initialize(
207 parent_, name_ +
".TrajectoryValidator",
208 costmap_ros_, parameters_handler_, tf_buffer_, settings_);
210 RCLCPP_INFO(
logger_,
"Optimizer reset");
215 return motion_model_->isHolonomic();
222 const auto & base = settings_.base_constraints;
223 const auto & curr = settings_.constraints;
224 return base.vx_max != curr.vx_max ||
225 base.vx_min != curr.vx_min ||
226 base.vy != curr.vy ||
231 const geometry_msgs::msg::PoseStamped & robot_pose,
232 const geometry_msgs::msg::Twist & robot_speed,
233 const nav_msgs::msg::Path & plan,
234 const geometry_msgs::msg::Pose & goal,
237 prepare(robot_pose, robot_speed, plan, goal, goal_checker);
238 Eigen::ArrayXXf optimal_trajectory;
239 bool trajectory_valid =
true;
244 switch (trajectory_validator_->validateTrajectory(
245 optimal_trajectory, control_sequence_, robot_pose, robot_speed, plan, goal))
247 case mppi::ValidationResult::SOFT_RESET:
248 trajectory_valid =
false;
249 RCLCPP_WARN(
logger_,
"Soft reset triggered by trajectory validator");
251 case mppi::ValidationResult::FAILURE:
253 "Trajectory validator failed to validate trajectory, hard reset triggered.");
254 case mppi::ValidationResult::SUCCESS:
256 trajectory_valid =
true;
259 }
while (
fallback(critics_data_.fail_flag || !trajectory_valid));
263 last_command_vel_ = control.twist;
265 if (settings_.shift_control_sequence) {
269 return std::make_tuple(control, optimal_trajectory);
274 for (
size_t i = 0; i < settings_.iteration_count; ++i) {
283 static size_t counter = 0;
292 if (++counter > settings_.retry_attempt_limit) {
301 const geometry_msgs::msg::PoseStamped & robot_pose,
302 const geometry_msgs::msg::Twist & robot_speed,
303 const nav_msgs::msg::Path & plan,
304 const geometry_msgs::msg::Pose & goal,
307 if (settings_.open_loop) {
308 state_.speed = last_command_vel_;
313 const auto & c = settings_.constraints;
314 const double dt = settings_.controller_period;
315 state_.speed = robot_speed;
316 state_.speed.linear.x = std::clamp(
317 last_command_vel_.linear.x,
318 robot_speed.linear.x + dt * c.ax_min,
319 robot_speed.linear.x + dt * c.ax_max);
320 state_.speed.angular.z = std::clamp(
321 last_command_vel_.angular.z,
322 robot_speed.angular.z - dt * c.az_max,
323 robot_speed.angular.z + dt * c.az_max);
325 state_.speed.linear.y = std::clamp(
326 last_command_vel_.linear.y,
327 robot_speed.linear.y + dt * c.ay_min,
328 robot_speed.linear.y + dt * c.ay_max);
332 state_.pose = robot_pose;
333 state_.local_path_length = nav2_util::geometry_utils::calculate_path_length(plan);
334 path_ = utils::toTensor(plan);
335 costs_.setZero(settings_.batch_size);
338 critics_data_.fail_flag =
false;
339 critics_data_.goal_checker = goal_checker;
340 critics_data_.motion_model = motion_model_;
341 critics_data_.furthest_reached_path_point.reset();
342 critics_data_.path_pts_valid.reset();
347 auto size = control_sequence_.vx.size();
348 utils::shiftColumnsByOnePlace(control_sequence_.vx, -1);
349 utils::shiftColumnsByOnePlace(control_sequence_.wz, -1);
350 control_sequence_.vx(size - 1) = control_sequence_.vx(size - 2);
351 control_sequence_.wz(size - 1) = control_sequence_.wz(size - 2);
354 utils::shiftColumnsByOnePlace(control_sequence_.vy, -1);
355 control_sequence_.vy(size - 1) = control_sequence_.vy(size - 2);
372 auto & s = settings_;
373 float first_dt = s.controller_period;
374 float max_delta_vx = first_dt * s.constraints.ax_max;
375 float min_delta_vx = first_dt * s.constraints.ax_min;
376 float max_delta_vy = first_dt * s.constraints.ay_max;
377 float min_delta_vy = first_dt * s.constraints.ay_min;
378 float max_delta_wz = first_dt * s.constraints.az_max;
380 float speed_vx =
static_cast<float>(state_.speed.linear.x);
381 float speed_wz =
static_cast<float>(state_.speed.angular.z);
382 if (s.shift_control_sequence) {
385 control_sequence_.vx(0) = speed_vx;
386 control_sequence_.wz(0) = speed_wz;
388 control_sequence_.vy(0) =
static_cast<float>(state_.speed.linear.y);
392 control_sequence_.vx(0) = utils::clampVelocityByAccel(
393 speed_vx, control_sequence_.vx(0), min_delta_vx, max_delta_vx);
394 control_sequence_.wz(0) = utils::clampVelocityByAccel(
395 speed_wz, control_sequence_.wz(0), -max_delta_wz, max_delta_wz);
397 float speed_vy =
static_cast<float>(state_.speed.linear.y);
398 control_sequence_.vy(0) = utils::clampVelocityByAccel(
399 speed_vy, control_sequence_.vy(0), min_delta_vy, max_delta_vy);
406 auto & s = settings_;
409 motion_model_->applyConstraints(control_sequence_);
412 float first_dt = s.controller_period;
413 float max_delta_vx = first_dt * s.constraints.ax_max;
414 float min_delta_vx = first_dt * s.constraints.ax_min;
415 float max_delta_vy = first_dt * s.constraints.ay_max;
416 float min_delta_vy = first_dt * s.constraints.ay_min;
417 float max_delta_wz = first_dt * s.constraints.az_max;
420 float vx_last =
static_cast<float>(state_.speed.linear.x);
421 float wz_last =
static_cast<float>(state_.speed.angular.z);
422 float vy_last =
isHolonomic() ?
static_cast<float>(state_.speed.linear.y) : 0.0f;
426 if (s.shift_control_sequence) {
427 control_sequence_.vx(0) = vx_last;
428 control_sequence_.wz(0) = wz_last;
430 control_sequence_.vy(0) = vy_last;
434 for (
unsigned int i = 0; i != control_sequence_.vx.size(); i++) {
437 max_delta_vx = s.model_dt * s.constraints.ax_max;
438 min_delta_vx = s.model_dt * s.constraints.ax_min;
439 max_delta_vy = s.model_dt * s.constraints.ay_max;
440 min_delta_vy = s.model_dt * s.constraints.ay_min;
441 max_delta_wz = s.model_dt * s.constraints.az_max;
444 float & vx_curr = control_sequence_.vx(i);
445 vx_curr = utils::clamp(s.constraints.vx_min, s.constraints.vx_max, vx_curr);
446 vx_curr = utils::clampVelocityByAccel(vx_last, vx_curr, min_delta_vx, max_delta_vx);
449 float & wz_curr = control_sequence_.wz(i);
450 wz_curr = utils::clamp(-s.constraints.wz, s.constraints.wz, wz_curr);
451 wz_curr = utils::clampVelocityByAccel(wz_last, wz_curr, -max_delta_wz, max_delta_wz);
455 float & vy_curr = control_sequence_.vy(i);
456 vy_curr = utils::clamp(-s.constraints.vy, s.constraints.vy, vy_curr);
457 vy_curr = utils::clampVelocityByAccel(vy_last, vy_curr, min_delta_vy, max_delta_vy);
463 motion_model_->applyConstraints(control_sequence_);
475 state.vx.col(0) =
static_cast<float>(state.speed.linear.x);
476 state.wz.col(0) =
static_cast<float>(state.speed.angular.z);
479 state.vy.col(0) =
static_cast<float>(state.speed.linear.y);
486 motion_model_->predict(state);
490 Eigen::Array<float, Eigen::Dynamic, 3> & trajectory,
491 const Eigen::ArrayXXf & sequence)
const
493 float initial_yaw =
static_cast<float>(tf2::getYaw(state_.pose.pose.orientation));
495 const auto vx = sequence.col(0);
496 const auto wz = sequence.col(1);
498 auto traj_x = trajectory.col(0);
499 auto traj_y = trajectory.col(1);
500 auto traj_yaws = trajectory.col(2);
502 const size_t n_size = traj_yaws.size();
507 float last_yaw = initial_yaw;
508 for (
size_t i = 0; i != n_size; i++) {
509 last_yaw += wz(i) * settings_.model_dt;
510 traj_yaws(i) = last_yaw;
513 Eigen::ArrayXf yaw_cos = traj_yaws.cos();
514 Eigen::ArrayXf yaw_sin = traj_yaws.sin();
515 utils::shiftColumnsByOnePlace(yaw_cos, 1);
516 utils::shiftColumnsByOnePlace(yaw_sin, 1);
517 yaw_cos(0) = cosf(initial_yaw);
518 yaw_sin(0) = sinf(initial_yaw);
520 auto dx = (vx * yaw_cos).eval();
521 auto dy = (vx * yaw_sin).eval();
524 auto vy = sequence.col(2);
525 dx = (dx - vy * yaw_sin).eval();
526 dy = (dy + vy * yaw_cos).eval();
529 float last_x = state_.pose.pose.position.x;
530 float last_y = state_.pose.pose.position.y;
531 for (
size_t i = 0; i != n_size; i++) {
532 last_x += dx(i) * settings_.model_dt;
533 last_y += dy(i) * settings_.model_dt;
543 auto initial_yaw =
static_cast<float>(tf2::getYaw(state.pose.pose.orientation));
544 const size_t n_cols = trajectories.yaws.cols();
546 Eigen::ArrayXf last_yaws = Eigen::ArrayXf::Constant(trajectories.yaws.rows(), initial_yaw);
547 for (
size_t i = 0; i != n_cols; i++) {
548 last_yaws += state.wz.col(i) * settings_.model_dt;
549 trajectories.yaws.col(i) = last_yaws;
552 Eigen::ArrayXXf yaw_cos = trajectories.yaws.cos();
553 Eigen::ArrayXXf yaw_sin = trajectories.yaws.sin();
554 utils::shiftColumnsByOnePlace(yaw_cos, 1);
555 utils::shiftColumnsByOnePlace(yaw_sin, 1);
556 yaw_cos.col(0) = cosf(initial_yaw);
557 yaw_sin.col(0) = sinf(initial_yaw);
559 auto dx = (state.vx * yaw_cos).eval();
560 auto dy = (state.vx * yaw_sin).eval();
563 dx -= state.vy * yaw_sin;
564 dy += state.vy * yaw_cos;
567 Eigen::ArrayXf last_x = Eigen::ArrayXf::Constant(
568 trajectories.x.rows(),
569 state.pose.pose.position.x);
570 Eigen::ArrayXf last_y = Eigen::ArrayXf::Constant(
571 trajectories.y.rows(),
572 state.pose.pose.position.y);
574 for (
size_t i = 0; i != n_cols; i++) {
575 last_x += dx.col(i) * settings_.model_dt;
576 last_y += dy.col(i) * settings_.model_dt;
577 trajectories.x.col(i) = last_x;
578 trajectories.y.col(i) = last_y;
585 Eigen::ArrayXXf sequence = Eigen::ArrayXXf(settings_.time_steps, is_holo ? 3 : 2);
586 Eigen::Array<float, Eigen::Dynamic, 3> trajectories =
587 Eigen::Array<float, Eigen::Dynamic, 3>(settings_.time_steps, 3);
589 sequence.col(0) = control_sequence_.vx;
590 sequence.col(1) = control_sequence_.wz;
593 sequence.col(2) = control_sequence_.vy;
602 return control_sequence_;
608 auto & s = settings_;
610 auto vx_T = control_sequence_.vx.transpose();
611 auto bounded_noises_vx = state_.cvx.rowwise() - vx_T;
612 const float gamma_vx = s.gamma / (s.sampling_std.vx * s.sampling_std.vx);
613 costs_ += (gamma_vx * (bounded_noises_vx.rowwise() * vx_T).rowwise().sum()).eval();
615 if (s.sampling_std.wz > 0.0f) {
616 auto wz_T = control_sequence_.wz.transpose();
617 auto bounded_noises_wz = state_.cwz.rowwise() - wz_T;
618 const float gamma_wz = s.gamma / (s.sampling_std.wz * s.sampling_std.wz);
619 costs_ += (gamma_wz * (bounded_noises_wz.rowwise() * wz_T).rowwise().sum()).eval();
623 auto vy_T = control_sequence_.vy.transpose();
624 auto bounded_noises_vy = state_.cvy.rowwise() - vy_T;
625 const float gamma_vy = s.gamma / (s.sampling_std.vy * s.sampling_std.vy);
626 costs_ += (gamma_vy * (bounded_noises_vy.rowwise() * vy_T).rowwise().sum()).eval();
629 auto costs_normalized = costs_ - costs_.minCoeff();
630 const float inv_temp = 1.0f / s.temperature;
631 auto softmaxes = (-inv_temp * costs_normalized).exp().eval();
632 softmaxes /= softmaxes.sum();
634 auto softmax_mat = softmaxes.matrix();
635 control_sequence_.vx = state_.cvx.transpose().matrix() * softmax_mat;
636 control_sequence_.wz = state_.cwz.transpose().matrix() * softmax_mat;
639 control_sequence_.vy = state_.cvy.transpose().matrix() * softmax_mat;
642 utils::savitskyGolayFilter(control_sequence_, control_history_, settings_);
648 const builtin_interfaces::msg::Time & stamp)
650 unsigned int offset = settings_.shift_control_sequence ? 1 : 0;
652 auto vx = control_sequence_.vx(offset);
653 auto wz = control_sequence_.wz(offset);
654 auto vy =
isHolonomic() ? control_sequence_.vy(offset) : 0.0f;
657 motion_model_->pushCommandHistory(vx, vy, wz);
660 return utils::toTwistStamped(vx, vy, wz, stamp, costmap_ros_->getBaseFrameID());
663 return utils::toTwistStamped(vx, wz, stamp, costmap_ros_->getBaseFrameID());
668 auto node = parent_.lock();
669 const std::string plugin_ns = name_ +
"." + motion_model_name;
670 std::string plugin_type;
671 motion_model_loader_ =
672 std::make_unique<pluginlib::ClassLoader<MotionModel>>(
673 "nav2_mppi_controller",
"mppi::MotionModel");
676 plugin_type = nav2::get_plugin_type_param(node, plugin_ns);
677 motion_model_ = motion_model_loader_->createSharedInstance(plugin_type);
678 motion_model_->initialize(parameters_handler_, plugin_ns);
679 motion_model_->setConstraints(settings_.constraints, settings_.model_dt,
680 settings_.model_delay_vx, settings_.model_delay_vy, settings_.model_delay_wz,
681 settings_.clamp_raw_controls);
682 }
catch (
const pluginlib::PluginlibException & ex) {
684 std::string(
"Failed to load motion model plugin '") + motion_model_name +
688 RCLCPP_INFO(
logger_,
"Loaded motion model plugin: %s", plugin_type.c_str());
693 auto & s = settings_;
694 if (speed_limit == nav2_costmap_2d::NO_SPEED_LIMIT) {
695 s.constraints.vx_max = s.base_constraints.vx_max;
696 s.constraints.vx_min = s.base_constraints.vx_min;
697 s.constraints.vy = s.base_constraints.vy;
698 s.constraints.wz = s.base_constraints.wz;
702 double ratio = speed_limit / 100.0;
703 s.constraints.vx_max = s.base_constraints.vx_max * ratio;
704 s.constraints.vx_min = s.base_constraints.vx_min * ratio;
705 s.constraints.vy = s.base_constraints.vy * ratio;
706 s.constraints.wz = s.base_constraints.wz * ratio;
709 double ratio = speed_limit / s.base_constraints.vx_max;
710 s.constraints.vx_max = s.base_constraints.vx_max * ratio;
711 s.constraints.vx_min = s.base_constraints.vx_min * ratio;
712 s.constraints.vy = s.base_constraints.vy * ratio;
713 s.constraints.wz = s.base_constraints.wz * ratio;
716 motion_model_->setConstraints(settings_.constraints, settings_.model_dt,
717 settings_.model_delay_vx, settings_.model_delay_vy, settings_.model_delay_wz,
718 settings_.clamp_raw_controls);
723 return generated_trajectories_;
void on_configure(nav2::LifecycleNode::WeakPtr parent, const std::string &name, std::shared_ptr< nav2_costmap_2d::Costmap2DROS >, ParametersHandler *)
Configure critic manager on bringup and load plugins.
void evalTrajectoriesScores(CriticData &data)
Score trajectories by the set of loaded critic functions.
void reset(mppi::models::OptimizerSettings &settings, bool is_holonomic)
Reset noise generator with settings and model types.
void initialize(mppi::models::OptimizerSettings &settings, bool is_holonomic, const std::string &name, ParametersHandler *param_handler)
Initialize noise generator with settings and model types.
void setNoisedControls(models::State &state, const models::ControlSequence &control_sequence)
set noised control_sequence to state controls
void shutdown()
Shutdown noise generator thread.
void generateNextNoises()
Signal to the noise thread the controller is ready to generate a new noised control for the next iter...
void updateStateVelocities(models::State &state) const
Update velocities in state.
const models::ControlSequence & getOptimalControlSequence()
Get the optimal control sequence for a cycle for visualization.
void setMotionModel(const std::string &model)
Set the motion model of the vehicle platform.
Eigen::ArrayXXf getOptimizedTrajectory()
Get the optimal trajectory for a cycle for visualization.
void reset(bool reset_dynamic_speed_limits=true)
Reset the optimization problem to initial conditions.
rclcpp::Logger logger_
Caution, keep references.
void prepare(const geometry_msgs::msg::PoseStamped &robot_pose, const geometry_msgs::msg::Twist &robot_speed, const nav_msgs::msg::Path &plan, const geometry_msgs::msg::Pose &goal, nav2_core::GoalChecker *goal_checker)
Prepare state information on new request for trajectory rollouts.
std::tuple< geometry_msgs::msg::TwistStamped, Eigen::ArrayXXf > evalControl(const geometry_msgs::msg::PoseStamped &robot_pose, const geometry_msgs::msg::Twist &robot_speed, const nav_msgs::msg::Path &plan, const geometry_msgs::msg::Pose &goal, nav2_core::GoalChecker *goal_checker)
Compute control using MPPI algorithm.
void integrateStateVelocities(models::Trajectories &trajectories, const models::State &state) const
Rollout velocities in state to poses.
void applyControlSequenceInterIterationConstraints()
Apply inter-iteration dynamic feasibility constraints on the first control sequence element before no...
void updateControlSequence()
Update control sequence with state controls weighted by costs using softmax function.
bool isSpeedLimitActive() const
Check if a dynamic speed limit is currently active.
void generateNoisedTrajectories()
updates generated trajectories with noised trajectories from the last cycle's optimal control
bool fallback(bool fail)
Perform fallback behavior to try to recover from a set of trajectories in collision.
bool isHolonomic() const
Whether the motion model is holonomic.
models::Trajectories & getGeneratedTrajectories()
Get the trajectories generated in a cycle for visualization.
void updateInitialStateVelocities(models::State &state) const
Update initial velocity in state.
void shutdown()
Shutdown for optimizer at process end.
void optimize()
Main function to generate, score, and return trajectories.
void setOffset(double controller_period)
Using control period and time step size, determine if trajectory offset should be used to populate in...
void setSpeedLimit(double speed_limit, bool percentage)
Set the maximum speed based on the speed limits callback.
void shiftControlSequence()
Shift the optimal control sequence after processing for next iterations initial conditions after exec...
void applyControlSequenceConstraints()
Apply hard vehicle constraints on control sequence.
void getParams()
Obtain the main controller's parameters.
void propagateStateVelocitiesFromInitials(models::State &state) const
predict velocities in state using model for time horizon equal to timesteps
geometry_msgs::msg::TwistStamped getControlFromSequenceAsTwist(const builtin_interfaces::msg::Time &stamp)
Convert control sequence to a twist command.
void initialize(nav2::LifecycleNode::WeakPtr parent, const std::string &name, std::shared_ptr< nav2_costmap_2d::Costmap2DROS > costmap_ros, nav2::TransformBuffer::SharedPtr tf_buffer, ParametersHandler *dynamic_parameters_handler)
Initializes optimizer on startup.
Handles getting parameters and dynamic parameter changes.
void addPostCallback(T &&callback)
Set a callback to process after parameter changes.
void addPreCallback(const std::string &name, T &&callback)
Set a callback to process before parameter changes.
auto getParamGetter(const std::string &ns)
Get an object to retrieve parameters.
Function-object for checking whether a goal has been reached.
A control sequence over time (e.g. trajectory)
State information: velocities, controls, poses, speed.
void reset(unsigned int batch_size, unsigned int time_steps)
Reset state data.
void reset(unsigned int batch_size, unsigned int time_steps)
Reset state data.