找回密码
 立即注册
首页 业界区 业界 基于ROS2/MoveIt!的工业机械臂控制系统开发全攻略 ...

基于ROS2/MoveIt!的工业机械臂控制系统开发全攻略

兑谓 2025-6-3 00:02:49
1. 系统架构设计

1.1 系统组成模块
  1. [Vision System] --> [Perception Node]
  2.           |<robot name="industrial_arm">
  3.   <group name="manipulator">
  4.     <chain base_link="base_link" tip_link="tool0"/>
  5.   </group>
  6.   
  7.   <end_effector name="gripper" parent_link="tool0" group="gripper"/>
  8. </robot> |
  9. [Gazebo Sim] <--> [ROS2 Control] <--> [MoveIt! Planner]
  10.           |<robot name="industrial_arm">
  11.   <group name="manipulator">
  12.     <chain base_link="base_link" tip_link="tool0"/>
  13.   </group>
  14.   
  15.   <end_effector name="gripper" parent_link="tool0" group="gripper"/>
  16. </robot> |
  17. [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 基础环境配置
  1. # 安装ROS2 Humble
  2. sudo apt install ros-humble-desktop
  3. # 安装MoveIt2
  4. sudo apt install ros-humble-moveit
  5. # 创建工作空间
  6. mkdir -p ~/arm_ws/src
  7. cd ~/arm_ws/
  8. colcon build --symlink-install
复制代码
2.2 关键依赖安装
  1. # 工业机械臂驱动包
  2. sudo apt install ros-humble-industrial-core
  3. # 视觉处理包
  4. sudo apt install ros-humble-vision-opencv
  5. # 深度相机驱动
  6. sudo apt install ros-humble-realsense2
复制代码
3. 机械臂运动学建模

3.1 URDF模型构建(示例:6轴机械臂)
  1. <robot name="industrial_arm" xmlns:xacro="http://www.ros.org/wiki/xacro">
  2.   <xacro:macro name="arm_joint" params="name parent child origin_xyz origin_rpy">
  3.     <joint name="${name}_joint" type="revolute">
  4.       <parent link="${parent}"/>
  5.       <child link="${child}"/>
  6.       <origin xyz="${origin_xyz}" rpy="${origin_rpy}"/>
  7.       
  8.       <limit effort="100" velocity="1.0" lower="${-pi}" upper="${pi}"/>
  9.     </joint>
  10.   </xacro:macro>
  11.   
  12.   <link name="base_link">
  13.     <visual>
  14.       <geometry>
  15.         <cylinder radius="0.15" length="0.1"/>
  16.       </geometry>
  17.     </visual>
  18.   </link>
  19.   
  20.   <xacro:arm_joint
  21.     name="joint1"
  22.     parent="base_link"
  23.     child="link1"
  24.     origin_xyz="0 0 0.1"
  25.     origin_rpy="0 0 0"/>
  26.   
  27. </robot>
复制代码
3.2 运动学参数配置(SRDF文件)
  1. <robot name="industrial_arm">
  2.   <group name="manipulator">
  3.     <chain base_link="base_link" tip_link="tool0"/>
  4.   </group>
  5.   
  6.   <end_effector name="gripper" parent_link="tool0" group="gripper"/>
  7. </robot>
复制代码
4. 核心运动规划实现

4.1 MoveIt!配置流程
  1. # 初始化MoveIt!配置包
  2. ros2 launch moveit_setup_assistant setup_assistant.launch
复制代码
配置关键参数:

  • 规划组设置(Planning Groups);
  • 碰撞矩阵(Collision Matrix);
  • 被动关节(Passive Joints);
  • 末端执行器(End Effectors)。
4.2 逆运动学求解(C++实现)
  1. // arm_controller/src/ik_solver.cpp#include  class IKSolver {public:  bool computeIK(const geometry_msgs::msg::PoseStamped& target_pose,<robot name="industrial_arm">
  2.   <group name="manipulator">
  3.     <chain base_link="base_link" tip_link="tool0"/>
  4.   </group>
  5.   
  6.   <end_effector name="gripper" parent_link="tool0" group="gripper"/>
  7. </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版)
  1. # 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">
  2.   <group name="manipulator">
  3.     <chain base_link="base_link" tip_link="tool0"/>
  4.   </group>
  5.   
  6.   <end_effector name="gripper" parent_link="tool0" group="gripper"/>
  7. </robot>    # 2. 规划抓取路径        if not self.plan_grasp(target_pose):<robot name="industrial_arm">
  8.   <group name="manipulator">
  9.     <chain base_link="base_link" tip_link="tool0"/>
  10.   </group>
  11.   
  12.   <end_effector name="gripper" parent_link="tool0" group="gripper"/>
  13. </robot>return Status.FAILURE<robot name="industrial_arm">
  14.   <group name="manipulator">
  15.     <chain base_link="base_link" tip_link="tool0"/>
  16.   </group>
  17.   
  18.   <end_effector name="gripper" parent_link="tool0" group="gripper"/>
  19. </robot>        # 3. 执行抓取动作        self.execute_grasp()<robot name="industrial_arm">
  20.   <group name="manipulator">
  21.     <chain base_link="base_link" tip_link="tool0"/>
  22.   </group>
  23.   
  24.   <end_effector name="gripper" parent_link="tool0" group="gripper"/>
  25. </robot>    # 4. 规划放置路径        if not self.plan_place():<robot name="industrial_arm">
  26.   <group name="manipulator">
  27.     <chain base_link="base_link" tip_link="tool0"/>
  28.   </group>
  29.   
  30.   <end_effector name="gripper" parent_link="tool0" group="gripper"/>
  31. </robot>return Status.FAILURE<robot name="industrial_arm">
  32.   <group name="manipulator">
  33.     <chain base_link="base_link" tip_link="tool0"/>
  34.   </group>
  35.   
  36.   <end_effector name="gripper" parent_link="tool0" group="gripper"/>
  37. </robot>        return Status.SUCCESS     def plan_grasp(self, target_pose):        # 调用MoveIt!规划服务        return True
