Skip to content

Refine and sync colliders for all variants - #23

Merged
T-K-233 merged 6 commits into
mainfrom
feat/collider-refit
Oct 10, 2026
Merged

T-K-233 merged 6 commits into
mainfrom
feat/collider-refit

Conversation

@T-K-233

@T-K-233 T-K-233 commented Oct 9, 2026 •

Copy link
Copy Markdown
Member

Summary

Refits the colliders of every Lite variant.

  • Shoe (lite_biped, lite, lite_pro): seven r8 capsules across each sole, ends 4 mm inside the outline. This replaces the 11 spheres of the biped and the 2 boxes of lite and lite_pro. The optional flat-bottomed sole hull is in a separate PR, Ship an optional flat-bottomed sole hull for lite_biped #24.
  • Body (all six variants): one capsule per segment, the same in every variant that has it.
  • Excludes: physics.json takes an exclude list of body pairs. The four legged variants exclude pelvis ↔ <side>_hip_roll, because the hip-motor capsule overlaps both butt capsules at rest.
  • Fresh Onshape export of lite, lite_pro, lite_bimanual and lite_biped_debug (see below).
Segment Collider Body
pelvis r69 capsule over the pelvis block; r52 capsule across both hip-pitch motors, on their axes pelvis
butt r51 capsule flush with the rear face of the shell (24°) <side>_hip_roll
thigh r55 capsule, hip-yaw axis to knee axis <side>_hip_yaw
shank r44 capsule, knee to ankle <side>_knee_pitch
torso r74 and r58 spheres on the torso axis chest
head r97 capsule, 234 mm head
upper arm, forearm r35, r32 capsules (wrist_yaw has none) <side>_shoulder_yaw, <side>_elbow_pitch
hand 2–3 capsules over the palm and the fingers <side>_hand
shoe 7 r8 capsules across the sole (debug foot: the box) <side>_foot

Fit rules: first fit a contact face flush (the sole, the rear of the butt). Then fit for the coverage of the whole shell. A capsule that crosses a joint is on the joint axis. Where two capsules touched but their shells did not, in rest poses and single-joint sweeps, the capsule ends became shorter by 10 mm or less. The radii did not change. Contacts where the shells also touch stay, for example the forearm on the hip motors with the arms down. Each scad file tells why its collider has its shape.

Impact

Variant Colliders Shell > 5 mm outside every collider (zero pose)
lite_biped 26 → 22 72% → 28%
lite_biped_debug 6 → 10 66% → 24%
lite, lite_pro 17 → 35 58–59% → 26–27%
lite_dummy 12 → 11 54% → 52% (the chest mount has no collider)
lite_bimanual 11 → 10 67% → 58% (the chest mount has no collider)

Shoe, measured on lite_biped against the 11 spheres. Drops are of a free 8 kg foot, 256 per case:

11 spheres 7 capsules
underside within 3 mm of a collider 5% 36% (before the 4 mm inset)
step time, flat / rough terrain (mujoco-warp, 4096 worlds) – +3 to +5% / −23 to −25%
stays on a step edge (side over the edge, centre over the step) 58–60% 97%
lands turned over on ±2 cm bumps 12–14% 23–24%

The 4 mm inset of the capsule ends increased the turn-overs on bumps from 16–18% to 23–24%.

Names change for consumers. The thigh moves from <side>_hip_roll_collision_0 (old: a 250 mm capsule along the hip-yaw axis) to <side>_hip_yaw_collision_0. <side>_hip_roll_collision_0 is now the butt. lite-motion-tracking's LEG_COLLISION_EXPR must add hip_yaw, so that the thigh continues to collide. berkeley-humanoids/lite-motion-tracking#6 does this.

With the arm colliders on, a retargeted LAFAN1 clip puts the arms into the torso and pelvis colliders in more frames than before, mostly where the shells also touch. lite-motion-tracking collides the legs only.

Fresh Onshape export

The fresh export was converted offline (onshape-to-robot --convert) from its robot.pkl and part meshes, with the scad files of this branch. Changes against the previous export:

