Skip to content

Commit 81b6402

Browse files
Validation of line of sight computation
The issue had been fixed in a prior commit for 0.4.4
1 parent 2532881 commit 81b6402

File tree

3 files changed

+54
-6
lines changed

3 files changed

+54
-6
lines changed

anise/src/almanac/aer.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ impl Almanac {
3535
/// Computes the azimuth (in degrees), elevation (in degrees), and range (in kilometers) of the
3636
/// receiver state (`rx`) seen from the transmitter state (`tx`), once converted into the SEZ frame of the transmitter.
3737
///
38+
/// # Warning
39+
/// The obstructing body _should_ be a tri-axial ellipsoid body, e.g. IAU_MOON_FRAME.
40+
///
3841
/// # Algorithm
3942
/// 1. If any obstructing_bodies are provided, ensure that none of these are obstructing the line of sight between the receiver and transmitter.
4043
/// 2. Compute the SEZ (South East Zenith) frame of the transmitter.

anise/src/astro/mod.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,7 @@ use std::fmt::Display;
1313
use crate::errors::PhysicsError;
1414
use crate::frames::Frame;
1515

16-
use hifitime::{Duration, Epoch, TimeUnits};
17-
18-
use crate::constants::SPEED_OF_LIGHT_KM_S;
16+
use hifitime::{Duration, Epoch};
1917

2018
#[cfg(feature = "python")]
2119
use pyo3::exceptions::PyTypeError;
@@ -60,7 +58,7 @@ impl AzElRange {
6058
}
6159

6260
/// Returns whether there is an obstruction.
63-
pub fn is_obstructed(&self) -> bool {
61+
pub const fn is_obstructed(&self) -> bool {
6462
self.obstructed_by.is_some()
6563
}
6664

@@ -75,6 +73,9 @@ impl AzElRange {
7573
range_rate_km_s: f64,
7674
obstructed_by: Option<Frame>,
7775
) -> Self {
76+
use crate::constants::SPEED_OF_LIGHT_KM_S;
77+
use hifitime::TimeUnits;
78+
7879
Self {
7980
epoch,
8081
azimuth_deg,

anise/tests/ephemerides/transform.rs

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Documentation: https://nyxspace.com/
99
*/
1010

11-
use anise::astro::Occultation;
11+
use anise::astro::{AzElRange, Occultation};
1212
use anise::constants::celestial_objects::{EARTH, VENUS};
1313
use anise::constants::frames::{
1414
EARTH_ITRF93, EARTH_J2000, IAU_EARTH_FRAME, IAU_MOON_FRAME, MOON_J2000, SUN_J2000, VENUS_J2000,
@@ -317,6 +317,14 @@ fn validate_gh_283_multi_barycenter_and_los(almanac: Almanac) {
317317
let obsrvr = "-85";
318318

319319
let mut prev_occult: Option<Occultation> = None;
320+
let mut prev_aer: Option<AzElRange> = None;
321+
let mut access_count = 0;
322+
let mut access_start: Option<Epoch> = None;
323+
324+
let access_times = [
325+
Unit::Minute * 4 + Unit::Second * 1,
326+
Unit::Hour * 1 + Unit::Minute * 6 + 49 * Unit::Second,
327+
];
320328

321329
for epoch in TimeSeries::inclusive(epoch, epoch + period, 1.seconds()) {
322330
// Rebuild the ground station at this new epoch
@@ -335,8 +343,33 @@ fn validate_gh_283_multi_barycenter_and_los(almanac: Almanac) {
335343
.unwrap();
336344

337345
let aer = almanac
338-
.azimuth_elevation_range_sez(rx_lro, tx_madrid, Some(MOON_J2000), None)
346+
.azimuth_elevation_range_sez(rx_lro, tx_madrid, Some(IAU_MOON_FRAME), None)
339347
.unwrap();
348+
349+
if let Some(prev_aer) = prev_aer {
350+
if prev_aer.is_obstructed() && !aer.is_obstructed() {
351+
// New access
352+
access_count += 1;
353+
access_start = Some(aer.epoch);
354+
} else if !prev_aer.is_obstructed() && aer.is_obstructed() {
355+
// End of access
356+
if let Some(access_start) = access_start {
357+
// We've had a full access strand.
358+
let access_end = aer.epoch;
359+
let access_duration = (access_end - access_start).round(Unit::Second * 1);
360+
println!(
361+
"#{access_count}\t{access_start} - {access_end}\t{}",
362+
access_duration
363+
);
364+
assert_eq!(access_times[access_count], access_duration);
365+
}
366+
}
367+
// dbg!(prev_aer.is_obstructed(), aer.is_obstructed());
368+
} else if !aer.is_obstructed() {
369+
access_start = Some(aer.epoch);
370+
}
371+
prev_aer = Some(aer);
372+
340373
if aer.obstructed_by.is_some() {
341374
obstructions += 1;
342375
} else {
@@ -417,6 +450,17 @@ fn validate_gh_283_multi_barycenter_and_los(almanac: Almanac) {
417450
prev_occult = Some(occult)
418451
}
419452

453+
if let Some(access_start) = access_start {
454+
// We've had a full access strand.
455+
let access_end = epoch + period;
456+
let access_duration = (access_end - access_start).round(Unit::Second * 1);
457+
println!(
458+
"#{access_count}\t{access_start} - {access_end}\t{}",
459+
access_duration
460+
);
461+
assert_eq!(access_times[access_count], access_duration);
462+
}
463+
420464
assert_eq!(obstructions, 2762);
421465
assert_eq!(no_obstructions, 4250);
422466
}

0 commit comments

Comments
 (0)