复制代码
5.2 状态机实现(C++版)
  1. // task_planner/include/state_machine.h
  2. #include <smacc2/smacc2.hpp>
  3. class AssemblySM : public smacc2::SmaccStateMachineBase {
  4. public:
  5.   using SmaccStateMachineBase::SmaccStateMachineBase;
  6.   
  7.   struct Orthogonal : smacc2::Orthogonal<Orthogonal> {};
  8.   
  9.   struct StateIdle : smacc2::SmaccState<StateIdle, AssemblySM> {
  10.     smacc2::Transition onEvent() override {
  11.       return transit<StatePick>();
  12.     }
  13.   };
  14.   // 后续状态定义(略)
  15. };
复制代码
6. 视觉伺服系统集成

6.1 深度相机标定
  1. # 相机内参标定
  2. ros2 run camera_calibration cameracalibrator \
  3.   --size 8x6 --square 0.0245 image:=/camera/color/image_raw
复制代码
6.2 目标检测与位姿估计(Python实现)
  1. # 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">
  2.   <group name="manipulator">
  3.     <chain base_link="base_link" tip_link="tool0"/>
  4.   </group>
  5.   
  6.   <end_effector name="gripper" parent_link="tool0" group="gripper"/>
  7. </robot>gray, self.aruco_dict, parameters=self.aruco_params)<robot name="industrial_arm">
  8.   <group name="manipulator">
  9.     <chain base_link="base_link" tip_link="tool0"/>
  10.   </group>
  11.   
  12.   <end_effector name="gripper" parent_link="tool0" group="gripper"/>
  13. </robot>    if ids is not None:<robot name="industrial_arm">
  14.   <group name="manipulator">
  15.     <chain base_link="base_link" tip_link="tool0"/>
  16.   </group>
  17.   
  18.   <end_effector name="gripper" parent_link="tool0" group="gripper"/>
  19. </robot>rvec, tvec, _ = cv2.aruco.estimatePoseSingleMarkers(<robot name="industrial_arm">
  20.   <group name="manipulator">
  21.     <chain base_link="base_link" tip_link="tool0"/>
  22.   </group>
  23.   
  24.   <end_effector name="gripper" parent_link="tool0" group="gripper"/>
  25. </robot>    corners, 0.05, camera_matrix, dist_coeffs)<robot name="industrial_arm">
  26.   <group name="manipulator">
  27.     <chain base_link="base_link" tip_link="tool0"/>
  28.   </group>
  29.   
  30.   <end_effector name="gripper" parent_link="tool0" group="gripper"/>
  31. </robot>return tvec[0][0], rvec[0][0]        return None
复制代码
7. Gazebo仿真验证

7.1 仿真环境配置
  1.       model://ground_plane         0 0 0.75 0 0 0    true          model://table<robot name="industrial_arm">
  2.   <group name="manipulator">
  3.     <chain base_link="base_link" tip_link="tool0"/>
  4.   </group>
  5.   
  6.   <end_effector name="gripper" parent_link="tool0" group="gripper"/>
  7. </robot>   model://gear_part    0.3 0 0.8 0 0 0  
复制代码
7.2 完整仿真流程
  1. # 启动仿真环境
  2. ros2 launch arm_gazebo assembly_world.launch.py
  3. # 启动MoveIt!规划场景
  4. ros2 launch arm_moveit_config moveit_rviz.launch.py
  5. # 启动控制节点
  6. ros2 run arm_controller arm_control_node
复制代码
8. 实机部署注意事项


  • 硬件接口适配:
[code]// 修改硬件接口驱动void write(const std::vector& commands) override {  // 将关节角度转换为PWM信号  for(size_t i=0; i
您需要登录后才可以回帖 登录 | 立即注册