Commit | Line | Data |
---|---|---|
cfe4f77b SK |
1 | -module(x_plane_datum). |
2 | ||
3 | -include("x_plane_datum_defaults.hrl"). | |
4 | -include("include/x_plane_data.hrl"). | |
5 | ||
6 | -export_type( | |
7 | [ t/0 | |
8 | , label/0 | |
9 | , anonymous/0 | |
10 | , identified/0 | |
11 | , parsing_error/0 | |
12 | ]). | |
13 | ||
14 | -export( | |
15 | [ of_bin/1 % Use default max index | |
16 | , of_bin/2 % Specify max index | |
17 | ]). | |
18 | ||
19 | -type parsing_error() :: | |
20 | {block_structure_invalid, binary()} | |
21 | | {block_index_byte_out_of_range, anonymous()} | |
22 | . | |
23 | ||
24 | -type anonymous() :: | |
25 | { non_neg_integer() | |
26 | , float() | |
27 | , float() | |
28 | , float() | |
29 | , float() | |
30 | , float() | |
31 | , float() | |
32 | , float() | |
33 | , float() | |
34 | }. | |
35 | ||
36 | -type label() :: | |
37 | speeds | |
38 | | pitch_roll_heading | |
39 | | lat_lon_alt | |
40 | . | |
41 | ||
42 | -type identified() :: | |
43 | #x_plane_datum_speeds{} | |
44 | | #x_plane_datum_pitch_roll_heading{} | |
45 | | #x_plane_datum_lat_lon_alt{} | |
46 | . | |
47 | ||
48 | -type t() :: | |
49 | {non_neg_integer() , anonymous()} | |
50 | | {label() , identified()} | |
51 | . | |
52 | ||
53 | -spec of_bin(binary()) -> | |
54 | hope_result:t(t(), parsing_error()). | |
55 | of_bin(<<Block/binary>>) -> | |
56 | of_bin(Block, ?DEFAULT_MAX_INDEX). | |
57 | ||
58 | -spec of_bin(binary(), non_neg_integer()) -> | |
59 | hope_result:t(t(), parsing_error()). | |
60 | of_bin(<<Block/binary>>, MaxIndex) -> | |
61 | case anonymous_of_bin(Block, MaxIndex) | |
62 | of {ok, Anonymous} -> | |
63 | IdentifiedOrIndexed = identify_or_index(Anonymous), | |
64 | {ok, IdentifiedOrIndexed} | |
65 | ; {error, _}=Error -> | |
66 | Error | |
67 | end. | |
68 | ||
69 | -spec anonymous_of_bin(binary(), non_neg_integer()) -> | |
70 | hope_result:t(anonymous(), parsing_error()). | |
71 | anonymous_of_bin( | |
72 | << Index:32/little-integer | |
73 | , V1:32/little-float | |
74 | , V2:32/little-float | |
75 | , V3:32/little-float | |
76 | , V4:32/little-float | |
77 | , V5:32/little-float | |
78 | , V6:32/little-float | |
79 | , V7:32/little-float | |
80 | , V8:32/little-float | |
81 | >>, | |
82 | MaxIndex | |
83 | ) -> | |
84 | Anonymous = {Index, V1, V2, V3, V4, V5, V6, V7, V8}, | |
85 | if Index > 0 andalso Index =< MaxIndex -> | |
86 | {ok, Anonymous} | |
87 | ; true -> | |
88 | {error, {block_index_byte_out_of_range, Anonymous}} | |
89 | end; | |
90 | anonymous_of_bin(<<Block/binary>>, _) -> | |
36501649 SK |
91 | % This case shouldn't be possible with a correct packet length, but we want |
92 | % to allow for possibility of using this module independently of it's | |
93 | % parent, data module. | |
cfe4f77b SK |
94 | {error, {block_structure_invalid, Block}}. |
95 | ||
96 | -spec identify_or_index(anonymous()) -> | |
97 | t(). | |
98 | identify_or_index({3, V1, V2, V3, V4, _, V6, V7, V8}) -> | |
99 | Datum = | |
100 | #x_plane_datum_speeds | |
101 | { vind_kias = V1 | |
102 | , vind_keas = V2 | |
103 | , vtrue_ktas = V3 | |
104 | , vtrue_ktgs = V4 | |
105 | ||
106 | , vind_mph = V6 | |
107 | , vtrue_mphas = V7 | |
108 | , vtrue_mphgs = V8 | |
109 | }, | |
110 | {speeds, Datum}; | |
111 | identify_or_index({17, V1, V2, V3, V4, _, _, _, _}) -> | |
112 | Datum = | |
113 | #x_plane_datum_pitch_roll_heading | |
114 | { pitch_deg = V1 | |
115 | , roll_deg = V2 | |
116 | , hding_true = V3 | |
117 | , hding_mag = V4 | |
118 | }, | |
119 | {pitch_roll_heading, Datum}; | |
120 | identify_or_index({20, V1, V2, V3, V4, V5, V6, V7, V8}) -> | |
121 | Datum = | |
122 | #x_plane_datum_lat_lon_alt | |
123 | { lat_deg = V1 | |
124 | , lon_deg = V2 | |
125 | , alt_ftmsl = V3 | |
126 | , alt_ftagl = V4 | |
127 | , on_runwy = V5 | |
128 | , alt_ind = V6 | |
129 | , lat_south = V7 | |
9101c998 | 130 | , lon_west = V8 |
cfe4f77b SK |
131 | }, |
132 | {lat_lon_alt, Datum}; | |
133 | identify_or_index({Index, _, _, _, _, _, _, _, _}=Anonymous) -> | |
134 | {Index, Anonymous}. |