// Copyright (c) CNES 2008 // // This software is part of CelestLab, a CNES toolbox for Scilab // // This software is governed by the CeCILL license under French law and // abiding by the rules of distribution of free software. You can use, // modify and/ or redistribute the software under the terms of the CeCILL // license as circulated by CEA, CNRS and INRIA at the following URL // 'http://www.cecill.info'. function [tle] = CL_tle_parse(str, desc) // TLE structure from two-line string // // Calling Sequence // tle = CL_tle_parse(str [, desc]) // // Description // // //

This function creates a TLE structure from two-line elements given as a two-line string.

//

//

The optional argument desc may be used to pass additional information (name of object...).

//

The created structure contains the same information as initially present in the string: there is no change of reference frame or time scale.

//

//

In case of parsing errors (unexpected characters encountered, bad checksum value(s)...), the status field in the TLE structure is set to a non-zero value:

//

-1: Error while trying to get the value of some field.

//

-2: Invalid checksum for the first or second line.

//

//

Note:

//

The checksum checking can be by-passed by removing the checksum characters in the two-line strings or by replacing them by an non-numeric characters.

//
//
// // Parameters // str: (string) Standard two-line elements (2xN) // desc: (string, optional) TLE Descriptions (1xN) // tle: TLE structure containing all the (decoded) two-line elements (size N) // // Authors // CNES - DCT/SB/MS // // See also // CL_tle_load // CL_tle_new // // Examples // str = [.. // "1 00005U 58002B 00179.78495062 .00000023 00000-0 28098-4 0 4753"; .. // "2 00005 34.2682 348.7242 1859667 331.7664 19.3264 10.82419157413667" ]; // tle = CL_tle_parse(str) // ---------------------------- // string to double // returns %nan if invalid character encountered // str: Nx1: string // val: Nx1: double (may be %nan) // ---------------------------- function [val] = tle_strtod(str) // considers 68 characters str = stripblanks(str, %f); // c: character that should not be present in the string c = ascii(1); [val, endc] = strtod(str + c); I = find(endc <> c); val(I) = %nan; endfunction // ---------------------------- // x: NxP // ---------------------------- // not valid if one element is %nan function [valid] = tle_validp(x) valid = ~isnan(sum(x, "c")); endfunction if (~exists("desc", "local")) desc = emptystr(str(1,:)); end if (size(desc, 2) <> size(str,2)) CL__error("Invalid arguments sizes"); end // str == empty => returns empty TLE if (str == []) tle = CL__tle_create(); return; end if (size(str,1) <> 2) CL__error("Invalid 2-line string"); end if (size(desc,1) <> 1) CL__error("Invalid description string"); end // column vectors line1 = str(1,:)'; line2 = str(2,:)'; // column N = size(line1, 1); desc = desc'; // ---------- // line 1 // ---------- num1 = tle_strtod(part(line1, 1)); satnum1 = tle_strtod(part(line1, 3:7)); classif = part(line1, 8); intldesg = stripblanks(part(line1, 10:17)); // epoch (year + decimal day of year) epochyr = tle_strtod(part(line1, 19:20)) + 2000; I = find(epochyr >= 2057); epochyr(I) = epochyr(I) - 100 * ones(I)'; epochdays = tle_strtod(part(line1, 21:32)); // ndot/2 (rev/day^2 -> rad/s^2) ndot = tle_strtod(part(line1, 34:43)) * (%pi/180)/86400^2; // nddot/6 (rev/day^3 -> rad/s^3) nddot = tle_strtod(part(line1, 45:50)); nexp = tle_strtod(part(line1, 51:52)); nddot = nddot .* 10.^(nexp-5) * (%pi/180)/86400^3; // bstar (unit=1/Earth radii) bstar = tle_strtod(part(line1, 54:59)); ibexp = tle_strtod(part(line1, 60:61)); bstar = bstar .* 10.^(ibexp-5); // ephemeris type (0-7) ephtype = tle_strtod(part(line1, 63)); // element number elnum = tle_strtod(part(line1, 65:68)); // checksum: - <=> 1, letter, . <=> 0, numbers <=> value checksum1 = tle_strtod(part(line1, 69)); valid1 = tle_validp([num1,satnum1,epochyr,epochdays,ndot,.. nddot,bstar,ephtype,elnum]); // ---------- // line 2 // ---------- num2 = tle_strtod(part(line2, 1)); satnum2 = tle_strtod(part(line2, 3:7)); // inclination (rad) inc = tle_strtod(part(line2, 9:16)) * (%pi/180); // right ascension of ascending node (rad) raan = tle_strtod(part(line2, 18:25)) * (%pi/180); // eccentricity ecc = tle_strtod(part(line2, 27:33)) * 1.e-7; // aarg of perigee (rad) argp = tle_strtod(part(line2, 35:42)) * (%pi/180); // anm (rad) ma = tle_strtod(part(line2, 44:51)) * (%pi/180); // mean motion (rad/sec) n = tle_strtod(part(line2, 53:63)) * 2*%pi / 86400; // revolution number revnum = tle_strtod(part(line2, 64:68)); checksum2 = tle_strtod(part(line2, 69)); valid2 = tle_validp([num2,satnum2,inc,raan,ecc,.. argp,ma,n,revnum]); // ---------- // check // ---------- status = zeros(N,1); I = find(num1 <> 1 | num2 <> 2 | satnum1 <> satnum2 | ~valid1 | ~valid2); status(I) = -1; // check checksum line 1 I = find(status == 0 & CL__tle_checksum(part(line1, 1:68)) <> checksum1 & ~isnan(checksum1)); status(I) = -2; // check checksum line 2 I = find(status == 0 & CL__tle_checksum(part(line2, 1:68)) <> checksum2 & ~isnan(checksum2)); status(I) = -2; // create structure // epoch from 1/1/1950 0h (CJD) epoch_cjd = %nan * ones(N,1); I = find(~isnan(epochyr) & ~isnan(epochdays)); if (I <> []) epoch_cjd(I) = (CL_dat_cal2cjd(epochyr(I)', 1, 1) + epochdays(I)' - 1)'; end tle = CL__tle_create(satnum1', classif', intldesg', ephtype', .. elnum', epoch_cjd', revnum', ecc', inc', argp', .. raan', ma', n', ndot', nddot', bstar', desc', status'); endfunction