diff --git a/CMakeLists.txt b/CMakeLists.txt index 59d9d32d..17796924 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,6 +66,7 @@ set(LIB_ARCSEC wire) set(THIRD_PARTY_FOLDER thirdparty) set(LIB_CXX_FS -lstdc++fs) set(LIB_CATCH2 Catch2) +set(LIB_GPS gps) set(LIB_JSON_NAME nlohmann_json::nlohmann_json) # Set path names @@ -221,6 +222,7 @@ if((NOT BUILD_Q7S_SIMPLE_MODE) AND (NOT EIVE_BUILD_WATCHDOG)) if(TGT_BSP MATCHES "arm/q7s") target_link_libraries(${TARGET_NAME} PRIVATE ${LIB_ARCSEC} + ${LIB_GPS} ) endif() endif() diff --git a/Justfile b/Justfile index f9d9504b..278ace99 100644 --- a/Justfile +++ b/Justfile @@ -5,5 +5,8 @@ default: q7s-debug-make q7s-debug-make: {{python_script}} -o linux -g make -b debug -t "arm/q7s" -l build-Debug-Q7S +q7s-release-make: + {{python_script}} -o linux -g make -b release -t "arm/q7s" -l build-Release-Q7S + q7s-debug-ninja: {{python_script}} -o linux -g ninja -b debug -t "arm/q7s" -l build-Debug-Q7S diff --git a/README.md b/README.md index 5ac8f6e6..adb3c3e5 100644 --- a/README.md +++ b/README.md @@ -1045,26 +1045,7 @@ cat file.bin | hexdump -v -n X ## Preparation of a fresh rootfs and SD card -This section summarizes important changes between a fresh rootfs and the current -EIVE implementation - -### rootfs - -- Mount point `/mnt/sd0` created for SD card 0. Created with `mkdir` -- Mount point `/mnt/sd1` created for SD card 1. Created with `mkdir` -- Folder `scripts` in `/home/root` folder. -- `scripts` folder currently contains a few shell helper scripts -- Folder `profile.d` in `/etc` folder which contains the `path-set.sh` script - which is sourced at software startup -- Library `libwire.so` in `/usr/lib` folder - -### SD Cards - -- Folder `bin` for binaries, for example the OBSW -- Folder `misc` for miscellaneous files. Contains `ls` for directory listings -- Folder `tc` for telecommands -- Folder `tm` for telemetry -- Folder `xdi` for XDI components (e.g. for firmware or device tree updates) +See [q7s-package repository README](https://egit.irs.uni-stuttgart.de/eive/q7s-package) # Running cppcheck on the Software diff --git a/bsp_linux_board/ObjectFactory.cpp b/bsp_linux_board/ObjectFactory.cpp index 5cd52c91..bb86ecce 100644 --- a/bsp_linux_board/ObjectFactory.cpp +++ b/bsp_linux_board/ObjectFactory.cpp @@ -14,7 +14,7 @@ #include "mission/core/GenericFactory.h" #include "mission/utility/TmFunnel.h" #include -#include "mission/devices/GyroADIS16507Handler.h" +#include "mission/devices/GyroADIS1650XHandler.h" #include "fsfw/datapoollocal/LocalDataPoolManager.h" #include "fsfw/tmtcservices/CommandingServiceBase.h" diff --git a/bsp_q7s/boardtest/Q7STestTask.cpp b/bsp_q7s/boardtest/Q7STestTask.cpp index 5cead3d5..dc87cd3b 100644 --- a/bsp_q7s/boardtest/Q7STestTask.cpp +++ b/bsp_q7s/boardtest/Q7STestTask.cpp @@ -12,17 +12,28 @@ #include "test/DummyParameter.h" #include +#include +#include +#include #include +#include #include #include Q7STestTask::Q7STestTask(object_id_t objectId): TestTask(objectId) { + doTestSdCard = false; + doTestScratchApi = false; + doTestGps = false; } ReturnValue_t Q7STestTask::performOneShotAction() { - //testSdCard(); - //testScratchApi(); + if (doTestSdCard) { + testSdCard(); + } + if (doTestScratchApi) { + testScratchApi(); + } //testJsonLibDirect(); //testDummyParams(); //testProtHandler(); @@ -31,6 +42,13 @@ ReturnValue_t Q7STestTask::performOneShotAction() { return TestTask::performOneShotAction(); } +ReturnValue_t Q7STestTask::performPeriodicAction() { + if(doTestGps) { + testGpsDaemon(); + } + return TestTask::performPeriodicAction(); +} + void Q7STestTask::testSdCard() { using namespace std; Stopwatch stopwatch; @@ -224,6 +242,26 @@ void Q7STestTask::testProtHandler() { } } +void Q7STestTask::testGpsDaemon() { + gpsmm gpsmm(GPSD_SHARED_MEMORY, 0); + gps_data_t* gps; + gps = gpsmm.read(); + if(gps == nullptr) { + sif::warning << "Q7STestTask: Reading GPS data failed" << std::endl; + } + sif::info << "-- Q7STestTask: GPS shared memory read test --" << std::endl; + time_t timeRaw = gps->fix.time.tv_sec; + std::tm* time = gmtime(&timeRaw); + sif::info << "Time: " << std::put_time(time, "%c %Z") << std::endl; + sif::info << "Visible satellites: " << gps->satellites_visible << std::endl; + sif::info << "Satellites used: " << gps->satellites_used << std::endl; + sif::info << "Fix (0:Not Seen|1:No Fix|2:2D|3:3D): " << gps->fix.mode << std::endl; + sif::info << "Latitude: " << gps->fix.latitude << std::endl; + sif::info << "Longitude: " << gps->fix.longitude << std::endl; + sif::info << "Altitude(MSL): " << gps->fix.altMSL << std::endl; + sif::info << "Speed(m/s): " << gps->fix.speed << std::endl; +} + void Q7STestTask::testFileSystemHandlerDirect(FsOpCodes opCode) { auto fsHandler = ObjectManager::instance()-> get(objects::FILE_SYSTEM_HANDLER); diff --git a/bsp_q7s/boardtest/Q7STestTask.h b/bsp_q7s/boardtest/Q7STestTask.h index 5e11b374..91e8c3d6 100644 --- a/bsp_q7s/boardtest/Q7STestTask.h +++ b/bsp_q7s/boardtest/Q7STestTask.h @@ -9,8 +9,15 @@ public: ReturnValue_t initialize() override; private: + bool doTestSdCard = false; + bool doTestScratchApi = false; + bool doTestGps = false; + CoreController* coreController = nullptr; ReturnValue_t performOneShotAction() override; + ReturnValue_t performPeriodicAction() override; + + void testGpsDaemon(); void testSdCard(); void fileTests(); diff --git a/bsp_q7s/core/InitMission.cpp b/bsp_q7s/core/InitMission.cpp index 7977deed..df857d59 100644 --- a/bsp_q7s/core/InitMission.cpp +++ b/bsp_q7s/core/InitMission.cpp @@ -117,6 +117,13 @@ void initmission::initTasks() { } #endif /* OBSW_USE_CCSDS_IP_CORE == 1 */ + PeriodicTaskIF* acsCtrl = factory->createPeriodicTask( + "ACS_CTRL", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.4, missedDeadlineFunc); + result = acsCtrl->addComponent(objects::GPS_CONTROLLER); + if(result != HasReturnvaluesIF::RETURN_OK) { + initmission::printAddObjectError("ACS_CTRL", objects::GPS_CONTROLLER); + } + # if BOARD_TE0720 == 0 // FS task, task interval does not matter because it runs in permanent loop, priority low // because it is a non-essential background task @@ -202,6 +209,8 @@ void initmission::initTasks() { #endif /* OBSW_ADD_STAR_TRACKER == 1 */ #endif + acsCtrl->startTask(); + sif::info << "Tasks started.." << std::endl; } diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index 1c5bb2df..7b111c4f 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -449,14 +449,14 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF *gpioComIF, UartComI gpioCookieAcsBoard->addGpio(gpioIds::MGM_3_RM3100_CS, gpio); consumer.str(""); - consumer << "0x" << std::hex << objects::GPS0_HANDLER; + consumer << "0x" << std::hex << objects::GPS_CONTROLLER; // GNSS reset pins are active low gpio = new GpiodRegularByLineName(q7s::gpioNames::RESET_GNSS_0, consumer.str(), gpio::DIR_OUT, gpio::HIGH); gpioCookieAcsBoard->addGpio(gpioIds::GNSS_0_NRESET, gpio); consumer.str(""); - consumer << "0x" << std::hex << objects::GPS1_HANDLER; + consumer << "0x" << std::hex << objects::GPS_CONTROLLER; gpio = new GpiodRegularByLineName(q7s::gpioNames::RESET_GNSS_1, consumer.str(), gpio::DIR_OUT, gpio::HIGH); gpioCookieAcsBoard->addGpio(gpioIds::GNSS_1_NRESET, gpio); @@ -476,13 +476,13 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF *gpioComIF, UartComI // Enable pins for GNSS consumer.str(""); - consumer << "0x" << std::hex << objects::GPS0_HANDLER; + consumer << "0x" << std::hex << objects::GPS_CONTROLLER; gpio = new GpiodRegularByLineName(q7s::gpioNames::GNSS_0_ENABLE, consumer.str(), gpio::DIR_OUT, gpio::LOW); gpioCookieAcsBoard->addGpio(gpioIds::GNSS_0_ENABLE, gpio); consumer.str(""); - consumer << "0x" << std::hex << objects::GPS1_HANDLER; + consumer << "0x" << std::hex << objects::GPS_CONTROLLER; gpio = new GpiodRegularByLineName(q7s::gpioNames::GNSS_1_ENABLE, consumer.str(), gpio::DIR_OUT, gpio::LOW); gpioCookieAcsBoard->addGpio(gpioIds::GNSS_1_ENABLE, gpio); @@ -570,14 +570,9 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF *gpioComIF, UartComI resetArgsGnss0.gnss1 = false; resetArgsGnss0.gpioComIF = gpioComIF; resetArgsGnss0.waitPeriodMs = 100; - auto uartCookieGps0 = new UartCookie(objects::GPS0_HANDLER, q7s::UART_GNSS_DEV, - UartModes::CANONICAL, uart::GNSS_BAUD, uart::HYPERION_GPS_REPLY_MAX_BUFFER); - uartCookieGps0->setToFlushInput(true); - uartCookieGps0->setReadCycles(6); - auto gpsHandler0 = new GPSHyperionHandler(objects::GPS0_HANDLER, objects::UART_COM_IF, - uartCookieGps0, debugGps); + auto gpsHandler0 = new GPSHyperionHandler(objects::GPS_CONTROLLER, objects::NO_OBJECT, + debugGps); gpsHandler0->setResetPinTriggerFunction(gps::triggerGpioResetPin, &resetArgsGnss0); - gpsHandler0->setStartUpImmediately(); } void ObjectFactory::createHeaterComponents() { diff --git a/bsp_q7s/devices/startracker/StrHelper.cpp b/bsp_q7s/devices/startracker/StrHelper.cpp index 0be38ad7..59587317 100644 --- a/bsp_q7s/devices/startracker/StrHelper.cpp +++ b/bsp_q7s/devices/startracker/StrHelper.cpp @@ -634,7 +634,7 @@ ReturnValue_t StrHelper::checkFlashActionReply(uint8_t region_, uint32_t address << std::endl; return result; } - uint16_t length; + uint16_t length = 0; size = sizeof(length); const uint8_t* lengthData = data + LENGTH_OFFSET; result = SerializeAdapter::deSerialize(&length, lengthData, &size, diff --git a/common/config/commonObjects.h b/common/config/commonObjects.h index cce3616f..135259d6 100644 --- a/common/config/commonObjects.h +++ b/common/config/commonObjects.h @@ -79,8 +79,7 @@ enum commonObjects: uint32_t { SUS_12 = 0x44120043, SUS_13 = 0x44120044, - GPS0_HANDLER = 0x44130045, - GPS1_HANDLER = 0x44130146, + GPS_CONTROLLER = 0x44130045, RW1 = 0x44120047, RW2 = 0x44120148, diff --git a/fsfw b/fsfw index b98c85d3..c1e0bcee 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit b98c85d33fd79853e674f75dadd0a082a962aee4 +Subproject commit c1e0bcee6db652d6c474c87a4099e61ecf86b694 diff --git a/linux/boardtest/SpiTestClass.cpp b/linux/boardtest/SpiTestClass.cpp index b043b55d..65f2ca9f 100644 --- a/linux/boardtest/SpiTestClass.cpp +++ b/linux/boardtest/SpiTestClass.cpp @@ -297,31 +297,31 @@ void SpiTestClass::acsInit() { GpiodRegularByChip* gpio = nullptr; std::string rpiGpioName = "gpiochip0"; gpio = new GpiodRegularByChip(rpiGpioName, mgm0Lis3mdlChipSelect, "MGM_0_LIS3", - gpio::DIR_OUT, 1); + gpio::DIR_OUT, gpio::HIGH); gpioCookie->addGpio(gpioIds::MGM_0_LIS3_CS, gpio); gpio = new GpiodRegularByChip(rpiGpioName, mgm1Rm3100ChipSelect, "MGM_1_RM3100", - gpio::DIR_OUT, 1); + gpio::DIR_OUT, gpio::HIGH); gpioCookie->addGpio(gpioIds::MGM_1_RM3100_CS, gpio); gpio = new GpiodRegularByChip(rpiGpioName, gyro0AdisChipSelect, "GYRO_0_ADIS", - gpio::DIR_OUT, 1); + gpio::DIR_OUT, gpio::HIGH); gpioCookie->addGpio(gpioIds::GYRO_0_ADIS_CS, gpio); gpio = new GpiodRegularByChip(rpiGpioName, gyro1L3gd20ChipSelect, "GYRO_1_L3G", - gpio::DIR_OUT, 1); + gpio::DIR_OUT, gpio::HIGH); gpioCookie->addGpio(gpioIds::GYRO_1_L3G_CS, gpio); gpio = new GpiodRegularByChip(rpiGpioName, gyro3L3gd20ChipSelect, "GYRO_2_L3G", - gpio::DIR_OUT, 1); + gpio::DIR_OUT, gpio::HIGH); gpioCookie->addGpio(gpioIds::GYRO_3_L3G_CS, gpio); gpio = new GpiodRegularByChip(rpiGpioName, mgm2Lis3mdlChipSelect, "MGM_2_LIS3", - gpio::DIR_OUT, 1); + gpio::DIR_OUT, gpio::HIGH); gpioCookie->addGpio(gpioIds::MGM_2_LIS3_CS, gpio); gpio = new GpiodRegularByChip(rpiGpioName, mgm3Rm3100ChipSelect, "MGM_3_RM3100", - gpio::DIR_OUT, 1); + gpio::DIR_OUT, gpio::HIGH); gpioCookie->addGpio(gpioIds::MGM_3_RM3100_CS, gpio); #elif defined(XIPHOS_Q7S) GpiodRegularByLineName* gpio = nullptr; diff --git a/linux/fsfwconfig/OBSWConfig.h.in b/linux/fsfwconfig/OBSWConfig.h.in index 4a7bca35..ea26425b 100644 --- a/linux/fsfwconfig/OBSWConfig.h.in +++ b/linux/fsfwconfig/OBSWConfig.h.in @@ -47,8 +47,6 @@ debugging. */ #define OBSW_ADD_PLOC_MPSOC 0 #define OBSW_ADD_SUN_SENSORS 0 #define OBSW_ADD_ACS_BOARD 0 -#define OBSW_ADD_GPS_0 0 -#define OBSW_ADD_GPS_1 0 #define OBSW_ADD_RW 0 #define OBSW_ADD_RTD_DEVICES 0 #define OBSW_ADD_TMP_DEVICES 0 @@ -109,7 +107,7 @@ debugging. */ #define OBSW_DEBUG_STARTRACKER 0 #define OBSW_DEBUG_PLOC_MPSOC 0 #define OBSW_DEBUG_PLOC_SUPERVISOR 0 -#define OBSW_DEBUG_PDEC_HANDLER 1 +#define OBSW_DEBUG_PDEC_HANDLER 0 /*******************************************************************/ /** Hardcoded */ diff --git a/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp b/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp index 07bc4a8f..82748821 100644 --- a/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp +++ b/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp @@ -614,38 +614,6 @@ ReturnValue_t pst::pstUart(FixedTimeslotTaskIF *thisSequence) { DeviceHandlerIF::GET_READ); #endif -#if OBSW_ADD_ACS_BOARD == 1 - -#if OBSW_ADD_GPS_0 == 1 - uartPstEmpty = false; - thisSequence->addSlot(objects::GPS0_HANDLER, length * 0, - DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::GPS0_HANDLER, length * 0.2, - DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::GPS0_HANDLER, length * 0.4, - DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::GPS0_HANDLER, length * 0.6, - DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::GPS0_HANDLER, length * 0.8, - DeviceHandlerIF::GET_READ); -#endif /* OBSW_ADD_GPS_0 == 1 */ - -#if OBSW_ADD_GPS_1 == 1 - uartPstEmpty = false; - thisSequence->addSlot(objects::GPS1_HANDLER, length * 0, - DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::GPS1_HANDLER, length * 0.2, - DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::GPS1_HANDLER, length * 0.4, - DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::GPS1_HANDLER, length * 0.6, - DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::GPS1_HANDLER, length * 0.8, - DeviceHandlerIF::GET_READ); -#endif /* OBSW_ADD_GPS_1 == 1 */ - -#endif /* OBSW_ADD_ACS_BOARD == 1 */ - #if OBSW_ADD_STAR_TRACKER == 1 uartPstEmpty = false; thisSequence->addSlot(objects::STAR_TRACKER, length * 0, DeviceHandlerIF::PERFORM_OPERATION); diff --git a/mission/devices/GPSHyperionHandler.cpp b/mission/devices/GPSHyperionHandler.cpp index 8944d17a..a0036867 100644 --- a/mission/devices/GPSHyperionHandler.cpp +++ b/mission/devices/GPSHyperionHandler.cpp @@ -4,57 +4,44 @@ #include "fsfw/datapool/PoolReadGuard.h" #include "fsfw/timemanager/Clock.h" -#include "lwgps/lwgps.h" +#ifdef FSFW_OSAL_LINUX +#include +#include +#endif + +#include #if FSFW_DEV_HYPERION_GPS_CREATE_NMEA_CSV == 1 #include #include #endif -GPSHyperionHandler::GPSHyperionHandler(object_id_t objectId, object_id_t deviceCommunication, - CookieIF *comCookie, bool debugHyperionGps): - DeviceHandlerBase(objectId, deviceCommunication, comCookie), gpsSet(this), +GPSHyperionHandler::GPSHyperionHandler(object_id_t objectId, object_id_t parentId, + bool debugHyperionGps): + ExtendedControllerBase(objectId, objects::NO_OBJECT), gpsSet(this), debugHyperionGps(debugHyperionGps) { - lwgps_init(&gpsData); } GPSHyperionHandler::~GPSHyperionHandler() {} -void GPSHyperionHandler::doStartUp() { - if(internalState == InternalStates::NONE) { - commandExecuted = false; - internalState = InternalStates::WAIT_FIRST_MESSAGE; - } - - if(internalState == InternalStates::WAIT_FIRST_MESSAGE) { - if(commandExecuted) { - internalState = InternalStates::IDLE; - setMode(MODE_ON); - commandExecuted = false; - } - } +void GPSHyperionHandler::performControlOperation() { +#ifdef FSFW_OSAL_LINUX + readGpsDataFromGpsd(); +#endif } -void GPSHyperionHandler::doShutDown() { - internalState = InternalStates::NONE; - commandExecuted = false; - setMode(_MODE_POWER_DOWN); +LocalPoolDataSetBase* GPSHyperionHandler::getDataSetHandle(sid_t sid) { + return nullptr; } -ReturnValue_t GPSHyperionHandler::buildTransitionDeviceCommand(DeviceCommandId_t *id) { - return NOTHING_TO_SEND; +ReturnValue_t GPSHyperionHandler::checkModeCommand(Mode_t mode, Submode_t submode, + uint32_t *msToReachTheMode) { + return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t GPSHyperionHandler::buildNormalDeviceCommand(DeviceCommandId_t *id) { - return NOTHING_TO_SEND; -} - -ReturnValue_t GPSHyperionHandler::buildCommandFromCommand( - DeviceCommandId_t deviceCommand, const uint8_t *commandData, - size_t commandDataLen) { - // By default, send nothing - rawPacketLen = 0; - switch(deviceCommand) { +ReturnValue_t GPSHyperionHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, + const uint8_t *data, size_t size) { + switch(actionId) { case(GpsHyperion::TRIGGER_RESET_PIN): { if(resetCallback != nullptr) { PoolReadGuard pg(&gpsSet); @@ -69,99 +56,6 @@ ReturnValue_t GPSHyperionHandler::buildCommandFromCommand( return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t GPSHyperionHandler::scanForReply(const uint8_t *start, size_t len, - DeviceCommandId_t *foundId, size_t *foundLen) { - // Pass data to GPS library - if(len > 0) { - // sif::debug << "GPSHandler::scanForReply: Received " << len << " bytes" << std::endl; - if (internalState == InternalStates::WAIT_FIRST_MESSAGE) { - // TODO: Check whether data is valid by checking whether NMEA start string is valid? - commandExecuted = true; - } - int result = lwgps_process(&gpsData, start, len); - if(result != 1) { - sif::warning << "GPSHandler::scanForReply: Issue processing GPS data with lwgps" - << std::endl; - } - else { - // The data from the device will generally be read all at once. Therefore, we - // can set all field here - PoolReadGuard pg(&gpsSet); - if(pg.getReadResult() != HasReturnvaluesIF::RETURN_OK) { -#if FSFW_VERBOSE_LEVEL >= 1 - sif::warning << "GPSHyperionHandler::scanForReply: Reading dataset failed" - << std::endl; -#endif - } - // Print messages - if(gpsData.is_valid) { - // Set all entries valid now, set invalid on case basis if values are sanitized - gpsSet.setValidity(true, true); - } - // Negative latitude -> South direction - gpsSet.latitude.value = gpsData.latitude; - // Negative longitude -> West direction - gpsSet.longitude.value = gpsData.longitude; - if(gpsData.altitude > 600000.0 or gpsData.altitude < 400000.0) { - gpsSet.altitude.setValid(false); - } - else { - gpsSet.altitude.setValid(true); - gpsSet.altitude.value = gpsData.altitude; - } - gpsSet.fixMode.value = gpsData.fix_mode; - gpsSet.satInUse.value = gpsData.sats_in_use; - Clock::TimeOfDay_t timeStruct = {}; - timeStruct.day = gpsData.date; - timeStruct.hour = gpsData.hours; - timeStruct.minute = gpsData.minutes; - timeStruct.month = gpsData.month; - timeStruct.second = gpsData.seconds; - // Convert two-digit year to full year (AD) - timeStruct.year = gpsData.year + 2000; - timeval timeval = {}; - Clock::convertTimeOfDayToTimeval(&timeStruct, &timeval); - gpsSet.year = timeStruct.year; - gpsSet.month = gpsData.month; - gpsSet.day = gpsData.date; - gpsSet.hours = gpsData.hours; - gpsSet.minutes = gpsData.minutes; - gpsSet.seconds = gpsData.seconds; - gpsSet.unixSeconds = timeval.tv_sec; - if(debugHyperionGps) { - sif::info << "GPS Data" << std::endl; - printf("Valid status: %d\n", gpsData.is_valid); - printf("Latitude: %f degrees\n", gpsData.latitude); - printf("Longitude: %f degrees\n", gpsData.longitude); - printf("Altitude: %f meters\n", gpsData.altitude); - } -#if FSFW_DEV_HYPERION_GPS_CREATE_NMEA_CSV == 1 - std::string filename = "/mnt/sd0/gps_log.txt"; - std::ofstream gpsFile; - if(not std::filesystem::exists(filename)) { - gpsFile.open(filename, std::ofstream::out); - } - gpsFile.open(filename, std::ofstream::out | std::ofstream::app); - gpsFile.write("\n", 1); - gpsFile.write(reinterpret_cast(start), len); -#endif - } - *foundLen = len; - *foundId = GpsHyperion::GPS_REPLY; - } - return HasReturnvaluesIF::RETURN_OK; - -} - -ReturnValue_t GPSHyperionHandler::interpretDeviceReply(DeviceCommandId_t id, - const uint8_t *packet) { - return HasReturnvaluesIF::RETURN_OK; -} - -uint32_t GPSHyperionHandler::getTransitionDelayMs(Mode_t from, Mode_t to) { - return 5000; -} - ReturnValue_t GPSHyperionHandler::initializeLocalDataPool( localpool::DataPool &localDataPoolMap, LocalDataPoolManager &poolManager) { localDataPoolMap.emplace(GpsHyperion::ALTITUDE, new PoolEntry({0.0})); @@ -180,35 +74,108 @@ ReturnValue_t GPSHyperionHandler::initializeLocalDataPool( return HasReturnvaluesIF::RETURN_OK; } -void GPSHyperionHandler::fillCommandAndReplyMap() { - // Reply length does not matter, packets should always arrive periodically - insertInReplyMap(GpsHyperion::GPS_REPLY, 4, &gpsSet, 0, true); - insertInCommandMap(GpsHyperion::TRIGGER_RESET_PIN); -} - -void GPSHyperionHandler::modeChanged() { - internalState = InternalStates::NONE; -} - void GPSHyperionHandler::setResetPinTriggerFunction(gpioResetFunction_t resetCallback, void *args) { this->resetCallback = resetCallback; resetCallbackArgs = args; } -void GPSHyperionHandler::debugInterface(uint8_t positionTracker, object_id_t objectId, - uint32_t parameter) { -} ReturnValue_t GPSHyperionHandler::initialize() { - ReturnValue_t result = DeviceHandlerBase::initialize(); + ReturnValue_t result = ExtendedControllerBase::initialize(); if(result != HasReturnvaluesIF::RETURN_OK) { return result; } - // Enable reply immediately for now - return updatePeriodicReply(true, GpsHyperion::GPS_REPLY); + return result; } -ReturnValue_t GPSHyperionHandler::acceptExternalDeviceCommands() { - return DeviceHandlerBase::acceptExternalDeviceCommands(); +ReturnValue_t GPSHyperionHandler::handleCommandMessage(CommandMessage *message) { + return ExtendedControllerBase::handleCommandMessage(message); } + +#ifdef FSFW_OSAL_LINUX +void GPSHyperionHandler::readGpsDataFromGpsd() { + // The data from the device will generally be read all at once. Therefore, we + // can set all field here + gpsmm gpsmm(GPSD_SHARED_MEMORY, 0); + gps_data_t* gps; + gps = gpsmm.read(); + if(gps == nullptr) { + sif::warning << "Q7STestTask: Reading GPS data failed" << std::endl; + } + PoolReadGuard pg(&gpsSet); + if(pg.getReadResult() != HasReturnvaluesIF::RETURN_OK) { +#if FSFW_VERBOSE_LEVEL >= 1 + sif::warning << "GPSHyperionHandler::scanForReply: Reading dataset failed" + << std::endl; +#endif + } + // Print messages + if((gps->set & MODE_SET) != MODE_SET) { + // Could not even set mode + gpsSet.setValidity(false, true); + return; + } + + if(gps->satellites_used > 0) { + gpsSet.setValidity(true, true); + } + + gpsSet.satInUse.value = gps->satellites_used; + gpsSet.satInView.value = gps->satellites_visible; + + // 0: Not seen, 1: No fix, 2: 2D-Fix, 3: 3D-Fix + gpsSet.fixMode = gps->fix.mode; + if(std::isfinite(gps->fix.latitude)) { + // Negative latitude -> South direction + gpsSet.latitude.value = gps->fix.latitude; + } else { + gpsSet.latitude.setValid(false); + } + + if(std::isfinite(gps->fix.longitude)) { + // Negative longitude -> West direction + gpsSet.longitude.value = gps->fix.longitude; + } else { + gpsSet.longitude.setValid(false); + } + + if(std::isfinite(gps->fix.altitude)) { + gpsSet.altitude.value = gps->fix.altitude; + } else { + gpsSet.altitude.setValid(false); + } + + if(std::isfinite(gps->fix.speed)) { + gpsSet.speed.value = gps->fix.speed; + } else { + gpsSet.speed.setValid(false); + } + + gpsSet.unixSeconds.value = gps->fix.time.tv_sec; + timeval time = {}; + time.tv_sec = gpsSet.unixSeconds.value; + time.tv_usec = gps->fix.time.tv_nsec / 1000; + Clock::TimeOfDay_t timeOfDay = {}; + Clock::convertTimevalToTimeOfDay(&time, &timeOfDay); + gpsSet.year = timeOfDay.year; + gpsSet.month = timeOfDay.month; + gpsSet.day = timeOfDay.day; + gpsSet.hours = timeOfDay.hour; + gpsSet.minutes = timeOfDay.minute; + gpsSet.seconds = timeOfDay.second; + if(debugHyperionGps) { + sif::info << "-- Hyperion GPS Data --" << std::endl; + time_t timeRaw = gps->fix.time.tv_sec; + std::tm* time = gmtime(&timeRaw); + std::cout << "Time: " << std::put_time(time, "%c %Z") << std::endl; + std::cout << "Visible satellites: " << gps->satellites_visible << std::endl; + std::cout << "Satellites used: " << gps->satellites_used << std::endl; + std::cout << "Fix (0:Not Seen|1:No Fix|2:2D|3:3D): " << gps->fix.mode << std::endl; + std::cout << "Latitude: " << gps->fix.latitude << std::endl; + std::cout << "Longitude: " << gps->fix.longitude << std::endl; + std::cout << "Altitude(MSL): " << gps->fix.altMSL << std::endl; + std::cout << "Speed(m/s): " << gps->fix.speed << std::endl; + } +} +#endif diff --git a/mission/devices/GPSHyperionHandler.h b/mission/devices/GPSHyperionHandler.h index e7c925be..96d6089e 100644 --- a/mission/devices/GPSHyperionHandler.h +++ b/mission/devices/GPSHyperionHandler.h @@ -3,8 +3,8 @@ #include "fsfw/FSFW.h" #include "fsfw/devicehandlers/DeviceHandlerBase.h" +#include "fsfw/controller/ExtendedControllerBase.h" #include "devicedefinitions/GPSDefinitions.h" -#include "lwgps/lwgps.h" /** * @brief Device handler for the Hyperion HT-GPS200 device @@ -12,58 +12,38 @@ * Flight manual: * https://egit.irs.uni-stuttgart.de/redmine/projects/eive-flight-manual/wiki/Hyperion_HT-GPS200 */ -class GPSHyperionHandler: public DeviceHandlerBase { +class GPSHyperionHandler: public ExtendedControllerBase { public: - GPSHyperionHandler(object_id_t objectId, object_id_t deviceCommunication, - CookieIF* comCookie, bool debugHyperionGps = false); + GPSHyperionHandler(object_id_t objectId, object_id_t parentId, + bool debugHyperionGps = false); virtual ~GPSHyperionHandler(); using gpioResetFunction_t = ReturnValue_t (*) (void* args); void setResetPinTriggerFunction(gpioResetFunction_t resetCallback, void*args); - ReturnValue_t acceptExternalDeviceCommands() override; - + ReturnValue_t handleCommandMessage(CommandMessage *message) override; + void performControlOperation() override; + LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override; + ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, + uint32_t *msToReachTheMode) override; + ReturnValue_t executeAction(ActionId_t actionId, + MessageQueueId_t commandedBy, const uint8_t* data, + size_t size) override; ReturnValue_t initialize() override; protected: gpioResetFunction_t resetCallback = nullptr; void* resetCallbackArgs = nullptr; - enum class InternalStates { - NONE, - WAIT_FIRST_MESSAGE, - IDLE - }; - InternalStates internalState = InternalStates::NONE; - bool commandExecuted = false; - - /* DeviceHandlerBase overrides */ - ReturnValue_t buildTransitionDeviceCommand( - DeviceCommandId_t *id) override; - void doStartUp() override; - void doShutDown() override; - ReturnValue_t buildNormalDeviceCommand( - DeviceCommandId_t *id) override; - ReturnValue_t buildCommandFromCommand( - DeviceCommandId_t deviceCommand, const uint8_t *commandData, - size_t commandDataLen) override; - ReturnValue_t scanForReply(const uint8_t *start, size_t len, - DeviceCommandId_t *foundId, size_t *foundLen) override; - ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, - const uint8_t *packet) override; - - void fillCommandAndReplyMap() override; - void modeChanged() override; - uint32_t getTransitionDelayMs(Mode_t from, Mode_t to) override; ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap, LocalDataPoolManager &poolManager) override; - virtual void debugInterface(uint8_t positionTracker = 0, - object_id_t objectId = 0, uint32_t parameter = 0) override; + private: - lwgps_t gpsData = {}; GpsPrimaryDataset gpsSet; bool debugHyperionGps = false; + + void readGpsDataFromGpsd(); }; #endif /* MISSION_DEVICES_GPSHYPERIONHANDLER_H_ */ diff --git a/mission/devices/devicedefinitions/GPSDefinitions.h b/mission/devices/devicedefinitions/GPSDefinitions.h index 90fdb123..aea442a2 100644 --- a/mission/devices/devicedefinitions/GPSDefinitions.h +++ b/mission/devices/devicedefinitions/GPSDefinitions.h @@ -15,15 +15,17 @@ enum GpsPoolIds: lp_id_t { LATITUDE = 0, LONGITUDE = 1, ALTITUDE = 2, - FIX_MODE = 3, - SATS_IN_USE = 4, - UNIX_SECONDS = 5, - YEAR = 6, - MONTH = 7, - DAY = 8, - HOURS = 9, - MINUTES = 10, - SECONDS = 11 + SPEED = 3, + FIX_MODE = 4, + SATS_IN_USE = 5, + SATS_IN_VIEW = 6, + UNIX_SECONDS = 7, + YEAR = 8, + MONTH = 9, + DAY = 10, + HOURS = 11, + MINUTES = 12, + SECONDS = 13 }; enum GpsFixModes: uint8_t { @@ -47,8 +49,10 @@ public: lp_var_t longitude = lp_var_t(sid.objectId, GpsHyperion::LONGITUDE, this); lp_var_t altitude = lp_var_t(sid.objectId, GpsHyperion::ALTITUDE, this); + lp_var_t speed = lp_var_t(sid.objectId, GpsHyperion::SPEED, this); lp_var_t fixMode = lp_var_t(sid.objectId, GpsHyperion::FIX_MODE, this); lp_var_t satInUse = lp_var_t(sid.objectId, GpsHyperion::SATS_IN_USE, this); + lp_var_t satInView = lp_var_t(sid.objectId, GpsHyperion::SATS_IN_VIEW, this); lp_var_t year = lp_var_t(sid.objectId, GpsHyperion::YEAR, this); lp_var_t month = lp_var_t(sid.objectId, GpsHyperion::MONTH, this); lp_var_t day = lp_var_t(sid.objectId, GpsHyperion::DAY, this); diff --git a/scripts/rpi-port.sh b/scripts/rpi-port.sh new file mode 100755 index 00000000..5801fb50 --- /dev/null +++ b/scripts/rpi-port.sh @@ -0,0 +1,8 @@ +#!/bin/bash +echo "-L 1538:raspberrypi.local:1538 for Raspberry Pi connect with TCF agent" +echo "-L 1539:raspberrypi.local:22 for Raspberry Pi file transfers" + +ssh -L 1538:raspberrypi.local:1534 \ + -L 1539:raspberrypi.local:22 \ + eive@2001:7c0:2018:1099:babe:0:e1fe:f1a5 \ + -t 'CONSOLE_PREFIX="[RPi Tunnel]" /bin/bash' diff --git a/thirdparty/arcsec_star_tracker b/thirdparty/arcsec_star_tracker index f596c533..2d10c6b8 160000 --- a/thirdparty/arcsec_star_tracker +++ b/thirdparty/arcsec_star_tracker @@ -1 +1 @@ -Subproject commit f596c53315f1f81facb28faec3150612a5ad2ca0 +Subproject commit 2d10c6b85ea4cab4f4baf1918c51d54eee4202c2 diff --git a/tmtc b/tmtc index dfed6b7a..c86cd187 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit dfed6b7adf957ba46ff04e0885a5948ea080d59d +Subproject commit c86cd1874f605a89277e1b8fcf4496f9302c941e