Biorbd
KalmanReconsMarkers.cpp
1 #define BIORBD_API_EXPORTS
2 #include "RigidBody/KalmanReconsMarkers.h"
3 
4 #include <rbdl/Model.h>
5 #include <rbdl/Kinematics.h>
6 #include "BiorbdModel.h"
7 #include "Utils/Error.h"
8 #include "Utils/Matrix.h"
9 #include "RigidBody/GeneralizedCoordinates.h"
10 #include "RigidBody/GeneralizedVelocity.h"
11 #include "RigidBody/GeneralizedAcceleration.h"
12 #include "RigidBody/NodeSegment.h"
13 
15  biorbd::rigidbody::KalmanRecons(),
16  m_PpInitial(std::make_shared<biorbd::utils::Matrix>()),
17  m_firstIteration(std::make_shared<bool>(true))
18 {
19 
20 }
21 
23  biorbd::Model &model,
25  biorbd::rigidbody::KalmanRecons(model, model.nbTechnicalMarkers()*3, params),
26  m_PpInitial(std::make_shared<biorbd::utils::Matrix>()),
27  m_firstIteration(std::make_shared<bool>(true))
28 {
29 
30  // Initialize the filter
31  initialize();
32 
33 }
34 
36 {
38  copy.DeepCopy(*this);
39  return copy;
40 }
41 
43 {
45  *m_PpInitial = *other.m_PpInitial;
46  *m_firstIteration = *other.m_firstIteration;
47 }
48 
51 
52  // Keep in mind the initial m_Pp
53  m_PpInitial = m_Pp;
54 }
55 
57  biorbd::utils::Matrix &InvTp,
58  utils::Vector &measure,
59  const std::vector<unsigned int> &occlusion)
60 {
61  for (unsigned int i = 0; i < occlusion.size(); ++i)
62  for (unsigned int j=occlusion[i] * 3; j< occlusion[i] * 3+3; ++j){
63  InvTp(j,j) = 0; // Artefact due to the fact that m_R has a value at (j:j+2,j:j+2)
64  measure[j] = 0;
65  }
66 }
67 
69 {
70  return *m_firstIteration;
71 }
72 
74  biorbd::Model &model,
75  const biorbd::rigidbody::Markers &Tobs,
79  bool removeAxes){
80  // Separate the tobs in a big vector
81  biorbd::utils::Vector T(3*Tobs.nbMarkers());
82  for (unsigned int i=0; i<Tobs.nbMarkers(); ++i)
83  T.block(i*3, 0, 3, 1) = Tobs.marker(i);
84 
85  // Reconstruct the kinematics
86  reconstructFrame(model, T, Q, Qdot, Qddot, removeAxes);
87 }
88 
90  biorbd::Model &model,
91  const std::vector<biorbd::rigidbody::NodeSegment> &Tobs,
95  bool removeAxes){
96  // Separate the tobs in a big vector
97  biorbd::utils::Vector T(static_cast<unsigned int>(3*Tobs.size()));
98  for (unsigned int i=0; i<Tobs.size(); ++i)
99  T.block(i*3, 0, 3, 1) = Tobs[i];
100 
101  // Reconstruct the kinematics
102  reconstructFrame(model, T, Q, Qdot, Qddot, removeAxes);
103 }
104 
105 
107  biorbd::Model &model,
108  const utils::Vector &Tobs,
112  bool removeAxes){
113  // An iteration of the Kalman filter
114  if (*m_firstIteration){
115  *m_firstIteration = false;
116  biorbd::utils::Vector TobsTP(Tobs);
117  TobsTP.block(3*model.nbTechnicalMarkers(0), 0, 3*model.nbTechnicalMarkers()-3*model.nbTechnicalMarkers(0), 1) =
118  biorbd::utils::Vector::Zero(3*model.nbTechnicalMarkers()-3*model.nbTechnicalMarkers(0)); // Only keep the markers of the root
119  for (unsigned int j = 0; j < 2; ++j){ // Do the root and then the rest of the body
120  if (j != 0)
121  TobsTP = Tobs; // Re-take all the markers
122 
123  for (unsigned int i=0; i<50; ++i){
124  // The first time, call in a recursive manner to get a descent initial position
125  reconstructFrame(model, TobsTP, nullptr, nullptr, nullptr);
126 
127  // Reset Pp to initial (we are not interested in the velocity to get to the initial position)
128  m_Pp = m_PpInitial;
129  m_xp->block(*m_nbDof, 0, *m_nbDof*2, 1) = biorbd::utils::Vector::Zero(*m_nbDof*2); // Set velocity and acceleration to zero
130  }
131  }
132  }
133 
134  // Projected state
135  const biorbd::utils::Vector& xkm(*m_A * *m_xp);
136  const biorbd::rigidbody::GeneralizedCoordinates& Q_tp(xkm.topRows(*m_nbDof));
137  model.UpdateKinematicsCustom (&Q_tp, nullptr, nullptr);
138 
139  // Projected markers
140  const std::vector<biorbd::rigidbody::NodeSegment>& zest_tp(model.technicalMarkers(Q_tp, removeAxes, false));
141  // Jacobian
142  const std::vector<biorbd::utils::Matrix>& J_tp(model.technicalMarkersJacobian(Q_tp, removeAxes, false));
143  // Create only one matrix for zest and Jacobian
144  biorbd::utils::Matrix H(biorbd::utils::Matrix::Zero(*m_nMeasure, *m_nbDof*3)); // 3*nMarkers => X,Y,Z ; 3*nbDof => Q, Qdot, Qddot
145  biorbd::utils::Vector zest(biorbd::utils::Vector::Zero(*m_nMeasure));
146  std::vector<unsigned int> occlusionIdx;
147  for (unsigned int i=0; i<*m_nMeasure/3; ++i) // Divided by 3 because we are integrate once xyz
148 #ifdef BIORBD_USE_CASADI_MATH
149  // If there is a marker
150  if (!Tobs(i*3).is_zero() && !Tobs(i*3+1).is_zero() && !Tobs(i*3+2).is_zero()){
151 #else
152  if (Tobs(i*3)*Tobs(i*3) + Tobs(i*3+1)*Tobs(i*3+1) + Tobs(i*3+2)*Tobs(i*3+2) != 0.0){
153 #endif
154  H.block(i*3,0,3,*m_nbDof) = J_tp[i];
155  zest.block(i*3, 0, 3, 1) = zest_tp[i];
156  }
157  else
158  occlusionIdx.push_back(i);
159 
160  // Filter
161  iteration(Tobs, zest, H, occlusionIdx);
162 
163  getState(Q, Qdot, Qddot);
164 }
165 
167 {
168  biorbd::utils::Error::raise("Implémentation impossible");
169 }
biorbd::rigidbody::KalmanReconsMarkers::reconstructFrame
virtual void reconstructFrame()
This function cannot be used to reconstruct frames.
Definition: KalmanReconsMarkers.cpp:166
biorbd::rigidbody::KalmanReconsMarkers::KalmanReconsMarkers
KalmanReconsMarkers()
Initialize the Kalman filter and Kalman reconstruction for Markers data.
Definition: KalmanReconsMarkers.cpp:14
biorbd::utils::Vector
Wrapper of the Eigen VectorXd.
Definition: Vector.h:20
biorbd::rigidbody::KalmanReconsMarkers::initialize
virtual void initialize()
Initialization of the filter.
Definition: KalmanReconsMarkers.cpp:49
biorbd::rigidbody::KalmanReconsMarkers::manageOcclusionDuringIteration
virtual void manageOcclusionDuringIteration(biorbd::utils::Matrix &InvTp, biorbd::utils::Vector &measure, const std::vector< unsigned int > &occlusion)
Manage the occlusion during the iteration.
Definition: KalmanReconsMarkers.cpp:56
biorbd::rigidbody::KalmanParam
Parameters of the reconstruction.
Definition: KalmanRecons.h:25
biorbd::rigidbody::GeneralizedCoordinates
Class GeneralizedCoordinates.
Definition: GeneralizedCoordinates.h:15
biorbd::rigidbody::KalmanReconsMarkers::m_PpInitial
std::shared_ptr< biorbd::utils::Matrix > m_PpInitial
Initial covariance matrix.
Definition: KalmanReconsMarkers.h:127
biorbd::rigidbody::Markers
Holder for the marker set.
Definition: Markers.h:23
biorbd::rigidbody::Markers::technicalMarkersJacobian
std::vector< biorbd::utils::Matrix > technicalMarkersJacobian(const biorbd::rigidbody::GeneralizedCoordinates &Q, bool removeAxis=true, bool updateKin=true)
Return the jacobian of the technical markers.
Definition: Markers.cpp:316
biorbd::utils::Error::raise
static void raise(const biorbd::utils::String &message)
Throw an error message.
Definition: Error.cpp:4
biorbd::rigidbody::Markers::nbMarkers
unsigned int nbMarkers() const
Return the number of markers.
Definition: Markers.cpp:286
biorbd::rigidbody::KalmanReconsMarkers
Class Kinematic reconstruction algorithm using an Extended Kalman Filter using skin markers.
Definition: KalmanReconsMarkers.h:17
biorbd::Model
The actual musculoskeletal model that holds everything in biorbd.
Definition: BiorbdModel.h:78
biorbd::rigidbody::KalmanReconsMarkers::m_firstIteration
std::shared_ptr< bool > m_firstIteration
If first iteration was done.
Definition: KalmanReconsMarkers.h:128
biorbd::utils::Matrix
A wrapper for the Eigen::MatrixXd.
Definition: Matrix.h:21
biorbd::rigidbody::GeneralizedAcceleration
Class GeneralizedAcceleration.
Definition: GeneralizedAcceleration.h:15
biorbd::rigidbody::KalmanRecons::DeepCopy
void DeepCopy(const biorbd::rigidbody::KalmanRecons &other)
Deep copy of Kalman reconstruction.
Definition: KalmanRecons.cpp:46
biorbd::rigidbody::Markers::nbTechnicalMarkers
unsigned int nbTechnicalMarkers()
Return the number of technical markers.
Definition: Markers.cpp:413
biorbd::rigidbody::KalmanReconsMarkers::DeepCopy
biorbd::rigidbody::KalmanReconsMarkers DeepCopy() const
Deep copy of the Kalman reconstruction.
Definition: KalmanReconsMarkers.cpp:35
biorbd::rigidbody::KalmanRecons::initialize
virtual void initialize()
Initialization of the filter.
Definition: KalmanRecons.cpp:160
biorbd::rigidbody::Markers::marker
const biorbd::rigidbody::NodeSegment & marker(unsigned int idx) const
Return the marker of index idx.
Definition: Markers.cpp:60
biorbd::rigidbody::KalmanRecons
Class Kinematic reconstruction algorithm using an Extended Kalman Filter.
Definition: KalmanRecons.h:63
biorbd::rigidbody::KalmanReconsMarkers::first
bool first()
Return if the first iteration was done.
Definition: KalmanReconsMarkers.cpp:68
biorbd::rigidbody::Joints::UpdateKinematicsCustom
void UpdateKinematicsCustom(const biorbd::rigidbody::GeneralizedCoordinates *Q=nullptr, const biorbd::rigidbody::GeneralizedVelocity *Qdot=nullptr, const biorbd::rigidbody::GeneralizedAcceleration *Qddot=nullptr)
Update the kinematic variables such as body velocities and accelerations in the model to reflect the ...
Definition: Joints.cpp:1063
biorbd::rigidbody::GeneralizedVelocity
Class GeneralizedVelocity.
Definition: GeneralizedVelocity.h:15
biorbd::rigidbody::Markers::technicalMarkers
std::vector< biorbd::rigidbody::NodeSegment > technicalMarkers(const biorbd::rigidbody::GeneralizedCoordinates &Q, bool removeAxis=true, bool updateKin=true)
Return all the technical markers at a given Q in the global reference frame.
Definition: Markers.cpp:202