FhSim  3.1.0
Marine systems simulation
Loading...
Searching...
No Matches
SampleClock.h
1#pragma once
2
11#include <fhsim/NFhSim.h>
12#include <fhsim/PrintDuringExec.h>
13#include <cmath>
14#include <limits>
15#include <stdexcept>
16#include <string>
17
43{
44public:
53 explicit SampleClock(const double period, const double firstSampleTime = 0.0)
54 : m_period(period)
55 , m_next(firstSampleTime)
56 {
57 if (!(std::isfinite(period) && period > 0.0))
58 throw std::invalid_argument("SampleClock: the sample period must be finite and positive, it is " + std::to_string(period) + " s.");
59 }
60
62 static SampleClock Never() { return SampleClock(NeverTag {}); }
63
72 void StartAt(const double tStart)
73 {
74 if (std::isfinite(m_period))
75 m_next = tStart;
76 }
77
82 void SetLogger(PrintDuringExec* const print) { m_print = print; }
83
90 bool Due(const double t)
91 {
92 if (t < m_next)
93 return false;
94
95 WarnOnceIfLate(t);
96 m_next += m_period;
97 return true;
98 }
99
101 double NextSampleTime() const { return m_next; }
102
104 double Period() const { return m_period; }
105
107 bool LatenessWarningGiven() const { return m_latenessWarningGiven; }
108
109private:
111 struct NeverTag
112 {
113 };
114
115 explicit SampleClock(NeverTag)
116 : m_period(std::numeric_limits<double>::infinity())
117 , m_next(std::numeric_limits<double>::infinity())
118 {
119 }
120
125 void WarnOnceIfLate(const double t)
126 {
127 const double lateness = t - m_next;
128 if (lateness <= kLatenessFraction * m_period || m_latenessWarningGiven)
129 return;
130
131 m_latenessWarningGiven = true;
132 if (m_print == nullptr)
133 return;
134
135 m_print->WriteLog("In SampleClock. A sample due at t = " + std::to_string(m_next) + " s was taken " + std::to_string(lateness) + " s late, which is more than " + std::to_string(kLatenessFraction) + " of the sample period of " + std::to_string(m_period) + " s. The integrator step is too coarse for this "
136 "sample rate; set StepMax to " +
137 std::to_string(kLatenessFraction * m_period) + " s or less. This warning is given once.",
138 fhsim::LogLevel_Warning);
139 }
140
142 static constexpr double kLatenessFraction = 0.25;
143
144 double m_period;
145 double m_next;
146
147 PrintDuringExec* m_print = nullptr;
148 bool m_latenessWarningGiven = false;
149};
Definition SampleClock.h:43
bool Due(const double t)
Definition SampleClock.h:90
SampleClock(const double period, const double firstSampleTime=0.0)
Definition SampleClock.h:53
void StartAt(const double tStart)
Definition SampleClock.h:72
void SetLogger(PrintDuringExec *const print)
Definition SampleClock.h:82
double NextSampleTime() const
The time at which the next sample is due, s.
Definition SampleClock.h:101
bool LatenessWarningGiven() const
True once the too-coarse-step warning has been given.
Definition SampleClock.h:107
double Period() const
The time between samples, s.
Definition SampleClock.h:104
static SampleClock Never()
A clock that never fires: for a sensor that has no sample rate yet.
Definition SampleClock.h:62