control
Store definition
// SPDX-FileCopyrightText: 2020-2023 Jochem Rutgers
//
// SPDX-License-Identifier: CC0-1.0
(float) frequency (Hz)
{
	float[10] x
} interconnect
{
	// Control frequency
	(float) frequency (Hz)
	// Inputs
	float y
	float setpoint
	bool=true enable
	// Coefficients
	float=0.5 Kp
	float=0.25 Ti (s)
	float=0.05 Td (s)
	float=0 Kff
	// Ti integrator
	float=0 int
	float=-inf int low
	float=inf int high
	// Bounds on the output
	float=0 low
	float=1 high
	float=inf epsilon
	// Misc control
	bool=true reset
	float=nan override
	// Output
	float u
	// Interconnections
	uint8=0 evaluation order
	int8=2 x setpoint
	int8=5 x y
	int8=3 x u
} pid
{
	float input
	bool=true enable
	float=2 gain
	float=-0.1 offset
	float=-inf low
	float=inf high
	float=nan override
	float output
	// Interconnections
	uint8=1 evaluation order
	int8=3 x input
	int8=4 x output
} amp
{
	(float) sample frequency (Hz)
	float=1 amplitude
	float=0.02 frequency (Hz)
	float=0 phase (rad)
	bool=true enable
	float=nan override
	float output
	// Interconnections
	uint8=0 evaluation order
	int8=0 x output
} sine
{
	(float) sample frequency (Hz)
	float=1 amplitude
	float=0.159 frequency (Hz)
	float=0 phase (rad)
	float=0.25 duty cycle
	bool=true enable
	float=nan override
	float output
	// Interconnections
	uint8=0 evaluation order
	int8=0 x duty cycle
	int8=1 x output
} pulse
{
	(float) sample frequency (Hz)
	float input
	float=0.2 cutoff frequency (Hz)
	bool=true enable
	bool reset
	float=nan override
	float output
	// Interconnections
	uint8=0 evaluation order
	int8=4 x input
	int8=5 x output
} lowpass
{
	(float) sample frequency (Hz)
	float input
	float=0.5 speed limit
	float=0.05 acceleration limit
	bool reset
	bool=true enable
	float=nan override
	float output
	// Interconnections
	uint8=0 evaluation order
	int8=1 x input
	int8=2 x output
} ramp
Application
// SPDX-FileCopyrightText: 2020-2023 Jochem Rutgers
//
// SPDX-License-Identifier: CC0-1.0
/*!
 * \file
 * \brief libstored's control example.
 *
 * This example instantiates several control related components.  All inputs
 * and output are mapped onto <tt>/interconnect/x</tt>, and this mapping can be
 * changed dynamically.  This allows you to play around with the sequence of
 * the components.
 *
 * The default configuration is:
 *
 * - sine wave sets the duty cycle of pulse
 * - pulse via ramp as setpoint to PID
 * - PID output via amplifier and lowpass filter to PID input
 *
 * C++14 is required for this example, as stored/components.h requires it.
 */
