visual_servo_pioneer.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 #include <visp_bridge/3dpose.h>
7 #include <visp_bridge/camera.h>
8 #include <sensor_msgs/CameraInfo.h>
9 
10 #include <visp/vpAdaptiveGain.h>
11 #include <visp/vpCameraParameters.h>
12 #include <visp/vpDot.h>
13 #include <visp/vpDot2.h>
14 #include <visp/vpFeatureBuilder.h>
15 #include <visp/vpFeatureDepth.h>
16 #include <visp/vpFeaturePoint.h>
17 #include <visp/vpHomogeneousMatrix.h>
18 #include <visp/vpPioneer.h>
19 #include <visp/vpServo.h>
20 #include <visp/vpVelocityTwistMatrix.h>
21 
22 class VS
23 {
24 private:
27  ros::Subscriber subPose_; // pose_stamped
28  ros::Subscriber subStatus_; // pose_stamped
29  ros::Subscriber sub_cam_info; // Camera parameters
30 
31  vpServo task;
32  // Current and desired visual feature associated to the x coordinate of the point
33  vpFeaturePoint s_x, s_xd;
34  vpFeatureDepth s_Z, s_Zd;
35 
36 
37 
38  vpCameraParameters cam;
39  bool Stream_info_camera; //Is equal to one if we received the information about the camera
40  double depth;
41  double Z, Zd;
42  double lambda;
43 
44  bool valid_pose;
46 
47  double t_start_loop;
48  double tinit;
49 
50  vpColVector v;
51  vpColVector vi;
52  double mu;
53  vpAdaptiveGain lambda_adapt;
54 
55 public:
56  void init_vs();
57  void poseCallback(const geometry_msgs::PoseStampedConstPtr& msg);
58  void statusCallback(const std_msgs::Int8ConstPtr& msg);
59  void CameraInfoCb(const sensor_msgs::CameraInfo& msg);
60  VS(int argc, char**argv);
61  virtual ~VS() {
62  task.kill();
63  };
64 };
65 
66 VS::VS(int argc, char**argv)
67 {
68  //init_vs();
69 
70  subPose_ = nh_.subscribe("/visp_auto_tracker/object_position", 1000, &VS::poseCallback, this);
71  subStatus_ = nh_.subscribe("/visp_auto_tracker/status", 1000, &VS::statusCallback, this);
72  pubTwist_ = nh_.advertise<geometry_msgs::Twist>("vs/pioneer/cmd_vel", 1000);
73  // Subscribe to the topic Camera info in order to receive the camera paramenter. The callback function will be called only one time.
74  sub_cam_info = nh_.subscribe("/camera_info", 1000,&VS::CameraInfoCb,this);
75 
76  depth = 0.4;
77  lambda = 1.;
78  valid_pose = false;
79  valid_pose_prev = false;
80 
82 
83  Z = Zd = depth;
84 
85  v.resize(2);
86  vi.resize(2);
87  v = 0; vi = 0;
88  mu = 4;
89 
90  t_start_loop = 0.0;
91  tinit = 0.0;
92 }
93 
95 {
96 
97 
98  //cam.initPersProjWithoutDistortion(800, 795, 320, 216);
99 
100 
101  lambda_adapt.initStandard(3, 0.2, 40);
102 
103 
104  task.setServo(vpServo::EYEINHAND_L_cVe_eJe) ;
105  task.setInteractionMatrixType(vpServo::DESIRED, vpServo::PSEUDO_INVERSE) ;
106  task.setLambda(lambda_adapt) ;
107 
108  vpPioneer robot; // Pas top ! devrait etre vpRobotPioneer
109  vpVelocityTwistMatrix cVe = robot.get_cVe();
110  vpMatrix eJe = robot.get_eJe();
111  task.set_cVe( cVe );
112  task.set_eJe( eJe );
113 
114  vpImagePoint ip(0,0);
115 
116  // Create the current x visual feature
117  vpFeatureBuilder::create(s_x, cam, ip);
118 
119  // Create the desired x* visual feature
120  s_xd.buildFrom(0, 0, Zd);
121 
122  // Add the feature
123  task.addFeature(s_x, s_xd, vpFeaturePoint::selectX()) ;
124 
125  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
126  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
127 
128  // Add the feature
129  task.addFeature(s_Z, s_Zd) ;
130 
131 }
132 
133 void VS::statusCallback(const std_msgs::Int8ConstPtr& msg)
134 {
135  if (msg->data == 3)
136  valid_pose = true;
137  else
138  valid_pose = false;
139 }
140 
141 void VS::poseCallback(const geometry_msgs::PoseStampedConstPtr& msg)
142 {
143 
144  if (!Stream_info_camera ) // We check if the streaming of images is started or not
145  {
146  std::cout << "Waiting for the camera parameters."<<std::endl;
147  return;
148  }
149 
150 
151  geometry_msgs::Twist out_cmd_vel;
152  try {
153  t_start_loop = vpTime::measureTimeMs();
154 
155  std::ostringstream strs;
156  strs << "Receive a new pose" << std::endl;
157  std::string str;
158  str = strs.str();
159  ROS_DEBUG("%s", str.c_str());
160 
161  vpHomogeneousMatrix cMo = visp_bridge::toVispHomogeneousMatrix(msg->pose);
162 
163  vpPoint origin;
164  origin.setWorldCoordinates(0,0,0);
165  origin.project(cMo);
166  Z = origin.get_Z();
167 
168  if (Z <= 0)
169  ROS_DEBUG("Z <= 0");
170 
171  if (! valid_pose || Z <= 0) {
172  ROS_DEBUG("not valid pose");
173 
174  out_cmd_vel.linear.x = 0;
175  out_cmd_vel.linear.y = 0;
176  out_cmd_vel.linear.z = 0;
177  out_cmd_vel.angular.x = 0;
178  out_cmd_vel.angular.y = 0;
179  out_cmd_vel.angular.z = 0;
180  pubTwist_.publish(out_cmd_vel);
181 
182  valid_pose = false;
184 
185  return;
186  }
187 
188  // Update the current x feature
189  s_x.set_xyZ(origin.p[0], origin.p[1], Z);
190 
191  // Update log(Z/Z*) feature. Since the depth Z change, we need to update the intection matrix
192  s_Z.buildFrom(s_x.get_x(), s_x.get_y(), Z, log(Z/Zd)) ;
193 
194  vpPioneer robot; // Pas top ! devrait etre vpRobotPioneer
195  vpVelocityTwistMatrix cVe = robot.get_cVe();
196  vpMatrix eJe = robot.get_eJe();
197  task.set_cVe( cVe );
198  task.set_eJe( eJe );
199 
200  // Compute the control law. Velocities are computed in the mobile robot reference frame
201  v = task.computeControlLaw() ;
202 
203  if (0) { //valid_pose_prev == false) {
204  // Start a new visual servo
205  ROS_INFO("Reinit visual servo");
206 
208  vi = v;
209  }
210 
211  v = v - vi*exp(-mu*(t_start_loop - tinit)/1000.);
212  double max_linear_vel = 0.5;
213  double max_angular_vel = vpMath::rad(50);
214 
215  if (std::abs(v[0]) > max_linear_vel || std::abs(v[1]) > max_angular_vel) {
216  ROS_INFO("Vel exceed max allowed");
217  for (unsigned int i=0; i< v.size(); i++)
218  ROS_INFO("v[%d]=%f", i, v[i]);
219  v = 0;
220  }
221 
222  out_cmd_vel.linear.x = v[0];
223  out_cmd_vel.linear.y = 0;
224  out_cmd_vel.linear.z = 0;
225  out_cmd_vel.angular.x = 0;
226  out_cmd_vel.angular.y = 0;
227  out_cmd_vel.angular.z = v[1];
228 
229  pubTwist_.publish(out_cmd_vel);
231 
232  valid_pose = false;
233  }
234  catch(...) {
235  ROS_INFO("Catch an exception: set vel to 0");
236  out_cmd_vel.linear.x = 0;
237  out_cmd_vel.linear.y = 0;
238  out_cmd_vel.linear.z = 0;
239  out_cmd_vel.angular.x = 0;
240  out_cmd_vel.angular.y = 0;
241  out_cmd_vel.angular.z = 0;
242  pubTwist_.publish(out_cmd_vel);
243  }
244 }
245 
246 
247 void VS::CameraInfoCb(const sensor_msgs::CameraInfo& msg)
248  {
249  std::cout << "Received Camera INFO"<<std::endl;
250  // Convert the paramenter in the visp format
252  cam.printParameters();
253 
254  // Stop the subscriber (we don't need it anymore)
255  this->sub_cam_info.shutdown();
256 
257  Stream_info_camera = 1;
258  init_vs();
259 
260 
261  }
262 
263 
264 
265 int main(int argc, char **argv)
266 {
267  ros::init(argc, argv, "pioneer");
268 
269  VS vs(argc, argv);
270 
271  ros::spin();
272 }
273 
274 
ros::Subscriber subPose_
vpFeatureDepth s_Zd
void publish(const boost::shared_ptr< M > &message) const
VS(int argc, char **argv)
vpHomogeneousMatrix toVispHomogeneousMatrix(const geometry_msgs::Transform &trans)
vpCameraParameters toVispCameraParameters(const sensor_msgs::CameraInfo &cam_info)
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)
bool Stream_info_camera
vpPioneerPan robot
bool valid_pose_prev
double depth
vpColVector vi
void CameraInfoCb(const sensor_msgs::CameraInfo &msg)
void statusCallback(const std_msgs::Int8ConstPtr &msg)
double t_start_loop
void init_vs()
ROSCPP_DECL void spin(Spinner &spinner)
vpAdaptiveGain lambda_adapt
#define ROS_INFO(...)
vpFeaturePoint s_xd
vpColVector v
ros::Subscriber sub_cam_info
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
double tinit
vpFeatureDepth s_Z
ros::Publisher pubTwist_
virtual ~VS()
void poseCallback(const geometry_msgs::PoseStampedConstPtr &msg)
int main(int argc, char **argv)
vpCameraParameters cam
vpServo task
double lambda
ros::Subscriber subStatus_
#define ROS_DEBUG(...)


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