赞
踩
**
**
SLAM是Simultaneous Localization and Mapping的缩写,即同时定位与地图构建。
它是一种用于自主导航和机器人感知的技术,旨在通过在未知环境中同时进行自主定位和构建环境地图,实现机器人的导航与路径规划。
它涉及到很多复杂的算法和方法,包括特征提取与匹配、传感器融合、滤波器(如扩展卡尔曼滤波器和粒子滤波器)和优化算法等。
SLAM技术主要应用于无人驾驶汽车、无人机、机器人和增强现实等领域。在实时定位和地图构建的过程中,SLAM系统会使用各种传感器(如摄像头、激光雷达、惯性测量单元等)获取环境信息,并利用这些信息进行自主定位和地图构建。
自主定位是指机器人在未知环境中确定自身位置的过程,通过对传感器数据进行处理和分析,结合地图信息,估计机器人相对于环境的位置和姿态。
地图构建则是将机器人在移动过程中获取的传感器数据融合起来,生成环境的地图表示,包括地标、障碍物和空间结构等信息。
(1)基于传感器类型分类
✔视觉SLAM:主要使用相机或摄像头获取图像信息进行定位和地图构建。
✔激光SLAM:使用激光雷达来感知环境并生成地图,激光测距可以提供精确的距离信息。
(2)基于地图的分类
✔基于拓扑图的SLAM:将环境表示为节点和边的拓扑结构,用于描述不同位置之间的关系。
✔基于网格地图的SLAM:使用二维或三维网格表示环境,将地图分割为离散的网格单元,每个单元表示不同的属性或占据状态。
✔基于稠密地图的SLAM:生成具有高密度信息的地图,通常使用点云或三维模型表示环境。
(3)基于算法的分类
✔滤波器方法:使用滤波器(如扩展卡尔曼滤波器或粒子滤波器)进行状态估计和数据融合。
✔优化方法:通过最小化误差函数或优化目标函数,使用图优化算法(如非线性最小二乘法)进行定位和地图优化。
✔学习方法:利用机器学习或深度学习技术,通过训练数据进行定位和地图构建。
激光SLAM,有哪些应用场景?
(1)自主导航和移动机器人:激光SLAM可用于移动机器人的自主导航和路径规划。
(2)无人驾驶和自动驾驶汽车:激光SLAM是无人驾驶和自动驾驶汽车中关键的感知技术之一。激光雷达能够提供车辆周围环境的精确地图和距离信息,用于定位车辆和障碍物检测。通过将激光SLAM与其他传感器(如相机、雷达和GPS)进行融合,实现全面的环境感知和高级驾驶决策。
(3)建筑和室内地图构建:激光雷达可以快速而准确地扫描建筑物的结构,捕捉墙壁、家具和其他物体的几何信息。
(4)无人机和航空领域:激光雷达可以提供无人机周围环境的高精度地图和距离信息,支持无人机的自主飞行、目标检测和障碍物避让。
(5)工业自动化和机器视觉:例如,用于机器人在工厂环境中的定位、零件装配和物体识别。激光雷达提供的精确距离信息可以用于精确的位置控制和目标检测。
大学本科阶段的基础数学知识,如微积分、线性代数、概率论。
大学研究生阶段的数学知识:最优化、矩阵论,一小部分李群与李代数知识。
计算机科学知识:单片机开发、嵌入式、Linux系统操作、C++语言。
easy_mqOS 是笔者仿照ROS 搭建的基于MQTT的简易机器人分布式开发框架,是一种轻量级并且十分容易上手的框架,支持多个节点的主题的订阅和单topic发布,节点之间独立、解耦合。没有复杂的文件配置,一定的make编程基础,像正常启动服务一样,就可以运行。甚至可以在嵌入式linux上使用,而不用安装Ubuntu没有复杂的插件,很容易上手和学习。支持c.c++ ,python,js.MQTT协议特点
使用发布/订阅消息模式,提供一对多的消息分发,解除应用程序耦合。
消息传输对有效载荷内容不可知。
使用TCP/IP提供基础网络连接。
有3个消息发布服务质量级别。
轻量传输,协议交换最小化,以降低网络网络流量。
提供一种机制,当客户端异常中断时,利用 Last Will 和 Testament 特性来通知有关各方。
对于不需要搭建太复杂的机器人,笔者认为easy_mqos就可以满足自主建图和避障导航的功能。
首先它是一个机器人开发的分布框架。
解决繁杂的上外网更新问题。
解决非Ubuntu不能用的问题。
避免繁杂配置出错问题。
避免非ROS无机器人的境地。
通过下面案例的应用,已经证明该框架用于机器人学习是没有问题的。
优点:
SLAM建图和导航避障在不依赖ROS的情况下可以实现;
不需要复杂的配置;
不需要复杂的编译链;
不需要远程配置master;
没有复杂的TF坐标转换概念;
可以将精力放到深入研究算法中;
可以自己修改算法;
可以转成ros 节点;
可适用于Linux系统例如raspbian\ubuntu\centos\armbian\嵌入式Linux。单片机?
缺点:
仅适合学习机器人相关的知识,不能复杂的深入学习3D坐标系统;
不支持机械臂;
没有rqt 数据流等。
驱动程序:单片机STM32
核心算法:树莓派/Orangepi/旭日派/nanoPi 等Linux系统
编码示例:
C++
int main (int argc, char ** argv) { //创建实例 easymqos *e_demo = new easymqos(CLIENT_PUB); //发布话题的设置 e_demo->Init_Pub("/sensors/filter"); //设置代理服务器 e_demo->Set_broker("127.0.0.1"); e_demo->Set_config_Pub(); //可订阅多个主题 vector<string> topicStr_subscribe; topicStr_subscribe.push_back("/sensors/demo");//支持多个话题的订阅 topicStr_subscribe.push_back("/sensors/test"); e_demo->Init_Sub(topicStr_subscribe); //可创建和启动多个线程 pthread_attr_t attr; pthread_t pthread_id = 0 ; struct sched_param param; /*create task mqtt com queue */ pthread_attr_init (&attr); pthread_attr_setschedpolicy (&attr, SCHED_RR); param.sched_priority = 5; pthread_attr_setschedparam (&attr, ¶m); pthread_create (&pthread_id, &attr, &Mqtt_PublishTask, NULL);//可以启动线程做更多事情 pthread_attr_destroy (&attr); /*create task mqtt client queue */ //启动订阅话题和回调函数 e_demo->Start_Sub(call_back);//启动订阅和回调处理函数 }
python示例
import adafruit_bno08x from adafruit_bno08x_rvc import BNO08x_RVC import serial import time import numpy as np import argparse import os import math import time import sys import datetime from paho.mqtt import client as mqtt_client import random import threading import json #添加串口 uart = serial.Serial("/dev/ttyS5", 115200) #MQTT相关 broker = '127.0.0.1' port = 1883 #添加订阅的主题 topic1 = "/sensors/topic1" #添加发布的主题 cmd_topic = "/cmd/vel" client_id = 'python-mqtt-{}'.format(random.randint(0, 1000)) #定义mqtt的client client = mqtt_client.Client(client_id) def getcmd(roll,pitch,yaw,ax,ay,az): data = {"roll":"%2.2f"%(roll),"pitch":"%2.2f"%(pitch),"yaw":"%2.2f"%(yaw),"ax":"%f" %(ax),"ay":"%f" %(ay),"az":"%f" %(az) } return data #如果有需要可创建启动线程 def thread1(): time.sleep(0.1) while True: #add your code here cmd =getcmd(roll,pitch,yaw,x_accel,y_accel,z_accel) json_data = json.dumps(cmd) #发送数据到topic result = client.publish(topic,json_data,0) # result: [0, 1] status = result[0] if status == 0: print(f"Send to topic `{topic}`") else: print(f"Failed to send message to topic {topic}") th1 = threading.Thread(target = thread1) th1.setDaemon(True) th1.start() def on_connect(client, userdata, flags, rc): print("Connected with result code "+str(rc)) #用于处理接收的多个主题 def on_message(client, userdata, msg): global _switch #print(msg.topic+" "+msg.payload.decode("utf-8")) _switch = ord(msg.payload.decode("utf-8"))-48 #add your code here #any thing print("%d"%_switch) #根据需要设计可有可无 def publish(client): global last_time global detect_ok global resultImg msg_count = 0 while True: #add your code here time.sleep(0.001) if __name__ == '__main__': print(" connected!") client.on_connect = on_connect client.on_message = on_message client.connect(broker, port, 60) #publish(client) # 订阅主题 client.subscribe(topic1) client.subscribe(topic2) client.subscribe(topicn) client.loop_forever()
js编码
var hostname = '192.168.1.2', //'', devid =111111, port = 8083, clientId = 'client-mao2180', timeout = 5, keepAlive = 50, cleanSession = false, ssl = false, topic1 = '/state/gps'; var urlPath = window.document.location.href; var docPath = window.document.location.pathname; //文件在服务器相对地址 /ISV/demo.aspx var index = urlPath.indexOf(docPath); var serverPath = urlPath.substring(0, index); var serverip = serverPath.substring(7); console.log(serverip); //启动链接 MQTTconnect(); function MQTTconnect(){ topic = '/s/vel'; console.log(topic); client = new Paho.MQTT.Client(serverip, Number(port), clientId); client.onConnectionLost = onConnectionLost;//注册连接断开处理事件 client.onMessageArrived = onMessageArrived;//注册消息接收处理事件 client.connect({onSuccess:onConnect});//连接服务器并注册连接成功处理事件 }; function onConnect() { // Once a connection has been made, make a subscription and send a message. console.log("onConnect:"+topic); //订阅的主题列表 client.subscribe(topic1); client.subscribe(topic2); client.subscribe(topicn); }; function onConnectionLost(responseObject) { if (responseObject.errorCode !== 0) console.log("onConnectionLost:"+responseObject.errorMessage); console.log("连接已断开"); }; function onMessageArrived(message) { //console.log("收到消息:"+message.payloadString); //console.log("主题:"+message.destinationName); //console.log("长度:"+strlen(message.payloadString)); //add your code here }; //发送信息到指定主题 function send_x_y(velocity,angle){ console.log("into send message"); //add your code here // s = "{time:"+new Date().Format("yyyy-MM-dd hh:mm:ss")+", content:"+(s)+", from: web console}"; message = new Paho.MQTT.Message("test in robot"); message.destinationName = sendtopic; client.send(message); }
启动程序
/easymqOs_navigation$ ./navigation
/easymqos_basecomm$ ./basecomm_node
/easymqos_imu$ python3 read_bno.py
想入门学习机器人规划和导航的同学。
快速入门SLAM建图的同学。
学习自主导航的同学。
学习局部规划的同学。
学习避障算法的同学。
想快速测试效果的同学。
关注神经网络和机器人应用的同学。
机器人爱好者。
GITHUB目前开放的节点:
SLAM 建图效果
EasyMQOS简易机器人开发框架教程
www.zhihu.com/column/c_1609592563807002624
室内SLAM建图与导航机器人
实验环境:室内。
建图条件:需要事先SLAM建图。
避障传感器:A1激光雷达。
测速:霍尔编码器。
驱动方式:双轮差速驱动。
IMU:9轴
主控:OPI2\旭日X3
驱动板:stm32
建图精度:±5cm
定位精度;±10cm 以内
框架:easymqos
github:https://github.com/horo2016/easyMQOS
避障局部规划:魔改DWA+自定义
全局规划:a* ,需要继续优化,但不影响使用了
页面交互
页面交互设计使用HTML+JS实现通信、控制。画布用的canvas直接将接收到的地图数据画出来,同时还支持
轨迹;
雷达帧;
规划的路径;
机器人显示;
充电站显示;
A点显示;
B点显示;
设置目标点;
路径规划操作;
导航到达;
直达操作;
充电;
去指定的点操作。
SLAM建图介绍
文章:
轮式机器人爱好者剥离ROS,搭建非主流机器人分布式开发框架,实现slam建图和简单自主导航
视频:
轮式机器人爱好者剥离ROS,搭建非主流机器人分布式开发框架,实现slam建图和简单自主导航测试
b.导航篇介绍
文章:
演示视频
进阶,在轮式机器人上实现自主导航和避障(无ROS)
介绍:
轮式机器人爱好者剥离ROS,搭建非主流机器人分布式开发框架,实现slam建图和简单自主导航测试
机器人框架:easyMQos 基于MQTT
建图:2d栅格 粒子滤波
显示:web 页面 导航:无障碍 路径跟随
全局规划算法:A* 、梯度规划
局部避障导航:dwa+puresuit
公众号:视觉动力机器人
建图精度:±5cm
定位精度;±10cm 以内
GPS定位与导航机器人
欢迎大家尝试使用。
参考推荐:《轮式自主移动机器人编程实战》
公众号首发【视觉动力机器人】
B:机器人指哪去那
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。