eive-obsw/linux/acs/GpsHyperionLinuxController.h
2024-04-09 13:30:22 +02:00

100 lines
3.5 KiB
C++

#ifndef MISSION_DEVICES_GPSHYPERIONHANDLER_H_
#define MISSION_DEVICES_GPSHYPERIONHANDLER_H_
#include <common/config/eive/eventSubsystemIds.h>
#include <fsfw/FSFW.h>
#include <fsfw/controller/ExtendedControllerBase.h>
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
#include <linux/acs/GPSDefinitions.h>
#include <mission/utility/trace.h>
#ifdef FSFW_OSAL_LINUX
#include <gps.h>
#include <libgpsmm.h>
#endif
/**
* @brief Device handler for the Hyperion HT-GPS200 device
* @details
* Flight manual:
* https://egit.irs.uni-stuttgart.de/redmine/projects/eive-flight-manual/wiki/Hyperion_HT-GPS200
* This device handler can only be used on Linux system where the gpsd daemon with shared memory
* export is running.
*/
class GpsHyperionLinuxController : public ExtendedControllerBase {
public:
// 15 minutes
static constexpr uint32_t MAX_SECONDS_TO_REACH_FIX = 60 * 15;
enum ReadModes { SHM = 0, SOCKET = 1 };
GpsHyperionLinuxController(object_id_t objectId, object_id_t parentId, bool enableHkSets,
bool debugHyperionGps = false);
virtual ~GpsHyperionLinuxController();
using gpioResetFunction_t = ReturnValue_t (*)(const uint8_t* actionData, size_t len, void* args);
ReturnValue_t performOperation(uint8_t opCode) override;
void setResetPinTriggerFunction(gpioResetFunction_t resetCallback, void* args);
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;
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) override;
ReturnValue_t handleGpsReadData();
ReturnValue_t handleCoreTelemetry(bool modeIsSet);
ReturnValue_t handleSkyviewTelemetry();
private:
GpsPrimaryDataset gpsSet;
SkyviewDataset skyviewSet;
gps_data_t gps = {};
bool enableHkSets = false;
const char* currentClientBuf = nullptr;
ReadModes readMode = ReadModes::SOCKET;
Countdown maxTimeToReachFix = Countdown(MAX_SECONDS_TO_REACH_FIX * 1000);
Countdown gainedNewFix = Countdown(60 * 2 * 1000);
uint32_t fixChangeCounter = 0;
bool timeInit = false;
uint8_t satNotSetCounter = 0;
#if OBSW_THREAD_TRACING == 1
uint32_t opCounter = 0;
#endif
struct OneShotSwitches {
void reset() {
gpsReadFailedSwitch = true;
cantGetFixSwitch = true;
}
bool gpsReadFailedSwitch = true;
bool cantGetFixSwitch = true;
} oneShotSwitches;
bool debugHyperionGps = false;
// Returns true if the function should be called again or false if other
// controller handling can be done.
bool readGpsDataFromGpsd();
// If the time is totally wrong (e.g. year 2000 after system reset because we do not have a RTC)
// we set it with the roughly valid time from the GPS. For some reason, NTP might only work
// if the time difference between sys time and current time is not too large
void overwriteTimeIfNotSane(timeval time, bool validFix);
void handleFixChangedEvent(uint8_t newFix);
};
#endif /* MISSION_DEVICES_GPSHYPERIONHANDLER_H_ */