K210为sipeed的Dock,全引脚引出,比较好操作。
云台为二维云台,舵机:SG90,最常用的一款。
基于前面一位大佬的学习笔记的学习笔记,做了自己的一些理解以及修改,现在实现的功能为设定指定色块,实时追踪实现色块始终在屏幕中央。
做的比较匆忙,没有很多解释,以后会再来改进
很新手,有错误请指正。程序不完善会有想不到的bug,有更进方法也请在评论区发言
用到的库有:
from machine import Timer,PWM
import sensor, time, image, lcd # 导入感光元件模块 sensor 跟踪运行时间模块 time 机器视觉模块 image
import utime # 导入延时模块 utime
from fpioa_manager import fm # 从 GPIO 模块中导入 引脚注册模块 fm
from Maix import GPIO # 从 Maix 模块中导入 模块 GPIO
import lcd # 导入 LCD 模块
from machine import UART
1.注册串口
根据需要注册自己想要的串口,其实这些到后面都没有用过,是LED指示灯以及串口通信用的,这里都没用到。
#------------------------------------------------------------------------------------------
#注册串口
#------------------------------------------------------------------------------------------
fm.register(6, fm.fpioa.UART2_RX)
fm.register(8, fm.fpioa.UART2_TX)
fm.register(16,fm.fpioa.GPIO1)
fm.register(14,fm.fpioa.GPIOHS0)
fm.register(13,fm.fpioa.GPIOHS1)
fm.register(12,fm.fpioa.GPIOHS2)
K_1 = GPIO(GPIO.GPIO1,GPIO.IN)
yb_uart = UART(UART.UART2, 115200, 8, 0, 0, timeout=1000, read_buf_len=4096)
2.普通正常的相机初始化
#--------------------------------------------------------------------------------------------------------------------
# 感光元件设置初始化
#--------------------------------------------------------------------------------------------------------------------
sensor.reset() # 重置并初始化感光元件 默认设置为 摄像头频率 24M 不开启双缓冲模式
#sensor.reset(freq=24000000, dual_buff=True) # 设置摄像头频率 24M 开启双缓冲模式 会提高帧率 但内存占用增加
sensor.set_pixformat(sensor.RGB565) # 设置图像格式为 RGB565 (彩色) 除此之外 还可设置格式为 GRAYSCALE 或者 YUV422
sensor.set_framesize(sensor.QVGA)
sensor.set_vflip(1) #水平
sensor.set_hmirror(1) #垂直
sensor.set_auto_exposure(1) #自动曝光
#sensor.set_contrast(1)
#sensor.set_auto_gain(0, gain_db = 30) #增益加强
sensor.set_auto_gain(False)
sensor.skip_frames(time = 2000)
lcd.init()
clock = time.clock()
3.设置定时器0,1
定时器0用来回调,定时器1用来输出PWM使舵机转动。
一般SG90的周期为20ms,故我们设置定时器1的频率为50Hz,这样到后面好驱动
#--------------------------------------------------------------------------------------------------------------------
# 定时器使用,定义定时器属性
#--------------------------------------------------------------------------------------------------------------------
class timer_property():
cnt = 0 #定时器计数值
cnt_max = 0 #定时器计数上线
period = 0 #定时器周期
freq = 0 #定时器频率
#定时器0 配置
#定时器0 实例化类
timer0 = timer_property()
timer0.cnt_max = 9 #设定 定时器0 的计数上限为9
timer0.period = 100 #设定 定时器0 的周期为100
#定时器0 定义回调函数
def timer0_back(tim_0):
if timer0.cnt < timer0.cnt_max:
timer0.cnt += 1
else:
timer0.cnt = 0 #超出计数值上限,归零
# 定时器初始化,
tim_0 = Timer(Timer.TIMER0,Timer.CHANNEL0, # 定时器编号 定时器0
mode = Timer.MODE_PERIODIC, # 定时器模式,为周期性
unit = Timer.UNIT_MS, # 定时器周期单位,为ms
period = timer0.period, # 定时器周期,单位ms
callback = timer0_back) # 定时器触发中断后执行的回调函数timer0_back
#定时器1 实例化类
timer1 = timer_property()
timer1.freq = 50
# 定时器1 通道0
tim_1_ch0 = Timer(Timer.TIMER1,
Timer.CHANNEL0,
mode = Timer.MODE_PWM) # 定时器模式,为PWM
# 定时器1 通道1
tim_1_ch1 = Timer(Timer.TIMER0,
Timer.CHANNEL0,
mode = Timer.MODE_PWM) # 定时器模式,为周期性
#定时器使用:在while循环中,当定时器0的计数器值被重置为0的时候,执行函数
4.定义颜色类,以及实例
#--------------------------------------------------------------------------------------------------------------------
#定义寻找颜色类
#--------------------------------------------------------------------------------------------------------------------
class color_property():
cx = 0 # x轴中心坐标
cy = 0 # y轴中心坐标
flag = 0 # 色块标志位: 1找到 0没找到
color = 0 # 色块颜色标志位,可以用 1 来表示黑色这种
density = 0 # 色块密度比,反映色块锁定程度,值越大,锁定程度越好
pixels_max = 0 # 色块像素最大值
led_flag = 0 # LED标志位 方便调试用
color_threshold = (0, 0, 0, 0, 0, 0) # 色块颜色阈值, 返回为LAB
color_roi = (0,0,320,240) # 色块寻找区域(感兴趣区域)
color_x_stride = 1 # 色块 x轴 像素最小宽度 色块如果比较大可以调大此参数 提高寻找精确度
color_y_stride = 1 # 色块 y轴 像素最小宽度
color_pixels_threshold = 100 # 色块 像素个数阈值 例如调节此参数为100 则可以滤除色块像素小于100的色块
color_area_threshold = 100 # 色块 被框面积阈值 例如调节此参数为100 则可以滤除色块被框面积小于100的色块
color_merge = True # 是否合并寻找到的色块 True 则合并 False 则不合并
color_margin = 1 # 色块合并间距 例如调节此参数为1 若上面选择True合并色块 且被找到的色块有多个 相距1像素 则会将这些色块合并
# 实例化类
# 黑色
black = color_property()
black.color_threshold = (98, 57, -62, 40, 50, 127)# 线的色块颜色阈值LAB
black.color_roi = (0,0,320,240) # 色块寻找区域,x,y,w,h
black.color_x_stride = 1
black.color_y_stride = 1
black.color_pixels_threshold = 150 # 像素个数阈值 越大查找色块越精确
black.color_area_threshold = 150 # 被框面积阈值 越大查找色块越精确
black.color_merge = True
black.color_margin = 2 # 色块合并间距 例如调节此参数为1 若上面选择True合并色块 且被找到的色块有多个 相距1像素 则会将这些色块合并
5.定义寻找色块的函数
# 定义寻找色块函数
def opv_find_blobs(color,led_flag):
color.pixels_max = 0 # 重置 色块 最大像素数量
color.flag = 0 # 重置 色块 标志位
color.led_flag = 0 # 重置 led 标志位
for blobs in img.find_blobs([color.color_threshold], # 色块颜色阈值
roi = color.color_roi, # 色块寻找区域(感兴趣区域)
x_stride = color.color_x_stride, # 色块 x轴 像素最小宽度 色块如果比较大可以调大此参数 提高寻找速度
y_stride = color.color_y_stride, # 色块 y轴 像素最小宽度 色块如果比较大可以调大此参数 提高寻找速度
pixels_threshold = color.color_pixels_threshold, # 色块 像素个数阈值 例如调节此参数为100 则可以滤除色块像素小于100的色块
area_threshold = color.color_area_threshold, # 色块 被框面积阈值 例如调节此参数为100 则可以滤除色块被框面积小于100的色块
merge = color.color_merge, # 是否合并寻找到的色块 True 则合并 False 则不合并
margin = color.color_margin): # 色块合并间距 例如调节此参数为1 若上面选择True合并色块 且被找到的色块有多个 相距1像素 则会将这些色块合并
img.draw_rectangle(blobs[0:4]) # 圈出找到的色块
if color.pixels_max < blobs.pixels(): # 找到面积最大的色块
color.pixels_max = blobs.pixels()
color.cx = blobs.cx() # 将面积最大的色块的 x轴 中心坐标值 赋值给 color
color.cy = blobs.cy() # 将面积最大的色块的 y轴 中心坐标值 赋值给 color
color.flag = 1 # 标志画面中有找到色块
color.density = blobs.density() # 将面积最大的色块的 色块密度比 赋值给 color
color.led_flag = led_flag # 将控制led颜色的标志位的值 赋值给 color
if color.flag == 1: # 标记画面中被找到的最大色块的中心坐标
img.draw_cross(color.cx,color.cy, color=127, size = 15)
img.draw_circle(color.cx,color.cy, 15, color = 127)
6.电机类以及实例
初设了4个电机,其实不需要这么多,因为太懒了没把电机改成舵机,其实motor这代表的是舵机
#--------------------------------------------------------------------------------------------------------------------
# 电机类定义
#--------------------------------------------------------------------------------------------------------------------
class Motor_Property():
motor1_duty = 0 # 电机1 占空比
motor2_duty = 0 # 电机2 占空比
motor3_duty = 0 # 电机3 占空比
motor4_duty = 0 # 电机4 占空比
duty1_center = 0 #当物体移至画面中心时,占空比中间值,即舵机的位置,
duty2_center = 0
motor1_pin = 0 # 电机1 引脚
motor2_pin = 0 # 电机2 引脚
motor3_pin = 0 # 电机3 引脚
motor4_pin = 0 # 电机4 引脚
control_x = 0 # 被控坐标 x
control_y = 0 # 被控坐标 y
control_flag_x = 'x' #打个向哪个地方转的标签
control_flag_y = 'y'
# 实例化电机类
motor = Motor_Property() # 实例化电机类 Motor_Property() 为 motor
motor.motor1_duty = 7.5 # 电机1的占空比 初始设置, x轴是7.5%为中心,duty范围为2-13
motor.motor2_duty = 8 # 电机2的占空比 初始设置, y轴是 8%为水平线
motor.duty1_center = 7.5
motor.duty2_center = 6
motor.motor1_pin = 11 # 电机1的引脚 也就是x轴
motor.motor2_pin = 12 # 电机2的引脚 也就是y轴
motor.control_x = 160
motor.control_y = 120 # 被控坐标 y
control_flag_x = 'x' #打个向哪个地方转的标签
control_flag_y = 'y'
7.初始化俩舵机的PWM
motor1 = PWM(tim_1_ch0, freq=timer1.freq,duty=motor.motor1_duty,pin=11)# 电机1, x轴
motor2 = PWM(tim_1_ch1, freq=timer1.freq,duty=motor.motor2_duty,pin=12)# 电机2, y轴
8.定义舵机的占空比,控制舵机移动
#定义电机占空比控制函数
def motor_control(motor,x,y): #比如控制舵机也可以在这里写
val_1 = 0
val_2 = 0
if x <= motor.control_x: # 若色块当前x坐标小于画面中心,物体在小车左边,向左走
val_1 = (motor.control_x - x) *0.004375 # 这里算的是与中心相差距离,得出屏幕的相对距离
control_flag_x = 'left'
motor.motor1_duty = motor.duty1_center + val_1 #减小电机1的占空比
#print("x_duty:",motor.motor1_duty)
yb_uart.write(control_flag_x)
if x > motor.control_x: # 若当前x坐标大于画面中心,物体在小车右边,向左走
#val_1 = (x - motor.control_x) *0.034375
val_1 = (x - motor.control_x) *0.0045
control_flag_x = 'right'
motor.motor1_duty = motor.duty1_center - val_1 #增大电机1的占空比,现在发现是反的
#print("x_duty:",motor.motor1_duty)
yb_uart.write(control_flag_x)
if y <= motor.control_y: # 若当前y坐标小于画面中心,物体在小车上边
#val_2 = (motor.control_y - y) *0.016665
val_2 = (motor.control_y - y) *0.008465
control_flag_y = 'forward'
motor.motor2_duty = motor.duty2_center - val_2
yb_uart.write(control_flag_y)
print("y_duty:",motor.motor2_duty)
if y > motor.control_y: # 若当前y坐标大于画面中心,物体在小车下边,向后走
val_2 = (y - motor.control_y) *0.008465
control_flag_y = 'backward'
yb_uart.write(control_flag_y)
motor.motor2_duty = motor.duty2_center + val_2
print("y_duty:",motor.motor2_duty)
9.主要函数
这里实现的便是驱动舵机运转,我们知道SG90的转动有限,从0-180°,占空比一般为5%-10%,所以我先提前做了测试,测出舵机极限的占空比以及对应的位置:
当到了极限的时候,需要让舵机一直等于极限值即可,不要让舵机发疯
while(black.cx!=motor.control_x or black.cy!=motor.control_y): # 不在中心点
motor1.duty(motor.motor1_duty) # 将获取到的电机1占空比 装载,x轴
motor2.duty(motor.motor2_duty) # y轴
if (motor.motor1_duty>=13 ):
motor.motor1_duty = 13
if (motor.motor2_duty>=8):
motor.motor2_duty = 8
if (motor.motor1_duty <=3):
motor.motor1_duty = 3
if (motor.motor2_duty<=3):
motor.motor2_duty = 3 # 3是向上抬头
if black.cx <= motor.control_x:
black.cx += 1
if black.cx > motor.control_x:
black.cx -= 1
if black.cy <= motor.control_y:
black.cy += 1
if black.cy > motor.control_y:
black.cy -= 1
if (black.cx==motor.control_x and black.cy==motor.control_y):
motor.duty1_center = motor.motor1_duty
motor.duty2_center = motor.motor2_duty
break
10.总代码:
from machine import Timer,PWM
import sensor, time, image, lcd # 导入感光元件模块 sensor 跟踪运行时间模块 time 机器视觉模块 image
import utime # 导入延时模块 utime
from fpioa_manager import fm # 从 GPIO 模块中导入 引脚注册模块 fm
from Maix import GPIO # 从 Maix 模块中导入 模块 GPIO
import lcd # 导入 LCD 模块
from machine import UART
#--------------------------------------------------------------------------------------------------------------------
#注册串口
#--------------------------------------------------------------------------------------------------------------------
fm.register(6, fm.fpioa.UART2_RX)
fm.register(8, fm.fpioa.UART2_TX)
fm.register(16,fm.fpioa.GPIO1)
fm.register(14,fm.fpioa.GPIOHS0)
fm.register(13,fm.fpioa.GPIOHS1)
fm.register(12,fm.fpioa.GPIOHS2)
K_1 = GPIO(GPIO.GPIO1,GPIO.IN)
yb_uart = UART(UART.UART2, 115200, 8, 0, 0, timeout=1000, read_buf_len=4096)
#LED_blue = GPIO(GPIO.GPIOHS0,GPIO.OUT)
#LED_red = GPIO(GPIO.GPIOHS1,GPIO.OUT)
#LED_green = GPIO(GPIO.GPIOHS2,GPIO.OUT)
#--------------------------------------------------------------------------------------------------------------------
# 感光元件设置初始化
#--------------------------------------------------------------------------------------------------------------------
sensor.reset() # 重置并初始化感光元件 默认设置为 摄像头频率 24M 不开启双缓冲模式
#sensor.reset(freq=24000000, dual_buff=True) # 设置摄像头频率 24M 开启双缓冲模式 会提高帧率 但内存占用增加
sensor.set_pixformat(sensor.RGB565) # 设置图像格式为 RGB565 (彩色) 除此之外 还可设置格式为 GRAYSCALE 或者 YUV422
sensor.set_framesize(sensor.QVGA)
sensor.set_vflip(1) #水平
sensor.set_hmirror(1) #垂直
sensor.set_auto_exposure(1) #自动曝光
#sensor.set_contrast(1)
#sensor.set_auto_gain(0, gain_db = 30) #增益加强
sensor.set_auto_gain(False)
sensor.skip_frames(time = 2000)
lcd.init()
clock = time.clock()
#--------------------------------------------------------------------------------------------------------------------
# 定时器使用,定义定时器属性
#--------------------------------------------------------------------------------------------------------------------
class timer_property():
cnt = 0 #定时器计数值
cnt_max = 0 #定时器计数上线
period = 0 #定时器周期
freq = 0 #定时器频率
#定时器0 配置
#定时器0 实例化类
timer0 = timer_property()
timer0.cnt_max = 9 #设定 定时器0 的计数上限为9
timer0.period = 100 #设定 定时器0 的周期为100
#定时器0 定义回调函数
def timer0_back(tim_0):
if timer0.cnt < timer0.cnt_max:
timer0.cnt += 1
else:
timer0.cnt = 0 #超出计数值上限,归零
# 定时器初始化,
tim_0 = Timer(Timer.TIMER0,Timer.CHANNEL0, # 定时器编号 定时器0
mode = Timer.MODE_PERIODIC, # 定时器模式,为周期性
unit = Timer.UNIT_MS, # 定时器周期单位,为ms
period = timer0.period, # 定时器周期,单位ms
callback = timer0_back) # 定时器触发中断后执行的回调函数timer0_back
#定时器1 实例化类
timer1 = timer_property()
timer1.freq = 50
# 定时器1 通道0
tim_1_ch0 = Timer(Timer.TIMER1,
Timer.CHANNEL0,
mode = Timer.MODE_PWM) # 定时器模式,为PWM
# 定时器1 通道1
tim_1_ch1 = Timer(Timer.TIMER0,
Timer.CHANNEL0,
mode = Timer.MODE_PWM) # 定时器模式,为周期性
#定时器使用:在while循环中,当定时器0的计数器值被重置为0的时候,执行函数
#--------------------------------------------------------------------------------------------------------------------
#定义寻找颜色类
#--------------------------------------------------------------------------------------------------------------------
class color_property():
cx = 0 # x轴中心坐标
cy = 0 # y轴中心坐标
flag = 0 # 色块标志位: 1找到 0没找到
color = 0 # 色块颜色标志位,可以用 1 来表示黑色这种
density = 0 # 色块密度比,反映色块锁定程度,值越大,锁定程度越好
pixels_max = 0 # 色块像素最大值
led_flag = 0 # LED标志位 方便调试用
color_threshold = (0, 0, 0, 0, 0, 0) # 色块颜色阈值, 返回为LAB
color_roi = (0,0,320,240) # 色块寻找区域(感兴趣区域)
color_x_stride = 1 # 色块 x轴 像素最小宽度 色块如果比较大可以调大此参数 提高寻找精确度
color_y_stride = 1 # 色块 y轴 像素最小宽度
color_pixels_threshold = 100 # 色块 像素个数阈值 例如调节此参数为100 则可以滤除色块像素小于100的色块
color_area_threshold = 100 # 色块 被框面积阈值 例如调节此参数为100 则可以滤除色块被框面积小于100的色块
color_merge = True # 是否合并寻找到的色块 True 则合并 False 则不合并
color_margin = 1 # 色块合并间距 例如调节此参数为1 若上面选择True合并色块 且被找到的色块有多个 相距1像素 则会将这些色块合并
# 实例化类
# 黑色
black = color_property()
black.color_threshold = (98, 57, -62, 40, 50, 127)# 线的色块颜色阈值LAB
black.color_roi = (0,0,320,240) # 色块寻找区域,x,y,w,h
black.color_x_stride = 1
black.color_y_stride = 1
black.color_pixels_threshold = 150 # 像素个数阈值 越大查找色块越精确
black.color_area_threshold = 150 # 被框面积阈值 越大查找色块越精确
black.color_merge = True
black.color_margin = 2 # 色块合并间距 例如调节此参数为1 若上面选择True合并色块 且被找到的色块有多个 相距1像素 则会将这些色块合并
# 红色
red = color_property()
red.color_threshold = (73, 2, -118, 94, -103, 99)
red.color_roi = (0,0,320,240)
red.color_x_stride = 1
red.color_y_stride = 1
red.color_pixels_threshold = 100
red.color_area_threshold = 100
red.color_merge = True
red.color_margin = 1
# 绿色 预留
green = color_property()
# 蓝色 预留
blue = color_property()
# 定义寻找色块函数
def opv_find_blobs(color,led_flag):
color.pixels_max = 0 # 重置 色块 最大像素数量
color.flag = 0 # 重置 色块 标志位
color.led_flag = 0 # 重置 led 标志位
for blobs in img.find_blobs([color.color_threshold], # 色块颜色阈值
roi = color.color_roi, # 色块寻找区域(感兴趣区域)
x_stride = color.color_x_stride, # 色块 x轴 像素最小宽度 色块如果比较大可以调大此参数 提高寻找速度
y_stride = color.color_y_stride, # 色块 y轴 像素最小宽度 色块如果比较大可以调大此参数 提高寻找速度
pixels_threshold = color.color_pixels_threshold, # 色块 像素个数阈值 例如调节此参数为100 则可以滤除色块像素小于100的色块
area_threshold = color.color_area_threshold, # 色块 被框面积阈值 例如调节此参数为100 则可以滤除色块被框面积小于100的色块
merge = color.color_merge, # 是否合并寻找到的色块 True 则合并 False 则不合并
margin = color.color_margin): # 色块合并间距 例如调节此参数为1 若上面选择True合并色块 且被找到的色块有多个 相距1像素 则会将这些色块合并
img.draw_rectangle(blobs[0:4]) # 圈出找到的色块
if color.pixels_max < blobs.pixels(): # 找到面积最大的色块
color.pixels_max = blobs.pixels()
color.cx = blobs.cx() # 将面积最大的色块的 x轴 中心坐标值 赋值给 color
color.cy = blobs.cy() # 将面积最大的色块的 y轴 中心坐标值 赋值给 color
color.flag = 1 # 标志画面中有找到色块
color.density = blobs.density() # 将面积最大的色块的 色块密度比 赋值给 color
color.led_flag = led_flag # 将控制led颜色的标志位的值 赋值给 color
if color.flag == 1: # 标记画面中被找到的最大色块的中心坐标
img.draw_cross(color.cx,color.cy, color=127, size = 15)
img.draw_circle(color.cx,color.cy, 15, color = 127)
# 定义打印色块参数函数
def print_blobs_property(color,name):
print(name,"cx:",color.cx,"cy:",color.cy,"flag:",color.flag,"color:",color.color,"density:",color.density,"led_flag:",color.led_flag)
#--------------------------------------------------------------------------------------------------------------------
# 电机类定义
#--------------------------------------------------------------------------------------------------------------------
class Motor_Property():
motor1_duty = 0 # 电机1 占空比
motor2_duty = 0 # 电机2 占空比
motor3_duty = 0 # 电机3 占空比
motor4_duty = 0 # 电机4 占空比
duty1_center = 0 #当物体移至画面中心时,占空比中间值,即舵机的位置,
duty2_center = 0
motor1_pin = 0 # 电机1 引脚
motor2_pin = 0 # 电机2 引脚
motor3_pin = 0 # 电机3 引脚
motor4_pin = 0 # 电机4 引脚
control_x = 0 # 被控坐标 x
control_y = 0 # 被控坐标 y
control_flag_x = 'x' #打个向哪个地方转的标签
control_flag_y = 'y'
# 实例化电机类
motor = Motor_Property() # 实例化电机类 Motor_Property() 为 motor
motor.motor1_duty = 7.5 # 电机1的占空比 初始设置, x轴是7.5%为中心,duty范围为2-13
motor.motor2_duty = 8 # 电机2的占空比 初始设置, y轴是 8%为水平线
motor.duty1_center = 7.5
motor.duty2_center = 6
motor.motor1_pin = 11 # 电机1的引脚 也就是x轴
motor.motor2_pin = 12 # 电机2的引脚 也就是y轴
motor.control_x = 160
motor.control_y = 120 # 被控坐标 y
control_flag_x = 'x' #打个向哪个地方转的标签
control_flag_y = 'y'
# 创建对象 电机1, 通道0, 定时器1控制的, 占空比
# motor1 = PWM(tim_1_ch0, freq=timer1.freq,duty=motor.motor1_duty,pin=motor.motor1_pin)
# motor2 = PWM(tim_1_ch1, freq=timer1.freq,duty=motor.motor2_duty,pin=motor.motor2_pin)
motor1 = PWM(tim_1_ch0, freq=timer1.freq,duty=motor.motor1_duty,pin=11)# 电机1, x轴
motor2 = PWM(tim_1_ch1, freq=timer1.freq,duty=motor.motor2_duty,pin=12)# 电机2, y轴
#定义电机占空比控制函数
def motor_control(motor,x,y): #比如控制舵机也可以在这里写
val_1 = 0
val_2 = 0
if x <= motor.control_x: # 若色块当前x坐标小于画面中心,物体在小车左边,向左走
val_1 = (motor.control_x - x) *0.004375 # 这里算的是与中心相差距离,得出屏幕的相对距离
control_flag_x = 'left'
motor.motor1_duty = motor.duty1_center + val_1 #减小电机1的占空比
#print("x_duty:",motor.motor1_duty)
yb_uart.write(control_flag_x)
if x > motor.control_x: # 若当前x坐标大于画面中心,物体在小车右边,向左走
#val_1 = (x - motor.control_x) *0.034375
val_1 = (x - motor.control_x) *0.0045
control_flag_x = 'right'
motor.motor1_duty = motor.duty1_center - val_1 #增大电机1的占空比,现在发现是反的
#print("x_duty:",motor.motor1_duty)
yb_uart.write(control_flag_x)
if y <= motor.control_y: # 若当前y坐标小于画面中心,物体在小车上边
#val_2 = (motor.control_y - y) *0.016665
val_2 = (motor.control_y - y) *0.008465
control_flag_y = 'forward'
motor.motor2_duty = motor.duty2_center - val_2
yb_uart.write(control_flag_y)
print("y_duty:",motor.motor2_duty)
if y > motor.control_y: # 若当前y坐标大于画面中心,物体在小车下边,向后走
val_2 = (y - motor.control_y) *0.008465
control_flag_y = 'backward'
yb_uart.write(control_flag_y)
motor.motor2_duty = motor.duty2_center + val_2
print("y_duty:",motor.motor2_duty)
#motor.motor1_duty = int(motor.motor1_duty) # 电机1占空比,转为int,x方向
#motor.motor2_duty = int(motor.motor2_duty)
while(True):
clock.tick()
img = sensor.snapshot()
lcd.display(img)
#lcd.rotation(0) # Dock的屏幕有点怪怪的,就这样吧
#lcd.mirror(True)
opv_find_blobs(black,1) #找线!
motor_control(motor, black.cx, black.cy)
while(black.cx!=motor.control_x or black.cy!=motor.control_y): # 不在中心点
motor1.duty(motor.motor1_duty) # 将获取到的电机1占空比 装载,x轴
motor2.duty(motor.motor2_duty) # y轴
if (motor.motor1_duty>=13 ):
motor.motor1_duty = 13
if (motor.motor2_duty>=8):
motor.motor2_duty = 8
if (motor.motor1_duty <=3):
motor.motor1_duty = 3
if (motor.motor2_duty<=3):
motor.motor2_duty = 3 # 3是向上抬头
if black.cx <= motor.control_x:
black.cx += 1
if black.cx > motor.control_x:
black.cx -= 1
if black.cy <= motor.control_y:
black.cy += 1
if black.cy > motor.control_y:
black.cy -= 1
if (black.cx==motor.control_x and black.cy==motor.control_y):
motor.duty1_center = motor.motor1_duty
motor.duty2_center = motor.motor2_duty
break