光电比赛小车寻宝【1】--循迹策略

news2024/7/11 18:11:45

2023光电比赛总结:主要功能实现了,就是视频没做好,落选了非常的遗憾,也有很多的不甘心,也可以作为最后摆烂的惩罚吧,在这里总结一下经验教训。整体感觉时间不是非常充分,因为得到比赛的消息后突然一阳了,拖了几乎俩星期才开始,感觉身体状态不是特别好,需要做的东西很多,当然有的同门已经开始做了,硬件选取还有软件的实现可以借鉴一下思路,当然最多的还是自己亲自动手去实现。困难是常在的,而方法是需要摸索的。


循迹部分:为什么开始说循迹部分,因为这一部分花了特别多的时间去处理,开始的时候感觉没那么困难,因为查阅了相关的实现案例,不管是二路传感器,三路传感器都是可以按照规定的黑线进行循迹效果也特别好,我们购买的一款车是麦克纳姆轮的小车,这一款小车自带的四路传感器,因为传感器的距离定死了,所以循迹中出现问题的情况就非常的多,那么下面我就来说说具体有哪些问题。


使用四路传感器进行循迹,可能出现需要微调的情况0我分为三种:小微调、中微调、大微调,这三种调整方式是调整移动方向、转的角度不同来定的,这样能保证更平稳的进行循迹。因为正常情况下走直线需要传感器2、3同时在线上即都为True的情况,而麦轮小车按照此控制方式行走不能走直线所以需要时刻微调来保证车身随时调正行走,这样提高循迹的精准度。

1、 小微调:

        当传感器2或者3在线上的时候,如图5所示,中间两个传感器,需要进行小微调,当传感器2压线其他传感器都没压线需要往传感器2的方向微调(移动为向2的斜方向移动、加上一个很小的角速度)保证更快的纠正车身,直到2、3同时压线即直行,当传感器3压线其他不压线同理。情况如下:

图6小微调展示图

2、中微调:

        在循迹过程中,当黑线在传感器1、2之间或者3、4之间,这个时候所有的传感器都没有信号,那么这个时候需要进行中微调,线在哪边向哪个方向微调。(或者前进一点点距离即可触碰到传感器1或者4,那么即可进入下一个大微调阶段)在转弯的时候容易出现这样的情况。

图6中微调展示图

3、 大微调:

        当传感器1或4压线,这个时候也是向传感器的方向进行微调,这个时候同时斜向移动和提供角速度的移动就体现出优势,可以快速的进行矫正。在转弯的时候容易出现这样的情况。

图7大微调展示图

图8走直线展示图

4、具体做法: 微调操作使用的方法是角度加方向一起作用,这样的效果能够更快的反应更有效地找到路径。因为麦克纳姆轮可以全方向移动,那么可以利用这个点来进行微调。这里使用多线程控制信号获取,会出现信号遗漏的情况所以我用到了一个巧妙的方法:可以看这篇文章如何解决传感器交互信息(双线程)遗漏信号的问题

5、代码实现:

#!/usr/bin/python3
# coding=utf8
# sudo python3 TurboPi/HiwonderSDK/FourInfrared.py
import smbus
import numpy
import sys
sys.path.append('/home/pi/TurboPi/')
import cv2
import time
import math
import signal
import Camera
import argparse
import threading
import numpy as np
import yaml_handle
import HiwonderSDK.PID as PID
import HiwonderSDK.Misc as Misc
import HiwonderSDK.Board as Board
import HiwonderSDK.mecanum as mecanum
import baoCamera
import CameraCalibration.image_recognition as image_recognition

#四路巡线传感器
__isRunning = True
car = mecanum.MecanumChassis()
res_path = image_recognition.image_run()
# baoCamera_run = baoCamera.run()
print(11)
# print("1111111",res_path)
# print("qqqqqqq",res_path[0])

#定义一个状态值
godown = False
num_right=0
num_left=0
numA=0
numB=0
is_turn = False
sensor_turn_threading=None
linear = 0
turn_lists = res_path
res_path_little=[]
turn_require = 0
turn_lists = ([1,1,2,2,2,4],[2,1,1,2,2,4],[0,2,1,2,2,4],[0,2,1,2,2,4],[0,2,1,2,2,4],[0,2,1,2,2,4],[0,2,1,2,2,4],[0,2,1,2,2,4],[0,2,1,2,2,4])
# print(len(turn_lists))
i=0
j=0
k=0
m=0
# while i< len(res_path):
#     res_path_little = res_path[i]
#     # print(res_path_little)
#     j = len(res_path_little)
#     if res_path[i][j-1] == 1:
#         turn_lists[i][j-1] = 3
#     elif res_path[i][j-1] == 2:
#         turn_lists[i][j-1] = 4
#     elif res_path[i][j-1] == 0:
#         turn_lists[i][j - 1] = 5
#     i += 1

