11.jpg
GIF 2023-11-24 16-55-04.gif
跳高是一项重要的体育竞技项目,传统的跳高训练或竞赛操作繁琐,需要频繁地人工调节。
主要包括试跳成功后提高高度;试跳失败后最终的成绩记录以及跳高杆恢复等工作。而这些工作不能由运动员来做,必须配备两个工作人员(需要两边各站一个人)才能实现良好的训练效果。所以训练或成本高,效率低。

我们收到比赛主题后就联想到了我校运动会期间的跳高比赛场景。决定通过今天的人工智能竞赛完成一个能够解决这些问题的机器人系统。

我们的系统分成“跳高杆自动恢复及成绩记录系统”和“后勤及安全保障系统”两部分。

1.首先我来介绍“跳高杆自动恢复及成绩记录系统”。

“跳高杆自动恢复及成绩记录系统”由树莓派、显示屏、跳高杆抬升舵机、跳高杆复位舵机及相应传感器组成。

在跳高杆支撑架上安装有光敏传感器,当跳高杆正确放置时光敏传感器检测到黑暗,摄像头检测到有人时,门打开,允许跳高。跳完后,跳高人员回到进门处,摄像头检测到第二次人脸,跳高杆抬升舵机转动抬升一定高度,进行第二轮跳,以此类推。

当光敏传感器检测到亮起时则说明跳高失败,此时需要开启跳高杆恢复工作。此时红色提示灯亮起,大门关闭。跳高杆复位舵机转动,将跳高杆恢复到正确位置,光敏传感器检测到黑暗,此时跳高杆抬升舵机转动抬升到上一次的高度,并把本次跳高最终成绩显示在显示屏上。

import pyfirmata
import cv2
import time

# 加载人脸检测器
face_cascade = cv2.CascadeClassifier('/home/pi/opencv-3.4.3/data/haarcascades_cuda/haarcascade_frontalface_default.xml')

# 打开摄像头
cap = cv2.VideoCapture(0)
# 设置分辨率为 640x480
cap.set(3, 320)
cap.set(4, 240)

# 设置Arduino的串口
port = '/dev/ttyUSB0'  # 根据你的连接设置正确的串口
# 创建Arduino对象
board = pyfirmata.Arduino(port)
# 启动模拟输入的迭代器
it = pyfirmata.util.Iterator(board)
it.start()

# 获取舵机引脚
servo1_pin = 9  # 跳高杆归位舵机
servo2_pin = 10  # 左抬升舵机
servo3_pin = 11  # 右抬升舵机

# 获取舵机对象
servo1 = board.get_pin('d:' + str(servo1_pin) + ':s')
servo2 = board.get_pin('d:' + str(servo2_pin) + ':s')
servo3 = board.get_pin('d:' + str(servo3_pin) + ':s')

# 跳高杆初始高度
height = 60

# 上一次检测到人的时间
last_detection_time = 0

# 检测到的人次数
detection_count = 0

# 获取开门继电器引脚
door_pin = 12
# 获取开门继电器对象
door = board.get_pin('d:' + str(door_pin) + ':s')

# 获取光敏电阻引脚
potentiometer_pin = 0 
# 获取光敏电阻对象
potentiometer = board.get_pin('a:' + str(potentiometer_pin) + ':i')

## 初始化

# 门关闭。
door.write(0)

# 舵机转到初始状态
servo1.write(20)
servo2.write(20)
servo3.write(20)

time.sleep(1)

# 跳高杆复位
pot_value = potentiometer.read()
if pot_value is not None:
    if pot_value < 0.8:
        print("光强:", pot_value)
        print('请放置跳高杆')
    # 如果光敏电阻值检测到跳高杆不在则等待
    while pot_value < 0.8:
        time.sleep(1)
        pot_value = potentiometer.read()
    print("光强:", pot_value)
    print("已检测到跳高杆")
    for angle in range(20, 60):  # 抬起到初始起跳高度
        servo2.write(angle)
        servo3.write(angle)
        time.sleep(0.03)

print("开始识别人脸,跳高杆初始高度为 60 ")

while True:
       # 读取一帧
    ret, frame = cap.read()

    # 将图像转换为灰度
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    # 使用人脸检测器检测人脸
    faces = face_cascade.detectMultiScale(gray, scaleFactor=1.3, minNeighbors=5, minSize=(30, 30))

    # 在检测到的人脸周围绘制矩形
    for (x, y, w, h) in faces:
        cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 0, 0), 2)

    # 检测到有人
    if len(faces) > 0 and time.time() - last_detection_time > 5:
        detection_count += 1
        last_detection_time = time.time()
        
        if detection_count>1:
        # 如果光敏电阻值检测到暗(跳高杆没有掉落),并且已经检测到人脸,则增加高度
            if height + detection_count * 5 <= 105:
                for angle in range(height + (detection_count-2) * 5, height +(detection_count-1) * 5):  # 抬起来,增加高度
                    servo2.write(angle)
                    servo3.write(angle)
                    time.sleep(0.03)
                print('第'+str(detection_count)+'次试跳,'+"跳高杆已抬升,高度为:"+str(height + (detection_count-1)* 5))
            else:
                print("你已经达到最高高度,即将初始化跳高杆")
                # 重置高度和计数器
                height = 60
                for angle in range(60, 20, -1):  # 降下去
                    servo2.write(angle)
                    servo3.write(angle)
                    time.sleep(0.03)
                detection_count = 0
        else:
            print('第1次试跳,高度为:60')
        
    else:
        # 读取光敏电阻值
        pot_value = potentiometer.read()
        if pot_value is not None:
            if pot_value < 0.8:
                print("跳高杆掉落,请立即离开")
                time.sleep(3)
                # 门关闭。
                door.write(0)
                print("跳高杆正在复位")
                for angle in range(height, 20, -1):  # 降下来
                    servo2.write(angle)
                    servo3.write(angle)
                    time.sleep(0.03)
                for angle in range(20, 100):  # 推过来
                    servo1.write(angle)
                    time.sleep(0.03)
                for angle in range(100, 20,-1):  # 回去
                    servo1.write(angle)
                    time.sleep(0.01)
                    # 如果光敏电阻值检测到跳高杆不在则等待
                pot_value = potentiometer.read()
                while pot_value < 0.8:
                    print('请手动恢复跳高杆')
                    time.sleep(1)
                    pot_value = potentiometer.read()
                print("已检测到跳高杆")
                for angle in range(20, 60):  # 抬起到初始起跳高度
                    servo2.write(angle)
                    servo3.write(angle)
                    time.sleep(0.03)    
                door.write(1)# 门打开
                print('你的最终成绩为:' + str(height + (detection_count-1) * 5))
                print('开始识别人脸,跳高杆初始高度为 60')
                detection_count = 0

    # 显示结果
    cv2.imshow('Face Detection', frame)

    # 按 'q' 键退出循环
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# 释放摄像头资源
cap.release()
cv2.destroyAllWindows()
board.exit()

10.jpg
9.jpg
7.jpg
8.jpg
QQ截图20231124161315.jpg
6.jpg
4.jpg
5.jpg
QQ截图20231124150825.jpg
2.jpg
3.jpg

发表评论