自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(40)
  • 收藏
  • 关注

转载 欧拉角和旋转矩阵相互转换

如果将每一个角度用旋转矩阵表示如下:所以,容易得到,欧拉角转旋转矩阵如下:

2020-01-09 15:29:46 1428 1

原创 相关性扫描匹配CSM与分支限界加速

前言在激光SLAM中,相关性扫描匹配可是重点中的重点,而分支限界加速更是大大提高了它的实时性。本文就来详细解读一下其中的奥秘。激光SLAM前端既然是SLAM,那么通常都会分为前端和后端。前端充当里程计的角色,比如我们熟知的VO(视觉里程计)和VIO(视觉惯性里程计)。激光SLAM也需要前端,对于每一帧点云,通常是使用所谓的扫描匹配(scan-match)方法进行位姿估计。简单地说,扫描匹配...

2019-12-12 16:31:52 4522 3

原创 ros tf 坐标系:base_link odom map base_laser理解

1 前言ros机器人系统里面,往往存在着多个坐标系系统,这些坐标系系统有着约定俗成的命名规范,便于机器人开发人员更好的理解代码,这里进行总结一下各个坐标系的含义。关键注意的是odom坐标系,最容易理解错2 各个坐标系base_link坐标系base_link是机器人本体坐标系,以底座中心为原点(一般为机器人的旋转中心)。跟随robot一起运动,robot身上的任何零件都是以该坐标系...

2019-12-11 17:16:32 3090 3

原创 ICP算法公式推导

一、引言ICP算法可以用于匹配两个点云,得到两个点云之间的位姿转换关系。本文主要介绍已知对应点的ICP匹配算法。二、ICP算法首先计算两个点云的质心:然后将原始点云减去对应的质心,得到去除质心的点云:计算新产生的两个点云形成的W矩阵,并SVD分解:那么,两个原始点云的转换关系R和t如下所示:三、推导过程对于两组点云:求解R和t,使得下式最小:上式进行变换:其中,...

2019-11-18 17:18:19 5269 3

转载 SLAM 算法工程师经验

https://www.cnblogs.com/xtl9/p/8053331.htmlhttps://zhuanlan.zhihu.com/p/285655631.编程基础《Effective C++》《C++ Primer》《Effective STL》c++112.数据结构与算法。入门推荐《数据结构(C++ 语言版)》刷题,leetcode和剑指offer。时间来不及推荐这...

2019-06-03 19:49:56 3622 1

原创 浮点数比较大小

float 类型不能比较相等或不等,但可以比较>,<,>=,<=用==从语法上说没错,但是本来应该相等的两个浮点数由于计算机内部表示的原因可能略有微小的误差,这时用==就会认为它们不等。应该使用两个浮点数之间的差异的绝对值小于某个可以接受的值来判断判断它们是否相等,比如用 if (fabs(price - p) < 0.000001)来代替 if...

2019-05-31 18:46:57 8702 1

原创 用数组名作函数参数

关于用数组名作函数参数有两点要说明:(1) 如果函数实参是数组名,形参也应为数组名(或指针变量),形参不能声明为普通变量(如int array;)。实参数组与形参数组类型应一致(现都为int型),如不一致,结果将出错。(2) 需要特别说明的是: 数组名代表数组首元素的地址,并不代表数组中的全部元素。因此用数组名作函数实参时,不是把实参数组的值传递给形参,而只是将实参数组首元素的地址传递给形参。...

2019-05-31 18:46:10 12867

原创 Linux 共享库命名规则

linux 里面共享库总是存在很多链接文件lrwxrwxrwx. 1 root root 24 Aug 19 2017 libavahi-client.so.3 -> libavahi-client.so.3.2.9-rwxr-xr-x. 1 root root 69968 Nov 5 2016 libavahi-client.so.3.2.9lrwxrwx...

2019-05-31 18:45:19 873

原创 静态库和共享库(动态链接库)的区别

1 静态库在共享库出现之前,公用功能是以静态库的形式存在的,它把通用功能模块的多个目标文件打包在一起,用到它的程序只需要在链接时指定这个库文件,链接器就会从这个库中抽取出用到的功能代码拷贝到目标程序中,而不需要每次都对这些通用功能代码重新编译。静态库体现出了很好的模块化思想,但是随着计算机产业规模的发展,静态库逐渐暴露出了自身两个比较严重的问题。一是磁盘和内存空间占用大。静态库虽然加快了编...

2019-05-31 18:44:41 4198

原创 进程内存布局

进程访问的地址是自己进程空间内的线性地址,内核负责把线性地址映射为实际的物理地址。操作系统以内存页为单位管理物理内存。在 Linux 中,默认的内存分页大小是 4KB,也就是说,操作系统把物理内存分割成一个个大小为 4KB 的格子,进而管理它们,内存的换入换出也以这样的格子为基本单位。在每个进程的内核数据结构中,都会维护一个内存页表,记录线性地址到物理内存页的映射关系。...

2019-05-31 18:43:54 138

原创 pthread线程库函数

所有线程都有一个线程号,也就是Thread ID。其类型为pthread_t。通过调用pthread_self()函数可以获得自身的线程号。1 创建线程创建线程的函数如下:int pthread_create(pthread_t *restrict thread, const pthread_attr_t *restrict attr, void *(*start_routine)(void...

2019-05-31 18:43:14 2538

原创 线程的连接和分离

新创建的线程和进程一样,也需要被连接以监听其退出状态,否则也会变成僵尸线程。背后原因与进程一样,其退出之后,内核会为它保留退出状态数据,直到有人取走为止。连接线程的库函数如下所示:int pthread_join(pthread_t thread, void **retval);进程连接与线程连接在以下几个方面存在一些区别:任何线程都可以监听一个指定线程的退出,而不需要是创建该线程的线程...

2019-05-31 18:41:44 1646

原创 线程同步与互斥锁

相比多进程模型,多线程模型最大的优势在于数据共享非常方便,同一进程内的多个线程可以使用相同的地址值访问同一块内存数据。但是,当多个线程对同一块内存数据执行“读−处理−更新”操作时,会由于线程的交叉执行而造成数据的错误。例如以下代码段,当 thread_func() 同时在多个线程中执行时,更新到 glob_value 中的值就会互相干扰,产生错误结果。#define LOOP_COUNT ...

2019-05-31 18:41:00 555

原创 进程的终止

正常终止一个进程可以用 _exit 系统调用来实现,原型为:void _exit(int status);其中的 status 会返回 wait() 类的系统调用。进程退出时会清理掉该进程占用的所有系统资源,包括关闭打开的文件描述符、释放持有的文件锁和内存锁、取消内存映射等,还会给一些子进程发送信号(后面课程再详细展开)。该系统调用一定会成功,永远不会返回。在退出之前,还希望做一些个性化的...

2019-05-31 18:39:11 492

转载 学习-> 积累-> 大牛

学习是什么?为什么要学习?如何学习?抓住重点学习。什么是重点?能解决你的问题,那就是重点,所以要明确问题是什么(目的是什么),东西是学不完的。积累是什么?为什么要积累?怎么积累?记录关键点。站在巨人的肩膀上思考问题才更有效。从前者的代码和思路中得到的。大牛是什么?为什么是大牛?怎么成为大牛?主动对关键点进行用和修改。就是主动思考的过程。看的目的是理解并提取核心点并记录并会用和修...

2019-05-20 19:43:00 178

转载 监控子进程状态

在 Linux 应用中,父进程需要监控其创建的所有子进程的退出状态,可以通过如下几个系统调用来实现。pid_t wait(int * statua)一直阻塞地等待任意一个子进程退出,返回值为退出的子进程的 ID,status 中包含子进程设置的退出标志。pid_t waitpid(pid_t pid, int * status, int options)可以用 pid 参数指定要等待的...

2019-04-26 08:11:13 1132

转载 fexecve() 系统调用

glibc 从 2.3.2 版本开始提供 fexecv() 函数,它与 execve() 的区别在于,第一个参数使用的是打开的文件描述符,而非文件路径名。增加这个函数是为了满足这样的应用需求:有些应用在执行某个程序文件之前,需要先打开文件验证文件内容的校验和,确保文件内容没有被恶意修改过。在这种情景下,使用 fexecve 是更加安全的方案。组合使用 open() 和 execve() 虽然可...

2019-04-26 08:10:41 1113

转载 execve() 系统调用

execve() 系统调用的作用是运行另外一个指定的程序。它会把新程序加载到当前进程的内存空间内,当前的进程会被丢弃,它的堆、栈和所有的段数据都会被新进程相应的部分代替,然后会从新程序的初始化代码和 main 函数开始运行。同时,进程的 ID 将保持不变。execve() 系统调用通常与 fork() 系统调用配合使用。从一个进程中启动另一个程序时,通常是先 fork() 一个子进程,然后在子进...

2019-04-26 08:10:19 6161

转载 fork() 系统调用

fork() 系统调用将创建一个与父进程几乎一样的新进程,之后继续执行下面的指令。程序可以根据 fork() 的返回值,确定当前处于父进程中,还是子进程中——在父进程中,返回值为新创建子进程的进程 ID,在子进程中,返回值是 0。一些使用多进程模型的服务器程序(比如 sshd),就是通过 fork() 系统调用来实现的,每当新用户接入时,系统就会专门创建一个新进程,来服务该用户。fork() 系...

2019-04-26 08:09:52 4327

转载 强行修改const只读变量

修改const只读变量,只能修改局部常量,不能修改全局静态常量。例如:// 某函数内部const int const_value = 100;int * ptr = (int *)&const_value;*ptr = 200;因为在函数内部声明的 const_value,其本质上还是一个函数内的局部变量,存储区在该函数的栈帧内,而程序对该内存区拥有修改的权限。相应地,用同...

2019-04-26 08:09:12 1739

转载 errno 的多线程问题

思考一个问题,每个系统调用失败后都会设置 errno,如果在多线程程序中,不同线程中的系统调用设置的 errno 会不会互相干扰呢?如果 errno 是一个全局变量,答案是肯定的。如果真是这样的话,那系统调用的局限性也就太大了,总不能在每个系统调用之前都加锁保护吧。优秀的 Linux 肯定不会这么弱,那么,这个 errno 的问题又是怎么解决的呢?根据 man 手册,要使用 errno,首先需...

2019-04-26 08:08:32 3319

转载 系统调用 错误处理函数

1 perrorperror函数是用来打印错误提示信息的,原型是:#include <stdio.h>void perror(const char *s);它先打印s指向的字符串,然后输出当前errno值所对应的错误提示信息,例如当前errno若为12,调用perror(“ABC”),会输出"ABC: Cannot allocate memory"。测试程序:#inclu...

2019-04-26 08:07:28 370

转载 系统调用的标准使用方法

系统调用,一般是指 glibc 中的包装函数。这些函数会在执行系统调用前设置寄存器的状态,并仔细检查输入参数的有效性。系统调用执行完成后,会从 EAX 寄存器中获取内核代码执行结果。内核执行系统调用时,一旦发生错误,便将 EAX 设置为一个负整数,包装函数随之将这个负数去掉符号后,放置到一个全局的 errno 中,并返回 −1。若没有发生错误,EAX 将被设置为 0,包装函数获取该值后,并返回 ...

2019-04-26 08:06:24 330

转载 linux系统调用错误码 errno

为防止和正常的返回值混淆,系统调用并不直接返回错误码,而是将错误码放入一个名为errno的全局变量中。如果一个系统调用失败,你可以读出errno的值来确定问题所在。errno不同数值所代表的错误消息定义在errno.h中,你也可以通过命令"man 3 errno"来查看它们。需要注意的是,errno的值只在函数发生错误时设置,如果函数不发生错误,errno的值就无定义,并不会被置为0。另外,在...

2019-04-26 08:05:27 3972

转载 管道与查找

ps -ef | grep redis-clips ,即process status,显示进程状态信息,参数-e代表显示全部进程,-f代表显示进程之间的关系|, 管道命令grep ,即global search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来,是一种强大的文本搜索工具,它能使用正则表达式搜索文本,...

2019-04-26 08:04:17 482

原创 基于采样的局部规划与避障算法

一、引言目前为系统添加了局部路径规划模块,结合之前做的视觉激光雷达信息融合模块,系统需要进一步对避障部分进行处理。局部路径规划总的来说是在全局路径规划模块下,结合避障信息重新生成局部路径的模块,上层的全局路径规划确定了A到B的一个全局路径,不过轨迹跟踪模块(比如 pure persuit)实际进行跟踪的不能是这个直接生成的全局路径,因为系统实际工作可能会有其他情况发生,轨迹跟踪模块实际跟踪的是...

2019-02-26 14:55:26 9603 27

原创 Autoware 关键模块解读

引言本文参考Autoware_wiki_overview,主要描述了Autoware的整体框架和模块描述,主要包括感知和规划两大部分。感知包括定位模块,检测模块,预测模块。定位模块使用3D map和SLAM算法来实现,辅助以GNSS和IMU传感器。检测模块使用摄像头和激光雷达,结合传感器融合算法和深度学习网络进行目标检测。预测模块使用定位和检测的结果来预测跟踪目标。规划模块主要是基于感知的...

2019-01-31 16:44:51 7653 1

原创 视觉激光雷达信息融合与联合标定

一、引言最近在为车辆添加障碍物检测模块,障碍物检测可以使用激光雷达进行物体聚类,但是我们使用的是16线的velodyne,线数还是有些稀疏,对于较远的物体过于稀疏的线数聚类效果并不好,因此考虑使用视觉进行目标检测,然后投影到3D点云里面,获取障碍物位置,同时视觉还可以给出障碍物类别信息。使用视觉进行目标检测,将检测结果2D bounding box坐标信息投影到点云里面获得3D boundin...

2019-01-27 15:59:34 16140 63

原创 opencv 图像深拷贝、浅拷贝与蒙版拷贝

在复制图像时,有两种情况,一种是浅拷贝,一种是深拷贝。所谓浅拷贝仅仅是引用,即创建了一个新的矩阵头,仍然指向原来的数据空间。而所谓的深拷贝,是指完全创建一整套新的Mat对象(包括矩阵头和数据空间)。操作()和 = 操作都属于浅拷贝,例如:Mat image = imread("1.png" , 0) ;Mat image1(image) ;//仅是创建了Mat的头部分,image1与im...

2019-01-06 21:01:44 917

原创 opencv cv::Mat数据类型总结

在以下两个场景中使用OpenCV时,我们必须事先知道矩阵元素的数据类型:使用 at 方法访问数据元素的时候要指明数据类型做数值运算的时候,比如究竟是整数除法还是浮点数除法。cv::Mat 类的对象有一个成员函数type()用来返回矩阵元素的数据类型,返回值是 int 类型,不同的返回值代表不同的类型,具体对应关系如下所示:类型C1C2C3C4CV_8U0...

2019-01-06 20:28:00 36367 8

原创 ROS项目调试:rqt工具使用总结

rqt工具的使用这里介绍一下ROS中无敌强大的rqt工具安装rqt工具sudo apt-get install ros-indigo-rqtsudo apt-get install ros-indigo-rqt-common-plugins运行rqtrqt进入上方菜单栏的Plugins,里面有很多十分有用的用于ROS调试的插件下面简单列举一些十分有用的插件功能:插件...

2018-12-26 00:44:53 24975 3

原创 ros项目调试:vscode下配置开发ROS项目

引言在vscode下面配置用于ROS项目开发的环境包括头文件目录的配置,catkin_make命令的配置,GDB debug的配置,以及ROS插件。vscode头文件目录配置安装“c/c++”插件到vscode左边栏的EXTENSIONS中,搜索“C/C++”并安装生成c_cpp_properties.jsonvscode自身配置文件全部在./.vscode/目录下但是,在最开始对...

2018-12-25 21:19:45 43902 31

原创 ros项目调试:ROS项目使用GDB调试

引言在写ROS工程代码,有时候找一个bug非常麻烦,尤其是运行时出错的bug,这时候借助一些调试器可以极大的提高查找bug的效率。下面介绍如何使用GDB调试器来进行ROS C++项目的调试在debug模式编译编译器有些优化会让debug无法进行。为了避免这种情况,程序编译时要加上debug选项,让cmake以debug模式编译,不然可能会在gdb调试的时候不能跳转到源代码,只能进入断点。...

2018-12-25 21:17:13 25157 6

原创 RC-car硬件平台搭建及arduino控制

引言想做一个自动驾驶的demo,用于算法的验证和展示。目前完成了车辆平台的搭建和电机控制,后续会陆续更新其他部分:路径规划、激光slam建图与定位,语义地图的构建,控制算法等等。硬件平台:计算平台Jetson TX2arduino-uno车载平台RC-car传感器velodyne-16Razor-9dof-imu整个基本框架是Jetson TX2做上层感知,...

2018-12-20 23:39:42 1688 3

原创 一种基于激光雷达的自动驾驶技术路线

引言描述一种基于激光雷达的技术路线。一、NDT_mapping用途:使用激光雷达点云数据创建3D地图使用的传感器:16线激光雷达 + IMU二、NDT_matching用途:基于建好的3D地图和车辆当前扫描的点云帧,得到车辆位置和朝向三、云端地图生成用途:录制云端轨迹数据,用于将来下发给车端,最终生成一系列目标轨迹点waypoints,每一个点都包含了位置和速度信息,用于我们之...

2018-12-16 17:31:11 1935 7

原创 TX2安装使用razor_imu_9dof

文章同步到我的知乎专栏:SUNM的实验室, 欢迎关注一、引言自动驾驶中IMU起到了越来越重要的作用。对于定位环节来说,首先,IMU不依赖于外界环境进行定位,只要精度高,漂移少,那么IMU提供的定位信息是很准的,而且频率也高。其次,IMU可以弥补GPS更新频率慢的问题,还可以用于辅助激光SLAM定位,例如为激光SLAM建图提供一个初始的位姿估计。但是IMU不同品质价格差异巨大,精度高的IMU可...

2018-12-15 15:34:54 1733

原创 c++多线程学习总结

一、创建线程#include &lt;pthread.h&gt;pthread_create (thread, attr, start_routine, arg)创建线程成功时,函数返回 0,若返回值不为 0 则说明创建线程失败。参数描述thread指向线程标识符指针。attr一个不透明的属性对象,可以被用来设置线程属性。一般使用默认值 NULL。st...

2018-12-13 17:27:09 317

原创 点云PCD文件格式解读及手动生成

引言起因是在python下处理点云数据比较麻烦,对于一些深度学习模型输出的点云处理结果,想在C++下使用pcl库进行后处理,所以考虑到如何将任意的xyz数据输出为.pcd文件,然后使用pcl库读取.pcd文件来处理点云。下面的内容分析了pcd文件的前缀格式和含义。脚本地址:GitHub1. PCD版本在点云库PCL 1.0发布之前,PCD文件格式就已经发展更新了许多版本。这些新旧不同的版本...

2018-12-13 17:24:21 3199

原创 CMakeList.txt 分析

文章目录一、引言二、整体结构三、版本和名称四、查找相关包五、catkin_package()六、添加头文件路径和库路径6.1 头文件路径6.2 库路径七、 指定目标及其源文件7.1 构建可执行文件作为目标7.2 构建库作为目标八、 添加依赖关系九、设置install一、引言ROS使用cmake来编译代码,cmake首先会一步一步处理CMakeLists.txt的内容,然后生成一个MakeFil...

2018-12-13 17:10:50 1670 1

原创 git 用法总结

git 用法总结版本控制的形象比喻:好比玩RPG游戏时,每通过一关就会自动把游戏状态存盘,如果某一关没过去,你还可以选择读取前一关的状态。有些时候,在打Boss之前,你会手动存盘,以便万一打Boss失败了,可以从最近的地方重新开始。Git也是一样,每当你觉得文件修改到一定程度的时候,就可以“保存一个快照”,这个快照在Git中被称为commit。一旦你把文件改乱了,或者误删了文件,还可以从最近...

2018-12-13 17:03:06 172

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除