1. 系统架构设计
1.1 系统组成模块
- [Vision System] --> [Perception Node]
- |<robot name="industrial_arm">
- <group name="manipulator">
- <chain base_link="base_link" tip_link="tool0"/>
- </group>
-
- <end_effector name="gripper" parent_link="tool0" group="gripper"/>
- </robot> |
- [Gazebo Sim] <--> [ROS2 Control] <--> [MoveIt! Planner]
- |<robot name="industrial_arm">
- <group name="manipulator">
- <chain base_link="base_link" tip_link="tool0"/>
- </group>
-
- <end_effector name="gripper" parent_link="tool0" group="gripper"/>
- </robot> |
- [Hardware Interface] --> [Real Arm]
复制代码 1.2 技术栈选型
- 操作系统:Ubuntu 22.04 LTS;
- 机器人框架:ROS2 Humble Hawksbill;
- 运动规划:MoveIt2 + OMPL;
- 仿真环境:Gazebo 11 + Ignition;
- 视觉处理:OpenCV 4.5 + RealSense D435i;
- 开发语言:C++(核心模块) + Python(快速验证)。
2. 开发环境搭建
2.1 基础环境配置
- # 安装ROS2 Humble
- sudo apt install ros-humble-desktop
- # 安装MoveIt2
- sudo apt install ros-humble-moveit
- # 创建工作空间
- mkdir -p ~/arm_ws/src
- cd ~/arm_ws/
- colcon build --symlink-install
复制代码 2.2 关键依赖安装
- # 工业机械臂驱动包
- sudo apt install ros-humble-industrial-core
- # 视觉处理包
- sudo apt install ros-humble-vision-opencv
- # 深度相机驱动
- sudo apt install ros-humble-realsense2
复制代码 3. 机械臂运动学建模
3.1 URDF模型构建(示例:6轴机械臂)
- <robot name="industrial_arm" xmlns:xacro="http://www.ros.org/wiki/xacro">
- <xacro:macro name="arm_joint" params="name parent child origin_xyz origin_rpy">
- <joint name="${name}_joint" type="revolute">
- <parent link="${parent}"/>
- <child link="${child}"/>
- <origin xyz="${origin_xyz}" rpy="${origin_rpy}"/>
-
- <limit effort="100" velocity="1.0" lower="${-pi}" upper="${pi}"/>
- </joint>
- </xacro:macro>
-
-
- <link name="base_link">
- <visual>
- <geometry>
- <cylinder radius="0.15" length="0.1"/>
- </geometry>
- </visual>
- </link>
-
-
- <xacro:arm_joint
- name="joint1"
- parent="base_link"
- child="link1"
- origin_xyz="0 0 0.1"
- origin_rpy="0 0 0"/>
-
-
- </robot>
复制代码 3.2 运动学参数配置(SRDF文件)
- <robot name="industrial_arm">
- <group name="manipulator">
- <chain base_link="base_link" tip_link="tool0"/>
- </group>
-
- <end_effector name="gripper" parent_link="tool0" group="gripper"/>
- </robot>
复制代码 4. 核心运动规划实现
4.1 MoveIt!配置流程
- # 初始化MoveIt!配置包
- ros2 launch moveit_setup_assistant setup_assistant.launch
复制代码 配置关键参数:
- 规划组设置(Planning Groups);
- 碰撞矩阵(Collision Matrix);
- 被动关节(Passive Joints);
- 末端执行器(End Effectors)。
4.2 逆运动学求解(C++实现)
- // arm_controller/src/ik_solver.cpp#include class IKSolver {public: bool computeIK(const geometry_msgs::msg::PoseStamped& target_pose,<robot name="industrial_arm">
- <group name="manipulator">
- <chain base_link="base_link" tip_link="tool0"/>
- </group>
-
- <end_effector name="gripper" parent_link="tool0" group="gripper"/>
- </robot> std::vector& joint_values) { moveit::core::RobotStatePtr current_state = move_group->getCurrentState(); bool found_ik = current_state->setFromIK( move_group->getRobotModel()->getJointModelGroup("manipulator"), target_pose.pose, 10, 0.1); if(found_ik) { current_state->copyJointGroupPositions( "manipulator", joint_values); return true; } return false; }};
复制代码 5. 任务规划器开发
5.1 行为树实现(Python版)
- # task_planner/bt_nodes/assembly_task.pyfrom py_trees import Behaviour, Blackboardfrom py_trees.common import Status class PickPlaceTask(Behaviour): def __init__(self, name): super().__init__(name) self.blackboard = Blackboard() def update(self): # 1. 获取视觉目标位姿 target_pose = self.blackboard.get("target_pose")<robot name="industrial_arm">
- <group name="manipulator">
- <chain base_link="base_link" tip_link="tool0"/>
- </group>
-
- <end_effector name="gripper" parent_link="tool0" group="gripper"/>
- </robot> # 2. 规划抓取路径 if not self.plan_grasp(target_pose):<robot name="industrial_arm">
- <group name="manipulator">
- <chain base_link="base_link" tip_link="tool0"/>
- </group>
-
- <end_effector name="gripper" parent_link="tool0" group="gripper"/>
- </robot>return Status.FAILURE<robot name="industrial_arm">
- <group name="manipulator">
- <chain base_link="base_link" tip_link="tool0"/>
- </group>
-
- <end_effector name="gripper" parent_link="tool0" group="gripper"/>
- </robot> # 3. 执行抓取动作 self.execute_grasp()<robot name="industrial_arm">
- <group name="manipulator">
- <chain base_link="base_link" tip_link="tool0"/>
- </group>
-
- <end_effector name="gripper" parent_link="tool0" group="gripper"/>
- </robot> # 4. 规划放置路径 if not self.plan_place():<robot name="industrial_arm">
- <group name="manipulator">
- <chain base_link="base_link" tip_link="tool0"/>
- </group>
-
- <end_effector name="gripper" parent_link="tool0" group="gripper"/>
- </robot>return Status.FAILURE<robot name="industrial_arm">
- <group name="manipulator">
- <chain base_link="base_link" tip_link="tool0"/>
- </group>
-
- <end_effector name="gripper" parent_link="tool0" group="gripper"/>
- </robot> return Status.SUCCESS def plan_grasp(self, target_pose): # 调用MoveIt!规划服务 return True
复制代码 5.2 状态机实现(C++版)
- // task_planner/include/state_machine.h
- #include <smacc2/smacc2.hpp>
-
- class AssemblySM : public smacc2::SmaccStateMachineBase {
- public:
- using SmaccStateMachineBase::SmaccStateMachineBase;
-
- struct Orthogonal : smacc2::Orthogonal<Orthogonal> {};
-
- struct StateIdle : smacc2::SmaccState<StateIdle, AssemblySM> {
- smacc2::Transition onEvent() override {
- return transit<StatePick>();
- }
- };
-
- // 后续状态定义(略)
- };
复制代码 6. 视觉伺服系统集成
6.1 深度相机标定
- # 相机内参标定
- ros2 run camera_calibration cameracalibrator \
- --size 8x6 --square 0.0245 image:=/camera/color/image_raw
复制代码 6.2 目标检测与位姿估计(Python实现)
- # vision_system/src/object_detector.pyimport cv2import numpy as np class ObjectDetector: def __init__(self): self.aruco_dict = cv2.aruco.Dictionary_get(cv2.aruco.DICT_6X6_250) self.aruco_params = cv2.aruco.DetectorParameters_create() def detect_pose(self, img): gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) corners, ids, _ = cv2.aruco.detectMarkers(<robot name="industrial_arm">
- <group name="manipulator">
- <chain base_link="base_link" tip_link="tool0"/>
- </group>
-
- <end_effector name="gripper" parent_link="tool0" group="gripper"/>
- </robot>gray, self.aruco_dict, parameters=self.aruco_params)<robot name="industrial_arm">
- <group name="manipulator">
- <chain base_link="base_link" tip_link="tool0"/>
- </group>
-
- <end_effector name="gripper" parent_link="tool0" group="gripper"/>
- </robot> if ids is not None:<robot name="industrial_arm">
- <group name="manipulator">
- <chain base_link="base_link" tip_link="tool0"/>
- </group>
-
- <end_effector name="gripper" parent_link="tool0" group="gripper"/>
- </robot>rvec, tvec, _ = cv2.aruco.estimatePoseSingleMarkers(<robot name="industrial_arm">
- <group name="manipulator">
- <chain base_link="base_link" tip_link="tool0"/>
- </group>
-
- <end_effector name="gripper" parent_link="tool0" group="gripper"/>
- </robot> corners, 0.05, camera_matrix, dist_coeffs)<robot name="industrial_arm">
- <group name="manipulator">
- <chain base_link="base_link" tip_link="tool0"/>
- </group>
-
- <end_effector name="gripper" parent_link="tool0" group="gripper"/>
- </robot>return tvec[0][0], rvec[0][0] return None
复制代码 7. Gazebo仿真验证
7.1 仿真环境配置
- model://ground_plane 0 0 0.75 0 0 0 true model://table<robot name="industrial_arm">
- <group name="manipulator">
- <chain base_link="base_link" tip_link="tool0"/>
- </group>
-
- <end_effector name="gripper" parent_link="tool0" group="gripper"/>
- </robot> model://gear_part 0.3 0 0.8 0 0 0
复制代码 7.2 完整仿真流程
- # 启动仿真环境
- ros2 launch arm_gazebo assembly_world.launch.py
-
- # 启动MoveIt!规划场景
- ros2 launch arm_moveit_config moveit_rviz.launch.py
-
- # 启动控制节点
- ros2 run arm_controller arm_control_node
复制代码 8. 实机部署注意事项
[code]// 修改硬件接口驱动void write(const std::vector& commands) override { // 将关节角度转换为PWM信号 for(size_t i=0; i |