# cartographer_standalone **Repository Path**: xiaojake/cartographer_standalone ## Basic Information - **Project Name**: cartographer_standalone - **Description**: 实现Cartographer与Cartographer_ros剥离,剥离后的Cartographer可以在不启动roscore的情况下正常建图,同时可与ROS进行通讯。 https://blog.csdn.net/zhzwang/article/details/109311339 - **Primary Language**: C++ - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 3 - **Forks**: 13 - **Created**: 2021-04-06 - **Last Updated**: 2025-08-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # cartographer_standalone 终极版 ## 11.30 更新 1、恢复(重写)了原版poll_manager,完善了多线程下智能指针调用和内存空间回收功能,并使用官方测试工具test通过。 2、完成了11.07的1/2 Flag. ![测试成功](https://gitee.com/harryzhangabc/cartographer_standalone/raw/master/pic/screenshot11301708.jpg) ## 11.07 更新 1.完善了相关写法,加入了try{}catch{}以保证线程稳定性。 2.更新了任务列表,请完成任务并编写相关文档(.md)上传到gitee,我会把你的网址附在这里。 (1)测试11.06更新的多线程通讯程序,编译并执行程序(方法在11.06)。 (2)完成boost多线程回调的例程,要求:使用Boost库bind接口实现***非类成员函数***作为回调函数,并给出例程,然后再把相关源码发到gitee上。 程序要求:在cartographer_standalone下创建bind_test文件夹,把你写的源代码放在bind_test/src里面,h文件放在bind/include里面,编写CMakeLists.txt文件 ``` (CMakeLists.txt模板) cmake_minimum_required(VERSION 2.8.3) project(你的项目名字) # 用boost编程用它来寻找库 find_package(Boost REQUIRED COMPONENTS system thread) # .h文件放到/项目名称/include 里面 # .cpp文件放到/项目名称/src 里面 include_directories(include) file(GLOB SRCS *.cpp *.c) add_library(${CMAKE_PROJECT_NAME} STATIC ${SRCS}) set(libs ${Boost_LIBRARIES} boost_system rt) add_executable(你编译的文件名称 src/你的文件.cpp) target_link_libraries(read libs) ``` 然后,把你的程序,加到总的CMakeLists.txt里面! ``` (cartographer_standalone/CMakeLists.txt) ...... add_subdirectory(cartographer_ros/cartographer_ros_msgs) add_subdirectory(cartographer_ros/cartographer_ros) # 把你的驱动程序放到这里 add_subdirectory(halloworld) add_subdirectory(test_node_mem) add_subdirectory(你的文件夹名称(例如bind_test)) <------加入这个!!! # add_subdirectory(rplidar_ros) # add_subdirectory(path_to_your_sensor_driver) add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0) ...... ``` ## 11.06 更新 1.本次更新了在多线程环境下共享内存的机制(基于boost、realtime library),具体实现请查看ros_stub/node_manager.cpp 2.Boost多线程api使用例程请参考test_node_mem/read.cpp(读取线程)、test_node_mem/writer.cpp(写入线程) 3.本次更新的目的是完成任务计划二第一步,即创建节点管理器共享空间,接下来会用这个空间作为节点管理器的回调函数指针*fp保存空间来进行队列管理。 ```bash sudo add-apt-repository universe sudo apt update sudo apt install git cmake bzip2 libbz2-dev libceres-dev libprotobuf-dev protobuf-compiler libpcl-dev liburdfdom-headers-dev liburdfdom-model liblz4-dev libtinyxml-dev liburdfdom-dev liburdfdom-tools git clone https://gitee.com/harryzhangabc/cartographer_standalone ./cartographer_standalone/cartographer/scripts/install_debs_cmake.sh cd cartographer_standalone mkdir build && cd build cmake -DCMAKE_BUILD_TYPE=Debug -DFORCE_DEBUG_BUILD=True .. make -j24 #安装该软件,如果你已经安装请忽略 #(api测试步骤) #(新开一个终端) cd ~/cartographer_standalone/build/test_node_mem ./writer #(再新开一个终端) cd ~/cartographer_standalone/build/test_node_mem ./reader #观察多线程下的内存共享/通讯状态 ``` ### 编译状态 - [x] ubuntu18.04 - [ ] openeuler 20 等待测试 ## 11.01 V2.0更新 1.全面支持rosbridge(cpp)功能,可以和外部ros进行通讯了。 2.bug全面修复,make all成功。 3.支持dbg模式,具体如下: ```bash cd cartographer_standalone/build cmake -DCMAKE_BUILD_TYPE=Debug -DFORCE_DEBUG_BUILD=True .. make -j24 ``` 然后你会在build文件夹看到所有编译好的二进制文件。 ### 编译状态 - [x] ubuntu18.04 - [ ] openeuler 20 等待测试 ## 写在前面 在经历过无数踩坑以后,发现直接移植cartographer_ros不是一个快速、可靠的办法。虽然官网提示cartogrpher_ros是开发cartographer一个不错的示例。但是在后来的研究中,发现自己写的程序无法完全实现cartographer_ros的全部功能,因为使用cartographer库需要严格的定时器设置、数据缓存池设计(带时间戳)、严格的数据格式,而这些还需要按照一定顺序去调用、实现,非常麻烦和费时。虽然自己写的程序刚好能够建图,但是bug层出无穷(大部分bug是定时器和数据结构不匹配,也和本人功底不够深厚有关)。因此,有没有一个很好的办法,即不用运行在ros上,又能够完美实现所有cartographer_ros的所有功能,并且支持官方更新呢?(google也知道他们的程序有bug所以会经常更新) ## 实现原理 我们知道,cartographer_ros是cartographer和ros的一个桥梁,cartographer_ros通过ros获得传感器数据,打包起来按照顺序输入cartographer并从cartographer获取相对坐标的变换数据通过cartographer_ros输出到TF变换。如果,此时保持cartographer_ros原封不动,对ros进行改造,使原来的ros变成一个"fake ros",首先把ros"多余"的部分清空,变成空循环,优化程序执行效率,然后再把ros的数据接口、定时器、rosbag等所有重要原始.c文件都打包起来把他们放在一起编译,最后把数据像原来ros的方式"喂"给cartographer_ros并加入ros_bridge,这样既不会丢失输入、输出原始ros的格式,也可以实现所有cartographer_ros的功能,可谓一举两得。 ## 注意事项 截止到写这篇文章时,cartographer/ 和 cartographer_ros/ 并不是当前的最新版本,如果google发布了最新版本,你可以直接clone最新版本并替换掉他们,但是你可能需要在一个安装了最新版本的cartographer_ros、ros的机器里面找到ros_stub/include/cartographer_ros_msgs里面的相同的文件并替换掉他们。 ## 使用说明 ***以下所有的操作均在ubuntu18.04实现,ubuntu16.04可以实现但是部分库必须从源码编译且有版本要求,比较麻烦*** ### 1.安装该程序 ```bash sudo add-apt-repository universe sudo apt update sudo apt install git cmake bzip2 libbz2-dev libceres-dev libprotobuf-dev protobuf-compiler libpcl-dev liburdfdom-headers-dev liburdfdom-model liblz4-dev libtinyxml-dev liburdfdom-dev liburdfdom-tools git clone https://gitee.com/harryzhangabc/cartographer_standalone ./cartographer_standalone/cartographer/scripts/install_debs_cmake.sh cd cartographer_standalone mkdir build && cd build cmake .. -DCMAKE_BUILD_TYPE=Release make cartographer_offline_node -j24 ``` ### 2.使用离线的方式测试程序 ```bash cd cartographer_standalone\build\cartographer_ros\cartographer_ros\cartographer_ros ./cartographer_offline_node \path\to\your\rosbag\ ``` 可以看出来,因为cartographer_ros是完整的,所以该程序也支持在不安装ros的情况下直接跑rosbag,运行完后会得到一个.pbstream文件和.pgm地图文件和相关的.yaml文件。 ### 3.使用在线的方式测试程序 注意,到这一步,由于代码的特殊性,请把你的激光雷达、IMU等传感器ros驱动文件放到cartographer_standalone文件夹中,并在.cmakelists里面加入有关于你驱动的信息(打开cmakelists有详细的教程),然后,需要通过改动你的驱动文件把你的驱动做成一个C++的库,然后在cartographer_ros\cartographer_ros\cartographer_ros\node_main.cc里面调用你的驱动,只要调用一次打开传感器、注册个回调程序就可以了,注册成功后只要传感器数据一来就自动喂入cartographer进行建图。 然后,编译程序,执行node程序,建完图后直接ctrl+c关闭程序生成一个.pbstream文件和.pgm地图文件和相关的.yaml文件。 ```bash cd cartographer_standalone cd build cmake .. -DCMAKE_BUILD_TYPE=Release make cartographer_node -j24 cd cartographer_standalone\build\cartographer_ros\cartographer_ros\cartographer_ros ./cartographer_node ``` #### 参考资料 1、http://wiki.ros.org/cartographer 2、https://github.com/larics/cartographer_superbuild 3、https://google-cartographer-ros.readthedocs.io/en/latest 4、https://github.com/cartographer-project/cartographer