diff --git a/CLAUDE.md b/CLAUDE.md index 579f724..c49c241 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -199,6 +199,26 @@ wall_position = [2.0, 0.0, 1.0] # 错误! **修复文件**:`src/simulation/environment.py` +### RRT*算法路径终点精度问题(2025-09-13)🚧 进行中 +**现象**:路径规划生成的路径终点不是精确的目标配置,存在数厘米的偏差。 + +**根本原因**: +- RRT*算法使用`STEP_SIZE = 0.1`(约5.7度)作为目标到达判断条件 +- 当新节点与目标距离 < 0.1弧度时,算法认为"到达目标"并返回路径 +- 但此时的终点节点不是精确的目标配置,存在最大0.1弧度的关节误差 +- 这导致末端执行器位置偏差数厘米 + +**调试发现**: +- 逆运动学求解完全正确(误差0.0000m) +- 问题在于RRT*的目标判断条件过于宽松 +- 实际终点vs期望终点示例:`[0.606, 0.502, 0.511]` vs `[0.600, 0.500, 0.500]` + +**解决方案**: +- 修改ai_rrt_star.py第205行的目标到达判断条件 +- 使用更严格的精度要求,确保路径终点是精确目标 + +**修复文件**:`src/planning/ai_rrt_star.py`(第205行) + ### 代码重复和一致性问题(2025-09-12)✅ 已解决 **现象**: 1. `path_executor.py` 中存在未使用的重复方法 `_move_to_configuration_reset()` diff --git a/src/planning/ai_rrt_star.py b/src/planning/ai_rrt_star.py index abca813..a8ecd22 100644 --- a/src/planning/ai_rrt_star.py +++ b/src/planning/ai_rrt_star.py @@ -24,6 +24,7 @@ GOAL_SAMPLE_RATE = 0.15 SEARCH_RADIUS = 0.5 HOLE_BIAS_RATE = 0.3 ENFORCE_HOLE_CROSSING = False +GOAL_TOLERANCE = 0.01 # 目标到达精度容差(弧度) class TreeNode: @@ -201,8 +202,8 @@ class AIRRTStarPlanner: # 更新自适应参数 self.params.update(success=True) - # 检查是否到达目标 - if np.linalg.norm(new_config - np.array(goal_config)) < self.params.step_size: + # 检查是否到达目标(使用严格的精度要求) + if np.linalg.norm(new_config - np.array(goal_config)) < GOAL_TOLERANCE: # 找到路径,提取并返回 path = self._extract_path(new_node) diff --git a/src/planning/path_executor.py b/src/planning/path_executor.py index 8a33503..a7e336c 100644 --- a/src/planning/path_executor.py +++ b/src/planning/path_executor.py @@ -98,8 +98,9 @@ class PathExecutor: self.arm_controller.set_joint_positions(interpolated.tolist()) - # 执行仿真步进,让物理引擎更新 - p.stepSimulation(physicsClientId=self.arm_controller.physics_client) + # 执行多次仿真步进让控制器充分收敛 + for _ in range(10): + p.stepSimulation(physicsClientId=self.arm_controller.physics_client) time.sleep(self.timestep) @@ -113,13 +114,26 @@ class PathExecutor: np.array(target_config) - np.array(final_config) ) if final_distance <= self.position_tolerance: + # 输出成功到达的调试信息 + target_pos, _ = self.arm_controller.forward_kinematics(target_config) + actual_pos, _ = self.arm_controller.get_current_pose() + pos_error = np.linalg.norm(np.array(target_pos) - np.array(actual_pos)) + print(f"waypoint {getattr(self, '_current_waypoint', 'N')} 成功: 关节误差{final_distance:.4f}, 末端位置误差{pos_error:.4f}m") return True - # 执行仿真步进 - p.stepSimulation(physicsClientId=self.arm_controller.physics_client) + # 执行多次仿真步进让机械臂继续收敛 + for _ in range(10): + p.stepSimulation(physicsClientId=self.arm_controller.physics_client) time.sleep(self.timestep) final_config = self.arm_controller.get_current_joint_positions() final_distance = np.linalg.norm(np.array(target_config) - np.array(final_config)) + + # 输出调试信息 + target_pos, _ = self.arm_controller.forward_kinematics(target_config) + actual_pos, _ = self.arm_controller.get_current_pose() + pos_error = np.linalg.norm(np.array(target_pos) - np.array(actual_pos)) + print(f"waypoint {getattr(self, '_current_waypoint', 'X')} 失败: 关节误差{final_distance:.4f}, 末端位置误差{pos_error:.4f}m") + raise RuntimeError(f"Failed to reach target, error: {final_distance}") def _close_gripper(self):