flightplanner/
flightplanner.rs1use std::collections::HashMap;
17
18use efb::error::Result;
19use efb::nd::{RunwayConditionCode, RunwaySurface};
20use efb::prelude::*;
21use efb::*;
22
23const ARINC_424_RECORDS: &'static [u8] = br#"
24SEURP EDDHEDA 0 N N53374900E009591762E002000053 P MWGE HAMBURG 356462409
25SEURP EDDHEDGRW05 0106630500 N53371100E009580180 151 124362502
26SEURP EDDHEDGRW23 0106632300 N53380900E009595876 151 124362502
27SEURP EDDHEDGRW15 0120271530 N53391500E009583076 151 124362502
28SEURP EDDHEDGRW33 0120273330 N53374300E009595081 151 124362502
29SEURPCEDDHED N1 ED0 V N53482105E010015451 WGE NOVEMBER1 359892409
30SEURPCEDDHED N2 ED0 V N53405701E010000576 WGE NOVEMBER2 359902409
31SEURP EDHFEDA 0 N N53593300E009343600E000000082 P MWGE ITZEHOE/HUNGRIGER WOLF 320782409
32SEURP EDHFEDGRW02 0034120260 N53591751E009342331 098 120792502
33SEURP EDHFEDGRW20 0034122060 N53594752E009344856 098 120792502
34SEURP EDHFEDGRW09 0023230910 N53592877E009335932 131 120792502
35SEURP EDHFEDGRW27 0023232710 N53592838E009344247 131 120792502
36"#;
37
38fn main() -> Result<()> {
39 let perf = Performance::from_fn(
42 |vd| {
43 let tas = if *vd >= VerticalDistance::Altitude(10000) {
44 Speed::kt(114.0)
45 } else if *vd >= VerticalDistance::Altitude(8000) {
46 Speed::kt(112.0)
47 } else if *vd >= VerticalDistance::Altitude(6000) {
48 Speed::kt(110.0)
49 } else if *vd >= VerticalDistance::Altitude(4000) {
50 Speed::kt(109.0)
51 } else {
52 Speed::kt(107.0)
53 };
54
55 let ff = FuelFlow::PerHour(diesel!(Volume::l(21.0)));
56
57 (tas, ff)
58 },
59 VerticalDistance::Altitude(10000),
62 );
63
64 let takeoff_perf = TakeoffLandingPerformance::builder(vec![
65 (
66 VerticalDistance::PressureAltitude(0),
67 Temperature::c(0.0),
68 Length::ft(845.0),
69 Length::ft(1510.0),
70 ),
71 (
72 VerticalDistance::PressureAltitude(0),
73 Temperature::c(10.0),
74 Length::ft(910.0),
75 Length::ft(1625.0),
76 ),
77 (
78 VerticalDistance::PressureAltitude(0),
79 Temperature::c(20.0),
80 Length::ft(980.0),
81 Length::ft(1745.0),
82 ),
83 (
84 VerticalDistance::PressureAltitude(0),
85 Temperature::c(30.0),
86 Length::ft(1055.0),
87 Length::ft(1875.0),
88 ),
89 (
90 VerticalDistance::PressureAltitude(0),
91 Temperature::c(40.0),
92 Length::ft(1135.0),
93 Length::ft(2015.0),
94 ),
95 ])
96 .factors(vec![
97 AlteringFactor::DecreaseHeadwind(FactorOfEffect::Rate {
101 numerator: 0.1,
102 denominator: Speed::kt(9.0),
103 }),
104 AlteringFactor::IncreaseTailwind(FactorOfEffect::Rate {
105 numerator: 0.1,
106 denominator: Speed::kt(2.0),
107 }),
108 AlteringFactor::IncreaseRWYCC(HashMap::from([
111 ((None, Some(RunwaySurface::Grass)), 0.15), ])),
113 ])
114 .build();
115
116 let aircraft = Aircraft::builder()
117 .registration("N12345".to_string())
118 .stations(vec![
119 Station::new(Length::m(0.94), Some(String::from("front seats"))),
120 Station::new(Length::m(1.85), Some(String::from("back seats"))),
121 Station::new(
122 Length::m(2.41),
123 Some(String::from("first cargo compartment")),
124 ),
125 Station::new(
126 Length::m(3.12),
127 Some(String::from("second cargo compartment")),
128 ),
129 ])
130 .empty_mass(Mass::kg(807.0))
131 .empty_balance(Length::m(1.0))
132 .fuel_type(FuelType::Diesel)
133 .tanks(vec![FuelTank::new(Volume::l(168.8), Length::m(1.22))])
134 .cg_envelope(vec![
135 CGLimit::new(Mass::kg(0.0), Length::m(0.89)),
136 CGLimit::new(Mass::kg(885.0), Length::m(0.89)),
137 CGLimit::new(Mass::kg(1111.0), Length::m(1.02)),
138 CGLimit::new(Mass::kg(1111.0), Length::m(1.20)),
139 CGLimit::new(Mass::kg(0.0), Length::m(1.20)),
140 ])
141 .build()
142 .expect("all required aircraft parameter should be configured");
143
144 let mut fms = FMS::new();
145
146 let ed_nd = NavigationData::try_from_arinc424(ARINC_424_RECORDS)?;
148
149 fms.modify_nd(|nd| nd.append(ed_nd))?;
150
151 fms.decode("29020KT N0107 A0250 EDDH33 N2 N1 DCT EDHF20".to_string())?;
155
156 let mut builder = FlightPlanning::builder();
159
160 builder
161 .aircraft(aircraft)
162 .mass(vec![
163 Mass::kg(80.0),
165 Mass::kg(0.0),
167 Mass::kg(0.0),
168 Mass::kg(0.0),
169 ])
170 .policy(FuelPolicy::ManualFuel(diesel!(Volume::l(80.0))))
171 .taxi(diesel!(Volume::l(10.0)))
172 .reserve(Reserve::Manual(Duration::s(1800))) .perf(perf)
174 .takeoff_perf(takeoff_perf)
175 .origin_rwycc(RunwayConditionCode::Six)
177 .origin_temperature(Temperature::c(20.0));
178
179 fms.set_flight_planning(builder)?;
180
181 println!("{}", fms.print(40));
182
183 Ok(())
184}