diff --git a/docs/source/_static/robots/dexforcew1.jpg b/docs/source/_static/robots/dexforcew1.jpg deleted file mode 100644 index e119d54a6..000000000 Binary files a/docs/source/_static/robots/dexforcew1.jpg and /dev/null differ diff --git a/docs/source/_static/robots/dexforcew1_render.json b/docs/source/_static/robots/dexforcew1_render.json new file mode 100644 index 000000000..998f6afc6 --- /dev/null +++ b/docs/source/_static/robots/dexforcew1_render.json @@ -0,0 +1,169 @@ +{ + "description": "W1 documentation images captured with shared native rendering and camera settings.", + "source_commit": "f063f80bb9d546eaca7998b2b2a21f1d29d78513", + "render_cfg": { + "renderer": "rt", + "spp": 1, + "denoising": { + "window": "dlss", + "offscreen": "dlss" + }, + "dlss": { + "dlss_quality": 2, + "upsample_ratio": null, + "render_width": 0, + "render_height": 0, + "target_width": 0, + "target_height": 0, + "tiled_enabled": true, + "exposure_compensation": 1.0 + }, + "nrd": { + "max_indirect_bounces": 1, + "denoising_range": 500000.0, + "disocclusion_threshold": 0.01, + "disocclusion_threshold_alternate": 0.05, + "disocclusion_threshold_mix_enabled": true, + "history_confidence_enabled": true, + "history_confidence_probe_stride": 5, + "history_confidence_sigma_scale": 2.0, + "history_confidence_sensitivity": 1.0, + "max_accumulated_frame_num": 30, + "max_fast_accumulated_frame_num": 6, + "history_fix_frame_num": 3, + "diffuse_prepass_blur_radius": 30.0, + "specular_prepass_blur_radius": 50.0, + "anti_firefly_enabled": false, + "sh_mode_enabled": false, + "validation_enabled": false, + "max_stabilized_frame_num": 63, + "min_blur_radius": 1.0, + "max_blur_radius": 30.0, + "antilag_luminance_sigma_scale": 2.0, + "antilag_luminance_sensitivity": 3.0, + "taa_min_current_weight": 0.0625, + "taa_sigma_scale": 2.0, + "taa_depth_rejection_enabled": true, + "taa_tone_mapping_enabled": false + }, + "tone_mapping_enabled": false, + "tone_mapping_exposure": 1.0, + "min_bounces": 4, + "max_bounces": 8 + }, + "camera": { + "width": 960, + "height": 1200, + "intrinsics": [ + 2350.0, + 2350.0, + 480.0, + 600.0 + ], + "eye": [ + 2.4, + -3.2, + 2.2 + ], + "target": [ + 0.06, + 0.0, + 0.94 + ], + "up": [ + 0.0, + 0.0, + 1.0 + ], + "near": 0.03, + "far": 60.0 + }, + "scene": { + "presentation": "SimulationManager defaults", + "direct_lights": [], + "emission_color": [ + 0.92, + 0.95, + 1.0 + ], + "emission_intensity": 80.0 + }, + "physics_stepped": false, + "warmup_frames": 48, + "images": { + "dexforcew1_v021.jpg": { + "variant": "v021/BrainCo", + "hand_asset_version": "v021", + "independent_control_dof": 32, + "joint_positions": { + "ANKLE": 0.0, + "KNEE": 0.0, + "BUTTOCK": 0.0, + "WAIST": 0.0, + "NECK1": 0.0, + "NECK2": 0.0, + "LEFT_J1": 0.0, + "RIGHT_J1": 0.0, + "LEFT_J2": -1.2000000476837158, + "RIGHT_J2": 1.2000000476837158, + "LEFT_J3": 0.0, + "RIGHT_J3": 0.0, + "LEFT_J4": -1.399999976158142, + "RIGHT_J4": 1.399999976158142, + "LEFT_J5": 0.0, + "RIGHT_J5": 0.0, + "LEFT_J6": 0.0, + "RIGHT_J6": 0.0, + "LEFT_J7": 0.0, + "RIGHT_J7": 0.0, + "LEFT_HAND_INDEX": 0.0, + "LEFT_HAND_MIDDLE": 0.0, + "LEFT_HAND_PINKY": 0.0, + "LEFT_HAND_RING": 0.0, + "LEFT_HAND_THUMB2": 0.0, + "RIGHT_HAND_INDEX": 0.0, + "RIGHT_HAND_MIDDLE": 0.0, + "RIGHT_HAND_PINKY": 0.0, + "RIGHT_HAND_RING": 0.0, + "RIGHT_HAND_THUMB2": 0.0, + "LEFT_INDEX_PIP": 0.0, + "LEFT_MIDDLE_PIP": 0.0, + "LEFT_PINKY_PIP": 0.0, + "LEFT_RING_PIP": 0.0, + "LEFT_HAND_THUMB1": 0.0, + "RIGHT_INDEX_PIP": 0.0, + "RIGHT_MIDDLE_PIP": 0.0, + "RIGHT_PINKY_PIP": 0.0, + "RIGHT_RING_PIP": 0.0, + "RIGHT_HAND_THUMB1": 0.0 + } + }, + "dexforcew1_v030.jpg": { + "variant": "v030/bare", + "hand_asset_version": null, + "independent_control_dof": 20, + "joint_positions": { + "ANKLE": 0.0, + "KNEE": 0.0, + "BUTTOCK": 0.0, + "WAIST": 0.0, + "NECK1": 0.0, + "LEFT_J1": 0.0, + "RIGHT_J1": 0.0, + "NECK2": 0.0, + "LEFT_J2": -1.2000000476837158, + "RIGHT_J2": 1.2000000476837158, + "LEFT_J3": 0.0, + "RIGHT_J3": 0.0, + "LEFT_J4": -1.399999976158142, + "RIGHT_J4": 1.399999976158142, + "LEFT_J5": 0.0, + "RIGHT_J5": 0.0, + "LEFT_J6": 0.0, + "RIGHT_J6": 0.0, + "LEFT_J7": 0.0, + "RIGHT_J7": 0.0 + } + } + } +} diff --git a/docs/source/_static/robots/dexforcew1_v021.jpg b/docs/source/_static/robots/dexforcew1_v021.jpg new file mode 100644 index 000000000..03d2815f7 Binary files /dev/null and b/docs/source/_static/robots/dexforcew1_v021.jpg differ diff --git a/docs/source/_static/robots/dexforcew1_v030.jpg b/docs/source/_static/robots/dexforcew1_v030.jpg index b76866979..0a347855e 100644 Binary files a/docs/source/_static/robots/dexforcew1_v030.jpg and b/docs/source/_static/robots/dexforcew1_v030.jpg differ diff --git a/docs/source/resources/robot/dexforce_w1.md b/docs/source/resources/robot/dexforce_w1.md index ca6c95697..4074b1336 100644 --- a/docs/source/resources/robot/dexforce_w1.md +++ b/docs/source/resources/robot/dexforce_w1.md @@ -1,156 +1,140 @@ +# DexForce W1 -# Dexforce W1 - -Dexforce W1 is a dual-arm humanoid robot developed by DexForce Technology Co., Ltd. +DexForce W1 is a mobile dual-arm humanoid with two 7-DOF arms, a 4-DOF torso +and a 2-DOF head. The bare body has 20 independent control DOFs; end effectors +are configured separately.
- Earlier Dexforce W1 rendering with attached hands -
Earlier W1 with hands
+ DexForce W1 V021 with two BrainCo V021 hands, 32 independent control DOFs +
W1 V021 · BrainCo V021 hands · 32 DOF
v021/BrainCo
- Dexforce W1 V030 standard bare-body simulation render -
W1 V030 — standard bare body (20 DOF)
+ DexForce W1 V030 standard bare body without end effectors, 20 independent control DOFs +
W1 V030 · Bare body · 20 DOF
v030/bare
-The V030 image uses the registered `v030/bare` asset in a bent-elbow display -pose, rendered with `RenderCfg(renderer="rt")` (OfflineRT). All other -`RenderCfg` fields and scene lighting use their defaults. Its physical wrist flanges -are shown without detachable end effectors. - -## Key Features +Both images use the same camera, bent-elbow display pose and current +`RenderCfg(renderer="rt")` defaults (OfflineRT), with default scene lighting. +The display pose is for illustration; it does not change the preset home pose. -- Supports dual 7-DOF arms -- Supports version-owned asset layouts and calibration parameters -- Configurable left/right hand brand and version -- Flexible URDF assembly and simulation configuration -- Compatible with SimulationManager simulation environment +:::{dropdown} Image rendering settings +960 × 1200; 1 sample per pixel; DLSS offscreen reconstruction (quality 2); +tone mapping off; exposure 1.0; path depths 4–8. The scene uses the default +ground and environment emission, with no added direct lights. Camera and +joint settings are recorded in the +[render manifest](../../_static/robots/dexforcew1_render.json). +::: ## Supported Body Revisions -EmbodiChain supports four complete W1 body revisions. Select the revision -explicitly when reproducing an asset or calibration setup: - -| Body revision | Default arm solver | Default end effectors | Default control DOF | Asset and calibration differences | +| Body revision | Default arm solver | Default end effectors | Independent control DOF | Revision differences | |---|---|---|---|---| -| `v021` | `SRSSolver` | Dual BrainCo hands | 32 | Separate component datasets and a separate eyes component; identity revision mounting offset | -| `v022` | `SRSSolver` | Dual BrainCo hands | 32 | Unified body/component archive; eyes included in the head; provisional identity flange calibration | -| `v025` | `SRSSolver` | Dual BrainCo hands | 32 | Unified archive; calibrated `+0.012 m` revision mounting offset along each arm's `ee` Z axis | -| `v030` | `FEPSolver` | None: standard bare body | 20 | Unified bare-body archive; flange TCPs; optional tools assembled separately; no wrist-camera mounting frames | +| `v021` | `SRSSolver` | BrainCo V021 hands | 32 | Separate component datasets and eyes component; identity mounting offset | +| `v022` | `SRSSolver` | BrainCo V021 hands | 32 | Unified archive; eyes included in the head; provisional identity flange calibration | +| `v025` | `SRSSolver` | BrainCo V021 hands | 32 | Unified archive; calibrated 12 mm mounting offset along each arm's `ee` Z axis | +| `v030` | `FEPSolver` | None | 20 | Standard bare body; flange TCPs; no wrist-camera mounting frames | + +The default remains `v021/BrainCo`. A body revision selects the chassis, +torso, head and both arms together; mixed body/arm revisions are unsupported. +Hand versions are independent of body versions. -The unmodified configuration still defaults to `v021/BrainCo`. V021, V022, -and V025 also support bare-body and DH gripper profiles described below. One -revision selects the chassis, torso, head and both arms together; mixed body -and arm revisions are unsupported. +## Configuration -Use the exact catalog variant to select each released default: +Select an exact catalog variant to reproduce a configuration: ```python from embodichain.robot_registry import resolve_robot_cfg -w1_v021 = resolve_robot_cfg("DexforceW1", variant="v021/BrainCo") -w1_v022 = resolve_robot_cfg("DexforceW1", variant="v022/BrainCo") -w1_v025 = resolve_robot_cfg("DexforceW1", variant="v025/BrainCo") -w1_v030 = resolve_robot_cfg("DexforceW1", variant="v030/bare") - +cfg = resolve_robot_cfg("DexforceW1", variant="v030/bare") # sim is an existing SimulationManager. -robot = sim.add_robot(cfg=w1_v030) +robot = sim.add_robot(cfg=cfg) ``` -## Configuration with `DexforceW1Cfg.from_dict` - -Catalog resolution calls `DexforceW1Cfg.from_dict`, which can also be used -directly. Each configuration describes the complete chassis, torso, head and -both arms for one body revision. V021 assembles eyes as a separate component; -V022, V025 and V030 include eyes in the head. V021/V022/V025 add the registered -wrist-camera mounting frames. V030 leaves wrist cameras to optional -attachments with their own calibration. - -**Parameters:** - -- `version`: Body revision: `v021`, `v022`, `v025`, or `v030`. -- `hand_types`: Dict specifying hand brand for each arm side (`LEFT`/`RIGHT`). -- `hand_versions`: Dict specifying hand version for each arm side. -- `with_default_eef`: Whether to install the registered default end effectors. - Defaults to `True` for V021/V022/V025 and `False` for V030. -- `hand_attach_xposes`: Optional hand-specific mounting transforms. -- `solver_cfg`: Optional per-arm solver overrides, including a tool-specific TCP. +Use `DexforceW1Cfg.from_dict` when customizing the end effectors: ```python from embodichain_robots import DexforceW1Cfg cfg = DexforceW1Cfg.from_dict( { - "uid": "dexforce_w1", "version": "v025", - "hand_types": { - "left": "BRAINCO_HAND", - "right": "BRAINCO_HAND", - }, + "hand_types": {"left": "BRAINCO_HAND", "right": "BRAINCO_HAND"}, "hand_versions": {"left": "v021", "right": "v021"}, } ) robot = sim.add_robot(cfg=cfg) ``` -For the standard V030 body, `DexforceW1Cfg.from_dict({"version": "v030"})` -selects the bare body and calibrated FEP defaults without specifying hands. +| Field | Purpose | +|---|---| +| `version` | Body revision: `v021`, `v022`, `v025` or `v030` | +| `hand_types` | Per-side brand: `BRAINCO_HAND`, `DH_PGC_GRIPPER` or `DH_PGC_GRIPPER_M` | +| `hand_versions` | Per-side hand asset revision; current registrations use `v021` | +| `with_default_eef` | Install registered end effectors; defaults to `True` for V021/V022/V025 and `False` for V030 | +| `hand_attach_xposes` | Per-side hand mounting transforms | +| `solver_cfg` | Per-arm solver overrides, including tool TCPs | + +Side keys accept `left` / `right` or `DexforceW1ArmSide` values. +`DexforceW1Cfg.from_dict({"version": "v030"})` selects the standard bare body. +Optional V030 tools require their own mounting and TCP calibration. ## Catalog Variants and Control DOFs -`embodichain list-robot` advertises **19 W1 variants**: six profiles for each of -V021, V022 and V025, plus the standard `v030/bare` profile. +`embodichain list-robot` lists 19 W1 variants: six profiles each for V021, +V022 and V025, plus `v030/bare`. | Profile suffix | Body revisions | End effectors | Independent control DOF | |---|---|---|---| -| `BrainCo` | `v021`, `v022`, `v025` | Two `BRAINCO_HAND` hands | 32 | -| `DH_PGC` | `v021`, `v022`, `v025` | Two `DH_PGC_GRIPPER` grippers | 22 | -| `DH_PGC_M` | `v021`, `v022`, `v025` | Two `DH_PGC_GRIPPER_M` grippers | 22 | -| `L=DH_PGC,R=DH_PGC_M` | `v021`, `v022`, `v025` | Left DH_PGC, right DH_PGC_M | 22 | -| `L=DH_PGC_M,R=DH_PGC` | `v021`, `v022`, `v025` | Left DH_PGC_M, right DH_PGC | 22 | -| `bare` | `v021`, `v022`, `v025`, `v030` | No default end effector | 20 | +| `BrainCo` | V021/V022/V025 | Two BrainCo hands | 32 | +| `DH_PGC` / `DH_PGC_M` | V021/V022/V025 | Two matching DH grippers | 22 | +| `L=DH_PGC,R=DH_PGC_M` / `L=DH_PGC_M,R=DH_PGC` | V021/V022/V025 | Mixed DH grippers | 22 | +| `bare` | V021/V022/V025/V030 | None | 20 | + +Combine a revision and suffix, for example `v022/DH_PGC_M`. +Each BrainCo hand contributes six independent joints; its PIP followers are +outside the default EEF control group. Each DH gripper contributes one +independent joint and one mimic follower (`1+1m`). See +{doc}`/guides/robot_catalog` for hand-pairing and selection details. + +The bare-body control parts are `torso`, `head`, `left_arm`, `right_arm`, +`dual_arm` and `full_body`. The last two combine existing joints; `full_body` +excludes hands. Installed hands add `left_eef` and `right_eef`. Joint positions +use radians and revision-specific mirrored axes; preserve the selected +URDF's coordinates and limits when transferring poses. -Combine the body revision and suffix, for example `v022/DH_PGC_M` or -`v025/L=DH_PGC,R=DH_PGC_M`. Dexterous-hand/two-finger-gripper mixtures are -omitted from the catalog. V030 only advertises `v030/bare`: constructing an -optional hand assembly through `with_default_eef=True` does not establish -that its mount and TCP have been validated for that revision. - -BrainCo PIP followers are passive joints outside the default hand control -groups. They are listed as mimic joints while each `left_eef` / `right_eef` -group contains six independent control joints. DH gripper groups each have -one independent joint and one follower, displayed as `1+1m`. - -See {doc}`/guides/robot_catalog` for the complete hand-pairing table and -examples of selecting these profiles through configuration fields. +## Solver and TCP Calibration -## Control Parts and Joint Coordinates +V021/V022/V025 use version-owned SRS settings and legacy tool TCPs. Their +`bare` profiles retain those TCPs; configure an explicit flange TCP when +controlling the physical flange. -Every bare body has four torso joints, two head joints and two seven-joint -arms, for 20 independent control DOFs. The control parts are `torso`, `head`, -`left_arm`, `right_arm`, `dual_arm`, and `full_body`. The last two overlap -their constituent groups and do not add independent joints. Installing hands -adds `left_eef` and `right_eef`; `full_body` remains the torso, head and arms. +V030 uses FEP, source-URDF joint limits and identity TCPs at `left_ee` / +`right_ee`. Its left CAD wrist has a small J7 axis tilt, handled by explicit +revision tolerances; accepted solutions are checked against source-URDF FK. +Redundancy search scores joint distance and limit margin without a swivel-angle +preference (`arm_angle_weight=0.0`), because the outstretched home pose has no +defined GeoFIK swivel angle. These settings describe simulator kinematics; +hardware and tool calibration remain separate. -The arms use revision-specific mirrored axes. Joint positions are in radians -and retain the selected asset's coordinate convention. Use the configured -left/right solvers and source joint limits when transferring poses between -arms or revisions. +The body revision owns the mounting correction: identity for V021, provisional +identity for V022, **+12 mm along each `ee` Z axis for V025**, and identity at +the physical flange for V030. Configuration assembly applies it to both the +hand transform and solver TCP: -## Type Descriptions +```python +final_attach_xpos = version_attach_xpos @ eef_attach_xpos +final_tcp = version_attach_xpos @ solver_tcp +``` -| Type | Options / Values | Description | -|-------------------------|-------------------------------------------------------|------------------------------------| -| `DexforceW1HandBrand` | `BRAINCO_HAND`, `DH_PGC_GRIPPER`, `DH_PGC_GRIPPER_M` | Hand brand | -| `DexforceW1Version` | `V021`, `V022`, `V025`, `V030` | Body release version | -| `DexforceW1HandVersion` | `V021` | External hand/gripper asset version | -| `DexforceW1ArmSide` | `LEFT`, `RIGHT` | Left/right hand identifier | +Supply hand transforms and TCPs relative to the standard mounting surface; +do not add the V025 correction manually. This also applies to custom hand +components and explicit solver overrides. Serialization removes and restores +the derived offset so it is applied once. ## Assets and Download Layout -The body dataset and full-robot path are version-owned: - | Body revision | Dataset ID | Full-robot asset path | |---|---|---| | `v021` | `DexforceW1V021` | `DexforceW1V021/DexforceW1_v02_1.urdf` | @@ -158,145 +142,12 @@ The body dataset and full-robot path are version-owned: | `v025` | `DexforceW1V025` | `DexforceW1V025/w1/robot.urdf` | | `v030` | `DexforceW1V030` | `DexforceW1V030/w1/robot.urdf` | -V021 runtime assembly uses the separate `DexforceW1ChassisV021`, -`DexforceW1TorsoV021`, `DexforceW1HeadV021`, `DexforceW1EyesV021`, -`DexforceW1LeftArmV021`, and `DexforceW1RightArmV021` datasets. V022, V025 and -V030 each use one unified archive for the full body and all five components: - -```text -dexforce_w1//w1.zip -└── w1/ - ├── robot.urdf - ├── chassis.urdf - ├── torso.urdf - ├── head.urdf - ├── left_arm.urdf - ├── right_arm.urdf - ├── visual/ # V022/V025 - ├── visual_recoloured/ # V030 - └── collision/ -``` - -For unified archives, direct FK/IK uses `robot.urdf` or the arm URDFs, while -configurable assembly reads components from the same extracted directory. -Registered downloads use the shared asset cache and validate the archive -checksum before extraction. - -The [V030 asset release](https://huggingface.co/datasets/DexForceAI/embodichain_data/tree/main/dexforce_w1/v030) -contains the complete standard body, a preview and a per-file checksum -manifest. Its `w1.zip` is 25.58 MiB and contains 49 files: seven URDFs, 21 -visual GLBs and 21 collision OBJs. `robot_with_ee.urdf` is an identical -compatibility alias of the bare `robot.urdf`. Detachable grippers and -unreferenced duplicate/backup meshes are excluded. Each component's visual, -collision and inertial definitions match the full body. - -## Solver and TCP Calibration - -V021/V022/V025 use their version-owned SRS parameters and legacy tool TCPs. -Selecting a bare profile on those revisions preserves the configured tool -TCP; choose an explicit flange TCP if that is the intended control frame. -V030 uses FEP with source-URDF joint limits and identity TCPs at `left_ee` and -`right_ee` by default. - -### V030 FEP defaults - -| Parameter | Left arm | Right arm | -|---|---|---| -| `reference_qpos` (radians) | `[0, 0, -pi/2, 0, 0, -pi/2, 0]` | `[0, 0, -pi/2, 0, 0, pi/2, 0]` | -| `axis_alignment_tolerance` | `2e-5` | `1e-6` | -| `position_tolerance` (metres) | `1e-5` | `1e-5` | -| `rotation_tolerance` (radians) | `5e-5` | `1e-5` | -| `redundancy_search` | `True` | `True` | -| `arm_angle_weight` | `0.0` | `0.0` | - -The reference posture rebases the geometric reconstruction; inputs, returned -joints and limits retain the original URDF coordinates. The left CAD model -has a small J7 axis tilt, so its geometry and rotation tolerances are explicit -revision settings. Every accepted solution is checked against the original -URDF FK. This remains an FEP-family geometric solver; the axis allowance is an -approximation and does not establish complete reachability coverage. - -Joint-distance and limit-margin scoring are enabled without a swivel-angle -preference because the outstretched V030 home pose has an undefined GeoFIK -swivel angle. A tool assembly owns its mounting transform and TCP calibration; -configure these separately from the standard body. - -For the standard configuration, 9,216 CPU/CUDA IK samples passed source-chain -FK and joint-limit checks, with maximum position error 8.42 micrometres and -orientation error 0.00159 degrees. Native kinematic checks also passed with -the default and Newton backends. These measurements validate simulator -kinematics, not hardware or dynamics calibration. - -### Version-owned end-effector offset - -Different arm revisions may place the physical mounting surface at different -positions relative to the arm `ee` frame. This difference belongs to the W1 -revision, not to a BrainCo hand, DH gripper, PIKA gripper, or any other -end-effector. - -`W1VersionSpec.default_eef_attach_xpos` is the single source of truth for this -revision offset: - -| Version | Left arm | Right arm | -|---------|----------|-----------| -| V021 | Identity | Identity | -| V022 | Identity (provisional; calibration required) | Identity (provisional; calibration required) | -| V025 | `+0.012 m` along the `ee` frame Z axis | `+0.012 m` along the `ee` frame Z axis | -| V030 | Identity at the physical flange | Identity at the physical flange | - -The final assembly transform and solver TCP are derived as follows: - -```python -final_attach_xpos = version_attach_xpos @ eef_attach_xpos -final_tcp = version_attach_xpos @ solver_tcp -``` - -Therefore, the V025 offset affects both the assembled end-effector position and -FK/IK results. The offset is also applied when callers provide a custom -`hand_attach_xposes` value, a custom `left_hand`/`right_hand` component -transform, or an explicit arm TCP through `DexforceW1Cfg.from_dict`. -Serialization removes the derived offset and restores it on loading, so a -configuration round trip does not apply the offset twice. - -Do not manually add the 12 mm correction to an end-effector transform or TCP. -Those values must describe the end-effector relative to the standard mounting -surface; the W1 version layer adds the robot revision correction. - -Robot and hand versions are independent. `DexforceW1Version` selects the W1 -body, arm assets, kinematics, and flange calibration. `DexforceW1HandVersion` -selects an external hand or gripper asset from -`embodichain_robots/dexforce_w1/hand_specs.py`. - -The currently released BrainCo hand and DH gripper registrations all use -`DexforceW1HandVersion.V021`. V021/V022/V025 install that hand revision by -default. V030 installs no hands; explicitly enabling a registered hand also -selects hand V021 unless overridden. This is an independent hand-release -default, not a compatibility alias or a validation of every body/tool pairing. - -## Extending Body and Hand Revisions - -To add another W1 revision: - -1. Register the new `DexforceW1Version` value and dataset archive. -2. Add one `W1VersionSpec` entry in - `embodichain_robots/dexforce_w1/specs.py`. -3. Register component URDF paths and the full-robot URDF path. -4. Set the matching solver configuration, arm kinematic parameters and - `default_eef_attach_xpos` for both sides. Use identity only after confirming - that the arm `ee` frame is already at the physical mounting surface. -5. Verify that the same version offset is present in both the assembled - end-effector pose and the final FK/IK TCP. -6. Validate FK/IK and joint limits against the source URDF. Register optional - hand/gripper and camera assemblies only with their corresponding mount/TCP - calibration and integration checks. - -To add another hand release: - -1. Add a `DexforceW1HandVersion` value. -2. Register each supported brand and side in `hand_specs.py`, including its - URDF, joint names, root/end links, and mounting transform. -3. Select it explicitly through `hand_versions`; an unregistered version fails - during config construction. +V021 assembles separate chassis, torso, head, eyes and arm datasets. Each later +revision uses one checksum-validated archive containing the full robot and +five component URDFs, with matching visual, collision and inertial definitions. +V030's `robot_with_ee.urdf` is a compatibility alias of its bare `robot.urdf`; +detachable tools are separate assets. -Control parts, assembly, TCP selection, analytical parameters and FK/IK then use -the version specification without revision-specific branches. +Body assets, solvers and mounting offsets are registered in +`embodichain_robots/dexforce_w1/specs.py`; external hand assets and transforms +are registered independently in `hand_specs.py`.