ShieldController Class

class automationshield.ShieldController(shield: BaseShield)[source]

Bases: object

The ShieldController class implements a controller interface for the various shield classes. This class should be subclassed to create custom controllers. In a subclass, overwrite the ShieldController.controller() method to implement your controller. Optionally, overwrite the ShieldController.variables() method to initialise instance variables that should persist beyond the scope of the controller method.

Example:

>>> class MyController(ShieldController):
...     def controller(self, t: float, dt: float, ref: float, pot: float, sensor: float) -> float:
...         return ref
Parameters:

shield (BaseShield) – shield class instance.

variables() None[source]

Define variables to be used by the controller or saved during the experiment.

Return type:

None

add_tracked_variable(name: str, size: int = 1) dict[str, int][source]

Add a variable to the list of variables whose value should be tracked during the experiment and returned afterwards. Variables should be instance variables of the class, otherwise they won’t be accessible!

Parameters:
  • name (str) – Name of the variable, without ‘self.’

  • size (int) – Size of the variable, e.g. 3 for a three-dimensional position vector. Defaults to 1, i.e. single values.

Returns:

A copy of the current map of tracked variables and their respective size.

Return type:

dict[str, int]

reference_callback(cntr: int, t: float, pot: float) int | float[source]

Calculate reference value. If used, this method is called every cycle to calculate a new reference. After implementing this method on a subclass of ShieldController, you can use it during an experiment as follows:

>>> my_controller = MyController(shield=shield)
>>> my_controller.run(freq=freq, cycles=cycles, ref=my_controller.reference_callback)

This implementation allows for multiple callback functions to be defined on the controller class or outside of it. It is not mandatory to override this specific method.

Parameters:
  • cntr (int) – Number of the current cycle.

  • t (float) – Time since start of experiment in seconds.

  • pot (float) – Potentiometer value in percent.

Returns:

Reference value.

Return type:

float

controller(t: float, dt: float, ref: int | float, pot: float, sensor: float) int | float[source]

Implement the controller here. You can subclass ShieldController and overwrite the controller.

Parameters:
  • t (float) – Time since start of run in seconds.

  • dt (float) – Length of current time step in seconds.

  • ref (float) – Reference value for the current step.

  • pot (float) – Potentiometer value in percent.

  • sensor (float) – Sensor value, calibrated if applicable.

Returns:

input value for actuator. the motor value will be saturated afterwards.

Return type:

float

run(freq: int | float, cycles: int | None = None, ref: int | float | Sequence[int | float] | Callable[[int, float, float], int | float] | Reference | None = None, live_plotter: LivePlotter | None = None) ndarray[tuple[int, ...], dtype[float64]][source]

Run the controller on a shield device.

You can stop the experiment at any time by pressing Ctrl-C. The experiment will exit gracefully and return the gathered data up to the point of the interrupt.

Parameters:
  • freq (int) – Desired frequency of the loop.

  • cycles (int) – Number of cycles to run the experiment. If ref is an array, cycles is optional and the length of the reference is used as the number of cycles. Defaults to None.

  • ref (float | int | Sequence[float | int] | Callable[[int, float, float], float], Type[Reference], optional) – The reference to follow. It can be an array, a single value (i.e. constant reference) or a function or class to be called in each cycle. If it’s an array, it should have a length equal to freq * cycles. See the documentation for ShieldController.reference_callback() on how to define a callback function. A class should expose a __call__() method, whose signature must match that of a callback function, like in ~automationshield.controller.Reference. The class doesn’t need to inherit from ~automationshield.controller.reference. Defaults to None, in which case the reference is set to 0.

  • live_plotter (LivePlotter, optional) – Optional LivePlotter instance to use for displaying a live plot, defaults to None.

Returns:

Experiment data. The columns of the array are time, reference, potentiometer, sensor, actuator, and any additional variables in the order they were added.

Return type:

npt.NDArray[np.float64]