15 #ifndef NAV2_MPPI_CONTROLLER__OPTIMAL_TRAJECTORY_VALIDATOR_HPP_
16 #define NAV2_MPPI_CONTROLLER__OPTIMAL_TRAJECTORY_VALIDATOR_HPP_
22 #include "nav2_ros_common/lifecycle_node.hpp"
23 #include "nav2_costmap_2d/costmap_2d_ros.hpp"
24 #include "tf2_ros/buffer.hpp"
25 #include "geometry_msgs/msg/twist.hpp"
26 #include "geometry_msgs/msg/pose_stamped.hpp"
27 #include "nav_msgs/msg/path.hpp"
29 #include "nav2_mppi_controller/tools/parameters_handler.hpp"
30 #include "nav2_mppi_controller/models/control_sequence.hpp"
31 #include "nav2_mppi_controller/models/optimizer_settings.hpp"
36 enum class ValidationResult
50 using Ptr = std::shared_ptr<OptimalTrajectoryValidator>;
72 const nav2::LifecycleNode::WeakPtr & parent,
73 const std::string & name,
74 const std::shared_ptr<nav2_costmap_2d::Costmap2DROS> costmap,
76 const std::shared_ptr<tf2_ros::Buffer> tf_buffer,
79 param_handler_ = param_handler;
82 costmap_ros_ = costmap;
83 tf_buffer_ = tf_buffer;
85 auto node = node_.lock();
87 getParam(collision_lookahead_time_,
"collision_lookahead_time", 2.0f);
88 traj_samples_to_evaluate_ = collision_lookahead_time_ / settings.model_dt;
89 if (traj_samples_to_evaluate_ > settings.time_steps) {
90 traj_samples_to_evaluate_ = settings.time_steps;
93 "Collision lookahead time is greater than the number of trajectory samples, "
94 "setting it to the maximum number of samples (%u).",
95 traj_samples_to_evaluate_);
98 getParam(consider_footprint_,
"consider_footprint",
false);
99 if (consider_footprint_) {
118 const Eigen::ArrayXXf & optimal_trajectory,
120 const geometry_msgs::msg::PoseStamped & ,
121 const geometry_msgs::msg::Twist & ,
122 const nav_msgs::msg::Path & ,
123 const geometry_msgs::msg::Pose & )
131 auto costmap = costmap_ros_->getCostmap();
132 for (
size_t i = 0; i < traj_samples_to_evaluate_; ++i) {
133 const double x =
static_cast<double>(optimal_trajectory(i, 0));
134 const double y =
static_cast<double>(optimal_trajectory(i, 1));
136 if (consider_footprint_) {
137 const double theta =
static_cast<double>(optimal_trajectory(i, 2));
138 double footprint_cost = collision_checker_->footprintCostAtPose(
139 x, y, theta, costmap_ros_->getRobotFootprint());
140 if (footprint_cost ==
static_cast<double>(nav2_costmap_2d::LETHAL_OBSTACLE)) {
141 return ValidationResult::SOFT_RESET;
144 unsigned int x_i = 0u, y_i = 0u;
145 if (!costmap->worldToMap(x, y, x_i, y_i)) {
148 unsigned char cost = costmap->getCost(x_i, y_i);
149 if (cost == nav2_costmap_2d::INSCRIBED_INFLATED_OBSTACLE ||
150 cost == nav2_costmap_2d::LETHAL_OBSTACLE)
152 return ValidationResult::SOFT_RESET;
157 return ValidationResult::SUCCESS;
161 nav2::LifecycleNode::WeakPtr node_;
163 std::shared_ptr<nav2_costmap_2d::Costmap2DROS> costmap_ros_;
165 std::shared_ptr<tf2_ros::Buffer> tf_buffer_;
166 float collision_lookahead_time_{1.0f};
167 unsigned int traj_samples_to_evaluate_{0u};
168 bool consider_footprint_{
false};
169 std::unique_ptr<nav2_costmap_2d::FootprintCollisionChecker<nav2_costmap_2d::Costmap2D *>>
Abstract base class for validating optimal trajectories from MPPI optimization.
virtual ValidationResult validateTrajectory(const Eigen::ArrayXXf &optimal_trajectory, const models::ControlSequence &, const geometry_msgs::msg::PoseStamped &, const geometry_msgs::msg::Twist &, const nav_msgs::msg::Path &, const geometry_msgs::msg::Pose &)
Validate the optimal trajectory from MPPI optimization Could be used to check for collisions,...
OptimalTrajectoryValidator()=default
Constructor for mppi::OptimalTrajectoryValidator.
virtual void initialize(const nav2::LifecycleNode::WeakPtr &parent, const std::string &name, const std::shared_ptr< nav2_costmap_2d::Costmap2DROS > costmap, ParametersHandler *param_handler, const std::shared_ptr< tf2_ros::Buffer > tf_buffer, const models::OptimizerSettings &settings)
Initialize the trajectory validator.
virtual ~OptimalTrajectoryValidator()=default
Destructor for mppi::OptimalTrajectoryValidator.
Handles getting parameters and dynamic parameter changes.
auto getParamGetter(const std::string &ns)
Get an object to retrieve parameters.
A 2D costmap provides a mapping between points in the world and their associated "costs".
A control sequence over time (e.g. trajectory)
Settings for the optimizer to use.