python机器人编程——差速AGV机器、基于视觉和预测控制的循迹、自动行驶(下篇)

2023-11-17

一、前言

基于最近的测试,得到了一种粗略控制的算法,其控制效果适合单线路和急转弯的情况,本人认为可以稍微进行改进适用于十字路口等复杂轨迹的单目视觉循迹运行,本篇是对python机器人编程——差速机器人小车的控制,控制模型、轨迹跟踪,轨迹规划、自动泊车(中)未完成部分给补充,也提供了一种比较可靠和新的思路——我们把它暂且命名为《基于轨迹与路面重心偏离度误差的预测自动差速小车循迹控制》。
在这里插入图片描述
如上图所示,该算法可以在速度360m/h的情况下,比较粗略的自动转过一个大于90度的急转弯。虽然线不是非常贴切,但是我们认为这个方法实际比较可行。下面详细对该方法做个说明:

二、基于轨迹与路面重心偏离度误差的预测自动差速小车循迹控制策略

该方法中差速小车的控制还是用前面提到的预测控制方法,程序是一个以步长为dt的不断根据接受到的图像进行小车正反方向进行未来时刻轨迹预测的过程,并在边界条件下搜索出误差最靠近图像采集轨迹的小车左右轮子对应的速度即为当前步序的最优小车速度设定值。具体的算法流程伪代码如下:

  1. while True:
  2. 	记录预测间隔累计时间con_Hz=con_Hz+1
    
  3. 	读取摄像头图像,并进行处理(具体方法见第三节)获得路径的重心图像坐标cu、cv
    
  4. 	 if 当时间间隔到达预测控制的步长时con_Hz=300毫秒:
    
  5. 			con_Hz=0
    
  6. 			进入预测控制模块best_move(处理过的轨迹,当前的速度状态clv,重心坐标):			
    
  7. 					定义最佳速度设定值bestv=clv
    
  8. 					定义预测的微增速度dv=0.001
    
  9. 					定义预测的边界范围vmax=10
    
  10.    				for i in vmax:#速度增加的方向预测vmax个dv
    
  11.    						左轮的速度sl_n=当前速度+i*dv
    
  12.    						根据恒定速度计算右轮速度
    
  13.    						计算当前速度下未来2.5秒后(可以调整)的轨迹线存在pv、pu的list中
    
  14.    						将当前预测轨迹按照摄像头内参转化到图像坐标
    
  15.    						计算预测轨迹的重心图像坐标(cpu、cpv)
    
  16.    						计算重心距离dei=sqrt((cpu-cu)**2+(cpv-cv)**2)
    
  17.    						if dei<de:
    
  18.    								更新误差de=dei
    
  19.    								更新bestv=sl_n
    
  20.    				for i in vmax:#速度减小的方向预测vmax个dv
    
  21.    						左轮的速度sl_n=当前速度-i*dv
    
  22.    						根据恒定速度计算右轮速度
    
  23.    						计算当前速度下未来2.5秒后(可以调整)的轨迹线存在pv、pu的list中
    
  24.    						将当前预测轨迹按照摄像头内参转化到图像坐标
    
  25.    						计算预测轨迹的重心图像坐标(cpu、cpv)
    
  26.    						计算重心距离dei=sqrt((cpu-cu)**2+(cpv-cv)**2)
    
  27.    						if dei<de:
    
  28.    								更新误差de=dei
    
  29.    								更新bestv=sl_n
    
  30.    			reurn  bestv#返回最优控制速度设定值
    
  31.    	将当前最优控制速度值下发至小车
    
  32.    	进入下一个循环。
    

以上是主要的算法描述。
在这里插入图片描述
根据这个算法,在仿真环境下,跑了很久,也没有大的偏离出轨道。如上图所示,中间的黑色图中:黄色为处理过的路径,蓝色的点为路径的重心点位置,红色的线在当前边界下最佳速度设定值时的预测未来行驶轨迹,当前轨迹是最靠近蓝色重心的,小车始终在这样的策略下运行。

三、轨迹图像的处理要点

对于获取的轨迹图像处理,主要流程如下:

  1. 获取摄像头当前的图像img
  2. 根据颜色选择算法留下黄色轨迹部分信息图像bimg
  3. 将bimg图像进行二值化,留下轨迹的像素为1,得到图binary
  4. 去除binary中小车部分的像素(图像的小下半部分)得到一个新的binary
  5. 计算当前轨迹的重心点cu、cv,供输入预测控制模块
    图像的重心计算代码示例如下:
import cv2
import numpy as np
import matplotlib.pyplot as plt

# Load the binary image
img = cv2.imread('binary_image.png', 0)

# Calculate the moments of the image
M = cv2.moments(img)

# Calculate the centroid
cx = int(M['m10'] / M['m00'])
cy = int(M['m01'] / M['m00'])

