Robot Reflection System¶
This page explains the robot reflection system that automatically detects the connected hardware components and configures the robot accordingly.
Note
The robot reflection system will not detect hardware components if the emergency stop is pressed during boot because the power cut prevents the components from being detected.
The boot process¶
When the robot is powered on, the robot reflection system is run as a systemd service. It scans the connected hardware components for which plugins are installed, and configures the robot accordingly.
After the reflection process is performed, the module manager is started to launch all the applications. See The startup process of the robot and application management for more details.
How to re-run the robot reflection system¶
If you want to re-run the robot reflection system without rebooting the robot, you can use the following command:
pal module_manager restart --restart-reflection
Then the robot reflection system will be executed again, detecting the connected hardware and applying the necessary configurations. After that, the module manager will be restarted to relaunch all the applications with the new configuration.
If you just want to restart the robot reflection system without restarting the module manager, you can use the following command:
systemctl restart robot_reflection.service
How to check the detected hardware for the last boot¶
In order to check the logs of the robot reflection system, you can use the following command:
journalctl -u robot_reflection.service -b
How to disable robot reflection on boot¶
If you don’t want the robot reflection system to run on boot, you can disable the service by running the following command:
systemctl disable robot_reflection.service
Or you can export the following environment variable in the ~/.bashrc file:
export DISABLE_ROBOT_REFLECTION=1
How to re-enable robot reflection on boot¶
If you have previously disabled the robot reflection system service, you can re-enable it by running the following command:
systemctl enable robot_reflection.service
In case you have disabled it via the environment variable, just unset it by removing the
line from your ~/.bashrc file or set it to 0:
export DISABLE_ROBOT_REFLECTION=0
How to run manually¶
For running the robot reflection system manually, you can use the following command:
ros2 launch robot_reflection detect_hardware.py
with the following optional arguments:
verbose: To choose if you want more verbose output. Default is True.dry_run: Do not apply changes, only simulate. Default is False.plugin: To specify a particular plugin to run. Default is to run all available plugins.
Example:
ros2 launch robot_reflection detect_hardware.py verbose:=True dry_run:=True plugin:=pal_pro_gripper
How to create new plugins¶
For integrating new hardware components into the Robot Reflection framework, you must create a custom plugin.
A plugin must be a valid Python package containing a class that inherits from the
HardwareReflection base class.
The framework provides two base classes in robot_reflection.hardware_reflection:
HardwareReflection: Base class for all hardware reflection plugins.run(): Executes detection logic.get_robot_info(): Returns a dictionary of the detected info.get_default_robot_info(): Returns a dictionary of default info if hardware is not detected.detect_hardware(): Orchestrates the run/get cycle and handles errors.
HardwareReflectionCmd: An extension for plugins that rely on shell commands.run_cmd(...): Safely execute shell commands with timeouts.
Implementation step-by-step¶
Create a class that implements the required methods. Below is an example of a component named
dummy_component.
from typing import Dict from robot_reflection.hardware_reflection import HardwareReflectionCmd KEY = 'dummy_component' class DummyComponentReflection(HardwareReflectionCmd): def __init__(self): super().__init__() self.result = None def run(self) -> None: # execute logic or run shell commands cmd_result = self.run_cmd('echo "Dummy component detected"') self.result = cmd_result.stdout.strip() def get_robot_info(self) -> Dict: if self.result is None: raise RuntimeError('run() must be called before get_robot_info()') info = {} # Parse result and update dictionary if self.result == 'Dummy component detected': info[KEY] = True else: info[KEY] = False return info def get_default_robot_info(self) -> Dict: if self.result is None: raise RuntimeError('run() must be called before get_robot_info()') info = {} # Parse result and update dictionary if self.result == 'Dummy component detected': info[KEY] = True else: info[KEY] = False return info
Register the Plugin
To register the plugin, add an entry point in the
setup.pyfile of your package:entry_points={ 'robot_reflection.hardware': [ 'dummy_component = dummy_component_reflection.detect_dummy_component:DummyComponentReflection', ], }
3. Compile and source your package, and the robot reflection system will automatically detect and use your new plugin during its execution. You can test your plugin by running the robot reflection system manually as described above, specifying your plugin name if desired.