当前位置: 首页 > news >正文

开源|快速入门和理解并模拟实现GPS户外机器人的定位与导航

户外机器人的定位导航相对于需要建图的场景来说,是比较简单容易实现的,因为可以借助第三方地图完成定位,并在第三方地图中完成路径规划和下发航点等操作,实现的难题在于如何控制机器人完成步行和转弯。

这些在不引进RTK高精度定位的前提下而言。由于存在干扰,以及传感器的精度可能不高,实际操作中,并不一定能够按期待的动作实现定位和导航。

笔者简单的搭了一个模拟机器人的程序,意在实现地图上的定位和快速导航,这样能快速理解其中的逻辑和一些简单的算法。

先看一下效果:
https://mp.weixin.qq.com/s/c783rHvsMxiH9a6IDtMCNA

废话不多说直接上程序,主要的处理逻辑如下:
while(GLOBAL_SWITCH)
{
if(onceread ==0)
{
onceread =1;
if(is_file_exist(“waypoints.csv”)!=0)//判断航点的文件是否存在
{
GLOBAL_STATUS=STOP_STATUS;
GLOBAL_SWITCH =0 ;
onceread =0;
DEBUG(LOG_ERR,“waypoint file is not exist \n”);
break;
}
}
if((latitude ==0.0)&&(longitude == 0.0))//是否定位成功
{
DEBUG(LOG_ERR,“GPS CANNOT LOCATION PLEASE CHECK \n”);
GLOBAL_STATUS = STOP_STATUS;
GLOBAL_SWITCH = 0;
break;

    }if ((getmillis() - lastSubMillis > SUBSUMPTION_INTERVAL))//定时处理{switch(GLOBAL_STATUS){case STANDBY_STATUS://启动后的初始状态DEBUG(LOG_DEBUG,"STANDBY STATUS \n");lastGPSMillis =0 ;ReadWaypointsFile();//读取航点到队列CalculateHeadingToWaypoint();//计算当前角度和航点的方向CalculateDistanceToWaypoint();//计算当前和航点的距离GLOBAL_STATUS = ROTATE_STATUS ;break;case CACULATE_STATUS://计算状态DEBUG(LOG_DEBUG,"CACULATE STATUS \n");CalculateHeadingToWaypoint();CalculateDistanceToWaypoint();GLOBAL_STATUS = ROTATE_STATUS ;break;case ROTATE_STATUS ://旋转状态DEBUG(LOG_DEBUG,"ROTATE_STATUS   \n");if (abs((int)car_heading_simulation - (int)targetHeading) > 10){RotateDegrees(targetHeading);//这里需要根据求出的角度进行转动,需要旋转的角度位 当前航向角-两点之间的角度,需要做-180~180之间的归一化}else {GLOBAL_STATUS = MOVE_STATUS ;}break;case MOVE_STATUS ://前进状态  DEBUG(LOG_DEBUG,"MOVE_STATUS   \n");if((waypointRange > 200))//大于100m 认为不合法 所以规划路径时需要注意{  DEBUG(LOG_ERR,"distance > 200m \n");break;}  MoveDistance(waypointRange);break;    case WAYPOINTARRIVE_STATUS://读取下一个航点DEBUG(LOG_DEBUG,"WAYPOINTARRIVE_STATUS,currentWaypoint:%d,waypointCount:%d\n",currentWaypoint,waypointCount);if(currentWaypoint < waypointCount-1 ){currentWaypoint ++;DEBUG(LOG_DEBUG,"currentWaypoint ++\n");GLOBAL_STATUS = CACULATE_STATUS ;}else  if(currentWaypoint >= waypointCount-1 ){GLOBAL_STATUS = STOP_STATUS ;DEBUG(LOG_ERR,"currentWaypoint >= waypointCount stop status\n");}break;case STOP_STATUS :break;case MANUAL_STATUS :break;default :break;}//end switch// 必须先运行一次 standby 状态 只有当在目的地附近3米内才会转换状态ret =  isInRange(3, latitude , longitude, waypoints[currentWaypoint].latitude, waypoints[currentWaypoint].longitude);if (ret == 1) //点在圆圈内{   DEBUG(LOG_DEBUG,"arrive into circle scale ,will read next point  \n");GLOBAL_STATUS = WAYPOINTARRIVE_STATUS ;}waypointlongitude =  waypoints[currentWaypoint].longitude;waypointlatitude = waypoints[currentWaypoint].latitude;CalculateHeadingToWaypoint();//计算两点之间的角度int b_heading = abs((int)car_heading_simulation - (int)targetHeading);//获取当前航向和两点之间的差值DEBUG(LOG_DEBUG,"caculate b-heading:%d  ,ret=%d \n",b_heading,ret);if ((b_heading > 10 )&&(ret != 1)  ){GLOBAL_STATUS = ROTATE_STATUS ;}lastSubMillis = getmillis();}//end  sub loop}//end while switch on

}

