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

news2025/7/13 5:09:16

目录

  • 一、前言
  • 二、主要思路
    • 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+90
    print("当前小车角度:",angle1)
    print("当前小车坐标:",p0x,p0y)
    f,angle0=single_vangle([p0x,p0y,p1x,p1y])
    print("当前中间点角度:",angle0)
    dangle=angle0-angle1
    print("转角角度:",dangle)
    if dangle>=0:#顺时针转rv>0>lv
        dangle=dangle/180*math.pi#转弧度
        vr=tspeed
        vl=-tspeed
        #旋转时间=角度/角速度,角速度=线速度/r
        tita=abs(dangle/(vr*10*0.164))
        orders.append([tita,(vl,vr),clientID,TTHandle])
    else:
        dangle=-dangle/180*math.pi#转弧度
        vr=-tspeed
        vl=tspeed
        #旋转时间=角度/角速度,角速度=线速度/r
        tita=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,0
    start_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+ang0
        else:
            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+ang1
                if 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)/tita
                
                print("角速度(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)/tita
                print("线速度(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=speed
    vr=speed
    tita=distance/(vl*10*24)
    orders.append([tita,(vl,vr),clientID,TTHandle])
    ######part2------接下部分###############

step3 调整姿态

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

######part3------接part2部分###############
#计算中间点位置旋转
    dangle=90-angle0
    if dangle>=0:#顺时针转rv>0>lv
        
        dangle=dangle/180*math.pi#转弧度
        vr=tspeed
        vl=-tspeed
        #旋转时间=角度/角速度,角速度=线速度/r
        tita=abs(dangle/(vr*10*0.164))
        orders.append([tita,(vl,vr),clientID,TTHandle])
    else:
        dangle=-dangle/180*math.pi#转弧度
        vr=-tspeed
        vl=tspeed
        #旋转时间=角度/角速度,角速度=线速度/r
        tita=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等其它控制手段,实现小车位置的精调回正。

三、效果

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

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

四、全篇总结

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

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

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

相关文章

_cpp 位图

文章目录1. 位图概念1.1 给40亿个不重复的无符号整数&#xff0c;没排过序。给一个无符号整数&#xff0c;如何快速判断一个数是否在这40亿个数中。2. 位图的实现2.1 运行结果&#xff1a;3. 位图应用3.1 具体代码封装实现如下3.2 部分结果演示&#xff1a;3.3 应用总结&#x…

力扣(LeetCode)791. 自定义字符串排序(C++)

排序 这道题只关心 orderorderorder 出现的字符&#xff0c;在 sss 中的排序。 sss 中不在 orderorderorder 的字符&#xff0c;在排序后是什么位置&#xff0c;不影响答案。 可以用 sortsortsort 函数&#xff0c;传入我们自定义的排序方式&#xff0c;按照 orderorderorder …

【JavaSE】类和对象 (二) —— 封装、包以及 static 关键字

目录 1. 封装 1.1 封装的概念 1.2 访问限定符 2. 包 2.1 包的概念 2.2 导入包中的类 2.3 自定义包 2.3.1 包的基本规则 2.3.2 创建一个包 2.4 包访问权限——defualt 3. 何为封装 3.1 private 关键字 4. static 成员 4.1 对学生类的进一步思考 4.2 static 修饰成员变量 4.3 …

计算机毕业设计之java+javaweb的物业管理系统

项目介绍 系统权限按管理员,物业和住户这三类涉及用户划分。 (a) 管理员&#xff1a;管理员使用本系统涉到的功能主要有&#xff1a;首页,个人中心,用户管理,员工管理,房屋类型管理,房源信息管理,房屋预约管理,订单信息管理,我的收藏管理,系统管理等功能。 (b) 住户&#xf…

基于单片机的导盲拐杖设计

目 录 引言 1 1 系统概述 1 1.1 设计研究的背景和意义 1 1.2 本次设计内容 1 2 系统设计的整体方案 2 2.1 主控芯片的方案论证 2 2.2 显示模块的方案论证 3 2.3 本章小节 4 3 系统硬件电路设计 4 3.1 单片机最小系统的电路设计 4 3.1.1 STC…

李峋同款爱心代码!跳动的心,给你爱的人一个惊喜!

Hello 大家好 如何浪漫的表白&#xff0c;作为程序员出身的小编&#xff0c;今天就带你实现热播剧《点燃我&#xff0c;温暖你》中超火的李峋同款爱心代码&#xff01;前面是教程&#xff0c;怕麻烦的朋友可以直接划到文末&#xff0c;下载现成的&#xff0c;下载完成后打开就可…

java毕业设计基于的校园头条新闻管理系统的设计与实现(附源码、数据库)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; Springboot mybatis Maven Vue 等等组成&#xff0c;B/…

【Linux】基础:进程地址空间

【Linux】基础&#xff1a;进程地址空间 摘要&#xff1a;本文首先通过复习关于C语言内存空间的知识来做实验提出问题&#xff0c;从而引入进程的地址空间。需要理解的是进程地址空间的组织形式与其表示意义&#xff0c;在需要理解如何完成进程地址空间的划分以及关键对应物理内…

C++12 ---对象于对象的关系

一、对象于对象的关系 在一个系统中&#xff0c;一个对象可能与不同的对象相关&#xff0c;以下是不同的关系。 依赖(Dependency) (使用一个) 关联(Association) (使用一个) 聚合(Aggregation) (有一个) 组合(Composition ) (有一个&#xff0c;"用..来实现") …

从Matlab实例学习遗传算法

文章目录前言问题背景遗传算法Matlab实例代码附录君主方案遗传算法解决旅行商问题前言 本文旨在使用智能优化算法及其MATLAB实例&#xff08;第2版&#xff09; 一书中的例子&#xff0c;来透彻理解遗传算法的本质。 问题背景 目标&#xff1a; 求解最大化函数 f(x)x10sin⁡…

2023最新SSM计算机毕业设计选题大全(附源码+LW)之java星光之夜香水网站的设计与开发bfmcr

大学计算机专业毕业的&#xff0c;实际上到了毕业的时候&#xff0c;基本属于会与不会之间。说会&#xff0c;是因为学了整套的理论和方法&#xff0c;就是所谓的科班出身。说不会&#xff0c;是因为实践能力极差。 不会的问题&#xff0c;集中体现在毕设的时候&#xff0c;系…

CTFSHOW菜狗杯 web

文章目录web签到web2 c0me_t0_s1gn我的眼里只有$抽老婆一言既出驷马难追TapTapTapWebshell化零为整无一幸免传说之下&#xff08;雾&#xff09;算力超群算力升级2遍地飘零茶歇区小舔田&#xff1f;LSB探姬Is_Not_Obfuscate龙珠NFTweb签到 eval($_REQUEST[$_GET[$_POST[$_COOK…

Ubuntu22.04虚拟机配置双网

文章目录Ubuntu22.04虚拟机配置双网一、 虚拟机网络1、 简介1.1 概述1.2 四种网络2、 配置双网2.1 NAT2.2 主机模式3、 添加到虚拟机二、 ubuntu设置Ubuntu22.04虚拟机配置双网 一、 虚拟机网络 1、 简介 1.1 概述 近期在使用VirtualBox的时候遇到这样的场景&#xff0c;我…

Docker(五)—— 镜像原理、容器快照commit

一、如何得到镜像 1&#xff09;从远程仓库下载 2&#xff09;朋友/同事拷贝给你 3&#xff09;自己制作DockerFile 二、联合文件系统 Docker的镜像是由一层层的文件系统组成&#xff0c;这种层级的文件系统叫做联合文件系统UnionFS。 三、Docker镜像加载原理 1. bootfs:…

第十四届蓝桥杯校内模拟赛第一期——Python

第十四届蓝桥杯校内模拟赛第一期——Python 文章目录第十四届蓝桥杯校内模拟赛第一期——Python1.二进制位数问题描述参考答案扩展2. 晨跑问题描述参考答案扩展3. 调和级数问题描述参考答案4. 山谷问题描述参考答案5. 最小矩阵问题描述参考答案6. 核酸日期问题描述输入格式输出…

redux与react-redux的学习笔记之react-redux

redux与react-redux前言一、redux和react-redux是啥&#xff1f;二、redux使用步骤1.引入库2.原理图原理图释义actions1&#xff09;含义2&#xff09;demostore.js1&#xff09;含义2&#xff09;demoreducer.js1&#xff09;含义2&#xff09;demoCount.jsx1&#xff09;含义…

2022年,我们为什么要学习C++?

“C已死” 大学时代&#xff0c;我就听过这样的说法——差不多十多年前的事儿了。那时候至少在美国&#xff0c;Java已经成了各公司的主流语言。程序员也许都很熟悉Joel Spolsky在2005年12月对JavaSchools发起的批驳。此外&#xff0c;作为微软应对Java的手段&#xff0c;2000…

Ubuntu环境配置(instant-ngp)

综合环境配置 这篇文章的综合配置我是在恒源云上配的&#xff0c;自己穷买不起机子&#xff0c;就只能租咯&#xff0c;这家价格还行&#xff0c;而且可以装VNC&#xff0c;非推广&#xff0c;只是感觉方便&#xff0c;请大家结合自身实际情况 数据上传 这里有几种方法&…

【免费】多种方法手把手教你如何将自己做的网页做成网络链接(直接访问)

目录 前言 ​一、github&#xff08;最常用的&#xff09; 二、七牛云&#xff08;推荐小白使用&#xff0c;简单粗暴&#xff09; 三、NATAPP 四、codepen&#xff08;建议学网页的人群使用&#xff09; 彩蛋 前言 http://t.csdn.cn/VaiP1我之前发的爱心代码&#xff0c;…

电脑突然开机无反应,怎么办

电脑常见故障之三开机无响应&#xff08;上&#xff09; 经常使用电脑的朋友应该会碰到这种情况&#xff0c;开机时按下电源按钮后&#xff0c;电脑无响应&#xff0c;显示器黑屏不亮。 除去那些傻瓜式的故障原因&#xff0c;如显示器、主机电源没插好&#xff1b;显示器与主…