print("turn_lists",turn_lists)
class FourInfrared:
    def __init__(self, address=0x78, bus=1):
        self.address = address
        self.bus = smbus.SMBus(bus)

    def readData(self, register=0x01):
        value = self.bus.read_byte_data(self.address, register)
        return [True if value & v > 0 else False for v in [0x01, 0x02, 0x04, 0x08]]

line = FourInfrared()
# 停
def car_stop():
    car.set_velocity(0,0,0)  # 关闭所有电机 Turn off all motors
#左偏移
def car_leftlittle():
    # car.set_velocity(50, 90, -0.13)
    car.set_velocity(linear, 98, -0.05)  # 左上
#右偏移
def car_rightlittle():
    # car.set_velocity(50, 90, 0.13)
    car.set_velocity(linear, 82, 0.05)  # 右上
#左中调
def car_leftmiddle():
    car.set_velocity(linear, 110, -0.05)  # 右上
#右中调
def car_rightmiddle():
    car.set_velocity(linear, 70, 0.05)  # 右上
#直走
def car_go():
    car.set_velocity(linear, 90, 0)
#直走一点点
def car_golittle():
    car.set_velocity(linear, 90, 0)
    time.sleep(0.1)
#右转
def car_right():
    global data
    is_turning =True
    while is_turning:
        car.set_velocity(0, 90, 0.4)
        if data[3]:
            is_turning=False
    is_turning=True
    # car.set_velocity(0, 90, 0.75)
    # time.sleep(0.65)


#左转
def car_left():
    global data
    is_turning = True
    while is_turning:
        car.set_velocity(0, 90, -0.4)
        if data[0]:
            is_turning = False
    is_turning = True
# 关闭前处理  Processing before exit
def manual_stop(signum, frame):
    global numA
    global numB
    global __isRunning
    print('关闭中...')
    __isRunning = False
    print(f"numA={numA},numB={numB}")
    car_stop()  # 关闭所有电机  Turn off all motors