关于实现整套系统,需要搭建一个web服务器,然后使用MQTT协议实现通信,嵌入式中使用BOA来实现简单的web并包含地图的代码。

模拟程序依赖libmosquitto. 需要安装

sudo apt-get install mosquitto-dev

sudo apt-get install mosquitto-client

sudo find / -name “libmosquitto*.so”

找到后,将libmosquitto.so 替换MQtt文件下lib的libmosquitto.so库。

模拟程序使用c开发,直接 make就可以使用。

BOA搭建些许麻烦,可以使用 www.woyilian.com 中的仿真界面实现。如下图:

图片

该工程的源码在这里下载:
请在链接末尾处下载。

相关文章:

开源|快速入门和理解并模拟实现GPS户外机器人的定位与导航

户外机器人的定位导航相对于需要建图的场景来说&#xff0c;是比较简单容易实现的&#xff0c;因为可以借助第三方地图完成定位&#xff0c;并在第三方地图中完成路径规划和下发航点等操作&#xff0c;实现的难题在于如何控制机器人完成步行和转弯。 这些在不引进RTK高精度定位…...

Java多线程系列--synchronized的原理

原文网址&#xff1a;Java多线程系列--synchronized的原理_IT利刃出鞘的博客-CSDN博客 简介 本文介绍Java的synchronized的原理。 反编译出字节码 Test.java public class Test {private static Object LOCK new Object();public static int main(String[] args) {synchro…...

QEMU启动ARM64 Linux内核

目录前言前置知识virt开发板ARM处理器家族简介安装qemu-system-aarch64安装交叉编译工具交叉编译ARM64 Linux内核交叉编译ARM64 Busybox使用busybox制作initramfs使用QEMU启动ARM64 Linux内核前言 本文介绍采用 qemu 模拟ARM-64bit开发板&#xff08;针对ARM-32bit的有另一篇文…...

Linux->进程程序替换

目录 前言&#xff1a; 1 程序替换原理 2 单进程替换 3 替换函数 3.1 函数使用 4 程序去替换自己的另一个程序操作方式 5 实现自己的shell 前言&#xff1a; 通过我们之前对于子进程的应用&#xff0c;我相信大家一定是能够想到创建子进程的目的之一就是为了代劳父进程执…...

最强分布式锁工具:Redisson

1 Redisson概述1.1 什么是Redisson&#xff1f;Redisson是一个在Redis的基础上实现的Java驻内存数据网格&#xff08;In-Memory Data Grid&#xff09;。它不仅提供了一系列的分布式的Java常用对象&#xff0c;还提供了许多分布式服务。其中包括(BitSet, Set, Multimap, Sorted…...

Java9-17新特性

Java9-17新特性 一、接口的私有方法 Java8版本接口增加了两类成员&#xff1a; 公共的默认方法公共的静态方法 Java9版本接口又新增了一类成员&#xff1a; 私有的方法 为什么JDK1.9要允许接口定义私有方法呢&#xff1f;因为我们说接口是规范&#xff0c;规范时需要公开…...