# Print the centroid coordinates
print(f'Centroid: ({cx}, {cy})')

# Draw a circle at the centroid
img_with_centroid = cv2.circle(img.copy(), (cx, cy), 5, (255, 0, 0), -1)

# Display the image with the centroid
plt.imshow(img_with_centroid, cmap='gray')
plt.show()

四、本篇部分核心控制策略python代码:

def best_move(sl,Pathimg,vc=0.1,dt=0.5,barycenter=(256,256)):
    #控制增量
    dvl=0.001
    #要预测的控制量     
    sl_n=sl

    #最优的控制量
    best_sl=sl
    mod="G"
    #方差
    de=500
    dei=e+100
    Gbest_sl=sl
    
    for i in range(10):#逐次减小控制量
        sl_n=sl_n-i*dvl
        #待入预测函数获取预测序列        
        xx,yy,tt=predicate(0,0,math.pi/2,sl_n,step=5,dt=dt,vc=vc,dspeed=True)
        #中心轨迹转化为车头轨迹        
        pv=[]
        pu=[]

        #将小车坐标转化到图像坐标
        for i in range(len(xx)):
            puv1=realxy2uv(xx[i],yy[i],Pathimg,xymax=0.5,zero="self_define",dzero=(256,286))
            pu.append(puv1[0])
            pv.append(puv1[1])

        cpu=np.average(pu)
        cpv=np.average(pv) 
        dei= np.sqrt((barycenter[0]-cpu)**2+(barycenter[1]-cpv)**2)   
        if dei<de:
            de=dei
            Gbest_sl=sl_n   

    sl_n=sl  
    for i in range(10):#逐次增大控制量
        sl_n=sl_n+i*dvl
        xx,yy,tt=predicate(0,0,math.pi/2,sl_n,step=5,dt=dt,vc=vc,dspeed=True)    

        #将小车坐标转化到图像坐标
        pv=[]
        pu=[]
        for i in range(len(xx)):
            puv1=realxy2uv(xx[i],yy[i],Pathimg,xymax=0.5,zero="self_define",dzero=(256,286))
            pu.append(puv1[0])
            pv.append(puv1[1])

        cpu=np.average(pu)
        cpv=np.average(pv)     
        
        dei= np.sqrt((barycenter[0]-cpu)**2+(barycenter[1]-cpv)**2)

        if dei<de:
            de=dei
            Gbest_sl=sl_n   
            print("Gbest_sll:",best_sl)
    #返回最优控制量

    if mod=="G":
        return Gbest_sl
    else:
        return best_sl,np

五、结论

后续还有对复杂轨迹的处理需要改进。如需要本篇的仿真环境和源代码,可以加入公众号或者私信留言。
在这里插入图片描述
换了个其它的路径,可以看出这个办法鲁棒性还是不错的,路面有破损只要是趋向于均匀的,自动驾驶也有好的表现:
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

python机器人编程——差速AGV机器、基于视觉和预测控制的循迹、自动行驶(下篇) 的相关文章