def move():
    global num_right
    global num_left
    global data
    global __isRunning
    global numB
    global linear
    global k
    global m
    global turn_require
    while m<len(turn_lists):
        # print("turn_lists[m]", len(turn_lists[m]))
        turn_pop_len = len(turn_lists[m])
        # turn_pop = turn_lists[m]#坑都跟着变化
        while k<turn_pop_len:
            # turn_require = 0
            print("m",m)
            print("len(turn_lists[m])",len(turn_lists[m]))
            print("len(turn_lists[m])",turn_lists[m])
            if __isRunning:
                print("线速度",linear)
                print("turn_require",turn_require)
                if linear == 0:
                    # print("拐弯信号", data[0], data[1], data[2], data[3])
                    if turn_lists[m]==[]:
                        break
                    turn = turn_lists[m].pop(0)
                    print("turn:",turn)
                    # if turn==-1:
                    #     break
                    if turn == 1:
                        k += 1
                        print("k",k)
                        print("正在左转...")
                        car_stop()
                        time.sleep(1)
                        car_golittle()
                        # print("正在zuo转...")
                        car_stop()
                        time.sleep(0.3)
                        car_left()
                        car_stop()
                        time.sleep(1)
                        # if turn_lists[m][0]==5:
                        #     car.set_velocity(linear, 90, 0)
                        #     # time.sleep(0.3)
                        #     turn_require = 1
                        #     time.sleep(0.7)
                        # print("停左转")
                        # car_golittle()
                    elif turn == 2:
                        k += 1
                        print("正在右转...")
                        car_stop()
                        # print("正在you转...")
                        time.sleep(1)
                        car_golittle()
                        car_stop()
                        time.sleep(0.3)
                        car_right()
                        car_stop()
                        time.sleep(1)
                        # if turn_lists[m][0]==5:
                        #     car.set_velocity(linear, 90, 0)
                        #     turn_require = 1
                        #     time.sleep(0.7)
                        # print("停右转")
                    elif turn == 0:
                        k += 1
                        print("直行...")
                        car.set_velocity(linear, 90, 0)
                        time.sleep(1)
                        if turn_lists[m][0]==5:
                            car.set_velocity(linear, 90, 0)
                            turn_require = 1
                            time.sleep(0.7)
                    elif turn == 3:
                        k += 1
                        print("正在左转到宝藏...")
                        car_stop()
                        time.sleep(1)
                        car_golittle()
                        # print("正在zuo转...")
                        car_stop()
                        time.sleep(0.3)
                        car_left()
                        car_stop()
                        time.sleep(1)
                        # print("停左转")
                        # car_golittle()
                        baoCamera_run = baoCamera.run()
                        car_stop()
                        time.sleep(0.3)
                        if baoCamera_run == 1:
                            car.set_velocity(linear, 90, 0)
                            time.sleep(1.3)
                            car_left()
                            baoCamera_run == 0
                        else:
                            car.set_velocity(linear, 90, 0)
                            time.sleep(0.7)
                            car_right()

                    elif turn == 4:
                        k += 1
                        print("正在右转到宝藏...")
                        car_stop()
                        time.sleep(1)
                        car_golittle()
                        # print("正在zuo转...")
                        car_stop()
                        time.sleep(0.3)
                        car_right()
                        car_stop()
                        time.sleep(1)
                        # print("停左转")
                        # car_golittle()
                        baoCamera_run = baoCamera.run()
                        car_stop()
                        time.sleep(0.3)
                        if baoCamera_run == 1:
                            car.set_velocity(linear, 90, 0)
                            time.sleep(1.3)
                            car_left()
                            baoCamera_run == 0
                        else:
                            car.set_velocity(linear, 90, 0)
                            time.sleep(0.7)
                            car_right()
                    elif turn == 5:
                        # car.set_velocity(0, 0, 0)
                        k += 1
                        print("直行到宝藏...")
                        car.set_velocity(linear, 90, 0)
                        time.sleep(2)
                        turn_require == 0
                        baoCamera_run = baoCamera.run()
                        car_stop()
                        time.sleep(2)
                        if baoCamera_run == 1:
                            # turn_require == 0
                            print("是")
                            car.set_velocity(50, 90, 0)
                            time.sleep(2.5)
                            car_left()
                            car_stop()
                            time.sleep(0.6)
                            baoCamera_run == 0
                            turn_require = 0
                            time.sleep(0.7)
                            # break
                        else:
                            print("不是")
                            car.set_velocity(50, 90, 0)
                            time.sleep(0.7)
                            car_right()
                            car_stop()
                            # time.sleep(1)
                            # 如果等于0那么就不停
                            turn_require = 0
                            time.sleep(0.7)
                            # break
                        # turn_require == 0
                else:
                    if not data[0] and data[1] and data[2] and not data[3]:     #第2、3个传感器是true走
                        car_go()
                        # print("直走",data[0] , data[1],data[2] , data[3])
                    elif not data[0] and not data[1] and data[2] and not data[3]:  # 第2个传感器是false向右偏移
                        car_rightlittle()
                        # print("右偏移")
                        # print("右偏移信号",data[0] , data[1],data[2] , data[3])
                    elif not data[2] and not data[0] and not data[3] and data[1]:  # 第3个传感器是false向左偏移
                        car_leftlittle()
                        # print("左偏移信号",data[0] , data[1],data[2] , data[3])

                    #增加只有一个传感器在线上的情况
                    elif data[0] and not data[1] and not data[2] and not data[3]:  # 第1个传感器是true,前进一点,停,等待左转
                        car.set_velocity(linear, 110, -0.15)
                        # car.set_velocity(50, 90, -0.3)
                        # print("左偏移大微调...", data[0], data[1], data[2], data[3])
                    elif data[3] and not data[0] and not data[1] and not data[2]:  # 第1个传感器是true,前进一点,停,等待左转
                        car.set_velocity(linear, 70, 0.15)
                        # car.set_velocity(50, 90, 0.3)
                        # print("右偏移大微调...", data[0], data[1], data[2], data[3])
                    #增加线在第1、2或者3、4之间的情况
                    elif not data[0] and not data[1] and not data[2] and not data[3]:  # 所有传感器是false停
                        car_golittle()
            else:
                car_stop()
        # k=0
        m += 1

def sensor():
    global data
    global __isRunning
    global numA
    global linear
    global turn_require
    while __isRunning:
        data = line.readData()
        # print("转弯信号识别。。。",data[0],data[1],data[2],data[3])
        # print("turn_lende===================",turn_require)
        if ((data[0] and data[1]) or (data[2] and data[3]) or turn_require == 1):
            # print("停的信号:",data[0],data[1],data[2],data[3])
            linear = 0
            time.sleep(0.3)
        else:
            linear = 50
            # print("linear-----------------===================",linear)