电脑开机找不到启动设备怎么办?

电脑正常开机&#xff0c;却提示“找不到启动设备”&#xff0c;这时我们该怎么办呢&#xff1f;本文就为大家介绍几种针对该问题的解决方法&#xff0c;一起来看看吧&#xff01;“找不到启动设备”是什么意思&#xff1f;可引导设备&#xff08;又称启动设备&#xff09;是一…...

使用langchain打造自己的大型语言模型(LLMs)

我们知道Openai的聊天机器人可以回答用户提出的绝大多数问题,它几乎无所不知&#xff0c;无所不能&#xff0c;但是由于有机器人所学习到的是截止到2021年9月以前的知识&#xff0c;所以当用户询问机器人关于2021年9月以后发送的事情时&#xff0c;它无法给出正确的答案&#x…...

assert()宏函数

assert()宏函数 assert是宏&#xff0c;而不是函数。在C的assert.h文件中 #include <assert.h> void assert( int expression );assert的作用是先计算表达式expression&#xff0c; 如果其值为假&#xff08;即为0&#xff09;&#xff0c;那么它会打印出来assert的内容…...

Docker圣经:大白话说Docker底层原理,6W字实现Docker自由

说在前面&#xff1a; 现在拿到offer超级难&#xff0c;甚至连面试电话&#xff0c;一个都搞不到。 尼恩的技术社群&#xff08;50&#xff09;中&#xff0c;很多小伙伴凭借 “左手云原生右手大数据”的绝活&#xff0c;拿到了offer&#xff0c;并且是非常优质的offer&#…...

Redis+Caffeine多级(二级)缓存,让访问速度纵享丝滑

目录多级缓存的引入多级缓存的优势CaffeineRedis实现多级缓存V1.0版本V2.0版本V3.0版本多级缓存的引入 在高性能的服务架构设计中&#xff0c;缓存是一个不可或缺的环节。在实际的项目中&#xff0c;我们通常会将一些热点数据存储到Redis或MemCache这类缓存中间件中&#xff0…...

C#和.net框架之第一弹

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录C# 简介一、微软平台的编程二、使用VS创建第一个c#程序1、第一步2、第二步3、第三步4、第四步5、第五步C# 简介 C# 是一个现代的、通用的、面向对象的编程语言&…...

C++---背包模型---潜水员(每日一道算法2023.3.12)

注意事项&#xff1a; 本题是"动态规划—01背包"和"背包模型—二维费用的背包问题"的扩展题&#xff0c;优化思路不多赘述&#xff0c;dp思路会稍有不同&#xff0c;下面详细讲解。 题目&#xff1a; 潜水员为了潜水要使用特殊的装备。 他有一个带2种气体…...

C++类的成员变量和成员函数详解

类可以看做是一种数据类型,它类似于普通的数据类型,但是又有别于普通的数据类型。类这种数据类型是一个包含成员变量和成员函数的集合。 类的成员变量和普通变量一样,也有数据类型和名称,占用固定长度的内存。但是,在定义类的时候不能对成员变量赋值,因为类只是一种数据类…...

(枚举)(模拟)(位运算)116. 飞行员兄弟

目录 题目链接 一些话 切入点 流程 套路 ac代码 题目链接 116. 飞行员兄弟 - AcWing题库 我草&#xff0c;又~在&#xff5e;水&#xff5e;字&#xff5e;数&#xff5e;啦&#xff01;我草&#xff0c;又~在&#xff5e;水&#xff5e;字&#xff5e;数&#xff5e;啦…...

详解Array.prototype.shift.call(arguments)

经常看到如下代码&#xff1a; function foo() {let k Array.prototype.shift.call(arguments);console.log(k) } foo(11,22) //11 Array.prototype.shift.call(arguments)的作用是&#xff1a; 取 arguments 中的第一个参数 一、为啥要这么写&#xff0c;不直接使用argume…...

Tina_Linux_Wi-Fi_开发指南