随机推荐

  • Kotlin之高阶函数

    一 定义高阶函数 高阶函数和Lambda的关系密不可分 在Lambda编程的基础知识 使用的一些与集合相关的函数式API用法 如map filter函数等 又比如Kotlin的标准函数 如run apply函数等 这几个函数都有一个共同的特
  • 用python进行FamaMacBeth回归

    from linearmodels import FamaMacBeth import pandas as pd import numpy as np 生成所用面板数据集 该数据集在不同的日期有不同的个体 期望回归模型 Y 3 6 X1 4
  • 前端例程20221227:下雪动画

    演示 动图太大了不好上传 这里就放个静态图吧 实际上这里是雪花从上到下飘落的效果 代码
  • 分集 复用 多址

    1 分集 是在多条独立路径上传输相同的数据 接收端通过分集合并技术 抵抗信道衰落 提高传输可靠性 降低误码率 复用 是在多条独立路径上传输不同数据 充分利用系统资源 提高系统容量 即总数据率 2 分集 是一个信号通过多条路径送达接收端 好处
  • UVA-11212 编辑书稿 题解答案代码 算法竞赛入门经典第二版

    GitHub jzplp aoapc UVA Answer 算法竞赛入门经典 例题和习题答案 刘汝佳 第二版 这道题目在书上的 迭代加深搜索 章节出现 即是采用迭代加深搜索的方法来做 但是咋一看题目 我认为用广度优先搜索也合适 因为题目要求
  • python爬虫系列X--小知识汇总

    X系列不针对专门技术 只是一些辅助 内容零散添加 1 为爬虫运行状态设置邮件提醒 使用python smtp email模块完成 from email mime text import MIMETextfrom email header i
  • 【第63篇】CSI-Net:统一的人体特征和姿态识别

    摘要 https arxiv org pdf 1810 03064 pdf 我们构建了CSI Net 一个统一的深度神经网络 DNN 来学习WiFi信号的表示 使用CSI Net 我们共同解决了两个身体特征问题 生物特征估计 包括身体脂肪
  • 【美国大学生数学建模比赛】2020C题(总结和原创参赛论文)百度云请自取

    最新想法 本学期选修了下大数据 发现其实本题的解法还涉及到数据库 大数据各个层次数据处理和分布式数据流blabla 而之前那几天美赛做的还停留在最基础的数据处理层 而且我现在觉得如果要做大的话不应该在这个层里面进行深度学习 前面的数据库处理
  • 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?实现 int sqrt(int x) 函数。

    今天我们来爬一爬楼梯 假设你正在爬楼梯 需要 n 阶你才能到达楼顶 每次你可以爬 1 或 2 个台阶 你有多少种不同的方法可以爬到楼顶呢 注意 给定 n 是一个正整数 示例 1 输入 2 输出 2 解释 有两种方法可以爬到楼顶 1 阶 1
  • 为啥 Python 运行速度这么慢 ?

    作者 Anthony Shaw 是 Python 软件基金会成员和 Apache 基金会成员 近来Python可谓人气骤升 这门编程语言用于开发运维 DevOps 数据科学 网站开发和安全 然而 它没有因速度而赢得任何奖牌 Java在速度方
  • javascript防抖(Debouncing)和节流阀(Throttling)

    中文原文链接 https jinlong github io 2016 04 24 Debouncing and Throttling Explained Through Examples 英文原文链接 https css tricks c
  • C++ 生命周期

    C 程序的生命周期要经过编码 Coding 预处理 Pre processing 编译 Compiling 和运行 Running 四个阶段 编码即coding阶段 这阶段主要是定义变量 写语句 实现各种数据结构 函数和类 预处理是 C C
  • Qt::带返回值的信号发射方式

    一般来说 我们发出信号使用emit这个关键字来操作 但是会发现 emit并不算一个调用 所以它没有返回值 那么如果我们发出这个信号想获取一个返回值怎么办呢 两个办法 1 通过出参形式返回 引用或者指针的方式带回 比如emit sig int
  • 【SHELL脚本】MYSQLDUMP备份数据库,含忽略数据表

    背景介绍 项目的数据库十分重要 必须保证数据不能丢失 项目组的数据库为mysql5 7 12 采用备份工具mysqldump 开发需求 备份指定多个数据库 部分数据库的部分数据表需要指定忽略 打包上传到go FastDFS文件管理器 下面为
  • jvm 内存分配

    1 任何对象都是以8字节为粒度进行对齐的 2 类属性按照如下优先级进行排列 长整型和双精度类型 8字节 整型和浮点型 4字节 字符和短整型 2字节 字符类型和布尔类型 1字节 最后时引用类型 3 不同类型继承关系类的成员不能混合排列 首先按
  • 程序员究竟还需要读书么?

    近来看了2篇和读书有关的文章 一篇提到Joel讲现在程序员不太读书了 主要靠在网上找各种参考资料 一篇则是马总说的 成功与情商有关 与读书多少关系不大 一定程度上这两个观点都有点道理 可以靠StackOverflow com和搜索引擎找到各
  • 1 FFmpeg从入门到精通-FFmpeg简介

    1 FFmpeg从入门到精通 FFmpeg简介 2 FFmpeg从入门到精通 FFmpeg工具使用基础 3 FFmpeg从入门到精通 FFmpeg转封装 4 FFmpeg从入门到精通 FFmpeg转码 5 FFmpeg从入门到精通 FFmp
  • 一个人开发APP系列之实战1 制作APP产品启动图标

    声明 写这个博客系列也是为了清晰思路 新手写的不好 请大神们指导指导 建议想学的还是先去android develops官网看看相关资料吧 好了 不闲扯了 进入正题 今天的目的是使用Android Studio自带的工具Image Asse
  • TencentOS-tiny 功耗管理 (二十 二)- tickless(低功耗)

    一 功耗管理 tickless 概述 TencentOS tiny的tickless机制提供了一套非周期性时钟的方案 在系统无需systick驱动调度的情况下 停掉systick 初级功耗管理方案下 因为还有系统systick的存在 因此系
  • python机器人编程——差速AGV机器、基于视觉和预测控制的循迹、自动行驶(下篇)

    目录 一 前言 二 基于轨迹与路面重心偏离度误差的预测自动差速小车循迹控制策略 三 轨迹图像的处理要点 四 本篇部分核心控制策略python代码 五 结论 一 前言 基于最近的测试 得到了一种粗略控制的算法 其控制效果适合单线路和急转弯的情