Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/HKUST-Aerial-Robotics/Vins-Fusion/llms.txt

Use this file to discover all available pages before exploring further.

VINS-Fusion depends on a carefully tuned chain of sensor inputs, calibration parameters, and build environment components. Problems most commonly appear during the initial build, during sensor initialization, or when the estimator receives poor-quality data. The issues below cover the most frequently encountered failure modes along with concrete steps to resolve each one, drawn directly from the codebase’s behavior and the upstream README recommendations.
Symptom: The build exits with compiler errors, missing dependency errors, or CMake configuration failures.Causes and fixes:
  1. Stale build artifacts. Delete the build and devel directories and retry:
    cd ~/catkin_ws
    rm -rf build devel
    catkin_make
    source devel/setup.bash
    
  2. Ceres Solver not installed or wrong version. VINS-Fusion requires Ceres. Follow the official Ceres installation guide. The Docker image pins Ceres 1.12.0 and installs it automatically.
  3. Missing ROS dependencies. Ensure ros-kinetic-cv-bridge, ros-kinetic-image-transport, ros-kinetic-message-filters, and ros-kinetic-tf (or the Melodic equivalents) are installed:
    sudo apt-get install ros-${ROS_DISTRO}-cv-bridge \
                         ros-${ROS_DISTRO}-image-transport \
                         ros-${ROS_DISTRO}-message-filters \
                         ros-${ROS_DISTRO}-tf
    
  4. Incompatible system environment. As noted in the README: “if you fail in this step, try to find another computer with clean system or reinstall Ubuntu and ROS.” The supported platforms are Ubuntu 16.04 with ROS Kinetic and Ubuntu 18.04 with ROS Melodic.
Symptom: Running make build or ./run.sh prints something like Got permission denied while trying to connect to the Docker daemon socket.Fix: Add your user to the docker group, then start a new login session:
sudo usermod -aG docker $USER
After running that command you must log out and log back in — or reboot. Simply opening a new terminal tab or running source ~/.bashrc is not sufficient because group membership is evaluated at login time.Verify the fix worked:
groups | grep docker
docker run hello-world
If you are inside a Docker container already (e.g. a CI environment), you may need to use sudo docker instead or configure the Docker socket permissions differently.
Symptom: The terminal prints waiting for image and imu... followed by pose output, but the /vins_estimator/odometry topic is never published (or RViz shows no green path). The estimator is stuck in the INITIAL solver state — pubOdometry in visualization.cpp only publishes when solver_flag == NON_LINEAR.Causes and fixes:
  1. Insufficient parallax during initialization. VINS-Fusion requires enough baseline motion to triangulate an initial structure-from-motion solution. If the camera is stationary or rotating in place, initialization will not complete. Introduce translational motion in the first few seconds.
  2. Poor IMU parameters. Incorrect IMU noise values (acc_n, gyr_n, acc_w, gyr_w) cause the IMU preintegration to diverge or the IMU-vision alignment to fail. Check your IMU datasheet and set these accurately. Starting with conservative (higher) noise values is safer than too-tight values.
  3. IMU data not arriving. Confirm the imu_topic in your config YAML matches the topic being published:
    rostopic list | grep imu
    rostopic hz /imu0
    
    The node subscribes to IMU_TOPIC with queue depth 2000. Missing IMU data means initialization will never succeed.
  4. Camera-IMU time offset too large. If estimate_td: 0 in your config but there is a real time offset between camera and IMU timestamps, the system may fail to align them. Set estimate_td: 1 to enable online temporal calibration.
  5. Image topics not arriving or wrong encoding. rosNodeTest.cpp accepts mono8 and 8UC1 image encodings. Verify:
    rostopic hz /cam0/image_raw
    rostopic echo /cam0/image_raw/encoding
    
Symptom: The estimator was running correctly, then suddenly the position jumps or estimator.clearState() is triggered internally (you may see a WARN log). The path restarts from the origin or a new position.Causes and fixes:
  1. Wrong IMU noise parameters. This is the most common cause of divergence. If acc_n or gyr_n are too small, the optimizer over-trusts the IMU and any small sensor error accumulates rapidly. Cross-check your values against the IMU manufacturer specification and the values used in the EuRoC config files as a reference.
  2. Camera and IMU not hardware-synchronized. A time offset between camera and IMU causes the preintegration to use IMU data from the wrong time interval. Enable online temporal calibration with estimate_td: 1 in the config, or hardware-synchronize your sensors.
  3. Aggressive motion exceeding IMU range. Check that angular velocity and linear acceleration during your flight/drive do not saturate the IMU. Saturation causes step changes in the measurements that look like instantaneous large rotations.
  4. /vins_restart accidentally published. If anything on your system publishes true to /vins_restart, the estimator calls clearState() and setParameter(), resetting all accumulated state. Check for unintended publishers:
    rostopic info /vins_restart
    
  5. Stereo sync tolerance exceeded. In stereo mode, rosNodeTest.cpp enforces a 3 ms sync tolerance between left and right image timestamps. Frames further apart are dropped with throw img0 or throw img1 printed to the console. Frequent drops indicate a camera sync issue.
