| name | material-override |
| description | Tune PBR metallic / roughness on URDF visual meshes without re-exporting DAE — author an inline `<material_override>` element inside any `<visual>`, and let the engine's URDF→USD pipeline patch the converter's defaults post-conversion. Useful for sim-to-real visual fidelity (DAE materials round-trip poorly; Isaac Sim's importer lands every embedded material at roughness=0.5, metallic=0.0 by default). Trigger: When the user asks to "tune material", "change roughness / metallic", "make the gripper shinier", "fix dull PBR", "override material", "PBR override", or any time the simulator looks washed out after a URDF→USD import.
|
| license | MPL-2.0 |
| metadata | {"author":"genie-sim","version":"1.0"} |
| prerequisites | ["geniesim_ros:build-workspace"] |
| inputs | [{"name":"urdf_or_xacro_path","desc":"URDF / xacro file containing the `<visual>` to tune","required":true},{"name":"roughness","desc":"PBR roughness 0..1 (omit to leave unchanged)","required":false},{"name":"metallic","desc":"PBR metallic 0..1 (omit to leave unchanged)","required":false}] |
| outputs | [{"desc":"`<material_override>` element added inside the target `<visual>`; engine regenerates `robot.usda` with patched metallic / roughness on next launch"}] |
When to Use
- Robot or asset visual meshes import with washed-out / flat
shading after the URDF→USD converter runs.
- User wants to A/B PBR values without re-exporting DAE meshes from
Blender / Maya.
- Polishing a robot for sim-to-real visual transfer.
- Author of a new URDF (see
add-robot skill) wants the meshes to
look right without round-tripping DAE materials.
Do not use for:
- Replacing albedo / textures → must be done in the DAE export.
- Per-prim material at runtime → that's a runtime USD edit, not the
<material_override> element.
- Adding a brand-new material — only patches metallic / roughness on
the embedded one.
Critical Patterns
- Author inside
<visual>, not on the link. The override
auto-scopes to exactly the mesh it sits under. A link with N
<visual> elements just gets N independent overrides.
urdfdom / RSP / MoveIt / Isaac's converter all ignore it.
assemble_robot.py strips the element from the URDF it feeds the
converter, then re-applies the values to the converted USD via
_parse_material_override_blocks / _apply_material_overrides.
- Only
roughness and metallic are exposed. Other UsdPreviewSurface
inputs (specular, opacity, IOR) are not on the contract.
- Range 0..1. Outside that range the importer warns and clamps.
- No attributes needed. Scoping is positional. Don't try to
target a sibling visual by name — author one override per visual.
Schema
<visual>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<mesh filename="package://.../base_link.dae"/>
</geometry>
<material_override>
<roughness>0.45</roughness>
<metallic>0.85</metallic>
</material_override>
</visual>
Either child is optional — author only what you need. Default for
an absent child is "leave as the converter wrote it" (typically
0.5 / 0.0 for DAE imports).
PBR cheat-sheet
| Look | roughness | metallic | Notes |
|---|
| Brushed steel | 0.40 | 0.95 | Most arm shells |
| Anodised aluminium | 0.55 | 0.30 | UR-style structural |
| Polished chrome | 0.05 | 1.00 | Decorative trims, mirror parts |
| Matte plastic | 0.70 | 0.00 | Cable guards, end-stops |
| Rubber pads | 0.85 | 0.00 | Soft contact surfaces |
| Anodised gold (gripper bushings) | 0.30 | 0.90 | Highlights |
These are starting points; A/B against a photograph of the real
robot if you have one.
Workflow
Step 1 — Find the visual you want to tune
grep -nR "<visual>" source/geniesim_ros/src/ros_ws/src/genie_sim_robot_model/robots/ | head
Step 2 — Add the override
Open the xacro, drop <material_override> into the <visual>
block. Existing reference: aloha arm xacro carries an override on
every visual:
<visual>
<origin xyz="0 0 0" rpy="0 0 0" />
<geometry>
<mesh filename="${mesh_dir}/base_link.dae" />
</geometry>
<material_override><roughness>0.45</roughness><metallic>0.85</metallic></material_override>
</visual>
Step 3 — Rebuild the workspace
geniesim ros build dev && source devel/setup.bash
Step 4 — Force a USD regenerate
The robot USD is cache-gated by manifest.json. Bust the cache:
rm -rf assets/scenes/<scene>/
ros2 launch genie_sim_bringup app.launch.py … always_regenerate_robot_usd:=true
Step 5 — Launch and inspect
ros2 launch genie_sim_bringup app.launch.py \
scene:=<scene> \
launcher_config:=launcher_ovrtx_isaac_physx \
headless:=false
In the OVRtx viewport, compare against the unmodified baseline.
Iterate values, rebuild, re-launch.
Step 6 — Verify the converted USD
grep -n "roughness\|metallic" assets/scenes/<scene>/robot/robot.usda | head
You should see the patched values on the relevant material prims.
Notes
assemble_robot.py walks each <visual> in author order; if a
visual has multiple meshes (rare in our robots), the override
applies to every embedded material of that visual.
- The override is stripped from the URDF before it reaches the
converter, so MoveIt / RSP / urdfdom never see it. They'll happily
consume the same xacro.
- For brand-new materials (no DAE-embedded source), prefer authoring
a real
<material> block — material_override is patch-only.
- Material is rendered by OVRtx + Isaac Sim. The Newton GL viewer
uses simple shading and won't reflect roughness / metallic — use
OVRtx for visual QA.
Resources