1. 从零开始搭建gici-open开发环境
第一次接触gici-open这个多传感器融合框架时,我被它强大的功能所吸引,但也被复杂的编译过程难住了。作为上海交大最新开源的GNSS/INS/Camera组合框架,它集成了RTKLIB、OKVIS等知名算法,但想要跑通第一个demo还真不容易。这里分享我在Ubuntu 20.04系统下的完整编译经验,帮你避开那些坑。
编译环境准备其实就三大件:glog、gflags和ceres-solver。但千万别小看这几个依赖库,版本冲突能让你怀疑人生。我建议先用apt list --installed检查现有版本,避免后续出现"幽灵依赖"问题。特别是ceres-solver,必须2.1.0以上版本,否则会直接编译失败。
安装gflags时有个小技巧:编译时记得加上-DBUILD_SHARED_LIBS=ON参数,这样生成的动态库才能被glog正确链接。具体操作如下:
git clone https://github.com/gflags/gflags.git cd gflags mkdir build && cd build cmake .. -DBUILD_SHARED_LIBS=ON make -j$(nproc) sudo make install接着安装glog时,我发现0.6.0版本最稳定。编译时要特别注意设置-DWITH_GFLAGS=ON,否则会报找不到gflags的错误。安装完记得运行sudo ldconfig更新库链接,这一步很多教程都会漏掉。
2. 解决依赖冲突的实战技巧
在编译gici-open时,我遇到了最棘手的版本冲突问题。错误提示flag 'logtostderr' was defined more than once,这其实是glog库被重复加载导致的。经过排查发现,系统里竟然存在三个不同来源的glog库:通过apt安装的、手动编译安装的、还有ceres-solver自带的。
我的解决方案是彻底清理环境后重新安装。先用locate glog找出所有相关文件,特别注意/usr/local/和/usr/目录下的残留。清理命令要谨慎使用:
sudo rm -rf /usr/local/include/glog/ sudo rm -rf /usr/local/lib/libglog* sudo apt purge libgoogle-glog-dev更稳妥的做法是先创建虚拟机快照。清理完成后,建议通过源码统一安装特定版本。这里有个小发现:ceres-solver 2.1.0其实已经自带了glog,所以如果先装ceres,再装gici-open时会自动使用兼容版本。
对于Ceres的版本管理,我推荐在CMakeLists.txt里明确指定路径。比如我的配置是这样的:
set(Ceres_DIR "/opt/ceres-solver-2.1.0/share/Ceres") set(CMAKE_BUILD_TYPE "RelWithDebInfo")3. 深入解析Stream Node配置
gici-open的配置文件设计非常精妙,特别是Stream Node部分。以pseudo_real_time_estimation_SPP_RRR.yaml为例,每个streamer都像乐高积木一样可以自由组合。第一次看配置文件时,我被各种tag搞得晕头转向,后来发现其实遵循着清晰的逻辑。
关键是要理解数据流的"输入-处理-输出"链条。比如GNSS数据流的典型配置包含:
str_gnss_rov_file:流动站观测数据str_gnss_eph:星历数据str_imu:惯性测量数据str_camera:图像数据
每个streamer的type属性特别重要。我测试过几种类型:
file:直接读取本地文件(适合回放数据集)serial:串口实时数据(需要设置波特率)tcp-client:网络传输(实测延迟约50ms)
时间同步是另一个重点。enable_time_tag选项开启后,系统会严格按时间戳对齐多传感器数据。我建议首次使用时先在数据集上测试,确认时间对齐效果后再部署到实时系统。
4. Formators的多源数据融合秘诀
Formators就像数据流的"翻译官",把不同来源的原始数据转换成统一格式。在调试过程中,我发现几个关键点值得注意:
首先是IO方向不能设反。比如IMU数据应该是input,而解算结果应该是output。新手容易犯的错误是在formators里把方向搞反,导致数据流中断。
其次是标定参数的处理。相机内参、IMU噪声参数等都需要通过formators正确传递。我整理了一个典型配置对照表:
| 传感器类型 | 必要参数 | 推荐格式 |
|---|---|---|
| GNSS | 天线偏移 | ENU坐标系 |
| IMU | 噪声密度 | YAML数组 |
| Camera | 畸变模型 | OpenCV格式 |
数据同步策略也很讲究。gici-open支持三种同步模式:
- 严格时间戳匹配(适合高精度场景)
- 最近邻匹配(低延迟需求)
- 插值补偿(运动剧烈时更平滑)
5. 实战运行与调试技巧
第一次运行示例数据集时,我遇到了经典的"核心已转储"错误。经过排查发现是路径配置问题。gici-open对文件路径非常敏感,建议使用绝对路径,并在yaml文件里做好注释。
运行命令虽然简单:
./gici_main ../option/your_config.yaml但有几个参数会极大影响性能:
max_queue_size:处理队列长度(内存占用与延迟的平衡)thread_priority:实时性要求高的可以设为SCHED_FIFOlog_level:调试时设为VERBOSE,生产环境用WARNING
与RTKLIB的联动是个亮点。通过TCP连接rtkplot时,我发现内网穿透的延迟会影响显示效果。后来改用本地直接连接,配合以下配置就稳定了:
streamers: - streamer: tag: str_rtk_out type: tcp-server port: 210006. 常见问题与解决方案
在三个月的使用中,我整理了一些典型错误和解决方法:
问题一:Open streamer failed
- 检查文件路径权限(特别是/tmp目录)
- 确认数据集时间范围与配置匹配
- 查看传感器数据是否完整
问题二:IMU和Camera时间不同步
- 校准设备硬件时钟
- 调整
time_offset参数 - 检查
enable_time_tag是否开启
问题三:内存泄漏
- 定期检查
/proc/<pid>/status中的VmRSS - 限制
max_queue_size - 升级到最新代码库(2023年后版本有明显改善)
性能优化方面,我总结了几点经验:
- 在x86平台编译时加上
-march=native优化 - 关闭调试日志可提升30%吞吐量
- 多传感器数据建议分开存储,降低IO压力
7. 进阶开发与二次开发
理解gici-open的架构后,我开始尝试添加自己的算法模块。框架的核心抽象非常清晰:
Pipeline管理整个数据处理流程Node对应不同功能模块Message是数据交换的载体
添加新传感器的关键步骤:
- 继承
Sensor基类实现数据采集 - 在
formators中注册数据解析器 - 编写对应的
Estimator处理算法
我最近成功接入了Livox激光雷达,主要修改了:
- 新增
pointcloud数据类型 - 扩展
formators支持PCD格式 - 实现基于ICP的初始对准
调试时强烈建议使用gici-open内置的日志系统,通过GLOG_v=2可以输出详细调用栈信息。对于实时性要求高的模块,可以用Tracer类统计处理耗时。