Symptom: RViz shows very few points on the feature track image, or features disappear quickly. The estimator may fail to initialize because it cannot observe enough parallax.Causes and fixes:
  1. max_cnt too low. This parameter in the config YAML controls the maximum number of features tracked per frame. Increase it (e.g. from 150 to 200) if the scene has enough texture but VINS is tracking too few points.
  2. min_dist too high. This is the minimum pixel distance between tracked features. If it is too large, features are spread too sparsely and may all be lost at once when a scene region exits the view. Reduce it to allow denser tracking.
  3. Motion blur or poor exposure. Global shutter cameras and proper exposure settings are strongly recommended. The README states: “VIO heavily relies on hardware quality. For beginners, we recommend you run VIO with professional equipment, which contains global shutter cameras and hardware synchronization.” Rolling shutter cameras introduce geometric distortions that harm feature tracking.
  4. Image topic not in grayscale. The feature tracker expects mono images. If you are publishing a color image, ensure image_transport or your driver is converting it, or configure the driver to publish grayscale.
Symptom: loop_fusion_node is running but the red loop-corrected path in RViz never diverges from the green VIO path, or no loop closure events are printed to the console even when revisiting known locations.Causes and fixes:
  1. pose_graph_save_path not set or directory does not exist. Check your config YAML for pose_graph_save_path and ensure the directory exists and is writable. The loop fusion node reads this path from fsSettings["pose_graph_save_path"].
  2. DBoW2 vocabulary file not found. The node loads the vocabulary from <loop_fusion_package_path>/../support_files/brief_k10L6.bin. If you moved the package or are using a non-standard install, this path will be wrong. Verify:
    rospack find loop_fusion
    ls $(rospack find loop_fusion)/../support_files/brief_k10L6.bin
    
  3. Not enough scene revisitation. Loop closure requires that the same location is observed from a similar viewpoint. Fast traversal or purely one-way paths will not produce loops.
  4. SKIP_CNT or SKIP_DIS filtering out frames. The pose graph node skips keyframes that are too close together (SKIP_DIS) or too frequent (SKIP_CNT). If these are set aggressively in the config, loop candidates may never be added to the database.
  5. loop_fusion_node not receiving keyframe topics. Confirm that vins_node is publishing:
    rostopic hz /vins_estimator/keyframe_pose
    rostopic hz /vins_estimator/keyframe_point
    
    These are only published when a marginalization event occurs (not every frame).
Symptom: global_fusion_node is running but /globalEstimator/global_path is empty or identical to the VIO path. Or the global path appears but is offset from the expected GPS ground truth.Causes and fixes:
  1. /gps topic not being published. The global_fusion_node subscribes to the hardcoded topic /gps (type sensor_msgs/NavSatFix). For the KITTI GPS example, kitti_gps_test publishes this topic from the raw dataset. For live systems, ensure your GPS driver publishes to exactly /gps:
    rostopic info /gps
    
  2. GPS and VIO timestamps not aligned. The node matches GPS measurements to VIO odometry within ±10 ms (gps_t >= t - 0.01 && gps_t <= t + 0.01). If timestamps differ by more than 10 ms, GPS measurements are discarded. Check that your GPS receiver’s clock is synchronized (e.g. via PPS or GPS-disciplined NTP).
  3. GPS position covariance is zero or negative. The node reads GPS_msg->position_covariance[0] as position accuracy. If it is ≤ 0, the code sets it to 1.0 as a fallback. Very low-accuracy GPS (large covariance values) will give weak constraints in the optimizer.
  4. global_fusion_node started before VIO is initialized. Start global_fusion_node after vins_node has exited the INITIAL state and is publishing to /vins_estimator/odometry.
Symptom: RViz launches (either from run.sh or roslaunch vins vins_rviz.launch) but no path, point cloud, or odometry is displayed even though the nodes appear to be running.Causes and fixes:
  1. Topic names do not match RViz configuration. The bundled config/vins_rviz_config.rviz expects topics under /vins_estimator/. If you are running nodes inside Docker with --net=host, topics are shared on the host ROS master — verify with:
    rostopic list | grep vins_estimator
    
  2. Estimator not yet in NON_LINEAR state. /vins_estimator/odometry and /vins_estimator/path are only published after the estimator has completed initialization. The point cloud topics (point_cloud, margin_cloud) are also gated on this condition. Wait for initialization to complete (watch the console for pose output).
  3. rosrun failed silently. If the config file path argument is wrong, vins_node exits immediately after printing a usage error. Check that the config file exists at the path you passed:
    rosrun vins vins_node /full/path/to/config.yaml
    
  4. ROS master mismatch. If ROS_MASTER_URI differs between the terminal running roscore and the terminals running nodes or RViz, they will not see each other’s topics. Ensure all terminals share the same ROS_MASTER_URI (default http://localhost:11311).

Build docs developers (and LLMs) love