#include "ExampleControl.h"
#include <stored>
#include <chrono>
#include <iostream>
#include <utility>
class ExampleControlStore : public STORE_T(ExampleControlStore, stored::ExampleControlBase) {
	STORE_CLASS(ExampleControlStore, stored::ExampleControlBase)
public:
	ExampleControlStore() = default;
	// You can change the control frequency dynamically.
	void __frequency_Hz(bool set, float& value)
	{
		if(!set) {
			value = m_frequency_Hz;
		} else {
			m_frequency_Hz = std::max(0.1f, value);
			pid__reset = true;
			lowpass__reset = true;
			ramp__reset = true;
		}
	}
	void __pid__frequency_Hz(bool set, float& value)
	{
		if(!set)
			value = frequency_Hz.get();
		else
			frequency_Hz = value;
	}
	void __sine__sample_frequency_Hz(bool set, float& value)
	{
		if(!set)
			value = frequency_Hz.get();
		else
			frequency_Hz = value;
	}
	void __pulse__sample_frequency_Hz(bool set, float& value)
	{
		if(!set)
			value = frequency_Hz.get();
		else
			frequency_Hz = value;
	}
	void __lowpass__sample_frequency_Hz(bool set, float& value)
	{
		if(!set)
			value = frequency_Hz.get();
		else
			frequency_Hz = value;
	}
	void __ramp__sample_frequency_Hz(bool set, float& value)
	{
		if(!set)
			value = frequency_Hz.get();
		else
			frequency_Hz = value;
	}
private:
	float m_frequency_Hz{10.0f};
};
static ExampleControlStore store;
using value_type = decltype(std::declval<ExampleControlStore>().interconnect__x_0.get());
static void pid()
{
	constexpr auto pid_o = stored::PID<ExampleControlStore>::objects("/pid/");
	static stored::PID<ExampleControlStore, pid_o.flags()> pid_v{pid_o, store};
	auto x_setpoint = store.interconnect__x_a(store.pid__x_setpoint.get());
	if(x_setpoint.valid())
		store.pid__setpoint = x_setpoint.get<value_type>();
	auto x_y = store.interconnect__x_a(store.pid__x_y.get());
	if(x_y.valid())
		store.pid__y = x_y.get<value_type>();
	auto u = pid_v();
	if(!pid_v.isHealthy())
		std::cout << "/pid not healthy" << std::endl;
	auto x_u = store.interconnect__x_a(store.pid__x_u.get());
	if(x_u.valid())
		x_u.set(u);
}
static void amp()
{
	constexpr auto amp_o = stored::Amplifier<ExampleControlStore>::objects("/amp/");
	static stored::Amplifier<ExampleControlStore, amp_o.flags()> amp_v{amp_o, store};
	auto x_input = store.interconnect__x_a(store.amp__x_input.get());
	if(x_input.valid())
		store.amp__input = x_input.get<value_type>();
	auto output = amp_v();
	auto x_output = store.interconnect__x_a(store.amp__x_output.get());
	if(x_output.valid())
		x_output.set(output);
}
static void sine()
{
	constexpr auto sine_o = stored::Sine<ExampleControlStore>::objects("/sine/");
	static stored::Sine<ExampleControlStore, sine_o.flags()> sine_v{sine_o, store};
	auto y = sine_v();
	if(!sine_v.isHealthy())
		std::cout << "/sine not healthy" << std::endl;
	auto x_output = store.interconnect__x_a(store.sine__x_output.get());
	if(x_output.valid())
		x_output.set(y);
}
static void pulse()
{
	constexpr auto pulse_o = stored::PulseWave<ExampleControlStore>::objects("/pulse/");
	static stored::PulseWave<ExampleControlStore, pulse_o.flags()> pulse_v{pulse_o, store};
	auto x_duty_cycle = store.interconnect__x_a(store.pulse__x_duty_cycle.get());
	if(x_duty_cycle.valid())
		store.pulse__duty_cycle = x_duty_cycle.get<value_type>();
	auto y = pulse_v();
	if(!pulse_v.isHealthy())
		std::cout << "/pulse not healthy" << std::endl;
	auto x_output = store.interconnect__x_a(store.pulse__x_output.get());
	if(x_output.valid())
		x_output.set(y);
}
static void lowpass()
{
	constexpr auto lowpass_o = stored::LowPass<ExampleControlStore>::objects("/lowpass/");
	static stored::LowPass<ExampleControlStore, lowpass_o.flags()> lowpass_v{lowpass_o, store};
	auto x_input = store.interconnect__x_a(store.lowpass__x_input.get());
	if(x_input.valid())
		store.lowpass__input = x_input.get<value_type>();
	auto output = lowpass_v();
	auto x_output = store.interconnect__x_a(store.lowpass__x_output.get());
	if(x_output.valid())
		x_output.set(output);
}
static void ramp()
{
	constexpr auto ramp_o = stored::Ramp<ExampleControlStore>::objects("/ramp/");
	static stored::Ramp<ExampleControlStore, ramp_o.flags()> ramp_v{ramp_o, store};
	auto x_input = store.interconnect__x_a(store.ramp__x_input.get());
	if(x_input.valid())
		store.ramp__input = x_input.get<value_type>();
	auto output = ramp_v();
	if(!ramp_v.isHealthy())
		std::cout << "/ramp not healthy" << std::endl;
	auto x_output = store.interconnect__x_a(store.ramp__x_output.get());
	if(x_output.valid())
		x_output.set(output);
}
static void control()
{
	using f_type = std::pair<void (*)(), stored::Variable<uint8_t, ExampleControlStore>>;
	static std::array<f_type, 6> fs = {{
		f_type{&pid, store.pid__evaluation_order},
		f_type{&, store.amp__evaluation_order},
		f_type{&sine, store.sine__evaluation_order},
		f_type{&pulse, store.pulse__evaluation_order},
		f_type{&lowpass, store.lowpass__evaluation_order},
		f_type{&ramp, store.ramp__evaluation_order},
	}};
	std::stable_sort(fs.begin(), fs.end(), [](f_type const& a, f_type const& b) {
		return a.second.get() < b.second.get();
	});
	for(auto const& f : fs)
		f.first();
}
int main()
{
	printf("Dynamically change the interconnections between the components\n");
	printf("by modifying the /<component>/x <variable>.\n");
	// Construct the protocol stack.
	stored::Debugger debugger{"control"};
	debugger.map(store);
	stored::DebugZmqLayer zmqLayer;
	if((errno = zmqLayer.lastError())) {
		printf("Cannot initialize ZMQ layer; %s (error %d)\n", zmq_strerror(errno), errno);
		exit(1);
	}
	zmqLayer.wrap(debugger);
	stored::Poller poller;
	stored::PollableZmqLayer pollableZmq(zmqLayer, stored::Pollable::PollIn);
	if((errno = poller.add(pollableZmq))) {
		printf("Cannot add to poller; %s (error %d)\n", zmq_strerror(errno), errno);
		exit(1);
	}
	auto t = std::chrono::system_clock::now();
	while(true) {
		auto now = std::chrono::system_clock::now();
		auto rem = std::chrono::duration_cast<std::chrono::microseconds>(t - now);
		auto rem_us = rem.count();
		if(rem_us <= 0) {
			t += std::chrono::milliseconds(
				(long long)(1.0e3f / store.frequency_Hz.get()));
			// This is where the magic takes place.
			control();
			continue;
		}
		if(poller.poll(std::max<int>(0, (int)(rem_us / 1000L))).empty()) {
			switch(errno) {
			case EINTR:
			case EAGAIN:
				break;
			default:
				perror("Cannot poll");
				exit(1);
			} // else timeout
		} else if((errno = zmqLayer.recv())) {
			printf("Cannot recv; %s (error %d)\n", zmq_strerror(errno), errno);
			exit(1);
		}
	}
}
Store reference
- 
template<typename Base_, typename Implementation_>
class ExampleControlObjects All ExampleControlBase’s objects.
Subclassed by stored::ExampleControlBase< ExampleControlStore >, stored::ExampleControlBase< ExampleControl >, stored::ExampleControlBase< QExampleControl >
Public Members
- 
impl::StoreVariable<Base, Implementation, bool, 105u, 1> amp__enable
 amp/enable
