15 #include <nav_msgs/Odometry.h> 26 std::string param_name;
27 private_nh.
searchParam(
"latch_xy_goal_tolerance", param_name);
46 if ( ! planner_util->
getGoal(goal_pose)) {
50 double goal_x = goal_pose.getOrigin().getX();
51 double goal_y = goal_pose.getOrigin().getY();
75 nav_msgs::Odometry base_odom;
80 if ( ! planner_util->
getGoal(goal_pose)) {
84 double goal_x = goal_pose.getOrigin().getX();
85 double goal_y = goal_pose.getOrigin().getY();
95 ROS_DEBUG(
"Goal position reached (check), stopping and turning in place");
98 double goal_th =
tf::getYaw(goal_pose.getRotation());
113 geometry_msgs::Twist& cmd_vel,
114 Eigen::Vector3f acc_lim,
116 boost::function<
bool (Eigen::Vector3f pos,
118 Eigen::Vector3f vel_samples)> obstacle_check) {
122 double vx =
sign(robot_vel.getOrigin().x()) * std::max(0.0, (fabs(robot_vel.getOrigin().x()) - acc_lim[0] * sim_period));
123 double vy =
sign(robot_vel.getOrigin().y()) * std::max(0.0, (fabs(robot_vel.getOrigin().y()) - acc_lim[1] * sim_period));
125 double vel_yaw =
tf::getYaw(robot_vel.getRotation());
126 double vth =
sign(vel_yaw) * std::max(0.0, (fabs(vel_yaw) - acc_lim[2] * sim_period));
129 double yaw =
tf::getYaw(global_pose.getRotation());
130 bool valid_cmd = obstacle_check(Eigen::Vector3f(global_pose.getOrigin().getX(), global_pose.getOrigin().getY(), yaw),
131 Eigen::Vector3f(robot_vel.getOrigin().getX(), robot_vel.getOrigin().getY(), vel_yaw),
132 Eigen::Vector3f(vx, vy, vth));
136 ROS_DEBUG_NAMED(
"latched_stop_rotate",
"Slowing down... using vx, vy, vth: %.2f, %.2f, %.2f", vx, vy, vth);
137 cmd_vel.linear.x = vx;
138 cmd_vel.linear.y = vy;
139 cmd_vel.angular.z = vth;
142 ROS_WARN(
"Stopping cmd in collision");
143 cmd_vel.linear.x = 0.0;
144 cmd_vel.linear.y = 0.0;
145 cmd_vel.angular.z = 0.0;
153 geometry_msgs::Twist& cmd_vel,
154 Eigen::Vector3f acc_lim,
157 boost::function<
bool (Eigen::Vector3f pos,
159 Eigen::Vector3f vel_samples)> obstacle_check) {
160 double yaw =
tf::getYaw(global_pose.getRotation());
161 double vel_yaw =
tf::getYaw(robot_vel.getRotation());
162 cmd_vel.linear.x = 0;
163 cmd_vel.linear.y = 0;
169 double max_acc_vel = fabs(vel_yaw) + acc_lim[2] * sim_period;
170 double min_acc_vel = fabs(vel_yaw) - acc_lim[2] * sim_period;
172 v_theta_samp = std::min(std::max(fabs(v_theta_samp), min_acc_vel), max_acc_vel);
175 double max_speed_to_stop =
sqrt(2 * acc_lim[2] * fabs(ang_diff));
176 v_theta_samp = std::min(max_speed_to_stop, fabs(v_theta_samp));
181 v_theta_samp = - v_theta_samp;
185 bool valid_cmd = obstacle_check(Eigen::Vector3f(global_pose.getOrigin().getX(), global_pose.getOrigin().getY(), yaw),
186 Eigen::Vector3f(robot_vel.getOrigin().getX(), robot_vel.getOrigin().getY(), vel_yaw),
187 Eigen::Vector3f( 0.0, 0.0, v_theta_samp));
190 ROS_DEBUG_NAMED(
"dwa_local_planner",
"Moving to desired goal orientation, th cmd: %.2f, valid_cmd: %d", v_theta_samp, valid_cmd);
191 cmd_vel.angular.z = v_theta_samp;
194 ROS_WARN(
"Rotation cmd in collision");
195 cmd_vel.angular.z = 0.0;
201 Eigen::Vector3f acc_lim,
206 boost::function<
bool (Eigen::Vector3f pos,
208 Eigen::Vector3f vel_samples)> obstacle_check) {
211 if ( ! planner_util->
getGoal(goal_pose)) {
221 ROS_INFO(
"Goal position reached, stopping and turning in place");
225 double goal_th =
tf::getYaw(goal_pose.getRotation());
229 cmd_vel.linear.x = 0.0;
230 cmd_vel.linear.y = 0.0;
231 cmd_vel.angular.z = 0.0;
237 nav_msgs::Odometry base_odom;
238 odom_helper_.
getOdom(base_odom);
bool getGoal(tf::Stamped< tf::Pose > &goal_pose)
void getRobotVel(tf::Stamped< tf::Pose > &robot_vel)
double getGoalPositionDistance(const tf::Stamped< tf::Pose > &global_pose, double goal_x, double goal_y)
return squared distance to check if the goal position has been achieved
static double getYaw(const Quaternion &bt_q)
bool isGoalReached(LocalPlannerUtil *planner_util, OdometryHelperRos &odom_helper, tf::Stamped< tf::Pose > global_pose)
void getOdom(nav_msgs::Odometry &base_odom)
bool stopped(const nav_msgs::Odometry &base_odom, const double &rot_stopped_velocity, const double &trans_stopped_velocity)
Check whether the robot is stopped or not.
TFSIMD_FORCE_INLINE tfScalar angle(const Quaternion &q1, const Quaternion &q2)
bool latch_xy_goal_tolerance_
#define ROS_DEBUG_NAMED(name,...)
bool computeVelocityCommandsStopRotate(geometry_msgs::Twist &cmd_vel, Eigen::Vector3f acc_lim, double sim_period, LocalPlannerUtil *planner_util, OdometryHelperRos &odom_helper, tf::Stamped< tf::Pose > global_pose, boost::function< bool(Eigen::Vector3f pos, Eigen::Vector3f vel, Eigen::Vector3f vel_samples)> obstacle_check)
bool stopWithAccLimits(const tf::Stamped< tf::Pose > &global_pose, const tf::Stamped< tf::Pose > &robot_vel, geometry_msgs::Twist &cmd_vel, Eigen::Vector3f acc_lim, double sim_period, boost::function< bool(Eigen::Vector3f pos, Eigen::Vector3f vel, Eigen::Vector3f vel_samples)> obstacle_check)
Stop the robot taking into account acceleration limits.
bool searchParam(const std::string &key, std::string &result) const
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
LocalPlannerLimits getCurrentLimits()
void initialize(const std::string &name="")
INLINE Rall1d< T, V, S > sqrt(const Rall1d< T, V, S > &arg)
LatchedStopRotateController()
bool rotateToGoal(const tf::Stamped< tf::Pose > &global_pose, const tf::Stamped< tf::Pose > &robot_vel, double goal_th, geometry_msgs::Twist &cmd_vel, Eigen::Vector3f acc_lim, double sim_period, base_local_planner::LocalPlannerLimits &limits, boost::function< bool(Eigen::Vector3f pos, Eigen::Vector3f vel, Eigen::Vector3f vel_samples)> obstacle_check)
Once a goal position is reached... rotate to the goal orientation.
Helper class implementing infrastructure code many local planner implementations may need...
virtual ~LatchedStopRotateController()
def shortest_angular_distance(from_angle, to_angle)
double getGoalOrientationAngleDifference(const tf::Stamped< tf::Pose > &global_pose, double goal_th)
return angle difference to goal to check if the goal orientation has been achieved ...
double yaw_goal_tolerance
bool isPositionReached(LocalPlannerUtil *planner_util, tf::Stamped< tf::Pose > global_pose)