Hello :),
I’ve got a 10hz GPS module successfully logging out data to a file on a microsd and I would love to get some smoothing going. I’m having difficulty finding some kalman filter stuff for GPS within arduino specifically. I’m happy for you to correct me here and post a load of them :P.
Anyway, i discovered this yesterday GitHub - lacker/ikalman: An iPhone-friendly Kalman filter written in C. and after making a few changes to my preference such as wrapping the actual logic into an object and fixing up the for loops to work in or out of C99 mode (i forget which way round that is :P) i’ve got it successfully compiling onto an Uno. My changes can be found here: https://github.com/rfox90/ikalman its highly likely i may of made a silly mistake there I’m not exactly proficient at C++ and especially not code I don’t understand due to the maths behind it.
The problem appears to be that I run out of RAM on the Arduino as its restarting. This occurs the moment i call an update to the filter.
Am I heading in the right direction or just condemning myself to run out of RAM?
#include <SoftwareSerial.h>
#include <TinyGPS.h>
#include <GPSFilter.h>
#include <PString.h>
#define RXPIN 2
#define TXPIN 3
//Defined in the specs for the module i am using
#define GPSBAUD 38400
#define error(s) sd.errorHalt_P(PSTR(s))
TinyGPS gps;
SoftwareSerial uart_gps(RXPIN, TXPIN);
GPSFilter f(2.5);
int freeRam();
char buff[50];
char pbuff[100];
PString line(pbuff,sizeof pbuff);
unsigned long lastUpdate;
unsigned long lastSentence;
float c;
void setup()
{
Serial.begin(115200);
Serial.println(F("...waiting for lock..."));
uart_gps.begin(GPSBAUD);
uart_gps.write("$PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28\r\n");
uart_gps.write("$PMTK220,100*2F\r\n");
lastSentence = millis();
lastUpdate = millis();
}
void loop()
{
while(uart_gps.available()) { // While there is data on RX
char c = uart_gps.read();
if(c == '
){
// Serial.println();
}
// Serial.print(c);
if(gps.encode(c)) {
int year;
byte month, day, hour, minute, second, hundredths;
unsigned long age;
gps.crack_datetime(&year,&month,&day,&hour,&minute,&second,&hundredths,&age); //Get the date from the GPS
unsigned long date;
gps.get_datetime(&date,0,0);
if(date == TinyGPS::GPS_INVALID_DATE){
Serial.println(F(“Invalid Age”));
//continue;
}
if(age == TinyGPS::GPS_INVALID_AGE) {
Serial.println(F(“Waiting for more valid data”));
continue;
}
float latitude, longitude;
double dlat,dlong;
gps.f_get_position(&latitude, &longitude);
double ulat,ulong;
ulat = (double)latitude;
ulong = (double)longitude;
c = (millis() - lastSentence)/1000;
//seconds since last update
f.update_velocity2d(ulat,ulong,c);
lastSentence = millis();
Serial.println(F(“Does not get here”);
if((millis() - lastUpdate) >= 500 || lastUpdate == NULL){
f.get_lat_long(&dlat,&dlong);
line.begin();
line.print(“201,”);
line.print(dlat,8);
line.print(",");
line.print(dlong,8);
line.print(",");
line.print(year);
line.print("-");
line.print(month);
line.print("-");
line.print(day);
line.print(" “);
line.print(hour);
line.print(”:");
line.print(minute);
line.print(":");
//Serial.println(second);
line.print(second);
line.print(".");
line.print(hundredths);
line.print(",");
line.print(gps.f_altitude(),2);
line.print(",");
line.print(gps.f_course(),2);
line.print(",");
line.print(gps.f_speed_kmph(),2);
Serial.println(line);
lastUpdate = millis();
}
}
}
}
int freeRam () {
extern int __heap_start, *__brkval;
int v;
return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}