latched_stop_rotate_controller.cpp
Go to the documentation of this file.
1 /*
2  * latched_stop_rotate_controller.cpp
3  *
4  * Created on: Apr 16, 2012
5  * Author: tkruse
6  */
7 
9 
10 #include <cmath>
11 
12 #include <Eigen/Core>
13 
14 #include <angles/angles.h>
15 #include <nav_msgs/Odometry.h>
16 
19 
20 #include <tf2/utils.h>
21 
22 namespace base_local_planner {
23 
25  ros::NodeHandle private_nh("~/" + name);
26  private_nh.param("latch_xy_goal_tolerance", latch_xy_goal_tolerance_, false);
27 
28  rotating_to_goal_ = false;
29 }
30 
32 
33 
40  const geometry_msgs::PoseStamped& global_pose) {
41  double xy_goal_tolerance = planner_util->getCurrentLimits().xy_goal_tolerance;
42 
43  //we assume the global goal is the last point in the global plan
44  geometry_msgs::PoseStamped goal_pose;
45  if ( ! planner_util->getGoal(goal_pose)) {
46  return false;
47  }
48 
49  double goal_x = goal_pose.pose.position.x;
50  double goal_y = goal_pose.pose.position.y;
51 
52  //check to see if we've reached the goal position
54  base_local_planner::getGoalPositionDistance(global_pose, goal_x, goal_y) <= xy_goal_tolerance) {
55  xy_tolerance_latch_ = true;
56  return true;
57  }
58  return false;
59 }
60 
61 
67  OdometryHelperRos& odom_helper,
68  const geometry_msgs::PoseStamped& global_pose) {
69  double xy_goal_tolerance = planner_util->getCurrentLimits().xy_goal_tolerance;
70  double theta_stopped_vel = planner_util->getCurrentLimits().theta_stopped_vel;
71  double trans_stopped_vel = planner_util->getCurrentLimits().trans_stopped_vel;
72 
73  //copy over the odometry information
74  nav_msgs::Odometry base_odom;
75  odom_helper.getOdom(base_odom);
76 
77  //we assume the global goal is the last point in the global plan
78  geometry_msgs::PoseStamped goal_pose;
79  if ( ! planner_util->getGoal(goal_pose)) {
80  return false;
81  }
82 
83  double goal_x = goal_pose.pose.position.x;
84  double goal_y = goal_pose.pose.position.y;
85 
87 
88  //check to see if we've reached the goal position
90  base_local_planner::getGoalPositionDistance(global_pose, goal_x, goal_y) <= xy_goal_tolerance) {
91  //if the user wants to latch goal tolerance, if we ever reach the goal location, we'll
92  //just rotate in place
94  ROS_DEBUG("Goal position reached (check), stopping and turning in place");
95  xy_tolerance_latch_ = true;
96  }
97  double goal_th = tf2::getYaw(goal_pose.pose.orientation);
98  double angle = base_local_planner::getGoalOrientationAngleDifference(global_pose, goal_th);
99  //check to see if the goal orientation has been reached
100  if (fabs(angle) <= limits.yaw_goal_tolerance) {
101  //make sure that we're actually stopped before returning success
102  if (base_local_planner::stopped(base_odom, theta_stopped_vel, trans_stopped_vel)) {
103  return true;
104  }
105  }
106  }
107  return false;
108 }
109 
110 bool LatchedStopRotateController::stopWithAccLimits(const geometry_msgs::PoseStamped& global_pose,
111  const geometry_msgs::PoseStamped& robot_vel,
112  geometry_msgs::Twist& cmd_vel,
113  Eigen::Vector3f acc_lim,
114  double sim_period,
115  boost::function<bool (Eigen::Vector3f pos,
116  Eigen::Vector3f vel,
117  Eigen::Vector3f vel_samples)> obstacle_check) {
118 
119  //slow down with the maximum possible acceleration... we should really use the frequency that we're running at to determine what is feasible
120  //but we'll use a tenth of a second to be consistent with the implementation of the local planner.
121  double vx = sign(robot_vel.pose.position.x) * std::max(0.0, (fabs(robot_vel.pose.position.x) - acc_lim[0] * sim_period));
122  double vy = sign(robot_vel.pose.position.y) * std::max(0.0, (fabs(robot_vel.pose.position.y) - acc_lim[1] * sim_period));
123 
124  double vel_yaw = tf2::getYaw(robot_vel.pose.orientation);
125  double vth = sign(vel_yaw) * std::max(0.0, (fabs(vel_yaw) - acc_lim[2] * sim_period));
126 
127  //we do want to check whether or not the command is valid
128  double yaw = tf2::getYaw(global_pose.pose.orientation);
129  bool valid_cmd = obstacle_check(Eigen::Vector3f(global_pose.pose.position.x, global_pose.pose.position.y, yaw),
130  Eigen::Vector3f(robot_vel.pose.position.x, robot_vel.pose.position.y, vel_yaw),
131  Eigen::Vector3f(vx, vy, vth));
132 
133  //if we have a valid command, we'll pass it on, otherwise we'll command all zeros
134  if(valid_cmd){
135  ROS_DEBUG_NAMED("latched_stop_rotate", "Slowing down... using vx, vy, vth: %.2f, %.2f, %.2f", vx, vy, vth);
136  cmd_vel.linear.x = vx;
137  cmd_vel.linear.y = vy;
138  cmd_vel.angular.z = vth;
139  return true;
140  }
141  ROS_WARN("Stopping cmd in collision");
142  cmd_vel.linear.x = 0.0;
143  cmd_vel.linear.y = 0.0;
144  cmd_vel.angular.z = 0.0;
145  return false;
146 }
147 
149  const geometry_msgs::PoseStamped& global_pose,
150  const geometry_msgs::PoseStamped& robot_vel,
151  double goal_th,
152  geometry_msgs::Twist& cmd_vel,
153  Eigen::Vector3f acc_lim,
154  double sim_period,
156  boost::function<bool (Eigen::Vector3f pos,
157  Eigen::Vector3f vel,
158  Eigen::Vector3f vel_samples)> obstacle_check) {
159  double yaw = tf2::getYaw(global_pose.pose.orientation);
160  double vel_yaw = tf2::getYaw(robot_vel.pose.orientation);
161  cmd_vel.linear.x = 0;
162  cmd_vel.linear.y = 0;
163  double ang_diff = angles::shortest_angular_distance(yaw, goal_th);
164 
165  double v_theta_samp = std::min(limits.max_vel_theta, std::max(limits.min_vel_theta, fabs(ang_diff)));
166 
167  //take the acceleration limits of the robot into account
168  double max_acc_vel = fabs(vel_yaw) + acc_lim[2] * sim_period;
169  double min_acc_vel = fabs(vel_yaw) - acc_lim[2] * sim_period;
170 
171  v_theta_samp = std::min(std::max(fabs(v_theta_samp), min_acc_vel), max_acc_vel);
172 
173  //we also want to make sure to send a velocity that allows us to stop when we reach the goal given our acceleration limits
174  double max_speed_to_stop = sqrt(2 * acc_lim[2] * fabs(ang_diff));
175  v_theta_samp = std::min(max_speed_to_stop, fabs(v_theta_samp));
176 
177  v_theta_samp = std::min(limits.max_vel_theta, std::max(limits.min_vel_theta, v_theta_samp));
178 
179  if (ang_diff < 0) {
180  v_theta_samp = - v_theta_samp;
181  }
182 
183  //we still want to lay down the footprint of the robot and check if the action is legal
184  bool valid_cmd = obstacle_check(Eigen::Vector3f(global_pose.pose.position.x, global_pose.pose.position.y, yaw),
185  Eigen::Vector3f(robot_vel.pose.position.x, robot_vel.pose.position.y, vel_yaw),
186  Eigen::Vector3f( 0.0, 0.0, v_theta_samp));
187 
188  if (valid_cmd) {
189  ROS_DEBUG_NAMED("dwa_local_planner", "Moving to desired goal orientation, th cmd: %.2f, valid_cmd: %d", v_theta_samp, valid_cmd);
190  cmd_vel.angular.z = v_theta_samp;
191  return true;
192  }
193  ROS_WARN("Rotation cmd in collision");
194  cmd_vel.angular.z = 0.0;
195  return false;
196 
197 }
198 
200  Eigen::Vector3f acc_lim,
201  double sim_period,
202  LocalPlannerUtil* planner_util,
203  OdometryHelperRos& odom_helper_,
204  const geometry_msgs::PoseStamped& global_pose,
205  boost::function<bool (Eigen::Vector3f pos,
206  Eigen::Vector3f vel,
207  Eigen::Vector3f vel_samples)> obstacle_check) {
208  //we assume the global goal is the last point in the global plan
209  geometry_msgs::PoseStamped goal_pose;
210  if ( ! planner_util->getGoal(goal_pose)) {
211  ROS_ERROR("Could not get goal pose");
212  return false;
213  }
214 
216 
217  //if the user wants to latch goal tolerance, if we ever reach the goal location, we'll
218  //just rotate in place
220  ROS_INFO("Goal position reached, stopping and turning in place");
221  xy_tolerance_latch_ = true;
222  }
223  //check to see if the goal orientation has been reached
224  double goal_th = tf2::getYaw(goal_pose.pose.orientation);
225  double angle = base_local_planner::getGoalOrientationAngleDifference(global_pose, goal_th);
226  if (fabs(angle) <= limits.yaw_goal_tolerance) {
227  //set the velocity command to zero
228  cmd_vel.linear.x = 0.0;
229  cmd_vel.linear.y = 0.0;
230  cmd_vel.angular.z = 0.0;
231  rotating_to_goal_ = false;
232  } else {
233  ROS_DEBUG("Angle: %f Tolerance: %f", angle, limits.yaw_goal_tolerance);
234  geometry_msgs::PoseStamped robot_vel;
235  odom_helper_.getRobotVel(robot_vel);
236  nav_msgs::Odometry base_odom;
237  odom_helper_.getOdom(base_odom);
238 
239  //if we're not stopped yet... we want to stop... taking into account the acceleration limits of the robot
241  if ( ! stopWithAccLimits(
242  global_pose,
243  robot_vel,
244  cmd_vel,
245  acc_lim,
246  sim_period,
247  obstacle_check)) {
248  ROS_INFO("Error when stopping.");
249  return false;
250  }
251  ROS_DEBUG("Stopping...");
252  }
253  //if we're stopped... then we want to rotate to goal
254  else {
255  //set this so that we know its OK to be moving
256  rotating_to_goal_ = true;
257  if ( ! rotateToGoal(
258  global_pose,
259  robot_vel,
260  goal_th,
261  cmd_vel,
262  acc_lim,
263  sim_period,
264  limits,
265  obstacle_check)) {
266  ROS_INFO("Error when rotating.");
267  return false;
268  }
269  ROS_DEBUG("Rotating...");
270  }
271  }
272 
273  return true;
274 
275 }
276 
277 
278 } /* namespace base_local_planner */
base_local_planner::LatchedStopRotateController::computeVelocityCommandsStopRotate
bool computeVelocityCommandsStopRotate(geometry_msgs::Twist &cmd_vel, Eigen::Vector3f acc_lim, double sim_period, LocalPlannerUtil *planner_util, OdometryHelperRos &odom_helper, const geometry_msgs::PoseStamped &global_pose, boost::function< bool(Eigen::Vector3f pos, Eigen::Vector3f vel, Eigen::Vector3f vel_samples)> obstacle_check)
Definition: latched_stop_rotate_controller.cpp:199
angles::shortest_angular_distance
static double shortest_angular_distance(double from, double to)
angle
TFSIMD_FORCE_INLINE tfScalar angle(const Quaternion &q1, const Quaternion &q2)
base_local_planner::LatchedStopRotateController::stopWithAccLimits
bool stopWithAccLimits(const geometry_msgs::PoseStamped &global_pose, const geometry_msgs::PoseStamped &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.
Definition: latched_stop_rotate_controller.cpp:110
tf2::getYaw
double getYaw(const A &a)
utils.h
base_local_planner::OdometryHelperRos::getOdom
void getOdom(nav_msgs::Odometry &base_odom)
Definition: odometry_helper_ros.cpp:97
base_local_planner::LocalPlannerUtil
Helper class implementing infrastructure code many local planner implementations may need.
Definition: local_planner_util.h:92
base_local_planner::LocalPlannerLimits::xy_goal_tolerance
double xy_goal_tolerance
Definition: local_planner_limits.h:124
base_local_planner::getGoalPositionDistance
double getGoalPositionDistance(const geometry_msgs::PoseStamped &global_pose, double goal_x, double goal_y)
return squared distance to check if the goal position has been achieved
Definition: goal_functions.cpp:49
base_local_planner::LocalPlannerLimits
Definition: local_planner_limits.h:75
base_local_planner::LatchedStopRotateController::isPositionReached
bool isPositionReached(LocalPlannerUtil *planner_util, const geometry_msgs::PoseStamped &global_pose)
Definition: latched_stop_rotate_controller.cpp:39
base_local_planner::LocalPlannerLimits::max_vel_theta
double max_vel_theta
Definition: local_planner_limits.h:117
base_local_planner::OdometryHelperRos::getRobotVel
void getRobotVel(geometry_msgs::PoseStamped &robot_vel)
Definition: odometry_helper_ros.cpp:103
base_local_planner::LatchedStopRotateController::sign
double sign(double x)
Definition: latched_stop_rotate_controller.h:82
base_local_planner::LocalPlannerLimits::theta_stopped_vel
double theta_stopped_vel
Definition: local_planner_limits.h:127
ROS_DEBUG
#define ROS_DEBUG(...)
local_planner_limits.h
ROS_DEBUG_NAMED
#define ROS_DEBUG_NAMED(name,...)
base_local_planner::LatchedStopRotateController::xy_tolerance_latch_
bool xy_tolerance_latch_
Definition: latched_stop_rotate_controller.h:88
base_local_planner::OdometryHelperRos
Definition: odometry_helper_ros.h:83
base_local_planner::getGoalOrientationAngleDifference
double getGoalOrientationAngleDifference(const geometry_msgs::PoseStamped &global_pose, double goal_th)
return angle difference to goal to check if the goal orientation has been achieved
Definition: goal_functions.cpp:53
goal_functions.h
ROS_WARN
#define ROS_WARN(...)
base_local_planner::LocalPlannerLimits::min_vel_theta
double min_vel_theta
Definition: local_planner_limits.h:118
base_local_planner::LatchedStopRotateController::rotateToGoal
bool rotateToGoal(const geometry_msgs::PoseStamped &global_pose, const geometry_msgs::PoseStamped &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.
Definition: latched_stop_rotate_controller.cpp:148
latched_stop_rotate_controller.h
base_local_planner::LatchedStopRotateController::isGoalReached
bool isGoalReached(LocalPlannerUtil *planner_util, OdometryHelperRos &odom_helper, const geometry_msgs::PoseStamped &global_pose)
Definition: latched_stop_rotate_controller.cpp:66
base_local_planner::LatchedStopRotateController::~LatchedStopRotateController
virtual ~LatchedStopRotateController()
Definition: latched_stop_rotate_controller.cpp:31
base_local_planner::LatchedStopRotateController::LatchedStopRotateController
LatchedStopRotateController(const std::string &name="")
Definition: latched_stop_rotate_controller.cpp:24
ROS_ERROR
#define ROS_ERROR(...)
ros::NodeHandle::param
T param(const std::string &param_name, const T &default_val) const
base_local_planner::LocalPlannerLimits::trans_stopped_vel
double trans_stopped_vel
Definition: local_planner_limits.h:126
base_local_planner::LocalPlannerUtil::getCurrentLimits
LocalPlannerLimits getCurrentLimits()
Definition: local_planner_util.cpp:112
base_local_planner::LocalPlannerUtil::getGoal
bool getGoal(geometry_msgs::PoseStamped &goal_pose)
Definition: local_planner_util.cpp:118
base_local_planner
Definition: costmap_model.h:44
ROS_INFO
#define ROS_INFO(...)
base_local_planner::LatchedStopRotateController::rotating_to_goal_
bool rotating_to_goal_
Definition: latched_stop_rotate_controller.h:89
base_local_planner::LatchedStopRotateController::latch_xy_goal_tolerance_
bool latch_xy_goal_tolerance_
Definition: latched_stop_rotate_controller.h:88
base_local_planner::LocalPlannerLimits::yaw_goal_tolerance
double yaw_goal_tolerance
Definition: local_planner_limits.h:125
ros::NodeHandle
angles.h
base_local_planner::stopped
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.
Definition: goal_functions.cpp:239


base_local_planner
Author(s): Eitan Marder-Eppstein, Eric Perko, contradict@gmail.com
autogenerated on Mon Mar 6 2023 03:50:24