AI - Steering behaviorsII(碰撞避免,跟随)

Steering Behaviors系统中的碰撞避免,路径跟随,队长跟随

Collision Avoid

在物体前进的方向,延伸一定长度的向量进行检测。相当于物体对前方一定可使范围进行检测障碍物的碰撞
在这里插入图片描述
延伸的向量与碰撞物圆心的距离小于碰撞物的半径,则判断前进方向有阻挡物
在这里插入图片描述
我们会对所有障碍物进行碰撞检测,但是只取最近的一个做处理
在这里插入图片描述

可以延伸多条不同长度的同方向向量进行检测,以免过于靠近物体而使检测向量超过了碰撞物
在这里插入图片描述
前方视野向量检测到有障碍物的话,就会进行躲避,有障碍物圆心减去检测向量得到躲避力的方向
在这里插入图片描述
注意这里是和flee的最主要区别。avoid力相当于提前检测前方行进方向是否有障碍物,然后提前开始避开了。而flee力则是用当前自身自身的位置判断是否flee目标点,并以自身位置进行反向逃离计算
这里一个关键点是ahead的向量,如果ahead向量是个固定长度的,会有个问题就是,物体无法停在障碍物的前方。因为可能此生的检测向量一直在障碍物的范围内。如下图
在这里插入图片描述
因此ahead向量的长度要通过当前速度与最大速度的比例来设置,如果当前速度接近0,则ahead的长度也接近于0

Vec2 MoveNode::collisionAvoid(float maxSpeed) {
    Vec2 avoidForce = Vec2::ZERO;
    float dynamicLen = _velocity.getLength() / maxSpeed;
    //Vec2 ahead = this->getPosition() + _velocity.getNormalized() * _aheadLen;
    Vec2 ahead = this->getPosition() + _velocity.getNormalized() * dynamicLen;
    Vec2 obstaclePos = findNearestObstacle(maxSpeed);
    if (obstaclePos != Vec2(-1, -1)) {
        avoidForce = ahead - obstaclePos;
        avoidForce.normalize();
        avoidForce *= _avoidForce;
    }
    return avoidForce;
}
//找到最具威胁的阻碍物,ahead为检测向量,与所有障碍物的圆心进行距离判定
Vec2 MoveNode::findNearestObstacle(float maxSpeed) {
    Vec2 pos = this->getPosition();
    /*Vec2 ahead = pos + _velocity.getNormalized() * _aheadLen;
    Vec2 ahead2 = pos + _velocity.getNormalized() * _aheadLen / 2;*/
    float dynamicLen = _velocity.getLength() / maxSpeed;
    Vec2 ahead = pos + _velocity.getNormalized() * dynamicLen;
    Vec2 ahead2 = pos + _velocity.getNormalized() * dynamicLen / 2;
    Vec2 v = Vec2(-1, -1);
    for (auto obstacle : _obstacles) {
        Vec2 center = obstacle.first;
        float radius = obstacle.second;
        bool isCollision = ahead.getDistance(center) < radius || ahead2.getDistance(center) < radius;
        if(isCollision && (v == Vec2(-1,-1) || pos.getDistance(center) < pos.getDistance(v))) v = center;
    }
    return v;
}

效果
在这里插入图片描述

Path Following

比较简单的实现是,将路径划分多个路径点,对每个路径点进行seek
在这里插入图片描述
因为物体是带有类似惯性的,所有对每个路径点seek时,需要判定到达路径点一定范围内就算到达当前路径点,然后前往下一路径点,否则会在初始点无限循环
在这里插入图片描述
注意路径点的到达半径如果太短的话,物体由于速度过快可能会在路径点周围绕一圈,才走进了到达的范围内,才前往下一路径点
在这里插入图片描述

在这里插入图片描述

//_pathDir表示了路径点索引的方向,我们这里是抵达起始点或终点后进行反向
Vec2 MoveNode::pathFollowing() {
    Vec2 steering = Vec2::ZERO;
    if (_pathNodes.empty()) return steering;
    auto pathNode = _pathNodes[_pathNodeIdx];
    Vec2 pos = pathNode.first;
    float arriveRadius = pathNode.second;
    if (this->getPosition().getDistance(pos) <= arriveRadius) {
        _pathNodeIdx += _pathDir;
        if (_pathNodeIdx >= _pathNodes.size() || _pathNodeIdx < 0) {
            _pathDir *= -1;
            _pathNodeIdx += _pathDir;
        }
    }
    return seek(_pathNodes[_pathNodeIdx].first);
}

在这里插入图片描述

Leader Following

跟随一个队长的路径
队长跟随类似追捕目标,只不过追捕目标是预测目标点前进几帧后的方向进行seek,但是跟随是队长前进方向的反向一定距离进行跟随
在这里插入图片描述
如上图,求出队长速度的反向,在一定长度的位置behind,队员对behind的位置进行arrive

