fixed int32_t to double warnings. reformats

This commit is contained in:
Marius Eggert 2022-10-24 10:29:57 +02:00
parent 0d3509b991
commit 8b23fd3dd2
4 changed files with 1186 additions and 1248 deletions

View File

@ -6,115 +6,97 @@
*/
#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/QuaternionOperations.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*/
MultiplicativeKalmanFilter::MultiplicativeKalmanFilter(AcsParameters *acsParameters_) :
initialQuaternion { 0.5, 0.5, 0.5, 0.5 },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}}{
MultiplicativeKalmanFilter::MultiplicativeKalmanFilter(AcsParameters *acsParameters_)
: initialQuaternion{0.5, 0.5, 0.5, 0.5},
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}} {
loadAcsParameters(acsParameters_);
}
MultiplicativeKalmanFilter::~MultiplicativeKalmanFilter() {
MultiplicativeKalmanFilter::~MultiplicativeKalmanFilter() {}
}
void MultiplicativeKalmanFilter::loadAcsParameters(
AcsParameters *acsParameters_) {
void MultiplicativeKalmanFilter::loadAcsParameters(AcsParameters *acsParameters_) {
inertiaEIVE = &(acsParameters_->inertiaEIVE);
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_, const bool *validSS,
const double *sunDirJ, const bool *validSSModel,
const double *magFieldJ,const bool *validMagModel) { // valids for "model measurements"?
void MultiplicativeKalmanFilter::init(
const double *magneticField_, const bool *validMagField_, const double *sunDir_,
const bool *validSS, const double *sunDirJ, const bool *validSSModel, const double *magFieldJ,
const bool *validMagModel) { // valids for "model measurements"?
// check for valid mag/sun
if (*validMagField_ && *validSS && *validSSModel && *validMagModel) {
validInit = true;
//AcsParameters mekfEstParams;
//loadAcsParameters(&mekfEstParams);
// AcsParameters mekfEstParams;
// loadAcsParameters(&mekfEstParams);
// QUEST ALGO -----------------------------------------------------------------------
double sigmaSun = 0, sigmaMag = 0, sigmaGyro = 0;
sigmaSun = kalmanFilterParameters->sensorNoiseSS;
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},
normMagJ[3] = {0,0,0}, normSunJ[3] = {0,0,0};
double normMagB[3] = {0, 0, 0}, normSunB[3] = {0, 0, 0}, normMagJ[3] = {0, 0, 0},
normSunJ[3] = {0, 0, 0};
VectorOperations<double>::normalize(magneticField_, normMagB, 3); // b2
VectorOperations<double>::normalize(sunDir_, normSunB, 3); //b1
VectorOperations<double>::normalize(magFieldJ, normMagJ, 3); //r2
VectorOperations<double>::normalize(sunDirJ, normSunJ, 3); //r1
VectorOperations<double>::normalize(sunDir_, normSunB, 3); // b1
VectorOperations<double>::normalize(magFieldJ, normMagJ, 3); // r2
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(normSunB, normMagB, thirdAxis_B);
VectorOperations<double>::normalize(thirdAxis_J, thirdAxis_J, 3); //rx
VectorOperations<double>::normalize(thirdAxis_B, thirdAxis_B, 3); //bx
VectorOperations<double>::normalize(thirdAxis_J, thirdAxis_J, 3); // rx
VectorOperations<double>::normalize(thirdAxis_B, thirdAxis_B, 3); // bx
double weigthSun= 1 / (sigmaSun * sigmaSun); //a1
double weigthMag= 1 / (sigmaMag * sigmaMag); //a2
double weigthSun = 1 / (sigmaSun * sigmaSun); // a1
double weigthMag = 1 / (sigmaMag * sigmaMag); // a2
double a[3] = {0,0,0}, b[3] = {0,0,0};
VectorOperations<double>::mulScalar(normSunB, weigthSun, a, 3); //a
VectorOperations<double>::mulScalar(normMagB, weigthMag, b, 3); //b
double a[3] = {0, 0, 0}, b[3] = {0, 0, 0};
VectorOperations<double>::mulScalar(normSunB, weigthSun, a, 3); // a
VectorOperations<double>::mulScalar(normMagB, weigthMag, b, 3); // b
double thirdAxisCross[3] = {0,0,0}, weightACross[3] = {0,0,0},
weightBCross[3] = {0,0,0},weigthCrossSum[3] = {0,0,0};
double thirdAxisCross[3] = {0, 0, 0}, weightACross[3] = {0, 0, 0}, weightBCross[3] = {0, 0, 0},
weigthCrossSum[3] = {0, 0, 0};
VectorOperations<double>::cross(thirdAxis_B, thirdAxis_J,
thirdAxisCross); //cross(bx,rx)
thirdAxisCross); // cross(bx,rx)
VectorOperations<double>::cross(a, normSunJ, weightACross);
VectorOperations<double>::cross(b, normMagJ, weightBCross);
VectorOperations<double>::add(weightACross, weightBCross,
weigthCrossSum);
VectorOperations<double>::add(weightACross, weightBCross, 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(weightACross, weightBCross, sum2);
double alpha = 0, beta = 0, gamma = 0, constPlus = 0, constMin = 0;
alpha = (1 + VectorOperations<double>::dot(thirdAxis_B, thirdAxis_J))
* (VectorOperations<double>::dot(a, normSunJ)
+ VectorOperations<double>::dot(b, normMagJ))
+ VectorOperations<double>::dot(thirdAxisCross, weigthCrossSum);
alpha = (1 + VectorOperations<double>::dot(thirdAxis_B, thirdAxis_J)) *
(VectorOperations<double>::dot(a, normSunJ) +
VectorOperations<double>::dot(b, normMagJ)) +
VectorOperations<double>::dot(thirdAxisCross, weigthCrossSum);
beta = VectorOperations<double>::dot(thirdAxisSum, sum2);
gamma = sqrt(alpha * alpha + beta * beta);
constPlus = 1
/ (2
* sqrt(
gamma * (gamma + alpha)
* (1
+ VectorOperations<double>::dot(
thirdAxis_B,
thirdAxis_J))));
constMin = 1
/ (2
* sqrt(
gamma * (gamma - alpha)
* (1
+ VectorOperations<double>::dot(
thirdAxis_B,
thirdAxis_J))));
constPlus = 1 / (2 * sqrt(gamma * (gamma + alpha) *
(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*/
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) {
VectorOperations<double>::mulScalar(thirdAxisCross, gamma + alpha,
var1, 3);
VectorOperations<double>::mulScalar(thirdAxisCross, gamma + alpha, var1, 3);
VectorOperations<double>::add(thirdAxis_B, thirdAxis_J, var2, 3);
VectorOperations<double>::mulScalar(var2, beta, var2, 3);
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++) {
initialQuaternion[i] = quat[i];
}
initialQuaternion[3] = (gamma + alpha)
* (1
+ VectorOperations<double>::dot(thirdAxis_B,
thirdAxis_J));
VectorOperations<double>::mulScalar(initialQuaternion,
constPlus, initialQuaternion, 4);
initialQuaternion[3] =
(gamma + alpha) * (1 + VectorOperations<double>::dot(thirdAxis_B, thirdAxis_J));
VectorOperations<double>::mulScalar(initialQuaternion, constPlus, initialQuaternion, 4);
} else {
double diffGammaAlpha = gamma - alpha;
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++) {
initialQuaternion[i] = quat[i];
}
initialQuaternion[3] = beta
* (1
+ VectorOperations<double>::dot(thirdAxis_B,
thirdAxis_J));
VectorOperations<double>::mulScalar(initialQuaternion,
constMin, initialQuaternion, 4);
initialQuaternion[3] = beta * (1 + VectorOperations<double>::dot(thirdAxis_B, thirdAxis_J));
VectorOperations<double>::mulScalar(initialQuaternion, constMin, initialQuaternion, 4);
}
propagatedQuaternion[0] = initialQuaternion[0];
propagatedQuaternion[1] = initialQuaternion[1];
@ -151,55 +125,43 @@ void MultiplicativeKalmanFilter::init(const double *magneticField_, const bool *
propagatedQuaternion[3] = initialQuaternion[3];
/*Initial Covariance Matrix------------------------------------ */
double dcmBJ[3][3] = {{0,0,0},{0,0,0},{0,0,0}},
sunEstB[3] = {0,0,0}, magEstB[3] = {0,0,0};
double dcmBJ[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, sunEstB[3] = {0, 0, 0},
magEstB[3] = {0, 0, 0};
QuaternionOperations::toDcm(initialQuaternion, dcmBJ);
MatrixOperations<double>::multiply(*dcmBJ, normSunJ, sunEstB, 3, 3, 1);
MatrixOperations<double>::multiply(*dcmBJ, normMagJ, magEstB, 3, 3,
1);
MatrixOperations<double>::multiply(*dcmBJ, normMagJ, magEstB, 3, 3, 1);
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}},
matrixSunMag[3][3] = {{0,0,0},{0,0,0},{0,0,0}},
matrixMagSun[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}},
matrixSunMag[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)*/
MatrixOperations<double>::multiply(sunEstB, sunEstB, *matrixSun, 3, 1, 3);
MatrixOperations<double>::multiply(magEstB, magEstB, *matrixMag, 3, 1, 3);
MatrixOperations<double>::multiply(sunEstB, magEstB, *matrixSunMag, 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;
MatrixOperations<double>::multiplyScalar(*matrixSun,
weigthSun * weigthSun, *matrixSun, 3, 3);
MatrixOperations<double>::multiplyScalar(*matrixMag,
weigthMag * weigthMag, *matrixMag, 3, 3);
MatrixOperations<double>::add(*matrixSunMag, *matrixMagSun, *partA, 3,
3);
double factor = weigthMag * weigthSun
* VectorOperations<double>::dot(sunEstB, magEstB);
double partA[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, partB = 0;
MatrixOperations<double>::multiplyScalar(*matrixSun, weigthSun * weigthSun, *matrixSun, 3, 3);
MatrixOperations<double>::multiplyScalar(*matrixMag, weigthMag * weigthMag, *matrixMag, 3, 3);
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>::add(*partA, *matrixSun, *partA, 3, 3);
MatrixOperations<double>::add(*partA, *matrixMag, *partA, 3, 3);
double crossSunMag[3] = {0,0,0};
double identityMatrix3[3][3] = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } };
double crossSunMag[3] = {0, 0, 0};
double identityMatrix3[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
VectorOperations<double>::cross(sunEstB, magEstB, crossSunMag);
partB =
1
/ (weigthMag * weigthSun
* pow(
VectorOperations<double>::norm(
crossSunMag, 3), 2));
partB = 1 / (weigthMag * weigthSun * pow(VectorOperations<double>::norm(crossSunMag, 3), 2));
MatrixOperations<double>::multiplyScalar(*partA, partB, *partA, 3, 3);
MatrixOperations<double>::add(*matrixSunMag, *identityMatrix3, *partA, 3,
3);
MatrixOperations<double>::add(*matrixSunMag, *identityMatrix3, *partA, 3, 3);
factor = 1 / (weigthMag + weigthMag);
double questCovMatrix[3][3] = {{0,0,0},{0,0,0},{0,0,0}};
MatrixOperations<double>::multiplyScalar(*partA, factor,
*questCovMatrix, 3, 3);
double initGyroCov[3][3] = {{pow(sigmaGyro,2),0,0},{0,pow(sigmaGyro,2),0},
{0,0,pow(sigmaGyro,2)}};
double questCovMatrix[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MatrixOperations<double>::multiplyScalar(*partA, factor, *questCovMatrix, 3, 3);
double initGyroCov[3][3] = {
{pow(sigmaGyro, 2), 0, 0}, {0, pow(sigmaGyro, 2), 0}, {0, 0, pow(sigmaGyro, 2)}};
initialCovarianceMatrix[0][0] = questCovMatrix[0][0];
initialCovarianceMatrix[0][1] = questCovMatrix[0][1];
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][4] = initGyroCov[2][1];
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}};
} else {
// no initialisation possible, no valid measurements
@ -246,58 +208,47 @@ void MultiplicativeKalmanFilter::init(const double *magneticField_, const bool *
// --------------- MEKF DISCRETE TIME STEP -------------------------------
ReturnValue_t MultiplicativeKalmanFilter::mekfEst(
const double *quaternionSTR, const bool *validSTR_,
const double *rateRMUs_, const bool *validRMUs_,
const double *magneticField_, const bool *validMagField_,
const double *sunDir_, const bool *validSS,
const double *sunDirJ, const bool *validSSModel,
const double *magFieldJ,const bool *validMagModel,
double *outputQuat, double *outputSatRate) {
// Check for RMU Measurements
//AcsParameters mekfEstParams;
//loadAcsParameters(&mekfEstParams);
const double *quaternionSTR, const bool *validSTR_, const double *rateGYRs_,
const bool *validGYRs_, const double *magneticField_, const bool *validMagField_,
const double *sunDir_, const bool *validSS, const double *sunDirJ, const bool *validSSModel,
const double *magFieldJ, const bool *validMagModel, double *outputQuat, double *outputSatRate) {
// Check for GYR Measurements
// AcsParameters mekfEstParams;
// loadAcsParameters(&mekfEstParams);
int MDF = 0; // Matrix Dimension Factor
if (!(*validRMUs_)){
if (!(*validGYRs_)) {
validMekf = false;
return KALMAN_NO_RMU_MEAS;
return KALMAN_NO_GYR_MEAS;
}
// Check for Model Calculations
else if (!(*validSSModel) || !(*validMagModel)){
else if (!(*validSSModel) || !(*validMagModel)) {
validMekf = false;
return KALMAN_NO_MODEL;
}
// Check Measurements available from SS, MAG, STR
if (*validSS && *validMagField_ && *validSTR_){
if (*validSS && *validMagField_ && *validSTR_) {
sensorsAvail = 1;
MDF = 9;
}
else if (*validSS && *validMagField_ && !(*validSTR_)){
} else if (*validSS && *validMagField_ && !(*validSTR_)) {
sensorsAvail = 2;
MDF = 6;
}
else if (*validSS && !(*validMagField_) && *validSTR_){
} else if (*validSS && !(*validMagField_) && *validSTR_) {
sensorsAvail = 3;
MDF = 6;
}
else if (!(*validSS) && *validMagField_ && *validSTR_){
} else if (!(*validSS) && *validMagField_ && *validSTR_) {
sensorsAvail = 4;
MDF = 6;
}
else if (*validSS && !(*validMagField_) && !(*validSTR_)){
} else if (*validSS && !(*validMagField_) && !(*validSTR_)) {
sensorsAvail = 5;
MDF = 3;
}
else if (!(*validSS) && *validMagField_ && !(*validSTR_)){
} else if (!(*validSS) && *validMagField_ && !(*validSTR_)) {
sensorsAvail = 6;
MDF = 3;
}
else if (!(*validSS) && !(*validMagField_) && *validSTR_){
} else if (!(*validSS) && !(*validMagField_) && *validSTR_) {
sensorsAvail = 7;
MDF = 3;
}
else{
sensorsAvail = 8; //no measurements
} else {
sensorsAvail = 8; // no measurements
validMekf = false;
return returnvalue::FAILED;
}
@ -308,47 +259,48 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(
sigmaMag = kalmanFilterParameters->sensorNoiseMAG;
sigmaStr = kalmanFilterParameters->sensorNoiseSTR;
double normMagB[3] = {0,0,0}, normSunB[3] = {0,0,0},
normMagJ[3] = {0,0,0}, normSunJ[3] = {0,0,0};
double normMagB[3] = {0, 0, 0}, normSunB[3] = {0, 0, 0}, normMagJ[3] = {0, 0, 0},
normSunJ[3] = {0, 0, 0};
VectorOperations<double>::normalize(magneticField_, normMagB, 3); // b2
VectorOperations<double>::normalize(sunDir_, normSunB, 3); //b1
VectorOperations<double>::normalize(magFieldJ, normMagJ, 3); //r2
VectorOperations<double>::normalize(sunDirJ, normSunJ, 3); //r1
VectorOperations<double>::normalize(sunDir_, normSunB, 3); // b1
VectorOperations<double>::normalize(magFieldJ, normMagJ, 3); // r2
VectorOperations<double>::normalize(sunDirJ, normSunJ, 3); // r1
/*-------GAIN - UPDATE - STEP------*/
double covMatrix11[3][3] = {{pow(sigmaSun,2),0,0},{0,pow(sigmaSun,2),0},{0,0,pow(sigmaSun,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 covMatrix11[3][3] = {
{pow(sigmaSun, 2), 0, 0}, {0, pow(sigmaSun, 2), 0}, {0, 0, pow(sigmaSun, 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}},
sunEstB[3] = {0,0,0}, magEstB[3] = {0,0,0};
double dcmBJ[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, sunEstB[3] = {0, 0, 0},
magEstB[3] = {0, 0, 0};
QuaternionOperations::toDcm(propagatedQuaternion, dcmBJ);
MatrixOperations<double>::multiply(*dcmBJ, normSunJ, sunEstB, 3, 3, 1);
MatrixOperations<double>::multiply(*dcmBJ, normMagJ, magEstB, 3, 3,
1);
double quatEstErr[3] = {0,0,0};
MatrixOperations<double>::multiply(*dcmBJ, normMagJ, magEstB, 3, 3, 1);
double quatEstErr[3] = {0, 0, 0};
//Measurement Sensitivity Matrix
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 measSensMatrix33[3][3] = {{1,0,0},{0,1,0},{0,0,1}}; // str
// Measurement Sensitivity Matrix
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 measSensMatrix33[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}; // str
MathOperations<double>::skewMatrix(sunEstB, *measSensMatrix11);
MathOperations<double>::skewMatrix(magEstB, *measSensMatrix22);
double measVecQuat[3] = {0,0,0};
if (*validSTR_){
double quatError[4] = {0,0,0,0};
double invPropagatedQuat[4] = {0,0,0,0};
double measVecQuat[3] = {0, 0, 0};
if (*validSTR_) {
double quatError[4] = {0, 0, 0, 0};
double invPropagatedQuat[4] = {0, 0, 0, 0};
QuaternionOperations::inverse(propagatedQuaternion, invPropagatedQuat);
QuaternionOperations::multiply(quaternionSTR, invPropagatedQuat, quatError);
for (int i = 0 ; i < 3;i++){
measVecQuat[i]=2*quatError[i]/quatError[3];
for (int i = 0; i < 3; i++) {
measVecQuat[i] = 2 * quatError[i] / quatError[3];
}
}
// Adjust matrices based on valid measurements
double measSensMatrix[MDF][6], measCovMatrix[MDF][MDF], measVec[MDF],
measEstVec[MDF];
if (sensorsAvail==1){ //All measurements valid
double measSensMatrix[MDF][6], measCovMatrix[MDF][MDF], measVec[MDF], measEstVec[MDF];
if (sensorsAvail == 1) { // All measurements valid
measSensMatrix[0][0] = measSensMatrix11[0][0];
measSensMatrix[0][1] = measSensMatrix11[0][1];
measSensMatrix[0][2] = measSensMatrix11[0][2];
@ -506,8 +458,7 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(
measEstVec[7] = quatEstErr[1];
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][1] = measSensMatrix11[0][1];
measSensMatrix[0][2] = measSensMatrix11[0][2];
@ -596,8 +547,7 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(
measEstVec[4] = magEstB[1];
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][1] = measSensMatrix11[0][1];
@ -687,8 +637,7 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(
measEstVec[4] = quatEstErr[1];
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][1] = measSensMatrix22[0][1];
@ -778,8 +727,7 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(
measEstVec[4] = quatEstErr[1];
measEstVec[5] = quatEstErr[2];
}
else if (sensorsAvail == 5){ // only ss
} else if (sensorsAvail == 5) { // only ss
measSensMatrix[0][0] = measSensMatrix11[0][0];
measSensMatrix[0][1] = measSensMatrix11[0][1];
@ -818,8 +766,7 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(
measEstVec[1] = sunEstB[1];
measEstVec[2] = sunEstB[2];
}
else if (sensorsAvail == 6){ // only mag
} else if (sensorsAvail == 6) { // only mag
measSensMatrix[0][0] = measSensMatrix22[0][0];
measSensMatrix[0][1] = measSensMatrix22[0][1];
@ -858,8 +805,7 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(
measEstVec[1] = magEstB[1];
measEstVec[2] = magEstB[2];
}
else if (sensorsAvail == 7){ // only str
} else if (sensorsAvail == 7) { // only str
measSensMatrix[0][0] = measSensMatrix33[0][0];
measSensMatrix[0][1] = measSensMatrix33[0][1];
@ -897,70 +843,71 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(
measEstVec[0] = quatEstErr[0];
measEstVec[1] = quatEstErr[1];
measEstVec[2] = quatEstErr[2];
}
// Kalman Gain: [K = P * H' / (H * P * H' + R)]
double kalmanGain[6][MDF] = {{0}}, kalmanGain1[6][MDF] = {{0}};
double measSensMatrixTrans[6][MDF], residualCov[MDF][MDF],
residualCov1[6][MDF];
double measSensMatrixTrans[6][MDF], residualCov[MDF][MDF], residualCov1[6][MDF];
// H * P * H'
MatrixOperations<double>::transpose(*measSensMatrix,*measSensMatrixTrans,6,MDF);
MatrixOperations<double>::multiply(*initialCovarianceMatrix,*measSensMatrixTrans,*residualCov1,6,6,MDF);
MatrixOperations<double>::multiply(*measSensMatrix,*residualCov1,*residualCov,MDF,6,MDF);
MatrixOperations<double>::transpose(*measSensMatrix, *measSensMatrixTrans, 6, MDF);
MatrixOperations<double>::multiply(*initialCovarianceMatrix, *measSensMatrixTrans, *residualCov1,
6, 6, MDF);
MatrixOperations<double>::multiply(*measSensMatrix, *residualCov1, *residualCov, MDF, 6, MDF);
// negative values, restrictions ?
// (H * P * H' + R)
MatrixOperations<double>::add(*residualCov, *measCovMatrix, *residualCov, MDF, MDF);
// <<INVERSE residualCov HIER>>
double invResidualCov1[MDF] = {0};
double invResidualCov[MDF][MDF] = {{0}};
int inversionFailed = CholeskyDecomposition<double>::invertCholesky(*residualCov,*invResidualCov,invResidualCov1,MDF);
if(inversionFailed)
{
int inversionFailed = CholeskyDecomposition<double>::invertCholesky(*residualCov, *invResidualCov,
invResidualCov1, MDF);
if (inversionFailed) {
validMekf = false;
return KALMAN_INVERSION_FAILED; // RETURN VALUE ? -- Like: Kalman Inversion Failed
}
// [K = P * H' / (H * P * H' + R)]
MatrixOperations<double>::multiply(*measSensMatrixTrans,*invResidualCov,*kalmanGain1,6,MDF,MDF);
MatrixOperations<double>::multiply(*initialCovarianceMatrix,*kalmanGain1,*kalmanGain,6,6,MDF);
MatrixOperations<double>::multiply(*measSensMatrixTrans, *invResidualCov, *kalmanGain1, 6, MDF,
MDF);
MatrixOperations<double>::multiply(*initialCovarianceMatrix, *kalmanGain1, *kalmanGain, 6, 6,
MDF);
/* ------- UPDATE -STEP ---------*/
// 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},
{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},
{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},
{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>::subtract(*identityMatrix,*updateCov1,*updateCov1,6,6);
MatrixOperations<double>::multiply(*updateCov1,*initialCovarianceMatrix,*covMatPlus,6,6,6);
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}};
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}};
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}};
MatrixOperations<double>::multiply(*kalmanGain, *measSensMatrix, *updateCov1, 6, MDF, MDF);
MatrixOperations<double>::subtract(*identityMatrix, *updateCov1, *updateCov1, 6, 6);
MatrixOperations<double>::multiply(*updateCov1, *initialCovarianceMatrix, *covMatPlus, 6, 6, 6);
// 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};
VectorOperations<double>::subtract(measVec,measEstVec,errStateVec1,MDF);
MatrixOperations<double>::multiply(*kalmanGain,errStateVec1,errStateVec,6,MDF,1);
VectorOperations<double>::subtract(measVec, measEstVec, errStateVec1, MDF);
MatrixOperations<double>::multiply(*kalmanGain, errStateVec1, errStateVec, 6, MDF, 1);
double errStateQuat[3] = {errStateVec[0], errStateVec[1], errStateVec[2]};
double errStateGyroBias[3] = {errStateVec[3], errStateVec[4], errStateVec[5]};
// State Vector Elements
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}};
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}};
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>::add(*xi1, *xi2, *xi1, 3, 3);
double xi[4][3] = {{xi1[0][0],xi1[0][1],xi1[0][2]},
{xi1[1][0],xi1[1][1],xi1[1][2]},
{xi1[2][0],xi1[2][1],xi1[2][2]},
{-propagatedQuaternion[0],-propagatedQuaternion[1],-propagatedQuaternion[2]}};
double xi[4][3] = {
{xi1[0][0], xi1[0][1], xi1[0][2]},
{xi1[1][0], xi1[1][1], xi1[1][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);
VectorOperations<double>::mulScalar(errQuatTerm, 0.5, errQuatTerm, 4);
VectorOperations<double>::add(propagatedQuaternion, errQuatTerm, quatBJ, 4);
@ -971,28 +918,27 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(
outputQuat[2] = quatBJ[2];
outputQuat[3] = quatBJ[3];
double updatedGyroBias[3] = {0,0,0};
VectorOperations<double>::add(biasRMU, errStateGyroBias, updatedGyroBias, 3);
// Bias RMU State
biasRMU[0] = updatedGyroBias[0];
biasRMU[1] = updatedGyroBias[1];
biasRMU[2] = updatedGyroBias[2];
double updatedGyroBias[3] = {0, 0, 0};
VectorOperations<double>::add(biasGYR, errStateGyroBias, updatedGyroBias, 3);
// Bias GYR State
biasGYR[0] = updatedGyroBias[0];
biasGYR[1] = updatedGyroBias[1];
biasGYR[2] = updatedGyroBias[2];
/* ----------- PROPAGATION ----------*/
//double sigmaU = kalmanFilterParameters->sensorNoiseBsRMU;
//double sigmaV = kalmanFilterParameters->sensorNoiseArwRmu;
double sigmaU = 3*3.141/180/3600;
double sigmaV = 3*0.0043*3.141/sqrt(10)/180;
// double sigmaU = kalmanFilterParameters->sensorNoiseBsGYR;
// double sigmaV = kalmanFilterParameters->sensorNoiseArwGYR;
double sigmaU = 3 * 3.141 / 180 / 3600;
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},
{0,0,0,1,0,0},{0,0,0,0,1,0},{0,0,0,0,0,1}};
double rotRateEst[3] = {0,0,0};
VectorOperations<double>::subtract(rateRMUs_, updatedGyroBias, rotRateEst, 3);
double normRotEst =VectorOperations<double>::norm(rotRateEst, 3);
double crossRotEst[3][3] = {{0,-rotRateEst[2],rotRateEst[1]},
{rotRateEst[2],0,-rotRateEst[0]},
{-rotRateEst[1],rotRateEst[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}};
double rotRateEst[3] = {0, 0, 0};
VectorOperations<double>::subtract(rateGYRs_, updatedGyroBias, rotRateEst, 3);
double normRotEst = VectorOperations<double>::norm(rotRateEst, 3);
double crossRotEst[3][3] = {{0, -rotRateEst[2], rotRateEst[1]},
{rotRateEst[2], 0, -rotRateEst[0]},
{-rotRateEst[1], rotRateEst[0], 0}};
// Corrected Sat Rate via Bias
outputSatRate[0] = rotRateEst[0];
@ -1000,19 +946,19 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(
outputSatRate[2] = rotRateEst[2];
// Discrete Process Noise Covariance Q
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}};
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}},
covQ3[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){
double fact1 = sampleTime*pow(sigmaV,2)+pow(sampleTime,3)*pow(sigmaU,2/3);
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}};
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}},
covQ3[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) {
double fact1 = sampleTime * pow(sigmaV, 2) + pow(sampleTime, 3) * pow(sigmaU, 2 / 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>::transpose(*covQ2, *transCovQ2, 3);
double fact3 = sampleTime*pow(sigmaU,2);
double fact3 = sampleTime * pow(sigmaU, 2);
MatrixOperations<double>::multiplyScalar(*identityMatrix3, fact3, *covQ3, 3, 3);
discProcessNoiseCov[0][0] = covQ1[0][0];
@ -1051,34 +997,35 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(
discProcessNoiseCov[5][3] = covQ3[2][0];
discProcessNoiseCov[5][4] = covQ3[2][1];
discProcessNoiseCov[5][5] = covQ3[2][2];
}
else{
//double fact1 = sampleTime*pow(sigmaV,2);
double covQ11[3][3],covQ12[3][3],covQ13[3][3];
//MatrixOperations<double>::multiplyScalar(*identityMatrix3, fact1, *covQ1, 3, 3);
double fact1 = (2*normRotEst+sampleTime-2*sin(normRotEst*sampleTime)
-pow(normRotEst,3)/3*pow(sampleTime,3))/pow(normRotEst,5);
} else {
// double fact1 = sampleTime*pow(sigmaV,2);
double covQ11[3][3], covQ12[3][3], covQ13[3][3];
// MatrixOperations<double>::multiplyScalar(*identityMatrix3, fact1, *covQ1, 3, 3);
double fact1 = (2 * normRotEst + sampleTime - 2 * sin(normRotEst * sampleTime) -
pow(normRotEst, 3) / 3 * pow(sampleTime, 3)) /
pow(normRotEst, 5);
MatrixOperations<double>::multiply(*crossRotEst, *crossRotEst, *covQ11, 3, 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>::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>::add(*covQ13, *covQ11, *covQ1, 3, 3);
double covQ21[3][3], covQ22[3][3], covQ23[3][3];
double fact4 = (0.5*pow(normRotEst,2)*pow(sampleTime,2)
+cos(normRotEst*sampleTime)-1)/pow(normRotEst,4);
double fact4 =
(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>::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>::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>::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(*identityMatrix3, fact7, *covQ3, 3, 3);
@ -1122,24 +1069,24 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(
}
// State Transition Matrix phi
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}},
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}};
double phi11[3][3],phi12[3][3];
double fact1 = sin(normRotEst*sampleTime);
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}},
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}};
double phi11[3][3], phi12[3][3];
double fact1 = sin(normRotEst * sampleTime);
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>::multiplyScalar(*phi12, fact2, *phi12, 3, 3);
MatrixOperations<double>::subtract(*identityMatrix3, *phi11, *phi11, 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(*identityMatrix3, sampleTime, *phi22, 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>::multiplyScalar(*phi22, fact3, *phi22, 3, 3);
MatrixOperations<double>::subtract(*phi21, *phi22, *phi2, 3, 3);
@ -1164,10 +1111,9 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(
phi[2][5] = phi2[2][2];
// Propagated Quaternion
double rotSin[3] = {0,0,0},
omega1[3][3] = {{0,0,0},{0,0,0},{0,0,0}};
double rotCos = cos(0.5*normRotEst*sampleTime);
double sinFac = sin(0.5*normRotEst*sampleTime)/normRotEst;
double rotSin[3] = {0, 0, 0}, omega1[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double rotCos = cos(0.5 * normRotEst * sampleTime);
double sinFac = sin(0.5 * normRotEst * sampleTime) / normRotEst;
VectorOperations<double>::mulScalar(rotRateEst, sinFac, rotSin, 3);
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>::subtract(*omega1, *skewSin, *omega1, 3, 3);
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[2][0],omega1[2][1],omega1[2][2],rotSin[2]},
{-rotSin[0],-rotSin[1],-rotSin[2],rotCos}};
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[2][0], omega1[2][1], omega1[2][2], rotSin[2]},
{-rotSin[0], -rotSin[1], -rotSin[2], rotCos}};
MatrixOperations<double>::multiply(*omega, quatBJ, propagatedQuaternion, 4, 4, 1);
// Update Covariance Matrix
double cov1[6][6], cov2[6][6], transDiscTimeMatrix[6][6],
transPhi[6][6];
double cov1[6][6], cov2[6][6], transDiscTimeMatrix[6][6], transPhi[6][6];
MatrixOperations<double>::transpose(*discTimeMatrix, *transDiscTimeMatrix, 6);
MatrixOperations<double>::multiply(*discProcessNoiseCov, *transDiscTimeMatrix, *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);
validMekf = true;
// Discrete Time Step
// Check for new data in measurement -> SensorProcessing ?

View File

@ -7,22 +7,24 @@
* @brief: This class handles the calculation of an estimated quaternion and the gyro bias by
* 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
*/
#ifndef MULTIPLICATIVEKALMANFILTER_H_
#define MULTIPLICATIVEKALMANFILTER_H_
#include "config/classIds.h"
#include <stdint.h> //uint8_t
#include <time.h> /*purpose, timeval ?*/
#include "config/classIds.h"
//#include <_timeval.h>
#include "AcsParameters.h"
class MultiplicativeKalmanFilter{
public:
class MultiplicativeKalmanFilter {
public:
/* @brief: Constructor
* @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
/* @brief: init() - This function initializes the Kalman Filter and will provide the first quaternion through
* the QUEST algorithm
/* @brief: init() - This function initializes the Kalman Filter and will provide the first
* quaternion through the QUEST algorithm
* @param: magneticField_ magnetic field vector in the body frame
* sunDir_ sun direction vector in the body frame
* sunDirJ sun direction vector in the ECI frame
* magFieldJ magnetic field vector in the ECI frame
*/
void init(const double *magneticField_, const bool *validMagField_,
const double *sunDir_, const bool *validSS,
const double *sunDirJ, const bool *validSSModel,
const double *magFieldJ,const bool *validMagModel);
void init(const double *magneticField_, const bool *validMagField_, const double *sunDir_,
const bool *validSS, const double *sunDirJ, const bool *validSSModel,
const double *magFieldJ, const bool *validMagModel);
/* @brief: mekfEst() - This function calculates the quaternion and gyro bias of the Kalman Filter for the current step
* after the initalization
/* @brief: mekfEst() - This function calculates the quaternion and gyro bias of the Kalman Filter
* for the current step after the initalization
* @param: quaternionSTR Star Tracker Quaternion between from body to ECI frame
* rateRMUs_ Estimated satellite rotation rate from the Rate Measurement Units [rad/s]
* magneticField_ magnetic field vector in the body frame
* sunDir_ sun direction vector in the body frame
* sunDirJ sun direction vector in the ECI frame
* magFieldJ magnetic field vector in the ECI frame
* rateGYRs_ Estimated satellite rotation rate from the
* Gyroscopes [rad/s] magneticField_ magnetic field vector in the body frame sunDir_
* sun direction vector in the body frame sunDirJ sun direction vector in the ECI
* frame magFieldJ magnetic field vector in the ECI frame
* outputQuat Stores the calculated quaternion
* 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,
* KALMAN_NO_MODEL if no sunDirJ or magFieldJ was given from the model calculations,
* KALMAN_INVERSION_FAILED if the calculation of the Gain matrix was not possible,
* @return ReturnValue_t Feedback of this class, KALMAN_NO_GYR_MEAS if no satellite rate from
* the sensors was provided, KALMAN_NO_MODEL if no sunDirJ or magFieldJ was given from the model
* calculations, KALMAN_INVERSION_FAILED if the calculation of the Gain matrix was not possible,
* RETURN_OK else
*/
ReturnValue_t mekfEst(
const double *quaternionSTR, const bool *validSTR_,
const double *rateRMUs_, const bool *validRMUs_,
const double *magneticField_, const bool *validMagField_,
const double *sunDir_, const bool *validSS,
const double *sunDirJ, const bool *validSSModel,
const double *magFieldJ,const bool *validMagModel,
double *outputQuat, double *outputSatRate);
ReturnValue_t mekfEst(const double *quaternionSTR, const bool *validSTR_, const double *rateGYRs_,
const bool *validGYRs_, const double *magneticField_,
const bool *validMagField_, const double *sunDir_, const bool *validSS,
const double *sunDirJ, const bool *validSSModel, const double *magFieldJ,
const bool *validMagModel, double *outputQuat, double *outputSatRate);
// 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 Event RESET = MAKE_EVENT(1,severity::INFO);//typedef uint32_t Event (Event.h), should be
// static const uint8_t INTERFACE_ID = CLASS_ID::MEKF; //CLASS IDS ND
// (/config/returnvalues/classIDs.h) static const Event RESET =
// MAKE_EVENT(1,severity::INFO);//typedef uint32_t Event (Event.h), should be
// resetting Mekf
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_INVERSION_FAILED = MAKE_RETURN_CODE(0x03);
private:
/*Parameters*/
AcsParameters::InertiaEIVE* inertiaEIVE;
AcsParameters::KalmanFilterParameters* kalmanFilterParameters;
private:
/*Parameters*/
AcsParameters::InertiaEIVE *inertiaEIVE;
AcsParameters::KalmanFilterParameters *kalmanFilterParameters;
double quaternion_STR_SB[4];
bool validInit;
double sampleTime = 0.1;
/*States*/
/*States*/
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*/
bool validMekf;
uint8_t sensorsAvail;
/*Outputs*/
/*Outputs*/
double quatBJ[4]; /* Output Quaternion */
double biasRMU[3]; /*Between measured and estimated sat Rate*/
/*Parameter INIT*/
//double alpha, gamma, beta;
/*Functions*/
double biasGYR[3]; /*Between measured and estimated sat Rate*/
/*Parameter INIT*/
// double alpha, gamma, beta;
/*Functions*/
void loadAcsParameters(AcsParameters *acsParameters_);
};
#endif /* ACS_MULTIPLICATIVEKALMANFILTER_H_ */

View File

@ -36,8 +36,7 @@ void Navigation::useMekf(ACS::SensorValues *sensorValues, ACS::OutputValues *out
&outputValues->sunDirEstValid, outputValues->sunDirModel, &outputValues->sunDirModelValid,
outputValues->magFieldModel, &outputValues->magFieldModelValid, outputValues->quatMekfBJ,
outputValues->satRateMekf); // VALIDS FOR QUAT AND RATE ??
}
else {
} else {
multiplicativeKalmanFilter.init(outputValues->magFieldEst, &outputValues->magFieldEstValid,
outputValues->sunDirEst, &outputValues->sunDirEstValid,
outputValues->sunDirModel, &outputValues->sunDirModelValid,
@ -45,7 +44,8 @@ void Navigation::useMekf(ACS::SensorValues *sensorValues, ACS::OutputValues *out
kalmanInit = true;
*mekfValid = 0;
// Maybe we need feedback from kalmanfilter to identify if there was a problem with the init
//of kalman filter where does this class know from that kalman filter was not initialized ?
// Maybe we need feedback from kalmanfilter to identify if there was a problem with the
// init of kalman filter where does this class know from that kalman filter was not
// initialized ?
}
}

View File

@ -123,7 +123,7 @@ void PtgCtrl::ptgDesaturation(double *magFieldEst, bool *magFieldEstValid, doubl
}
// 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};
VectorOperations<double>::mulScalar(speedRws, rwHandlingParameters->inertiaWheel, momentumRwU, 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,
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 rpmOffset[4] = {1, 1, 1, -1}, factor = 350 * 2 * Math::PI / 60;
// Conversion to [rad/s] for further calculations