From 7053ad02da0d4375f94eac06a317c4064b38fcd7 Mon Sep 17 00:00:00 2001 From: Oliver Jowett Date: Tue, 10 Feb 2015 21:49:37 +0000 Subject: [PATCH] Make aircraft tracking use milliseconds everywhere. --- dump1090.c | 2 +- dump1090.h | 8 ++------ interactive.c | 19 ++++++++++--------- net_io.c | 40 ++++++++++++++++++++-------------------- public_html/script.js | 6 +++--- track.c | 19 +++++++++---------- track.h | 14 +++++++------- view1090.c | 2 +- 8 files changed, 53 insertions(+), 57 deletions(-) diff --git a/dump1090.c b/dump1090.c index 3c3a969..3aa9adf 100644 --- a/dump1090.c +++ b/dump1090.c @@ -876,7 +876,7 @@ int main(int argc, char **argv) { } else if (!strcmp(argv[j],"--interactive-rows") && more) { Modes.interactive_rows = atoi(argv[++j]); } else if (!strcmp(argv[j],"--interactive-ttl") && more) { - Modes.interactive_display_ttl = atoi(argv[++j]); + Modes.interactive_display_ttl = (uint64_t)(1000 * atof(argv[++j])); } else if (!strcmp(argv[j],"--lat") && more) { Modes.fUserLat = atof(argv[++j]); } else if (!strcmp(argv[j],"--lon") && more) { diff --git a/dump1090.h b/dump1090.h index 9e0d862..2adf207 100644 --- a/dump1090.h +++ b/dump1090.h @@ -178,7 +178,7 @@ #define MODES_INTERACTIVE_REFRESH_TIME 250 // Milliseconds #define MODES_INTERACTIVE_ROWS 22 // Rows on screen -#define MODES_INTERACTIVE_DISPLAY_TTL 60 // Delete from display after 60 seconds +#define MODES_INTERACTIVE_DISPLAY_TTL 60000 // Delete from display after 60 seconds #define MODES_NET_HEARTBEAT_INTERVAL 60 // seconds @@ -316,8 +316,7 @@ struct { // Internal state int quiet; // Suppress stdout int interactive; // Interactive mode int interactive_rows; // Interactive mode: max number of rows - int interactive_display_ttl; // Interactive mode: TTL display - int interactive_delete_ttl; // Interactive mode: TTL before deletion + uint64_t interactive_display_ttl;// Interactive mode: TTL display int stats; // Print stats at exit in --ifile mode int onlyaddr; // Print only ICAO addresses int metric; // Use metric units @@ -342,9 +341,6 @@ struct { // Internal state // State tracking struct aircraft *aircrafts; - // Interactive mode - uint64_t interactive_last_update; // Last screen update in milliseconds - // Statistics struct stats stats_current; struct stats stats_alltime; diff --git a/interactive.c b/interactive.c index 07dfcff..22221a7 100644 --- a/interactive.c +++ b/interactive.c @@ -60,18 +60,19 @@ // void interactiveShowData(void) { struct aircraft *a = Modes.aircrafts; - time_t now = time(NULL); + static uint64_t next_update; + uint64_t now = mstime(); int count = 0; char progress; char spinner[4] = "|/-\\"; // Refresh screen every (MODES_INTERACTIVE_REFRESH_TIME) miliseconde - if ((mstime() - Modes.interactive_last_update) < MODES_INTERACTIVE_REFRESH_TIME) - {return;} + if (now < next_update) + return; - Modes.interactive_last_update = mstime(); + next_update = now + MODES_INTERACTIVE_REFRESH_TIME; - progress = spinner[time(NULL)%4]; + progress = spinner[(now/1000)%4]; #ifndef _WIN32 printf("\x1b[H\x1b[2J"); // Clear the screen @@ -129,8 +130,8 @@ void interactiveShowData(void) { if (a->bFlags & MODES_ACFLAGS_ALTITUDE_VALID) { snprintf(strFl,6,"F%03d",(altitude/100)); } - printf("%06x %-8s %-4s %-3s %-3s %4s %-6d %-2d\n", - a->addr, a->flight, strFl, strGs, strTt, strSquawk, msgs, (int)(now - a->seen)); + printf("%06x %-8s %-4s %-3s %-3s %4s %-6d %-2.0f\n", + a->addr, a->flight, strFl, strGs, strTt, strSquawk, msgs, (now - a->seen)/1000.0); } else { // Dump1090 display mode char strMode[5] = " "; @@ -159,10 +160,10 @@ void interactiveShowData(void) { snprintf(strFl, 6, "%5d", altitude); } - printf("%s%06X %-4s %-4s %-8s %5s %3s %3s %7s %8s %5.1f %5d %2d\n", + printf("%s%06X %-4s %-4s %-8s %5s %3s %3s %7s %8s %5.1f %5d %2.0f\n", (a->addr & MODES_NON_ICAO_ADDRESS) ? "~" : " ", (a->addr & 0xffffff), strMode, strSquawk, a->flight, strFl, strGs, strTt, - strLat, strLon, 10 * log10(signalAverage), msgs, (int)(now - a->seen)); + strLat, strLon, 10 * log10(signalAverage), msgs, (now - a->seen)/1000.0); } count++; } diff --git a/net_io.c b/net_io.c index 8f9821b..8a5528d 100644 --- a/net_io.c +++ b/net_io.c @@ -741,7 +741,7 @@ static const char *jsonEscapeString(const char *str) { } char *generateAircraftJson(const char *url_path, int *len) { - time_t now = time(NULL); + uint64_t now = mstime(); struct aircraft *a; int buflen = 1024; // The initial buffer is incremented as needed char *buf = (char *) malloc(buflen), *p = buf, *end = buf+buflen; @@ -750,10 +750,10 @@ char *generateAircraftJson(const char *url_path, int *len) { MODES_NOTUSED(url_path); p += snprintf(p, end-p, - "{ \"now\" : %d,\n" + "{ \"now\" : %.1f,\n" " \"messages\" : %u,\n" " \"aircraft\" : [", - (int)now, + now / 1000.0, Modes.stats_current.messages_total + Modes.stats_alltime.messages_total); for (a = Modes.aircrafts; a; a = a->next) { @@ -776,7 +776,7 @@ char *generateAircraftJson(const char *url_path, int *len) { if (a->bFlags & MODES_ACFLAGS_CALLSIGN_VALID) p += snprintf(p, end-p, ",\"flight\":\"%s\"", jsonEscapeString(a->flight)); if (a->bFlags & MODES_ACFLAGS_LATLON_VALID) - p += snprintf(p, end-p, ",\"lat\":%f,\"lon\":%f,\"seen_pos\":%d", a->lat, a->lon, (int)(now - a->seenLatLon)); + p += snprintf(p, end-p, ",\"lat\":%f,\"lon\":%f,\"seen_pos\":%.1f", a->lat, a->lon, (now - a->seenLatLon)/1000.0); if ((a->bFlags & MODES_ACFLAGS_AOG_VALID) && (a->bFlags & MODES_ACFLAGS_AOG)) p += snprintf(p, end-p, ",\"altitude\":\"ground\""); else if (a->bFlags & MODES_ACFLAGS_ALTITUDE_VALID) @@ -788,8 +788,8 @@ char *generateAircraftJson(const char *url_path, int *len) { if (a->bFlags & MODES_ACFLAGS_SPEED_VALID) p += snprintf(p, end-p, ",\"speed\":%d", a->speed); - p += snprintf(p, end-p, ",\"messages\":%ld,\"seen\":%d,\"rssi\":%.1f}", - a->messages, (int)(now - a->seen), + p += snprintf(p, end-p, ",\"messages\":%ld,\"seen\":%.1f,\"rssi\":%.1f}", + a->messages, (now - a->seen)/1000.0, 10 * log10((a->signalLevel[0] + a->signalLevel[1] + a->signalLevel[2] + a->signalLevel[3] + a->signalLevel[4] + a->signalLevel[5] + a->signalLevel[6] + a->signalLevel[7] + 1e-5) / 8)); @@ -1378,20 +1378,20 @@ void modesReadFromClient(struct client *c, char *sep, static void writeFATSV() { struct aircraft *a; - time_t now; - static time_t lastTime = 0; + uint64_t now; + static uint64_t next_update; if (!Modes.fatsv_out.connections) { return; // no active connections } - now = time(NULL); - if (now <= lastTime) { - // scan once a second at most + now = mstime(); + if (now < next_update) { return; } - lastTime = now; + // scan once a second at most + next_update = now + 1000; for (a = Modes.aircrafts; a; a = a->next) { int altValid = 0; @@ -1400,7 +1400,7 @@ static void writeFATSV() { int ground = 0; int latlonValid = 0; int useful = 0; - int emittedSecondsAgo; + uint64_t emittedMillisAgo; char *p, *end; // skip non-ICAO @@ -1415,10 +1415,10 @@ static void writeFATSV() { continue; } - emittedSecondsAgo = (int)(now - a->fatsv_last_emitted); + emittedMillisAgo = (now - a->fatsv_last_emitted); // don't emit more than once every five seconds - if (emittedSecondsAgo < 5) { + if (emittedMillisAgo < 5000) { continue; } @@ -1441,14 +1441,14 @@ static void writeFATSV() { } // if it's over 10,000 feet, don't emit more than once every 10 seconds - if (alt > 10000 && emittedSecondsAgo < 10) { + if (alt > 10000 && emittedMillisAgo < 10000) { continue; } // disable if you want only ads-b // also don't send mode S very often if (!latlonValid) { - if (emittedSecondsAgo < 30) { + if (emittedMillisAgo < 30000) { continue; } } else { @@ -1458,13 +1458,13 @@ static void writeFATSV() { if (alt < 10000) { // it hasn't changed much but we're below 10,000 feet // so update more frequently - if (emittedSecondsAgo < 10) { + if (emittedMillisAgo < 10000) { continue; } } else { // above 10,000 feet, don't update so often when it // hasn't changed much - if (emittedSecondsAgo < 30) { + if (emittedMillisAgo < 30000) { continue; } } @@ -1477,7 +1477,7 @@ static void writeFATSV() { end = p + TSV_MAX_PACKET_SIZE; # define bufsize(_p,_e) ((_p) >= (_e) ? (size_t)0 : (size_t)((_e) - (_p))) - p += snprintf(p, bufsize(p,end), "clock\t%ld\thexid\t%06X", a->seen, a->addr); + p += snprintf(p, bufsize(p,end), "clock\t%ld\thexid\t%06X", (long)(a->seen / 1000), a->addr); if (*a->flight != '\0') { p += snprintf(p, bufsize(p,end), "\tident\t%s", a->flight); diff --git a/public_html/script.js b/public_html/script.js index 0c2edc5..aa77af3 100644 --- a/public_html/script.js +++ b/public_html/script.js @@ -664,7 +664,7 @@ function refreshSelected() { if (selected.seen <= 1) { $('#selected_seen').text('now'); } else { - $('#selected_seen').text(selected.seen + 's'); + $('#selected_seen').text(selected.seen.toFixed(1) + 's'); } if (selected.position === null) { @@ -672,7 +672,7 @@ function refreshSelected() { $('#selected_follow').addClass('hidden'); } else { if (selected.seen_pos > 1) { - $('#selected_position').text(format_latlng(selected.position) + " (" + selected.seen_pos + "s)"); + $('#selected_position').text(format_latlng(selected.position) + " (" + selected.seen_pos.toFixed(1) + "s)"); } else { $('#selected_position').text(format_latlng(selected.position)); } @@ -728,7 +728,7 @@ function refreshTableInfo() { tableplane.tr.cells[5].textContent = format_distance_brief(tableplane.sitedist); tableplane.tr.cells[6].textContent = format_track_brief(tableplane.track); tableplane.tr.cells[7].textContent = tableplane.messages; - tableplane.tr.cells[8].textContent = tableplane.seen; + tableplane.tr.cells[8].textContent = tableplane.seen.toFixed(0); tableplane.tr.className = classes; diff --git a/track.c b/track.c index 97476cd..ae7f66f 100644 --- a/track.c +++ b/track.c @@ -170,7 +170,7 @@ static int doGlobalCPR(struct aircraft *a, int fflag, int surface) return 0; } -static int doLocalCPR(struct aircraft *a, int fflag, int surface, time_t now) +static int doLocalCPR(struct aircraft *a, int fflag, int surface, uint64_t now) { // relative CPR // find reference location @@ -179,14 +179,13 @@ static int doLocalCPR(struct aircraft *a, int fflag, int surface, time_t now) int result; if (a->bFlags & MODES_ACFLAGS_LATLON_REL_OK) { - int elapsed = (int)(now - a->seenLatLon); - if (elapsed < 0) elapsed = 0; + uint64_t elapsed = (now - a->seenLatLon); reflat = a->lat; reflon = a->lon; // impose a range limit based on 2000km/h speed - range_limit = 5e3 + (2000e3 * elapsed / 3600); // 5km + 2000km/h + range_limit = 5e3 + (2000e3 * elapsed / 3600 / 1000); // 5km + 2000km/h } else if (!surface && (Modes.bUserFlags & MODES_USER_LATLON_VALID)) { reflat = Modes.fUserLat; reflon = Modes.fUserLon; @@ -232,7 +231,7 @@ static int doLocalCPR(struct aircraft *a, int fflag, int surface, time_t now) return 0; } -static void updatePosition(struct aircraft *a, struct modesMessage *mm, time_t now) +static void updatePosition(struct aircraft *a, struct modesMessage *mm, uint64_t now) { int location_result = -1; int max_elapsed; @@ -312,7 +311,7 @@ static void updatePosition(struct aircraft *a, struct modesMessage *mm, time_t n struct aircraft *trackUpdateFromMessage(struct modesMessage *mm) { struct aircraft *a; - time_t now = time(NULL); + uint64_t now = mstime(); // Lookup our aircraft or create a new one a = trackFindAircraft(mm->addr); @@ -495,7 +494,7 @@ static void trackUpdateAircraftModeS() // If we don't receive new nessages within TRACK_AIRCRAFT_TTL // we remove the aircraft from the list. // -static void trackRemoveStaleAircraft(time_t now) +static void trackRemoveStaleAircraft(uint64_t now) { struct aircraft *a = Modes.aircrafts; struct aircraft *prev = NULL; @@ -528,12 +527,12 @@ static void trackRemoveStaleAircraft(time_t now) void trackPeriodicUpdate() { - static time_t next_update; - time_t now = time(NULL); + static uint64_t next_update; + uint64_t now = mstime(); // Only do updates once per second if (now >= next_update) { - next_update = now; + next_update = now + 1000; trackRemoveStaleAircraft(now); trackUpdateAircraftModeS(); } diff --git a/track.h b/track.h index 452b8d4..02e9611 100644 --- a/track.h +++ b/track.h @@ -50,11 +50,11 @@ #ifndef DUMP1090_TRACK_H #define DUMP1090_TRACK_H -/* Maximum age of tracked aircraft in seconds */ -#define TRACK_AIRCRAFT_TTL 300 +/* Maximum age of tracked aircraft in milliseconds */ +#define TRACK_AIRCRAFT_TTL 300000 -/* Maximum age of a tracked aircraft with only 1 message received, in seconds */ -#define TRACK_AIRCRAFT_ONEHIT_TTL 60 +/* Maximum age of a tracked aircraft with only 1 message received, in milliseconds */ +#define TRACK_AIRCRAFT_ONEHIT_TTL 60000 /* Structure used to describe the state of one tracked aircraft */ struct aircraft { @@ -65,8 +65,8 @@ struct aircraft { int speed; // Velocity int track; // Angle of flight int vert_rate; // Vertical rate. - time_t seen; // Time at which the last packet was received - time_t seenLatLon; // Time at which the last lat long was calculated + uint64_t seen; // Time (millis) at which the last packet was received + uint64_t seenLatLon; // Time (millis) at which the last lat long was calculated long messages; // Number of Mode S messages received int modeA; // Squawk int modeC; // Altitude @@ -76,7 +76,7 @@ struct aircraft { int fatsv_emitted_altitude; // last FA emitted altitude int fatsv_emitted_track; // last FA emitted angle of flight - time_t fatsv_last_emitted; // time aircraft was last FA emitted + uint64_t fatsv_last_emitted; // time (millis) aircraft was last FA emitted // Encoded latitude and longitude as extracted by odd and even CPR encoded messages int odd_cprlat; diff --git a/view1090.c b/view1090.c index 2ba21aa..e2ec008 100644 --- a/view1090.c +++ b/view1090.c @@ -233,7 +233,7 @@ int main(int argc, char **argv) { } else if (!strcmp(argv[j],"--interactive")) { Modes.interactive = 1; } else if (!strcmp(argv[j],"--interactive-ttl") && more) { - Modes.interactive_display_ttl = atoi(argv[++j]); + Modes.interactive_display_ttl = (uint64_t)(1000 * atof(argv[++j])); } else if (!strcmp(argv[j],"--interactive-rtl1090")) { Modes.interactive = 1; Modes.interactive_rtl1090 = 1;