4240bb889a
- 三接口契约:自包含 MJCF / 配置 schema / 报告计算规范 - Python 流水线:urdf_to_mjcf → generate_schema → simulate_report(validate_module 一键编排) - 输入案例 urdf + 生成产物 output(自包含 MJCF/schema/报告/网格副本) - 详细架构说明 docs/architecture.md
160 lines
7.7 KiB
Markdown
160 lines
7.7 KiB
Markdown
# 接口 2 —— 关节模组配置 Schema
|
||
|
||
> 用途:给「浏览器端 WASM 仿真」一个**统一观测接口**。无论用户上传的是什么构型的关节模组
|
||
> (一级/多级、三个/四个行星轮、太阳轮+行星架、谐波、摆线…),后端把它归一化成这份 JSON,
|
||
> 前端只读这份 JSON 就能:找到输入端/输出端、知道减速比、拿到限位、按默认参数跑仿真。
|
||
|
||
---
|
||
|
||
## 1. Schema 是什么 / 不是什么
|
||
|
||
| | 说明 |
|
||
|---|---|
|
||
| ✅ 是什么 | 关节模组的**对外观测契约**:输入关节、输出关节、减速比、限位、默认仿真参数 |
|
||
| ❌ 不是什么 | **不描述内部构型**(几级传动、几个行星轮、齿数、几何)。这些全部已经编码在 MJCF 里,前端不需要知道 |
|
||
| ❌ 不是用户上传的 | 这份 JSON 是**后端从 URDF 生成**的,不是用户填写的。用户上传的始终是「URDF + mesh」的 zip |
|
||
|
||
**为什么必须要有 schema?**
|
||
1. 报告里要测的输入/输出力矩,是「哪个关节」取决于构型。schema 告诉前端哪两个关节是输入/输出端。
|
||
2. 减速比的标称值(`gear_ratio`)可能来自 URDF 的 `<mimic>`,也可能是标定/手动填的,需要显式声明来源。
|
||
3. 前端要做统一的限位检查、统一的安全余量,就需要统一格式的限位。
|
||
|
||
> 一句话:**MJCF 管「怎么动」,schema 管「观测什么」,报告规范管「算出什么」。**
|
||
|
||
---
|
||
|
||
## 2. 字段定义(格式契约,定义一次)
|
||
|
||
| 字段 | 类型 | 单位 | 必填 | 含义 | 取值来源 |
|
||
|---|---|---|---|---|---|
|
||
| `module_id` | string | — | ✅ | 模组唯一标识 | 后端生成(如模型名) |
|
||
| `name` | string | — | | 显示名 | 后端生成 |
|
||
| `model` | string | — | ✅ | 要加载的 MJCF 文件名(自包含,网格与它同目录) | 转换工具输出 |
|
||
| `input_joint` | string | — | ✅ | **输入关节名**(电机端) | URDF 里唯一没有 `<mimic>` 的关节 |
|
||
| `output_joint` | string | — | ✅ | **输出关节名**(模组输出端) | URDF 里以正 multiplier 跟随输入的关节 |
|
||
| `gear_ratio` | number | — | ✅ | 标称减速比 = 输入 / 输出 = `1/multiplier` | 默认取 `<mimic multiplier>` 倒数;可标定覆盖 |
|
||
| `gear_ratio_source` | enum | — | ✅ | `mimic` / `calibrated` / `manual` | 减速比来源 |
|
||
| `limits.position` | [number, number] | rad | ✅ | 输入关节位置限位 `[lower, upper]` | URDF `<limit lower/upper>` |
|
||
| `limits.torque` | [number, number] | N·m | ✅ | 输入力矩限位 `[-T, +T]` | MJCF `<actuator ctrlrange>`(占位,待填真实值) |
|
||
| `limits.velocity` | [number, number] | rad/s | | 速度限位 | URDF `<limit velocity>`(若有) |
|
||
| `simulation.timestep` | number | s | ✅ | 仿真步长 | 默认 `0.001` |
|
||
| `simulation.duration` | number | s | ✅ | 仿真时长 | 默认 `4.0` |
|
||
| `simulation.kp` / `kd` | number | — | ✅ | 输入 PD 位置控制增益 | 默认 `20.0` / `0.3` |
|
||
| `simulation.amplitude` | number | rad | ✅ | 参考轨迹幅值 | 默认 `2π`(1 圈) |
|
||
| `simulation.frequency` | number | Hz | ✅ | 参考轨迹频率 | 默认 `0.25` |
|
||
| `simulation.load_torque` | number | N·m | ✅ | 输出端恒值负载(负 = 阻力) | 默认 `-3.0` |
|
||
| `simulation.damping` | number | N·m·s/rad | ✅ | 关节粘性阻尼 | 默认 `0.01` |
|
||
| `simulation.mode` | enum | — | ✅ | 仿真模式:`normal` / `overload` | 默认 `normal` |
|
||
|
||
> 所有带默认值的字段,前端都可以覆盖(用户调参)。`input_joint` / `output_joint` /
|
||
> `limits` / `gear_ratio` 是后端算好的「事实」,前端只读。
|
||
|
||
---
|
||
|
||
## 3. 形式化 JSON Schema(供前端校验用,draft 2020-12)
|
||
|
||
```json
|
||
{
|
||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||
"$id": "joint-module.schema.json",
|
||
"title": "关节模组配置",
|
||
"type": "object",
|
||
"required": ["module_id", "model", "input_joint", "output_joint",
|
||
"gear_ratio", "gear_ratio_source", "limits", "simulation"],
|
||
"additionalProperties": false,
|
||
"properties": {
|
||
"module_id": { "type": "string" },
|
||
"name": { "type": "string" },
|
||
"model": { "type": "string" },
|
||
"input_joint": { "type": "string" },
|
||
"output_joint": { "type": "string" },
|
||
"gear_ratio": { "type": "number", "exclusiveMinimum": 0 },
|
||
"gear_ratio_source": { "type": "string", "enum": ["mimic", "calibrated", "manual"] },
|
||
"limits": {
|
||
"type": "object",
|
||
"required": ["position", "torque"],
|
||
"properties": {
|
||
"position": { "type": "array", "items": { "type": "number" }, "minItems": 2, "maxItems": 2 },
|
||
"torque": { "type": "array", "items": { "type": "number" }, "minItems": 2, "maxItems": 2 },
|
||
"velocity": { "type": "array", "items": { "type": "number" }, "minItems": 2, "maxItems": 2 }
|
||
}
|
||
},
|
||
"simulation": {
|
||
"type": "object",
|
||
"properties": {
|
||
"timestep": { "type": "number", "default": 0.001 },
|
||
"duration": { "type": "number", "default": 4.0 },
|
||
"kp": { "type": "number", "default": 20.0 },
|
||
"kd": { "type": "number", "default": 0.3 },
|
||
"amplitude": { "type": "number", "default": 6.283185307179586 },
|
||
"frequency": { "type": "number", "default": 0.25 },
|
||
"load_torque": { "type": "number", "default": -3.0 },
|
||
"damping": { "type": "number", "default": 0.01 },
|
||
"mode": { "type": "string", "enum": ["normal", "overload"], "default": "normal" }
|
||
}
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 4. 本案例的实例
|
||
|
||
```json
|
||
{
|
||
"module_id": "planetary_joint_split_motor_demo",
|
||
"name": "行星轮系分体电机关节模组",
|
||
"model": "planetary_joint_split_motor_demo.xml",
|
||
|
||
"input_joint": "sun_input_joint",
|
||
"output_joint": "carrier_output_joint",
|
||
|
||
"gear_ratio": 6.0,
|
||
"gear_ratio_source": "mimic",
|
||
|
||
"limits": {
|
||
"position": [-37.6991118431, 37.6991118431],
|
||
"torque": [-10.0, 10.0],
|
||
"velocity": [-6.28318530718, 6.28318530718]
|
||
},
|
||
|
||
"simulation": {
|
||
"timestep": 0.001,
|
||
"duration": 4.0,
|
||
"kp": 20.0,
|
||
"kd": 0.3,
|
||
"amplitude": 6.283185307179586,
|
||
"frequency": 0.25,
|
||
"load_torque": -3.0,
|
||
"damping": 0.01,
|
||
"mode": "normal"
|
||
}
|
||
}
|
||
```
|
||
|
||
对照说明:
|
||
|
||
| 实例值 | 怎么来的 |
|
||
|---|---|
|
||
| `input_joint = sun_input_joint` | URDF 里 5 个关节中,唯一没有 `<mimic>` 的是 `sun_input_joint`(独立驱动源) |
|
||
| `output_joint = carrier_output_joint` | `<mimic joint="sun_input_joint" multiplier="0.16667">`,正 multiplier → 减速输出端 |
|
||
| `gear_ratio = 6.0` | `1 / 0.166666666666667 = 6`(1 级行星轮系,齿圈固定,太阳轮:行星架 = 6:1) |
|
||
| `limits.position = ±37.6991` | URDF `<limit lower="-37.6991118431" upper="37.6991118431">`(±6 圈 = ±12π) |
|
||
| `limits.torque = ±10` | MJCF `<actuator ctrlrange="-10 10">`(**占位**,待填真实电机额定值) |
|
||
| `limits.velocity = ±6.2832` | URDF `<limit velocity="6.28318530718">`(1 圈/秒) |
|
||
| `simulation.*` | 报告规范的默认场景参数,见 [report_spec.md](report_spec.md) |
|
||
|
||
---
|
||
|
||
## 5. 减速比来源的优先级(多来源怎么取)
|
||
|
||
后端生成 schema 时,`gear_ratio` 按下面顺序确定,并在 `gear_ratio_source` 里记录用的是哪个:
|
||
|
||
1. **`mimic`** —— URDF `<mimic multiplier>` 的倒数(最优先,本案例)。
|
||
2. **`calibrated`** —— 跑一次仿真,`mean(q_out / q_in)` 标定得到(无 `<mimic>` 或传动力不可靠时)。
|
||
3. **`manual`** —— 前端手动填(都没有时兜底)。
|
||
|
||
> 减速比只进 schema 与报告,**不进 MJCF**——MJCF 里的传动关系由 `<equality>` 精确表达,
|
||
> schema 里的 `gear_ratio` 只是「标称参考值」,用于报告的效率/理想力矩计算。
|