Skip to content

Commit

Permalink
Merge pull request #6 from ZeSly/datetime2
Browse files Browse the repository at this point in the history
Fix gpx time and add --datetime option to add a dateTime column in csv
  • Loading branch information
stronnag authored Jun 13, 2019
2 parents fde7718 + d5bdb27 commit f856c02
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 13 deletions.
1 change: 1 addition & 0 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ Options:
--index <num> Choose the log from the file that should be decoded (or omit to decode all)
--limits Print the limits and range of each field
--stdout Write log to stdout instead of to a file
--datetime Add a dateTime column with UTC date time
--unit-amperage <unit> Current meter unit (raw|mA|A), default is A (amps)
--unit-frame-time <unit> Frame timestamp unit (us|s), default is us (microseconds)
--unit-height <unit> Height unit (m|cm|ft), default is cm (centimeters)
Expand Down
46 changes: 39 additions & 7 deletions src/blackbox_decode.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ typedef struct decodeOptions_t {
int simulateIMU, imuIgnoreMag;
int simulateCurrentMeter;
int mergeGPS;
int datetime;
const char *outputPrefix;

bool overrideSimCurrentMeterOffset, overrideSimCurrentMeterScale;
Expand All @@ -55,6 +56,7 @@ decodeOptions_t options = {
.simulateIMU = false, .imuIgnoreMag = 0,
.simulateCurrentMeter = false,
.mergeGPS = 0,
.datetime = 0,

.overrideSimCurrentMeterOffset = false,
.overrideSimCurrentMeterScale = false,
Expand Down Expand Up @@ -151,8 +153,12 @@ static void fprintfMilliampsInUnit(FILE *file, int32_t milliamps, Unit unit)
}
}

