Porting to v2.10 ================ Version 2.10 introduces a few significant changes to the XBot2 framework, i.e.: - **Joint device management:** versions prior to v2.10 included a component named *JointMaster*, which would act as a centralized authority for communicating with all joint devices at once, sitting in the middle between *RobotInterface* objects, and the HAL. Notably, safety policies and filtering used to be integrated at the *JointMaster* layer. Starting from version v2.10, *RobotInterface* objects communicate directly with the HAL layer, therefore simplifying the information flow by removing the hidden man-in-the-middle. - **Customizable safety system:** since safety is no longer managed at the (hidden) *JointMaster* layer, it needs to explicitly be handler by the developer implementing the HAL interface for the robot or simulator. XBot2 now provides the ``XBot::Hal::JointSafety`` object, which takes care of enforcing safety policies as well as filtering, in a customizable way (via callbacks) which is also integrated with the rest of the framrework. - **Safety-aware plugins:** thanks to the above mentioned integration, plugins are now safety aware. By default, all plugins are aborted whenever the safety system is triggered. Users can override this behavior by providing their own implementation of `XBot::ControlPlugin::on_safety_triggered`. - **Resource management system:** prior to version v2.10, no check was performed to understand whether two or more plugins were commanding the same device at the same time, possibly leading to conflicts, and undesired behavior. Starting from v2.10, XBot2 provides a built-in resource management system. The simplest highest-level API is implemented inside the usual `XBot::RobotInterface::setControlMode` set of functions. Plugins can leverage on this API to implement simple, safe policies such as refusing to start if a resource conflict is detected. - **Serialization support:** for internal topics, services, parameters. This allows to interact with XBot2's internal intra-process communicacion system in a YAML-based, type-free fashion. - **Dedicated Safety API:** to check if filters are enabled, their cutoff frequency, etc What actions do I need to take? ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 1. **Rename safety-related parameters:** in the main configuration file, inside the ``xbotcore_param`` field: - ``/jm/tx_filter_autostart:`` becomes ``/xbot/hal/joint_device/filter_autostart`` - ``/jm/tx_filter_cutoff:`` becomes ``/xbot/hal/joint_device/filter_cutoff_hz`` - ``/jm/enable_safety`` becomes ``/xbot/hal/enable_safety`` - it is possible to customize the cutoff frequency for the three profiles *safe*, *medium*, and *fast*, via the parameter ``/xbot/hal/joint_safety/filter__cutoff_hz`` For example: .. code-block:: yaml xbotcore_param: /xbot/hal/joint_safety/filter_autostart: {value: true, type: bool} /xbot/hal/joint_safety/filter_cutoff_hz: {value: 2.0, type: double} /xbot/hal/enable_safety: {value: true, type: bool} 2. **Declare joint resources:** inside the ``on_initialize`` function of your control plugin, you can call ``setDefaultControlMode`` to declare what joint resources your plugin will need upon execution. If the declared resources are not available upon plugin start, the start command is discarded and an error appears on the terminal. Closing the plugin who is holding the contended resources will fix the issue. For example: .. code-block:: c++ bool MyPlugin::on_initialize() { // your own initialization logic // prior to version 2.10, it was customary to set the robot's // control mode once and for all, as follows: // _robot->setControlMode(ControlMode::Position()); // from 2.10 onwards, we need to declare the required resources // with a different API, as in the following example: // all joints use position references setDefaultControlMode(ControlMode::Position()); // override wheels std::map wheel_ctrl_map; wheel_ctrl_map["wheel_1"] = ControlMode::Velocity(); wheel_ctrl_map["wheel_2"] = ControlMode::Velocity(); setDefaultControlMode(wheel_ctrl_map); return true; } If you forget to do so, calling ``robot->move()`` will not have any effect. 3. **Handling safety events:** control plugins are now safety aware, and the default reaction is to abort on a safety triggered event. If you wish to change this behavior, you need to override the ``on_safety_triggered`` virtual method: .. code-block:: c++ void MyPlugin::on_safety_triggered() { // no op jinfo("safety triggered: ignoring"); } 4. **Using the Safety API** to check its status as in the following example; note that this API is currently *NOT* real-time safe .. code-block:: c++ #include auto safety_status = Hal::JointSafety::status(); // note: not real-time safe! jinfo("safety enabled: {}", safety_status.safety_enabled); jinfo("filter enabled: {}", safety_status.filter_enabled); jinfo("filter cutoff : {} Hz", safety_status.cutoff_hz); 5. **Update HAL drivers** to use the new ``Hal::JointSafety`` component, which is the new way to enforce safety policies. Reaction to safety events can be customized via callbacks. Developers with source code access can check `this (internal) example `_. 6. **Update signature for HAL device constructors** to accept an additional parameter as follows. *Note: developers only!* .. code-block:: c++ /* device driver, device client */ // old signature // MyDevice(Hal::DeviceInfo dinfo); // new signature MyDevice(Hal::DeviceInfo dinfo, const Hal::Device::CommonParams& params); /* device containers */ // old signature // MyDeviceContainer(std::vector dinfo); // new signature MyDeviceContainer(std::vector dinfo, const Hal::Device::CommonParams& params);