diff --git a/rffit.c b/rffit.c index 38b9021..488664c 100644 --- a/rffit.c +++ b/rffit.c @@ -112,6 +112,7 @@ void format_tle(orbit_t orb,char *line1,char *line2) int i,csum; char sbstar[]=" 00000-0",bstar[13]; char csumstr[2]; + char satstr[6]; // Format Bstar term if (fabs(orb.bstar)>1e-9) { @@ -120,8 +121,10 @@ void format_tle(orbit_t orb,char *line1,char *line2) sbstar[4] = bstar[5]; sbstar[5] = bstar[6]; sbstar[6] = bstar[8]; sbstar[7] = bstar[10]; sbstar[8] = '\0'; } // Print lines - sprintf(line1,"1 %05dU %2d%012.8f .00000000 00000-0 %8s 0 0",orb.satno,orb.ep_year-2000,orb.ep_day,sbstar); - sprintf(line2,"2 %05d %8.4f %8.4f %07.0f %8.4f %8.4f %11.8f 0",orb.satno,DEG(orb.eqinc),DEG(orb.ascn),1E7*orb.ecc,DEG(orb.argp),DEG(orb.mnan),orb.rev); + number_to_alpha5(orb.satno,satstr); + satstr[5]='\0'; + sprintf(line1,"1 %5sU %2d%012.8f .00000000 00000-0 %8s 0 0",satstr,orb.ep_year-2000,orb.ep_day,sbstar); + sprintf(line2,"2 %5s %8.4f %8.4f %07.0f %8.4f %8.4f %11.8f 0",satstr,DEG(orb.eqinc),DEG(orb.ascn),1E7*orb.ecc,DEG(orb.argp),DEG(orb.mnan),orb.rev); // Compute checksums for (i=0,csum=0;i static char *st_start(char *buf); static long i_read(char *str, int start, int stop); static double d_read(char *str, int start, int stop); +// Fixed mapping +// Only capital letters and numbers are used in Alpha-5. The letters “I” and “O” are omitted to avoid confusion with the numbers “1” and “0”. +const char mapping[] = "0123456789ABCDEFGHJKLMNPQRSTUVWXYZ"; + +// Function to convert alpha5 format to number +int alpha5_to_number(const char *s) +{ + // Split components + char first_char = s[0]; + int digits = 0; + sscanf(s + 1, "%4d", &digits); // Get the last four digits + + // Decode first character + int first_digit = 0; + if (first_char == ' ') { + first_digit = 0; + } else if (isdigit(first_char)) { + first_digit = first_char - '0'; + } else { + for (int i = 0; mapping[i] != '\0'; i++) { + if (mapping[i] == first_char) { + first_digit = i; + break; + } + } + } + + // Create and return number + return first_digit * 10000 + digits; +} + +// Function to convert number to alpha5 format +void number_to_alpha5(int number, char *result) +{ + // Split components + int first_digit = number / 10000; + int digits = number % 10000; + + // Get char + char first_char = mapping[first_digit]; + + // Create string + sprintf(result, "%c%04d", first_char, digits); + + return; +} + +// Function to strip leading spaces +void strip_leading_spaces(const char *s, char *result) +{ + while (*s == ' ') { + s++; // Skip leading spaces + } + strcpy(result, s); // Copy the remainder of the string + + return; +} + +// Function to zero pad a string +void zero_pad(const char *s, char *result) +{ + char stripped[6]; // Temporarily store the string without leading spaces + strip_leading_spaces(s, stripped); + + if (isdigit(stripped[0])) { + int value = atoi(stripped); + sprintf(result, "%05d", value); + } else { + strcpy(result, stripped); // No zero-padding for non-digit strings + } +} + + /* ==================================================================== Read a string from key board, remove CR/LF etc. ==================================================================== */ @@ -78,6 +150,7 @@ int read_twoline(FILE *fp, long search_satno, orbit_t *orb, char *satname) static char search[ST_SIZE]; static char line1[ST_SIZE]; static char line2[ST_SIZE]; + char search_satstr[6]; char *st1, *st2; int found = 0; double bm, bx; @@ -85,6 +158,9 @@ int read_twoline(FILE *fp, long search_satno, orbit_t *orb, char *satname) st1 = line1; st2 = line2; + // alpha5 designation to search + number_to_alpha5(search_satno, search_satstr); + do { if(fgets(line1, ST_SIZE-1, fp) == NULL) return -1; st1 = st_start(line1); @@ -93,11 +169,14 @@ int read_twoline(FILE *fp, long search_satno, orbit_t *orb, char *satname) } while((st1[0] != '1') || (st1[1] != ' ')); if (search_satno != 0) { - sprintf(search, "1 %05ld", search_satno); + sprintf(search, "1 %5s", search_satstr); } else { // If no search_satno given, set it to the currently read one // so next do/while loop will find it - search_satno = atol(st1+2); + //search_satno = atol(st1+2); + strncpy(search_satstr, st1+2, 5); + search_satstr[5]='\0'; + search_satno=alpha5_to_number(search_satstr); strncpy(search, line1, 7); search[7] = '\0'; } diff --git a/satutl.h b/satutl.h index e40717e..8d04ad8 100644 --- a/satutl.h +++ b/satutl.h @@ -17,13 +17,17 @@ void conditional_copy_satname(char * satname, char * current_line); int read_twoline(FILE *fp, long satno, orbit_t *orb, char *satname); void *vector(size_t num, size_t size); void print_orb(orbit_t *orb); - +int alpha5_to_number(const char *s); +void number_to_alpha5(int number, char *result); +void zero_pad(const char *s, char *result); +void strip_leading_spaces(const char *s, char *result); + /** aries.c **/ double gha_aries(double jd); /** ferror.c **/ void fatal_error(const char *format, ...); - + #ifdef __cplusplus } #endif diff --git a/tests/data/alpha5.tle b/tests/data/alpha5.tle new file mode 100644 index 0000000..d8c00d4 --- /dev/null +++ b/tests/data/alpha5.tle @@ -0,0 +1,6 @@ +0 ISS (ZARYA) +1 B5544U 98067A 24356.58519896 .00014389 00000-0 25222-3 0 9992 +2 B5544 51.6403 106.8969 0007877 6.1421 113.2479 15.50801739487615 +0 ISS (ZARYA) +1 Z9999U 98067A 24356.58519896 .00014389 00000-0 25222-3 0 9992 +2 Z9999 51.6403 106.8969 0007877 6.1421 113.2479 15.50801739487615 diff --git a/tests/tests_rftles.c b/tests/tests_rftles.c index 5fe833c..7aa90fd 100644 --- a/tests/tests_rftles.c +++ b/tests/tests_rftles.c @@ -45,6 +45,18 @@ int setup(void **state) { return 0; } +int setup_alpha5(void **state) { + tle_array_t * tle_array = load_tles("tests/data/alpha5.tle"); + + if (tle_array == NULL) { + return -1; + } + + *state = tle_array; + + return 0; +} + int teardown(void **state) { free_tles(*state); @@ -212,6 +224,32 @@ void TLE_load_catalog_id_from_file(void **state) { assert_string_equal(tle->name, "OSCAR 7 (AO-7)"); } +void TLE_decode_alpha5_designation(void **state) { + tle_array_t tle_array = **(tle_array_t **)state; + + assert_non_null(tle_array.tles); + assert_int_equal(tle_array.number_of_elements, 2); + + // 1st element, B5544 - ISS + tle_t * tle = get_tle_by_catalog_id(&tle_array, 115544); + + assert_non_null(tle->name); + assert_string_equal(tle->name, "ISS (ZARYA)"); + + assert_string_equal(tle->orbit.desig, "98067A"); + assert_int_equal(tle->orbit.satno, 115544); + + // 2nd element, 339999 - ISS + tle = get_tle_by_catalog_id(&tle_array, 339999); + + assert_non_null(tle->name); + assert_string_equal(tle->name, "ISS (ZARYA)"); + + assert_string_equal(tle->orbit.desig, "98067A"); + assert_int_equal(tle->orbit.satno, 339999); + +} + // Entry point to run all tests int run_tle_tests() { const struct CMUnitTest tests[] = { @@ -221,6 +259,7 @@ int run_tle_tests() { cmocka_unit_test_setup_teardown(TLE_load_index_from_file, setup, teardown), cmocka_unit_test_setup_teardown(TLE_load_invalid_catalog_id_from_file, setup, teardown), cmocka_unit_test_setup_teardown(TLE_load_catalog_id_from_file, setup, teardown), + cmocka_unit_test_setup_teardown(TLE_decode_alpha5_designation, setup_alpha5, teardown), }; return cmocka_run_group_tests_name("TLE", tests, NULL, NULL);