- 
impl::StoreVariable<Base, Implementation, uint8_t, 106u, 1> amp__evaluation_order
 amp/evaluation order
- 
impl::StoreVariable<Base, Implementation, float, 32u, 4> amp__gain
 amp/gain
- 
impl::StoreVariable<Base, Implementation, float, 44u, 4> amp__high
 amp/high
- 
impl::StoreVariable<Base, Implementation, float, 184u, 4> amp__input
 amp/input
- 
impl::StoreVariable<Base, Implementation, float, 40u, 4> amp__low
 amp/low
- 
impl::StoreVariable<Base, Implementation, float, 36u, 4> amp__offset
 amp/offset
- 
impl::StoreVariable<Base, Implementation, float, 188u, 4> amp__output
 amp/output
- 
impl::StoreVariable<Base, Implementation, float, 48u, 4> amp__override
 amp/override
- 
impl::StoreVariable<Base, Implementation, int8_t, 107u, 1> amp__x_input
 amp/x input
- 
impl::StoreVariable<Base, Implementation, int8_t, 108u, 1> amp__x_output
 amp/x output
- 
impl::StoreFunction<Base, Implementation, ExampleControlFunctionMap, 1u> frequency_Hz
 frequency (Hz)
- 
impl::StoreVariable<Base, Implementation, float, 120u, 4> interconnect__x_0
 interconnect/x[0]
- 
impl::StoreVariable<Base, Implementation, float, 124u, 4> interconnect__x_1
 interconnect/x[1]
- 
impl::StoreVariable<Base, Implementation, float, 128u, 4> interconnect__x_2
 interconnect/x[2]
- 
impl::StoreVariable<Base, Implementation, float, 132u, 4> interconnect__x_3
 interconnect/x[3]
- 
impl::StoreVariable<Base, Implementation, float, 136u, 4> interconnect__x_4
 interconnect/x[4]
- 
impl::StoreVariable<Base, Implementation, float, 140u, 4> interconnect__x_5
 interconnect/x[5]
- 
impl::StoreVariable<Base, Implementation, float, 144u, 4> interconnect__x_6
 interconnect/x[6]
- 
impl::StoreVariable<Base, Implementation, float, 148u, 4> interconnect__x_7
 interconnect/x[7]
- 
impl::StoreVariable<Base, Implementation, float, 152u, 4> interconnect__x_8
 interconnect/x[8]
- 
impl::StoreVariable<Base, Implementation, float, 156u, 4> interconnect__x_9
 interconnect/x[9]
- 
impl::StoreVariable<Base, Implementation, float, 80u, 4> lowpass__cutoff_frequency_Hz
 lowpass/cutoff frequency (Hz)
- 
impl::StoreVariable<Base, Implementation, bool, 112u, 1> lowpass__enable
 lowpass/enable
- 
impl::StoreVariable<Base, Implementation, uint8_t, 230u, 1> lowpass__evaluation_order
 lowpass/evaluation order
- 
impl::StoreVariable<Base, Implementation, float, 208u, 4> lowpass__input
 lowpass/input
- 
impl::StoreVariable<Base, Implementation, float, 212u, 4> lowpass__output
 lowpass/output