//_leaderBehindDist:跟随在队长背后的距离
Vec2 MoveNode::leaderFollowing() {
    Vec2 steering = Vec2::ZERO;
    if (_leader == nullptr) return steering;
    Vec2 tv = _leader->getVelocity() * -1;
    tv.normalize();
    tv *= _leaderBehindDist;
    Vec2 followPos = _leader->getPosition() + tv;

    steering += seek(followPos);
    return steering;
}

在这里插入图片描述
我们看到队员跟随在队长背后,但是此时队员都挤成了一团,因此对队员加上集群模拟的separation力
在这里插入图片描述
另一个问题是,跟随队长的队员,是不允许挡在队长前进的前方的。此时,我们给队长一个前方的视线检测向量和一个检测半径,如果队员在这个视线检测范围内的话,就要对队长进行避让evade
在这里插入图片描述

//pos是队员的坐标位置,_leaderAhead是队长视线的检测的长度,与队长速度方向求的检测向量,_leaderAheadRadius是检测的范围半径。该函数判定队员位置是否在队长前进的方向上
bool MoveNode::isInAheadArea(Vec2 pos) {
    Vec2 srcPos = this->getPosition();
    Vec2 aheadPos = _velocity.getNormalized()* _leaderAhead + srcPos;
    return srcPos.getDistance(pos) < _leaderAheadRadius || aheadPos.getDistance(pos) < _leaderAheadRadius;
}

evade的逻辑于pursuit类似,预测队长几帧后的前进位置,对该位置进行flee

Vec2 MoveNode::leaderFollowing() {
    Vec2 steering = Vec2::ZERO;
    if (_leader == nullptr) return steering;
    Vec2 tv = _leader->getVelocity() * -1;
    tv.normalize();
    tv *= _leaderBehindDist;
    Vec2 followPos = _leader->getPosition() + tv;
    
    //如果在队长视野前方,则预测队长行进路线进行逃离evade
    if (_leader->isInAheadArea(this->getPosition())) {
        Vec2 leadPos = _leader->getPosition();
        float t = this->getPosition().getDistance(leadPos) / _dtSpeed;
        Vec2 fleePos = leadPos + _leader->getVelocity() * t;
        steering += flee(fleePos);
    }
    steering += seek(followPos);
    return steering;
}

在这里插入图片描述
下面是队长跟随路径移动,队员跟随队长移动的结合例子
在这里插入图片描述

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

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

相关文章

Maven的安装和使用

Maven是一个基于项目对象模型&#xff08;POM&#xff09;&#xff0c;可以管理项目构建、依赖管理、项目报告等的工具&#xff0c;使构建Java项目更容易。可以说Maven是一个项目管理和构建工具&#xff0c;它可以从管理项目的角度出发&#xff0c;将开发过程中的需求纳入进来&…

解密性能测试:深入剖析性能问题的步骤!

前言 性能测试大致分以下几个步骤&#xff1a; 需求分析脚本准备测试执行结果整理问题分析 今天要说的是最后一个步骤——“问题分析”&#xff1b; 需求描述 有一个服务&#xff0c;启动时会加载一个1G的词表文件到内存&#xff0c;请求来了之后&#xff0c;会把请求词去…

优化-查询数据接口太慢

有一个查询接口&#xff0c;主业务表有几万多条数据&#xff0c;没超过十万&#xff0c;由于没有使用分页&#xff0c;所以每次查询都要返回大几万的数据&#xff0c;然后问题是前端页面查询数据显示数据要转很久。 压缩响应体大小 我发现查询的时间是1秒多&#xff0c;但是浏…

基于STC12C5A60S2系列1T 8051单片机的液晶显示器LCD1602显示整数、小数应用

基于STC12C5A60S2系列1T 8051单片机的液晶显示器LCD1602显示整数、小数应用 STC12C5A60S2系列1T 8051单片机管脚图STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式及配置STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式介绍液晶显示器LCD1602简单介绍IIC通信简单介绍…

Android UiAutoMatorViewer打不开

UIAutoMatorViewer是个很好用的工具&#xff0c;能解析出任意手机页面的UI树&#xff0c;非常方便。 工具位置&#xff1a;SDK\tools\bin\uiautomatorviewer.bat 一般双击就能打开。 但有时会打不开&#xff0c;双击后无反应&#xff0c;在cmd窗口中运行也是如此。 这种情况…

python用YOLOv8对图片进行分类

用yolov8的模型进行分类 先上效果图 图片资源 模型下载地址 https://github.com/ultralytics/ultralytics 代码 import matplotlib.pyplot as plt from ultralytics import YOLO from PIL import Image import cv2model YOLO(../ultralytics/yolov8n.pt)# print(model…

【NodeJS】 API Key 实现 短信验证码功能

这里使用的平台是 短信宝整体来讲还是挺麻烦的平台必须企业才行&#xff0c;个人是无法使用该平台的 平台必须完成 身份信息认证 和 企业认证 这里就需要 “营业执照”了 &#xff0c;没有 “营业执照” 的朋友还是后退一步吧 后端我用的是NodeJS &#xff0c;使用第三方库 ro…

连接mysql 出现can‘t connect to server on ‘localhost‘ (10061) 报错

