autonomous_exploration.cpp
Go to the documentation of this file.
00001 #include "ros/ros.h"
00002 #include "sensor_msgs/PointCloud.h"
00003 #include "geometry_msgs/Pose.h"
00004 #include "move_base_msgs/MoveBaseAction.h"
00005 #include "actionlib/client/simple_action_client.h"
00006 #include "pcl/common/angles.h"
00007 #include "LinearMath/btQuaternion.h"
00008 #include <pr2_controllers_msgs/SingleJointPositionAction.h>
00009 #include <pr2_msgs/SetPeriodicCmd.h>
00010 #include <pr2_msgs/PeriodicCmd.h>
00011 #include <pr2_msgs/LaserTrajCmd.h>
00012 #include <pr2_msgs/SetLaserTrajCmd.h>
00013 #include "pr2_msgs/LaserScannerSignal.h"
00014 class AutonomousExploration
00015 {
00016   public:
00017     AutonomousExploration();
00018     ~AutonomousExploration();
00019     void autonomousExplorationCallBack(const geometry_msgs::Pose& pose_msg);
00020     void pointcloudCallBack(const sensor_msgs::PointCloud& pointcloud_msg);
00021     void laserScannerSignalCallBack(const pr2_msgs::LaserScannerSignal laser_scanner_signal_msg);
00022     void moveRobot(geometry_msgs::Pose goal_pose);
00023     void moveTorso(double position, double velocity, std::string direction);
00024     void setLaserProfile(std::string mode);
00025     void run();
00026     void spin();
00027 
00028   private:
00029     ros::NodeHandle nh_;
00030     ros::Subscriber pose_subscriber_;
00031     ros::Subscriber pointcloud_subscriber_;
00032     ros::Subscriber laser_signal_subscriber_;
00033     ros::Publisher pointcloud_publisher_;
00034     ros::Publisher tilt_laser_publisher_;
00035     ros::Publisher tilt_laser_traj_cmd_publisher_;
00036     std::string subscribe_pose_topic_;
00037     boost::thread spin_thread_;
00038     geometry_msgs::Pose pose_msg_;
00039     bool get_pointcloud_, received_pose_, received_laser_signal_;
00040     //ros::ServiceClient tilt_laser_client_;
00041 };
00042 
00043 AutonomousExploration::AutonomousExploration():nh_("~")
00044 {
00045   nh_.param("subscribe_pose_topic", subscribe_pose_topic_, std::string("/robot_pose"));
00046   ROS_INFO("autonomous_exploration node is up and running.");
00047   get_pointcloud_ = false;
00048   received_pose_ = false;
00049   received_laser_signal_ = false;
00050   run();
00051 }
00052 AutonomousExploration::~AutonomousExploration()
00053 {
00054   ROS_INFO("Shutting down autonomous_exploration node.");
00055 }
00056 
00057 void AutonomousExploration::run()
00058 {
00059   pose_subscriber_ = nh_.subscribe(subscribe_pose_topic_, 100, &AutonomousExploration::autonomousExplorationCallBack, this);
00060   pointcloud_publisher_ = nh_.advertise<sensor_msgs::PointCloud>("pointcloud", 100);
00061   tilt_laser_publisher_ = nh_.advertise<pr2_msgs::PeriodicCmd>("/laser_tilt_controller/set_periodic_cmd", 1);
00062   pointcloud_subscriber_ = nh_.subscribe("/shoulder_cloud", 100, &AutonomousExploration::pointcloudCallBack, this);
00063   laser_signal_subscriber_ = nh_.subscribe("/laser_tilt_controller/laser_scanner_signal", 1, &AutonomousExploration::laserScannerSignalCallBack, this);
00064  // tilt_laser_client_ = nh_.serviceClient<pr2_msgs::SetPeriodicCmd>("laser_tilt_controller/set_periodic_cmd");
00065   tilt_laser_traj_cmd_publisher_ = nh_.advertise<pr2_msgs::LaserTrajCmd>("/laser_tilt_controller/set_traj_cmd", 1);
00066   spin_thread_ = boost::thread (boost::bind (&ros::spin));
00067   //ros::spin();
00068 }
00069 void AutonomousExploration::spin()
00070 {
00071   ros::Rate loop(1);
00072   while(nh_.ok())
00073   {
00074     loop.sleep();
00075     if(received_pose_ )
00076     {
00077       //move robot to the received pose
00078       moveRobot(pose_msg_);
00079       //rise the spine up to scan
00080       setLaserProfile("scan");
00081       moveTorso(0.3, 1.0, "up");
00082       double angles = 0.0;
00083       while(angles <= 360)
00084       {
00085         geometry_msgs::Pose new_pose;
00086         btQuaternion q ( pcl::deg2rad(angles), 0, 0);
00087         new_pose.position.x = pose_msg_.position.x;
00088         new_pose.position.y = pose_msg_.position.y;
00089         new_pose.position.z = pose_msg_.position.z;
00090         new_pose.orientation.x = q.x();
00091         new_pose.orientation.y = q.y();
00092         new_pose.orientation.z = q.z();
00093         new_pose.orientation.w = q.w();
00094         //setLaserProfile("scan");
00095         moveRobot(new_pose);
00096         //setLaserProfile("navigation");
00097 
00098         received_laser_signal_ = false;
00099         while(!received_laser_signal_)
00100         {
00101           loop.sleep();
00102         }
00103 
00104         //TODO: Use laser service to sync
00105         //Wait 11 seconds before taking a scan
00106         sleep(11);
00107         //get a point cloud
00108         get_pointcloud_ = true;
00109         angles += 30.0;
00110       }
00111       received_pose_ = false;
00112       //lower the spine to navigate some place else
00113       moveTorso(0.01, 1.0, "down");
00114       setLaserProfile("navigation");
00115     }
00116   }
00117 }
00118 void AutonomousExploration::moveRobot(geometry_msgs::Pose goal_pose)
00119 {
00120   actionlib::SimpleActionClient<move_base_msgs::MoveBaseAction> ac("move_base", true);
00121 
00122   //wait for the action server to come up
00123   while(!ac.waitForServer(ros::Duration(5.0)))
00124   {
00125     ROS_INFO("Waiting for the move_base action server to come up");
00126   }
00127 
00128   move_base_msgs::MoveBaseGoal goal;
00129   goal.target_pose.header.frame_id = "/map";
00130   goal.target_pose.header.stamp = ros::Time::now();
00131 
00132   goal.target_pose.pose = goal_pose;
00133 
00134   ROS_INFO("Sending goal");
00135   ac.sendGoal(goal);
00136   ac.waitForResult();
00137 
00138   ROS_INFO("Pose Position x: %f, y:%f, z:%f Orientation x:%f, y:%f, z:%f, w:%f", goal.target_pose.pose.position.x,
00139       goal.target_pose.pose.position.y, goal.target_pose.pose.position.z, goal.target_pose.pose.orientation.x,
00140       goal.target_pose.pose.orientation.y, goal.target_pose.pose.orientation.z, goal.target_pose.pose.orientation.w);
00141 
00142   if(ac.getState() == actionlib::SimpleClientGoalState::SUCCEEDED)
00143   {
00144     ROS_INFO("Robot has moved to the goal pose");
00145   }
00146   else
00147   {
00148     ROS_ERROR("Error in moving robot to goal pose.");
00149     exit(1);
00150   }
00151 }
00152 
00153 void AutonomousExploration::moveTorso(double position, double velocity, std::string direction)
00154 {
00155   actionlib::SimpleActionClient<pr2_controllers_msgs::SingleJointPositionAction> tc ("torso_controller/position_joint_action", true);
00156 
00157   //wait for the action server to come up
00158   while(!tc.waitForServer(ros::Duration(5.0)))
00159   {
00160     ROS_INFO("Waiting for the torso action server to come up");
00161   }
00162   pr2_controllers_msgs::SingleJointPositionGoal goal;
00163   goal.position = position;  //all the way up is 0.3
00164   goal.min_duration = ros::Duration(2.0);
00165   goal.max_velocity = velocity;
00166 
00167   ROS_INFO("Sending '%s' goal", direction.c_str());
00168   tc.sendGoal(goal);
00169   tc.waitForResult();
00170 
00171   if(tc.getState() == actionlib::SimpleClientGoalState::SUCCEEDED)
00172   {
00173     ROS_INFO("Torso moved %s.", direction.c_str());
00174   }
00175   else
00176   {
00177     ROS_ERROR("Error in moving torso %s.", direction.c_str());
00178   }
00179 }
00180 
00181 void AutonomousExploration::setLaserProfile(std::string mode)
00182 {
00183   //while ( !ros::service::waitForService("laser_tilt_controller/set_periodic_cmd", ros::Duration(2.0)) && nh_.ok() )
00184   //{
00185   //  ROS_INFO("Waiting for tilt laser periodic command service to come up");
00186   //}
00187 
00188   //pr2_msgs::SetPeriodicCmd::Request req;
00189   //pr2_msgs::SetPeriodicCmd::Response res;
00190   //req.command.header.frame_id = "/map";
00191   //req.command.header.stamp = ros::Time::now();
00192   //req.command.header.seq = 0;
00193 
00194   //req.command.profile = "linear";
00195 
00196   if(mode == "scan")
00197   {
00198     pr2_msgs::PeriodicCmd periodic_cmd_msg;
00199 
00200     periodic_cmd_msg.header.frame_id = "/map";
00201     periodic_cmd_msg.header.stamp = ros::Time::now();
00202 
00203     periodic_cmd_msg.profile = "linear";
00204     periodic_cmd_msg.offset = 0.3;
00205     periodic_cmd_msg.period = 20.0;
00206     periodic_cmd_msg.amplitude = 0.8;
00207     //req.command.period = 20.0;
00208     //req.command.amplitude = 0.8;
00209     //req.command.offset = 0.3;
00210     tilt_laser_publisher_.publish(periodic_cmd_msg);
00211     ROS_INFO("Tilt laser successfully published. Mode: %s", mode.c_str());
00212   }
00213   else if(mode == "navigation")
00214   {
00215     pr2_msgs::LaserTrajCmd laser_traj_cmd_msg;
00216 
00217     laser_traj_cmd_msg.header.frame_id = "/map";
00218     laser_traj_cmd_msg.header.stamp = ros::Time::now();
00219 
00220     laser_traj_cmd_msg.profile = "blended_linear";
00221     laser_traj_cmd_msg.position.resize(3);
00222     ROS_INFO("Resized");
00223     laser_traj_cmd_msg.position[0] = 1.05;
00224     laser_traj_cmd_msg.position[1] = -0.7;
00225     laser_traj_cmd_msg.position[2] = 1.05;
00226 
00227     ros::Duration dur;
00228     laser_traj_cmd_msg.time_from_start.resize(3);
00229     ROS_INFO("Resized time_from_start");
00230     laser_traj_cmd_msg.time_from_start[0] = dur.fromSec(0.0);
00231     laser_traj_cmd_msg.time_from_start[1] = dur.fromSec(1.8);
00232     laser_traj_cmd_msg.time_from_start[2] = dur.fromSec(2.3125);
00233 
00234     laser_traj_cmd_msg.max_velocity = 10;
00235     laser_traj_cmd_msg.max_acceleration = 30;
00236     tilt_laser_traj_cmd_publisher_.publish(laser_traj_cmd_msg);
00237     ROS_INFO("Tilt Laser Traj Command successfully called. Mode: %s\n", mode.c_str());
00238 
00239   }
00240   //if(!tilt_laser_client_.call(req,res))
00241   //{
00242   //  ROS_ERROR("Tilt laser service call failed.\n");
00243   //  exit(1);
00244   //}
00245   //else
00246   //{
00247   //  ROS_INFO("Tilt laser service successfully called.\n");
00248   //}
00249 }
00250 void AutonomousExploration::laserScannerSignalCallBack(const pr2_msgs::LaserScannerSignal laser_scanner_signal_msg)
00251 {
00252   if(!received_laser_signal_)
00253   {
00254     received_laser_signal_ = true;
00255   }
00256 }
00257 void AutonomousExploration::pointcloudCallBack(const sensor_msgs::PointCloud& pointcloud_msg)
00258 {
00259   if(get_pointcloud_)
00260   {
00261     ROS_INFO("pointcloud received");
00262     pointcloud_publisher_.publish(pointcloud_msg);
00263     ROS_INFO("pointcloud published");
00264     get_pointcloud_ = false;
00265   }
00266 }
00267 void AutonomousExploration::autonomousExplorationCallBack(const geometry_msgs::Pose& pose_msg)
00268 {
00269   pose_msg_ = pose_msg;
00270   received_pose_ = true;
00271   ROS_INFO("Received a Pose");
00272 
00273 }
00274 
00275 int main( int argc, char** argv)
00276 {
00277   ros::init(argc, argv, "autonomous_exploration");
00278   AutonomousExploration autonomous_exploration;
00279   autonomous_exploration.spin();
00280   return 0;
00281 }
00282 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Friends Defines


pointcloud_registration
Author(s): Hozefa Indorewala
autogenerated on Thu May 23 2013 16:01:13