go-kalmanfilter
go-kalmanfilter copied to clipboard
How to smoothen out sensor readings with this lib?
For a robotics project I'm building an autonomous boat which moves in a grid with x and y readings. These location sensor readings are a little noisy however, and as far as I understand, a Kalman filter is built specifically to smoothen out noise from sensor readings and get an estimation of the next value. Your lib seems to be perfect to do this.
I pasted some noisy readings below (every item also has a datetime object, but I left them out for clarity).
// X Y
{399, 293},
{403, 299},
{409, 308},
{416, 315},
{418, 318},
{420, 323},
{429, 326}, // <== Noise in X
{423, 328},
{429, 334},
{431, 337},
{433, 342},
{434, 352}, // <== Noise in Y
{434, 349},
{433, 350},
{431, 350},
{430, 349},
{428, 347},
{427, 345},
{425, 341},
{429, 338}, // <== Noise in X
{431, 328}, // <== Noise in X
{410, 313},
{406, 306},
{402, 299},
{397, 291},
{391, 294}, // <== Noise in Y
{376, 270},
{372, 272},
{351, 248},
{336, 244},
{327, 236},
{307, 220}
So from the example code in the readme and my sensor readings I created the following code:
package main
import (
"fmt"
"time"
"github.com/shantanubhadoria/go-kalmanfilter/kalmanfilter"
)
func getStateSensorReading(readings [][]int, i int) int {
return readings[i][0]
}
func getDeltaSensorReading(readings [][]int, i int) int {
return readings[i][0] - readings[i-1][0]
}
func main() {
readings := [][]int{
{399, 293},
{403, 299},
{409, 308},
{416, 315},
{418, 318},
{420, 323},
{429, 326}, // <== Noise in X
{423, 328},
{429, 334},
{431, 337},
{433, 342},
{434, 352}, // <== Noise in Y
{434, 349},
{433, 350},
{431, 350},
{430, 349},
{428, 347},
{427, 345},
{425, 341},
{429, 338}, // <== Noise in X
{431, 328}, // <== Noise in X
{410, 313},
{406, 306},
{402, 299},
{397, 291},
{391, 294}, // <== Noise in Y
{376, 270},
{372, 272},
{351, 248},
{336, 244},
{327, 236},
{307, 220},
}
myFilterData := new(kalmanfilter.FilterData)
var oldTime time.Time = time.Now()
i := 1
for i < len(readings) {
stateReading := float64(getStateSensorReading(readings, i)) // in units X
deltaReading := float64(getDeltaSensorReading(readings, i)) // in unit X per nanosecond
fmt.Println(stateReading, deltaReading) // Prints out correct values
var newTime time.Time = time.Now()
var duration time.Duration = newTime.Sub(oldTime)
oldTime = newTime
newState := myFilterData.Update(stateReading, deltaReading, float64(duration/time.Nanosecond))
fmt.Println(newState) // Only Prints out NaN
fmt.Println(myFilterData)
i++
}
}
With this code I only attempt to smoothen out the sensor readings for X. Unfortunately newState
is only NaN
(as you can see in the comments in the code).
Would anybody know how I can smoothen out the sensor readings and get estimations for the next sensor reading? I obviously need to do the same for Y. Would I simply copy the same logic as for Y, or can I combine X and Y somehow?