首先确保你自己已经安装了mysql。 如果安装了mysql 还是有问题。我们可以在 任务管理器 》服务 中找Mysql服务。 如果有Mysql 服务&#xff0c;启动服务即可。 如果没有这个服务&#xff0c;需要我们下载服务。具体操作如下 管理员启动终端&#xff0c;找到安装的mysql &…

转战MySQL Shell!数据库备份新姿势,轻松搞定备份操作!

MySQL8.0后续版本中主推使用MySQL Shell进行相关日常管理及维护操作&#xff0c;如果后续移除了mysqldump等命令后&#xff0c;如何进行数据库备份等相关操作呢&#xff1f;本文开始进行数据库备份的操作。 1. MySQL Shell 安装 1.1 下载 可以在MySQL官网进行下载&#xff0…

分布式系统:CAP 定理

欢迎来到分布式系统系列。在本文中&#xff0c;我们将学习并理解什么是 CAP 定理。CAP 代表一致性、可用性和分区容错性。当我们谈论CAP定理时&#xff0c;我们主要谈论的是分布式系统。首先&#xff0c;让我们了解一下什么是分布式系统。分布式系统是由运行在单台或多台机器上…

【驱动】串口驱动分析(一)-软件架构

区分不同的终端类型 串行端口终端&#xff08;/dev/ttySn&#xff09; 串行端口终端&#xff08;Serial Port Terminal&#xff09;是使用计算机串行端口连接的终端设备。计算机把每个串行端口都看作是一个字符设备。 有段时间这些串行端口设备通常被称为终端设备&#xff0…

Redis哈希对象(listpack介绍)

哈希对象的编码可以是ziplist或者hashtable。再redis5.0版本之后出现listpack&#xff0c;为了是代替ziplist。 一. 使用ziplist编码 ziplist编码的哈希对象使用压缩列表作为底层实现&#xff0c;每当有新的键值对要加入到哈希对象时&#xff0c;程序都会先将保存了键值对的键…

el-table实现动态表头

1.1el-table渲染 <el-tableref"refreshTable":data"tableData"highlight-current-row><el-table-columnfixedwidth"170px"label"测点"align"center"prop"测站名称"/><el-table-column label"…

万户ezOFFICE wpsservlet任意文件上传漏洞复现

0x01 产品简介 万户OA ezoffice是万户网络协同办公产品多年来一直将主要精力致力于中高端市场的一款OA协同办公软件产品&#xff0c;统一的基础管理平台&#xff0c;实现用户数据统一管理、权限统一分配、身份统一认证。统一规划门户网站群和协同办公平台&#xff0c;将外网信息…

位图和布隆过滤器(C++)

位图和布隆过滤器 一、位图1. 引入2. 概念3. 代码实现setreset完整代码 4. 位图的应用 二、布隆过滤器1. 引入2. 概念3. 逻辑结构4. 特点5. 代码实现6. 布隆过滤器的应用 三、哈希切割 一、位图 1. 引入 当面对海量数据需要处理时&#xff0c;内存不足以加载这些数据&#xf…

C语言二叉树与堆的实现(一)

目录 二叉树 二叉树的分类&#xff08;目前只谈两种&#xff09; 满二叉树 完全二叉树 二叉树的性质&#xff08;其余的可以自己总结&#xff09; 选择练习 二叉树的存储结构 顺序存储方式 链式存储方式 一种完全二叉树&#xff1a;堆 堆的概念 堆的性质 建堆的时…

Windows本地搭建Emby媒体库服务器并实现远程访问「内网穿透」

文章目录 1.前言2. Emby网站搭建2.1. Emby下载和安装2.2 Emby网页测试 3. 本地网页发布3.1 注册并安装cpolar内网穿透3.2 Cpolar云端设置3.3 Cpolar内网穿透本地设置 4.公网访问测试5.结语 1.前言 在现代五花八门的网络应用场景中&#xff0c;观看视频绝对是主力应用场景之一&…

OpenCvSharp从入门到实践-(06)创建图像

目录 1、创建图像 1.1实例1-创建黑色图像 1.2实例2-创建白色图像 1.3实例3-创建随机像素的雪花点图像 2、图像拼接 2.1水平拼接图像 2.2垂直拼接图像 2.3实例4-垂直和水平两种方式拼接两张图像 在OpenCV中&#xff0c;黑白图像其实就是一个二维数组&#xff0c;彩色图像…

GCN01——Ubuntu中设置vivado编辑器为vscode

确定vscode位置 在命令行中输入 which code得到文件地址 进入文件夹后可看到&#xff0c;这是个链接文件&#xff0c;不过无所谓&#xff0c;就用这个地址就行 设置Text Editor 打开setting选择右侧text editor 这里说明了如何进行设置 将自己的地址加进去就行 /usr/share…

Springboot快速整合kafka

kafka的基本了解 kafka也是 目前常用的消息中间件,支持同步与异步通信,和rabbitmq一样,工作模式大概相同,并且被spingboot整合的后的都是 中间件Template的实列化客户端类 ,消费者监听注解为KafkaListener,和RabbitListener和很相似,这些消息中间件使用过后,发现大致都是相同的…