Using a Kalman filter on a single analog channel

kalman_voltage
Things have been slow here at YardBot HQ recently. Not only do I work full time as a mobile software developer, but part time I work for a mechanical engineering company (same building and owners) that will be releasing a rather exciting computer product in the near future. Add it up together and it means that my robot aspirations are somewhat lower priority. Fortunately with winter tightening its grip here in Canada, I have a little extra time indoors to devote to learning more about ROS and its related systems. One of the things I wanted to learn more about is called the Kalman Filter.

This is a math process that comes up often when looking at IMU and navigation systems. As I understand it in simple terms, it revolves around the concept of filtering data by using previous measurements and merging that with the estimated variance between measurements to predict its current state. This can be done with 1 channel or, in the case of ROS’ robot_pose_ekf node, multiple sensors. The advantage of the extended Kalman filter in the IMU example is that you can combine sensors that have different levels of drift to retrieve a more accurate snapshot of the robot’s position. I haven’t done that yet, so I’m starting simple.

Currently I have 2 Arduinos sending back analog sensor data and controlling a DC motor and linear actuator. This analog data records things like temperature, humidity, current and voltage. Current and voltage both use the MEGA’s ADC pins, so they’re susceptible to noise. I decided to develop a reusable Kalman filter class for reducing or eliminating the noise on one of these single channels.

The result is seen in the photo above. The rocky blue line is the pure data coming in from the Arduino while the nice flat red line is the output of the Kalman filter node. Unfortunately using a voltage sensor for analog filtering doesn’t quite demonstrate the entire system, as the actual value doesn’t really move around, so I’ll be trying it with other sensor inputs later.

For demonstration, here are two files that were used: the single channel kalman filter class I wrote and the ROS node that takes advantage of it.

I pulled examples from multiple sites to get this class, and the core math came from this blog. The filter itself is used in a lot of different places so you should be able to find plenty of examples. That link includes a much deeper dive into the math, so give it a read. In this file, I start by defining the coming methods and variables. Essentially you can make an instance with the required filter properties, then add an input and get the new filtered value out.

This is the file that makes it all work together. It’s configured like a typical ROS node: start the node and retrieve the included launch properties, then start up the subscribers and publishers. I create a subscriber for the unfiltered voltage topic then add a callback to generate the filtered response. In the callback you can also see where I add the input to the SingleChannelKalman instance configured earlier.

The end result is pretty solid as a first try, so I’ll be trying this setup with other analog inputs to see how it fairs.

Posted in Software Tagged with: , , , ,

Leave a Reply

Your email address will not be published. Required fields are marked *

*