Change
lite, lite_pro mass They carry the lite_biped legs: the same link masses. Total mass 32.2 → 25.2 kg (lite) and 33.3 → 26.3 kg (lite_pro). Per leg: pelvis 3.97 → 2.10, hip_pitch 0.62 → 0.18, hip_roll 1.30 → 0.93, hip_yaw 2.09 → 1.54, knee_pitch 0.44 → 0.23, ankle_yaw 1.43 → 1.03, ankle_pitch 0.18 → 0.34, foot 1.21 → 0.44 kg.
lite, lite_pro shoe The older shoe, with a 12 mm shorter heel, is gone. The foot mesh is now the biped shoe, vertex for vertex. Its part frame moved 5 mm, so the foot scad files are now those of lite_biped. The sole capsules do not move. Now they agree with the shoe outline.
Joint limits ankle_yaw ±45° → ±90° (lite, lite_pro, as on the biped). shoulder_yaw ±90° → ±120°, and wrist_yaw ±120° on both sides, where one side stopped at 90° (lite, lite_pro, lite_bimanual). The lite_bimanual ros2_control limits follow.
lite_biped_debug The foot is now a front and a rear part. Foot mass 0.326 → 0.310 kg, mesh within 4 mm.
lite_bimanual Hand mass 0.1675 → 0.1677 kg.
Other Joint origins and axes do not change. The other meshes change by 1–2 mm (a new simplification), with the same area.

lite_biped and lite_dummy are not re-exported. The "Sim Biped" configuration now gives the debug foot, so it does not give the lite_biped shoe. The other lite_biped links agree with the fresh export.

Check of the colliders. The export gives the exact part frame of every scad file. The frames that were inferred for <side>_hip_yaw, waist and <side>_elbow_pitch are correct to 2 µm. Against the assumed frame, the head frame turns 180° about the head axis. Thus an export put the head capsule 19.5 mm too far back. head.scad is now written in the exact frame (also in lite_dummy, which has the same Head part). With this fix, the export reproduces the colliders of this branch in all four variants.

How the colliders were written

The capsules were fitted in link frames. The scad files hold them in Onshape part frames.

  • Existing scad files: the part frame of each of the 49 files was recovered from its URDF collisions, all within 7 µm.
  • New scad files (<side>_hip_yaw; <side>_elbow_pitch; waist on the bipeds): they take the part frame of their neighbours.
    • The leg parts share one frame. The cached Onshape meshes of Hip Yaw and Waist confirm it to 0.3 mm.
    • The elbow takes the frame that the shoulder and wrist parts share.
  • URDF hub: its collisions were computed from the scad files through the parser of onshape-to-robot, as an export does. Then the MJCF and xacro were regenerated.
  • Consistency: the same part gives a byte-identical scad file in every variant.

This step did not use an Onshape export.

Test plan

  • pytest: 1605 passed, 36 skipped (adds exclude tests)
  • STE and clean-code pass: each scad file parses to the same shapes
  • lite-description-generate <variant> --only urdf,mjcf,xacro reproduces the committed files for all six variants
  • Every MJCF collider matches the fitted set to 7 µm and 0.006°
  • Every existing scad file reproduces its old URDF collisions under the recovered part frames (49 files, ≤ 7 µm)
  • Fresh Onshape export (lite, lite_pro, lite_bimanual, lite_biped_debug): the colliders do not change, after the head frame fix
  • pytest after the re-export: 1605 passed, 36 skipped
  • Confirm the wider shoulder_yaw and wrist_yaw limits (±120°) on the bimanual hardware before a deploy

🤖 Generated with Claude Code

https://claude.ai/code/session_01HpFUBhqSfbDuibPRVhscr9

@T-K-233 T-K-233 changed the title Refit the colliders: one capsule per segment, and a seven-rod shoe Refine and sync colliders for all variants Oct 9, 2026
T-K-233 and others added 6 commits October 9, 2026 12:03
The biped shoe collided through 11 r8 spheres. They supported only 5% of
the underside of the shoe. A foot that fell with its side over a step
edge slid off and turned over in 40-42% of the drops, also with its
centre over the step, because the edge was between two spheres. lite and
lite_pro used two boxes from an older, shorter shoe.

The three variants now share one shoe: seven r8 capsules across the
sole, at equal intervals from the heel tip to the toe tip. The centres
of the capsule ends are on the sole outline. The five capsules under the
flat sole are flush with it, 65 mm below the foot origin, where the
training foot site is. The last two follow the toe spring. The MJCF
stage changes the scad cylinders into capsules.

Measured on lite_biped against the 11 spheres. Step time: mujoco-warp,
4096 worlds, the solver settings of the velocity task. Drops: a free
8 kg foot, 256 drops per case.

                                   spheres   7 capsules
  underside within 3 mm            5%        36%
  flat ground step time            -         +3 to +5%
  rough terrain step time          -         -23 to -25%
  stays on a step edge (side over
  the edge, centre over the step)  58-60%    97%
  lands turned over on bumps       12-14%    16-18%

