1. 环境准备与依赖管理
第一次接触gici-open这个多传感器融合框架时,我完全被它的功能震撼到了。作为上海交大最新开源的GNSS/INS/Camera组合框架,它集成了RTKLIB、OKVIS和SVO等知名算法的精华。但在实际部署时,我发现环境配置就像玩俄罗斯方块,稍有不慎就会引发连锁反应。
Ubuntu 20.04是最稳妥的选择,因为开发者就是用这个版本测试的。我建议先创建一个干净的Python虚拟环境(虽然不是必须,但能避免很多奇怪的问题):
sudo apt-get install python3-venv python3 -m venv gici-env source gici-env/bin/activate依赖库的版本管理是个技术活。有次我编译失败后才发现,系统里同时存在三个不同版本的Eigen库。后来我养成了个好习惯:在安装新库前先用locate命令检查现有版本。比如查Eigen:
locate eigen3 | grep /usrglog库的安装最容易踩坑。直接git clone最新版可能会报错,因为缺少前置依赖。正确的姿势是分步走:
- 先装gflags(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以上版本):
git clone https://github.com/google/glog cd glog && mkdir build && cd build cmake .. -DBUILD_SHARED_LIBS=ON make -j$(nproc) sudo make installCeres-solver的版本管理更是个玄学问题。我电脑上原本有1.14版的Ceres,但gici-open需要2.1.0以上。最稳妥的方法是源码编译安装:
git clone https://github.com/ceres-solver/ceres-solver.git cd ceres-solver git checkout 2.1.0 # 明确指定版本 mkdir build && cd build cmake .. -DBUILD_SHARED_LIBS=ON make -j$(nproc) sudo make install2. 源码编译实战技巧
当所有依赖就绪后,真正的挑战才开始。gici-open的编译过程就像在拆解精密仪器,每个参数都要恰到好处。
首先在CMakeLists.txt里做好两处关键设置:
- 指定Ceres路径(避免系统误认旧版本):
set(Ceres_DIR "/usr/local/lib/cmake/Ceres")- 强制使用Release模式(Debug模式会慢得怀疑人生):
set(CMAKE_BUILD_TYPE "Release")编译命令看似常规,但有隐藏技巧:
mkdir build && cd build cmake .. -DCMAKE_PREFIX_PATH="/usr/local" # 确保找到正确版本的库 make -j$(($(nproc)-1)) # 留一个核心给系统,避免卡死我遇到过最诡异的错误是flag 'logtostderr' was defined more than once。这其实是glog库冲突的表现。终极解决方案是:
# 彻底清理旧版本 sudo apt-get purge libgoogle-glog-dev sudo rm -rf /usr/local/include/glog sudo rm -rf /usr/local/lib/libglog* # 重新安装 cd glog/build && sudo make install有时编译通过但运行时崩溃,可能是动态链接库路径问题。我习惯在~/.bashrc里添加:
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH3. 配置文件深度解析
gici-open的YAML配置文件就像乐高说明书,拼不对就得不到想要的效果。经过多次试错,我总结出配置文件的三层结构:
Stream节点是数据入口,相当于工厂的原料输送带。以GNSS数据流为例:
streamers: - streamer: tag: str_gnss_rov_file type: file path: "/data/gnss/rov.obs" enable_time_tag: true format: - gnss_obs - gnss_ephFormators是数据转换器,就像流水线上的加工机床。关键是要和streamers里的output_tag对应:
formators: - formator: tag: gnss_obs io: in type: gnss_obs - formator: tag: solution io: out type: solutionEstimate节点最复杂,它控制着融合算法的核心参数。比如松组合模式配置:
estimators: - estimator: type: gnss_loose gnss_loose: dynamics: static error_type: pos gnss: spp时间同步参数容易被忽视,但直接影响融合效果:
time_synchronization: enable: true max_time_diff: 0.05 # 50ms同步阈值4. 多传感器数据融合实战
当一切准备就绪,运行命令看似简单:
./gici_main config/pseudo_real_time.yaml但第一次运行时我遇到了经典的"核心已转储"错误。通过glog输出的错误日志,发现是数据路径问题。gici-open对路径格式极其敏感:
- 必须使用绝对路径
- 不能有中文或特殊字符
- 目录需要755权限
RTKLIB可视化连接是个实用功能。在配置文件中添加:
streamers: - streamer: tag: str_rtklib type: tcp-server port: 6000 format: [solution]然后在RTKLIB的strsvr中选择"TCP Client",地址填localhost:6000。如果连接成功,会在终端看到:
[INFO] TCP connection established with client 127.0.0.1时间戳对齐是多传感器融合的关键。我开发了个检查脚本:
import numpy as np imu_times = np.loadtxt('imu.time') camera_times = np.loadtxt('camera.time') print(f"IMU-Camera时间差均值:{np.mean(imu_times - camera_times):.3f}s")当所有传感器数据流畅运行时,终端会输出类似这样的融合结果:
[INFO] EKF Update: Pos(23.456,134.567,45.678) Vel(0.12,-0.34,0.01) [INFO] Image feature tracked: 127 points [INFO] GNSS SPP solution: 2.3m accuracy记得定期检查日志文件(默认在logs目录),我经常从中发现传感器数据不同步或外参不准的问题。比如这样的警告就说明IMU和相机需要重新标定:
[WARNING] IMU-Camera时间差超过阈值(0.1s) at 1234.567s