单车模型下Stanley循迹

文章目录

  • 1 Stanley方法
  • 2 实现
  • 3 参考资料

1 Stanley方法

  Stanley与pure pursuit方法都是基于几何的路径跟踪方法,pure pursuit的思想是要让车辆的后轴中心经过目标点,从而计算车辆的前轮转角。Stanley则除了利用横向跟踪误差外,还利用车辆的航向角偏差来计算车辆的前轮转角。因此相对于pure pursuit方法,stanley的计算起来要更复杂一些,它还需要轨迹线的角度作为输入,同时在弯路上的跟踪效果精度要优于pure pursuit
在这里插入图片描述

  Stanley基于航向角误差 θ e \theta_e θe与横向误差 e e e,如上图。其中航向角误差是当前车辆航向角与距离前轮中心最近的轨迹点所在的切线方向的夹角。在忽略航向角误差的情况下,横向误差 e e e越大,前轮转角应该越大(很符合直觉,车要想尽力开到轨迹线上就会努力往那个方向打轮)。 d ( t ) d(t) d(t)是最近轨迹点所在的切线方向与前轮预期的行进方向的交点产生,则有:
δ e ( t ) = a r c t a n e ( t ) d ( t ) \delta_e(t) = arctan\cfrac{e(t)}{d(t)} δe(t)=arctand(t)e(t)
由于 d ( t ) d(t) d(t)与车速相关,可以写成 v ( t ) v(t) v(t)的形式

δ e ( t ) = a r c t a n k e ( t ) v ( t ) \delta_e(t) = arctan\cfrac{ke(t)}{v(t)} δe(t)=arctanv(t)ke(t)
最后:
δ ( t ) = θ e ( t ) + a r c t a n k e ( t ) v ( t ) \delta(t) = \theta_e(t) + arctan\cfrac{ke(t)}{v(t)} δ(t)=θe(t)+arctanv(t)ke(t)

2 实现

  同样利用manim动画系统演示一下

class FollowTraj(Scene):

    def construct(self) -> None:
		# 动画相关
        self.frame.set_width(80)
        axes = Axes(x_range=[-500, 500], y_range=[-20, 20])
        self.play(ShowCreation(axes))
		
		# 轨迹线,sin函数
        trajectory = np.zeros((1000, 2))
        trajectory[:, 0] = np.linspace(0, 1000, 1000)
        trajectory[:, 1] = 5 * np.sin(trajectory[:, 0] / 20)
        # 轨迹点的切线方向,sin的导数
        trajectory_head = 0.25 * np.cos(trajectory[:, 0] / 20)

        refer_tree = KDTree(trajectory)

        # 动画相关
        trajectory_dot = VGroup()
        for i in range(len(trajectory)):
            dot = Dot().move_to(axes.c2p(trajectory[i, 0], trajectory[i, 1]))
            dot.set_color(BLUE)
            trajectory_dot.add(dot)
        self.play(ShowCreation(trajectory_dot))

		# 轴距
        L = 2.8
        v = 5.0 # 初始速度

        # 初始化车辆,仿真模拟步长0.1s,单车模型
        car = KinematicModelBackCenter(0, 2.0, 0, v, L, 0.1)

		# 动画相关
        car_center = Dot(color=RED).move_to(axes.c2p(car.x, car.y))
        car_polygon = get_polygon(car.x, car.y, car.psi, 3.0, 1.0, 2.1).set_color(RED)

        idx = 0
        pidx = 0
        k = 0.5
        for i in range(1000):
            self.frame.move_to(axes.c2p(car.x, car.y))
            car_pos = np.array([car.x, car.y])
            car_fwheel = np.array([car.x + car.L * np.cos(car.psi),
                                   car.y + car.L * np.sin(car.psi)])

            _, idx = refer_tree.query(car_fwheel)
            if idx < pidx:
                idx = pidx
            else:
                pidx = idx

            # 前轮中心到当前最近的轨迹线的距离
            dist = np.linalg.norm(car_fwheel - trajectory[idx])
            # 前轮中心到最近的轨迹点的向量,以及该向量的角度
            dx, dy = trajectory[idx] - car_fwheel
            alpha = math.atan2(dy, dx)
            # 这个是航向角误差
            dtheta = normalize_angle(trajectory_head[idx] - car.psi)
    		# 横向误差
            e = np.sign(np.sin(alpha - car.psi)) * dist
            theta_d = np.arctan2(k*e, car.v)
            # 前轮转角
            delta = dtheta + theta_d
            #  限制车轮转角 [-30, 30]
		    if delta > np.pi / 6.0:
		        delta = np.pi / 6.0
		    elif delta < - np.pi / 6.0:
		        delta = - np.pi / 6.0
            # 更新车辆状态
            car.update_state(0, delta)

            # 动画相关
            cur_car_center = Dot(color=RED).move_to(axes.c2p(car.x, car.y))
            cur_car_polygon = get_polygon(car.x, car.y, car.psi, 3.0, 1.0, 2.1).set_color(RED)

            # 动画相关
            self.play(Transform(car_center, cur_car_center),
                      Transform(car_polygon, cur_car_polygon), run_time=0.01)

