visual_servo_pioneer_pan.cpp
Go to the documentation of this file.
1 #include <ros/ros.h>
2 #include <ros/console.h>
3 #include <std_msgs/Int8.h>
4 #include <geometry_msgs/Twist.h>
5 #include <geometry_msgs/PoseStamped.h>
6 
7 #include <visp_bridge/3dpose.h>
8 
9 #include <visp/vpAdaptiveGain.h>
10 #include <visp/vpCameraParameters.h>
11 #include <visp/vpDot.h>
12 #include <visp/vpDot2.h>
13 #include <visp/vpFeatureBuilder.h>
14 #include <visp/vpFeatureDepth.h>
15 #include <visp/vpFeaturePoint.h>
16 #include <visp/vpHomogeneousMatrix.h>
17 #include <visp/vpPioneerPan.h>
18 #include <visp/vpRobot.h>
19 #include <visp/vpServo.h>
20 #include <visp/vpVelocityTwistMatrix.h>
21 
22 class VS
23 {
24 private:
31 
32  vpServo task;
33  // Current and desired visual feature associated to the x coordinate of the point
34  vpFeaturePoint s_x, s_xd;
35  vpFeatureDepth s_Z, s_Zd;
36 
37  vpCameraParameters cam;
38  double depth;
39  double Z, Zd;
40  double lambda;
41 
42  bool valid_pose;
43  bool valid_pose_prev;
44 
45  double t_start_loop;
46  double tinit;
47 
48  vpColVector v;
49  vpColVector vi;
50  vpColVector qm; // Biclops odom
51  double qm_pan; // Measured pan position (tilt is not handled in that example)
52  double mu;
53  vpAdaptiveGain lambda_adapt;
54  vpPioneerPan robot;
55 
56 public:
57  void init_vs();
58  void poseCallback(const geometry_msgs::PoseStampedConstPtr& msg);
59  void biclopsOdomCallback(const geometry_msgs::PoseStampedConstPtr& msg);
60  void statusCallback(const std_msgs::Int8ConstPtr& msg);
61  VS(int argc, char**argv);
62  virtual ~VS() {
63  task.kill();
64  };
65 };
66 
67 VS::VS(int argc, char**argv)
68 {
69  init_vs();
70 
71  subPoseTarget_ = nh_.subscribe("/visp_auto_tracker/object_position", 1000, &VS::poseCallback, this);
72  subStatusTarget_ = nh_.subscribe("/visp_auto_tracker/status", 1000, &VS::statusCallback, this);
73  subBiclopsOdom_ = nh_.subscribe("/biclops/odom", 1000, &VS::biclopsOdomCallback, this);
74  pubTwistPioneer_ = nh_.advertise<geometry_msgs::Twist>("vs/pioneer/cmd_vel", 1000);
75  pubTwistBiclops_ = nh_.advertise<geometry_msgs::Twist>("vs/biclops/cmd_vel", 1000);
76 }
77 
78 void VS::init_vs()
79 {
80  depth = 0.4;
81  lambda = 1.;
82  valid_pose = false;
83  valid_pose_prev = false;
84 
85  Z = Zd = depth;
86 
87  v.resize(2);
88  vi.resize(2);
89  qm.resize(2);
90  v = 0; vi = 0; qm = 0;
91  mu = 4;
92  qm_pan = 0;
93 
94  //lambda_adapt.initStandard(4, 0.5, 40);
95  lambda_adapt.initStandard(3.5, 1.5, 15);
96 
97  cam.initPersProjWithoutDistortion(800, 795, 320, 216);
98 
99  task.setServo(vpServo::EYEINHAND_L_cVe_eJe) ;
100  task.setInteractionMatrixType(vpServo::DESIRED, vpServo::PSEUDO_INVERSE) ;
101  task.setLambda(lambda_adapt) ;
102 
103  vpVelocityTwistMatrix cVe = robot.get_cVe();
104  // Update the robot jacobian that depends on the pan position
105  robot.set_eJe(qm_pan);
106  // Get the robot jacobian
107  vpMatrix eJe = robot.get_eJe();
108  task.set_eJe( eJe );
109 
110  vpImagePoint ip(0,0);
111 
112  // Create the current x visual feature
113  vpFeatureBuilder::create(s_x, cam, ip);
114 
115  // Create the desired x* visual feature
116  s_xd.buildFrom(0, 0, Zd);
117 
118  // Add the feature
119  task.addFeature(s_x, s_xd, vpFeaturePoint::selectX()) ;
120 
121  s_Z.buildFrom(s_x.get_x(), s_x.get_y(), Z , 0); // log(Z/Z*) = 0 that's why the last parameter is 0
122  s_Zd.buildFrom(s_x.get_x(), s_x.get_y(), Zd , 0); // log(Z/Z*) = 0 that's why the last parameter is 0
123 
124  // Add the feature
125  task.addFeature(s_Z, s_Zd) ;
126 
127 }
128 
129 void VS::statusCallback(const std_msgs::Int8ConstPtr& msg)
130 {
131  if (msg->data == 3)
132  valid_pose = true;
133  else
134  valid_pose = false;
135 }
136 
137 void VS::biclopsOdomCallback(const geometry_msgs::PoseStampedConstPtr& msg)
138 {
139  geometry_msgs::PoseStamped position;
140  qm[1] = position.pose.orientation.x;
141  qm[0] = position.pose.orientation.y;
142 }
143 
144 void VS::poseCallback(const geometry_msgs::PoseStampedConstPtr& msg)
145 {
146  geometry_msgs::Twist out_cmd_vel;
147  geometry_msgs::Twist pioneer_cmd_vel;
148  geometry_msgs::Twist biclops_cmd_vel;
149  try {
150  t_start_loop = vpTime::measureTimeMs();
151 
152  std::ostringstream strs;
153  strs << "Receive a new pose" << std::endl;
154  std::string str;
155  str = strs.str();
156  ROS_DEBUG("%s", str.c_str());
157 
158  vpHomogeneousMatrix cMo = visp_bridge::toVispHomogeneousMatrix(msg->pose);
159 
160  vpPoint origin;
161  origin.setWorldCoordinates(0,0,0);
162  origin.project(cMo);
163  Z = origin.get_Z();
164 
165  if (Z <= 0)
166  ROS_DEBUG("Z <= 0");
167 
168  if (! valid_pose || Z <= 0) {
169  ROS_DEBUG("not valid pose");
170 
171  out_cmd_vel.linear.x = 0;
172  out_cmd_vel.linear.y = 0;
173  out_cmd_vel.linear.z = 0;
174  out_cmd_vel.angular.x = 0;
175  out_cmd_vel.angular.y = 0;
176  out_cmd_vel.angular.z = 0;
177  pubTwistPioneer_.publish(out_cmd_vel);
178  pubTwistBiclops_.publish(out_cmd_vel);
179 
180  valid_pose = false;
182 
183  return;
184  }
185 
186  // Update the current x feature
187  s_x.set_xyZ(origin.p[0], origin.p[1], Z);
188 
189  // Update log(Z/Z*) feature. Since the depth Z change, we need to update the intection matrix
190  s_Z.buildFrom(s_x.get_x(), s_x.get_y(), Z, log(Z/Zd)) ;
191 
192  vpVelocityTwistMatrix cVe = robot.get_cVe();
193  task.set_cVe( cVe );
194 
195  // Update the robot jacobian that depends on the pan position
196  robot.set_eJe(qm_pan);
197  // Get the robot jacobian
198  vpMatrix eJe = robot.get_eJe();
199  // Update the jacobian that will be used to compute the control law
200  task.set_eJe(eJe);
201 
202  // Compute the control law. Velocities are computed in the mobile robot reference frame
203  v = task.computeControlLaw() ;
204 
205  static unsigned long iter = 0;
206 // if (valid_pose_prev == false) {
207  if (iter == 0) {
208  // Start a new visual servo
209  ROS_INFO("Reinit visual servo");
210 
212  vi = v;
213  }
214  iter ++;
215 
216  //v = v - vi*exp(-mu*(t_start_loop - tinit)/1000.);
217  double max_linear_vel = 0.5;
218  double max_angular_vel = vpMath::rad(50);
219  vpColVector v_max(3);
220  v_max[0] = max_linear_vel;
221  v_max[1] = max_angular_vel;
222  v_max[2] = max_angular_vel;
223 
224  vpColVector v_sat = vpRobot::saturateVelocities(v, v_max);
225 
226 // if (std::abs(v[0]) > max_linear_vel || std::abs(v[1]) > max_angular_vel || std::abs(v[2]) > max_angular_vel) {
227 // ROS_INFO("Vel exceed max allowed");
228 // for (unsigned int i=0; i< v.size(); i++)
229 // ROS_INFO("v[%d]=%f", i, v[i]);
230 // v = 0;
231 // }
232 
233 
234  pioneer_cmd_vel.linear.x = v_sat[0];
235  pioneer_cmd_vel.linear.y = 0;
236  pioneer_cmd_vel.linear.z = 0;
237  pioneer_cmd_vel.angular.x = 0;
238  pioneer_cmd_vel.angular.y = 0;
239  pioneer_cmd_vel.angular.z = v_sat[1];
240 
241  biclops_cmd_vel.linear.x = 0;
242  biclops_cmd_vel.linear.y = 0;
243  biclops_cmd_vel.linear.z = 0;
244  biclops_cmd_vel.angular.x = 0;
245  biclops_cmd_vel.angular.y = v_sat[2];
246  biclops_cmd_vel.angular.z = 0;
247 
248  pubTwistPioneer_.publish(pioneer_cmd_vel);
249  if (t_start_loop - tinit>2000)
250  pubTwistBiclops_.publish(biclops_cmd_vel);
252 
253  valid_pose = false;
254  }
255  catch(...) {
256  ROS_INFO("Catch an exception: set vel to 0");
257  out_cmd_vel.linear.x = 0;
258  out_cmd_vel.linear.y = 0;
259  out_cmd_vel.linear.z = 0;
260  out_cmd_vel.angular.x = 0;
261  out_cmd_vel.angular.y = 0;
262  out_cmd_vel.angular.z = 0;
263  pubTwistPioneer_.publish(out_cmd_vel);
264  pubTwistBiclops_.publish(out_cmd_vel);
265  }
266 }
267 
268 int main(int argc, char **argv)
269 {
270  ros::init(argc, argv, "PioneerPan");
271 
272  VS vs(argc, argv);
273 
274  ros::spin();
275 }
276 
277 
msg
vpFeatureDepth s_Zd
void publish(const boost::shared_ptr< M > &message) const
VS(int argc, char **argv)
vpHomogeneousMatrix toVispHomogeneousMatrix(const geometry_msgs::Transform &trans)
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
vpFeaturePoint s_x
ros::NodeHandle nh_
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
vpPioneerPan robot
bool valid_pose_prev
double depth
vpColVector vi
void statusCallback(const std_msgs::Int8ConstPtr &msg)
double t_start_loop
void init_vs()
ROSCPP_DECL void spin(Spinner &spinner)
vpAdaptiveGain lambda_adapt
vpColVector qm
#define ROS_INFO(...)
vpFeaturePoint s_xd
vpColVector v
ros::Publisher pubTwistPioneer_
void biclopsOdomCallback(const geometry_msgs::PoseStampedConstPtr &msg)
ros::Subscriber subStatusTarget_
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
double tinit
vpFeatureDepth s_Z
int main(int argc, char **argv)
void poseCallback(const geometry_msgs::PoseStampedConstPtr &msg)
vpCameraParameters cam
vpServo task
ros::Subscriber subBiclopsOdom_
double lambda
ros::Subscriber subPoseTarget_
ros::Publisher pubTwistBiclops_
#define ROS_DEBUG(...)


demo_pioneer
Author(s): Fabien Spindler
autogenerated on Wed Jun 5 2019 20:53:56