Unable to connect RPi 4 + ROS2 via serial

Hello everybody.

I’m not sure this is the best title, but there’s a lot going on and I tried to shorten as much as possible.

I have a custom speedybeef4v4 Copter 4.5 built using --enable-dds. SERIAL3_BAUD=9 (matches stty < /dev/serial0 9600 on the Pi), SERIAL_PROTOCOL=45.

speedybee

Connected to the SpeedyBee, I have the Raspberry Pi 4:

FC — RPi
R3 — GPIO14
T3 — GPIO15
G — G
(everything has it’s own power source)

As you can see by my custom build and connections, I’m trying to get ROS2 running on the Pi to talk to ArduPilot running on the FC, but I’m unable to make that happen following the guides. I’m not sure what I’m trying is even possible (DDS via serial) or if I should use MAVLink in this case.

Using the MAVLink Inspector in Mission Planner I can see information being updated, so I assume things are fine on FC side.

On the RPi4, I have Ubuntu 22, ROS2 Humble and followed the AP guide to ROS2 ROS 2 — Dev documentation

Everything works fine until colcon test --executor sequential --parallel-workers 0 --base-paths src/ardupilot --event-handlers=console_cohesion+
This is the output of the failed tests (not sure how useful it is since it’s trying to test using SITL, but here it is):
colcon_test.txt (126.1 KB)

Also, running ros2 run micro_ros_agent micro_ros_agent serial -b 9600 -D /dev/serial0 and running ros2 node list in another terminal doesn’t return any node.

With SITL on my machine, I have everything set up and fine, but when it comes to connecting the hardware, I’m hitting these walls. So my questions are: is this (DDS over serial and RPi connected to FC via RX/TX) even possible? If so, what am I doing wrong?

Thank you in advance!

Hi @estevanmaito, it should be possible to connect the RPi4 to the FC and run DDS via serial, though your configured baud rate seems low.

Have you managed to get mavlink through the serial link? That’s often a good first step to ensure the wiring and UART is set up correctly.

There is a much better way to connect the RPi4 to a FC, and that is using a high-speed (12500000 baud) serial connection and PPP, provided the FC supports the --enable-ppp flag. That allows up to 4 network ports: so DDS, MAVLink, etc.

This is the arrangement on the EDU-450 / CubeOrangePlus copter I use for testing DDS development. I’m in the process of putting together a set-up guide for this and networking the camera. If you like I could write up some of the steps required to get this working here (which I can later incorporate into self contained dev-wiki entry).

The pic below shows the vehicle. The RPi4 is connected by a flow control enabled UART to the CubeOrangePlus. That provides the network connection to the FC. There is also an ethernet switch onboard which connects the RPi4 to a Herelink AirUnit and a SIYI A8 camera. The Pi runs Ubuntu Server 24.04 and ros2 jazzy, which is not the documented version in the wiki, but is the OSRF supported version for that version of Ubuntu. The FC is running Copter 4.5.7-beta with a couple of patches, the main one relevant to DDS is a patch that allows the DDS connection timeout to be adjusted in params which is essential if you want the FC to wait for the Pi to boot and the PPP and micro-ROS services to come online before the DDS client gives up waiting.

The PPP daemon and micro-ros-agent are brought up on boot using systemctl services and there is a small custom hat for the UART, power, and reset switches (the latter so the Pi can be powered down properly before the main battery is disconnected).

Thanks for your reply @rhys

So I changed SERIAL3_BAUD=115 (matching the Pi’s 115200) and SERIAL3_PROTOCOL=2 in the FC and installed MAVProxy on the Pi.

Running mavproxy shows that my connection works at least, but also that I’m running 4.6.0 and not 4.5

raspberrypi@ubuntu:~$ mavproxy.py --master=/dev/serial0 --baudrate 115200 --aircraft MyCopter
Connect /dev/serial0 source_system=255
no script MyCopter/mavinit.scr
Log Directory: MyCopter/logs/2024-10-13/flight1
Telemetry log: MyCopter/logs/2024-10-13/flight1/flight.tlog
Waiting for heartbeat from /dev/serial0
MAV> link 1 down
AP: ArduCopter V4.6.0-dev (1439aebf)
AP: ChibiOS: 8fc176ac
AP: speedybeef4v4 004A002D 35335116 32343431
AP: RCOut: PWM:1-9
AP: Frame: QUAD/X
Detected vehicle 1:1 on link 0
link 1 OK
online system 1
STABILIZE> Mode STABILIZE
AP: ArduCopter V4.6.0-dev (1439aebf)
AP: ChibiOS: 8fc176ac
AP: speedybeef4v4 004A002D 35335116 32343431
AP: RCOut: PWM:1-9
AP: Frame: QUAD/X
Received 1112 parameters (ftp)
Saved 1112 parameters to MyCopter/logs/2024-10-13/flight1/mav.parm
Saved 1112 defaults to MyCopter/logs/2024-10-13/flight1/defaults.parm
fence present
Flight battery 100 percent
AP: PreArm: RC not found
AP: PreArm: 3D Accel calibration needed
AP: PreArm: Compass not calibrated
AP: PreArm: Battery 1 below minimum arming voltage
AP: PreArm: Terrain out of memory
AP: PreArm: RC not found
AP: PreArm: 3D Accel calibration needed
AP: PreArm: Compass not calibrated
AP: PreArm: Battery 1 below minimum arming voltage
AP: PreArm: Terrain out of memory

