项目概述本项目基于 BCR Arm 机械臂https://github.com/blackcoffeerobotics/bcr_arm实现随机初始位置下红、蓝、紫三色积木的识别、抓取、三层堆叠、移除和换层任务并支持文字和语音指令。系统集成了视觉反馈闭环、任务状态机、异常恢复机制以及 Gazebo 场景快照功能技术实现RGB-D 相机识别红、蓝、紫三色积木随机初始位置下自动计算抓取位姿支持单块抓取、两层及三层堆叠指定颜色和层数的积木移除支持任意层间互换场景清空与恢复文字输入与语音指令控制Gazebo 场景快照保存与恢复Docker 环境一键部署系统架构语言与文本任务识别指令输入模块这里指令输入模块只要是使用了OpenAI的Whisper本地模型没有调用云端语音识别接口云端https://github.com/openai/whisper这里同时可以使用一些国内的语音识别的ASR的API接口例如科大讯飞的API接口https://www.xfyun.cn/services/online_tts这里调用的本地模型使用 PyAudio 采集 16kHz 单声道音频并保存为 WAV 文件再通过 Whisper base 模型进行中文语音识别。识别得到的文本随后送入任务解析模块将自然语言命令转换为结构化机械臂控制指令。result model.transcribe( audio_path, languageChinese, fp16False, temperature0.0, condition_on_previous_textFalse, initial_promptWHISPER_INITIAL_PROMPT, )这里本项目的自然语言解析用的是DeepSeek API,这里需要自费API接口的费用https://api-docs.deepseek.com/client OpenAI(api_keyapi_key, base_urlhttps://api.deepseek.com) DEFAULT_DEEPSEEK_MODEL deepseek-v4-flash任务解析识别模块任务识别模块负责将用户输入的自然语言命令转换为机械臂可以执行的结构化任务。系统同时支持文字输入和语音输入两种方式。文字输入时用户可以直接输入自然语言任务语音输入时系统使用 PyAudio 采集 16kHz 单声道音频并保存为临时 WAV 文件。随后通过本地 Whisper base 模型进行中文语音识别得到用户命令文本。为了提升机械臂任务场景下的识别准确率在 Whisper 识别时加入了机械臂领域提示词例如“蓝色、红色、紫色、木块、第一层、第二层、第三层、回正”等常见命令词。得到文本后系统调用 DeepSeek 大语言模型进行任务解析将自然语言转换为严格的结构化 JSON。解析结果包括任务类型、目标颜色、目标层数、是否连续执行、是否回到初始姿态等字段。例如{ tasks: [ { task_mode: place, source_color: blue, target_layer: 1, return_to_upright_after_task: false, chain_from_stack: false, post_remove_hover_layer: 0, post_remove_source_color: , use_source_home_pose: false, remove_buffer_slot: 0 } ] }字段说明字段名称类型含义task_modestring任务类型place表示放置remove表示移除source_colorstring目标积木颜色可选blue、red、purpletarget_layerint目标层数可选1、2、3return_to_upright_after_taskbool当前任务结束后是否回到机械臂初始姿态chain_from_stackbool是否从当前堆叠状态连续执行下一步任务post_remove_hover_layerint移除任务完成后机械臂返回到指定层上方的安全悬停位置0表示不使用post_remove_source_colorstring移除任务完成后下一步需要前往抓取的源区颜色为空表示不指定use_source_home_posebool是否使用之前保存的源区位姿进行抓取常用于remove后重新placeremove_buffer_slotint换层任务中的临时缓存区编号0表示不使用缓存区任务识别模块负责将用户的语音或文本指令转换为系统可执行的结构化任务。对于语音输入系统会先完成语音转文字对于文本输入则直接进入任务解析流程。随后LLM 根据自然语言内容识别任务意图并提取任务类型、目标颜色、目标层数、是否连续执行等关键信息最终生成统一格式的结构化 JSON。在得到 JSON 后系统不会直接执行而是先进行字段校验确保任务类型、颜色、层数和连续执行参数合法。校验通过后控制端将结构化任务封装为 ROS2 服务请求并发送到 /execute_stack_task由机械臂执行节点统一调度。执行节点收到任务后会根据任务类型进入不同流程。如果是堆叠任务系统会等待 RGB-D 相机检测目标积木和放置区域如果是移除或换层任务则会结合当前堆叠状态和已保存的层信息确定抓取目标。随后系统根据视觉检测结果计算抓取高度、放置高度、夹爪 yaw 角和转移路径并调用 MoveIt2 完成运动规划与轨迹执行。在整个流程中LLM 只负责自然语言理解和任务结构化不直接参与机械臂底层控制。真正的运动执行由 ROS2 服务、任务状态机、MoveIt2 规划模块和 Gazebo 仿真环境完成。这样既保留了自然语言交互的灵活性也避免了大模型直接控制机械臂带来的不确定性多步任务实例交换第二层和第三层{ tasks: [ { task_mode: remove, source_color: red, target_layer: 3, return_to_upright_after_task: false, chain_from_stack: false, post_remove_hover_layer: 2, post_remove_source_color: , use_source_home_pose: false, remove_buffer_slot: 1 }, { task_mode: remove, source_color: purple, target_layer: 2, return_to_upright_after_task: false, chain_from_stack: false, post_remove_hover_layer: 0, post_remove_source_color: red, use_source_home_pose: false, remove_buffer_slot: 2 }, { task_mode: place, source_color: red, target_layer: 2, return_to_upright_after_task: false, chain_from_stack: true, post_remove_hover_layer: 0, post_remove_source_color: , use_source_home_pose: true, remove_buffer_slot: 0 }, { task_mode: place, source_color: purple, target_layer: 3, return_to_upright_after_task: false, chain_from_stack: true, post_remove_hover_layer: 0, post_remove_source_color: , use_source_home_pose: true, remove_buffer_slot: 0 } ] }这个 JSON 的含义是先移除第三层红色积木并放到缓存区 1再移除第二层紫色积木并放到缓存区 2然后从保存的源区位姿抓取红色积木放到第二层最后从保存的源区位姿抓取紫色积木放到第三层完成换层流程图如下RGB-D视觉感知模块视觉感知模块RGB-D 相机实现积木和放置区域的实时感知。系统从相机获取彩色图像与深度信息后对红、蓝、紫三色积木进行颜色分割提取目标区域轮廓代码如下def detect_color_block(rgb_image, color): hsv cv2.cvtColor(rgb_image, cv2.COLOR_BGR2HSV) color_ranges { red: [ (np.array([0, 80, 80]), np.array([10, 255, 255])), (np.array([170, 80, 80]), np.array([180, 255, 255])) ], blue: [ (np.array([95, 80, 80]), np.array([130, 255, 255])) ], purple: [ (np.array([130, 60, 60]), np.array([165, 255, 255])) ] } mask np.zeros(hsv.shape[:2], dtypenp.uint8) for lower, upper in color_ranges[color]: mask | cv2.inRange(hsv, lower, upper) mask cv2.morphologyEx(mask, cv2.MORPH_OPEN, np.ones((5, 5), np.uint8)) mask cv2.morphologyEx(mask, cv2.MORPH_CLOSE, np.ones((5, 5), np.uint8)) contours, _ cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) if not contours: return None contour max(contours, keycv2.contourArea) if cv2.contourArea(contour) 100: return None rect cv2.minAreaRect(contour) (u, v), (w, h), angle rect return { pixel_x: int(u), pixel_y: int(v), width: w, height: h, yaw: angle, contour: contour }RGB相机下的视角俯视侧视检测与视觉修正RGB相机视角根据颜色分割同时结合深度图计算积木在世界坐标系下的三维位置。同时根据积木轮廓方向估计其平面姿态角为后续夹爪对准和抓取规划提供目标位姿。#深度图转换为三维坐标 def pixel_to_camera_point(u, v, depth_image, fx, fy, cx, cy): depth depth_image[v, u] if depth 0: return None z depth x (u - cx) * z / fx y (v - cy) * z / fy return x, y, z #估计积木yaw角 import math def estimate_block_yaw(contour): rect cv2.minAreaRect(contour) (_, _), (w, h), angle rect if w h: angle angle 90.0 yaw math.radians(angle) return yaw在堆叠任务中视觉模块不仅用于识别待抓取积木还用于检测当前放置区域和已堆叠积木的位置。对于第二层、第三层放置系统会根据下层积木的实际中心点和姿态动态修正上层放置目标减少因仿真误差、抓取偏移和积木滑动造成的累计误差。#高层叠层时的视觉修正逻辑 def compute_place_target(base_block_pose, target_layer): block_height 0.045 safe_offset 0.010 target_x base_block_pose[x] target_y base_block_pose[y] target_yaw base_block_pose[yaw] target_z base_block_pose[z] block_height * target_layer safe_offset return { x: target_x, y: target_y, z: target_z, yaw: target_yaw }为了提高调试效率项目中额外实现了一个 RGB-D Camera View 可视化窗口。该窗口会实时显示相机图像将检测到的 red、blue、purple、place 等目标中心点标注在画面上。在开发过程中主要通过该 GUI 判断以下问题1. 当前颜色阈值是否能稳定识别积木2. 目标中心点是否落在积木真实中心附近3. 放置区域是否被正确检测4. 抓取失败是视觉检测误差导致还是运动规划/夹爪控制导致。运动规划模块在机械臂抓取和堆叠任务中运动规划是整个系统的核心部分。视觉模块只负责告诉系统“积木在哪里、姿态是什么样”而运动规划模块需要把这些位姿信息转换成机械臂可以执行的动作序列。如果直接让机械臂从当前位置一次性规划到抓取点或放置点轨迹往往不可控。尤其是在积木附近机械臂可能会出现低位横向移动、末端大角度旋转或者夹爪扫过堆叠区域的问题。因此本项目没有采用单段式规划而是将完整任务拆分为多个阶段笛卡尔规划执行整体流程如下移动到积木上方安全高度垂直向下到到抓取高度夹爪通常保持张开状态开口宽度要大于木块宽度保证下降时夹爪两侧不会提前碰到木块。闭合夹爪垂直抬升到安全高度水平转移到放置区的上方打开夹爪垂直撤离放置蓝色木块视频如下视频链接https://live.csdn.net/v/527331在规划方式上主要采用两种规划普通规划用于从upright状态到目标区域上方笛卡尔规划用于靠近积木的垂直下降抬升水平移动和放置任务保证末端执行器方向可控抓取阶段视觉模块检测到积木后系统会得到积木的中心坐标和 yaw 角。运动规划模块根据这些信息计算夹爪目标位姿。抓取时不是直接移动到积木位置而是先移动到积木上方的安全高度pick_high_pose 积木中心上方安全位置 pick_low_pose 夹爪实际抓取位置执行时先到 pick_high_pose再通过笛卡尔路径垂直下降到 pick_low_pose。这样可以避免机械臂从侧面靠近积木减少夹爪碰撞积木的概率。同时系统会根据积木 yaw 调整夹爪 yaw使夹爪两侧尽量对齐。这样可以提高夹爪闭合时的接触稳定性避免夹偏或把积木推走。视频链接https://live.csdn.net/v/527340转移阶段抓取成功后机械臂不会直接横向移动而是先把积木抬升到安全高度transfer_z max(当前层高度 安全余量, 默认安全高度)然后再进行水平转移。这个设计主要是为了避免积木在转移过程中碰到桌面、已有堆叠或其他积木。在换层任务中这一点更重要。因为机械臂可能需要从第二层或第三层取下积木再移动到源区或临时区域。如果抬升高度不够夹爪或被夹住的积木很容易碰到下层积木视频链接:https://live.csdn.net/v/527339放置阶段放置时同样采用“先到上方再垂直下降”的方式。系统先移动到目标放置区域上方的安全高度然后沿 Z 方向下降到放置高度打开夹爪释放积木最后再垂直抬升撤离。place_high_pose 放置点上方安全位置 place_low_pose 实际释放积木的位置这种方式可以保证积木是从上方放下去而不是从侧面推进去能减少放置过程中的偏移。视频链接:https://live.csdn.net/v/527338高层堆叠视觉纠正叠层修正策略一开始如果每一层都使用固定放置坐标堆到第二层、第三层时会出现明显误差累积。比如第一层积木放置后可能会有几厘米偏差如果第二层仍然按照理论坐标放置就可能没有放在第一层正上方导致堆叠不稳。具体来说第一层放置完成后系统会再次通过 RGB-D 相机检测当前已放置积木的实际位置和 yaw 角。后续第二层、第三层的放置目标不再完全依赖固定坐标而是根据下层积木的实际检测结果动态调整上层放置 x 下层积木实际 x 上层放置 y 下层积木实际 y 上层放置 yaw 下层积木实际 yaw 上层放置 z 下层高度 积木高度 安全补偿这样即使第一层存在一定偏移第二层仍然会跟随第一层的实际位置进行堆叠而不是继续按照理论位置放置。安全补偿是人为添加的这里是通过仿真观察来进行人为的微调得来的。在高层的堆叠处理中三层堆叠相比单块和双层放置更容易失败因为目标高度更高对z的方向误差更敏感同时下层积木可能存在轻微偏移误差会逐渐累积等系统在高层任务中根据目标层数动态调整放置高度而不是固定下降高度同时转移过程中保持较高安全高度避免扫到已有堆叠。// 1. 根据目标层数动态计算放置高度 poses.place_low_z place_pose.z config.place_low_offset_z static_castdouble(target_layer - 1) * cube_size; poses.place_center_z place_pose.z config.place_center_z_offset static_castdouble(target_layer - 1) * cube_size; // 高层放置额外补偿 if (target_layer 1) { poses.place_low_z config.stack_place_low_extra_offset; } // 2. 根据目标层数动态计算安全转移高度 const double base_transfer_z block_pose.z config.transfer_offset_z; const double min_stack_transfer_z poses.place_low_z config.stack_transfer_clearance_z; poses.transfer_z std::max(base_transfer_z, min_stack_transfer_z); if (target_layer 1) { poses.transfer_z std::max( poses.transfer_z, config.min_stack_transfer_z_abs ); }当目标层数大于第一层时系统不会直接使用固定放置点而是优先读取当前堆叠顶部积木的视觉检测结果将上层积木的 x、y 和 yaw 对齐到下层积木。如果当前视觉检测不可用则使用上一轮任务保存的堆叠状态作为备用参考。if (target_layer 1) { auto stack_reference_pose wait_for_stack_reference_pose( node, default_place_x, default_place_y, 3s ); if (stack_reference_pose.found) { place_pose.x stack_reference_pose.x; place_pose.y stack_reference_pose.y; place_pose.yaw stack_reference_pose.yaw; } else { auto persisted_stack_state load_persisted_stack_state(); if (persisted_stack_state.valid) { place_pose.x persisted_stack_state.x; place_pose.y persisted_stack_state.y; place_pose.yaw persisted_stack_state.yaw; } } }最终放置前还会做视觉修正微调if (target_layer 1) { // 高层放置前先到预释放高度 auto pre_release_pose active_place_low_pose; pre_release_pose.position.z active_place_low_pose.position.z pre_release_clearance_z; execute_cartesian_to_pose( node, move_group, cartesian_down_to_place_pre_release, pre_release_pose, 0.90 ); // 根据相机重新修正放置中心 refine_place_alignment_from_stack_camera( node, move_group, config, support_reference_topic, carried_reference_topic, place_target_label, pre_release_pose, active_place_high_pose, active_place_check_pose, active_place_low_pose, active_place_center_x, active_place_center_y ); }视觉修正蓝红紫放置视频链接https://live.csdn.net/v/527341ROS2执行与状态更新执行模块首先MoveIt2 会根据目标末端位姿计算一条可执行的关节轨迹。轨迹中包含多个时间点下各个关节的目标角度相当于告诉机械臂每个关节应该在什么时间运动到什么位置。规划成功后MoveIt2 会通过 FollowJointTrajectory 接口将轨迹发送给 joint_trajectory_controller。该控制器负责按照轨迹中的时间序列对机械臂关节进行插值和控制保证机械臂能够连续、平滑地完成动作。在仿真环境中joint_trajectory_controller 并不直接驱动真实电机而是通过 ros2_control 与 Gazebo 中的机械臂模型连接。ros2_control 相当于中间层它将 ROS2 控制指令转换为 Gazebo 关节可以执行的运动命令从而驱动仿真机械臂运动。夹爪部分使用独立的控制器进行开合控制。系统在抓取前发送打开夹爪指令使夹爪开口大于积木宽度当夹爪下降到抓取高度后发送闭合指令夹住积木到达放置位置后再发送打开指令释放积木。这样机械臂主体运动和夹爪动作可以分开控制。执行完成后任务并不会立即结束。系统会再次调用视觉检测模块对积木实际放置位置进行检查并根据检测结果更新当前堆叠状态。如果是连续任务例如多层堆叠或换层任务更新后的状态会作为下一步任务的输入。//轨迹规划 moveit::planning_interface::MoveGroupInterface::Plan plan; bool success static_castbool(move_group.plan(plan)); if (success) { move_group.execute(plan); } //夹爪控制 control_msgs::action::GripperCommand::Goal goal; goal.command.position 0.014; goal.command.max_effort 40.0; gripper_client-async_send_goal(goal);状态更新在本项目中放置完成后会先执行视觉检查若检测到积木成功放置则使用检测到的实际位置更新堆叠状态如果当前视觉检测不可用则使用本次规划中的目标位姿作为备用状态。移除任务完成后系统会根据被移除的层数更新当前最高层并记录新的顶部积木信息当所有积木都被移除后系统会清空持久化状态避免后续任务读取到过期数据。在机械臂完成一次抓取、放置或移除任务后系统不会简单地认为任务结束而是会根据视觉检查结果和当前任务类型更新内部状态。这个状态主要用于记录当前堆叠区有哪些积木、最高层是哪一层、每层积木的颜色、位置和 yaw 角。例如当系统完成第一层蓝色积木的放置后会记录struct StackState { bool valid; int top_layer; std::string top_color; double x; double y; double z; double yaw; }; void updateStackStateAfterPlace( StackState state, int target_layer, const std::string color, const DetectedPose placed_pose) { state.valid true; state.top_layer target_layer; state.top_color color; state.x placed_pose.x; state.y placed_pose.y; state.z placed_pose.z; state.yaw placed_pose.yaw; } //移除后的状态更新 void updateStackStateAfterRemove(StackState state, int removed_layer) { if (removed_layer 1) { state.valid false; state.top_layer 0; state.top_color.clear(); return; } state.top_layer removed_layer - 1; }当后续执行第二层或第三层放置时系统就可以根据这个状态知道下层积木在哪里从而修正高层放置目标。任务状态机与异常恢复机械臂抓取堆叠任务中一个完整任务并不是单次运动规划就能完成而是由多个连续阶段组成。为了让系统能够稳定执行堆叠、移除和换层任务本项目将任务拆分为多个状态并在每个状态后检查执行结果。如果某一步失败系统会根据失败类型选择重试、调整路径或终止任务。视觉检测失败如果相机没有在15秒内检测到目标积木或放置区域系统就会执行超时然后后终止任务避免使用错误位姿。if (!wait_for_detected_block_poses( node, red_block_pose, blue_block_pose, purple_block_pose, place_pose, require_red_pose, require_blue_pose, require_purple_pose, require_place_pose, 15s)) { if (failure_reason) { *failure_reason Timeout waiting for detected poses.; } return false; }路径规划失败如果 MoveIt2 或笛卡尔路径规划失败系统会停止当前阶段并根据任务类型选择是否提高安全高度后重试。//笛卡尔规划失败 const double fraction move_group.computeCartesianPath( waypoints, 0.005, 0.0, trajectory, avoid_collisions); if (fraction required_fraction) { RCLCPP_ERROR( node-get_logger(), Cartesian path failed: %s, fraction %.3f %.3f, name.c_str(), fraction, required_fraction ); return false; } //普通规划失败 moveit::planning_interface::MoveGroupInterface::Plan plan; const bool planned static_castbool(move_group.plan(plan)); if (!planned) { RCLCPP_ERROR(node-get_logger(), Pose planning failed: %s, name.c_str()); return false; }对于部分链式换层场景系统尝试在源区抓取前进行安全高度调整如果路径规划仍然失败则立即终止当前任务避免机械臂在不可靠位姿下继续抓取。if (!source_xy_reached(transfer_hover_z, _source_home_translate_xy_safe_height)) { const double retry_hover_z std::min( kSavedRemoveYawFallbackMaxZ, std::max({ transfer_hover_z 0.035, kSourceHomeChainTransferZ 0.035, retry_current_pose.position.z 0.030 })); if (!execute_cartesian_to_pose( node, move_group, motion_name _source_home_raise_for_xy_retry, retry_z_pose, 0.70)) { return false; } if (!source_xy_reached( retry_hover_z, _source_home_retry_translate_xy_safe_height)) { return false; } }抓取失败如果夹爪闭合后积木没有被稳定带起系统会通过后续位姿检测或任务结果判断失败并停止继续堆叠。const bool gripper_has_object got_gripper_opening gripper_opening min_gripper_opening_with_object; const bool got_after_pose wait_for_detected_pose_on_topic(node, topic_name, after_pose, timeout, false); original_position_cleared xy_shift original_position_xy_threshold; block_near_gripper eef_xy 0.120 eef_dz 0.030 eef_dz 0.200; int score 0; score gripper_has_object ? 1 : 0; score original_position_cleared ? 1 : 0; score block_near_gripper ? 1 : 0;放置失败放置后系统会再次调用视觉检测比较目标位置和实际位置的偏差如果偏差超过阈值则判定为放置失败。const double dx result.placed_pose.x - target_x; const double dy result.placed_pose.y - target_y; const double dz result.placed_pose.z - target_z; const double xy_error std::hypot(dx, dy); const double z_error std::abs(dz); const bool xy_ok xy_error xy_threshold; const bool z_ok z_error z_threshold;连续任务中断对于多层堆叠和换层任务如果中间某一步失败系统不会继续执行后续任务避免错误状态继续传播。for index, task in enumerate(tasks, start1): future client.call_async(request) rclpy.spin_until_future_complete(node, future) response future.result() if not response.success: print(f任务失败: {response.message}, filesys.stderr) return 7 print(f任务完成: {response.message})Gazebo场景快拍机制在机械臂堆叠和换层任务调试过程中经常需要反复测试同一个场景。例如蓝、紫、红三块积木已经堆成三层后需要多次测试“移除第三层”“交换第二层和第三层”等任务。如果每次失败后都手动重新搭建场景不仅耗时而且每次摆放的位置和角度也会有差异影响测试结果。为了解决这个问题项目中实现了 Gazebo 场景快照机制。快照机制可以记录当前仿真场景中各个积木的位置和姿态并保存为一个指定名称的场景状态。后续测试时可以直接恢复这个快照让积木重新回到保存时的位置和朝向。它的作用主要有三个提高重复测试效率避免每次手动重新摆放积木。保证测试场景一致使不同策略之间的对比更加可靠。方便调试复杂任务例如三层堆叠、移除任务和层间交换任务。项目结果从实验结果来看系统在单块抓取和一层放置任务中表现较稳定两层堆叠在加入视觉修正和安全高度策略后成功率明显提高三层堆叠由于对夹爪姿态、放置高度和下层稳定性要求更高仍然存在一定失败概率但整体能够完成完整流程验证。失败情况主要集中在以下几类积木在夹爪中发生轻微滑动、MoveIt2 笛卡尔路径规划 fraction 不足、夹爪 yaw 与积木边缘不完全对齐、高层放置时存在小幅偏移。针对这些问题项目中加入了分阶段运动、安全高度转移、视觉反馈修正和放置后检测等策略。任务类型成功率单块抓取98%二层堆叠90%三层堆叠89%二三层互换88%一三层互换78%一二层互换97%问题分析1. 视觉检测不稳定RGB-D 相机检测依赖颜色分割和深度信息。当积木被机械臂遮挡、距离相机较远或者积木颜色区域在图像中过小时可能出现检测不到目标、中心点偏移或 yaw 角估计不准的问题。尤其是在高层堆叠和移除任务中夹爪靠近积木后可能遮挡相机视野导致短时间内检测结果丢失。解决思路通过等待检测、超时退出、可视化 GUI 调试颜色分割效果以及在高层堆叠中使用已保存的堆叠状态作为备用参考减少视觉检测不稳定对任务执行的影响。2. MoveIt2 路径规划失败机械臂在靠近积木或堆叠区时工作空间较小夹爪姿态限制较多容易出现普通规划失败或笛卡尔路径 fraction 不足的问题。如果强行继续执行可能导致机械臂轨迹不完整或碰撞积木。解决思路将任务拆分为多个阶段远距离移动使用普通规划靠近积木后使用笛卡尔规划同时设置安全高度使机械臂先抬升再水平移动避免低位横向扫动。3. 夹爪 yaw 对齐问题积木是长方体夹爪方向如果没有和积木边缘对齐就算夹爪位置到达目标点也可能夹偏、推走积木或者抓取后发生滑动。尤其是在 remove 和换层任务中积木已经在高层位置夹爪方向错误会明显增加失败概率。解决思路根据视觉检测得到的积木 yaw 角计算夹爪目标 yaw并在安全高度完成方向对齐低位只进行垂直下降抓取避免在靠近积木时进行大角度旋转。4. 高层堆叠误差累积如果第二层、第三层仍然使用固定放置点第一层放置时产生的小偏差会继续累积导致上层积木没有放在下层中心位置堆叠稳定性下降。解决思路在高层堆叠时加入视觉反馈修正根据下层积木的实际中心点和 yaw 动态调整上层放置目标而不是完全依赖固定理论坐标。5. 积木在夹爪中滑动由于 Gazebo 中物理接触、摩擦参数和夹爪闭合力度都会影响抓取效果积木在转移过程中可能出现轻微滑动。滑动会导致放置时实际位置和规划位置不一致。解决思路采用预夹紧和最终夹紧两步夹爪控制并在转移过程中使用较高安全高度和较平稳的笛卡尔路径减少突然运动导致的滑动。6. 换层任务复杂度高换层任务不是单个抓取放置动作而是由多个 remove 和 place 任务组合而成。中间如果某一步位置偏移、状态更新错误或路径规划失败后续任务都会受到影响。解决思路通过任务状态机保存每层积木颜色、位置、yaw 和悬停点信息每一步执行后更新堆叠状态失败时中断后续任务避免错误继续传播。技术栈模块技术工具操作系统/中间件Ubuntu 22.04 / ROS2 Humble运动规划MoveIt2仿真环境Gazebo / ros_gz感知输入RGB-D Camera交互方式文本指令 / 语音指令 / LLM附件Gazebo 仿真截图与演示视频红蓝紫实现搭建三层语音https://live.csdn.net/v/527318红蓝紫实现拆解三层语音https://live.csdn.net/v/527319蓝紫红实现搭建三层语音https://live.csdn.net/v/527324蓝紫红实现拆解三层文本https://live.csdn.net/v/527327篮紫红实现二三层换层https://live.csdn.net/v/527315蓝红紫实现搭建三层语音https://live.csdn.net/v/527320蓝红紫实现拆解三层语音https://live.csdn.net/v/527321无语音文本实现搭建三层https://live.csdn.net/v/527260后续优化方向视觉优化增强视觉感知能力引入动态障碍物避障、多角度多相机融合以及深度学习目标识别提高复杂场景下积木识别和定位精度。任务规划与智能化升级 LLM/DeepSeek 解析能力支持组合任务、条件逻辑任务结合强化学习或模仿学习优化放置策略提高机械臂自主决策能力。。用户交互与可视化开发网页或平板端实时控制界面展示任务进度、堆叠状态与成功率增加语音对话式控制提升用户操作便利性与交互体验。