/* * GPS Test Tool - PC Application * * Tests GPS filtering and GPX generation using actual embedded code * Usage: ./gps-test-tool * * Generates: * - output_filtered.gpx * - output_unfiltered.gpx * - debug_filtered.txt * - debug_unfiltered.txt */ #define PC_BUILD #include "main.h" /* Global variables expected by project code */ volatile struct system_s System; struct location_s location; time_t utc; unsigned char config_flags = 0; /* File handle for debug output redirection */ FILE *debug_output = NULL; /* Function prototypes from project files */ unsigned char gpx_init(FIL *file); unsigned char gpx_close(FIL *file); void gpx_process_point(struct location_s *loc, FIL *file); time_t gps_parse(const char *nmea); /* Time function implementation */ char *get_iso_time(time_t time, unsigned char local) { static char output[32]; struct tm *ct = gmtime(&time); sprintf(output, "%04d-%02d-%02dT%02d:%02d:%02d.000Z", ct->tm_year + 1900, ct->tm_mon + 1, ct->tm_mday, ct->tm_hour, ct->tm_min, ct->tm_sec); return output; } void iso_time_to_filename(char *time) { while (*time) { switch (*time) { case ':': *time = '-'; break; case '+': *time = 'p'; break; } time++; } } /* Reset system state */ void reset_system(void) { memset((void*)&System, 0, sizeof(System)); memset(&location, 0, sizeof(location)); System.conf.skip_points = 0; /* Don't skip points for testing */ System.conf.auto_pause_dist = 100; System.conf.min_sats = 4; /* Require at least 4 satellites */ System.tracking_paused = 0; System.tracking_auto_paused = 0; utc = 0; } /* Process NMEA file with specified filter setting */ int process_nmea_file(const char *input_file, const char *output_gpx, const char *debug_file, int filters_enabled) { FILE *input; FIL gpx_file; char line[256]; int point_count = 0; /* Open input file */ input = fopen(input_file, "r"); if (!input) { fprintf(stderr, "Error: Cannot open input file '%s'\n", input_file); return 1; } /* Open debug output file */ debug_output = fopen(debug_file, "w"); if (!debug_output) { fprintf(stderr, "Error: Cannot open debug file '%s'\n", debug_file); fclose(input); return 1; } /* Configure filters */ config_flags = filters_enabled ? 0 : CONFFLAG_DISABLE_FILTERS; /* Reset system state */ reset_system(); /* Open GPX output file */ if (f_open(&gpx_file, output_gpx, FA_WRITE | FA_OPEN_ALWAYS) != 0) { fprintf(stderr, "Error: Cannot open GPX file '%s'\n", output_gpx); fclose(input); fclose(debug_output); return 1; } /* Initialize GPX file */ if (gpx_init(&gpx_file) != 0) { fprintf(stderr, "Error: GPX initialization failed\n"); fclose(input); fclose(debug_output); f_close(&gpx_file); return 1; } fprintf(debug_output, "=== GPS Test Tool - %s ===\n", filters_enabled ? "FILTERS ENABLED" : "FILTERS DISABLED"); fprintf(debug_output, "Input: %s\n", input_file); fprintf(debug_output, "Output: %s\n\n", output_gpx); /* Process NMEA file line by line */ while (fgets(line, sizeof(line), input)) { size_t len = strlen(line); /* Skip empty lines */ if (len == 0) continue; /* Ensure line ends with \r\n as expected by gps_parse */ if (len > 0 && line[len-1] == '\n') { line[len-1] = '\0'; len--; } if (len > 0 && line[len-1] == '\r') { line[len-1] = '\0'; len--; } /* Add back \r\n for gps_parse */ strcat(line, "\r\n"); /* Parse NMEA sentence */ if (gps_parse(line) != 0) { /* Valid location data received (RMC parsed) */ /* Only process if we have valid coordinates from GGA */ if (System.location_valid == LOC_VALID_NEW || System.location_valid == LOC_VALID) { gpx_process_point(&location, &gpx_file); point_count++; } } } /* Close GPX file */ gpx_close(&gpx_file); /* Print summary */ fprintf(debug_output, "\n=== Summary ===\n"); fprintf(debug_output, "Points processed: %d\n", point_count); fprintf(debug_output, "Total distance: %.2f km\n", System.distance / 100000.0); fprintf(debug_output, "Elevation gain: %.1f m\n", System.elevation_gain / 10.0); fprintf(debug_output, "Elevation loss: %.1f m\n", System.elevation_loss / 10.0); /* Close files */ fclose(input); fclose(debug_output); debug_output = NULL; printf("Processed %d points -> %s (filters %s)\n", point_count, output_gpx, filters_enabled ? "ON" : "OFF"); return 0; } int main(int argc, char *argv[]) { int ret; printf("GPS Test Tool v1.0\n"); printf("==================\n\n"); if (argc != 2) { fprintf(stderr, "Usage: %s \n", argv[0]); fprintf(stderr, "\nGenerates:\n"); fprintf(stderr, " - output_filtered.gpx\n"); fprintf(stderr, " - output_unfiltered.gpx\n"); fprintf(stderr, " - debug_filtered.txt\n"); fprintf(stderr, " - debug_unfiltered.txt\n"); return 1; } /* Process with filters enabled */ printf("Processing with filters ENABLED...\n"); ret = process_nmea_file(argv[1], "output_filtered.gpx", "debug_filtered.txt", 1); if (ret != 0) { fprintf(stderr, "Failed to process with filters enabled\n"); return ret; } /* Process with filters disabled */ printf("Processing with filters DISABLED...\n"); ret = process_nmea_file(argv[1], "output_unfiltered.gpx", "debug_unfiltered.txt", 0); if (ret != 0) { fprintf(stderr, "Failed to process with filters disabled\n"); return ret; } printf("\nProcessing complete!\n"); printf("Generated files:\n"); printf(" - output_filtered.gpx (filters ON)\n"); printf(" - output_unfiltered.gpx (filters OFF)\n"); printf(" - debug_filtered.txt (debug output with filters)\n"); printf(" - debug_unfiltered.txt (debug output without filters)\n"); return 0; }