- 博客(68)
- 资源 (3)
- 收藏
- 关注
原创 Docker镜像构建
可以基于已有的docker镜像,构建新的镜像,并在构建时就安装好需要的包。当然也可以先构建一个镜像,在镜像里安装需要的包,再导出。比如,下面基于本地的x5:v1.0的镜像,构建x5:v2.0的新镜像。就可以构建出一个新的docker镜像了。
2026-02-10 16:14:31
138
原创 远程ssh免密登录
上传到远程服务器上ssh-copy-id -i ~/.ssh/id_rsa.pub username@remote_server_ip。生成本地秘钥ssh-keygen -t rsa -b 4096,会在。~/.ssh/config,可以避免输入ip,并给远程服务器取名。这个就是需要上传到服务器上的文件。
2026-02-06 15:06:09
363
原创 python工程的路径,引用包总结
在linux下使用python脚本,有时候会面临找不到引用的路径这类问题。这是因为在用一些编辑器打开代码的时候,并不是以整个独立工程的视角看代码文件的,这样文件之间的引用关系,相对路径就都不对。本文就在总结解决这类问题的方法。
2026-01-09 17:34:34
325
原创 pkl解析方法
因为使用了一个特定工具链推理量化的模型,生成的推理结果是pkl的。结合之前也有一些数据的读取也是会从pkl这种序列化后的文件中读取,所以整理一下pkl文件解析的方法。因为是序列化的文件,所以看起来就不很直观,不知道里面包含哪些内容。
2026-01-09 16:32:13
719
原创 《C++并发编程实战》精读总结:第四章 并发操作的同步
之前我们实现的是对公共数据的保护,但是线程之间几乎没有其他任何的交互操作。像“某线程需要等待另一线程完成后,才能开始执行”这种行为,我们通常称为线程的同步。本章主要是来展示线程是如何进行同步(交互)的。
2025-03-14 17:36:15
391
原创 《C++并发编程实战》精读总结:第三章 在线程间共享数据
多线程数据共享的问题多是由于对数据的改动引起的,要对共享的数据进行保护,比较直接的方法就是实用互斥和加锁。下面看一个简单的例子,使用到了互斥mutex,和对互斥加锁lock_guard<>。这里,假设一个线程调用add向stack1里添加元素时,如果另外一个线程调用top_value想要看stack顶部的元素是无法做到的,因为add已经锁住了互斥mutex1。注意,互斥标记的是代码。锁住互斥就是锁住标记代码涉及到的共享数据。
2025-03-06 18:57:56
286
原创 《C++并发编程实战》精读总结:第二章 线程管控
传递进线程的unique_ptr会以副本的形式被复制到线程的空间中,这与智能存在唯一一个unique_ptr指向对象冲突,刚刚的任务是最简单的一种,是一个普通函数,返回为空,也不接收参数。复杂一些的任务就不能用简单的函数表示了,可以用函数对象,函数指针,lambda表达式等。其实上面的代码中,我们已经在给线程中的任务(函数)传递参数了,但是目前为止我们并没有发现给线程上的函数传递参数有什么不同,而这恰恰是在线程上写代码的一个特殊之处,所以这里单独分一个标题来讲。以最简单的任务,一个空函数为例。
2025-02-28 17:02:35
825
原创 《Effective C++》精读总结 — 3. 尽可能使用const
第一次是为了顺利调用const成员函数,将this将至转换成const类型(因为如果默认调用non-const成员函数,说明调用函数的对象是non-const的),否则就会递归调用non-const成员函数自己。另外,如果const成员函数的返回值也有const修饰,则需要借助const_cast<int>做第二次类型转换,目的是将返回的结果中的const移除,如上面代码中被注释掉的地方。这里注意最后,我们为了重复使用const成员函数的逻辑,其实是直接返回了const成员函数,但是做了一次类型转换。
2025-02-21 14:52:16
587
原创 ROS使用Rviz画图的方法2——不使用catkin
但是往往实际应用中我们是既有的C++工程,并不是完全基于ROS构建的,那么就可以借助CMakeLists来调用ROS的库,直接使用C++的编译器来进行编译,也能够完成在Rviz中显示的目的。在上一篇介绍了如何使用ROS的Rviz来显示我们想要的图形,整个编译的环境还是借助了catkin完成的,可以参考(这种方法比较适用在将ROS融入到现有的工程中。就能够在Rviz中有相同的显示效果。
2025-02-11 13:34:50
337
原创 ROS使用Rviz画图的方法
目录1. 事例代码2. 发送框架及内容分析3. rviz中显示效果及设置4. 关于ros信号建立先后的补充在一些需要可视化的任务重,我们通常会借助ROS里的Rviz来进行,比如自动驾驶调试的车辆显示。本篇以一个简单的例子,介绍如何使用ROS在Rviz中进行显示。先看完整代码:2. 发送框架及内容分析先关注main函数的部分,想要在rviz中显示,需要四个基本步骤:有了上面的基本框架,就可以填充消息内容了,在第三步创建消息发布者时,对消息的类型和使用的话题进行了定义,定义类型为visualizati
2025-02-11 10:47:09
1186
原创 CMakeLists 写法总结2.0
上述代码中PLATFORM是由于我们想提供交叉编译的可能,所以将其定义在最上层的CMakeLists中,并且在后续代码中,通过if判断,来设定不同的编译处理器,分别对x86和arm的平台增加不同的编译选项。在app文件夹下的子层CMakeLists逻辑就简单很多,主要是根据平台的不同,选择不同的子文件夹路径,这里对同一个平台,比如x86平台想编译不同功能的主函数入口,也可以从这里进行分支,主要就是找到对应平台及功能主函数的路径下的底层CMakeLists.txt。
2025-02-10 15:41:12
1282
原创 《Effective C++》精读总结 — 2. 尽量以const,enum,inline替换#define
文中说这个条款也可以改成“尽量以编译器替换预处理器”,个人觉得这句话主要是说编译器是方便对代码本身进行调试的,但是预处理器其实和代码的逻辑无关,如果程序报错是很难排查的。所以尽量减少在预处理阶段的操作。宏定义常量可以替换为const常量,这样做即能够统一管理,还增加了类型检查等宏定义无法实现的优点。最后,#define的需求降低了,但是#include和#ifdef/#ifndef仍然很重要,所以预处理器的工作不能完全替代。
2025-01-17 17:07:01
794
原创 《Effective C++》精读总结 — 1.视C++为一个语言联邦
C中进行值传递效率会更高(往往是内置的数据类型),而object-oriented和template中因为涉及到自定义的构造和析构,通常通过引用+const的方式进行传递效率会更高。而到了STL中,迭代器和函数对象都是在C指针上塑造出来的,所以值传递又再次变得更加适用。第一个条款是一个很好的对C++总体认识的说明,我们接触C++的时候往往只是在其中一个领域深耕,而忽略了。C++ 包含4层语言体系,
2025-01-13 19:30:18
223
原创 Python获取命令行参数
在写python程序的时候,经常需要获取命令行的参数,以达到灵活配置和批量执行(结合配置文件和sh脚本)的目的。下面介绍两种方法,一种适合简单的参数输入,一种适合更多更专业的参数输入。
2025-01-03 16:58:30
855
原创 旋转矩阵乘法,自动驾驶中的点及坐标系变换推导
CA(1,1)向量经过逆时针旋转90°,得到CB向量(-1,1),向量的旋转矩阵不存在坐标系的变换,不用在意上面的定义,直接用点左乘具体的旋转矩阵即可。我们将原坐标系逆时针旋转90°,得到DBE坐标,其中BD为x轴,BE为y轴,在DBE坐标系中(以坐标系G'),A点在G’坐标系中的坐标表示为A'(1,-2)。关于旋转变换,离不开矩阵的乘法,而矩阵乘法的物理意义和本身数学上矩阵乘法的内向相消决定了乘法的顺序,在CBD坐标系中(以坐标系G代表),其中BC为x轴,BD为y轴,A点的坐标为(2,1)
2024-09-20 16:53:13
1588
原创 如何用Shell写一个启动脚本
通常情况下,我们在Linux下运行一个编译好的程序,只需要在可执行文件的路径下直接运行即可。但随着程序变得复杂,编译选项的增多,使用库的增加以及对可执行程序输入的参数变多,直接执行的过程变得比较麻烦。这时可以写一个启动的脚本来一键拉起程序。下面我们来看下如何用shell来创建一个拉起程序的脚本。
2024-05-28 17:22:39
1069
原创 Python 多进程和多线程在加速程序运行上的差别
IO密集型指的是系统运作大部分的情况是CPU在等 I/O(硬盘/内存/网络等等)的读/写操作,这时候CPU的占用率是非常低的(这也是多进程加速表现不明显的原因)。起因是在处理一个需要大量计算且批量生成文件的程序时,使用多线程的方法处理计算任务加速效果不理想,后来采用了多进程的方式加速效果很好,所以花点时间探究一下两者之间的区别。对于IO密集型,CPU占用率低,一个任务执行后需要CPU一直等待,如果使用多线程对程序进行并发执行,那么CPU在原本等待的时间就可以执行其他任务,进而加速程序的执行。
2024-05-08 09:54:32
801
1
原创 将double类型转为两个float类型存储(顺带看看初版到最终版的优化思路)
实际工作中碰到一个需求,将一个double类型的变量,存储成两个float类型。最后再根据两个float类型转回double类型。因为实际的信号列表已经定义了好了两个float类型,所以只能以这种折中的方法将double类型存储下来。
2024-03-30 10:57:21
783
原创 C++ 关键字小结
delete 的作用和=default 有点相反,是显式的表示不用某个默认的函数。比如,有时候我们不想使用默认的拷贝构造函数,就可以写如下的代码。比如,用户如果写了自己的构造函数,那么编译器就不会创造默认的构造函数了,这有可能会带来编译错误。在执行A a3 = a1;=default 一般会放在默认的构造函数,析构函数,拷贝构造函数,拷贝赋值函数,
2024-02-14 21:31:07
267
原创 shared_ptr放入vector,要及时clear,避免内存泄漏
最近碰到一个内存泄漏的问题,查了半天发现是vector数组的成员中有共享指针,而vector没有释放引用计数导致的。可以看到,因为使用了vector而没有清空,增加了智能指针的引用次数,但是在使用完vector之后没有释放,到时计数没有回归。我们看看嵌套一个结构体,结构体里也有一个共享指针会如何。这里我们来引深一下,为什么放入Vector之后,
2024-02-14 18:54:55
2472
原创 卡尔曼滤波详解(1)
更新部分的三个公式来源,实际上是由两个正态分布的公式相乘的结果得到的。根据预测部分的结果,我们得到了预测的当前时刻的状态量,这个状态量其实服从高斯分布。同时,在当前时刻,我们有当前时刻的观测量,这个量也服从高斯分布。更新部分的主要操作,就是将这两个高斯分布的量结合,得到一个方差更小的高斯分布。图示如下(这个图是来自。
2024-02-12 20:50:38
3235
原创 C++单例模式详解
起因是在程序中重复声明了一个单例模式的变量,后来程序怎么调都不对,最后发现变量是用单例模式,修改是全局的,所以决定好好梳理一下单例模式。首先,为什么要用单例模式,就是因为我们希望一个类只有唯一一个实例,并且提供一个全局的访问点。从这个描述不难看出,这个实例应该是要static来修饰的。。
2024-02-05 16:44:08
2853
原创 ASAN 内存问题检查工具
ASAN可以定位的内存问题有:内存越界(堆内存越界,栈内存越界,全局变量越界),内存释放后使用,读取未初始化内存,内存泄漏。
2023-09-22 16:41:37
1120
原创 C++:constexpr 和 const 的区别
constexpr 是 C++ 11 标准新添加的关键字,原先的标准中是只有const关键字的,作用是表示只读常量。但是,其实只读常量是两个属性,分为只读和常量,都用const来表示会产生歧义。这里补充const的一个重要概念就是,const后面的变量,仅仅表示不能通过该变量改变背后实际的值,但是如果其他变量也能够表示同一块内存空间,这个内存空间里的值是可以通过其他变量来改变的。上面的程序做如下修改,arr2就可以正常的编译,因为传入的是一个constexpr代表的常量类型。
2023-09-18 19:10:07
578
原创 小记录:tcpdump的常用命令
基本的抓包命令, 从eth0 抓取,保存到xxx.pcap。# 可以按照协议抓取,如udp,ip,arp等。# 抓取源ip 或目的 ip的包。# 抓取多个源ip的包。
2023-09-11 15:52:01
873
原创 旋转矩阵左右乘,弄清变换关系更重要
关于矩阵左乘和右乘的区别,看了不少数学解释,大概是我水平不够,不是很懂的样子。但本来我也是做应用,抛开理论不谈,看看左乘的实际的使用情况。这个非常的重要,如果没有定义好矩阵下标和坐标系之间变化的关系,就会彻底陷入混乱。但实际上我们是把上述坐标系的变换定义为左乘的,这比较符合我们的阅读习惯。先不考虑左乘还是右乘,对于矩阵乘法来说,是遵循内项相消的。这里,如果我们有坐标系3到坐标系2的矩阵变换关系。,就可以得到坐标系3转到坐标系1的变换矩阵了,即。,以及坐标系2到坐标系1的矩阵变换关系。就是说,我们是先有了。
2023-09-06 20:03:48
2428
7
原创 C++小技巧, vector的resize,reserve和push_back
在使用C++的vector时,一不注意就会是的vector越界,或者在push_back后遍历vector发现前面的值根本不是自己想要的值。可以明显看到,resize之后,vector的size变成了5,而在push_back之后size变成了6。而往往我们想事先初始化vector的空间,其实应该使用reserve,而不是resize。
2023-08-25 17:09:11
1048
原创 Yaml配置文件读取方法
另外,上面提到的类型问题,在这里用.as来体现,将对应的配置文件中的值,读入成程序中期望得到的值的类型,这里test_name希望读入为string。在日常的代码中,有一些值是配置文件中定义的,这些值可以根据用户的要求进行调整和改变。这样开放程序给用户时,就可以不必开放对应的源码,只开放yaml格式的配置文件即可。但是读入之后,其实是有对应需要的类型的,比如is_debug读入后需要时bool类型,test_time读入之后需要是int类型。我们先写一个简单的配置文件,然后将其中的值读入到程序中。
2023-08-24 17:21:52
1487
原创 C++ 编译告警: delete called on that is abstract but has non-virtual destructor
上述告警在使用arm编译器编译的时候报出,意思是缺少虚的析构函数,在delete被调用的时候,会造成问题。典型的就是内存泄漏。看例子:、1. 正常情况上面代码中的两个类,一个是基类Base,一个是继承Base的子类Child。按照正常的声明方式,调用运行。这是最正常的情况,声明了一个子类,首先会调用父类的构造函数,然后调用子类的构造函数。析构时先调用子类的析构函数,再调用父类的析构函数。
2023-07-06 17:53:12
1448
原创 C++结构体内有指针,直接赋值报Segmentation fault原因分析
最近写程序的时候,用了别人定义好的结构体,结构体的成员变量包含指针,直接赋值后运行报段错误。下面对这个问题进行一下分析。
2023-06-08 19:19:21
1944
原创 CMakeLists 写法总结1.0
之前简单介绍了makefile的写法,但实际工程中基本不会手写makefile,通常情况是会写一个CMakeLists甚至是多层多个CMakeLists来构建整个工程。关于makefile和CMakeLists的关系:make命令实际上是按照makefile中的内容来执行的,而CMakeLists就是用来生成makefile的,是cmake命令按照CMakeLists中的内容生成makefile文件。
2023-04-08 22:17:56
3490
1
原创 Linux定时器2
1. POSIX定义的定时器有了上一篇关于setitimer定时器的介绍,相信Linux下定时器的用法已经有了基本了解。我个人在使用setitimer定时器的时候,有一个非常头疼的问题,就是setitimer定时器不能设置多个。严格意义上讲,setitimer定时器只能按照时间处理的类别,分别设置三种定时器,即ITIMER_REAL,ITIMER_VIRTUAL和ITIMER_PROF三类,具体解释见上一篇博客。但这非常限制Linux下定时器的使用。解决方法,就是用POSIX下定义的定时器。可以把P
2021-11-26 15:02:40
2330
原创 Linux定时器1
目录1.itimerval-定时器的基本时间单元2.setitimer——创建定时器3.简单实例1.itimerval-定时器的基本时间单元首先要理解itimerval结构体,这是组成定时器的基本时间单元。关于timeval结构体,上一篇博客有讲到,是由秒时间和微秒时间组成的。这里it_interval表示的是一个timeval类型的时间,这个时间是创建的定时器的周期性。即如果这一时间设置为5s,则该定时器每5s触发一次。Itvalue也是timeval类型的时间,表示首次倒计时时距离定
2021-11-17 18:37:28
859
visial studio2019缺少的MsBuild文件
2020-11-02
armv8-Liunx交叉编译工具.rar
2020-10-18
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