main.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. /*
  2. * GPS Test Tool - PC Application
  3. *
  4. * Tests GPS filtering and GPX generation using actual embedded code
  5. * Usage: ./gps-test-tool <input.nmea>
  6. *
  7. * Generates:
  8. * - output_filtered.gpx
  9. * - output_unfiltered.gpx
  10. * - debug_filtered.txt
  11. * - debug_unfiltered.txt
  12. */
  13. #define PC_BUILD
  14. #include "main.h"
  15. /* Global variables expected by project code */
  16. volatile struct system_s System;
  17. struct location_s location;
  18. time_t utc;
  19. unsigned char config_flags = 0;
  20. /* File handle for debug output redirection */
  21. FILE *debug_output = NULL;
  22. /* Function prototypes from project files */
  23. unsigned char gpx_init(FIL *file);
  24. unsigned char gpx_close(FIL *file);
  25. void gpx_process_point(struct location_s *loc, FIL *file);
  26. time_t gps_parse(const char *nmea);
  27. /* Time function implementation */
  28. char *get_iso_time(time_t time, unsigned char local) {
  29. static char output[32];
  30. struct tm *ct = gmtime(&time);
  31. sprintf(output, "%04d-%02d-%02dT%02d:%02d:%02d.000Z",
  32. ct->tm_year + 1900, ct->tm_mon + 1, ct->tm_mday,
  33. ct->tm_hour, ct->tm_min, ct->tm_sec);
  34. return output;
  35. }
  36. void iso_time_to_filename(char *time) {
  37. while (*time) {
  38. switch (*time) {
  39. case ':': *time = '-'; break;
  40. case '+': *time = 'p'; break;
  41. }
  42. time++;
  43. }
  44. }
  45. /* Reset system state */
  46. void reset_system(void) {
  47. memset((void*)&System, 0, sizeof(System));
  48. memset(&location, 0, sizeof(location));
  49. System.conf.skip_points = 0; /* Don't skip points for testing */
  50. System.conf.auto_pause_dist = 100;
  51. System.conf.min_sats = 4; /* Require at least 4 satellites */
  52. System.tracking_paused = 0;
  53. System.tracking_auto_paused = 0;
  54. utc = 0;
  55. }
  56. /* Process NMEA file with specified filter setting */
  57. int process_nmea_file(const char *input_file, const char *output_gpx,
  58. const char *debug_file, int filters_enabled) {
  59. FILE *input;
  60. FIL gpx_file;
  61. char line[256];
  62. int point_count = 0;
  63. /* Open input file */
  64. input = fopen(input_file, "r");
  65. if (!input) {
  66. fprintf(stderr, "Error: Cannot open input file '%s'\n", input_file);
  67. return 1;
  68. }
  69. /* Open debug output file */
  70. debug_output = fopen(debug_file, "w");
  71. if (!debug_output) {
  72. fprintf(stderr, "Error: Cannot open debug file '%s'\n", debug_file);
  73. fclose(input);
  74. return 1;
  75. }
  76. /* Configure filters */
  77. config_flags = filters_enabled ? 0 : CONFFLAG_DISABLE_FILTERS;
  78. /* Reset system state */
  79. reset_system();
  80. /* Open GPX output file */
  81. if (f_open(&gpx_file, output_gpx, FA_WRITE | FA_OPEN_ALWAYS) != 0) {
  82. fprintf(stderr, "Error: Cannot open GPX file '%s'\n", output_gpx);
  83. fclose(input);
  84. fclose(debug_output);
  85. return 1;
  86. }
  87. /* Initialize GPX file */
  88. if (gpx_init(&gpx_file) != 0) {
  89. fprintf(stderr, "Error: GPX initialization failed\n");
  90. fclose(input);
  91. fclose(debug_output);
  92. f_close(&gpx_file);
  93. return 1;
  94. }
  95. fprintf(debug_output, "=== GPS Test Tool - %s ===\n",
  96. filters_enabled ? "FILTERS ENABLED" : "FILTERS DISABLED");
  97. fprintf(debug_output, "Input: %s\n", input_file);
  98. fprintf(debug_output, "Output: %s\n\n", output_gpx);
  99. /* Process NMEA file line by line */
  100. while (fgets(line, sizeof(line), input)) {
  101. size_t len = strlen(line);
  102. /* Skip empty lines */
  103. if (len == 0) continue;
  104. /* Ensure line ends with \r\n as expected by gps_parse */
  105. if (len > 0 && line[len-1] == '\n') {
  106. line[len-1] = '\0';
  107. len--;
  108. }
  109. if (len > 0 && line[len-1] == '\r') {
  110. line[len-1] = '\0';
  111. len--;
  112. }
  113. /* Add back \r\n for gps_parse */
  114. strcat(line, "\r\n");
  115. /* Parse NMEA sentence */
  116. if (gps_parse(line) != 0) {
  117. /* Valid location data received (RMC parsed) */
  118. /* Only process if we have valid coordinates from GGA */
  119. if (System.location_valid == LOC_VALID_NEW || System.location_valid == LOC_VALID) {
  120. gpx_process_point(&location, &gpx_file);
  121. point_count++;
  122. }
  123. }
  124. }
  125. /* Close GPX file */
  126. gpx_close(&gpx_file);
  127. /* Print summary */
  128. fprintf(debug_output, "\n=== Summary ===\n");
  129. fprintf(debug_output, "Points processed: %d\n", point_count);
  130. fprintf(debug_output, "Total distance: %.2f km\n", System.distance / 100000.0);
  131. fprintf(debug_output, "Elevation gain: %.1f m\n", System.elevation_gain / 10.0);
  132. fprintf(debug_output, "Elevation loss: %.1f m\n", System.elevation_loss / 10.0);
  133. /* Close files */
  134. fclose(input);
  135. fclose(debug_output);
  136. debug_output = NULL;
  137. printf("Processed %d points -> %s (filters %s)\n",
  138. point_count, output_gpx, filters_enabled ? "ON" : "OFF");
  139. return 0;
  140. }
  141. int main(int argc, char *argv[]) {
  142. int ret;
  143. printf("GPS Test Tool v1.0\n");
  144. printf("==================\n\n");
  145. if (argc != 2) {
  146. fprintf(stderr, "Usage: %s <input.nmea>\n", argv[0]);
  147. fprintf(stderr, "\nGenerates:\n");
  148. fprintf(stderr, " - output_filtered.gpx\n");
  149. fprintf(stderr, " - output_unfiltered.gpx\n");
  150. fprintf(stderr, " - debug_filtered.txt\n");
  151. fprintf(stderr, " - debug_unfiltered.txt\n");
  152. return 1;
  153. }
  154. /* Process with filters enabled */
  155. printf("Processing with filters ENABLED...\n");
  156. ret = process_nmea_file(argv[1], "output_filtered.gpx",
  157. "debug_filtered.txt", 1);
  158. if (ret != 0) {
  159. fprintf(stderr, "Failed to process with filters enabled\n");
  160. return ret;
  161. }
  162. /* Process with filters disabled */
  163. printf("Processing with filters DISABLED...\n");
  164. ret = process_nmea_file(argv[1], "output_unfiltered.gpx",
  165. "debug_unfiltered.txt", 0);
  166. if (ret != 0) {
  167. fprintf(stderr, "Failed to process with filters disabled\n");
  168. return ret;
  169. }
  170. printf("\nProcessing complete!\n");
  171. printf("Generated files:\n");
  172. printf(" - output_filtered.gpx (filters ON)\n");
  173. printf(" - output_unfiltered.gpx (filters OFF)\n");
  174. printf(" - debug_filtered.txt (debug output with filters)\n");
  175. printf(" - debug_unfiltered.txt (debug output without filters)\n");
  176. return 0;
  177. }