问题描述:ORB-SLAM3中有一个地图保存和加载机制,但是在跑数据集和实车测试过程中,保存地图会出现高频的崩溃现象,而且有时保存地图后再次加载地图时会出现地图匹配慢甚至匹配不上的问题。针对这两个问题的优化进行记录。
这个问题根据调试的现象分析,初步是认为加载的地图特征信息较少,SLAM系统需要一定的时间寻找足够多的匹配。
如果在同一个地方多做一些运动,尽可能多的将运动环境信息添加到环境地图中,会加快与地图的匹配效率。
另外也可以实现在同一个测试环境录制多个bag数据集,将所有数据集的信息累积到同一个地图中,原理和上面相同,还是增加地图中环境信息的丰富程度。这个可以在配置文件中进行设置,如果没有自己加上就好了,不断得跑数据集加载已经生成的地图然后再保存为新的地图。
#--------------------------------------------------------------------------------------------
# System config
#--------------------------------------------------------------------------------------------
# When the variables are commented, the system doesn't load a previous session or not store the current one
# If the LoadFile doesn't exist, the system give a message and create a new Atlas from scratch
System.LoadAtlasFromFile: "map-debug1"
# The store file is created from the current session, if a file with the same name exists it is deleted
System.SaveAtlasToFile: "map-debug"
之前在debug调试时,差不多已经定位到这个问题。
debug找到的,每次崩溃都会出现在关键帧或者地图点的PreSave(*)函数中,一开始认为是内存溢出导致的,所以尝试reserve用于存放地图点的容器的大小,扩大至2倍。Shutdown()时,局部建图和回环检测线程还未结束就进行了地图保存,导致出现了线程资源使用出现了冲突,因为这两个线程会用到关键帧和地图点信息。所以在保存地图之前进行了更严格一点的判断,确保在局部建图和回环检测完全结束后再进行地图保存。有大佬给出了更为精确的定位和解决,并且咋git上发布了优化版本(链接),如果不想过多深入了解,直接拿这个大佬的优化代码跑就可以了
1.对于思路1主要在System.cc->Shutdown()做了以下工作:
-等待回环检测线程中的全局BA结束
-等待viewer线程释放资源结束
-等待LocalMapping和LoopClosing线程结束
-所有的线程都结束之后再额外等待10秒,再次确保所SLAM系统所有线程都已经结束
2.对于思路2主要是在PreSave(*)函数中,在对地图点进行处理之前创建一个临时容器,将点copy一份到临时容器中,然后在对这个临时容器中Mappoints进行处理,防止与其他线程的调用出现冲突
经过EuRoC数据集和实车测试,上述问题得到解决。
更加详细的分析可以参考ORB-SLAM3 git官网中Issue #443(链接),这里开发者们给出了问题的讨论和解决办法,有兴趣可以自己深入看一下。