- 
impl::StoreVariable<Base, Implementation, float, 84u, 4> lowpass__override
 lowpass/override
- 
impl::StoreVariable<Base, Implementation, bool, 229u, 1> lowpass__reset
 lowpass/reset
- 
impl::StoreFunction<Base, Implementation, ExampleControlFunctionMap, 5u> lowpass__sample_frequency_Hz
 lowpass/sample frequency (Hz)
- 
impl::StoreVariable<Base, Implementation, int8_t, 113u, 1> lowpass__x_input
 lowpass/x input
- 
impl::StoreVariable<Base, Implementation, int8_t, 114u, 1> lowpass__x_output
 lowpass/x output
- 
impl::StoreVariable<Base, Implementation, bool, 100u, 1> pid__enable
 pid/enable
- 
impl::StoreVariable<Base, Implementation, float, 24u, 4> pid__epsilon
 pid/epsilon
- 
impl::StoreVariable<Base, Implementation, uint8_t, 224u, 1> pid__evaluation_order
 pid/evaluation order
- 
impl::StoreFunction<Base, Implementation, ExampleControlFunctionMap, 2u> pid__frequency_Hz
 pid/frequency (Hz)
- 
impl::StoreVariable<Base, Implementation, float, 20u, 4> pid__high
 pid/high
- 
impl::StoreVariable<Base, Implementation, float, 172u, 4> pid__int
 pid/int
- 
impl::StoreVariable<Base, Implementation, float, 16u, 4> pid__int_high
 pid/int high
- 
impl::StoreVariable<Base, Implementation, float, 12u, 4> pid__int_low
 pid/int low
- 
impl::StoreVariable<Base, Implementation, float, 168u, 4> pid__Kff
 pid/Kff
- 
impl::StoreVariable<Base, Implementation, float, 0u, 4> pid__Kp
 pid/Kp
- 
impl::StoreVariable<Base, Implementation, float, 176u, 4> pid__low
 pid/low
- 
impl::StoreVariable<Base, Implementation, float, 28u, 4> pid__override
 pid/override
- 
impl::StoreVariable<Base, Implementation, bool, 101u, 1> pid__reset
 pid/reset
- 
impl::StoreVariable<Base, Implementation, float, 164u, 4> pid__setpoint
 pid/setpoint
- 
impl::StoreVariable<Base, Implementation, float, 8u, 4> pid__Td_s
 pid/Td (s)
- 
impl::StoreVariable<Base, Implementation, float, 4u, 4> pid__Ti_s
 pid/Ti (s)
- 
impl::StoreVariable<Base, Implementation, float, 180u, 4> pid__u
 pid/u
- 
impl::StoreVariable<Base, Implementation, int8_t, 102u, 1> pid__x_setpoint
 pid/x setpoint
- 
impl::StoreVariable<Base, Implementation, int8_t, 104u, 1> pid__x_u
 pid/x u
- 
impl::StoreVariable<Base, Implementation, int8_t, 103u, 1> pid__x_y
 pid/x y
- 
impl::StoreVariable<Base, Implementation, float, 160u, 4> pid__y
 pid/y
- 
impl::StoreVariable<Base, Implementation, float, 64u, 4> pulse__amplitude
 pulse/amplitude
- 
impl::StoreVariable<Base, Implementation, float, 72u, 4> pulse__duty_cycle
 pulse/duty cycle
- 
impl::StoreVariable<Base, Implementation, bool, 110u, 1> pulse__enable
 pulse/enable
- 
impl::StoreVariable<Base, Implementation, uint8_t, 227u, 1> pulse__evaluation_order
 pulse/evaluation order
- 
impl::StoreVariable<Base, Implementation, float, 68u, 4> pulse__frequency_Hz
 pulse/frequency (Hz)
- 
impl::StoreVariable<Base, Implementation, float, 204u, 4> pulse__output
 pulse/output
- 
impl::StoreVariable<Base, Implementation, float, 76u, 4> pulse__override
 pulse/override
- 
impl::StoreVariable<Base, Implementation, float, 200u, 4> pulse__phase_rad
 pulse/phase (rad)
- 
impl::StoreFunction<Base, Implementation, ExampleControlFunctionMap, 4u> pulse__sample_frequency_Hz
 pulse/sample frequency (Hz)
- 
impl::StoreVariable<Base, Implementation, int8_t, 228u, 1> pulse__x_duty_cycle
 pulse/x duty cycle
- 
impl::StoreVariable<Base, Implementation, int8_t, 111u, 1> pulse__x_output
 pulse/x output
- 
impl::StoreVariable<Base, Implementation, float, 92u, 4> ramp__acceleration_limit
 ramp/acceleration limit
- 
impl::StoreVariable<Base, Implementation, bool, 115u, 1> ramp__enable
 ramp/enable
