.. raw:: html

Already familiar with the Bota Control Toolkit?

Explore directly its components.

Driver Filters Payload Utilities Transformation Utilities

First time here?

Continue reading to learn about its architecture

-------- Bota Control Toolkit Architecture ============ Bota Systems has developed a unified control architecture for force control applications, enabling seamless integration and coordination of various control components, such as hardware drivers, signal filters, kinematics and dynamics utilities, etc. All the components included in the control toolkit follow the design pattern of the so called ``Bota Control Block`` described in the next section :ref:`bota_control_block`. This design pattern ensures that all control blocks have a consistent interface and behavior, making it easier to integrate them as shown in the latter section :ref:`bundled_controller_pipeline`, as well as to implement extensive error handling strategies across the whole control pipeline, as described in the last section :ref:`error_handling`. .. _bota_control_block: Bota Control Block ----------------- The blocks are implemented as objects to be used in OOP-frameworks. They are structured around three main elemennts: - **Instantiation**: The block is instantiated as an object of the corresponding class. It acepts a configuration in the form of a JSON file. - **In-line Configuration**: If certain parameters can be changed later on, the block provides methods to update them at configuration time (static configuration) and/or at runtime (dynamic configuration). - **Runtime Update**: The block provides an update method that performs the desired algorithm. This will be called in a loop at runtime. This method must return a code that indicates the status of the performed step, which can be used to implement the desired error handling strategy. Runtime Update """""""""""""""" Depending on the specific functionality of the blocks, the following signatures are allowed for the **Runtime Update** method: - **Input/Output blocks**: These blocks have an update method that accepts a reference to an input signal and writes the output signal to a passed reference. The signature of the update method is as follows: ``return_code = block.update(input_signal, output_signal)`` This signature is used for example in the blocks in **Bota Payload Utilities** and **Bota TF Utilities**, where the input and output signals are of different nature. .. figure:: /_static/images/io_block.png :alt: Input/Output block architecture :align: center :width: 800px Input/Output block architecture - **Inplace blocks**: These blocks have an update method that accepts a reference to an input signal and updates it in-place. The signature of the update method is as follows: ``return_code = block.updateInplace(signal)`` This signature is used for example in the blocks in **Bota Filters**, where the input and output signals are of the same nature, and the block performs a filtering operation on the input signal to produce the output signal. .. figure:: /_static/images/inplace_block.png :alt: In-place block architecture :align: center :width: 800px In-place block architecture - **Observer blocks**: These blocks have an update method that accepts a reference to an measurement signal and produces a state estimate, written to the corresponding referenced variable. The signature of the update method is as follows: ``return_code = block.updateObserver(measurement, state_estimate)`` This signature is used for example in the blocks in **Bota Observers**. - **Controller blocks**: These blocks have an update method that accepts a reference to a reference and to a state estimate signal and produces a control action, written to the corresponding referenced variable. The signature of the update method is as follows: ``return_code = block.updateController(reference, state_estimate, control_action)`` This signature is used for example in the blocks in **Bota Controllers**. .. _bundled_controller_pipeline: Wiring Controller Pipeline ----------------- When working in an OOP-framework, such as Python or C++, the ``Bota Control Block`` can be easily chained together to create a bundled control pipeline, where the output of one block is fed as input to the next block in the chain. .. code-block:: python ################################################# ## EXAMPLE OF A BUNDLED CONTROL PIPELINE USING THE BOTA CONTROL BLOCKS ## ################################################# ## Signal variable allocation signal_1 signal_2 signal_3 ## Instantiation & Configuration at initialization time block_1 = Block1(config_1) # input/output block block_2 = Block2(config_2) # in-place block block_3 = Block3(config_3) # input/output block ## Block in-line static configuration block_1.set_parameter(value) block_2.set_parameter(value) block_3.set_parameter(value) ## RUNTIME LOOP while running: # Block in-line dynamic configuration block_1.set_parameter(value) block_2.set_parameter(value) block_3.set_parameter(value) # Update the blocks and use the signals return_code1 = block_1.update(signal_1, signal_2) # -> signal_2 freshly updated by block_1 algorithm can be used HERE return_code2 = block_2.updateInplace(signal_2) # -> signal_2 freshly updated by block_2 algorithm can be used HERE return_code3 = block_3.update(signal_2, signal_3) # -> signal_3 freshly updated by block_3 algorithm can be used HERE # Timed-loop sleep(0.01) # 100 Hz .. figure:: /_static/images/wired_blocks.png :alt: Wired block architecture :align: center :width: 800px Example of a wired control pipeline using the Bota Control Blocks Given the structure of a bundle controller pipeline, it can be wrapped in a higher level class that also follows the ``Bota Control Block`` design pattern, this allows to create blocks that already encapsulate complex functionality directly out-of-the-self. This meta-blocks can be easily used and integrated in the user code. .. _error_handling: Error handling ----------------- As described before, the update methods of the blocks must return a code that indicates the **status of the performed step**. This status return code must be **monitored at runtime** to implement the desired error handling strategy, which is crucial to ensure the robustness and safety of the control system. Return Codes """""""""""""""" The following :ok:`OK`, :warning:`WARNING` and :error:`ERROR` **return codes** are defined: - :ok:`OK`: The block executed successfully and produced a valid output. - :warning:`Stale`: The block executed successfully but the produced output is stale, e.g. the input data is too old or the sensor is not responding. - :warning:`Degraded`: The block executed successfully but the produced output is degraded, i.e. reduced quality or confidence. - :error:`NonFatalError`: The block encountered an internal error that can be recoverable by reset. - :error:`FatalError`: The block encountered an unrecoverable error. Control Policy """""""""""""""" The blocks can be configured to react differently to the different conditions/events depending on the desired **control policy**, which can be one of the following: - **Best-effort**: Taking longer than budgeted does not raise a warning. If the input data is stale or degraded, the block will return a warning code. Recoverable and unrecoverable error are differentiated. - **Soft RT**: Identical to best-effort, but taking longer than budgeted raises a DeadlineMissed warning. - **Hard RT**: Taking longer than budgeted and degraded output raise a FatalError. Stale input still raise a warning. - **Strict RT**: Any condition different from OK raises a FatalError. The control policy choice depends on the specific requirements of the application and the desired level of robustness and safety. The following table summarizes the different conditions/events and the corresponding return codes for each control policy: .. list-table:: :header-rows: 1 :widths: 25 20 20 15 15 * - **CONDITION/POLICY** - **Best effort** - **Soft RT** - **Hard RT** - **Strict RT** * - **Deadline missed** - :ok:`OK` - :warning:`DeadlineMissed` - :error:`FatalError` - :error:`FatalError` * - **Not-updated Input** - :warning:`Stale` - :warning:`Stale` - :warning:`Stale` - :error:`FatalError` * - **Degraded Output** - :warning:`Degraded` - :warning:`Degraded` - :error:`FatalError` - :error:`FatalError` * - **Internal Error** - :error:`NonFatalError` - :error:`NonFatalError` - :error:`FatalError` - :error:`FatalError` * - **Fatal** - :error:`FatalError` - :error:`FatalError` - :error:`FatalError` - :error:`FatalError` Loop Reaction """""""""""""""" The bundled control pipeline must **react to the return codes**: - In case of :ok:`OK`, continue the normal execution of the control pipeline. - In case of :warning:`WARNING`, raise an alert and continue the execution of the control pipeline, but monitor the situation closely and consider taking corrective actions if the condition persists. - In case of :error:`NonFatalError`, attempt to reset the block or take corrective actions to recover from the error, while raising an alert to notify the issue. - In case of :error:`FatalError`, immediately stop the execution of the control pipeline and take necessary safety measures to prevent any potential harm or damage, while raising an alert to notify the issue. ------- Implementations ------- This block logic is implemented for each of the available programming languages, for which the **Bota Control Toolkit** solutions are offered. .. raw:: html

Explore the Bota Control Block implementations

Choose your development platform

C++ Python ROS2
.. toctree:: :maxdepth: 2 :caption: "Bota Control Toolkit Documentation" :hidden: C++ Python ROS2