Architecture Overview

The stack is built around a single sim-to-real switch (use_sim). The same application nodes and topic names run in both modes; the hardware plugin, optional controllers, and tension data source change.

This page is the navigation hub. For exhaustive detail, follow the links below.

Start here

I want to…

Go to

Understand each Python package in depth

Package Guide

See all ROS 2 nodes & topics (sim vs HW)

ROS 2 Communication Graph

Download diagrams for my report

Standalone Diagram Exports

Look up launch args / YAML params

Package Reference

Read Python class/function docs

Python API Reference

Build and run the stack

Getting Started

System context

        flowchart LR
    classDef cmake fill:#fff8e1,stroke:#f57f17,stroke-width:1.5px
    classDef python fill:#e3f2fd,stroke:#1565c0,stroke-width:1.5px
    classDef external fill:#eceff1,stroke:#607d8b,stroke-width:1.5px

    DESC["description<br/>URDF · MJCF"]:::cmake
    BR["bringup<br/>robot.launch.py"]:::cmake
    IFACE["interfaces<br/>FishingTension"]:::cmake

    CTRL["control"]:::python
    SENS["sensors"]:::python
    PLAN["planning"]:::python
    DIAG["diagnostics"]:::python

    CM["ros2_control host"]:::external
    RSP["robot_state_publisher"]:::external

    DESC --> BR
    BR --> CTRL & SENS & PLAN & DIAG
    BR --> CM & RSP
    CTRL & SENS & DIAG --> IFACE
    SENS -->|tension| CTRL
    PLAN -->|fish effort| CM
    CTRL -->|trajectory| CM
    

The sim-to-real switch

The use_sim launch argument is resolved at xacro preprocess time, which swaps the <hardware> plugin in the URDF before the controller manager loads it:

Concern

use_sim:=true (simulation)

use_sim:=false (hardware)

Hardware plugin

mujoco_ros2_control

dynamixel_hardware

Controller host

MuJoCo’s bundled ros2_control_node

Standalone controller_manager

Extra ros2_control

fish_effort_controller, tension_sensor_broadcaster

(none beyond arm controllers)

Tension source

MuJoCo line stretch model (+ FTS fallback)

HX711 load cell

Disturbance

planning/fish_agent

Real fish / manual load

Sim-only URDF

fish_swim joint, tension_sensor FTS

Omitted from HW URDF

Full branching logic: bringup — Launch Orchestration.

Closed-loop control

Both modes implement the same ROS-level tension regulation loop:

        flowchart LR
    classDef sense fill:#e3f2fd,stroke:#1565c0,stroke-width:1.5px
    classDef decide fill:#e8f5e9,stroke:#2e7d32,stroke-width:1.5px
    classDef act fill:#fce4ec,stroke:#c62828,stroke-width:1.5px

    DIST["disturbance"]:::act
    ARM["2-DOF arm"]:::act
    LC["load_cell_node"]:::sense
    CTRL["tension ctrl<br/>MONITOR→HOOK→REG"]:::decide
    PTC["pos_traj_controller"]:::act

    DIST --> ARM
    ARM --> LC
    LC -->|/fishing_arm/tension| CTRL
    CTRL -->|/joint_trajectory| PTC --> ARM
    ARM -.->|/joint_states| CTRL
    

Controller internals (state machine, admittance vs force-feedback): control — Tension Controllers.

ROS 2 graphs at a glance

Simulation

        flowchart TB
    classDef node fill:#e8f4fc,stroke:#0b6e99,stroke-width:1.5px
    classDef sim fill:#fff3e0,stroke:#e65100,stroke-width:1.5px
    classDef ctrl fill:#e8f5e9,stroke:#2e7d32,stroke-width:1.5px
    classDef infra fill:#f3e5f5,stroke:#6a1b9a,stroke-width:1.5px
    classDef topic fill:#fafafa,stroke:#757575,stroke-width:1px,font-size:11px

    subgraph lane1["Lane 1 · Disturbance (sim only)"]
        direction LR
        FISH["fish_agent<br/><i>planning</i>"]:::sim
        T_FISH["/fish_effort_controller/commands"]:::topic
        FEC["fish_effort_controller"]:::sim
        MJ1["mujoco_ros2_control"]:::sim
        FISH --> T_FISH --> FEC --> MJ1
    end

    subgraph lane2["Lane 2 · Arm control loop"]
        direction LR
        CTRL["admittance / force_feedback<br/><i>control</i>"]:::ctrl
        T_TRAJ["/position_trajectory_controller/joint_trajectory"]:::topic
        PTC["position_trajectory_controller"]:::ctrl
        MJ2["mujoco_ros2_control"]:::sim
        JSB["joint_state_broadcaster"]:::infra
        T_JS["/joint_states"]:::topic
        CTRL --> T_TRAJ --> PTC --> MJ2 --> JSB --> T_JS --> CTRL
    end

    subgraph lane3["Lane 3 · Tension sensing"]
        direction LR
        MJ3["mujoco_ros2_control"]:::sim
        TSB["tension_sensor_broadcaster"]:::sim
        T_WRENCH["/tension_sensor_broadcaster/wrench"]:::topic
        LC["load_cell_node<br/><i>sim_fts</i>"]:::node
        T_TEN["/fishing_arm/tension"]:::topic
        MJ3 --> TSB --> T_WRENCH --> LC --> T_TEN --> CTRL
    end

    subgraph lane4["Lane 4 · TF & logging (optional)"]
        direction LR
        RSP["robot_state_publisher"]:::infra
        T_TF["/tf · /tf_static"]:::topic
        REC["recorder<br/><i>record:=true</i>"]:::node
        RSP --> T_TF -.-> LC
        T_JS -.-> REC
        T_TEN -.-> REC
    end

    MJ1 ~~~ MJ2
    MJ2 ~~~ MJ3
    

Detailed node/topic tables: Simulation ROS 2 Graph.

Hardware

        flowchart TB
    classDef node fill:#e8f4fc,stroke:#0b6e99,stroke-width:1.5px
    classDef hw fill:#fce4ec,stroke:#c62828,stroke-width:1.5px
    classDef ctrl fill:#e8f5e9,stroke:#2e7d32,stroke-width:1.5px
    classDef infra fill:#f3e5f5,stroke:#6a1b9a,stroke-width:1.5px
    classDef topic fill:#fafafa,stroke:#757575,stroke-width:1px,font-size:11px
    classDef absent fill:#f5f5f5,stroke:#bdbdbd,stroke-width:1px,stroke-dasharray:4 4

    subgraph lane1["Lane 1 · Arm control loop"]
        direction LR
        CTRL["admittance / force_feedback<br/><i>control</i>"]:::ctrl
        T_TRAJ["/position_trajectory_controller/joint_trajectory"]:::topic
        PTC["position_trajectory_controller"]:::ctrl
        CM["controller_manager<br/><i>dynamixel_hardware</i>"]:::hw
        DX["Dynamixel XL430<br/>Joint_1 · Joint_2"]:::hw
        JSB["joint_state_broadcaster"]:::infra
        T_JS["/joint_states"]:::topic
        CTRL --> T_TRAJ --> PTC --> CM <-->|pos / fbk| DX
        CM --> JSB --> T_JS --> CTRL
    end

    subgraph lane2["Lane 2 · Tension sensing"]
        direction LR
        HX["HX711 load cell"]:::hw
        LC["load_cell_node<br/><i>hardware</i>"]:::node
        T_TEN["/fishing_arm/tension"]:::topic
        HX -->|"ADC"| LC --> T_TEN --> CTRL
    end

    subgraph lane3["Lane 3 · TF & bring-up test"]
        direction LR
        RSP["robot_state_publisher"]:::infra
        T_TF["/tf · /tf_static"]:::topic
        HWC["hardware_check<br/><i>optional</i>"]:::node
        RSP --> T_TF
        HWC -.-> T_TRAJ
        T_JS -.-> HWC
        T_TEN -.-> HWC
    end

    subgraph lane4["Sim-only (absent on hardware)"]
        direction LR
        X1["fish_agent"]:::absent
        X2["fish_effort_controller"]:::absent
        X3["tension_sensor_broadcaster"]:::absent
        X4["MuJoCo / recorder"]:::absent
    end
    

Detailed node/topic tables: Hardware ROS 2 Graph.

Packages at a glance

Package

Build type

Role

bringup — Launch Orchestration

ament_cmake

Top-level launch orchestration, controller config.

control — Tension Controllers

ament_python

Admittance & force-feedback tension controllers.

sensors — Line Tension Sensing

ament_python

FishingTension publisher (HX711 or sim stretch model).

planning — Virtual Fish (Simulation Only)

ament_python

Virtual fish disturbance (sim only).

diagnostics — Recording & Bring-Up Tests

ament_python

Run recorder + hardware bring-up self-test.

description — Robot Model Assets

ament_cmake

URDF/xacro, MuJoCo MJCF, STL meshes.

interfaces — Custom Messages

ament_cmake

FishingTension.msg.

Layered architecture

        flowchart TB
    subgraph L0["Layer 0 — Physical"]
        SIM["MuJoCo physics + tendon"]
        HW["Dynamixel + HX711"]
    end
    subgraph L1["Layer 1 — ros2_control"]
        CM["controller_manager / mujoco_ros2_control"]
        CTRL["joint_state_broadcaster · position_trajectory_controller"]
        SIMCTRL["fish_effort · tension_sensor (sim)"]
    end
    subgraph L2["Layer 2 — Application (Python)"]
        APP["control · sensors · planning · diagnostics"]
    end
    subgraph L3["Layer 3 — Orchestration"]
        BR["bringup/robot.launch.py"]
    end
    L0 --> L1
    L1 --> L2
    L3 --> L1
    L3 --> L2
    

Data-flow summary

Signal

Sim origin

HW origin

Consumer(s)

Joint positions

MuJoCo → joint_state_broadcaster

Dynamixel encoders

control, diagnostics

Line tension

Stretch model / FTS → load_cell_node

HX711 → load_cell_node

control, diagnostics

Joint commands

controlposition_trajectory_controller

same

MuJoCo / Dynamixel

Fish force

fish_agentfish_effort_controller

N/A

MuJoCo only

Auto-generated topic index: ROS 2 Topic & Node Reference.