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
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
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
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
00078 moveRobot(pose_msg_);
00079
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
00095 moveRobot(new_pose);
00096
00097
00098 received_laser_signal_ = false;
00099 while(!received_laser_signal_)
00100 {
00101 loop.sleep();
00102 }
00103
00104
00105
00106 sleep(11);
00107
00108 get_pointcloud_ = true;
00109 angles += 30.0;
00110 }
00111 received_pose_ = false;
00112
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
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
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;
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
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
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
00208
00209
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
00241
00242
00243
00244
00245
00246
00247
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