The foot collisions of the URDF hub come from the new scad files,
without an Onshape export. The OpenSCAD parser of onshape-to-robot reads
each foot scad file, and a map from the part frame to the link frame
gives the URDF collisions. The map gives the old spheres and boxes, and
the new capsules, to 4 um. The MJCF and xacro of the three variants are
regenerated. Only the foot geoms change.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HpFUBhqSfbDuibPRVhscr9
The centres of the capsule ends were on the sole outline. Thus each
round end extended a full radius, 8 mm, past the shoe. Now the centres
are half a radius inside the outline. The ends extend 4 mm, and each
capsule is 8 mm shorter.

The flat sole goes to the outline. Thus on flat ground, the contact
points are now 4 mm inside the real sole edge on each side: 76 mm apart
at the widest capsule, against 84 mm of shoe. The narrower support has
an effect when the foot rolls. Drops of a free 8 kg foot, 256 drops per
case, against the capsules with their end centres on the outline:

                                   centres on   centres 4 mm
                                   outline      inside
  stays on a step edge (side over
  the edge, centre over the step)  97%          97%
  lands turned over on bumps       16-18%       23-24%
  roll pivot error vs the shell    1.6 mm       2.8 mm

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HpFUBhqSfbDuibPRVhscr9
physics.json takes an "exclude" list of body pairs. The MJCF stage
writes one <contact><exclude> for each pair. MuJoCo drops the contacts
of a body with its parent only. A collider that overlaps a body farther
down the chain at rest needs an explicit exclude.

A physics.json that sets no <option> attribute, only a comment and
excludes, gives no empty <option> element.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HpFUBhqSfbDuibPRVhscr9
The body colliders were scad primitives of different ages, put in
position by hand:

- a 250 mm capsule on hip_roll, along the hip-yaw axis, for the thigh
- a 210 mm head capsule with the shape of a disc
- one box for each hand, and one for the chest
- short capsules on the shoulder and wrist links
- no collider on the biped pelvis or on the hip-pitch motors

At the zero pose, 59-70% of the visual shell of lite, lite_pro and
lite_biped was more than 5 mm outside all colliders.

Now each segment has one capsule, the same in each variant that has the
segment:

  pelvis     r69 on the pelvis block. r52 across both hip-pitch
             motors, on the hip-pitch axes, to the outer faces of the
             motors.
  butt       r51 on hip_roll, flush with the rear face of the shell.
             That face leans 24 deg from vertical.
  thigh      r55 on hip_yaw, from the hip-yaw axis to the knee axis. It
             leans 3.95 deg from the hip-yaw axis, so that the knee end
             does not extend past the front of the knee.
  shank      r44 on knee_pitch, from the knee to the ankle.
  torso      r74 and r58 spheres on the torso axis. The radii are
             limited so that the upper arms can hang down without
             contact.
  head       r97, 234 mm, on the axis of the old head capsule. It is
             fitted to the shell, then moved 10 mm forward, with the
             radius 5 mm larger and the bottom 10 mm lower. This covers
             the cheeks and the jaw.
  upper arm  r35 on shoulder_yaw, from the shoulder outline to the
             elbow.
  forearm    r32 on elbow_pitch, from the elbow to the wrist. wrist_yaw
             has no collider.
  hand       lite, lite_pro: two capsules on the palm and the fingers,
             and one on the thumb. dummy, bimanual: one capsule on the
             palm, and one on the finger.

The rules of the fit:

- First fit a contact face flush (the rear of the butt, the sole). Then
  fit for the coverage of the whole shell.
- Put a capsule that crosses a joint on the joint axis.
- Where two capsules touched but their shells did not, in rest poses and
  single-joint sweeps, make the capsule ends shorter by 10 mm or less.
  Do not change the radii.
- Keep the contacts where the shells also touch, such as the forearm on
  the hip motors with the arms down.

At rest, the hip-motor capsule overlaps both butt capsules. Thus
physics.json excludes pelvis <-> hip_roll on the four variants with
legs. Each scad file tells why its collider has its shape.

                     colliders   shell more than 5 mm outside
                                 all colliders
  lite_biped         18 -> 22    70% -> 28%
  lite_biped_debug    6 -> 10    66% -> 24%
  lite, lite_pro     27 -> 35    59-60% -> 26-27%
  lite_dummy         12 -> 11    54% -> 52%
  lite_bimanual      11 -> 10    67% -> 58%

