#include "fsfw/housekeeping/PeriodicHousekeepingHelper.h" #include #include "fsfw/datapoollocal/LocalPoolDataSetBase.h" PeriodicHousekeepingHelper::PeriodicHousekeepingHelper(LocalPoolDataSetBase* owner) : owner(owner) {} void PeriodicHousekeepingHelper::initialize(float collectionInterval, dur_millis_t minimumPeriodicInterval) { this->minimumPeriodicInterval = minimumPeriodicInterval; collectionIntervalTicks = intervalSecondsToIntervalTicks(collectionInterval); /* This will cause a checkOpNecessary call to be true immediately. I think it's okay if a HK packet is generated immediately instead of waiting one generation cycle. */ internalTickCounter = collectionIntervalTicks; } float PeriodicHousekeepingHelper::getCollectionIntervalInSeconds() const { return intervalTicksToSeconds(collectionIntervalTicks); } bool PeriodicHousekeepingHelper::checkOpNecessary() { if (internalTickCounter >= collectionIntervalTicks) { internalTickCounter = 1; return true; } internalTickCounter++; return false; } uint32_t PeriodicHousekeepingHelper::intervalSecondsToIntervalTicks( float collectionIntervalSeconds) { if (owner == nullptr) { return 0; } /* Avoid division by zero */ if (minimumPeriodicInterval == 0) { /* Perform operation each cycle */ return 1; } else { dur_millis_t intervalInMs = collectionIntervalSeconds * 1000; uint32_t divisor = minimumPeriodicInterval; uint32_t ticks = std::ceil(static_cast(intervalInMs) / divisor); return ticks; } } float PeriodicHousekeepingHelper::intervalTicksToSeconds(uint32_t collectionInterval) const { /* Number of ticks times the minimum interval is in milliseconds, so we divide by 1000 to get the value in seconds */ return static_cast(collectionInterval * minimumPeriodicInterval / 1000.0); } void PeriodicHousekeepingHelper::changeCollectionInterval(float newIntervalSeconds) { collectionIntervalTicks = intervalSecondsToIntervalTicks(newIntervalSeconds); }