no_collision_alg_node.cpp
Go to the documentation of this file.
00001 #include "no_collision_alg_node.h"
00002 #include<tf/tf.h>
00003 
00004 NoCollisionAlgNode::NoCollisionAlgNode(void) :
00005   move_base_aserver_(public_node_handle_, "MoveBase"),
00006   tf_listener_(ros::Duration(10.f)),
00007   tf_listener2_(ros::Duration(10.f)),
00008   is_laser_ready_(false),
00009   target_frame_("/base_link"),
00010   fixed_frame_("/odom")
00011 {
00012   //init class attributes if necessary
00013   loop_rate_ = 10;//5;//10;//in [Hz]
00014 
00015   // [init publishers]
00016   goal_marker_publisher_    = public_node_handle_.advertise<visualization_msgs::Marker>("goal_marker", 100);
00017   segway_cmd_publisher_     = public_node_handle_.advertise<geometry_msgs::Twist>("segway_cmd", 100);
00018   
00019   // [init subscribers]
00020   this->target_vel_subscriber_ = this->public_node_handle_.subscribe("target_vel", 100, &NoCollisionAlgNode::target_vel_callback, this);
00021   frontal_laser_subscriber_ = public_node_handle_.subscribe("scan", 100, &NoCollisionAlgNode::frontal_laser_callback, this);
00022   
00023   // [init services]
00024   
00025   // [init clients]
00026   
00027   // [init action servers]
00028   move_base_aserver_.registerStartCallback(boost::bind(&NoCollisionAlgNode::startCallback, this, _1));
00029   move_base_aserver_.registerStopCallback(boost::bind(&NoCollisionAlgNode::stopCallback, this));
00030   move_base_aserver_.registerIsFinishedCallback(boost::bind(&NoCollisionAlgNode::isFinishedCallback, this));
00031   move_base_aserver_.registerHasSucceedCallback(boost::bind(&NoCollisionAlgNode::hasSucceedCallback, this));
00032   move_base_aserver_.registerGetResultCallback(boost::bind(&NoCollisionAlgNode::getResultCallback, this, _1));
00033   move_base_aserver_.registerGetFeedbackCallback(boost::bind(&NoCollisionAlgNode::getFeedbackCallback, this, _1));
00034 
00035   // [init action clients]
00036 
00037   goal_marker_.pose.orientation = tf::createQuaternionMsgFromYaw(0);
00038   goal_marker_.type = visualization_msgs::Marker::CYLINDER;
00039   goal_marker_.action = visualization_msgs::Marker::ADD;
00040   goal_marker_.scale.x = 0.5;
00041   goal_marker_.scale.y = 0.5;
00042   goal_marker_.scale.z = 0.5;
00043   goal_marker_.color.a = 1.0;
00044   goal_marker_.color.r = 0.0;
00045   goal_marker_.color.g = 1.0;
00046   goal_marker_.color.b = 0.0;
00047 
00048   std::string tf_prefix;
00049   public_node_handle_.param<std::string>("tf_prefix", tf_prefix, "");
00050 
00051   target_frame_ = tf_prefix + "/base_link";
00052   fixed_frame_  = tf_prefix  + "/odom";
00053 
00054   action_running_=false;
00055 }
00056 
00057 NoCollisionAlgNode::~NoCollisionAlgNode(void)
00058 {
00059   // [free dynamic memory]
00060 }
00061 
00062 void NoCollisionAlgNode::mainNodeThread(void)
00063 {
00064   ros::Time target_time=ros::Time::now();
00065   geometry_msgs::PoseStamped current_local_goal;
00066   std::string source_frame = goal_pose_.header.frame_id; //(tf_prefix+"/base_link");
00067 
00068   if(!move_base_aserver_.isStarted())
00069   {
00070     if(is_laser_ready_)
00071     {
00072       move_base_aserver_.start();
00073       ROS_INFO("NoCollisionAlgNode:: Server Started!"); 
00074     }
00075   }
00076   else
00077   {
00078     if(action_running_)
00079     {
00080       try
00081       {
00082         // update the time stamp of the goal_pose_
00083         goal_pose_.header.stamp=ros::Time::now();
00084         // wait for a transformation between the fixed frame and the target_frame to be available now
00085                                     //waitForTransform(fixed_frame,   target_frame, target_time,        timeout, polling_sleep_duration);
00086         bool tf_exists = tf_listener_.waitForTransform(fixed_frame_, target_frame_, target_time, ros::Duration(10), ros::Duration(0.01));
00087         if(tf_exists)
00088         {
00089           geometry_msgs::Twist twist;
00090           // get the transformation of the goal_pose_ with respect to the current target_frame
00091           //tf_listener_.transformPose(target_frame, target_time, poseIn, fixed_frame, poseOut);
00092           tf_listener_.transformPose(target_frame_, target_time, goal_pose_, fixed_frame_, current_local_goal);
00093           // send nav goal marker for rviz visualization
00094           //goal_marker_.header.seq      = goal_pose_.header.seq;
00095           //goal_marker_.header.stamp    = target_time;
00096           //goal_marker_.header.frame_id = target_frame;
00097           goal_marker_.header          = goal_pose_.header;
00098           goal_marker_.pose            = goal_pose_.pose;//current_local_goal.pose;
00099           goal_marker_publisher_.publish(goal_marker_);
00100           // compute new twist based on laser scan and current goal position
00101           if(alg_.movePlatform(scan_, current_local_goal.pose,twist))
00102             action_running_=false;
00103           // send twist to platform
00104           segway_cmd_publisher_.publish(twist);
00105         }
00106         else
00107         {
00108           geometry_msgs::Twist twist;
00109           // send twist to platform
00110           segway_cmd_publisher_.publish(twist);
00111           ROS_INFO("NoCollisionAlgNode::No transform: %s-->%s", fixed_frame_.c_str(), target_frame_.c_str());
00112           move_base_aserver_.setAborted();
00113         }
00114       }
00115       catch (tf::TransformException &ex)
00116       {
00117         geometry_msgs::Twist twist;
00118         // send twist to platform
00119         segway_cmd_publisher_.publish(twist);
00120         ROS_INFO("NoCollisionAlgNode:: %s",ex.what());
00121         move_base_aserver_.setAborted();
00122       }
00123     }
00124   }
00125 
00126     // [fill msg structures]
00127 
00128     // [fill srv structure and make request to the server]
00129 
00130     // [fill action structure and make request to the action server]
00131 
00132     // [publish messages]
00133 }
00134 
00135 /*  [subscriber callbacks] */
00136 void NoCollisionAlgNode::frontal_laser_callback(const sensor_msgs::LaserScan::ConstPtr& msg) 
00137 { 
00138 //   ROS_INFO("NoCollisionAlgNode::frontal_laser_callback: New Message Received"); 
00139 
00140   alg_.lock();
00141     is_laser_ready_ = true;
00142 
00143     scan_.header          = msg->header;
00144     scan_.angle_min       = msg->angle_min;
00145     scan_.angle_max       = msg->angle_max;
00146     scan_.angle_increment = msg->angle_increment;
00147     scan_.time_increment  = msg->time_increment; 
00148     scan_.scan_time       = msg->scan_time;
00149     scan_.range_min       = msg->range_min;
00150     scan_.range_max       = msg->range_max;
00151     scan_.ranges          = msg->ranges;
00152     scan_.intensities     = msg->intensities;
00153 
00154   alg_.unlock();
00155 }
00156 
00157 void NoCollisionAlgNode::target_vel_callback(const geometry_msgs::Twist::ConstPtr& msg) 
00158 { 
00159   ROS_INFO("NoCollisionAlgNode::target_vel_callback: New Message Received"); 
00160 
00161   //use appropiate mutex to shared variables if necessary 
00162   //this->alg_.lock(); 
00163   //this->target_vel_mutex_.enter(); 
00164 
00165   this->alg_.setTranslationalSpeed(msg->linear.x);
00166   this->alg_.setRotationalSpeed(msg->angular.z);
00167   //std::cout << msg->data << std::endl; 
00168 
00169   //unlock previously blocked shared variables 
00170   //this->alg_.unlock(); 
00171   //this->target_vel_mutex_.exit(); 
00172 }
00173 
00174 /*  [service callbacks] */
00175 
00176 /*  [action callbacks] */
00177 
00178 
00179 void NoCollisionAlgNode::startCallback(const move_base_msgs::MoveBaseGoalConstPtr& goal)
00180 {
00181   ROS_INFO("NoCollisionAlgNode::start action: New action received"); 
00182 
00183   try
00184   {
00185     std::string source_frame = goal->target_pose.header.frame_id;
00186     ros::Time   source_time  = goal->target_pose.header.stamp;
00187 
00188                                  //waitForTransform(target_frame,       target_time, source_frame, source_time,  fixed_frame,           timeout, polling_sleep_duration);
00189     bool tf_exists  = tf_listener_.waitForTransform(target_frame_, ros::Time::now(), source_frame, source_time, fixed_frame_, ros::Duration(10), ros::Duration(0.01));
00190 
00191                                    //waitForTransform(target_frame,  source_frame,        time,           timeout, polling_sleep_duration);
00192     //bool tf_exists  = tf_listener_.waitForTransform(fixed_frame_,  source_frame, source_time, ros::Duration(10), ros::Duration(0.01));
00193     //bool tf_exists2 = tf_listener_.waitForTransform(target_frame_, fixed_frame_, source_time, ros::Duration(10), ros::Duration(0.01));
00194     if(tf_exists /*&& tf_exists2*/ )
00195     {
00196       geometry_msgs::PoseStamped current_local_goal;
00197       geometry_msgs::Twist twist;
00198       // get the position of the goal in the fixed_frame_ reference frame
00199       tf_listener_.transformPose(fixed_frame_,goal->target_pose,goal_pose_);
00200       // set the frame of the new goal_pose_ (hust in case)
00201       goal_pose_.header.frame_id=fixed_frame_;
00202       // get the position of the goal in the base_link frame
00203       tf_listener_.transformPose(target_frame_, source_time, goal_pose_, fixed_frame_, current_local_goal);
00204       // reset distance to goal for new action
00205       alg_.setGoal(current_local_goal.pose);
00206       alg_.movePlatform(scan_, current_local_goal.pose,twist);
00207       // get current time
00208       action_start_ = ros::Time::now();
00209       // send twist to platform
00210       segway_cmd_publisher_.publish(twist);
00211       action_running_=true;
00212     }
00213     else
00214     {
00215       ROS_ERROR("NoCollisionAlgNode::No transform");
00216       move_base_aserver_.setAborted();
00217     }
00218   }
00219   catch (tf::TransformException &ex)
00220   {
00221     ROS_ERROR("NoCollisionAlgNode::startCallback: %s", ex.what());
00222     move_base_aserver_.setAborted(); 
00223   }
00224 
00225 }
00226 
00227 void NoCollisionAlgNode::stopCallback(void)
00228 {
00229   ROS_WARN("NoCollisionAlgNode::stopCallback!!");
00230   //lock access to driver if necessary
00231   alg_.lock();
00232       geometry_msgs::Twist twist;// set both speeds to 0
00233       // send twist to platform
00234       segway_cmd_publisher_.publish(twist);
00235   //lock access to driver if necessary
00236   alg_.unlock();
00237 }
00238 
00239 bool NoCollisionAlgNode::isFinishedCallback(void)
00240 {
00241   bool ret;
00242 
00243     ros::Duration elapsed_time = action_start_ - ros::Time::now();
00244     ret = ( alg_.isGoalReached() || elapsed_time.toSec() > ACTION_TIMEOUT );
00245 
00246   return ret;
00247 }
00248 
00249 bool NoCollisionAlgNode::hasSucceedCallback(void)
00250 {
00251   bool ret;
00252 
00253   ret = alg_.isGoalReached();
00254 
00255   return ret;
00256 }
00257 
00258 void NoCollisionAlgNode::getResultCallback(move_base_msgs::MoveBaseResultPtr& result)
00259 {
00260   //lock access to driver if necessary
00261   alg_.lock();
00262 
00263   //lock access to driver if necessary
00264   alg_.unlock();
00265 }
00266 
00267 void NoCollisionAlgNode::getFeedbackCallback(move_base_msgs::MoveBaseFeedbackPtr& feedback)
00268 {
00269   ROS_WARN("NoCollisionAlgNode::Feedback");
00270   // update feedback with distance to goal
00271 //  alg_.getDistance2Goal(feedback->base_position.pose);
00272 //  feedback->base_position.header.stamp = ros::Time::now();
00273 //  feedback->base_position.header.frame_id = target_frame_;
00274 }
00275 
00276 /*  [action requests] */
00277 
00278 void NoCollisionAlgNode::node_config_update(Config &config, uint32_t level)
00279 {
00280 }
00281 
00282 void NoCollisionAlgNode::addNodeDiagnostics(void)
00283 {
00284 }
00285 
00286 /* main function */
00287 int main(int argc,char *argv[])
00288 {
00289   return algorithm_base::main<NoCollisionAlgNode>(argc, argv, "no_collision_alg_node");
00290 }


iri_no_collision
Author(s):
autogenerated on Fri Dec 6 2013 21:10:48