Tina Linux Wi-Fi 开发指南 1 前言 1.1 文档简介 介绍Allwinner 平台上Wi-Fi 驱动移植&#xff0c;介绍Tina Wi-Fi 管理框架&#xff0c;包括Station&#xff0c;Ap 以及Wi-Fi 常见问题。 1.2 目标读者 适用Tina 平台的广大客户和对Tina Wi-Fi 感兴趣的同事。 1.3 适用范…...

Spring AOP(AOP概念、组成、Spring AOP实现及实现原理)

文章目录1. Spring AOP 是什么2. 为什么要用 AOP3. 怎么学 Spring AOP4. AOP 组成5. Spring AOP 实现5.1 添加 Spring AOP 框架支持5.2 定义切面和切点5.3 实现通知方法5.4 使⽤ AOP 统计 UserController 每个⽅法的执⾏时间 StopWatch5.4 切点表达式说明 AspectJ6. Spring AOP…...

8.条件渲染指令

目录 1 v-if v-show 2 v-if v-else-if v-else 1 v-if v-show v-if与v-show都可以控制DOM的显示与隐藏 由于flag是布尔值&#xff0c;所以这里可以直接写 v-if"flag" 当flag为true的时候&#xff0c;v-if与v-show控制的div都会被显示出来 当flag为false的时候&a…...

2023年全网最全最细最流行的自动化测试工具有哪些?你都知道吗!

下面就是我个人整理的一些比较常用的自动化测试工具&#xff0c;并且还有视频版本的详细介绍&#xff0c;同时在线学习人数超过1000人&#xff01; B站讲的最详细的Python接口自动化测试实战教程全集&#xff08;实战最新版&#xff09;一&#xff1a;前言 随着测试工程师技能和…...

RocketMQ延迟消息机制

两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数&#xff0c;对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后&#xf…...

在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module

1、为什么要修改 CONNECT 报文&#xff1f; 多租户隔离&#xff1a;自动为接入设备追加租户前缀&#xff0c;后端按 ClientID 拆分队列。零代码鉴权&#xff1a;将入站用户名替换为 OAuth Access-Token&#xff0c;后端 Broker 统一校验。灰度发布&#xff1a;根据 IP/地理位写…...

基于当前项目通过npm包形式暴露公共组件

1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹&#xff0c;并新增内容 3.创建package文件夹...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

#Uniapp篇:chrome调试unapp适配

chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器&#xff1a;Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...

JVM虚拟机:内存结构、垃圾回收、性能优化

1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...

通过MicroSip配置自己的freeswitch服务器进行调试记录

之前用docker安装的freeswitch的&#xff0c;启动是正常的&#xff0c; 但用下面的Microsip连接不上 主要原因有可能一下几个 1、通过下面命令可以看 [rootlocalhost default]# docker exec -it freeswitch fs_cli -x "sofia status profile internal"Name …...

VisualXML全新升级 | 新增数据库编辑功能

VisualXML是一个功能强大的网络总线设计工具&#xff0c;专注于简化汽车电子系统中复杂的网络数据设计操作。它支持多种主流总线网络格式的数据编辑&#xff08;如DBC、LDF、ARXML、HEX等&#xff09;&#xff0c;并能够基于Excel表格的方式生成和转换多种数据库文件。由此&…...

如何配置一个sql server使得其它用户可以通过excel odbc获取数据

要让其他用户通过 Excel 使用 ODBC 连接到 SQL Server 获取数据&#xff0c;你需要完成以下配置步骤&#xff1a; ✅ 一、在 SQL Server 端配置&#xff08;服务器设置&#xff09; 1. 启用 TCP/IP 协议 打开 “SQL Server 配置管理器”。导航到&#xff1a;SQL Server 网络配…...

Unity VR/MR开发-VR开发与传统3D开发的差异

视频讲解链接&#xff1a;【XR马斯维】VR/MR开发与传统3D开发的差异【UnityVR/MR开发教程--入门】_哔哩哔哩_bilibili...