运行效果如下
请添加图片描述

3 参考资料

  • https://blog.csdn.net/renyushuai900/article/details/98460758
  • https://windses.blog.csdn.net/article/details/103518011
  • manim动画系统

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CSS基础常用属性之颜色(如果想知道CSS的颜色知识点,那么只看这一篇就足够了!)

前言&#xff1a;在我们学习CSS的时候&#xff0c;主要学习选择器和常用的属性&#xff0c;而这篇文章讲解的就是最基础的属性——颜色。 ✨✨✨这里是秋刀鱼不做梦的BLOG ✨✨✨想要了解更多内容可以访问我的主页秋刀鱼不做梦-CSDN博客 目录 1.颜色属性 【1】使用颜色关键词表…

《苍穹外卖》Day01知识点记录

一、Yapi 网址为&#xff1a;https://yapi.pro/ 二、Swagger 1. 常用注解 通过注解可以控制生成的接口文档&#xff0c;使接口文档拥有更好的可读性&#xff0c;常用注解如下&#xff1a; 注解说明Api用在类上&#xff0c;例如Controller&#xff0c;表示对类的说明ApiMod…

视频号小店的红利来了,跟谁打工不是打工,自己开店,给自己打工

大家好&#xff0c;我是电商花花。 自动抖音小店的飞速崛起&#xff0c;打破了电商何惧&#xff0c;给电商行业注入了新能量&#xff0c;新活力。 而作为一直想要进军电商的腾讯&#xff0c;自然也是不想放过这个机会&#xff0c;更是携着视频号带着视频号小店来电商讨一碗饭…

Java岗大厂面试百日冲刺 - 日积月累,每日三题【Day11】 —— MyBatis1

市面上主流ORM框架: EJB&#xff1a;重量级、高花费的ORM技术&#xff0c;支持JPA&#xff0c;尤其是EJB3低侵入式 的设计&#xff0c;增加了Annotation Hibernate&#xff1a;开源&#xff0c;支持JPA &#xff0c;被选作JBoss的持久层解决方案 iBatis&#xff1a;”SQL Mappi…

CCF区块链论文录用资讯--ICSE 2024

ICSE是CCF A类会议 &#xff08;软件工程/系统软件/程序设计语言&#xff09; 其2024录用了13篇区块链论文 Smart Contract and DeFi Security Tools: Do They Meet the Needs of Practitioners? 智能合约和 DeFi 安全工具&#xff1a;它们满足从业者的需求吗&#xff1f; St…

node和go的列表转树形, 执行速度测试对比

保证数据一致性&#xff0c;先生成4000条json数据到本地&#xff0c;然后分别读取文本执行处理 node代码 node是用midway框架 forNum1:number 0forNum2:number 0//执行测试async index(){// 生成菜单列表// const menuList await this.generateMenuList([], 4000);const men…

多任务学习,在共享层,究竟在共享什么?

在多任务学习中&#xff0c;共享层所共享的主要是网络结构和参数。具体来说&#xff0c;当多个任务在共享层进行参数硬共享时&#xff0c;它们使用的是相同的网络结构&#xff08;例如三层全连接神经网络&#xff09;&#xff0c;并且这些网络层的权重&#xff08;weights&…

java新冠病毒密接者跟踪系统(springboot+mysql源码+文档)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的新冠病毒密接者跟踪系统。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 新冠病毒密接者跟…

【计算机组成原理】加法器原理及其优化

苏泽 本专栏纯个人笔记作用 用于记录408 学习的笔记记录&#xff08;敲了两年码实在不习惯手写笔记了&#xff09; 如果能帮助到大家当然最好 但由于是工作后退下来备考 很多说法和想法都会结合实际开发的思想 可能不是那么的纯粹应试哈 希望大家挑选自己喜欢的口味食用…

