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{&amp, 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 >

Public Types

typedef Base_ Base
typedef Implementation_ Implementation

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

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::store or stored::store_t. Alternatively, use STORE_T(...) instead, providing the template parameters of stored::store as macro arguments.

See also

stored::ExampleControlData

Subclassed by stored::ExampleControlDefaultFunctions< ExampleControlBase< ExampleControl > >

Public Types

enum [anonymous]

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.

typedef Implementation_ Implementation

Type of the actual implementation, which is the (lowest) subclass.

typedef uintptr_t Key

Type of a key.

See also

bufferToKey()

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 self for stored::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) noexcept

Calls a callback for every object in the longDirectory().

See also

stored::list()

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

stored::list()

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

stored::list()

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 constexpr 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 constexpr 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.