<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Manan Kharwar</title>
    <description>The latest articles on DEV Community by Manan Kharwar (@manankharwar).</description>
    <link>https://dev.to/manankharwar</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3901315%2F003fd8f8-cca1-46ab-a157-159d6158924a.jpeg</url>
      <title>DEV Community: Manan Kharwar</title>
      <link>https://dev.to/manankharwar</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/manankharwar"/>
    <language>en</language>
    <item>
      <title>ROS 2 sensor fusion in 2026: robot_localization vs fuse vs FusionCore</title>
      <dc:creator>Manan Kharwar</dc:creator>
      <pubDate>Mon, 27 Apr 2026 23:31:57 +0000</pubDate>
      <link>https://dev.to/manankharwar/ros-2-sensor-fusion-in-2026-robotlocalization-vs-fuse-vs-fusioncore-306c</link>
      <guid>https://dev.to/manankharwar/ros-2-sensor-fusion-in-2026-robotlocalization-vs-fuse-vs-fusioncore-306c</guid>
      <description>&lt;p&gt;If you're building an outdoor mobile robot in ROS 2 and need to fuse GPS, IMU and wheel encoders into a single position estimate, you have three real options right now. I've used all three and benchmarked two of them on a public dataset. Here's the honest picture.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;robot_localization&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The default answer for years. Mature, well documented, large community. It ships an EKF and a UKF node and handles GPS through a separate &lt;code&gt;navsat_transform&lt;/code&gt; node that converts GPS coordinates into odometry the filter can consume.&lt;/p&gt;

&lt;p&gt;The problems in practice:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;navsat_transform&lt;/code&gt; uses UTM projection internally. UTM zones are 6 degrees of longitude wide. If your robot crosses a zone boundary mid-mission, the coordinate origin shifts and your position estimate jumps. For most indoor or small outdoor missions this never matters. For large area agricultural or survey robots it's a real issue.&lt;/p&gt;

&lt;p&gt;There's no IMU bias estimation. Your IMU's gyro and accelerometer biases drift with temperature and time and robot_localization has no mechanism to estimate them. You absorb the bias error directly into your position estimate.&lt;/p&gt;

&lt;p&gt;Noise covariances are static YAML parameters. When your environment changes.... moving from open field to urban canyon: the optimal noise model changes too. You retune manually or you accept degraded performance.&lt;/p&gt;

&lt;p&gt;That said: it works, it's in every ROS distro, and if your use case is simple it's probably still the right choice.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bottom line&lt;/strong&gt;: Proven, well supported, best choice for simple setups. Starts showing cracks on large outdoor missions or when GPS quality is variable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fuse&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The designated long-term successor to robot_localization. Factor graph architecture instead of a Kalman filter... theoretically more flexible, supports loop closure, handles delayed measurements cleanly by design.&lt;/p&gt;

&lt;p&gt;In practice in early 2026: GPS support is still incomplete. No native ECEF handling, no RTK quality gating. The plugin architecture is powerful but it means every sensor needs a custom plugin and the documentation for writing those is thin. For teams with the engineering bandwidth to build on it, fuse is the right long-term bet. For a team that needs GPS fusion working this week, it's not there yet.&lt;/p&gt;

&lt;p&gt;Bottom line: The future of ROS sensor fusion, not the present. Watch it, don't bet your project on it yet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;FusionCore&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I built this after running into the navsat_transform UTM zone issue on a real project. It's a 22-state UKF that fuses IMU, wheel encoders and GPS in a single node. GPS is handled directly in ECEF... no coordinate projection, no zone boundaries. Gyro and accelerometer biases are estimated online. Noise covariance adapts automatically from the innovation sequence.&lt;/p&gt;

&lt;p&gt;I benchmarked it against robot_localization EKF on 6 sequences from the NCLT public dataset.... a real Segway robot on a university campus with RTK GPS ground truth. Same data, both packages, full reproduce instructions in the repo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feq4a2d7bvyltsmpjp95y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feq4a2d7bvyltsmpjp95y.png" alt=" " width="800" height="564"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbwhcxst5y2m3xe20pngt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbwhcxst5y2m3xe20pngt.png" alt=" " width="791" height="361"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;FusionCore wins 5 of 6. On the 6th sequence, prolonged GPS degradation under fall foliage meant the outlier gate kept rejecting GPS while drift accumulated. robot_localization has no gate so it accepted the noisy GPS and self-corrected when signal returned. I think that tradeoff is worth understanding rather than hiding... the gate protects you from spikes but costs you during slow degradation.&lt;/p&gt;

&lt;p&gt;robot_localization UKF diverged to NaN on all six sequences.&lt;/p&gt;

&lt;p&gt;It's Apache 2.0, in the ROS 2 Jazzy apt repo, and has a Zenodo DOI if you need to cite it.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo apt install ros-jazzy-fusioncore-ros&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/manankharwar/fusioncore" rel="noopener noreferrer"&gt;https://github.com/manankharwar/fusioncore&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bottom line&lt;/strong&gt;: Best measured accuracy on this dataset, honest about the one loss, single node with no coordinate transform dependency. Good fit if you need GPS fusion working reliably on a real outdoor robot today.&lt;/p&gt;

</description>
      <category>ros</category>
      <category>robotics</category>
      <category>opensource</category>
      <category>cpp</category>
    </item>
  </channel>
</rss>
