gflag
先看DEFINE
宏,有三个宏:flag的名称,flag的默认值,help字符串。如何查看help信息呢,在执行可执行文件时加上–help选项即可,但是如果要显示help信息,代码里需要调用接口gflags::ParseCommandLineFlags(&argc, &argv, true)
gflags支持的变量类型如下:
- DEFINE_bool: 布尔类型
- DEFINE_int32: 32-bit 整型
- DEFINE_int64: 64-bit 整型
- DEFINE_uint64: 无符号 64-bit 整型
- DEFINE_double: double
- DEFINE_string: C++ string
在程序中使用flag,对于DEFINE过的flag我们可以像使用普通变量那样读写它,只需加一个FLAGS_
前缀即可,如下:1
2
3
4
5
6
7
8if (FLAGS_is_handsome)
FLAGS_is_handsome = false;
std::cout << FLAGS_hobby << std::endl;
DEFINE_string(configuration_directory, "",
"First directory in which configuration files are searched, "
"second is always the Cartographer installation to allow "
"including files from there.");
1 | CHECK_EQ(x,y) == |
glog
Google glog是一个基于程序级记录日志信息的c++库,编程使用方式与c++的stream操作类似。 每个级别的日志除了输出到对应日志文件中,还输出到每个低级别日志文件中。默认ERROR和FATAL消息除了输出到日志文件中之外,还会输出到标准错误中
每个级别都对应有相应的日志文件,文件默认存放在临时文件中,Linux是 /tmp
。运行cartographer之后,可以在/tmp
里看到
glog的库文件都在/usr/lib/x86_64-linux-gnu
自定义cartographer的日志格式
glog
的明显缺点就是配置输出格式不方便,还要修改源码的logging.cc
,重新编译。我下载glog 0.5.0
后,修改logging.cc文件再编译安装,结果导致cartographer报错,ScopedRosLogSink::send
没有链接,应当是和现有的glog造成了冲突,然后一直解决不了。
然后尝试在ros_log_sink.cc
中添加函数,就是把::google::LogSink::ToString
重新定义到ros_log_sink.cc
,这样避开glog的链接问题。头文件当然也要添加这个成员函数1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20string ScopedRosLogSink::ToString(const ::google::LogSeverity severity, const char* file, int line,
const struct ::tm* tm_time,
const char* message, size_t message_len)
{
ostringstream stream(string(message, message_len));
stream.fill('0');
stream << '['
<< setw(2) << 1+tm_time->tm_mon
<< '_'
<< setw(2) << tm_time->tm_mday
<< " "
<< setw(2) << tm_time->tm_hour << ':'
<< setw(2) << tm_time->tm_min << ':'
<< setw(2) << tm_time->tm_sec << " "
<< file << ": " << line << "] ";
stream << string(message, message_len);
return stream.str();
}tm_time
只精确到秒,这样日志就不能精确到毫秒了,不过目前还不需要。ScopedRosLogSink::send
的开头改为ToString
函数。这样改完后,日志格式可能还不是想要的
后来才发现原来cartographer的日志格式是把glog的格式和ROS的格式融合一起了,所以修改环境变量如下1
export ROSCONSOLE_FORMAT='[${message}'
几个常用参数
1 | FLAGS_logtostderr = true; // 设置日志消息是否转到标准输出而不是日志文件 |
cartographer的大部分文件都可以直接使用LOG(INFO)<<"log";
这样的语句,因为都提前配置好了,但是最好重新指定日志路径。
google::SetLogDestination(google::INFO, "log/INFO_");
// 设置特定级别的日志的输出目录和前缀。第一个参数为日志级别,第二个参数表示输出目录及日志文件名前缀
1 |
|
每次运行cartographer后发现在自定义的路径里,INFO开头的日志文件每次都会新建,而INFO结尾的日志是最新运行得到的日志