SolidWorks 装配体自动导出STL文件、凸分解、配置关节、生成 MuJoCo 仿真 XML 文件的完整流程。
- ✅ 自动从 SolidWorks 导出 STL 网格文件
- ✅ 提取零件质量信息和坐标系变换
- ✅ 中文文件名自动转换为拼音 [2、3项参考:https://github.com/Albusgive/mujoco_learning/tree/main/MJCF/Chapter10-from_CAD_software]
- ✅ CoCAD凸分解(可选,支持正则表达式过滤)[这里借助:https://github.com/SarahWeiii/CoACD]
- ✅ 图形化配置组件层级关系和关节类型
- ✅ 生成标准 MuJoCo MJCF XML 文件
- ✅ 自动清理中间文件(可选)
- Windows 操作系统
- Python 3.8+
- SolidWorks(用于导出 STL)
- 必需的 Python 包:
pip install -r requirements_convex.txt
sld2mjcf/
├── sld_input/ # SolidWorks 装配体输入目录
│ ├── robot_Scene/ # 场景文件夹(自定义名称)
│ │ └── robot_Scene.SLDASM
│ └── material_rack/
│ └── material_rack.SLDASM
├── sld2stl/ # STL 导出模块(中间输出)
├── mjcf_output/ # MJCF XML 输出目录
│ ├── robot_Scene/
│ │ └── robot_Scene.xml
│ └── material_rack/
│ └── material_rack.xml
├── run_full_pipeline.py # 主流程脚本 ⭐
├── convex_decompose_and_build_xml.py
└── coordinate_system_utils.py
将 SolidWorks 装配体文件放入 sld_input/ 目录:
sld_input/
└── 你的场景名称/
└── 你的场景名称.SLDASM
编辑 run_full_pipeline.py 文件中的 main() 函数配置:
def main():
# ========== 配置参数 ==========
# 场景名称(对应 sld_input 下的文件夹名)
SCENE_NAME = "robot_Scene"
# SolidWorks 装配体文件路径(自动生成)
ASSEMBLY_PATH = Path(__file__).parent / "sld_input" / SCENE_NAME / f"{SCENE_NAME}.SLDASM"
# 是否使用组件坐标系
# True = 使用子装配体各自的坐标系
# False = 使用顶层装配体的全局坐标系
USE_COMPONENT_COORDINATE = True
# 是否启用凸分解
# True = 对网格进行凸分解(提高物理仿真精度)
# False = 使用原始 STL 网格
ENABLE_DECOMPOSE = True
# 组件级别凸分解过滤器(使用正则表达式)
# None = 对所有组件都进行凸分解
# [] = 所有组件都不进行凸分解
# [r".*gripper.*", r".*arm.*"] = 只对包含 "gripper" 或 "arm" 的组件凸分解
COMPONENT_DECOMPOSE_FILTER = None
# 是否清理中间文件
# True = 完成后删除整个 STL 输出文件夹
# False = 保留所有中间文件
CLEANUP_INTERMEDIATE = Truepython run_full_pipeline.py运行过程中会弹出 GUI 窗口,用于配置:
在弹出窗口中为每个组件设置:
-
父组件:选择该组件的父级(串联/并联关系)
- 根组件选择 "无父组件"
- 串联关系:选择上一个组件作为父组件
- 并联关系:选择同一个父组件
-
关节类型:选择组件的关节类型
null:无关节(固定连接)hinge:铰链关节(1自由度旋转)slide:滑动关节(1自由度平移)ball:球形关节(3自由度旋转)free:自由关节(6自由度),需要设置free的关节,父组件选择"无父组件"
hinge:axis: "0 0 1",range: "-3.14 3.14"slide:axis: "0 0 1",range: "-1 1"ball和free:无额外参数null:不添加关节元素
点击"确认"后自动计算相对位姿并继续。
完成后在 mjcf_output/你的场景名称/ 目录下会生成:
你的场景名称.xml:顶层装配体 XML(主文件)组件1.xml:各个子组件的 XML 文件组件2.xml- ...
组件名称/:包含处理后的网格文件(OBJ/STL)
- 自动启动 SolidWorks
- 递归导出所有子装配体和零件的 STL 文件
- 提取质量信息保存为 CSV
- 提取坐标系变换矩阵(如果启用)
- 将中文文件名转换为拼音(兼容 MuJoCo)
- 生成名称映射表
- 重命名所有 STL 文件
- 读取质量和坐标系信息
- GUI 配置层级关系和关节类型
- 对指定组件执行凸分解(CoACD 算法)
- 为每个组件生成独立 XML
- 生成顶层装配体 XML(自动合并)
- 删除
..._output_stl文件夹(如果启用清理) - 保留最终的 MJCF XML 和网格文件
在 run_full_pipeline.py 的 step3_convex_decompose_and_build_xml() 中:
COACD_CONFIG = convex_module.CoacdArgs(
threshold=0.05, # 凸性阈值 (0.01-1),值越大分解越粗糙但速度越快,默认=0.05
preprocess_mode='auto', # 流型预处理模式 ("on", "off", "auto"),默认="auto",
preprocess_resolution=50, # 预处理分辨率 (20-100),默认=50
mcts_iterations=100, # MCTS 迭代次数 (60-2000),值越大质量越好但越慢,默认=100
mcts_max_depth=3, # MCTS 最大深度 (2-7),默认=3
mcts_nodes=20, # MCTS 子节点数 (10-40),默认=20
resolution=2000, # Hausdorff 距离采样分辨率 (1000-10000),值越大越精细但越慢,默认=2000
pca=False, # 是否启用 PCA 预处理,默认=False
seed=43 # 随机种子,用于结果复现,默认=43
)# 只对包含 "gripper" 的组件凸分解
COMPONENT_DECOMPOSE_FILTER = [r".*gripper.*"]
# 对多个模式匹配
COMPONENT_DECOMPOSE_FILTER = [r".*arm.*", r".*hand.*", r".*finger.*"]
# 对所有带 "_pinyin" 的组件凸分解
COMPONENT_DECOMPOSE_FILTER = [r".*_pinyin.*"]
# 所有组件都不凸分解(使用原始 STL)
COMPONENT_DECOMPOSE_FILTER = []- 文件命名:装配体文件名应与文件夹名一致
- 中文支持:中文名称会自动转换为拼音
- 坐标系:建议在 SolidWorks 中为各子装配体创建坐标系
- 关节配置:根组件应选择"无父组件",避免循环依赖
- 检查 STL 网格是否有效
- 尝试调整凸分解参数(降低
threshold) - 将失败的组件加入过滤器,使用原始网格
- 检查网格文件路径是否正确
- 验证所有引用的网格文件是否存在
- 使用 MuJoCo 的诊断工具检查 XML 语法
欢迎提交 Issue 和 Pull Request!
快速上手示例:
# 1. 准备装配体文件
cp your_assembly.SLDASM sld_input/my_robot/my_robot.SLDASM
# 2. 修改配置
# 编辑 run_full_pipeline.py,设置 SCENE_NAME = "my_robot"
# 3. 运行
python run_full_pipeline.py
# 4. 查看结果
ls mjcf_output/my_robot/