pan_tilt_object_tracking_pid.cpp
Go to the documentation of this file.
1 
2 
3 #include <ros/ros.h>
4 #include <std_msgs/Float64MultiArray.h>
6 #include <sensor_msgs/JointState.h>
7 #include <trajectory_msgs/JointTrajectory.h>
8 
9 template <typename T> int sgn(T val);
10 void callback(const sensor_msgs::JointState::ConstPtr& joint_state);
11 void reset();
12 
14 bool have_pan=false,have_tilt=false,tracking=false;
16  trajectory_msgs::JointTrajectory traj;
17 
18 
19 void callback(const sensor_msgs::JointState::ConstPtr& joint_state)
20 {
21  // std::vector<std::string> joint_names = joint_state->name;
22  for (int i=0;i<joint_state->name.size();i++)
23  {
24  if (joint_state->name[i] == "head_pan_joint")
25  {
26  pan_position = joint_state->position[i];
27  if (!have_pan) have_pan=true;
28  }
29  else if (joint_state->name[i] == "head_tilt_joint")
30  {
31  tilt_position = joint_state->position[i];
32  if (!have_tilt) have_tilt=true;
33  }
34  }
35 
36  // tilt_position = joint_state->position[find (joint_names.begin(),joint_names.end(), "head_tilt_joint") - joint_names.begin()];
37 
38 
39 }
40 
41 
42 template <typename T> int sgn(T val) {
43  return (T(0) < val) - (val < T(0));
44 }
45 
46 void reset() {
47 
48  traj.points[0].positions[0] = 0.0;
49  traj.points[0].positions[1] = 0.0;
50  traj.header.stamp = ros::Time::now();
51  traj.points[0].time_from_start = ros::Duration(0.1);
52  pub_controller_command.publish(traj);
53 }
54 
55 int main(int argc, char **argv) {
56  ros::init(argc, argv, "pan_tilt_api");
57  ros::NodeHandle nh;
58  pub_controller_command = nh.advertise<trajectory_msgs::JointTrajectory>("pan_tilt_trajectory_controller/command", 2);
59 
60  // pan_tilt_pub = nh.advertise<std_msgs::Float64MultiArray>("pan_tilt_controller/command", 10);
61  ros::Subscriber sub = nh.subscribe ("joint_states", 10, callback);
62  double max_rate,kp_pan,kp_tilt,kd_pan,kd_tilt,pre_pan_err=0,pre_tilt_err=0,target_tol;
63  std::string object_frame,depth_camera_frame;
64  double no_object_timeout;
65  double loop_hz;
66  nh.param<double>("max_rate", max_rate, 0.3); //rad/s
67  nh.param<std::string>("object_frame", object_frame, "object_frame");
68  nh.param<double>("kp_pan", kp_pan, 4.0);
69  nh.param<double>("kp_tilt", kp_tilt, 3.0);
70  nh.param<double>("kd_pan", kd_pan, 0.01);
71  nh.param<double>("kd_tilt", kd_tilt, 0.01);
72  nh.param<double>("loop_hz", loop_hz, 30);
73  nh.param<double>("target_tol", target_tol,1.0*M_PI/180.0);
74  nh.param<double>("no_object_timeout", no_object_timeout,5.0);
75  nh.param<std::string>("depth_camera_frame", depth_camera_frame, "kinect2_depth_optical_frame");
76 
77  tf::TransformListener listener;
78  tf::StampedTransform transform;
79 
80  ros::Duration dt;
81  ros::Rate loopRate(loop_hz);
82  ros::Time pre_t=ros::Time::now();
83 
84 
85  while (!listener.waitForTransform(depth_camera_frame, object_frame,ros::Time::now(), ros::Duration(1.0))) {
86  ROS_INFO("Waiting for tranformations...");
87  }
88  ROS_INFO("Ready to track!");
89  bool first=true;
90 
91 
92  traj.joint_names.push_back("head_pan_joint");
93  traj.joint_names.push_back("head_tilt_joint");
94  traj.points.resize(1);
95  traj.points[0].velocities.push_back(0);
96  traj.points[0].velocities.push_back(0);
97  traj.points[0].positions.push_back(0);
98  traj.points[0].positions.push_back(0);
99 
100  while(ros::ok()) {
101  if ((have_tilt)&&(have_pan)) {
102  try {
103 
104  listener.lookupTransform(depth_camera_frame, object_frame, ros::Time(0), transform);
105 
106  ros::Duration d=ros::Time::now()-transform.stamp_;
107  if (d.toSec()>no_object_timeout) { //no object timeout
108  if (tracking) {
109  reset();
110  tracking=false;
111  }
112  continue;
113  }
114  if (!tracking) tracking=true;
115 
116  tf::Vector3 v=transform.getOrigin();
117  double pan_err=-atan2(v.x(),v.z());
118  double tilt_err=atan2(v.y(),v.z());
119 
120  if (first) {
121 
122  pre_pan_err=pan_err;
123  pre_tilt_err=tilt_err;
124  first=false;
125 
126 
127  }
129  dt=(now-pre_t);
130 
131  double pan_rate=pan_err*kp_pan+kd_pan*(pan_err-pre_pan_err)/dt.toSec();
132  double tilt_rate=tilt_err*kp_tilt+kd_tilt*(tilt_err-pre_tilt_err)/dt.toSec();;
133 
134  if (pan_rate>max_rate) pan_rate=max_rate;
135  else if(pan_rate<-max_rate) pan_rate=-max_rate;
136  if (tilt_rate>max_rate) tilt_rate=max_rate;
137  else if(tilt_rate<-max_rate) tilt_rate=-max_rate;
138 
139  if(fabs(pan_err)<target_tol) pan_rate=0;
140  if(fabs(tilt_err)<target_tol) tilt_rate=0;
141 
142 
143  pre_t=now;
144 
145 
146 
147  double pan_cmd=pan_position+pan_rate*dt.toSec();
148  double tilt_cmd=tilt_position+tilt_rate*dt.toSec();
149 
150 
151  traj.header.stamp = ros::Time::now();
152  traj.points[0].time_from_start = ros::Duration(dt.toSec());
153  traj.points[0].positions[0] = pan_cmd;
154  traj.points[0].positions[1] = tilt_cmd;
155  pub_controller_command.publish(traj);
156 
157 
158  }
159  catch (tf::TransformException ex) {
160  ROS_ERROR("Pan-Tilt tracking node error: %s",ex.what());
161  reset();
162  }
163  }
164  //
165  ros::spinOnce();
166  loopRate.sleep();
167  }
168 
169 
170  return 0;
171 
172 
173 }
d
int main(int argc, char **argv)
void publish(const boost::shared_ptr< M > &message) const
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
double tilt_position
#define M_PI
TFSIMD_FORCE_INLINE const tfScalar & x() const
TFSIMD_FORCE_INLINE const tfScalar & z() const
#define ROS_INFO(...)
bool param(const std::string &param_name, T &param_val, const T &default_val) const
int sgn(T val)
ROSCPP_DECL bool ok()
TFSIMD_FORCE_INLINE const tfScalar & y() const
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
TFSIMD_FORCE_INLINE Vector3 & getOrigin()
bool sleep()
ros::Publisher pub_controller_command
trajectory_msgs::JointTrajectory traj
static Time now()
void callback(const sensor_msgs::JointState::ConstPtr &joint_state)
ROSCPP_DECL void spinOnce()
#define ROS_ERROR(...)


robotican_common
Author(s):
autogenerated on Wed Jan 3 2018 03:48:33