机器人的非接触式充电和无线充电有什么区别?

文 | BFT机器人 在日新月异的技术浪潮中&#xff0c;接触式与非接触式无线充电之间的微妙差异变得愈发重要&#xff0c;这如同在纷繁复杂的迷雾中增添了一层难以捉摸的迷离。而今&#xff0c;一些所谓的“无线”充电站纷纷涌入市场&#xff0c;它们自诩为无需线缆束缚的新时代…

FAT16文件系统

FAT16 大端存储&#xff1a;高位字节放在低地址端&#xff0c;低位字节放在高地址端。 小端存储&#xff1a;低位字节放在低地址端&#xff0c;高位字节放在高地址端。 举一个例子&#xff0c;比如数字0x12 34 56 78在内存中的表示形式为&#xff1a; 大端模式&#xff1a; 低地…

2024年软件开发行业的薪资水平在下滑的原因?

下降的原因主要包括&#xff1a; 科技行业竞争加剧&#xff1a;随着科技行业竞争的加剧&#xff0c;企业为了压缩成本&#xff0c;开始降低程序员的薪资水平。 人才供应过剩&#xff1a;在计算机成为热门学科的同时&#xff0c;社会上出现了对IT业泡沫和虚假繁荣的质疑。大量…

【ROS2笔记七】ROS中的参数通信

7.ROS中的参数通信 文章目录 7.ROS中的参数通信7.1使用CLI工具调整参数7.2参数通信之rclcpp实现7.2.1创建节点7.2.2rclcpp参数API Reference ROS2中的参数是由键值对组成的&#xff0c;参数可以实现动态调整。 7.1使用CLI工具调整参数 启动turtlesim功能包的环境 ros2 run …

java算法day56 | 动态规划part15 ● 392.判断子序列 ● 115.不同的子序列

392.判断子序列 动规五部曲&#xff1a; 确定dp数组&#xff08;dp table&#xff09;以及下标的含义 dp[i][j] 表示以下标i-1为结尾的字符串s&#xff0c;和以下标j-1为结尾的字符串t&#xff0c;相同子序列的长度为dp[i][j]。确定递推公式 在确定递推公式的时候&#xff0c;…

第21天:信息打点-公众号服务Github监控供应链网盘泄漏证书图标邮箱资产

第二十一天 一、开发泄漏-Github监控 1.短期查看 1.密码搜索 根据攻击目标的域名在GitHub上进行搜索密码&#xff0c;如果目标网站的文件与搜索到的源码相关&#xff0c;那就可以联想目标网站是否使用这套源码进行开发 原理就是开发者在上传文件的时候忘记更改敏感文件或者…

探索VR数字展厅,对企业未来展示新模式

在数字化浪潮的推动下&#xff0c;企业展示也在经历着一场革命&#xff0c;VR数字展厅正在以一种全新的方式重塑我们的生活和工作空间&#xff0c;不仅重塑了客户的观展体验&#xff0c;也为企业营销打开了新的渠道。 VR数字展厅作为实体展厅的数字化延伸&#xff0c;正以其沉浸…

SpringBoot框架——7.整合MybatisPlus

这篇主要介绍Springboot整合MybatisPlus&#xff0c;另外介绍一个插件JBLSpringbootAppGen,以及一个经常用于测试的基于内存的h2数据库。 Mybatisplus是mybatis的增强工具&#xff0c;和tk-mybatis相似&#xff0c;但功能更强大&#xff0c;可避免重复CRUD语句&#xff0c;先来…

JWT的使用

0、JWT原理 header JWT第一部分是header,header主要包含两个部分,alg指加密类型&#xff0c;可选值为HS256、RSA等等&#xff0c;typJWT为固定值&#xff0c;表示token的类型。 Payload JWT第二部分是payload,payload是token的详细内容,一般包括iss (发行者), exp (过期时间),…

速看!2024中国(厦门)国际康复医疗展览会

2024中国&#xff08;厦门&#xff09;国际康复医疗展览会 2024 China (Xiamen) International Rehabilitation Medical Exhibition 时 间&#xff1a;2024年8月13-15日 August 13-15, 2024 地 点&#xff1a;厦门国际会展中心 Xiamen International Conference & Exh…

分布式调度器timer和spring task

1. Timer&#xff08;了解&#xff09; 一、Timer使用方式 Task1 public class Task1 extends TimerTask {Overridepublic void run(){System.out.println("com.aware.Task run");} } Task2 public class Task2 extends TimerTask {Overridepublic void run(){…