X-Plane UDP data parser
=======================
-Example
--------
+Examples
+--------
+
+### Receive data packet
```erlang
--include_lib("include/x_plane_data.hrl").
+{ok, Socket} = gen_udp:open(Port, [binary, {active, false}]),
+{ok, {_, _, <<XPlaneDataPacket/binary>>}} = gen_udp:recv(Socket, 0),
+```
-main(Port) ->
- {ok, Socket} = gen_udp:open(Port, [binary, {active, false}]),
- {ok, {_, _, <<XPlaneDataPacket/binary>>}} = gen_udp:recv(Socket, 0),
- {ok, XPlaneData} = x_plane_data:of_bin(XPlaneDataPacket),
+### Parse data packet
- % Currently there're 133 possible data types sent by X-Plane 10, of which
- % I've identified and labeled only some of. See x_plane_datum:t() type for
- % what is currently labeled.
- % The types I've not yet labeled are in the format specified by
- % x_plane_datum:anonymous() and can be looked-up by their index number.
+```erlang
+{ok, {64=Index, GroupsRaw}=DataRaw} = x_plane_data_raw:of_bin(XPlaneDataPacket),
+```
- % Find a labeled data type
- {some, #x_plane_datum_speeds{}} = hope_kv_list:get(XPlaneData, speeds),
- {some, #x_plane_datum_pitch_roll_heading{}} = hope_kv_list:get(XPlaneData, pitch_roll_heading),
- {some, #x_plane_datum_lat_lon_alt{}} = hope_kv_list:get(XPlaneData, lat_lon_alt),
+### Access parsed data
- % Find an unlabled data type
- {some, {10, V1, V2, V3, V4, V5, V6, V7, V8}} = hope_kv_list:get(XPlaneData, 10),
+#### Raw
- % Attempt to find a data type that was not included in current packet
- none = hope_kv_list:get(XPlaneData, 130),
- none = hope_kv_list:get(XPlaneData, 67),
+At this stage, only the structure of the packet was parsed. No attempt at
+interpreting the values have been made:
- ...
+```erlang
+% Speeds are in group 3
+{3, Speeds} = lists:keyfind(3, 1, GroupsRaw),
+{ VindKias
+, VindKeas
+, VtrueKtas
+, VtrueKtgs
+, _
+, VindMph
+, VtrueMphas
+, VtrueMphgs
+} = Speeds,
+
+% Pitch roll and headings values are in group 17
+{17, PitchRollHeadings} = lists:keyfind(17, 1, GroupsRaw),
+{ PitchDeg
+, RollDeg
+, HdingTrue
+, HdingMag
+, _
+, _
+, _
+, _
+} = PitchRollHeadings,
```
-Note: you can, of course, use any other method to search a `[{K, V}]` list
-(which is how `x_plane_data:t()` is structured), such as:
-`proplists:get_value/2`, `lists:keyfind/3`, etc., but I prefer the API of
-`hope_kv_list`, so I used that.
+#### Named
+
+Here we identify what each of the numbered groups mean in a given X-Plane
+version. Right now only X-Plane 10 (packet index 64) is supported and I only
+identified 3 groups so far:
+
+| packet index | group index | group name |
+|--------------|-------------|----------------------|
+| 64 | 3 | `speeds` |
+| 64 | 17 | `pitch_roll_heading` |
+| 64 | 20 | `lat_lon_alt` |
+
+Unidentified groups (with index other than what is listed above) will be
+absent from the list of named groups (think of `x_plane_data_named:of_raw/1` as
+a filter), so you'll have to access their raw version, if needed.
+##### Identify
+```erlang
+{ok, {x_plane_data_v10, GroupsNamed}} = x_plane_data_named:of_raw(DataRaw),
+```
+
+##### Access
+```erlang
+-include_lib("x_plane_data/include/x_plane_data_group_lat_lon_alt.hrl").
+-include_lib("x_plane_data/include/x_plane_data_group_pitch_roll_heading.hrl").
+-include_lib("x_plane_data/include/x_plane_data_group_speeds.hrl").
+
+...
+
+{speeds, #x_plane_data_group_speeds
+ { vind_kias = VindKias
+ , vind_keas = VindKeas
+ , vtrue_ktas = VtrueKtas
+ , vtrue_ktgs = VtrueKtgs
+ , vind_mph = VindMph
+ , vtrue_mphas = VtrueMphas
+ , vtrue_mphgs = VtrueMphgs
+ }
+} = lists:keyfind(speeds, 1, GroupsNamed),
+
+{pitch_roll_heading, #x_plane_data_group_pitch_roll_heading
+ { pitch_deg = PitchDeg
+ , roll_deg = RollDeg
+ , hding_true = HdingTrue
+ , hding_mag = HdingMag
+ }
+} = lists:keyfind(pitch_roll_heading, 1, GroupsNamed),
+```
Data format references
----------------------