12 #include "geometry_msgs/PolygonStamped.h" 13 #include "nav_msgs/Path.h" 22 : nh_(), world_model_(NULL), tc_(NULL), costmap_ros_(costmap_ros),
tf_(tf) {
25 double acc_lim_x, acc_lim_y, acc_lim_theta, sim_time, sim_granularity;
26 int vx_samples, vy_samples, vtheta_samples;
27 double userdist_scale, occdist_scale;
28 bool dwa, holonomic_robot;
29 double max_vel_x, min_vel_x;
30 double max_vel_y, min_vel_y;
31 string world_model_type;
50 geometry_msgs::Twist vel;
59 private_nh.
param(
"acc_lim_x", acc_lim_x, 2.5);
60 private_nh.
param(
"acc_lim_y", acc_lim_y, 2.5);
61 private_nh.
param(
"acc_lim_th", acc_lim_theta, 3.2);
62 private_nh.
param(
"sim_time", sim_time, 1.0);
63 private_nh.
param(
"sim_granularity", sim_granularity, 0.025);
64 private_nh.
param(
"vx_samples", vx_samples, 3);
65 private_nh.
param(
"vy_samples", vy_samples, 5);
66 private_nh.
param(
"vtheta_samples", vtheta_samples, 10);
67 private_nh.
param(
"user_bias", userdist_scale, 0.6);
68 private_nh.
param(
"occdist_scale", occdist_scale, 0.01);
69 private_nh.
param(
"max_vel_x", max_vel_x, 0.5);
70 private_nh.
param(
"min_vel_x", min_vel_x, 0.1);
71 private_nh.
param(
"max_vel_y", max_vel_y, 0.2);
72 private_nh.
param(
"min_vel_y", min_vel_y, -0.2);
75 double max_rotational_vel;
76 private_nh.
param(
"max_rotational_vel", max_rotational_vel, 1.0);
80 private_nh.
param(
"world_model", world_model_type,
string(
"costmap"));
81 private_nh.
param(
"holonomic_robot", holonomic_robot,
true);
82 private_nh.
param(
"dwa", dwa,
true);
86 double min_pt_separation, max_obstacle_height, grid_resolution;
88 private_nh.
param(
"point_grid/min_pt_separation", min_pt_separation, 0.01);
89 private_nh.
param(
"point_grid/max_obstacle_height", max_obstacle_height, 2.0);
90 private_nh.
param(
"point_grid/grid_resolution", grid_resolution, 0.2);
92 ROS_ASSERT_MSG(world_model_type ==
"costmap",
"At this time, only costmap world models are supported by this controller");
95 std::vector<double> y_vels =
loadYVels(private_nh);
98 acc_lim_x, acc_lim_y, acc_lim_theta, sim_time, sim_granularity, vx_samples, vy_samples, vtheta_samples,
99 userdist_scale, occdist_scale,
101 holonomic_robot, dwa);
105 std::vector<double> y_vels;
108 if(node.
getParam(
"y_vels", y_vel_list)){
110 "The y velocities to explore must be specified as a list");
112 for(
int i = 0; i < y_vel_list.
size(); ++i){
120 y_vels.push_back(y_vel);
126 y_vels.push_back(-0.3);
127 y_vels.push_back(-0.1);
128 y_vels.push_back(0.1);
129 y_vels.push_back(0.3);
144 boost::recursive_mutex::scoped_lock(
odom_lock_);
151 return sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
156 boost::recursive_mutex::scoped_lock(
odom_lock_);
157 base_odom_.twist.twist.linear.x = msg->twist.twist.linear.x;
158 base_odom_.twist.twist.linear.y = msg->twist.twist.linear.y;
159 base_odom_.twist.twist.angular.z = msg->twist.twist.angular.z;
165 if ((
safe_backwards_ && ((fabs(vel->linear.x) > 0) || (fabs(vel->linear.y) > 0))) ||
166 (!
safe_backwards_ && ((vel->linear.x > 0) || (fabs(vel->linear.y) > 0))))
168 geometry_msgs::Twist safe_vel;
171 if ((vel->linear.x != safe_vel.linear.x) || (vel->angular.z != safe_vel.angular.z)) {
172 ROS_DEBUG(
"safe: (%.2f, %.2f) -> (%.2f, %.2f)",
173 vel->linear.x, vel->angular.z,
174 safe_vel.linear.x, safe_vel.angular.z);
177 geometry_msgs::Twist zero_vel;
179 ROS_DEBUG(
"zero: (%.2f, %.2f) -> (%.2f, %.2f)",
180 vel->linear.x, vel->angular.z,
181 zero_vel.linear.x, zero_vel.angular.z);
190 std::vector<geometry_msgs::PoseStamped> local_plan;
191 std::vector<geometry_msgs::PoseStamped> user_plan;
193 #if ROS_VERSION_MINIMUM(1, 14, 0) // ROS_MELODIC 194 geometry_msgs::PoseStamped global_pose_stamped;
210 geometry_msgs::Twist global_vel;
213 global_vel.linear.x =
base_odom_.twist.twist.linear.x;
214 global_vel.linear.y =
base_odom_.twist.twist.linear.y;
215 global_vel.angular.z =
base_odom_.twist.twist.angular.z;
251 cmd_vel.linear.x = drive_cmds.getOrigin().getX();
252 cmd_vel.linear.y = drive_cmds.getOrigin().getY();
253 cmd_vel.angular.z =
tf::getYaw(drive_cmds.getRotation());
265 double p_x, p_y, p_th;
269 geometry_msgs::PoseStamped pose;
271 local_plan.push_back(pose);
276 double p_x, p_y, p_th;
277 user_path.
getPoint(i, p_x, p_y, p_th);
280 geometry_msgs::PoseStamped pose;
282 user_plan.push_back(pose);
297 nav_msgs::Path gui_path;
298 gui_path.poses.resize(path.size());
300 gui_path.header.stamp = path[0].header.stamp;
303 for(
unsigned int i=0; i < path.size(); i++){
304 gui_path.poses[i] = path[i];
316 int main(
int argc,
char** argv) {
317 ros::init(argc, argv,
"safe_trajectory_node");
318 #if ROS_VERSION_MINIMUM(1, 14, 0) // ROS_MELODIC
int main(int argc, char **argv)
void publish(const boost::shared_ptr< M > &message) const
void setData(const T &input)
double distance(double x1, double y1, double x2, double y2)
Compute the distance between two points.
bool getRobotPose(tf::Stamped< tf::Pose > &global_pose) const
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
static void poseStampedTFToMsg(const Stamped< Pose > &bt, geometry_msgs::PoseStamped &msg)
static double getYaw(const Quaternion &bt_q)
void publishPlan(const std::vector< geometry_msgs::PoseStamped > &path, const ros::Publisher &pub, double r, double g, double b, double a)
Publish a plan for visualization purposes.
std::string getGlobalFrameID()
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
double max_sensor_range_
Keep track of the effective maximum range of our sensors.
ros::ServiceServer clear_costmaps_srv_
costmap_2d::Costmap2D costmap_
The costmap the controller will use.
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
void getPoint(unsigned int index, double &x, double &y, double &th) const
std::string robot_base_frame_
Used as the base frame id of the robot.
Type const & getType() const
costmap_2d::Costmap2DROS * costmap_ros_
The ROS wrapper for the costmap the controller will use.
ROSCPP_DECL void spin(Spinner &spinner)
void odomCallback(const nav_msgs::Odometry::ConstPtr &msg)
Computes control velocities for a robot given a costmap, a plan, and the robot's position in the worl...
double getInscribedRadius()
double trans_stopped_velocity_
ros::Publisher u_plan_pub_
void cmdCallback(const geometry_msgs::Twist::ConstPtr &vel)
nav_msgs::Odometry base_odom_
Used to get the velocity of the robot.
static Quaternion createQuaternionFromYaw(double yaw)
base_local_planner::Trajectory findPath(tf::Stamped< tf::Pose > global_pose, tf::Stamped< tf::Pose > global_vel, tf::Stamped< tf::Pose > user_vel)
Given the current position, orientation, and velocity of the robot, return a trajectory to follow...
double circumscribed_radius_
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
#define ROS_ASSERT_MSG(cond,...)
ros::Subscriber user_sub_
bool clearCostmapsService(std_srvs::Empty::Request &req, std_srvs::Empty::Response &resp)
std::string getBaseFrameID()
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
ros::Subscriber odom_sub_
std::string global_frame_
The frame in which the controller will run.
A ROS wrapper for the trajectory controller that queries the param server to construct a controller...
unsigned int getPointsSize() const
bool stopped()
Check whether the robot is stopped or not.
~SafeTrajectoryPlannerROS()
Destructor for the wrapper.
std::vector< double > loadYVels(ros::NodeHandle node)
boost::recursive_mutex odom_lock_
bool getParam(const std::string &key, std::string &s) const
static void poseStampedMsgToTF(const geometry_msgs::PoseStamped &msg, Stamped< Pose > &bt)
bool computeVelocityCommands(const geometry_msgs::Twist::ConstPtr &vel, geometry_msgs::Twist &cmd_vel)
Given the current position, orientation, and velocity of the robot, compute velocity commands to send...
double rot_stopped_velocity_
base_local_planner::Trajectory findBestPath(tf::Stamped< tf::Pose > global_pose, tf::Stamped< tf::Pose > global_vel, tf::Stamped< tf::Pose > user_vel, tf::Stamped< tf::Pose > &drive_velocities)
Given the current position, orientation, and velocity of the robot, return a trajectory to follow...
std::vector< geometry_msgs::Point > getRobotFootprint()
double getCircumscribedRadius()
base_local_planner::WorldModel * world_model_
The world model that the controller will use.
ros::Publisher l_plan_pub_
SafeTrajectoryPlanner * tc_
The trajectory controller.
LayeredCostmap * getLayeredCostmap()