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


原文地址:https://blog.csdn.net/kanbide/article/details/127734882
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/699774

相关文章

Python FastMCP构建MCP服务端与客户端的详细步骤

《PythonFastMCP构建MCP服务端与客户端的详细步骤》MCP(Multi-ClientProtocol)是一种用于构建可扩展服务的通信协议框架,本文将使用FastMCP搭建一个支持St... 目录简介环境准备服务端实现(server.py)客户端实现(client.py)运行效果扩展方向常见问题结

Spring组件实例化扩展点之InstantiationAwareBeanPostProcessor使用场景解析

《Spring组件实例化扩展点之InstantiationAwareBeanPostProcessor使用场景解析》InstantiationAwareBeanPostProcessor是Spring... 目录一、什么是InstantiationAwareBeanPostProcessor?二、核心方法解

详解如何使用Python构建从数据到文档的自动化工作流

《详解如何使用Python构建从数据到文档的自动化工作流》这篇文章将通过真实工作场景拆解,为大家展示如何用Python构建自动化工作流,让工具代替人力完成这些数字苦力活,感兴趣的小伙伴可以跟随小编一起... 目录一、Excel处理:从数据搬运工到智能分析师二、PDF处理:文档工厂的智能生产线三、邮件自动化:

Python实现自动化Word文档样式复制与内容生成

《Python实现自动化Word文档样式复制与内容生成》在办公自动化领域,高效处理Word文档的样式和内容复制是一个常见需求,本文将展示如何利用Python的python-docx库实现... 目录一、为什么需要自动化 Word 文档处理二、核心功能实现:样式与表格的深度复制1. 表格复制(含样式与内容)2

Java 枚举的基本使用方法及实际使用场景

《Java枚举的基本使用方法及实际使用场景》枚举是Java中一种特殊的类,用于定义一组固定的常量,枚举类型提供了更好的类型安全性和可读性,适用于需要定义一组有限且固定的值的场景,本文给大家介绍Jav... 目录一、什么是枚举?二、枚举的基本使用方法定义枚举三、实际使用场景代替常量状态机四、更多用法1.实现接

python获取cmd环境变量值的实现代码

《python获取cmd环境变量值的实现代码》:本文主要介绍在Python中获取命令行(cmd)环境变量的值,可以使用标准库中的os模块,需要的朋友可以参考下... 前言全局说明在执行py过程中,总要使用到系统环境变量一、说明1.1 环境:Windows 11 家庭版 24H2 26100.4061

Python中文件读取操作漏洞深度解析与防护指南

《Python中文件读取操作漏洞深度解析与防护指南》在Web应用开发中,文件操作是最基础也最危险的功能之一,这篇文章将全面剖析Python环境中常见的文件读取漏洞类型,成因及防护方案,感兴趣的小伙伴可... 目录引言一、静态资源处理中的路径穿越漏洞1.1 典型漏洞场景1.2 os.path.join()的陷

Python数据分析与可视化的全面指南(从数据清洗到图表呈现)

《Python数据分析与可视化的全面指南(从数据清洗到图表呈现)》Python是数据分析与可视化领域中最受欢迎的编程语言之一,凭借其丰富的库和工具,Python能够帮助我们快速处理、分析数据并生成高质... 目录一、数据采集与初步探索二、数据清洗的七种武器1. 缺失值处理策略2. 异常值检测与修正3. 数据

Python中bisect_left 函数实现高效插入与有序列表管理

《Python中bisect_left函数实现高效插入与有序列表管理》Python的bisect_left函数通过二分查找高效定位有序列表插入位置,与bisect_right的区别在于处理重复元素时... 目录一、bisect_left 基本介绍1.1 函数定义1.2 核心功能二、bisect_left 与

Python使用Tkinter打造一个完整的桌面应用

《Python使用Tkinter打造一个完整的桌面应用》在Python生态中,Tkinter就像一把瑞士军刀,它没有花哨的特效,却能快速搭建出实用的图形界面,作为Python自带的标准库,无需安装即可... 目录一、界面搭建:像搭积木一样组合控件二、菜单系统:给应用装上“控制中枢”三、事件驱动:让界面“活”