# 运行子线程move,sensor

if __name__ == "__main__":
    global data
    data=[]
    # global __isRunning
    __isRunning = True
    # th3 = threading.Thread(target=sensor_turn)
    # th3.setDaemon(True)
    # th3.start()
    th2 = threading.Thread(target=sensor)
    th2.setDaemon(True)
    th2.start()
    th = threading.Thread(target=move)
    th.setDaemon(True)
    th.start()
    signal.signal(signal.SIGINT, manual_stop)
    while __isRunning:
        1
        # print("Sensor1:", data[0], " Sensor2:", data[1], " Sensor3:", data[2], " Sensor4:", data[3])
        # data = line.readData()
        #True表示识别到黑线,False表示没有识别到黑线
        # print("asdsad",line.readData()[0])
        # time.sleep(0.5)
        # move()




本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/903272.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux之管理逻辑卷

目录 管理逻辑卷 认识LInux逻辑卷 LVM基本概念 部署逻辑卷 常用LVM部署命令 案例 管理与调整LVM卷 1.扩展卷组——添加/dev/nvme0n2p4物理卷到vg01中 2.在线扩展逻辑卷 管理逻辑卷 逻辑卷管理器是Linux 系统用于对硬盘分区进行管理的一种机制&#xff0c; 理论性较强 &…

安装搭建私有仓库 Harbor

目录 一. 准备环境 1.1安装 Docker 1.2安装 Docker Compose 二. 下载 Harbor 安装包 三. 解压安装包 四. 配置 Harbor 五. 安装 Harbor 六. 访问 Harbor 七. 创建项目、用户和角色 一. 准备环境 确保您的服务器满足 Harbor 的系统要求。最低要求是至少 2 核 CPU、4GB…

【沁恒蓝牙mesh】CH58x串口环形FIFO数据处理

本文章主要针对沁恒科技的CH58x芯片&#xff0c;以 BLE_UART 工程为依托&#xff0c;介绍串口数据的接收与处理。 该工程中 串口数据的处理用到了环形FIFO机制&#xff0c;可作为其他开发工具 &#x1f4cb; 个人简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我…

【LLM数据篇】预训练数据集+指令生成sft数据集

note 在《Aligning Large Language Models with Human: A Survey》综述中对LLM数据分类为典型的人工标注数据、self-instruct数据集等优秀的开源sft数据集&#xff1a;alpaca_data、belle、千言数据集、firefly、moss-003-sft-data多轮对话数据集等 文章目录 note构造指令实例…

k8s扩缩容与滚动更新

使用kubectl run创建应用 kubectl run kubernetes-bootcamp \> --imagedocker.io/jocatalin/kubernetes-bootcamp:v1 \> --port8080 端口暴露出去 kubectl expose pod kubernetes-bootcamp --type"NodePort" --port 8080 使用kubectl create创建应用 kubect…

该产品与此版 VMware Workstation 不兼容,因此无法使用

目录 VMware虚拟机开机报错 解决错误 VMware虚拟机开机报错 配置文件“D:\Users\tyn\Documents\Virtual Machines\Ubuntu16 的克隆\Ubuntu16 的克隆.vmx”是由 VMware 产品创建&#xff0c;但该产品与此版 VMware Workstation 不兼容&#xff0c;因此无法使用。 无法打开配…

VMware 虚拟机三种网络模式详解

文章目录 前言桥接模式(Bridged)桥接模式特点: 仅主机模式 (Host-only)仅主机模式 (Host-only)特点: NAT网络地址转换模式(NAT)仅主机模式 (Host-only)特点: 前言 很多同学在初次接触虚拟机的时候对 VMware 产品的三种网络模式不是很理解,本文就 VMware 的三种网络模式进行说明…

线上异常的处理

一、线上问题的排查 进程ID 简称为PID free -m 查看内存使用情况 iostat 查看磁盘读写活动情况 netstat 查看网络连接情况 df -h 查看磁盘空间使用情况 du -sh 查看文件大小情况 1.1、top 命令查看CPU占用情况 top -n num 查看CPU占用最高的num个进程top -Hp PID 或 top -H -p…

Vulnhub系列靶机--- Hackadmeic.RTB1

