This package provides a learning-based cooperative controller for a group of autonomous underwater vehicles (AUVs) operating together in simulation. The controller is designed for cooperative mission execution under uncertain dynamics and includes a neural-network-based learning component to improve coordination, tracking, and adaptability.
The package also includes supporting launch files, configuration files, CUDA-based RBF utilities, and a yaw extraction node used in the control pipeline.
- ROS 2: Jazzy
- Ubuntu: 24.04
configswarm_control.yaml: controller and mission-related parameters.
includerbf_cuda.hpp: header for CUDA-based RBF neural network utilities.
launchswarm_control.launch.py: launch file for the controller setup.
srcrbf_cuda.cu: CUDA implementation of the RBF neural-network-related computations.simple_controller.cpp: main controller implementation.
yaw_extractor_node.cpp: node for extracting desired yaw information from odometry/waypoint topics.
testsendwaypoints_srv_call.txt: example service call for sending waypoints.
- Learning-based cooperative control for multiple agents
- Neural-network-based adaptation for uncertain system dynamics
- Support for single-vehicle and multi-vehicle launch setups
- CUDA-based RBF utility implementation
- Yaw extraction utility for waypoint-following/control integration
This package is intended to be used inside a ROS 2 workspace together with the simulation and MVP-related packages used in the project.
Typical dependencies may include:
rclcppstd_msgsgeometry_msgsnav_msgstf2tf2_rostf2_geometry_msgsEigen3- CUDA (for
rbf_cuda.cu)
Please make sure the required ROS 2 packages and system libraries are installed before building.
From the root of your ROS 2 workspace:
cd ~/ros2_ws
colcon build --packages-select simple_controller_pkg
source install/setup.bashEach controller node exposes a runtime parameter called learning_phase.
The supported values are:
learningsteady_recordingfrozen
The commands below switch all three agents together. They assume the controller nodes are running as:
/mauv_1/simple_controller_node/mauv_2/simple_controller_node/mauv_3/simple_controller_node
This keeps learning active and starts collecting steady-phase weight samples inside each controller.
for agent in mauv_1 mauv_2 mauv_3; do
ros2 param set /${agent}/simple_controller_node learning_phase steady_recording
doneThis computes the averaged steady-phase weight w_bar for each agent,
uploads it to the GPU, and disables further weight updates.
for agent in mauv_1 mauv_2 mauv_3; do
ros2 param set /${agent}/simple_controller_node learning_phase frozen
doneAfter all three agents have frozen their local w_bar, the
swarm_weight_manager_node computes:
Wbar_shared = (Wbar_1 + Wbar_2 + Wbar_3) / 3
Use the command below to tell all agents to replace their local frozen knowledge with the shared swarm-average weight:
for agent in mauv_1 mauv_2 mauv_3; do
ros2 param set /${agent}/simple_controller_node knowledge_source swarm_average
doneTo start directly with the saved shared swarm weight and no new learning:
ros2 launch simple_controller_pkg swarm_control.launch.py use_saved_shared_weights:=trueTo start directly with the saved shared weight in the rotated formation:
ros2 launch simple_controller_pkg swarm_control.launch.py use_saved_shared_weights:=true formation_profile:=rotatedThe saved files are:
~/.ros/simple_controller/shared_wbar.bin~/.ros/simple_controller/shared_wbar.meta
If you want to switch back from the shared swarm average to each agent's own
local frozen w_bar:
for agent in mauv_1 mauv_2 mauv_3; do
ros2 param set /${agent}/simple_controller_node knowledge_source local_average
doneThis keeps the mission running, but changes the role/slot assignment so the agents test the learned knowledge in a new configuration:
mauv_1takes the oldmauv_2slotmauv_2takes the oldmauv_3slotmauv_3takes the oldmauv_1slot
for agent in mauv_1 mauv_2 mauv_3; do
ros2 param set /${agent}/simple_controller_node formation_profile rotated
doneTo restore the original learned/training configuration:
for agent in mauv_1 mauv_2 mauv_3; do
ros2 param set /${agent}/simple_controller_node formation_profile training
doneEach controller node also exposes a runtime parameter called
mission_profile.
The supported values are:
figure_eightquarter_square_hold
The default mission remains figure_eight.
The new quarter_square_hold mission moves along a smooth square-corner
path and then holds the final point.
ros2 launch simple_controller_pkg swarm_control.launch.py mission_profile:=quarter_square_holdfor agent in mauv_1 mauv_2 mauv_3; do
ros2 param set /${agent}/simple_controller_node mission_profile quarter_square_hold
donefor agent in mauv_1 mauv_2 mauv_3; do
ros2 param set /${agent}/simple_controller_node mission_profile figure_eight
doneThe quarter-square geometry and timing are configured in
config/swarm_control.yaml using:
quarter_square_origin_xquarter_square_origin_yquarter_square_side_lengthquarter_square_turn_radiusquarter_square_leg_timequarter_square_turn_time
This re-enables online weight updates for all agents.
for agent in mauv_1 mauv_2 mauv_3; do
ros2 param set /${agent}/simple_controller_node learning_phase learning
doneTo confirm the current learning phase for all three agents:
for agent in mauv_1 mauv_2 mauv_3; do
ros2 param get /${agent}/simple_controller_node learning_phase
doneTo confirm the active knowledge source for all three agents:
for agent in mauv_1 mauv_2 mauv_3; do
ros2 param get /${agent}/simple_controller_node knowledge_source
doneTo fully confirm the runtime mode, check both:
for agent in mauv_1 mauv_2 mauv_3; do
echo -n "${agent} phase: "
ros2 param get /${agent}/simple_controller_node learning_phase
echo -n "${agent} source: "
ros2 param get /${agent}/simple_controller_node knowledge_source
doneTo confirm the active formation profile for all three agents:
for agent in mauv_1 mauv_2 mauv_3; do
ros2 param get /${agent}/simple_controller_node formation_profile
doneDo not switch to frozen before running steady_recording long enough to
collect samples. If no steady-phase samples were recorded, the node will
reject the freeze request and stay in its current mode.