最近项目上需要用到cartographer,于是把一些东西写下来,防止以后忘记了。
cartographer为了拓展性和易用性,使用了ROS作为传感器和机器人的接口,又用了谷歌的ceres solver进行优化。对于slam优化的库现在主流的主要是两个,ceres solver和g2o。对于ceres solver的教程以后再说。
ROS作为一个越来越主流的机器人操作系统,对于一些小项目的开发是很有帮助的,其中定义的一些数据接口和驱动很多都可以直接调用。同时对于机器人仿真,也有由于扩展的优势。但是其劣势是所需运行内存太大,运行需要占用很多资源,这对于一些嵌入式项目的开发和一些面向工业的机器人开发还是会有很多问题。而且只有一个master的结构崩掉之后系统就是死掉的状态,据说这些在ROS 2.0上有一些改进。
话说回来,在cartographer_ros中,首先要启动的是launch文件,根据具体需求,cartographer_ros源码中有很多launch文件,其中对于启动的节点有具体要求。并配合lua文件对系统进行配置。
<node name="cartographer_node" pkg="cartographer_ros"
type="cartographer_node" args="
-configuration_directory $(find cartographer_ros)/configuration_files
-configuration_basename backpack_3d.lua"
output="screen">
通过launch文件,启动cartograpehr_node,打开cartographer_node主程序
int main(int argc, char** argv) {
google::InitGoogleLogging(argv[0]);
google::ParseCommandLineFlags(&argc, &argv, true);
CHECK(!FLAGS_configuration_directory.empty())
<< "-configuration_directory is missing.";
CHECK(!FLAGS_configuration_basename.empty())
<< "-configuration_basename is missing.";
::ros::init(argc, argv, "cartographer_node"); //Cartographer_node(node_name)
::ros::start();
cartographer_ros::ScopedRosLogSink ros_log_sink; //Log System
cartographer_ros::Run();
::ros::shutdown();
}
通过cartographer_ros::run()进入Run()这个全局函数。
在Run()中,首先加载lua项和tf关系,之后进行node.Initialize(),之后接受各种传感器信息,主要是激光、imu、以及里程计,通过trajectory_builder_->AddImuData 和trajectory_builder_->AddHorizontalLaserFan调用信息构建地图,最后使用spin()函开始ROS消息回调处理函数,开始进行整个程序进程。