force_rotate_recovery.cpp
Go to the documentation of this file.
00001 #include <force_rotate_recovery/force_rotate_recovery.h>
00002 #include <pluginlib/class_list_macros.h>
00003 
00004 PLUGINLIB_EXPORT_CLASS(force_rotate_recovery::ForceRotateRecovery, nav_core::RecoveryBehavior);
00005 
00006 namespace force_rotate_recovery {
00007     ForceRotateRecovery::ForceRotateRecovery() : 
00008         global_costmap_(NULL), 
00009         local_costmap_(NULL), 
00010         initialized_(false), 
00011         world_model_(NULL) 
00012     {
00013 
00014     } 
00015 
00016     void ForceRotateRecovery::initialize(std::string name, tf::TransformListener* tf,
00017                                          costmap_2d::Costmap2DROS* global_costmap, costmap_2d::Costmap2DROS* local_costmap){
00018         if(!initialized_){
00019             name_ = name;
00020             global_costmap_ = global_costmap;
00021             local_costmap_ = local_costmap;
00022 
00023             //get some parameters from the parameter server
00024             ros::NodeHandle private_nh("~/" + name_);
00025             ros::NodeHandle blp_nh("~/TrajectoryPlannerROS");
00026 
00027             //we'll simulate every degree by default
00028             private_nh.param("sim_granularity", sim_granularity_, 0.017);
00029             private_nh.param("frequency", frequency_, 20.0);
00030 
00031             blp_nh.param("acc_lim_th", acc_lim_th_, 3.2);
00032             blp_nh.param("max_rotational_vel", max_rotational_vel_, 1.0);
00033             blp_nh.param("min_in_place_rotational_vel", min_rotational_vel_, 0.4);
00034             blp_nh.param("yaw_goal_tolerance", tolerance_, 0.10);
00035 
00036             world_model_ = new base_local_planner::CostmapModel(*local_costmap_->getCostmap());
00037 
00038             initialized_ = true;
00039         }else{
00040             ROS_ERROR("You should not call initialize twice on this object, doing nothing");
00041         }
00042     }
00043     
00044     void ForceRotateRecovery::runBehavior(){
00045         if(!initialized_){
00046             ROS_ERROR("This object must be initialized before runBehavior is called");
00047             return;
00048         }
00049 
00050         if(global_costmap_ == NULL || local_costmap_ == NULL){
00051             ROS_ERROR("The costmaps passed to the ForceRotateRecovery object cannot be NULL. Doing nothing.");
00052             return;
00053         }
00054         
00055         ROS_WARN("rotate recovery behavior -f started.");
00056 
00057         ros::Rate r(frequency_);
00058         ros::NodeHandle n;
00059         ros::Publisher vel_pub = n.advertise<geometry_msgs::Twist>("cmd_vel", 10);
00060       
00061         tf::Stamped<tf::Pose> global_pose;
00062         local_costmap_->getRobotPose(global_pose);
00063 
00064         double current_angle = -1.0 * M_PI;
00065 
00066         bool got_180 = false;
00067 
00068         double start_offset = 0 - angles::normalize_angle(tf::getYaw(global_pose.getRotation()));
00069         while(n.ok()){
00070             local_costmap_->getRobotPose(global_pose);
00071 
00072             double norm_angle = angles::normalize_angle(tf::getYaw(global_pose.getRotation()));
00073             current_angle = angles::normalize_angle(norm_angle + start_offset);
00074 
00075             //compute the distance left to rotate
00076             double dist_left = 4 * M_PI - current_angle;
00077 
00078             double x = global_pose.getOrigin().x(), y = global_pose.getOrigin().y();
00079 
00080             //check if that velocity is legal by forward simulating
00081             double sim_angle = 0.0;
00082             while(sim_angle < dist_left){
00083                 double theta = tf::getYaw(global_pose.getRotation()) + sim_angle;
00084 
00085                 double footprint_cost = world_model_->footprintCost(x, y, theta, local_costmap_->getRobotFootprint(), 0.0, 0.0);
00086                 if(footprint_cost < 0.0){
00087                     ROS_WARN("Rotate recovery can't rotate in place because there is a potential collision. Cost: %.2f", footprint_cost);
00088                 }
00089 
00090                 sim_angle += sim_granularity_;
00091             }
00092 
00093             double vel = sqrt(2 * acc_lim_th_ * dist_left);
00094 
00095             vel = std::min(std::max(vel, min_rotational_vel_), max_rotational_vel_);
00096 
00097             geometry_msgs::Twist cmd_vel;
00098             cmd_vel.linear.x = 0.0;
00099             cmd_vel.linear.y = 0.0;
00100             cmd_vel.angular.z = vel;
00101 
00102             vel_pub.publish(cmd_vel);
00103 
00104             if(current_angle < 0.0)
00105               got_180 = true;
00106 
00107             if(got_180 && current_angle >= (0.0 - tolerance_))
00108                 return;
00109 
00110             r.sleep();
00111       }
00112     }
00113 };
00114 


force_rotate_recovery
Author(s): Eitan Marder-Eppstein, contradict@gmail.com, Daiki Maekawa
autogenerated on Fri Oct 16 2015 10:27:42