前言
想来想去还是总结一下这糟糕的2023点电赛,并且开源一下发挥部分。唉 因为舵机精度问题,我前两天调的基础部分用openmv控精度达不到,就让队友来转成stm32来主控,精度可以高3倍。但,唉 还是自己前些天没玩32,在玩西门子,让队友来用32控然后写死了 但验收时并没有对准 ,也直接让发挥部分让测都不让测,直接比赛一行代码没跑我的 ,真的很绷不住。但发挥部分效果还算可以。
主程序
解释一下
全都由openmv H7 plus 主控 识别红色光斑并返回xy坐标,控制两个舵机控制二维云台xy轴(p8-控制左右,p7-控制上下)p2 连接蜂鸣器,LED(3),p1 引脚连接开关。直接放图片
充电宝直接通过usb线给openmv供电。
电池通过降压模块将12v电压降压为5v驱动舵机。
绿色激光笔买不到绿色激光模块 只能用激光笔,还是上电池手指按压常量。我用solidworks画了个支架,用螺丝仿真人手按压。
我一天干坏俩openmvh7 plus 舵机失控结构问题usb供电下载口接着线直接别下来了
我的老师牛逼 直接焊枪焊上
废话不多说,放代码。
import sensor, image, time, math, pyb
from pid import PID
from pyb import Servo, Pin #调用库
x_servo=Servo(2) #p8-控制左右
y_servo=Servo(1) #p7-控制上下
led = pyb.LED(3)
p2_fengming = Pin('P2', Pin.OUT_PP)#设置p_out为输出引脚 蜂鸣器
#p0.high()#设置p_out引脚为高
p_in = Pin('P1', Pin.IN, Pin.PULL_UP)#设置p_in为输入引脚,并开启上拉电阻 开关
value = p_in.value() # get value, 0 or 1#读入p_in引脚的值
#pin_kaiguan = Pin('P1', Pin.OUT_PP, Pin.PULL_NONE)
#red_threshold = (30, 100, 15, 127, -40, 127)
red_threshold = (0,100,21,127,43,-21)
#红色色素块
#while(True):
x_pid = PID(p=0.030,i=0.01,imax=90) #左右脱机
y_pid = PID(p=0.030,i=0.01,imax=90) #上下脱机
sensor.reset() # Initialize the camera sensor.
sensor.set_auto_gain(False)
sensor.set_auto_whitebal(False)
sensor.set_pixformat(sensor.RGB565) # use RGB565.
sensor.set_framesize(sensor.VGA) # use QQVGA for speed.
sensor.set_auto_exposure(False, exposure_us=20000)
sensor.skip_frames(time=900) #跳过几帧,让新的设置生效。
#调曝光度,调节完可以比较清晰地看清激光点
sensor.set_auto_whitebal(False) # turn this off.
clock = time.clock() # Tracks FPS. #基本参数设置
#====================================================
def find_max(blobs):
max_size=0
for blob in blobs:
if blob[2]*blob[3] > max_size:
max_blob=blob
max_size = blob[2]*blob[3]
return max_blob #找到视野中的最大色素块
def show_xy():
img = sensor.snapshot()
blobs = img.find_blobs([red_threshold])
cx=0;cy=0;
if blobs:
max_blob = find_max(blobs)
cx = max_blob.cx()
cy = max_blob.cy()
print(cx,cy)
img.draw_cross(cx,cy) # 在图像中绘制色块中心的十字标记
return (cx,cy)
#===========================舵机云台初始化====================
x_servo.angle(10)
y_servo.angle(-35)
# x轴舵机 光点向左 数值增加
# y轴舵机 光点向下 数值减小
time.sleep(1)
while(True):
value = p_in.value()
if value == 1:
led.off()
p2_fengming.low()#设置p_out引脚为高
if value == 0:
clock.tick() # Track elapsed milliseconds between snapshots().
img = sensor.snapshot() # Take a picture and return the image.
blobs = img.find_blobs([red_threshold])
if blobs:
max_blob = find_max(blobs)
x,y = show_xy()
#pan_error = max_blob.cx()-img.width()/2
#tilt_error = max_blob.cy()-img.height()/2
x_error = -(276-max_blob.cx()) # 横轴方向上的修正参数
y_error = -(205-max_blob.cy()) # 纵轴方向上的修正参数
img.draw_rectangle(max_blob.rect()) # rect #在色块外围四周处画框
img.draw_cross(max_blob.cx(), max_blob.cy()) # cx, cy #色块中心坐标处画十字
x_output=x_pid.get_pid(x_error,2)/2
y_output=y_pid.get_pid(y_error,2)/2
#print("output",x_output)
#print("outut",y_output)
x_servo.angle(x_servo.angle()-round(x_output)) #控制下面舵机x轴移动
y_servo.angle(y_servo.angle()-round(y_output)) #控制上面舵机y轴移动
if x_error < 30 and x_error > -30 and y_error<30 and y_error > -30:
p2_fengming.high()#设置p_out引脚为高
led.on()
else:
p2_fengming.low()#设置p_out引脚为高
led.off()
else:
p2_fengming.low()#设置p_out引脚为高
led.off()
再解释一下
if x_error < 30 and x_error > -30 and y_error<30 and y_error > -30:
p2_fengming.high()#设置p_out引脚为高
led.on()
这里是30个像素点的误差 绿色激光与红色激光相对距离小于30个像素点,就将p2引脚拉高,蜂鸣器响。led亮。追踪到,声光报警。
pid用的官方历程里的pid,只能说因为舵机精度问题,这个angle 看似可以设置到0.1度 但舵机不动,所以xy_output 再调也精度不咋够 最小移动1度舵机,反应在白慕上大概就是2cm。唉
仅供参考 真的很绷不住,还是自己菜 。
要是有人想看,抽空我把基础部分也整理一下
最后放个视频连接吧
链接
https://www.bilibili.com/video/BV1N8411z7UG/?vd_source=be917c0725519481af6231a29754ace8
散会