1 /*****************************************************************************
2  *   Copyright (C) 2004-2018 The pykep development team,                     *
3  *   Advanced Concepts Team (ACT), European Space Agency (ESA)               *
4  *                                                                           *
5  *   https://gitter.im/esa/pykep                                             *
6  *   https://github.com/esa/pykep                                            *
7  *                                                                           *
8  *   act@esa.int                                                             *
9  *                                                                           *
10  *   This program is free software; you can redistribute it and/or modify    *
11  *   it under the terms of the GNU General Public License as published by    *
12  *   the Free Software Foundation; either version 2 of the License, or       *
13  *   (at your option) any later version.                                     *
14  *                                                                           *
15  *   This program is distributed in the hope that it will be useful,         *
16  *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
17  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
18  *   GNU General Public License for more details.                            *
19  *                                                                           *
20  *   You should have received a copy of the GNU General Public License       *
21  *   along with this program; if not, write to the                           *
22  *   Free Software Foundation, Inc.,                                         *
23  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.               *
24  *****************************************************************************/
25 
26 #include <keplerian_toolbox/core_functions/array3D_operations.hpp>
27 #include <keplerian_toolbox/planet/tle.hpp>
28 #include <algorithm>
29 #include <fstream>
30 #include <iostream>
31 #include <numeric>
32 
33 using namespace kep_toolbox;
34 
35 // In this test we read the historical two line elements of a GPS satellite
36 // from the file sgp4_test.txt
37 // These represent actual observations made on the satellite r and v.
38 // We then compute r and v propagating the TLE of the previous observation
39 // up to the current observation and measure the error. The test passes if
40 // the max error is less than 10 km on the position and 15 m/s/ on the velocity
41 
main()42 int main()
43 {
44     std::ifstream txtfile("sgp4_test.txt");
45     std::string line1, line2, line21, line22;
46     array3D r1, v1, r2, v2, err_r, err_v;
47     std::vector<double> errors_r, errors_v;
48     if (!txtfile.good()) {
49         std::cout << "File sgp4_test.txt not found" << std::endl;
50         return 1; // exit if file not found
51     }
52     getline(txtfile, line1);
53     getline(txtfile, line2);
54     while (!txtfile.eof()) {
55         getline(txtfile, line21);
56         getline(txtfile, line22);
57         planet::tle sat1(line1.substr(0, 69), line2.substr(0, 69));
58         planet::tle sat2(line21.substr(0, 69), line22.substr(0, 69));
59         sat1.eph(sat2.get_ref_mjd2000(), r1, v1);
60         sat2.eph(sat2.get_ref_mjd2000(), r2, v2);
61         diff(err_r, r1, r2);
62         diff(err_v, v1, v2);
63         errors_r.push_back(norm(err_r));
64         errors_v.push_back(norm(err_v));
65         if (norm(err_r) > 10000) {
66             std::cout << line1 << std::endl;
67             std::cout << line2 << std::endl;
68         }
69         line1 = line21;
70         line2 = line22;
71     }
72     double sum = std::accumulate(errors_r.begin(), errors_r.end(), 0.0);
73     double mean_r = sum / static_cast<double>(errors_r.size());
74 
75     sum = std::accumulate(errors_v.begin(), errors_v.end(), 0.0);
76     double mean_v = sum / static_cast<double>(errors_v.size());
77     double max_r = *std::max_element(errors_r.begin(), errors_r.end());
78     double max_v = *std::max_element(errors_v.begin(), errors_v.end());
79 
80     std::cout << "Mean error r (m): " << mean_r << std::endl;
81     std::cout << "Mean error v (m/s): " << mean_v << std::endl;
82     std::cout << "Max error r (m/s): " << max_r << std::endl;
83     std::cout << "Max error v (m/s): " << max_v << std::endl;
84 
85     if (max_r < 10000 && max_v < 15) {
86         std::cout << "PASS" << std::endl;
87         return 0;
88     } else {
89         std::cout << "FAIL" << std::endl;
90         return 1;
91     }
92 }
93