python机器人编程——基于单目视觉、固定场景下的自动泊车(下)

2024-02-11 12:30

本文主要是介绍python机器人编程——基于单目视觉、固定场景下的自动泊车(下),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • 一、前言
  • 二、主要思路
    • step0 设定一个中间位置
    • step1 掉转马头
    • step2 直线匀速前进
    • step3 调整姿态
    • step4 视觉匹配
  • 三、效果
  • 四、全篇总结

一、前言

本篇来讨论一下在固定场景下,如何仅通过单目视觉,实现差速小车的自动停靠,这种方式实现成本比较低,可适应的范围比较广,比如可以应用于小车的自动充电桩寻找、工位的最准等应用场景。我们还是尝试应用有限、浅显的数学对固定场景下,通过坐标的变换、几何的分析、结合单目摄像头获取的图像,进行相机位置(或者小车的位置)的估计,并控制差速小车行驶至我们预设的位置停靠。本篇根据上篇已经识别的位置,进一步实现小车的控制部分。
在这里插入图片描述

二、主要思路

由于我们讨论的是简单场景,在知道了当前小车位置和方向角后,要行驶至固定点位,最直接粗暴的方法是走直线了,我们可以这样进行路线的控制:

step0 设定一个中间位置

由于视觉判断出来的位置毕竟准确的不高,我们有必要设立一个在目标停车区前面设置一个中间位置,用于最后停进去前进行缓冲,稍微精确的进行位置调整,类似两个空间站对接的场景。如上图绿色点,例如这个坐标如设为(0,-2500)单位mm,目标点坐标为(0,-1500)。

step1 掉转马头

这一步是直接原地转向,根据视觉计算的位置和中间点位置,将当前方向角原地旋转调整至朝向中间点的位置。如下图:
在这里插入图片描述
应该调整的角度dtheta=theta_t1-theta_t0,其中,theta_t1是根据向量Pt0---->Pt1计算获取,向量的旋转角度计算程序如下:

def single_vangle(v1):"""计算单个向量夹角,返回弧度和角度"""dx1 = v1[2] - v1[0]    dy1 = v1[3] - v1[1]    fangle1 = math.atan2(dy1, dx1)    angle1 = round(fangle1 * 180/math.pi,2)    return fangle1,angle1

用程序计算小车在Pt0点应该旋转的角度如下:

def move2ready(location,theta,clientID,TTHandle,speed=0.15,tspeed=0.05,main_local=(0,-2500),r=0.16):"""r:小车中心到轮子的距离"""p0x=location[0]p0y=location[1]p1x=main_local[0]p1y=main_local[1]orders=[]angle1=theta+90print("当前小车角度:",angle1)print("当前小车坐标:",p0x,p0y)f,angle0=single_vangle([p0x,p0y,p1x,p1y])print("当前中间点角度:",angle0)dangle=angle0-angle1print("转角角度:",dangle)if dangle>=0:#顺时针转rv>0>lvdangle=dangle/180*math.pi#转弧度vr=tspeedvl=-tspeed#旋转时间=角度/角速度,角速度=线速度/rtita=abs(dangle/(vr*10*0.164))orders.append([tita,(vl,vr),clientID,TTHandle])else:dangle=-dangle/180*math.pi#转弧度vr=-tspeedvl=tspeed#旋转时间=角度/角速度,角速度=线速度/rtita=abs(dangle/(vr*10*0.164))orders.append([tita,(vl,vr),clientID,TTHandle])######part1------接下部分###############

PS:如何控制小车按照既定的指令前进,比如:先让小车左转30度,再匀速直行1米,再右转20度…
这里我们可以通过设置一个独立的线程,将需要的一些先后顺序的控制指令封装在一个list里面,命名为orders,其结构如下:
orders=[[执行时间t,(执行的左右轮速度),小车的ID号,小车的反馈状态句柄],…]
然后编制一个顺序指令函数,来解释这个orders,并按一定的先后顺序根据计时时间下发到小车,这样就形成了一个顺序控制(CCS)过程:

