开源|快速入门和理解并模拟实现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户外机器人的定位与导航
户外机器人的定位导航相对于需要建图的场景来说,是比较简单容易实现的,因为可以借助第三方地图完成定位,并在第三方地图中完成路径规划和下发航点等操作,实现的难题在于如何控制机器人完成步行和转弯。 这些在不引进RTK高精度定位…...

Java多线程系列--synchronized的原理
原文网址: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开发板(针对ARM-32bit的有另一篇文…...

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

最强分布式锁工具:Redisson
1 Redisson概述1.1 什么是Redisson?Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid)。它不仅提供了一系列的分布式的Java常用对象,还提供了许多分布式服务。其中包括(BitSet, Set, Multimap, Sorted…...
Java9-17新特性
Java9-17新特性 一、接口的私有方法 Java8版本接口增加了两类成员: 公共的默认方法公共的静态方法 Java9版本接口又新增了一类成员: 私有的方法 为什么JDK1.9要允许接口定义私有方法呢?因为我们说接口是规范,规范时需要公开…...

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

使用langchain打造自己的大型语言模型(LLMs)
我们知道Openai的聊天机器人可以回答用户提出的绝大多数问题,它几乎无所不知,无所不能,但是由于有机器人所学习到的是截止到2021年9月以前的知识,所以当用户询问机器人关于2021年9月以后发送的事情时,它无法给出正确的答案&#x…...
assert()宏函数
assert()宏函数 assert是宏,而不是函数。在C的assert.h文件中 #include <assert.h> void assert( int expression );assert的作用是先计算表达式expression, 如果其值为假(即为0),那么它会打印出来assert的内容…...

Docker圣经:大白话说Docker底层原理,6W字实现Docker自由
说在前面: 现在拿到offer超级难,甚至连面试电话,一个都搞不到。 尼恩的技术社群(50)中,很多小伙伴凭借 “左手云原生右手大数据”的绝活,拿到了offer,并且是非常优质的offer&#…...

Redis+Caffeine多级(二级)缓存,让访问速度纵享丝滑
目录多级缓存的引入多级缓存的优势CaffeineRedis实现多级缓存V1.0版本V2.0版本V3.0版本多级缓存的引入 在高性能的服务架构设计中,缓存是一个不可或缺的环节。在实际的项目中,我们通常会将一些热点数据存储到Redis或MemCache这类缓存中间件中࿰…...

C#和.net框架之第一弹
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录C# 简介一、微软平台的编程二、使用VS创建第一个c#程序1、第一步2、第二步3、第三步4、第四步5、第五步C# 简介 C# 是一个现代的、通用的、面向对象的编程语言&…...
C++---背包模型---潜水员(每日一道算法2023.3.12)
注意事项: 本题是"动态规划—01背包"和"背包模型—二维费用的背包问题"的扩展题,优化思路不多赘述,dp思路会稍有不同,下面详细讲解。 题目: 潜水员为了潜水要使用特殊的装备。 他有一个带2种气体…...
C++类的成员变量和成员函数详解
类可以看做是一种数据类型,它类似于普通的数据类型,但是又有别于普通的数据类型。类这种数据类型是一个包含成员变量和成员函数的集合。 类的成员变量和普通变量一样,也有数据类型和名称,占用固定长度的内存。但是,在定义类的时候不能对成员变量赋值,因为类只是一种数据类…...
(枚举)(模拟)(位运算)116. 飞行员兄弟
目录 题目链接 一些话 切入点 流程 套路 ac代码 题目链接 116. 飞行员兄弟 - AcWing题库 我草,又~在~水~字~数~啦!我草,又~在~水~字~数~啦…...

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

Tina_Linux_Wi-Fi_开发指南
Tina Linux Wi-Fi 开发指南 1 前言 1.1 文档简介 介绍Allwinner 平台上Wi-Fi 驱动移植,介绍Tina Wi-Fi 管理框架,包括Station,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是布尔值,所以这里可以直接写 v-if"flag" 当flag为true的时候,v-if与v-show控制的div都会被显示出来 当flag为false的时候&a…...

2023年全网最全最细最流行的自动化测试工具有哪些?你都知道吗!
下面就是我个人整理的一些比较常用的自动化测试工具,并且还有视频版本的详细介绍,同时在线学习人数超过1000人! B站讲的最详细的Python接口自动化测试实战教程全集(实战最新版)一:前言 随着测试工程师技能和…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
MVC 数据库
MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...
Linux云原生安全:零信任架构与机密计算
Linux云原生安全:零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言:云原生安全的范式革命 随着云原生技术的普及,安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测,到2025年,零信任架构将成为超…...

IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...

用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...
基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解
JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用,结合SQLite数据库实现联系人管理功能,并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能,同时可以最小化到系统…...

嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...