Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,8 @@
author = 'Honu Robotics'

extensions = ['sphinx_honu']

# Anchors for headings down to ###, so a page can link to a section
# (`page.md#section-title`) in a way GitHub renders too.
myst_heading_anchors = 3
honu_github = ('HonuRobotics', 'bluerobotics_models')
2 changes: 0 additions & 2 deletions docs/design/buoyancy.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,6 @@ contact geometry. The box itself never collides (`collide_bitmask`
`0x00`). The same pattern as the BlueBoat's pontoons, with the box solved
instead of declared.

(marked-for-any-world)=

## Marked for any world

The displacement collisions of both vehicles carry `gz:buoyancy="true"`.
Expand Down
4 changes: 2 additions & 2 deletions docs/design/gazebo-composition.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ side never held a coordinate.
`generate_bridge_config.py` reads the fitted instances from the URDF's
`<assembly_part>` manifest and emits one bridge entry per topic of each
part type that has topics (`PART_TOPICS`: a propeller's `/cmd` command,
the Ping's `/range`), plus `/clock` and `/<ns>/joint_states`; per instance topic
the Ping's `/range`), plus `/clock` and `/<name>/joint_states`; per instance topic
overrides come from the config entry that fitted it. Nothing about the
drivetrain is hardcoded and no topic bakes the model name. The model's
plugin and sensor topics and the bridge's topics therefore derive from the
Expand Down Expand Up @@ -78,5 +78,5 @@ launch.
| `hull_displacement` link | box pontoons from the config; `<enable>blueboat::hull_displacement</enable>` in the world |
| `gz-sim-hydrodynamics-system` | placeholder USV damping coefficients, to be identified |
| `gz-maritime-thruster-system`, one per propeller | on `<name>_joint`, normalized command scaled onto the limits and diameter from the part's `drive` table (T200 16 V placeholders today), counter rotating |
| `gz-sim-joint-state-publisher-system` | `/<ns>/joint_states`, bridged for RViz |
| `gz-sim-joint-state-publisher-system` | `/<name>/joint_states`, bridged for RViz |
| `gpu_lidar` "ping" | the Ping2 as a one ray downward range sensor at `ping_beam` |
2 changes: 1 addition & 1 deletion docs/how-to/change-parts.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Recipes for the vehicle config. The concepts (slots, defaults, free
placement) are explained in [Configuring the BlueBoat](../vehicles/blueboat/configuration.md);
the full key list is in {ref}`Configuration keys <configuration-keys>`.
the full key list is in [Configuration keys](../reference/parts-catalog.md#configuration-keys).

Start from a copy of the shipped config:

Expand Down
16 changes: 9 additions & 7 deletions docs/how-to/namespaces.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,18 @@

Every instance of a vehicle goes by one name, which is at once its Gazebo
model name and its topic namespace (`/<name>/...` for every sensor and
thruster topic, on both the Gazebo and the ROS side). By default the name is
the config's `topic_namespace` (`blueboat` or `bluerov2`). A name is letters,
thruster topic, on both the Gazebo and the ROS side). A name is letters,
digits and underscores, starting with a letter, because it also has to be a
valid ROS name; the generator refuses anything else.

`name:=` on the sim launch is passed to `configure_vehicle.py --name`, which
applies it to the config before generating the artifacts (the config actually
used is written next to them as `vehicle.yaml`), so the model name, the
plugin topics and the bridge cannot disagree. `x`, `y`, `z`, `roll`, `pitch`
and `yaw` place the instance:
The launch argument is the name. `sim.launch.xml` always passes `name:=`,
`blueboat` or `bluerov2` by default, to `configure_vehicle.py --name`, which
applies it to the config before generating the artifacts (the config
actually used is written next to them as `vehicle.yaml`), so the model
name, the plugin topics and the bridge cannot disagree. A `topic_namespace`
in a custom config is therefore overridden by the launch; it only names the
instance when the generator runs without `--name`. `x`, `y`, `z`, `roll`,
`pitch` and `yaw` place the instance:

```bash
ros2 launch blueboat_gazebo sim.launch.xml name:=boat_b x:=4 yaw:=1.57
Expand Down
2 changes: 1 addition & 1 deletion docs/how-to/own-world.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ cp $(ros2 pkg prefix --share blueboat_gazebo)/worlds/blueboat_water.sdf my_world

A world running gz-maritime's buoyancy system needs no `<enable>` entry:
the displacement collisions are marked, so the vehicle floats under any
spawn name ({ref}`Marked for any world <marked-for-any-world>`).
spawn name ([Marked for any world](../design/buoyancy.md#marked-for-any-world)).

## Include the default model

Expand Down
3 changes: 1 addition & 2 deletions docs/reference/parts-catalog.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ after the slot by default.
`thruster_8` and `thruster_body_1` … `thruster_body_8` and keeps the same
accessory slots.

(configuration-keys)=
## Configuration keys

The vehicle config (`<vehicle>_description/config/<vehicle>.yaml`, or any
Expand All @@ -77,7 +76,7 @@ for both vehicles:

| Key | Required | Meaning |
|---|---|---|
| `topic_namespace` | no (the vehicle name) | prefix of every part topic: `/<ns>/<name>/...` |
| `topic_namespace` | no (the vehicle name) | prefix of every part topic: `/<name>/<name>/...` |
| `base` | yes | the root part: `{type, name (default base_link), collision (default true)}` |
| `parts` | no (`[]`) | slot entries and free placements, see below |
| `slots` | no | ad hoc slots: `{of (instance, default base_link), name, xyz, rpy (default "0 0 0"), accepts (list, optional), default (type or none), joint}` |
Expand Down
19 changes: 11 additions & 8 deletions docs/vehicles/blueboat/actuators.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,15 @@ following the [Add a part](../../how-to/add-part.md) guide.
### Thrusters

Each thruster plugin subscribes to a gz transport topic. Each of those gz
topics is bridged to ROS and named after its motor:
topics is bridged to ROS and named after its motor, under the instance
name, `<name>`: `blueboat` for the default instance, which the commands
below use, or whatever the boat was spawned as
([Several vehicles](../../how-to/namespaces.md)).

| ROS Topic | Description | Message type |
|---|---|---|
| `/blueboat/motor_port/cmd` | Normalized thrust command in [-1, 1]: +1 full ahead, -1 full astern, 0 stop | [std_msgs/msg/Float64](https://docs.ros.org/en/rolling/p/std_msgs/interfaces/msg/Float64.html) |
| `/blueboat/motor_stbd/cmd` | Normalized thrust command in [-1, 1]: +1 full ahead, -1 full astern, 0 stop | [std_msgs/msg/Float64](https://docs.ros.org/en/rolling/p/std_msgs/interfaces/msg/Float64.html) |
| `/<name>/motor_port/cmd` | Normalized thrust command in [-1, 1]: +1 full ahead, -1 full astern, 0 stop | [std_msgs/msg/Float64](https://docs.ros.org/en/rolling/p/std_msgs/interfaces/msg/Float64.html) |
| `/<name>/motor_stbd/cmd` | Normalized thrust command in [-1, 1]: +1 full ahead, -1 full astern, 0 stop | [std_msgs/msg/Float64](https://docs.ros.org/en/rolling/p/std_msgs/interfaces/msg/Float64.html) |

The command is a fraction of the propeller's own limits, which the model
takes from the part's drive table - 51.5 N ahead and -40.2 N astern for a
Expand Down Expand Up @@ -61,15 +64,15 @@ under the same names), plus a speed feedback per motor:

| gz Topic | Description | Message type |
|---|---|---|
| `/blueboat/motor_<side>/cmd` | Normalized thrust command in [-1, 1] | `gz.msgs.Double` |
| `/blueboat/motor_<side>/cmd/ang_vel` | Propeller speed feedback (rad/s) | `gz.msgs.Double` |
| `/<name>/motor_<side>/cmd` | Normalized thrust command in [-1, 1] | `gz.msgs.Double` |
| `/<name>/motor_<side>/cmd/ang_vel` | Propeller speed feedback (rad/s) | `gz.msgs.Double` |

```bash
gz topic -t /blueboat/motor_port/cmd -m gz.msgs.Double -p 'data: 0.2' &
gz topic -t /blueboat/motor_stbd/cmd -m gz.msgs.Double -p 'data: 0.2' &
wait
```

Topic bases follow `/<namespace>/<instance>/...`: fit a different
propeller, rename it or leave a motor slot empty and the command topics
follow the fitted parts.
A command topic follows the part's own name: fit a different propeller,
rename it or leave a motor slot empty and the topics follow the fitted
parts ([Configuration](configuration.md)).
2 changes: 1 addition & 1 deletion docs/vehicles/blueboat/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ config entry each. The fitted options and their topics live in
| `ping_mount` | `blueboat_ping_singlebeam_mount` | the bracket (which fits the Ping in its own `ping` slot) |

Slot entries, free placements, ad hoc slots and topic overrides are
described in the {ref}`Configuration keys <configuration-keys>` and
described in the [Configuration keys](../../reference/parts-catalog.md#configuration-keys) and
walked through in [Change the fitted parts](../../how-to/change-parts.md); the
instance key is `of:`, not `on:`. Mistakes fail the build or the launch
with a message naming the problem.
18 changes: 9 additions & 9 deletions docs/vehicles/blueboat/sensors.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,17 @@ starboard hull.

| ROS Topic | Description | Message type |
|---|---|---|
| `/blueboat/ping/range` | Range to the seabed; bridged lazily, the Gazebo subscription starts with the first ROS subscriber | [sensor_msgs/msg/LaserScan](https://docs.ros.org/en/rolling/p/sensor_msgs/interfaces/msg/LaserScan.html) |
| `/<name>/ping/range` | Range to the seabed; bridged lazily, the Gazebo subscription starts with the first ROS subscriber | [sensor_msgs/msg/LaserScan](https://docs.ros.org/en/rolling/p/sensor_msgs/interfaces/msg/LaserScan.html) |

```bash
ros2 topic echo /blueboat/ping/range --once
```

Topic bases follow `/<namespace>/<instance>/...`: empty a slot and its
topics disappear, rename the instance and they follow, and per part
`topic` / `gz_topic` / `ros_topic` overrides in the config rename the
base under the namespace (one starting with a slash is used as given).
Sensor messages carry a frame the part declares as `frame_id`
(`ping_beam`, the transducer face), under the instance name
(`blueboat/ping_beam`), which is how TF carries it. Rendered sensors need
a GPU (headless EGL works).
`<name>` is the instance name, `blueboat` for the default instance, or
whatever the boat was spawned as ([Several vehicles](../../how-to/namespaces.md)).
A part topic follows the part's own name (`ping` above), so a part renamed
or removed in the config moves or drops its topics
([Configuration](configuration.md)). Sensor messages carry a frame the
part declares as `frame_id` (`ping_beam`, the transducer face), under the
instance name (`<name>/ping_beam`), which is how TF carries it. Rendered
sensors need a GPU (headless EGL works).
15 changes: 9 additions & 6 deletions docs/vehicles/bluerov2/actuators.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,14 @@ Thruster numbering, top view.
```

Each thruster plugin subscribes to a gz transport topic. Each of those gz
topics is bridged to ROS and indexed by number, starting at 1:
topics is bridged to ROS and indexed by number, starting at 1, under the
instance name, `<name>`: `bluerov2` for the default instance, which the
commands below use, or whatever the vehicle was spawned as
([Several vehicles](../../how-to/namespaces.md)).

| ROS Topic | Description | Message type |
|---|---|---|
| `/bluerov2/thruster_<n>/cmd` | Normalized thrust command in [-1, 1]: +1 full ahead, -1 full astern, 0 stop | [std_msgs/msg/Float64](https://docs.ros.org/en/rolling/p/std_msgs/interfaces/msg/Float64.html) |
| `/<name>/thruster_<n>/cmd` | Normalized thrust command in [-1, 1]: +1 full ahead, -1 full astern, 0 stop | [std_msgs/msg/Float64](https://docs.ros.org/en/rolling/p/std_msgs/interfaces/msg/Float64.html) |

The command is a fraction of the propeller's own limits, which the model
takes from the part's drive table - 51.5 N ahead and -40.2 N astern for a
Expand Down Expand Up @@ -75,7 +78,7 @@ thrusters.

| ROS Topic | Description | Message type |
|---|---|---|
| `/bluerov2/gripper/cmd_pos` | Jaw angle command, 0 rad closed to 0.6 rad open | [std_msgs/msg/Float64](https://docs.ros.org/en/rolling/p/std_msgs/interfaces/msg/Float64.html) |
| `/<name>/gripper/cmd_pos` | Jaw angle command, 0 rad closed to 0.6 rad open | [std_msgs/msg/Float64](https://docs.ros.org/en/rolling/p/std_msgs/interfaces/msg/Float64.html) |


To drive with a gamepad instead, a ready mixer for either vehicle is in
Expand All @@ -88,9 +91,9 @@ under the same names), plus a speed feedback per thruster:

| gz Topic | Description | Message type |
|---|---|---|
| `/bluerov2/thruster_<n>/cmd` | Normalized thrust command in [-1, 1] | `gz.msgs.Double` |
| `/bluerov2/thruster_<n>/cmd/ang_vel` | Propeller speed feedback (rad/s) | `gz.msgs.Double` |
| `/bluerov2/gripper/cmd_pos` | Jaw angle command | `gz.msgs.Double` |
| `/<name>/thruster_<n>/cmd` | Normalized thrust command in [-1, 1] | `gz.msgs.Double` |
| `/<name>/thruster_<n>/cmd/ang_vel` | Propeller speed feedback (rad/s) | `gz.msgs.Double` |
| `/<name>/gripper/cmd_pos` | Jaw angle command | `gz.msgs.Double` |

Command the mix **together** (`&` + `wait` publishes in parallel):

Expand Down
2 changes: 1 addition & 1 deletion docs/vehicles/bluerov2/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,6 @@ config entry each. The fitted options and their topics live in

Slot entries, free placements, ad hoc slots and topic overrides follow
the same schema as the BlueBoat
({ref}`Configuration keys <configuration-keys>`); the instance key is
([Configuration keys](../../reference/parts-catalog.md#configuration-keys)); the instance key is
`of:`, not `on:`. Mistakes fail the build or the launch with a message
naming the problem.
33 changes: 17 additions & 16 deletions docs/vehicles/bluerov2/sensors.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,34 +22,35 @@ live with the [actuators](actuators.md).

| ROS Topic | Description | Message type |
|---|---|---|
| `/bluerov2/camera/image` | Camera image | [sensor_msgs/msg/Image](https://docs.ros.org/en/rolling/p/sensor_msgs/interfaces/msg/Image.html) |
| `/bluerov2/camera/camera_info` | Camera intrinsics | [sensor_msgs/msg/CameraInfo](https://docs.ros.org/en/rolling/p/sensor_msgs/interfaces/msg/CameraInfo.html) |
| `/<name>/camera/image` | Camera image | [sensor_msgs/msg/Image](https://docs.ros.org/en/rolling/p/sensor_msgs/interfaces/msg/Image.html) |
| `/<name>/camera/camera_info` | Camera intrinsics | [sensor_msgs/msg/CameraInfo](https://docs.ros.org/en/rolling/p/sensor_msgs/interfaces/msg/CameraInfo.html) |

### Stereo camera

| ROS Topic | Description | Message type |
|---|---|---|
| `/bluerov2/stereo/image` | RGB image | [sensor_msgs/msg/Image](https://docs.ros.org/en/rolling/p/sensor_msgs/interfaces/msg/Image.html) |
| `/bluerov2/stereo/depth_image` | Depth image | [sensor_msgs/msg/Image](https://docs.ros.org/en/rolling/p/sensor_msgs/interfaces/msg/Image.html) |
| `/bluerov2/stereo/points` | Point cloud | [sensor_msgs/msg/PointCloud2](https://docs.ros.org/en/rolling/p/sensor_msgs/interfaces/msg/PointCloud2.html) |
| `/bluerov2/stereo/camera_info` | Camera intrinsics | [sensor_msgs/msg/CameraInfo](https://docs.ros.org/en/rolling/p/sensor_msgs/interfaces/msg/CameraInfo.html) |
| `/<name>/stereo/image` | RGB image | [sensor_msgs/msg/Image](https://docs.ros.org/en/rolling/p/sensor_msgs/interfaces/msg/Image.html) |
| `/<name>/stereo/depth_image` | Depth image | [sensor_msgs/msg/Image](https://docs.ros.org/en/rolling/p/sensor_msgs/interfaces/msg/Image.html) |
| `/<name>/stereo/points` | Point cloud | [sensor_msgs/msg/PointCloud2](https://docs.ros.org/en/rolling/p/sensor_msgs/interfaces/msg/PointCloud2.html) |
| `/<name>/stereo/camera_info` | Camera intrinsics | [sensor_msgs/msg/CameraInfo](https://docs.ros.org/en/rolling/p/sensor_msgs/interfaces/msg/CameraInfo.html) |

### Scanning sonar

| ROS Topic | Description | Message type |
|---|---|---|
| `/bluerov2/sonar/scan` | Horizontal range scan (modelled as a planar gpu_lidar; no acoustics) | [sensor_msgs/msg/LaserScan](https://docs.ros.org/en/rolling/p/sensor_msgs/interfaces/msg/LaserScan.html) |
| `/<name>/sonar/scan` | Horizontal range scan (modelled as a planar gpu_lidar; no acoustics) | [sensor_msgs/msg/LaserScan](https://docs.ros.org/en/rolling/p/sensor_msgs/interfaces/msg/LaserScan.html) |

### DVL

| ROS Topic | Description | Message type |
|---|---|---|
| `/bluerov2/dvl/velocity` | Bottom track velocity | [marine_acoustic_msgs/msg/Dvl](https://github.com/apl-ocean-engineering/hydrographic_msgs/blob/main/marine_acoustic_msgs/msg/Dvl.msg) |

Topic bases follow `/<namespace>/<instance>/...`: empty a slot and its
topics disappear, rename the instance and they follow, and per part
`topic` / `gz_topic` / `ros_topic` overrides in the config rename the
base under the namespace (one starting with a slash is used as given).
Sensor messages carry the part's own link as `frame_id`, under the
instance name (`bluerov2/camera`), which is how TF carries it; cameras deliberately use the body frame (x forward), not a
REP 145 optical frame.
| `/<name>/dvl/velocity` | Bottom track velocity | [marine_acoustic_msgs/msg/Dvl](https://github.com/apl-ocean-engineering/hydrographic_msgs/blob/main/marine_acoustic_msgs/msg/Dvl.msg) |

`<name>` is the instance name, `bluerov2` for the default instance, or
whatever the vehicle was spawned as ([Several vehicles](../../how-to/namespaces.md)).
A part topic follows the part's own name (`camera` above), so a part
renamed or removed in the config moves or drops its topics
([Configuration](configuration.md)). Sensor messages carry the part's own
link as `frame_id`, under the instance name (`<name>/camera`), which is
how TF carries it; cameras deliberately use the body frame (x forward),
not a REP 145 optical frame.