Skip to content

BlueBoat: assemble the chassis and props from the PR #83 Blender scene - #85

Open
bsb808 wants to merge 11 commits into
lyricalfrom
bsb/blueboat-blend-assembly
Open

bsb808 wants to merge 11 commits into
lyricalfrom
bsb/blueboat-blend-assembly

Conversation

@bsb808

@bsb808 bsb808 commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

Overview

This PR modifies the URDF xacro assemble. Key parts of the work are

  • De-scoped the Blue Boat assembly to just the chassis and two props for reasons already discussed. I added the ping sensor (without the bracket) and the IMU back in as functional sensors, but without th evisuals.
  • Once Rslee/blueboat source assembly #83 is merged, this will use the new gltf-robotics compliant glb files
  • All parts use their native coordinate systems (blender -> gltf -> {Gazebo, RVIZ} )
  • Uses the Blender assembly from the artist to deterimine the assembly.
  • Changed names of slots from motor_* to prop_*. The parts are propellers - the motors are in the hull. And this is consistent with the part names.
  • Visual orientation in gz sim and RVIZ. Applies the coordinate conventions from gltf-robotics
  • Slot joint axis: the scene mounts each prop with a 180° yaw, which points the prop's own +x, its spin axis 1 0 0, aft. Technically, we may want to have Ryan flip the axis of the prop models, but I'd like to leave that for future work.
  • Updated docs to be consistent with the changes.
  • worlds/parts_check.sdf regenerated; it was already stale before this branch. This is partially vestigial, but worth keeping around.
  • This also clears the CI flag that was introduced when force merging Rslee/blueboat source assembly #83

Assembly geometry from Blender scene

Because this is not evident from the repo, here is how the offsets in blueboat_chassis.urdf.xacro, I added comments to the file on where the offsets came from.

Basically,

  1. Ryan provided the .blend file for the assembly (boat and two props)
  2. Exported via blender - the full assembly
  3. Used gltf-summary from gltf-robotics extract the node transforms
  4. Those offsets were then used in blueboat_chassis.urdf.xacro to position the parts relative to the chassis

This worked well, but isn't captured in the PR.

Tests

IMHO, main has/had quite a bit of test bloat. It appears that the tests were generated based on the one configuration with no affordance for the user configuation to change. So any change to the config, requries a change to the tests. Anything other that the full default blueboat config failed dozens of tests.

Looks like tests were written against the one vehicle the repo shipped and it captured that vehicle faithfully. Now that the configuration is meant to change, some of those tests were checking the example rather than the rules behind it. The changes, all in the three BlueBoat test files:

I supervised CC in modifying the tests:

  • Removed: two tests and one assertion whose subject was the contents of the shipped config. The config is mutable, not static.
  • Given their own vehicle: about a dozen tests whose subject is a rule (thrusters follow the propeller parts, sensor frames resolve in TF, ArduPilot channels follow topic overrides, slots chain through their parent part, the bridge and the model agree) built their vehicle by reading the shipped config, swapping its parts: or editing its text. They now build it from a fixture (make_config() / kit_config(): the shipped hull and namespace with slot_defaults: true), so the shipped config can change.
  • Widened: the Ping below waterline check now runs on the kit and on the shipped config whenever it fits a Ping; the two visual rotation checks accept both the earlier and the profile glTF conventions.

Result: all 198 (!!) remaining tests pass across bluerobotics_parts, both BlueBoat packages, bluerobotics_teleop and both BlueROV2 packages, launch tests included.

For the reviewer: please verify visually

These checks are visual and require human judgement.

Follow the /bluerobotics_models/docs/vehicles/blueboat/running.md instructions. I added some images of the coordinate systems.

  • Check assembly in both Gazebo and RVIZ
  • The base_link frame is consistent with ISO 9787 / ROS REP 103 (x forward, y left, z up) relative to the chassis geometry in both Gazebo and RVIZ. I added example images to src/bluerobotics_models/docs/vehicles/blueboat/running.md.
  • Check the details of the assembly - that the props are mounted in the correct location and orientation.
  • Thrust direction. Publish data: 0.3 on /blueboat/prop_port/cmd and /blueboat/prop_stbd/cmd: the boat moves toward +X (measured at about 2 m/s). The reason to test this is the flip in axis noted above.

Known and open

  • BlueROV2's tests use the same two patterns (snapshots of the shipped default, fixtures built from the shipped file). The tests currently pass, but will likely need to be modified when we re-configure the ROV.

Base automatically changed from rslee/blueboat-source-assembly to lyrical October 18, 2026 23:17
bsb808 and others added 11 commits October 18, 2026 16:30
An increment to simplify the assembly while the prop offsets are worked
out from the .blend scene: the vehicle is now just blueboat_chassis and
the two M200 propellers.

- assembly.xacro: opt-in slot defaults. A config's `slot_defaults: false`
  leaves every slot without a config entry empty, so the config lists what
  IS fitted rather than what is removed. Omitted or true keeps the old
  fill-every-slot behavior (BlueROV2 unchanged). Passed by both
  blueboat.urdf.xacro and model.sdf.xacro; accepted by the config check.
- blueboat.yaml: slot_defaults: false, parts list the two props; flag,
  Ping2 kit, Ping, mast and payload kept as commented entries.
- Rename the chassis slots motor_port/motor_stbd to prop_port/prop_stbd:
  the part is the propeller, matching the mesh names. Instance, joint and
  topic names follow (/blueboat/prop_port/cmd). Updated in the ArduPilot
  channels, the teleop mixer and the tests; docs/ not yet.
