pan_tilt_object_tracking_pid.cpp
Go to the documentation of this file.
00001 
00002 
00003 #include <ros/ros.h>
00004 #include <std_msgs/Float64MultiArray.h>
00005 #include <tf/transform_listener.h>
00006 #include <sensor_msgs/JointState.h>
00007 #include <trajectory_msgs/JointTrajectory.h>
00008 
00009 template <typename T> int sgn(T val);
00010 void callback(const sensor_msgs::JointState::ConstPtr& joint_state);
00011 void reset();
00012 
00013 double pan_position=0,tilt_position=0;
00014 bool have_pan=false,have_tilt=false,tracking=false;
00015 ros::Publisher pub_controller_command;
00016  trajectory_msgs::JointTrajectory traj;
00017 
00018 
00019 void callback(const sensor_msgs::JointState::ConstPtr& joint_state)
00020 {
00021     // std::vector<std::string> joint_names = joint_state->name;
00022     for (int i=0;i<joint_state->name.size();i++)
00023     {
00024         if (joint_state->name[i] == "head_pan_joint")
00025         {
00026             pan_position = joint_state->position[i];
00027             if (!have_pan) have_pan=true;
00028         }
00029         else if (joint_state->name[i] == "head_tilt_joint")
00030         {
00031             tilt_position = joint_state->position[i];
00032             if (!have_tilt) have_tilt=true;
00033         }
00034     }
00035 
00036     // tilt_position = joint_state->position[find (joint_names.begin(),joint_names.end(), "head_tilt_joint") - joint_names.begin()];
00037 
00038 
00039 }
00040 
00041 
00042 template <typename T> int sgn(T val) {
00043     return (T(0) < val) - (val < T(0));
00044 }
00045 
00046 void reset() {
00047 
00048     traj.points[0].positions[0] = 0.0;
00049     traj.points[0].positions[1] = 0.0;
00050     traj.header.stamp = ros::Time::now();
00051     traj.points[0].time_from_start = ros::Duration(0.1);
00052     pub_controller_command.publish(traj);
00053 }
00054 
00055 int main(int argc, char **argv) {
00056     ros::init(argc, argv, "pan_tilt_api");
00057     ros::NodeHandle nh;
00058     pub_controller_command = nh.advertise<trajectory_msgs::JointTrajectory>("pan_tilt_trajectory_controller/command", 2);
00059 
00060   //  pan_tilt_pub = nh.advertise<std_msgs::Float64MultiArray>("pan_tilt_controller/command", 10);
00061     ros::Subscriber sub = nh.subscribe ("joint_states", 10, callback);
00062     double max_rate,kp_pan,kp_tilt,kd_pan,kd_tilt,pre_pan_err=0,pre_tilt_err=0,target_tol;
00063     std::string object_frame,depth_camera_frame;
00064     double no_object_timeout;
00065     double loop_hz;
00066     nh.param<double>("max_rate", max_rate, 0.3); //rad/s
00067     nh.param<std::string>("object_frame", object_frame, "object_frame");
00068     nh.param<double>("kp_pan", kp_pan, 4.0);
00069     nh.param<double>("kp_tilt", kp_tilt, 3.0);
00070     nh.param<double>("kd_pan", kd_pan, 0.01);
00071     nh.param<double>("kd_tilt", kd_tilt, 0.01);
00072     nh.param<double>("loop_hz", loop_hz, 30);
00073     nh.param<double>("target_tol", target_tol,1.0*M_PI/180.0);
00074      nh.param<double>("no_object_timeout", no_object_timeout,5.0);
00075     nh.param<std::string>("depth_camera_frame", depth_camera_frame, "kinect2_depth_optical_frame");
00076 
00077     tf::TransformListener listener;
00078     tf::StampedTransform transform;
00079 
00080     ros::Duration dt;
00081     ros::Rate loopRate(loop_hz);
00082     ros::Time pre_t=ros::Time::now();
00083 
00084 
00085     while (!listener.waitForTransform(depth_camera_frame, object_frame,ros::Time::now(), ros::Duration(1.0))) {
00086         ROS_INFO("Waiting for tranformations...");
00087     }
00088     ROS_INFO("Ready to track!");
00089     bool first=true;
00090 
00091 
00092      traj.joint_names.push_back("head_pan_joint");
00093      traj.joint_names.push_back("head_tilt_joint");
00094      traj.points.resize(1);
00095       traj.points[0].velocities.push_back(0);
00096       traj.points[0].velocities.push_back(0);
00097       traj.points[0].positions.push_back(0);
00098       traj.points[0].positions.push_back(0);
00099 
00100     while(ros::ok()) {
00101         if ((have_tilt)&&(have_pan)) {
00102             try {
00103 
00104                 listener.lookupTransform(depth_camera_frame, object_frame, ros::Time(0), transform);
00105 
00106                 ros::Duration d=ros::Time::now()-transform.stamp_;
00107                 if (d.toSec()>no_object_timeout) { //no object timeout
00108                     if (tracking) {
00109                         reset();
00110                         tracking=false;
00111                     }
00112                     continue;
00113                 }
00114                 if (!tracking) tracking=true;
00115 
00116                 tf::Vector3 v=transform.getOrigin();
00117                 double pan_err=-atan2(v.x(),v.z());
00118                 double tilt_err=atan2(v.y(),v.z());
00119 
00120                 if (first) {
00121 
00122                     pre_pan_err=pan_err;
00123                     pre_tilt_err=tilt_err;
00124                     first=false;
00125 
00126 
00127                 }
00128                 ros::Time now=ros::Time::now();
00129                 dt=(now-pre_t);
00130 
00131                 double pan_rate=pan_err*kp_pan+kd_pan*(pan_err-pre_pan_err)/dt.toSec();
00132                 double tilt_rate=tilt_err*kp_tilt+kd_tilt*(tilt_err-pre_tilt_err)/dt.toSec();;
00133 
00134                 if (pan_rate>max_rate) pan_rate=max_rate;
00135                 else if(pan_rate<-max_rate) pan_rate=-max_rate;
00136                 if (tilt_rate>max_rate) tilt_rate=max_rate;
00137                 else if(tilt_rate<-max_rate) tilt_rate=-max_rate;
00138 
00139                 if(fabs(pan_err)<target_tol) pan_rate=0;
00140                 if(fabs(tilt_err)<target_tol) tilt_rate=0;
00141 
00142 
00143                 pre_t=now;
00144 
00145 
00146 
00147                 double pan_cmd=pan_position+pan_rate*dt.toSec();
00148                 double tilt_cmd=tilt_position+tilt_rate*dt.toSec();
00149 
00150 
00151                 traj.header.stamp = ros::Time::now();
00152                 traj.points[0].time_from_start = ros::Duration(dt.toSec());
00153                 traj.points[0].positions[0] = pan_cmd;
00154                 traj.points[0].positions[1] = tilt_cmd;
00155                 pub_controller_command.publish(traj);
00156 
00157 
00158             }
00159             catch (tf::TransformException ex) {
00160                  ROS_ERROR("Pan-Tilt tracking node error: %s",ex.what());
00161                 reset();
00162             }
00163         }
00164         //
00165         ros::spinOnce();
00166         loopRate.sleep();
00167     }
00168 
00169 
00170     return 0;
00171 
00172 
00173 }


robotican_common
Author(s):
autogenerated on Fri Oct 27 2017 03:02:37