PrismaticJointFilter.cpp
Go to the documentation of this file.
2 
3 #include <Eigen/Geometry>
4 
5 #include <fstream>
6 
7 #include <sstream>
8 
9 #include <Eigen/Eigenvalues>
10 
11 #include <boost/math/distributions/chi_squared.hpp>
12 
13 #include <omip_common/OMIPUtils.h>
14 
15 using namespace omip;
16 using namespace MatrixWrapper;
17 using namespace BFL;
18 
19 // Dimensions of the system state of the filter that tracks a prismatic joint: orientation (2 values), joint variable, and joint velocity
20 #define PRISM_STATE_DIM 4
21 #define MEAS_DIM 6
22 
44  JointFilter(),
45  _sys_PDF(NULL),
46  _sys_MODEL(NULL),
47  _meas_PDF(NULL),
48  _meas_MODEL(NULL),
49  _ekf(NULL),
50  _sigma_delta_meas_uncertainty_linear(-1)
51 {
52 
53 }
54 
55 void PrismaticJointFilter::setCovarianceDeltaMeasurementLinear(double sigma_delta_meas_uncertainty_linear)
56 {
57  this->_sigma_delta_meas_uncertainty_linear = sigma_delta_meas_uncertainty_linear;
58 }
59 
61 {
63 
64 // std::cout << "this->_srb_current_pose_in_sff" << std::endl;
65 // std::cout << this->_srb_current_pose_in_sf << std::endl;
66 // std::cout << this->_srb_current_pose_in_sf.exp(1e-9).toHomogeneousMatrix() << std::endl;
67 // std::cout << "this->_srb_initial_pose_in_rrbf" << std::endl;
68 // std::cout << this->_srb_initial_pose_in_rrbf << std::endl;
69 // std::cout << this->_srb_initial_pose_in_rrbf.exp(1e-9).toHomogeneousMatrix() << std::endl;
70 // std::cout << "this->_current_delta_pose_in_rrbf" << std::endl;
71 // std::cout << this->_current_delta_pose_in_rrbf << std::endl;
72 // std::cout << this->_current_delta_pose_in_rrbf.exp(1e-9).toHomogeneousMatrix() << std::endl;
73 
74  this->_joint_orientation = Eigen::Vector3d(
75  this->_current_delta_pose_in_rrbf.vx(),
76  this->_current_delta_pose_in_rrbf.vy(),
77  this->_current_delta_pose_in_rrbf.vz());
78  this->_joint_state = this->_joint_orientation.norm();
79 
80  this->_joint_states_all.push_back(this->_joint_state);
81  //this->_joint_velocity = this->_joint_state/(this->_loop_period_ns/1e9);
82  // Setting it to 0 is better.
83  // The best approximation would be to (this->_rev_variable/num_steps_to_rev_variable)/(this->_loop_period_ns/1e9)
84  // but we don't know how many steps passed since we estimated the first time the joint variable
85  this->_joint_velocity = 0.0;
86  this->_joint_orientation.normalize();
87 
88  // The position of the prismatic joint is the centroid of the features that belong to the second rigid body (in RBF)
89  Eigen::Displacementd current_ref_pose_displ = this->_rrb_current_pose_in_sf.exp(1e-12);
90  Eigen::Affine3d current_ref_pose;
91  current_ref_pose.matrix() = current_ref_pose_displ.toHomogeneousMatrix();
92  this->_joint_position = current_ref_pose.inverse() * this->_srb_centroid_in_sf;
93 
94  this->_initializeSystemModel();
96  this->_initializeEKF();
97 }
98 
100 {
101  // create SYSTEM MODEL
102  Matrix A(PRISM_STATE_DIM, PRISM_STATE_DIM);
103  A = 0.;
104  for (unsigned int i = 1; i <= PRISM_STATE_DIM; i++)
105  {
106  A(i, i) = 1.0;
107  }
108  A(3, 4) = this->_loop_period_ns/1e9; //Adding the velocity (times the time) to the position of the joint variable
109 
110  ColumnVector sys_noise_MU(PRISM_STATE_DIM);
111  sys_noise_MU = 0;
112 
113  SymmetricMatrix sys_noise_COV(PRISM_STATE_DIM);
114  sys_noise_COV = 0.0;
115  sys_noise_COV(1, 1) = this->_sigma_sys_noise_phi* (std::pow((this->_loop_period_ns/1e9),3) / 3.0);
116  sys_noise_COV(2, 2) = this->_sigma_sys_noise_theta* (std::pow((this->_loop_period_ns/1e9),3) / 3.0);
117  sys_noise_COV(3, 3) = this->_sigma_sys_noise_jv* (std::pow((this->_loop_period_ns/1e9),3) / 3.0);
118  sys_noise_COV(4, 4) = this->_sigma_sys_noise_jvd*(this->_loop_period_ns/1e9);
119 
120  // Initialize System Model
121  Gaussian system_uncertainty_PDF(sys_noise_MU, sys_noise_COV);
122  this->_sys_PDF = new LinearAnalyticConditionalGaussian( A, system_uncertainty_PDF);
123  this->_sys_MODEL = new LinearAnalyticSystemModelGaussianUncertainty( this->_sys_PDF);
124 }
125 
127 {
128  // create MEASUREMENT MODEL
129  ColumnVector meas_noise_MU(MEAS_DIM);
130  meas_noise_MU = 0.0;
131  SymmetricMatrix meas_noise_COV(MEAS_DIM);
132  meas_noise_COV = 0.0;
133  for (unsigned int i = 1; i <= MEAS_DIM; i++)
134  meas_noise_COV(i, i) = this->_sigma_meas_noise;
135 
136  Gaussian meas_uncertainty_PDF(meas_noise_MU, meas_noise_COV);
137 
138  this->_meas_PDF = new NonLinearPrismaticMeasurementPdf(meas_uncertainty_PDF);
139  this->_meas_MODEL = new AnalyticMeasurementModelGaussianUncertainty(this->_meas_PDF);
140 
141 
142  // create MEASUREMENT MODEL Force Torque sensor
143  ColumnVector meas_noise_ft_MU(6);
144  meas_noise_ft_MU = 0;
145  SymmetricMatrix meas_noise_ft_COV(6);
146  meas_noise_ft_COV = 0;
147  for (unsigned int i=1; i<=6; i++)
148  meas_noise_ft_COV(i,i) = 1;
149  Gaussian meas_uncertainty_ft_PDF(meas_noise_ft_MU, meas_noise_ft_COV);
150 
151  // Matrix Himu(3,6); Himu = 0;
152  // Himu(1,4) = 1; Himu(2,5) = 1; Himu(3,6) = 1;
153  // imu_meas_pdf_ = new LinearAnalyticConditionalGaussian(Himu, measurement_Uncertainty_Imu);
154  // imu_meas_model_ = new LinearAnalyticMeasurementModelGaussianUncertainty(imu_meas_pdf_);
155 }
156 
158 {
159  ColumnVector prior_MU(PRISM_STATE_DIM);
160  prior_MU = 0.0;
161 
162  SymmetricMatrix prior_COV(PRISM_STATE_DIM);
163  prior_COV = 0.0;
164 
165  prior_MU(1) = atan2(this->_joint_orientation.y() , this->_joint_orientation.x());
166 
167  // NOTE: I make phi between 0 and 2pi
168  // if(prior_MU(1) < 0.0)
169  // {
170  // prior_MU(1) += 2*M_PI;
171  // }
172 
173  prior_MU(2) = acos(this->_joint_orientation.z());
174  prior_MU(3) = this->_joint_state;
175  prior_MU(4) = this->_joint_velocity;
176 
177  ROS_INFO_STREAM_NAMED( "PrismaticJointFilter::_initializeEKF",
178  "Prismatic initial state (phi, theta, jv, jv_dot): " << prior_MU(1) << " " << prior_MU(2) << " " << prior_MU(3) << " " << prior_MU(4));
179 
180  for (int i = 1; i <= PRISM_STATE_DIM; i++)
181  {
182  prior_COV(i, i) = this->_prior_cov_vel;
183  }
184 
185  Gaussian prior_PDF(prior_MU, prior_COV);
186 
187  this->_ekf = new ExtendedKalmanFilter(&prior_PDF);
188 }
189 
191 {
192  if (this->_sys_PDF)
193  {
194  delete this->_sys_PDF;
195  this->_sys_PDF = NULL;
196  }
197  if (this->_sys_MODEL)
198  {
199  delete this->_sys_MODEL;
200  this->_sys_MODEL = NULL;
201  }
202  if (this->_meas_PDF)
203  {
204  delete this->_meas_PDF;
205  this->_meas_PDF = NULL;
206  }
207  if (this->_meas_MODEL)
208  {
209  delete this->_meas_MODEL;
210  this->_meas_MODEL = NULL;
211  }
212  if (this->_ekf)
213  {
214  delete this->_ekf;
215  this->_ekf = NULL;
216  }
217 }
218 
220  JointFilter(prismatic_joint)
221 {
223  this->_sys_PDF = new LinearAnalyticConditionalGaussian( *(prismatic_joint._sys_PDF));
224  this->_sys_MODEL = new LinearAnalyticSystemModelGaussianUncertainty( *(prismatic_joint._sys_MODEL));
225  this->_meas_PDF = new NonLinearPrismaticMeasurementPdf( *(prismatic_joint._meas_PDF));
226  this->_meas_MODEL = new AnalyticMeasurementModelGaussianUncertainty( *(prismatic_joint._meas_MODEL));
227  this->_ekf = new ExtendedKalmanFilter(*(prismatic_joint._ekf));
228 }
229 
230 void PrismaticJointFilter::predictState(double time_interval_ns)
231 {
232  // Estimate the new cov matrix depending on the time elapsed between the previous and the current measurement
233  SymmetricMatrix sys_noise_COV(PRISM_STATE_DIM);
234  sys_noise_COV = 0.0;
235  sys_noise_COV(1, 1) = this->_sigma_sys_noise_phi* (std::pow((time_interval_ns/1e9),3) / 3.0);
236  sys_noise_COV(2, 2) = this->_sigma_sys_noise_theta* (std::pow((time_interval_ns/1e9),3) / 3.0);
237  sys_noise_COV(3, 3) = this->_sigma_sys_noise_jv* (std::pow((time_interval_ns/1e9),3) / 3.0);
238  sys_noise_COV(4, 4) = this->_sigma_sys_noise_jvd*(time_interval_ns/1e9);
239 
240  // Estimate the new updating matrix which also depends on the time elapsed between the previous and the current measurement
241  // x(t+1) = x(t) + v(t) * delta_t
242  Matrix A(PRISM_STATE_DIM, PRISM_STATE_DIM);
243  A = 0.;
244  for (unsigned int i = 1; i <= PRISM_STATE_DIM; i++)
245  {
246  A(i, i) = 1.0;
247  }
248  A(3, 4) = time_interval_ns/1e9; //Adding the velocity (times the time) to the position of the joint variable
249 
250  this->_sys_PDF->MatrixSet(0, A);
251  this->_sys_PDF->AdditiveNoiseSigmaSet(sys_noise_COV);
252  this->_ekf->Update(this->_sys_MODEL);
253 }
254 
256 {
257  Eigen::Twistd predicted_delta_pose_in_sf = this->_rrb_current_pose_in_sf.exp(1e-12).adjoint()*this->_predicted_delta_pose_in_rrbf;
258 
259  geometry_msgs::TwistWithCovariance hypothesis;
260 
261  hypothesis.twist.linear.x = predicted_delta_pose_in_sf.vx();
262  hypothesis.twist.linear.y = predicted_delta_pose_in_sf.vy();
263  hypothesis.twist.linear.z = predicted_delta_pose_in_sf.vz();
264  hypothesis.twist.angular.x = predicted_delta_pose_in_sf.rx();
265  hypothesis.twist.angular.y = predicted_delta_pose_in_sf.ry();
266  hypothesis.twist.angular.z = predicted_delta_pose_in_sf.rz();
267 
268  // This call gives me the covariance of the predicted measurement: the relative pose between RBs
269  ColumnVector empty;
270  ColumnVector state_updated_state = this->_ekf->PostGet()->ExpectedValueGet();
271  SymmetricMatrix measurement_cov = this->_meas_MODEL->CovarianceGet(empty, state_updated_state);
272  for(int i=0; i<6; i++)
273  {
274  for(int j=0; j<6; j++)
275  {
276  hypothesis.covariance[6 * i + j] = measurement_cov(i+1,j+1);
277  }
278  }
279 
280  return hypothesis;
281 }
282 
284 {
285  Eigen::Twistd predicted_delta_pose_in_sf = this->_rrb_current_pose_in_sf.exp(1e-12).adjoint()*(this->_predicted_delta_pose_in_rrbf/(_loop_period_ns/1e9));
286 
287  geometry_msgs::TwistWithCovariance hypothesis;
288 
289  hypothesis.twist.linear.x = predicted_delta_pose_in_sf.vx();
290  hypothesis.twist.linear.y = predicted_delta_pose_in_sf.vy();
291  hypothesis.twist.linear.z = predicted_delta_pose_in_sf.vz();
292  hypothesis.twist.angular.x = predicted_delta_pose_in_sf.rx();
293  hypothesis.twist.angular.y = predicted_delta_pose_in_sf.ry();
294  hypothesis.twist.angular.z = predicted_delta_pose_in_sf.rz();
295 
296  // This call gives me the covariance of the predicted measurement: the relative pose between RBs
297  ColumnVector empty;
298  ColumnVector state_updated_state = this->_ekf->PostGet()->ExpectedValueGet();
299  SymmetricMatrix measurement_cov = this->_meas_MODEL->CovarianceGet(empty, state_updated_state);
300  for(int i=0; i<6; i++)
301  {
302  for(int j=0; j<6; j++)
303  {
304  hypothesis.covariance[6 * i + j] = measurement_cov(i+1,j+1);
305  }
306  }
307 
308  return hypothesis;
309 }
310 
312 {
313  ColumnVector empty;
314  ColumnVector state_updated_state = this->_ekf->PostGet()->ExpectedValueGet();
315 
316  ROS_DEBUG_STREAM_NAMED( "PrismaticJointFilter::UpdateJointParameters",
317  "Prismatic state after state update: " << state_updated_state(1) << " " << state_updated_state(2) << " " << state_updated_state(3) << " " << state_updated_state(4));
318 
319  ColumnVector predicted_delta_pose_in_rrbf = this->_meas_MODEL->PredictionGet(empty, state_updated_state);
320 
321  this->_predicted_delta_pose_in_rrbf = Eigen::Twistd( predicted_delta_pose_in_rrbf(4), predicted_delta_pose_in_rrbf(5),
322  predicted_delta_pose_in_rrbf(6), predicted_delta_pose_in_rrbf(1),
323  predicted_delta_pose_in_rrbf(2), predicted_delta_pose_in_rrbf(3));
324 
325  Eigen::Displacementd predicted_delta = this->_predicted_delta_pose_in_rrbf.exp(1e-20);
326  Eigen::Displacementd T_rrbf_srbf_t0 = this->_srb_initial_pose_in_rrbf.exp(1.0e-20);
327  Eigen::Displacementd T_rrbf_srbf_t_next = predicted_delta * T_rrbf_srbf_t0;
328 
329  this->_srb_predicted_pose_in_rrbf = T_rrbf_srbf_t_next.log(1.0e-20);
330 }
331 
333 {
334  // New 26.8.2016 -> There is small rotations in the reference frame that cause the prismatic joint to rotate
335  // We eliminate this: we search for the closest motion without rotation that resembles the relative motion
336  Eigen::Matrix4d _srb_current_pose_in_rrbf_matrix;
337  Twist2TransformMatrix( _srb_current_pose_in_rrbf, _srb_current_pose_in_rrbf_matrix);
338 
339  //Then set the rotation to the identity
340  for(int i=0; i<3; i++)
341  {
342  for(int j=0; j<3; j++)
343  {
344  if(i==j)
345  {
346  _srb_current_pose_in_rrbf_matrix(i,j) = 1;
347  }else{
348  _srb_current_pose_in_rrbf_matrix(i,j) = 0;
349  }
350  }
351  }
352 
353  Eigen::Twistd _srb_current_pose_in_rrbf_no_rot;
354  TransformMatrix2Twist(_srb_current_pose_in_rrbf_matrix, _srb_current_pose_in_rrbf_no_rot);
355 
356  Eigen::Twistd _current_delta_pose_in_rrbf_no_rot = (_srb_current_pose_in_rrbf_no_rot.exp(1e-12)*_srb_initial_pose_in_rrbf.exp(1e-12).inverse()).log(1e-12);
357 
358  ColumnVector rb2_measured_delta_relative_pose_cv(MEAS_DIM);
359  rb2_measured_delta_relative_pose_cv = 0.;
360  rb2_measured_delta_relative_pose_cv(1) = _current_delta_pose_in_rrbf_no_rot.vx();
361  rb2_measured_delta_relative_pose_cv(2) = _current_delta_pose_in_rrbf_no_rot.vy();
362  rb2_measured_delta_relative_pose_cv(3) = _current_delta_pose_in_rrbf_no_rot.vz();
363  rb2_measured_delta_relative_pose_cv(4) = _current_delta_pose_in_rrbf_no_rot.rx();
364  rb2_measured_delta_relative_pose_cv(5) = _current_delta_pose_in_rrbf_no_rot.ry();
365  rb2_measured_delta_relative_pose_cv(6) = _current_delta_pose_in_rrbf_no_rot.rz();
366 
367  // Update the uncertainty on the measurement
368  // NEW: The uncertainty on the measurement (the delta motion of the second rigid body wrt the reference rigid body) will be large if the measurement
369  // is small and small if the measurement is large
370  double meas_uncertainty_factor = 1.0 / (1.0 - exp(-this->_current_delta_pose_in_rrbf.norm()/this->_sigma_delta_meas_uncertainty_linear));
371 
372  // Truncate the factor
373  meas_uncertainty_factor = std::min(meas_uncertainty_factor, 1e6);
374 
375  SymmetricMatrix current_delta_pose_cov_in_rrbf(6);
376  for (unsigned int i = 0; i < 6; i++)
377  {
378  for (unsigned int j = 0; j < 6; j++)
379  {
380  current_delta_pose_cov_in_rrbf(i + 1, j + 1) = _current_delta_pose_cov_in_rrbf(i, j);
381  }
382  }
383  this->_meas_PDF->AdditiveNoiseSigmaSet(current_delta_pose_cov_in_rrbf * meas_uncertainty_factor);
384 
385  this->_ekf->Update(this->_meas_MODEL, rb2_measured_delta_relative_pose_cv);
386 
387  ColumnVector updated_state = this->_ekf->PostGet()->ExpectedValueGet();
388 
389  // The joint is defined in the space of the relative motion
390  this->_joint_orientation(0) = sin(updated_state(2)) * cos(updated_state(1));
391  this->_joint_orientation(1) = sin(updated_state(2)) * sin(updated_state(1));
392  this->_joint_orientation(2) = cos(updated_state(2));
393 
394  SymmetricMatrix updated_uncertainty = this->_ekf->PostGet()->CovarianceGet();
395 
396  this->_joint_state = updated_state(3);
397  this->_uncertainty_joint_state = updated_uncertainty(3,3);
398  this->_joint_velocity = updated_state(4);
399  this->_uncertainty_joint_velocity = updated_uncertainty(4,4);
400 
401  this->_joint_orientation_phi = updated_state(1);
402  this->_joint_orientation_theta = updated_state(2);
403  this->_uncertainty_joint_orientation_phitheta(0,0) = updated_uncertainty(1, 1);
404  this->_uncertainty_joint_orientation_phitheta(0,1) = updated_uncertainty(1, 2);
405  this->_uncertainty_joint_orientation_phitheta(1,0) = updated_uncertainty(1, 2);
406  this->_uncertainty_joint_orientation_phitheta(1,1) = updated_uncertainty(2, 2);
407 }
408 
410 {
411  double accumulated_error = 0.;
412 
413  double p_one_meas_given_model_params = 0;
414  double p_all_meas_given_model_params = 0;
415 
416  double sigma_translation = 0.05;
417  double sigma_rotation = 0.2;
418 
419  ColumnVector state_updated_state = this->_ekf->PostGet()->ExpectedValueGet();
420  double phi = state_updated_state(1);
421  double theta = state_updated_state(2);
422 
423  this->_joint_states_all.push_back(state_updated_state(3));
424 
425  // This vector is in the ref RB with the initial relative transformation to the second RB
426  Eigen::Vector3d prism_joint_translation_unitary = Eigen::Vector3d(cos(phi) * sin(theta), sin(phi) * sin(theta), cos(theta));
427  prism_joint_translation_unitary.normalize();
428 
429  double frame_counter = 0.;
430  size_t trajectory_length = this->_delta_poses_in_rrbf.size();
431  size_t amount_samples = std::min(trajectory_length, (size_t)this->_likelihood_sample_num);
432  double delta_idx_samples = (double)std::max(1., (double)trajectory_length/(double)this->_likelihood_sample_num);
433  size_t current_idx = 0;
434 
435  double max_norm_of_deltas = 0;
436 
437 
438  // Estimation of the quality of the parameters of the prismatic joint
439  // If the joint is prismatic and the parameters are accurate, the joint axis orientation should not change over time
440  // That means that the current orientation, multiplied by the amount of prismatic displacement at each time step, should provide the delta in the relative
441  // pose between ref and second rb at each time step
442  // We test amount_samples of the relative trajectory
443  for (size_t sample_idx = 0; sample_idx < amount_samples; sample_idx++)
444  {
445  current_idx = boost::math::round(sample_idx*delta_idx_samples);
446  Eigen::Displacementd rb2_last_delta_relative_displ = this->_delta_poses_in_rrbf.at(current_idx).exp(1e-12);
447 
448  max_norm_of_deltas = std::max(this->_delta_poses_in_rrbf.at(current_idx).norm(), max_norm_of_deltas);
449 
450  Eigen::Vector3d rb2_last_delta_relative_translation = rb2_last_delta_relative_displ.getTranslation();
451  Eigen::Quaterniond rb2_last_delta_relative_rotation = Eigen::Quaterniond(rb2_last_delta_relative_displ.qw(),
452  rb2_last_delta_relative_displ.qx(),
453  rb2_last_delta_relative_displ.qy(),
454  rb2_last_delta_relative_displ.qz());
455 
456  Eigen::Vector3d prism_joint_translation = this->_joint_states_all.at(current_idx) * prism_joint_translation_unitary;
457  Eigen::Displacementd rb2_last_delta_relative_displ_prism_hyp = Eigen::Twistd(0.,
458  0.,
459  0.,
460  prism_joint_translation.x(),
461  prism_joint_translation.y(),
462  prism_joint_translation.z()).exp(1e-12);
463  Eigen::Vector3d rb2_last_delta_relative_translation_prism_hyp = rb2_last_delta_relative_displ_prism_hyp.getTranslation();
464  Eigen::Quaterniond rb2_last_delta_relative_rotation_prism_hyp = Eigen::Quaterniond(rb2_last_delta_relative_displ_prism_hyp.qw(),
465  rb2_last_delta_relative_displ_prism_hyp.qx(),
466  rb2_last_delta_relative_displ_prism_hyp.qy(),
467  rb2_last_delta_relative_displ_prism_hyp.qz());
468 
469  // Distance proposed by park and okamura in "Kinematic calibration using the product of exponentials formula"
470  double translation_error = (rb2_last_delta_relative_translation - rb2_last_delta_relative_translation_prism_hyp).norm();
471  // Actually both rotations should be zero because a prismatic joint constraints the rotation
472  Eigen::Quaterniond rotation_error = rb2_last_delta_relative_rotation.inverse() * rb2_last_delta_relative_rotation_prism_hyp;
473  double rotation_error_angle = Eigen::Displacementd(0., 0., 0., rotation_error.w(),rotation_error.x(), rotation_error.y(),rotation_error.z()).log(1e-12).norm();
474 
475 
476  accumulated_error += translation_error + fabs(rotation_error_angle);
477 
478  p_one_meas_given_model_params = (1.0/(sigma_translation*sqrt(2.0*M_PI)))*exp((-1.0/2.0)*pow(translation_error/sigma_translation, 2)) *
479  (1.0/(sigma_rotation*sqrt(2.0*M_PI)))*exp((-1.0/2.0)*pow(rotation_error_angle/sigma_rotation, 2));
480 
481  p_all_meas_given_model_params += (p_one_meas_given_model_params/(double)amount_samples);
482 
483  frame_counter++;
484  }
485 
486  if(frame_counter != 0)
487  {
488  this->_measurements_likelihood = p_all_meas_given_model_params;
489  }else{
490  this->_measurements_likelihood = 1e-5;
491  }
492 }
493 
495 {
497 }
498 
500 {
501  Eigen::Twistd delta_rrb_in_sf = this->_rrb_current_vel_in_sf*(this->_loop_period_ns/1e9);
502  Eigen::Twistd rrb_next_pose_in_sf = (delta_rrb_in_sf.exp(1e-12)*this->_rrb_current_pose_in_sf.exp(1e-12)).log(1e-12);
503 
504  //Eigen::Twistd rrb_next_pose_in_sf = this->_rrb_current_pose_in_sf + this->_rrb_current_vel_in_sf;
505  Eigen::Displacementd T_sf_rrbf_next = rrb_next_pose_in_sf.exp(1e-12);
506  Eigen::Displacementd T_rrbf_srbf_next = this->_srb_predicted_pose_in_rrbf.exp(1e-12);
507 
508  Eigen::Displacementd T_sf_srbf_next = T_rrbf_srbf_next*T_sf_rrbf_next;
509 
510  Eigen::Twistd srb_next_pose_in_sf = T_sf_srbf_next.log(1e-12);
511 
512  geometry_msgs::TwistWithCovariance hypothesis;
513 
514  hypothesis.twist.linear.x = srb_next_pose_in_sf.vx();
515  hypothesis.twist.linear.y = srb_next_pose_in_sf.vy();
516  hypothesis.twist.linear.z = srb_next_pose_in_sf.vz();
517  hypothesis.twist.angular.x = srb_next_pose_in_sf.rx();
518  hypothesis.twist.angular.y = srb_next_pose_in_sf.ry();
519  hypothesis.twist.angular.z = srb_next_pose_in_sf.rz();
520 
521  // This call gives me the covariance of the predicted measurement: the relative pose between RBs
522  ColumnVector empty;
523  ColumnVector state_updated_state = this->_ekf->PostGet()->ExpectedValueGet();
524  SymmetricMatrix measurement_cov = this->_meas_MODEL->CovarianceGet(empty, state_updated_state);
525  Eigen::Matrix<double,6,6> measurement_cov_eigen;
526  for(int i=0; i<6; i++)
527  {
528  for(int j=0; j<6; j++)
529  {
530  measurement_cov_eigen(i,j) = measurement_cov(i+1,j+1);
531  }
532  }
533  // I need the covariance of the absolute pose of the second RB, so I add the cov of the relative pose to the
534  // cov of the reference pose. I need to "move" the second covariance to align it to the reference frame (see Barfoot)
535  Eigen::Matrix<double,6,6> adjoint_eigen = this->_rrb_current_pose_in_sf.exp(1e-12).adjoint();
536  Eigen::Matrix<double,6,6> new_pose_covariance = this->_rrb_pose_cov_in_sf + adjoint_eigen*measurement_cov_eigen*adjoint_eigen.transpose();
537  for (unsigned int i = 0; i < 6; i++)
538  {
539  for (unsigned int j = 0; j < 6; j++)
540  {
541  hypothesis.covariance[6 * i + j] = new_pose_covariance(i, j);
542  }
543  }
544 
545 #ifdef PUBLISH_PREDICTED_POSE_AS_PWC
546  // This is used to visualize the predictions based on the joint hypothesis
547  geometry_msgs::PoseWithCovarianceStamped pose_with_cov_stamped;
548  pose_with_cov_stamped.header.stamp = ros::Time::now();
549  pose_with_cov_stamped.header.frame_id = "camera_rgb_optical_frame";
550 
551  Eigen::Displacementd displ_from_twist = srb_next_pose_in_sf.exp(1e-12);
552  pose_with_cov_stamped.pose.pose.position.x = displ_from_twist.x();
553  pose_with_cov_stamped.pose.pose.position.y = displ_from_twist.y();
554  pose_with_cov_stamped.pose.pose.position.z = displ_from_twist.z();
555  pose_with_cov_stamped.pose.pose.orientation.x = displ_from_twist.qx();
556  pose_with_cov_stamped.pose.pose.orientation.y = displ_from_twist.qy();
557  pose_with_cov_stamped.pose.pose.orientation.z = displ_from_twist.qz();
558  pose_with_cov_stamped.pose.pose.orientation.w = displ_from_twist.qw();
559 
560  for (unsigned int i = 0; i < 6; i++)
561  for (unsigned int j = 0; j < 6; j++)
562  pose_with_cov_stamped.pose.covariance[6 * i + j] = new_pose_covariance(i, j);
563  _predicted_next_pose_publisher.publish(pose_with_cov_stamped);
564 #endif
565 
566  return hypothesis;
567 }
568 
569 std::vector<visualization_msgs::Marker> PrismaticJointFilter::getJointMarkersInRRBFrame() const
570 {
571  // The class variable _prism_joint_orientation (also _uncertainty_o_phi and _uncertainty_o_theta) are defined in the frame of the
572  // ref RB with the initial relative transformation to the second RB
573  // We want the variables to be in the ref RB frame, without the initial relative transformation to the second RB
574  Eigen::Vector3d prism_joint_ori_in_ref_rb = this->_joint_orientation;
575 
576  std::vector<visualization_msgs::Marker> prismatic_markers;
577  // AXIS MARKER 1 -> The axis ///////////////////////////////////////////////////////////////////////////////////////////////////////////
578  visualization_msgs::Marker axis_orientation_marker;
579  axis_orientation_marker.ns = "kinematic_structure";
580  axis_orientation_marker.action = visualization_msgs::Marker::ADD;
581  axis_orientation_marker.type = visualization_msgs::Marker::ARROW;
582  axis_orientation_marker.id = 3 * this->_joint_id;
583  axis_orientation_marker.scale.x = JOINT_AXIS_AND_VARIABLE_MARKER_RADIUS;
584  axis_orientation_marker.scale.y = 0.f;
585  axis_orientation_marker.scale.z = 0.f;
586  axis_orientation_marker.color.r = 0.f;
587  axis_orientation_marker.color.g = 1.f;
588  axis_orientation_marker.color.b = 0.f;
589  axis_orientation_marker.color.a = 1.f;
590  // Estimate position from supporting features:
591  // Eigen::Displacementd current_ref_pose_displ = this->_rrb_current_pose_in_sf.exp(1e-12);
592  // Eigen::Affine3d current_ref_pose;
593  // current_ref_pose.matrix() = current_ref_pose_displ.toHomogeneousMatrix();
594  // =current_ref_pose.inverse() * this->_srb_centroid_in_sf;
595  Eigen::Vector3d second_centroid_relative_to_ref_body = this->getJointPositionInRRBFrame();
596  Eigen::Vector3d position1 = second_centroid_relative_to_ref_body - this->_joint_state * prism_joint_ori_in_ref_rb;
597  geometry_msgs::Point pt1;
598  pt1.x = position1.x();
599  pt1.y = position1.y();
600  pt1.z = position1.z();
601  axis_orientation_marker.points.push_back(pt1);
602  Eigen::Vector3d position2 = second_centroid_relative_to_ref_body + this->_joint_state * prism_joint_ori_in_ref_rb;
603  geometry_msgs::Point pt2;
604  pt2.x = position2.x();
605  pt2.y = position2.y();
606  pt2.z = position2.z();
607  axis_orientation_marker.points.push_back(pt2);
608 
609  prismatic_markers.push_back(axis_orientation_marker);
610 
611  // AXIS MARKER 2 -> Proportional to joint state ///////////////////////////////////////////////////////////////////////////////////////////////////////////
612  axis_orientation_marker.points.clear();
613  axis_orientation_marker.id = 3 * this->_joint_id + 1;
614  axis_orientation_marker.scale.x = JOINT_AXIS_MARKER_RADIUS;
615  // Estimate position from supporting features:
616  Eigen::Vector3d position12 = second_centroid_relative_to_ref_body - 100 * prism_joint_ori_in_ref_rb;
617  geometry_msgs::Point pt12;
618  pt12.x = position12.x();
619  pt12.y = position12.y();
620  pt12.z = position12.z();
621  axis_orientation_marker.points.push_back(pt12);
622  Eigen::Vector3d position22 = second_centroid_relative_to_ref_body + 100 * prism_joint_ori_in_ref_rb;
623  geometry_msgs::Point pt22;
624  pt22.x = position22.x();
625  pt22.y = position22.y();
626  pt22.z = position22.z();
627  axis_orientation_marker.points.push_back(pt22);
628 
629  prismatic_markers.push_back(axis_orientation_marker);
630 
631  // AXIS MARKER 3 -> Text with the joint state ///////////////////////////////////////////////////////////////////////////////////////////////////////////
632  axis_orientation_marker.points.clear();
633  axis_orientation_marker.id = 3 * this->_joint_id + 2;
634  axis_orientation_marker.type = visualization_msgs::Marker::TEXT_VIEW_FACING;
635  axis_orientation_marker.scale.z = JOINT_VALUE_TEXT_SIZE;
636  std::ostringstream oss_joint_value;
637  oss_joint_value << std::fixed<< std::setprecision(1) << 100*this->_joint_state;
638  axis_orientation_marker.text = oss_joint_value.str() + std::string(" cm");
639  axis_orientation_marker.pose.position.x = second_centroid_relative_to_ref_body.x();
640  axis_orientation_marker.pose.position.y = second_centroid_relative_to_ref_body.y();
641  axis_orientation_marker.pose.position.z = second_centroid_relative_to_ref_body.z();
642  axis_orientation_marker.pose.orientation.x = 0;
643  axis_orientation_marker.pose.orientation.y = 0;
644  axis_orientation_marker.pose.orientation.z = 0;
645  axis_orientation_marker.pose.orientation.w = 1;
646 
647  prismatic_markers.push_back(axis_orientation_marker);
648 
649  // UNCERTAINTY MARKERS ///////////////////////////////////////////////////////////////////////////////////////////////////////
650 
651  // This first marker is just to match the number of markers of the revolute joint, but prismatic joint has no position
652  visualization_msgs::Marker axis_position_uncertainty_marker;
653  axis_position_uncertainty_marker.pose.position.x = second_centroid_relative_to_ref_body.x();
654  axis_position_uncertainty_marker.pose.position.y = second_centroid_relative_to_ref_body.y();
655  axis_position_uncertainty_marker.pose.position.z = second_centroid_relative_to_ref_body.z();
656  axis_position_uncertainty_marker.ns = "kinematic_structure_uncertainty";
657  axis_position_uncertainty_marker.type = visualization_msgs::Marker::SPHERE;
658  axis_position_uncertainty_marker.action = visualization_msgs::Marker::DELETE;
659  axis_position_uncertainty_marker.id = 3 * this->_joint_id ;
660 
661  prismatic_markers.push_back(axis_position_uncertainty_marker);
662 
663  visualization_msgs::Marker prism_axis_unc_cone1;
664  prism_axis_unc_cone1.type = visualization_msgs::Marker::MESH_RESOURCE;
665  prism_axis_unc_cone1.action = visualization_msgs::Marker::ADD;
666  prism_axis_unc_cone1.mesh_resource = "package://joint_tracker/meshes/cone.stl";
667  prism_axis_unc_cone1.pose.position.x = second_centroid_relative_to_ref_body.x();
668  prism_axis_unc_cone1.pose.position.y = second_centroid_relative_to_ref_body.y();
669  prism_axis_unc_cone1.pose.position.z = second_centroid_relative_to_ref_body.z();
670 
671  // NOTE:
672  // Estimation of the uncertainty cones -----------------------------------------------
673  // We estimate the orientation of the prismatic axis in spherical coordinates (r=1 always)
674  // We estimate phi: angle from the x axis to the projection of the prismatic joint axis to the xy plane
675  // We estimate theta: angle from the z axis to the prismatic joint axis
676  // [TODO: phi and theta are in the reference rigid body. Do we need to transform it (adding uncertainty) to the reference frame?]
677  // The covariance of phi and theta (a 2x2 matrix) gives us the uncertainty of the orientation of the joint
678  // If we look from the joint axis, we would see an ellipse given by this covariance matrix [http://www.visiondummy.com/2014/04/draw-error-ellipse-representing-covariance-matrix/]
679  // But in RVIZ we can only set the scale of our cone mesh in x and y, not in a different axis
680  // The first thing is then to estimate the direction of the major and minor axis of the ellipse and their size
681  Eigen::SelfAdjointEigenSolver<Eigen::Matrix2d> eigensolver(this->_uncertainty_joint_orientation_phitheta);
682 
683  // The sizes of the major and minor axes of the ellipse are given by the eigenvalues and the chi square distribution P(x<critical_value) = confidence_value
684  // For 50% of confidence on the cones shown
685  double confidence_value = 0.5;
686  boost::math::chi_squared chi_sq_dist(2);
687  double critical_value = boost::math::quantile(chi_sq_dist, confidence_value);
688  double major_axis_length = 2*eigensolver.eigenvalues()[1]*std::sqrt(critical_value);
689  double minor_axis_length = 2*eigensolver.eigenvalues()[0]*std::sqrt(critical_value);
690 
691  // If z is pointing in the direction of the joint, the angle between the x axis and the largest axis of the ellipse is arctg(v1_y/v1_x) where v1 is the eigenvector of
692  // largest eigenvalue (the last column in the matrix returned by eigenvectors() in eigen library):
693  double alpha = atan2(eigensolver.eigenvectors().col(1)[1],eigensolver.eigenvectors().col(1)[0]);
694  // We create a rotation around the z axis to align the ellipse to have the major axis aligned to the x-axis (we UNDO the rotation of the ellipse):
695  Eigen::AngleAxisd init_rot(-alpha, Eigen::Vector3d::UnitZ());
696 
697  // Now I need to rotate the mesh so that:
698  // 1) The z axis of the mesh points in the direction of the joint
699  // 2) The x axis of the mesh is contained in the x-y plane of the reference frame
700 
701  // To get the z axis of the mesh to point in the direction of the joint
702  Eigen::Quaterniond ori_quat;
703  ori_quat.setFromTwoVectors(Eigen::Vector3d::UnitZ(), prism_joint_ori_in_ref_rb);
704 
705  // To get the x axis of the mesh to be contained in the x-y plane of the reference frame
706  // First, find a vector that is orthogonal to the joint orientation and also to the z_axis (this latter implies to be contained in the xy plane)
707  Eigen::Vector3d coplanar_xy_orthogonal_to_joint_ori = prism_joint_ori_in_ref_rb.cross(Eigen::Vector3d::UnitZ());
708  // Normalize it -> Gives me the desired x axis after the rotation
709  coplanar_xy_orthogonal_to_joint_ori.normalize();
710 
711  // Then find the corresponding y axis after the rotation as the cross product of the z axis after rotation (orientation of the joint)
712  // and the x axis after rotation
713  Eigen::Vector3d y_pos = prism_joint_ori_in_ref_rb.cross(coplanar_xy_orthogonal_to_joint_ori);
714 
715  // Create a matrix with the values of the vectors after rotation
716  Eigen::Matrix3d rotation_pos;
717  rotation_pos << coplanar_xy_orthogonal_to_joint_ori.x(),y_pos.x(),prism_joint_ori_in_ref_rb.x(),
718  coplanar_xy_orthogonal_to_joint_ori.y(),y_pos.y(),prism_joint_ori_in_ref_rb.y(),
719  coplanar_xy_orthogonal_to_joint_ori.z(),y_pos.z(),prism_joint_ori_in_ref_rb.z();
720 
721  // Create a quaternion with the matrix
722  Eigen::Quaterniond ori_quat_final(rotation_pos);
723 
724  Eigen::Quaterniond ori_quat_final_ellipse(ori_quat_final.toRotationMatrix()*init_rot.toRotationMatrix());
725 
726  prism_axis_unc_cone1.pose.orientation.x = ori_quat_final_ellipse.x();
727  prism_axis_unc_cone1.pose.orientation.y = ori_quat_final_ellipse.y();
728  prism_axis_unc_cone1.pose.orientation.z = ori_quat_final_ellipse.z();
729  prism_axis_unc_cone1.pose.orientation.w = ori_quat_final_ellipse.w();
730  prism_axis_unc_cone1.ns = "kinematic_structure_uncertainty";
731  prism_axis_unc_cone1.id = 3 * this->_joint_id + 1;
732  prism_axis_unc_cone1.color.a = 0.4;
733  prism_axis_unc_cone1.color.r = 0.0;
734  prism_axis_unc_cone1.color.g = 1.0;
735  prism_axis_unc_cone1.color.b = 0.0;
736 
737  // If the uncertainty is pi/6 (30 degrees) the scale in this direction should be 1
738  // If the uncertainty is pi/12 (15 degrees) the scale in this direction should be 0.5
739  // If the uncertainty is close to 0 the scale in this direction should be 0
740  // If the uncertainty is close to pi the scale in this direction should be inf
741 
742  prism_axis_unc_cone1.scale.x = major_axis_length / (M_PI / 6.0);
743  prism_axis_unc_cone1.scale.y = minor_axis_length / (M_PI / 6.0);
744  prism_axis_unc_cone1.scale.z = 1.;
745 
746  prismatic_markers.push_back(prism_axis_unc_cone1);
747 
748  // We repeat the process for the cone in the other direction
749  // To get the z axis of the mesh to point in the direction of the joint (negative)
750  Eigen::Vector3d prism_joint_ori_in_ref_rb_neg = -prism_joint_ori_in_ref_rb;
751  Eigen::Quaterniond ori_quat_neg;
752  ori_quat_neg.setFromTwoVectors(Eigen::Vector3d::UnitZ(), prism_joint_ori_in_ref_rb_neg);
753 
754  // To get the x axis of the mesh to be contained in the x-y plane of the reference frame
755  // First, find a vector that is orthogonal to the joint orientation and also to the z_axis (this latter implies to be contained in the xy plane)
756  Eigen::Vector3d coplanar_xy_orthogonal_to_joint_ori_neg = prism_joint_ori_in_ref_rb_neg.cross(Eigen::Vector3d::UnitZ());
757  // Normalize it -> Gives me the desired x axis after the rotation
758  coplanar_xy_orthogonal_to_joint_ori_neg.normalize();
759 
760  // Then find the corresponding y axis after the rotation as the cross product of the z axis after rotation (orientation of the joint)
761  // and the x axis after rotation
762  Eigen::Vector3d y_neg = prism_joint_ori_in_ref_rb_neg.cross(coplanar_xy_orthogonal_to_joint_ori_neg);
763 
764  // Create a matrix with the values of the vectors after rotation
765  Eigen::Matrix3d rotation_neg;
766  rotation_neg << coplanar_xy_orthogonal_to_joint_ori_neg.x(),y_neg.x(),prism_joint_ori_in_ref_rb_neg.x(),
767  coplanar_xy_orthogonal_to_joint_ori_neg.y(),y_neg.y(),prism_joint_ori_in_ref_rb_neg.y(),
768  coplanar_xy_orthogonal_to_joint_ori_neg.z(),y_neg.z(),prism_joint_ori_in_ref_rb_neg.z();
769 
770  // Create a quaternion with the matrix
771  Eigen::Quaterniond ori_quat_neg_final(rotation_neg);
772 
773  // We undo the rotation of the ellipse (but negative!):
774  Eigen::AngleAxisd init_rot_neg(alpha, Eigen::Vector3d::UnitZ());
775  Eigen::Quaterniond ori_quat_neg_final_ellipse(ori_quat_neg_final.toRotationMatrix()*init_rot_neg.toRotationMatrix());
776 
777  prism_axis_unc_cone1.pose.orientation.x = ori_quat_neg_final_ellipse.x();
778  prism_axis_unc_cone1.pose.orientation.y = ori_quat_neg_final_ellipse.y();
779  prism_axis_unc_cone1.pose.orientation.z = ori_quat_neg_final_ellipse.z();
780  prism_axis_unc_cone1.pose.orientation.w = ori_quat_neg_final_ellipse.w();
781  prism_axis_unc_cone1.scale.x = major_axis_length / (M_PI / 6.0);
782  prism_axis_unc_cone1.scale.y = minor_axis_length / (M_PI / 6.0);
783  prism_axis_unc_cone1.scale.z = 1.;
784  prism_axis_unc_cone1.id =3 * this->_joint_id + 2;
785 
786  prismatic_markers.push_back(prism_axis_unc_cone1);
787 
788  return prismatic_markers;
789 }
790 
792 {
793  return PRISMATIC_JOINT;
794 }
795 
797 {
798  return std::string("PrismaticJointFilter");
799 }
Eigen::Twistd _rrb_current_pose_in_sf
Definition: JointFilter.h:417
#define ROS_DEBUG_STREAM_NAMED(name, args)
virtual void estimateMeasurementHistoryLikelihood()
Eigen::Twistd _predicted_delta_pose_in_rrbf
Definition: JointFilter.h:439
EIGEN_MAKE_ALIGNED_OPERATOR_NEW PrismaticJointFilter()
INLINE Rall1d< T, V, S > log(const Rall1d< T, V, S > &arg)
Eigen::Matrix< double, 6, 6 > _current_delta_pose_cov_in_rrbf
Definition: JointFilter.h:437
virtual void initialize()
JointFilterType
Definition: JointFilter.h:71
double _joint_orientation_phi
Definition: JointFilter.h:359
double _uncertainty_joint_velocity
Definition: JointFilter.h:377
Eigen::Twistd _srb_current_pose_in_rrbf
Definition: JointFilter.h:430
void TransformMatrix2Twist(const Eigen::Matrix4d &transformation_matrix, Eigen::Twistd &twist)
Eigen::Twistd _srb_initial_pose_in_rrbf
Definition: JointFilter.h:428
virtual void setCovarianceDeltaMeasurementLinear(double delta_meas)
virtual std::vector< visualization_msgs::Marker > getJointMarkersInRRBFrame() const
#define ROS_INFO_STREAM_NAMED(name, args)
std::vector< double > _joint_states_all
Definition: JointFilter.h:372
Eigen::Matrix< double, 6, 6 > _rrb_pose_cov_in_sf
Definition: JointFilter.h:419
Eigen::Twistd _rrb_current_vel_in_sf
Definition: JointFilter.h:420
double _model_prior_probability
Definition: JointFilter.h:348
Eigen::Twistd _srb_predicted_pose_in_rrbf
Definition: JointFilter.h:434
Eigen::Matrix2d _uncertainty_joint_orientation_phitheta
Definition: JointFilter.h:364
virtual geometry_msgs::TwistWithCovariance getPredictedSRBPoseWithCovInSensorFrame()
We use the kinematic structure to predict the next pose-twist of the second rigid body of the joint (...
virtual void estimateUnnormalizedModelProbability()
double _uncertainty_joint_state
Definition: JointFilter.h:369
virtual geometry_msgs::TwistWithCovariance getPredictedSRBVelocityWithCovInSensorFrame()
Generate a prediction about the velocity of the second rigid body (SRB) and its covariance using the ...
void Twist2TransformMatrix(const Eigen::Twistd &transformation_twist, Eigen::Matrix4d &matrix)
#define JOINT_VALUE_TEXT_SIZE
Definition: JointFilter.h:62
Eigen::Vector3d _joint_orientation
Definition: JointFilter.h:362
virtual Eigen::Vector3d getJointPositionInRRBFrame() const
BFL::NonLinearPrismaticMeasurementPdf * _meas_PDF
double _measurements_likelihood
Definition: JointFilter.h:346
double _unnormalized_model_probability
Definition: JointFilter.h:351
#define PRISM_STATE_DIM
virtual void predictState(double time_interval_ns)
First step when updating the filter. The next state is predicted from current state and system model...
Eigen::Vector3d _joint_position
Definition: JointFilter.h:354
BFL::LinearAnalyticConditionalGaussian * _sys_PDF
BFL::AnalyticMeasurementModelGaussianUncertainty * _meas_MODEL
INLINE Rall1d< T, V, S > sqrt(const Rall1d< T, V, S > &arg)
BFL::ExtendedKalmanFilter * _ekf
double _joint_orientation_theta
Definition: JointFilter.h:360
virtual std::string getJointFilterTypeStr() const
#define JOINT_AXIS_AND_VARIABLE_MARKER_RADIUS
Definition: JointFilter.h:61
virtual JointFilterType getJointFilterType() const
INLINE Rall1d< T, V, S > exp(const Rall1d< T, V, S > &arg)
Eigen::Twistd _current_delta_pose_in_rrbf
Definition: JointFilter.h:436
INLINE Rall1d< T, V, S > pow(const Rall1d< T, V, S > &arg, double m)
INLINE Rall1d< T, V, S > acos(const Rall1d< T, V, S > &x)
BFL::LinearAnalyticSystemModelGaussianUncertainty * _sys_MODEL
JointCombinedFilterId _joint_id
Definition: JointFilter.h:332
double _sigma_sys_noise_theta
Definition: JointFilter.h:391
#define JOINT_AXIS_MARKER_RADIUS
Definition: JointFilter.h:60
double _sigma_sys_noise_jvd
Definition: JointFilter.h:396
INLINE Rall1d< T, V, S > atan2(const Rall1d< T, V, S > &y, const Rall1d< T, V, S > &x)
std::vector< Eigen::Twistd > _delta_poses_in_rrbf
Definition: JointFilter.h:440
static Time now()
double _sigma_sys_noise_jv
Definition: JointFilter.h:395
INLINE Rall1d< T, V, S > cos(const Rall1d< T, V, S > &arg)
double _joint_velocity
Definition: JointFilter.h:375
Eigen::Vector3d _srb_centroid_in_sf
Definition: JointFilter.h:386
double _sigma_sys_noise_phi
Definition: JointFilter.h:390
virtual geometry_msgs::TwistWithCovariance getPredictedSRBDeltaPoseWithCovInSensorFrame()
Generate a prediction about the change in pose of the second rigid body (SRB) and its covariance usin...
double _loop_period_ns
Definition: JointFilter.h:444
INLINE Rall1d< T, V, S > sin(const Rall1d< T, V, S > &arg)
double _sigma_meas_noise
Definition: JointFilter.h:397
#define MEAS_DIM


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