【Apollo源码分析】系列的第一部分【common】

本文是Apollo源码分析系列的第一篇,聚焦于Common模块。介绍了macro.h中的宏定义,如DISALLOW_COPY_AND_ASSIGN,以及log.h中使用glog的日志库。讨论了time.h中的时间管理,特别是Clock类。还涵盖了util包下的文件操作、字符串处理和工厂模式。此外,提到了Adapter管理和VehicleState类,以及Monitor模块的监控功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【Apollo源码分析】系列的第一部分【common】

源码分析

Apollo 整体上由13个模块构成,分别是

 
 
 
  1. canbus -汽车CAN总线控制模块
  2. common - 公有的源码模块
  3. control -控制模块
  4. decision -决策模块
  5. dreamview -可视化模块
  6. drivers -驱动模块
  7. hmi -人机交互模块
  8. localization-定位模块
  9. monitor -监控模块
  10. perception -感知模块
  11. planning -运动规划模块
  12. prediction -预测模块
  13. tools -通用监控与可视化工具

Apollo采用bazel 作为代码编译构建工具。 
每个源码文件夹下有一个BUILD文件,作用是按照bazel的格式来编译代码。 
关于如何使用bazel编译c++代码,可以查看以下网址: 
【1】https://docs.bazel.build/versions/master/tutorial/cpp.html 
【2】https://docs.bazel.build/versions/master/tutorial/cpp-use-cases.html


ok。现在开始分析源码。系列文章的第一篇,首先分析modules/common目录下面的源码。

modules/common/macro.h


宏定义 DISALLOW_COPY_AND_ASSIGN:

 
 
 
  1. #define DISALLOW_COPY_AND_ASSIGN(classname) \
  2. private: \
  3. classname(const classname &); \
  4. classname &operator=(const classname &);
用于在C++中禁止class的拷贝构造函数和赋值构造函数,良好的c++代码应该主动管理这2个操作符。
在caffe和cartographer或者其他的著名库中均有类似的操作。

宏定义 DISALLOW_IMPLICIT_CONSTRUCTORS:

 
 
 
  1. #define DISALLOW_IMPLICIT_CONSTRUCTORS(classname) \
  2. private: \
  3. classname(); \
  4. DISALLOW_COPY_AND_ASSIGN(classname);
禁止class的无参构造函数。

宏定义 DECLARE_SINGLETON:

 
 
 
  1. #define DECLARE_SINGLETON(classname) \
  2. public: \
  3. static classname *instance() { \
  4. static classname instance; \
  5. return &instance; \
  6. } \
  7. DISALLOW_IMPLICIT_CONSTRUCTORS(classname) \
单例类定义,instance() 返回指向同一个class对象的指针。禁止拷贝/赋值运算符。

modules/common/log.h

apollo内部使用谷歌的glog作为日志库。 
有5个日志级别,分别是DEBUG,INFO,WARNING,ERROR,FATAL。

 
 
 
  1. #include "glog/logging.h"
  2. #define ADEBUG VLOG(4) << "[DEBUG] "
  3. #define AINFO VLOG(3) << "[INFO] "
  4. #define AWARN LOG(WARNING)
  5. #define AERROR LOG(ERROR)
  6. #define AFATAL LOG(FATAL)

modules/common/time/time.h

apollo内部使用c++ 11的 chrono库作为时间管理工具。默认精度是纳秒(1e-9). 
std::chrono::duration 表示时间间隔大小。 
std::chrono::time_point 表示时间中的一个点。

定义2个别名:

  • Duration,1纳秒,1e-9s。
  • Timestamp,以纳秒ns为单位的时间点。
全局函数:
  • int64_t AsInt64(const Duration &duration)
 
 
 
  1. 将纳秒ns转换为以PrecisionDuration为精度单位计的int64整数。
  • int64_t AsInt64(const Timestamp &timestamp) :
 
 
 
  1. Timestamp(时间点)转换为64位整数表示。
  • double ToSecond(const Duration &duration) :
 
 
 
  1. 将纳秒ns转换为秒s
  • inline double ToSecond(const Timestamp &timestamp) :
 
 
 
  1. 将以纳秒表示的时间点ns转换为秒s
  • Timestamp FromInt64(int64_t timestamp_value) :
 
 
 
  1. 将以PrecisionDuration为精度计的int64整数转换为Timestamp(时间点)。
  • Timestamp From(double timestamp_value):
 
 
 
  1. 将秒s转换为时间点Timestamp。即FromInt64的特化版本:先将时间转换为ns计的64位整数nanos_value,再转换为Timestamp

Clock 类:

Clock是封装c++ 11 chrono后抽象的时钟计时类class。

是线程安全的单例模式(c++ 11的语法可确保)。

数据成员:

 
 
 
  1. bool is_system_clock_; true表示系统时间,false表示模拟时间
  2. Timestamp mock_now_; 模拟时间的当前值。

为啥要标记模拟时间?:为了仿真训练。多次仿真,反复训练。 
Clock类没有公有的构造函数。私有构造函数初始化为使用cpu的系统时间。

Clock提供4个static 公有函数:

 
 
 
  1. static Timestamp Now()
  2. 返回当前时间的最新值。
  3. static void UseSystemClock(bool is_system_clock)
  4. 设置是否使用模拟时间。
  5. static bool IsSystemClock()
  6. 返回是否使用系统时间。
  7. static void SetNow(const Duration &duration)
  8. Clock使用mock时间时,将系统时间设定为给定值。
  9. 否则抛出运行时错误。(只有模拟时间才可调整值,系统时间不可调整)

modules/common/time/time_test.cc

 
 
 
  1. Duration duration = std::chrono::milliseconds(12); //12ms
  2. EXPECT_EQ(12000, AsInt64<micros>(duration)); //==121000us
 
 
 
  1. Duration duration = std::chrono::microseconds(1234567);//1234567us
  2. EXPECT_EQ(1234, AsInt64<millis>(duration)); //==1234ms
 
 
 
  1. Duration duration = std::chrono::microseconds(123 456 789 012);//123...us
  2. EXPECT_FLOAT_EQ(123456.789012, ToSecond(duration)); //123456(s)
  3. ...略.
 
 
 
  1. EXPECT_TRUE(Clock::IsSystemClock()); //默认是cpu系统时间
  2. Clock::UseSystemClock(false); //修改。
  3. EXPECT_FALSE(Clock::IsSystemClock());
  4. EXPECT_EQ(0, AsInt64<micros>(Clock::Now())); //模拟时间的初值是0.
  5. Clock::SetNow(micros(123)); //修改为123 (us)
  6. EXPECT_EQ(123, AsInt64<micros>(Clock::Now()));

modules/common/util/util.h

函数原型:

 
 
 
  1. bool EndWith(const std::string &original, const std::string &pattern);
  • 当original字符串以 pattern 结尾时,返回true

  •  测试代码,util_test.cc:

 
 
 
  1. EXPECT_TRUE(EndWith("abc.def", "def"));
  2. EXPECT_TRUE(EndWith("abc.def", ".def"));
  3. EXPECT_FALSE(EndWith("abc.def", "abc"));
  4. EXPECT_FALSE(EndWith("abc.def", "de"));

modules/common/util/file.h

file.h提供了多个关于操作文件(关于protobuf文件的读,写,删)的函数。 
都是模板类函数:

 
 
 
  1. template <typename MessageType>
  •  (1). 将message存储到filename中,以ascii格式存储.
 
 
 
  1. bool SetProtoToASCIIFile(const MessageType &message,
  2. const
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值