35 #include "dwb_critics/rotate_to_goal.hpp"
38 #include "dwb_core/exceptions.hpp"
39 #include "pluginlib/class_list_macros.hpp"
40 #include "dwb_core/trajectory_utils.hpp"
41 #include "nav2_util/geometry_utils.hpp"
42 #include "angles/angles.h"
49 inline double hypot_sq(
double dx,
double dy)
51 return dx * dx + dy * dy;
54 void RotateToGoalCritic::onInit()
56 auto node = node_.lock();
58 throw std::runtime_error{
"Failed to lock node"};
61 xy_goal_tolerance_ = node->declare_or_get_parameter(
62 dwb_plugin_name_ +
".xy_goal_tolerance", 0.25);
63 xy_goal_tolerance_sq_ = xy_goal_tolerance_ * xy_goal_tolerance_;
64 path_length_tolerance_ = node->declare_or_get_parameter(
65 dwb_plugin_name_ +
"path_length_tolerance", 1.0);
66 double stopped_xy_velocity = node->declare_or_get_parameter(
67 dwb_plugin_name_ +
".trans_stopped_velocity", 0.25);
68 stopped_xy_velocity_sq_ = stopped_xy_velocity * stopped_xy_velocity;
69 slowing_factor_ = node->declare_or_get_parameter(
70 dwb_plugin_name_ +
"." + name_ +
".slowing_factor", 5.0);
71 lookahead_time_ = node->declare_or_get_parameter(
72 dwb_plugin_name_ +
"." + name_ +
".lookahead_time", -1.0);
83 const geometry_msgs::msg::Pose & pose,
const nav_2d_msgs::msg::Twist2D & vel,
84 const geometry_msgs::msg::Pose & goal,
85 const nav_msgs::msg::Path & transformed_global_plan)
87 double dxy_sq = hypot_sq(pose.position.x - goal.position.x, pose.position.y - goal.position.y);
88 double path_length = nav2_util::geometry_utils::calculate_path_length(transformed_global_plan);
89 in_window_ = in_window_ ||
90 (dxy_sq <= xy_goal_tolerance_sq_ && path_length <= path_length_tolerance_);
91 current_xy_speed_sq_ = hypot_sq(vel.x, vel.y);
92 rotating_ = rotating_ || (in_window_ && current_xy_speed_sq_ <= stopped_xy_velocity_sq_);
93 goal_yaw_ = tf2::getYaw(goal.orientation);
102 }
else if (!rotating_) {
103 double speed_sq = hypot_sq(traj.velocity.x, traj.velocity.y);
104 if (speed_sq >= current_xy_speed_sq_) {
111 if (fabs(traj.velocity.x) > 0 || fabs(traj.velocity.y) > 0) {
113 IllegalTrajectoryException(name_,
"Nonrotation command near goal.");
121 if (traj.poses.empty()) {
126 if (lookahead_time_ >= 0.0) {
127 geometry_msgs::msg::Pose eval_pose = dwb_core::projectPose(traj, lookahead_time_);
128 end_yaw = tf2::getYaw(eval_pose.orientation);
130 end_yaw = tf2::getYaw(traj.poses.back().orientation);
132 return fabs(angles::shortest_angular_distance(end_yaw, goal_yaw_));
Thrown when one of the critics encountered a fatal error.
Evaluates a Trajectory2D to produce a score.
Forces the commanded trajectories to only be rotations if within a certain distance window.
bool prepare(const geometry_msgs::msg::Pose &pose, const nav_2d_msgs::msg::Twist2D &vel, const geometry_msgs::msg::Pose &goal, const nav_msgs::msg::Path &global_plan) override
Prior to evaluating any trajectories, look at contextual information constant across all trajectories...
void reset() override
Reset the state of the critic.
virtual double scoreRotation(const dwb_msgs::msg::Trajectory2D &traj)
Assuming that this is an actual rotation when near the goal, score the trajectory.
double scoreTrajectory(const dwb_msgs::msg::Trajectory2D &traj) override
Return a raw score for the given trajectory.