3

I'm trying to get GPS time out of a pixhawk. I've found a bunch of discussions about such but none that appear to have been resolved. Is there any update?

This guy and this guy were both told to just use system time (which is not UTC) I also tried to get GLOBAL_POSITION_INT_COV but found it was not available.

Here is a long dev discussion about such that was never resolved (circa 2013)

Another dev discussion that references a bunch of pull requests for such - but doesn't look like any of them ever made it in or am I wrong?

Much thanks!

Community
  • 1
  • 1
r4space
  • 31
  • 4
  • Did you find a solution? I too am looking for the time from the GPS, not the system time converted to UTC. – proximous Jan 04 '18 at 02:23

2 Answers2

3

As noted in your second link, ArduPilot sends unix time in the SYSTEM_TIME message. You didn't mention what language you are using, but in Python, unix time can easily be converted to UTC using the datetime module.

@vehicle.on_message('SYSTEM_TIME')
def listener(self, name, message):
    unix_time = (int) (message.time_unix_usec/1000000)
    print(datetime.datetime.fromtimestamp( unix_time ))
squilter
  • 400
  • 1
  • 6
  • It's not a format thing it's about getting the actual real time from the GPS. – r4space Jan 04 '18 at 15:18
  • At least as of ArduCopter 3.5.5 (maybe much earlier) and DroneKit v 2 it looks like the actual real time is what is being reported now. – syntheticgio Mar 08 '18 at 23:24
0

GPS times reported in MAVLink messages are in two parts: The GPS week number, and the number of milliseconds since the start of that week. Also, need to know when GPS weeks started (Jan 6, 1980).

Here's a bit of javascript code that seems to work well for me (could easily be ported to other languages):

// no. of milliseconds in a date since midnight of
// January 1, 1970, according to UTC time;
// months are zero-based, but days are 1-based
var GPS_EPOCH_MILLIS = (new Date(1980, 0, 6, 0, 0, 0, 0)).getTime();

// all the leap seconds that have been defined so far;
// must keep this list current!
var leapSecondsMillis = [
    (new Date(1981, 6, 1, 0, 0, 0, 0)).getTime(),
    (new Date(1982, 6, 1, 0, 0, 0, 0)).getTime(),
    (new Date(1983, 6, 1, 0, 0, 0, 0)).getTime(),
    (new Date(1985, 6, 1, 0, 0, 0, 0)).getTime(),
    (new Date(1988, 0, 1, 0, 0, 0, 0)).getTime(),
    (new Date(1990, 0, 1, 0, 0, 0, 0)).getTime(),
    (new Date(1991, 0, 1, 0, 0, 0, 0)).getTime(),
    (new Date(1992, 6, 1, 0, 0, 0, 0)).getTime(),
    (new Date(1993, 6, 1, 0, 0, 0, 0)).getTime(),
    (new Date(1994, 6, 1, 0, 0, 0, 0)).getTime(),
    (new Date(1996, 0, 1, 0, 0, 0, 0)).getTime(),
    (new Date(1997, 6, 1, 0, 0, 0, 0)).getTime(),
    (new Date(1999, 0, 1, 0, 0, 0, 0)).getTime(),
    (new Date(2006, 0, 1, 0, 0, 0, 0)).getTime(),
    (new Date(2009, 0, 1, 0, 0, 0, 0)).getTime(),
    (new Date(2012, 6, 1, 0, 0, 0, 0)).getTime(),
    (new Date(2015, 6, 1, 0, 0, 0, 0)).getTime(),
    (new Date(2017, 0, 1, 0, 0, 0, 0)).getTime()
];

// convert GPS time to a date & time object
var gpsTimeToDate = function(gpsWeek, millisIntoGPSWeek) {
    return new Date(gpsTimeToMillis(gpsWeek, millisIntoGPSWeek));
};

// 604,800 seconds in a week (60 x 60 x 24 x 7)
var gpsTimeToMillis = function(gpsWeek, millisIntoGPSWeek) {
    var millis = GPS_EPOCH_MILLIS + (gpsWeek * 604800000) + millisIntoGPSWeek; 

    // add leap seconds as appropriate
    for (var leap in leapSecondsMillis)
        if (millis >= leap)
            millis -= 1000;

    return millis;
};
Will Bain
  • 1
  • 2