2023-03-12 23:18:29 -03:00
# Testing with DDS/micro-Ros
## Architecture
2023-05-23 12:54:29 -03:00
Ardupilot contains the DDS Client library, which can run as SITL. Then, the DDS application runs a ROS2 node, an EProsima Integration Service, and the MicroXRCE Agent. The two systems communicate can communicate over serial or UDP.
```mermaid
---
title: UDP Loopback
---
graph LR
subgraph Linux Computer
subgraph Ardupilot SITL
veh[sim_vehicle.py] < -- > xrceClient[EProsima Micro XRCE DDS Client]
xrceClient < -- > port1[udp:2019]
end
subgraph DDS Application
ros[ROS2 Node] < -- > agent[Micro ROS Agent]
agent < -- > port1[udp:2019]
end
loopback
end
```
2023-03-12 23:18:29 -03:00
```mermaid
---
title: Hardware Serial Port Loopback
---
graph LR
subgraph Linux Computer
subgraph Ardupilot SITL
veh[sim_vehicle.py] < -- > xrceClient[EProsima Micro XRCE DDS Client]
xrceClient < -- > port1[devUSB1]
end
subgraph DDS Application
ros[ROS2 Node] < -- > agent[Micro ROS Agent]
agent < -- > port2[devUSB2]
end
port1 < -- > port2
end
```
## Installing Build Dependencies
While DDS support in Ardupilot is mostly through git submodules, another tool needs to be available on your system: Micro XRCE DDS Gen.
2023-03-26 13:07:20 -03:00
- Go to a directory on your system to clone the repo (perhaps next to `ardupilot` )
- Install java
2023-03-12 23:18:29 -03:00
```console
2023-03-26 13:07:20 -03:00
sudo apt install default-jre
2023-03-12 23:18:29 -03:00
````
2023-04-14 14:32:52 -03:00
- Follow instructions [here ](https://micro-xrce-dds.docs.eprosima.com/en/latest/installation.html#installing-the-micro-xrce-dds-gen-tool ) to install the latest version of the generator using Ardupilot's mirror
2023-03-12 23:18:29 -03:00
```console
2023-04-14 14:32:52 -03:00
git clone --recurse-submodules https://github.com/ardupilot/Micro-XRCE-DDS-Gen.git
2023-03-12 23:18:29 -03:00
cd Micro-XRCE-DDS-Gen
./gradlew assemble
```
2023-05-23 12:54:29 -03:00
- Add the generator directory to $PATH.
2023-03-26 13:07:20 -03:00
```console
# Add this to ~/.bashrc
export PATH=$PATH:/your/path/to/Micro-XRCE-DDS-Gen/scripts
```
- Test it
2023-03-12 23:18:29 -03:00
```console
cd /path/to/ardupilot
microxrceddsgen -version
# openjdk version "11.0.18" 2023-01-17
# OpenJDK Runtime Environment (build 11.0.18+10-post-Ubuntu-0ubuntu122.04)
# OpenJDK 64-Bit Server VM (build 11.0.18+10-post-Ubuntu-0ubuntu122.04, mixed mode, sharing)
# microxrceddsgen version: 1.0.0beta2
```
> :warning: **If you have installed FastDDS or FastDDSGen globally on your system**:
eProsima's libraries and the packaging system in Ardupilot are not determistic in this scenario.
You may experience the wrong version of a library brought in, or runtime segfaults.
For now, avoid having simultaneous local and global installs.
If you followed the [global install ](https://fast-dds.docs.eprosima.com/en/latest/installation/sources/sources_linux.html#global-installation )
section, you should remove it and switch to local install.
2023-05-23 12:54:29 -03:00
### Serial Only: Set up serial for SITL with DDS
2023-03-12 23:18:29 -03:00
2023-03-27 11:05:51 -03:00
On Linux, creating a virtual serial port will be necessary to use serial in SITL, because of that install socat.
2023-03-12 23:18:29 -03:00
```
sudo apt-get update
sudo apt-get install socat
```
2023-03-27 11:05:51 -03:00
## Setup ardupilot for SITL with DDS
2023-03-12 23:18:29 -03:00
Set up your [SITL ](https://ardupilot.org/dev/docs/setting-up-sitl-on-linux.html ).
2023-05-23 12:54:29 -03:00
Run the simulator with the following command. If using UDP, the only parameter you need to set it `DDS_ENABLE` .
2023-03-27 11:05:51 -03:00
| Name | Description |
| - | - |
2023-04-24 02:13:32 -03:00
| DDS_ENABLE | Set to 1 to enable DDS |
2023-03-27 11:05:51 -03:00
| SERIAL1_BAUD | The serial baud rate for DDS |
| SERIAL1_PROTOCOL | Set this to 45 to use DDS on the serial port |
```bash
2023-03-12 23:18:29 -03:00
# Wipe params till you see "AP: ArduPilot Ready"
# Select your favorite vehicle type
2023-05-23 12:54:29 -03:00
sim_vehicle.py -w -v ArduPlane --console -DG --enable-dds
2023-03-12 23:18:29 -03:00
2023-05-23 12:54:29 -03:00
# Enable DDS (both for UDP or Serial)
2023-04-24 02:13:32 -03:00
param set DDS_ENABLE 1
2023-05-23 12:54:29 -03:00
# Only for Serial
2023-03-12 23:18:29 -03:00
param set SERIAL1_BAUD 115
# See libraries/AP_SerialManager/AP_SerialManager.h AP_SerialManager SerialProtocol_DDS_XRCE
param set SERIAL1_PROTOCOL 45
```
2023-05-23 12:54:29 -03:00
Because `DDS_ENABLE` requires a reboot, stop the simulator with ctrl+C and proceed to the next section.
2023-03-27 11:05:51 -03:00
## Setup ROS 2 and micro-ROS
2023-03-12 23:18:29 -03:00
Follow the steps to use the microROS Agent
- Install ROS Humble (as described here)
- https://docs.ros.org/en/humble/Installation/Ubuntu-Install-Debians.html
2023-04-18 14:23:03 -03:00
- Install geographic_msgs
```bash
sudo apt install ros-humble-geographic-msgs
```
2023-03-12 23:18:29 -03:00
- Install and run the microROS agent (as descibed here). Make sure to use the `humble` branch.
2023-03-27 11:05:51 -03:00
- Follow [the instructions ](https://micro.ros.org/docs/tutorials/core/first_application_linux/ ) for the following:
2023-03-12 23:18:29 -03:00
2023-03-27 11:05:51 -03:00
- Do "Installing ROS 2 and the micro-ROS build system"
- Skip the docker run command, build it locally instead
- Skip "Creating a new firmware workspace"
- Skip "Building the firmware"
- Do "Creating the micro-ROS agent"
- Source your ROS workspace
2023-03-12 23:18:29 -03:00
2023-03-26 13:07:20 -03:00
Until this [PR ](https://github.com/micro-ROS/micro-ROS.github.io/pull/401 ) is merged, ignore the notes about `foxy` . It works on `humble` .
2023-03-12 23:18:29 -03:00
2023-03-27 11:05:51 -03:00
## Using the ROS2 CLI to Read Ardupilot Data
2023-03-12 23:18:29 -03:00
2023-03-27 11:05:51 -03:00
After your setups are complete, do the following:
2023-03-12 23:18:29 -03:00
- Source the ros2 installation
2023-03-26 13:07:20 -03:00
```bash
source /opt/ros/humble/setup.bash
```
2023-05-23 12:54:29 -03:00
Next, follow the associated section for your chosen transport, and finally you can use the ROS 2 CLI.
### UDP (recommended for SITL)
- Run the microROS agent
```bash
cd ardupilot/libraries/AP_DDS
ros2 run micro_ros_agent micro_ros_agent udp4 -p 2019 -r dds_xrce_profile.xml
```
- Run SITL (remember to kill any terminals running ardupilot SITL beforehand)
```bash
sim_vehicle.py -v ArduPlane -DG --console --enable-dds
```
### Serial
2023-03-27 11:05:51 -03:00
- Start a virtual serial port with socat. Take note of the two `/dev/pts/*` ports. If yours are different, substitute as needed.
```bash
socat -d -d pty,raw,echo=0 pty,raw,echo=0
>>> 2023/02/21 05:26:06 socat[334] N PTY is /dev/pts/1
>>> 2023/02/21 05:26:06 socat[334] N PTY is /dev/pts/2
>>> 2023/02/21 05:26:06 socat[334] N starting data transfer loop with FDs [5,5] and [7,7]
```
2023-03-26 13:07:20 -03:00
- Run the microROS agent
```bash
cd ardupilot/libraries/AP_DDS
2023-05-23 12:54:29 -03:00
# assuming we are using tty/pts/2 for DDS Application
ros2 run micro_ros_agent micro_ros_agent serial -b 115200 -r dds_xrce_profile.xml -D /dev/pts/2
2023-03-26 13:07:20 -03:00
```
2023-03-27 11:05:51 -03:00
- Run SITL (remember to kill any terminals running ardupilot SITL beforehand)
2023-03-26 13:07:20 -03:00
```bash
2023-05-23 12:54:29 -03:00
# assuming we are using /dev/pts/1 for Ardupilot SITL
sim_vehicle.py -v ArduPlane -DG --console --enable-dds -A "--uartC=uart:/dev/pts/1"
2023-03-26 13:07:20 -03:00
```
2023-05-23 12:54:29 -03:00
## Use ROS 2 CLI
2023-03-26 13:07:20 -03:00
- You should be able to see the agent here and view the data output.
```bash
$ ros2 node list
/Ardupilot_DDS_XRCE_Client
$ ros2 topic list -v
Published topics:
2023-04-21 17:40:34 -03:00
* /ap/battery/battery0 [sensor_msgs/msg/BatteryState] 1 publisher
2023-05-10 06:47:39 -03:00
* /ap/clock [rosgraph_msgs/msg/Clock] 1 publisher
* /ap/geopose/filtered [geographic_msgs/msg/GeoPoseStamped] 1 publisher
2023-04-21 17:40:34 -03:00
* /ap/navsat/navsat0 [sensor_msgs/msg/NavSatFix] 1 publisher
* /ap/pose/filtered [geometry_msgs/msg/PoseStamped] 1 publisher
* /ap/tf_static [tf2_msgs/msg/TFMessage] 1 publisher
2023-05-10 06:47:39 -03:00
* /ap/time [builtin_interfaces/msg/Time] 1 publisher
* /ap/twist/filtered [geometry_msgs/msg/TwistStamped] 1 publisher
2023-04-21 17:40:34 -03:00
* /parameter_events [rcl_interfaces/msg/ParameterEvent] 1 publisher
* /rosout [rcl_interfaces/msg/Log] 1 publisher
2023-03-26 13:07:20 -03:00
Subscribed topics:
2023-06-11 14:12:12 -03:00
* /ap/joy [sensor_msgs/msg/Joy] 1 subscriber
2023-06-28 00:43:59 -03:00
* /ap/tf [tf2_msgs/msg/TFMessage] 1 subscriber
2023-08-02 21:02:20 -03:00
* /ap/cmd_vel [geometry_msgs/msg/TwistStamped] 1 subscriber
2023-04-21 17:40:34 -03:00
2023-05-10 06:47:39 -03:00
$ ros2 topic hz /ap/time
2023-03-26 13:07:20 -03:00
average rate: 50.115
min: 0.012s max: 0.024s std dev: 0.00328s window: 52
2023-05-23 12:54:29 -03:00
$ ros2 topic echo /ap/time
2023-03-26 13:07:20 -03:00
sec: 1678668735
nanosec: 729410000
2023-06-27 03:46:06 -03:00
$ ros2 service list
/arm_motors
2023-03-26 13:07:20 -03:00
---
```
2023-03-12 23:18:29 -03:00
2023-04-05 03:16:36 -03:00
The static transforms for enabled sensors are also published, and can be recieved like so:
```console
2023-04-21 17:40:34 -03:00
ros2 topic echo /ap/tf_static --qos-depth 1 --qos-history keep_last --qos-reliability reliable --qos-durability transient_local --once
2023-04-05 03:16:36 -03:00
```
2023-05-23 12:54:29 -03:00
In order to consume the transforms, it's highly recommended to [create and run a transform broadcaster in ROS 2 ](https://docs.ros.org/en/humble/Concepts/About-Tf2.html#tutorials ).
2023-04-05 03:16:36 -03:00
2023-06-27 03:46:06 -03:00
## Using ROS 2 services (with Integration Services)
### Prerequisites
- Install and setup [Micro-XRCE Agent ](https://micro-xrce-dds.docs.eprosima.com/en/latest/installation.html#installing-the-agent-standalone )
- Install and setup [Integration Services ](https://integration-service.docs.eprosima.com/en/latest/installation_manual/installation.html ) (it would be good to have a separate workspace for this)
- Get System Handles for [ROS 2 ](https://github.com/eProsima/ROS2-SH )
- Get System Handles for [Fast-DDS ](https://github.com/eProsima/FastDDS-SH )
- Once the above-mentioned System Handles have been cloned, build the Integration Services with the following command :
`colcon build --cmake-args -DMIX_ROS_PACKAGES="example_interfaces ardupilot_msgs"`
### Setup
- The necessary ROS 2 messages and service defintions (especially for the Arming/Disarming Services) are already defined in the `ardupilot_msgs` folder in the `Tools` directory.
### Terminal 1 (XRCE Agent)
- Move to the **AP_DDS** folder and run the XRCE Agent as follows `MicroXRCEAgent udp4 -p 2019 -r dds_xrce_profile.xml`
### Terminal 2 (Integration Service)
- Source ROS 2 installation
- Source Integration Service installation
- Move to the **AP_DDS** folder and run the following command `integration-service Is-Config/Arm_Motors_DDS_IS_config.yaml`
### Terminal 3 (Ardupilot)
- Make sure you have successfully setup Ardupilot and the `DDS_ENABLE` param is set to 1
- Run SITL with the following command `sim_vehicle.py -v ArduPlane -DG --console --enable-dds`
2023-04-17 21:47:22 -03:00
2023-06-27 03:46:06 -03:00
### Terminal 4 (ROS 2 Client)
- Run the following command : `ros2 service call /arm_motors ardupilot_msgs/srv/ArmMotors "{arm: True}"`
2023-04-17 21:47:22 -03:00
## Contributing to AP_DDS library
### Adding DDS messages to Ardupilot
2023-03-12 23:18:29 -03:00
Unlike the use of ROS 2 `.msg` files, since Ardupilot supports native DDS, the message files follow [OMG IDL DDS v4.2 ](https://www.omg.org/spec/IDL/4.2/PDF ).
2023-04-05 10:23:19 -03:00
This package is intended to work with any `.idl` file complying with those extensions.
2023-03-12 23:18:29 -03:00
2023-05-23 12:54:29 -03:00
Over time, these restrictions will ideally go away.
2023-03-12 23:18:29 -03:00
To get a new IDL file from ROS2, follow this process:
```console
cd ardupilot
source /opt/ros/humble/setup.bash
# Find the IDL file
find /opt/ros/$ROS_DISTRO -type f -wholename \*builtin_interfaces/msg/Time.idl
2023-04-05 10:23:19 -03:00
# Create the directory in the source tree if it doesn't exist similar to the one found in the ros directory
mkdir -p libraries/AP_DDS/Idl/builtin_interfaces/msg/
2023-03-12 23:18:29 -03:00
# Copy the IDL
2023-04-05 10:23:19 -03:00
cp /opt/ros/humble/share/builtin_interfaces/msg/Time.idl libraries/AP_DDS/Idl/builtin_interfaces/msg/
2023-05-23 12:54:29 -03:00
# Build the code again with the `--enable-dds` flag as described above
2023-03-12 23:18:29 -03:00
```
2023-04-17 21:47:22 -03:00
### Development Requirements
Astyle is used to format the C++ code in AP_DDS. This is required for CI to pass the build.
See [Tools/CodeStyle/ardupilot-astyle.sh ](../../Tools/CodeStyle/ardupilot-astyle.sh ).
```console
./Tools/CodeStyle/ardupilot-astyle.sh libraries/AP_DDS/*.h libraries/AP_DDS/*.cpp
```
2023-05-23 12:54:29 -03:00
Pre-commit is used for other things like formatting python and XML code.
2023-04-17 21:47:22 -03:00
This will run the tools automatically when you commit. If there are changes, just add them back your staging index and commit again.
1. Install [pre-commit ](https://pre-commit.com/#installation ) python package.
1. Install ArduPilot's hooks in the root of the repo, then commit like normal
```console
cd ardupilot
pre-commit install
git commit
```