livox_ros_driver2 日志系统工作原理解析:DRIVER_INFO/DRIVER_ERROR 宏设计的完整指南
2026/9/20 23:56:12 网站建设 项目流程

livox_ros_driver2 日志系统工作原理解析:DRIVER_INFO/DRIVER_ERROR 宏设计的完整指南

【免费下载链接】livox_ros_driver2Livox device driver under Ros(Compatible with ros and ros2), support Lidar HAP and Mid-360.项目地址: https://gitcode.com/GitHub_Trending/li/livox_ros_driver2

livox_ros_driver2 是乐鑫(Livox)官方第二代激光雷达 ROS 驱动,同时兼容 ROS 与 ROS2,支持 HAP、MID360 等机型。它通过 DRIVER_INFO、DRIVER_ERROR 等日志宏实现统一的日志输出,让同一份业务代码在两种框架下无缝编译运行。本文将带你快速看懂这套日志系统的工作原理。

一、为什么需要 DRIVER_INFO / DRIVER_ERROR 日志宏?🔍

ROS1 和 ROS2 的日志 API 完全不同:

  • ROS1使用ROS_INFO()ROS_ERROR()等全局宏,底层基于ros::console
  • ROS2使用RCLCPP_INFO(logger, ...)等宏,每条日志都必须绑定一个节点自带的 logger。

如果业务代码直接调用原生宏,就得为 ROS1/ROS2 各维护一套代码。livox_ros_driver2 的解法很巧妙:定义一层DRIVER_前缀的日志宏作为统一日志接口,把平台差异全部收进头文件里,业务代码一行都不用改。

二、日志宏的整体架构:3 个头文件的分工

日志系统的核心是 src/include/ 下的 3 个头文件:

文件职责
ros_headers.h总入口,根据编译开关自动选择 ROS1 或 ROS2 头文件
ros1_headers.h定义 ROS1 版的 DRIVER_ 系列日志宏
ros2_headers.h定义 ROS2 版的 DRIVER_ 系列日志宏

ros_headers.h 的核心逻辑只有几行条件编译:

#ifdef BUILDING_ROS1 #include "ros1_headers.h" #elif defined BUILDING_ROS2 #include "ros2_headers.h" #endif

也就是说,编译期BUILDING_ROS1/BUILDING_ROS2这两个开关决定日志宏展开到哪一套 API,而业务代码只看到统一的DRIVER_*名称。

三、DRIVER_INFO / DRIVER_ERROR 宏在不同平台下的展开方式

ros1_headers.h 中的定义非常直接,把 node 参数直接忽略掉:

#define DRIVER_INFO(node, ...) ROS_INFO(__VA_ARGS__) #define DRIVER_ERROR(node, ...) ROS_ERROR(__VA_ARGS__)

而 ros2_headers.h 中,node 参数派上了用场——取节点的 logger 传给 RCLCPP 宏:

#define DRIVER_INFO(node, ...) RCLCPP_INFO((node).get_logger(), __VA_ARGS__) #define DRIVER_ERROR(node, ...) RCLCPP_ERROR((node).get_logger(), __VA_ARGS__)

这就是同一个调用DRIVER_INFO(livox_node, "xxx")在两端都能编译的关键:ROS1 端 node 被丢弃,ROS2 端 node 被用来获取 logger

EXTRA 变体:一次/节流输出技巧

两个头文件里还各有一套_EXTRA宏,例如 DRIVER_INFO_EXTRA。它利用 C 预处理的##记号拼接能力,把中间参数拼进宏名:

#define DRIVER_INFO_EXTRA(node, EXTRA, ...) RCLCPP_INFO_##EXTRA((node).get_logger(), __VA_ARGS__)

这样就能灵活展开成RCLCPP_INFO_ONCE(只打印一次)、RCLCPP_INFO_THROTTLE(节流打印)等原生变体,非常适合高频数据流中避免日志刷屏的场景。

四、编译期开关:CMake 如何决定日志走向

开关来自 CMakeLists.txt 中的编译定义:

  • ROS1 构建时注入-DBUILDING_ROS1(见 CMakeLists.txt)
  • ROS2 构建时注入-DBUILDING_ROS2(见 CMakeLists.txt)

构建脚本根据 ROS1 / ROS2 / humble / jazzy 等不同参数选择分支,最终只有对应的日志宏集合生效。整个链路是:

构建脚本 → CMake 定义宏 → ros_headers.h 条件包含 → 平台专属日志宏 → ROS/ROS2 原生日志系统

五、源码中的真实日志调用示例

节点类型定义在 driver_node.h 中,ROS1 下DriverNode继承ros::NodeHandle,ROS2 下继承rclcpp::Node——这正是两种平台都能调用.get_logger()的前提。

在主入口 livox_ros_driver2.cpp 中能看到典型用法:

  • 启动时打印版本:DRIVER_INFO(livox_node, "Livox Ros Driver2 Version: %s", ...)(第 51 行)
  • 打印配置信息:DRIVER_INFO(*this, "Config file : %s", user_config_path.c_str())(第 167 行)
  • 初始化失败报错:DRIVER_ERROR(*this, "Init lds lidar fail!");(第 178 行)
  • 参数非法提示:DRIVER_ERROR(livox_node, "Invalid data src (%d), please check the launch file", data_src);(第 105 行)

另外,ROS1 分支在main()开头还会主动把日志级别调高到 Debug(第 42-44 行),方便用户排查问题时看到更详细的输出。数据分发模块 lddc.cpp 中也大量使用DRIVER_INFO打印 bag 文件创建、多话题模式等状态信息(如 第 189 行)。

六、新手上手建议 💡

  1. 看日志级别选型:正常状态用DRIVER_INFO,可恢复的异常用DRIVER_WARN,致命问题用DRIVER_ERROR/DRIVER_FATAL,与 ROS 日志级别一一对应;
  2. 高频路径慎用 INFO:点云回调中每帧都打印会刷屏,可参考_EXTRA变体的思路使用节流或一次性输出;
  3. 排查启动问题:程序启动时版本、Config fileData Source三条 INFO 日志是最快的自检清单,任何一条缺失都说明配置或参数有问题;
  4. 阅读源码路径:想深入日志设计,按 ros_headers.h → ros1_headers.h / ros2_headers.h 的顺序阅读即可,全文不超过 100 行。

这套"统一宏名 + 条件编译分流"的设计,是 livox_ros_driver2 能一份源码同时支持 ROS 和 ROS2 的关键技巧之一,也很适合你在自己的双框架兼容项目中借鉴。

【免费下载链接】livox_ros_driver2Livox device driver under Ros(Compatible with ros and ros2), support Lidar HAP and Mid-360.项目地址: https://gitcode.com/GitHub_Trending/li/livox_ros_driver2

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询