def tick_tack(orders,circle=True):"""按时间执行控制,orders=[[tita,(leftspeed,rightpeed),clientID]]"""x,y,xe,ye,ang0,ang1=0,0,0,0,0,0start_time=time.time()for i in range(len(orders)):          tita=orders[i][0]lv=orders[i][1][0]rv=orders[i][1][1]clientID=orders[i][2]TTHandle=orders[i][3]if circle:ret, arr = sim.simxGetObjectOrientation(clientID, TTHandle, -1, sim.simx_opmode_blocking)if ret==sim.simx_return_ok:x=round(arr[0]*1000,2)y=round(arr[1]*1000,2)  ang0=round(arr[2],2) print("角度:",arr)if ang0<0:ang0=math.pi*2+ang0else:ret, arr = sim.simxGetObjectPosition(clientID, TTHandle, -1, sim.simx_opmode_blocking)if ret==sim.simx_return_ok:x=round(arr[0]*1000,2)y=round(arr[1]*1000,2)  ang0=round(arr[2],2)  send_LR(clientID,lv,rv)            time.sleep(tita)if circle:ret, arr = sim.simxGetObjectOrientation(clientID, TTHandle, -1, sim.simx_opmode_blocking)if ret==sim.simx_return_ok:xe=round(arr[0]*1000,2)ye=round(arr[1]*1000,2)ang1=round(arr[2],2)  if ang1<0:ang1=math.pi*2+ang1if ang1<ang0:aspeed=(ang1+math.pi*2-ang0)/tita                    #speed=math.sqrt((xe-x)**2+(ye-y)**2)/tita#print("线速度(mm):",speed)else:aspeed=(ang1-ang0)/titaprint("角速度(mm):",aspeed)print("角度:",arr)else:ret, arr = sim.simxGetObjectPosition(clientID, TTHandle, -1, sim.simx_opmode_blocking)if ret==sim.simx_return_ok:xe=round(arr[0]*1000,2)ye=round(arr[1]*1000,2)                     speed=math.sqrt((xe-x)**2+(ye-y)**2)/titaprint("线速度(mm):",speed)send_LR(clientID,0,0)send_LR(clientID,0,0)time.sleep(0.01)end_time=time.time()   print("用时:",end_time-start_time)return True,end_time-start_time

step2 直线匀速前进

掉转朝向完成后,我们就控制小车左右轮速为相等,计算好直线移动至中间位置的时间,利用计算机监控时间,倒计时停止后,即为中间位置。
此处比较好理解,只要计算一下当前点Pt0到中间点Pt1的距离,并且设定好合适的速度,就可以计算小车应该行进的时间,于是生成指令加入orders序列:

######part2------接part1部分################计算前进时间distance=math.sqrt((p0x-p1x)**2+(p0y-p1y)**2)vl=speedvr=speedtita=distance/(vl*10*24)orders.append([tita,(vl,vr),clientID,TTHandle])######part2------接下部分###############

step3 调整姿态

在中间位置附近了,就可以根据当前的朝向,原地旋转小车,将小车朝向调整至垂直面向目的区域,并且下车的控制由模型计算控制转为视觉导航为主的位置精调控制。
这一步跟第一步是一样的只要调整好小车方向至中间点至原点向量的角度就可以:

######part3------接part2部分###############
#计算中间点位置旋转dangle=90-angle0if dangle>=0:#顺时针转rv>0>lvdangle=dangle/180*math.pi#转弧度vr=tspeedvl=-tspeed#旋转时间=角度/角速度,角速度=线速度/rtita=abs(dangle/(vr*10*0.164))orders.append([tita,(vl,vr),clientID,TTHandle])else:dangle=-dangle/180*math.pi#转弧度vr=-tspeedvl=tspeed#旋转时间=角度/角速度,角速度=线速度/rtita=abs(dangle/(vr*10*0.164))orders.append([tita,(vl,vr),clientID,TTHandle])print("bigen move:",i,orders) t=threading.Thread(target=tick_tack,args=(orders,))t.setDaemon(True)t.start()return t

最后创建一个新的线程,将生成的顺序控制指令orders用我们的顺序控制函数tick_tack执行。小车就会执行一些列的动作,移动到中间点附近了!
在这里插入图片描述

step4 视觉匹配

类似于导弹的地形匹配,我们利用单目视觉获得的图像,在小车前进中进行位置角度的调整,原则上是使得固定二维码中心始终在图像的中心位置,且其它参考点P1、P2相对中心点位置距离比例是相等的,垂直、横向二维码点不产生比例偏移。直至小车运动至目标位置停止。
这个问题其实就是一个阶跃的响应控制问题:
在这里插入图片描述
这里我们还是利用之前博文中所用到的预测控制思想去控制小车至目标设定值,上图红线所示。这里也可以通过PID等其它控制手段,实现小车位置的精调回正。

