SLAM从入门到精通(基础数学)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】

        不可否认,slam中的有一部分内容来自于数学。但是,我们在学习使用的过程中,也不用纠结于整个数学的推导过程,能正确使用数学结论也是可以的。有能力的同学,按照书本提示的方法,自己推导一下,也无可厚非。实在觉得麻烦,可以暂时先放下,或者用的比较熟练了,再来查看相关的推导原理也可以。和那些复杂的高维矩阵运算、优化算法相比,有一些基本的数学和规则,可能大家在日常处理中遇到的机会更大,这里不妨总结一下。

1、浮点数

        过去我们自己编写web前后端、或者写os、db的时候,遇到浮点数的机会并不多。即使遇到,也是简单的加减法。但是slam学习中,大量的操作都是浮点数。既然是浮点数,那么就离不开比较、除法、滤波、平方根这些计算。

1.1 数值比较

        既然做浮点运算,那么数值比较肯定是少不了的。这个时候,大家一定要理解,浮点数之间是没有绝对相等的。要比较他们是否相等,只要判断是不是在一个范围内即可,

if(fabs(f1 - f2) < 1e-6)
{std::cout << "equal" << std::endl;
}
else
{std::cout << "not equal" << std::endl;
}

1.2 除法运算

        用浮点做除法运算,本身是一件很危险的事情。因为f1/f2的时候,如果f2很小,那么f1/f2就会是非常大的一个数值。这样的话,这个结果本身其实是没有任何意义的。所以,即使要做除法运算,一定、一定要约束一下f2的数值范围。

1.3 数值滤波

        SLAM中用到的数据大部分都是从传感器采集过来的。既然是采集的物理数据,就会不可避免地引入噪声。所以这个时候,就要对浮点数进行降噪处理,常用的方法一般有,

1)取平均值;

2)去掉最大值、最小值,取平均值;

3)v_new = v_old * 0.95 + v_capture * (1 - 0.95);

4)连续满足某个条件之后,才开始采样等等。

1.4 平方根

        SLAM中的欧氏距离真的很好用。有的时候,最简单的方法往往就是最鲁棒的方法。所以distance = sqrt (pow(x, 2) + pow(y, 2))这样的计算方法一定要多看多用。

2、角度的计算

        在一个平面上面,假设有一个x轴和一个y轴,那么任何的坐标p都会被拆解为(x0,y0)。其中它和x轴的角度称之为theta,那么就会有了下面一些列的计算,

2.1 点p到原点的距离

r = sqrt (pow(x, 2) + pow(y, 2))

2.2 对应的角度theta该如何计算

theta = atan(y0 / x0)

2.3 角度和弧度的对应关系

rad = (angle * 2 * pi) / 360

2.4 sin、cos、tan

        由于时间的关系,大家对于sin、cos、tan的周期性可能没有那么熟悉了,这里为了方便大家回忆。我们分别贴上sin&cos的周期图、tan的周期图。首先是sin&cos的周期图,

        其次是tan的周期图,

        仔细观察下,sin的周期是2*pi,其中(-pi,0)为负,(0,pi)为正。cos的周期也是2*pi,其中(-pi/2,pi/2)为正,(-pi,-pi/2)&(pi/2,pi)为负。tan的周期是pi,其中(-pi/2,0)为负,(0,pi/2)为正。

2.5 一个有意思的旋转

        之前我们谈到,假设有一个点,他处在(x0,y0),这个时候,如果逆时针旋转alpha角度,新的坐标是多少。要注意,这里面其实是有一个不变的量,那就是距离distance,也可以记着为r。按照道理,新的坐标应该是,

x1 = r * cos(theta + alpha)
y1 = r * sin(theta + alpha)

        如果仅仅是这样,那么数值并不太容易求出来,所以这里需要进一步分解一下,

x1 = r * cos(alpha + theta)= r * (cos(alpha) * cos(theta) - sin(alpha) * sin(theta))= x * cos(alpha) - y * sin(alpha)y1 = r * sin(alpha + theta)= r * (sin(alpha) * cos(theta) + cos(alpha) * sin(theta))= x * sin(alpha) + y * cos(alpha)

        如果换成矩阵,其实写起来就很容易了,

[x_new, y_new] = [cos(alpha), -sin(alpha); sin(alpha), cos(alpha)] * [x, y]

3、矩阵的计算

        大学数学里面除了高等代数,也就是微分和积分之外,最重要的两门数学课就是线性代数和概率。而线性代数中最重要的计算就是矩阵。例2中提到的旋转,大家就可以转变成矩阵乘法的形式来进行处理,就是这样的,

pos_new = matrix * pos_old;

        有些同学也许忘记了矩阵的相关内容,没关系。其实大家只要会使用eigen这个库就好了。这个库是一个模板库,本身没有.a或者.so文件,直接使用即可。

sudo apt-get install libeigen3-dev

4、概率的计算

        概率这部分,大部分都是浮点的相关计算。中间以统计、加减法为主,本身困难不大。需要注意的地方就两个,一个是随机数的生成;一个就是高斯分布的生成。两个都很重要。

        如果是随机数的生成,一般是先给一个种子,然后生成随机数,

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, char *argv[])
{int i;srand((int) time(0));for(i=0;i< 10;i++){printf(" %d ", rand());}printf("n");return 0;
}

        另外一个就是高斯分布的生成,两个参数,一个是平均值,一个是方差,

#include <random>
#include <chrono>
#include <iostream>int main(int argc, char* argv[]) 
{unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();std::default_random_engine generator(seed);std::normal_distribution<double> distribution(0.0, 1.0);for (int i = 0; i < 10; ++i){std::cout << distribution(generator) << std::endl;}return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

36、springboot --- 对 tomcat服务器 和 undertow服务器 配置访客日志

springboot 配置访客日志 ★ 配置访客日志&#xff1a; 访客日志&#xff1a; Web服务器可以将所有访问用户的记录都以日志的形式记录下来&#xff0c;主要就是记录来自哪个IP的用户、在哪个时间点、访问了哪个资源。 Web服务器可将所有访问记录以日志形式记录下来&#xff…

nuxt3+ts+vue3的ssr项目总结

目录 一、什么是SSR、SEO、SPA&#xff0c;它们之间的关系又是怎样的。 二、VUE做SSR的几种方法 1、插件prerender-spa-plugin 2、VUE开启SSR渲染模式 3、使用NUXT框架 三、NUXT3VUE3TS &#xff08;一&#xff09;基本配置 1、文件夹介绍 assets components pages…

QT 界面相关操作

1> 创建自定义类时需要指定父类 2> 第一个界面的相关操作 #include "widget.h" #include<iostream> //printf #include<QDebug> //qDebuf #include<QIcon> //图标的头文件 using namespace std; //coutWidget::Widget(QWidget *…

1.RTKLIB环境配置和调试

1.源码下载 下载链接&#xff1a;rtklib 注&#xff1a;2.4.2 p13为稳定版本&#xff08;标识p代表稳定版本&#xff09;&#xff0c;2.4.3 b34为最新实验版本&#xff08;标识b&#xff09;。点击2.4.3 b34 的Source Programs and Data 链接下载源码。 2.环境配置 **集成…

尚硅谷SpringMVC

五、域对象共享数据 1、使用ServletAPI向request域对象共享数据 首页&#xff1a; Controller public class TestController {RequestMapping("/")public String index(){return "index";} } <!DOCTYPE html> <html lang"en" xmln…

【ACM出版】第四届人工智能与计算工程国际学术会议(ICAICE 2023)

ACM出版|第四届人工智能与计算工程国际学术会议 The 4th International Conference on Artificial Intelligence and Computer Engineering 为了在人工智能技术应用与计算工程领域进一步的探索&#xff0c;与国内外学界和业界相关人员交流新问题、新发现、新成果、新应用&…

eureka迁移到nacos--双服务中心注册

服务注册中心的迁移有多种方式&#xff0c;官网使用nacos sync&#xff0c;还有民间开发的双注册中心组件eureka-nacos-proxy&#xff0c;但是我用了不太顺利&#xff0c;所以用的是阿里巴巴的双注册中心组件edas-sc-migration-starter spring boot&#xff1a;2.5.3 引入依赖 …

Springboot集成Docker并将镜像推送linux服务器

案例使用springboot项目&#xff0c;在IDEA 中集成Docker生成镜像&#xff0c;并将镜像发布到linux服务器 具体步骤如下&#xff1a; 1、Centos7安装Docker 更新系统的软件包列表 sudo yum update安装Docker所需的软件包和依赖项&#xff1a; sudo yum install docker完成…

华为OD机试 - 数字序列比大小 - 贪心算法(Java 2023 B卷 100分)

目录 一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 一、题目描述 A&#xff0c;B两个人万一个数字比大小的游戏&#xff0c;在游戏前&#xff0c;两个人会拿…

Linux 内核动态打印调试(dev_info、 dev_dbg )

目录 前言 1 printk消息级别 2 调整内核printk打印级别 3 dev_xxx函数简介 4 配置内核使用动态打印 5 动态调试使用方法 6 动态打印调试的基本原理 &#x1f388;个人主页&#x1f388;&#xff1a;linux_嵌入式大师之路的博客-CSDN博客&#x1f389;&#x1f389;&…

xss-labs靶场通关详解

文章目录 前言level1level2level3level4level5level6level7level8level9level10level11level12level13level14level15level16level17level18level19&level20 前言 赶着假期结尾的时候&#xff0c;赶紧给自己找点任务做。现在对xss还是一知半解&#xff0c;只是了解个大概&a…

Java seven 解读正则表达式、java方法的使用

目录 Java 正则表达式1. java.util.regex 包2. 捕获组3. 正则表达式语法4. Matcher 类的方法 Java 方法1. 定义&#xff1a;2. 优点3. 命名规则4. 方法调用5. 方法的重载6. 构造方法7. 可变参数8. finalize() 方法 Java 正则表达式 1. java.util.regex 包 Pattern 类&#xff…

自用Eclipse配置记录

喜欢用eclipse写代码&#xff0c;由于现在的eclipse配置导出的功能缺失较多。这里开一帖把本人常用的配置记录一番&#xff0c;省得再到处找。 另&#xff1a;工作空间中有个.metadata 目录保存了相关的插件及配置&#xff0c;可以复制到其他空工作间中复用配置。 设置工作空间…

Unity碰撞检测

Unity碰撞检测 前言准备材料代码使用OnCollisionEnter()进行碰撞Collider状态代码 使用OnTriggerEnter()进行碰撞Collider状态代码 区别代码OnCollisionEnter()OnTriggerEnter() 碰撞显示效果OnCollisionEnter()OnTriggerEnter() 提示结语 前言 碰撞检测可以说时学习Unity中最…

ChatGPT⼊门到精通(5):ChatGPT 和Claude区别

⼀、Claude介绍 Claude是Anthropic开发的⼀款⼈⼯智能助⼿。 官⽅⽹站&#xff1a; ⼆、Claude能做什么 它可以通过⾃然语⾔与您进⾏交互,理解您的问题并作出回复。Claude的主要功能包括: 1、问答功能 Claude可以解答⼴泛的常识问题与知识问题。⽆论是历史上的某个事件,理科…

k8s之存储篇---数据卷Volume

数据卷概述 Kubernetes Volume&#xff08;数据卷&#xff09;主要解决了如下两方面问题&#xff1a; 数据持久性&#xff1a;通常情况下&#xff0c;容器运行起来之后&#xff0c;写入到其文件系统的文件暂时性的。当容器崩溃后&#xff0c;kubelet 将会重启该容器&#xff…

Javaweb入门

Spring Spring发展到今天已经形成一种开发生态圈&#xff0c;Spring提供若干个子项目&#xff0c;每个项目用于完成特定的功能。 Spring Boot可以帮助我们非常快速的构建应用程序、简化开发、提高效率 SpringBootWeb入门 需求&#xff1a;使用Spring Boot开发一个web应用&a…

软件测试面试怎样介绍自己的测试项目?会问到什么程度?

想知道面试时该怎样介绍测试项目&#xff1f;会问到什么程度&#xff1f;那就需要换位思考&#xff0c;思考HR在这个环节想知道什么。 HR在该环节普遍想获得的情报主要是下面这2个方面&#xff1a; 1&#xff09;应聘者的具体经验和技术能力&#xff0c; 2&#xff09;应聘者的…

Vector 动态数组(迭代器)

C数据结构与算法 目录 本文前驱课程 1 C自学精简教程 目录(必读) 2 Vector<T> 动态数组&#xff08;模板语法&#xff09; 本文目标 1 熟悉迭代器设计模式&#xff1b; 2 实现数组的迭代器&#xff1b; 3 基于迭代器的容器遍历&#xff1b; 迭代器语法介绍 对迭…

新版HBuilderX在uni_modules创建搜索search组件

1、创建自定义组件 my-search 新版HBuilder没有了 component 文件夹&#xff0c;但是有 uni_modules 文件夹&#xff0c;用来创建组件&#xff1a; 右键 uni_modules 文件夹&#xff0c;点击 新建uni_modules创建在弹出框&#xff0c;填写组件名字&#xff0c;例如&#xff1a…