Rust机器人仿真系统总体方案
项目代号:robot_sim | 版本:v1.0 | 日期:2026-04-28
一、项目目标
构建一个轻量级、跨平台、Rust原生的机器人仿真系统,核心能力:
- 解析URDF文件,可视化机器人模型
- 实现正/逆运动学求解,驱动关节运动
- 集成ROS2,对接MoveIt2实现机械臂规划控制
- 碰撞检测,支撑规划场景查询
- 桌面端运行,未来可移植树莓派
非目标(明确排除):
- 不做完整物理引擎(重力、摩擦、接触动力学)
- 不做传感器仿真(相机、激光雷达)
- 不做多机器人协同
二、系统架构
┌──────────────────────────────────────────────────────┐
│ 应用层 │
│ egui控制面板 + 键鼠交互 + 日志输出 │
├──────────────────────────────────────────────────────┤
│ 渲染层 │
│ OpenGL 3.3 Core Profile (glow) │
│ 相机系统 │ 着色器 │ 网格渲染 │ 坐标轴/网格地面 │
├──────────────────────────────────────────────────────┤
│ 仿真引擎层 │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ URDF解析 │ │ 运动学 │ │ 碰撞检测 │ │
│ │ urdf-rs │ │ nalgebra │ │ parry3d │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ ┌──────────┐ ┌──────────┐ │
│ │ 关节状态 │ │ 场景管理 │ │
│ │ 管理 │ │ │ │
│ └──────────┘ └──────────┘ │
├──────────────────────────────────────────────────────┤
│ ROS2通信层 │
│ rclrs绑定 │
│ JointState发布 │ Trajectory订阅 │ TF广播 │
├──────────────────────────────────────────────────────┤
│ 平台抽象层 │
│ winit(窗口) + glow(GL) + EGL(树莓派) │
└──────────────────────────────────────────────────────┘
三、技术选型
3.1 核心依赖
| 功能 | 库 | 版本 | 选型理由 |
|---|---|---|---|
| OpenGL封装 | glow |
0.14 | 纯Rust,跨平台GL,支持OpenGL 3.3 |
| 窗口管理 | winit |
0.30 | Rust标准窗口库,树莓派支持 |
| 即时GUI | egui + egui_glow |
0.29 | 轻量级控制面板,无需Qt/GTK |
| 线性代数 | nalgebra |
0.33 | Rust标准数学库,运动学核心 |
| URDF解析 | urdf-rs |
0.8 | 已有Rust URDF解析库,支持STL引用 |
| 碰撞检测 | parry3d |
0.17 | Rust原生3D碰撞,nphysics生态 |
| STL加载 | stl-rs |
0.3 | 解析二进制/文本STL文件 |
| ROS2通信 | rclrs |
0.4 | Rust ROS2客户端库 |
| 日志 | tracing |
0.1 | Rust标准日志框架 |
| 错误处理 | anyhow |
1.0 | 简化错误传播 |
3.2 可选依赖(Phase 2+)
| 功能 | 库 | 说明 |
|---|---|---|
| DAE加载 | collada |
解析Collada/DAE网格(URDF可选格式) |
| 纹理加载 | image |
加载PNG/JPG纹理贴图 |
| 序列化 | serde + serde_json |
配置文件读写 |
3.3 OpenGL版本策略
桌面端 (x86_64):OpenGL 3.3 Core Profile
树莓派4 (ARM) :OpenGL 3.3 (Mesa驱动) 或 OpenGL ES 3.0
通过feature flag切换:
[features]
default = ["gl33"]
gl33 = []
gles3 = []
四、模块设计
4.1 项目结构
robot_sim/
├── Cargo.toml
├── README.md
│
├── src/
│ ├── main.rs # 入口:窗口创建+主循环
│ ├── lib.rs # 库入口:公共模块导出
│ │
│ ├── renderer/ # 渲染模块
│ │ ├── mod.rs # 渲染器主逻辑
│ │ ├── shader.rs # 着色器编译/链接
│ │ ├── camera.rs # 轨道相机(旋转/缩放/平移)
│ │ ├── mesh.rs # 网格数据结构+GPU上传
│ │ └── primitives.rs # 坐标轴/网格地面/箭头
│ │
│ ├── urdf/ # URDF解析模块
│ │ ├── mod.rs # URDF加载入口
│ │ ├── loader.rs # 文件解析(urdf-rs封装)
│ │ ├── robot.rs # 机器人模型数据结构
│ │ └── visual.rs # 视觉模型→渲染数据转换
│ │
│ ├── kinematics/ # 运动学模块
│ │ ├── mod.rs # 运动学入口
│ │ ├── forward.rs # 正运动学(DH参数法)
│ │ ├── inverse.rs # 逆运动学(雅可比伪逆)
│ │ └── joint.rs # 关节状态管理
│ │
│ ├── collision/ # 碰撞检测模块
│ │ ├── mod.rs # 碰撞检测入口
│ │ ├── scene.rs # 碰撞场景管理
│ │ └── query.rs # 碰撞查询接口
│ │
│ ├── ros2/ # ROS2通信模块
│ │ ├── mod.rs # ROS2入口
│ │ ├── node.rs # 节点创建
│ │ ├── joint_state.rs # JointState发布
│ │ ├── trajectory.rs # JointTrajectory订阅
│ │ └── tf.rs # TF广播
│ │
│ └── app.rs # 应用状态管理
│
├── shaders/ # GLSL着色器
│ ├── basic.vert # 基础顶点着色器
│ ├── basic.frag # 基础片段着色器
│ ├── robot.vert # 机器人顶点着色器
│ └── robot.frag # 机器人片段着色器
│
├── assets/ # 资源文件
│ └── urdf/ # 测试URDF模型
│ └── simple_arm/ # 简易2轴机械臂
│ ├── model.urdf
│ └── meshes/
│ ├── base.stl
│ ├── link1.stl
│ └── link2.stl
│
└── config/ # 配置文件
└── default.toml # 默认配置
4.2 核心数据结构
// 机器人模型
struct Robot {
name: String,
links: Vec<Link>,
joints: Vec<Joint>,
root_link: usize,
}
struct Link {
name: String,
visual: Option<Visual>,
collision: Option<Collision>,
inertial: Option<Inertial>,
}
struct Joint {
name: String,
joint_type: JointType,
parent_link: usize,
child_link: usize,
origin: Isometry3<f64>,
axis: UnitVector3<f64>,
limits: Option<JointLimits>,
current_position: f64,
}
enum JointType {
Revolute,
Continuous,
Prismatic,
Fixed,
}
// 渲染数据
struct RenderMesh {
vertices: Vec<[f32; 3]>,
normals: Vec<[f32; 3]>,
indices: Vec<u32>,
color: [f32; 4],
transform: Isometry3<f32>,
vao: u32, // OpenGL VAO
vbo: u32, // OpenGL VBO
ebo: u32, // OpenGL EBO
}
// 关节状态
struct JointState {
name: String,
position: f64,
velocity: f64,
effort: f64,
}
4.3 模块间接口
main.rs
│
├── App::new()
│ ├── Renderer::new(window)
│ ├── Robot::from_urdf(path)
│ ├── Kinematics::new(robot)
│ ├── CollisionScene::new(robot)
│ └── Ros2Node::new() (可选)
│
└── 主循环
├── 处理输入事件
├── 更新关节状态
│ ├── Kinematics::forward_kinematics()
│ └── Kinematics::inverse_kinematics() (按需)
├── 更新碰撞场景
│ └── CollisionScene::update(joint_states)
├── 更新ROS2通信
│ ├── Ros2Node::publish_joint_states()
│ └── Ros2Node::spin_once()
└── 渲染
├── Renderer::draw_robot(robot)
├── Renderer::draw_grid()
└── egui::draw_panel()
五、开发阶段
Phase 0:OpenGL渲染框架(1周)
目标:窗口+相机+基础渲染
产出:
- 创建OpenGL 3.3窗口
- 轨道相机(鼠标旋转/缩放/平移)
- 渲染坐标轴和网格地面
- 渲染一个彩色立方体
验证标准:
- 窗口正常显示,60fps
- 鼠标拖拽旋转视角,滚轮缩放
- 坐标轴RGB三色清晰可见
Phase 1:STL网格渲染(1周)
目标:加载并渲染STL文件
产出:
- STL文件解析(二进制+文本格式)
- 网格数据上传GPU
- 基础光照着色器(法线+方向光)
- 渲染一个STL模型文件
验证标准:
- 加载STL文件并正确渲染
- 光照效果正常,模型有立体感
- 可旋转查看模型各角度
Phase 2:URDF解析+机器人可视化(2周)
目标:加载URDF,显示完整机器人
产出:
- URDF文件解析(urdf-rs库)
- 关节树构建(parent-child关系)
- 每个link的visual mesh渲染
- 关节坐标系可视化(小坐标轴)
- egui面板:显示机器人信息
验证标准:
- 加载简易2轴机械臂URDF
- 所有link正确渲染在对应位置
- 关节坐标系方向正确
Phase 3:正运动学(1周)
目标:驱动关节旋转,实时更新姿态
产出:
- DH参数提取(从URDF joint定义)
- 正运动学求解(递归遍历关节树)
- egui滑块控制各关节角度
- 关节旋转时mesh实时更新
验证标准:
- 拖动滑块,关节实时旋转
- 末端执行器位置计算正确
- 所有子link跟随父link运动
Phase 4:逆运动学(2周)
目标:指定末端位置,自动求解关节角
产出:
- 雅可比矩阵计算
- 伪逆法IK求解
- 阻尼最小二乘法(避免奇异点)
- egui面板:输入目标位姿,点击求解
验证标准:
- 输入目标位置,关节自动调整
- 求解结果末端位置误差<1mm
- 奇异点附近不发散
Phase 5:ROS2通信(2周)
目标:与ROS2系统互联互通
产出:
- rclrs节点创建
- /joint_states话题发布
- /joint_trajectory话题订阅
- TF树广播
- 脱离ROS2时独立运行(feature flag控制)
验证标准:
- ros2 topic echo /joint_states能看到数据
- ros2 run rviz2 rviz2能显示机器人模型
- 发送轨迹命令,仿真器执行运动
Phase 6:碰撞检测(1周)
目标:检测机器人自碰撞和环境碰撞
产出:
- parry3d碰撞场景构建
- 自碰撞检测(link之间)
- 环境碰撞检测(障碍物)
- 碰撞可视化(碰撞对高亮显示)
- PlanningScene查询接口
验证标准:
- 关节运动到自碰撞位置时检测到碰撞
- 碰撞的link对高亮显示为红色
- PlanningScene查询返回正确碰撞结果
Phase 7:MoveIt2对接(2周)
目标:完整规划-执行闭环
产出:
- MoveIt2配置文件生成(SRDF/Kinematics)
- PlanningScene服务端
- ExecuteTrajectoryAction服务端
- 端到端demo:MoveIt2规划→仿真器执行
验证标准:
- MoveIt2 RViz插件中规划路径
- 仿真器接收轨迹并执行运动
- 碰撞场景同步,避障规划生效
Phase 8:树莓派移植(1周)
目标:ARM平台运行
产出:
- 交叉编译配置(aarch64-unknown-linux-gnu)
- EGL上下文创建(替代GLFW)
- 渲染性能优化(LOD/简化着色器)
- 启动脚本和部署文档
验证标准:
- 树莓派4上编译运行
- 渲染帧率≥15fps
- ROS2通信正常
六、关键技术决策
| 决策项 | 选择 | 理由 |
|---|---|---|
| 渲染API | OpenGL 3.3 | 树莓派4支持,Rust生态成熟 |
| URDF解析 | urdf-rs | 已有Rust库,避免重复造轮子 |
| 碰撞检测 | parry3d | Rust原生,与nalgebra同生态 |
| ROS2绑定 | rclrs | 官方Rust绑定,活跃维护 |
| 窗口库 | winit | 跨平台标准,egui原生支持 |
| IK算法 | 阻尼最小二乘 | 通用性好,不依赖特定构型 |
| 相机模型 | 轨道相机 | 适合3D查看,实现简单 |
七、风险与对策
| 风险 | 影响 | 对策 |
|---|---|---|
| rclrs功能不完整 | ROS2通信受限 | 备选r2r库,或FFI调用rcl C接口 |
| 树莓派GL驱动不稳定 | 渲染异常 | 提供OpenGL ES 3.0回退路径 |
| IK求解不收敛 | 运动控制失败 | 提供关节限位+迭代次数上限 |
| URDF格式差异大 | 解析失败 | 先支持核心标签,逐步扩展 |
| parry3d性能不足 | 碰撞检测慢 | 使用AABB粗筛+OBB精筛两级策略 |
八、与Rust系列文章关系
本系统作为Rust底层开发系列的第6篇(终极实战篇),覆盖前5篇所有知识点:
| 系列篇数 | 知识点 | 仿真系统中的应用 |
|---|---|---|
| 第1篇 | 环境搭建 | Cargo项目配置、依赖管理 |
| 第2篇 | 所有权 | Robot/Joint数据结构的生命周期管理 |
| 第3篇 | Trait+泛型 | Renderable Trait、JointType枚举 |
| 第4篇 | 并发+FFI | ROS2多线程通信、OpenGL C接口调用 |
| 第5篇 | 系统实战 | 完整项目架构、模块化设计 |
九、验收标准
最小可用版本(Phase 0-3完成)
- [ ] 加载URDF文件显示机器人模型
- [ ] 鼠标控制相机旋转/缩放
- [ ] 滑块控制关节角度
- [ ] 正运动学实时更新
完整版本(Phase 0-7完成)
- [ ] ROS2 joint_states发布
- [ ] ROS2 trajectory订阅执行
- [ ] 碰撞检测+可视化
- [ ] MoveIt2规划-执行闭环
移植版本(Phase 0-8完成)
- [ ] 树莓派4编译运行
- [ ] 渲染帧率≥15fps
- [ ] ROS2通信正常
十、开发进度记录
最后更新:2026-05-01
当前状态:Phase 0-3 完成(Step 0-11 已完成)
Step-by-Step 开发进度
| Step | 内容 | 状态 | 说明 |
|---|---|---|---|
| Step 0 | 检查VM OpenGL环境 | ✅ 已完成 | 虚拟机Ubuntu 22.04,需软件渲染 |
| Step 1 | 创建Cargo项目+依赖 | ✅ 已完成 | glow 0.14 + winit 0.30 + glutin 0.32 |
| Step 2 | 创建OpenGL窗口+日志 | ✅ 已完成 | 遇到EGL初始化问题,转向headless |
| Step 3 | 渲染彩色三角形 | ✅ 已完成 | 验证着色器管线正常 |
| Step 4 | 添加轨道相机+鼠标控制 | ✅ 已完成 | 球坐标OrbitCamera实现 |
| Step 5 | 渲染坐标轴+网格地面 | ✅ 已完成 | Headless模式3帧验证通过 |
| Step 6 | 渲染简易2轴机械臂(几何体) | ✅ 已完成 | 圆柱体base+长方体link1/link2+层级变换 |
| Step 7 | 添加关节旋转动画 | ✅ 已完成 | 正弦波动画+键盘控制+窗口模式 |
| Step 8 | 添加egui控制面板 | ✅ 已完成 | 关节滑块+末端位置+FPS显示 |
| Step 9 | 逆运动学求解器 | ✅ 已完成 | DLS阻尼最小二乘+数值雅可比+目标标记 |
| Step 10 | 轨迹规划与回放 | ✅ 已完成 | 录制/回放/暂停/循环+速度控制 |
| Step 11 | 碰撞检测 | ✅ 已完成 | 地面碰撞+自碰撞+红色高亮 |
已完成步骤详细记录
Step 0:VM OpenGL环境检查
- 环境:Ubuntu 22.04 虚拟机(192.168.170.128),8GB内存
- 发现:虚拟机无硬件GPU加速,需使用软件渲染(
LIBGL_ALWAYS_SOFTWARE=1) - X11转发:需设置
DISPLAY=:0和XAUTHORITY环境变量
Step 1:Cargo项目创建
- 项目路径:
~/robot_sim/ - 本地开发文件:
d:\code\doc\技术文章\temp\robot_sim_main.rs+Cargo.toml - Cargo源配置:已配置阿里云镜像(
~/.cargo/config.toml)
当前 Cargo.toml 依赖:
[package]
name = "robot_sim"
version = "0.1.0"
edition = "2021"
[dependencies]
glow = "0.14"
winit = "0.26"
glutin = "0.26"
tracing = "0.1"
tracing-subscriber = "0.3"
nalgebra = "0.33"
bytemuck = "1.16"
注意:winit和glutin版本锁定为0.26,因高版本API不兼容
Step 2-3:OpenGL窗口与着色器
- 关键决策:由于虚拟机EGL初始化失败,改用 headless渲染模式
- 着色器:OpenGL 3.3 Core Profile,顶点+片段着色器
- 着色器代码:
- 顶点着色器:
aPos→uView×uProj变换 - 片段着色器:
uColor均匀颜色输出
Step 4:轨道相机实现
- OrbitCamera 结构体:球坐标参数(theta, phi, distance, target)
- 视图矩阵:手写lookAt矩阵计算(eye/target/up)
- 交互:
orbit(delta_theta, delta_phi)旋转,zoom(delta)缩放 - phi限位:clamp(0.1, PI-0.1) 防止万向锁
Step 5:坐标轴+网格地面渲染
- 网格地面:20×20单位,步长1.0,共84条线
- 坐标轴:X=红色,Y=绿色,Z=蓝色,各5单位长
- 渲染验证:Headless模式3帧渲染循环,通过日志验证
- 相机轨道验证:每帧orbit(0.1, 0.0),日志输出theta/phi值
Step 6:简易2轴机械臂渲染
- 机械臂结构:
- Base:圆柱体(半径0.4,高度0.3),灰色,固定在地面
- Link1:长方体(0.25×1.2×0.25),橙色,上臂
- Link2:长方体(1.0×0.2×0.2),蓝色,前臂
- 关节定义:
- Joint0:绕Y轴旋转(base腰部旋转),位于base顶部(y=0.3)
- Joint1:绕Z轴旋转(shoulder俯仰),位于link1顶部(y=1.5)
- 层级变换链:
- Base:
T(0, 0.15, 0) - Link1:
T(0, 0.3, 0) × Ry(j0) × T(0, 0.6, 0) - Link2:
T(0, 0.3, 0) × Ry(j0) × T(0, 1.2, 0) × Rz(j1) × T(0.5, 0, 0) - 新增矩阵运算:
mat4_identity,mat4_mul,mat4_translate,mat4_rotate_y,mat4_rotate_z,mat4_to_flat - 新增几何体生成器:
generate_cylinder(radius, height, segments),generate_cuboid(w, h, d) - 着色器更新:添加
uniform mat4 uModel,顶点变换改为uProj × uView × uModel × aPos - 关节坐标系指示器:0.3单位长小坐标轴,在每个关节位置渲染
- 末端执行器位置计算:
get_end_effector_pos()通过变换链计算 - 矩阵约定修复(关键bug修复):
- 原代码使用行主序矩阵(平移在最后一行),但点变换用
M*v(列向量)约定 - 修复为列主序:平移在第4列,旋转矩阵转置
- 视图矩阵:从行主序lookAt改为列主序(转置+平移移到第4列)
- 投影矩阵:从行主序改为列主序(-1移到第4行,2fn移到第4列)
- 验证结果(Headless 7帧,VM Ubuntu 24.04):
- Frame 1 (0°,0°): EE=(1.0000,1.5000,0.0000) PASS
- Frame 2 (45°,0°): EE=(0.7071,1.5000,0.7071) PASS
- Frame 3 (45°,45°): EE=(0.5000,2.2071,0.5000) PASS
- Frame 4 (90°,0°): EE=(0.0000,1.5000,1.0000) PASS
- Frame 5 (0°,90°): EE=(0.0000,2.5000,0.0000) PASS
- Frame 6 (0°,-45°): EE=(0.7071,0.7929,0.0000) PASS
- Frame 7 (180°,90°): EE=(0.0000,2.5000,0.0000) PASS
- 相机调整:target改为(0, 0.8, 0),distance改为6.0,更适合观察机械臂
踩坑经验总结
| 问题 | 原因 | 解决方案 |
|---|---|---|
| EGL初始化失败 | 虚拟机无GPU/DRM设备 | 使用glutin headless模式 |
| VSync扩展未找到 | 软件渲染不支持 | with_vsync(false) |
| Cargo下载慢 | 默认crates.io源慢 | 配置阿里云镜像 |
| winit API不兼容 | 版本0.30+ API大改 | 锁定winit 0.26 |
| glow HasContext未导入 | Rust trait需显式use | use glow::HasContext |
| 中文编码问题 | 源文件含非ASCII字符 | 源码使用纯ASCII |
| Cargo包缓存锁 | 多进程并发访问 | killall -9 cargo; rm ~/.cargo/.package-cache |
| 矩阵行/列主序混淆 | 平移在最后一行但点变换用M*v | 统一为列主序:平移在第4列,旋转转置 |
| VM Wayland不兼容glutin | glutin 0.26无法在Wayland创建EGL | 使用headless模式或DISPLAY=:99(Xvfb) |
当前代码架构(单文件 main.rs)
main.rs
├── OrbitCamera // 轨道相机(球坐标)
│ ├── new() // 初始化
│ ├── get_view_matrix() // 计算视图矩阵
│ ├── orbit() // 旋转
│ └── zoom() // 缩放
├── perspective() // 透视投影矩阵
├── mat4_*() // 4x4矩阵运算(identity/mul/translate/rotate_y/rotate_z/to_flat)
├── generate_target_marker() // IK目标位置十字标记
├── compute_jacobian() // 数值雅可比矩阵(有限差分法)
├── mat3_det/inverse() // 3x3矩阵运算(备用)
├── solve_ik_step() // DLS阻尼最小二乘IK单步求解
├── generate_cylinder() // 圆柱体顶点生成
├── generate_cuboid() // 长方体顶点生成
├── RobotArm // 2轴机械臂
│ ├── new() // 初始化
│ ├── get_base/link1/link2_transform() // 模型矩阵
│ ├── get_joint0/joint1_frame() // 关节坐标系
│ └── get_end_effector_pos() // 末端执行器位置
├── TrajPoint + Trajectory // 轨迹点+轨迹管理
│ ├── start/stop_record() // 录制控制
│ ├── start/pause/stop_play() // 回放控制
│ └── update() // 线性插值回放
├── CollisionState + check_collisions() // 碰撞检测
├── App // 应用主结构体
│ ├── init_gl() // OpenGL+egui初始化
│ └── render() // 渲染循环(动画+IK+轨迹+碰撞+3D渲染+egui面板)
└── main() // 入口
当前 Cargo.toml 依赖:
[dependencies]
glow = "0.14"
glutin = "0.32"
winit = "0.30"
glutin-winit = "0.5"
raw-window-handle = "0.6"
tracing = "0.1"
tracing-subscriber = "0.3"
bytemuck = "1.16"
egui = "0.30"
egui_glow = "0.30"
待开发步骤规划
Step 12+:后续开发方向
- URDF解析:使用urdf-rs库加载真实机器人模型
- STL网格渲染:加载并渲染STL文件,基础光照着色器
- ROS2通信:rclrs绑定,JointState发布/Trajectory订阅
- parry3d碰撞检测:替换简化碰撞为精确碰撞
- 树莓派移植:交叉编译+EGL上下文
Step 7-11 已完成功能详情
Step 7:关节旋转动画
- 正弦波动画:joint0 = sin(t0.5)PI/3, joint1 = sin(t0.7)PI/4
- 键盘控制:Q/A控制Joint0,W/S控制Joint1,Space切换动画
- 窗口模式:glutin 0.32 + winit 0.30,支持Wayland/X11
Step 8:egui控制面板
- 集成egui 0.30 + egui_glow 0.30
- 关节角度滑块(-PI~PI)
- 末端执行器位置实时显示
- FPS计数器
- 动画控制按钮
Step 9:逆运动学求解器
- 数值雅可比矩阵:有限差分法,delta=0.001
- DLS求解器:阻尼最小二乘法,2x2系统直接求逆
- 收敛判据:位置误差<0.001,最大迭代500次
- 目标标记:黄/青/品红三色十字标记
- egui控制:目标位置滑块、Set from EE、Solve IK按钮、Damping调节
- 验证结果:8个可达目标全部PASS,位置误差<1mm
Step 10:轨迹规划与回放
- TrajPoint:关节角度+时间戳
- 录制:30fps采样,记录关节角度序列
- 回放:线性插值,支持暂停/继续/停止
- 控制:速度调节(0.1x~3x)、循环播放
- 快捷键:P=播放/暂停,L=循环切换
Step 11:碰撞检测
- 地面碰撞:检测Link1/Link2最低点是否低于y=0
- 自碰撞:检测Link2折叠时是否与Base/Link1重叠
- 可视化:碰撞时link变红色
- egui控制:启用/禁用开关、碰撞状态显示
十一、版本历史
| 版本 | 日期 | 更新内容 |
|---|---|---|
| v1.0 | 2026-04-28 | 初始方案文档 |
| v1.1 | 2026-05-01 | 添加开发进度记录(Step 0-5完成,Step 6-8待开发) |
| v1.2 | 2026-05-01 | Step 6完成:2轴机械臂渲染+层级变换+关节坐标系+末端位置计算 |
| v1.3 | 2026-05-01 | 修复矩阵行/列主序bug,VM验证7帧全部PASS |