Components
Components are C++ classes that use store objects for input/output/parameters/control. This let’s you easily tune and debug an application.
The instances of these classes are tuned at compile-time to reflect the objects in the store. Especially, no resources are used for (optional) fields that do not exist in the store, and all store lookups in the directory are done at compile-time. You need C++14 (or later), though.
Check out the components and control examples.
stored::Amplifier
-
template<typename Container, unsigned long long flags = 0, typename T = float>
class Amplifier An offset/gain amplifier, based on store variables.
This class comes in very handy when converting ADC inputs to some SI-value. It includes an override field to force inputs to some test value.
To use this class, add a scope to your store, like:
{ float input bool=true enable float=1 gain float=0 offset float=-inf low float=inf high float=nan override float output } ampAll fields are optional. All variables of type
floatcan be any other type, as long as it matches the template parameterT.When not all fields are in the store, names may become ambiguous. For example, if override and output are not there, the store’s directory may resolve
oto any of the three fields. In this case, you have to specify which fields are to be processed. For this, use the following ids:field
id
input
Ienable
egain
goffset
olow
lhigh
hoverride
Foutput
OThe amplifier basically does:
if(override is nan) output = min(high, max(low, input * gain + offset)) else output = overrideThen, instantiate the amplifier like this:
// Construct a compile-time object, which resolves all fields in your store. constexpr auto amp_o = stored::Amplifier<stored::YourStore>::objects("/amp/"); // Instantiate an Amplifier, tailored to the available fields in the store. stored::Amplifier<stored::YourStore, amp_o.flags()> amp{amp_o, yourStore};Or, for example when you know there are only the offset and gain fields in the store, and ambiguity must be resolved:
// Construct a compile-time object, which resolves only two fields in your store. constexpr auto amp_o = stored::Amplifier<stored::YourStore>::objects<'o','g'>("/amp/"); stored::Amplifier<stored::YourStore, amp_o.flags()> amp{amp_o, yourStore};Calling
amp()now uses theinputand produces the value inoutput. Alternatively, or when theinputfield is absent in the store, callamp(x), wherexis the input.Public Types
Public Functions
-
constexpr Amplifier() noexcept = default
Default ctor.
Use this when initialization is postponed. Do not access or run the Amplifier instance, as it does not hold proper references to a store. You can just assign another Amplifier instance.
-
inline constexpr Amplifier(AmplifierObjects<Container, type> const &o, Container &container)
Initialize the Amplifier, given a list of objects and a container.
-
inline void disable() noexcept
Disable the Amplifier.
Ignored when the
enableobject is not available.
-
inline void enable(bool value = true) noexcept
Enable (or disable) the Amplifier.
Ignored when the
enableobject is not available.
-
inline bool enabled() const noexcept
Return the
enablevalue, which istruewhen not available.
-
inline decltype(auto) enableObject() const noexcept
Return the
enableobject.
-
inline decltype(auto) enableObject() noexcept
Return the
enableobject.
-
inline decltype(auto) gainObject() const noexcept
Return the
gainobject.
-
inline decltype(auto) gainObject() noexcept
Return the
gainobject.
-
inline decltype(auto) highObject() const noexcept
Return the
highobject.
-
inline decltype(auto) highObject() noexcept
Return the
highobject.
-
inline decltype(auto) inputObject() const noexcept
Return the
inputobject.
-
inline decltype(auto) inputObject() noexcept
Return the
inputobject.
-
inline decltype(auto) lowObject() const noexcept
Return the
lowobject.
-
inline decltype(auto) lowObject() noexcept
Return the
lowobject.
-
inline decltype(auto) offsetObject() const noexcept
Return the
offsetobject.
-
inline decltype(auto) offsetObject() noexcept
Return the
offsetobject.
-
inline type operator()() noexcept
Compute the Amplifier output, given the input as stored in the store.
-
inline decltype(auto) outputObject() const noexcept
Return the
outputobject.
-
inline decltype(auto) outputObject() noexcept
Return the
outputobject.
-
inline decltype(auto) overrideObject() const noexcept
Return the
overrideobject.
-
inline decltype(auto) overrideObject() noexcept
Return the
overrideobject.
-
constexpr Amplifier() noexcept = default
stored::FirstOrderFilter
-
template<typename Container, bool LowPass, unsigned long long flags = 0, typename T = float>
class FirstOrderFilter First-order low- or high-pass filter, based on store variables.
To use this class, add a scope to your store, like:
{ (float) sample frequency (Hz) float input float cutoff frequency (Hz) bool=true enable bool reset float=nan override float output } filterOnly
sample frequencyandcutoff frequencyare mandatory. All variables of typefloat, except forsample frequency, can be any other type, as long as it matches the template parameterT.Then, instantiate the controller like this:
// Construct a compile-time object, which resolves all fields in your store. constexpr auto filter_o = stored::LowPass<stored::YourStore>::objects("/filter/"); // Instantiate the filter, tailored to the available fields in the store. stored::LowPass<stored::YourStore, filter_o.flags()> filter{filter_o, yourStore}; // ...or use HighPass instead of LowPass.The cutoff frequency can be changed while running (by setting
resettotrue). It will applied smoothly; the output will gradually take the new cutoff frequency into account.Public Types
Public Functions
-
constexpr FirstOrderFilter() noexcept = default
Default ctor.
Use this when initialization is postponed. You can assign another instance later on.
-
inline constexpr FirstOrderFilter(FirstOrderFilterObjects<Container, type> const &o, Container &container)
Initialize the filter, given a list of objects and a container.
-
inline decltype(auto) cutoffFrequencyObject() const noexcept
Return the
cutoff frequencyobject.
-
inline decltype(auto) cutoffFrequencyObject() noexcept
Return the
cutoff frequencyobject.
-
inline void disable() noexcept
Disable the pulse wave.
Ignored when the
enableobject is not available.
-
inline void enable(bool value = true) noexcept
Enable (or disable) the pulse wave.
Ignored when the
enableobject is not available.
-
inline bool enabled() const noexcept
Return the
enablevalue, ortruewhen not available.
-
inline decltype(auto) enableObject() const noexcept
Return the
enableobject.
-
inline decltype(auto) enableObject() noexcept
Return the
enableobject.
-
inline decltype(auto) inputObject() const noexcept
Return the
inputobject.
-
inline decltype(auto) inputObject() noexcept
Return the
inputobject.
-
inline decltype(auto) outputObject() const noexcept
Return the
outputobject.
-
inline decltype(auto) outputObject() noexcept
Return the
outputobject.
-
inline decltype(auto) overrideObject() const noexcept
Return the
overrideobject.
-
inline decltype(auto) overrideObject() noexcept
Return the
overrideobject.
-
inline void recomputeCoefficients()
Recompute alpha after changed filter parameters.
-
inline bool reset() const noexcept
Return the
resetvalue, orfalsewhen not available.
-
inline decltype(auto) resetObject() const noexcept
Return the
resetobject.
-
inline decltype(auto) resetObject() noexcept
Return the
resetobject.
-
inline float sampleFrequency() const noexcept
Return the sample frequency.
-
inline decltype(auto) sampleFrequencyObject() const noexcept
Return the
sample frequencyobject.
-
constexpr FirstOrderFilter() noexcept = default
There are stored::LowPass and stored::HighPass aliases for the corresponding stored::FistOrderFilter template parameters.
stored::PID
-
template<typename Container, unsigned long long flags = 0, typename T = float>
class PID PID controller, based on store variables.
To use this class, add a scope to your store, like:
{ (float) frequency (Hz) float y float setpoint bool=true enable float=1 Kp float=inf Ti (s) float=0 Td (s) float=0 Kff float int float=-inf int low float=inf int high float=-inf low float=inf high float=inf error max float=inf epsilon bool reset float=nan override float u } pidOnly
frequency,setpoint, andKpare mandatory. All variables of typefloat, except forfrequency, can be any other type, as long as it matches the template parameterT.It has the following objects:
frequency:the control frequency; the application must invoke the PID controller at this frequencyy:the process variable (output of the plant)setpoint:the setpoint to controlytoKp:P coefficientTi:I time constantTd:D time constantKff:feed-forward coefficientint:current integral valueint low: lower bound forintint high: upper bound forintlow:lower bound for computeduhigh:upper bound for computeduepsilon:minimum value of the error ( |setpoint-y| ), which must result in a change of the outputu. Otherwise, numerical stability is compromised. See isHealthy().reset:when set totrue, recompute and apply changed control parametersoverride:when not NaN, forceuto this value, withoutlowandhighappliedu:control output (input for the plant)
Then, instantiate the controller like this:
// Construct a compile-time object, which resolves all fields in your store. constexpr auto pid_o = stored::PID<stored::YourStore>::objects("/pid/"); // Instantiate a PID, tailored to the available fields in the store. stored::PID<stored::YourStore, pid_o.flags()> pid{pid_o, yourStore};The PID controller has the following properties:
The parameters specify a serial PID.
The integral windup prevention stops the integral when the output clips.
Changing Ti is implemented smoothly; changing the parameters (and setting
resetafterwards) can be done while running.isHealthy() checks for numerical stability.
Public Types
Public Functions
-
constexpr PID() noexcept = default
Default ctor.
Use this when initialization is postponed. You can assign another instance later on.
-
inline constexpr PID(PIDObjects<Container, type> const &o, Container &container)
Initialize the pin, given a list of objects and a container.
-
inline void enable(bool value = true) noexcept
Enable (or disable) the PID.
Ignored when the
enableobject is not available.
-
inline bool enabled() const noexcept
Return the
enablevalue, ortruewhen not available.
-
inline decltype(auto) enableObject() const noexcept
Return the
enableobject.
-
inline decltype(auto) enableObject() noexcept
Return the
enableobject.
-
inline decltype(auto) epsilonObject() const noexcept
Return the
epsilonobject.
-
inline decltype(auto) epsilonObject() noexcept
Return the
epsilonobject.
-
inline decltype(auto) errorMaxObject() const noexcept
Return the
error maxobject.
-
inline decltype(auto) errorMaxObject() noexcept
Return the
error maxobject.
-
inline float frequency() const noexcept
Return the control frequency.
-
inline decltype(auto) frequencyObject() const noexcept
Return the
frequencyobject.
-
inline decltype(auto) highObject() const noexcept
Return the
highobject.
-
inline decltype(auto) highObject() noexcept
Return the
highobject.
-
inline type int_() const noexcept
Return the current integral value.
This is the integral of the
(setpoint - y) * Ki. So, when Ti (and there fore Ki) changes, it may take a while till the new Ti is in effect, depending on the current integral value.
-
inline decltype(auto) intHighObject() const noexcept
Return the
int highobject.
-
inline decltype(auto) intHighObject() noexcept
Return the
int highobject.
-
inline decltype(auto) intLowObject() const noexcept
Return the
int lowobject.
-
inline decltype(auto) intLowObject() noexcept
Return the
int lowobject.
-
inline decltype(auto) intObject() const noexcept
Return the
intobject.
-
inline decltype(auto) intObject() noexcept
Return the
intobject.
-
inline bool isHealthy() const noexcept
Check numerical stability.
epsilon() is the smallest change in error ( | setpoint() - y() | ) that must have influence the output u(). If the error is smaller, the output may remain the same. This function checks if that is still the case.
The integrator is especially interesting. If it becomes too large, successive (small) errors may not be able to reduce it anymore, because of rounding. If that is the case, it is considered unhealthy.
This value can optionally be defined in the store. If omitted, this function always returns
true.You may want to check (or assert on) this function once in a while, like once per second or after every run, to detect a stuck controller within reasonable time for your application.
-
inline decltype(auto) KffObject() const noexcept
Return the
Kffobject.
-
inline decltype(auto) KffObject() noexcept
Return the
Kffobject.
-
inline decltype(auto) KpObject() const noexcept
Return the
Kpobject.
-
inline decltype(auto) KpObject() noexcept
Return the
Kpobject.
-
inline decltype(auto) lowObject() const noexcept
Return the
lowobject.
-
inline decltype(auto) lowObject() noexcept
Return the
lowobject.
-
inline decltype(auto) overrideObject() const noexcept
Return the
overrideobject.
-
inline decltype(auto) overrideObject() noexcept
Return the
overrideobject.
-
inline bool reset() const noexcept
Return the
resetvalue, orfalsewhen not available.
-
inline decltype(auto) resetObject() const noexcept
Return the
resetobject.
-
inline decltype(auto) resetObject() noexcept
Return the
resetobject.
-
inline decltype(auto) setpointObject() const noexcept
Return the
setpointobject.
-
inline decltype(auto) setpointObject() noexcept
Return the
setpointobject.
-
inline decltype(auto) TdObject() const noexcept
Return the
Tdobject.
-
inline decltype(auto) TdObject() noexcept
Return the
Tdobject.
-
inline decltype(auto) TiObject() const noexcept
Return the
Tiobject.
-
inline decltype(auto) TiObject() noexcept
Return the
Tiobject.
-
inline decltype(auto) uObject() const noexcept
Return the
uobject.
-
inline decltype(auto) uObject() noexcept
Return the
uobject.
-
inline decltype(auto) yObject() const noexcept
Return the
yobject.
-
inline decltype(auto) yObject() noexcept
Return the
yobject.
stored::PinIn
-
template<typename Container, unsigned long long flags = 0>
class PinIn An GPIO input pin, based on store variables.
This class comes in very handy when a GPIO input should be observed and overridden while debugging. It gives some interface between the hardware pin and the input that the application sees.
To use this class, add a scope to your store, like:
{ (bool) pin int8=-1 override bool input (bool) get } pinAll fields are optional. You can implement the store’s
pinfunction, override the virtualpin()function of the PinIn class, or pass the hardware pin value as an argument to the PinIn::operator().The pin basically does:
switch(override) { case -1: input = pin; break; case 0: input = false; break; case 1: input = true; break; case 2: input = !pin; break; }Then, instantiate the pin like this:
// Construct a compile-time object, which resolves all fields in your store. constexpr auto pin_o = stored::PinIn<stored::YourStore>::objects("/pin/"); // Instantiate an PinIn, tailored to the available fields in the store. stored::PinIn<stored::YourStore, pin_o.flags()> pin{pin_o, yourStore};When
pin()is called, it will invoke thepinfunction to get the actual hardware pin status. Then, it will set theinputvariable.The
getfunction is not used/provided by thisPinIn. Implement this store function such that it calls and returnspin(). When applications read thegetfunction, they will always get the appropriate/actual pin value.Public Functions
-
constexpr PinIn() noexcept = default
Default ctor.
Use this when initialization is postponed. You can assign another instance later on.
-
inline constexpr PinIn(PinInObjects<Container> const &o, Container &container)
Initialize the pin, given a list of objects and a container.
-
virtual ~PinIn() = default
Dtor.
-
template<char I = 'i', std::enable_if_t<Bound::template has<I>(), int> = 0>
inline bool input() const noexcept Return the last computed
inputvalue, or compute the pin state when the object is not available.
-
template<char I = 'i', std::enable_if_t<!Bound::template has<I>(), int> = 0>
inline bool input() noexcept Return the last computed
inputvalue, or compute the pin state when the object is not available.
-
inline decltype(auto) inputObject() const noexcept
Return the
inputobject.
-
inline decltype(auto) inputObject() noexcept
Return the
inputobject.
-
inline bool operator()() noexcept
Determine pin input, given the current hardware state.
-
inline bool operator()(bool pin) noexcept
Determine pin input, given the provided hardware state.
-
inline int8_t override_() const noexcept
Return the
overridevalue, or -1 when the object is not available.
-
inline decltype(auto) overrideObject() const noexcept
Return the
overrideobject.
-
inline decltype(auto) overrideObject() noexcept
Return the
overrideobject.
-
inline virtual bool pin() const noexcept
Return the hardware pin value.
By default, it calls the
pinfunction in the store. Override in a subclass to implement other behavior.
-
inline decltype(auto) pinObject() const noexcept
Return the
pinobject.
-
constexpr PinIn() noexcept = default
stored::PinOut
-
template<typename Container, unsigned long long flags = 0>
class PinOut An GPIO output pin, based on store variables.
This class comes in very handy when a GPIO output should be observed and overridden while debugging. It gives some interface between the hardware pin and the output that the application wants.
To use this class, add a scope to your store, like:
{ (bool) set bool output (int8) override (bool) pin } pinAll fields are optional, except
output. You can implement the store’spinfunction, override the virtualpin()function of the PinOut class, or forward the return value of PinOut::operator() to the hardware pin.The pin basically does:
switch(override) { case -1: pin = output; break; case 0: pin = false; break; case 1: pin = true; break; case 2: pin = !output; break; }Then, instantiate the pin like this:
// Construct a compile-time object, which resolves all fields in your store. constexpr auto pin_o = stored::PinOut<stored::YourStore>::objects("/pin/"); // Instantiate an PinOut, tailored to the available fields in the store. stored::PinOut<stored::YourStore, pin_o.flags()> pin{pin_o, yourStore};The
setfunction is not used/provided by thisPinOut. Implement this store function such that it callspin()with the provided value. When applications write thesetfunction, they will immediately control the hardware pin.Similar holds for the
overridefunction; implement it to call the override_() of PinOut. This way, if one sets the override value, the hardware pin is updated accordingly.Public Functions
-
constexpr PinOut() noexcept = default
Default ctor.
Use this when initialization is postponed. You can assign another instance later on.
-
inline constexpr PinOut(PinOutObjects<Container> const &o, Container &container)
Initialize the pin, given a list of objects and a container.
-
virtual ~PinOut() = default
Dtor.
-
inline bool operator()() noexcept
Compute and set the hardware pin status, given the last provided application’s output value.
-
inline bool operator()(bool output) noexcept
Compute and set the hardware pin status, given the application’s output value.
-
inline bool output() const noexcept
Return the
outputvalue.
-
inline decltype(auto) outputObject() const noexcept
Return the
outputobject.
-
inline decltype(auto) outputObject() noexcept
Return the
outputobject.
-
inline int8_t override_() const noexcept
Return the override value.
-
inline void override_(int8_t x) noexcept
Set the override value.
-
inline virtual void pin(bool value) noexcept
Set the hardware pin state.
The default implementation calls the store’s
pinfunction. Override in a subclass to implement custom behavior.
-
inline decltype(auto) pinObject() noexcept
Return the
pinobject.
-
constexpr PinOut() noexcept = default
stored::PulseWave
-
template<typename Container, unsigned long long flags = 0, typename T = float>
class PulseWave Pulse wave generator, based on store variables.
To use this class, add a scope to your store, like:
{ (float) sample frequency (Hz) float=1 amplitude float=1 frequency (Hz) float=0 phase (rad) float=0.5 duty cycle bool=true enable float=nan override float output } pulseOnly
sample frequencyis mandatory. All variables of typefloat, except forsample frequency, can be any other type, as long as it matches the template parameterT.When either
overrideoroutputis omitted, names may become ambiguous. In that case, provide the ids of the fields that are in the store, as template parameters to objects():field
id
sample frequency
samplitude
Afrequency
fphase
pduty cycle
denable
eoverride
Foutput
OThen, instantiate the controller like this:
// Construct a compile-time object, which resolves all fields in your store. constexpr auto pulse_o = stored::PulseWave<stored::YourStore>::objects("/pulse/"); // Instantiate the generator, tailored to the available fields in the store. stored::PulseWave<stored::YourStore, pulse_o.flags()> pulse{pulse_o, yourStore};Public Types
Public Functions
-
constexpr PulseWave() noexcept = default
Default ctor.
Use this when initialization is postponed. You can assign another instance later on.
-
inline constexpr PulseWave(PulseWaveObjects<Container, type> const &o, Container &container)
Initialize the pulse wave, given a list of objects and a container.
-
inline decltype(auto) amplitudeObject() const noexcept
Return the
amplitudeobject.
-
inline decltype(auto) amplitudeObject() noexcept
Return the
amplitudeobject.
-
inline void disable() noexcept
Disable the pulse wave.
Ignored when the
enableobject is not available.
-
inline decltype(auto) dutyCycleObject() const noexcept
Return the
duty cycleobject.
-
inline decltype(auto) dutyCycleObject() noexcept
Return the
duty cycleobject.
-
inline void enable(bool value = true) noexcept
Enable (or disable) the pulse wave.
Ignored when the
enableobject is not available.
-
inline bool enabled() const noexcept
Return the
enablevalue, ortruewhen not available.
-
inline decltype(auto) enableObject() const noexcept
Return the
enableobject.
-
inline decltype(auto) enableObject() noexcept
Return the
enableobject.
-
inline decltype(auto) frequencyObject() const noexcept
Return the
frequencyobject.
-
inline decltype(auto) frequencyObject() noexcept
Return the
frequencyobject.
-
inline bool isHealthy() const noexcept
Check numerical stability.
This function checks if for every control interval (1 / sampleFrequency()), the output is actually updated. Especially the period and phase values are checked if they are not too big.
You may want to check (or assert on) this function once in a while, like once per second or after every run, to detect a stuck controller within reasonable time for your application.
-
inline decltype(auto) outputObject() const noexcept
Return the
outputobject.
-
inline decltype(auto) outputObject() noexcept
Return the
outputobject.
-
inline decltype(auto) overrideObject() const noexcept
Return the
overrideobject.
-
inline decltype(auto) overrideObject() noexcept
Return the
overrideobject.
-
inline decltype(auto) phaseObject() const noexcept
Return the
phaseobject.
-
inline decltype(auto) phaseObject() noexcept
Return the
phaseobject.
-
inline float sampleFrequency() const noexcept
Return the sample frequency.
-
inline decltype(auto) sampleFrequencyObject() const noexcept
Return the
sample frequencyobject.
-
constexpr PulseWave() noexcept = default
stored::Ramp
-
template<typename Container, unsigned long long flags = 0, typename T = float>
class Ramp Ramping setpoints, based on store variables.
This is a quadratic path planner, that creates a smooth path from the current output towards the provided input. The speed and acceleration can be limited.
To use this class, add a scope to your store, like:
{ (float) sample frequency (Hz) float input float=inf speed limit float=inf acceleration limit bool reset bool=true enable float=nan override float output } rampOnly
sample frequencyis mandatory. All variables of typefloat, except forsample frequency, can be any other type, as long as it matches the template parameterT.Then, instantiate the controller like this:
// Construct a compile-time object, which resolves all fields in your store. constexpr auto ramp_o = stored::Ramp<stored::YourStore>::objects("/ramp/"); // Instantiate the generator, tailored to the available fields in the store. stored::Ramp<stored::YourStore, ramp_o.flags()> ramp{ramp_o, yourStore};The parameters can be changed while running (when
resetis set totrue). The change will be applied smoothly to the path.Public Types
-
using type_ = long
Public Functions
-
constexpr Ramp() noexcept = default
Default ctor.
Use this when initialization is postponed. You can assign another instance later on.
-
inline constexpr Ramp(RampObjects<Container, type> const &o, Container &container)
Initialize the ramp, given a list of objects and a container.
-
inline type accelerationLimit() const noexcept
Return the
acceleration limitvalue, or inf when not available.
-
inline decltype(auto) accelerationLimitObject() const noexcept
Return the
acceleration limitobject.
-
inline decltype(auto) accelerationLimitObject() noexcept
Return the
acceleration limitobject.
-
inline void disable() noexcept
Disable the pulse wave.
Ignored when the
enableobject is not available.
-
inline void enable(bool value = true) noexcept
Enable (or disable) the ramp.
Ignored when the
enableobject is not available.
-
inline bool enabled() const noexcept
Return the
enablevalue, ortruewhen not available.
-
inline decltype(auto) enableObject() const noexcept
Return the
enableobject.
-
inline decltype(auto) enableObject() noexcept
Return the
enableobject.
-
inline decltype(auto) inputObject() const noexcept
Return the
inputobject.
-
inline decltype(auto) inputObject() noexcept
Return the
inputobject.
-
inline bool isHealthy() const noexcept
Check numerical stability.
The Ramp is considered healthy when the configured acceleration and speed values are within the floating point precision.
You may want to check (or assert on) this function once in a while, like once per second or after every run, to detect a stuck ramp within reasonable time for your application.
-
inline decltype(auto) outputObject() const noexcept
Return the
outputobject.
-
inline decltype(auto) outputObject() noexcept
Return the
outputobject.
-
inline decltype(auto) overrideObject() const noexcept
Return the
overrideobject.
-
inline decltype(auto) overrideObject() noexcept
Return the
overrideobject.
-
inline bool reset() const noexcept
Return the
resetvalue, orfalsewhen not available.
-
inline decltype(auto) resetObject() const noexcept
Return the
resetobject.
-
inline decltype(auto) resetObject() noexcept
Return the
resetobject.
-
inline float sampleFrequency() const noexcept
Return the sample frequency.
-
inline decltype(auto) sampleFrequencyObject() const noexcept
Return the
sample frequencyobject.
-
inline decltype(auto) speedLimitObject() const noexcept
Return the
speed limitobject.
-
inline decltype(auto) speedLimitObject() noexcept
Return the
speed limitobject.
-
using type_ = long
stored::Sine
-
template<typename Container, unsigned long long flags = 0, typename T = float>
class Sine Sine wave generator, based on store variables.
To use this class, add a scope to your store, like:
{ (float) sample frequency (Hz) float=1 amplitude float=0.159 frequency (Hz) float=0 phase (rad) float=0 offset bool=true enable float=nan override float output } sineOnly
sample frequencyis mandatory. All variables of typefloat, except forsample frequency, can be any other type, as long as it matches the template parameterT.When either
overrideoroutputis omitted, names may become ambiguous. In that case, provide the ids of the fields that are in the store, as template parameters to objects():field
id
sample frequency
samplitude
Afrequency
fphase
poffset
oenable
eoverride
Foutput
OThen, instantiate the sine wave generator like this:
// Construct a compile-time object, which resolves all fields in your store. constexpr auto sine_o = stored::Sine<stored::YourStore>::objects("/sine/"); // Instantiate the generator, tailored to the available fields in the store. stored::Sine<stored::YourStore, sine_o.flags()> sine{sine_o, yourStore};When the parameters of the sine wave are changed while running, they are applied immediately, without a smooth transition.
Public Types
Public Functions
-
constexpr Sine() noexcept = default
Default ctor.
Use this when initialization is postponed. You can assign another instance later on.
-
inline constexpr Sine(SineObjects<Container, type> const &o, Container &container)
Initialize the sine, given a list of objects and a container.
-
inline decltype(auto) amplitudeObject() const noexcept
Return the
amplitudeobject.
-
inline decltype(auto) amplitudeObject() noexcept
Return the
amplitudeobject.
-
inline void disable() noexcept
Disable the sine wave.
Ignored when the
enableobject is not available.
-
inline void enable(bool value = true) noexcept
Enable (or disable) the sine wave.
Ignored when the
enableobject is not available.
-
inline bool enabled() const noexcept
Return the
enablevalue, ortruewhen not available.
-
inline decltype(auto) enableObject() const noexcept
Return the
enableobject.
-
inline decltype(auto) enableObject() noexcept
Return the
enableobject.
-
inline decltype(auto) frequencyObject() const noexcept
Return the
frequencyobject.
-
inline decltype(auto) frequencyObject() noexcept
Return the
frequencyobject.
-
inline bool isHealthy() const noexcept
Check numerical stability.
This function checks if for every control interval (1 / sampleFrequency()), the output is actually updated. Especially the period and phase values are checked if they are not too big.
You may want to check (or assert on) this function once in a while, like once per second or after every run, to detect a stuck controller within reasonable time for your application.
-
inline decltype(auto) offsetObject() const noexcept
Return the
offsetobject.
-
inline decltype(auto) offsetObject() noexcept
Return the
offsetobject.
-
inline decltype(auto) outputObject() const noexcept
Return the
outputobject.
-
inline decltype(auto) outputObject() noexcept
Return the
outputobject.
-
inline decltype(auto) overrideObject() const noexcept
Return the
overrideobject.
-
inline decltype(auto) overrideObject() noexcept
Return the
overrideobject.
-
inline decltype(auto) phaseObject() const noexcept
Return the
phaseobject.
-
inline decltype(auto) phaseObject() noexcept
Return the
phaseobject.
-
inline float sampleFrequency() const noexcept
Return the sample frequency.
-
inline decltype(auto) sampleFrequencyObject() const noexcept
Return the
sample frequencyobject.
-
constexpr Sine() noexcept = default