三、效果

移动到中间点:
在这里插入图片描述

最后精细控制至目标点:
在这里插入图片描述

四、全篇总结

至此,初步完成了在简单固定场景仿真环境下,基于单目视觉的自动停靠控制,通过测试,即使在理想的仿真环境下面,基于单目视觉简单的定位也存在着一定的误差,需要反复的进行调整参数,由此可见应用于实际场景,相对情况要复杂很多,单单利用单目视觉和简单的特征识别处理在实际应用场景还是不够的,要引入更多的信息源(如激光传感、深度传感)、使用优化算法来提高系统的可靠性和准确性。
后续还有很多改进的地方,让我们继续深入研究吧!

这篇关于python机器人编程——基于单目视觉、固定场景下的自动泊车(下)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/699774

相关文章

python panda库从基础到高级操作分析

《pythonpanda库从基础到高级操作分析》本文介绍了Pandas库的核心功能,包括处理结构化数据的Series和DataFrame数据结构,数据读取、清洗、分组聚合、合并、时间序列分析及大数据... 目录1. Pandas 概述2. 基本操作:数据读取与查看3. 索引操作:精准定位数据4. Group

Python pandas库自学超详细教程

《Pythonpandas库自学超详细教程》文章介绍了Pandas库的基本功能、安装方法及核心操作,涵盖数据导入(CSV/Excel等)、数据结构(Series、DataFrame)、数据清洗、转换... 目录一、什么是Pandas库(1)、Pandas 应用(2)、Pandas 功能(3)、数据结构二、安

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我

Python安装Pandas库的两种方法

《Python安装Pandas库的两种方法》本文介绍了三种安装PythonPandas库的方法,通过cmd命令行安装并解决版本冲突,手动下载whl文件安装,更换国内镜像源加速下载,最后建议用pipli... 目录方法一:cmd命令行执行pip install pandas方法二:找到pandas下载库,然后

MySQL常用字符串函数示例和场景介绍

《MySQL常用字符串函数示例和场景介绍》MySQL提供了丰富的字符串函数帮助我们高效地对字符串进行处理、转换和分析,本文我将全面且深入地介绍MySQL常用的字符串函数,并结合具体示例和场景,帮你熟练... 目录一、字符串函数概述1.1 字符串函数的作用1.2 字符串函数分类二、字符串长度与统计函数2.1

Python实现网格交易策略的过程

《Python实现网格交易策略的过程》本文讲解Python网格交易策略,利用ccxt获取加密货币数据及backtrader回测,通过设定网格节点,低买高卖获利,适合震荡行情,下面跟我一起看看我们的第一... 网格交易是一种经典的量化交易策略,其核心思想是在价格上下预设多个“网格”,当价格触发特定网格时执行买

Python标准库之数据压缩和存档的应用详解

《Python标准库之数据压缩和存档的应用详解》在数据处理与存储领域,压缩和存档是提升效率的关键技术,Python标准库提供了一套完整的工具链,下面小编就来和大家简单介绍一下吧... 目录一、核心模块架构与设计哲学二、关键模块深度解析1.tarfile:专业级归档工具2.zipfile:跨平台归档首选3.

使用Python构建智能BAT文件生成器的完美解决方案

《使用Python构建智能BAT文件生成器的完美解决方案》这篇文章主要为大家详细介绍了如何使用wxPython构建一个智能的BAT文件生成器,它不仅能够为Python脚本生成启动脚本,还提供了完整的文... 目录引言运行效果图项目背景与需求分析核心需求技术选型核心功能实现1. 数据库设计2. 界面布局设计3

SQL Server跟踪自动统计信息更新实战指南

《SQLServer跟踪自动统计信息更新实战指南》本文详解SQLServer自动统计信息更新的跟踪方法,推荐使用扩展事件实时捕获更新操作及详细信息,同时结合系统视图快速检查统计信息状态,重点强调修... 目录SQL Server 如何跟踪自动统计信息更新:深入解析与实战指南 核心跟踪方法1️⃣ 利用系统目录

Python进行JSON和Excel文件转换处理指南

《Python进行JSON和Excel文件转换处理指南》在数据交换与系统集成中,JSON与Excel是两种极为常见的数据格式,本文将介绍如何使用Python实现将JSON转换为格式化的Excel文件,... 目录将 jsON 导入为格式化 Excel将 Excel 导出为结构化 JSON处理嵌套 JSON: