- 博客(216)
- 资源 (1)
- 收藏
- 关注

原创 985硕机器人算法方向毕业五年,对读研和求职规划选择的一点感想总结
这7年,从双非到考上985研的开心,读研写论文的焦灼,毕业时候的未来可期,到刚参加工作时的996,以及果断换行寻找所谓热爱的方向,但对未来仍还是有焦虑和迷茫。
2025-01-04 09:15:59
1206
原创 计算机时间为什么从1970年开始算起?
Unix时间戳以1970年1月1日00:00:00 UTC为起点,主要源于早期Unix系统的技术限制和设计需求。32位有符号整数的时间范围决定了选择1970年可确保足够使用到2038年(避免过早溢出),同时便于底层计算和存储。历史背景上,1970年接近Unix开发时期,且UTC基准简化了跨平台时间处理。相比之下,其他系统如Windows使用1601年起点,Mac OS采用1904年变种。虽然2038年问题(32位溢出)仍需应对,但64位方案已基本解决。这一设定因Unix的广泛影响成为行业标准,体现了早期计算
2025-06-13 14:11:32
596
原创 第5.2章 组合导航GPS时间转为Unix时间代码实战
本文解析了GPS时间与Unix时间的转换原理及注意事项。GPS时间从1980年1月6日起算,由周数和周内秒数组成;Unix时间从1970年1月1日起算。两者转换需考虑315964782秒的起始时间差和闰秒调整(GPS包含闰秒而Unix忽略)。关键区别在于:GPS时间采用连续计时且存在1024周溢出问题,Unix时间广泛用于计算机系统。实现转换时需注意周计数器修正、精度损失等问题,建议使用专业库处理并定期更新闰秒信息,特别是在高精度应用中需谨慎处理时间同步误差。
2025-06-13 14:10:40
619
原创 C++ 容器 `data()` 方法的完整用法总结
C++标准库容器的data()方法提供对底层数据缓冲区的直接访问,支持零拷贝操作和与C接口交互。该方法适用于vector、array、string等连续存储容器,返回元素类型指针。核心用途包括高性能计算、内存优化和序列化处理,需注意指针在容器扩容时会失效,且无边界检查。与C++20的std::span结合可实现更安全的视图访问。最佳实践包括避免在持有指针时修改容器,并配合size()进行边界控制。
2025-06-13 11:09:25
749
原创 C++多线程中wait()为什么要传入锁lock,而且必须传入的还是std::unique_lock?
C++多线程中wait函数必须传入锁的设计原理可以类比餐厅排队场景:就像顾客需要持排队号(锁)才能等待座位(共享资源),线程通过锁原子性地释放资源并进入等待,避免竞态条件。技术层面,锁确保共享数据安全访问,unique_lock支持灵活解锁/加锁,配合条件变量实现线程同步。这种机制防止虚假唤醒,保证条件满足前线程安全等待,是线程同步的关键设计。
2025-06-11 10:37:01
217
原创 第3.2.2章 什么时候使用Eigen::Isometry3d还是Affine3d:详解与选择指南
选择Isometry3d还是Affine3d取决于你的变换是否需要保持刚体性质。如果仅涉及旋转和平移,优先使用Isometry3d,它更高效且语义明确;如果需要缩放、剪切等更复杂的变换,则使用Affine3d。合理选择类型可以提高代码的安全性、可读性和性能。
2025-06-10 16:06:49
261
原创 Eigen::Vector3d 元素访问方式总结
推荐使用x()y()z()成员函数访问的元素,因为它们语义明确、不易出错,且性能最优。在需要高性能或与 C 库交互时,可使用data()指针。
2025-06-10 14:45:42
284
原创 第3.2.1章 Eigen代码实战:四元数赋值用法总结及与变换矩阵转换
Eigen库中四元数(Quaternion)的赋值方法解析:Quaterniond和Quaternion<double>本质相同,但Quaterniond是更简洁的别名。主要赋值方式包括直接构造(w,x,y,z分量、旋转矩阵或轴角)、赋值运算符和成员函数赋值。使用时需注意参数顺序、归一化处理和头文件包含,常见错误包括模板参数缺失和构造顺序错误。四元数广泛应用于旋转矩阵转换、姿态组合等场景,合理选择赋值方式能提高代码可读性和正确性。
2025-06-10 14:29:26
305
原创 `std::tuple` 的取值方式代码示例和适用场景总结
摘要:C++中std::tuple的取值方式主要有:1)std::get<索引>通过编译期常量索引访问;2)结构化绑定(C++17+)直接解包到变量;3)std::tie绑定到已有变量并可忽略元素;4)std::get<类型>通过唯一类型访问;5)运行时索引需配合std::variant;6)std::tuple_element获取元素类型。不同方法适用于静态/动态访问、选择性解包等场景,需注意索引越界和类型唯一性等限制。结构化绑定和std::get<索引>是推荐首选方式
2025-06-10 14:17:08
250
原创 第12.6章 PCL工程实战:NDT匹配初始位姿用Eigen::Affine3d还是Eigen::Matrix4f类型好?
摘要: 在C++机器人及计算机视觉中,Eigen::Affine3d与Eigen::Matrix4f均用于三维变换,但存在设计差异。Affine3d采用双精度,封装旋转平移,提供几何API,内存效率更高;Matrix4f为单精度通用矩阵。NDT匹配推荐使用Affine3d:语义明确(直接表示变换)、精度更高(减少误差)、兼容PCL库,且可通过cast<float>()高效转换。性能场景中,Affine3d内存占用更优,而实时低精度需求可选Matrix4f。最佳实践是优先用Affine3d构建变换
2025-06-10 11:19:08
195
原创 使用`std::fixed`和`std::setprecision`设置输出的浮点数精度
本文介绍了3种在C++日志中显示6位小数浮点数的方法:1)使用std::fixed和std::setprecision格式化;2)自定义格式化函数;3)修改日志宏定义。所有方法都能将输出精度固定为小数点后6位,如"1746410000.123456"。使用时需注意std::fixed会对后续输出产生影响,大数值可考虑用科学计数法。
2025-06-10 11:07:59
250
原创 C++ 标准库二分查找算法std::lower_bound
std::prev是C++标准库中的迭代器操作函数,用于获取双向或随机访问迭代器的前驱位置。主要特点包括:返回输入迭代器前n个位置的迭代器(默认n=1);适用于双向迭代器(如list)和随机访问迭代器(如vector);随机访问时效率为O(1),双向迭代需O(n)步骤。使用时需注意迭代器类型限制和越界风险,典型应用包括获取容器末尾元素(如std::prev(v.end()))或在循环中安全访问前驱元素。该函数比手动递减操作更安全便捷,需包含<iterator>头文件使用。
2025-06-10 10:35:45
277
原创 C++ 标准库`std::prev`介绍
std::prev是C++标准库中的迭代器操作函数,用于获取双向或随机访问迭代器的前驱位置。主要特点包括:返回输入迭代器前n个位置的迭代器(默认n=1);适用于双向迭代器(如list)和随机访问迭代器(如vector);随机访问时效率为O(1),双向迭代需O(n)步骤。使用时需注意迭代器类型限制和越界风险,典型应用包括获取容器末尾元素(如std::prev(v.end()))或在循环中安全访问前驱元素。该函数比手动递减操作更安全便捷,需包含<iterator>头文件使用。
2025-06-09 16:52:16
274
原创 自动驾驶中 BEV 与 BEVFusion是什么,该如何学习?
自动驾驶技术中,BEV(鸟瞰图)感知为环境感知和定位提供了统一视角。BEV通过多传感器数据融合,将摄像头、激光雷达等信息转换为全局鸟瞰图,解决了传统2D感知的遮挡问题,提升了目标检测精度。BEVFusion框架进一步优化了多模态数据融合,增强系统鲁棒性。目前特斯拉等车企已广泛应用BEV技术。学习BEV需掌握传感器原理、深度学习和坐标变换等知识,并通过开源项目实践。BEV技术将持续推动自动驾驶发展,是实现安全高效自动驾驶的重要支撑。
2025-06-06 11:21:09
537
原创 用老板、打工人、任务看板例子通俗解释C++多线程中wait、join和notify_one三者联系及区别
本文通过公司角色类比解析C++多线程编程的核心机制。主线程(老板)通过条件变量(任务看板)和互斥锁(钥匙)控制子线程(员工)的工作流程:wait()让线程休眠并释放锁,notify_one()唤醒单个线程,join()等待线程结束。重点阐述了三者的原子性协作、底层实现原理及常见误区,强调循环等待和带谓词wait的重要性,并给出终止线程的最佳实践(设置标志+通知+join)。这些机制共同构成了线程同步与协作的基础。
2025-06-06 10:40:38
537
原创 C++多线程中`wait`、`join`和`notify_one`的协作机制与原理
wait():线程释放锁并休眠,等待通知(厨师放下钥匙睡觉):唤醒一个等待中的线程(传菜员拍醒厨师)join():等待线程执行完毕并回收资源(老板等厨师下班)三者结合实现了线程间的同步与协作,是C++多线程编程的核心机制。理解它们的底层原理,能帮助你写出更安全、高效的多线程代码。
2025-06-05 17:57:48
683
原创 C++多线程的 `wait()` 为何支持 Lambda?
C++条件变量的wait()方法有两种形式:带Lambda谓词的版本会自动循环检查条件,防止虚假唤醒,等价于手动编写的while(!condition) cv.wait(lock);而不带Lambda的版本需要开发者自行处理条件检查和循环,容易因遗漏循环导致错误。Lambda版本更安全且代码简洁,两种方式性能相同,强烈推荐优先使用带Lambda的写法。典型应用场景包括生产者-消费者模型和初始化完成通知等同步操作。
2025-06-05 17:13:37
165
原创 C++条件变量中`wait()`的用法总结
摘要:std::condition_variable::wait()是C++多线程编程中的关键同步机制,必须配合互斥锁使用以确保线程安全。它提供两种形式:无谓词形式需手动处理虚假唤醒,而带谓词形式则自动处理循环检查。典型应用包括生产者-消费者模型和初始化通知场景。使用时需注意锁管理(必须用unique_lock)、通知时机和虚假唤醒问题。最佳实践为获取锁→检查条件→等待通知→重新检查条件→处理数据的模式,配合notify_one/all实现高效线程同步,必要时可采用超时等待优化性能。
2025-06-05 17:11:28
743
原创 C++右值引用与移动语义超快速入门
C++右值引用(&&)和移动语义是提升性能的关键技术。右值引用用于标识临时对象,移动语义则通过移动构造函数和移动赋值运算符实现资源高效转移,避免深拷贝。核心机制是从临时对象"窃取"资源(如指针),并将原对象置空。实用技巧包括使用std::move强制移动左值,以及将移动操作标记为noexcept。典型应用场景包括容器插入临时对象、函数返回值和智能指针资源转移。二者结合实现了C++中临时对象的高效处理,显著提升程序性能。
2025-06-05 16:59:38
244
原创 C++中`noexcept`的作用与应用场景
noexcept是C++11引入的关键字,用于声明函数不会抛出异常,具有性能优化和增强移动语义安全性的重要作用。语法分为无条件noexcept和条件性noexcept两种形式。核心价值在于优化函数调用、支持标准库容器的移动操作,以及明确接口契约。移动构造函数特别需要noexcept标记,否则标准库会退回到拷贝构造。最佳实践包括对移动操作、析构函数等标记noexcept,但需避免滥用导致程序意外终止。noexcept相比旧式throw()规范具有编译时检查的优势,是C++异常处理机制的重要改进。
2025-06-05 16:52:47
302
原创 C++中的锁机制详解及应用场景
C++多线程编程中的锁机制是确保线程安全的核心工具。标准库提供了多种锁类型(mutex、recursive_mutex、timed_mutex等)和锁包装器(lock_guard、unique_lock、shared_lock),各有不同特性和适用场景。其中,unique_lock功能最强大,支持超时锁定、手动解锁和所有权转移,但开销较大;而lock_guard轻量高效,适合简单锁定场景。最佳实践应根据具体需求选择锁类型,如简单作用域用lock_guard,需要灵活控制则用unique_lock,读多写少场
2025-06-05 16:45:44
860
原创 std::atomic的 load()方法详解
摘要:std::atomic提供了load()方法用于线程安全读取原子变量,同时还支持隐式转换语法(如bool value = atomic_var;)。核心操作包括load、store及算术修改方法。查阅API可通过cppreference文档、IDE自动补全或查看<atomic>头文件。原子操作比互斥锁更轻量,但仅适合简单场景,复杂状态仍需mutex。最佳实践包括优先简洁语法、合理指定内存序,并避免原子类型滥用。官方文档和权威书籍是学习并发编程的重要资源。(149字)
2025-06-05 16:40:06
841
原创 第5.1章 自动驾驶工程实战:如何将INS传感器在ENU坐标系下的速度转换为车身RFU坐标系下的速度?
本文详细介绍了机器人及自动驾驶中坐标系转换的原理与应用。重点分析了ENU(东-北-上)和RFU(右-前-上)两种坐标系,以及使用四元数进行坐标系旋转转换的方法。文章指出,通过四元数的逆操作可以正确实现ENU到RFU的速度向量转换,并具体解析了代码实现过程,包括速度分量提取和转换验证。最后强调了四元数归一化、坐标系一致性和性能优化等注意事项,为自动驾驶系统中的坐标系转换提供了实用的技术指导。
2025-06-05 16:16:25
15
原创 你知道C++中std::bind与Lambda的区别吗?有了lambda后bind还有多大意义?
本文对比了C++中std::bind与Lambda的差异与应用场景。std::bind作为函数适配器,主要用于绑定成员函数和参数预绑定,而Lambda通过捕获列表实现闭包,语法更简洁。性能上Lambda更具优势,调用开销更低。现代C++建议优先使用Lambda,但std::bind仍适用于参数重排和旧代码兼容等特定场景。开发者应根据需求选择合适方式,但Lambda因其简洁高效已成为主流选择。
2025-06-05 16:12:48
242
原创 你知道C++线程std::thread是如何区分 Lambda 与成员函数的吗?
Lambda 是自包含的函数对象捕获this后,Lambda 内部可以直接访问成员变量和方法,无需外部传递对象指针。成员函数依赖对象实例调用成员函数必须通过对象或指针,因此需要显式传递。编译时类型检查在编译时根据参数类型生成不同的调用逻辑,确保正确传递对象指针(如果需要)。通过这种设计,C++ 既保持了类型安全,又提供了灵活的语法,让开发者可以根据场景选择最适合的线程创建方式。
2025-06-05 15:47:25
354
原创 你知道在使用c++多线程std::thread()时到底要传入几个参数吗?
std::thread的参数数量由线程函数类型决定: 普通函数:函数指针+实参(总参数量=函数参数+1) 成员函数:成员函数指针+对象指针+实参(总参数量=函数参数+2) 函数对象/Lambda:函数对象+实参(总参数量=调用参数+1) 关键注意事项: 传递对象需确保生命周期安全 默认参数会拷贝,引用传递需用std::ref 优先使用Lambda可简化参数传递 (字数:98)
2025-06-05 15:45:22
240
原创 你知道C++多线程编程实际工作中有哪几种实现方式吗?
场景特征推荐实现方式简单独立任务直接函数指针需要访问类成员类成员函数需要捕获局部变量Lambda表达式需要异步返回值std::async保护复杂共享资源高频计数器/标志位生产者-消费者模型读多写少场景大量短耗时任务线程池需要异步结果的计算。
2025-06-05 15:00:58
961
原创 你知道std::atomic<bool> 与普通 bool`的区别及atomic背后原理吗?
std::atomic<bool>与普通bool的核心差异在于原子性、内存序和线程安全。普通bool的读写操作可能被中断且无法避免重排序,而std::atomic<bool>通过CPU原子指令确保操作的不可分割性,并提供多种内存序选项(如release/acquire)控制执行顺序。在性能上,std::atomic<bool>的无锁特性明显优于加锁的普通bool,适合实现线程间标志位或无锁算法。关键结论:多线程环境下应优先使用std::atomic<bool>
2025-06-05 14:18:53
599
原创 C++多线程入门实战:你知道C++ 条件多线程需要哪些头文件以及知道如何编写多线程吗?
摘要:C++中实现多线程同步需包含3个核心头文件: <thread>:提供线程管理功能(如std::thread); <mutex>:实现互斥锁(std::mutex、std::lock_guard); <condition_variable>:支持条件变量(wait()/notify机制)。 典型应用如生产者-消费者模型,需结合互斥锁和条件变量协调线程操作。复杂场景可扩展使用<atomic>或<future>等库。示例代码展示了缓冲区同步控制的完
2025-06-05 14:06:29
262
原创 你知道什么时候用uint32_t 和 size_t吗?它们有什么区别?
uint32_t是C++11标准中定义的固定宽度无符号整数类型,明确表示32位无符号整数,定义在<cstdint>头文件中。精确的数值类型,用于存储32位无符号整数。size_t是C++标准中定义的与平台相关的无符号整数类型,通常用于表示内存大小、数组索引等。依赖平台的别名,实际类型可能是或(取决于编译器和系统)。特性uint32_tsize_t定义来源<cstdint>(C++11标准)C++标准内置类型别名数据宽度固定32位(4字节)32位系统4字节,64位系统8字节平台相关性。
2025-06-04 11:14:48
408
原创 第12.5章 PCL工程实战:你知道NDT匹配参数调试取值一般怎么取值吗?
本文介绍了NDT点云配准算法的关键参数及其调优方法。参数包括网格分辨率ndt_resolution(影响精度与速度)、迭代步长ndt_step_size(平衡收敛速度与稳定性)、收敛阈值ndt_transformation_epsilon(控制终止条件)和最大迭代次数ndt_maximum_iterations(限制计算时长)。针对不同应用场景,文章建议粗配准阶段使用较大网格和步长,精配准时调小参数提高精度;实时应用可降低分辨率减少计算量,高噪声环境则需增大网格尺寸增强鲁棒性。合理配置这些参数可有效优化ND
2025-06-04 10:57:08
776
原创 第12.4章 PCL工程实战:你知道创建并初始化PCL点云的智能指针时到底要不要加括号()呢?
本文对比了两种C++初始化智能指针的方式:显式构造(new T())和隐式构造(new T)。对于类类型,两种方式等效,均调用默认构造函数。现代C++推荐省略空括号,因其更简洁且避免歧义。更优方案是使用C++11的make_shared,兼具安全和效率。主要区别在于内置类型的初始化行为,但对类对象无差异。建议遵循现代C++风格,优先使用隐式构造或智能指针工厂方法。
2025-06-04 09:57:15
149
原创 第12.3章 你知道PCL库为何loadPCDFile函数返回0表示成功,返回-1表示失败吗?
C++函数返回0表示成功、非零值表示失败的约定起源于C语言和Unix系统设计。PCL库遵循这一传统,使用0表示成功,-1表示通用错误,以保持简洁性和兼容性。相比布尔值或异常机制,整数返回值能提供更丰富的错误信息。尽管现代C++引入改进方案,PCL仍沿用传统方式便于集成。这种设计体现了C/C++社区的一致性原则,建议开发者养成检查返回值的习惯以确保程序健壮性。(149字)
2025-06-03 16:43:56
81
原创 第12.2章 PCL实战:你知道在类中初始化 pcl::PointCloud`智能指针成员变量有哪几种方式吗?
摘要:PCL点云智能指针成员变量的初始化方式有多种。(1)推荐使用构造函数初始化列表,简洁高效;(2)C++11后可选用std::make_shared或成员变量声明时直接初始化,代码更简洁;(3)复杂初始化可采用工厂函数封装;(4)特殊场景可考虑从文件加载数据。最佳实践优先选择初始化列表结合std::make_shared,既符合现代C++规范又能保证性能。所有方法均能正确初始化点云指针,开发者可根据具体场景选择最合适的方式。(150字)
2025-06-03 15:59:06
274
原创 你知道CMake怎么用get_filename_component函数解析文件路径的各个组成部分(如目录、文件名、扩展名等),或生成绝对路径吗
get_filename_component是CMake中用于解析文件路径的核心命令,主要功能包括获取绝对路径、提取目录/文件名/扩展名等。其基本语法为get_filename_component(<VAR> <FileName> <COMPONENT> [CACHE]),支持ABSOLUTE、PATH、NAME、EXT等组件类型。典型应用场景包括路径规范化、文件名分割、动态路径生成等。使用时需注意路径相对性、文件存在性检查以及缓存变量作用域等问题,常与file(GLOB
2025-05-30 15:40:56
277
原创 第3.7.1章 Protocol Buffers在机器人自动驾驶中的工程应用,附代码实例
摘要:Protocol Buffers(Protobuf)在机器人自动驾驶系统中发挥着核心作用,解决了异构模块间高效数据传输的挑战。相比ROS消息,Protobuf具有序列化效率高、跨语言兼容性强、扩展性好等优势,适用于传感器数据处理、模块间通信及数据记录等场景。实践表明,合理设计消息结构并优化性能后,Protobuf能显著提升自动驾驶系统的处理效率和可靠性,同时保持与ROS生态的无缝集成。
2025-05-30 11:20:08
151
原创 第3.7 章 Google开源数据协议Protocol Buffers 概述及代码入门
Protocol Buffers(简称Protobuf)是Google开发的一种语言无关、平台无关、可扩展的序列化数据格式。它通过定义数据结构(.proto文件),生成高效的序列化代码,广泛用于通信协议、数据存储等场景。在机器人自动驾驶系统工程中,Protocol Buffers(简称 Protobuf)作为核心数据传输与存储方案,发挥着至关重要的作用。核心优势高性能:序列化/反序列化速度远快于XML/JSON二进制格式:数据体积小,传输效率高强类型:编译时类型检查,减少运行时错误向后兼容。
2025-05-30 11:15:01
19
原创 CMake中如何使用macro和file递归搜索指定目录下的所有C/C++源文件和头文件,避免手写所有文件?
这段CMake代码定义了一个名为的宏,用于递归搜索指定目录下的所有C/C++源文件和头文件,并将结果存储在指定变量中。其核心作用是自动收集项目源文件,避免在CMakeLists.txt中手动列出每个文件。macro:用于创建可复用的CMake代码片段,通过参数传递增强灵活性:递归搜索文件的便捷方式,但需注意缓存问题学习资源:官方文档、社区项目和IDE自动补全是掌握CMake的关键工具最佳实践:小型项目可使用GLOB,大型项目建议手动管理源文件列表。
2025-05-30 10:49:01
560
原创 第4.2章 手把手教你读懂ORB-SLAM3 位姿优化函数PoseOptimization,以及如何添加GPS或轮速等观测进行优化
本文介绍了ORB-SLAM3系统中位姿优化函数PoseOptimization的实现原理与方法。该函数通过3D-2D投影关系建立最小二乘问题,优化当前帧的相机位姿。文章详细解析了优化器的构建步骤:首先建立稀疏优化器和Levenberg算法;然后添加当前帧位姿作为顶点;接着构建单目/双目重投影误差边;最后通过4次迭代优化(每次10次迭代)更新位姿。优化过程中采用卡方检验剔除异常值,优化结果包含内点数量、内外点标记和更新后的位姿。该方法为ORB-SLAM3融合GPS等传感器提供了优化基础。
2025-05-29 15:42:33
312
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人