docs: bilingual comments for the dump examples
This commit is contained in:
parent
1eb7564bde
commit
172ef61c06
|
|
@ -9,6 +9,15 @@
|
||||||
//! higher orbit, where it is large; the equatorial and polar cases; and a
|
//! higher orbit, where it is large; the equatorial and polar cases; and a
|
||||||
//! zero mask, where the footprint reaches the horizon.
|
//! zero mask, where the footprint reaches the horizon.
|
||||||
//!
|
//!
|
||||||
|
//! 写出本工作区为一组用例计算的覆盖几何。
|
||||||
|
//!
|
||||||
|
//! 输出是标准输出上的 CSV,带一行表头。它由
|
||||||
|
//! `validation/python/constellation/check_coverage.py` 消费,后者从球面三角形
|
||||||
|
//! 关系重算相同的量并比较。
|
||||||
|
//!
|
||||||
|
//! 各用例的选取跨越了有意思的几何:低仰角遮蔽的低轨,其覆盖区相对地球很小;
|
||||||
|
//! 更高的轨道,其覆盖区很大;赤道与极地情形;以及零遮蔽,其覆盖区直到地平。
|
||||||
|
//!
|
||||||
//! Usage:
|
//! Usage:
|
||||||
//!
|
//!
|
||||||
//! ```text
|
//! ```text
|
||||||
|
|
@ -27,15 +36,28 @@ use core::f64::consts::PI;
|
||||||
/// The coverage geometry is spherical, so a single radius is used. The
|
/// The coverage geometry is spherical, so a single radius is used. The
|
||||||
/// value comes from the shared constants rather than being repeated, so a
|
/// value comes from the shared constants rather than being repeated, so a
|
||||||
/// change to the ellipsoid reaches here.
|
/// change to the ellipsoid reaches here.
|
||||||
|
///
|
||||||
|
/// WGS 84 赤道半径,单位为千米。
|
||||||
|
///
|
||||||
|
/// 覆盖几何是球面的,故只用一个半径。该值来自共享常量而非重复书写,故椭球的
|
||||||
|
/// 改动会传到这里。
|
||||||
const BODY_RADIUS_KM: f64 = apsis_core::constant::EARTH_EQUATORIAL_RADIUS;
|
const BODY_RADIUS_KM: f64 = apsis_core::constant::EARTH_EQUATORIAL_RADIUS;
|
||||||
|
|
||||||
/// One coverage case: an orbital radius and an elevation mask.
|
/// One coverage case: an orbital radius and an elevation mask.
|
||||||
|
///
|
||||||
|
/// 一个覆盖用例:一个轨道半径与一个仰角遮蔽。
|
||||||
struct Case {
|
struct Case {
|
||||||
/// A name for the case, so a failure in the report is readable.
|
/// A name for the case, so a failure in the report is readable.
|
||||||
|
///
|
||||||
|
/// 用例的名称,使报告中的失败可读。
|
||||||
name: &'static str,
|
name: &'static str,
|
||||||
/// The geocentric radius of the satellite, in kilometers.
|
/// The geocentric radius of the satellite, in kilometers.
|
||||||
|
///
|
||||||
|
/// 卫星的地心半径,单位为千米。
|
||||||
satellite_radius_km: f64,
|
satellite_radius_km: f64,
|
||||||
/// The elevation mask at the ground point, in degrees.
|
/// The elevation mask at the ground point, in degrees.
|
||||||
|
///
|
||||||
|
/// 地面点处的仰角遮蔽,单位为度。
|
||||||
elevation_mask_degrees: f64,
|
elevation_mask_degrees: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -44,6 +66,11 @@ struct Case {
|
||||||
/// The satellite radii span a low Earth orbit, two higher altitudes, and a
|
/// The satellite radii span a low Earth orbit, two higher altitudes, and a
|
||||||
/// geostationary one. The masks span the horizon, a typical station mask, and
|
/// geostationary one. The masks span the horizon, a typical station mask, and
|
||||||
/// a strict one.
|
/// a strict one.
|
||||||
|
///
|
||||||
|
/// 被检查的各用例。
|
||||||
|
///
|
||||||
|
/// 卫星半径跨越低轨、两个更高高度以及一个地球静止轨道。遮蔽跨越地平、典型
|
||||||
|
/// 地面站遮蔽,以及一个严格遮蔽。
|
||||||
const CASES: &[Case] = &[
|
const CASES: &[Case] = &[
|
||||||
Case {
|
Case {
|
||||||
name: "leo_low_mask",
|
name: "leo_low_mask",
|
||||||
|
|
@ -83,11 +110,19 @@ const CASES: &[Case] = &[
|
||||||
/// is fed back through `earth_central_angle`, so the pair must compose to the
|
/// is fed back through `earth_central_angle`, so the pair must compose to the
|
||||||
/// identity. The angles span zero to a little past the largest footprint the
|
/// identity. The angles span zero to a little past the largest footprint the
|
||||||
/// cases produce.
|
/// cases produce.
|
||||||
|
///
|
||||||
|
/// 一组用于反解关系检查的中心角,单位为度。
|
||||||
|
///
|
||||||
|
/// 每个都被送入 `elevation_from_central_angle`,其返回的仰角经
|
||||||
|
/// `earth_central_angle` 送回,故这一对必须合成为恒等。各角从零到略超过各用例
|
||||||
|
/// 所产生的最大覆盖区。
|
||||||
const CENTRAL_ANGLES_DEGREES: &[f64] = &[0.0, 1.0, 5.0, 15.0, 30.0, 45.0, 60.0, 75.0];
|
const CENTRAL_ANGLES_DEGREES: &[f64] = &[0.0, 1.0, 5.0, 15.0, 30.0, 45.0, 60.0, 75.0];
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// The header names every column so that the Python side can read by name
|
// The header names every column so that the Python side can read by name
|
||||||
// rather than by position.
|
// rather than by position.
|
||||||
|
//
|
||||||
|
// 表头为每一列命名,使 Python 侧可以按名而非按位置读取。
|
||||||
println!(
|
println!(
|
||||||
"case,satellite_radius_km,body_radius_km,elevation_mask_rad,\
|
"case,satellite_radius_km,body_radius_km,elevation_mask_rad,\
|
||||||
nadir_rad,central_rad,slant_range_km,footprint_central_rad,\
|
nadir_rad,central_rad,slant_range_km,footprint_central_rad,\
|
||||||
|
|
@ -127,6 +162,8 @@ fn main() {
|
||||||
|
|
||||||
// The inverse relation, written with its own header so the Python side
|
// The inverse relation, written with its own header so the Python side
|
||||||
// can tell the two blocks apart by the first column.
|
// can tell the two blocks apart by the first column.
|
||||||
|
//
|
||||||
|
// 反解关系,带上它自己的表头,使 Python 侧可以按第一列区分两个块。
|
||||||
println!();
|
println!();
|
||||||
println!("inverse_central_degrees,elevation_rad,round_trip_central_degrees");
|
println!("inverse_central_degrees,elevation_rad,round_trip_central_degrees");
|
||||||
for degrees in CENTRAL_ANGLES_DEGREES {
|
for degrees in CENTRAL_ANGLES_DEGREES {
|
||||||
|
|
@ -134,6 +171,9 @@ fn main() {
|
||||||
// Use the equatorial radius as the satellite radius for the inverse
|
// Use the equatorial radius as the satellite radius for the inverse
|
||||||
// check, so the geometry is the degenerate one where the elevation is
|
// check, so the geometry is the degenerate one where the elevation is
|
||||||
// always zero. A more useful check uses a satellite altitude.
|
// always zero. A more useful check uses a satellite altitude.
|
||||||
|
//
|
||||||
|
// 反解检查把赤道半径用作卫星半径,故几何是退化的那种,其中仰角恒为零。更
|
||||||
|
// 有用的检查要用卫星高度。
|
||||||
let satellite_radius = BODY_RADIUS_KM + 550.0;
|
let satellite_radius = BODY_RADIUS_KM + 550.0;
|
||||||
let Ok(elevation) =
|
let Ok(elevation) =
|
||||||
elevation_from_central_angle(satellite_radius, BODY_RADIUS_KM, central).ok_or(())
|
elevation_from_central_angle(satellite_radius, BODY_RADIUS_KM, central).ok_or(())
|
||||||
|
|
@ -141,6 +181,8 @@ fn main() {
|
||||||
// Beyond the horizon the inverse has no solution, which is
|
// Beyond the horizon the inverse has no solution, which is
|
||||||
// reported as an empty row rather than skipped, so the count of
|
// reported as an empty row rather than skipped, so the count of
|
||||||
// rows stays fixed.
|
// rows stays fixed.
|
||||||
|
//
|
||||||
|
// 在地平之外反解无解,故报告为一个空行而非跳过,使行数保持固定。
|
||||||
println!("{degrees},,");
|
println!("{degrees},,");
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
//! Writes the specific and zenith gaseous attenuation computed by this
|
//! Writes the specific and zenith gaseous attenuation computed by this
|
||||||
//! workspace, for cross-checking against ITU-R P.676-12.
|
//! workspace, for cross-checking against ITU-R P.676-12.
|
||||||
//!
|
//!
|
||||||
|
//! 写出本工作区计算的比与天顶气体衰减,用于对照 ITU-R P.676-12 交叉核对。
|
||||||
|
//!
|
||||||
//! Usage:
|
//! Usage:
|
||||||
//!
|
//!
|
||||||
//! ```text
|
//! ```text
|
||||||
|
|
@ -15,6 +17,9 @@ use apsis_atmosphere::{
|
||||||
/// The frequencies sampled, in gigahertz. They span the oxygen complex near
|
/// The frequencies sampled, in gigahertz. They span the oxygen complex near
|
||||||
/// 60 GHz, the water vapour lines at 22.235 and 183.31 GHz, and the windows
|
/// 60 GHz, the water vapour lines at 22.235 and 183.31 GHz, and the windows
|
||||||
/// between them.
|
/// between them.
|
||||||
|
///
|
||||||
|
/// 所采样的频率,单位为吉赫兹。它们跨越 60 GHz 附近的氧复合体、22.235 与
|
||||||
|
/// 183.31 GHz 的水汽线,以及其间的窗口。
|
||||||
const FREQUENCIES_GHZ: &[f64] = &[
|
const FREQUENCIES_GHZ: &[f64] = &[
|
||||||
1.0, 2.0, 4.0, 6.0, 10.0, 12.0, 15.0, 20.0, 22.235, 30.0, 40.0, 50.0, 60.0, 70.0, 100.0, 118.0,
|
1.0, 2.0, 4.0, 6.0, 10.0, 12.0, 15.0, 20.0, 22.235, 30.0, 40.0, 50.0, 60.0, 70.0, 100.0, 118.0,
|
||||||
183.0, 300.0,
|
183.0, 300.0,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
//! Writes the exact slant path gaseous attenuation computed by this
|
//! Writes the exact slant path gaseous attenuation computed by this
|
||||||
//! workspace, for cross-checking against ITU-R P.676-12.
|
//! workspace, for cross-checking against ITU-R P.676-12.
|
||||||
//!
|
//!
|
||||||
|
//! 写出本工作区计算的精确斜路径气体衰减,用于对照 ITU-R P.676-12 交叉核对。
|
||||||
|
//!
|
||||||
//! Usage:
|
//! Usage:
|
||||||
//!
|
//!
|
||||||
//! ```text
|
//! ```text
|
||||||
|
|
@ -12,6 +14,8 @@ use apsis_atmosphere::{Atmosphere, slant_path_attenuation_exact};
|
||||||
|
|
||||||
/// The scenarios sampled, as frequency in gigahertz and elevation in
|
/// The scenarios sampled, as frequency in gigahertz and elevation in
|
||||||
/// degrees.
|
/// degrees.
|
||||||
|
///
|
||||||
|
/// 所采样的场景,以吉赫兹计的频率与以度计的仰角。
|
||||||
const SCENARIOS: &[(f64, f64)] = &[
|
const SCENARIOS: &[(f64, f64)] = &[
|
||||||
(12.0, 90.0),
|
(12.0, 90.0),
|
||||||
(12.0, 30.0),
|
(12.0, 30.0),
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,12 @@
|
||||||
//! by `validation/python/coord/check_geodetic.py`, which recomputes the same
|
//! by `validation/python/coord/check_geodetic.py`, which recomputes the same
|
||||||
//! positions with a reference implementation and compares the two.
|
//! positions with a reference implementation and compares the two.
|
||||||
//!
|
//!
|
||||||
|
//! 写出一个大地位置网格,以及本工作区为它们计算的地固直角坐标。
|
||||||
|
//!
|
||||||
|
//! 输出是标准输出上的 CSV,带一行表头。它由
|
||||||
|
//! `validation/python/coord/check_geodetic.py` 消费,后者用参考实现重算相同的
|
||||||
|
//! 位置并比较二者。
|
||||||
|
//!
|
||||||
//! Usage:
|
//! Usage:
|
||||||
//!
|
//!
|
||||||
//! ```text
|
//! ```text
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
//! Writes the IAU 2000/2006 Earth orientation quantities computed by this
|
//! Writes the IAU 2000/2006 Earth orientation quantities computed by this
|
||||||
//! workspace, for cross-checking against ERFA.
|
//! workspace, for cross-checking against ERFA.
|
||||||
//!
|
//!
|
||||||
|
//! 写出本工作区计算的 IAU 2000/2006 地球定向量,用于对照 ERFA 交叉核对。
|
||||||
|
//!
|
||||||
//! Usage:
|
//! Usage:
|
||||||
//!
|
//!
|
||||||
//! ```text
|
//! ```text
|
||||||
|
|
@ -17,20 +19,31 @@ use apsis_math::Mat3;
|
||||||
|
|
||||||
/// The Modified Julian Dates sampled. They span from 1970 to 2050 so that
|
/// The Modified Julian Dates sampled. They span from 1970 to 2050 so that
|
||||||
/// the precession is exercised over a range of a century.
|
/// the precession is exercised over a range of a century.
|
||||||
|
///
|
||||||
|
/// 所采样的约化儒略日。它们从 1970 到 2050,使岁差在一个世纪的跨度上被
|
||||||
|
/// 检验。
|
||||||
const MJD: &[f64] = &[
|
const MJD: &[f64] = &[
|
||||||
40_587.0, 51_544.5, 53_000.0, 55_000.0, 57_000.0, 58_000.0, 60_000.0, 62_000.0,
|
40_587.0, 51_544.5, 53_000.0, 55_000.0, 57_000.0, 58_000.0, 60_000.0, 62_000.0,
|
||||||
];
|
];
|
||||||
|
|
||||||
/// The Terrestrial Time offset from TAI, in seconds.
|
/// The Terrestrial Time offset from TAI, in seconds.
|
||||||
|
///
|
||||||
|
/// 地球时相对 TAI 的偏移,单位为秒。
|
||||||
const TT_MINUS_TAI: f64 = 32.184;
|
const TT_MINUS_TAI: f64 = 32.184;
|
||||||
|
|
||||||
/// The TAI minus UTC offset used for this check, in seconds. It is the value
|
/// The TAI minus UTC offset used for this check, in seconds. It is the value
|
||||||
/// in force from 2017 onward.
|
/// in force from 2017 onward.
|
||||||
|
///
|
||||||
|
/// 本检查所用的 TAI 减 UTC 偏移,单位为秒。它是自 2017 年起生效的值。
|
||||||
const TAI_MINUS_UTC: f64 = 37.0;
|
const TAI_MINUS_UTC: f64 = 37.0;
|
||||||
|
|
||||||
/// Returns the TT Julian date for a Modified Julian Date on the UTC scale.
|
/// Returns the TT Julian date for a Modified Julian Date on the UTC scale.
|
||||||
|
///
|
||||||
|
/// 返回 UTC 时标上某约化儒略日对应的 TT 儒略日。
|
||||||
fn tt_julian_date(utc_mjd: f64) -> f64 {
|
fn tt_julian_date(utc_mjd: f64) -> f64 {
|
||||||
// TAI = UTC + 37, TT = TAI + 32.184, so TT = UTC + 69.184 seconds.
|
// TAI = UTC + 37, TT = TAI + 32.184, so TT = UTC + 69.184 seconds.
|
||||||
|
//
|
||||||
|
// TAI = UTC + 37,TT = TAI + 32.184,故 TT = UTC + 69.184 秒。
|
||||||
utc_mjd + 2_400_000.5 + (TT_MINUS_TAI + TAI_MINUS_UTC) / 86_400.0
|
utc_mjd + 2_400_000.5 + (TT_MINUS_TAI + TAI_MINUS_UTC) / 86_400.0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -41,19 +54,27 @@ fn main() {
|
||||||
let t = (tt - 2_451_545.0) / 36_525.0;
|
let t = (tt - 2_451_545.0) / 36_525.0;
|
||||||
|
|
||||||
// The obliquity, in radians.
|
// The obliquity, in radians.
|
||||||
|
//
|
||||||
|
// 黄赤交角,单位为弧度。
|
||||||
println!("{mjd},obliquity,0,{:.17e}", mean_obliquity(t));
|
println!("{mjd},obliquity,0,{:.17e}", mean_obliquity(t));
|
||||||
|
|
||||||
// The nutation, from the IAU 2000A model.
|
// The nutation, from the IAU 2000A model.
|
||||||
|
//
|
||||||
|
// 章动,取自 IAU 2000A 模型。
|
||||||
let nutation = nutation_2000a(t);
|
let nutation = nutation_2000a(t);
|
||||||
println!("{mjd},nutation_longitude_a,0,{:.17e}", nutation.longitude);
|
println!("{mjd},nutation_longitude_a,0,{:.17e}", nutation.longitude);
|
||||||
println!("{mjd},nutation_obliquity_a,0,{:.17e}", nutation.obliquity);
|
println!("{mjd},nutation_obliquity_a,0,{:.17e}", nutation.obliquity);
|
||||||
|
|
||||||
// The nutation with the IAU 2006 adjustment.
|
// The nutation with the IAU 2006 adjustment.
|
||||||
|
//
|
||||||
|
// 施加 IAU 2006 调整后的章动。
|
||||||
let adjusted = nutation_2000a_with_2006_adjustment(t);
|
let adjusted = nutation_2000a_with_2006_adjustment(t);
|
||||||
println!("{mjd},nutation_longitude_06a,0,{:.17e}", adjusted.longitude);
|
println!("{mjd},nutation_longitude_06a,0,{:.17e}", adjusted.longitude);
|
||||||
println!("{mjd},nutation_obliquity_06a,0,{:.17e}", adjusted.obliquity);
|
println!("{mjd},nutation_obliquity_06a,0,{:.17e}", adjusted.obliquity);
|
||||||
|
|
||||||
// The four precession angles.
|
// The four precession angles.
|
||||||
|
//
|
||||||
|
// 四个岁差角。
|
||||||
let angles = precession_angles(t);
|
let angles = precession_angles(t);
|
||||||
println!("{mjd},precession_gamma_bar,0,{:.17e}", angles.gamma_bar);
|
println!("{mjd},precession_gamma_bar,0,{:.17e}", angles.gamma_bar);
|
||||||
println!("{mjd},precession_phi_bar,0,{:.17e}", angles.phi_bar);
|
println!("{mjd},precession_phi_bar,0,{:.17e}", angles.phi_bar);
|
||||||
|
|
@ -62,6 +83,8 @@ fn main() {
|
||||||
|
|
||||||
// The bias-precession-nutation matrix, which carries the celestial
|
// The bias-precession-nutation matrix, which carries the celestial
|
||||||
// reference frame to the true equator and equinox of date.
|
// reference frame to the true equator and equinox of date.
|
||||||
|
//
|
||||||
|
// 偏差-岁差-章动矩阵,它把天球参考系带到该日的真赤道与真春分点。
|
||||||
let bpn = bias_precession_nutation_matrix(t);
|
let bpn = bias_precession_nutation_matrix(t);
|
||||||
for row in 0..3 {
|
for row in 0..3 {
|
||||||
for column in 0..3 {
|
for column in 0..3 {
|
||||||
|
|
@ -71,12 +94,16 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Greenwich apparent sidereal time, in radians.
|
// Greenwich apparent sidereal time, in radians.
|
||||||
|
//
|
||||||
|
// 格林尼治视恒星时,单位为弧度。
|
||||||
println!(
|
println!(
|
||||||
"{mjd},gast,0,{:.17e}",
|
"{mjd},gast,0,{:.17e}",
|
||||||
greenwich_apparent_sidereal_time(tt, tt)
|
greenwich_apparent_sidereal_time(tt, tt)
|
||||||
);
|
);
|
||||||
|
|
||||||
// The celestial-to-terrestrial matrix, with zero polar motion.
|
// The celestial-to-terrestrial matrix, with zero polar motion.
|
||||||
|
//
|
||||||
|
// 天球到地球坐标系矩阵,极移为零。
|
||||||
let matrix = celestial_to_terrestrial_matrix(tt, tt, PolarMotion::NONE);
|
let matrix = celestial_to_terrestrial_matrix(tt, tt, PolarMotion::NONE);
|
||||||
for row in 0..3 {
|
for row in 0..3 {
|
||||||
for column in 0..3 {
|
for column in 0..3 {
|
||||||
|
|
@ -88,5 +115,7 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Keeps the matrix type in scope for the documentation build.
|
/// Keeps the matrix type in scope for the documentation build.
|
||||||
|
///
|
||||||
|
/// 为使文档构建保持在作用域内而保留矩阵类型。
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
fn _uses_matrix(_matrix: Mat3) {}
|
fn _uses_matrix(_matrix: Mat3) {}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,16 @@
|
||||||
//! elements, which exercises the vector algebra and the conic section
|
//! elements, which exercises the vector algebra and the conic section
|
||||||
//! relations rather than a single formula.
|
//! relations rather than a single formula.
|
||||||
//!
|
//!
|
||||||
|
//! 写出本工作区计算的二体换算。
|
||||||
|
//!
|
||||||
|
//! 输出是标准输出上的 CSV,带一行表头。它由
|
||||||
|
//! `validation/python/orbit/check_kepler.py` 消费,后者从闭式表达式重算相同的量
|
||||||
|
//! 并比较。Python 侧是依据几何而非依据本代码写成的,故转录错误会表现为不一致。
|
||||||
|
//!
|
||||||
|
//! 写出两张表。第一张在一系列轨道上把开普勒根数转成直角坐标状态,这是规划调用方
|
||||||
|
//! 所用的路径。第二张往另一方向转并记录所恢复的根数,它检验的是矢量代数与圆锥
|
||||||
|
//! 曲线关系,而非单一公式。
|
||||||
|
//!
|
||||||
//! Usage:
|
//! Usage:
|
||||||
//!
|
//!
|
||||||
//! ```text
|
//! ```text
|
||||||
|
|
@ -22,28 +32,48 @@
|
||||||
use apsis_kepler::{GravityParameter, KeplerianElements};
|
use apsis_kepler::{GravityParameter, KeplerianElements};
|
||||||
|
|
||||||
/// The gravitational parameter used throughout, WGS 84.
|
/// The gravitational parameter used throughout, WGS 84.
|
||||||
|
///
|
||||||
|
/// 全程所用的引力参数,WGS 84。
|
||||||
const MU: GravityParameter = GravityParameter::WGS84;
|
const MU: GravityParameter = GravityParameter::WGS84;
|
||||||
|
|
||||||
/// One orbit to convert, chosen to span the shapes the model must handle.
|
/// One orbit to convert, chosen to span the shapes the model must handle.
|
||||||
|
///
|
||||||
|
/// 一个要转换的轨道,其选取跨越该模型必须处理的各形状。
|
||||||
struct Case {
|
struct Case {
|
||||||
/// A name for the case, so a failure in the report is readable.
|
/// A name for the case, so a failure in the report is readable.
|
||||||
|
///
|
||||||
|
/// 用例的名称,使报告中的失败可读。
|
||||||
name: &'static str,
|
name: &'static str,
|
||||||
/// Semi-major axis, in kilometers.
|
/// Semi-major axis, in kilometers.
|
||||||
|
///
|
||||||
|
/// 半长轴,单位为千米。
|
||||||
semi_major_axis: f64,
|
semi_major_axis: f64,
|
||||||
/// Eccentricity, dimensionless.
|
/// Eccentricity, dimensionless.
|
||||||
|
///
|
||||||
|
/// 偏心率,无量纲。
|
||||||
eccentricity: f64,
|
eccentricity: f64,
|
||||||
/// Inclination, in degrees.
|
/// Inclination, in degrees.
|
||||||
|
///
|
||||||
|
/// 倾角,单位为度。
|
||||||
inclination_deg: f64,
|
inclination_deg: f64,
|
||||||
/// Right ascension of the ascending node, in degrees.
|
/// Right ascension of the ascending node, in degrees.
|
||||||
|
///
|
||||||
|
/// 升交点赤经,单位为度。
|
||||||
right_ascension_deg: f64,
|
right_ascension_deg: f64,
|
||||||
/// Argument of perigee, in degrees.
|
/// Argument of perigee, in degrees.
|
||||||
|
///
|
||||||
|
/// 近地点幅角,单位为度。
|
||||||
argument_of_perigee_deg: f64,
|
argument_of_perigee_deg: f64,
|
||||||
/// True anomaly, in degrees.
|
/// True anomaly, in degrees.
|
||||||
|
///
|
||||||
|
/// 真近点角,单位为度。
|
||||||
true_anomaly_deg: f64,
|
true_anomaly_deg: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Case {
|
impl Case {
|
||||||
/// Returns the case as elements in the units the crate uses.
|
/// Returns the case as elements in the units the crate uses.
|
||||||
|
///
|
||||||
|
/// 以本 crate 所用的单位把该用例返回为根数。
|
||||||
fn elements(&self) -> KeplerianElements {
|
fn elements(&self) -> KeplerianElements {
|
||||||
KeplerianElements {
|
KeplerianElements {
|
||||||
semi_major_axis: self.semi_major_axis,
|
semi_major_axis: self.semi_major_axis,
|
||||||
|
|
@ -61,6 +91,11 @@ impl Case {
|
||||||
/// The set spans a circular orbit, two mildly eccentric ones, a highly
|
/// The set spans a circular orbit, two mildly eccentric ones, a highly
|
||||||
/// eccentric one that exercises the near-parabolic branch of the anomaly
|
/// eccentric one that exercises the near-parabolic branch of the anomaly
|
||||||
/// iteration, a retrograde one, and one inclined close to the polar limit.
|
/// iteration, a retrograde one, and one inclined close to the polar limit.
|
||||||
|
///
|
||||||
|
/// 被转换的各轨道。
|
||||||
|
///
|
||||||
|
/// 该集合跨越一个圆轨道、两个轻度偏心者、一个检验近点角迭代近抛物线分支的
|
||||||
|
/// 高度偏心者、一个逆行轨道,以及一个倾角接近极地极限的轨道。
|
||||||
const CASES: &[Case] = &[
|
const CASES: &[Case] = &[
|
||||||
Case {
|
Case {
|
||||||
name: "circular_equatorial",
|
name: "circular_equatorial",
|
||||||
|
|
@ -119,10 +154,14 @@ const CASES: &[Case] = &[
|
||||||
];
|
];
|
||||||
|
|
||||||
/// The geostationary radius, used for a circular orbit at that altitude.
|
/// The geostationary radius, used for a circular orbit at that altitude.
|
||||||
|
///
|
||||||
|
/// 地球静止轨道半径,用于该高度处的圆轨道。
|
||||||
const GEO_RADIUS: f64 = 42_164.0;
|
const GEO_RADIUS: f64 = 42_164.0;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// The first table: elements to a Cartesian state.
|
// The first table: elements to a Cartesian state.
|
||||||
|
//
|
||||||
|
// 第一张表:根数到直角坐标状态。
|
||||||
println!(
|
println!(
|
||||||
"case,semi_major_axis_km,eccentricity,inclination_rad,right_ascension_rad,\
|
"case,semi_major_axis_km,eccentricity,inclination_rad,right_ascension_rad,\
|
||||||
argument_of_perigee_rad,true_anomaly_rad,x_km,y_km,z_km,vx_kms,vy_kms,vz_kms,\
|
argument_of_perigee_rad,true_anomaly_rad,x_km,y_km,z_km,vx_kms,vy_kms,vz_kms,\
|
||||||
|
|
@ -136,6 +175,8 @@ fn main() {
|
||||||
// The specific energy is reported as well, because it is the
|
// The specific energy is reported as well, because it is the
|
||||||
// quantity the Python side uses to check the speed independently of
|
// quantity the Python side uses to check the speed independently of
|
||||||
// the direction.
|
// the direction.
|
||||||
|
//
|
||||||
|
// 比能量也被报告,因为它是 Python 侧用来独立于方向核对速率的量。
|
||||||
let radius = state.position.norm();
|
let radius = state.position.norm();
|
||||||
let energy = state.velocity.norm_squared() / 2.0 - MU.value() / radius;
|
let energy = state.velocity.norm_squared() / 2.0 - MU.value() / radius;
|
||||||
println!(
|
println!(
|
||||||
|
|
@ -160,6 +201,8 @@ fn main() {
|
||||||
|
|
||||||
// A circular orbit at the geostationary radius, whose speed has a closed
|
// A circular orbit at the geostationary radius, whose speed has a closed
|
||||||
// form, is included in the same table under its own name.
|
// form, is included in the same table under its own name.
|
||||||
|
//
|
||||||
|
// 地球静止半径处的圆轨道,其速率有闭式,故以它自己的名称纳入同一张表。
|
||||||
let geo = KeplerianElements {
|
let geo = KeplerianElements {
|
||||||
semi_major_axis: GEO_RADIUS,
|
semi_major_axis: GEO_RADIUS,
|
||||||
eccentricity: 0.0,
|
eccentricity: 0.0,
|
||||||
|
|
@ -192,6 +235,9 @@ fn main() {
|
||||||
// The second table: a state back to elements, over a grid of true
|
// The second table: a state back to elements, over a grid of true
|
||||||
// anomalies on one orbit. This exercises the vector algebra rather than
|
// anomalies on one orbit. This exercises the vector algebra rather than
|
||||||
// the perifocal formulae the first table uses.
|
// the perifocal formulae the first table uses.
|
||||||
|
//
|
||||||
|
// 第二张表:在一个轨道的真近点角网格上从状态转回根数。它检验矢量代数,而非
|
||||||
|
// 第一张表所用的近焦点公式。
|
||||||
println!();
|
println!();
|
||||||
println!(
|
println!(
|
||||||
"true_anomaly_deg,recovered_semi_major_axis_km,recovered_eccentricity,\
|
"true_anomaly_deg,recovered_semi_major_axis_km,recovered_eccentricity,\
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,12 @@
|
||||||
//! by `validation/python/link/check_link.py`, which recomputes the same
|
//! by `validation/python/link/check_link.py`, which recomputes the same
|
||||||
//! quantities from the link equation and compares.
|
//! quantities from the link equation and compares.
|
||||||
//!
|
//!
|
||||||
|
//! 写出链路预算输入以及本工作区为它们计算的各数字。
|
||||||
|
//!
|
||||||
|
//! 输出是标准输出上的 CSV,带一行表头。它由
|
||||||
|
//! `validation/python/link/check_link.py` 消费,后者从链路方程重算相同的量并
|
||||||
|
//! 比较。
|
||||||
|
//!
|
||||||
//! Usage:
|
//! Usage:
|
||||||
//!
|
//!
|
||||||
//! ```text
|
//! ```text
|
||||||
|
|
@ -19,6 +25,11 @@ use apsis_rf::{Decibel, Gain, Power};
|
||||||
///
|
///
|
||||||
/// The unit of each field is in its name: powers and gains in decibels,
|
/// The unit of each field is in its name: powers and gains in decibels,
|
||||||
/// temperature in kelvin, and everything else in SI base units.
|
/// temperature in kelvin, and everything else in SI base units.
|
||||||
|
///
|
||||||
|
/// 一个链路场景,命名使各字段在每次使用时保持可读。
|
||||||
|
///
|
||||||
|
/// 每个字段的单位在其名称中:功率与增益以分贝计,温度以开尔文计,其余以 SI
|
||||||
|
/// 基本单位计。
|
||||||
struct Scenario {
|
struct Scenario {
|
||||||
transmit_dbw: f64,
|
transmit_dbw: f64,
|
||||||
transmit_dbi: f64,
|
transmit_dbi: f64,
|
||||||
|
|
@ -33,6 +44,9 @@ struct Scenario {
|
||||||
|
|
||||||
/// The scenarios checked. They cover a Ku band downlink, an S band link, a
|
/// The scenarios checked. They cover a Ku band downlink, an S band link, a
|
||||||
/// wideband Ka link, and an L band link with a warmer receiver.
|
/// wideband Ka link, and an L band link with a warmer receiver.
|
||||||
|
///
|
||||||
|
/// 被检查的各场景。它们覆盖 Ku 频段下行、S 频段链路、宽带 Ka 链路,以及一个
|
||||||
|
/// 接收机更热的 L 频段链路。
|
||||||
const SCENARIOS: &[Scenario] = &[
|
const SCENARIOS: &[Scenario] = &[
|
||||||
Scenario {
|
Scenario {
|
||||||
transmit_dbw: 10.0,
|
transmit_dbw: 10.0,
|
||||||
|
|
@ -130,6 +144,8 @@ fn main() {
|
||||||
let cn = budget.carrier_to_noise().map(|value| value.db());
|
let cn = budget.carrier_to_noise().map(|value| value.db());
|
||||||
// The energy per bit ratio is reported at a fixed data rate equal to
|
// The energy per bit ratio is reported at a fixed data rate equal to
|
||||||
// the bandwidth, which makes it the carrier to noise ratio.
|
// the bandwidth, which makes it the carrier to noise ratio.
|
||||||
|
//
|
||||||
|
// 每比特能量比在等于带宽的固定数据速率下报告,这使它即为载噪比。
|
||||||
let ebn0 = budget
|
let ebn0 = budget
|
||||||
.energy_per_bit_over_noise(bandwidth)
|
.energy_per_bit_over_noise(bandwidth)
|
||||||
.map(|value| value.db());
|
.map(|value| value.db());
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,12 @@
|
||||||
//! which propagates the same element sets with the reference implementation
|
//! which propagates the same element sets with the reference implementation
|
||||||
//! and compares.
|
//! and compares.
|
||||||
//!
|
//!
|
||||||
|
//! 为一组根数集与时刻写出传播后的状态。
|
||||||
|
//!
|
||||||
|
//! 输出是标准输出上的 CSV,表头命名根数集下标、距历元的分钟数,以及位置与速度
|
||||||
|
//! 分量。它由 `validation/python/orbit/check_sgp4.py` 消费,后者用参考实现传播
|
||||||
|
//! 相同的根数集并比较。
|
||||||
|
//!
|
||||||
//! Usage:
|
//! Usage:
|
||||||
//!
|
//!
|
||||||
//! ```text
|
//! ```text
|
||||||
|
|
@ -19,24 +25,35 @@ use apsis_tle::TwoLineElement;
|
||||||
/// The element sets used by the cross-check. They are the historical test
|
/// The element sets used by the cross-check. They are the historical test
|
||||||
/// cases distributed with the SGP4 reference implementation, which cover
|
/// cases distributed with the SGP4 reference implementation, which cover
|
||||||
/// low, medium, and high eccentricity and the deep space branch.
|
/// low, medium, and high eccentricity and the deep space branch.
|
||||||
|
///
|
||||||
|
/// 交叉核对所用的各根数集。它们是随 SGP4 参考实现分发的历史测试用例,覆盖低、
|
||||||
|
/// 中、高偏心率以及深空分支。
|
||||||
const ELEMENT_SETS: &[&str] = &[
|
const ELEMENT_SETS: &[&str] = &[
|
||||||
// International Space Station, near circular low Earth orbit.
|
// International Space Station, near circular low Earth orbit.
|
||||||
|
//
|
||||||
|
// 国际空间站,近圆形低轨。
|
||||||
concat!(
|
concat!(
|
||||||
"1 25544U 98067A 08264.51782528 -.00002182 00000-0 -11606-4 0 2927\r\n",
|
"1 25544U 98067A 08264.51782528 -.00002182 00000-0 -11606-4 0 2927\r\n",
|
||||||
"2 25544 51.6416 247.4627 0006703 130.5360 325.0288 15.72125391563537\r\n",
|
"2 25544 51.6416 247.4627 0006703 130.5360 325.0288 15.72125391563537\r\n",
|
||||||
),
|
),
|
||||||
// A highly eccentric orbit, which exercises the eccentric anomaly
|
// A highly eccentric orbit, which exercises the eccentric anomaly
|
||||||
// iteration and the drag terms away from circular motion.
|
// iteration and the drag terms away from circular motion.
|
||||||
|
//
|
||||||
|
// 一个高度偏心的轨道,它检验偏近点角迭代以及远离圆运动时的阻力项。
|
||||||
concat!(
|
concat!(
|
||||||
"1 00005U 58002B 00179.78495062 .00000023 00000-0 28098-4 0 4753\r\n",
|
"1 00005U 58002B 00179.78495062 .00000023 00000-0 28098-4 0 4753\r\n",
|
||||||
"2 00005 34.2682 348.7242 1859667 331.7664 19.3264 10.82419157413667\r\n",
|
"2 00005 34.2682 348.7242 1859667 331.7664 19.3264 10.82419157413667\r\n",
|
||||||
),
|
),
|
||||||
// A geostationary transfer orbit with a low perigee.
|
// A geostationary transfer orbit with a low perigee.
|
||||||
|
//
|
||||||
|
// 一个近地点很低的地球静止转移轨道。
|
||||||
concat!(
|
concat!(
|
||||||
"1 27651U 03004A 06185.99374200 .00000109 00000-0 19909-4 0 445\r\n",
|
"1 27651U 03004A 06185.99374200 .00000109 00000-0 19909-4 0 445\r\n",
|
||||||
"2 27651 7.1743 182.9443 7867251 269.0386 18.6601 1.03461646 9884\r\n",
|
"2 27651 7.1743 182.9443 7867251 269.0386 18.6601 1.03461646 9884\r\n",
|
||||||
),
|
),
|
||||||
// A deep space orbit, whose period exceeds 225 minutes.
|
// A deep space orbit, whose period exceeds 225 minutes.
|
||||||
|
//
|
||||||
|
// 一个深空轨道,其周期超过 225 分钟。
|
||||||
concat!(
|
concat!(
|
||||||
"1 09880U 77021A 06174.85710247 .00000090 00000-0 10000-3 0 7322\r\n",
|
"1 09880U 77021A 06174.85710247 .00000090 00000-0 10000-3 0 7322\r\n",
|
||||||
"2 09880 64.1526 313.1296 6546925 103.4683 305.3980 2.00754276 13047\r\n",
|
"2 09880 64.1526 313.1296 6546925 103.4683 305.3980 2.00754276 13047\r\n",
|
||||||
|
|
@ -44,6 +61,8 @@ const ELEMENT_SETS: &[&str] = &[
|
||||||
];
|
];
|
||||||
|
|
||||||
/// The times to sample, in minutes from the element epoch.
|
/// The times to sample, in minutes from the element epoch.
|
||||||
|
///
|
||||||
|
/// 要采样的时刻,以距根数历元的分钟数计。
|
||||||
const TIMES_MINUTES: &[f64] = &[
|
const TIMES_MINUTES: &[f64] = &[
|
||||||
0.0, 1.0, 60.0, 360.0, 720.0, 1_440.0, 2_880.0, 10_080.0, -1_440.0,
|
0.0, 1.0, 60.0, 360.0, 720.0, 1_440.0, 2_880.0, 10_080.0, -1_440.0,
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
//! Writes the rain height computed by this workspace, for cross-checking
|
//! Writes the rain height computed by this workspace, for cross-checking
|
||||||
//! against ITU-R P.839-4.
|
//! against ITU-R P.839-4.
|
||||||
//!
|
//!
|
||||||
|
//! 写出本工作区计算的雨顶高度,用于对照 ITU-R P.839-4 交叉核对。
|
||||||
|
//!
|
||||||
//! Usage:
|
//! Usage:
|
||||||
//!
|
//!
|
||||||
//! ```text
|
//! ```text
|
||||||
|
|
@ -11,6 +13,8 @@
|
||||||
use apsis_atmosphere::{rain_height, zero_isotherm_height};
|
use apsis_atmosphere::{rain_height, zero_isotherm_height};
|
||||||
|
|
||||||
/// The locations sampled, as latitude and longitude in degrees.
|
/// The locations sampled, as latitude and longitude in degrees.
|
||||||
|
///
|
||||||
|
/// 所采样的位置,以度计的纬度与经度。
|
||||||
const POINTS: &[(f64, f64)] = &[
|
const POINTS: &[(f64, f64)] = &[
|
||||||
(0.0, 0.0),
|
(0.0, 0.0),
|
||||||
(45.0, 0.0),
|
(45.0, 0.0),
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
//! Writes the P.838-3 rain coefficients computed by this workspace, for
|
//! Writes the P.838-3 rain coefficients computed by this workspace, for
|
||||||
//! cross-checking against ITU-R P.838-3.
|
//! cross-checking against ITU-R P.838-3.
|
||||||
//!
|
//!
|
||||||
|
//! 写出本工作区计算的 P.838-3 降雨系数,用于对照 ITU-R P.838-3 交叉核对。
|
||||||
|
//!
|
||||||
//! Usage:
|
//! Usage:
|
||||||
//!
|
//!
|
||||||
//! ```text
|
//! ```text
|
||||||
|
|
@ -11,6 +13,8 @@
|
||||||
use apsis_atmosphere::rain_coefficients;
|
use apsis_atmosphere::rain_coefficients;
|
||||||
|
|
||||||
/// The frequencies sampled, in gigahertz.
|
/// The frequencies sampled, in gigahertz.
|
||||||
|
///
|
||||||
|
/// 所采样的频率,单位为吉赫兹。
|
||||||
const FREQUENCIES_GHZ: &[f64] = &[
|
const FREQUENCIES_GHZ: &[f64] = &[
|
||||||
1.0, 2.0, 4.0, 6.0, 8.0, 10.0, 12.0, 15.0, 20.0, 22.0, 25.0, 30.0, 40.0, 50.0, 60.0, 70.0,
|
1.0, 2.0, 4.0, 6.0, 8.0, 10.0, 12.0, 15.0, 20.0, 22.0, 25.0, 30.0, 40.0, 50.0, 60.0, 70.0,
|
||||||
100.0,
|
100.0,
|
||||||
|
|
@ -21,6 +25,8 @@ fn main() {
|
||||||
for &frequency in FREQUENCIES_GHZ {
|
for &frequency in FREQUENCIES_GHZ {
|
||||||
// A horizontal path, which removes the elevation dependence and
|
// A horizontal path, which removes the elevation dependence and
|
||||||
// isolates the coefficient curves.
|
// isolates the coefficient curves.
|
||||||
|
//
|
||||||
|
// 水平路径,它去除仰角依赖并分离出各系数曲线。
|
||||||
for &(elevation_degrees, polarisation_degrees) in
|
for &(elevation_degrees, polarisation_degrees) in
|
||||||
&[(90.0_f64, 0.0_f64), (90.0, 90.0), (30.0, 0.0), (30.0, 45.0)]
|
&[(90.0_f64, 0.0_f64), (90.0, 90.0), (30.0, 0.0), (30.0, 45.0)]
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
//! Writes rain path attenuation computed by this workspace, for
|
//! Writes rain path attenuation computed by this workspace, for
|
||||||
//! cross-checking the ITU-R P.618-13 slant path method.
|
//! cross-checking the ITU-R P.618-13 slant path method.
|
||||||
//!
|
//!
|
||||||
|
//! 写出本工作区计算的降雨路径衰减,用于交叉核对 ITU-R P.618-13 斜路径方法。
|
||||||
|
//!
|
||||||
//! Usage:
|
//! Usage:
|
||||||
//!
|
//!
|
||||||
//! ```text
|
//! ```text
|
||||||
|
|
@ -13,6 +15,9 @@ use apsis_atmosphere::{DEFAULT_RAIN_HEIGHT_KM, rain_attenuation};
|
||||||
/// The scenarios sampled. Each is a rain rate in millimeters per hour, a
|
/// The scenarios sampled. Each is a rain rate in millimeters per hour, a
|
||||||
/// frequency in gigahertz, an elevation in degrees, and a latitude in
|
/// frequency in gigahertz, an elevation in degrees, and a latitude in
|
||||||
/// degrees. The station height is zero and the rain height is the default.
|
/// degrees. The station height is zero and the rain height is the default.
|
||||||
|
///
|
||||||
|
/// 所采样的场景。每个都是以毫米每小时计的降雨率、以吉赫兹计的频率、以度计的
|
||||||
|
/// 仰角,以及以度计的纬度。站高为零,雨顶高度为缺省值。
|
||||||
const SCENARIOS: &[(f64, f64, f64, f64)] = &[
|
const SCENARIOS: &[(f64, f64, f64, f64)] = &[
|
||||||
(20.0, 12.0, 30.0, 45.0),
|
(20.0, 12.0, 30.0, 45.0),
|
||||||
(20.0, 12.0, 10.0, 45.0),
|
(20.0, 12.0, 10.0, 45.0),
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
//! Writes the ITU-R S.465 reference pattern computed by this workspace, for
|
//! Writes the ITU-R S.465 reference pattern computed by this workspace, for
|
||||||
//! cross-checking against the recommendation.
|
//! cross-checking against the recommendation.
|
||||||
//!
|
//!
|
||||||
|
//! 写出本工作区计算的 ITU-R S.465 参考方向图,用于对照该建议书交叉核对。
|
||||||
|
//!
|
||||||
//! Usage:
|
//! Usage:
|
||||||
//!
|
//!
|
||||||
//! ```text
|
//! ```text
|
||||||
|
|
@ -11,9 +13,13 @@
|
||||||
use apsis_antenna::{main_lobe_break_angle, reference_pattern_gain, reference_peak_gain};
|
use apsis_antenna::{main_lobe_break_angle, reference_pattern_gain, reference_peak_gain};
|
||||||
|
|
||||||
/// The antenna sizes sampled, as diameter to wavelength ratios.
|
/// The antenna sizes sampled, as diameter to wavelength ratios.
|
||||||
|
///
|
||||||
|
/// 所采样的天线尺寸,以口径与波长之比表示。
|
||||||
const RATIOS: &[f64] = &[50.0, 100.0, 200.0];
|
const RATIOS: &[f64] = &[50.0, 100.0, 200.0];
|
||||||
|
|
||||||
/// The off-axis angles sampled, in degrees.
|
/// The off-axis angles sampled, in degrees.
|
||||||
|
///
|
||||||
|
/// 所采样的偏轴角,单位为度。
|
||||||
const ANGLES_DEGREES: &[f64] = &[0.1, 0.5, 1.0, 5.0, 20.0, 36.0, 48.0, 90.0];
|
const ANGLES_DEGREES: &[f64] = &[0.1, 0.5, 1.0, 5.0, 20.0, 36.0, 48.0, 90.0];
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
//! Writes the TEME to Earth-fixed transformation computed by this workspace,
|
//! Writes the TEME to Earth-fixed transformation computed by this workspace,
|
||||||
//! for cross-checking against astropy.
|
//! for cross-checking against astropy.
|
||||||
//!
|
//!
|
||||||
|
//! 写出本工作区计算的 TEME 到地固坐标变换,用于对照 astropy 交叉核对。
|
||||||
|
//!
|
||||||
//! Usage:
|
//! Usage:
|
||||||
//!
|
//!
|
||||||
//! ```text
|
//! ```text
|
||||||
|
|
@ -12,6 +14,8 @@ use apsis_frames::iau2000::{PolarMotion, teme_to_terrestrial_matrix};
|
||||||
|
|
||||||
/// The samples, as a UTC Modified Julian Date and a TEME position in
|
/// The samples, as a UTC Modified Julian Date and a TEME position in
|
||||||
/// kilometers.
|
/// kilometers.
|
||||||
|
///
|
||||||
|
/// 各样本,为一个 UTC 约化儒略日与一个以千米计的 TEME 位置。
|
||||||
const SAMPLES: &[(f64, [f64; 3])] = &[
|
const SAMPLES: &[(f64, [f64; 3])] = &[
|
||||||
(60_481.5, [7_000.0, 1_000.0, 2_000.0]),
|
(60_481.5, [7_000.0, 1_000.0, 2_000.0]),
|
||||||
(51_544.5, [7_000.0, -3_000.0, 1_000.0]),
|
(51_544.5, [7_000.0, -3_000.0, 1_000.0]),
|
||||||
|
|
@ -28,6 +32,10 @@ fn main() {
|
||||||
// is used directly here and the check tolerates that difference.
|
// is used directly here and the check tolerates that difference.
|
||||||
// The Julian date is split into a whole number of days and a
|
// The Julian date is split into a whole number of days and a
|
||||||
// fraction, which preserves more of the day than a single value.
|
// fraction, which preserves more of the day than a single value.
|
||||||
|
//
|
||||||
|
// 该变换需要 UT1 时间,因为是地球自转在带动坐标系。UT1 与 UTC 相差不到
|
||||||
|
// 0.9 秒,即 0.0037 度的转动,故此处直接使用 UTC 值,而检查容忍该差异。儒略日
|
||||||
|
// 被拆成整数天数与零头,这比单个值保留更多当日信息。
|
||||||
let matrix = teme_to_terrestrial_matrix(2_400_000.5, utc_mjd, PolarMotion::NONE);
|
let matrix = teme_to_terrestrial_matrix(2_400_000.5, utc_mjd, PolarMotion::NONE);
|
||||||
let vector = apsis_math::Vec3::new(position[0], position[1], position[2]);
|
let vector = apsis_math::Vec3::new(position[0], position[1], position[2]);
|
||||||
let result = matrix * vector;
|
let result = matrix * vector;
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,15 @@
|
||||||
//! Julian Date near 60 000 to better than about 40 microseconds. The two
|
//! Julian Date near 60 000 to better than about 40 microseconds. The two
|
||||||
//! parts let the checker compare instants to well below a microsecond.
|
//! parts let the checker compare instants to well below a microsecond.
|
||||||
//!
|
//!
|
||||||
|
//! 写出闰秒偏移以及本工作区在一系列瞬时上计算的时标换算。
|
||||||
|
//!
|
||||||
|
//! 输出是标准输出上的 CSV,带一行表头。它由
|
||||||
|
//! `validation/python/time/check_time.py` 消费,后者用参考实现重算每个瞬时。
|
||||||
|
//!
|
||||||
|
//! TAI 瞬时按两部分写出,一个整数约化儒略日与一天的零头,因为单个 `f64` 无法
|
||||||
|
//! 把接近 60 000 的约化儒略日保持到优于约 40 微秒。两部分使检查器能把瞬时比较
|
||||||
|
//! 到远低于一微秒。
|
||||||
|
//!
|
||||||
//! Usage:
|
//! Usage:
|
||||||
//!
|
//!
|
||||||
//! ```text
|
//! ```text
|
||||||
|
|
@ -21,6 +30,8 @@ use apsis_leap::{LEAP_SECONDS, tai_minus_utc_at_mjd};
|
||||||
use apsis_time::{Calendar, Epoch, TT_MINUS_TAI, TimeScale};
|
use apsis_time::{Calendar, Epoch, TT_MINUS_TAI, TimeScale};
|
||||||
|
|
||||||
/// Splits a Modified Julian Date into its integer day and its fraction.
|
/// Splits a Modified Julian Date into its integer day and its fraction.
|
||||||
|
///
|
||||||
|
/// 把约化儒略日拆为其整数日与零头。
|
||||||
fn split(mjd: f64) -> (i64, f64) {
|
fn split(mjd: f64) -> (i64, f64) {
|
||||||
let day = mjd.floor();
|
let day = mjd.floor();
|
||||||
(day as i64, mjd - day)
|
(day as i64, mjd - day)
|
||||||
|
|
@ -51,6 +62,8 @@ fn main() {
|
||||||
|
|
||||||
// Sample every leap second boundary at several times of day, so that
|
// Sample every leap second boundary at several times of day, so that
|
||||||
// the step behaviour and the interior of each interval are covered.
|
// the step behaviour and the interior of each interval are covered.
|
||||||
|
//
|
||||||
|
// 在一天中的若干时刻对每个闰秒边界采样,使阶跃行为与每个区间的内部都被覆盖。
|
||||||
for entry in LEAP_SECONDS {
|
for entry in LEAP_SECONDS {
|
||||||
for (hour, minute, second) in [(0, 0, 0.0), (6, 0, 0.0), (12, 0, 0.0), (18, 0, 0.0)] {
|
for (hour, minute, second) in [(0, 0, 0.0), (6, 0, 0.0), (12, 0, 0.0), (18, 0, 0.0)] {
|
||||||
let calendar = Calendar::new(entry.year, entry.month, entry.day, hour, minute, second);
|
let calendar = Calendar::new(entry.year, entry.month, entry.day, hour, minute, second);
|
||||||
|
|
@ -61,6 +74,8 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// The last second before a leap second and the first second after it.
|
// The last second before a leap second and the first second after it.
|
||||||
|
//
|
||||||
|
// 闰秒前的最后一秒与其后的第一秒。
|
||||||
for (year, month, day, hour, minute, second) in [
|
for (year, month, day, hour, minute, second) in [
|
||||||
(2016, 12, 31, 23, 59, 59.0),
|
(2016, 12, 31, 23, 59, 59.0),
|
||||||
(2017, 1, 1, 0, 0, 0.0),
|
(2017, 1, 1, 0, 0, 0.0),
|
||||||
|
|
@ -76,5 +91,7 @@ fn main() {
|
||||||
|
|
||||||
// The Terrestrial Time offset is a defining constant, written here so
|
// The Terrestrial Time offset is a defining constant, written here so
|
||||||
// that the checker can verify it without recomputing the calendar.
|
// that the checker can verify it without recomputing the calendar.
|
||||||
|
//
|
||||||
|
// 地球时偏移是一个定义常量,写在这里使检查器无需重算日历即可核验它。
|
||||||
println!("# tt_minus_tai_seconds={TT_MINUS_TAI:.3}");
|
println!("# tt_minus_tai_seconds={TT_MINUS_TAI:.3}");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,15 @@
|
||||||
//! eccentricity, a retrograde inclination, a negative drag term, and a century
|
//! eccentricity, a retrograde inclination, a negative drag term, and a century
|
||||||
//! rollover in the two digit epoch year.
|
//! rollover in the two digit epoch year.
|
||||||
//!
|
//!
|
||||||
|
//! 写出本工作区从两行集解析出的根数字段。
|
||||||
|
//!
|
||||||
|
//! 输出是标准输出上的 CSV,带一行表头。它由
|
||||||
|
//! `validation/python/orbit/check_tle.py` 消费,后者用一个独立的、按列索引的
|
||||||
|
//! 读取器重新解析相同的集合、比较每个字段,并重算每行对十取模的校验和。
|
||||||
|
//!
|
||||||
|
//! 各集合包括随 SGP4 参考实现分发的历史测试用例,以及检验格式各角落的合成用例:
|
||||||
|
//! 偏心率带隐含前导零的圆轨道、逆行倾角、负阻力项,以及两位历元年份的世纪翻转。
|
||||||
|
//!
|
||||||
//! Usage:
|
//! Usage:
|
||||||
//!
|
//!
|
||||||
//! ```text
|
//! ```text
|
||||||
|
|
@ -22,10 +31,16 @@ use apsis_time::TimeScale;
|
||||||
use apsis_tle::{Classification, TwoLineElement, line_checksum};
|
use apsis_tle::{Classification, TwoLineElement, line_checksum};
|
||||||
|
|
||||||
/// One element set to parse, with a name for the report.
|
/// One element set to parse, with a name for the report.
|
||||||
|
///
|
||||||
|
/// 一个要解析的根数集,带一个用于报告的名称。
|
||||||
struct Sample {
|
struct Sample {
|
||||||
/// A name for the sample, so a failure in the report is readable.
|
/// A name for the sample, so a failure in the report is readable.
|
||||||
|
///
|
||||||
|
/// 样本的名称,使报告中的失败可读。
|
||||||
name: &'static str,
|
name: &'static str,
|
||||||
/// The two lines of the set, without a trailing carriage return.
|
/// The two lines of the set, without a trailing carriage return.
|
||||||
|
///
|
||||||
|
/// 该集合的两行,不带尾随回车。
|
||||||
lines: [&'static str; 2],
|
lines: [&'static str; 2],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -43,6 +58,12 @@ const fn sample(name: &'static str, first: &'static str, second: &'static str) -
|
||||||
/// the format: an implied leading zero in the eccentricity, a retrograde
|
/// the format: an implied leading zero in the eccentricity, a retrograde
|
||||||
/// inclination, a negative first derivative of the mean motion, a century
|
/// inclination, a negative first derivative of the mean motion, a century
|
||||||
/// rollover in the two digit epoch year, and a name line.
|
/// rollover in the two digit epoch year, and a name line.
|
||||||
|
///
|
||||||
|
/// 被解析的各根数集。
|
||||||
|
///
|
||||||
|
/// 前四个是随 SGP4 参考实现分发的历史测试用例。其余是合成的,覆盖格式的边缘:
|
||||||
|
/// 偏心率带隐含前导零、逆行倾角、平运动一阶导数为负、两位历元年份的世纪翻转,
|
||||||
|
/// 以及一个名称行。
|
||||||
const SAMPLES: &[Sample] = &[
|
const SAMPLES: &[Sample] = &[
|
||||||
sample(
|
sample(
|
||||||
"vanguard_1",
|
"vanguard_1",
|
||||||
|
|
@ -77,6 +98,8 @@ const SAMPLES: &[Sample] = &[
|
||||||
sample(
|
sample(
|
||||||
// A two digit year of 99 must expand to 1999, the last year of the
|
// A two digit year of 99 must expand to 1999, the last year of the
|
||||||
// twentieth century branch of the convention.
|
// twentieth century branch of the convention.
|
||||||
|
//
|
||||||
|
// 两位年份 99 必须展开为 1999,即该约定二十世纪分支的最后一年。
|
||||||
"two_digit_year_1999",
|
"two_digit_year_1999",
|
||||||
"1 10000U 99001A 99365.00000000 .00000000 00000-0 00000-0 0 05",
|
"1 10000U 99001A 99365.00000000 .00000000 00000-0 00000-0 0 05",
|
||||||
"2 10000 45.0000 10.0000 0001000 0.0000 0.0000 14.00000000 09",
|
"2 10000 45.0000 10.0000 0001000 0.0000 0.0000 14.00000000 09",
|
||||||
|
|
@ -93,6 +116,11 @@ const SAMPLES: &[Sample] = &[
|
||||||
/// The epoch field of an element set stores the day of the year and its
|
/// The epoch field of an element set stores the day of the year and its
|
||||||
/// fraction, so the year and month are combined back into a day of year
|
/// fraction, so the year and month are combined back into a day of year
|
||||||
/// before the fraction of the day is added.
|
/// before the fraction of the day is added.
|
||||||
|
///
|
||||||
|
/// 返回某日历日期在该年中的第几天,以小数表示。
|
||||||
|
///
|
||||||
|
/// 根数集的历元字段保存一年中的第几天及其零头,故年与月先合回一年中的第几天,
|
||||||
|
/// 再加上当日的零头。
|
||||||
fn day_of_year_fraction(year: i32, month: u32, day: u32) -> f64 {
|
fn day_of_year_fraction(year: i32, month: u32, day: u32) -> f64 {
|
||||||
use apsis_time::days_in_month;
|
use apsis_time::days_in_month;
|
||||||
let mut total = 0_u32;
|
let mut total = 0_u32;
|
||||||
|
|
@ -123,6 +151,9 @@ fn main() {
|
||||||
// The epoch is stored as a Modified Julian Date; the calendar form
|
// The epoch is stored as a Modified Julian Date; the calendar form
|
||||||
// is written so the reader can compare the year and the day of year
|
// is written so the reader can compare the year and the day of year
|
||||||
// against the two digit year and fraction the line encodes.
|
// against the two digit year and fraction the line encodes.
|
||||||
|
//
|
||||||
|
// 历元存为约化儒略日;写出日历形式,使读者可以把年与一年中的第几天对照该行
|
||||||
|
// 所编码的两位年份与零头。
|
||||||
let calendar = element
|
let calendar = element
|
||||||
.epoch
|
.epoch
|
||||||
.calendar(TimeScale::Utc)
|
.calendar(TimeScale::Utc)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue