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
00018 ros::NodeHandle action_nh("move_base");
00019 action_goal_pub_ = action_nh.advertise<move_base_msgs::MoveBaseActionGoal>("goal", 1);
00020
00021
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
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
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
00098 bool at_goal = false;
00099 bool coll=false;
00100 double goal_tolerance = 0.03;
00101 double goal_tolerance_rot = 0.11;
00102 double xy_scale = 0.2;
00103 double rot_scale = 1.4;
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
00113
00114 geometry_msgs::PoseStamped goal = goalToLocalFrame(move_base_goal->target_pose);
00115 double goal_yaw = tf::getYaw(goal.pose.orientation);
00116
00117
00118
00119
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
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
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)
00171 {
00172 if(rot_vel>-min_rot_vel)
00173 {
00174 rot_vel=-min_rot_vel;
00175 }
00176 }
00177 else
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)
00193 {
00194 if(left_collision)
00195 {
00196 coll=true;
00197 }
00198 }
00199 else if(cmd_vel.linear.y<-0.001)
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 }