Skip to content

PoliTOcean/nereo_ros2_code

Repository files navigation

Nereo PoliTOcean

Code for the Nereo ROV by PoliTOcean.

The project is split into two ROS 2 (Humble) workspaces:

Workspace Side Purpose
gui_ws Control station (PC) GUI, joystick, web controller, safety arbitration
rpi_ws Raspberry Pi (on the ROV) IMU / barometer / sonar acquisition

The PID/state-space controller lives in a separate repository, ros2_controller_tuning_aid, and is wired in by the workstation.launch.py of gui_pkg.


Table of contents

  1. Installation
  2. Build
  3. Run
  4. Workspace structure
  5. ROS 2 node and topic map
  6. GUI features
  7. Web controller (phone / tablet)
  8. Local testing (no ROV hardware)
  9. Troubleshooting

Installation

0. Clone the repos

nereo_interfaces is a git submodule of this repo. Clone with --recurse-submodules:

git clone --recurse-submodules https://github.com/PoliTOcean/nereo_ros2_code.git

If already cloned without it:

git submodule update --init

Clone the controller repo next to this one (paths in workstation.launch.py assume they are siblings under ~/Documents/PoliTOcean/RD/):

git clone https://github.com/PoliTOcean/ros2_controller_tuning_aid.git

1. System dependencies

sudo apt update
sudo apt install \
    ros-humble-rosbridge-suite \
    ros-humble-tf-transformations \
    gstreamer1.0-plugins-good gstreamer1.0-plugins-base gstreamer1.0-tools \
    python3-qrcode python3-pil
Package Used by Why it's needed
ros-humble-rosbridge-suite web_pkg WebSocket bridge for the web controller (port 9090)
ros-humble-tf-transformations gui_pkg Quaternion → RPY conversion in the GUI
gstreamer1.0-plugins-* gui_pkg Live H.264/UDP video from the ROV cameras
python3-qrcode, python3-pil gui_pkg Generates the QR code shown on Ctrl+Q for the web controller URL

2. PyQt6 with QML bindings (pip)

The apt python3-pyqt6 package ships without QtQml/QtQuick. Install via pip:

pip install PyQt6

3. Register the custom rosdep sources

A few dependencies (PyQt6, bluerobotics-ping) are not in the default rosdep index. The local override sits at rosdep.yaml in this repo:

echo "yaml file://$(pwd)/rosdep.yaml" | sudo tee /etc/ros/rosdep/sources.list.d/nereo.list
rosdep update

4. Install per-package dependencies

# Control station (PC)
cd gui_ws
rosdep install --from-paths src --ignore-src -r -y

# Raspberry Pi
cd ../rpi_ws
rosdep install --from-paths src --ignore-src -r -y

Build

# Controller (must be built first — gui_ws launch file pulls it in via AMENT_PREFIX_PATH)
cd ../ros2_controller_tuning_aid && colcon build && source install/setup.zsh

# Control station
cd ../nereo_ros2_code/gui_ws && colcon build && source install/setup.zsh

# Raspberry Pi
cd ../rpi_ws && colcon build && source install/setup.zsh

Run

A single launch file starts everything on the workstation: joystick driver, command translator, GUI, safety arbiter, rosbridge WebSocket (port 9090), web controller server (port 8080), and the controller node.

ros2 launch gui_pkg workstation.launch.py

The launch file auto-prepends the ros2_controller_tuning_aid install dir to AMENT_PREFIX_PATH, so you do not need to source that overlay manually.

Launch arguments

Argument Default Description
device /dev/input/js0 Joystick device path
deadzone 0.05 Joystick deadzone
max_steps 10 Quantization steps for axes
btn_arm 8 Arm/disarm button index
btn_mode 6 Direct ↔ Controller mode toggle button index
control_mode 0 Initial controller mode (0=passthrough, 1=PID, 2=PID-AW, 3=CS)

Physical controller mapping

Input Action Xbox One S (default) DS5
Left stick Y/X Surge / Sway
Right stick Y/X Heave / Yaw
D-pad up/down Pitch trim
D-pad left/right Roll trim
Arm/Disarm Toggle arm Xbox (btn 8) PS (btn 10)
Mode toggle Direct ↔ Controller View (btn 6) Share (btn 8)

