fsfw/src/fsfw/housekeeping/PeriodicHousekeepingHelper.cpp

88 lines
3.2 KiB
C++
Raw Normal View History

2021-07-13 20:22:54 +02:00
#include "fsfw/housekeeping/PeriodicHousekeepingHelper.h"
2020-12-03 13:00:04 +01:00
2020-10-01 12:05:24 +02:00
#include <cmath>
2022-02-02 10:29:30 +01:00
#include "fsfw/datapoollocal/LocalPoolDataSetBase.h"
PeriodicHousekeepingHelper::PeriodicHousekeepingHelper(LocalPoolDataSetBase* owner)
: owner(owner) {}
2020-10-01 12:05:24 +02:00
void PeriodicHousekeepingHelper::initialize(float collectionInterval,
2022-02-02 10:29:30 +01:00
dur_millis_t minimumPeriodicInterval,
uint8_t nonDiagIntervalFactor) {
this->minimumPeriodicInterval = minimumPeriodicInterval;
this->nonDiagIntervalFactor = nonDiagIntervalFactor;
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;
2020-10-01 12:05:24 +02:00
}
2021-03-10 21:17:08 +01:00
float PeriodicHousekeepingHelper::getCollectionIntervalInSeconds() const {
2022-02-02 10:29:30 +01:00
return intervalTicksToSeconds(collectionIntervalTicks);
2020-10-01 12:05:24 +02:00
}
bool PeriodicHousekeepingHelper::checkOpNecessary() {
2022-02-02 10:29:30 +01:00
if (internalTickCounter >= collectionIntervalTicks) {
internalTickCounter = 1;
return true;
}
internalTickCounter++;
return false;
2020-10-01 12:05:24 +02:00
}
2021-03-10 21:17:08 +01:00
uint32_t PeriodicHousekeepingHelper::intervalSecondsToIntervalTicks(
2022-02-02 10:29:30 +01:00
float collectionIntervalSeconds) {
if (owner == nullptr) {
return 0;
}
bool isDiagnostics = owner->isDiagnostics();
2021-03-11 12:04:54 +01:00
2022-02-02 10:29:30 +01:00
/* Avoid division by zero */
if (minimumPeriodicInterval == 0) {
if (isDiagnostics) {
/* Perform operation each cycle */
return 1;
} else {
return nonDiagIntervalFactor;
}
} else {
dur_millis_t intervalInMs = collectionIntervalSeconds * 1000;
uint32_t divisor = minimumPeriodicInterval;
if (not isDiagnostics) {
/* We need to multiply the divisor because non-diagnostics only
allow a multiple of the minimum periodic interval */
divisor *= nonDiagIntervalFactor;
2021-03-10 21:17:08 +01:00
}
2022-02-02 10:29:30 +01:00
uint32_t ticks = std::ceil(static_cast<float>(intervalInMs) / divisor);
if (not isDiagnostics) {
/* Now we need to multiply the calculated ticks with the factor as as well
because the minimum tick count to generate a non-diagnostic is the factor itself.
2021-03-10 21:17:08 +01:00
2022-02-02 10:29:30 +01:00
Example calculation for non-diagnostic with
0.4 second interval and 0.2 second task interval.
Resultant tick count of 5 is equal to operation each second.
2021-03-10 21:17:08 +01:00
2022-02-02 10:29:30 +01:00
Examle calculation for non-diagnostic with 2.0 second interval and 0.2 second
task interval.
Resultant tick count of 10 is equal to operatin every 2 seconds.
2021-03-10 21:17:08 +01:00
2022-02-02 10:29:30 +01:00
Example calculation for diagnostic with 0.4 second interval and 0.3
second task interval. Resulting tick count of 2 is equal to operation
every 0.6 seconds. */
ticks *= nonDiagIntervalFactor;
2021-03-10 21:17:08 +01:00
}
2022-02-02 10:29:30 +01:00
return ticks;
}
2020-10-01 12:05:24 +02:00
}
2022-02-02 10:29:30 +01:00
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<float>(collectionInterval * minimumPeriodicInterval / 1000.0);
2020-10-01 12:05:24 +02:00
}
2022-02-02 10:29:30 +01:00
void PeriodicHousekeepingHelper::changeCollectionInterval(float newIntervalSeconds) {
collectionIntervalTicks = intervalSecondsToIntervalTicks(newIntervalSeconds);
2020-10-01 12:05:24 +02:00
}