move_omni_base.cpp
Go to the documentation of this file.
00001 #include <omnix/move_omni_base.h>
00002 #include <iostream>
00003 #include <stdio.h>
00004 
00005 MoveOmniBase::MoveOmniBase(std::string name, tf::TransformListener& tf) :
00006   tf_(tf),
00007   as_(NULL),
00008 enableLaser(true){
00009   ROS_INFO("Starting move omnibase");
00010   as_ = new MoveBaseActionServer(ros::NodeHandle(), "move_base", boost::bind(&MoveOmniBase::executeCb, this, _1), false);
00011 
00012         left_collision=false;
00013         right_collision=false;
00014         front_collision=false;
00015   vel_pub_ = nh.advertise<geometry_msgs::Twist>("cmd_vel", 1);
00016 
00017   //Set up move base action
00018   ros::NodeHandle action_nh("move_base");
00019   action_goal_pub_ = action_nh.advertise<move_base_msgs::MoveBaseActionGoal>("goal", 1);
00020 
00021   //Set up simple goal subscriber for Rviz
00022   ros::NodeHandle simple_nh("move_omni_base_simple");
00023   goal_sub_ = simple_nh.subscribe<geometry_msgs::PoseStamped>("goal", 1, boost::bind(&MoveOmniBase::goalCB, this, _1));
00024   base_scan_sub_ = simple_nh.subscribe<sensor_msgs::LaserScan>("/base_scan",1,boost::bind(&MoveOmniBase::BaseLaserCB, this, _1));
00025   as_->start();
00026   ROS_INFO("Move omni base started.");
00027 }
00028 
00029 void MoveOmniBase::BaseLaserCB(const sensor_msgs::LaserScan::ConstPtr& scan_in)
00030 {
00031 if(enableLaser)
00032 {
00033 sensor_msgs::PointCloud cloud;
00034 laser_geometry::LaserProjection projector_;
00035 projector_.projectLaser(*scan_in,cloud);
00036 //ROS_INFO("LASER %d PTS",cloud.points.size());
00037 front_collision=false;
00038 left_collision=false;
00039 right_collision=false;
00040 for(unsigned int i=0;i<cloud.points.size();i++)
00041 {
00042 geometry_msgs::Point32 pt=cloud.points[i];
00043         if(pt.x<0.09 && pt.x>0 && ((pt.y<0.3 && pt.y>0)||(pt.y>-0.3 && pt.y<0)) )
00044         {
00045         front_collision=true;
00046         }
00047         if(pt.y>0.2 && pt.y<0.36 && pt.x<0.05 && pt.x>-0.6)
00048         {
00049         left_collision=true;
00050         }
00051         if(pt.y>-0.36 && pt.y<-0.2 && pt.x<0.05 && pt.x>-0.6)
00052         {
00053         right_collision=true;
00054         }
00055 }
00056 //ROS_INFO("COLL: %d %d %d",left_collision,front_collision,right_collision);
00057 }
00058 return;
00059 }
00060 
00061 void MoveOmniBase::goalCB(const geometry_msgs::PoseStamped::ConstPtr& goal)
00062 {
00063   ROS_INFO("In goal callback!");
00064   move_base_msgs::MoveBaseActionGoal action_goal;
00065   action_goal.header.stamp = ros::Time::now();
00066   action_goal.goal.target_pose = *goal;
00067   action_goal_pub_.publish(action_goal);
00068 }
00069 
00070 geometry_msgs::PoseStamped MoveOmniBase::goalToLocalFrame(const geometry_msgs::PoseStamped& goal_pose_msg)
00071 {
00072   tf::Stamped<tf::Pose> goal_pose, local_pose;
00073   poseStampedMsgToTF(goal_pose_msg, goal_pose);
00074   
00075   goal_pose.stamp_ = ros::Time();
00076   
00077   try{
00078     tf_.transformPose("/base_link", goal_pose, local_pose);
00079   } catch (tf::TransformException& ex) {
00080     ROS_WARN("move_omni_base: TF fail.");
00081     return goal_pose_msg;
00082   }
00083   
00084   geometry_msgs::PoseStamped local_pose_msg;
00085   tf::poseStampedTFToMsg(local_pose, local_pose_msg);
00086   return local_pose_msg;
00087 }
00088 
00089 double MoveOmniBase::distance(const geometry_msgs::PoseStamped& p1, const geometry_msgs::PoseStamped& p2)
00090 {
00091   return sqrt((p1.pose.position.x - p2.pose.position.x) * (p1.pose.position.x - p2.pose.position.x)
00092               + (p1.pose.position.y - p2.pose.position.y) * (p1.pose.position.y - p2.pose.position.y));
00093 }
00094 
00095 void MoveOmniBase::executeCb(const move_base_msgs::MoveBaseGoalConstPtr& move_base_goal)
00096 {
00097   //ROS_INFO("in executeCB");
00098   bool at_goal = false;
00099         bool coll=false;
00100   double goal_tolerance = 0.03;//meters
00101   double goal_tolerance_rot = 0.11;
00102   double xy_scale = 0.2;
00103   double rot_scale = 1.4; //0.1
00104   ros::Rate r(30);
00105         
00106         double min_rot_vel=0.12;
00107         
00108   geometry_msgs::PoseStamped base = geometry_msgs::PoseStamped();
00109   enableLaser=true;
00110   
00111   while(!(as_->isPreemptRequested()) && (ros::ok()) && (!at_goal)){
00112     //Get the goal location in the base frame
00113     
00114                 geometry_msgs::PoseStamped goal = goalToLocalFrame(move_base_goal->target_pose);
00115     double goal_yaw = tf::getYaw(goal.pose.orientation);
00116     
00117     //Check if we're close enough
00118         //std::cout<<"(distance(goal,base): "<<distance(goal,base)<<std::endl;
00119         //std::cout<<"fabs(goal_yaw): "<<fabs(goal_yaw)<<std::endl;
00120 
00121 bool yaw_satisfied;
00122 if(fabs(goal_yaw) < goal_tolerance_rot)
00123 yaw_satisfied=true;
00124 else
00125 yaw_satisfied=false;
00126 
00127 bool pos_satisfied;
00128 if(distance(goal,base) <= goal_tolerance)
00129 pos_satisfied=true;
00130 else
00131 pos_satisfied=false;
00132         
00133         if(yaw_satisfied && pos_satisfied)
00134     {
00135       at_goal = true;
00136       break;
00137     } 
00138     else 
00139     {      
00140       //Calculate a velocity
00141       double xvel, yvel = 0.0;
00142       tf::Vector3 vel_vec = tf::Vector3(goal.pose.position.x,
00143                                         goal.pose.position.y,
00144                                         0.0);
00145       vel_vec.normalize();
00146       xvel = vel_vec.getX();
00147       yvel = vel_vec.getY();
00148 
00149       //ROS_INFO("Goal yaw: %lf",goal_yaw);
00150       
00151       geometry_msgs::Twist cmd_vel;
00152                         if(pos_satisfied)
00153                         {
00154                         cmd_vel.linear.x =0.0;
00155                         cmd_vel.linear.y =0.0;
00156                         }
00157                         else
00158                         {
00159       cmd_vel.linear.x = xvel * xy_scale;
00160       cmd_vel.linear.y = yvel * xy_scale;
00161                         }
00162                 if(yaw_satisfied)
00163                 {
00164                 cmd_vel.angular.z=0;
00165                 }
00166                 else
00167                 {
00168       double rot_vel =  (goal_yaw / M_PI) * rot_scale;
00169 
00170                         if(rot_vel<0.0) //rot_vel negative
00171                         {
00172                                 if(rot_vel>-min_rot_vel)
00173                                 {
00174                                         rot_vel=-min_rot_vel;
00175                                 }
00176                         }
00177                         else //rot_vel positive
00178                         {
00179                                 if(rot_vel<min_rot_vel)
00180                                 {
00181                                 rot_vel=min_rot_vel;
00182                                 }
00183                         }
00184                         
00185       cmd_vel.angular.z = rot_vel;      
00186                 }
00187                 
00188                 if(cmd_vel.linear.x>0.001 && front_collision)
00189                 {
00190                 coll=true;
00191                 }
00192                 if(cmd_vel.linear.y>0.001) //check left
00193                 {
00194                         if(left_collision)
00195                         {
00196                         coll=true;
00197                         }
00198                 }
00199                 else if(cmd_vel.linear.y<-0.001) //check right
00200                 {
00201                         if(right_collision)
00202                         {
00203                         coll=true;
00204                         }
00205                 }
00206         if(coll)
00207         {
00208         cmd_vel.linear.x=0;
00209         cmd_vel.linear.y=0;
00210         cmd_vel.linear.z=0;
00211         cmd_vel.angular.z=0;
00212         vel_pub_.publish(cmd_vel);
00213 break;
00214         }
00215         else
00216         {
00217                                 vel_pub_.publish(cmd_vel);
00218         }
00219                                                                         
00220       r.sleep();
00221     }
00222   }
00223 
00224   if(at_goal)
00225   {
00226     as_->setSucceeded(move_base_msgs::MoveBaseResult(), "Goal reached.");
00227   }
00228         else
00229         {
00230                 as_->setAborted(move_base_msgs::MoveBaseResult(), "Goal aborted.");
00231         }
00232         enableLaser=false;
00233         front_collision=false;
00234         left_collision=false;
00235         right_collision=false;
00236   return;
00237 }
00238 
00239 
00240 int main(int argc, char** argv){
00241   ros::init(argc, argv, "move_omni_base_node");
00242   tf::TransformListener tf(ros::Duration(10));
00243   
00244   MoveOmniBase move_omni_base("move_omni_base", tf);
00245   
00246   ros::spin();
00247   
00248   return(0);
00249 }


omnix
Author(s): Alexander J Trevor
autogenerated on Wed Nov 27 2013 12:06:10