Examples:

# DS5 button mapping
ros2 launch gui_pkg workstation.launch.py btn_arm:=10 btn_mode:=8

# Different joystick device
ros2 launch gui_pkg workstation.launch.py device:=/dev/input/js1

Direct mode (red lock icon in GUI): commands go to /nereo_cmd_vel_joysafety_node → ROV. Controller mode (blue lock icon in GUI): commands go to /nereo_cmd_vel_no_fb → controller node → safety_node → ROV.


Workspace structure

nereo_ros2_code/
├── gui_ws/                          # Workstation workspace
│   └── src/
│       ├── gui_pkg/                 # QML/PyQt6 dashboard + joystick + rov simulator
│       │   ├── gui_pkg/
│       │   │   ├── gui_node.py      # Main node + ROSQmlBridge / SonarBridge / ControllerBridge
│       │   │   ├── rov_sim_node.py  # Full ROV simulator (IMU, barometer, cameras, joy)
│       │   │   └── qml/             # QML UI
│       │   │       ├── main.qml
│       │   │       └── components/
│       │   │           ├── ControllerTunerWindow.qml   # PID/CS tuning UI (deg/m setpoints)
│       │   │           ├── ControlPanelWindow.qml
│       │   │           ├── SonarWindow.qml
│       │   │           ├── Orientation2D.qml
│       │   │           └── VideoBox.qml
│       │   └── launch/
│       │       └── workstation.launch.py
│       ├── joystick_pkg/            # joy → CommandVelocity
│       ├── web_pkg/
│       │   ├── web_server_node.py   # HTTP server on :8080
│       │   ├── safety_node.py       # Arbitrates physical vs. web commands
│       │   └── static/              # Web controller UI assets
│       └── nereo_interfaces/        # CommandVelocity, ThrusterStatuses (submodule)
└── rpi_ws/                          # Raspberry Pi workspace
    └── src/
        ├── nereo_sensors_pkg/       # C++ — IMU (WT61P) + barometer (MS5837)
        │   ├── src/imuPub.cpp       # publishes /imu_data, service imu_reset_reference
        │   ├── src/barPub.cpp       # publishes /barometer_*, service barometer_reset_reference
        │   └── include/nereo_sensors_pkg/
        └── sonar_pkg/               # Python — Blue Robotics Ping1D

ROS 2 node and topic map

Nodes

