2023-07-19 16:25:03 +02:00
|
|
|
#include "FusedRotationEstimation.h"
|
|
|
|
|
|
|
|
FusedRotationEstimation::FusedRotationEstimation(AcsParameters *acsParameters_) {
|
|
|
|
acsParameters = acsParameters_;
|
|
|
|
}
|
|
|
|
|
2023-11-14 13:22:35 +01:00
|
|
|
void FusedRotationEstimation::estimateFusedRotationRate(
|
2024-02-26 10:14:15 +01:00
|
|
|
const Mode_t mode, acsctrl::SusDataProcessed *susDataProcessed,
|
2024-02-23 14:53:28 +01:00
|
|
|
acsctrl::MgmDataProcessed *mgmDataProcessed, acsctrl::GyrDataProcessed *gyrDataProcessed,
|
|
|
|
ACS::SensorValues *sensorValues, acsctrl::AttitudeEstimationData *attitudeEstimationData,
|
|
|
|
const double timeDelta, acsctrl::FusedRotRateSourcesData *fusedRotRateSourcesData,
|
2023-11-23 16:56:36 +01:00
|
|
|
acsctrl::FusedRotRateData *fusedRotRateData) {
|
|
|
|
estimateFusedRotationRateStr(sensorValues, timeDelta, fusedRotRateSourcesData);
|
|
|
|
estimateFusedRotationRateQuest(attitudeEstimationData, timeDelta, fusedRotRateSourcesData);
|
2023-11-24 10:52:36 +01:00
|
|
|
estimateFusedRotationRateSusMgm(susDataProcessed, mgmDataProcessed, gyrDataProcessed,
|
|
|
|
fusedRotRateSourcesData);
|
2023-11-23 16:56:36 +01:00
|
|
|
|
2024-02-26 10:14:15 +01:00
|
|
|
if (not(mode == acs::AcsMode::SAFE) and (fusedRotRateSourcesData->rotRateTotalStr.isValid() and
|
|
|
|
acsParameters->onBoardParams.fusedRateFromStr)) {
|
2023-11-24 10:52:36 +01:00
|
|
|
PoolReadGuard pg(fusedRotRateData);
|
|
|
|
if (pg.getReadResult() == returnvalue::OK) {
|
2024-06-12 16:32:47 +02:00
|
|
|
std::memcpy(fusedRotRateData->rotRateTotalSource.value,
|
2023-11-24 10:52:36 +01:00
|
|
|
fusedRotRateSourcesData->rotRateTotalStr.value, 3 * sizeof(double));
|
2024-06-12 16:32:47 +02:00
|
|
|
fusedRotRateData->rotRateTotalSource.setValid(true);
|
2023-11-27 10:37:40 +01:00
|
|
|
fusedRotRateData->rotRateSource.value = acs::rotrate::Source::STR;
|
2023-11-24 11:30:27 +01:00
|
|
|
fusedRotRateData->rotRateSource.setValid(true);
|
2023-11-24 10:52:36 +01:00
|
|
|
}
|
2024-02-26 10:14:15 +01:00
|
|
|
} else if (not(mode == acs::AcsMode::SAFE) and
|
|
|
|
(fusedRotRateSourcesData->rotRateTotalQuest.isValid() and
|
|
|
|
acsParameters->onBoardParams.fusedRateFromQuest)) {
|
2023-11-24 10:52:36 +01:00
|
|
|
PoolReadGuard pg(fusedRotRateData);
|
|
|
|
if (pg.getReadResult() == returnvalue::OK) {
|
2024-06-12 16:32:47 +02:00
|
|
|
std::memcpy(fusedRotRateData->rotRateTotalSource.value,
|
2023-11-24 10:52:36 +01:00
|
|
|
fusedRotRateSourcesData->rotRateTotalQuest.value, 3 * sizeof(double));
|
2024-06-12 16:32:47 +02:00
|
|
|
fusedRotRateData->rotRateTotalSource.setValid(true);
|
2023-11-27 10:37:40 +01:00
|
|
|
fusedRotRateData->rotRateSource.value = acs::rotrate::Source::QUEST;
|
2023-11-24 11:30:27 +01:00
|
|
|
fusedRotRateData->rotRateSource.setValid(true);
|
2023-11-24 10:52:36 +01:00
|
|
|
}
|
|
|
|
} else if (fusedRotRateSourcesData->rotRateTotalSusMgm.isValid()) {
|
2024-06-12 16:32:47 +02:00
|
|
|
std::memcpy(fusedRotRateData->rotRateTotalSource.value,
|
2023-11-24 10:52:36 +01:00
|
|
|
fusedRotRateSourcesData->rotRateTotalSusMgm.value, 3 * sizeof(double));
|
2023-11-27 10:37:40 +01:00
|
|
|
fusedRotRateData->rotRateSource.value = acs::rotrate::Source::SUSMGM;
|
2023-11-24 11:30:27 +01:00
|
|
|
fusedRotRateData->rotRateSource.setValid(true);
|
2023-11-24 10:52:36 +01:00
|
|
|
} else {
|
|
|
|
PoolReadGuard pg(fusedRotRateData);
|
|
|
|
if (pg.getReadResult() == returnvalue::OK) {
|
2024-06-12 16:32:47 +02:00
|
|
|
std::memcpy(fusedRotRateData->rotRateTotalSource.value, ZERO_VEC3, 3 * sizeof(double));
|
|
|
|
fusedRotRateData->rotRateTotalSource.setValid(false);
|
2023-12-05 15:11:22 +01:00
|
|
|
fusedRotRateData->rotRateSource.value = acs::rotrate::Source::NONE;
|
|
|
|
fusedRotRateData->rotRateSource.setValid(true);
|
2023-11-24 10:52:36 +01:00
|
|
|
}
|
|
|
|
}
|
2024-06-12 16:32:47 +02:00
|
|
|
if (fusedRotRateSourcesData->rotRateTotalSusMgm.isValid()) {
|
|
|
|
std::memcpy(fusedRotRateData->rotRateTotalSusMgm.value,
|
|
|
|
fusedRotRateSourcesData->rotRateTotalSusMgm.value, 3 * sizeof(double));
|
|
|
|
fusedRotRateData->rotRateTotalSusMgm.setValid(false);
|
|
|
|
} else {
|
|
|
|
PoolReadGuard pg(fusedRotRateData);
|
|
|
|
if (pg.getReadResult() == returnvalue::OK) {
|
|
|
|
std::memcpy(fusedRotRateData->rotRateTotalSusMgm.value, ZERO_VEC3, 3 * sizeof(double));
|
|
|
|
fusedRotRateData->rotRateTotalSusMgm.setValid(false);
|
|
|
|
}
|
|
|
|
}
|
2023-11-24 10:52:36 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void FusedRotationEstimation::estimateFusedRotationRateStr(
|
|
|
|
ACS::SensorValues *sensorValues, const double timeDelta,
|
|
|
|
acsctrl::FusedRotRateSourcesData *fusedRotRateSourcesData) {
|
2023-12-06 15:52:20 +01:00
|
|
|
if (not(sensorValues->strSet.caliQw.isValid() and sensorValues->strSet.caliQx.isValid() and
|
|
|
|
sensorValues->strSet.caliQy.isValid() and sensorValues->strSet.caliQz.isValid())) {
|
|
|
|
{
|
|
|
|
PoolReadGuard pg(fusedRotRateSourcesData);
|
|
|
|
if (pg.getReadResult() == returnvalue::OK) {
|
|
|
|
std::memcpy(fusedRotRateSourcesData->rotRateTotalStr.value, ZERO_VEC3, 3 * sizeof(double));
|
|
|
|
fusedRotRateSourcesData->rotRateTotalStr.setValid(false);
|
2023-12-05 15:02:17 +01:00
|
|
|
}
|
2023-12-06 15:52:20 +01:00
|
|
|
}
|
|
|
|
std::memcpy(quatOldStr, ZERO_VEC4, sizeof(quatOldStr));
|
|
|
|
return;
|
|
|
|
}
|
2023-11-24 10:52:36 +01:00
|
|
|
|
2023-12-06 15:52:20 +01:00
|
|
|
double quatNew[4] = {sensorValues->strSet.caliQx.value, sensorValues->strSet.caliQy.value,
|
|
|
|
sensorValues->strSet.caliQz.value, sensorValues->strSet.caliQw.value};
|
|
|
|
if (VectorOperations<double>::norm(quatOldStr, 4) != 0 and timeDelta != 0) {
|
|
|
|
double quatOldInv[4] = {0, 0, 0, 0};
|
|
|
|
double quatDelta[4] = {0, 0, 0, 0};
|
|
|
|
|
|
|
|
QuaternionOperations::inverse(quatOldStr, quatOldInv);
|
|
|
|
QuaternionOperations::multiply(quatNew, quatOldInv, quatDelta);
|
|
|
|
if (VectorOperations<double>::norm(quatDelta, 4) != 0.0) {
|
|
|
|
QuaternionOperations::normalize(quatDelta);
|
|
|
|
}
|
|
|
|
|
|
|
|
double rotVec[3] = {0, 0, 0};
|
|
|
|
double angle = QuaternionOperations::getAngle(quatDelta);
|
|
|
|
if (VectorOperations<double>::norm(quatDelta, 3) == 0.0) {
|
2023-11-23 16:56:36 +01:00
|
|
|
{
|
|
|
|
PoolReadGuard pg(fusedRotRateSourcesData);
|
2023-11-24 10:52:36 +01:00
|
|
|
if (pg.getReadResult() == returnvalue::OK) {
|
2023-12-06 15:52:20 +01:00
|
|
|
std::memcpy(fusedRotRateSourcesData->rotRateTotalStr.value, ZERO_VEC3,
|
|
|
|
3 * sizeof(double));
|
2023-11-24 10:52:36 +01:00
|
|
|
fusedRotRateSourcesData->rotRateTotalStr.setValid(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
std::memcpy(quatOldStr, quatNew, sizeof(quatOldStr));
|
|
|
|
return;
|
|
|
|
}
|
2023-12-06 15:52:20 +01:00
|
|
|
VectorOperations<double>::normalize(quatDelta, rotVec, 3);
|
|
|
|
VectorOperations<double>::mulScalar(rotVec, angle / timeDelta, rotVec, 3);
|
2023-11-24 10:52:36 +01:00
|
|
|
{
|
|
|
|
PoolReadGuard pg(fusedRotRateSourcesData);
|
|
|
|
if (pg.getReadResult() == returnvalue::OK) {
|
2023-12-06 15:52:20 +01:00
|
|
|
std::memcpy(fusedRotRateSourcesData->rotRateTotalStr.value, rotVec, 3 * sizeof(double));
|
|
|
|
fusedRotRateSourcesData->rotRateTotalStr.setValid(true);
|
2023-11-23 16:56:36 +01:00
|
|
|
}
|
2023-11-14 13:22:35 +01:00
|
|
|
}
|
2023-11-23 16:56:36 +01:00
|
|
|
std::memcpy(quatOldStr, quatNew, sizeof(quatOldStr));
|
2023-11-24 10:52:36 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
{
|
|
|
|
PoolReadGuard pg(fusedRotRateSourcesData);
|
|
|
|
if (pg.getReadResult() == returnvalue::OK) {
|
2023-11-23 16:56:36 +01:00
|
|
|
std::memcpy(fusedRotRateSourcesData->rotRateTotalStr.value, ZERO_VEC3, 3 * sizeof(double));
|
|
|
|
fusedRotRateSourcesData->rotRateTotalStr.setValid(false);
|
|
|
|
}
|
2023-11-14 13:22:35 +01:00
|
|
|
}
|
2023-12-06 15:52:20 +01:00
|
|
|
std::memcpy(quatOldStr, quatNew, sizeof(quatOldStr));
|
|
|
|
return;
|
2023-11-24 10:52:36 +01:00
|
|
|
}
|
2023-11-23 16:56:36 +01:00
|
|
|
|
2023-11-24 10:52:36 +01:00
|
|
|
void FusedRotationEstimation::estimateFusedRotationRateQuest(
|
|
|
|
acsctrl::AttitudeEstimationData *attitudeEstimationData, const double timeDelta,
|
|
|
|
acsctrl::FusedRotRateSourcesData *fusedRotRateSourcesData) {
|
2023-12-06 15:52:20 +01:00
|
|
|
if (not attitudeEstimationData->quatQuest.isValid()) {
|
|
|
|
{
|
|
|
|
PoolReadGuard pg(fusedRotRateSourcesData);
|
|
|
|
if (pg.getReadResult() == returnvalue::OK) {
|
|
|
|
std::memcpy(fusedRotRateSourcesData->rotRateTotalQuest.value, ZERO_VEC3,
|
|
|
|
3 * sizeof(double));
|
|
|
|
fusedRotRateSourcesData->rotRateTotalQuest.setValid(false);
|
2023-12-05 15:02:17 +01:00
|
|
|
}
|
2023-12-06 15:52:20 +01:00
|
|
|
}
|
|
|
|
std::memcpy(quatOldQuest, ZERO_VEC4, sizeof(quatOldQuest));
|
|
|
|
}
|
2023-11-24 10:52:36 +01:00
|
|
|
|
2023-12-06 15:52:20 +01:00
|
|
|
if (VectorOperations<double>::norm(quatOldQuest, 4) != 0 and timeDelta != 0) {
|
|
|
|
double quatOldInv[4] = {0, 0, 0, 0};
|
|
|
|
double quatDelta[4] = {0, 0, 0, 0};
|
|
|
|
|
|
|
|
QuaternionOperations::inverse(quatOldQuest, quatOldInv);
|
|
|
|
QuaternionOperations::multiply(attitudeEstimationData->quatQuest.value, quatOldInv, quatDelta);
|
|
|
|
if (VectorOperations<double>::norm(quatDelta, 4) != 0.0) {
|
|
|
|
QuaternionOperations::normalize(quatDelta);
|
|
|
|
}
|
|
|
|
|
|
|
|
double rotVec[3] = {0, 0, 0};
|
|
|
|
double angle = QuaternionOperations::getAngle(quatDelta);
|
|
|
|
if (VectorOperations<double>::norm(quatDelta, 3) == 0.0) {
|
2023-11-23 16:56:36 +01:00
|
|
|
{
|
|
|
|
PoolReadGuard pg(fusedRotRateSourcesData);
|
2023-11-24 10:52:36 +01:00
|
|
|
if (pg.getReadResult() == returnvalue::OK) {
|
2023-12-06 15:52:20 +01:00
|
|
|
std::memcpy(fusedRotRateSourcesData->rotRateTotalQuest.value, ZERO_VEC3,
|
|
|
|
3 * sizeof(double));
|
2023-11-24 10:52:36 +01:00
|
|
|
fusedRotRateSourcesData->rotRateTotalQuest.setValid(true);
|
|
|
|
}
|
2023-11-23 16:56:36 +01:00
|
|
|
}
|
2023-11-24 10:52:36 +01:00
|
|
|
std::memcpy(quatOldQuest, attitudeEstimationData->quatQuest.value, sizeof(quatOldQuest));
|
|
|
|
return;
|
2023-11-23 16:56:36 +01:00
|
|
|
}
|
2023-12-06 15:52:20 +01:00
|
|
|
VectorOperations<double>::normalize(quatDelta, rotVec, 3);
|
|
|
|
VectorOperations<double>::mulScalar(rotVec, angle / timeDelta, rotVec, 3);
|
2023-11-14 16:07:14 +01:00
|
|
|
{
|
2023-11-23 16:56:36 +01:00
|
|
|
PoolReadGuard pg(fusedRotRateSourcesData);
|
2023-11-24 10:52:36 +01:00
|
|
|
if (pg.getReadResult() == returnvalue::OK) {
|
2023-12-06 15:52:20 +01:00
|
|
|
std::memcpy(fusedRotRateSourcesData->rotRateTotalQuest.value, rotVec, 3 * sizeof(double));
|
|
|
|
fusedRotRateSourcesData->rotRateTotalQuest.setValid(true);
|
2023-11-23 16:56:36 +01:00
|
|
|
}
|
2023-11-14 16:07:14 +01:00
|
|
|
}
|
2023-11-24 10:52:36 +01:00
|
|
|
std::memcpy(quatOldQuest, attitudeEstimationData->quatQuest.value, sizeof(quatOldQuest));
|
|
|
|
return;
|
2023-11-14 16:07:14 +01:00
|
|
|
}
|
|
|
|
{
|
2023-11-23 16:56:36 +01:00
|
|
|
PoolReadGuard pg(fusedRotRateSourcesData);
|
2023-11-24 10:52:36 +01:00
|
|
|
if (pg.getReadResult() == returnvalue::OK) {
|
|
|
|
std::memcpy(fusedRotRateSourcesData->rotRateTotalQuest.value, ZERO_VEC3, 3 * sizeof(double));
|
|
|
|
fusedRotRateSourcesData->rotRateTotalQuest.setValid(false);
|
2023-11-23 16:56:36 +01:00
|
|
|
}
|
2023-11-14 16:07:14 +01:00
|
|
|
}
|
2023-12-06 15:52:20 +01:00
|
|
|
std::memcpy(quatOldQuest, attitudeEstimationData->quatQuest.value, sizeof(quatOldQuest));
|
|
|
|
return;
|
2023-11-14 16:07:14 +01:00
|
|
|
}
|
2023-11-14 13:22:35 +01:00
|
|
|
|
2023-11-24 10:52:36 +01:00
|
|
|
void FusedRotationEstimation::estimateFusedRotationRateSusMgm(
|
2023-07-20 11:09:34 +02:00
|
|
|
acsctrl::SusDataProcessed *susDataProcessed, acsctrl::MgmDataProcessed *mgmDataProcessed,
|
2023-11-24 10:52:36 +01:00
|
|
|
acsctrl::GyrDataProcessed *gyrDataProcessed,
|
|
|
|
acsctrl::FusedRotRateSourcesData *fusedRotRateSourcesData) {
|
2023-07-20 14:22:24 +02:00
|
|
|
if ((not mgmDataProcessed->mgmVecTot.isValid() and not susDataProcessed->susVecTot.isValid() and
|
2023-11-24 10:52:36 +01:00
|
|
|
not fusedRotRateSourcesData->rotRateTotalSusMgm.isValid()) or
|
2023-07-20 13:09:49 +02:00
|
|
|
(not susDataProcessed->susVecTotDerivative.isValid() and
|
|
|
|
not mgmDataProcessed->mgmVecTotDerivative.isValid())) {
|
2023-07-20 11:09:34 +02:00
|
|
|
{
|
2023-11-24 10:52:36 +01:00
|
|
|
PoolReadGuard pg(fusedRotRateSourcesData);
|
|
|
|
if (pg.getReadResult() == returnvalue::OK) {
|
|
|
|
std::memcpy(fusedRotRateSourcesData->rotRateOrthogonalSusMgm.value, ZERO_VEC3,
|
|
|
|
3 * sizeof(double));
|
|
|
|
fusedRotRateSourcesData->rotRateOrthogonalSusMgm.setValid(false);
|
|
|
|
std::memcpy(fusedRotRateSourcesData->rotRateParallelSusMgm.value, ZERO_VEC3,
|
|
|
|
3 * sizeof(double));
|
|
|
|
fusedRotRateSourcesData->rotRateParallelSusMgm.setValid(false);
|
|
|
|
std::memcpy(fusedRotRateSourcesData->rotRateTotalSusMgm.value, ZERO_VEC3,
|
|
|
|
3 * sizeof(double));
|
|
|
|
fusedRotRateSourcesData->rotRateTotalSusMgm.setValid(false);
|
|
|
|
}
|
2023-07-20 11:09:34 +02:00
|
|
|
}
|
2023-08-03 11:32:08 +02:00
|
|
|
// store for calculation of angular acceleration
|
|
|
|
if (gyrDataProcessed->gyrVecTot.isValid()) {
|
|
|
|
std::memcpy(rotRateOldB, gyrDataProcessed->gyrVecTot.value, 3 * sizeof(double));
|
|
|
|
}
|
2023-07-19 16:25:03 +02:00
|
|
|
return;
|
|
|
|
}
|
2023-07-20 11:09:34 +02:00
|
|
|
if (not susDataProcessed->susVecTot.isValid()) {
|
2023-11-24 10:52:36 +01:00
|
|
|
estimateFusedRotationRateEclipse(gyrDataProcessed, fusedRotRateSourcesData);
|
2023-08-02 16:26:57 +02:00
|
|
|
// store for calculation of angular acceleration
|
|
|
|
if (gyrDataProcessed->gyrVecTot.isValid()) {
|
|
|
|
std::memcpy(rotRateOldB, gyrDataProcessed->gyrVecTot.value, 3 * sizeof(double));
|
|
|
|
}
|
2023-07-19 16:25:03 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// calculate rotation around the sun
|
|
|
|
double magSunCross[3] = {0, 0, 0};
|
|
|
|
|
2023-07-20 11:09:34 +02:00
|
|
|
VectorOperations<double>::cross(mgmDataProcessed->mgmVecTot.value,
|
|
|
|
susDataProcessed->susVecTot.value, magSunCross);
|
2023-07-19 16:25:03 +02:00
|
|
|
double magSunCrossNorm = VectorOperations<double>::norm(magSunCross, 3);
|
2023-07-20 11:09:34 +02:00
|
|
|
double magNorm = VectorOperations<double>::norm(mgmDataProcessed->mgmVecTot.value, 3);
|
|
|
|
double fusedRotRateParallel[3] = {0, 0, 0};
|
2023-07-19 16:25:03 +02:00
|
|
|
if (magSunCrossNorm >
|
|
|
|
(acsParameters->safeModeControllerParameters.sineLimitSunRotRate * magNorm)) {
|
|
|
|
double omegaParallel =
|
2023-07-20 11:09:34 +02:00
|
|
|
VectorOperations<double>::dot(mgmDataProcessed->mgmVecTotDerivative.value, magSunCross) *
|
|
|
|
pow(magSunCrossNorm, -2);
|
|
|
|
VectorOperations<double>::mulScalar(susDataProcessed->susVecTot.value, omegaParallel,
|
|
|
|
fusedRotRateParallel, 3);
|
2023-07-19 16:25:03 +02:00
|
|
|
} else {
|
2023-11-24 10:52:36 +01:00
|
|
|
estimateFusedRotationRateEclipse(gyrDataProcessed, fusedRotRateSourcesData);
|
2023-08-02 16:26:57 +02:00
|
|
|
// store for calculation of angular acceleration
|
|
|
|
if (gyrDataProcessed->gyrVecTot.isValid()) {
|
|
|
|
std::memcpy(rotRateOldB, gyrDataProcessed->gyrVecTot.value, 3 * sizeof(double));
|
|
|
|
}
|
2023-07-19 16:25:03 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// calculate rotation orthogonal to the sun
|
2023-07-20 11:09:34 +02:00
|
|
|
double fusedRotRateOrthogonal[3] = {0, 0, 0};
|
|
|
|
VectorOperations<double>::cross(susDataProcessed->susVecTotDerivative.value,
|
|
|
|
susDataProcessed->susVecTot.value, fusedRotRateOrthogonal);
|
|
|
|
VectorOperations<double>::mulScalar(
|
|
|
|
fusedRotRateOrthogonal,
|
2023-07-21 11:10:09 +02:00
|
|
|
pow(VectorOperations<double>::norm(susDataProcessed->susVecTot.value, 3), -2),
|
2023-07-20 11:09:34 +02:00
|
|
|
fusedRotRateOrthogonal, 3);
|
2023-07-19 16:25:03 +02:00
|
|
|
|
|
|
|
// calculate total rotation rate
|
2023-07-20 11:09:34 +02:00
|
|
|
double fusedRotRateTotal[3] = {0, 0, 0};
|
|
|
|
VectorOperations<double>::add(fusedRotRateParallel, fusedRotRateOrthogonal, fusedRotRateTotal);
|
2023-07-19 16:25:03 +02:00
|
|
|
|
2023-07-20 11:09:34 +02:00
|
|
|
{
|
2023-11-24 10:52:36 +01:00
|
|
|
PoolReadGuard pg(fusedRotRateSourcesData);
|
|
|
|
if (pg.getReadResult() == returnvalue::OK) {
|
|
|
|
std::memcpy(fusedRotRateSourcesData->rotRateOrthogonalSusMgm.value, fusedRotRateOrthogonal,
|
|
|
|
3 * sizeof(double));
|
|
|
|
fusedRotRateSourcesData->rotRateOrthogonalSusMgm.setValid(true);
|
|
|
|
std::memcpy(fusedRotRateSourcesData->rotRateParallelSusMgm.value, fusedRotRateParallel,
|
|
|
|
3 * sizeof(double));
|
|
|
|
fusedRotRateSourcesData->rotRateParallelSusMgm.setValid(true);
|
|
|
|
std::memcpy(fusedRotRateSourcesData->rotRateTotalSusMgm.value, fusedRotRateTotal,
|
|
|
|
3 * sizeof(double));
|
|
|
|
fusedRotRateSourcesData->rotRateTotalSusMgm.setValid(true);
|
|
|
|
}
|
2023-07-19 16:25:03 +02:00
|
|
|
}
|
2023-08-03 11:34:29 +02:00
|
|
|
|
|
|
|
// store for calculation of angular acceleration
|
|
|
|
if (gyrDataProcessed->gyrVecTot.isValid()) {
|
|
|
|
std::memcpy(rotRateOldB, gyrDataProcessed->gyrVecTot.value, 3 * sizeof(double));
|
|
|
|
}
|
2023-07-19 16:25:03 +02:00
|
|
|
}
|
|
|
|
|
2023-07-20 11:09:34 +02:00
|
|
|
void FusedRotationEstimation::estimateFusedRotationRateEclipse(
|
2023-11-24 10:52:36 +01:00
|
|
|
acsctrl::GyrDataProcessed *gyrDataProcessed,
|
|
|
|
acsctrl::FusedRotRateSourcesData *fusedRotRateSourcesData) {
|
2023-08-03 10:09:43 +02:00
|
|
|
if (not acsParameters->onBoardParams.fusedRateSafeDuringEclipse or
|
|
|
|
not gyrDataProcessed->gyrVecTot.isValid() or
|
2023-11-24 10:52:36 +01:00
|
|
|
VectorOperations<double>::norm(fusedRotRateSourcesData->rotRateTotalSusMgm.value, 3) == 0) {
|
2023-07-20 11:09:34 +02:00
|
|
|
{
|
2023-11-24 10:52:36 +01:00
|
|
|
PoolReadGuard pg(fusedRotRateSourcesData);
|
|
|
|
if (pg.getReadResult() == returnvalue::OK) {
|
|
|
|
std::memcpy(fusedRotRateSourcesData->rotRateOrthogonalSusMgm.value, ZERO_VEC3,
|
|
|
|
3 * sizeof(double));
|
|
|
|
fusedRotRateSourcesData->rotRateOrthogonalSusMgm.setValid(false);
|
|
|
|
std::memcpy(fusedRotRateSourcesData->rotRateParallelSusMgm.value, ZERO_VEC3,
|
|
|
|
3 * sizeof(double));
|
|
|
|
fusedRotRateSourcesData->rotRateParallelSusMgm.setValid(false);
|
|
|
|
std::memcpy(fusedRotRateSourcesData->rotRateTotalSusMgm.value, ZERO_VEC3,
|
|
|
|
3 * sizeof(double));
|
|
|
|
fusedRotRateSourcesData->rotRateTotalSusMgm.setValid(false);
|
|
|
|
}
|
2023-07-20 11:09:34 +02:00
|
|
|
}
|
2023-07-19 16:25:03 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
double angAccelB[3] = {0, 0, 0};
|
2023-07-20 11:09:34 +02:00
|
|
|
VectorOperations<double>::subtract(gyrDataProcessed->gyrVecTot.value, rotRateOldB, angAccelB, 3);
|
|
|
|
double fusedRotRateTotal[3] = {0, 0, 0};
|
2023-11-24 10:52:36 +01:00
|
|
|
VectorOperations<double>::add(fusedRotRateSourcesData->rotRateTotalSusMgm.value, angAccelB,
|
|
|
|
fusedRotRateTotal, 3);
|
2023-07-20 11:09:34 +02:00
|
|
|
{
|
2023-11-24 10:52:36 +01:00
|
|
|
PoolReadGuard pg(fusedRotRateSourcesData);
|
|
|
|
if (pg.getReadResult() == returnvalue::OK) {
|
|
|
|
std::memcpy(fusedRotRateSourcesData->rotRateOrthogonalSusMgm.value, ZERO_VEC3,
|
|
|
|
3 * sizeof(double));
|
|
|
|
fusedRotRateSourcesData->rotRateOrthogonalSusMgm.setValid(false);
|
|
|
|
std::memcpy(fusedRotRateSourcesData->rotRateParallelSusMgm.value, ZERO_VEC3,
|
|
|
|
3 * sizeof(double));
|
|
|
|
fusedRotRateSourcesData->rotRateParallelSusMgm.setValid(false);
|
|
|
|
std::memcpy(fusedRotRateSourcesData->rotRateTotalSusMgm.value, fusedRotRateTotal,
|
|
|
|
3 * sizeof(double));
|
|
|
|
fusedRotRateSourcesData->rotRateTotalSusMgm.setValid(true);
|
|
|
|
}
|
2023-07-20 11:09:34 +02:00
|
|
|
}
|
2023-07-19 16:25:03 +02:00
|
|
|
}
|