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
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
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
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);
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) {
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 }