Node Package Side Role
imu_publisher nereo_sensors_pkg RPi WT61P over I2C → /imu_data; service imu_reset_reference
bar_publisher nereo_sensors_pkg RPi MS5837 over I2C → /barometer_*; service barometer_reset_reference
sonar_node sonar_pkg RPi Ping1D over serial → /sonar/*
gui_node gui_pkg PC QML dashboard, telemetry fusion, QR code, tuner
joy_to_cmd_vel joystick_pkg PC Joystick → CommandVelocity
safety_node web_pkg PC Arbitrates controller + web commands → /nereo_cmd_vel
web_server_node web_pkg PC Serves the web controller on :8080
rosbridge_websocket rosbridge_server PC WebSocket bridge for the web client (:9090)
nereo_controller_node nereo_controller_node PC PID / state-space controller (separate repo)
rov_sim_node gui_pkg PC Local ROV simulator (no hardware needed)
sonar_sim_node sonar_pkg PC Synthetic sonar data

Topics

Publisher Topic Type Consumers
imu_publisher imu_data sensor_msgs/Imu gui_node, nereo_controller_node
imu_publisher imu_diagnostic diagnostic_msgs/DiagnosticArray
bar_publisher barometer_pressure sensor_msgs/FluidPressure gui_node, nereo_controller_node
bar_publisher barometer_depth_salt std_msgs/Float32 gui_node (depth widget)
bar_publisher barometer_depth_fresh std_msgs/Float32
bar_publisher barometer_temperature sensor_msgs/Temperature gui_node
bar_publisher barometer_diagnostic diagnostic_msgs/DiagnosticArray
sonar_node / sonar_sim_node sonar/distance std_msgs/Float32 gui_node
sonar_node / sonar_sim_node sonar/confidence std_msgs/Int32 gui_node
sonar_node / sonar_sim_node sonar/profile std_msgs/Float32MultiArray gui_node
joy_to_cmd_vel /nereo_cmd_vel_joy nereo_interfaces/CommandVelocity safety_node
joy_to_cmd_vel /nereo_cmd_vel_no_fb nereo_interfaces/CommandVelocity nereo_controller_node
joy_to_cmd_vel /joy_control_active std_msgs/Bool gui_node, web
joy_to_cmd_vel / web /set_arm_mode std_msgs/Bool ROV firmware
nereo_controller_node /nereo_cmd_vel (controller mode) nereo_interfaces/CommandVelocity safety_node
nereo_controller_node /controller/setpoints std_msgs/Float64MultiArray tuner GUI
nereo_controller_node /controller/errors std_msgs/Float64MultiArray tuner GUI
nereo_controller_node /controller/pid_terms std_msgs/Float64MultiArray tuner GUI
web client /web_cmd_vel nereo_interfaces/CommandVelocity safety_node
safety_node /nereo_cmd_vel (direct mode) nereo_interfaces/CommandVelocity ROV firmware
ROV firmware /rov_armed std_msgs/Bool gui_node, joy_to_cmd_vel, web
ROV firmware /thruster_status nereo_interfaces/ThrusterStatuses

Services

Service Type Provider Used by Effect
barometer_reset_reference std_srvs/Trigger bar_publisher GUI "ZERO" button Re-zeroes the surface pressure → depth = 0 at current spot
imu_reset_reference std_srvs/Trigger imu_publisher GUI "ZERO RPY" button Stores current orientation as offset → roll/pitch/yaw = 0 at current attitude

Safety arbitration (safety_node)

Condition Output
Controller active (last msg < 0.5 s) Controller command forwarded, web ignored
Only web active Web command forwarded
Web silent 0–1 s Last web command held
Web silent 1–1.5 s Command ramped to zero
Web silent > 1.5 s Zero command sent
No source active Zero command sent

Architecture diagram

graph LR
   subgraph RPI[rpi_ws — Raspberry Pi]
      IMU[imu_publisher\nimu_reset_reference svc]
      BAR[bar_publisher\nbarometer_reset_reference svc]
      SONAR[sonar_node]
      CAM[GStreamer cameras\nH264 UDP]
   end

   subgraph CTRL[gui_ws — Control Station]
      GUI[gui_node\nROSQmlBridge / SonarBridge / ControllerBridge]
      JOY[joy_to_cmd_vel]
      SAFETY[safety_node]
      WEB[web_server_node\nport 8080]
      RB[rosbridge_websocket\nport 9090]
   end

   subgraph TUNE[ros2_controller_tuning_aid]
      NCN[nereo_controller_node]
   end

   subgraph SIM[Simulators — local testing]
      ROVSIM[rov_sim_node]
      SONARSIM[sonar_sim_node]
   end

   PHONE[Phone / tablet\nbrowser]

   IMU -.->|imu_data| GUI
   IMU -.->|imu_data| NCN
   BAR -.->|barometer_pressure| GUI
   BAR -.->|barometer_pressure| NCN
   BAR -.->|barometer_depth_salt| GUI
   SONAR -.->|sonar/*| GUI
   CAM -.->|RTP/UDP 5001-5003| GUI

   JOY -->|nereo_cmd_vel_joy| SAFETY
   JOY -->|nereo_cmd_vel_no_fb| NCN
   NCN -->|nereo_cmd_vel| SAFETY
   PHONE -->|web_cmd_vel via :9090| RB
   RB --> SAFETY
   WEB -->|UI :8080| PHONE
   SAFETY -->|nereo_cmd_vel| ROV[(ROV firmware\nmicroROS)]
   JOY -->|set_arm_mode| ROV
   ROV -->|rov_armed| GUI
   ROV -->|rov_armed| JOY

   GUI -.->|set_parameters| NCN
   NCN -.->|/controller/*| GUI
Loading

GUI features

Main dashboard

  • 3× live H.264/UDP camera streams (main + 2 secondary)
  • IMU orientation widget (yaw / pitch / roll)
  • Depth, temperature, ROV arm/connection status
  • ZERO button → re-zeroes depth at the surface (calls barometer_reset_reference)
  • ZERO RPY button → re-zeroes attitude when the ROV is sitting level (calls imu_reset_reference)
  • Ctrl+Q → opens a popup with a QR code + URL (http://<ip>:8080) for the web controller. The IP is recomputed every time the shortcut is pressed, so it works even if you connect to Wi-Fi after launching the GUI.

Controller Tuner window (TUNER button)

  • Selects control mode (0 passthrough / 1 PID / 2 PID anti-windup / 3 CS)
  • Edits kp/ki/kd for depth/roll/pitch/yaw
  • Manual setpoint toggles per axis
  • Setpoint inputs in display units: depth in metres, roll/pitch/yaw in degrees. Conversion to controller units (Pa, rad) is done inside QML (density ρ = 1025 kg/m³, salt water — matches barometer_depth_salt). The controller-side parameters stay in their native units.
  • Full CS controller section (kx, ki, heave/angle limits)
  • Live telemetry: /controller/setpoints, /controller/errors, /controller/pid_terms

Sonar Viewer (SONAR button)

Waterfall + A-scan rendered into a QQuickImageProvider, confidence threshold filter.

Control Panel (CONTROL PANEL button)

Manual arming / mode toggles independent from the joystick.


Web controller (phone / tablet)

Open from any device on the same network:

  • Controller: http://<workstation-ip>:8080
  • ROV simulator: http://<workstation-ip>:8080/sim.html

The fastest way to get the URL on a phone: focus the GUI and press Ctrl+Q — a QR code with the URL appears.

The web client publishes on /web_cmd_vel. safety_node gives priority to the physical controller when both are active.

The web_server_node is robust to GUI shutdown: it installs a SIGTERM handler, closes the HTTP socket, and joins its serving thread on destroy_node(), so port 8080 is released cleanly and the launch file can be restarted without pkill.


Local testing (no ROV hardware)

# Terminal 1 — full ROV simulator (IMU, barometer, joystick, arm, 3 GStreamer test streams)
ros2 run gui_pkg rov_sim_node
# (without GStreamer: --ros-args -p simulate_cameras:=false)

# Terminal 2 — sonar simulator
ros2 run sonar_pkg sonar_sim_node

# Terminal 3 — workstation stack
ros2 launch gui_pkg workstation.launch.py

Open http://localhost:8080 for the web controller and http://localhost:8080/sim.html for the top-down ROV simulator.

Manual test helpers

  • gui_ws/src/gui_pkg/test/cam_test.sh — three independent GStreamer test streams
  • ros2 run joystick_pkg rov_cmd_monitor — terminal dashboard of the live 6-DOF command vector

Unit tests

Inside unit_tests/ each subfolder is a CMake project for stdout-level debugging:

cd unit_tests/<name>
cmake . && make
./<name>

Troubleshooting

Symptom Cause Fix
Address already in use :8080 at relaunch Old web_server_node still running Should not happen anymore (the node releases the socket on SIGTERM); if it does, pkill -f web_server_node
GUI starts but no nereo_controller_node ros2_controller_tuning_aid not built or not at sibling path Check ~/Documents/PoliTOcean/RD/ros2_controller_tuning_aid/install/ exists
imu_reset_reference service not available rpi_ws not rebuilt after the new service was added On the Pi: colcon build --packages-select nereo_sensors_pkg
Ctrl+Q shows "Nessuna rete" No default-route interface up Connect to Wi-Fi / Ethernet, press Ctrl+Q again (re-evaluated each time)
Ctrl+Q shows "Pacchetto python3-qrcode mancante" Missing system package sudo apt install python3-qrcode python3-pil
Tuner setpoint value looks wrong after RELOAD Controller still has old unit value The GUI now converts deg↔rad and m↔Pa; if you set parameters from CLI in raw units, RELOAD will display them converted

About

No description, website, or topics provided.

Resources

License

Stars

3 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors