planning — Virtual Fish (Simulation Only)¶
The planning package provides an environmental disturbance source for
MuJoCo simulation. It models a fish fighting on the line without any direct
coupling to the tension controller.
Source: software/src/planning/planning/fish_agent.py
Python API: planning
Config: config/fish_params.yaml
Important
fish_agent is launched only when use_sim:=true. It does not run on
real hardware — the disturbance there comes from an actual fish (or manual load).
Design: indirect coupling¶
The fish never publishes to the controller. The causal chain is:
flowchart LR
classDef agent fill:#fff3e0,stroke:#e65100,stroke-width:1.5px
classDef physics fill:#e8f5e9,stroke:#2e7d32,stroke-width:1.5px
classDef sensor fill:#e3f2fd,stroke:#1565c0,stroke-width:1.5px
FA["fish_agent"]:::agent
MOTOR["fish_force motor"]:::physics
FISH["fish body"]:::physics
TENDON["line tendon<br/>k·ΔL + c·ΔL̇"]:::physics
ROD["rod tip"]:::physics
LC["load_cell_node<br/>stretch / FTS"]:::sensor
CTRL["tension controller"]:::sensor
FA -->|effort| MOTOR --> FISH --> TENDON --> ROD
ROD -->|FTS or TF length| LC -->|FishingTension| CTRL
fish_agentpublishes effort commands.fish_effort_controller(ros2_control) forwards them to MuJoCo’sfish_forcemotor.MuJoCo applies force on the
fish_swimprismatic joint.The line tendon transmits force to the rod tip.
sensors — Line Tension Sensing measures resulting tension.
control — Tension Controllers reacts to measured tension.
This mirrors real fishing: the controller only sees the load cell, not the fish.
Node: fish_agent¶
Disturbance model¶
Sinusoidal “fight” superimposed on a steady pull:
force(t) = mean_force + amplitude * sin(2π * frequency * t)
Default profile (from fish_params.yaml):
Parameter |
Value |
Meaning |
|---|---|---|
|
3.5 N |
Steady pull — centred on controller |
|
1.2 N |
Fight oscillation peak |
|
0.5 Hz |
Thrash rate |
|
50 Hz |
Command update rate |
ROS 2 interfaces¶
Direction |
Topic |
Type |
|---|---|---|
Publish |
|
|
The message data field contains a single element: effort in Newtons applied
along the fish slide joint axis.
ros2_control path¶
Configured in bringup/config/controllers.yaml:
fish_effort_controller:
ros__parameters:
joints: [fish_swim]
interface_name: effort
The spawner runs only in sim (robot.launch.py, IfCondition(use_sim)).
URDF / MJCF requirements¶
The fish exists only in simulation:
URDF (
fishing-robot.urdf.xacro):fish_link+fish_swimprismatic joint gated onuse_sim.MJCF (
fishing-robot_sim.xml): fish body,fish_forcemotor, line tendon.
See description — Robot Model Assets for asset details.
Interactions¶
Component |
Interaction |
|---|---|
Includes |
|
|
Subscribes to commands; writes effort to MuJoCo |
Indirect — fish force → line tension → |
|
Indirect — regulates tension caused by fish |
|
diagnostics — Recording & Bring-Up Tests / |
Logs resulting joint/tension time series |
Tuning tips¶
Increase
amplitudeorfrequencyto stress-test controller stability.Match
mean_forcetotarget_tensioninparams.yamlfor steady-state tracking tests.Disable fish entirely by not launching planning (would require custom launch) or set
mean_force:=0 amplitude:=0.
Launch¶
# Included automatically in sim bringup; standalone:
ros2 launch planning fish.launch.py
Only useful when fish_effort_controller is already active in MuJoCo.