Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00041 #include <eband_local_planner/FollowBaseTrajectoryAction.h>
00042 #include <actionlib/server/simple_action_server.h>
00043 #include <geometry_msgs/Twist.h>
00044 #include <tf/transform_listener.h>
00045 #include <eband_local_planner/eband_local_planner_ros.h>
00046 #include <boost/thread.hpp>
00047 #include <boost/foreach.hpp>
00048 #include <boost/format.hpp>
00049 
00050 namespace al=actionlib;
00051 namespace gm=geometry_msgs;
00052 namespace cmap=costmap_2d;
00053 namespace eband=eband_local_planner;
00054 
00055 using std::string;
00056 using boost::format;
00057 
00058 namespace eband_local_planner
00059 {
00060 
00061 typedef FollowBaseTrajectoryGoalConstPtr GoalPtr;
00062 typedef FollowBaseTrajectoryResult Result;
00063 typedef boost::mutex::scoped_lock Lock;
00064 
00065 Result result (const string& msg)
00066 {
00067   Result r;
00068   r.msg = msg;
00069   return r;
00070 }
00071 
00072 Result result (const format& f)
00073 {
00074   return result(f.str());
00075 }
00076 
00077 
00078 struct ScopedCostmapActivate
00079 {
00080   ScopedCostmapActivate (cmap::Costmap2DROS* cmap) : cmap(cmap)
00081   {
00082     cmap->start();
00083   }
00084 
00085   ~ScopedCostmapActivate ()
00086   {
00087     cmap->pause();
00088   }
00089 
00090   cmap::Costmap2DROS* cmap;
00091 };
00092 
00093 
00094 class Node
00095 {
00096 public:
00097   
00098   Node ();
00099   void execute (const GoalPtr& goal);
00100 
00101 private:
00102 
00103   ros::Rate control_rate_;
00104   ros::Duration control_timeout_;
00105 
00106   ros::Time last_valid_control_;
00107   
00108   boost::mutex mutex_;
00109   ros::NodeHandle nh_;
00110   tf::TransformListener tf_;
00111   al::SimpleActionServer<FollowBaseTrajectoryAction> as_;
00112   cmap::Costmap2DROS costmap_ros_;
00113   ros::Publisher vel_pub_;
00114   eband::EBandPlannerROS tc_;
00115 
00116 };
00117 
00118 inline gm::Twist zeroVelocity ()
00119 {
00120   return gm::Twist();
00121 }
00122 
00123 
00124 Node::Node () :
00125   control_rate_(10.0), control_timeout_(2.0),
00126   as_(nh_, "follow_base_trajectory", boost::bind(&Node::execute, this, _1), false),
00127   costmap_ros_("elastic_band_planner", tf_),
00128   vel_pub_(nh_.advertise<gm::Twist>("cmd_vel", 10))
00129 {
00130   Lock l(mutex_);
00131   costmap_ros_.pause();
00132   
00133   
00134   tc_.initialize("elastic_band_planner", &tf_, &costmap_ros_);
00135   as_.start();
00136   ROS_INFO ("Eband node initialized");
00137 }
00138 
00139 void Node::execute (const GoalPtr& goal)
00140 {
00141   
00142   ScopedCostmapActivate cmap_activate(&costmap_ros_);
00143   Lock l(mutex_);
00144 
00145   const unsigned n=goal->path.size();
00146   if (n<2)
00147   {
00148     as_.setAborted(result(format("Path had length %1%") % n));
00149     return;
00150   }
00151   
00152   
00153   ROS_DEBUG_STREAM_NAMED ("control", "Received trajectory of length " << n <<
00154                           " going from " << goal->path[0].pose << " to "
00155                           << goal->path[n-1].pose);
00156   if (!tc_.setPlan(goal->path))
00157   {
00158     as_.setAborted(result("Failed setting plan for controller;"
00159                           "see stdout for error message"));
00160     return;
00161   }
00162   
00163 
00164   
00165   last_valid_control_ = ros::Time::now();
00166   while (ros::ok() && !tc_.isGoalReached())
00167   {
00168     gm::Twist vel;
00169     if (!tc_.computeVelocityCommands(vel))
00170     {
00171       ROS_DEBUG_STREAM_NAMED ("control", "Didn't find valid control");
00172       vel_pub_.publish(zeroVelocity());
00173       if (ros::Time::now() - last_valid_control_ > control_timeout_)
00174       {
00175         as_.setAborted(result("Timed out finding a valid control"));
00176         return;
00177       }
00178       continue;
00179     }
00180 
00181     
00182     ROS_DEBUG_STREAM_THROTTLE_NAMED (1.0, "control", "Sending control " << vel);
00183     vel_pub_.publish(vel);
00184     last_valid_control_ = ros::Time::now();
00185     ros::spinOnce();
00186     control_rate_.sleep();
00187   }
00188 
00189   ROS_DEBUG_STREAM_NAMED ("control", "Succeeded");
00190   as_.setSucceeded();
00191 }
00192 
00193 } 
00194 
00195 int main (int argc, char** argv)
00196 {
00197   ros::init(argc, argv, "eband_action");
00198   ros::NodeHandle nh;
00199   eband_local_planner::Node node;
00200   ros::spin();
00201   return 0;
00202 }