Go to the documentation of this file.00001 #include <cmath>
00002 #include <ros/ros.h>
00003 #include <tf/transform_listener.h>
00004 #include <actionlib/client/simple_action_client.h>
00005 #include <pr2_controllers_msgs/PointHeadAction.h>
00006
00007
00008 typedef actionlib::SimpleActionClient<pr2_controllers_msgs::PointHeadAction> PointHeadClient;
00009
00010 class RobotHead
00011 {
00012 private:
00013 PointHeadClient* point_head_client_;
00014 std::string frame_to_point;
00015 std::string frame_to_track;
00016 tf::TransformListener listener;
00017 ros::Time last_pose;
00018 float angle_range;
00019 float height_range;
00020
00021 public:
00023 RobotHead() :frame_to_point("/narrow_stereo_optical_frame"),
00024 frame_to_track("/checkerboard_0"),
00025 angle_range(45.0),
00026 height_range(0.2)
00027 {
00028 last_pose = ros::Time::now();
00029
00030 point_head_client_ = new PointHeadClient("/head_traj_controller/point_head_action", true);
00031
00032
00033 while(!point_head_client_->waitForServer(ros::Duration(5.0))){
00034 ROS_INFO("Waiting for the point_head_action server to come up");
00035 }
00036 }
00037
00038 ~RobotHead()
00039 {
00040 delete point_head_client_;
00041 }
00042
00044 void lookAt(std::string frame_id, double x, double y, double z, double max_velocity = 0.15, double max_wait_seconds = 10.0)
00045 {
00046 ROS_INFO("Moving with velocity: %f", max_velocity);
00047
00048 pr2_controllers_msgs::PointHeadGoal goal;
00049
00050
00051 geometry_msgs::PointStamped point;
00052 point.header.frame_id = frame_id;
00053 point.point.x = x; point.point.y = y; point.point.z = z;
00054 goal.target = point;
00055
00056
00057
00058 goal.pointing_frame = this->frame_to_point;
00059
00060
00061 goal.min_duration = ros::Duration(0.4);
00062
00063
00064 goal.max_velocity = max_velocity;
00065
00066
00067 point_head_client_->sendGoal(goal);
00068 ros::Time start = ros::Time::now();
00069 while(ros::ok() && !point_head_client_->waitForResult(ros::Duration(0.5))){
00070 if(start < (ros::Time::now() - ros::Duration(max_wait_seconds))){
00071 break;
00072 }
00073 ros::spinOnce();
00074 }
00075 }
00076
00077 void track(geometry_msgs::PoseStamped ps){
00078 ROS_INFO("Adjusting look at checkerboard");
00079 last_pose = ros::Time::now();
00080 angle_range = 30.0;
00081 point_head_client_->cancelAllGoals();
00082 if(listener.waitForTransform(frame_to_track, frame_to_point, ros::Time::now(), ros::Duration(4.0)))
00083 lookAt(this->frame_to_track, 0,0,0, 0.01, 0.0);
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118 }
00119
00121 void search_and_spin()
00122 {
00123 srand(10);
00124 float radius = 1.0;
00125 ros::Rate r(5);
00126 while (ros::ok())
00127 {
00128 ros::spinOnce();
00129 r.sleep();
00130 if(last_pose < (ros::Time::now() - ros::Duration(10.0))){
00131 ROS_INFO("Searching Checkerboard");
00132 float height = ((rand() % 100*height_range) - 50*height_range)/100.0;
00133 height *= height;
00134
00135 lookAt("/head_pan_link", radius, 0.0, height, 1.0);
00136 if(last_pose > (ros::Time::now() - ros::Duration(10.0))){
00137 continue;
00138 }
00139
00140 ROS_INFO("Searching...");
00141 angle_range*= -1.0;
00142 lookAt("/torso_lift_link", radius*cos(angle_range/180.0*M_PI),radius*sin(angle_range/180.0*M_PI), height+0.374, 1.0);
00143 if(abs(angle_range) < 120) angle_range *= 1.1;
00144 if(height_range < 1.0) angle_range *= 1.05;
00145 }
00146 }
00147 }
00148 };
00149
00150 int main(int argc, char** argv)
00151 {
00152
00153 ros::init(argc, argv, "checkerboard_tracker");
00154 ROS_INFO("Checkerboard Tracker started...");
00155 ros::NodeHandle n;
00156 RobotHead head;
00157 ros::Subscriber pose_sub = n.subscribe("pose0", 5, &RobotHead::track, &head);
00158 head.search_and_spin();
00159 }
00160