Biorbd
KalmanRecons.cpp
1 #define BIORBD_API_EXPORTS
2 #include "RigidBody/KalmanRecons.h"
3 
4 #include "BiorbdModel.h"
5 #include "Utils/Matrix.h"
6 #include "Utils/Vector.h"
7 #include "RigidBody/GeneralizedCoordinates.h"
8 #include "RigidBody/GeneralizedVelocity.h"
9 #include "RigidBody/GeneralizedAcceleration.h"
10 
12  m_params(std::make_shared<KalmanParam>()),
13  m_Te(std::make_shared<double>(1.0/(m_params->acquisitionFrequency()))),
14  m_nbDof(std::make_shared<unsigned int>()),
15  m_nMeasure(std::make_shared<unsigned int>()),
16  m_xp(std::make_shared<biorbd::utils::Vector>()),
17  m_A(std::make_shared<biorbd::utils::Matrix>()),
18  m_Q(std::make_shared<biorbd::utils::Matrix>()),
19  m_R(std::make_shared<biorbd::utils::Matrix>()),
20  m_Pp(std::make_shared<biorbd::utils::Matrix>())
21 {
22 
23 }
24 
26  unsigned int nbMeasure,
27  KalmanParam params) :
28  m_params(std::make_shared<KalmanParam>(params)),
29  m_Te(std::make_shared<double>(1.0/(m_params->acquisitionFrequency()))),
30  m_nbDof(std::make_shared<unsigned int>(model.dof_count)),
31  m_nMeasure(std::make_shared<unsigned int>(nbMeasure)),
32  m_xp(std::make_shared<biorbd::utils::Vector>()),
33  m_A(std::make_shared<biorbd::utils::Matrix>()),
34  m_Q(std::make_shared<biorbd::utils::Matrix>()),
35  m_R(std::make_shared<biorbd::utils::Matrix>()),
36  m_Pp(std::make_shared<biorbd::utils::Matrix>())
37 {
38 
39 }
40 
42 {
43 
44 }
45 
47 {
48  *m_params = *other.m_params;
49  *m_Te = *other.m_Te;
50  *m_nbDof = *other.m_nbDof;
51  *m_nMeasure = *other.m_nMeasure;
52  *m_xp = *other.m_xp;
53  *m_A = *other.m_A;
54  *m_Q = *other.m_Q;
55  *m_R = *other.m_R;
56  *m_Pp = *other.m_Pp;
57 }
58 
60  biorbd::utils::Vector measure,
61  const biorbd::utils::Vector &projectedMeasure,
62  const biorbd::utils::Matrix &Hessian,
63  const std::vector<unsigned int> &occlusion){
64  // Prediction
65  const biorbd::utils::Vector& xkm(*m_A * *m_xp);
66  const biorbd::utils::Matrix& Pkm(*m_A * *m_Pp * m_A->transpose() + *m_Q);
67 
68  // Correction
69  biorbd::utils::Matrix InvTp( (Hessian * Pkm * Hessian.transpose() + *m_R).inverse() );
70  manageOcclusionDuringIteration(InvTp, measure, occlusion);
71  const biorbd::utils::Matrix& K(Pkm*Hessian.transpose() * InvTp); // Gain
72 
73  *m_xp = xkm+K*(measure-projectedMeasure); // New estimated state
74  const RigidBodyDynamics::Math::MatrixNd& temp(biorbd::utils::Matrix::Identity(3* *m_nbDof, 3* *m_nbDof) - K*Hessian);
75  *m_Pp = temp * Pkm * temp.transpose() + K* *m_R*K.transpose();
76 
77 }
78 
80  biorbd::utils::Matrix &InvTp,
81  biorbd::utils::Vector &measure,
82  const std::vector<unsigned int> &occlusion){
83  for (unsigned int i = 0; i < occlusion.size(); ++i)
84  for (unsigned int j=occlusion[i]; j< occlusion[i]+1; ++j){
85  InvTp(j,j) = 0; // Artifact due to the fact that m_R has a value at (j:j+2,j:j+2)
86  measure(j) = 0;
87  }
88 }
89 
94 
95  if (Q != nullptr)
96  *Q = m_xp->block(0, 0, *m_nbDof, 1);
97 
98  if (Qdot != nullptr)
99  *Qdot = m_xp->block(*m_nbDof, 0, *m_nbDof, 1);
100 
101  if (Qddot != nullptr)
102  *Qddot = m_xp->block(2* *m_nbDof, 0, *m_nbDof, 1);
103 }
104 
105 
107  const unsigned int nQ,
108  unsigned int n,
109  double Te){
110  // m : number of degrees of freedom
111  // n : order of Taylor development
112  // Te : 1 / (acquisition frequency)
113 
114  n += 1;
115  biorbd::utils::Matrix A(biorbd::utils::Matrix::Identity(nQ*n, nQ*n));
116  double c = 1;
117  for (unsigned int i=2; i<n+1; ++i){
118 
119  unsigned int j=(i-1) * nQ;
120  c = c/(i-1);
121 
122 
123  for (unsigned int cmp=0; cmp<nQ*n-j; ++cmp)
124  A(0+cmp,j+cmp) += c* static_cast<double>(std::pow(Te,(static_cast<double>(i)-1.0)));
125  }
126 
127  return A;
128 }
129 
131  const unsigned int nbQ,
132  double Te){
133 
134  // Find the coefficients values
135  double c1 = 1.0/20.0 * pow(Te,5);
136  double c2 = 1.0/8.0 * pow(Te,4);
137  double c3 = 1.0/6.0 * pow(Te,3);
138  double c4 = 1.0/3.0 * pow(Te,3);
139  double c5 = 1.0/2.0 * pow(Te,2);
140  double c6 = Te;
141 
142  // Ouput matrix
143  biorbd::utils::Matrix Q(biorbd::utils::Matrix::Zero(3*nbQ,3*nbQ));
144  for (unsigned int j=0; j<nbQ; ++j){
145  Q( j, j) = c1;
146  Q( j, nbQ+j) = c2;
147  Q( j, 2*nbQ+j) = c3;
148  Q( nbQ+j, j) = c2;
149  Q( nbQ+j, nbQ+j) = c4;
150  Q( nbQ+j, 2*nbQ+j) = c5;
151  Q(2*nbQ+j, j) = c3;
152  Q(2*nbQ+j, nbQ+j) = c5;
153  Q(2*nbQ+j, 2*nbQ+j) = c6;
154  }
155 
156  return Q;
157 }
158 
159 // Methods during the initialization
161 
162  // Declaration of the evolution matrix
163  *m_A = evolutionMatrix(*m_nbDof, 2, *m_Te);
164 
165  // Process Noise Matrix
166  *m_Q = processNoiseMatrix(*m_nbDof, *m_Te);
167 
168  // Matrix of the noise on the measurement
169  *m_R = measurementNoiseMatrix(*m_nMeasure, m_params->noiseFactor());
170 
171  // Initialize the state
172  *m_xp = initState(*m_nbDof);
173 
174  // Matrix Pp
175  *m_Pp = initCovariance(*m_nbDof, m_params->errorFactor());
176 }
177 
178 
180  const unsigned int nbT,
181  double val){
182  biorbd::utils::Matrix R(biorbd::utils::Matrix::Zero(nbT, nbT));
183  for (unsigned int i=0; i<nbT; ++i)
184  R(i,i) = val;
185  return R;
186 }
187 
189  const unsigned int nbQ){
190  return biorbd::rigidbody::GeneralizedCoordinates::Zero(3*nbQ); // Q, Qdot, Qddot
191 }
192 
197  if (Q != nullptr)
198  m_xp->block(0, 0, *m_nbDof, 1) = *Q;
199 
200  if (Qdot != nullptr)
201  m_xp->block(*m_nbDof, 0, *m_nbDof, 1) = *Qdot;
202 
203  if (Qddot != nullptr)
204  m_xp->block(2* *m_nbDof, 0, *m_nbDof, 1) = *Qddot;
205 }
206 
207 
209  double val){
210  biorbd::utils::Matrix Pp(biorbd::utils::Matrix::Zero(3*nbQ, 3*nbQ));
211  for (unsigned int i=0; i<3*nbQ; ++i)
212  Pp(i,i) = val;
213  return Pp;
214 }
215 
216 
217 
218 
219 
221  double frequency,
222  double noiseFactor,
223  double errorFactor):
224  m_acquisitionFrequency(frequency),
225  m_noiseFactor(noiseFactor),
226  m_errorFactor(errorFactor){}
227 
229  return m_acquisitionFrequency;
230 }
231 
233 {
234  return m_noiseFactor;
235 }
236 
238 {
239  return m_errorFactor;
240 }
biorbd::rigidbody::KalmanRecons::initCovariance
biorbd::utils::Matrix initCovariance(const unsigned int nbQ, double val)
Returns a initialized covianriance matrix.
Definition: KalmanRecons.cpp:208
biorbd::utils::Vector
Wrapper of the Eigen VectorXd.
Definition: Vector.h:20
biorbd::rigidbody::KalmanRecons::setInitState
void setInitState(const biorbd::rigidbody::GeneralizedCoordinates *Q=nullptr, const biorbd::rigidbody::GeneralizedVelocity *Qdot=nullptr, const biorbd::rigidbody::GeneralizedAcceleration *Qddot=nullptr)
Set the initial guess of the reconstruction.
Definition: KalmanRecons.cpp:193
biorbd::rigidbody::KalmanRecons::m_nbDof
std::shared_ptr< unsigned int > m_nbDof
Number of states.
Definition: KalmanRecons.h:206
biorbd::rigidbody::KalmanParam::KalmanParam
KalmanParam(double frequency=100, double noiseFactor=1e-10, double errorFactor=1e-5)
Set the Kalman filter parameters.
Definition: KalmanRecons.cpp:220
biorbd::rigidbody::KalmanRecons::getState
void getState(biorbd::rigidbody::GeneralizedCoordinates *Q=nullptr, biorbd::rigidbody::GeneralizedVelocity *Qdot=nullptr, biorbd::rigidbody::GeneralizedAcceleration *Qddot=nullptr)
Get the state (Q, Qdot, Qddot)
Definition: KalmanRecons.cpp:90
biorbd::rigidbody::KalmanParam
Parameters of the reconstruction.
Definition: KalmanRecons.h:25
biorbd::rigidbody::KalmanRecons::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: KalmanRecons.cpp:79
biorbd::rigidbody::KalmanParam::noiseFactor
double noiseFactor() const
Return the noise factor.
Definition: KalmanRecons.cpp:232
biorbd::rigidbody::GeneralizedCoordinates
Class GeneralizedCoordinates.
Definition: GeneralizedCoordinates.h:15
biorbd::rigidbody::KalmanRecons::KalmanRecons
KalmanRecons()
Kalman reconstruction.
Definition: KalmanRecons.cpp:11
biorbd::Model
The actual musculoskeletal model that holds everything in biorbd.
Definition: BiorbdModel.h:78
biorbd::rigidbody::KalmanRecons::evolutionMatrix
biorbd::utils::Matrix evolutionMatrix(const unsigned int m, unsigned int n, double Te)
Create the evolution matrix.
Definition: KalmanRecons.cpp:106
biorbd::rigidbody::KalmanRecons::processNoiseMatrix
biorbd::utils::Matrix processNoiseMatrix(const unsigned int nbQ, double Te)
Process the noise matrix.
Definition: KalmanRecons.cpp:130
biorbd::rigidbody::KalmanRecons::m_xp
std::shared_ptr< biorbd::utils::Vector > m_xp
State vector.
Definition: KalmanRecons.h:210
biorbd::rigidbody::KalmanRecons::iteration
void iteration(biorbd::utils::Vector measure, const biorbd::utils::Vector &projectedMeasure, const biorbd::utils::Matrix &Hessian, const std::vector< unsigned int > &occlusion=std::vector< unsigned int >())
Compute an iteration of the Kalman filter.
Definition: KalmanRecons.cpp:59
biorbd::rigidbody::KalmanRecons::m_Te
std::shared_ptr< double > m_Te
Inherent parameter to the frequency.
Definition: KalmanRecons.h:205
biorbd::rigidbody::KalmanRecons::~KalmanRecons
virtual ~KalmanRecons()
Destroy class properly.
Definition: KalmanRecons.cpp:41
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::KalmanParam::errorFactor
double errorFactor() const
Return the error factor.
Definition: KalmanRecons.cpp:237
biorbd::rigidbody::KalmanRecons::initialize
virtual void initialize()
Initialization of the filter.
Definition: KalmanRecons.cpp:160
biorbd::rigidbody::KalmanRecons
Class Kinematic reconstruction algorithm using an Extended Kalman Filter.
Definition: KalmanRecons.h:63
biorbd::rigidbody::KalmanRecons::measurementNoiseMatrix
biorbd::utils::Matrix measurementNoiseMatrix(const unsigned int nbT, double val)
Matrix of the noise on the measurements.
Definition: KalmanRecons.cpp:179
biorbd::rigidbody::KalmanParam::acquisitionFrequency
double acquisitionFrequency() const
Return the acquisition frequency.
Definition: KalmanRecons.cpp:228
biorbd::rigidbody::KalmanRecons::m_params
std::shared_ptr< KalmanParam > m_params
The parameters of the Kalman filter.
Definition: KalmanRecons.h:204
biorbd::rigidbody::KalmanRecons::m_nMeasure
std::shared_ptr< unsigned int > m_nMeasure
Number of measurements.
Definition: KalmanRecons.h:207
biorbd::rigidbody::KalmanRecons::m_Pp
std::shared_ptr< biorbd::utils::Matrix > m_Pp
Covariance matrix.
Definition: KalmanRecons.h:214
biorbd::rigidbody::KalmanRecons::m_A
std::shared_ptr< biorbd::utils::Matrix > m_A
Evolution matrix.
Definition: KalmanRecons.h:211
biorbd::rigidbody::GeneralizedVelocity
Class GeneralizedVelocity.
Definition: GeneralizedVelocity.h:15
biorbd::rigidbody::KalmanRecons::initState
biorbd::rigidbody::GeneralizedCoordinates initState(const unsigned int nbQ)
Initialize the states.
Definition: KalmanRecons.cpp:188
biorbd::rigidbody::KalmanRecons::m_R
std::shared_ptr< biorbd::utils::Matrix > m_R
Matrix of the noise on the measurements.
Definition: KalmanRecons.h:213
biorbd::rigidbody::KalmanRecons::m_Q
std::shared_ptr< biorbd::utils::Matrix > m_Q
Noise matrix.
Definition: KalmanRecons.h:212