系列&#xff1a;Hackademic&#xff08;此系列共2台&#xff09; 难度&#xff1a;初级 信息收集 主机发现 netdiscover -r 192.168.80.0/24端口扫描 nmap -A -p- 192.168.80.143访问80端口 使用指纹识别插件查看是WordPress 根据首页显示的内容&#xff0c;点击target 点击…

Java-类与对象(上)

什么是面向对象 Java是一门纯面向对象的语言(Object Oriented Program&#xff0c;简称OOP)&#xff0c;在面向对象的世界里&#xff0c;一切皆为对象。 面向对象是解决问题的一种思想&#xff0c;主要依靠对象之间的交互完成一件事情。 以面向对象方式来进行处理&#xff0c;就…

宏病毒的实践

一、实验目的&#xff1a; 1、了解梅丽莎宏病毒基本概念 2、自己实验梅丽莎宏病毒 二、预备知识&#xff1a; 1.什么是word宏 宏是一个批处理程序命令&#xff0c;正确地运用它可以提高工作效率。微软的office软件运行用户自己编写&#xff0c;叫VBA的脚本来增加其灵活性&…

12. 登录拦截器

由于论坛中的所有功能接口都需要在用户登录的情况下才能访问&#xff0c;所以要做统一的登录身份校验。 1. 在 interceptor 包下创建 LoginInterceptor Component // 交给 Spring 管理 public class LoginInterceptor implements HandlerInterceptor {// 从配置文件中读取配…

ChatGPT和Claude的能力全测评

创造性思维/语言 提示&#xff1a;“写一首 4 行诗&#xff0c;每行只有 3 个词&#xff0c;描写重庆” ChatGPT写诗&#x1f447; Claude写诗&#x1f447; 仁者见仁&#xff0c;您怎么看谁更强&#xff1f; 提示&#xff1a; "如果你随机选择这个问题的答案&#xff0c;…

postgresql 的递归查询

postgresql 的递归查询功能很强大&#xff0c;可以实现传统 sql 无法实现的事情。那递归查询的执行逻辑是什么呢&#xff1f;在递归查询中&#xff0c;我们一般会用到 union 或者 union all&#xff0c;他们两者之间的区别是什么呢&#xff1f; 递归查询的执行逻辑 递归查询的…

⛳ TCP 协议面试题

目录 ⛳ TCP 协议面试题&#x1f43e; 一、为什么关闭连接的需要四次挥⼿&#xff0c;⽽建⽴连接却只要三次握⼿呢&#xff1f;&#x1f3ed; 二、为什么连接建⽴的时候是三次握⼿&#xff0c;可以改成两次握⼿吗&#xff1f;&#x1f463; 三、为什么主动断开⽅在TIME-WAIT状态…

shell 简单且常用的几种

目录 一、配置环境的shell脚本 二、系统资源脚本 一、要求 二、脚本内容 三、脚本解析 四、赋权并验证 一、配置环境的shell脚本 systemctl stop firewalld systemctl disable firewalld systemctl stop NetworkManager systemctl disable NetworkManager setenforce…

动物IT

动物是地球上最丰富和多样化的生物群体之一。它们包括鱼类、鸟类、爬行动物、两栖动物和哺乳动物等各种类型。动物在地球上有着不同的生态角色和生活习性。 动物对于维持生态平衡和生态系统的稳定性至关重要。它们在食物链中扮演着重要的角色&#xff0c;通过捕食和被捕食来保…

【李沐】3.5、softmax回归的从0开始实现

注意&#xff1a; 把每个像素位置看作⼀个特征 # 导入PyTorch库 import torch # 从IPython库中导入display模块&#xff0c;用于在交互式环境中显示内容 from IPython import display # 从d2l.torch模块中导入torch作为d2l的别名&#xff0c;方便后续使用d2l库中的功能 from d…

阿里云轻量应用服务器和云服务器有什么区别?2023更新

阿里云轻量应用服务器和云服务器ECS有什么区别&#xff1f;ECS是专业级云服务器&#xff0c;轻量应用服务器是轻量级服务器&#xff0c;轻量服务器使用门槛更低&#xff0c;适合个人开发者或中小企业新手使用&#xff0c;可视化运维&#xff0c;云服务器ECS适合集群类、高可用、…

ForkJoin框架

1. ForkJoin框架概述 ForkJoin模式先把一个大任务分解成许多个独立的子任务&#xff0c;然后开启多个线程并行去处理这些子任务。有可能子任务还是很大而需要进一步分解&#xff0c;最终得到足够小的任务。ForkJoin模式的任务分解和执行过程大致如下图所示。 ForkJoin模式借助…