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

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 += 1print("turn_lists",turn_lists)
class FourInfrared:def __init__(self, address=0x78, bus=1):self.address = addressself.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 datais_turning =Truewhile is_turning:car.set_velocity(0, 90, 0.4)if data[3]:is_turning=Falseis_turning=True# car.set_velocity(0, 90, 0.75)# time.sleep(0.65)#左转
def car_left():global datais_turning = Truewhile is_turning:car.set_velocity(0, 90, -0.4)if data[0]:is_turning = Falseis_turning = True
# 关闭前处理  Processing before exit
def manual_stop(signum, frame):global numAglobal numBglobal __isRunningprint('关闭中...')__isRunning = Falseprint(f"numA={numA},numB={numB}")car_stop()  # 关闭所有电机  Turn off all motors
def move():global num_rightglobal num_leftglobal dataglobal __isRunningglobal numBglobal linearglobal kglobal mglobal turn_requirewhile 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 = 0print("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]==[]:breakturn = turn_lists[m].pop(0)print("turn:",turn)# if turn==-1:#     breakif turn == 1:k += 1print("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 += 1print("正在右转...")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 += 1print("直行...")car.set_velocity(linear, 90, 0)time.sleep(1)if turn_lists[m][0]==5:car.set_velocity(linear, 90, 0)turn_require = 1time.sleep(0.7)elif turn == 3:k += 1print("正在左转到宝藏...")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 == 0else:car.set_velocity(linear, 90, 0)time.sleep(0.7)car_right()elif turn == 4:k += 1print("正在右转到宝藏...")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 == 0else:car.set_velocity(linear, 90, 0)time.sleep(0.7)car_right()elif turn == 5:# car.set_velocity(0, 0, 0)k += 1print("直行到宝藏...")car.set_velocity(linear, 90, 0)time.sleep(2)turn_require == 0baoCamera_run = baoCamera.run()car_stop()time.sleep(2)if baoCamera_run == 1:# turn_require == 0print("是")car.set_velocity(50, 90, 0)time.sleep(2.5)car_left()car_stop()time.sleep(0.6)baoCamera_run == 0turn_require = 0time.sleep(0.7)# breakelse:print("不是")car.set_velocity(50, 90, 0)time.sleep(0.7)car_right()car_stop()# time.sleep(1)# 如果等于0那么就不停turn_require = 0time.sleep(0.7)# break# turn_require == 0else: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=0m += 1def sensor():global dataglobal __isRunningglobal numAglobal linearglobal turn_requirewhile __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 = 0time.sleep(0.3)else:linear = 50# print("linear-----------------===================",linear)
# 运行子线程move,sensorif __name__ == "__main__":global datadata=[]# 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.rhkb.cn/news/97844.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网上购物系统的设计与实现/在线商城/基于spring boot的电商平台/基于Java的商品销售系统

摘 要 本毕业设计的内容是设计并且实现一个基于Springboot的网上购物系统。它是在Windows下&#xff0c;以MYSQL为数据库开发平台&#xff0c;Tomcat网络信息服务作为应用服务器。网上购物系统的功能已基本实现&#xff0c;主要包括用户管理、数码分类管理、数码产品管理、服…

【计算机视觉】相机基本知识(还在更新)

1.面阵工业相机与线阵工业相机 1.1 基本概念区别 面阵相机则主要采用的连续的、面状扫描光线来实现产品的检测&#xff1b; 线阵相机即利用单束扫描光来进行物体扫描的工作的。 1.2 优缺点 &#xff08;1&#xff09;面阵CCD工业相机&#xff1a; 优点&#xff1a;应用面…

【IDEA报错:Cause: java.sql.SQLSyntaxErrorException: ORA-00942: 表或视图不存在】

报错内容如下&#xff1a; 2023-08-17 11:17:16.274 ERROR [egrant-biz,e44d96001eb5f212,e44d96001eb5f212,true] 29700 --- [ XNIO-1 task-2] c.i.c.l.c.RestExceptionController : 服务器异常org.springframework.jdbc.BadSqlGrammarException: ### Error queryin…

Pytest使用fixture实现token共享

同学们在做pytest接口自动化时&#xff0c;会遇到一个场景就是不同的测试用例需要有一个登录的前置步骤&#xff0c;登录完成后会获取到token&#xff0c;用于之后的代码中。首先我先演示一个常规的做法。 首先在conftest定义一个login的方法&#xff0c;方法返回token pytes…

[Raspberry Pi]如何用VNC遠端控制樹莓派(Ubuntu desktop 23.04)?

之前曾利用VMware探索CentOS&#xff0c;熟悉Linux操作系統的指令和配置運作方式&#xff0c;後來在樹莓派價格飛漲的時期&#xff0c;遇到貴人贈送Raspberry Pi 4 model B / 8GB&#xff0c;這下工具到位了&#xff0c;索性跳過樹莓派官方系統(Raspberry Pi OS)&#xff0c;直…

解决多模块内核心模块有接口打包成jar后被依赖并调用遇到的问题(springcloud集成ruoyi.quartz)

项目准备开发个新功能&#xff0c;刚好很喜欢ruoyi写的任务调度&#xff0c;因此想到了集成ruoyi.quartz模块 &#xff0c;遇到了很多问题: 首先因为ruoyi.quartz模块依赖了ruoyi.common模块&#xff0c;因此第一步我需要把common模块一部分依赖项复制到了quartz模块内&#xf…

Spring学习笔记+SpringMvc+SpringBoot学习笔记

壹、核心概念&#xff1a; 1.1. IOC和DI IOC&#xff08;Inversion of Control&#xff09;控制反转&#xff1a;对象的创建控制权由程序转移到外部&#xff0c;这种思想称为控制反转。/使用对象时&#xff0c;由主动new产生对象转换为由外部提供对象&#xff0c;此过程种对象…

【Lua】(一)VSCode 搭建 Lua 开发环境

前言 最近在找工作&#xff0c;基本所有的岗位都会问到 Lua&#xff08;甚至拼 UI 的都要求会 Lua&#xff09;&#xff0c;咱能怎么办呢&#xff0c;咱也只能学啊…… 工欲善其事&#xff0c;必先利其器。第一步&#xff0c;先来把环境配置好吧&#xff01; 当前适用版本&a…

PostgreSQL基本操作总结

安装按PostgreSQL数据库后&#xff0c;会默认创建用户postgres和数据库postgres&#xff0c;这个用户是超级用户&#xff0c;权限最高&#xff0c;可以创建其他用户和权限&#xff0c;在实际开发过程中&#xff0c;会新创建用户和业务数据库&#xff0c;本文主要介绍用户权限和…

学习笔记:Opencv实现限制对比度得自适应直方图均衡CLAHE

2023.8.19 为了完成深度学习的进阶&#xff0c;得学习学习传统算法拓展知识面&#xff0c;记录自己的学习心得 CLAHE百科&#xff1a; 一种限制对比度自适应直方图均衡化方法&#xff0c;采用了限制直方图分布的方法和加速的插值方法 clahe&#xff08;限制对比度自适应直方图…

mapper.xml中循环执行多条语句时报错,但是单独拿SQL到数据库却可以执行

我是批量修改数据&#xff0c;用foreach标签包住update语句&#xff0c;报错信息如下&#xff1a; nested exception is java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the …

OJ练习第152题——分割回文串 II

分割回文串 II 力扣链接&#xff1a;132. 分割回文串 II 题目描述 给你一个字符串 s&#xff0c;请你将 s 分割成一些子串&#xff0c;使每个子串都是回文。 返回符合要求的 最少分割次数 。 示例 Java代码 class Solution {public int minCut(String s) {int n s.leng…

11. 实现业务功能--获取用户信息

目录 1. 实现 Controller 2. 单体测试 3. 修复返回值存在的缺陷 3.1 用户的隐私数据&#xff1a;密码的密文和盐不能显示 3.2 将值为 null 的字段可以进行过滤 3.3 时间的格式需要进行处理&#xff0c;如 yyyy-mmmm-ddd HH:mm:ss 3.4 data 属性没有返回 4. 实现前端页…

mybatis日志工厂

一、LOG4J 特点&#xff1a;可控制日志信息输送的目的地是控制台、文件等。 可控制每一条日志的输出格式&#xff1b; 通过定义每一条日志信息的级别&#xff0c;能够更加细致的控制日志的生成过程&#xff1b; 通过一个配置文件来灵活的进行配置&#xff0c;而不需要修改应…

Git判断本地是否最新

场景需求 需要判断是否有新内容更新,确定有更新之后执行pull操作&#xff0c;然后pull成功之后再将新内容进行复制到其他地方 pgit log -1 --prettyformat:"%H" HEAD -- . "origin/HEAD" rgit rev-parse origin/HEAD if [[ $p $r ]];thenecho "Is La…

时序预测 | MATLAB实现基于CNN-BiLSTM卷积双向长短期记忆神经网络的时间序列预测-递归预测未来(多指标评价)

时序预测 | MATLAB实现基于CNN-BiLSTM卷积双向长短期记忆神经网络的时间序列预测-递归预测未来(多指标评价) 目录 时序预测 | MATLAB实现基于CNN-BiLSTM卷积双向长短期记忆神经网络的时间序列预测-递归预测未来(多指标评价)预测结果基本介绍程序设计参考资料 预测结果 基本介绍…

C++系列-内存模型

内存模型 内存模型四个区代码区全局区栈区堆区内存开辟和释放在堆区开辟数组 内存模型四个区 不同区域存放的数据生命周期是不同的&#xff0c;更为灵活。 代码区&#xff1a;存放函数体的二进制代码&#xff0c;操作系统管理。全局区&#xff1a;存放全局变量&#xff0c;常…

计算机竞赛 python+大数据校园卡数据分析

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于yolov5的深度学习车牌识别系统实现 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;4分工作量&#xff1a;4分创新点&#xff1a;3分 该项目较为新颖&am…

【网络架构】华为hw交换机网络高可用网络架构拓扑图以及配置

一、网络拓扑 1.网络架构 核心层:接入网络----路由器 汇聚层:vlan间通信 创建vlan ---什么是vlan:虚拟局域网,在大型平面网络中,为了实现广播控制引入了vlan,可以根据功能或者部门等创建vlan,再把相关的端口加入到vlan.为了实现不用交换机上的相同vlan通信,需要配置中继,为了…

论文笔记 Graph Attention Networks

2018 ICLR 1 intro 1.1. GCN的不足 无法完成inductive任务 inductive任务是指&#xff1a; 训练阶段与测试阶段需要处理的graph不同。通常是训练阶段只是在子图上进行&#xff0c;测试阶段需要处理未知的顶点。GGN 的参数依赖于邻接矩阵A/拉普拉斯矩阵L&#xff0c;所以换了…