diff --git a/CHANGELOG.md b/CHANGELOG.md index 18ba4097..dd4cb9cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,19 @@ will consitute of a breaking change warranting a new major release: # [unreleased] +- `eive-tmtc`: + +## Added + +- Skyview dataset for more GPS TM has been added + +## Fixed +- The handling function of the GPS data is only called once per GPS read. This should remove + the fake fix-has-changed events. + +## Changed +- GPS Fix has changed event is no longer triggered for the EM + # [v6.3.0] 2023-08-03 ## Fixed diff --git a/linux/acs/GpsHyperionLinuxController.cpp b/linux/acs/GpsHyperionLinuxController.cpp index 900de0aa..a2dbd81b 100644 --- a/linux/acs/GpsHyperionLinuxController.cpp +++ b/linux/acs/GpsHyperionLinuxController.cpp @@ -21,6 +21,7 @@ GpsHyperionLinuxController::GpsHyperionLinuxController(object_id_t objectId, obj bool enableHkSets, bool debugHyperionGps) : ExtendedControllerBase(objectId), gpsSet(this), + skyviewSet(this), enableHkSets(enableHkSets), debugHyperionGps(debugHyperionGps) {} @@ -29,7 +30,17 @@ GpsHyperionLinuxController::~GpsHyperionLinuxController() { gps_close(&gps); } -LocalPoolDataSetBase *GpsHyperionLinuxController::getDataSetHandle(sid_t sid) { return &gpsSet; } +LocalPoolDataSetBase *GpsHyperionLinuxController::getDataSetHandle(sid_t sid) { + switch (sid.ownerSetId) { + case GpsHyperion::CORE_DATASET: + return &gpsSet; + case GpsHyperion::SKYVIEW_DATASET: + return &skyviewSet; + default: + return nullptr; + } + return nullptr; +} ReturnValue_t GpsHyperionLinuxController::checkModeCommand(Mode_t mode, Submode_t submode, uint32_t *msToReachTheMode) { @@ -90,6 +101,13 @@ ReturnValue_t GpsHyperionLinuxController::initializeLocalDataPool( localDataPoolMap.emplace(GpsHyperion::SATS_IN_VIEW, new PoolEntry()); localDataPoolMap.emplace(GpsHyperion::FIX_MODE, new PoolEntry()); poolManager.subscribeForRegularPeriodicPacket({gpsSet.getSid(), enableHkSets, 30.0}); + localDataPoolMap.emplace(GpsHyperion::SKYVIEW_UNIX_SECONDS, new PoolEntry()); + localDataPoolMap.emplace(GpsHyperion::PRN_ID, new PoolEntry()); + localDataPoolMap.emplace(GpsHyperion::AZIMUTH, new PoolEntry()); + localDataPoolMap.emplace(GpsHyperion::ELEVATION, new PoolEntry()); + localDataPoolMap.emplace(GpsHyperion::SIGNAL2NOISE, new PoolEntry()); + localDataPoolMap.emplace(GpsHyperion::USED, new PoolEntry()); + poolManager.subscribeForRegularPeriodicPacket({skyviewSet.getSid(), false, 120.0}); return returnvalue::OK; } @@ -166,30 +184,32 @@ bool GpsHyperionLinuxController::readGpsDataFromGpsd() { if (mode == MODE_OFF) { return false; } + unsigned int readIdx = 0; if (readMode == ReadModes::SOCKET) { // Poll the GPS. - if (gps_waiting(&gps, 0)) { - if (-1 == gps_read(&gps)) { + while (gps_waiting(&gps, 0)) { + int retval = gps_read(&gps); + if (retval < 0) { readError(); return false; } - oneShotSwitches.gpsReadFailedSwitch = true; - ReturnValue_t result = handleGpsReadData(); - if (result == returnvalue::OK) { - return true; - } else { - return false; + readIdx++; + if (readIdx >= 40) { + sif::warning << "GpsHyperionLinuxController: Received " << readIdx + << " GPSD message consecutively" << std::endl; + break; } - noModeSetCntr = 0; - } else { - return false; + } + if (readIdx > 0) { + oneShotSwitches.gpsReadFailedSwitch = true; + handleGpsReadData(); } } else if (readMode == ReadModes::SHM) { sif::error << "GpsHyperionLinuxController::readGpsDataFromGpsdPermanentLoop: " "SHM read not implemented" << std::endl; } - return true; + return false; } ReturnValue_t GpsHyperionLinuxController::handleGpsReadData() { @@ -208,7 +228,15 @@ ReturnValue_t GpsHyperionLinuxController::handleGpsReadData() { return returnvalue::FAILED; } } + ReturnValue_t result = handleCoreTelemetry(modeIsSet); + if (result != returnvalue::OK) { + return result; + } + result = handleSkyviewTelemetry(); + return result; +} +ReturnValue_t GpsHyperionLinuxController::handleCoreTelemetry(bool modeIsSet) { PoolReadGuard pg(&gpsSet); if (pg.getReadResult() != returnvalue::OK) { #if FSFW_VERBOSE_LEVEL >= 1 @@ -236,7 +264,9 @@ ReturnValue_t GpsHyperionLinuxController::handleGpsReadData() { } } if (gpsSet.fixMode.value != newFix) { +#if OBSW_Q7S_EM != 1 triggerEvent(GpsHyperion::GPS_FIX_CHANGE, gpsSet.fixMode.value, newFix); +#endif } gpsSet.fixMode = newFix; gpsSet.fixMode.setValid(modeIsSet); @@ -369,6 +399,22 @@ ReturnValue_t GpsHyperionLinuxController::handleGpsReadData() { return returnvalue::OK; } +ReturnValue_t GpsHyperionLinuxController::handleSkyviewTelemetry() { + PoolReadGuard pg(&skyviewSet); + if (pg.getReadResult() != returnvalue::OK) { + return returnvalue::FAILED; + } + skyviewSet.unixSeconds.value = gps.skyview_time; + for (int sat = 0; sat < GpsHyperion::MAX_SATELLITES; sat++) { + skyviewSet.prn_id.value[sat] = gps.skyview[sat].PRN; + skyviewSet.azimuth.value[sat] = gps.skyview[sat].azimuth; + skyviewSet.elevation.value[sat] = gps.skyview[sat].elevation; + skyviewSet.signal2noise.value[sat] = gps.skyview[sat].ss; + skyviewSet.used.value[sat] = gps.skyview[sat].used; + } + return returnvalue::OK; +} + void GpsHyperionLinuxController::overwriteTimeIfNotSane(timeval time, bool validFix) { if (not timeInit and validFix) { if (not utility::timeSanityCheck()) { diff --git a/linux/acs/GpsHyperionLinuxController.h b/linux/acs/GpsHyperionLinuxController.h index d5b1f637..3378ac55 100644 --- a/linux/acs/GpsHyperionLinuxController.h +++ b/linux/acs/GpsHyperionLinuxController.h @@ -54,9 +54,12 @@ class GpsHyperionLinuxController : public ExtendedControllerBase { 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; @@ -81,7 +84,6 @@ class GpsHyperionLinuxController : public ExtendedControllerBase { } oneShotSwitches; bool debugHyperionGps = false; - int32_t noModeSetCntr = 0; // Returns true if the function should be called again or false if other // controller handling can be done. diff --git a/mission/acs/archive/GPSDefinitions.h b/mission/acs/archive/GPSDefinitions.h index d9f93173..67169cbc 100644 --- a/mission/acs/archive/GPSDefinitions.h +++ b/mission/acs/archive/GPSDefinitions.h @@ -20,32 +20,47 @@ static constexpr Event CANT_GET_FIX = event::makeEvent(SUBSYSTEM_ID, 1, severity static constexpr DeviceCommandId_t GPS_REPLY = 0; static constexpr DeviceCommandId_t TRIGGER_RESET_PIN_GNSS = 5; -static constexpr uint32_t DATASET_ID = 0; +enum SetIds : uint32_t { + CORE_DATASET, + SKYVIEW_DATASET, +}; enum GpsPoolIds : lp_id_t { - LATITUDE = 0, - LONGITUDE = 1, - ALTITUDE = 2, - 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 + LATITUDE, + LONGITUDE, + ALTITUDE, + SPEED, + FIX_MODE, + SATS_IN_USE, + SATS_IN_VIEW, + UNIX_SECONDS, + YEAR, + MONTH, + DAY, + HOURS, + MINUTES, + SECONDS, + SKYVIEW_UNIX_SECONDS, + PRN_ID, + AZIMUTH, + ELEVATION, + SIGNAL2NOISE, + USED, }; +static constexpr uint8_t CORE_DATASET_ENTRIES = 14; +static constexpr uint8_t SKYVIEW_ENTRIES = 6; + +static constexpr uint8_t MAX_SATELLITES = 30; + enum GpsFixModes : uint8_t { INVALID = 0, NO_FIX = 1, FIX_2D = 2, FIX_3D = 3 }; } // namespace GpsHyperion -class GpsPrimaryDataset : public StaticLocalDataSet<18> { +class GpsPrimaryDataset : public StaticLocalDataSet { public: - GpsPrimaryDataset(object_id_t gpsId) : StaticLocalDataSet(sid_t(gpsId, GpsHyperion::DATASET_ID)) { + GpsPrimaryDataset(object_id_t gpsId) + : StaticLocalDataSet(sid_t(gpsId, GpsHyperion::CORE_DATASET)) { setAllVariablesReadOnly(); } @@ -69,7 +84,34 @@ class GpsPrimaryDataset : public StaticLocalDataSet<18> { friend class GpsHyperionLinuxController; friend class GpsCtrlDummy; GpsPrimaryDataset(HasLocalDataPoolIF* hkOwner) - : StaticLocalDataSet(hkOwner, GpsHyperion::DATASET_ID) {} + : StaticLocalDataSet(hkOwner, GpsHyperion::CORE_DATASET) {} +}; + +class SkyviewDataset : public StaticLocalDataSet { + public: + SkyviewDataset(object_id_t gpsId) + : StaticLocalDataSet(sid_t(gpsId, GpsHyperion::SKYVIEW_DATASET)) { + setAllVariablesReadOnly(); + } + + lp_var_t unixSeconds = + lp_var_t(sid.objectId, GpsHyperion::SKYVIEW_UNIX_SECONDS, this); + lp_vec_t prn_id = + lp_vec_t(sid.objectId, GpsHyperion::PRN_ID, this); + lp_vec_t azimuth = + lp_vec_t(sid.objectId, GpsHyperion::AZIMUTH, this); + lp_vec_t elevation = + lp_vec_t(sid.objectId, GpsHyperion::ELEVATION, this); + lp_vec_t signal2noise = + lp_vec_t(sid.objectId, GpsHyperion::SIGNAL2NOISE, this); + lp_vec_t used = + lp_vec_t(sid.objectId, GpsHyperion::USED, this); + + private: + friend class GpsHyperionLinuxController; + friend class GpsCtrlDummy; + SkyviewDataset(HasLocalDataPoolIF* hkOwner) + : StaticLocalDataSet(hkOwner, GpsHyperion::SKYVIEW_DATASET) {} }; #endif /* MISSION_ACS_ARCHIVE_GPSDEFINITIONS_H_ */