The dummy and bimanual values include their chest mounts. No collider
covers the chest mounts.

The capsules were fitted in link frames, and the scad files hold them
in part frames. The URDF collisions of each of the 49 old scad files
gave its part frame, all within 7 um. The new files (<side>_hip_yaw,
<side>_elbow_pitch, and waist on the bipeds) use the part frame of their
neighbours. The leg parts share one frame, and the cached Onshape meshes
of Hip Yaw and Waist confirm it to 0.3 mm. The elbow uses the frame that
the shoulder and wrist parts share.

Then the parser of onshape-to-robot read the scad files and gave the
URDF hub collisions, as an export does. The MJCF and xacro are
regenerated. The same part gives the same scad file, byte for byte, in
all variants. The MJCF agrees with the fitted set to 7 um and 0.006 deg.
The two torso capsules had a 0.1 mm half-length, and are now spheres.

The next Onshape export must not change the collision blocks of the
URDF. A change there shows that a part frame is incorrect.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HpFUBhqSfbDuibPRVhscr9
A fresh Onshape export gives the exact part frame of Head in lite and
lite_pro. This frame turns 180 deg about the axis of the old head disc,
against the frame that head.scad assumed. A centred disc did not show
the difference. In the assumed frame, the scad put the head capsule
9.75 mm behind the part origin, not 9.75 mm in front of it. Thus an
export moved the capsule by 19.5 mm.

head.scad now holds the capsule in the exact frame. lite_dummy has the
same Head part and gets the same change. The URDF and MJCF do not
change.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HpFUBhqSfbDuibPRVhscr9
…hape

The hubs are converted offline (onshape-to-robot --convert) from the
robot.pkl and part meshes of a fresh export, with the scad files of
this branch. Changes against the previous export:

- lite and lite_pro carry the lite_biped legs: the same link masses and
  the same shoe mesh, vertex for vertex. Total mass: lite
  32.2 -> 25.2 kg, lite_pro 33.3 -> 26.3 kg. Per leg: pelvis
  3.97 -> 2.10 kg, hip_pitch 0.62 -> 0.18, hip_roll 1.30 -> 0.93,
  hip_yaw 2.09 -> 1.54, knee_pitch 0.44 -> 0.23, ankle_yaw
  1.43 -> 1.03, ankle_pitch 0.18 -> 0.34, foot 1.21 -> 0.44.
- The older lite shoe, with a 12 mm shorter heel, is gone. Its part
  frame moved 5 mm, so the foot scad files of lite and lite_pro are now
  those of lite_biped. The sole capsules do not move in the URDF. Now
  they agree with the shoe outline, as on the biped.
- Joint limits of lite and lite_pro: ankle_yaw +-45 -> +-90 deg, as on
  the biped.
- Joint limits of lite, lite_pro and lite_bimanual: shoulder_yaw
  +-90 -> +-120 deg. wrist_yaw is now +-120 deg on both sides. Before,
  one side stopped at 90 deg. The lite_bimanual ros2_control limits
  follow.
- lite_biped_debug: the foot is now a front part and a rear part. Foot
  mass 0.326 -> 0.310 kg, mesh within 4 mm.
- lite_bimanual: hand mass 0.1675 -> 0.1677 kg.
- Joint origins and axes do not change. The other meshes change by
  1-2 mm (a new simplification), with the same area.
- The colliders do not change: the export gives the colliders of this
  branch again. This confirms the part frames of <side>_hip_yaw, waist
  and <side>_elbow_pitch to 2 um.

config.json: lite now exports from the "Humanoid Export" assembly of
workspace 26c0b8ae0ee1fec90698ed7b, and lite_bimanual from "Bimanual".

lite_biped and lite_dummy are not re-exported. The "Sim Biped"
configuration now gives the debug foot, so it does not give the
lite_biped shoe. The other lite_biped links agree with the fresh export.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HpFUBhqSfbDuibPRVhscr9
@T-K-233
T-K-233 force-pushed the feat/collider-refit branch from a47774e to 3ca918a Compare October 9, 2026 19:12
@T-K-233
T-K-233 merged commit 206979d into main Oct 10, 2026
2 checks passed
@T-K-233
T-K-233 deleted the feat/collider-refit branch October 10, 2026 00:12
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