I’ll try PPP now, but I’m afraid this FC is too weak for those baud rates (also checking the docs, seems like an H7 chipset thing - which the CubeOrange has).

It would also be great if you could share at least the initial steps of setting things up with PPP/DDS on your drone.

PPP can run at lower baudrate as well, for example SERIALx_BAUD 921000 works when the UART does not support hardware flow control. There is an article here on testing PPP using a FC and PC, which may help establish if the chipset can support the protocol. Testing PPP and DDS on a desktop or laptop

I have not tested running DDS on hardware serial (vs udp) recently, so can’t confirm that everything is working as it should.

Looks like you are running master from the end of August. This PR adds timeout params: AP_DDS: add params for ping timeout and max retries by srmainwaring · Pull Request #28203 · ArduPilot/ardupilot · GitHub It was merged after the version you are using.

If you prefer to run a version slated for release, the Copter-4.5 branch (head is now Copter-4.5.7-beta) has DDS support and the earlier revisions have been extensively flight tested. The backport to Copter-4.5. for DDS timeout params is here: DDS Backport #28203 to 4.5: by srmainwaring · Pull Request #28237 · ArduPilot/ardupilot · GitHub

./waf clean
./waf configure --board speedybeef4v4 --enable-dds --enable-PPP
./waf copter -v

Running with PPP flag fails on the [1096/1102] Linking build/speedybeef4v4/bin/arducopter step of the build.

/opt/gcc-arm-none-eabi-10-2020-q4-major/bin/../lib/gcc/arm-none-eabi/10.2.1/../../../../arm-none-eabi/bin/ld:common.ld:202 cannot move location counter backwards (from 00000000081025c0 to 0000000008100000)
collect2: error: ld returned 1 exit status
# log continues

Removing the PPP flag builds as usual, so I’ll try enabling only DDS with the most recent master.

One point of confusion for me is the documentation for setting up ArduPilot + ROS2, that imports ros2.repos, one of the repos is the micro-ros-agent:

repositories:
  ardupilot:
    type: git
    url: https://github.com/ArduPilot/ardupilot.git
    version: master
  micro_ros_agent:
    type: git
    url: https://github.com/micro-ROS/micro-ROS-Agent.git
    version: humble

And then on AP_DDS readme it recommends to manually install the micro-ros-agent, specifically the “Creating the micro-ROS agent” with ros2 run micro_ros_setup build_agent.sh, since if you followed the wiki’s documentation, you already have that, right?

ros2 run micro_ros_setup build_agent.sh
Building micro-ROS Agent
[1.551s] WARNING:colcon.colcon_core.package_selection:Some selected packages are already built in one or more underlay workspaces:
	'micro_ros_agent' is in: /home/raspberrypi/ros2_ws/install/micro_ros_agent
	'micro_ros_msgs' is in: /opt/ros/humble

Checking your post on “testing ppp and dds”, I’d like to take one step back, and ask you which way did you follow?

While writing, up to this point, I was checking things and it worked in one of my tries. Turns out I ran ros2 run micro_ros_agent micro_ros_agent serial -b 230400 -D /dev/serial0 BEFORE turning the FC on this time, and THEN I realised what the relation of the ping timeout and max retries was in your last message. It’s a shame there wasn’t any alert that could’ve pointed this issue earlier (maybe if I had mavproxy running like during SITL, it could’ve showed up).

So now I’ll grab an empty SD card and try everything again, document it, and see if I can reliably reproduce this setup.

Thanks for your help @rhys (I’m still interested in the way you installed micro-ros-agent though :smiley: )

I clone the micro-ros-agent repo into the colcon workspace (using vcstool and the ros2.repos yaml file), then build with colcon. This works for my laptop, which is a M1 mac, and RPi4 companion.

Yes, mavproxy or another GCS such as MissionPlanner or QGC will report a ping failure and eventual exit of the DDS client if the micro-ros-agent is not running.

1 Like

Did you setup two serial interfaces? could it be the issue?

If the connection fails, instead of running the Micro ROS agent, debug the stream

python3 -m serial.tools.miniterm /dev/serial/by-id/usb-ArduPilot_Pixhawk6X_210028000151323131373139-if02  115200 --echo --encoding hexlify