Compare commits
59 Commits
Author | SHA1 | Date | |
---|---|---|---|
6fa53e1869 | |||
54328ff357 | |||
c43d9a5a9a | |||
b655c03564 | |||
6ef8c62aca | |||
94cf42fbeb | |||
fe1e236466 | |||
861ad9e62d | |||
5e4032032f | |||
3a137762f3 | |||
92a0752e18 | |||
6ed2fcd904 | |||
2c17aff124 | |||
3ee9a914cc | |||
7a119bab6e | |||
147c39d539 | |||
dcf01d822b | |||
a660d1d30a | |||
0732218249 | |||
4b0062e3b2 | |||
b2a666d432 | |||
7cc13d2024 | |||
0872fad7dc
|
|||
a87a01d072 | |||
73d7f0a1e5 | |||
c3679f044c | |||
68f84e71ff | |||
f2f33f5049 | |||
3314d07942 | |||
4155aa8776 | |||
86d22affe2 | |||
df4205c71e | |||
e130d45f0b | |||
3dbc01bd8a | |||
51a3a2f5cf | |||
cada6e0440 | |||
07ca95205d | |||
b56f2b4b0e | |||
05738d1e25 | |||
12bc9268f7
|
|||
a05a8ffb50
|
|||
cf875f7883 | |||
4bef1bd567 | |||
885fddd45f | |||
fab4cdd0dc | |||
693e11bcb2 | |||
9196b8b0ed | |||
65815e4646 | |||
57ecfadf43 | |||
71d417710e | |||
a66b503e57 | |||
88f3d92dd8 | |||
26199e7317 | |||
620dc60342 | |||
38305e723f | |||
cb879ea97f | |||
f58f4c302c | |||
fdf3657cf6 | |||
a4391c0515
|
36
CHANGELOG.md
36
CHANGELOG.md
@ -18,6 +18,42 @@ will consitute of a breaking change warranting a new major release:
|
|||||||
|
|
||||||
# [v4.0.0] to be released
|
# [v4.0.0] to be released
|
||||||
|
|
||||||
|
# [v3.2.0] 2023-06-21
|
||||||
|
|
||||||
|
## Fixed
|
||||||
|
|
||||||
|
- Fix sun vector calculation
|
||||||
|
- SUS total vector was not reset to being a zero vector during eclipse due to a wrong memcpy
|
||||||
|
length.
|
||||||
|
|
||||||
|
## Changed
|
||||||
|
|
||||||
|
- Reverted all changes related to VC0 handling to avoid FM bug possibly related to FPGA bug.
|
||||||
|
|
||||||
|
# [v3.1.1] 2023-06-14
|
||||||
|
|
||||||
|
## Fixed
|
||||||
|
|
||||||
|
- TMP1075 bugfix where negative temperatures could not be measured because of a two's-complement
|
||||||
|
conversion bug.
|
||||||
|
|
||||||
|
# [v3.1.0] 2023-06-14
|
||||||
|
|
||||||
|
- `eive-tmtc` version v4.1.0
|
||||||
|
|
||||||
|
## Fixed
|
||||||
|
|
||||||
|
- TCS heater switch enumeration naming was old/wrong and was not updated in sync with the object ID
|
||||||
|
update. This lead to the TCS controller commanding the wrong heaters.
|
||||||
|
|
||||||
|
## Changed
|
||||||
|
|
||||||
|
- Increase number of allowed parallel HK commands to 16
|
||||||
|
|
||||||
|
## Added
|
||||||
|
|
||||||
|
- Added `CONFIG_SET`, `MAN_HEATER_ON` and `MAN_HEATER_OFF` support for the BPX battery handler
|
||||||
|
|
||||||
# [v3.0.0] 2023-06-11
|
# [v3.0.0] 2023-06-11
|
||||||
|
|
||||||
- `eive-tmtc` version v4.0.0
|
- `eive-tmtc` version v4.0.0
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
cmake_minimum_required(VERSION 3.13)
|
cmake_minimum_required(VERSION 3.13)
|
||||||
|
|
||||||
set(OBSW_VERSION_MAJOR 3)
|
set(OBSW_VERSION_MAJOR 3)
|
||||||
set(OBSW_VERSION_MINOR 0)
|
set(OBSW_VERSION_MINOR 2)
|
||||||
set(OBSW_VERSION_REVISION 0)
|
set(OBSW_VERSION_REVISION 0)
|
||||||
|
|
||||||
# set(CMAKE_VERBOSE TRUE)
|
# set(CMAKE_VERBOSE TRUE)
|
||||||
@ -81,10 +81,14 @@ else()
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(OBSW_ADD_TMTC_TCP_SERVER
|
set(OBSW_ADD_TMTC_TCP_SERVER
|
||||||
${OBSW_Q7S_EM}
|
# TODO: Only activate on EM when VC0 issue has been resolved.
|
||||||
|
# ${OBSW_Q7S_EM}
|
||||||
|
1
|
||||||
CACHE STRING "Add TCP TMTC Server")
|
CACHE STRING "Add TCP TMTC Server")
|
||||||
set(OBSW_ADD_TMTC_UDP_SERVER
|
set(OBSW_ADD_TMTC_UDP_SERVER
|
||||||
0
|
# TODO: Disable completely when VC0 issue has been resolved
|
||||||
|
# 0
|
||||||
|
${INIT_VAL}
|
||||||
CACHE STRING "Add UDP TMTC Server")
|
CACHE STRING "Add UDP TMTC Server")
|
||||||
set(OBSW_ADD_MGT
|
set(OBSW_ADD_MGT
|
||||||
${INIT_VAL}
|
${INIT_VAL}
|
||||||
|
@ -97,7 +97,8 @@ void ObjectFactory::produce(void* args) {
|
|||||||
#if OBSW_TM_TO_PTME == 1
|
#if OBSW_TM_TO_PTME == 1
|
||||||
if (ccsdsArgs.liveDestination != nullptr) {
|
if (ccsdsArgs.liveDestination != nullptr) {
|
||||||
pusFunnel->addLiveDestination("VC0 LIVE TM", *ccsdsArgs.liveDestination, 0);
|
pusFunnel->addLiveDestination("VC0 LIVE TM", *ccsdsArgs.liveDestination, 0);
|
||||||
cfdpFunnel->addLiveDestination("VC0 LIVE TM", *ccsdsArgs.liveDestination, 0);
|
// Deactivated for tests to avoid changes to VC0 usage.
|
||||||
|
// cfdpFunnel->addLiveDestination("VC0 LIVE TM", *ccsdsArgs.liveDestination, 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif /* OBSW_ADD_CCSDS_IP_CORES == 1 */
|
#endif /* OBSW_ADD_CCSDS_IP_CORES == 1 */
|
||||||
|
2
fsfw
2
fsfw
Submodule fsfw updated: 5322de0599...0f76cdb3ba
@ -106,7 +106,7 @@ void StarTrackerHandler::doShutDown() {
|
|||||||
solutionSet.caliQx.value = 0.0;
|
solutionSet.caliQx.value = 0.0;
|
||||||
solutionSet.caliQy.value = 0.0;
|
solutionSet.caliQy.value = 0.0;
|
||||||
solutionSet.caliQz.value = 0.0;
|
solutionSet.caliQz.value = 0.0;
|
||||||
solutionSet.isTrustWorthy = 0;
|
solutionSet.isTrustWorthy.value = 0;
|
||||||
solutionSet.setValidity(false, true);
|
solutionSet.setValidity(false, true);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
@ -94,6 +94,13 @@ void TmStoreTaskBase::cancelDump(DumpContext& ctx, PersistentTmStore& store, boo
|
|||||||
ReturnValue_t TmStoreTaskBase::handleOneDump(PersistentTmStoreWithTmQueue& store,
|
ReturnValue_t TmStoreTaskBase::handleOneDump(PersistentTmStoreWithTmQueue& store,
|
||||||
DumpContext& dumpContext, bool& dumpPerformed) {
|
DumpContext& dumpContext, bool& dumpPerformed) {
|
||||||
ReturnValue_t result = returnvalue::OK;
|
ReturnValue_t result = returnvalue::OK;
|
||||||
|
// The PTME might have been reset an transmitter state change, so there is no point in continuing
|
||||||
|
// the dump.
|
||||||
|
// TODO: Will be solved in a cleaner way, this is kind of a hack.
|
||||||
|
if (not channel.isTxOn()) {
|
||||||
|
cancelDump(dumpContext, store, false);
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
// It is assumed that the PTME will only be locked for a short period (e.g. to change datarate).
|
// It is assumed that the PTME will only be locked for a short period (e.g. to change datarate).
|
||||||
if (not channel.isBusy() and not ptmeLocked) {
|
if (not channel.isBusy() and not ptmeLocked) {
|
||||||
performDump(store, dumpContext, dumpPerformed);
|
performDump(store, dumpContext, dumpPerformed);
|
||||||
@ -131,22 +138,25 @@ ReturnValue_t TmStoreTaskBase::performDump(PersistentTmStoreWithTmQueue& store,
|
|||||||
dumpContext.ptmeBusyCounter = 0;
|
dumpContext.ptmeBusyCounter = 0;
|
||||||
tmSinkBusyCd.resetTimer();
|
tmSinkBusyCd.resetTimer();
|
||||||
ReturnValue_t result = store.getNextDumpPacket(tmReader, fileHasSwapped);
|
ReturnValue_t result = store.getNextDumpPacket(tmReader, fileHasSwapped);
|
||||||
if (fileHasSwapped and result == PersistentTmStore::DUMP_DONE) {
|
if (result != returnvalue::OK) {
|
||||||
|
sif::error << "PersistentTmStore: Getting next dump packet failed" << std::endl;
|
||||||
|
} else if (fileHasSwapped or result == PersistentTmStore::DUMP_DONE) {
|
||||||
// This can happen if a file is corrupted and the next file swap completes the dump.
|
// This can happen if a file is corrupted and the next file swap completes the dump.
|
||||||
dumpDoneHandler();
|
dumpDoneHandler();
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
} else if (result != returnvalue::OK) {
|
|
||||||
sif::error << "PersistentTmStore: Getting next dump packet failed" << std::endl;
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
dumpedLen = tmReader.getFullPacketLen();
|
dumpedLen = tmReader.getFullPacketLen();
|
||||||
result = channel.write(tmReader.getFullData(), dumpedLen);
|
// Only write to VC if mode is on, but always confirm the dump.
|
||||||
if (result == DirectTmSinkIF::IS_BUSY) {
|
// If the mode is OFF, it is assumed the PTME is not usable and is not allowed to be written
|
||||||
sif::warning << "PersistentTmStore: Unexpected VC channel busy" << std::endl;
|
// (e.g. to confirm a reset or the transmitter is off anyway).
|
||||||
} else if (result != returnvalue::OK) {
|
if (mode == MODE_ON) {
|
||||||
sif::warning << "PersistentTmStore: Unexpected VC channel write failure" << std::endl;
|
result = channel.write(tmReader.getFullData(), dumpedLen);
|
||||||
|
if (result == DirectTmSinkIF::IS_BUSY) {
|
||||||
|
sif::warning << "PersistentTmStore: Unexpected VC channel busy" << std::endl;
|
||||||
|
} else if (result != returnvalue::OK) {
|
||||||
|
sif::warning << "PersistentTmStore: Unexpected VC channel write failure" << std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result = store.confirmDump(tmReader, fileHasSwapped);
|
result = store.confirmDump(tmReader, fileHasSwapped);
|
||||||
if ((result == PersistentTmStore::DUMP_DONE or result == returnvalue::OK)) {
|
if ((result == PersistentTmStore::DUMP_DONE or result == returnvalue::OK)) {
|
||||||
dumpPerformed = true;
|
dumpPerformed = true;
|
||||||
|
@ -11,14 +11,23 @@ ReturnValue_t VirtualChannel::sendNextTm(const uint8_t* data, size_t size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t VirtualChannel::write(const uint8_t* data, size_t size) {
|
ReturnValue_t VirtualChannel::write(const uint8_t* data, size_t size) {
|
||||||
return ptme.writeToVc(vcId, data, size);
|
if (txOn) {
|
||||||
|
return ptme.writeToVc(vcId, data, size);
|
||||||
|
}
|
||||||
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t VirtualChannel::getVcid() const { return vcId; }
|
uint8_t VirtualChannel::getVcid() const { return vcId; }
|
||||||
|
|
||||||
const char* VirtualChannel::getName() const { return vcName.c_str(); }
|
const char* VirtualChannel::getName() const { return vcName.c_str(); }
|
||||||
|
|
||||||
bool VirtualChannel::isBusy() const { return ptme.isBusy(vcId); }
|
bool VirtualChannel::isBusy() const {
|
||||||
|
// Data is discarded, so channel is not busy.
|
||||||
|
if (not txOn) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return ptme.isBusy(vcId);
|
||||||
|
}
|
||||||
|
|
||||||
void VirtualChannel::cancelTransfer() { ptme.cancelTransfer(vcId); }
|
void VirtualChannel::cancelTransfer() { ptme.cancelTransfer(vcId); }
|
||||||
|
|
||||||
|
@ -1002,7 +1002,7 @@ void ThermalController::copyDevices() {
|
|||||||
|
|
||||||
void ThermalController::ctrlAcsBoard() {
|
void ThermalController::ctrlAcsBoard() {
|
||||||
heater::Switch switchNr = heater::HEATER_2_ACS_BRD;
|
heater::Switch switchNr = heater::HEATER_2_ACS_BRD;
|
||||||
heater::Switch redSwitchNr = heater::HEATER_0_OBC_BRD;
|
heater::Switch redSwitchNr = heater::HEATER_3_OBC_BRD;
|
||||||
|
|
||||||
// A side
|
// A side
|
||||||
thermalComponent = ACS_BOARD;
|
thermalComponent = ACS_BOARD;
|
||||||
@ -1067,7 +1067,7 @@ void ThermalController::ctrlMgt() {
|
|||||||
sensors[2].first = sensorTemperatures.plpcduHeatspreader.isValid();
|
sensors[2].first = sensorTemperatures.plpcduHeatspreader.isValid();
|
||||||
sensors[2].second = sensorTemperatures.plpcduHeatspreader.value;
|
sensors[2].second = sensorTemperatures.plpcduHeatspreader.value;
|
||||||
numSensors = 3;
|
numSensors = 3;
|
||||||
HeaterContext htrCtx(heater::HEATER_2_ACS_BRD, heater::HEATER_3_PCDU_PDU, mgtLimits);
|
HeaterContext htrCtx(heater::HEATER_2_ACS_BRD, heater::HEATER_1_PCDU_PDU, mgtLimits);
|
||||||
ctrlComponentTemperature(htrCtx);
|
ctrlComponentTemperature(htrCtx);
|
||||||
if (componentAboveUpperLimit and not mgtTooHotFlag) {
|
if (componentAboveUpperLimit and not mgtTooHotFlag) {
|
||||||
triggerEvent(tcsCtrl::MGT_OVERHEATING, tempFloatToU32());
|
triggerEvent(tcsCtrl::MGT_OVERHEATING, tempFloatToU32());
|
||||||
@ -1206,7 +1206,7 @@ void ThermalController::ctrlIfBoard() {
|
|||||||
sensors[2].first = deviceTemperatures.mgm2SideB.isValid();
|
sensors[2].first = deviceTemperatures.mgm2SideB.isValid();
|
||||||
sensors[2].second = deviceTemperatures.mgm2SideB.value;
|
sensors[2].second = deviceTemperatures.mgm2SideB.value;
|
||||||
numSensors = 3;
|
numSensors = 3;
|
||||||
HeaterContext htrCtx(heater::HEATER_2_ACS_BRD, heater::HEATER_3_PCDU_PDU, ifBoardLimits);
|
HeaterContext htrCtx(heater::HEATER_2_ACS_BRD, heater::HEATER_1_PCDU_PDU, ifBoardLimits);
|
||||||
ctrlComponentTemperature(htrCtx);
|
ctrlComponentTemperature(htrCtx);
|
||||||
// TODO: special event overheating + could go back to safe mode
|
// TODO: special event overheating + could go back to safe mode
|
||||||
}
|
}
|
||||||
@ -1220,7 +1220,7 @@ void ThermalController::ctrlTcsBoard() {
|
|||||||
sensors[2].first = sensorTemperatures.tmp1075Tcs1.isValid();
|
sensors[2].first = sensorTemperatures.tmp1075Tcs1.isValid();
|
||||||
sensors[2].second = sensorTemperatures.tmp1075Tcs1.value;
|
sensors[2].second = sensorTemperatures.tmp1075Tcs1.value;
|
||||||
numSensors = 3;
|
numSensors = 3;
|
||||||
HeaterContext htrCtx(heater::HEATER_0_OBC_BRD, heater::HEATER_2_ACS_BRD, tcsBoardLimits);
|
HeaterContext htrCtx(heater::HEATER_3_OBC_BRD, heater::HEATER_2_ACS_BRD, tcsBoardLimits);
|
||||||
ctrlComponentTemperature(htrCtx);
|
ctrlComponentTemperature(htrCtx);
|
||||||
// TODO: special event overheating + could go back to safe mode
|
// TODO: special event overheating + could go back to safe mode
|
||||||
}
|
}
|
||||||
@ -1234,7 +1234,7 @@ void ThermalController::ctrlObc() {
|
|||||||
sensors[2].first = sensorTemperatures.tmp1075Tcs0.isValid();
|
sensors[2].first = sensorTemperatures.tmp1075Tcs0.isValid();
|
||||||
sensors[2].second = sensorTemperatures.tmp1075Tcs0.value;
|
sensors[2].second = sensorTemperatures.tmp1075Tcs0.value;
|
||||||
numSensors = 3;
|
numSensors = 3;
|
||||||
HeaterContext htrCtx(heater::HEATER_0_OBC_BRD, heater::HEATER_2_ACS_BRD, obcLimits);
|
HeaterContext htrCtx(heater::HEATER_3_OBC_BRD, heater::HEATER_2_ACS_BRD, obcLimits);
|
||||||
ctrlComponentTemperature(htrCtx);
|
ctrlComponentTemperature(htrCtx);
|
||||||
if (componentAboveUpperLimit and not obcTooHotFlag) {
|
if (componentAboveUpperLimit and not obcTooHotFlag) {
|
||||||
triggerEvent(tcsCtrl::OBC_OVERHEATING, tempFloatToU32());
|
triggerEvent(tcsCtrl::OBC_OVERHEATING, tempFloatToU32());
|
||||||
@ -1253,7 +1253,7 @@ void ThermalController::ctrlObcIfBoard() {
|
|||||||
sensors[2].first = sensorTemperatures.tmp1075Tcs1.isValid();
|
sensors[2].first = sensorTemperatures.tmp1075Tcs1.isValid();
|
||||||
sensors[2].second = sensorTemperatures.tmp1075Tcs1.value;
|
sensors[2].second = sensorTemperatures.tmp1075Tcs1.value;
|
||||||
numSensors = 3;
|
numSensors = 3;
|
||||||
HeaterContext htrCtx(heater::HEATER_0_OBC_BRD, heater::HEATER_2_ACS_BRD, obcIfBoardLimits);
|
HeaterContext htrCtx(heater::HEATER_3_OBC_BRD, heater::HEATER_2_ACS_BRD, obcIfBoardLimits);
|
||||||
ctrlComponentTemperature(htrCtx);
|
ctrlComponentTemperature(htrCtx);
|
||||||
if (componentAboveUpperLimit and not obcTooHotFlag) {
|
if (componentAboveUpperLimit and not obcTooHotFlag) {
|
||||||
triggerEvent(tcsCtrl::OBC_OVERHEATING, tempFloatToU32());
|
triggerEvent(tcsCtrl::OBC_OVERHEATING, tempFloatToU32());
|
||||||
@ -1288,7 +1288,7 @@ void ThermalController::ctrlPcduP60Board() {
|
|||||||
sensors[1].first = deviceTemperatures.temp2P60dock.isValid();
|
sensors[1].first = deviceTemperatures.temp2P60dock.isValid();
|
||||||
sensors[1].second = deviceTemperatures.temp2P60dock.value;
|
sensors[1].second = deviceTemperatures.temp2P60dock.value;
|
||||||
numSensors = 2;
|
numSensors = 2;
|
||||||
HeaterContext htrCtx(heater::HEATER_3_PCDU_PDU, heater::HEATER_2_ACS_BRD, pcduP60BoardLimits);
|
HeaterContext htrCtx(heater::HEATER_1_PCDU_PDU, heater::HEATER_2_ACS_BRD, pcduP60BoardLimits);
|
||||||
ctrlComponentTemperature(htrCtx);
|
ctrlComponentTemperature(htrCtx);
|
||||||
if (componentAboveUpperLimit and not pcduSystemTooHotFlag) {
|
if (componentAboveUpperLimit and not pcduSystemTooHotFlag) {
|
||||||
triggerEvent(tcsCtrl::PCDU_SYSTEM_OVERHEATING, tempFloatToU32());
|
triggerEvent(tcsCtrl::PCDU_SYSTEM_OVERHEATING, tempFloatToU32());
|
||||||
@ -1300,7 +1300,7 @@ void ThermalController::ctrlPcduP60Board() {
|
|||||||
|
|
||||||
void ThermalController::ctrlPcduAcu() {
|
void ThermalController::ctrlPcduAcu() {
|
||||||
thermalComponent = PCDUACU;
|
thermalComponent = PCDUACU;
|
||||||
heater::Switch switchNr = heater::HEATER_3_PCDU_PDU;
|
heater::Switch switchNr = heater::HEATER_1_PCDU_PDU;
|
||||||
heater::Switch redSwitchNr = heater::HEATER_2_ACS_BRD;
|
heater::Switch redSwitchNr = heater::HEATER_2_ACS_BRD;
|
||||||
|
|
||||||
if (chooseHeater(switchNr, redSwitchNr)) {
|
if (chooseHeater(switchNr, redSwitchNr)) {
|
||||||
@ -1340,7 +1340,7 @@ void ThermalController::ctrlPcduPdu() {
|
|||||||
sensors[2].first = sensorTemperatures.tmp1075Tcs0.isValid();
|
sensors[2].first = sensorTemperatures.tmp1075Tcs0.isValid();
|
||||||
sensors[2].second = sensorTemperatures.tmp1075Tcs0.value;
|
sensors[2].second = sensorTemperatures.tmp1075Tcs0.value;
|
||||||
numSensors = 3;
|
numSensors = 3;
|
||||||
HeaterContext htrCtx(heater::HEATER_3_PCDU_PDU, heater::HEATER_2_ACS_BRD, pcduPduLimits);
|
HeaterContext htrCtx(heater::HEATER_1_PCDU_PDU, heater::HEATER_2_ACS_BRD, pcduPduLimits);
|
||||||
ctrlComponentTemperature(htrCtx);
|
ctrlComponentTemperature(htrCtx);
|
||||||
if (componentAboveUpperLimit and not pcduSystemTooHotFlag) {
|
if (componentAboveUpperLimit and not pcduSystemTooHotFlag) {
|
||||||
triggerEvent(tcsCtrl::PCDU_SYSTEM_OVERHEATING, tempFloatToU32());
|
triggerEvent(tcsCtrl::PCDU_SYSTEM_OVERHEATING, tempFloatToU32());
|
||||||
@ -1361,7 +1361,7 @@ void ThermalController::ctrlPlPcduBoard() {
|
|||||||
sensors[3].first = sensorTemperatures.plpcduHeatspreader.isValid();
|
sensors[3].first = sensorTemperatures.plpcduHeatspreader.isValid();
|
||||||
sensors[3].second = sensorTemperatures.plpcduHeatspreader.value;
|
sensors[3].second = sensorTemperatures.plpcduHeatspreader.value;
|
||||||
numSensors = 4;
|
numSensors = 4;
|
||||||
HeaterContext htrCtx(heater::HEATER_3_PCDU_PDU, heater::HEATER_2_ACS_BRD, plPcduBoardLimits);
|
HeaterContext htrCtx(heater::HEATER_1_PCDU_PDU, heater::HEATER_2_ACS_BRD, plPcduBoardLimits);
|
||||||
ctrlComponentTemperature(htrCtx);
|
ctrlComponentTemperature(htrCtx);
|
||||||
tooHotHandler(objects::PLPCDU_HANDLER, eBandTooHotFlag);
|
tooHotHandler(objects::PLPCDU_HANDLER, eBandTooHotFlag);
|
||||||
}
|
}
|
||||||
@ -1375,7 +1375,7 @@ void ThermalController::ctrlPlocMissionBoard() {
|
|||||||
sensors[2].first = sensorTemperatures.dacHeatspreader.isValid();
|
sensors[2].first = sensorTemperatures.dacHeatspreader.isValid();
|
||||||
sensors[2].second = sensorTemperatures.dacHeatspreader.value;
|
sensors[2].second = sensorTemperatures.dacHeatspreader.value;
|
||||||
numSensors = 3;
|
numSensors = 3;
|
||||||
HeaterContext htrCtx(heater::HEATER_1_PLOC_PROC_BRD, heater::HEATER_0_OBC_BRD,
|
HeaterContext htrCtx(heater::HEATER_0_PLOC_PROC_BRD, heater::HEATER_3_OBC_BRD,
|
||||||
plocMissionBoardLimits);
|
plocMissionBoardLimits);
|
||||||
ctrlComponentTemperature(htrCtx);
|
ctrlComponentTemperature(htrCtx);
|
||||||
tooHotHandler(objects::PLOC_SUPERVISOR_HANDLER, plocTooHotFlag);
|
tooHotHandler(objects::PLOC_SUPERVISOR_HANDLER, plocTooHotFlag);
|
||||||
@ -1390,7 +1390,7 @@ void ThermalController::ctrlPlocProcessingBoard() {
|
|||||||
sensors[2].first = sensorTemperatures.dacHeatspreader.isValid();
|
sensors[2].first = sensorTemperatures.dacHeatspreader.isValid();
|
||||||
sensors[2].second = sensorTemperatures.dacHeatspreader.value;
|
sensors[2].second = sensorTemperatures.dacHeatspreader.value;
|
||||||
numSensors = 3;
|
numSensors = 3;
|
||||||
HeaterContext htrCtx(heater::HEATER_1_PLOC_PROC_BRD, heater::HEATER_0_OBC_BRD,
|
HeaterContext htrCtx(heater::HEATER_0_PLOC_PROC_BRD, heater::HEATER_3_OBC_BRD,
|
||||||
plocProcessingBoardLimits);
|
plocProcessingBoardLimits);
|
||||||
ctrlComponentTemperature(htrCtx);
|
ctrlComponentTemperature(htrCtx);
|
||||||
tooHotHandler(objects::PLOC_SUPERVISOR_HANDLER, plocTooHotFlag);
|
tooHotHandler(objects::PLOC_SUPERVISOR_HANDLER, plocTooHotFlag);
|
||||||
@ -1405,7 +1405,7 @@ void ThermalController::ctrlDac() {
|
|||||||
sensors[2].first = sensorTemperatures.plocHeatspreader.isValid();
|
sensors[2].first = sensorTemperatures.plocHeatspreader.isValid();
|
||||||
sensors[2].second = sensorTemperatures.plocHeatspreader.value;
|
sensors[2].second = sensorTemperatures.plocHeatspreader.value;
|
||||||
numSensors = 3;
|
numSensors = 3;
|
||||||
HeaterContext htrCtx(heater::HEATER_1_PLOC_PROC_BRD, heater::HEATER_0_OBC_BRD, dacLimits);
|
HeaterContext htrCtx(heater::HEATER_0_PLOC_PROC_BRD, heater::HEATER_3_OBC_BRD, dacLimits);
|
||||||
ctrlComponentTemperature(htrCtx);
|
ctrlComponentTemperature(htrCtx);
|
||||||
tooHotHandler(objects::PLPCDU_HANDLER, eBandTooHotFlag);
|
tooHotHandler(objects::PLPCDU_HANDLER, eBandTooHotFlag);
|
||||||
}
|
}
|
||||||
|
@ -221,6 +221,9 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
|||||||
case 0x23:
|
case 0x23:
|
||||||
parameterWrapper->setMatrix(susHandlingParameters.sus11coeffBeta);
|
parameterWrapper->setMatrix(susHandlingParameters.sus11coeffBeta);
|
||||||
break;
|
break;
|
||||||
|
case 0x24:
|
||||||
|
parameterWrapper->set(susHandlingParameters.susBrightnessThreshold);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return INVALID_IDENTIFIER_ID;
|
return INVALID_IDENTIFIER_ID;
|
||||||
}
|
}
|
||||||
|
@ -766,6 +766,7 @@ class AcsParameters : public HasParametersIF {
|
|||||||
{116.975421945286, -5.53022680362263, -5.61081660666997, 0.109754904982136,
|
{116.975421945286, -5.53022680362263, -5.61081660666997, 0.109754904982136,
|
||||||
0.167666815691513, 0.163137400730063, -0.000609874123906977, -0.00205336098697513,
|
0.167666815691513, 0.163137400730063, -0.000609874123906977, -0.00205336098697513,
|
||||||
-0.000889232196185857, -0.00168429567131815}};
|
-0.000889232196185857, -0.00168429567131815}};
|
||||||
|
float susBrightnessThreshold = 0.7;
|
||||||
} susHandlingParameters;
|
} susHandlingParameters;
|
||||||
|
|
||||||
struct GyrHandlingParameters {
|
struct GyrHandlingParameters {
|
||||||
|
@ -30,10 +30,7 @@ void SensorProcessing::processMgm(const float *mgm0Value, bool mgm0valid, const
|
|||||||
// ------------------------------------------------
|
// ------------------------------------------------
|
||||||
double magIgrfModel[3] = {0.0, 0.0, 0.0};
|
double magIgrfModel[3] = {0.0, 0.0, 0.0};
|
||||||
if (gpsValid) {
|
if (gpsValid) {
|
||||||
// Should be existing class object which will be called and modified here.
|
|
||||||
Igrf13Model igrf13;
|
Igrf13Model igrf13;
|
||||||
// So the line above should not be done here. Update: Can be done here as long updated coffs
|
|
||||||
// stored in acsParameters ?
|
|
||||||
igrf13.schmidtNormalization();
|
igrf13.schmidtNormalization();
|
||||||
igrf13.updateCoeffGH(timeOfMgmMeasurement);
|
igrf13.updateCoeffGH(timeOfMgmMeasurement);
|
||||||
// maybe put a condition here, to only update after a full day, this
|
// maybe put a condition here, to only update after a full day, this
|
||||||
@ -45,14 +42,13 @@ void SensorProcessing::processMgm(const float *mgm0Value, bool mgm0valid, const
|
|||||||
{
|
{
|
||||||
PoolReadGuard pg(mgmDataProcessed);
|
PoolReadGuard pg(mgmDataProcessed);
|
||||||
if (pg.getReadResult() == returnvalue::OK) {
|
if (pg.getReadResult() == returnvalue::OK) {
|
||||||
float zeroVec[3] = {0.0, 0.0, 0.0};
|
std::memcpy(mgmDataProcessed->mgm0vec.value, ZERO_VEC_F, 3 * sizeof(float));
|
||||||
std::memcpy(mgmDataProcessed->mgm0vec.value, zeroVec, 3 * sizeof(float));
|
std::memcpy(mgmDataProcessed->mgm1vec.value, ZERO_VEC_F, 3 * sizeof(float));
|
||||||
std::memcpy(mgmDataProcessed->mgm1vec.value, zeroVec, 3 * sizeof(float));
|
std::memcpy(mgmDataProcessed->mgm2vec.value, ZERO_VEC_F, 3 * sizeof(float));
|
||||||
std::memcpy(mgmDataProcessed->mgm2vec.value, zeroVec, 3 * sizeof(float));
|
std::memcpy(mgmDataProcessed->mgm3vec.value, ZERO_VEC_F, 3 * sizeof(float));
|
||||||
std::memcpy(mgmDataProcessed->mgm3vec.value, zeroVec, 3 * sizeof(float));
|
std::memcpy(mgmDataProcessed->mgm4vec.value, ZERO_VEC_F, 3 * sizeof(float));
|
||||||
std::memcpy(mgmDataProcessed->mgm4vec.value, zeroVec, 3 * sizeof(float));
|
std::memcpy(mgmDataProcessed->mgmVecTot.value, ZERO_VEC_D, 3 * sizeof(double));
|
||||||
std::memcpy(mgmDataProcessed->mgmVecTot.value, zeroVec, 3 * sizeof(float));
|
std::memcpy(mgmDataProcessed->mgmVecTotDerivative.value, ZERO_VEC_D, 3 * sizeof(double));
|
||||||
std::memcpy(mgmDataProcessed->mgmVecTotDerivative.value, zeroVec, 3 * sizeof(float));
|
|
||||||
mgmDataProcessed->setValidity(false, true);
|
mgmDataProcessed->setValidity(false, true);
|
||||||
std::memcpy(mgmDataProcessed->magIgrfModel.value, magIgrfModel, 3 * sizeof(double));
|
std::memcpy(mgmDataProcessed->magIgrfModel.value, magIgrfModel, 3 * sizeof(double));
|
||||||
mgmDataProcessed->magIgrfModel.setValid(gpsValid);
|
mgmDataProcessed->magIgrfModel.setValid(gpsValid);
|
||||||
@ -210,63 +206,68 @@ void SensorProcessing::processSus(
|
|||||||
sunIjkModel[0] = cos(eclipticLongitude);
|
sunIjkModel[0] = cos(eclipticLongitude);
|
||||||
sunIjkModel[1] = sin(eclipticLongitude) * cos(epsilon);
|
sunIjkModel[1] = sin(eclipticLongitude) * cos(epsilon);
|
||||||
sunIjkModel[2] = sin(eclipticLongitude) * sin(epsilon);
|
sunIjkModel[2] = sin(eclipticLongitude) * sin(epsilon);
|
||||||
|
|
||||||
|
uint64_t susBrightness[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||||
if (sus0valid) {
|
if (sus0valid) {
|
||||||
sus0valid = susConverter.checkSunSensorData(sus0Value);
|
susBrightness[0] = susConverter.checkSunSensorData(sus0Value);
|
||||||
}
|
}
|
||||||
if (sus1valid) {
|
if (sus1valid) {
|
||||||
sus1valid = susConverter.checkSunSensorData(sus1Value);
|
susBrightness[1] = susConverter.checkSunSensorData(sus1Value);
|
||||||
}
|
}
|
||||||
if (sus2valid) {
|
if (sus2valid) {
|
||||||
sus2valid = susConverter.checkSunSensorData(sus2Value);
|
susBrightness[2] = susConverter.checkSunSensorData(sus2Value);
|
||||||
}
|
}
|
||||||
if (sus3valid) {
|
if (sus3valid) {
|
||||||
sus3valid = susConverter.checkSunSensorData(sus3Value);
|
susBrightness[3] = susConverter.checkSunSensorData(sus3Value);
|
||||||
}
|
}
|
||||||
if (sus4valid) {
|
if (sus4valid) {
|
||||||
sus4valid = susConverter.checkSunSensorData(sus4Value);
|
susBrightness[4] = susConverter.checkSunSensorData(sus4Value);
|
||||||
}
|
}
|
||||||
if (sus5valid) {
|
if (sus5valid) {
|
||||||
sus5valid = susConverter.checkSunSensorData(sus5Value);
|
susBrightness[5] = susConverter.checkSunSensorData(sus5Value);
|
||||||
}
|
}
|
||||||
if (sus6valid) {
|
if (sus6valid) {
|
||||||
sus6valid = susConverter.checkSunSensorData(sus6Value);
|
susBrightness[6] = susConverter.checkSunSensorData(sus6Value);
|
||||||
}
|
}
|
||||||
if (sus7valid) {
|
if (sus7valid) {
|
||||||
sus7valid = susConverter.checkSunSensorData(sus7Value);
|
susBrightness[7] = susConverter.checkSunSensorData(sus7Value);
|
||||||
}
|
}
|
||||||
if (sus8valid) {
|
if (sus8valid) {
|
||||||
sus8valid = susConverter.checkSunSensorData(sus8Value);
|
susBrightness[8] = susConverter.checkSunSensorData(sus8Value);
|
||||||
}
|
}
|
||||||
if (sus9valid) {
|
if (sus9valid) {
|
||||||
sus9valid = susConverter.checkSunSensorData(sus9Value);
|
susBrightness[9] = susConverter.checkSunSensorData(sus9Value);
|
||||||
}
|
}
|
||||||
if (sus10valid) {
|
if (sus10valid) {
|
||||||
sus10valid = susConverter.checkSunSensorData(sus10Value);
|
susBrightness[10] = susConverter.checkSunSensorData(sus10Value);
|
||||||
}
|
}
|
||||||
if (sus11valid) {
|
if (sus11valid) {
|
||||||
sus11valid = susConverter.checkSunSensorData(sus11Value);
|
susBrightness[11] = susConverter.checkSunSensorData(sus11Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sus0valid && !sus1valid && !sus2valid && !sus3valid && !sus4valid && !sus5valid &&
|
bool susValid[12] = {sus0valid, sus1valid, sus2valid, sus3valid, sus4valid, sus5valid,
|
||||||
!sus6valid && !sus7valid && !sus8valid && !sus9valid && !sus10valid && !sus11valid) {
|
sus6valid, sus7valid, sus8valid, sus9valid, sus10valid, sus11valid};
|
||||||
|
bool allInvalid =
|
||||||
|
susConverter.checkValidity(susValid, susBrightness, susParameters->susBrightnessThreshold);
|
||||||
|
|
||||||
|
if (allInvalid) {
|
||||||
{
|
{
|
||||||
PoolReadGuard pg(susDataProcessed);
|
PoolReadGuard pg(susDataProcessed);
|
||||||
if (pg.getReadResult() == returnvalue::OK) {
|
if (pg.getReadResult() == returnvalue::OK) {
|
||||||
float zeroVec[3] = {0.0, 0.0, 0.0};
|
std::memcpy(susDataProcessed->sus0vec.value, ZERO_VEC_F, 3 * sizeof(float));
|
||||||
std::memcpy(susDataProcessed->sus0vec.value, zeroVec, 3 * sizeof(float));
|
std::memcpy(susDataProcessed->sus1vec.value, ZERO_VEC_F, 3 * sizeof(float));
|
||||||
std::memcpy(susDataProcessed->sus1vec.value, zeroVec, 3 * sizeof(float));
|
std::memcpy(susDataProcessed->sus2vec.value, ZERO_VEC_F, 3 * sizeof(float));
|
||||||
std::memcpy(susDataProcessed->sus2vec.value, zeroVec, 3 * sizeof(float));
|
std::memcpy(susDataProcessed->sus3vec.value, ZERO_VEC_F, 3 * sizeof(float));
|
||||||
std::memcpy(susDataProcessed->sus3vec.value, zeroVec, 3 * sizeof(float));
|
std::memcpy(susDataProcessed->sus4vec.value, ZERO_VEC_F, 3 * sizeof(float));
|
||||||
std::memcpy(susDataProcessed->sus4vec.value, zeroVec, 3 * sizeof(float));
|
std::memcpy(susDataProcessed->sus5vec.value, ZERO_VEC_F, 3 * sizeof(float));
|
||||||
std::memcpy(susDataProcessed->sus5vec.value, zeroVec, 3 * sizeof(float));
|
std::memcpy(susDataProcessed->sus6vec.value, ZERO_VEC_F, 3 * sizeof(float));
|
||||||
std::memcpy(susDataProcessed->sus6vec.value, zeroVec, 3 * sizeof(float));
|
std::memcpy(susDataProcessed->sus7vec.value, ZERO_VEC_F, 3 * sizeof(float));
|
||||||
std::memcpy(susDataProcessed->sus7vec.value, zeroVec, 3 * sizeof(float));
|
std::memcpy(susDataProcessed->sus8vec.value, ZERO_VEC_F, 3 * sizeof(float));
|
||||||
std::memcpy(susDataProcessed->sus8vec.value, zeroVec, 3 * sizeof(float));
|
std::memcpy(susDataProcessed->sus9vec.value, ZERO_VEC_F, 3 * sizeof(float));
|
||||||
std::memcpy(susDataProcessed->sus9vec.value, zeroVec, 3 * sizeof(float));
|
std::memcpy(susDataProcessed->sus10vec.value, ZERO_VEC_F, 3 * sizeof(float));
|
||||||
std::memcpy(susDataProcessed->sus10vec.value, zeroVec, 3 * sizeof(float));
|
std::memcpy(susDataProcessed->sus11vec.value, ZERO_VEC_F, 3 * sizeof(float));
|
||||||
std::memcpy(susDataProcessed->sus11vec.value, zeroVec, 3 * sizeof(float));
|
std::memcpy(susDataProcessed->susVecTot.value, ZERO_VEC_D, 3 * sizeof(double));
|
||||||
std::memcpy(susDataProcessed->susVecTot.value, zeroVec, 3 * sizeof(float));
|
std::memcpy(susDataProcessed->susVecTotDerivative.value, ZERO_VEC_D, 3 * sizeof(double));
|
||||||
std::memcpy(susDataProcessed->susVecTotDerivative.value, zeroVec, 3 * sizeof(float));
|
|
||||||
susDataProcessed->setValidity(false, true);
|
susDataProcessed->setValidity(false, true);
|
||||||
std::memcpy(susDataProcessed->sunIjkModel.value, sunIjkModel, 3 * sizeof(double));
|
std::memcpy(susDataProcessed->sunIjkModel.value, sunIjkModel, 3 * sizeof(double));
|
||||||
susDataProcessed->sunIjkModel.setValid(true);
|
susDataProcessed->sunIjkModel.setValid(true);
|
||||||
@ -274,118 +275,78 @@ void SensorProcessing::processSus(
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// WARNING: NOT TRANSFORMED IN BODY FRAME YET
|
|
||||||
// Transformation into Geomtry Frame
|
|
||||||
float sus0VecBody[3] = {0, 0, 0}, sus1VecBody[3] = {0, 0, 0}, sus2VecBody[3] = {0, 0, 0},
|
|
||||||
sus3VecBody[3] = {0, 0, 0}, sus4VecBody[3] = {0, 0, 0}, sus5VecBody[3] = {0, 0, 0},
|
|
||||||
sus6VecBody[3] = {0, 0, 0}, sus7VecBody[3] = {0, 0, 0}, sus8VecBody[3] = {0, 0, 0},
|
|
||||||
sus9VecBody[3] = {0, 0, 0}, sus10VecBody[3] = {0, 0, 0}, sus11VecBody[3] = {0, 0, 0};
|
|
||||||
|
|
||||||
if (sus0valid) {
|
float susVecSensor[12][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||||
MatrixOperations<float>::multiply(
|
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
||||||
susParameters->sus0orientationMatrix[0],
|
float susVecBody[12][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
|
||||||
susConverter.getSunVectorSensorFrame(sus0Value, susParameters->sus0coeffAlpha,
|
{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
||||||
susParameters->sus0coeffBeta),
|
|
||||||
sus0VecBody, 3, 3, 1);
|
|
||||||
}
|
|
||||||
if (sus1valid) {
|
|
||||||
MatrixOperations<float>::multiply(
|
|
||||||
susParameters->sus1orientationMatrix[0],
|
|
||||||
susConverter.getSunVectorSensorFrame(sus1Value, susParameters->sus1coeffAlpha,
|
|
||||||
susParameters->sus1coeffBeta),
|
|
||||||
sus1VecBody, 3, 3, 1);
|
|
||||||
}
|
|
||||||
if (sus2valid) {
|
|
||||||
MatrixOperations<float>::multiply(
|
|
||||||
susParameters->sus2orientationMatrix[0],
|
|
||||||
susConverter.getSunVectorSensorFrame(sus2Value, susParameters->sus2coeffAlpha,
|
|
||||||
susParameters->sus2coeffBeta),
|
|
||||||
sus2VecBody, 3, 3, 1);
|
|
||||||
}
|
|
||||||
if (sus3valid) {
|
|
||||||
MatrixOperations<float>::multiply(
|
|
||||||
susParameters->sus3orientationMatrix[0],
|
|
||||||
susConverter.getSunVectorSensorFrame(sus3Value, susParameters->sus3coeffAlpha,
|
|
||||||
susParameters->sus3coeffBeta),
|
|
||||||
sus3VecBody, 3, 3, 1);
|
|
||||||
}
|
|
||||||
if (sus4valid) {
|
|
||||||
MatrixOperations<float>::multiply(
|
|
||||||
susParameters->sus4orientationMatrix[0],
|
|
||||||
susConverter.getSunVectorSensorFrame(sus4Value, susParameters->sus4coeffAlpha,
|
|
||||||
susParameters->sus4coeffBeta),
|
|
||||||
sus4VecBody, 3, 3, 1);
|
|
||||||
}
|
|
||||||
if (sus5valid) {
|
|
||||||
MatrixOperations<float>::multiply(
|
|
||||||
susParameters->sus5orientationMatrix[0],
|
|
||||||
susConverter.getSunVectorSensorFrame(sus5Value, susParameters->sus5coeffAlpha,
|
|
||||||
susParameters->sus5coeffBeta),
|
|
||||||
sus5VecBody, 3, 3, 1);
|
|
||||||
}
|
|
||||||
if (sus6valid) {
|
|
||||||
MatrixOperations<float>::multiply(
|
|
||||||
susParameters->sus6orientationMatrix[0],
|
|
||||||
susConverter.getSunVectorSensorFrame(sus6Value, susParameters->sus6coeffAlpha,
|
|
||||||
susParameters->sus6coeffBeta),
|
|
||||||
sus6VecBody, 3, 3, 1);
|
|
||||||
}
|
|
||||||
if (sus7valid) {
|
|
||||||
MatrixOperations<float>::multiply(
|
|
||||||
susParameters->sus7orientationMatrix[0],
|
|
||||||
susConverter.getSunVectorSensorFrame(sus7Value, susParameters->sus7coeffAlpha,
|
|
||||||
susParameters->sus7coeffBeta),
|
|
||||||
sus7VecBody, 3, 3, 1);
|
|
||||||
}
|
|
||||||
if (sus8valid) {
|
|
||||||
MatrixOperations<float>::multiply(
|
|
||||||
susParameters->sus8orientationMatrix[0],
|
|
||||||
susConverter.getSunVectorSensorFrame(sus8Value, susParameters->sus8coeffAlpha,
|
|
||||||
susParameters->sus8coeffBeta),
|
|
||||||
sus8VecBody, 3, 3, 1);
|
|
||||||
}
|
|
||||||
if (sus9valid) {
|
|
||||||
MatrixOperations<float>::multiply(
|
|
||||||
susParameters->sus9orientationMatrix[0],
|
|
||||||
susConverter.getSunVectorSensorFrame(sus9Value, susParameters->sus9coeffAlpha,
|
|
||||||
susParameters->sus9coeffBeta),
|
|
||||||
sus9VecBody, 3, 3, 1);
|
|
||||||
}
|
|
||||||
if (sus10valid) {
|
|
||||||
MatrixOperations<float>::multiply(
|
|
||||||
susParameters->sus10orientationMatrix[0],
|
|
||||||
susConverter.getSunVectorSensorFrame(sus10Value, susParameters->sus10coeffAlpha,
|
|
||||||
susParameters->sus10coeffBeta),
|
|
||||||
sus10VecBody, 3, 3, 1);
|
|
||||||
}
|
|
||||||
if (sus11valid) {
|
|
||||||
MatrixOperations<float>::multiply(
|
|
||||||
susParameters->sus11orientationMatrix[0],
|
|
||||||
susConverter.getSunVectorSensorFrame(sus11Value, susParameters->sus11coeffAlpha,
|
|
||||||
susParameters->sus11coeffBeta),
|
|
||||||
sus11VecBody, 3, 3, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------ Mean Value: susDirEst ------ */
|
if (susValid[0]) {
|
||||||
bool validIds[12] = {sus0valid, sus1valid, sus2valid, sus3valid, sus4valid, sus5valid,
|
susConverter.calculateSunVector(susVecSensor[0], sus0Value);
|
||||||
sus6valid, sus7valid, sus8valid, sus9valid, sus10valid, sus11valid};
|
MatrixOperations<float>::multiply(susParameters->sus0orientationMatrix[0], susVecSensor[0],
|
||||||
float susVecBody[3][12] = {{sus0VecBody[0], sus1VecBody[0], sus2VecBody[0], sus3VecBody[0],
|
susVecBody[0], 3, 3, 1);
|
||||||
sus4VecBody[0], sus5VecBody[0], sus6VecBody[0], sus7VecBody[0],
|
}
|
||||||
sus8VecBody[0], sus9VecBody[0], sus10VecBody[0], sus11VecBody[0]},
|
if (susValid[1]) {
|
||||||
{sus0VecBody[1], sus1VecBody[1], sus2VecBody[1], sus3VecBody[1],
|
susConverter.calculateSunVector(susVecSensor[1], sus1Value);
|
||||||
sus4VecBody[1], sus5VecBody[1], sus6VecBody[1], sus7VecBody[1],
|
MatrixOperations<float>::multiply(susParameters->sus1orientationMatrix[0], susVecSensor[1],
|
||||||
sus8VecBody[1], sus9VecBody[1], sus10VecBody[1], sus11VecBody[1]},
|
susVecBody[1], 3, 3, 1);
|
||||||
{sus0VecBody[2], sus1VecBody[2], sus2VecBody[2], sus3VecBody[2],
|
}
|
||||||
sus4VecBody[2], sus5VecBody[2], sus6VecBody[2], sus7VecBody[2],
|
if (susValid[2]) {
|
||||||
sus8VecBody[2], sus9VecBody[2], sus10VecBody[2], sus11VecBody[2]}};
|
susConverter.calculateSunVector(susVecSensor[2], sus2Value);
|
||||||
|
MatrixOperations<float>::multiply(susParameters->sus2orientationMatrix[0], susVecSensor[2],
|
||||||
|
susVecBody[2], 3, 3, 1);
|
||||||
|
}
|
||||||
|
if (susValid[3]) {
|
||||||
|
susConverter.calculateSunVector(susVecSensor[3], sus3Value);
|
||||||
|
MatrixOperations<float>::multiply(susParameters->sus3orientationMatrix[0], susVecSensor[3],
|
||||||
|
susVecBody[3], 3, 3, 1);
|
||||||
|
}
|
||||||
|
if (susValid[4]) {
|
||||||
|
susConverter.calculateSunVector(susVecSensor[4], sus4Value);
|
||||||
|
MatrixOperations<float>::multiply(susParameters->sus4orientationMatrix[0], susVecSensor[4],
|
||||||
|
susVecBody[4], 3, 3, 1);
|
||||||
|
}
|
||||||
|
if (susValid[5]) {
|
||||||
|
susConverter.calculateSunVector(susVecSensor[5], sus5Value);
|
||||||
|
MatrixOperations<float>::multiply(susParameters->sus5orientationMatrix[0], susVecSensor[5],
|
||||||
|
susVecBody[5], 3, 3, 1);
|
||||||
|
}
|
||||||
|
if (susValid[6]) {
|
||||||
|
susConverter.calculateSunVector(susVecSensor[6], sus6Value);
|
||||||
|
MatrixOperations<float>::multiply(susParameters->sus6orientationMatrix[0], susVecSensor[6],
|
||||||
|
susVecBody[6], 3, 3, 1);
|
||||||
|
}
|
||||||
|
if (susValid[7]) {
|
||||||
|
susConverter.calculateSunVector(susVecSensor[7], sus7Value);
|
||||||
|
MatrixOperations<float>::multiply(susParameters->sus7orientationMatrix[0], susVecSensor[7],
|
||||||
|
susVecBody[7], 3, 3, 1);
|
||||||
|
}
|
||||||
|
if (susValid[8]) {
|
||||||
|
susConverter.calculateSunVector(susVecSensor[8], sus8Value);
|
||||||
|
MatrixOperations<float>::multiply(susParameters->sus8orientationMatrix[0], susVecSensor[8],
|
||||||
|
susVecBody[8], 3, 3, 1);
|
||||||
|
}
|
||||||
|
if (susValid[9]) {
|
||||||
|
susConverter.calculateSunVector(susVecSensor[9], sus9Value);
|
||||||
|
MatrixOperations<float>::multiply(susParameters->sus9orientationMatrix[0], susVecSensor[9],
|
||||||
|
susVecBody[9], 3, 3, 1);
|
||||||
|
}
|
||||||
|
if (susValid[10]) {
|
||||||
|
susConverter.calculateSunVector(susVecSensor[10], sus10Value);
|
||||||
|
MatrixOperations<float>::multiply(susParameters->sus10orientationMatrix[0], susVecSensor[10],
|
||||||
|
susVecBody[10], 3, 3, 1);
|
||||||
|
}
|
||||||
|
if (susValid[11]) {
|
||||||
|
susConverter.calculateSunVector(susVecSensor[11], sus11Value);
|
||||||
|
MatrixOperations<float>::multiply(susParameters->sus11orientationMatrix[0], susVecSensor[11],
|
||||||
|
susVecBody[11], 3, 3, 1);
|
||||||
|
}
|
||||||
|
|
||||||
double susMeanValue[3] = {0, 0, 0};
|
double susMeanValue[3] = {0, 0, 0};
|
||||||
for (uint8_t i = 0; i < 12; i++) {
|
for (uint8_t i = 0; i < 12; i++) {
|
||||||
if (validIds[i]) {
|
susMeanValue[0] += susVecBody[i][0];
|
||||||
susMeanValue[0] += susVecBody[0][i];
|
susMeanValue[1] += susVecBody[i][1];
|
||||||
susMeanValue[1] += susVecBody[1][i];
|
susMeanValue[2] += susVecBody[i][2];
|
||||||
susMeanValue[2] += susVecBody[2][i];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
double susVecTot[3] = {0.0, 0.0, 0.0};
|
double susVecTot[3] = {0.0, 0.0, 0.0};
|
||||||
VectorOperations<double>::normalize(susMeanValue, susVecTot, 3);
|
VectorOperations<double>::normalize(susMeanValue, susVecTot, 3);
|
||||||
@ -406,29 +367,29 @@ void SensorProcessing::processSus(
|
|||||||
{
|
{
|
||||||
PoolReadGuard pg(susDataProcessed);
|
PoolReadGuard pg(susDataProcessed);
|
||||||
if (pg.getReadResult() == returnvalue::OK) {
|
if (pg.getReadResult() == returnvalue::OK) {
|
||||||
std::memcpy(susDataProcessed->sus0vec.value, sus0VecBody, 3 * sizeof(float));
|
std::memcpy(susDataProcessed->sus0vec.value, susVecBody[0], 3 * sizeof(float));
|
||||||
susDataProcessed->sus0vec.setValid(sus0valid);
|
susDataProcessed->sus0vec.setValid(sus0valid);
|
||||||
std::memcpy(susDataProcessed->sus1vec.value, sus1VecBody, 3 * sizeof(float));
|
std::memcpy(susDataProcessed->sus1vec.value, susVecBody[1], 3 * sizeof(float));
|
||||||
susDataProcessed->sus1vec.setValid(sus1valid);
|
susDataProcessed->sus1vec.setValid(sus1valid);
|
||||||
std::memcpy(susDataProcessed->sus2vec.value, sus2VecBody, 3 * sizeof(float));
|
std::memcpy(susDataProcessed->sus2vec.value, susVecBody[2], 3 * sizeof(float));
|
||||||
susDataProcessed->sus2vec.setValid(sus2valid);
|
susDataProcessed->sus2vec.setValid(sus2valid);
|
||||||
std::memcpy(susDataProcessed->sus3vec.value, sus3VecBody, 3 * sizeof(float));
|
std::memcpy(susDataProcessed->sus3vec.value, susVecBody[3], 3 * sizeof(float));
|
||||||
susDataProcessed->sus3vec.setValid(sus3valid);
|
susDataProcessed->sus3vec.setValid(sus3valid);
|
||||||
std::memcpy(susDataProcessed->sus4vec.value, sus4VecBody, 3 * sizeof(float));
|
std::memcpy(susDataProcessed->sus4vec.value, susVecBody[4], 3 * sizeof(float));
|
||||||
susDataProcessed->sus4vec.setValid(sus4valid);
|
susDataProcessed->sus4vec.setValid(sus4valid);
|
||||||
std::memcpy(susDataProcessed->sus5vec.value, sus5VecBody, 3 * sizeof(float));
|
std::memcpy(susDataProcessed->sus5vec.value, susVecBody[5], 3 * sizeof(float));
|
||||||
susDataProcessed->sus5vec.setValid(sus5valid);
|
susDataProcessed->sus5vec.setValid(sus5valid);
|
||||||
std::memcpy(susDataProcessed->sus6vec.value, sus6VecBody, 3 * sizeof(float));
|
std::memcpy(susDataProcessed->sus6vec.value, susVecBody[6], 3 * sizeof(float));
|
||||||
susDataProcessed->sus6vec.setValid(sus6valid);
|
susDataProcessed->sus6vec.setValid(sus6valid);
|
||||||
std::memcpy(susDataProcessed->sus7vec.value, sus7VecBody, 3 * sizeof(float));
|
std::memcpy(susDataProcessed->sus7vec.value, susVecBody[7], 3 * sizeof(float));
|
||||||
susDataProcessed->sus7vec.setValid(sus7valid);
|
susDataProcessed->sus7vec.setValid(sus7valid);
|
||||||
std::memcpy(susDataProcessed->sus8vec.value, sus8VecBody, 3 * sizeof(float));
|
std::memcpy(susDataProcessed->sus8vec.value, susVecBody[8], 3 * sizeof(float));
|
||||||
susDataProcessed->sus8vec.setValid(sus8valid);
|
susDataProcessed->sus8vec.setValid(sus8valid);
|
||||||
std::memcpy(susDataProcessed->sus9vec.value, sus9VecBody, 3 * sizeof(float));
|
std::memcpy(susDataProcessed->sus9vec.value, susVecBody[9], 3 * sizeof(float));
|
||||||
susDataProcessed->sus9vec.setValid(sus9valid);
|
susDataProcessed->sus9vec.setValid(sus9valid);
|
||||||
std::memcpy(susDataProcessed->sus10vec.value, sus10VecBody, 3 * sizeof(float));
|
std::memcpy(susDataProcessed->sus10vec.value, susVecBody[10], 3 * sizeof(float));
|
||||||
susDataProcessed->sus10vec.setValid(sus10valid);
|
susDataProcessed->sus10vec.setValid(sus10valid);
|
||||||
std::memcpy(susDataProcessed->sus11vec.value, sus11VecBody, 3 * sizeof(float));
|
std::memcpy(susDataProcessed->sus11vec.value, susVecBody[11], 3 * sizeof(float));
|
||||||
susDataProcessed->sus11vec.setValid(sus11valid);
|
susDataProcessed->sus11vec.setValid(sus11valid);
|
||||||
std::memcpy(susDataProcessed->susVecTot.value, susVecTot, 3 * sizeof(double));
|
std::memcpy(susDataProcessed->susVecTot.value, susVecTot, 3 * sizeof(double));
|
||||||
susDataProcessed->susVecTot.setValid(true);
|
susDataProcessed->susVecTot.setValid(true);
|
||||||
@ -459,12 +420,11 @@ void SensorProcessing::processGyr(
|
|||||||
{
|
{
|
||||||
PoolReadGuard pg(gyrDataProcessed);
|
PoolReadGuard pg(gyrDataProcessed);
|
||||||
if (pg.getReadResult() == returnvalue::OK) {
|
if (pg.getReadResult() == returnvalue::OK) {
|
||||||
double zeroVector[3] = {0.0, 0.0, 0.0};
|
std::memcpy(gyrDataProcessed->gyr0vec.value, ZERO_VEC_D, 3 * sizeof(double));
|
||||||
std::memcpy(gyrDataProcessed->gyr0vec.value, zeroVector, 3 * sizeof(double));
|
std::memcpy(gyrDataProcessed->gyr1vec.value, ZERO_VEC_D, 3 * sizeof(double));
|
||||||
std::memcpy(gyrDataProcessed->gyr1vec.value, zeroVector, 3 * sizeof(double));
|
std::memcpy(gyrDataProcessed->gyr2vec.value, ZERO_VEC_D, 3 * sizeof(double));
|
||||||
std::memcpy(gyrDataProcessed->gyr2vec.value, zeroVector, 3 * sizeof(double));
|
std::memcpy(gyrDataProcessed->gyr3vec.value, ZERO_VEC_D, 3 * sizeof(double));
|
||||||
std::memcpy(gyrDataProcessed->gyr3vec.value, zeroVector, 3 * sizeof(double));
|
std::memcpy(gyrDataProcessed->gyrVecTot.value, ZERO_VEC_D, 3 * sizeof(double));
|
||||||
std::memcpy(gyrDataProcessed->gyrVecTot.value, zeroVector, 3 * sizeof(double));
|
|
||||||
gyrDataProcessed->setValidity(false, true);
|
gyrDataProcessed->setValidity(false, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,9 @@ class SensorProcessing {
|
|||||||
acsctrl::GpsDataProcessed *gpsDataProcessed,
|
acsctrl::GpsDataProcessed *gpsDataProcessed,
|
||||||
const AcsParameters *acsParameters); // Will call protected functions
|
const AcsParameters *acsParameters); // Will call protected functions
|
||||||
private:
|
private:
|
||||||
|
static constexpr float ZERO_VEC_F[3] = {0, 0, 0};
|
||||||
|
static constexpr double ZERO_VEC_D[3] = {0, 0, 0};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// short description needed for every function
|
// short description needed for every function
|
||||||
void processMgm(const float *mgm0Value, bool mgm0valid, const float *mgm1Value, bool mgm1valid,
|
void processMgm(const float *mgm0Value, bool mgm0valid, const float *mgm1Value, bool mgm1valid,
|
||||||
|
@ -1,121 +1,64 @@
|
|||||||
#include "SusConverter.h"
|
#include "SusConverter.h"
|
||||||
|
|
||||||
#include <fsfw/datapoollocal/LocalPoolVariable.h>
|
|
||||||
#include <fsfw/datapoollocal/LocalPoolVector.h>
|
|
||||||
#include <fsfw/globalfunctions/math/VectorOperations.h>
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include <iostream>
|
uint64_t SusConverter::checkSunSensorData(const uint16_t susChannel[6]) {
|
||||||
|
if (susChannel[0] <= SUS_CHANNEL_VALUE_LOW || susChannel[0] > SUS_CHANNEL_VALUE_HIGH ||
|
||||||
bool SusConverter::checkSunSensorData(const uint16_t susChannel[6]) {
|
|
||||||
if (susChannel[0] <= susChannelValueCheckLow || susChannel[0] > susChannelValueCheckHigh ||
|
|
||||||
susChannel[0] > susChannel[GNDREF]) {
|
susChannel[0] > susChannel[GNDREF]) {
|
||||||
return false;
|
return 0;
|
||||||
}
|
}
|
||||||
if (susChannel[1] <= susChannelValueCheckLow || susChannel[1] > susChannelValueCheckHigh ||
|
if (susChannel[1] <= SUS_CHANNEL_VALUE_LOW || susChannel[1] > SUS_CHANNEL_VALUE_HIGH ||
|
||||||
susChannel[1] > susChannel[GNDREF]) {
|
susChannel[1] > susChannel[GNDREF]) {
|
||||||
return false;
|
return 0;
|
||||||
};
|
};
|
||||||
if (susChannel[2] <= susChannelValueCheckLow || susChannel[2] > susChannelValueCheckHigh ||
|
if (susChannel[2] <= SUS_CHANNEL_VALUE_LOW || susChannel[2] > SUS_CHANNEL_VALUE_HIGH ||
|
||||||
susChannel[2] > susChannel[GNDREF]) {
|
susChannel[2] > susChannel[GNDREF]) {
|
||||||
return false;
|
return 0;
|
||||||
};
|
};
|
||||||
if (susChannel[3] <= susChannelValueCheckLow || susChannel[3] > susChannelValueCheckHigh ||
|
if (susChannel[3] <= SUS_CHANNEL_VALUE_LOW || susChannel[3] > SUS_CHANNEL_VALUE_HIGH ||
|
||||||
susChannel[3] > susChannel[GNDREF]) {
|
susChannel[3] > susChannel[GNDREF]) {
|
||||||
return false;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
susChannelValueSum =
|
uint64_t susChannelValueSum =
|
||||||
4 * susChannel[GNDREF] - (susChannel[0] + susChannel[1] + susChannel[2] + susChannel[3]);
|
4 * susChannel[GNDREF] - (susChannel[0] + susChannel[1] + susChannel[2] + susChannel[3]);
|
||||||
if ((susChannelValueSum < susChannelValueSumHigh) &&
|
if (susChannelValueSum < SUS_ALBEDO_CHECK) {
|
||||||
(susChannelValueSum > susChannelValueSumLow)) {
|
return 0;
|
||||||
return false;
|
|
||||||
};
|
};
|
||||||
return true;
|
return susChannelValueSum;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SusConverter::calcAngle(const uint16_t susChannel[6]) {
|
bool SusConverter::checkValidity(bool* susValid, const uint64_t brightness[12],
|
||||||
float xout, yout;
|
const float threshold) {
|
||||||
float s = 0.03; // s=[mm] gap between diodes
|
uint8_t maxBrightness = 0;
|
||||||
uint8_t d = 5; // d=[mm] edge length of the quadratic aperture
|
VectorOperations<uint64_t>::maxValue(brightness, 12, &maxBrightness);
|
||||||
uint8_t h = 1; // h=[mm] distance between diodes and aperture
|
if (brightness[maxBrightness] == 0) {
|
||||||
int ch0, ch1, ch2, ch3;
|
return true;
|
||||||
|
}
|
||||||
|
for (uint8_t idx = 0; idx < 12; idx++) {
|
||||||
|
if ((idx != maxBrightness) and (brightness[idx] < threshold * brightness[maxBrightness])) {
|
||||||
|
susValid[idx] = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
susValid[idx] = true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SusConverter::calculateSunVector(float* sunVectorSensorFrame, const uint16_t susChannel[6]) {
|
||||||
// Substract measurement values from GNDREF zero current threshold
|
// Substract measurement values from GNDREF zero current threshold
|
||||||
ch0 = susChannel[GNDREF] - susChannel[0];
|
float ch0 = susChannel[GNDREF] - susChannel[0];
|
||||||
ch1 = susChannel[GNDREF] - susChannel[1];
|
float ch1 = susChannel[GNDREF] - susChannel[1];
|
||||||
ch2 = susChannel[GNDREF] - susChannel[2];
|
float ch2 = susChannel[GNDREF] - susChannel[2];
|
||||||
ch3 = susChannel[GNDREF] - susChannel[3];
|
float ch3 = susChannel[GNDREF] - susChannel[3];
|
||||||
|
|
||||||
// Calculation of x and y
|
// Calculation of x and y
|
||||||
xout = ((d - s) / 2) * (ch2 - ch3 - ch0 + ch1) / (ch0 + ch1 + ch2 + ch3); //[mm]
|
float xout = ((D - S) / 2) * (ch2 - ch3 - ch0 + ch1) / (ch0 + ch1 + ch2 + ch3); //[mm]
|
||||||
yout = ((d - s) / 2) * (ch2 + ch3 - ch0 - ch1) / (ch0 + ch1 + ch2 + ch3); //[mm]
|
float yout = ((D - S) / 2) * (ch2 + ch3 - ch0 - ch1) / (ch0 + ch1 + ch2 + ch3); //[mm]
|
||||||
|
|
||||||
// Calculation of the angles
|
// Calculation of the angles
|
||||||
alphaBetaRaw[0] = atan2(xout, h) * (180 / M_PI); //[°]
|
sunVectorSensorFrame[0] = -xout;
|
||||||
alphaBetaRaw[1] = atan2(yout, h) * (180 / M_PI); //[°]
|
sunVectorSensorFrame[1] = -yout;
|
||||||
}
|
sunVectorSensorFrame[2] = H;
|
||||||
|
VectorOperations<float>::normalize(sunVectorSensorFrame, sunVectorSensorFrame, 3);
|
||||||
void SusConverter::calibration(const float coeffAlpha[9][10], const float coeffBeta[9][10]) {
|
|
||||||
uint8_t index, k, l;
|
|
||||||
|
|
||||||
// while loop iterates above all calibration cells to use the different calibration functions in
|
|
||||||
// each cell
|
|
||||||
k = 0;
|
|
||||||
while (k < 3) {
|
|
||||||
k++;
|
|
||||||
l = 0;
|
|
||||||
while (l < 3) {
|
|
||||||
l++;
|
|
||||||
// if-condition to check in which cell the data point has to be
|
|
||||||
if ((alphaBetaRaw[0] > ((completeCellWidth * ((k - 1) / 3.)) - halfCellWidth) &&
|
|
||||||
alphaBetaRaw[0] < ((completeCellWidth * (k / 3.)) - halfCellWidth)) &&
|
|
||||||
(alphaBetaRaw[1] > ((completeCellWidth * ((l - 1) / 3.)) - halfCellWidth) &&
|
|
||||||
alphaBetaRaw[1] < ((completeCellWidth * (l / 3.)) - halfCellWidth))) {
|
|
||||||
index = (3 * (k - 1) + l) - 1; // calculate the index of the datapoint for the right cell
|
|
||||||
alphaBetaCalibrated[0] =
|
|
||||||
coeffAlpha[index][0] + coeffAlpha[index][1] * alphaBetaRaw[0] +
|
|
||||||
coeffAlpha[index][2] * alphaBetaRaw[1] +
|
|
||||||
coeffAlpha[index][3] * alphaBetaRaw[0] * alphaBetaRaw[0] +
|
|
||||||
coeffAlpha[index][4] * alphaBetaRaw[0] * alphaBetaRaw[1] +
|
|
||||||
coeffAlpha[index][5] * alphaBetaRaw[1] * alphaBetaRaw[1] +
|
|
||||||
coeffAlpha[index][6] * alphaBetaRaw[0] * alphaBetaRaw[0] * alphaBetaRaw[0] +
|
|
||||||
coeffAlpha[index][7] * alphaBetaRaw[0] * alphaBetaRaw[0] * alphaBetaRaw[1] +
|
|
||||||
coeffAlpha[index][8] * alphaBetaRaw[0] * alphaBetaRaw[1] * alphaBetaRaw[1] +
|
|
||||||
coeffAlpha[index][9] * alphaBetaRaw[1] * alphaBetaRaw[1] * alphaBetaRaw[1]; //[°]
|
|
||||||
alphaBetaCalibrated[1] =
|
|
||||||
coeffBeta[index][0] + coeffBeta[index][1] * alphaBetaRaw[0] +
|
|
||||||
coeffBeta[index][2] * alphaBetaRaw[1] +
|
|
||||||
coeffBeta[index][3] * alphaBetaRaw[0] * alphaBetaRaw[0] +
|
|
||||||
coeffBeta[index][4] * alphaBetaRaw[0] * alphaBetaRaw[1] +
|
|
||||||
coeffBeta[index][5] * alphaBetaRaw[1] * alphaBetaRaw[1] +
|
|
||||||
coeffBeta[index][6] * alphaBetaRaw[0] * alphaBetaRaw[0] * alphaBetaRaw[0] +
|
|
||||||
coeffBeta[index][7] * alphaBetaRaw[0] * alphaBetaRaw[0] * alphaBetaRaw[1] +
|
|
||||||
coeffBeta[index][8] * alphaBetaRaw[0] * alphaBetaRaw[1] * alphaBetaRaw[1] +
|
|
||||||
coeffBeta[index][9] * alphaBetaRaw[1] * alphaBetaRaw[1] * alphaBetaRaw[1]; //[°]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
float* SusConverter::calculateSunVector() {
|
|
||||||
// Calculate the normalized Sun Vector
|
|
||||||
sunVectorSensorFrame[0] = -(tan(alphaBetaCalibrated[0] * (M_PI / 180)) /
|
|
||||||
(sqrt((powf(tan(alphaBetaCalibrated[0] * (M_PI / 180)), 2)) +
|
|
||||||
powf(tan((alphaBetaCalibrated[1] * (M_PI / 180))), 2) + (1))));
|
|
||||||
sunVectorSensorFrame[1] = -(tan(alphaBetaCalibrated[1] * (M_PI / 180)) /
|
|
||||||
(sqrt(powf((tan(alphaBetaCalibrated[0] * (M_PI / 180))), 2) +
|
|
||||||
powf(tan((alphaBetaCalibrated[1] * (M_PI / 180))), 2) + (1))));
|
|
||||||
sunVectorSensorFrame[2] =
|
|
||||||
-(-1 / (sqrt(powf((tan(alphaBetaCalibrated[0] * (M_PI / 180))), 2) +
|
|
||||||
powf((tan(alphaBetaCalibrated[1] * (M_PI / 180))), 2) + (1))));
|
|
||||||
|
|
||||||
return sunVectorSensorFrame;
|
|
||||||
}
|
|
||||||
|
|
||||||
float* SusConverter::getSunVectorSensorFrame(const uint16_t susChannel[6],
|
|
||||||
const float coeffAlpha[9][10],
|
|
||||||
const float coeffBeta[9][10]) {
|
|
||||||
calcAngle(susChannel);
|
|
||||||
calibration(coeffAlpha, coeffBeta);
|
|
||||||
return calculateSunVector();
|
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,4 @@
|
|||||||
#ifndef MISSION_CONTROLLER_ACS_SUSCONVERTER_H_
|
#include <fsfw/globalfunctions/math/VectorOperations.h>
|
||||||
#define MISSION_CONTROLLER_ACS_SUSCONVERTER_H_
|
|
||||||
|
|
||||||
#include <fsfw/datapoollocal/LocalPoolVector.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "AcsParameters.h"
|
#include "AcsParameters.h"
|
||||||
|
|
||||||
@ -10,41 +6,26 @@ class SusConverter {
|
|||||||
public:
|
public:
|
||||||
SusConverter() {}
|
SusConverter() {}
|
||||||
|
|
||||||
bool checkSunSensorData(const uint16_t susChannel[6]);
|
uint64_t checkSunSensorData(const uint16_t susChannel[6]);
|
||||||
|
bool checkValidity(bool* susValid, const uint64_t brightness[12], const float threshold);
|
||||||
void calcAngle(const uint16_t susChannel[6]);
|
void calculateSunVector(float* sunVectorSensorFrame, const uint16_t susChannel[6]);
|
||||||
void calibration(const float coeffAlpha[9][10], const float coeffBeta[9][10]);
|
|
||||||
float* calculateSunVector();
|
|
||||||
|
|
||||||
float* getSunVectorSensorFrame(const uint16_t susChannel[6], const float coeffAlpha[9][10],
|
|
||||||
const float coeffBeta[9][10]);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float alphaBetaRaw[2]; //[°]
|
|
||||||
float alphaBetaCalibrated[2]; //[°]
|
|
||||||
float sunVectorSensorFrame[3]; //[-]
|
|
||||||
|
|
||||||
bool validFlag[12] = {returnvalue::OK, returnvalue::OK, returnvalue::OK, returnvalue::OK,
|
|
||||||
returnvalue::OK, returnvalue::OK, returnvalue::OK, returnvalue::OK,
|
|
||||||
returnvalue::OK, returnvalue::OK, returnvalue::OK, returnvalue::OK};
|
|
||||||
|
|
||||||
static const uint8_t GNDREF = 4;
|
static const uint8_t GNDREF = 4;
|
||||||
uint16_t susChannelValueCheckHigh =
|
// =2^12[Bit]high borderline for the channel values of one sun sensor for validity Check
|
||||||
4096; //=2^12[Bit]high borderline for the channel values of one sun sensor for validity Check
|
static constexpr uint16_t SUS_CHANNEL_VALUE_HIGH = 4096;
|
||||||
uint8_t susChannelValueCheckLow =
|
// [Bit]low borderline for the channel values of one sun sensor for validity Check
|
||||||
0; //[Bit]low borderline for the channel values of one sun sensor for validity Check
|
static constexpr uint8_t SUS_CHANNEL_VALUE_LOW = 0;
|
||||||
uint16_t susChannelValueSumHigh =
|
// 4096[Bit]high borderline for check if the sun sensor is illuminated by the sun or by the
|
||||||
100; // 4096[Bit]high borderline for check if the sun sensor is illuminated by the sun or by
|
// reflection of sunlight from the moon/earth
|
||||||
// the reflection of sunlight from the moon/earth
|
static constexpr uint16_t SUS_ALBEDO_CHECK = 1000;
|
||||||
uint8_t susChannelValueSumLow =
|
// [Bit]low borderline for check if the sun sensor is illuminated by the sun or by the reflection
|
||||||
0; //[Bit]low borderline for check if the sun sensor is illuminated
|
// of sunlight from the moon/earth
|
||||||
// by the sun or by the reflection of sunlight from the moon/earth
|
static constexpr uint8_t SUS_CHANNEL_SUM_LOW = 0;
|
||||||
uint8_t completeCellWidth = 140,
|
|
||||||
halfCellWidth = 70; //[°] Width of the calibration cells --> necessary for checking in
|
static constexpr float S = 0.03; // S=[mm] gap between diodes
|
||||||
// which cell a data point should be
|
static constexpr float D = 5; // D=[mm] edge length of the quadratic aperture
|
||||||
uint16_t susChannelValueSum = 0;
|
static constexpr float H = 1; // H=[mm] distance between diodes and aperture
|
||||||
|
|
||||||
AcsParameters acsParameters;
|
AcsParameters acsParameters;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* MISSION_CONTROLLER_ACS_SUSCONVERTER_H_ */
|
|
||||||
|
@ -238,7 +238,7 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun
|
|||||||
new Service2DeviceAccess(objects::PUS_SERVICE_2_DEVICE_ACCESS, config::EIVE_PUS_APID,
|
new Service2DeviceAccess(objects::PUS_SERVICE_2_DEVICE_ACCESS, config::EIVE_PUS_APID,
|
||||||
pus::PUS_SERVICE_2, 3, 10);
|
pus::PUS_SERVICE_2, 3, 10);
|
||||||
new Service3Housekeeping(objects::PUS_SERVICE_3_HOUSEKEEPING, config::EIVE_PUS_APID,
|
new Service3Housekeeping(objects::PUS_SERVICE_3_HOUSEKEEPING, config::EIVE_PUS_APID,
|
||||||
pus::PUS_SERVICE_3, config::HK_SERVICE_QUEUE_DEPTH);
|
pus::PUS_SERVICE_3, config::HK_SERVICE_QUEUE_DEPTH, 16);
|
||||||
new Service5EventReporting(
|
new Service5EventReporting(
|
||||||
PsbParams(objects::PUS_SERVICE_5_EVENT_REPORTING, config::EIVE_PUS_APID, pus::PUS_SERVICE_5),
|
PsbParams(objects::PUS_SERVICE_5_EVENT_REPORTING, config::EIVE_PUS_APID, pus::PUS_SERVICE_5),
|
||||||
80, 160);
|
80, 160);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include <fsfw/datapool/PoolReadGuard.h>
|
#include <fsfw/datapool/PoolReadGuard.h>
|
||||||
|
#include <fsfw/globalfunctions/arrayprinter.h>
|
||||||
#include <mission/power/BpxBatteryHandler.h>
|
#include <mission/power/BpxBatteryHandler.h>
|
||||||
|
|
||||||
BpxBatteryHandler::BpxBatteryHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie,
|
BpxBatteryHandler::BpxBatteryHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie,
|
||||||
@ -51,6 +52,9 @@ void BpxBatteryHandler::fillCommandAndReplyMap() {
|
|||||||
insertInCommandAndReplyMap(bpxBat::RESET_COUNTERS, 1, nullptr, EMPTY_REPLY_LEN);
|
insertInCommandAndReplyMap(bpxBat::RESET_COUNTERS, 1, nullptr, EMPTY_REPLY_LEN);
|
||||||
insertInCommandAndReplyMap(bpxBat::CONFIG_CMD, 1, nullptr, EMPTY_REPLY_LEN);
|
insertInCommandAndReplyMap(bpxBat::CONFIG_CMD, 1, nullptr, EMPTY_REPLY_LEN);
|
||||||
insertInCommandAndReplyMap(bpxBat::CONFIG_GET, 1, &cfgSet, CONFIG_GET_REPLY_LEN);
|
insertInCommandAndReplyMap(bpxBat::CONFIG_GET, 1, &cfgSet, CONFIG_GET_REPLY_LEN);
|
||||||
|
insertInCommandAndReplyMap(bpxBat::CONFIG_SET, 1, nullptr, EMPTY_REPLY_LEN);
|
||||||
|
insertInCommandAndReplyMap(bpxBat::MAN_HEAT_ON, 1, nullptr, MAN_HEAT_REPLY_LEN);
|
||||||
|
insertInCommandAndReplyMap(bpxBat::MAN_HEAT_OFF, 1, nullptr, MAN_HEAT_REPLY_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t BpxBatteryHandler::buildCommandFromCommand(DeviceCommandId_t deviceCommand,
|
ReturnValue_t BpxBatteryHandler::buildCommandFromCommand(DeviceCommandId_t deviceCommand,
|
||||||
@ -155,7 +159,7 @@ ReturnValue_t BpxBatteryHandler::scanForReply(const uint8_t* start, size_t remai
|
|||||||
case (bpxBat::PING):
|
case (bpxBat::PING):
|
||||||
case (bpxBat::MAN_HEAT_ON):
|
case (bpxBat::MAN_HEAT_ON):
|
||||||
case (bpxBat::MAN_HEAT_OFF): {
|
case (bpxBat::MAN_HEAT_OFF): {
|
||||||
if (remainingSize != PING_REPLY_LEN) {
|
if (remainingSize != MAN_HEAT_REPLY_LEN) {
|
||||||
return DeviceHandlerIF::LENGTH_MISSMATCH;
|
return DeviceHandlerIF::LENGTH_MISSMATCH;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -48,6 +48,7 @@ static constexpr uint32_t CFG_SET_ID = CONFIG_GET;
|
|||||||
static constexpr size_t GET_HK_REPLY_LEN = 23;
|
static constexpr size_t GET_HK_REPLY_LEN = 23;
|
||||||
static constexpr size_t PING_REPLY_LEN = 3;
|
static constexpr size_t PING_REPLY_LEN = 3;
|
||||||
static constexpr size_t EMPTY_REPLY_LEN = 2;
|
static constexpr size_t EMPTY_REPLY_LEN = 2;
|
||||||
|
static constexpr size_t MAN_HEAT_REPLY_LEN = 3;
|
||||||
static constexpr size_t CONFIG_GET_REPLY_LEN = 5;
|
static constexpr size_t CONFIG_GET_REPLY_LEN = 5;
|
||||||
|
|
||||||
static constexpr uint8_t PORT_PING = 1;
|
static constexpr uint8_t PORT_PING = 1;
|
||||||
@ -219,6 +220,7 @@ class BpxBatteryCfg : public StaticLocalDataSet<bpxBat::CFG_ENTRIES> {
|
|||||||
if (size < 3) {
|
if (size < 3) {
|
||||||
return SerializeIF::STREAM_TOO_SHORT;
|
return SerializeIF::STREAM_TOO_SHORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
battheatermode.value = data[0];
|
battheatermode.value = data[0];
|
||||||
battheaterLow.value = data[1];
|
battheaterLow.value = data[1];
|
||||||
battheaterHigh.value = data[2];
|
battheaterHigh.value = data[2];
|
||||||
|
@ -86,8 +86,11 @@ ReturnValue_t Tmp1075Handler::scanForReply(const uint8_t *start, size_t remainin
|
|||||||
ReturnValue_t Tmp1075Handler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) {
|
ReturnValue_t Tmp1075Handler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) {
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case TMP1075::GET_TEMP: {
|
case TMP1075::GET_TEMP: {
|
||||||
int16_t tempValueRaw = 0;
|
// Convert 12 bit MSB first raw temperature to 16 bit first.
|
||||||
tempValueRaw = packet[0] << 4 | packet[1] >> 4;
|
int16_t tempValueRaw = static_cast<uint16_t>((packet[0] << 8) | packet[1]) >> 4;
|
||||||
|
// Sign extension to 16 bits: If the sign bit is set, fill up with ones on the left.
|
||||||
|
tempValueRaw = (packet[0] & 0x80) ? (tempValueRaw | 0xF000) : tempValueRaw;
|
||||||
|
// 0.0625 is the sensor sensitivity.
|
||||||
float tempValue = ((static_cast<float>(tempValueRaw)) * 0.0625);
|
float tempValue = ((static_cast<float>(tempValueRaw)) * 0.0625);
|
||||||
#if OBSW_DEBUG_TMP1075 == 1
|
#if OBSW_DEBUG_TMP1075 == 1
|
||||||
sif::info << "Tmp1075 with object id: 0x" << std::hex << getObjectId()
|
sif::info << "Tmp1075 with object id: 0x" << std::hex << getObjectId()
|
||||||
|
@ -5,10 +5,10 @@
|
|||||||
|
|
||||||
namespace heater {
|
namespace heater {
|
||||||
enum Switch : uint8_t {
|
enum Switch : uint8_t {
|
||||||
HEATER_0_OBC_BRD,
|
HEATER_0_PLOC_PROC_BRD,
|
||||||
HEATER_1_PLOC_PROC_BRD,
|
HEATER_1_PCDU_PDU,
|
||||||
HEATER_2_ACS_BRD,
|
HEATER_2_ACS_BRD,
|
||||||
HEATER_3_PCDU_PDU,
|
HEATER_3_OBC_BRD,
|
||||||
HEATER_4_CAMERA,
|
HEATER_4_CAMERA,
|
||||||
HEATER_5_STR,
|
HEATER_5_STR,
|
||||||
HEATER_6_DRO,
|
HEATER_6_DRO,
|
||||||
|
@ -268,6 +268,10 @@ ReturnValue_t PersistentTmStore::getNextDumpPacket(PusTmReader& reader, bool& fi
|
|||||||
// restore the file dump, but for now do not trust the file.
|
// restore the file dump, but for now do not trust the file.
|
||||||
std::error_code e;
|
std::error_code e;
|
||||||
std::filesystem::remove(dumpParams.dirEntry.path().c_str(), e);
|
std::filesystem::remove(dumpParams.dirEntry.path().c_str(), e);
|
||||||
|
if(dumpParams.dirEntry.path() == activeFile) {
|
||||||
|
activeFile == std::nullopt;
|
||||||
|
assignAndOrCreateMostRecentFile();
|
||||||
|
}
|
||||||
fileHasSwapped = true;
|
fileHasSwapped = true;
|
||||||
return loadNextDumpFile();
|
return loadNextDumpFile();
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,9 @@ OBSW Release Checklist
|
|||||||
2. Re-run the generators with `generators/gen.py all`
|
2. Re-run the generators with `generators/gen.py all`
|
||||||
3. Re-run the auto-formatters with the `scripts/auto-formatter.sh` script
|
3. Re-run the auto-formatters with the `scripts/auto-formatter.sh` script
|
||||||
4. Verify that the Q7S, Q7S EM and Host build are working
|
4. Verify that the Q7S, Q7S EM and Host build are working
|
||||||
5. Wait for CI/CD results
|
5. Update `CHANGELOG.md`: Add new `unreleased` section, convert old unreleased section to
|
||||||
|
header containing version number and release date.
|
||||||
|
6. Wait for CI/CD results
|
||||||
|
|
||||||
# Post-Release
|
# Post-Release
|
||||||
|
|
||||||
|
2
tmtc
2
tmtc
Submodule tmtc updated: 522f273c99...5f44cb96be
Reference in New Issue
Block a user