- 
impl::StoreVariable<Base, Implementation, uint8_t, 232u, 1> ramp__evaluation_order
 ramp/evaluation order
- 
impl::StoreVariable<Base, Implementation, float, 216u, 4> ramp__input
 ramp/input
- 
impl::StoreVariable<Base, Implementation, float, 220u, 4> ramp__output
 ramp/output
- 
impl::StoreVariable<Base, Implementation, float, 96u, 4> ramp__override
 ramp/override
- 
impl::StoreVariable<Base, Implementation, bool, 231u, 1> ramp__reset
 ramp/reset
- 
impl::StoreFunction<Base, Implementation, ExampleControlFunctionMap, 6u> ramp__sample_frequency_Hz
 ramp/sample frequency (Hz)
- 
impl::StoreVariable<Base, Implementation, float, 88u, 4> ramp__speed_limit
 ramp/speed limit
- 
impl::StoreVariable<Base, Implementation, int8_t, 116u, 1> ramp__x_input
 ramp/x input
- 
impl::StoreVariable<Base, Implementation, int8_t, 117u, 1> ramp__x_output
 ramp/x output
- 
impl::StoreVariable<Base, Implementation, float, 52u, 4> sine__amplitude
 sine/amplitude
- 
impl::StoreVariable<Base, Implementation, bool, 109u, 1> sine__enable
 sine/enable
- 
impl::StoreVariable<Base, Implementation, uint8_t, 225u, 1> sine__evaluation_order
 sine/evaluation order
- 
impl::StoreVariable<Base, Implementation, float, 56u, 4> sine__frequency_Hz
 sine/frequency (Hz)
- 
impl::StoreVariable<Base, Implementation, float, 196u, 4> sine__output
 sine/output
- 
impl::StoreVariable<Base, Implementation, float, 60u, 4> sine__override
 sine/override
- 
impl::StoreVariable<Base, Implementation, float, 192u, 4> sine__phase_rad
 sine/phase (rad)
- 
impl::StoreFunction<Base, Implementation, ExampleControlFunctionMap, 3u> sine__sample_frequency_Hz
 sine/sample frequency (Hz)
- 
impl::StoreVariable<Base, Implementation, int8_t, 226u, 1> sine__x_output
 sine/x output
- 
impl::StoreVariable<Base, Implementation, bool, 105u, 1> amp__enable
 
