当前位置:   article > 正文

如何不使用ROS实现SLAM建图和自主导航_slam技术如何实现地图创建

slam技术如何实现地图创建

**

SLAM 技术是什么?

**
SLAM是Simultaneous Localization and Mapping的缩写,即同时定位与地图构建。
它是一种用于自主导航和机器人感知的技术,旨在通过在未知环境中同时进行自主定位和构建环境地图,实现机器人的导航与路径规划。

它涉及到很多复杂的算法和方法,包括特征提取与匹配、传感器融合、滤波器(如扩展卡尔曼滤波器和粒子滤波器)和优化算法等。

SLAM技术主要应用于无人驾驶汽车、无人机、机器人和增强现实等领域。在实时定位和地图构建的过程中,SLAM系统会使用各种传感器(如摄像头、激光雷达、惯性测量单元等)获取环境信息,并利用这些信息进行自主定位和地图构建。

自主定位是指机器人在未知环境中确定自身位置的过程,通过对传感器数据进行处理和分析,结合地图信息,估计机器人相对于环境的位置和姿态。

地图构建则是将机器人在移动过程中获取的传感器数据融合起来,生成环境的地图表示,包括地标、障碍物和空间结构等信息。

SLAM 技术可以分为哪几类?

(1)基于传感器类型分类

✔视觉SLAM:主要使用相机或摄像头获取图像信息进行定位和地图构建。

✔激光SLAM:使用激光雷达来感知环境并生成地图,激光测距可以提供精确的距离信息。

(2)基于地图的分类

✔基于拓扑图的SLAM:将环境表示为节点和边的拓扑结构,用于描述不同位置之间的关系。

✔基于网格地图的SLAM:使用二维或三维网格表示环境,将地图分割为离散的网格单元,每个单元表示不同的属性或占据状态。

✔基于稠密地图的SLAM:生成具有高密度信息的地图,通常使用点云或三维模型表示环境。

(3)基于算法的分类

✔滤波器方法:使用滤波器(如扩展卡尔曼滤波器或粒子滤波器)进行状态估计和数据融合。

✔优化方法:通过最小化误差函数或优化目标函数,使用图优化算法(如非线性最小二乘法)进行定位和地图优化。

✔学习方法:利用机器学习或深度学习技术,通过训练数据进行定位和地图构建。

激光SLAM,有哪些应用场景?
(1)自主导航和移动机器人:激光SLAM可用于移动机器人的自主导航和路径规划。

(2)无人驾驶和自动驾驶汽车:激光SLAM是无人驾驶和自动驾驶汽车中关键的感知技术之一。激光雷达能够提供车辆周围环境的精确地图和距离信息,用于定位车辆和障碍物检测。通过将激光SLAM与其他传感器(如相机、雷达和GPS)进行融合,实现全面的环境感知和高级驾驶决策。

(3)建筑和室内地图构建:激光雷达可以快速而准确地扫描建筑物的结构,捕捉墙壁、家具和其他物体的几何信息。

(4)无人机和航空领域:激光雷达可以提供无人机周围环境的高精度地图和距离信息,支持无人机的自主飞行、目标检测和障碍物避让。

(5)工业自动化和机器视觉:例如,用于机器人在工厂环境中的定位、零件装配和物体识别。激光雷达提供的精确距离信息可以用于精确的位置控制和目标检测。

学习激光SLAM技术需要具备的基础知识

大学本科阶段的基础数学知识,如微积分、线性代数、概率论。

大学研究生阶段的数学知识:最优化、矩阵论,一小部分李群与李代数知识。

计算机科学知识:单片机开发、嵌入式、Linux系统操作、C++语言。

EasymqOS 机器人分布式开发框架

easy_mqOS 是笔者仿照ROS 搭建的基于MQTT的简易机器人分布式开发框架,是一种轻量级并且十分容易上手的框架,支持多个节点的主题的订阅和单topic发布,节点之间独立、解耦合。没有复杂的文件配置,一定的make编程基础,像正常启动服务一样,就可以运行。甚至可以在嵌入式linux上使用,而不用安装Ubuntu没有复杂的插件,很容易上手和学习。支持c.c++ ,python,js.MQTT协议特点

使用发布/订阅消息模式,提供一对多的消息分发,解除应用程序耦合。

消息传输对有效载荷内容不可知。

使用TCP/IP提供基础网络连接。

有3个消息发布服务质量级别。

轻量传输,协议交换最小化,以降低网络网络流量。

提供一种机制,当客户端异常中断时,利用 Last Will 和 Testament 特性来通知有关各方。

对于不需要搭建太复杂的机器人,笔者认为easy_mqos就可以满足自主建图和避障导航的功能。

easyMqos诞生的目的:

首先它是一个机器人开发的分布框架。

解决繁杂的上外网更新问题。

解决非Ubuntu不能用的问题。

避免繁杂配置出错问题。

避免非ROS无机器人的境地。

通过下面案例的应用,已经证明该框架用于机器人学习是没有问题的。

easyMqos优缺点:

优点:
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, &param);
	pthread_create (&pthread_id, &attr, &Mqtt_PublishTask, NULL);//可以启动线程做更多事情
	pthread_attr_destroy (&attr);
	  /*create task mqtt  client queue */
	//启动订阅话题和回调函数
    e_demo->Start_Sub(call_back);//启动订阅和回调处理函数
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

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()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91

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);
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59

启动程序

/easymqOs_navigation$ ./navigation
/easymqos_basecomm$ ./basecomm_node
/easymqos_imu$ python3 read_bno.py
  • 1
  • 2
  • 3

适合的人群:

想入门学习机器人规划和导航的同学。

快速入门SLAM建图的同学。

学习自主导航的同学。

学习局部规划的同学。

学习避障算法的同学。

想快速测试效果的同学。

关注神经网络和机器人应用的同学。

机器人爱好者。

GITHUB目前开放的节点:

图片

在这里插入图片描述

SLAM 建图效果
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

EasyMQOS简易机器人开发框架教程

www.zhihu.com/column/c_1609592563807002624

实战案例 1

室内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)
在这里插入图片描述

介绍:

轮式机器人爱好者剥离ROS,搭建非主流机器人分布式开发框架,实现slam建图和简单自主导航测试

机器人框架:easyMQos 基于MQTT

建图:2d栅格 粒子滤波

显示:web 页面 导航:无障碍 路径跟随

全局规划算法:A* 、梯度规划

局部避障导航:dwa+puresuit

公众号:视觉动力机器人

建图精度:±5cm

定位精度;±10cm 以内

实战案例 2

GPS定位与导航机器人

欢迎大家尝试使用。

参考推荐:《轮式自主移动机器人编程实战》
公众号首发【视觉动力机器人】
B:机器人指哪去那

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/916526
推荐阅读
相关标签
  

闽ICP备14008679号