- worlds/parts_check.sdf regenerated; it was already stale before this.

Known: 12 tests fail because they expect the shipped config to give the
full vehicle (flag, Ping) or edit its `parts: []` text; all pass but one
with slot_defaults true, and that one is the `parts: []` edit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Part of the same de-scoping increment as 850e769: the documentation now
matches how the BlueBoat's parts are configured.

- slot_defaults: documented in design/slots.md (rule and resolution
  diagram), the configuration keys table, the BlueBoat configuration and
  index pages, and change-parts (how the recipes read with defaults on or
  off, plus a "Fit the Ping2 kit" recipe listing mount and Ping).
- The shipped config fits the chassis and two props only: first-simulation
  drops the echosounder step, and the BlueBoat actuators/sensors tables say
  "Fitted in the shipped config" (the Ping now no).
- motor_port/motor_stbd renamed prop_port/prop_stbd in slot tables, TF
  examples and topics. docs/specs/ left as the historical record.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ified

The main result of this increment: base_link's frame is verified to follow
ISO 9787 / REP 103 (x forward, y left, z up) against the PR #83 chassis
geometry in Gazebo. The check was visual, in a visuals only spike world
(~/maritime_ws/spike/blueboat_frames, not in the repo) generated from the
real Gazebo flavoured expansion: one link, one visual, an ISO reference
triad beside the boat, View > Frames showing just the link and glTF frames
as in gltf-robotics docs/walkthroughs/coordinate_orientation_demo.md.

- parts.xacro: part_visual takes axes:=gltf for deliveries in the Honu glTF
  Asset Profile's axes (+x left, +y up, +z forward): rpy 1.5708 0 1.5708 for
  Gazebo, 0 0 1.5708 for RViz from Lyrical on (it adds the roll itself), as
  the walkthrough sets. axes:=legacy (default) keeps the old rotation for
  the earlier exports.
- blueboat_chassis, m200_weedless_prop_ccw/_cw opt in with axes="gltf".
  Rotated into base_link, the chassis mesh is 1.19 m along x and 0.93 m
  along y, on the colliders. Prop slot poses are unchanged.
- The two tests that pinned one visual rotation per flavour accept both.
- worlds/parts_check.sdf regenerated: the three parts' visual poses only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The prop_port / prop_stbd slot poses now come from the glTF export of the
Blender assembly (source_files/blueboat_assembly/
blueboat_chassis__ASSEMBLED_NODES.glb, PR #83): the prop nodes relative to
the chassis node, mapped from glTF axes to base_link's.

  prop_port  -0.52  0.301 -0.117, rpy 0 0 0 -> -0.5196  0.3016 -0.1268, rpy 0 0 3.1416
  prop_stbd  -0.52 -0.301 -0.117, rpy 0 0 0 -> -0.5196 -0.3016 -0.1270, rpy 0 0 3.1416

The scene's 180 degree yaw points the prop's own +x (its spin axis) aft,
which drove the boat astern on positive thrust (measured ~2 m/s toward -X
at cmd 0.3). Slots can now declare `axis`, the occupant's joint axis in its
own frame (entry axis:, else the slot's, else the part's), and the two
BlueBoat prop slots set -1 0 0: thrust is ahead again (~2 m/s toward +X).
The correction is in the BlueBoat mounting, not the M200 parts; whether
the export should face aft at all is open on #83.

The source and the axis reasoning are recorded in a comment in
blueboat_chassis.urdf.xacro; the parts contract, assembly.py's ad hoc slot
keys and the configuration keys reference list `axis`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d config

The shipped config fits the Ping again, free placed on base_link at the
pose the Ping2 kit gave it (0 -0.259 0), without the bracket: same name,
sensor and /blueboat/ping/range topic as before.

Tests (the three BlueBoat test files):
- Removed the checks whose subject was the shipped config's contents: the
  default parts snapshot (its invariants kept as
  test_props_spin_and_the_chassis_keeps_contact), the default Ping sensor
  test, and the "shipped default must carry the Ping" assertion.
- Rule tests that took their vehicle from the shipped config (reading it,
  swapping its parts, editing its text) now build it from a fixture,
  make_config() / kit_config(): shipped hull and namespace, slot_defaults
  true, parts stated by the test.
- The Ping below waterline check runs on the kit and on the shipped config
  whenever it fits a Ping.

All 187 tests pass across bluerobotics_parts, blueboat_description,
blueboat_gazebo, bluerobotics_teleop, bluerov2_description and
bluerov2_gazebo, launch tests included.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The base_link frame in Gazebo, base_link with the glTF visual frame, and
the TF frames in RViz, showing the geometry against the ISO / REP 103
convention.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Stamped with gltf-manifest from bluerobotics_parts/commissions/commission-blueboat.yaml
(gltf-robotics workflow Step 3); gltf-check reports all three compliant.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A stray 'ap' before '# Architecture' left the page without an H1, which
Sphinx -W reports twice (myst.header) and fails the docs build.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@bsb808
bsb808 force-pushed the bsb/blueboat-blend-assembly branch from 1da095c to afa003e Compare October 18, 2026 23:34
@bsb808
bsb808 requested a review from j-rivero October 18, 2026 23:40
@bsb808
bsb808 marked this pull request as ready for review October 18, 2026 23:40
@bsb808 bsb808 mentioned this pull request Oct 19, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant