cartographer 学习
编译并运行代码
由于cartographer整体分成了两个包
- 一个是cartographer,不带ros的内容
- 另一个是cartographer_ros,是已ros项目构建的
这样因为带了普通cmake的包,就没法使用catkin_make
了,只能使用catkin_make_isolated
编译:catkin_make_isolated --install --use-ninja
catkin_make_isolated
会生成三个目录:
- build_isolated
- devel_isolated
- install_isolated
其中所有的launch文件会被复制一份到install_isolated的share中。
也就是修改cartographer_ros
中的launch文件,需要再编译一次才会生效(这里编译其实就是再拷一份文件),而catkin_make
修改launch文件是不需要重新编译的
编译后source一下对应目录,然后启动就好了:
roslaunch cartographer_ros demo_backpack_2d.launch bag_filename:=${HOME}/Downloads/cartographer_paper_deutsches_museum.bag
启动demo的launch文件分析
demo_backpack_2d.launch
<launch><param name="/use_sim_time" value="true" /><include file="$(find cartographer_ros)/launch/backpack_2d.launch" /><node name="rviz" pkg="rviz" type="rviz" required="true"args="-d $(find cartographer_ros)/configuration_files/demo_2d.rviz" /><node name="playbag" pkg="rosbag" type="play"args="--clock $(arg bag_filename)" />
</launch>
param
是设置参数服务器,/use_sim_time
设置成true
是播放bag是使用仿真时间include
是添加其它的launch配置文件node
是启动节点,启动了rviz
,并且required="true"
是必须要启动成功,如果rviz
节点无法正常启动,launch文件将会终止运行并报错。-d
设置rviz的配置文件- 还启动了
playbag
节点,用于播放包,其中参数$(arg bag_filename)
是执行roslaunch
时指定的
backpack_2d.launch
<launch><param name="robot_description"textfile="$(find cartographer_ros)/urdf/backpack_2d.urdf" /><node name="robot_state_publisher" pkg="robot_state_publisher"type="robot_state_publisher" /><node name="cartographer_node" pkg="cartographer_ros"type="cartographer_node" args="-configuration_directory $(find cartographer_ros)/configuration_files-configuration_basename backpack_2d.lua"output="screen"><remap from="echoes" to="horizontal_laser_2d" /></node><node name="cartographer_occupancy_grid_node" pkg="cartographer_ros"type="cartographer_occupancy_grid_node" args="-resolution 0.05" />
</launch>
- 设置了参数
robot_description
,值是文本文件,这个参数用于提供机器人的URDF描述。 - 运行了节点
robot_state_publisher
,用于将机器人的关节状态发布为tf
变换。 - 运行了节点
cartographer_node
,输入参数给了一个lua配置文件 <remap>
标签用于重新映射节点的话题,将echoes
话题重映射为horizontal_laser_2d
话题。这样订阅echoes
可以很方便的更改为horizontal_laser_2d
而不需要重新编译- 运行了节点
cartographer_occupancy_grid_node
用来生成占据网格地图,设置了参数resolution
,网格分辨率是0.05m
查看相应信息
使用rqt_graph
可以查看节点连接情况
使用gflag库读取输入参数
GFlag
库是Google开发的一个命令行参数解析库,它提供了一种方便的方式来定义和解析命令行参数。它的实现原理涉及到解析命令行参数、存储参数值以及提供访问参数值的接口。
总共分成几步:
- 使用
DEFINE_type
定义好变量和类型,默认值,解释 - 将
argc/argv
传入解析内容,gflags::ParseCommandLineFlags(&argc, &argv, true);
- 执行可执行文件并传入参数
./my_program --verbose --count=10
- 使用参数是大写的
FLAGS_
+对应的变量名
,比如FLAGS_verbose
下面是一个简单的使用示例:
#include <gflags/gflags.h>
#include <iostream> DEFINE_bool(verbose, false, "Enable verbose output");
DEFINE_int32(count, 0, "Number of iterations"); int main(int argc, char* argv[]) { // 初始化GFlag库 gflags::ParseCommandLineFlags(&argc, &argv, true); // 使用定义的命令行参数 if (FLAGS_verbose) { std::cout << "Verbose output enabled" << std::endl; } std::cout << "Running " << FLAGS_count << " iterations" << std::endl; // 其他代码... return 0;
}
运行和输出是:
$ ./my_program --verbose --count=10
Verbose output enabled
Running 10 iterations