1. 项目背景与目标
这个项目源于一个真实的药品分装需求场景。在制药厂和医院药房中,经常需要将大包装的药板拆分成小包装。传统的人工分装方式效率低下且容易出错,我们团队尝试用机器人技术解决这个问题。
我们的核心目标是开发一套完整的自动化系统,能够:
- 准确识别药板的位置和姿态
- 规划机械臂运动轨迹
- 可靠抓取药板并放置到指定容器
- 整个过程无需人工干预
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 系统架构设计
2.1 硬件组成
系统采用模块化设计,主要硬件包括:
- Kinova Gen3机械臂:7自由度协作机械臂,负载2kg,重复定位精度±0.1mm
- Intel Realsense D435i深度相机:RGB-D相机,提供彩色和深度图像
- 定制化抓取工具:3D打印的专用末端执行器,集成伺服电机控制
2.2 软件架构
基于ROS2 Humble构建的分布式系统:
code复制┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 视觉识别节点 │───▶│ 运动规划节点 │───▶│ 机械臂控制节点 │
└─────────────────┘ └─────────────────┘ └─────────────────┘
▲ ▲ ▲
│ │ │
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Realsense驱动 │ │ 手眼标定数据 │ │ 抓取工具控制 │
└─────────────────┘ └─────────────────┘ └─────────────────┘
3. 视觉识别系统实现
3.1 相机配置与标定
首先需要正确配置D435i相机:
bash复制# 安装SDK
sudo apt install librealsense2-dev
rosdep install --from-paths src --ignore-src -r -y
# 启动相机节点
ros2 launch realsense2_camera rs_launch.py \
align_depth:=true \
enable_color:=true \
enable_depth:=true
注意:相机需要先进行内参标定,使用
ros2 run camera_calibration cameracalibrator工具完成
3.2 YOLOv8模型训练
3.2.1 数据准备
我们采用以下数据增强策略提升模型鲁棒性:
python复制# augment_dataset.py
import cv2
import albumentations as A
transform = A.Compose([
A.HorizontalFlip(p=0.5),
A.RandomBrightnessContrast(p=0.2),
A.GaussianBlur(p=0.1),
A.Affine(
scale=(0.8, 1.2),
translate_percent=(-0.1, 0.1),
rotate=(-10, 10),
shear=(-5, 5),
p=0.5
)
], bbox_params=A.BboxParams(format='yolo'))
3.2.2 模型训练配置
yaml复制# data.yaml
path: ~/vision_ws/src/simple_detector/dataset
train: images/train
val: images/val
names:
0: drugboard
训练命令:
bash复制yolo detect train \
data=data.yaml \
model=yolov8m.pt \
epochs=150 \
imgsz=640 \
batch=16 \
device=0 \
lr0=0.002 \
lrf=0.1
3.3 位姿估计实现
结合深度图像计算药板3D位姿:
python复制def get_pose(detection, depth_frame):
# 获取中心点深度
cx, cy = detection.center
depth = depth_frame.get_distance(cx, cy)
# 2D转3D
intrinsics = depth_frame.profile.as_video_stream_profile().intrinsics
x = (cx - intrinsics.ppx) * depth / intrinsics.fx
y = (cy - intrinsics.ppy) * depth / intrinsics.fy
z = depth
# 计算旋转角度
angle = detection.angle # 通过最小外接矩形获得
return PoseStamped(
position=Point(x=x, y=y, z=z),
orientation=Quaternion(*quaternion_from_euler(0, 0, angle))
)
4. 机械臂运动规划
4.1 MoveIt配置
创建MoveIt配置包:
bash复制ros2 pkg create --build-type ament_cmake kinova_moveit_config
关键配置文件:
yaml复制# kinova.srdf
<robot name="kinova_gen3">
<virtual_joint name="virtual_joint" type="fixed" parent_frame="world" child_link="base_link"/>
<group name="arm">
<joint name="joint_1"/>
<joint name="joint_2"/>
<!-- ...其他关节 -->
</group>
</robot>
4.2 运动规划实现
python复制class ArmController(Node):
def __init__(self):
super().__init__('arm_controller')
self.move_group = MoveGroupCommander("arm", wait_for_servers=10.0)
def move_to_pose(self, pose):
self.move_group.set_pose_target(pose)
success = self.move_group.go(wait=True)
self.move_group.stop()
self.move_group.clear_pose_targets()
return success
5. 系统集成与调试
5.1 手眼标定实现
采用Tsai-Lenz算法求解手眼矩阵:
python复制def solve_hand_eye(robot_poses, camera_poses):
# 转换为齐次变换矩阵
T_base_gripper = [pose_to_matrix(p) for p in robot_poses]
T_cam_target = [pose_to_matrix(p) for p in camera_poses]
# 使用OpenCV求解
R, t = cv2.calibrateHandEye(
[p[:3,:3] for p in T_base_gripper],
[p[:3,3] for p in T_base_gripper],
[p[:3,:3] for p in T_cam_target],
[p[:3,3] for p in T_cam_target],
method=cv2.CALIB_HAND_EYE_TSAI
)
return np.vstack((np.hstack((R, t)), [0, 0, 0, 1]))
5.2 完整工作流
- 启动系统:
bash复制ros2 launch realsense2_camera rs_launch.py
ros2 launch kinova_bringup robot.launch.py
ros2 run drug_detection detect_node
- 坐标转换流程:
code复制相机坐标系 → 手眼标定矩阵 → 基坐标系 → 逆运动学求解 → 关节角度
6. 关键问题与解决方案
6.1 识别精度问题
问题现象:初期模型会将键盘等物体误识别为药板
解决方案:
- 增加负样本训练集(COCO128数据集)
- 调整损失函数权重:
yaml复制cls: 1.5 # 分类损失权重 box: 7.5 # 定位损失权重 - 数据增强时加入背景替换
6.2 实时性问题
问题现象:节点运行几秒后系统卡死
优化措施:
- 限制检测频率(从30Hz降到10Hz)
- 使用CPU推理替代GPU
- 优化OpenCV代码:
python复制# 使用UMat加速 frame = cv2.UMat(frame) gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
6.3 机械臂抖动问题
问题现象:末端执行器接近目标时出现振荡
解决方法:
- 调整MoveIt速度参数:
yaml复制max_velocity_scaling_factor: 0.3 max_acceleration_scaling_factor: 0.2 - 增加轨迹滤波:
python复制self.move_group.set_trajectory_filter(True)
7. 实际应用效果
经过优化后的系统性能指标:
| 指标 | 数值 |
|---|---|
| 识别准确率 | 98.2% |
| 单次抓取耗时 | 4.5s |
| 位置重复精度 | ±0.3mm |
| 角度重复精度 | ±0.5° |
典型工作场景:
- 相机识别药板位置(耗时0.8s)
- 机械臂运动到抓取位置(2.1s)
- 执行抓取动作(1.0s)
- 移动到放置位置(2.3s)
- 执行放置动作(1.0s)
8. 扩展与改进方向
- 多目标识别:同时识别多个药板,优化抓取顺序
- 力反馈控制:在抓取阶段增加力传感器反馈
- 数字孪生:建立虚拟调试环境加速开发
- 异常处理:增加药板缺失、抓取失败等异常情况的处理逻辑
这个项目从零开始搭建完整的机���人应用系统,让我深刻理解了视觉-机械臂协同工作的技术细节。最大的收获是学会了如何将学术论文中的算法转化为实际可用的工程实现。
