- QGC/autopilot: vehicle drive and piloting
- Keep ROS and QGC responsibilities separate:
- QGC bridge UDP/ffmpeg settings
ros2 launch rov_onboard onboard_launch.py qgc_ip:=<CONTROL_LAPTOP_IP> pix_serial:=/dev/ttyACM0 pix_baud:=115200
onboard_launch.pynow auto-starts MAVLink forwarding (mavlink-routerd) whenQGC_IPis set or whenqgc_ip:=...is passed directly: export QGC_IP=<CONTROL_LAPTOP_IP> If QGC does not show video: Run laptop: Run onboard:
- QGC bridge UDP/ffmpeg settings
ros2 launch rov_onboard onboard_launch.py qgc_ip:=<CONTROL_LAPTOP_IP> pix_serial:=/dev/ttyACM0 pix_baud:=115200
camera_nodepublishes/rov/camera/image_compressedon onboard.qgc_video_bridge_nodeon laptop subscribes and forwards low-latency H.264 over RTP toudp_host:udp_port(default port5600) usingffmpeg.- In QGroundControl, set video source to UDP and port
5600. - If video does not decode in your QGC build, set
output_format: h264insrc/rov_control/config/control_params.yamlas fallback.
- Connect QGroundControl to your autopilot (USB/telemetry Ethernet).
- Calibrate joystick in QGroundControl.
- Configure vehicle mode/buttons in QGroundControl.
- Verify thruster response in QGC motor test / armed mode. Drive is handled outside of ROS by QGroundControl. To set up:
- Also assumes you have QGroundControl installed on the control laptop.
qgc_video_bridge_node[QGroundControl] --MAVLink--> [Autopilot/ESCs] (drive control path, not ROS) ^ | UDP video :5600 from ROS bridge [rov_control/qgc_video_bridge_node] <-- ROS compressed image -- [rov_onboard/camera_node] Control Laptop (Ubuntu + QGroundControl + ROS 2) Onboard Computer (Ubuntu + ROS 2 + autopilot HW)
MATEROV is an underwater robotics competition. This repository contains the ROS workspace for our 2026 entry, which includes:
- ROS 2 handles:
- arm encoder values from the control laptop -> onboard servo commands
- camera transport used by a QGC video bridge
- QGroundControl + autopilot stack handles vehicle driving/thrusters.
- QGroundControl + autopilot stack handles vehicle driving/thrusters.
Control Laptop (Ubuntu + QGroundControl + ROS 2) Onboard Computer (Ubuntu + ROS 2 + autopilot HW)
[QGroundControl] --MAVLink--> [Autopilot/ESCs] (drive control path, not ROS)
^
| UDP video :5600 from ROS bridge
[rov_control/qgc_video_bridge_node] <-- ROS compressed image -- [rov_onboard/camera_node]
[arm controller encoder USB] --/rov/arm/encoder_values--> [rov_control/arm_encoder_bridge_node]
|
'--/rov/arm/servo_command--> [rov_onboard/arm_servo_node -> PinPong servos]
Split into 2 main packages for the two hardware stacks, plus a shared messages package:
rov_msgsArmServoCommand.msg
rov_control(runs on control laptop)arm_encoder_bridge_nodeqgc_video_bridge_node
rov_onboard(runs on onboard computer)camera_nodearm_servo_node
| Topic | Type | Direction | Purpose |
|---|---|---|---|
/rov/arm/encoder_values |
std_msgs/Float32MultiArray |
Laptop local input | 8 encoder values from USB reader script/node |
/rov/arm/servo_command |
rov_msgs/ArmServoCommand |
Laptop -> Onboard | 8 servo target angles in degrees |
/rov/camera/image_raw |
sensor_msgs/Image |
Onboard -> Laptop | raw camera stream |
/rov/camera/image_compressed |
sensor_msgs/CompressedImage |
Onboard -> Laptop | compressed camera stream |
ArmServoCommand axis order defaults to:
[base, shoulder, elbow, wrist_pitch, wrist_roll, wrist_yaw, tool_rotate, gripper]
Run all commands on both machines unless noted.
- Assumes ROS 2 Humble and Ubuntu 22.04.
- Also assumes you have QGroundControl installed on the control laptop.
source /opt/ros/humble/setup.bash
sudo apt update
sudo apt install -y \
python3-opencv \
ros-humble-cv-bridge \
python3-pip \
ffmpeg \
mavlink-routerOn the onboard machine (for servos):
pip3 install pinpongClone workspace from GitHub then run on both machines:
cd ~/MATE2026
source /opt/ros/humble/setup.bash
colcon build --symlink-install
source install/setup.bashRun on both machines (same value on both):
echo 'export ROS_DOMAIN_ID=42' >> ~/.bashrc
source ~/.bashrcQuick check:
# machine A
ros2 topic pub /test std_msgs/String "data: hello"
# machine B
ros2 topic echo /testDrive is handled outside of ROS by QGroundControl. To set up:
- Connect QGroundControl to your autopilot (USB/telemetry Ethernet).
- Calibrate joystick in QGroundControl.
- Configure vehicle mode/buttons in QGroundControl.
- Verify thruster response in QGC motor test / armed mode.
camera_nodepublishes/rov/camera/image_compressedon onboard.qgc_video_bridge_nodeon laptop subscribes and forwards low-latency H.264 over RTP toudp_host:udp_port(default port5600) usingffmpeg.- In QGroundControl, set video source to UDP and port
5600. - If video does not decode in your QGC build, set
output_format: h264insrc/rov_control/config/control_params.yamlas fallback.
Run onboard:
cd ~/MATE2026
source install/setup.bash
ros2 launch rov_onboard camera_only_launch.pyRun laptop:
cd ~/MATE2026
source install/setup.bash
ros2 launch rov_control camera_viewer_only_launch.pyIf QGC does not show video:
# verify compressed topic exists
ros2 topic list | grep /rov/camera/image_compressed
# verify stream rate
ros2 topic hz /rov/camera/image_compressedThere is a script/node that reads 8 encoder values from USB and publishes to ROS topic:
- topic:
/rov/arm/encoder_values - type:
std_msgs/Float32MultiArray datalength: 8
These values can be degrees or raw units. Mapping to servo angles is done in control_params.yaml (scales and offsets_deg).
cd ~/MATE2026
source install/setup.bash
ros2 launch rov_control arm_only_launch.pycd ~/MATE2026
source install/setup.bash
ros2 launch rov_onboard arm_only_launch.pyEdit src/rov_onboard/config/onboard_params.yaml:
use_pinpong: true- set
pinpong_boardandpinpong_port - set
servo_pinsto your wiring - tune min/max/neutral values per axis
Then rebuild onboard:
cd ~/MATE2026
source /opt/ros/humble/setup.bash
colcon build --symlink-install
source install/setup.bashOnboard:
cd ~/MATE2026
source install/setup.bash
export QGC_IP=<CONTROL_LAPTOP_IP>
ros2 launch rov_onboard onboard_launch.pyonboard_launch.py now auto-starts MAVLink forwarding (mavlink-routerd) when QGC_IP is set
or when qgc_ip:=... is passed directly:
ros2 launch rov_onboard onboard_launch.py qgc_ip:=<CONTROL_LAPTOP_IP> pix_serial:=/dev/ttyACM0 pix_baud:=115200If needed, disable forwarding for bench tests:
ros2 launch rov_onboard onboard_launch.py enable_mavlink_forward:=falseLaptop:
cd ~/MATE2026
source install/setup.bash
ros2 launch rov_control control_launch.pysrc/rov_control/config/control_params.yaml- encoder input topic
- axis scaling/offset/clamps
- QGC bridge UDP/ffmpeg settings
src/rov_onboard/config/onboard_params.yaml- camera settings
- PinPong + servo pin/range/timeout settings
- Keep ROS and QGC responsibilities separate:
- ROS: arm + camera transport
- QGC/autopilot: vehicle drive and piloting