done #541
11
CHANGELOG.md
11
CHANGELOG.md
@ -20,6 +20,17 @@ will consitute of a breaking change warranting a new major release:
|
|||||||
|
|
||||||
- SCEX filename updates. Also use T as the file ID / date separator between date and time.
|
- SCEX filename updates. Also use T as the file ID / date separator between date and time.
|
||||||
|
|
||||||
|
## Fixed
|
||||||
|
|
||||||
|
- Bugfix for side lane transitions of the dual lane assemblies, which only worked when the
|
||||||
|
assembly was directly commanded
|
||||||
|
|
||||||
|
## Added
|
||||||
|
|
||||||
|
- Added GPS0 and GPS1 health device which are used by the ACS board assembly when deciding whether
|
||||||
|
to change to the other side or to go to dual side directly. Setting the health devices to faulty
|
||||||
|
should also trigger a side switch or a switch to dual mode.
|
||||||
|
|
||||||
# [v1.41.0] 2023-03-28
|
# [v1.41.0] 2023-03-28
|
||||||
|
|
||||||
eive-tmtc: v2.20.0
|
eive-tmtc: v2.20.0
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "ObjectFactory.h"
|
#include "ObjectFactory.h"
|
||||||
|
|
||||||
|
#include <fsfw/devicehandlers/HealthDevice.h>
|
||||||
#include <fsfw/subsystem/Subsystem.h>
|
#include <fsfw/subsystem/Subsystem.h>
|
||||||
#include <linux/acs/AcsBoardPolling.h>
|
#include <linux/acs/AcsBoardPolling.h>
|
||||||
#include <linux/acs/GpsHyperionLinuxController.h>
|
#include <linux/acs/GpsHyperionLinuxController.h>
|
||||||
@ -21,9 +22,9 @@
|
|||||||
#include <mission/acs/str/strHelpers.h>
|
#include <mission/acs/str/strHelpers.h>
|
||||||
#include <mission/power/CspCookie.h>
|
#include <mission/power/CspCookie.h>
|
||||||
#include <mission/system/acs/ImtqAssembly.h>
|
#include <mission/system/acs/ImtqAssembly.h>
|
||||||
|
#include <mission/system/acs/StrAssembly.h>
|
||||||
#include <mission/system/fdir/StrFdir.h>
|
#include <mission/system/fdir/StrFdir.h>
|
||||||
#include <mission/system/objects/CamSwitcher.h>
|
#include <mission/system/objects/CamSwitcher.h>
|
||||||
#include <mission/system/acs/StrAssembly.h>
|
|
||||||
#include <mission/system/objects/SyrlinksAssembly.h>
|
#include <mission/system/objects/SyrlinksAssembly.h>
|
||||||
#include <mission/tmtc/LiveTmTask.h>
|
#include <mission/tmtc/LiveTmTask.h>
|
||||||
#include <mission/tmtc/PersistentLogTmStoreTask.h>
|
#include <mission/tmtc/PersistentLogTmStoreTask.h>
|
||||||
@ -516,6 +517,8 @@ void ObjectFactory::createAcsBoardComponents(SpiComIF& spiComIF, LinuxLibgpioIF*
|
|||||||
new GpsHyperionLinuxController(objects::GPS_CONTROLLER, objects::NO_OBJECT, debugGps);
|
new GpsHyperionLinuxController(objects::GPS_CONTROLLER, objects::NO_OBJECT, debugGps);
|
||||||
gpsCtrl->setResetPinTriggerFunction(gps::triggerGpioResetPin, &RESET_ARGS_GNSS);
|
gpsCtrl->setResetPinTriggerFunction(gps::triggerGpioResetPin, &RESET_ARGS_GNSS);
|
||||||
|
|
||||||
|
new HealthDevice(objects::GPS_0_HEALTH_DEV, objects::ACS_BOARD_ASS);
|
||||||
|
new HealthDevice(objects::GPS_1_HEALTH_DEV, objects::ACS_BOARD_ASS);
|
||||||
ObjectFactory::createAcsBoardAssy(pwrSwitcher, assemblyChildren, gpsCtrl, gpioComIF);
|
ObjectFactory::createAcsBoardAssy(pwrSwitcher, assemblyChildren, gpsCtrl, gpioComIF);
|
||||||
#endif /* OBSW_ADD_ACS_HANDLERS == 1 */
|
#endif /* OBSW_ADD_ACS_HANDLERS == 1 */
|
||||||
}
|
}
|
||||||
|
@ -291,6 +291,14 @@ void scheduling::initTasks() {
|
|||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
scheduling::printAddObjectError("STR_ASSY", objects::STR_ASSY);
|
scheduling::printAddObjectError("STR_ASSY", objects::STR_ASSY);
|
||||||
}
|
}
|
||||||
|
result = acsSysTask->addComponent(objects::GPS_0_HEALTH_DEV);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
scheduling::printAddObjectError("GPS_0_HEALTH_DEV", objects::GPS_0_HEALTH_DEV);
|
||||||
|
}
|
||||||
|
result = acsSysTask->addComponent(objects::GPS_1_HEALTH_DEV);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
scheduling::printAddObjectError("GPS_1_HEALTH_DEV", objects::GPS_1_HEALTH_DEV);
|
||||||
|
}
|
||||||
|
|
||||||
PeriodicTaskIF* tcsSystemTask = factory->createPeriodicTask(
|
PeriodicTaskIF* tcsSystemTask = factory->createPeriodicTask(
|
||||||
"TCS_TASK", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.5, missedDeadlineFunc, &RR_SCHEDULING);
|
"TCS_TASK", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.5, missedDeadlineFunc, &RR_SCHEDULING);
|
||||||
|
@ -43,6 +43,8 @@ enum commonObjects : uint32_t {
|
|||||||
RW4 = 0x44120350,
|
RW4 = 0x44120350,
|
||||||
STAR_TRACKER = 0x44130001,
|
STAR_TRACKER = 0x44130001,
|
||||||
GPS_CONTROLLER = 0x44130045,
|
GPS_CONTROLLER = 0x44130045,
|
||||||
|
GPS_0_HEALTH_DEV = 0x44130046,
|
||||||
|
GPS_1_HEALTH_DEV = 0x44130047,
|
||||||
|
|
||||||
IMTQ_POLLING = 0x44140013,
|
IMTQ_POLLING = 0x44140013,
|
||||||
IMTQ_HANDLER = 0x44140014,
|
IMTQ_HANDLER = 0x44140014,
|
||||||
|
@ -99,6 +99,7 @@ void GpsHyperionLinuxController::setResetPinTriggerFunction(gpioResetFunction_t
|
|||||||
ReturnValue_t GpsHyperionLinuxController::performOperation(uint8_t opCode) {
|
ReturnValue_t GpsHyperionLinuxController::performOperation(uint8_t opCode) {
|
||||||
handleQueue();
|
handleQueue();
|
||||||
poolManager.performHkOperation();
|
poolManager.performHkOperation();
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
#if OBSW_THREAD_TRACING == 1
|
#if OBSW_THREAD_TRACING == 1
|
||||||
trace::threadTrace(opCounter, "GPS CTRL");
|
trace::threadTrace(opCounter, "GPS CTRL");
|
||||||
|
@ -87,12 +87,11 @@ ReturnValue_t GyrAdis1650XHandler::scanForReply(const uint8_t *start, size_t rem
|
|||||||
getMode() == _MODE_POWER_DOWN) {
|
getMode() == _MODE_POWER_DOWN) {
|
||||||
return IGNORE_FULL_PACKET;
|
return IGNORE_FULL_PACKET;
|
||||||
}
|
}
|
||||||
if (remainingSize != sizeof(acs::Adis1650XReply)) {
|
|
||||||
*foundLen = remainingSize;
|
*foundLen = remainingSize;
|
||||||
|
if (remainingSize != sizeof(acs::Adis1650XReply)) {
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
*foundId = adis1650x::REPLY;
|
*foundId = adis1650x::REPLY;
|
||||||
*foundLen = remainingSize;
|
|
||||||
if (internalState == InternalState::SHUTDOWN) {
|
if (internalState == InternalState::SHUTDOWN) {
|
||||||
commandExecuted = true;
|
commandExecuted = true;
|
||||||
}
|
}
|
||||||
|
@ -99,12 +99,11 @@ ReturnValue_t GyrL3gCustomHandler::scanForReply(const uint8_t *start, size_t len
|
|||||||
if (getMode() == _MODE_WAIT_OFF or getMode() == _MODE_WAIT_ON or getMode() == _MODE_POWER_DOWN) {
|
if (getMode() == _MODE_WAIT_OFF or getMode() == _MODE_WAIT_ON or getMode() == _MODE_POWER_DOWN) {
|
||||||
return IGNORE_FULL_PACKET;
|
return IGNORE_FULL_PACKET;
|
||||||
}
|
}
|
||||||
if (len != sizeof(acs::GyroL3gReply)) {
|
|
||||||
*foundLen = len;
|
*foundLen = len;
|
||||||
|
if (len != sizeof(acs::GyroL3gReply)) {
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
*foundId = l3gd20h::REPLY;
|
*foundId = adis1650x::REPLY;
|
||||||
*foundLen = len;
|
|
||||||
if (internalState == InternalState::SHUTDOWN) {
|
if (internalState == InternalState::SHUTDOWN) {
|
||||||
commandExecuted = true;
|
commandExecuted = true;
|
||||||
}
|
}
|
||||||
|
@ -347,7 +347,8 @@ void ObjectFactory::createAcsBoardAssy(PowerSwitchIF& pwrSwitcher,
|
|||||||
AcsBoardHelper acsBoardHelper = AcsBoardHelper(
|
AcsBoardHelper acsBoardHelper = AcsBoardHelper(
|
||||||
objects::MGM_0_LIS3_HANDLER, objects::MGM_1_RM3100_HANDLER, objects::MGM_2_LIS3_HANDLER,
|
objects::MGM_0_LIS3_HANDLER, objects::MGM_1_RM3100_HANDLER, objects::MGM_2_LIS3_HANDLER,
|
||||||
objects::MGM_3_RM3100_HANDLER, objects::GYRO_0_ADIS_HANDLER, objects::GYRO_1_L3G_HANDLER,
|
objects::MGM_3_RM3100_HANDLER, objects::GYRO_0_ADIS_HANDLER, objects::GYRO_1_L3G_HANDLER,
|
||||||
objects::GYRO_2_ADIS_HANDLER, objects::GYRO_3_L3G_HANDLER, objects::GPS_CONTROLLER);
|
objects::GYRO_2_ADIS_HANDLER, objects::GYRO_3_L3G_HANDLER, objects::GPS_CONTROLLER,
|
||||||
|
objects::GPS_0_HEALTH_DEV, objects::GPS_1_HEALTH_DEV);
|
||||||
auto acsAss =
|
auto acsAss =
|
||||||
new AcsBoardAssembly(objects::ACS_BOARD_ASS, &pwrSwitcher, acsBoardHelper, gpioComIF);
|
new AcsBoardAssembly(objects::ACS_BOARD_ASS, &pwrSwitcher, acsBoardHelper, gpioComIF);
|
||||||
for (auto& assChild : assemblyDhbs) {
|
for (auto& assChild : assemblyDhbs) {
|
||||||
|
@ -77,14 +77,16 @@ ReturnValue_t AcsBoardAssembly::checkChildrenStateOn(Mode_t wantedMode, Submode_
|
|||||||
if (wantedSubmode == A_SIDE) {
|
if (wantedSubmode == A_SIDE) {
|
||||||
if ((helper.gyro0SideAMode != wantedMode and helper.gyro1SideAMode != wantedMode) or
|
if ((helper.gyro0SideAMode != wantedMode and helper.gyro1SideAMode != wantedMode) or
|
||||||
(helper.mgm0SideAMode != wantedMode and helper.mgm1SideAMode != wantedMode) or
|
(helper.mgm0SideAMode != wantedMode and helper.mgm1SideAMode != wantedMode) or
|
||||||
helper.gpsMode != MODE_ON) {
|
(helper.gpsMode != MODE_ON) or
|
||||||
|
(healthHelper.healthTable->getHealth(helper.healthDevGps0) == FAULTY)) {
|
||||||
return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE;
|
return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE;
|
||||||
}
|
}
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
} else if (wantedSubmode == B_SIDE) {
|
} else if (wantedSubmode == B_SIDE) {
|
||||||
if ((helper.gyro2SideBMode != wantedMode and helper.gyro3SideBMode != wantedMode) or
|
if ((helper.gyro2SideBMode != wantedMode and helper.gyro3SideBMode != wantedMode) or
|
||||||
(helper.mgm2SideBMode != wantedMode and helper.mgm3SideBMode != wantedMode) or
|
(helper.mgm2SideBMode != wantedMode and helper.mgm3SideBMode != wantedMode) or
|
||||||
helper.gpsMode != MODE_ON) {
|
(helper.gpsMode != MODE_ON) or
|
||||||
|
(healthHelper.healthTable->getHealth(helper.healthDevGps1) == FAULTY)) {
|
||||||
return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE;
|
return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE;
|
||||||
}
|
}
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
@ -126,12 +128,33 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s
|
|||||||
auto cmdSeq = [&](object_id_t objectId, Mode_t devMode, ModeTableIdx tableIdx) {
|
auto cmdSeq = [&](object_id_t objectId, Mode_t devMode, ModeTableIdx tableIdx) {
|
||||||
if (mode == devMode) {
|
if (mode == devMode) {
|
||||||
modeTable[tableIdx].setMode(mode);
|
modeTable[tableIdx].setMode(mode);
|
||||||
} else if (isUseable(objectId, devMode)) {
|
} else if (isModeCommandable(objectId, devMode)) {
|
||||||
modeTable[tableIdx].setMode(mode);
|
modeTable[tableIdx].setMode(mode);
|
||||||
modeTable[tableIdx].setSubmode(SUBMODE_NONE);
|
modeTable[tableIdx].setSubmode(SUBMODE_NONE);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
bool gpsUsable = isUseable(helper.gpsId, helper.gpsMode);
|
bool gpsUsable = isModeCommandable(helper.gpsId, helper.gpsMode);
|
||||||
|
auto gpsCmd = [&](bool gnss0NReset, bool gnss1NReset, uint8_t gnssSelect) {
|
||||||
|
if (gpsUsable) {
|
||||||
|
if (mode == MODE_ON or mode == DeviceHandlerIF::MODE_NORMAL) {
|
||||||
|
modeTable[ModeTableIdx::GPS].setMode(MODE_ON);
|
||||||
|
} else if (mode == MODE_OFF) {
|
||||||
|
gnss0NReset = true;
|
||||||
|
gnss1NReset = true;
|
||||||
|
modeTable[ModeTableIdx::GPS].setMode(MODE_OFF);
|
||||||
|
}
|
||||||
|
modeTable[ModeTableIdx::GPS].setSubmode(SUBMODE_NONE);
|
||||||
|
|
||||||
|
gpioHandler(gpioIds::GNSS_0_NRESET, gnss0NReset,
|
||||||
|
"AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull nReset pin"
|
||||||
|
"of GNSS 0");
|
||||||
|
gpioHandler(gpioIds::GNSS_1_NRESET, gnss1NReset,
|
||||||
|
"AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull nReset pin"
|
||||||
|
"of GNSS 1");
|
||||||
|
gpioHandler(gpioIds::GNSS_SELECT, gnssSelect,
|
||||||
|
"AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull GNSS select");
|
||||||
|
}
|
||||||
|
};
|
||||||
switch (submode) {
|
switch (submode) {
|
||||||
case (A_SIDE): {
|
case (A_SIDE): {
|
||||||
modeTable[ModeTableIdx::GYRO_2_B].setMode(MODE_OFF);
|
modeTable[ModeTableIdx::GYRO_2_B].setMode(MODE_OFF);
|
||||||
@ -146,16 +169,7 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s
|
|||||||
cmdSeq(helper.gyro1L3gIdSideA, helper.gyro1SideAMode, ModeTableIdx::GYRO_1_A);
|
cmdSeq(helper.gyro1L3gIdSideA, helper.gyro1SideAMode, ModeTableIdx::GYRO_1_A);
|
||||||
cmdSeq(helper.mgm0Lis3IdSideA, helper.mgm0SideAMode, ModeTableIdx::MGM_0_A);
|
cmdSeq(helper.mgm0Lis3IdSideA, helper.mgm0SideAMode, ModeTableIdx::MGM_0_A);
|
||||||
cmdSeq(helper.mgm1Rm3100IdSideA, helper.mgm1SideAMode, ModeTableIdx::MGM_1_A);
|
cmdSeq(helper.mgm1Rm3100IdSideA, helper.mgm1SideAMode, ModeTableIdx::MGM_1_A);
|
||||||
if (gpsUsable) {
|
gpsCmd(true, false, 0);
|
||||||
gpioHandler(gpioIds::GNSS_0_NRESET, true,
|
|
||||||
"AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull nReset pin"
|
|
||||||
"of GNSS 0 high (used GNSS)");
|
|
||||||
gpioHandler(gpioIds::GNSS_1_NRESET, false,
|
|
||||||
"AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull nReset pin"
|
|
||||||
"of GNSS 1 low (unused GNSS)");
|
|
||||||
gpioHandler(gpioIds::GNSS_SELECT, false,
|
|
||||||
"AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull GNSS select low");
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case (B_SIDE): {
|
case (B_SIDE): {
|
||||||
@ -171,20 +185,10 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s
|
|||||||
cmdSeq(helper.gyro3L3gIdSideB, helper.gyro3SideBMode, ModeTableIdx::GYRO_3_B);
|
cmdSeq(helper.gyro3L3gIdSideB, helper.gyro3SideBMode, ModeTableIdx::GYRO_3_B);
|
||||||
cmdSeq(helper.mgm2Lis3IdSideB, helper.mgm2SideBMode, ModeTableIdx::MGM_2_B);
|
cmdSeq(helper.mgm2Lis3IdSideB, helper.mgm2SideBMode, ModeTableIdx::MGM_2_B);
|
||||||
cmdSeq(helper.mgm3Rm3100IdSideB, helper.mgm3SideBMode, ModeTableIdx::MGM_3_B);
|
cmdSeq(helper.mgm3Rm3100IdSideB, helper.mgm3SideBMode, ModeTableIdx::MGM_3_B);
|
||||||
if (gpsUsable) {
|
gpsCmd(false, true, 1);
|
||||||
gpioHandler(gpioIds::GNSS_0_NRESET, false,
|
|
||||||
"AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull nReset pin"
|
|
||||||
"of GNSS 0 low (unused GNSS)");
|
|
||||||
gpioHandler(gpioIds::GNSS_1_NRESET, true,
|
|
||||||
"AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull nReset pin"
|
|
||||||
"of GNSS 1 high (used GNSS)");
|
|
||||||
gpioHandler(gpioIds::GNSS_SELECT, true,
|
|
||||||
"AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull GNSS select high");
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case (DUAL_MODE): {
|
case (DUAL_MODE): {
|
||||||
cmdSeq(helper.gpsId, helper.gpsMode, ModeTableIdx::GPS);
|
|
||||||
cmdSeq(helper.gyro0AdisIdSideA, helper.gyro0SideAMode, ModeTableIdx::GYRO_0_A);
|
cmdSeq(helper.gyro0AdisIdSideA, helper.gyro0SideAMode, ModeTableIdx::GYRO_0_A);
|
||||||
cmdSeq(helper.gyro1L3gIdSideA, helper.gyro1SideAMode, ModeTableIdx::GYRO_1_A);
|
cmdSeq(helper.gyro1L3gIdSideA, helper.gyro1SideAMode, ModeTableIdx::GYRO_1_A);
|
||||||
cmdSeq(helper.mgm0Lis3IdSideA, helper.mgm0SideAMode, ModeTableIdx::MGM_0_A);
|
cmdSeq(helper.mgm0Lis3IdSideA, helper.mgm0SideAMode, ModeTableIdx::MGM_0_A);
|
||||||
@ -193,26 +197,10 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s
|
|||||||
cmdSeq(helper.gyro3L3gIdSideB, helper.gyro3SideBMode, ModeTableIdx::GYRO_3_B);
|
cmdSeq(helper.gyro3L3gIdSideB, helper.gyro3SideBMode, ModeTableIdx::GYRO_3_B);
|
||||||
cmdSeq(helper.mgm2Lis3IdSideB, helper.mgm2SideBMode, ModeTableIdx::MGM_2_B);
|
cmdSeq(helper.mgm2Lis3IdSideB, helper.mgm2SideBMode, ModeTableIdx::MGM_2_B);
|
||||||
cmdSeq(helper.mgm3Rm3100IdSideB, helper.mgm3SideBMode, ModeTableIdx::MGM_3_B);
|
cmdSeq(helper.mgm3Rm3100IdSideB, helper.mgm3SideBMode, ModeTableIdx::MGM_3_B);
|
||||||
ReturnValue_t status = returnvalue::OK;
|
|
||||||
if (gpsUsable) {
|
|
||||||
gpioHandler(gpioIds::GNSS_0_NRESET, true,
|
|
||||||
"AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull nReset pin"
|
|
||||||
"of GNSS 0 high (used GNSS)");
|
|
||||||
gpioHandler(gpioIds::GNSS_1_NRESET, true,
|
|
||||||
"AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull nReset pin"
|
|
||||||
"of GNSS 1 high (used GNSS)");
|
|
||||||
if (defaultSubmode == Submodes::A_SIDE) {
|
if (defaultSubmode == Submodes::A_SIDE) {
|
||||||
status = gpioIF->pullLow(gpioIds::GNSS_SELECT);
|
gpsCmd(true, true, 0);
|
||||||
} else {
|
} else {
|
||||||
status = gpioIF->pullHigh(gpioIds::GNSS_SELECT);
|
gpsCmd(true, true, 1);
|
||||||
}
|
|
||||||
if (status != returnvalue::OK) {
|
|
||||||
#if OBSW_VERBOSE_LEVEL >= 1
|
|
||||||
sif::error << "AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull GNSS select to"
|
|
||||||
"default side for dual mode"
|
|
||||||
<< std::endl;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -220,10 +208,6 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s
|
|||||||
sif::error << "AcsBoardAssembly::handleNormalModeCmd: Unknown submode" << std::endl;
|
sif::error << "AcsBoardAssembly::handleNormalModeCmd: Unknown submode" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (gpsUsable) {
|
|
||||||
modeTable[ModeTableIdx::GPS].setMode(MODE_ON);
|
|
||||||
modeTable[ModeTableIdx::GPS].setSubmode(SUBMODE_NONE);
|
|
||||||
}
|
|
||||||
if (needsSecondStep) {
|
if (needsSecondStep) {
|
||||||
result = NEED_SECOND_STEP;
|
result = NEED_SECOND_STEP;
|
||||||
}
|
}
|
||||||
@ -307,6 +291,9 @@ ReturnValue_t AcsBoardAssembly::checkAndHandleHealthStates(Mode_t deviceMode,
|
|||||||
modeHelper.setForced(true);
|
modeHelper.setForced(true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
if (healthHelper.healthTable->getHealth(helper.gpsId) == EXTERNAL_CONTROL) {
|
||||||
|
modeHelper.setForced(true);
|
||||||
|
}
|
||||||
if (deviceSubmode == duallane::DUAL_MODE) {
|
if (deviceSubmode == duallane::DUAL_MODE) {
|
||||||
checkAcsBoardSensorGroup(helper.mgm0Lis3IdSideA, helper.mgm1Rm3100IdSideA,
|
checkAcsBoardSensorGroup(helper.mgm0Lis3IdSideA, helper.mgm1Rm3100IdSideA,
|
||||||
helper.mgm2Lis3IdSideB, helper.mgm3Rm3100IdSideB);
|
helper.mgm2Lis3IdSideB, helper.mgm3Rm3100IdSideB);
|
||||||
@ -315,3 +302,25 @@ ReturnValue_t AcsBoardAssembly::checkAndHandleHealthStates(Mode_t deviceMode,
|
|||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AcsBoardAssembly::handleChildrenLostMode(ReturnValue_t result) {
|
||||||
|
using namespace duallane;
|
||||||
|
// Special handling to account for GPS devices being faulty. If the GPS device on the other
|
||||||
|
// side is marked faulty, directly to to dual side.
|
||||||
|
if (submode == Submodes::A_SIDE) {
|
||||||
|
if (healthHelper.healthTable->getHealth(helper.healthDevGps1) == FAULTY or
|
||||||
|
healthHelper.healthTable->getHealth(helper.healthDevGps1) == PERMANENT_FAULTY) {
|
||||||
|
triggerEvent(DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY, submode, 0);
|
||||||
|
startTransition(mode, Submodes::DUAL_MODE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if (submode == Submodes::B_SIDE) {
|
||||||
|
if (healthHelper.healthTable->getHealth(helper.healthDevGps0) == FAULTY or
|
||||||
|
healthHelper.healthTable->getHealth(helper.healthDevGps0) == PERMANENT_FAULTY) {
|
||||||
|
triggerEvent(DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY, submode, 0);
|
||||||
|
startTransition(mode, Submodes::DUAL_MODE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DualLaneAssemblyBase::handleChildrenLostMode(result);
|
||||||
|
}
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
struct AcsBoardHelper {
|
struct AcsBoardHelper {
|
||||||
AcsBoardHelper(object_id_t mgm0Id, object_id_t mgm1Id, object_id_t mgm2Id, object_id_t mgm3Id,
|
AcsBoardHelper(object_id_t mgm0Id, object_id_t mgm1Id, object_id_t mgm2Id, object_id_t mgm3Id,
|
||||||
object_id_t gyro0Id, object_id_t gyro1Id, object_id_t gyro2Id, object_id_t gyro3Id,
|
object_id_t gyro0Id, object_id_t gyro1Id, object_id_t gyro2Id, object_id_t gyro3Id,
|
||||||
object_id_t gpsId)
|
object_id_t gpsId, object_id_t gps0HealthDev, object_id_t gps1HealthDev)
|
||||||
: mgm0Lis3IdSideA(mgm0Id),
|
: mgm0Lis3IdSideA(mgm0Id),
|
||||||
mgm1Rm3100IdSideA(mgm1Id),
|
mgm1Rm3100IdSideA(mgm1Id),
|
||||||
mgm2Lis3IdSideB(mgm2Id),
|
mgm2Lis3IdSideB(mgm2Id),
|
||||||
@ -35,6 +35,9 @@ struct AcsBoardHelper {
|
|||||||
|
|
||||||
object_id_t gpsId = objects::NO_OBJECT;
|
object_id_t gpsId = objects::NO_OBJECT;
|
||||||
|
|
||||||
|
object_id_t healthDevGps0 = objects::NO_OBJECT;
|
||||||
|
object_id_t healthDevGps1 = objects::NO_OBJECT;
|
||||||
|
|
||||||
Mode_t gyro0SideAMode = HasModesIF::MODE_OFF;
|
Mode_t gyro0SideAMode = HasModesIF::MODE_OFF;
|
||||||
Mode_t gyro1SideAMode = HasModesIF::MODE_OFF;
|
Mode_t gyro1SideAMode = HasModesIF::MODE_OFF;
|
||||||
Mode_t gyro2SideBMode = HasModesIF::MODE_OFF;
|
Mode_t gyro2SideBMode = HasModesIF::MODE_OFF;
|
||||||
@ -91,6 +94,11 @@ class AcsBoardAssembly : public DualLaneAssemblyBase {
|
|||||||
//! desired mode/submode combination
|
//! desired mode/submode combination
|
||||||
static constexpr Event SIDE_SWITCH_TRANSITION_NOT_ALLOWED =
|
static constexpr Event SIDE_SWITCH_TRANSITION_NOT_ALLOWED =
|
||||||
event::makeEvent(SUBSYSTEM_ID, 3, severity::LOW);
|
event::makeEvent(SUBSYSTEM_ID, 3, severity::LOW);
|
||||||
|
//! [EXPORT] : [COMMENT] This is triggered when the assembly would have normally switched
|
||||||
|
//! the board side, but the GPS device of the other side was marked faulty.
|
||||||
|
//! P1: Current submode.
|
||||||
|
static constexpr Event DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY =
|
||||||
|
event::makeEvent(SUBSYSTEM_ID, 4, severity::MEDIUM);
|
||||||
|
|
||||||
static constexpr uint8_t NUMBER_DEVICES_MODE_TABLE = 9;
|
static constexpr uint8_t NUMBER_DEVICES_MODE_TABLE = 9;
|
||||||
|
|
||||||
@ -120,6 +128,8 @@ class AcsBoardAssembly : public DualLaneAssemblyBase {
|
|||||||
ReturnValue_t commandChildren(Mode_t mode, Submode_t submode) override;
|
ReturnValue_t commandChildren(Mode_t mode, Submode_t submode) override;
|
||||||
ReturnValue_t checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) override;
|
ReturnValue_t checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) override;
|
||||||
|
|
||||||
|
void handleChildrenLostMode(ReturnValue_t result) override;
|
||||||
|
|
||||||
ReturnValue_t handleNormalOrOnModeCmd(Mode_t mode, Submode_t submode);
|
ReturnValue_t handleNormalOrOnModeCmd(Mode_t mode, Submode_t submode);
|
||||||
ReturnValue_t checkAndHandleHealthStates(Mode_t deviceMode, Submode_t deviceSubmode);
|
ReturnValue_t checkAndHandleHealthStates(Mode_t deviceMode, Submode_t deviceSubmode);
|
||||||
void refreshHelperModes();
|
void refreshHelperModes();
|
||||||
|
@ -46,6 +46,9 @@ void DualLaneAssemblyBase::startTransition(Mode_t mode, Submode_t submode) {
|
|||||||
AssemblyBase::startTransition(mode, submode);
|
AssemblyBase::startTransition(mode, submode);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (sideSwitchState == SideSwitchState::NONE and sideSwitchTransition(mode, submode)) {
|
||||||
|
sideSwitchState = SideSwitchState::REQUESTED;
|
||||||
|
}
|
||||||
uint8_t pwrSubmode = submode;
|
uint8_t pwrSubmode = submode;
|
||||||
if (sideSwitchState == SideSwitchState::REQUESTED) {
|
if (sideSwitchState == SideSwitchState::REQUESTED) {
|
||||||
pwrSubmode = duallane::DUAL_MODE;
|
pwrSubmode = duallane::DUAL_MODE;
|
||||||
@ -61,7 +64,7 @@ void DualLaneAssemblyBase::startTransition(Mode_t mode, Submode_t submode) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DualLaneAssemblyBase::isUseable(object_id_t object, Mode_t mode) {
|
bool DualLaneAssemblyBase::isModeCommandable(object_id_t object, Mode_t mode) {
|
||||||
if (healthHelper.healthTable->isFaulty(object)) {
|
if (healthHelper.healthTable->isFaulty(object)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -70,10 +73,7 @@ bool DualLaneAssemblyBase::isUseable(object_id_t object, Mode_t mode) {
|
|||||||
if (childrenMap[object].mode == mode) {
|
if (childrenMap[object].mode == mode) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
// Check for external control health state is done by base class.
|
||||||
if (healthHelper.healthTable->isCommandable(object)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,9 +115,6 @@ ReturnValue_t DualLaneAssemblyBase::isModeCombinationValid(Mode_t mode, Submode_
|
|||||||
if (submode != A_SIDE and submode != B_SIDE and submode != DUAL_MODE) {
|
if (submode != A_SIDE and submode != B_SIDE and submode != DUAL_MODE) {
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
if (sideSwitchTransition(mode, submode)) {
|
|
||||||
sideSwitchState = SideSwitchState::REQUESTED;
|
|
||||||
}
|
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,12 +49,12 @@ class DualLaneAssemblyBase : public AssemblyBase, public ConfirmsFailuresIF {
|
|||||||
MessageQueueIF* eventQueue = nullptr;
|
MessageQueueIF* eventQueue = nullptr;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check whether it makes sense to send mode commands to the device
|
* Check whether it makes sense to send mode commands to the device.
|
||||||
* @param object
|
* @param object
|
||||||
* @param mode
|
* @param mode
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
bool isUseable(object_id_t object, Mode_t mode);
|
bool isModeCommandable(object_id_t object, Mode_t mode);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thin wrapper function which is required because the helper class
|
* Thin wrapper function which is required because the helper class
|
||||||
|
2
tmtc
2
tmtc
@ -1 +1 @@
|
|||||||
Subproject commit e8ccb4700a34c549eb7d943ee4a401258c69d8cb
|
Subproject commit 1f491a72a346eb7801d20eb56b2aafd1dea2d6f0
|
Loading…
Reference in New Issue
Block a user