MultiJointTrackerNode.cpp
Go to the documentation of this file.
1 #include <boost/foreach.hpp>
2 
5 
6 #include "geometry_msgs/PoseArray.h"
7 
8 #include <vector>
9 
10 #include <geometry_msgs/PoseWithCovarianceStamped.h>
11 
12 #include <stdio.h>
13 
15 
16 #include <rosbag/query.h>
17 
18 #include <rosbag/view.h>
19 
20 #include <ros/package.h>
21 
22 #include <Eigen/Eigen>
23 
24 #include <Eigen/Geometry>
25 
26 #include <std_msgs/String.h>
27 
28 #include <sensor_msgs/JointState.h>
29 
30 #include <omip_msgs/JointMsg.h>
31 
32 #define LINES_OF_TERMINAL_JT 20
33 
34 using namespace omip;
35 
38  _loop_period_ns(0.),
39  _sensor_fps(0.0),
40  _processing_factor(0)
41 
42 {
43  this->_namespace = std::string("joint_tracker");
44  this->ReadParameters();
46 
47  this->_state_publisher = this->_measurements_node_handle.advertise<omip_msgs::KinematicStructureMsg>(this->_namespace + "/state", 100);
48 
49  this->_state_publisher_rviz_markers = this->_measurements_node_handle.advertise<visualization_msgs::MarkerArray>(this->_namespace + "/markers", 100);
50 
51  this->_measurement_prediction_publisher = this->_measurements_node_handle.advertise<rbt_state_t>( "/rb_tracker/predicted_measurement", 100);
52 
53 
54  this->_urdf_pub_service = this->_measurements_node_handle.advertiseService("/joint_tracker/urdf_publisher_srv", &MultiJointTrackerNode::publishURDF, this);
55 
56  this->_state_publisher_urdf = this->_measurements_node_handle.advertise<std_msgs::String>(this->_namespace + "/state_urdf", 100);
57 
58  this->_state_publisher_joint_states = this->_measurements_node_handle.advertise<sensor_msgs::JointState>(this->_namespace + "/joint_states", 100);
59 
60  // This is used to build URDF models that link to the reconstructed shapes
61  this->_sr_path = ros::package::getPath("shape_reconstruction");
62 
63 }
64 
66 {
67 }
68 
70 {
71  int ks_analysis_type;
72  this->getROSParameter<int>(this->_namespace + std::string("/ks_analysis_type"), ks_analysis_type);
73  double disconnected_j_ne;
74  this->getROSParameter<double>(this->_namespace + std::string("/disconnected_ne"), disconnected_j_ne);
75  int likelihood_sample_num;
76  this->getROSParameter<int>(this->_namespace + std::string("/likelihood_sample_num"), likelihood_sample_num);
77  double sigma_delta_meas_uncertainty_linear;
78  this->getROSParameter<double>(this->_namespace + std::string("/sigma_delta_meas_uncertainty_linear"), sigma_delta_meas_uncertainty_linear);
79  double sigma_delta_meas_uncertainty_angular;
80  this->getROSParameter<double>(this->_namespace + std::string("/sigma_delta_meas_uncertainty_angular"), sigma_delta_meas_uncertainty_angular);
81 
82  double prism_prior_cov_vel;
83  this->getROSParameter<double>(this->_namespace + std::string("/prism_prior_cov_vel"), prism_prior_cov_vel);
84  double prism_sigma_sys_noise_phi;
85  this->getROSParameter<double>(this->_namespace + std::string("/prism_sigma_sys_noise_phi"), prism_sigma_sys_noise_phi);
86  double prism_sigma_sys_noise_theta;
87  this->getROSParameter<double>(this->_namespace + std::string("/prism_sigma_sys_noise_theta"), prism_sigma_sys_noise_theta);
88  double prism_sigma_sys_noise_pv;
89  this->getROSParameter<double>(this->_namespace + std::string("/prism_sigma_sys_noise_pv"), prism_sigma_sys_noise_pv);
90  double prism_sigma_sys_noise_pvd;
91  this->getROSParameter<double>(this->_namespace + std::string("/prism_sigma_sys_noise_pvd"), prism_sigma_sys_noise_pvd);
92  double prism_sigma_meas_noise;
93  this->getROSParameter<double>(this->_namespace + std::string("/prism_sigma_meas_noise"), prism_sigma_meas_noise);
94 
95  double rev_prior_cov_vel;
96  this->getROSParameter<double>(this->_namespace + std::string("/rev_prior_cov_vel"), rev_prior_cov_vel);
97  double rev_sigma_sys_noise_phi;
98  this->getROSParameter<double>(this->_namespace + std::string("/rev_sigma_sys_noise_phi"), rev_sigma_sys_noise_phi);
99  double rev_sigma_sys_noise_theta;
100  this->getROSParameter<double>(this->_namespace + std::string("/rev_sigma_sys_noise_theta"), rev_sigma_sys_noise_theta);
101  double rev_sigma_sys_noise_px;
102  this->getROSParameter<double>(this->_namespace + std::string("/rev_sigma_sys_noise_px"), rev_sigma_sys_noise_px);
103  double rev_sigma_sys_noise_py;
104  this->getROSParameter<double>(this->_namespace + std::string("/rev_sigma_sys_noise_py"), rev_sigma_sys_noise_py);
105  double rev_sigma_sys_noise_pz;
106  this->getROSParameter<double>(this->_namespace + std::string("/rev_sigma_sys_noise_pz"), rev_sigma_sys_noise_pz);
107  double rev_sigma_sys_noise_rv;
108  this->getROSParameter<double>(this->_namespace + std::string("/rev_sigma_sys_noise_rv"), rev_sigma_sys_noise_rv);
109  double rev_sigma_sys_noise_rvd;
110  this->getROSParameter<double>(this->_namespace + std::string("/rev_sigma_sys_noise_rvd"), rev_sigma_sys_noise_rvd);
111  double rev_sigma_meas_noise;
112  this->getROSParameter<double>(this->_namespace + std::string("/rev_sigma_meas_noise"), rev_sigma_meas_noise);
113  double rev_min_rot_for_ee;
114  this->getROSParameter<double>(this->_namespace + std::string("/rev_min_rot_for_ee"), rev_min_rot_for_ee);
115  double rev_max_joint_distance_for_ee;
116  this->getROSParameter<double>(this->_namespace + std::string("/rev_max_joint_distance_for_ee"), rev_max_joint_distance_for_ee);
117 
118  double rig_max_translation;
119  this->getROSParameter<double>(this->_namespace + std::string("/rig_max_translation"), rig_max_translation);
120  double rig_max_rotation;
121  this->getROSParameter<double>(this->_namespace + std::string("/rig_max_rotation"), rig_max_rotation);
122 
123  this->getROSParameter<int>(this->_namespace + std::string("/min_joint_age_for_ee"), this->_min_joint_age_for_ee);
124 
125  this->getROSParameter<double>(std::string("/omip/sensor_fps"), this->_sensor_fps);
126  this->getROSParameter<int>(std::string("/omip/processing_factor"), this->_processing_factor);
127  this->_loop_period_ns = 1e9/(this->_sensor_fps/(double)this->_processing_factor);
128 
129  int min_num_frames_for_new_rb;
130  this->getROSParameter<int>(std::string("/rb_tracker/min_num_frames_for_new_rb"), min_num_frames_for_new_rb);
131 
132  ROS_INFO_STREAM_NAMED( "MultiJointTrackerNode.ReadParameters", "MultiJointTrackerNode Parameters: " << std::endl << //
133  "\tType of kinematic analysis: " << ks_analysis_type << std::endl << //
134  "\tDisconnected joint normalized error (joint classification threshold): " << disconnected_j_ne << std::endl << //
135  "\tNumber of samples to estimate likelihood: " << likelihood_sample_num << std::endl << //
136  "\tSigma of the delta of measurements (linear): " << sigma_delta_meas_uncertainty_linear << std::endl << //
137  "\tSigma of the delta of measurements (angular): " << sigma_delta_meas_uncertainty_angular << std::endl <<
138  "\tSigma of the prior of the velocity prismatic joint: " << prism_prior_cov_vel << std::endl <<
139  "\tSigma of the system noise phi prismatic joint: " << prism_sigma_sys_noise_phi << std::endl <<
140  "\tSigma of the system noise theta prismatic joint: " << prism_sigma_sys_noise_theta << std::endl <<
141  "\tSigma of the system noise pv prismatic joint: " << prism_sigma_sys_noise_pv << std::endl <<
142  "\tSigma of the system noise pvd prismatic joint: " << prism_sigma_sys_noise_pvd << std::endl <<
143  "\tSigma of the measurement noise prismatic joint: " << prism_sigma_meas_noise << std::endl <<
144  "\tSigma of the prior of the velocity revolute joint: " << rev_prior_cov_vel << std::endl <<
145  "\tSigma of the system noise phi revolute joint: " << rev_sigma_sys_noise_phi << std::endl <<
146  "\tSigma of the system noise theta revolute joint: " << rev_sigma_sys_noise_theta << std::endl <<
147  "\tSigma of the system noise px revolute joint: " << rev_sigma_sys_noise_px << std::endl <<
148  "\tSigma of the system noise py revolute joint: " << rev_sigma_sys_noise_py << std::endl <<
149  "\tSigma of the system noise pz revolute joint: " << rev_sigma_sys_noise_pz << std::endl <<
150  "\tSigma of the system noise rv revolute joint: " << rev_sigma_sys_noise_rv << std::endl <<
151  "\tSigma of the system noise rvd revolute joint: " << rev_sigma_sys_noise_rvd << std::endl <<
152  "\tSigma of the measurement noise revolute joint: " << rev_sigma_meas_noise << std::endl <<
153  "\tMax translation to reject the rigid joint hyp: " << rig_max_translation << std::endl <<
154  "\tMax rotation to reject the rigid joint hyp: " << rig_max_rotation << std::endl <<
155  "\tMinimum joint age for ee: " << _min_joint_age_for_ee <<
156  "\tMinimum num frames for new rb: " << min_num_frames_for_new_rb
157  );
158 
159  this->_re_filter = new MultiJointTracker(this->_loop_period_ns, (ks_analysis_t)ks_analysis_type, disconnected_j_ne);
160  this->_re_filter->setNumSamplesLikelihoodEstimation(likelihood_sample_num);
161  this->_re_filter->setSigmaDeltaMeasurementUncertaintyLinear(sigma_delta_meas_uncertainty_linear);
162  this->_re_filter->setSigmaDeltaMeasurementUncertaintyAngular(sigma_delta_meas_uncertainty_angular);
163 
164  this->_re_filter->setPrismaticPriorCovarianceVelocity(prism_prior_cov_vel);
165  this->_re_filter->setPrismaticSigmaSystemNoisePhi(prism_sigma_sys_noise_phi);
166  this->_re_filter->setPrismaticSigmaSystemNoiseTheta(prism_sigma_sys_noise_theta);
167  this->_re_filter->setPrismaticSigmaSystemNoisePV(prism_sigma_sys_noise_pv);
168  this->_re_filter->setPrismaticSigmaSystemNoisePVd(prism_sigma_sys_noise_pvd);
169  this->_re_filter->setPrismaticSigmaMeasurementNoise(prism_sigma_meas_noise);
170 
171  this->_re_filter->setRevolutePriorCovarianceVelocity(rev_prior_cov_vel);
172  this->_re_filter->setRevoluteSigmaSystemNoisePhi(rev_sigma_sys_noise_phi);
173  this->_re_filter->setRevoluteSigmaSystemNoiseTheta(rev_sigma_sys_noise_theta);
174  this->_re_filter->setRevoluteSigmaSystemNoisePx(rev_sigma_sys_noise_px);
175  this->_re_filter->setRevoluteSigmaSystemNoisePy(rev_sigma_sys_noise_py);
176  this->_re_filter->setRevoluteSigmaSystemNoisePz(rev_sigma_sys_noise_pz);
177  this->_re_filter->setRevoluteSigmaSystemNoiseRV(rev_sigma_sys_noise_rv);
178  this->_re_filter->setRevoluteSigmaSystemNoiseRVd(rev_sigma_sys_noise_rvd);
179  this->_re_filter->setRevoluteSigmaMeasurementNoise(rev_sigma_meas_noise);
180 
181  this->_re_filter->setRevoluteMinimumRotForEstimation(rev_min_rot_for_ee);
182  this->_re_filter->setRevoluteMaximumJointDistanceForEstimation(rev_max_joint_distance_for_ee);
183 
184  this->_re_filter->setRigidMaxTranslation(rig_max_translation);
185  this->_re_filter->setRigidMaxRotation(rig_max_rotation);
186 
187  this->_re_filter->setMinimumJointAgeForEE(this->_min_joint_age_for_ee);
188 
189  this->_re_filter->setMinimumNumFramesForNewRB(min_num_frames_for_new_rb);
190 }
191 
193 {
194  ros::Time tinit = ros::Time::now();
195 
196  // Get the time of the measurement as reference time
197  this->_current_measurement_time = poses_and_vels->header.stamp;
198 
199  this->_re_filter->setMeasurement(*poses_and_vels, (double)poses_and_vels->header.stamp.toNSec());
200 
201  // Measure the time interval between the previous measurement and the current measurement
202  ros::Duration time_between_meas = this->_current_measurement_time - this->_previous_measurement_time;
203 
204  // The time interval between frames is the inverse of the max_framerate
205  double period_between_frames = 1.0/this->_sensor_fps;
206 
207  // The number of frames elapsed is the time elapsed divided by the period between frames
208  int frames_between_meas = round((time_between_meas.toSec())/period_between_frames);
209 
210  // Processing fps: ignore (this->_processing_factor - 1) frames and process one. This gives effectively the desired processing fps: _sensor_fps/_processing_factor
211  if( this->_previous_measurement_time.toSec() == 0.)
212  {
213  ROS_ERROR("Initial prediction of state and measurements (in KS estimation)!");
214 
215  // In the first iteration we clear the markers of the previous run (if the user wants that)
216  bool clear_rviz_markers;
217  this->getROSParameter<bool>(this->_namespace + std::string("/clear_rviz_markers"), clear_rviz_markers);
218  if(clear_rviz_markers)
219  {
220  ROS_INFO_STREAM("Clearing RVIZ markers");
221  // Clear all previous markers
222  // Create a map of the most probable joints
223  visualization_msgs::MarkerArray cleaning_markers;
224  for (int num_rbs=0; num_rbs<100; num_rbs++)
225  {
226  for(int num_joint_markers=0; num_joint_markers < 3; num_joint_markers++)
227  {
228  visualization_msgs::Marker cleaning_joint_marker;
229  cleaning_joint_marker.ns = "kinematic_structure";
230  cleaning_joint_marker.action = visualization_msgs::Marker::DELETE;
231  cleaning_joint_marker.type = visualization_msgs::Marker::ARROW;
232 
233  cleaning_joint_marker.header.stamp = ros::Time::now();
234  cleaning_joint_marker.id = 3*num_rbs + num_joint_markers;
235 
236  cleaning_markers.markers.push_back(cleaning_joint_marker);
237 
238  cleaning_joint_marker.ns = "kinematic_structure_uncertainty";
239  cleaning_markers.markers.push_back(cleaning_joint_marker);
240  }
241  }
242  this->_state_publisher_rviz_markers.publish(cleaning_markers);
243  }
244  }
245  else if( frames_between_meas != this->_processing_factor)
246  {
247  ROS_ERROR("Lost frames:%3d. Need to predict state and measurement again.", frames_between_meas - this->_processing_factor);
248 
249  // Predict next RE state
250  this->_re_filter->predictState((double)time_between_meas.toNSec());
251 
252  // Predict next measurement based on the predicted state
253  this->_re_filter->predictMeasurement();
254  }else{
255  ROS_INFO("Frames between measurements:%3d.", frames_between_meas);
256  }
257 
258  // In the first iteration we cannot correct the state because we have only one measurement
259  if(this->_previous_measurement_time.toSec() != 0.)
260  {
261  // Use the predicted measurement and the received measurement to correct the state
262  this->_re_filter->correctState();
263  }
264 
265  this->_re_filter->estimateJointFiltersProbabilities();
266  this->_publishState();
267  this->_PrintResults();
268  this->_re_filter->predictState(this->_loop_period_ns);
269  this->_re_filter->predictMeasurement();
270 
272 
273  this->_previous_measurement_time = this->_current_measurement_time;
274  ros::Time tend = ros::Time::now();
275  ROS_WARN_STREAM("Time between meas: " << time_between_meas.toSec()*1000 << " ms");
276  ROS_WARN_STREAM("Total meas processing time: " << (tend-tinit).toSec()*1000 << " ms");
277 }
278 
279 bool MultiJointTrackerNode::publishURDF(joint_tracker::publish_urdf::Request& request, joint_tracker::publish_urdf::Response& response)
280 {
281  std_msgs::String urdf_string_msg;
282  sensor_msgs::JointState joint_states_msg;
283  this->_generateURDF(urdf_string_msg, joint_states_msg);
284  response.urdf_str = urdf_string_msg.data;
285 
286 
287  if(request.write_to_file)
288  {
289  struct stat buffer2;
290  struct stat buffer3;
291  std::string urdf_file_path_dir = ros::package::getPath("joint_tracker");
292  std::string urdf_file_path_old = urdf_file_path_dir + std::string("/urdf/km1.urdf");
293  std::string urdf_file_path_new = urdf_file_path_dir + std::string("/urdf/km2.urdf");
294 
295 
296  if (stat (urdf_file_path_old.c_str(), &buffer2) == 0)
297  {
298  if (stat (urdf_file_path_new.c_str(), &buffer3) == 0)
299  {
300  std::remove(urdf_file_path_new.c_str());
301  }
302  std::rename(urdf_file_path_old.c_str(), urdf_file_path_new.c_str());
303  }
304  std::ofstream new_urdf_file(urdf_file_path_old.c_str());
305  new_urdf_file << response.urdf_str;
306  new_urdf_file.close();
307  }
308 
309  return true;
310 }
311 
312 void MultiJointTrackerNode::_generateURDF(std_msgs::String& urdf_string_msg, sensor_msgs::JointState& joint_state_msg) const
313 {
314  std::ostringstream urdf_stream;
315  int RB_id_first;
316  int RB_id_second;
317  KinematicModel kinematic_model_original = this->_re_filter->getState();
318 
319  typedef std::map<std::pair<int, int>, JointFilterPtr> map_type_temp;
320  map_type_temp kinematic_model;
321  std::map<std::pair<int, int>, JointCombinedFilterPtr>::const_iterator joint_combined_filters_it = kinematic_model_original.begin();
322  std::map<std::pair<int, int>, JointCombinedFilterPtr>::const_iterator joint_combined_filters_it_end = kinematic_model_original.end();
323  for (; joint_combined_filters_it != joint_combined_filters_it_end; joint_combined_filters_it++)
324  {
325  JointFilterPtr joint_hypothesis = joint_combined_filters_it->second->getMostProbableJointFilter();
326  kinematic_model[joint_combined_filters_it->first] = joint_hypothesis;
327  }
328 
329 
330  urdf_stream << "<?xml version=\"1.0\"?>" << std::endl;
331  urdf_stream << "<robot name=\"KinematicStructure\">" << std::endl;
332 
333  // First add the joints
334  // We need to add first the joints because this gives us the transformations we need to apply to the link visual's to bring them back to the origin
335  bool prism_or_rev = false;
336  std::map<int, std::pair<Eigen::Vector3d, Eigen::Vector3d> > link_visuals_origin;
337  double joint_state = 0.;
338  double joint_velocity = 0.;
339  Eigen::Vector3d joint_position(0.,0.,0.);
340  Eigen::Vector3d joint_orientation_rpy(0.,0.,0.);
341  Eigen::Vector3d joint_orientation_axis(0.,0.,0.);
342  BOOST_FOREACH(map_type_temp::value_type km_it, kinematic_model)
343  {
344  prism_or_rev = false;
345  RB_id_first = km_it.first.first;
346  RB_id_second = km_it.first.second;
347  joint_state = km_it.second->getJointState();
348  joint_velocity = km_it.second->getJointVelocity();
349  joint_position = km_it.second->getJointPositionInRRBFrame();
350  joint_orientation_rpy = km_it.second->getJointOrientationRPYInRRBFrame();
351  joint_orientation_axis = km_it.second->getJointOrientationUnitaryVector();
352 
353  std::ostringstream joint_unique_name;
354 
355  joint_unique_name << "joint" << km_it.second->getJointId();
356 
357  urdf_stream << " <joint name=\"" << joint_unique_name.str() << "\" type=\"";
358 
359  switch(km_it.second->getJointFilterType())
360  {
361  case RIGID_JOINT:
362  urdf_stream << "fixed\">" << std::endl;
363  break;
364  case PRISMATIC_JOINT:
365  prism_or_rev = true;
366  urdf_stream << "prismatic\">" << std::endl;
367  joint_state_msg.name.push_back(joint_unique_name.str());
368  joint_state_msg.position.push_back(joint_state);
369  joint_state_msg.velocity.push_back(joint_velocity);
370  joint_state_msg.effort.push_back(0.0);
371  break;
372  case REVOLUTE_JOINT:
373  prism_or_rev = true;
374  urdf_stream << "revolute\">" << std::endl;
375  joint_state_msg.name.push_back(joint_unique_name.str());
376  joint_state_msg.position.push_back(joint_state);
377  joint_state_msg.velocity.push_back(joint_velocity);
378  joint_state_msg.effort.push_back(0.0);
379  break;
380  case DISCONNECTED_JOINT:
381  urdf_stream << "floating\">" << std::endl;
382  break;
383  default:
384  std::cout << "ERROR deparsing the results into a urdf string. Joint type not defined" << std::endl;
385  return;
386  break;
387  }
388 
389  // Set the parent link
390  if(RB_id_first == 0)
391  {
392  urdf_stream << " <parent link=\"static_environment\"/>" << std::endl;
393  }
394  else{
395  urdf_stream << " <parent link=\"rb" << RB_id_first << "\"/>"<< std::endl;
396  }
397 
398  // Set the child link
399  urdf_stream << " <child link=\"rb" << RB_id_second << "\"/>"<< std::endl;
400 
401  // Set the properties of the link for revolute and prismatic joints
402  // We define the joint frame using the parameters of the joint
403  // The joint axis is always a unitary vector pointing in the z direction
404  if(prism_or_rev)
405  {
406  urdf_stream << " <origin xyz=\"" << joint_position.x() << " " << joint_position.y() << " "<< joint_position.z() <<
407  "\" rpy=\"" << 0.0 << " "<< 0.0 << " "<< 0.0 << "\"/>" << std::endl;
408  urdf_stream << " <axis xyz=\"" << joint_orientation_axis.x() << " " << joint_orientation_axis.y() << " " << joint_orientation_axis.z() << "\"/>" << std::endl;
409  link_visuals_origin[RB_id_second] = std::pair<Eigen::Vector3d,Eigen::Vector3d>(-joint_position, Eigen::Vector3d(0.,0.,0.));
410 
411 
412  // With rotation:
413  // urdf_stream << " <origin xyz=\"" << joint_position.x() << " " << joint_position.y() << " "<< joint_position.z() <<
414  // "\" rpy=\"" << joint_orientation_rpy.x() << " "<< joint_orientation_rpy.y() << " "<< joint_orientation_rpy.z() << "\"/>" << std::endl;
415  // urdf_stream << " <axis xyz=\"1 0 0\"/>" << std::endl;
416 
417 
418 
419  urdf_stream << " <limit effort=\"30\" velocity=\"1.0\" lower=\"-3.1416\" upper=\"3.1416\"/>" << std::endl;
420  }
421 
422  urdf_stream << " </joint>" << std::endl;
423  }
424 
425  // We add all the links to the model
426  std::vector<omip::RB_id_t> all_rb_ids;
427  BOOST_FOREACH(map_type_temp::value_type km_it, kinematic_model)
428  {
429  RB_id_first = km_it.first.first;
430  RB_id_second = km_it.first.second;
431 
432  if(std::find(all_rb_ids.begin(), all_rb_ids.end(), RB_id_first) == all_rb_ids.end())
433  {
434  all_rb_ids.push_back(RB_id_first);
435  }
436 
437  if(std::find(all_rb_ids.begin(), all_rb_ids.end(), RB_id_second) == all_rb_ids.end())
438  {
439  all_rb_ids.push_back(RB_id_second);
440  }
441  }
442 
443  std::vector<Eigen::Vector3d > rgb_colors;
444  rgb_colors.push_back(Eigen::Vector3d(255,255,255)/255.0); // white
445  rgb_colors.push_back(Eigen::Vector3d(255,0,0)/255.0); // red
446  rgb_colors.push_back(Eigen::Vector3d(0,0,255)/255.0); // blue
447  rgb_colors.push_back(Eigen::Vector3d(0,255,0)/255.0); // green
448  rgb_colors.push_back(Eigen::Vector3d(255,255,0)/255.0); // yellow
449  rgb_colors.push_back(Eigen::Vector3d(255,0,255)/255.0); // violet
450  rgb_colors.push_back(Eigen::Vector3d(0,255,255)/255.0); // turquese
451  rgb_colors.push_back(Eigen::Vector3d(255,128,0)/255.0); // orange
452  rgb_colors.push_back(Eigen::Vector3d(153,153,255)/255.0); // pink
453  rgb_colors.push_back(Eigen::Vector3d(128,128,128)/255.0); // gray
454 
455 
456  for(int links_idx = 0; links_idx < all_rb_ids.size(); links_idx++)
457  {
458  // Static environment
459  if(all_rb_ids.at(links_idx) == 0)
460  {
461  urdf_stream << " <link name=\"static_environment\"";
462  }
463  else{
464  urdf_stream << " <link name=\"rb" << all_rb_ids.at(links_idx) << "\"";
465  }
466 
467  std::string sr_path = this->_sr_path;
468 
469  sr_path += std::string("/meshes/");
470  std::stringstream name_ss;
471 
472  if(all_rb_ids.at(links_idx) == 0)
473  {
474  name_ss << "shape_static_env" << all_rb_ids.at(links_idx) << ".stl";
475  }else{
476  name_ss << "shape_rb" << all_rb_ids.at(links_idx) << ".stl";
477  }
478 
479  sr_path += name_ss.str();
480 
481  std::string sr_path_urdf = std::string(" <mesh filename=\"package://shape_reconstruction/meshes/");
482  sr_path_urdf += name_ss.str();
483 
484  // We check if there exists a mesh file for this link and if it exists we add it
485  struct stat buffer;
486 
487  if (stat (sr_path.c_str(), &buffer) == 0)
488  {
489  urdf_stream << ">" << std::endl;
490  urdf_stream << " <visual>" << std::endl <<
491  // " <origin xyz=\"0 0 0\" rpy=\"0 0 0\" />" << std::endl <<
492  " <origin xyz=\"" << link_visuals_origin[all_rb_ids.at(links_idx)].first.x() << " "
493  << link_visuals_origin[all_rb_ids.at(links_idx)].first.y() << " "
494  << link_visuals_origin[all_rb_ids.at(links_idx)].first.z() << "\" rpy=\""
495  << link_visuals_origin[all_rb_ids.at(links_idx)].second.x() << " "
496  << link_visuals_origin[all_rb_ids.at(links_idx)].second.y() << " "
497  << link_visuals_origin[all_rb_ids.at(links_idx)].second.z() << "\"/>" << std::endl <<
498  " <geometry>" << std::endl <<
499  sr_path_urdf << "\"/>"<< std::endl <<
500  " </geometry>" << std::endl <<
501  " <material name=\"" << "shape_rb" << all_rb_ids.at(links_idx) << "_color\">" << std::endl <<
502  " <color rgba=\"" << rgb_colors.at(all_rb_ids.at(links_idx)%rgb_colors.size()).x() << " "<<
503  rgb_colors.at(all_rb_ids.at(links_idx)%rgb_colors.size()).y() << " "<<
504  rgb_colors.at(all_rb_ids.at(links_idx)%rgb_colors.size()).z() << " 1\"/>" << std::endl <<
505  " </material>" << std::endl<<
506  " </visual>"<<std::endl <<
507  " </link>" << std::endl;
508  }else
509  {
510  urdf_stream << "/>" << std::endl;
511  }
512  }
513 
514  urdf_stream << "</robot>" << std::endl;
515 
516  urdf_string_msg.data = urdf_stream.str();
517 
518  joint_state_msg.header.stamp = ros::Time::now();
519 }
520 
522 {
523  visualization_msgs::MarkerArray cleaning_markers;
524  for (int num_rbs=0; num_rbs<100; num_rbs++)
525  {
526  for(int num_joint_markers=0; num_joint_markers < 3; num_joint_markers++)
527  {
528  visualization_msgs::Marker cleaning_joint_marker;
529  cleaning_joint_marker.ns = "kinematic_structure";
530  cleaning_joint_marker.action = visualization_msgs::Marker::DELETE;
531  cleaning_joint_marker.type = visualization_msgs::Marker::ARROW;
532 
533  cleaning_joint_marker.header.stamp = ros::Time::now();
534  cleaning_joint_marker.id = 3*num_rbs + num_joint_markers;
535 
536  cleaning_markers.markers.push_back(cleaning_joint_marker);
537 
538  cleaning_joint_marker.ns = "kinematic_structure_uncertainty";
539  cleaning_markers.markers.push_back(cleaning_joint_marker);
540  }
541  }
542  this->_state_publisher_rviz_markers.publish(cleaning_markers);
543 
544  ks_state_ros_t kinematic_structure;
545  visualization_msgs::MarkerArray markers_of_most_probable_structure;
546 
547  ros::Time time_markers = this->_current_measurement_time;
548  int RB_id;
549  KinematicModel kinematic_model = this->_re_filter->getState();
550 
551  omip_msgs::KinematicStructureMsg ks_msg;
552  // Populate a ros state message containing the kinematic structure (most probable joint and all others)
553  BOOST_FOREACH(KinematicModel::value_type km_it, kinematic_model)
554  {
555  omip_msgs::JointMsg joint_msg;
556  joint_msg.parent_rb_id = km_it.first.first;
557  joint_msg.child_rb_id = km_it.first.second;
558 
559  joint_msg.rigid_probability = km_it.second->getJointFilter(RIGID_JOINT)->getProbabilityOfJointFilter();
560  joint_msg.discon_probability = km_it.second->getJointFilter(DISCONNECTED_JOINT)->getProbabilityOfJointFilter();
561  joint_msg.rev_probability = km_it.second->getJointFilter(REVOLUTE_JOINT)->getProbabilityOfJointFilter();
562  joint_msg.prism_probability = km_it.second->getJointFilter(PRISMATIC_JOINT)->getProbabilityOfJointFilter();
563 
564  Eigen::Vector3d temp_eigen = km_it.second->getJointFilter(PRISMATIC_JOINT)->getJointPositionInRRBFrame();
565  geometry_msgs::Point temp_ros;
566  temp_ros.x = temp_eigen.x();
567  temp_ros.y = temp_eigen.y();
568  temp_ros.z = temp_eigen.z();
569  joint_msg.prism_position = temp_ros;
570 
571  geometry_msgs::Vector3 temp_ros_vect;
572  temp_eigen = km_it.second->getJointFilter(PRISMATIC_JOINT)->getJointOrientationUnitaryVector();
573  temp_ros_vect.x = temp_eigen.x();
574  temp_ros_vect.y = temp_eigen.y();
575  temp_ros_vect.z = temp_eigen.z();
576  joint_msg.prism_orientation = temp_ros_vect;
577 
578  joint_msg.prism_ori_phi = km_it.second->getJointFilter(PRISMATIC_JOINT)->getOrientationPhiInRRBFrame();
579  joint_msg.prism_ori_theta = km_it.second->getJointFilter(PRISMATIC_JOINT)->getOrientationThetaInRRBFrame();
580 
581  joint_msg.prism_ori_cov[0] = km_it.second->getJointFilter(PRISMATIC_JOINT)->getCovarianceOrientationPhiPhiInRRBFrame();
582  joint_msg.prism_ori_cov[1] = km_it.second->getJointFilter(PRISMATIC_JOINT)->getCovarianceOrientationPhiThetaInRRBFrame();
583  joint_msg.prism_ori_cov[2] = km_it.second->getJointFilter(PRISMATIC_JOINT)->getCovarianceOrientationPhiThetaInRRBFrame();
584  joint_msg.prism_ori_cov[3] = km_it.second->getJointFilter(PRISMATIC_JOINT)->getCovarianceOrientationThetaThetaInRRBFrame();
585 
586  joint_msg.prism_joint_value = km_it.second->getJointFilter(PRISMATIC_JOINT)->getJointState();
587 
588  temp_eigen = km_it.second->getJointFilter(REVOLUTE_JOINT)->getJointPositionInRRBFrame();
589  temp_ros.x = temp_eigen.x();
590  temp_ros.y = temp_eigen.y();
591  temp_ros.z = temp_eigen.z();
592  joint_msg.rev_position = temp_ros;
593 
594  temp_eigen = km_it.second->getJointFilter(REVOLUTE_JOINT)->getJointOrientationUnitaryVector();
595  temp_ros_vect.x = temp_eigen.x();
596  temp_ros_vect.y = temp_eigen.y();
597  temp_ros_vect.z = temp_eigen.z();
598  joint_msg.rev_orientation = temp_ros_vect;
599 
600  joint_msg.rev_ori_phi = km_it.second->getJointFilter(REVOLUTE_JOINT)->getOrientationPhiInRRBFrame();
601  joint_msg.rev_ori_theta = km_it.second->getJointFilter(REVOLUTE_JOINT)->getOrientationThetaInRRBFrame();
602 
603  joint_msg.rev_ori_cov[0] = km_it.second->getJointFilter(REVOLUTE_JOINT)->getCovarianceOrientationPhiPhiInRRBFrame();
604  joint_msg.rev_ori_cov[1] = km_it.second->getJointFilter(REVOLUTE_JOINT)->getCovarianceOrientationPhiThetaInRRBFrame();
605  joint_msg.rev_ori_cov[2] = km_it.second->getJointFilter(REVOLUTE_JOINT)->getCovarianceOrientationPhiThetaInRRBFrame();
606  joint_msg.rev_ori_cov[3] = km_it.second->getJointFilter(REVOLUTE_JOINT)->getCovarianceOrientationThetaThetaInRRBFrame();
607 
608  joint_msg.rev_joint_value = km_it.second->getJointFilter(REVOLUTE_JOINT)->getJointState();
609 
610  joint_msg.most_likely_joint = (int)km_it.second->getMostProbableJointFilter()->getJointFilterType();
611 
612  ks_msg.kinematic_structure.push_back(joint_msg);
613  }
614  ks_msg.header.stamp = time_markers;
615  this->_state_publisher.publish(ks_msg);
616 
617  // Create a map of the most probable joints
618  std::map<std::pair<int, int>, boost::shared_ptr<JointFilter> > most_probable_joints;
619  std::map<std::pair<int, int>, JointCombinedFilterPtr>::const_iterator joint_combined_filters_it = kinematic_model.begin();
620  std::map<std::pair<int, int>, JointCombinedFilterPtr>::const_iterator joint_combined_filters_it_end = kinematic_model.end();
621  for (; joint_combined_filters_it != joint_combined_filters_it_end; joint_combined_filters_it++)
622  {
623 
624  JointFilterPtr joint_hypothesis = joint_combined_filters_it->second->getMostProbableJointFilter();
625  most_probable_joints[joint_combined_filters_it->first] = joint_hypothesis;
626 
627  RB_id = joint_combined_filters_it->first.first;
628  std::ostringstream oss;
629 
630  // Static environment
631  if(RB_id == 0)
632  {
633  oss << "static_environment";
634  }
635  else{
636  oss << "ip/rb" << RB_id;
637  }
638  std::vector<visualization_msgs::Marker> joint_markers = joint_hypothesis->getJointMarkersInRRBFrame();
639  for (size_t markers_idx = 0; markers_idx < joint_markers.size(); markers_idx++)
640  {
641  joint_markers.at(markers_idx).header.stamp = time_markers;
642  joint_markers.at(markers_idx).header.frame_id = oss.str();
643 
644  markers_of_most_probable_structure.markers.push_back(joint_markers.at(markers_idx));
645  }
646  }
647  this->_state_publisher_rviz_markers.publish(markers_of_most_probable_structure);
648 
649  std_msgs::String urdf_string_msg;
650  sensor_msgs::JointState joint_states_msg;
651  this->_generateURDF(urdf_string_msg, joint_states_msg);
652  this->_state_publisher_urdf.publish(urdf_string_msg);
653  this->_state_publisher_joint_states.publish(joint_states_msg);
654 }
655 
657 {
658  omip_msgs::RigidBodyPosesAndVelsMsg hypotheses = this->_re_filter->getPredictedMeasurement();
659  hypotheses.header.frame_id = "/camera_rgb_optical_frame";
660  hypotheses.header.stamp = this->_current_measurement_time + ros::Duration(this->_loop_period_ns/1e9);
661  this->_measurement_prediction_publisher.publish(hypotheses);
662 }
663 
665 {
666  KinematicModel kinematic_model = this->_re_filter->getState();
667  int combined_filter_idx = 0;
668  BOOST_FOREACH(KinematicModel::value_type km_it, kinematic_model)
669  {
670  JointCombinedFilterPtr cf_ptr = this->_re_filter->getCombinedFilter(combined_filter_idx);
671  JointFilterPtr joint_hypothesis = km_it.second->getMostProbableJointFilter();
672  ROS_INFO_NAMED( "MultiJointTrackerNode::PrintAndPublishResults",
673  "Joint between RB%3d and RB%3d (JointID =%3d) of type %s (P=%2.2f, Rev=%2.2f, Rig=%2.2f, D=%2.2f)",
674  (int)km_it.first.first,
675  (int)km_it.first.second,
676  (int)km_it.second->getJointCombinedFilterId(),
677  joint_hypothesis->getJointFilterTypeStr().c_str(),
678  cf_ptr->getJointFilter(PRISMATIC_JOINT)->getProbabilityOfJointFilter(),
679  cf_ptr->getJointFilter(REVOLUTE_JOINT)->getProbabilityOfJointFilter(),
680  cf_ptr->getJointFilter(RIGID_JOINT)->getProbabilityOfJointFilter(),
681  cf_ptr->getJointFilter(DISCONNECTED_JOINT)->getProbabilityOfJointFilter());
682  combined_filter_idx++;
683  }
684 }
685 
686 int main(int argc, char** argv)
687 {
688  ros::init(argc, argv, "joint_tracker");
689  MultiJointTrackerNode ks_tracker_node;
690  ks_tracker_node.run();
691 
692  return (0);
693 }
omip_msgs::KinematicStructureMsg::Ptr ks_state_ros_t
virtual void _generateURDF(std_msgs::String &urdf_string_msg, sensor_msgs::JointState &joint_state_msg) const
#define ROS_INFO_NAMED(name,...)
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)
omip_msgs::RigidBodyPosesAndVelsMsg rbt_state_t
virtual void _PrintResults() const
Print the results of the joint tracker on the terminal.
#define ROS_INFO_STREAM_NAMED(name, args)
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
TFSIMD_FORCE_INLINE const tfScalar & y() const
std::map< std::pair< int, int >, boost::shared_ptr< JointCombinedFilter > > KinematicModel
virtual void _publishState() const
Publish the current state of this RE level.
virtual void _publishPredictedMeasurement() const
Publish the prediction about the next measurement by this RE level.
#define ROS_INFO(...)
int64_t toNSec() const
TFSIMD_FORCE_INLINE const tfScalar & x() const
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
#define ROS_WARN_STREAM(args)
ROSLIB_DECL std::string getPath(const std::string &package_name)
TFSIMD_FORCE_INLINE const tfScalar & z() const
#define ROS_INFO_STREAM(args)
virtual bool publishURDF(joint_tracker::publish_urdf::Request &request, joint_tracker::publish_urdf::Response &response)
static Time now()
virtual void measurementCallback(const boost::shared_ptr< ks_measurement_ros_t const > &poses_and_vels)
Callback for the measurements for this RE level (Poses and vels of the tracker RB from the lower leve...
int main(int argc, char **argv)
#define ROS_ERROR(...)


joint_tracker
Author(s): Roberto Martín-Martín
autogenerated on Mon Jun 10 2019 14:06:16