search_and_track_marker.cpp
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 #include <std_srvs/Empty.h>
00007 
00008 // Our Action interface type, provided as a typedef for convenience
00009 typedef actionlib::SimpleActionClient<pr2_controllers_msgs::PointHeadAction> PointHeadClient;
00010 
00011 class RobotHead
00012 {
00013 private:
00014   PointHeadClient point_head_client_;
00015   std::string frame_to_point;
00016   std::string frame_to_track;
00017   tf::TransformListener listener;
00018   bool active_;
00019   bool found_;
00020   ros::Subscriber pose_sub_;
00021   ros::ServiceServer service_on_, service_off_;
00022 
00023 public:
00025   RobotHead() : point_head_client_("/head_traj_controller/point_head_action", true),  //Initialize the client for the Action interface to the head controller
00026                 frame_to_point("/head_mount_kinect_rgb_link"),
00027                 frame_to_track("/checkerboard_0"),
00028                 active_(false),
00029                 found_(false)
00030   {
00031     ros::NodeHandle n; 
00032     pose_sub_ = n.subscribe("pose0", 2, &RobotHead::track, this);
00033     service_on_ = n.advertiseService("search_and_track_checkerboard_on", &RobotHead::switchActive, this);
00034     service_off_ = n.advertiseService("search_and_track_checkerboard_off", &RobotHead::switchInactive, this);
00035 
00036     ros::NodeHandle nh("~");
00037     nh.param<bool>("start_active", active_, active_); //By default wait for activation by service call
00038 
00039     //wait for head controller action server to come up 
00040     while(!point_head_client_.waitForServer(ros::Duration(1.0))){
00041       ROS_INFO_THROTTLE(10, "Waiting for the point_head_action server to come up");
00042     }
00043 
00044     ROS_INFO_COND(active_, "Searching for checkerboard. Deactivate by service call");
00045     ROS_INFO_COND(!active_, "Search for checkerboard available. Activate by service call");
00046   }
00047 
00048   void lookAt(geometry_msgs::PoseStamped pose_stamped)
00049   {
00050     if(!active_)return;
00051     found_ = true;
00052     //the goal message we will be sending
00053     pr2_controllers_msgs::PointHeadGoal goal;
00054     geometry_msgs::PointStamped point_stamped;
00055     point_stamped.header = pose_stamped.header;
00056     point_stamped.point = pose_stamped.pose.position;
00057     goal.target = point_stamped;
00058     goal.pointing_frame = this->frame_to_point;
00059 
00060     //take at least 0.5 seconds to get there
00061     goal.min_duration = ros::Duration(1.5);
00062 
00063     //and go no faster than 1 rad/s
00064     goal.max_velocity = 0.25;
00065 
00066     //send the goal
00067     point_head_client_.sendGoal(goal);
00068     point_head_client_.waitForResult(ros::Duration(5));
00069   }
00070 
00072   void lookAt(std::string frame_id, double x, double y, double z, double max_wait_seconds = 10.0)
00073   {
00074     if(!active_)return;
00075     //the goal message we will be sending
00076     pr2_controllers_msgs::PointHeadGoal goal;
00077 
00078     //the target point, expressed in the requested frame
00079     geometry_msgs::PointStamped point;
00080     point.header.frame_id = frame_id;
00081     point.point.x = x; point.point.y = y; point.point.z = z;
00082     goal.target = point;
00083 
00084     //we are pointing the high-def camera frame 
00085     //(pointing_axis defaults to X-axis)
00086     goal.pointing_frame = this->frame_to_point;
00087 
00088     //take at least 0.5 seconds to get there
00089     goal.min_duration = ros::Duration(0.5);
00090 
00091     //and go no faster than 1 rad/s
00092     goal.max_velocity = 0.25;
00093 
00094     //send the goal
00095     point_head_client_.sendGoal(goal);
00096     ros::Time start = ros::Time::now();
00097     while(ros::ok() && !point_head_client_.waitForResult(ros::Duration(0.5))){
00098       if(start < (ros::Time::now() - ros::Duration(max_wait_seconds))){
00099         break;
00100       }
00101       ros::spinOnce();
00102     }
00103   }
00104 
00105   void track(geometry_msgs::PoseStamped ps = geometry_msgs::PoseStamped() ){
00106       //this->lookAt(this->frame_to_track, 0, 0, 0, 0.5);
00107       if(active_) this->lookAt(ps);
00108   }
00109 
00111   void searchAndSpin(float step)
00112   {
00113     srand(10);
00114     float radius = 2.0;
00115     float height = -0.40; 
00116     while (ros::ok())
00117     {
00118       ros::spinOnce();
00119       ros::Duration(1.0).sleep();
00120       if(!active_)
00121         continue;
00122 
00123       if(listener.waitForTransform(frame_to_track, frame_to_point, ros::Time::now()-ros::Duration(0.1), ros::Duration(4.0))){
00124         if(!found_){
00125           ROS_INFO("Transformable frame %s", frame_to_track.c_str());
00126           found_=true;
00127         } 
00128         continue;
00129       }
00130       else {
00131         found_ = false;
00132       }
00133       lookAt("/head_pan_link", radius, 0.0, height);
00134       if(listener.waitForTransform(frame_to_track, frame_to_point, ros::Time::now()-ros::Duration(0.1), ros::Duration(4.0))){
00135         if(!found_){
00136           ROS_INFO("Transformable frame %s", frame_to_track.c_str());
00137           found_=true;
00138         } 
00139         continue;
00140       }
00141       else {
00142         found_ = false;
00143       }
00144 
00145       lookAt("/torso_lift_link", radius*cos(step/180.0*M_PI),radius*sin(step/180.0*M_PI), height);
00146       if(listener.waitForTransform(frame_to_track, frame_to_point, ros::Time::now()-ros::Duration(0.1), ros::Duration(4.0))){
00147         if(!found_){
00148           ROS_INFO("Transformable frame %s", frame_to_track.c_str());
00149           found_=true;
00150         } 
00151         continue;
00152       }
00153       else {
00154         found_ = false;
00155       }
00156     
00157       step *= -1.0;
00158       height = (rand() % 100)/100.0 - 0.5; 
00159       height *= height;
00160       radius = (rand() % 100)/100.0 + 1.0; // in the range -0.7cm to 30 cm above 
00161       ROS_INFO("Searching frame %s", frame_to_track.c_str());
00162     }
00163   }
00164 
00165   bool switchActive(std_srvs::Empty::Request  &req,
00166                     std_srvs::Empty::Response &res )
00167   {
00168     active_ = true;
00169     lookAt("/torso_lift_link", 0.8, 0.3, 0.2);
00170     
00171     return true;
00172   }
00173   bool switchInactive(std_srvs::Empty::Request  &req,
00174                       std_srvs::Empty::Response &res )
00175   {
00176     active_ = false;
00177     return true;
00178   }
00179 };
00180 
00181 
00182 int main(int argc, char** argv)
00183 {
00184   //init the ROS node
00185   ros::init(argc, argv, "look_around");
00186   
00187   RobotHead head;
00188   head.searchAndSpin(30);
00189   //ros::spin();
00190 }
00191 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Friends


door_perception
Author(s): Felix Endres
autogenerated on Wed Dec 26 2012 16:03:53