From 19270aa7790fe67657a326542b6e23fad7a2dfff Mon Sep 17 00:00:00 2001 From: Moritz Schmidt Date: Fri, 21 Nov 2025 10:19:53 +0100 Subject: [PATCH] docs: fix readme format --- README.md | 171 +++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 143 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 37430f9..9fc4443 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,21 @@ -Video explanation of its implemntation and how to use can be found [here](https://youtu.be/iEiZje8imeU?si=3jsBkv6SsXmHkQpW). # ModbusHardwareInterface + +Video explanation of its implementation and how to use can be found on +[YouTube](https://youtu.be/iEiZje8imeU?si=3jsBkv6SsXmHkQpW). + If you not familiar with `ros2_control.xacro` check the [section at the end](#mini-urdf-and-xacro-introduction). + ## Using ModbusHardwareInterface in ros2_control.xacro -In this files we define the hardware components like the servo, linear actuator and proximity sensor. You can see there which component (plugin) is used and how the component is configured. -Let's make an example: If we want to use the `ModbusHardwareInterface` in our project we can create a `my_example_hw.ros2_control.xacro`. In this file we define the used implementation with the `...` tag: +In this files we define the hardware components like the servo, linear actuator +and proximity sensor. You can see there which component (plugin) is used and how +the component is configured. + +Let's make an example: If we want to use the `ModbusHardwareInterface` in our +project we can create a `my_example_hw.ros2_control.xacro`. In this file we +define the used implementation with the `...` tag: + +```xml number_of_register*2 @@ -40,10 +57,12 @@ To define a command or state interface you have to supply following parameters f for converting to modbus ``` + **StateInterface:** -``` + +```xml - umber_of_register*2 + number_of_register*2 number of bits to read/register size how to convert from modbus int to double what modbus type @@ -51,34 +70,112 @@ To define a command or state interface you have to supply following parameters f or converting from modbus ``` -#### Available xml parameters: -The `ModbusHardwareInterface` supports the following parameters to configure how a StateInterface acquires its value from modbus or how a CommandInterface writes its value to modbus. + +### Full Example + +```xml + + + + + modbus_hardware_interface/ModbusHardwareInterface + $(modbus_server_ip) + ${modbus__server_port) + $(modbus_use_persistent_connection} + + + + 3 + 32 + to_int_to_modbus + + register + ${409600 / 0.005} # ticks per revolution / screw pitch in mm + + + 7 + 32 + to_int_to_float + register + 0.00587 # 9A / 1533 + + + + + +``` + +#### Available xml parameters + +The `ModbusHardwareInterface` supports the following parameters to configure how +a StateInterface acquires its value from modbus or how a CommandInterface writes +its value to modbus. + ##### register (mandatory) -Register number. Defines which register is requester for reading or writing. Check data sheet of your hardware for reference. + +Register number. Defines which register is requester for reading or writing. +Check data sheet of your hardware for reference. + ##### bits_to_read (mandatory) -How many bits we read/write when accessing this modbus register. For registers this needs to be the register size and a multiple of `sizeof(uint_16t)`. If the register is not a multiple of 16, which is the underlying modbus int size, this could be problematic. For bit it says how many bits are read/written in one call. + +How many bits we read/write when accessing this modbus register. For registers +this needs to be the register size and a multiple of `sizeof(uint_16t)`. If the +register is not a multiple of 16, which is the underlying modbus int size, this +could be problematic. For bit it says how many bits are read/written in one +call. + ##### conversion_fn -For reading: This maps to a function which is used to convert from uint_16t (register) or uint_8t (bits) used in modbus to double used in ros2_control. You can check the modbus [library](https://libmodbus.org/reference/) to see which functions are available and the implementations in [modbus_client.hpp](https://github.com/StoglRobotics/modbus_hardware_interface/blob/master/include/modbus_hardware_interface/modbus_client.hpp). If you need some special conversion you have to implement.\ -For writing: This maps to a function which is used to convert from double to uint_16t (register) or uint_8t (bits). + +For reading: This maps to a function which is used to convert from `uint_16t` +(register) or `uint_8t` (bits) used in modbus to `double` used in ros2_control. You +can check the modbus [library](https://libmodbus.org/reference/) to see which +functions are available and the implementations in +[modbus_client.hpp](https://github.com/StoglRobotics/modbus_hardware_interface/blob/master/include/modbus_hardware_interface/modbus_client.hpp). +If you need some special conversion you have to implement. +For writing: This maps to a function which is used to convert from double to +`uint_16t` (register) or `uint_8t` (bits). + ##### read_function/write_function (mandatory) -read_function is for StatateIntefaces only, write_functions for CommandInterfaces only. \ -We distinguish between reading a register or single bits. This is done by setting the *read_function/write_function*: + +read_function is for StatateIntefaces only, write_functions for +CommandInterfaces only. We distinguish between reading a register or single +bits. This is done by setting the *read_function/write_function*: + * register -> read/write register * input_register -> used for read only registers * bits -> read/write bits * input_bits -> read only bits + ##### factor and offset -Used for converting from the special modbus datatype to double. This is different then a conversion from uint_8t/uint_16 to double. With the conversion_fn we just convert from uint_8tuint_16 to double. For example the consider the position StateInterface is given in ticks but we want to provide a position in m in our StateInterface. Therefore we have to convert the double we receive by simply converting from modbus to double further. Therefore we supply the options of giving a factor and offset-> factor*converted_uint_16+offset.\ -The same is for the conversion from ros2_control double -> modbus uint_16 true. -## Using ModbusHardwareInterface in ros2_control.xacro +Used for converting from the special modbus datatype to double. This is +different then a conversion from `uint_8t`/ `uint_16` to `double`. With the +`conversion_fn` we just convert from `uint_8t`/`uint_16` to double. For example, the +position StateInterface is given in `ticks` but we want to provide a +position in `m` in our StateInterface. Therefore we have to convert the `double` we +receive by simply converting from modbus to double further. Therefore we supply +the options of giving a factor and $offset \rightarrow factor \cdot uint16_{converted} + offset$. +The same applies for the conversion from `ros2_control double -> modbus uint_16 true`. + +## Custom ModbusHardwareInterface in ros2_control.xacro + If you need a custom HardwareInterface you first have to inherit from the `ModbusHardwareInterface`: -``` + +```cpp class MyServo : public modbus_hardware_interface::ModbusHardwareInterface ``` -then override the functions you need some custom actions. Important! Don't forget to call the `ModbusHardwareInterface` functions in your implementations e.g. for: `on_init`, `read`, `write` like this -``` +then override the functions you need some custom actions. Important! Don't +forget to call the `ModbusHardwareInterface` functions in your implementations +e.g. for: `on_init`, `read`, `write` like this + +```cpp hardware_interface::CallbackReturn ServoHardwareInterface::on_init( const hardware_interface::HardwareInfo & info) { @@ -89,7 +186,8 @@ hardware_interface::CallbackReturn ServoHardwareInterface::on_init( ... } ``` -``` + +```cpp hardware_interface::return_type ServoHardwareInterface::read( const rclcpp::Time & time, const rclcpp::Duration & period) { @@ -101,16 +199,33 @@ hardware_interface::return_type ServoHardwareInterface::read( ..... } ``` -If you do not call those the modbus specific parameters in `ros2_control.xacro` will not be parsed and the StateInterfaces will not be read or CommandInterfaces be written. + +If you do not call those the modbus specific parameters in `ros2_control.xacro` +will not be parsed and the StateInterfaces will not be read or CommandInterfaces +be written. # Mini URDF and Xacro introduction + ## URDF -URDF, Unified Robot Description Format is an XML format for representing a robot model. URDF is commonly used in Robot Operating System (ROS) tools such as rviz (Ros Visualization tool) and Gazebo simulator. The model consists of links and joints motion. + +URDF, Unified Robot Description Format is an XML format for representing a robot +model. URDF is commonly used in Robot Operating System (ROS) tools such as rviz +(Ros Visualization tool) and Gazebo simulator. The model consists of links and +joints motion. + ## [Xacro](https://github.com/ros/xacro/wiki) -Xacro is an XML macro language and preprocessor that is typically used to simplify the generation of URDF files. However, it can be applied to any XML. Using parameterizable macros, re-occurring XML blocks can be created with a few commands only. + +Xacro is an XML macro language and preprocessor that is typically used to +simplify the generation of URDF files. However, it can be applied to any XML. +Using parameterizable macros, re-occurring XML blocks can be created with a few +commands only. + ## ros2_control.xacro + Check the [control docs](https://control.ros.org/rolling/doc/getting_started/getting_started.html#hardware-description-in-urdf) + # References + * [https://docs.ros.org/en/rolling/Tutorials/Intermediate/URDF/URDF-Main.html](https://docs.ros.org/en/rolling/Tutorials/Intermediate/URDF/URDF-Main.html) * [https://github.com/ros/xacro/wiki](https://github.com/ros/xacro/wiki) * [https://wiki.ros.org/xacro](https://wiki.ros.org/xacro)