static void fprintfMicrosecondsInUnit(FILE *file, int64_t microseconds, Unit unit)
static void fprintfMicrosecondsInUnit(flightLog_t *log, FILE *file, int64_t microseconds, Unit unit)
{
int64_t startTime = log->sysConfig.logStartTime.tm_hour * 3600 + log->sysConfig.logStartTime.tm_min * 60 + log->sysConfig.logStartTime.tm_sec;
int64_t time = microseconds + startTime * 1000000;
uint32_t hours, mins, secs, frac;

switch (unit) {
case UNIT_MICROSECONDS:
fprintf(file, "%" PRId64, microseconds);
Expand All @@ -168,6 +174,21 @@ static void fprintfMicrosecondsInUnit(FILE *file, int64_t microseconds, Unit uni
exit(-1);
break;
}

if (options.datetime) {
frac = (uint32_t)(time % 1000000);
secs = (uint32_t)(time / 1000000);

mins = secs / 60;
secs %= 60;

hours = mins / 60;
mins %= 60;

fprintf(file, ",%04u-%02u-%02uT%02u:%02u:%02u.%06uZ",
log->sysConfig.logStartTime.tm_year + 1900, log->sysConfig.logStartTime.tm_mon + 1, log->sysConfig.logStartTime.tm_mday,
hours, mins, secs, frac);
}
}

static bool fprintfMainFieldInUnit(flightLog_t *log, FILE *file, int fieldIndex, int64_t fieldValue, Unit unit)
Expand Down Expand Up @@ -258,7 +279,7 @@ static bool fprintfMainFieldInUnit(flightLog_t *log, FILE *file, int fieldIndex,
case UNIT_MILLISECONDS:
case UNIT_SECONDS:
if (fieldIndex == log->mainFieldIndexes.time) {
fprintfMicrosecondsInUnit(file, fieldValue, unit);
fprintfMicrosecondsInUnit(log, file, fieldValue, unit);
return true;
}
break;
Expand Down Expand Up @@ -384,7 +405,12 @@ void createGPSCSVFile(flightLog_t *log)

if (gpsCsvFile) {
// Since the GPS frame itself may or may not include a timestamp field, skip it and print our own:
fprintf(gpsCsvFile, "time (%s), ", UNIT_NAME[options.unitFrameTime]);
if (options.datetime) {
fprintf(gpsCsvFile, "time (%s), dateTime,", UNIT_NAME[options.unitFrameTime]);
}
else {
fprintf(gpsCsvFile, "time (%s),", UNIT_NAME[options.unitFrameTime]);
}

outputFieldNamesHeader(gpsCsvFile, &log->frameDefs['G'], gpsGFieldUnit, true);

Expand Down Expand Up @@ -517,13 +543,13 @@ void outputGPSFrame(flightLog_t *log, int64_t *frame)
bool haveRequiredPrecision = log->gpsFieldIndexes.GPS_numSat == -1 || frame[log->gpsFieldIndexes.GPS_numSat] >= MIN_GPS_SATELLITES;

if (haveRequiredFields && haveRequiredPrecision) {
gpxWriterAddPoint(gpx, gpsFrameTime, frame[log->gpsFieldIndexes.GPS_coord[0]], frame[log->gpsFieldIndexes.GPS_coord[1]], frame[log->gpsFieldIndexes.GPS_altitude]);
gpxWriterAddPoint(gpx, log, gpsFrameTime, frame[log->gpsFieldIndexes.GPS_coord[0]], frame[log->gpsFieldIndexes.GPS_coord[1]], frame[log->gpsFieldIndexes.GPS_altitude]);
}

createGPSCSVFile(log);

if (gpsCsvFile) {
fprintfMicrosecondsInUnit(gpsCsvFile, gpsFrameTime, options.unitFrameTime);
fprintfMicrosecondsInUnit(log, gpsCsvFile, gpsFrameTime, options.unitFrameTime);
fprintf(gpsCsvFile, ", ");

outputGPSFields(log, gpsCsvFile, frame);
Expand Down Expand Up @@ -694,7 +720,7 @@ void onFrameReadyMerge(flightLog_t *log, bool frameValid, int64_t *frame, uint8_
bool haveRequiredPrecision = log->gpsFieldIndexes.GPS_numSat == -1 || frame[log->gpsFieldIndexes.GPS_numSat] >= MIN_GPS_SATELLITES;

if (haveRequiredFields && haveRequiredPrecision) {
gpxWriterAddPoint(gpx, gpsFrameTime, frame[log->gpsFieldIndexes.GPS_coord[0]], frame[log->gpsFieldIndexes.GPS_coord[1]], frame[log->gpsFieldIndexes.GPS_altitude]);
gpxWriterAddPoint(gpx, log, gpsFrameTime, frame[log->gpsFieldIndexes.GPS_coord[0]], frame[log->gpsFieldIndexes.GPS_coord[1]], frame[log->gpsFieldIndexes.GPS_altitude]);
}
}
break;
Expand Down Expand Up @@ -908,6 +934,10 @@ void writeMainCSVHeader(flightLog_t *log)
if (mainFieldUnit[i] != UNIT_RAW) {
fprintf(csvFile, " (%s)", UNIT_NAME[mainFieldUnit[i]]);
}

if (options.datetime && strcmp(log->frameDefs['I'].fieldName[i], "time") == 0) {
fprintf(csvFile, ", dateTime");
}
}

if (options.simulateIMU) {
Expand Down Expand Up @@ -1234,6 +1264,7 @@ void printUsage(const char *argv0)
" --index <num> Choose the log from the file that should be decoded (or omit to decode all)\n"
" --limits Print the limits and range of each field\n"
" --stdout Write log to stdout instead of to a file\n"
" --datetime Add a dateTime column with UTC date time\n"
" --unit-amperage <unit> Current meter unit (raw|mA|A), default is A (amps)\n"
" --unit-flags <unit> State flags unit (raw|flags), default is flags\n"
" --unit-frame-time <unit> Frame timestamp unit (us|s), default is us (microseconds)\n"
Expand Down Expand Up @@ -1295,7 +1326,8 @@ void parseCommandlineOptions(int argc, char **argv)
{"debug", no_argument, &options.debug, 1},
{"limits", no_argument, &options.limits, 1},
{"stdout", no_argument, &options.toStdout, 1},
{"merge-gps", no_argument, &options.mergeGPS, 1},
{ "merge-gps", no_argument, &options.mergeGPS, 1 },
{ "datetime", no_argument, &options.datetime, 1 },
{"simulate-imu", no_argument, &options.simulateIMU, 1},
{"simulate-current-meter", no_argument, &options.simulateCurrentMeter, 1},
{"imu-ignore-mag", no_argument, &options.imuIgnoreMag, 1},
Expand Down
13 changes: 9 additions & 4 deletions src/gpxwriter.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ void gpxWriterAddPreamble(gpxWriter_t *gpx)
* Time is in microseconds since device power-on. Lat and lon are degrees multiplied by GPS_DEGREES_DIVIDER. Altitude
* is in meters.
*/
void gpxWriterAddPoint(gpxWriter_t *gpx, int64_t time, int32_t lat, int32_t lon, int16_t altitude)
void gpxWriterAddPoint(gpxWriter_t *gpx, flightLog_t *log, int64_t time, int32_t lat, int32_t lon, int16_t altitude)
{
char negSign[] = "-";
char noSign[] = "";
Expand All @@ -40,6 +40,7 @@ void gpxWriterAddPoint(gpxWriter_t *gpx, int64_t time, int32_t lat, int32_t lon,

fprintf(gpx->file, "<trk><name>Blackbox flight log</name><trkseg>\n");

gpx->startTime = log->sysConfig.logStartTime.tm_hour * 3600 + log->sysConfig.logStartTime.tm_min * 60 + log->sysConfig.logStartTime.tm_sec;
gpx->state = GPXWRITER_STATE_WRITING_TRACK;
}

Expand All @@ -58,16 +59,20 @@ void gpxWriterAddPoint(gpxWriter_t *gpx, int64_t time, int32_t lat, int32_t lon,
//We'll just assume that the timespan is less than 24 hours, and make up a date
uint32_t hours, mins, secs, frac;

frac = time % 1000000;
secs = time / 1000000;
time += gpx->startTime * 1000000;

frac = (uint32_t)(time % 1000000);
secs = (uint32_t)(time / 1000000);

mins = secs / 60;
secs %= 60;

hours = mins / 60;
mins %= 60;

fprintf(gpx->file, "<time>2000-01-01T%02u:%02u:%02u.%06uZ</time>", hours, mins, secs, frac);
fprintf(gpx->file, "<time>%04u-%02u-%02uT%02u:%02u:%02u.%06uZ</time>",
log->sysConfig.logStartTime.tm_year + 1900, log->sysConfig.logStartTime.tm_mon + 1, log->sysConfig.logStartTime.tm_mday,
hours, mins, secs, frac);
}
fprintf(gpx->file, "</trkpt>\n");
}
Expand Down
6 changes: 4 additions & 2 deletions src/gpxwriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include <stdint.h>
#include <stdio.h>

#include "parser.h"

typedef enum GpxWriterState {
GPXWRITER_STATE_EMPTY = 0,
GPXWRITER_STATE_WRITING_TRACK,
Expand All @@ -12,11 +14,11 @@ typedef enum GpxWriterState {
typedef struct gpxWriter_t {
GpxWriterState state;
FILE *file;

char *filename;
uint64_t startTime;
} gpxWriter_t;

void gpxWriterAddPoint(gpxWriter_t *gpx, int64_t time, int32_t lat, int32_t lon, int16_t altitude);
void gpxWriterAddPoint(gpxWriter_t *gpx, flightLog_t *log, int64_t time, int32_t lat, int32_t lon, int16_t altitude);
gpxWriter_t* gpxWriterCreate(const char *filename);
void gpxWriterDestroy(gpxWriter_t* gpx);

Expand Down
8 changes: 8 additions & 0 deletions src/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,14 @@ static void parseHeaderLine(flightLog_t *log, mmapStream_t *stream)
log->sysConfig.vbatType = INAV_V2;
}
}
else if (strcmp(fieldName, "Log start datetime") == 0) {
log->sysConfig.logStartTime.tm_year = atoi(fieldValue + 2) + 100;
log->sysConfig.logStartTime.tm_mon = atoi(fieldValue + 5) - 1;
log->sysConfig.logStartTime.tm_mday = atoi(fieldValue + 8);
log->sysConfig.logStartTime.tm_hour = atoi(fieldValue + 11);
log->sysConfig.logStartTime.tm_min = atoi(fieldValue + 14);
log->sysConfig.logStartTime.tm_sec = atoi(fieldValue + 17);
}
}

/**
Expand Down
3 changes: 3 additions & 0 deletions src/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <time.h>

#include "blackbox_fielddefs.h"

Expand Down Expand Up @@ -139,6 +140,8 @@ typedef struct flightLogSysConfig_t {
FirmwareRevison firmwareRevison;

VbatType vbatType;

struct tm logStartTime;
} flightLogSysConfig_t;

typedef struct flightLogFrameDef_t {
Expand Down

0 comments on commit f856c02

Please sign in to comment.