- 
template<typename Implementation_>
class ExampleControlBase : public stored::ExampleControlObjects<ExampleControlBase<Implementation_>, Implementation_> Base class with default interface of all ExampleControl implementations.
Although there are no virtual functions in the base class, subclasses can override them. The (lowest) subclass must pass the
Implementation_template paramater to its base, such that all calls from the base class can be directed to the proper overridden implementation.The base class cannot be instantiated. If a default implementation is required, which does not have side effects to functions, instantiate stored::ExampleControl. This class contains all data of all variables, so it can be large. So, be aware when instantiating it on the stack. Heap is fine. Static allocations is fine too, as the constructor and destructor are trivial.
To inherit the base class, you can use the following template:
class ExampleControl : public stored::store<ExampleControl, ExampleControlBase>::type { STORE_CLASS(ExampleControl, ExampleControlBase) public: // Your class implementation, such as: ExampleControl() is_default // ... };Some compilers or tools may get confused by the inheritance using
stored::storeorstored::store_t. Alternatively, useSTORE_T(...)instead, providing the template parameters ofstored::storeas macro arguments.See also
See also
stored::ExampleControlData
Public Types
Values:
- 
enumerator ObjectCount
 Number of objects in the store.
- 
enumerator VariableCount
 Number of variables in the store.
- 
enumerator FunctionCount
 Number of functions in the store.
- 
enumerator BufferSize
 Buffer size.
- 
enumerator ObjectCount
 
- 
typedef Implementation_ Implementation
 Type of the actual implementation, which is the (lowest) subclass.
- 
typedef uintptr_t Key
 Type of a key.
See also
- 
typedef Map<String::type, Variant<Implementation>>::type ObjectMap
 Map as generated by map().
- 
typedef ExampleControlObjects<ExampleControlBase, Implementation_> Objects
 
- 
typedef ExampleControlBase root
 We are the root, as used by
STORE_CLASS.
- 
typedef ExampleControlBase self
 Define
selfforstored::store.
Public Functions
- 
inline ~ExampleControlBase()
 
- 
void __frequency_Hz(bool set, float &value)
 Callback for frequency (Hz)
- 
void __lowpass__sample_frequency_Hz(bool set, float &value)
 Callback for lowpass/sample frequency (Hz)
- 
void __pid__frequency_Hz(bool set, float &value)
 Callback for pid/frequency (Hz)
- 
void __pulse__sample_frequency_Hz(bool set, float &value)
 Callback for pulse/sample frequency (Hz)
- 
void __ramp__sample_frequency_Hz(bool set, float &value)
 Callback for ramp/sample frequency (Hz)
- 
void __sine__sample_frequency_Hz(bool set, float &value)
 Callback for sine/sample frequency (Hz)
- 
inline Key bufferToKey(void const *buffer) const noexcept
 Converts a variable’s buffer to a key.
A key is unique for all variables of the same store, but identical for the same variables across different instances of the same store class. Therefore, the key can be used to synchronize between instances of the same store. A key does not contain meta data, such as type or length. It is up to the synchronization library to make sure that these properties are handled well.
For synchronization, when hookEntryX() or hookEntryRO() is invoked, one can compute the key of the object that is accessed. The key can be used, for example, in a key-to-Variant map. When data arrives from another party, the key can be used to find the proper Variant in the map.
This way, data exchange is type-safe, as the Variant can check if the data format matches the expected type. However, one cannot process data if the key is not set yet in the map.
- 
inline Type::type bufferToType(void const *buffer) noexcept
 Return the type of the variable, given its buffer.
- 
inline Variant<Implementation> find(char const *name, size_t len = std::numeric_limits<size_t>::max()) noexcept
 Finds an object with the given name.
- Returns:
 the object, or an invalid stored::Variant if not found.
- 
template<typename T>
inline Function<T, Implementation> function(char const *name, size_t len = std::numeric_limits<size_t>::max()) noexcept Finds a function with the given name.
The function, when it exists, must have the given (fixed) type.
- 
inline Implementation const &implementation() const noexcept
 Returns the reference to the implementation.
- 
inline Implementation &implementation() noexcept
 Returns the reference to the implementation.
- 
inline Variant<Implementation> interconnect__x_a(int a) noexcept
 Array-lookup accessor for interconnect/x[a].
- 
template<typename F>
inline void list(F f, void *arg, char const *prefix, String::type *nameBuffer) noexcept Calls a callback for every object in the longDirectory().
See also
- 
template<typename F>
inline void list(F f, void *arg, char const *prefix = nullptr) noexcept Calls a callback for every object in the longDirectory().
See also
- 
inline uint8_t const *longDirectory() const noexcept
 Retuns the long directory.
When not available, the short directory is returned.
- 
inline ObjectMap map(char const *prefix = nullptr)
 Create a name to Variant map for the store.
Generating the map may be expensive and the result is not cached.
- 
inline char const *name() const noexcept
 Returns the name of store, which can be used as prefix for stored::Debugger.
- 
inline uint8_t const *shortDirectory() const noexcept
 Returns the short directory.
- 
template<typename T>
inline Variable<T, Implementation> variable(char const *name, size_t len = std::numeric_limits<size_t>::max()) noexcept Finds a variable with the given name.
The variable, when it exists, must have the given (fixed) type.
Public Members
- 
impl::StoreVariable<Base, Implementation, bool, 105u, 1> amp__enable
 amp/enable
- 
impl::StoreVariable<Base, Implementation, uint8_t, 106u, 1> amp__evaluation_order
 amp/evaluation order
- 
impl::StoreVariable<Base, Implementation, float, 32u, 4> amp__gain
 amp/gain
- 
impl::StoreVariable<Base, Implementation, float, 44u, 4> amp__high
 amp/high
- 
impl::StoreVariable<Base, Implementation, float, 184u, 4> amp__input
 amp/input
- 
impl::StoreVariable<Base, Implementation, float, 40u, 4> amp__low
 amp/low
- 
impl::StoreVariable<Base, Implementation, float, 36u, 4> amp__offset
 amp/offset
- 
impl::StoreVariable<Base, Implementation, float, 188u, 4> amp__output
 amp/output
- 
impl::StoreVariable<Base, Implementation, float, 48u, 4> amp__override
 amp/override
- 
impl::StoreVariable<Base, Implementation, int8_t, 107u, 1> amp__x_input
 amp/x input
- 
impl::StoreVariable<Base, Implementation, int8_t, 108u, 1> amp__x_output
 amp/x output
- 
impl::StoreFunction<Base, Implementation, ExampleControlFunctionMap, 1u> frequency_Hz
 frequency (Hz)
- 
impl::StoreVariable<Base, Implementation, float, 120u, 4> interconnect__x_0
 interconnect/x[0]
- 
impl::StoreVariable<Base, Implementation, float, 124u, 4> interconnect__x_1
 interconnect/x[1]
- 
impl::StoreVariable<Base, Implementation, float, 128u, 4> interconnect__x_2
 interconnect/x[2]
- 
impl::StoreVariable<Base, Implementation, float, 132u, 4> interconnect__x_3
 interconnect/x[3]
- 
impl::StoreVariable<Base, Implementation, float, 136u, 4> interconnect__x_4
 interconnect/x[4]
- 
impl::StoreVariable<Base, Implementation, float, 140u, 4> interconnect__x_5
 interconnect/x[5]
- 
impl::StoreVariable<Base, Implementation, float, 144u, 4> interconnect__x_6
 interconnect/x[6]
- 
impl::StoreVariable<Base, Implementation, float, 148u, 4> interconnect__x_7
 interconnect/x[7]
- 
impl::StoreVariable<Base, Implementation, float, 152u, 4> interconnect__x_8
 interconnect/x[8]
- 
impl::StoreVariable<Base, Implementation, float, 156u, 4> interconnect__x_9
 interconnect/x[9]
- 
impl::StoreVariable<Base, Implementation, float, 80u, 4> lowpass__cutoff_frequency_Hz
 lowpass/cutoff frequency (Hz)
- 
impl::StoreVariable<Base, Implementation, bool, 112u, 1> lowpass__enable
 lowpass/enable
- 
impl::StoreVariable<Base, Implementation, uint8_t, 230u, 1> lowpass__evaluation_order
 lowpass/evaluation order
- 
impl::StoreVariable<Base, Implementation, float, 208u, 4> lowpass__input
 lowpass/input
- 
impl::StoreVariable<Base, Implementation, float, 212u, 4> lowpass__output
 lowpass/output
- 
impl::StoreVariable<Base, Implementation, float, 84u, 4> lowpass__override
 lowpass/override
- 
impl::StoreVariable<Base, Implementation, bool, 229u, 1> lowpass__reset
 lowpass/reset
- 
impl::StoreFunction<Base, Implementation, ExampleControlFunctionMap, 5u> lowpass__sample_frequency_Hz
 lowpass/sample frequency (Hz)
- 
impl::StoreVariable<Base, Implementation, int8_t, 113u, 1> lowpass__x_input
 lowpass/x input
- 
impl::StoreVariable<Base, Implementation, int8_t, 114u, 1> lowpass__x_output
 lowpass/x output
- 
impl::StoreVariable<Base, Implementation, bool, 100u, 1> pid__enable
 pid/enable
- 
impl::StoreVariable<Base, Implementation, float, 24u, 4> pid__epsilon
 pid/epsilon
- 
impl::StoreVariable<Base, Implementation, uint8_t, 224u, 1> pid__evaluation_order
 pid/evaluation order
- 
impl::StoreFunction<Base, Implementation, ExampleControlFunctionMap, 2u> pid__frequency_Hz
 pid/frequency (Hz)
- 
impl::StoreVariable<Base, Implementation, float, 20u, 4> pid__high
 pid/high
- 
impl::StoreVariable<Base, Implementation, float, 172u, 4> pid__int
 pid/int
- 
impl::StoreVariable<Base, Implementation, float, 16u, 4> pid__int_high
 pid/int high
- 
impl::StoreVariable<Base, Implementation, float, 12u, 4> pid__int_low
 pid/int low
- 
impl::StoreVariable<Base, Implementation, float, 168u, 4> pid__Kff
 pid/Kff
- 
impl::StoreVariable<Base, Implementation, float, 0u, 4> pid__Kp
 pid/Kp
- 
impl::StoreVariable<Base, Implementation, float, 176u, 4> pid__low
 pid/low
- 
impl::StoreVariable<Base, Implementation, float, 28u, 4> pid__override
 pid/override
- 
impl::StoreVariable<Base, Implementation, bool, 101u, 1> pid__reset
 pid/reset
- 
impl::StoreVariable<Base, Implementation, float, 164u, 4> pid__setpoint
 pid/setpoint
- 
impl::StoreVariable<Base, Implementation, float, 8u, 4> pid__Td_s
 pid/Td (s)
- 
impl::StoreVariable<Base, Implementation, float, 4u, 4> pid__Ti_s
 pid/Ti (s)
- 
impl::StoreVariable<Base, Implementation, float, 180u, 4> pid__u
 pid/u
- 
impl::StoreVariable<Base, Implementation, int8_t, 102u, 1> pid__x_setpoint
 pid/x setpoint
- 
impl::StoreVariable<Base, Implementation, int8_t, 104u, 1> pid__x_u
 pid/x u
- 
impl::StoreVariable<Base, Implementation, int8_t, 103u, 1> pid__x_y
 pid/x y
- 
impl::StoreVariable<Base, Implementation, float, 160u, 4> pid__y
 pid/y
- 
impl::StoreVariable<Base, Implementation, float, 64u, 4> pulse__amplitude
 pulse/amplitude
- 
impl::StoreVariable<Base, Implementation, float, 72u, 4> pulse__duty_cycle
 pulse/duty cycle
- 
impl::StoreVariable<Base, Implementation, bool, 110u, 1> pulse__enable
 pulse/enable
- 
impl::StoreVariable<Base, Implementation, uint8_t, 227u, 1> pulse__evaluation_order
 pulse/evaluation order
- 
impl::StoreVariable<Base, Implementation, float, 68u, 4> pulse__frequency_Hz
 pulse/frequency (Hz)
- 
impl::StoreVariable<Base, Implementation, float, 204u, 4> pulse__output
 pulse/output
- 
impl::StoreVariable<Base, Implementation, float, 76u, 4> pulse__override
 pulse/override
- 
impl::StoreVariable<Base, Implementation, float, 200u, 4> pulse__phase_rad
 pulse/phase (rad)
- 
impl::StoreFunction<Base, Implementation, ExampleControlFunctionMap, 4u> pulse__sample_frequency_Hz
 pulse/sample frequency (Hz)
- 
impl::StoreVariable<Base, Implementation, int8_t, 228u, 1> pulse__x_duty_cycle
 pulse/x duty cycle
- 
impl::StoreVariable<Base, Implementation, int8_t, 111u, 1> pulse__x_output
 pulse/x output
- 
impl::StoreVariable<Base, Implementation, float, 92u, 4> ramp__acceleration_limit
 ramp/acceleration limit
- 
impl::StoreVariable<Base, Implementation, bool, 115u, 1> ramp__enable
 ramp/enable
- 
impl::StoreVariable<Base, Implementation, uint8_t, 232u, 1> ramp__evaluation_order
 ramp/evaluation order
- 
impl::StoreVariable<Base, Implementation, float, 216u, 4> ramp__input
 ramp/input
- 
impl::StoreVariable<Base, Implementation, float, 220u, 4> ramp__output
 ramp/output
- 
impl::StoreVariable<Base, Implementation, float, 96u, 4> ramp__override
 ramp/override
- 
impl::StoreVariable<Base, Implementation, bool, 231u, 1> ramp__reset
 ramp/reset
- 
impl::StoreFunction<Base, Implementation, ExampleControlFunctionMap, 6u> ramp__sample_frequency_Hz
 ramp/sample frequency (Hz)
- 
impl::StoreVariable<Base, Implementation, float, 88u, 4> ramp__speed_limit
 ramp/speed limit
- 
impl::StoreVariable<Base, Implementation, int8_t, 116u, 1> ramp__x_input
 ramp/x input
- 
impl::StoreVariable<Base, Implementation, int8_t, 117u, 1> ramp__x_output
 ramp/x output
- 
impl::StoreVariable<Base, Implementation, float, 52u, 4> sine__amplitude
 sine/amplitude
- 
impl::StoreVariable<Base, Implementation, bool, 109u, 1> sine__enable
 sine/enable
- 
impl::StoreVariable<Base, Implementation, uint8_t, 225u, 1> sine__evaluation_order
 sine/evaluation order
- 
impl::StoreVariable<Base, Implementation, float, 56u, 4> sine__frequency_Hz
 sine/frequency (Hz)
- 
impl::StoreVariable<Base, Implementation, float, 196u, 4> sine__output
 sine/output
- 
impl::StoreVariable<Base, Implementation, float, 60u, 4> sine__override
 sine/override
- 
impl::StoreVariable<Base, Implementation, float, 192u, 4> sine__phase_rad
 sine/phase (rad)
- 
impl::StoreFunction<Base, Implementation, ExampleControlFunctionMap, 3u> sine__sample_frequency_Hz
 sine/sample frequency (Hz)
- 
impl::StoreVariable<Base, Implementation, int8_t, 226u, 1> sine__x_output
 sine/x output
Public Static Functions
- 
template<typename T>
static inline FreeFunction<T, Implementation> freeFunction(char const *name, size_t len = std::numeric_limits<size_t>::max()) noexcept Finds a function with the given name.
The function, when it exists, must have the given (fixed) type. It is returned as a free function; it is not bound yet to a specific store instance. This function is constexpr for C++14.
- 
template<typename T>
static inline FreeVariable<T, Implementation> freeVariable(char const *name, size_t len = std::numeric_limits<size_t>::max()) noexcept Finds a variable with the given name.
The variable, when it exists, must have the given (fixed) type. It is returned as a free variable; it is not bound yet to a specific store instance. This function is constexpr for C++14.
- 
static inline constexpr char const *hash() noexcept
 Returns a unique hash of the store.
Friends
- friend class impl::StoreFunction
 
- friend class impl::StoreVariable
 
- friend class impl::StoreVariantF
 
- friend class impl::StoreVariantV
 
- friend class stored::FreeVariable
 
- friend class stored::Variant< void >
 
- 
class ExampleControl : public stored::ExampleControlDefaultFunctions<ExampleControlBase<ExampleControl>>
 Default ExampleControlBase implementation.
Public Functions
- 
ExampleControl() = default
 Default constructor.
- 
ExampleControl() = default