|
| 1 | +use anise::{ |
| 2 | + constants::{ |
| 3 | + frames::{EME2000, IAU_EARTH_FRAME}, |
| 4 | + usual_planetary_constants::MEAN_EARTH_ANGULAR_VELOCITY_DEG_S, |
| 5 | + }, |
| 6 | + prelude::{Almanac, Orbit}, |
| 7 | +}; |
| 8 | +use core::str::FromStr; |
| 9 | +use hifitime::Epoch; |
| 10 | + |
| 11 | +// Define location of DSN DSS-65 in Madrid, Spain |
| 12 | +const DSS65_LATITUDE_DEG: f64 = 40.427_222; |
| 13 | +const DSS65_LONGITUDE_DEG: f64 = 4.250_556; |
| 14 | +const DSS65_HEIGHT_KM: f64 = 0.834_939; |
| 15 | + |
| 16 | +/// Validation test for azimuth, elevation, range, and range-rate computation. |
| 17 | +/// Importantly, we only test for range-rate here; I forget the set up used for DSS65 in GMAT, and could not export the az/el data. |
| 18 | +#[test] |
| 19 | +fn validate_aer_vs_gmat_cislunar1() { |
| 20 | + let almanac = Almanac::default() |
| 21 | + .load("../data/earth_latest_high_prec.bpc") |
| 22 | + .unwrap() |
| 23 | + .load("../data/pck11.pca") |
| 24 | + .unwrap() |
| 25 | + .load("../data/de430.bsp") |
| 26 | + .unwrap(); |
| 27 | + |
| 28 | + let eme2k = almanac.frame_from_uid(EME2000).unwrap(); |
| 29 | + |
| 30 | + let states = &[ |
| 31 | + Orbit::new( |
| 32 | + 58643.769540, |
| 33 | + -61696.435624, |
| 34 | + -36178.745722, |
| 35 | + 2.148654, |
| 36 | + -1.202489, |
| 37 | + -0.714016, |
| 38 | + Epoch::from_str("2023-11-16T13:35:30.231999909 UTC").unwrap(), |
| 39 | + eme2k, |
| 40 | + ), |
| 41 | + Orbit::new( |
| 42 | + 66932.786920, |
| 43 | + -66232.188134, |
| 44 | + -38873.611383, |
| 45 | + 2.040555, |
| 46 | + -1.092316, |
| 47 | + -0.649376, |
| 48 | + Epoch::from_str("2023-11-16T14:41:30.231999930 UTC").unwrap(), |
| 49 | + eme2k, |
| 50 | + ), |
| 51 | + Orbit::new( |
| 52 | + 74004.678872, |
| 53 | + -69951.400821, |
| 54 | + -41085.748329, |
| 55 | + 1.956606, |
| 56 | + -1.011239, |
| 57 | + -0.601766, |
| 58 | + Epoch::from_str("2023-11-16T15:40:30.231999839 UTC").unwrap(), |
| 59 | + eme2k, |
| 60 | + ), |
| 61 | + Orbit::new( |
| 62 | + 80796.572756, |
| 63 | + -73405.951304, |
| 64 | + -43142.418173, |
| 65 | + 1.882015, |
| 66 | + -0.942232, |
| 67 | + -0.561216, |
| 68 | + Epoch::from_str("2023-11-16T16:39:30.232000062 UTC").unwrap(), |
| 69 | + eme2k, |
| 70 | + ), |
| 71 | + Orbit::new( |
| 72 | + 91643.444941, |
| 73 | + -78707.219860, |
| 74 | + -46302.227968, |
| 75 | + 1.773135, |
| 76 | + -0.846264, |
| 77 | + -0.504775, |
| 78 | + Epoch::from_str("2023-11-16T18:18:30.231999937 UTC").unwrap(), |
| 79 | + eme2k, |
| 80 | + ), |
| 81 | + ]; |
| 82 | + |
| 83 | + let observations = &[ |
| 84 | + (91457.558, 2.199), |
| 85 | + (99965.056, 2.105), |
| 86 | + (107322.912, 2.056), |
| 87 | + (114551.675, 2.031), |
| 88 | + (126573.919, 2.021), |
| 89 | + ]; |
| 90 | + |
| 91 | + for (rx, (range_km, range_rate_km_s)) in |
| 92 | + states.iter().copied().zip(observations.iter().copied()) |
| 93 | + { |
| 94 | + // Rebuild the ground stations |
| 95 | + let tx = Orbit::try_latlongalt( |
| 96 | + DSS65_LATITUDE_DEG, |
| 97 | + DSS65_LONGITUDE_DEG, |
| 98 | + DSS65_HEIGHT_KM, |
| 99 | + MEAN_EARTH_ANGULAR_VELOCITY_DEG_S, |
| 100 | + rx.epoch, |
| 101 | + almanac.frame_from_uid(IAU_EARTH_FRAME).unwrap(), |
| 102 | + ) |
| 103 | + .unwrap(); |
| 104 | + |
| 105 | + let aer = almanac |
| 106 | + .azimuth_elevation_range_sez(rx, tx, None, None) |
| 107 | + .unwrap(); |
| 108 | + |
| 109 | + dbg!(aer.range_km - range_km); |
| 110 | + assert!( |
| 111 | + (aer.range_rate_km_s - range_rate_km_s).abs() < 1e-3, |
| 112 | + "more than 1 m/s error!" |
| 113 | + ); |
| 114 | + } |
| 115 | +} |
| 116 | + |
| 117 | +#[test] |
| 118 | +fn validate_aer_vs_gmat_cislunar2() { |
| 119 | + let almanac = Almanac::default() |
| 120 | + .load("../data/earth_latest_high_prec.bpc") |
| 121 | + .unwrap() |
| 122 | + .load("../data/pck11.pca") |
| 123 | + .unwrap() |
| 124 | + .load("../data/de430.bsp") |
| 125 | + .unwrap(); |
| 126 | + |
| 127 | + let eme2k = almanac.frame_from_uid(EME2000).unwrap(); |
| 128 | + |
| 129 | + let states = &[ |
| 130 | + Orbit::new( |
| 131 | + 102114.297454, |
| 132 | + 13933.746232, |
| 133 | + -671.117990, |
| 134 | + 2.193540, |
| 135 | + 0.906982, |
| 136 | + 0.333105, |
| 137 | + Epoch::from_str("2022-11-29T14:39:28.000000216 TAI").unwrap(), |
| 138 | + eme2k, |
| 139 | + ), |
| 140 | + Orbit::new( |
| 141 | + 110278.148176, |
| 142 | + 17379.224108, |
| 143 | + 608.602854, |
| 144 | + 2.062036, |
| 145 | + 0.887598, |
| 146 | + 0.333149, |
| 147 | + Epoch::from_str("2022-11-29T15:43:28.000000160 TAI").unwrap(), |
| 148 | + eme2k, |
| 149 | + ), |
| 150 | + Orbit::new( |
| 151 | + 117388.586896, |
| 152 | + 20490.340765, |
| 153 | + 1786.240391, |
| 154 | + 1.957486, |
| 155 | + 0.870185, |
| 156 | + 0.332038, |
| 157 | + Epoch::from_str("2022-11-29T16:42:28.000000384 TAI").unwrap(), |
| 158 | + eme2k, |
| 159 | + ), |
| 160 | + Orbit::new( |
| 161 | + 124151.820782, |
| 162 | + 23540.835319, |
| 163 | + 2958.593254, |
| 164 | + 1.865399, |
| 165 | + 0.853363, |
| 166 | + 0.330212, |
| 167 | + Epoch::from_str("2022-11-29T17:41:28.000000293 TAI").unwrap(), |
| 168 | + eme2k, |
| 169 | + ), |
| 170 | + Orbit::new( |
| 171 | + 131247.969145, |
| 172 | + 26834.012939, |
| 173 | + 4241.579371, |
| 174 | + 1.775455, |
| 175 | + 0.835578, |
| 176 | + 0.327653, |
| 177 | + Epoch::from_str("2022-11-29T18:46:28.000000433 TAI").unwrap(), |
| 178 | + eme2k, |
| 179 | + ), |
| 180 | + ]; |
| 181 | + |
| 182 | + let observations = &[ |
| 183 | + (102060.177, 1.957), |
| 184 | + (109389.490, 1.868), |
| 185 | + (115907.202, 1.820), |
| 186 | + (122305.708, 1.799), |
| 187 | + (129320.821, 1.802), |
| 188 | + ]; |
| 189 | + |
| 190 | + for (rx, (range_km, range_rate_km_s)) in |
| 191 | + states.iter().copied().zip(observations.iter().copied()) |
| 192 | + { |
| 193 | + // Rebuild the ground stations |
| 194 | + let tx = Orbit::try_latlongalt( |
| 195 | + DSS65_LATITUDE_DEG, |
| 196 | + DSS65_LONGITUDE_DEG, |
| 197 | + DSS65_HEIGHT_KM, |
| 198 | + MEAN_EARTH_ANGULAR_VELOCITY_DEG_S, |
| 199 | + rx.epoch, |
| 200 | + almanac.frame_from_uid(IAU_EARTH_FRAME).unwrap(), |
| 201 | + ) |
| 202 | + .unwrap(); |
| 203 | + |
| 204 | + let aer = almanac |
| 205 | + .azimuth_elevation_range_sez(rx, tx, None, None) |
| 206 | + .unwrap(); |
| 207 | + |
| 208 | + dbg!(aer.range_km - range_km); |
| 209 | + assert!( |
| 210 | + (aer.range_rate_km_s - range_rate_km_s).abs() < 1e-3, |
| 211 | + "more than 1 m/s error!" |
| 212 | + ); |
| 213 | + } |
| 214 | +} |
0 commit comments