Skip to content

Commit 1898f9f

Browse files
committed
Added new functionalities to PassCalculator.
Added new operators for DateTime class. Other minor fixes.
1 parent 0b6e3ac commit 1898f9f

File tree

14 files changed

+466
-64
lines changed

14 files changed

+466
-64
lines changed

LibDegorasSLR/CMakeModules/CMakeMacrosLibraries.cmake

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ MACRO(macro_setup_lib_basic_unit_tests tests_sources_path install_path ignore_pa
102102
# List of basic tests.
103103
file(GLOB_RECURSE TESTS_SOURCES RELATIVE "${tests_sources_path}" "${tests_sources_path}/*.cpp")
104104

105-
# For simple test we will avoit the include the external resources.
105+
# For simple test we will avoid the include the external resources.
106106
set(EXTERN)
107107

108108
# Filter out ignored paths.
@@ -151,7 +151,7 @@ MACRO(macro_setup_lib_basic_unit_tests tests_sources_path install_path ignore_pa
151151
${install_path})
152152

153153
# Install the runtime dependencies.
154-
macro_install_runtime_deps("${EXAMPLE_NAME}"
154+
macro_install_runtime_deps("${TEST_NAME}"
155155
"${MODULES_GLOBAL_MAIN_DEP_SET_NAME}"
156156
"${ext_libs_loc}"
157157
"${install_path}"

LibDegorasSLR/includes/LibDegorasSLR/Modules/UtilitiesSLR

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,4 @@
2727
**********************************************************************************************************************/
2828

2929
#include <LibDegorasSLR/UtilitiesSLR/predictors/predictor_slr_cpf.h>
30+
#include <LibDegorasSLR/UtilitiesSLR/utils/pass_calculator.h>

LibDegorasSLR/includes/LibDegorasSLR/Timing/dates/datetime.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,16 @@ class DateTime
150150

151151
DateTime operator+(const math::units::Seconds& seconds) const;
152152

153+
DateTime& operator+=(const math::units::Seconds& seconds);
154+
155+
DateTime& operator+=(const DateTime& other);
156+
157+
DateTime operator-(const math::units::Seconds& seconds) const;
158+
159+
DateTime& operator-=(const math::units::Seconds& seconds);
160+
161+
DateTime& operator-=(const DateTime& other);
162+
153163
static std::vector<DateTime> linspaceStep(const DateTime& start, const DateTime& end,
154164
const math::units::Seconds& step);
155165

LibDegorasSLR/includes/LibDegorasSLR/Timing/dates/datetime.tpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,36 @@ DateTime<DateType> DateTime<DateType>::operator+(const math::units::Seconds &sec
185185
return result;
186186
}
187187

188+
template <typename DateType>
189+
DateTime<DateType>& DateTime<DateType>::operator+=(const math::units::Seconds& seconds)
190+
{
191+
return *this = *this + seconds;
192+
}
193+
194+
template <typename DateType>
195+
DateTime<DateType>& DateTime<DateType>::operator+=(const DateTime<DateType>& other)
196+
{
197+
return *this = *this + other;
198+
}
199+
200+
template <typename DateType>
201+
DateTime<DateType> DateTime<DateType>::operator-(const math::units::Seconds& seconds) const
202+
{
203+
return *this + (-seconds);
204+
}
205+
206+
template <typename DateType>
207+
DateTime<DateType>& DateTime<DateType>::operator-=(const math::units::Seconds& seconds)
208+
{
209+
return *this = *this - seconds;
210+
}
211+
212+
template <typename DateType>
213+
DateTime<DateType>& DateTime<DateType>::operator-=(const DateTime<DateType>& other)
214+
{
215+
return *this = *this - other;
216+
}
217+
188218
template <typename DateType>
189219
void DateTime<DateType>::normalize()
190220
{

LibDegorasSLR/includes/LibDegorasSLR/UtilitiesSLR/predictors/predictor_slr_base.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,13 @@ class LIBDPSLR_EXPORT PredictorSlrBase
240240
*/
241241
bool isInsideTimeWindow(const timing::dates::MJDateTime& start, const timing::dates::MJDateTime& end) const;
242242

243+
/**
244+
* @brief Checks if given time is inside the valid prediction range.
245+
* @param time, the time to check if it is inside time window.
246+
* @return true if the time is inside, false otherwise.
247+
*/
248+
bool isInsideTime(const timing::dates::MJDateTime& time) const;
249+
243250
/**
244251
* @brief Interpolates position at requested instant.
245252
* @param mjdt, the modified julian datetime of the instant to be interpolated.

LibDegorasSLR/includes/LibDegorasSLR/UtilitiesSLR/utils/pass_calculator.h

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,13 +81,18 @@ class LIBDPSLR_EXPORT PassCalculator
8181
{
8282
public:
8383

84+
/**
85+
* @brief ResultCode enum represents the possible results of the operations performed by this class.
86+
*/
8487
enum ResultCode
8588
{
86-
NOT_ERROR,
87-
PREDICTOR_NOT_VALID,
88-
INTERVAL_OUTSIDE_OF_PREDICTOR,
89-
SOME_PREDICTIONS_NOT_VALID,
90-
OTHER_ERROR
89+
NOT_ERROR, ///< There was no error.
90+
PREDICTOR_NOT_VALID, ///< The predictor is not ready, so it cannot be used.
91+
INTERVAL_OUTSIDE_OF_PREDICTOR, ///< Requested interval for pass search is outside of predictor window.
92+
TIME_OUTSIDE_OF_PREDICTOR, ///< Requested time for next pass search is outside of predictor window.
93+
SOME_PREDICTIONS_NOT_VALID, ///< There was some errors at predictions.
94+
NO_NEXT_PASS_FOUND, ///< There is no next pass after given datetime.
95+
OTHER_ERROR ///< Other errors.
9196

9297
};
9398

@@ -126,13 +131,29 @@ class LIBDPSLR_EXPORT PassCalculator
126131
* @brief Get passes within the given interval of time.
127132
* @param mjd_start the modified julian date of interval start.
128133
* @param mjd_end the modified julian date of interval end.
129-
* @param passes the returned passes.
134+
* @param passes the returned passes, or empty if no pass was found.
130135
* @return The result of the operation.
131136
*/
132137
ResultCode getPasses(const timing::dates::MJDateTime &mjd_start,
133138
const timing::dates::MJDateTime &mjd_end,
134139
std::vector<Pass> &passes) const;
135140

141+
/**
142+
* @brief Get the next pass, starting from mjd_start datetime. If this datetime is already inside a pass, then
143+
* this pass will be returned.
144+
* @param mjd_start, the datetime to start lookig for next pass.
145+
* @param pass, the data of the pass. This data is not valid if returned code is different from NOT_ERROR.
146+
* @return The result of the operation. If the result is different from NOT_ERROR, pass data is not valid.
147+
*/
148+
ResultCode getNextPass(const timing::dates::MJDateTime &mjd_start, Pass &pass) const;
149+
150+
/**
151+
* @brief Checks is a given time is inside a pass.
152+
* @param mjd, the MJ datetime to check.
153+
* @return true if the datetime is inside of a pass, false if there was some error or the datetime is not inside a pass.
154+
*/
155+
bool isInsidePass(const timing::dates::MJDateTime &mjd) const;
156+
136157

137158
private:
138159
math::units::Degrees min_elev_;

LibDegorasSLR/sources/UtilitiesSLR/predictors/predictor_slr_base.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,18 @@ bool PredictorSlrBase::isInsideTimeWindow(const MJDateTime& start, const MJDateT
129129
return start >= predict_mjd_start && end <= predict_mjd_end;
130130
}
131131

132+
bool PredictorSlrBase::isInsideTime(const timing::dates::MJDateTime &time) const
133+
{
134+
// Auxiliar.
135+
MJDateTime predict_mjd_start, predict_mjd_end;
136+
137+
// Get the predict time window.
138+
this->getTimeWindow(predict_mjd_start, predict_mjd_end);
139+
140+
// Check if requested time is inside predict time window
141+
return time >= predict_mjd_start && time <= predict_mjd_end;
142+
}
143+
132144
PredictionSLRV PredictorSlrBase::predict(const MJDateTime &mjdt_start, const MJDateTime &mjdt_end,
133145
const Milliseconds &step) const
134146
{

LibDegorasSLR/sources/UtilitiesSLR/predictors/predictor_slr_cpf.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,8 @@ porque todo el sistema de referencia geocéntrica ECEF rotará durante el viaje
543543

544544
void PredictorSlrCPF::getTimeWindow(MJDateTime &start, MJDateTime &end) const
545545
{
546+
// TODO: maybe this should return the real valid time window, avoiding the time lapse where the interpolation
547+
// returns not in the middle error.
546548
if (this->isReady())
547549
{
548550
this->cpf_.getAvailableTimeWindow(start, end);

LibDegorasSLR/sources/UtilitiesSLR/utils/pass_calculator.cpp

Lines changed: 150 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,17 +67,18 @@ math::units::Seconds PassCalculator::interval() const
6767
}
6868

6969
PassCalculator::ResultCode PassCalculator::getPasses(const timing::dates::MJDateTime &mjd_start,
70-
const timing::dates::MJDateTime &mjd_end,
71-
std::vector<Pass> &passes) const
70+
const timing::dates::MJDateTime &mjd_end,
71+
std::vector<Pass> &passes) const
7272
{
7373
// Clear passes vector
7474
passes.clear();
7575

76-
// Check if predictor is valid and has data for the time window.
77-
if (this->predictor_->isReady())
76+
// Check if predictor is valid.
77+
if (!this->predictor_->isReady())
7878
return ResultCode::PREDICTOR_NOT_VALID;
7979

80-
if (this->predictor_->isInsideTimeWindow(mjd_start, mjd_end))
80+
// Check if time interval is inside valid prediction window.
81+
if (!this->predictor_->isInsideTimeWindow(mjd_start, mjd_end))
8182
return ResultCode::INTERVAL_OUTSIDE_OF_PREDICTOR;
8283

8384
// Calculate all the predictions.
@@ -139,5 +140,149 @@ PassCalculator::ResultCode PassCalculator::getPasses(const timing::dates::MJDate
139140
return PassCalculator::ResultCode::NOT_ERROR;
140141
}
141142

143+
PassCalculator::ResultCode PassCalculator::getNextPass(const timing::dates::MJDateTime &mjd_start, Pass &pass) const
144+
{
145+
// Clear passes vector
146+
pass = {};
147+
148+
// Check if predictor is valid.
149+
if (!this->predictor_->isReady())
150+
return ResultCode::PREDICTOR_NOT_VALID;
151+
152+
// Check if time is inside valid prediction window.
153+
if (!this->predictor_->isInsideTime(mjd_start))
154+
return ResultCode::TIME_OUTSIDE_OF_PREDICTOR;
155+
156+
timing::dates::MJDateTime mjdt_start_window, mjdt_end_window;
157+
this->predictor_->getTimeWindow(mjdt_start_window, mjdt_end_window);
158+
159+
// Calculate all the predictions.
160+
predictors::PredictionSLR pred;
161+
auto pred_error = this->predictor_->predict(mjd_start, pred);
162+
163+
if (0 != pred_error)
164+
return ResultCode::SOME_PREDICTIONS_NOT_VALID;
165+
166+
// Auxiliary variables.
167+
bool pass_started = pred.instant_data->altaz_coord.el >= this->min_elev_;
168+
pass.interval = this->interval_;
169+
pass.min_elev = this->min_elev_;
170+
std::vector<Pass::Step>& steps = pass.steps;
171+
timing::dates::MJDateTime mjdt;
172+
173+
if (pass_started)
174+
{
175+
// Insert start time position, since it is inside pass
176+
steps.push_back({mjdt, pred.instant_data->altaz_coord.az, pred.instant_data->altaz_coord.el, 0, 0});
177+
178+
// Look for the start of the pass going backwards from start.
179+
mjdt = mjd_start - this->interval_;
180+
do
181+
{
182+
pred_error = this->predictor_->predict(mjdt, pred);
183+
if (0 != pred_error)
184+
{
185+
pass = {};
186+
return ResultCode::SOME_PREDICTIONS_NOT_VALID;
187+
}
188+
// Store pass step.
189+
steps.push_back({mjdt, pred.instant_data->altaz_coord.az, pred.instant_data->altaz_coord.el, 0, 0});
190+
mjdt -= this->interval_;
191+
} while (pred.instant_data->altaz_coord.el >= this->min_elev_ && mjdt >= mjdt_start_window);
192+
193+
// If the whole pass is inside the predictor time window.
194+
if (mjdt >= mjdt_start_window)
195+
{
196+
// Delete last element, since it is outside of pass
197+
steps.pop_back();
198+
}
199+
200+
// Put elements in chronological order.
201+
std::reverse(steps.begin(), steps.end());
202+
203+
// Set time to position after start, to look for the end of the pass.
204+
mjdt = mjd_start + this->interval_;
205+
206+
}
207+
else
208+
{
209+
// Look for the start of the pass going forward from start.
210+
mjdt = mjd_start + this->interval_;
211+
do
212+
{
213+
pred_error = this->predictor_->predict(mjdt, pred);
214+
if (0 != pred_error)
215+
{
216+
pass = {};
217+
return ResultCode::SOME_PREDICTIONS_NOT_VALID;
218+
}
219+
mjdt += this->interval_;
220+
} while (pred.instant_data->altaz_coord.el < this->min_elev_ && mjdt <= mjdt_end_window);
221+
222+
// If end of predictor time window has not been reached, start was found. Otherwise return with no pass error.
223+
if (mjdt <= mjdt_end_window)
224+
{
225+
// Store pass step.
226+
steps.push_back({mjdt - this->interval_, pred.instant_data->altaz_coord.az,
227+
pred.instant_data->altaz_coord.el, 0, 0});
228+
}
229+
else
230+
{
231+
pass = {};
232+
return ResultCode::NO_NEXT_PASS_FOUND;
233+
}
234+
}
235+
236+
// Look for the end of the pass.
237+
do
238+
{
239+
pred_error = this->predictor_->predict(mjdt, pred);
240+
if (0 != pred_error)
241+
{
242+
pass = {};
243+
return ResultCode::SOME_PREDICTIONS_NOT_VALID;
244+
}
245+
// Store pass step.
246+
steps.push_back({mjdt, pred.instant_data->altaz_coord.az, pred.instant_data->altaz_coord.el, 0, 0});
247+
mjdt += this->interval_;
248+
} while (pred.instant_data->altaz_coord.el >= this->min_elev_ && mjdt <= mjdt_end_window);
249+
250+
251+
// If the whole pass is inside the predictor time window.
252+
if (mjdt <= mjdt_end_window)
253+
{
254+
// Delete last element, since it is outside of pass
255+
steps.pop_back();
256+
}
257+
258+
259+
// Update az and el rate.
260+
for (auto it = pass.steps.begin() + 1; it != pass.steps.end(); it++)
261+
{
262+
it->azim_rate = (it->azim - (it - 1)->azim) / this->interval_;
263+
it->elev_rate = (it->elev - (it - 1)->elev) / this->interval_;
264+
}
265+
266+
return PassCalculator::ResultCode::NOT_ERROR;
267+
}
268+
269+
bool PassCalculator::isInsidePass(const timing::dates::MJDateTime &mjd) const
270+
{
271+
// If predictor is not valid or time is outside of prediction time window, return false.
272+
if (!this->predictor_->isReady() || !this->predictor_->isInsideTime(mjd))
273+
return false;
274+
275+
// Calculate all the predictions.
276+
predictors::PredictionSLR pred;
277+
auto pred_error = this->predictor_->predict(mjd, pred);
278+
279+
// If there was an error at prediction, return false.
280+
if (0 != pred_error)
281+
return false;
282+
283+
// Return true if elevation of position is above minimum. False otherwise.
284+
return pred.instant_data->altaz_coord.el >= this->min_elev_;
285+
}
286+
142287
}}} // END NAMESPACES.
143288
// =====================================================================================================================

LibDegorasSLR/testing/AlgorithmsSLR/ComplexTest_GeneratePasses/CMakeLists.txt

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ message(STATUS "Setup complex test: ${TEST_NAME}")
2222
set(SOURCES "ComplexTest_GeneratePassesCPF.cpp")
2323

2424
# Set resources.
25-
set(RESOURCES ${CMAKE_CURRENT_SOURCE_DIR}/test_data/39380_cpf_230309_5681.tjr)
25+
set(RESOURCES ${CMAKE_CURRENT_SOURCE_DIR}/inputs/39380_cpf_230309_5681.tjr)
2626
source_group("Resource Files" FILES ${RESOURCES})
2727

2828
# Setup the launcher.
@@ -42,7 +42,30 @@ macro_install_runtime_artifacts(${TEST_NAME}
4242
${MODULES_GLOBAL_MAIN_DEP_SET_NAME}
4343
${TEST_INSTALL_PATH})
4444

45-
#file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/test_data/39380_cpf_230309_5681.tjr
46-
# DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test_data)
45+
# Prepare the external library search folders.
46+
set(ext_libs_loc
47+
${MODULES_GLOBAL_INSTALL_LIB_PATH}
48+
${MODULES_GLOBAL_INSTALL_BIN_PATH}
49+
${CMAKE_BINARY_DIR}/bin)
50+
51+
# Install the runtime dependencies.
52+
macro_install_runtime_deps("${TEST_NAME}"
53+
"${MODULES_GLOBAL_MAIN_DEP_SET_NAME}"
54+
"${ext_libs_loc}"
55+
"${TEST_INSTALL_PATH}"
56+
"" "")
57+
58+
# Add to the build step the necessary input files for the example.
59+
add_custom_command(TARGET "${TEST_NAME}" PRE_BUILD
60+
COMMAND ${CMAKE_COMMAND} -E copy_directory
61+
"${CMAKE_CURRENT_SOURCE_DIR}/inputs/" "$<TARGET_FILE_DIR:${TEST_NAME}>/inputs")
62+
63+
# Install example input data.
64+
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/inputs/"
65+
DESTINATION "${TEST_INSTALL_PATH}/inputs"
66+
FILES_MATCHING PATTERN "*")
67+
68+
#file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/inputs/39380_cpf_230309_5681.tjr
69+
# DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/inputs)
4770

4871

0 commit comments

Comments
 (0)