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.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.
catkin_make / catkin build fails during compilation
catkin_make / catkin build fails during compilation
Symptom: The build exits with compiler errors, missing dependency errors, or CMake configuration failures.Causes and fixes:
-
Stale build artifacts. Delete the build and devel directories and retry:
- 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.
-
Missing ROS dependencies. Ensure
ros-kinetic-cv-bridge,ros-kinetic-image-transport,ros-kinetic-message-filters, andros-kinetic-tf(or the Melodic equivalents) are installed: - 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.
Docker: 'Permission denied' when running make build or run.sh
Docker: 'Permission denied' when running make build or run.sh
Symptom: Running After running that command you must log out and log back in — or reboot. Simply opening a new terminal tab or running If you are inside a Docker container already (e.g. a CI environment), you may need to use
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:source ~/.bashrc is not sufficient because group membership is evaluated at login time.Verify the fix worked:sudo docker instead or configure the Docker socket permissions differently.Estimator stays in INITIAL state and never starts outputting odometry
Estimator stays in INITIAL state and never starts outputting odometry
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:- 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.
-
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. -
IMU data not arriving. Confirm the
imu_topicin your config YAML matches the topic being published:The node subscribes toIMU_TOPICwith queue depth 2000. Missing IMU data means initialization will never succeed. -
Camera-IMU time offset too large. If
estimate_td: 0in your config but there is a real time offset between camera and IMU timestamps, the system may fail to align them. Setestimate_td: 1to enable online temporal calibration. -
Image topics not arriving or wrong encoding.
rosNodeTest.cppacceptsmono8and8UC1image encodings. Verify:
Estimator diverges or resets mid-flight
Estimator diverges or resets mid-flight
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:-
Wrong IMU noise parameters. This is the most common cause of divergence. If
acc_norgyr_nare 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. -
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: 1in the config, or hardware-synchronize your sensors. - 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.
-
/vins_restartaccidentally published. If anything on your system publishestrueto/vins_restart, the estimator callsclearState()andsetParameter(), resetting all accumulated state. Check for unintended publishers: -
Stereo sync tolerance exceeded. In stereo mode,
rosNodeTest.cppenforces a 3 ms sync tolerance between left and right image timestamps. Frames further apart are dropped withthrow img0orthrow img1printed to the console. Frequent drops indicate a camera sync issue.
Feature tracking is poor — too few or unstable features
Feature tracking is poor — too few or unstable features
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:
-
max_cnttoo 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. -
min_disttoo 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. - 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.
-
Image topic not in grayscale. The feature tracker expects mono images. If you are publishing a color image, ensure
image_transportor your driver is converting it, or configure the driver to publish grayscale.
Loop closure is not detecting loops
Loop closure is not detecting loops
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:-
pose_graph_save_pathnot set or directory does not exist. Check your config YAML forpose_graph_save_pathand ensure the directory exists and is writable. The loop fusion node reads this path fromfsSettings["pose_graph_save_path"]. -
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: - 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.
-
SKIP_CNTorSKIP_DISfiltering 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. -
loop_fusion_nodenot receiving keyframe topics. Confirm thatvins_nodeis publishing:These are only published when a marginalization event occurs (not every frame).
GPS fusion produces no corrected path or fails to align
GPS fusion produces no corrected path or fails to align
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:-
/gpstopic not being published. Theglobal_fusion_nodesubscribes to the hardcoded topic/gps(typesensor_msgs/NavSatFix). For the KITTI GPS example,kitti_gps_testpublishes this topic from the raw dataset. For live systems, ensure your GPS driver publishes to exactly/gps: -
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). -
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. -
global_fusion_nodestarted before VIO is initialized. Startglobal_fusion_nodeaftervins_nodehas exited theINITIALstate and is publishing to/vins_estimator/odometry.
RViz shows no path or topics appear empty
RViz shows no path or topics appear empty
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:-
Topic names do not match RViz configuration. The bundled
config/vins_rviz_config.rvizexpects topics under/vins_estimator/. If you are running nodes inside Docker with--net=host, topics are shared on the host ROS master — verify with: -
Estimator not yet in NON_LINEAR state.
/vins_estimator/odometryand/vins_estimator/pathare 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). -
rosrunfailed silently. If the config file path argument is wrong,vins_nodeexits immediately after printing a usage error. Check that the config file exists at the path you passed: -
ROS master mismatch. If
ROS_MASTER_URIdiffers between the terminal runningroscoreand the terminals running nodes or RViz, they will not see each other’s topics. Ensure all terminals share the sameROS_MASTER_URI(defaulthttp://localhost:11311).