Ignition with ros2_control

### Ignition with ros2_control internals

continue to [Let's try Ignition Fortress](https://qiita.com/tomoyafujita/items/e3873608019d55cca250), just wanted to comprehend the architecture and design `how it works` for Ignition with [ros2_control](https://github.com/ros-controls/ros2_control).

#### Build and Run [ign_ros2_control](https://github.com/ignitionrobotics/ign_ros2_control/tree/main)

- Install `ros:galactic` on ubuntu:20.04, see [Installing ROS 2 via Debian Packages](https://docs.ros.org/en/galactic/Installation/Ubuntu-Install-Debians.html)

- Build [ign_ros2_control](https://github.com/ignitionrobotics/ign_ros2_control/tree/main)

```bash
# source ros:galactic env
source /opt/ros/galactic/setup.bash

# build sample colcon workspace
export IGNITION_VERSION=fortress
mkdir -p ~/ros_ign/src
cd ~/ros_ign/src
git clone https://github.com/ignitionrobotics/ign_ros2_control
rosdep install -r --from-paths . --ignore-src --rosdistro $ROS_DISTRO -y
cd ~/ros2_ign
colcon build
```

- Run [ign_ros2_control](https://github.com/ignitionrobotics/ign_ros2_control/tree/main)

```
ros2 launch ign_ros2_control_demos cart_example_velocity.launch.py
...
ros2 run ign_ros2_control_demos example_velocity
...
```

#### Architecture / Design

![ros2_control architecture](http://control.ros.org/_images/components_architecture.png)

this is ros2_control framework overview, as we can see user needs to develop `Controller`, `Interface` and `Plugin` such as Sensor, System and Actuator to integrate with ros2_control.

#### Implementation Detail

from ros2_control perspective, Ignition is one of `System` hardware object. `IgnitionSystem` possesses `IgnitionSystemInterface` inherited from `hardware_interface::SystemInterface`.
in other words, Ignition is just a hardware to control and plugged in to ros2_control.

we can refer to the implementation as below.

https://github.com/ignitionrobotics/ign_ros2_control/tree/main/ign_ros2_control


![ign_ros2_control_sample_velocity.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112819/1f8bdab1-51f3-c3f0-e255-787b00ec6938.png)

then sending velocity messages via `/velocity_controller/commands` topic to `/velocity_controller` to write the data `IgnitionSystem` joint `slider_to_cart`.

https://github.com/ignitionrobotics/ign_ros2_control/blob/2214047e95fac1cf3c70a4b7650e1612efa02bf7/ign_ros2_control_demos/urdf/test_cart_velocity.xacro.urdf#L114-L139

```urdf
  <ros2_control name="IgnitionSystem" type="system">
    <hardware>
      <plugin>ign_ros2_control/IgnitionSystem</plugin>
    </hardware>
    <joint name="slider_to_cart">
      <command_interface name="velocity">
        <param name="min">-15</param>
        <param name="max">15</param>
      </command_interface>
      <state_interface name="position"/>
      <state_interface name="velocity"/>
      <state_interface name="effort"/>
    </joint>

```

`IgnitionROS2ControlPlugin` is one of the `Ignition Gazebo System` plugin library.
It provides callback methods such as `Configure`, `PreUpdate` and `PostUpdate`.

- `Configure` will be called during initialization. in this plugin, it will read URDF from parameter server and instantiate ros2_control `ControllerManager` with parameters.
- `PreUpdate` will be called before modify state before physics runs. It calls `controller_manager_->write` that leads to `IgnitionSystem::write` to update `ignition::gazebo::components`.
- `PreUpdate` is mapped to `IgnitionSystem::read`.

### Reference

- https://github.com/ignitionrobotics/ros_ign
- https://github.com/ignitionrobotics/ign_ros2_control