fixed int32_t to double warnings. reformats
This commit is contained in:
parent
0d3509b991
commit
8b23fd3dd2
@ -6,115 +6,97 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "MultiplicativeKalmanFilter.h"
|
#include "MultiplicativeKalmanFilter.h"
|
||||||
#include "util/CholeskyDecomposition.h"
|
|
||||||
#include "util/MathOperations.h"
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <fsfw/globalfunctions/math/MatrixOperations.h>
|
#include <fsfw/globalfunctions/math/MatrixOperations.h>
|
||||||
#include <fsfw/globalfunctions/math/QuaternionOperations.h>
|
#include <fsfw/globalfunctions/math/QuaternionOperations.h>
|
||||||
#include <fsfw/globalfunctions/math/VectorOperations.h>
|
#include <fsfw/globalfunctions/math/VectorOperations.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "util/CholeskyDecomposition.h"
|
||||||
|
#include "util/MathOperations.h"
|
||||||
|
|
||||||
/*Initialisation of values for parameters in constructor*/
|
/*Initialisation of values for parameters in constructor*/
|
||||||
MultiplicativeKalmanFilter::MultiplicativeKalmanFilter(AcsParameters *acsParameters_) :
|
MultiplicativeKalmanFilter::MultiplicativeKalmanFilter(AcsParameters *acsParameters_)
|
||||||
initialQuaternion { 0.5, 0.5, 0.5, 0.5 },initialCovarianceMatrix
|
: initialQuaternion{0.5, 0.5, 0.5, 0.5},
|
||||||
{{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},
|
initialCovarianceMatrix{{0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0},
|
||||||
{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0}}{
|
{0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}} {
|
||||||
loadAcsParameters(acsParameters_);
|
loadAcsParameters(acsParameters_);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MultiplicativeKalmanFilter::~MultiplicativeKalmanFilter() {
|
MultiplicativeKalmanFilter::~MultiplicativeKalmanFilter() {}
|
||||||
|
|
||||||
}
|
void MultiplicativeKalmanFilter::loadAcsParameters(AcsParameters *acsParameters_) {
|
||||||
|
|
||||||
void MultiplicativeKalmanFilter::loadAcsParameters(
|
|
||||||
AcsParameters *acsParameters_) {
|
|
||||||
inertiaEIVE = &(acsParameters_->inertiaEIVE);
|
inertiaEIVE = &(acsParameters_->inertiaEIVE);
|
||||||
kalmanFilterParameters = &(acsParameters_->kalmanFilterParameters); /*Sensor noises also here*/
|
kalmanFilterParameters = &(acsParameters_->kalmanFilterParameters); /*Sensor noises also here*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void MultiplicativeKalmanFilter::reset() {
|
void MultiplicativeKalmanFilter::reset() {}
|
||||||
|
|
||||||
}
|
void MultiplicativeKalmanFilter::init(
|
||||||
|
const double *magneticField_, const bool *validMagField_, const double *sunDir_,
|
||||||
void MultiplicativeKalmanFilter::init(const double *magneticField_, const bool *validMagField_,
|
const bool *validSS, const double *sunDirJ, const bool *validSSModel, const double *magFieldJ,
|
||||||
const double *sunDir_, const bool *validSS,
|
const bool *validMagModel) { // valids for "model measurements"?
|
||||||
const double *sunDirJ, const bool *validSSModel,
|
|
||||||
const double *magFieldJ,const bool *validMagModel) { // valids for "model measurements"?
|
|
||||||
// check for valid mag/sun
|
// check for valid mag/sun
|
||||||
if (*validMagField_ && *validSS && *validSSModel && *validMagModel) {
|
if (*validMagField_ && *validSS && *validSSModel && *validMagModel) {
|
||||||
validInit = true;
|
validInit = true;
|
||||||
//AcsParameters mekfEstParams;
|
// AcsParameters mekfEstParams;
|
||||||
//loadAcsParameters(&mekfEstParams);
|
// loadAcsParameters(&mekfEstParams);
|
||||||
// QUEST ALGO -----------------------------------------------------------------------
|
// QUEST ALGO -----------------------------------------------------------------------
|
||||||
double sigmaSun = 0, sigmaMag = 0, sigmaGyro = 0;
|
double sigmaSun = 0, sigmaMag = 0, sigmaGyro = 0;
|
||||||
sigmaSun = kalmanFilterParameters->sensorNoiseSS;
|
sigmaSun = kalmanFilterParameters->sensorNoiseSS;
|
||||||
sigmaMag = kalmanFilterParameters->sensorNoiseMAG;
|
sigmaMag = kalmanFilterParameters->sensorNoiseMAG;
|
||||||
|
|
||||||
sigmaGyro = 0.1*3.141/180; // acs parameters
|
sigmaGyro = 0.1 * 3.141 / 180; // acs parameters
|
||||||
|
|
||||||
double normMagB[3] = {0,0,0}, normSunB[3] = {0,0,0},
|
double normMagB[3] = {0, 0, 0}, normSunB[3] = {0, 0, 0}, normMagJ[3] = {0, 0, 0},
|
||||||
normMagJ[3] = {0,0,0}, normSunJ[3] = {0,0,0};
|
normSunJ[3] = {0, 0, 0};
|
||||||
VectorOperations<double>::normalize(magneticField_, normMagB, 3); // b2
|
VectorOperations<double>::normalize(magneticField_, normMagB, 3); // b2
|
||||||
VectorOperations<double>::normalize(sunDir_, normSunB, 3); //b1
|
VectorOperations<double>::normalize(sunDir_, normSunB, 3); // b1
|
||||||
VectorOperations<double>::normalize(magFieldJ, normMagJ, 3); //r2
|
VectorOperations<double>::normalize(magFieldJ, normMagJ, 3); // r2
|
||||||
VectorOperations<double>::normalize(sunDirJ, normSunJ, 3); //r1
|
VectorOperations<double>::normalize(sunDirJ, normSunJ, 3); // r1
|
||||||
|
|
||||||
double thirdAxis_B[3] = {0,0,0}, thirdAxis_J[3] = {0,0,0};
|
double thirdAxis_B[3] = {0, 0, 0}, thirdAxis_J[3] = {0, 0, 0};
|
||||||
VectorOperations<double>::cross(normSunJ, normMagJ, thirdAxis_J);
|
VectorOperations<double>::cross(normSunJ, normMagJ, thirdAxis_J);
|
||||||
VectorOperations<double>::cross(normSunB, normMagB, thirdAxis_B);
|
VectorOperations<double>::cross(normSunB, normMagB, thirdAxis_B);
|
||||||
VectorOperations<double>::normalize(thirdAxis_J, thirdAxis_J, 3); //rx
|
VectorOperations<double>::normalize(thirdAxis_J, thirdAxis_J, 3); // rx
|
||||||
VectorOperations<double>::normalize(thirdAxis_B, thirdAxis_B, 3); //bx
|
VectorOperations<double>::normalize(thirdAxis_B, thirdAxis_B, 3); // bx
|
||||||
|
|
||||||
double weigthSun= 1 / (sigmaSun * sigmaSun); //a1
|
double weigthSun = 1 / (sigmaSun * sigmaSun); // a1
|
||||||
double weigthMag= 1 / (sigmaMag * sigmaMag); //a2
|
double weigthMag = 1 / (sigmaMag * sigmaMag); // a2
|
||||||
|
|
||||||
double a[3] = {0,0,0}, b[3] = {0,0,0};
|
double a[3] = {0, 0, 0}, b[3] = {0, 0, 0};
|
||||||
VectorOperations<double>::mulScalar(normSunB, weigthSun, a, 3); //a
|
VectorOperations<double>::mulScalar(normSunB, weigthSun, a, 3); // a
|
||||||
VectorOperations<double>::mulScalar(normMagB, weigthMag, b, 3); //b
|
VectorOperations<double>::mulScalar(normMagB, weigthMag, b, 3); // b
|
||||||
|
|
||||||
double thirdAxisCross[3] = {0,0,0}, weightACross[3] = {0,0,0},
|
double thirdAxisCross[3] = {0, 0, 0}, weightACross[3] = {0, 0, 0}, weightBCross[3] = {0, 0, 0},
|
||||||
weightBCross[3] = {0,0,0},weigthCrossSum[3] = {0,0,0};
|
weigthCrossSum[3] = {0, 0, 0};
|
||||||
VectorOperations<double>::cross(thirdAxis_B, thirdAxis_J,
|
VectorOperations<double>::cross(thirdAxis_B, thirdAxis_J,
|
||||||
thirdAxisCross); //cross(bx,rx)
|
thirdAxisCross); // cross(bx,rx)
|
||||||
VectorOperations<double>::cross(a, normSunJ, weightACross);
|
VectorOperations<double>::cross(a, normSunJ, weightACross);
|
||||||
VectorOperations<double>::cross(b, normMagJ, weightBCross);
|
VectorOperations<double>::cross(b, normMagJ, weightBCross);
|
||||||
VectorOperations<double>::add(weightACross, weightBCross,
|
VectorOperations<double>::add(weightACross, weightBCross, weigthCrossSum);
|
||||||
weigthCrossSum);
|
|
||||||
|
|
||||||
double thirdAxisSum[3] = {0,0,0}, sum2[3] = {0,0,0};
|
double thirdAxisSum[3] = {0, 0, 0}, sum2[3] = {0, 0, 0};
|
||||||
VectorOperations<double>::add(thirdAxis_B, thirdAxis_J, thirdAxisSum);
|
VectorOperations<double>::add(thirdAxis_B, thirdAxis_J, thirdAxisSum);
|
||||||
VectorOperations<double>::add(weightACross, weightBCross, sum2);
|
VectorOperations<double>::add(weightACross, weightBCross, sum2);
|
||||||
|
|
||||||
double alpha = 0, beta = 0, gamma = 0, constPlus = 0, constMin = 0;
|
double alpha = 0, beta = 0, gamma = 0, constPlus = 0, constMin = 0;
|
||||||
alpha = (1 + VectorOperations<double>::dot(thirdAxis_B, thirdAxis_J))
|
alpha = (1 + VectorOperations<double>::dot(thirdAxis_B, thirdAxis_J)) *
|
||||||
* (VectorOperations<double>::dot(a, normSunJ)
|
(VectorOperations<double>::dot(a, normSunJ) +
|
||||||
+ VectorOperations<double>::dot(b, normMagJ))
|
VectorOperations<double>::dot(b, normMagJ)) +
|
||||||
+ VectorOperations<double>::dot(thirdAxisCross, weigthCrossSum);
|
VectorOperations<double>::dot(thirdAxisCross, weigthCrossSum);
|
||||||
beta = VectorOperations<double>::dot(thirdAxisSum, sum2);
|
beta = VectorOperations<double>::dot(thirdAxisSum, sum2);
|
||||||
gamma = sqrt(alpha * alpha + beta * beta);
|
gamma = sqrt(alpha * alpha + beta * beta);
|
||||||
constPlus = 1
|
constPlus = 1 / (2 * sqrt(gamma * (gamma + alpha) *
|
||||||
/ (2
|
(1 + VectorOperations<double>::dot(thirdAxis_B, thirdAxis_J))));
|
||||||
* sqrt(
|
constMin = 1 / (2 * sqrt(gamma * (gamma - alpha) *
|
||||||
gamma * (gamma + alpha)
|
(1 + VectorOperations<double>::dot(thirdAxis_B, thirdAxis_J))));
|
||||||
* (1
|
|
||||||
+ VectorOperations<double>::dot(
|
|
||||||
thirdAxis_B,
|
|
||||||
thirdAxis_J))));
|
|
||||||
constMin = 1
|
|
||||||
/ (2
|
|
||||||
* sqrt(
|
|
||||||
gamma * (gamma - alpha)
|
|
||||||
* (1
|
|
||||||
+ VectorOperations<double>::dot(
|
|
||||||
thirdAxis_B,
|
|
||||||
thirdAxis_J))));
|
|
||||||
|
|
||||||
/*Quaternion Computation*/
|
/*Quaternion Computation*/
|
||||||
double quat[3] = {0,0,0}, var1[3] = {0,0,0}, var2[3] = {0,0,0};
|
double quat[3] = {0, 0, 0}, var1[3] = {0, 0, 0}, var2[3] = {0, 0, 0};
|
||||||
if (alpha >= 0) {
|
if (alpha >= 0) {
|
||||||
VectorOperations<double>::mulScalar(thirdAxisCross, gamma + alpha,
|
VectorOperations<double>::mulScalar(thirdAxisCross, gamma + alpha, var1, 3);
|
||||||
var1, 3);
|
|
||||||
VectorOperations<double>::add(thirdAxis_B, thirdAxis_J, var2, 3);
|
VectorOperations<double>::add(thirdAxis_B, thirdAxis_J, var2, 3);
|
||||||
VectorOperations<double>::mulScalar(var2, beta, var2, 3);
|
VectorOperations<double>::mulScalar(var2, beta, var2, 3);
|
||||||
VectorOperations<double>::add(var1, var2, quat);
|
VectorOperations<double>::add(var1, var2, quat);
|
||||||
@ -122,12 +104,9 @@ void MultiplicativeKalmanFilter::init(const double *magneticField_, const bool *
|
|||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
initialQuaternion[i] = quat[i];
|
initialQuaternion[i] = quat[i];
|
||||||
}
|
}
|
||||||
initialQuaternion[3] = (gamma + alpha)
|
initialQuaternion[3] =
|
||||||
* (1
|
(gamma + alpha) * (1 + VectorOperations<double>::dot(thirdAxis_B, thirdAxis_J));
|
||||||
+ VectorOperations<double>::dot(thirdAxis_B,
|
VectorOperations<double>::mulScalar(initialQuaternion, constPlus, initialQuaternion, 4);
|
||||||
thirdAxis_J));
|
|
||||||
VectorOperations<double>::mulScalar(initialQuaternion,
|
|
||||||
constPlus, initialQuaternion, 4);
|
|
||||||
} else {
|
} else {
|
||||||
double diffGammaAlpha = gamma - alpha;
|
double diffGammaAlpha = gamma - alpha;
|
||||||
VectorOperations<double>::mulScalar(thirdAxisCross, beta, var1, 3);
|
VectorOperations<double>::mulScalar(thirdAxisCross, beta, var1, 3);
|
||||||
@ -137,13 +116,8 @@ void MultiplicativeKalmanFilter::init(const double *magneticField_, const bool *
|
|||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
initialQuaternion[i] = quat[i];
|
initialQuaternion[i] = quat[i];
|
||||||
}
|
}
|
||||||
initialQuaternion[3] = beta
|
initialQuaternion[3] = beta * (1 + VectorOperations<double>::dot(thirdAxis_B, thirdAxis_J));
|
||||||
* (1
|
VectorOperations<double>::mulScalar(initialQuaternion, constMin, initialQuaternion, 4);
|
||||||
+ VectorOperations<double>::dot(thirdAxis_B,
|
|
||||||
thirdAxis_J));
|
|
||||||
VectorOperations<double>::mulScalar(initialQuaternion,
|
|
||||||
constMin, initialQuaternion, 4);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
propagatedQuaternion[0] = initialQuaternion[0];
|
propagatedQuaternion[0] = initialQuaternion[0];
|
||||||
propagatedQuaternion[1] = initialQuaternion[1];
|
propagatedQuaternion[1] = initialQuaternion[1];
|
||||||
@ -151,55 +125,43 @@ void MultiplicativeKalmanFilter::init(const double *magneticField_, const bool *
|
|||||||
propagatedQuaternion[3] = initialQuaternion[3];
|
propagatedQuaternion[3] = initialQuaternion[3];
|
||||||
|
|
||||||
/*Initial Covariance Matrix------------------------------------ */
|
/*Initial Covariance Matrix------------------------------------ */
|
||||||
double dcmBJ[3][3] = {{0,0,0},{0,0,0},{0,0,0}},
|
double dcmBJ[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, sunEstB[3] = {0, 0, 0},
|
||||||
sunEstB[3] = {0,0,0}, magEstB[3] = {0,0,0};
|
magEstB[3] = {0, 0, 0};
|
||||||
QuaternionOperations::toDcm(initialQuaternion, dcmBJ);
|
QuaternionOperations::toDcm(initialQuaternion, dcmBJ);
|
||||||
MatrixOperations<double>::multiply(*dcmBJ, normSunJ, sunEstB, 3, 3, 1);
|
MatrixOperations<double>::multiply(*dcmBJ, normSunJ, sunEstB, 3, 3, 1);
|
||||||
MatrixOperations<double>::multiply(*dcmBJ, normMagJ, magEstB, 3, 3,
|
MatrixOperations<double>::multiply(*dcmBJ, normMagJ, magEstB, 3, 3, 1);
|
||||||
1);
|
|
||||||
|
|
||||||
double matrixSun[3][3] = {{0,0,0},{0,0,0},{0,0,0}},
|
double matrixSun[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||||
matrixMag[3][3] = {{0,0,0},{0,0,0},{0,0,0}},
|
matrixMag[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||||
matrixSunMag[3][3] = {{0,0,0},{0,0,0},{0,0,0}},
|
matrixSunMag[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||||
matrixMagSun[3][3] = {{0,0,0},{0,0,0},{0,0,0}};
|
matrixMagSun[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
||||||
/* vector*transpose(vector)*/
|
/* vector*transpose(vector)*/
|
||||||
MatrixOperations<double>::multiply(sunEstB, sunEstB, *matrixSun, 3, 1, 3);
|
MatrixOperations<double>::multiply(sunEstB, sunEstB, *matrixSun, 3, 1, 3);
|
||||||
MatrixOperations<double>::multiply(magEstB, magEstB, *matrixMag, 3, 1, 3);
|
MatrixOperations<double>::multiply(magEstB, magEstB, *matrixMag, 3, 1, 3);
|
||||||
MatrixOperations<double>::multiply(sunEstB, magEstB, *matrixSunMag, 3, 1, 3);
|
MatrixOperations<double>::multiply(sunEstB, magEstB, *matrixSunMag, 3, 1, 3);
|
||||||
MatrixOperations<double>::multiply(magEstB, sunEstB, *matrixMagSun, 3, 1, 3);
|
MatrixOperations<double>::multiply(magEstB, sunEstB, *matrixMagSun, 3, 1, 3);
|
||||||
|
|
||||||
double partA[3][3] = {{0,0,0},{0,0,0},{0,0,0}}, partB = 0;
|
double partA[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, partB = 0;
|
||||||
MatrixOperations<double>::multiplyScalar(*matrixSun,
|
MatrixOperations<double>::multiplyScalar(*matrixSun, weigthSun * weigthSun, *matrixSun, 3, 3);
|
||||||
weigthSun * weigthSun, *matrixSun, 3, 3);
|
MatrixOperations<double>::multiplyScalar(*matrixMag, weigthMag * weigthMag, *matrixMag, 3, 3);
|
||||||
MatrixOperations<double>::multiplyScalar(*matrixMag,
|
MatrixOperations<double>::add(*matrixSunMag, *matrixMagSun, *partA, 3, 3);
|
||||||
weigthMag * weigthMag, *matrixMag, 3, 3);
|
double factor = weigthMag * weigthSun * VectorOperations<double>::dot(sunEstB, magEstB);
|
||||||
MatrixOperations<double>::add(*matrixSunMag, *matrixMagSun, *partA, 3,
|
|
||||||
3);
|
|
||||||
double factor = weigthMag * weigthSun
|
|
||||||
* VectorOperations<double>::dot(sunEstB, magEstB);
|
|
||||||
MatrixOperations<double>::multiplyScalar(*partA, factor, *partA, 3, 3);
|
MatrixOperations<double>::multiplyScalar(*partA, factor, *partA, 3, 3);
|
||||||
MatrixOperations<double>::add(*partA, *matrixSun, *partA, 3, 3);
|
MatrixOperations<double>::add(*partA, *matrixSun, *partA, 3, 3);
|
||||||
MatrixOperations<double>::add(*partA, *matrixMag, *partA, 3, 3);
|
MatrixOperations<double>::add(*partA, *matrixMag, *partA, 3, 3);
|
||||||
|
|
||||||
double crossSunMag[3] = {0,0,0};
|
double crossSunMag[3] = {0, 0, 0};
|
||||||
double identityMatrix3[3][3] = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } };
|
double identityMatrix3[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
|
||||||
VectorOperations<double>::cross(sunEstB, magEstB, crossSunMag);
|
VectorOperations<double>::cross(sunEstB, magEstB, crossSunMag);
|
||||||
partB =
|
partB = 1 / (weigthMag * weigthSun * pow(VectorOperations<double>::norm(crossSunMag, 3), 2));
|
||||||
1
|
|
||||||
/ (weigthMag * weigthSun
|
|
||||||
* pow(
|
|
||||||
VectorOperations<double>::norm(
|
|
||||||
crossSunMag, 3), 2));
|
|
||||||
MatrixOperations<double>::multiplyScalar(*partA, partB, *partA, 3, 3);
|
MatrixOperations<double>::multiplyScalar(*partA, partB, *partA, 3, 3);
|
||||||
MatrixOperations<double>::add(*matrixSunMag, *identityMatrix3, *partA, 3,
|
MatrixOperations<double>::add(*matrixSunMag, *identityMatrix3, *partA, 3, 3);
|
||||||
3);
|
|
||||||
factor = 1 / (weigthMag + weigthMag);
|
factor = 1 / (weigthMag + weigthMag);
|
||||||
|
|
||||||
double questCovMatrix[3][3] = {{0,0,0},{0,0,0},{0,0,0}};
|
double questCovMatrix[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
||||||
MatrixOperations<double>::multiplyScalar(*partA, factor,
|
MatrixOperations<double>::multiplyScalar(*partA, factor, *questCovMatrix, 3, 3);
|
||||||
*questCovMatrix, 3, 3);
|
double initGyroCov[3][3] = {
|
||||||
double initGyroCov[3][3] = {{pow(sigmaGyro,2),0,0},{0,pow(sigmaGyro,2),0},
|
{pow(sigmaGyro, 2), 0, 0}, {0, pow(sigmaGyro, 2), 0}, {0, 0, pow(sigmaGyro, 2)}};
|
||||||
{0,0,pow(sigmaGyro,2)}};
|
|
||||||
initialCovarianceMatrix[0][0] = questCovMatrix[0][0];
|
initialCovarianceMatrix[0][0] = questCovMatrix[0][0];
|
||||||
initialCovarianceMatrix[0][1] = questCovMatrix[0][1];
|
initialCovarianceMatrix[0][1] = questCovMatrix[0][1];
|
||||||
initialCovarianceMatrix[0][2] = questCovMatrix[0][2];
|
initialCovarianceMatrix[0][2] = questCovMatrix[0][2];
|
||||||
@ -236,7 +198,7 @@ void MultiplicativeKalmanFilter::init(const double *magneticField_, const bool *
|
|||||||
initialCovarianceMatrix[5][3] = initGyroCov[2][0];
|
initialCovarianceMatrix[5][3] = initGyroCov[2][0];
|
||||||
initialCovarianceMatrix[5][4] = initGyroCov[2][1];
|
initialCovarianceMatrix[5][4] = initGyroCov[2][1];
|
||||||
initialCovarianceMatrix[5][5] = initGyroCov[2][2];
|
initialCovarianceMatrix[5][5] = initGyroCov[2][2];
|
||||||
//initialCovarianceMatrix[][] = {{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},
|
// initialCovarianceMatrix[][] = {{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},
|
||||||
//{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0}};
|
//{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0}};
|
||||||
} else {
|
} else {
|
||||||
// no initialisation possible, no valid measurements
|
// no initialisation possible, no valid measurements
|
||||||
@ -246,58 +208,47 @@ void MultiplicativeKalmanFilter::init(const double *magneticField_, const bool *
|
|||||||
|
|
||||||
// --------------- MEKF DISCRETE TIME STEP -------------------------------
|
// --------------- MEKF DISCRETE TIME STEP -------------------------------
|
||||||
ReturnValue_t MultiplicativeKalmanFilter::mekfEst(
|
ReturnValue_t MultiplicativeKalmanFilter::mekfEst(
|
||||||
const double *quaternionSTR, const bool *validSTR_,
|
const double *quaternionSTR, const bool *validSTR_, const double *rateGYRs_,
|
||||||
const double *rateRMUs_, const bool *validRMUs_,
|
const bool *validGYRs_, const double *magneticField_, const bool *validMagField_,
|
||||||
const double *magneticField_, const bool *validMagField_,
|
const double *sunDir_, const bool *validSS, const double *sunDirJ, const bool *validSSModel,
|
||||||
const double *sunDir_, const bool *validSS,
|
const double *magFieldJ, const bool *validMagModel, double *outputQuat, double *outputSatRate) {
|
||||||
const double *sunDirJ, const bool *validSSModel,
|
// Check for GYR Measurements
|
||||||
const double *magFieldJ,const bool *validMagModel,
|
// AcsParameters mekfEstParams;
|
||||||
double *outputQuat, double *outputSatRate) {
|
// loadAcsParameters(&mekfEstParams);
|
||||||
|
|
||||||
// Check for RMU Measurements
|
|
||||||
//AcsParameters mekfEstParams;
|
|
||||||
//loadAcsParameters(&mekfEstParams);
|
|
||||||
int MDF = 0; // Matrix Dimension Factor
|
int MDF = 0; // Matrix Dimension Factor
|
||||||
if (!(*validRMUs_)){
|
if (!(*validGYRs_)) {
|
||||||
validMekf = false;
|
validMekf = false;
|
||||||
return KALMAN_NO_RMU_MEAS;
|
return KALMAN_NO_GYR_MEAS;
|
||||||
}
|
}
|
||||||
// Check for Model Calculations
|
// Check for Model Calculations
|
||||||
else if (!(*validSSModel) || !(*validMagModel)){
|
else if (!(*validSSModel) || !(*validMagModel)) {
|
||||||
validMekf = false;
|
validMekf = false;
|
||||||
return KALMAN_NO_MODEL;
|
return KALMAN_NO_MODEL;
|
||||||
}
|
}
|
||||||
// Check Measurements available from SS, MAG, STR
|
// Check Measurements available from SS, MAG, STR
|
||||||
if (*validSS && *validMagField_ && *validSTR_){
|
if (*validSS && *validMagField_ && *validSTR_) {
|
||||||
sensorsAvail = 1;
|
sensorsAvail = 1;
|
||||||
MDF = 9;
|
MDF = 9;
|
||||||
}
|
} else if (*validSS && *validMagField_ && !(*validSTR_)) {
|
||||||
else if (*validSS && *validMagField_ && !(*validSTR_)){
|
|
||||||
sensorsAvail = 2;
|
sensorsAvail = 2;
|
||||||
MDF = 6;
|
MDF = 6;
|
||||||
}
|
} else if (*validSS && !(*validMagField_) && *validSTR_) {
|
||||||
else if (*validSS && !(*validMagField_) && *validSTR_){
|
|
||||||
sensorsAvail = 3;
|
sensorsAvail = 3;
|
||||||
MDF = 6;
|
MDF = 6;
|
||||||
}
|
} else if (!(*validSS) && *validMagField_ && *validSTR_) {
|
||||||
else if (!(*validSS) && *validMagField_ && *validSTR_){
|
|
||||||
sensorsAvail = 4;
|
sensorsAvail = 4;
|
||||||
MDF = 6;
|
MDF = 6;
|
||||||
}
|
} else if (*validSS && !(*validMagField_) && !(*validSTR_)) {
|
||||||
else if (*validSS && !(*validMagField_) && !(*validSTR_)){
|
|
||||||
sensorsAvail = 5;
|
sensorsAvail = 5;
|
||||||
MDF = 3;
|
MDF = 3;
|
||||||
}
|
} else if (!(*validSS) && *validMagField_ && !(*validSTR_)) {
|
||||||
else if (!(*validSS) && *validMagField_ && !(*validSTR_)){
|
|
||||||
sensorsAvail = 6;
|
sensorsAvail = 6;
|
||||||
MDF = 3;
|
MDF = 3;
|
||||||
}
|
} else if (!(*validSS) && !(*validMagField_) && *validSTR_) {
|
||||||
else if (!(*validSS) && !(*validMagField_) && *validSTR_){
|
|
||||||
sensorsAvail = 7;
|
sensorsAvail = 7;
|
||||||
MDF = 3;
|
MDF = 3;
|
||||||
}
|
} else {
|
||||||
else{
|
sensorsAvail = 8; // no measurements
|
||||||
sensorsAvail = 8; //no measurements
|
|
||||||
validMekf = false;
|
validMekf = false;
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
@ -308,47 +259,48 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(
|
|||||||
sigmaMag = kalmanFilterParameters->sensorNoiseMAG;
|
sigmaMag = kalmanFilterParameters->sensorNoiseMAG;
|
||||||
sigmaStr = kalmanFilterParameters->sensorNoiseSTR;
|
sigmaStr = kalmanFilterParameters->sensorNoiseSTR;
|
||||||
|
|
||||||
double normMagB[3] = {0,0,0}, normSunB[3] = {0,0,0},
|
double normMagB[3] = {0, 0, 0}, normSunB[3] = {0, 0, 0}, normMagJ[3] = {0, 0, 0},
|
||||||
normMagJ[3] = {0,0,0}, normSunJ[3] = {0,0,0};
|
normSunJ[3] = {0, 0, 0};
|
||||||
VectorOperations<double>::normalize(magneticField_, normMagB, 3); // b2
|
VectorOperations<double>::normalize(magneticField_, normMagB, 3); // b2
|
||||||
VectorOperations<double>::normalize(sunDir_, normSunB, 3); //b1
|
VectorOperations<double>::normalize(sunDir_, normSunB, 3); // b1
|
||||||
VectorOperations<double>::normalize(magFieldJ, normMagJ, 3); //r2
|
VectorOperations<double>::normalize(magFieldJ, normMagJ, 3); // r2
|
||||||
VectorOperations<double>::normalize(sunDirJ, normSunJ, 3); //r1
|
VectorOperations<double>::normalize(sunDirJ, normSunJ, 3); // r1
|
||||||
|
|
||||||
/*-------GAIN - UPDATE - STEP------*/
|
/*-------GAIN - UPDATE - STEP------*/
|
||||||
double covMatrix11[3][3] = {{pow(sigmaSun,2),0,0},{0,pow(sigmaSun,2),0},{0,0,pow(sigmaSun,2)}};
|
double covMatrix11[3][3] = {
|
||||||
double covMatrix22[3][3] = {{pow(sigmaMag,2),0,0},{0,pow(sigmaMag,2),0},{0,0,pow(sigmaMag,2)}};
|
{pow(sigmaSun, 2), 0, 0}, {0, pow(sigmaSun, 2), 0}, {0, 0, pow(sigmaSun, 2)}};
|
||||||
double covMatrix33[3][3] = {{pow(sigmaStr,2),0,0},{0,pow(sigmaStr,2),0},{0,0,pow(sigmaStr,2)}};
|
double covMatrix22[3][3] = {
|
||||||
|
{pow(sigmaMag, 2), 0, 0}, {0, pow(sigmaMag, 2), 0}, {0, 0, pow(sigmaMag, 2)}};
|
||||||
|
double covMatrix33[3][3] = {
|
||||||
|
{pow(sigmaStr, 2), 0, 0}, {0, pow(sigmaStr, 2), 0}, {0, 0, pow(sigmaStr, 2)}};
|
||||||
|
|
||||||
double dcmBJ[3][3] = {{0,0,0},{0,0,0},{0,0,0}},
|
double dcmBJ[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, sunEstB[3] = {0, 0, 0},
|
||||||
sunEstB[3] = {0,0,0}, magEstB[3] = {0,0,0};
|
magEstB[3] = {0, 0, 0};
|
||||||
QuaternionOperations::toDcm(propagatedQuaternion, dcmBJ);
|
QuaternionOperations::toDcm(propagatedQuaternion, dcmBJ);
|
||||||
MatrixOperations<double>::multiply(*dcmBJ, normSunJ, sunEstB, 3, 3, 1);
|
MatrixOperations<double>::multiply(*dcmBJ, normSunJ, sunEstB, 3, 3, 1);
|
||||||
MatrixOperations<double>::multiply(*dcmBJ, normMagJ, magEstB, 3, 3,
|
MatrixOperations<double>::multiply(*dcmBJ, normMagJ, magEstB, 3, 3, 1);
|
||||||
1);
|
double quatEstErr[3] = {0, 0, 0};
|
||||||
double quatEstErr[3] = {0,0,0};
|
|
||||||
|
|
||||||
//Measurement Sensitivity Matrix
|
// Measurement Sensitivity Matrix
|
||||||
double measSensMatrix11[3][3] = {{0,0,0},{0,0,0},{0,0,0}}; // ss
|
double measSensMatrix11[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; // ss
|
||||||
double measSensMatrix22[3][3] = {{0,0,0},{0,0,0},{0,0,0}}; // mag
|
double measSensMatrix22[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; // mag
|
||||||
double measSensMatrix33[3][3] = {{1,0,0},{0,1,0},{0,0,1}}; // str
|
double measSensMatrix33[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}; // str
|
||||||
MathOperations<double>::skewMatrix(sunEstB, *measSensMatrix11);
|
MathOperations<double>::skewMatrix(sunEstB, *measSensMatrix11);
|
||||||
MathOperations<double>::skewMatrix(magEstB, *measSensMatrix22);
|
MathOperations<double>::skewMatrix(magEstB, *measSensMatrix22);
|
||||||
|
|
||||||
double measVecQuat[3] = {0,0,0};
|
double measVecQuat[3] = {0, 0, 0};
|
||||||
if (*validSTR_){
|
if (*validSTR_) {
|
||||||
double quatError[4] = {0,0,0,0};
|
double quatError[4] = {0, 0, 0, 0};
|
||||||
double invPropagatedQuat[4] = {0,0,0,0};
|
double invPropagatedQuat[4] = {0, 0, 0, 0};
|
||||||
QuaternionOperations::inverse(propagatedQuaternion, invPropagatedQuat);
|
QuaternionOperations::inverse(propagatedQuaternion, invPropagatedQuat);
|
||||||
QuaternionOperations::multiply(quaternionSTR, invPropagatedQuat, quatError);
|
QuaternionOperations::multiply(quaternionSTR, invPropagatedQuat, quatError);
|
||||||
for (int i = 0 ; i < 3;i++){
|
for (int i = 0; i < 3; i++) {
|
||||||
measVecQuat[i]=2*quatError[i]/quatError[3];
|
measVecQuat[i] = 2 * quatError[i] / quatError[3];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Adjust matrices based on valid measurements
|
// Adjust matrices based on valid measurements
|
||||||
double measSensMatrix[MDF][6], measCovMatrix[MDF][MDF], measVec[MDF],
|
double measSensMatrix[MDF][6], measCovMatrix[MDF][MDF], measVec[MDF], measEstVec[MDF];
|
||||||
measEstVec[MDF];
|
if (sensorsAvail == 1) { // All measurements valid
|
||||||
if (sensorsAvail==1){ //All measurements valid
|
|
||||||
measSensMatrix[0][0] = measSensMatrix11[0][0];
|
measSensMatrix[0][0] = measSensMatrix11[0][0];
|
||||||
measSensMatrix[0][1] = measSensMatrix11[0][1];
|
measSensMatrix[0][1] = measSensMatrix11[0][1];
|
||||||
measSensMatrix[0][2] = measSensMatrix11[0][2];
|
measSensMatrix[0][2] = measSensMatrix11[0][2];
|
||||||
@ -506,8 +458,7 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(
|
|||||||
measEstVec[7] = quatEstErr[1];
|
measEstVec[7] = quatEstErr[1];
|
||||||
measEstVec[8] = quatEstErr[2];
|
measEstVec[8] = quatEstErr[2];
|
||||||
|
|
||||||
}
|
} else if (sensorsAvail == 2) { // ss / mag valid
|
||||||
else if(sensorsAvail==2){ // ss / mag valid
|
|
||||||
measSensMatrix[0][0] = measSensMatrix11[0][0];
|
measSensMatrix[0][0] = measSensMatrix11[0][0];
|
||||||
measSensMatrix[0][1] = measSensMatrix11[0][1];
|
measSensMatrix[0][1] = measSensMatrix11[0][1];
|
||||||
measSensMatrix[0][2] = measSensMatrix11[0][2];
|
measSensMatrix[0][2] = measSensMatrix11[0][2];
|
||||||
@ -596,8 +547,7 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(
|
|||||||
measEstVec[4] = magEstB[1];
|
measEstVec[4] = magEstB[1];
|
||||||
measEstVec[5] = magEstB[2];
|
measEstVec[5] = magEstB[2];
|
||||||
|
|
||||||
}
|
} else if (sensorsAvail == 3) { // ss / str valid
|
||||||
else if(sensorsAvail==3){ // ss / str valid
|
|
||||||
|
|
||||||
measSensMatrix[0][0] = measSensMatrix11[0][0];
|
measSensMatrix[0][0] = measSensMatrix11[0][0];
|
||||||
measSensMatrix[0][1] = measSensMatrix11[0][1];
|
measSensMatrix[0][1] = measSensMatrix11[0][1];
|
||||||
@ -687,8 +637,7 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(
|
|||||||
measEstVec[4] = quatEstErr[1];
|
measEstVec[4] = quatEstErr[1];
|
||||||
measEstVec[5] = quatEstErr[2];
|
measEstVec[5] = quatEstErr[2];
|
||||||
|
|
||||||
}
|
} else if (sensorsAvail == 4) { // mag / str avail
|
||||||
else if (sensorsAvail == 4){ // mag / str avail
|
|
||||||
|
|
||||||
measSensMatrix[0][0] = measSensMatrix22[0][0];
|
measSensMatrix[0][0] = measSensMatrix22[0][0];
|
||||||
measSensMatrix[0][1] = measSensMatrix22[0][1];
|
measSensMatrix[0][1] = measSensMatrix22[0][1];
|
||||||
@ -778,8 +727,7 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(
|
|||||||
measEstVec[4] = quatEstErr[1];
|
measEstVec[4] = quatEstErr[1];
|
||||||
measEstVec[5] = quatEstErr[2];
|
measEstVec[5] = quatEstErr[2];
|
||||||
|
|
||||||
}
|
} else if (sensorsAvail == 5) { // only ss
|
||||||
else if (sensorsAvail == 5){ // only ss
|
|
||||||
|
|
||||||
measSensMatrix[0][0] = measSensMatrix11[0][0];
|
measSensMatrix[0][0] = measSensMatrix11[0][0];
|
||||||
measSensMatrix[0][1] = measSensMatrix11[0][1];
|
measSensMatrix[0][1] = measSensMatrix11[0][1];
|
||||||
@ -818,8 +766,7 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(
|
|||||||
measEstVec[1] = sunEstB[1];
|
measEstVec[1] = sunEstB[1];
|
||||||
measEstVec[2] = sunEstB[2];
|
measEstVec[2] = sunEstB[2];
|
||||||
|
|
||||||
}
|
} else if (sensorsAvail == 6) { // only mag
|
||||||
else if (sensorsAvail == 6){ // only mag
|
|
||||||
|
|
||||||
measSensMatrix[0][0] = measSensMatrix22[0][0];
|
measSensMatrix[0][0] = measSensMatrix22[0][0];
|
||||||
measSensMatrix[0][1] = measSensMatrix22[0][1];
|
measSensMatrix[0][1] = measSensMatrix22[0][1];
|
||||||
@ -858,8 +805,7 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(
|
|||||||
measEstVec[1] = magEstB[1];
|
measEstVec[1] = magEstB[1];
|
||||||
measEstVec[2] = magEstB[2];
|
measEstVec[2] = magEstB[2];
|
||||||
|
|
||||||
}
|
} else if (sensorsAvail == 7) { // only str
|
||||||
else if (sensorsAvail == 7){ // only str
|
|
||||||
|
|
||||||
measSensMatrix[0][0] = measSensMatrix33[0][0];
|
measSensMatrix[0][0] = measSensMatrix33[0][0];
|
||||||
measSensMatrix[0][1] = measSensMatrix33[0][1];
|
measSensMatrix[0][1] = measSensMatrix33[0][1];
|
||||||
@ -897,70 +843,71 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(
|
|||||||
measEstVec[0] = quatEstErr[0];
|
measEstVec[0] = quatEstErr[0];
|
||||||
measEstVec[1] = quatEstErr[1];
|
measEstVec[1] = quatEstErr[1];
|
||||||
measEstVec[2] = quatEstErr[2];
|
measEstVec[2] = quatEstErr[2];
|
||||||
|
|
||||||
}
|
}
|
||||||
// Kalman Gain: [K = P * H' / (H * P * H' + R)]
|
// Kalman Gain: [K = P * H' / (H * P * H' + R)]
|
||||||
double kalmanGain[6][MDF] = {{0}}, kalmanGain1[6][MDF] = {{0}};
|
double kalmanGain[6][MDF] = {{0}}, kalmanGain1[6][MDF] = {{0}};
|
||||||
|
|
||||||
double measSensMatrixTrans[6][MDF], residualCov[MDF][MDF],
|
double measSensMatrixTrans[6][MDF], residualCov[MDF][MDF], residualCov1[6][MDF];
|
||||||
residualCov1[6][MDF];
|
|
||||||
// H * P * H'
|
// H * P * H'
|
||||||
MatrixOperations<double>::transpose(*measSensMatrix,*measSensMatrixTrans,6,MDF);
|
MatrixOperations<double>::transpose(*measSensMatrix, *measSensMatrixTrans, 6, MDF);
|
||||||
MatrixOperations<double>::multiply(*initialCovarianceMatrix,*measSensMatrixTrans,*residualCov1,6,6,MDF);
|
MatrixOperations<double>::multiply(*initialCovarianceMatrix, *measSensMatrixTrans, *residualCov1,
|
||||||
MatrixOperations<double>::multiply(*measSensMatrix,*residualCov1,*residualCov,MDF,6,MDF);
|
6, 6, MDF);
|
||||||
|
MatrixOperations<double>::multiply(*measSensMatrix, *residualCov1, *residualCov, MDF, 6, MDF);
|
||||||
// negative values, restrictions ?
|
// negative values, restrictions ?
|
||||||
// (H * P * H' + R)
|
// (H * P * H' + R)
|
||||||
MatrixOperations<double>::add(*residualCov, *measCovMatrix, *residualCov, MDF, MDF);
|
MatrixOperations<double>::add(*residualCov, *measCovMatrix, *residualCov, MDF, MDF);
|
||||||
// <<INVERSE residualCov HIER>>
|
// <<INVERSE residualCov HIER>>
|
||||||
double invResidualCov1[MDF] = {0};
|
double invResidualCov1[MDF] = {0};
|
||||||
double invResidualCov[MDF][MDF] = {{0}};
|
double invResidualCov[MDF][MDF] = {{0}};
|
||||||
int inversionFailed = CholeskyDecomposition<double>::invertCholesky(*residualCov,*invResidualCov,invResidualCov1,MDF);
|
int inversionFailed = CholeskyDecomposition<double>::invertCholesky(*residualCov, *invResidualCov,
|
||||||
if(inversionFailed)
|
invResidualCov1, MDF);
|
||||||
{
|
if (inversionFailed) {
|
||||||
validMekf = false;
|
validMekf = false;
|
||||||
return KALMAN_INVERSION_FAILED; // RETURN VALUE ? -- Like: Kalman Inversion Failed
|
return KALMAN_INVERSION_FAILED; // RETURN VALUE ? -- Like: Kalman Inversion Failed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// [K = P * H' / (H * P * H' + R)]
|
// [K = P * H' / (H * P * H' + R)]
|
||||||
MatrixOperations<double>::multiply(*measSensMatrixTrans,*invResidualCov,*kalmanGain1,6,MDF,MDF);
|
MatrixOperations<double>::multiply(*measSensMatrixTrans, *invResidualCov, *kalmanGain1, 6, MDF,
|
||||||
MatrixOperations<double>::multiply(*initialCovarianceMatrix,*kalmanGain1,*kalmanGain,6,6,MDF);
|
MDF);
|
||||||
|
MatrixOperations<double>::multiply(*initialCovarianceMatrix, *kalmanGain1, *kalmanGain, 6, 6,
|
||||||
|
MDF);
|
||||||
|
|
||||||
/* ------- UPDATE -STEP ---------*/
|
/* ------- UPDATE -STEP ---------*/
|
||||||
|
|
||||||
// Update Covariance Matrix: P_plus = (I-K*H)*P_min
|
// Update Covariance Matrix: P_plus = (I-K*H)*P_min
|
||||||
double covMatPlus[6][6] = {{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},
|
double covMatPlus[6][6] = {{0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0},
|
||||||
{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0}};
|
{0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}};
|
||||||
double identityMatrix[6][6] = {{1,0,0,0,0,0},{0,1,0,0,0,0},{0,0,1,0,0,0},
|
double identityMatrix[6][6] = {{1, 0, 0, 0, 0, 0}, {0, 1, 0, 0, 0, 0}, {0, 0, 1, 0, 0, 0},
|
||||||
{0,0,0,1,0,0},{0,0,0,0,1,0},{0,0,0,0,0,1}};
|
{0, 0, 0, 1, 0, 0}, {0, 0, 0, 0, 1, 0}, {0, 0, 0, 0, 0, 1}};
|
||||||
double updateCov1[6][6] = {{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},
|
double updateCov1[6][6] = {{0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0},
|
||||||
{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0}};
|
{0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}};
|
||||||
MatrixOperations<double>::multiply(*kalmanGain,*measSensMatrix,*updateCov1,6,MDF,MDF);
|
MatrixOperations<double>::multiply(*kalmanGain, *measSensMatrix, *updateCov1, 6, MDF, MDF);
|
||||||
MatrixOperations<double>::subtract(*identityMatrix,*updateCov1,*updateCov1,6,6);
|
MatrixOperations<double>::subtract(*identityMatrix, *updateCov1, *updateCov1, 6, 6);
|
||||||
MatrixOperations<double>::multiply(*updateCov1,*initialCovarianceMatrix,*covMatPlus,6,6,6);
|
MatrixOperations<double>::multiply(*updateCov1, *initialCovarianceMatrix, *covMatPlus, 6, 6, 6);
|
||||||
|
|
||||||
// Error State Vector
|
// Error State Vector
|
||||||
double errStateVec[6] = {0,0,0,0,0,0};
|
double errStateVec[6] = {0, 0, 0, 0, 0, 0};
|
||||||
double errStateVec1[MDF] = {0};
|
double errStateVec1[MDF] = {0};
|
||||||
VectorOperations<double>::subtract(measVec,measEstVec,errStateVec1,MDF);
|
VectorOperations<double>::subtract(measVec, measEstVec, errStateVec1, MDF);
|
||||||
MatrixOperations<double>::multiply(*kalmanGain,errStateVec1,errStateVec,6,MDF,1);
|
MatrixOperations<double>::multiply(*kalmanGain, errStateVec1, errStateVec, 6, MDF, 1);
|
||||||
|
|
||||||
double errStateQuat[3] = {errStateVec[0], errStateVec[1], errStateVec[2]};
|
double errStateQuat[3] = {errStateVec[0], errStateVec[1], errStateVec[2]};
|
||||||
double errStateGyroBias[3] = {errStateVec[3], errStateVec[4], errStateVec[5]};
|
double errStateGyroBias[3] = {errStateVec[3], errStateVec[4], errStateVec[5]};
|
||||||
|
|
||||||
// State Vector Elements
|
// State Vector Elements
|
||||||
double xi1[3][3] = {{0,0,0},{0,0,0},{0,0,0}},
|
double xi1[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||||
xi2[3][3] = {{0,0,0},{0,0,0},{0,0,0}};
|
xi2[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
||||||
MathOperations<double>::skewMatrix(propagatedQuaternion, *xi2);
|
MathOperations<double>::skewMatrix(propagatedQuaternion, *xi2);
|
||||||
double identityMatrix3[3][3] = {{1,0,0},{0,1,0},{0,0,1}};
|
double identityMatrix3[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
|
||||||
MatrixOperations<double>::multiplyScalar(*identityMatrix3, propagatedQuaternion[3], *xi1, 3, 3);
|
MatrixOperations<double>::multiplyScalar(*identityMatrix3, propagatedQuaternion[3], *xi1, 3, 3);
|
||||||
MatrixOperations<double>::add(*xi1, *xi2, *xi1, 3, 3);
|
MatrixOperations<double>::add(*xi1, *xi2, *xi1, 3, 3);
|
||||||
double xi[4][3] = {{xi1[0][0],xi1[0][1],xi1[0][2]},
|
double xi[4][3] = {
|
||||||
{xi1[1][0],xi1[1][1],xi1[1][2]},
|
{xi1[0][0], xi1[0][1], xi1[0][2]},
|
||||||
{xi1[2][0],xi1[2][1],xi1[2][2]},
|
{xi1[1][0], xi1[1][1], xi1[1][2]},
|
||||||
{-propagatedQuaternion[0],-propagatedQuaternion[1],-propagatedQuaternion[2]}};
|
{xi1[2][0], xi1[2][1], xi1[2][2]},
|
||||||
|
{-propagatedQuaternion[0], -propagatedQuaternion[1], -propagatedQuaternion[2]}};
|
||||||
|
|
||||||
double errQuatTerm[4] = {0,0,0,0};
|
double errQuatTerm[4] = {0, 0, 0, 0};
|
||||||
MatrixOperations<double>::multiply(*xi, errStateQuat, errQuatTerm, 4, 3, 1);
|
MatrixOperations<double>::multiply(*xi, errStateQuat, errQuatTerm, 4, 3, 1);
|
||||||
VectorOperations<double>::mulScalar(errQuatTerm, 0.5, errQuatTerm, 4);
|
VectorOperations<double>::mulScalar(errQuatTerm, 0.5, errQuatTerm, 4);
|
||||||
VectorOperations<double>::add(propagatedQuaternion, errQuatTerm, quatBJ, 4);
|
VectorOperations<double>::add(propagatedQuaternion, errQuatTerm, quatBJ, 4);
|
||||||
@ -971,28 +918,27 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(
|
|||||||
outputQuat[2] = quatBJ[2];
|
outputQuat[2] = quatBJ[2];
|
||||||
outputQuat[3] = quatBJ[3];
|
outputQuat[3] = quatBJ[3];
|
||||||
|
|
||||||
double updatedGyroBias[3] = {0,0,0};
|
double updatedGyroBias[3] = {0, 0, 0};
|
||||||
VectorOperations<double>::add(biasRMU, errStateGyroBias, updatedGyroBias, 3);
|
VectorOperations<double>::add(biasGYR, errStateGyroBias, updatedGyroBias, 3);
|
||||||
// Bias RMU State
|
// Bias GYR State
|
||||||
biasRMU[0] = updatedGyroBias[0];
|
biasGYR[0] = updatedGyroBias[0];
|
||||||
biasRMU[1] = updatedGyroBias[1];
|
biasGYR[1] = updatedGyroBias[1];
|
||||||
biasRMU[2] = updatedGyroBias[2];
|
biasGYR[2] = updatedGyroBias[2];
|
||||||
|
|
||||||
|
|
||||||
/* ----------- PROPAGATION ----------*/
|
/* ----------- PROPAGATION ----------*/
|
||||||
//double sigmaU = kalmanFilterParameters->sensorNoiseBsRMU;
|
// double sigmaU = kalmanFilterParameters->sensorNoiseBsGYR;
|
||||||
//double sigmaV = kalmanFilterParameters->sensorNoiseArwRmu;
|
// double sigmaV = kalmanFilterParameters->sensorNoiseArwGYR;
|
||||||
double sigmaU = 3*3.141/180/3600;
|
double sigmaU = 3 * 3.141 / 180 / 3600;
|
||||||
double sigmaV = 3*0.0043*3.141/sqrt(10)/180;
|
double sigmaV = 3 * 0.0043 * 3.141 / sqrt(10) / 180;
|
||||||
|
|
||||||
double discTimeMatrix[6][6] = {{-1,0,0,0,0,0},{0,-1,0,0,0,0},{0,0,-1,0,0,0},
|
double discTimeMatrix[6][6] = {{-1, 0, 0, 0, 0, 0}, {0, -1, 0, 0, 0, 0}, {0, 0, -1, 0, 0, 0},
|
||||||
{0,0,0,1,0,0},{0,0,0,0,1,0},{0,0,0,0,0,1}};
|
{0, 0, 0, 1, 0, 0}, {0, 0, 0, 0, 1, 0}, {0, 0, 0, 0, 0, 1}};
|
||||||
double rotRateEst[3] = {0,0,0};
|
double rotRateEst[3] = {0, 0, 0};
|
||||||
VectorOperations<double>::subtract(rateRMUs_, updatedGyroBias, rotRateEst, 3);
|
VectorOperations<double>::subtract(rateGYRs_, updatedGyroBias, rotRateEst, 3);
|
||||||
double normRotEst =VectorOperations<double>::norm(rotRateEst, 3);
|
double normRotEst = VectorOperations<double>::norm(rotRateEst, 3);
|
||||||
double crossRotEst[3][3] = {{0,-rotRateEst[2],rotRateEst[1]},
|
double crossRotEst[3][3] = {{0, -rotRateEst[2], rotRateEst[1]},
|
||||||
{rotRateEst[2],0,-rotRateEst[0]},
|
{rotRateEst[2], 0, -rotRateEst[0]},
|
||||||
{-rotRateEst[1],rotRateEst[0],0}};
|
{-rotRateEst[1], rotRateEst[0], 0}};
|
||||||
|
|
||||||
// Corrected Sat Rate via Bias
|
// Corrected Sat Rate via Bias
|
||||||
outputSatRate[0] = rotRateEst[0];
|
outputSatRate[0] = rotRateEst[0];
|
||||||
@ -1000,19 +946,19 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(
|
|||||||
outputSatRate[2] = rotRateEst[2];
|
outputSatRate[2] = rotRateEst[2];
|
||||||
|
|
||||||
// Discrete Process Noise Covariance Q
|
// Discrete Process Noise Covariance Q
|
||||||
double discProcessNoiseCov[6][6] = {{0,0,0,0,0,0},{0,0,0,0,0,0},
|
double discProcessNoiseCov[6][6] = {{0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0},
|
||||||
{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0}};
|
{0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}};
|
||||||
double covQ1[3][3] = {{0,0,0},{0,0,0},{0,0,0}},
|
double covQ1[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||||
covQ2[3][3] = {{0,0,0},{0,0,0},{0,0,0}},
|
covQ2[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||||
covQ3[3][3] = {{0,0,0},{0,0,0},{0,0,0}},
|
covQ3[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||||
transCovQ2[3][3] = {{0,0,0},{0,0,0},{0,0,0}};
|
transCovQ2[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
||||||
if(normRotEst*sampleTime< 3.141/10){
|
if (normRotEst * sampleTime < 3.141 / 10) {
|
||||||
double fact1 = sampleTime*pow(sigmaV,2)+pow(sampleTime,3)*pow(sigmaU,2/3);
|
double fact1 = sampleTime * pow(sigmaV, 2) + pow(sampleTime, 3) * pow(sigmaU, 2 / 3);
|
||||||
MatrixOperations<double>::multiplyScalar(*identityMatrix3, fact1, *covQ1, 3, 3);
|
MatrixOperations<double>::multiplyScalar(*identityMatrix3, fact1, *covQ1, 3, 3);
|
||||||
double fact2 = -(0.5*pow(sampleTime,2)*pow(sigmaU,2));
|
double fact2 = -(0.5 * pow(sampleTime, 2) * pow(sigmaU, 2));
|
||||||
MatrixOperations<double>::multiplyScalar(*identityMatrix3, fact2, *covQ2, 3, 3);
|
MatrixOperations<double>::multiplyScalar(*identityMatrix3, fact2, *covQ2, 3, 3);
|
||||||
MatrixOperations<double>::transpose(*covQ2, *transCovQ2, 3);
|
MatrixOperations<double>::transpose(*covQ2, *transCovQ2, 3);
|
||||||
double fact3 = sampleTime*pow(sigmaU,2);
|
double fact3 = sampleTime * pow(sigmaU, 2);
|
||||||
MatrixOperations<double>::multiplyScalar(*identityMatrix3, fact3, *covQ3, 3, 3);
|
MatrixOperations<double>::multiplyScalar(*identityMatrix3, fact3, *covQ3, 3, 3);
|
||||||
|
|
||||||
discProcessNoiseCov[0][0] = covQ1[0][0];
|
discProcessNoiseCov[0][0] = covQ1[0][0];
|
||||||
@ -1051,34 +997,35 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(
|
|||||||
discProcessNoiseCov[5][3] = covQ3[2][0];
|
discProcessNoiseCov[5][3] = covQ3[2][0];
|
||||||
discProcessNoiseCov[5][4] = covQ3[2][1];
|
discProcessNoiseCov[5][4] = covQ3[2][1];
|
||||||
discProcessNoiseCov[5][5] = covQ3[2][2];
|
discProcessNoiseCov[5][5] = covQ3[2][2];
|
||||||
}
|
} else {
|
||||||
else{
|
// double fact1 = sampleTime*pow(sigmaV,2);
|
||||||
//double fact1 = sampleTime*pow(sigmaV,2);
|
double covQ11[3][3], covQ12[3][3], covQ13[3][3];
|
||||||
double covQ11[3][3],covQ12[3][3],covQ13[3][3];
|
// MatrixOperations<double>::multiplyScalar(*identityMatrix3, fact1, *covQ1, 3, 3);
|
||||||
//MatrixOperations<double>::multiplyScalar(*identityMatrix3, fact1, *covQ1, 3, 3);
|
double fact1 = (2 * normRotEst + sampleTime - 2 * sin(normRotEst * sampleTime) -
|
||||||
double fact1 = (2*normRotEst+sampleTime-2*sin(normRotEst*sampleTime)
|
pow(normRotEst, 3) / 3 * pow(sampleTime, 3)) /
|
||||||
-pow(normRotEst,3)/3*pow(sampleTime,3))/pow(normRotEst,5);
|
pow(normRotEst, 5);
|
||||||
MatrixOperations<double>::multiply(*crossRotEst, *crossRotEst, *covQ11, 3, 3, 3);
|
MatrixOperations<double>::multiply(*crossRotEst, *crossRotEst, *covQ11, 3, 3, 3);
|
||||||
MatrixOperations<double>::multiplyScalar(*covQ11, fact1, *covQ11, 3, 3);
|
MatrixOperations<double>::multiplyScalar(*covQ11, fact1, *covQ11, 3, 3);
|
||||||
double fact2 = pow(sampleTime,3);
|
double fact2 = pow(sampleTime, 3);
|
||||||
MatrixOperations<double>::multiplyScalar(*identityMatrix3, fact2, *covQ12, 3, 3);
|
MatrixOperations<double>::multiplyScalar(*identityMatrix3, fact2, *covQ12, 3, 3);
|
||||||
MatrixOperations<double>::subtract(*covQ12, *covQ11, *covQ11, 3, 3);
|
MatrixOperations<double>::subtract(*covQ12, *covQ11, *covQ11, 3, 3);
|
||||||
double fact3 = sampleTime*pow(sigmaV,2);
|
double fact3 = sampleTime * pow(sigmaV, 2);
|
||||||
MatrixOperations<double>::multiplyScalar(*identityMatrix3, fact3, *covQ13, 3, 3);
|
MatrixOperations<double>::multiplyScalar(*identityMatrix3, fact3, *covQ13, 3, 3);
|
||||||
MatrixOperations<double>::add(*covQ13, *covQ11, *covQ1, 3, 3);
|
MatrixOperations<double>::add(*covQ13, *covQ11, *covQ1, 3, 3);
|
||||||
|
|
||||||
double covQ21[3][3], covQ22[3][3], covQ23[3][3];
|
double covQ21[3][3], covQ22[3][3], covQ23[3][3];
|
||||||
double fact4 = (0.5*pow(normRotEst,2)*pow(sampleTime,2)
|
double fact4 =
|
||||||
+cos(normRotEst*sampleTime)-1)/pow(normRotEst,4);
|
(0.5 * pow(normRotEst, 2) * pow(sampleTime, 2) + cos(normRotEst * sampleTime) - 1) /
|
||||||
|
pow(normRotEst, 4);
|
||||||
MatrixOperations<double>::multiply(*crossRotEst, *crossRotEst, *covQ21, 3, 3, 3);
|
MatrixOperations<double>::multiply(*crossRotEst, *crossRotEst, *covQ21, 3, 3, 3);
|
||||||
MatrixOperations<double>::multiplyScalar(*covQ21, fact4, *covQ21, 3, 3);
|
MatrixOperations<double>::multiplyScalar(*covQ21, fact4, *covQ21, 3, 3);
|
||||||
double fact5 = 0.5*pow(sampleTime,2);
|
double fact5 = 0.5 * pow(sampleTime, 2);
|
||||||
MatrixOperations<double>::multiplyScalar(*identityMatrix3, fact5, *covQ22, 3, 3);
|
MatrixOperations<double>::multiplyScalar(*identityMatrix3, fact5, *covQ22, 3, 3);
|
||||||
MatrixOperations<double>::add(*covQ22, *covQ21, *covQ21, 3, 3);
|
MatrixOperations<double>::add(*covQ22, *covQ21, *covQ21, 3, 3);
|
||||||
double fact6 = normRotEst*sampleTime-sin(normRotEst*sampleTime)/pow(normRotEst,3);
|
double fact6 = normRotEst * sampleTime - sin(normRotEst * sampleTime) / pow(normRotEst, 3);
|
||||||
MatrixOperations<double>::multiplyScalar(*crossRotEst, fact6, *covQ23, 3, 3);
|
MatrixOperations<double>::multiplyScalar(*crossRotEst, fact6, *covQ23, 3, 3);
|
||||||
MatrixOperations<double>::subtract(*covQ23, *covQ21, *covQ21, 3, 3);
|
MatrixOperations<double>::subtract(*covQ23, *covQ21, *covQ21, 3, 3);
|
||||||
double fact7 = pow(sigmaU,2);
|
double fact7 = pow(sigmaU, 2);
|
||||||
MatrixOperations<double>::multiplyScalar(*covQ21, fact7, *covQ2, 3, 3);
|
MatrixOperations<double>::multiplyScalar(*covQ21, fact7, *covQ2, 3, 3);
|
||||||
|
|
||||||
MatrixOperations<double>::multiplyScalar(*identityMatrix3, fact7, *covQ3, 3, 3);
|
MatrixOperations<double>::multiplyScalar(*identityMatrix3, fact7, *covQ3, 3, 3);
|
||||||
@ -1122,24 +1069,24 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// State Transition Matrix phi
|
// State Transition Matrix phi
|
||||||
double phi1[3][3] = {{0,0,0},{0,0,0},{0,0,0}},
|
double phi1[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||||
phi2[3][3] = {{0,0,0},{0,0,0},{0,0,0}},
|
phi2[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||||
phi[6][6] = {{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},
|
phi[6][6] = {{0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0},
|
||||||
{0,0,0,1,0,0},{0,0,0,0,1,0},{0,0,0,0,0,1}};
|
{0, 0, 0, 1, 0, 0}, {0, 0, 0, 0, 1, 0}, {0, 0, 0, 0, 0, 1}};
|
||||||
double phi11[3][3],phi12[3][3];
|
double phi11[3][3], phi12[3][3];
|
||||||
double fact1 = sin(normRotEst*sampleTime);
|
double fact1 = sin(normRotEst * sampleTime);
|
||||||
MatrixOperations<double>::multiplyScalar(*crossRotEst, fact1, *phi11, 3, 3);
|
MatrixOperations<double>::multiplyScalar(*crossRotEst, fact1, *phi11, 3, 3);
|
||||||
double fact2 = (1-cos(normRotEst*sampleTime))/pow(normRotEst,2);
|
double fact2 = (1 - cos(normRotEst * sampleTime)) / pow(normRotEst, 2);
|
||||||
MatrixOperations<double>::multiply(*crossRotEst, *crossRotEst, *phi12, 3, 3, 3);
|
MatrixOperations<double>::multiply(*crossRotEst, *crossRotEst, *phi12, 3, 3, 3);
|
||||||
MatrixOperations<double>::multiplyScalar(*phi12, fact2, *phi12, 3, 3);
|
MatrixOperations<double>::multiplyScalar(*phi12, fact2, *phi12, 3, 3);
|
||||||
MatrixOperations<double>::subtract(*identityMatrix3, *phi11, *phi11, 3, 3);
|
MatrixOperations<double>::subtract(*identityMatrix3, *phi11, *phi11, 3, 3);
|
||||||
MatrixOperations<double>::add(*phi11, *phi12, *phi1, 3, 3);
|
MatrixOperations<double>::add(*phi11, *phi12, *phi1, 3, 3);
|
||||||
|
|
||||||
double phi21[3][3],phi22[3][3];
|
double phi21[3][3], phi22[3][3];
|
||||||
MatrixOperations<double>::multiplyScalar(*crossRotEst, fact2, *phi21, 3, 3);
|
MatrixOperations<double>::multiplyScalar(*crossRotEst, fact2, *phi21, 3, 3);
|
||||||
MatrixOperations<double>::multiplyScalar(*identityMatrix3, sampleTime, *phi22, 3, 3);
|
MatrixOperations<double>::multiplyScalar(*identityMatrix3, sampleTime, *phi22, 3, 3);
|
||||||
MatrixOperations<double>::subtract(*phi21, *phi22, *phi21, 3, 3);
|
MatrixOperations<double>::subtract(*phi21, *phi22, *phi21, 3, 3);
|
||||||
double fact3 = (normRotEst*sampleTime-sin(normRotEst*sampleTime)/pow(normRotEst,3));
|
double fact3 = (normRotEst * sampleTime - sin(normRotEst * sampleTime) / pow(normRotEst, 3));
|
||||||
MatrixOperations<double>::multiply(*crossRotEst, *crossRotEst, *phi22, 3, 3, 3);
|
MatrixOperations<double>::multiply(*crossRotEst, *crossRotEst, *phi22, 3, 3, 3);
|
||||||
MatrixOperations<double>::multiplyScalar(*phi22, fact3, *phi22, 3, 3);
|
MatrixOperations<double>::multiplyScalar(*phi22, fact3, *phi22, 3, 3);
|
||||||
MatrixOperations<double>::subtract(*phi21, *phi22, *phi2, 3, 3);
|
MatrixOperations<double>::subtract(*phi21, *phi22, *phi2, 3, 3);
|
||||||
@ -1164,10 +1111,9 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(
|
|||||||
phi[2][5] = phi2[2][2];
|
phi[2][5] = phi2[2][2];
|
||||||
|
|
||||||
// Propagated Quaternion
|
// Propagated Quaternion
|
||||||
double rotSin[3] = {0,0,0},
|
double rotSin[3] = {0, 0, 0}, omega1[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
||||||
omega1[3][3] = {{0,0,0},{0,0,0},{0,0,0}};
|
double rotCos = cos(0.5 * normRotEst * sampleTime);
|
||||||
double rotCos = cos(0.5*normRotEst*sampleTime);
|
double sinFac = sin(0.5 * normRotEst * sampleTime) / normRotEst;
|
||||||
double sinFac = sin(0.5*normRotEst*sampleTime)/normRotEst;
|
|
||||||
VectorOperations<double>::mulScalar(rotRateEst, sinFac, rotSin, 3);
|
VectorOperations<double>::mulScalar(rotRateEst, sinFac, rotSin, 3);
|
||||||
|
|
||||||
double skewSin[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
double skewSin[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
||||||
@ -1175,15 +1121,14 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(
|
|||||||
|
|
||||||
MatrixOperations<double>::multiplyScalar(*identityMatrix3, rotCos, *omega1, 3, 3);
|
MatrixOperations<double>::multiplyScalar(*identityMatrix3, rotCos, *omega1, 3, 3);
|
||||||
MatrixOperations<double>::subtract(*omega1, *skewSin, *omega1, 3, 3);
|
MatrixOperations<double>::subtract(*omega1, *skewSin, *omega1, 3, 3);
|
||||||
double omega[4][4] = {{omega1[0][0],omega1[0][1],omega1[0][2],rotSin[0]},
|
double omega[4][4] = {{omega1[0][0], omega1[0][1], omega1[0][2], rotSin[0]},
|
||||||
{omega1[1][0],omega1[1][1],omega1[1][2],rotSin[1]},
|
{omega1[1][0], omega1[1][1], omega1[1][2], rotSin[1]},
|
||||||
{omega1[2][0],omega1[2][1],omega1[2][2],rotSin[2]},
|
{omega1[2][0], omega1[2][1], omega1[2][2], rotSin[2]},
|
||||||
{-rotSin[0],-rotSin[1],-rotSin[2],rotCos}};
|
{-rotSin[0], -rotSin[1], -rotSin[2], rotCos}};
|
||||||
MatrixOperations<double>::multiply(*omega, quatBJ, propagatedQuaternion, 4, 4, 1);
|
MatrixOperations<double>::multiply(*omega, quatBJ, propagatedQuaternion, 4, 4, 1);
|
||||||
|
|
||||||
// Update Covariance Matrix
|
// Update Covariance Matrix
|
||||||
double cov1[6][6], cov2[6][6], transDiscTimeMatrix[6][6],
|
double cov1[6][6], cov2[6][6], transDiscTimeMatrix[6][6], transPhi[6][6];
|
||||||
transPhi[6][6];
|
|
||||||
MatrixOperations<double>::transpose(*discTimeMatrix, *transDiscTimeMatrix, 6);
|
MatrixOperations<double>::transpose(*discTimeMatrix, *transDiscTimeMatrix, 6);
|
||||||
MatrixOperations<double>::multiply(*discProcessNoiseCov, *transDiscTimeMatrix, *cov1, 6, 6, 6);
|
MatrixOperations<double>::multiply(*discProcessNoiseCov, *transDiscTimeMatrix, *cov1, 6, 6, 6);
|
||||||
MatrixOperations<double>::multiply(*discTimeMatrix, *cov1, *cov1, 6, 6, 6);
|
MatrixOperations<double>::multiply(*discTimeMatrix, *cov1, *cov1, 6, 6, 6);
|
||||||
@ -1195,7 +1140,6 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(
|
|||||||
MatrixOperations<double>::add(*cov2, *cov1, *initialCovarianceMatrix, 6, 6);
|
MatrixOperations<double>::add(*cov2, *cov1, *initialCovarianceMatrix, 6, 6);
|
||||||
validMekf = true;
|
validMekf = true;
|
||||||
|
|
||||||
|
|
||||||
// Discrete Time Step
|
// Discrete Time Step
|
||||||
|
|
||||||
// Check for new data in measurement -> SensorProcessing ?
|
// Check for new data in measurement -> SensorProcessing ?
|
||||||
|
@ -7,22 +7,24 @@
|
|||||||
* @brief: This class handles the calculation of an estimated quaternion and the gyro bias by
|
* @brief: This class handles the calculation of an estimated quaternion and the gyro bias by
|
||||||
* means of the spacecraft attitude sensors
|
* means of the spacecraft attitude sensors
|
||||||
*
|
*
|
||||||
* @note: A description of the used algorithms can be found in the bachelor thesis of Robin Marquardt
|
* @note: A description of the used algorithms can be found in the bachelor thesis of Robin
|
||||||
|
* Marquardt
|
||||||
* https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_Studenten/Marquardt_Robin&openfile=500811
|
* https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_Studenten/Marquardt_Robin&openfile=500811
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef MULTIPLICATIVEKALMANFILTER_H_
|
#ifndef MULTIPLICATIVEKALMANFILTER_H_
|
||||||
#define MULTIPLICATIVEKALMANFILTER_H_
|
#define MULTIPLICATIVEKALMANFILTER_H_
|
||||||
|
|
||||||
#include "config/classIds.h"
|
|
||||||
#include <stdint.h> //uint8_t
|
#include <stdint.h> //uint8_t
|
||||||
#include <time.h> /*purpose, timeval ?*/
|
#include <time.h> /*purpose, timeval ?*/
|
||||||
|
|
||||||
|
#include "config/classIds.h"
|
||||||
//#include <_timeval.h>
|
//#include <_timeval.h>
|
||||||
|
|
||||||
#include "AcsParameters.h"
|
#include "AcsParameters.h"
|
||||||
|
|
||||||
class MultiplicativeKalmanFilter{
|
class MultiplicativeKalmanFilter {
|
||||||
public:
|
public:
|
||||||
/* @brief: Constructor
|
/* @brief: Constructor
|
||||||
* @param: acsParameters_ Pointer to object which defines the ACS configuration parameters
|
* @param: acsParameters_ Pointer to object which defines the ACS configuration parameters
|
||||||
*/
|
*/
|
||||||
@ -31,77 +33,69 @@ public:
|
|||||||
|
|
||||||
void reset(); // NOT YET DEFINED - should only reset all mekf variables
|
void reset(); // NOT YET DEFINED - should only reset all mekf variables
|
||||||
|
|
||||||
/* @brief: init() - This function initializes the Kalman Filter and will provide the first quaternion through
|
/* @brief: init() - This function initializes the Kalman Filter and will provide the first
|
||||||
* the QUEST algorithm
|
* quaternion through the QUEST algorithm
|
||||||
* @param: magneticField_ magnetic field vector in the body frame
|
* @param: magneticField_ magnetic field vector in the body frame
|
||||||
* sunDir_ sun direction vector in the body frame
|
* sunDir_ sun direction vector in the body frame
|
||||||
* sunDirJ sun direction vector in the ECI frame
|
* sunDirJ sun direction vector in the ECI frame
|
||||||
* magFieldJ magnetic field vector in the ECI frame
|
* magFieldJ magnetic field vector in the ECI frame
|
||||||
*/
|
*/
|
||||||
void init(const double *magneticField_, const bool *validMagField_,
|
void init(const double *magneticField_, const bool *validMagField_, const double *sunDir_,
|
||||||
const double *sunDir_, const bool *validSS,
|
const bool *validSS, const double *sunDirJ, const bool *validSSModel,
|
||||||
const double *sunDirJ, const bool *validSSModel,
|
const double *magFieldJ, const bool *validMagModel);
|
||||||
const double *magFieldJ,const bool *validMagModel);
|
|
||||||
|
|
||||||
/* @brief: mekfEst() - This function calculates the quaternion and gyro bias of the Kalman Filter for the current step
|
/* @brief: mekfEst() - This function calculates the quaternion and gyro bias of the Kalman Filter
|
||||||
* after the initalization
|
* for the current step after the initalization
|
||||||
* @param: quaternionSTR Star Tracker Quaternion between from body to ECI frame
|
* @param: quaternionSTR Star Tracker Quaternion between from body to ECI frame
|
||||||
* rateRMUs_ Estimated satellite rotation rate from the Rate Measurement Units [rad/s]
|
* rateGYRs_ Estimated satellite rotation rate from the
|
||||||
* magneticField_ magnetic field vector in the body frame
|
* Gyroscopes [rad/s] magneticField_ magnetic field vector in the body frame sunDir_
|
||||||
* sunDir_ sun direction vector in the body frame
|
* sun direction vector in the body frame sunDirJ sun direction vector in the ECI
|
||||||
* sunDirJ sun direction vector in the ECI frame
|
* frame magFieldJ magnetic field vector in the ECI frame
|
||||||
* magFieldJ magnetic field vector in the ECI frame
|
|
||||||
* outputQuat Stores the calculated quaternion
|
* outputQuat Stores the calculated quaternion
|
||||||
* outputSatRate Stores the adjusted satellite rate
|
* outputSatRate Stores the adjusted satellite rate
|
||||||
* @return ReturnValue_t Feedback of this class, KALMAN_NO_RMU_MEAS if no satellite rate from the sensors was provided,
|
* @return ReturnValue_t Feedback of this class, KALMAN_NO_GYR_MEAS if no satellite rate from
|
||||||
* KALMAN_NO_MODEL if no sunDirJ or magFieldJ was given from the model calculations,
|
* the sensors was provided, KALMAN_NO_MODEL if no sunDirJ or magFieldJ was given from the model
|
||||||
* KALMAN_INVERSION_FAILED if the calculation of the Gain matrix was not possible,
|
* calculations, KALMAN_INVERSION_FAILED if the calculation of the Gain matrix was not possible,
|
||||||
* RETURN_OK else
|
* RETURN_OK else
|
||||||
*/
|
*/
|
||||||
ReturnValue_t mekfEst(
|
ReturnValue_t mekfEst(const double *quaternionSTR, const bool *validSTR_, const double *rateGYRs_,
|
||||||
const double *quaternionSTR, const bool *validSTR_,
|
const bool *validGYRs_, const double *magneticField_,
|
||||||
const double *rateRMUs_, const bool *validRMUs_,
|
const bool *validMagField_, const double *sunDir_, const bool *validSS,
|
||||||
const double *magneticField_, const bool *validMagField_,
|
const double *sunDirJ, const bool *validSSModel, const double *magFieldJ,
|
||||||
const double *sunDir_, const bool *validSS,
|
const bool *validMagModel, double *outputQuat, double *outputSatRate);
|
||||||
const double *sunDirJ, const bool *validSSModel,
|
|
||||||
const double *magFieldJ,const bool *validMagModel,
|
|
||||||
double *outputQuat, double *outputSatRate);
|
|
||||||
|
|
||||||
|
|
||||||
// Declaration of Events (like init) and memberships
|
// Declaration of Events (like init) and memberships
|
||||||
//static const uint8_t INTERFACE_ID = CLASS_ID::MEKF; //CLASS IDS ND (/config/returnvalues/classIDs.h)
|
// static const uint8_t INTERFACE_ID = CLASS_ID::MEKF; //CLASS IDS ND
|
||||||
//static const Event RESET = MAKE_EVENT(1,severity::INFO);//typedef uint32_t Event (Event.h), should be
|
// (/config/returnvalues/classIDs.h) static const Event RESET =
|
||||||
|
// MAKE_EVENT(1,severity::INFO);//typedef uint32_t Event (Event.h), should be
|
||||||
// resetting Mekf
|
// resetting Mekf
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::KALMAN;
|
static const uint8_t INTERFACE_ID = CLASS_ID::KALMAN;
|
||||||
static const ReturnValue_t KALMAN_NO_RMU_MEAS = MAKE_RETURN_CODE(0x01);
|
static const ReturnValue_t KALMAN_NO_GYR_MEAS = MAKE_RETURN_CODE(0x01);
|
||||||
static const ReturnValue_t KALMAN_NO_MODEL = MAKE_RETURN_CODE(0x02);
|
static const ReturnValue_t KALMAN_NO_MODEL = MAKE_RETURN_CODE(0x02);
|
||||||
static const ReturnValue_t KALMAN_INVERSION_FAILED = MAKE_RETURN_CODE(0x03);
|
static const ReturnValue_t KALMAN_INVERSION_FAILED = MAKE_RETURN_CODE(0x03);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*Parameters*/
|
/*Parameters*/
|
||||||
AcsParameters::InertiaEIVE* inertiaEIVE;
|
AcsParameters::InertiaEIVE *inertiaEIVE;
|
||||||
AcsParameters::KalmanFilterParameters* kalmanFilterParameters;
|
AcsParameters::KalmanFilterParameters *kalmanFilterParameters;
|
||||||
double quaternion_STR_SB[4];
|
double quaternion_STR_SB[4];
|
||||||
bool validInit;
|
bool validInit;
|
||||||
double sampleTime = 0.1;
|
double sampleTime = 0.1;
|
||||||
|
|
||||||
|
/*States*/
|
||||||
/*States*/
|
|
||||||
double initialQuaternion[4]; /*after reset?QUEST*/
|
double initialQuaternion[4]; /*after reset?QUEST*/
|
||||||
double initialCovarianceMatrix[6][6];/*after reset?QUEST*/
|
double initialCovarianceMatrix[6][6]; /*after reset?QUEST*/
|
||||||
double propagatedQuaternion[4]; /*Filter Quaternion for next step*/
|
double propagatedQuaternion[4]; /*Filter Quaternion for next step*/
|
||||||
bool validMekf;
|
bool validMekf;
|
||||||
uint8_t sensorsAvail;
|
uint8_t sensorsAvail;
|
||||||
|
|
||||||
/*Outputs*/
|
/*Outputs*/
|
||||||
double quatBJ[4]; /* Output Quaternion */
|
double quatBJ[4]; /* Output Quaternion */
|
||||||
double biasRMU[3]; /*Between measured and estimated sat Rate*/
|
double biasGYR[3]; /*Between measured and estimated sat Rate*/
|
||||||
/*Parameter INIT*/
|
/*Parameter INIT*/
|
||||||
//double alpha, gamma, beta;
|
// double alpha, gamma, beta;
|
||||||
/*Functions*/
|
/*Functions*/
|
||||||
void loadAcsParameters(AcsParameters *acsParameters_);
|
void loadAcsParameters(AcsParameters *acsParameters_);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* ACS_MULTIPLICATIVEKALMANFILTER_H_ */
|
#endif /* ACS_MULTIPLICATIVEKALMANFILTER_H_ */
|
||||||
|
@ -36,8 +36,7 @@ void Navigation::useMekf(ACS::SensorValues *sensorValues, ACS::OutputValues *out
|
|||||||
&outputValues->sunDirEstValid, outputValues->sunDirModel, &outputValues->sunDirModelValid,
|
&outputValues->sunDirEstValid, outputValues->sunDirModel, &outputValues->sunDirModelValid,
|
||||||
outputValues->magFieldModel, &outputValues->magFieldModelValid, outputValues->quatMekfBJ,
|
outputValues->magFieldModel, &outputValues->magFieldModelValid, outputValues->quatMekfBJ,
|
||||||
outputValues->satRateMekf); // VALIDS FOR QUAT AND RATE ??
|
outputValues->satRateMekf); // VALIDS FOR QUAT AND RATE ??
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
multiplicativeKalmanFilter.init(outputValues->magFieldEst, &outputValues->magFieldEstValid,
|
multiplicativeKalmanFilter.init(outputValues->magFieldEst, &outputValues->magFieldEstValid,
|
||||||
outputValues->sunDirEst, &outputValues->sunDirEstValid,
|
outputValues->sunDirEst, &outputValues->sunDirEstValid,
|
||||||
outputValues->sunDirModel, &outputValues->sunDirModelValid,
|
outputValues->sunDirModel, &outputValues->sunDirModelValid,
|
||||||
@ -45,7 +44,8 @@ void Navigation::useMekf(ACS::SensorValues *sensorValues, ACS::OutputValues *out
|
|||||||
kalmanInit = true;
|
kalmanInit = true;
|
||||||
*mekfValid = 0;
|
*mekfValid = 0;
|
||||||
|
|
||||||
// Maybe we need feedback from kalmanfilter to identify if there was a problem with the init
|
// Maybe we need feedback from kalmanfilter to identify if there was a problem with the
|
||||||
//of kalman filter where does this class know from that kalman filter was not initialized ?
|
// init of kalman filter where does this class know from that kalman filter was not
|
||||||
|
// initialized ?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -123,7 +123,7 @@ void PtgCtrl::ptgDesaturation(double *magFieldEst, bool *magFieldEstValid, doubl
|
|||||||
}
|
}
|
||||||
|
|
||||||
// calculating momentum of satellite and momentum of reaction wheels
|
// calculating momentum of satellite and momentum of reaction wheels
|
||||||
double speedRws[4] = {*speedRw0, *speedRw1, *speedRw2, *speedRw3};
|
double speedRws[4] = {(double)*speedRw0, (double)*speedRw1, (double)*speedRw2, (double)*speedRw3};
|
||||||
double momentumRwU[4] = {0, 0, 0, 0}, momentumRw[3] = {0, 0, 0};
|
double momentumRwU[4] = {0, 0, 0, 0}, momentumRw[3] = {0, 0, 0};
|
||||||
VectorOperations<double>::mulScalar(speedRws, rwHandlingParameters->inertiaWheel, momentumRwU, 4);
|
VectorOperations<double>::mulScalar(speedRws, rwHandlingParameters->inertiaWheel, momentumRwU, 4);
|
||||||
MatrixOperations<double>::multiply(*(rwMatrices->alignmentMatrix), momentumRwU, momentumRw, 3, 4,
|
MatrixOperations<double>::multiply(*(rwMatrices->alignmentMatrix), momentumRwU, momentumRw, 3, 4,
|
||||||
@ -145,7 +145,7 @@ void PtgCtrl::ptgDesaturation(double *magFieldEst, bool *magFieldEstValid, doubl
|
|||||||
|
|
||||||
void PtgCtrl::ptgNullspace(const int32_t *speedRw0, const int32_t *speedRw1,
|
void PtgCtrl::ptgNullspace(const int32_t *speedRw0, const int32_t *speedRw1,
|
||||||
const int32_t *speedRw2, const int32_t *speedRw3, double *rwTrqNs) {
|
const int32_t *speedRw2, const int32_t *speedRw3, double *rwTrqNs) {
|
||||||
double speedRws[4] = {*speedRw0, *speedRw1, *speedRw2, *speedRw3};
|
double speedRws[4] = {(double)*speedRw0, (double)*speedRw1, (double)*speedRw2, (double)*speedRw3};
|
||||||
double wheelMomentum[4] = {0, 0, 0, 0};
|
double wheelMomentum[4] = {0, 0, 0, 0};
|
||||||
double rpmOffset[4] = {1, 1, 1, -1}, factor = 350 * 2 * Math::PI / 60;
|
double rpmOffset[4] = {1, 1, 1, -1}, factor = 350 * 2 * Math::PI / 60;
|
||||||
// Conversion to [rad/s] for further calculations
|
// Conversion to [rad/s] for further calculations
|
||||||
|
Loading…
Reference in New Issue
Block a user