实验环境
(1)硬件环境
机械臂一台:具备视觉引导和运动控制功能的机械臂设备
摄像头:用于采集图像并进行颜色追踪的视觉设备
彩色物体:红、绿、蓝、黄等不同颜色的待追踪物体
(2)软件环境
Vmware虚拟环境:运行Ubuntu系统的虚拟化平台
Python 3.x 环境:支持OpenCV和机械臂控制库运行
OpenCV库:用于图像处理和颜色追踪的计算机视觉库
Jupyter Notebook:用于运行和调试颜色追踪代码的交互式环境
机械臂控制库:Arm_Lib(用于控制机械臂运动)
实验步骤
注意:请确保摄像头视觉范围内出现待追踪的颜色物体。
- 启动虚拟机,在Windows电脑中,使用Vmware运行Ubuntu系统。
- 找到路径
/Home/dofbot_ws/src/dofbot_color_follow/颜色追踪color_follow.ipynb,右击选择用Jupyter Notebook启动,输入密码shujia。 - 按照代码单元顺序执行程序,初始化机械臂位置并启动交互界面。
- 点击【learning_color】按钮,画面中心出现一个方框,在方框内放置待追踪物体,实时观察HSV的高低阈值,当方框下面出现【OK !!!】字样时,说明识别成功。
- 点击【learning_follow】按钮,机械臂将对学习到的颜色进行实时跟踪。
- 点击【follow_cancel】按钮可取消跟踪(不退出程序);点击【Exit】按钮可退出程序。
- 也可直接点击【color_follow】按钮,通过【choose_color】选择预设的红、绿、蓝、黄四种颜色进行追踪。
实验结果
-
- 取色追踪结果显示
实验原理
概述:目标追踪包含两种玩法:颜色追踪、取色追踪(学习追踪)。其原理是,通过相机对图像做一定的处理,通过特定的方式识别目标,获取到目标在相机下的坐标位置,计算目标中心点距离图像中心点的偏差值,通过PID算法调试,驱动机械臂移动,使得目标中心点与图像中心点重合。
PID算法基础
PID,就是对输入偏差进行比例积分微分运算,运算的叠加结果去控制执行机构。公式如下:
它由三部分组成:
- P(比例):输入偏差乘以一个系数
- I(积分):对输入偏差进行积分运算
- D(微分):对输入偏差进行微分运算
如下图所示就是一个基本的PID控制器:
(1)比例部分
比例部分的数学式表示是:
在模拟PID控制器中,比例环节的作用是对偏差瞬间作出反应。偏差一旦产生,控制器立即产生控制作用使控制量向减少偏差的方向变化。控制作用的强弱取决于比例系数,比例系数越大,控制作用越强,则过渡过程越快,控制过程的静态偏差也就越小;但是比例系数过大,也越容易产生振荡,破坏系统的稳定性。
优点:调整系统的开环比例系数,提高系统的稳态精度,减低系统的惰性,加快响应速度。
缺点:过大的开环比例系数不仅会使系统的超调量增大,而且会使系统稳定裕度变小,甚至不稳定。
(2)积分部分
积分部分的数学式表示是:∫e(t)dt * Ki
积分常数越大,积分的积累作用越弱,这时系统在过渡时不会产生振荡;但是增大积分常数会减慢静态误差的消除过程,消除偏差所需的时间也较长,但可以减少超调量,提高系统的稳定性。当积分常数较小时,则积分的作用较强,这时系统过渡时间中有可能产生振荡,不过消除偏差所需的时间较短。
优点:消除稳态误差。
缺点:会影响系统的稳定性,使系统的稳定裕度减小。
(3)微分部分
微分部分的数学式表示是:de(t)/dt * Kd
微分环节的作用是阻止偏差的变化。它是根据偏差的变化趋势(变化速度)进行控制。偏差变化的越快,微分控制器的输出就越大,并能在偏差值变大之前进行修正。微分作用的引入,将有助于减小超调量,克服振荡,使系统趋于稳定,特别对高阶系统非常有利,它加快了系统的跟踪速度。
优点:使系统的响应速度变快,超调减小,振荡减轻,对动态过程有"预测"作用。
缺点:对输入信号的噪声很敏感,对那些噪声较大的系统一般不用微分。
主要代码
代码路径:/Home/dofbot_ws/src/dofbot_color_follow/颜色追踪color_follow.ipynb
1. 导入头文件与初始化:
# 导入头文件
import cv2 as cv
import threading
import random
from time import sleep
import ipywidgets as widgets
from IPython.display import display
from color_follow import color_follow
# 初始化机械臂位置
import Arm_Lib
Arm = Arm_Lib.Arm_Device()
joints_0 = [90, 135, 20, 25, 90, 30]
Arm.Arm_serial_servo_write6_array(joints_0, 1000)
# 创建实例,初始化参数
follow = color_follow()
# 初始化模式
model = 'General'
# 初始化HSV_learning值
HSV_learning = ()
# 初始化HSV值
color_hsv = {"red" : ((0, 43, 46), (10, 255, 255)),
"green" : ((35, 43, 46), (77, 255, 255)),
"blue" : ((100, 43, 46), (124, 255, 255)),
"yellow": ((26, 43, 46), (34, 255, 255))}
# 设置随机颜色
color = [[random.randint(0, 255) for _ in range(3)] for _ in range(255)]
2. 创建交互控件:
button_layout = widgets.Layout(width='200px', height='100px',align_self='center')
# 输出控件
output = widgets.Output()
# 颜色追踪
color_follow = widgets.Button(description='color_follow', button_style='success', layout=button_layout)
# 选择颜色
choose_color = widgets.ToggleButtons(options=['red', 'green', 'blue', 'yellow'],
button_style='success',
tooltips=['Description of slow', 'Description of regular', 'Description of fast'])
# 取消追踪
follow_cancel = widgets.Button(description='follow_cancel', button_style='danger', layout=button_layout)
# 学习颜色
learning_color = widgets.Button(description='learning_color', button_style='primary', layout=button_layout)
# 学习颜色追踪
learning_follow = widgets.Button(description='learning_follow', button_style='success', layout=button_layout)
# 退出
exit_button = widgets.Button(description='Exit', button_style='danger', layout=button_layout)
# 图像控件
imgbox = widgets.Image(format='jpg', height=480, width=640, layout=widgets.Layout(align_self='auto'))
# 垂直布局
img_box = widgets.VBox([imgbox, choose_color], layout=widgets.Layout(align_self='auto'))
# 垂直布局
Slider_box = widgets.VBox([color_follow, learning_color,
learning_follow,follow_cancel,exit_button],
layout=widgets.Layout(align_self='auto'))
# 水平布局
controls_box = widgets.HBox([img_box, Slider_box],layout=widgets.Layout(align_self='auto'))
3. 模式切换函数:
def color_follow_Callback(value):
global model
model = 'color_follow'
def learning_color_Callback(value):
global model
model = 'learning_color'
def learning_follow_Callback(value):
global model
model = 'learning_follow'
def follow_cancel_Callback(value):
global model
model = 'General'
def exit_button_Callback(value):
global model
model = 'Exit'
# 绑定按钮事件
color_follow.on_click(color_follow_Callback)
learning_color.on_click(learning_color_Callback)
learning_follow.on_click(learning_follow_Callback)
follow_cancel.on_click(follow_cancel_Callback)
exit_button.on_click(exit_button_Callback)
4. 主程序:
def camera():
global HSV_learning,model
# 打开摄像头
capture = cv.VideoCapture(0)
capture.set(3, 640)
capture.set(4, 480)
capture.set(5, 30) # 设置帧率
# 当摄像头正常打开的情况下循环执行
while capture.isOpened():
try:
# 读取相机的每一帧
_, img = capture.read()
# 统一图像大小
img = cv.resize(img, (640, 480))
if model == 'color_follow':
img = follow.follow_function(img,color_hsv[choose_color.value])
# 添加文字
cv.putText(img, choose_color.value, (int(img.shape[0] / 2), 50),
cv.FONT_HERSHEY_SIMPLEX, 2, color[random.randint(0, 254)], 2)
if model == 'learning_color':
img,HSV_learning = follow.get_hsv(img)
if model == 'learning_follow':
img = follow.learning_follow(img, HSV_learning)
# 添加文字
cv.putText(img,'LeColor', (200, 50),
cv.FONT_HERSHEY_SIMPLEX, 1, color[random.randint(0, 254)], 1)
if model == 'Exit':
cv.destroyAllWindows()
capture.release()
break
# 更新图像显示
imgbox.value = cv.imencode('.jpg', img)[1].tobytes()
except KeyboardInterrupt:
capture.release()
# 启动程序
display(controls_box,output)
threading.Thread(target=camera, ).start()
代码说明:本实验实现了两种颜色追踪模式:预设颜色追踪和自定义取色追踪。系统通过OpenCV处理摄像头采集的图像,利用HSV颜色空间进行颜色识别。核心流程为:摄像头采集图像→根据选择的模式进行颜色识别(预设颜色或学习颜色)→计算目标位置与中心的偏差→通过PID算法控制机械臂运动→实时更新显示。界面提供了丰富的交互按钮,可实现模式切换、追踪控制和程序退出等功能,机械臂通过Arm_Lib库实现精准运动控制,确保目标始终保持在视野中心。
