The xplane_io (X-Plane I/O) program is used to establish network communications, via UDP, with the X-Plane flight simulator running on a computer. The code consists of class libraries that abstract the lower-level UDP packet encoding and decoding details, according to the UDP protocol specifications in X-Plane version 9. Any X-Plane DATA packets can be sent and received, and any X-Plane DataRefs can be set by sending DREF packets to X-Plane.
Dependencies: EthernetNetIf mbed ConfigFile
XPlaneIO/XPlaneIO.h@0:a5d13af495af, 2011-12-21 (annotated)
- Committer:
- bapowell
- Date:
- Wed Dec 21 22:29:59 2011 +0000
- Revision:
- 0:a5d13af495af
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
bapowell | 0:a5d13af495af | 1 | #ifndef XPLANEIO_H_INCLUDED |
bapowell | 0:a5d13af495af | 2 | #define XPLANEIO_H_INCLUDED |
bapowell | 0:a5d13af495af | 3 | |
bapowell | 0:a5d13af495af | 4 | #include <queue> |
bapowell | 0:a5d13af495af | 5 | #include "mbed.h" |
bapowell | 0:a5d13af495af | 6 | #include "EthernetNetIf.h" |
bapowell | 0:a5d13af495af | 7 | #include "UDPSocket.h" |
bapowell | 0:a5d13af495af | 8 | #include "XPlaneUdpDATA.h" |
bapowell | 0:a5d13af495af | 9 | #include "XPlaneUdpDecoder.h" |
bapowell | 0:a5d13af495af | 10 | #include "XPlaneUdpEncoder.h" |
bapowell | 0:a5d13af495af | 11 | #include "XPlaneAnalogIn.h" |
bapowell | 0:a5d13af495af | 12 | |
bapowell | 0:a5d13af495af | 13 | #define UDP_RECV_BUFFER_SIZE 512 |
bapowell | 0:a5d13af495af | 14 | #define UDP_SEND_BUFFER_SIZE 512 |
bapowell | 0:a5d13af495af | 15 | |
bapowell | 0:a5d13af495af | 16 | /** |
bapowell | 0:a5d13af495af | 17 | * XPlaneIO is used to establish networked communication with X-Plane. |
bapowell | 0:a5d13af495af | 18 | * Methods in this class allow the the client to send data to X-Plane as well as |
bapowell | 0:a5d13af495af | 19 | * read data that has been sent from X-Plane. |
bapowell | 0:a5d13af495af | 20 | */ |
bapowell | 0:a5d13af495af | 21 | |
bapowell | 0:a5d13af495af | 22 | class XPlaneIO { |
bapowell | 0:a5d13af495af | 23 | public: |
bapowell | 0:a5d13af495af | 24 | |
bapowell | 0:a5d13af495af | 25 | //XPlaneIO(); |
bapowell | 0:a5d13af495af | 26 | ~XPlaneIO(); |
bapowell | 0:a5d13af495af | 27 | |
bapowell | 0:a5d13af495af | 28 | /** |
bapowell | 0:a5d13af495af | 29 | * Read configuration file and initialize. |
bapowell | 0:a5d13af495af | 30 | */ |
bapowell | 0:a5d13af495af | 31 | bool setup(char * configFilename, Ethernet * ethernet); |
bapowell | 0:a5d13af495af | 32 | |
bapowell | 0:a5d13af495af | 33 | /** |
bapowell | 0:a5d13af495af | 34 | * Check if user wants to perform interactive XPlaneIO diagnostics. If so, enter diagnostics mode. |
bapowell | 0:a5d13af495af | 35 | */ |
bapowell | 0:a5d13af495af | 36 | void diagnostics(Serial & serialInOut); |
bapowell | 0:a5d13af495af | 37 | |
bapowell | 0:a5d13af495af | 38 | /** |
bapowell | 0:a5d13af495af | 39 | * Include a DATA message, of the given index, in the UDP map -- for receiving from X-Plane. |
bapowell | 0:a5d13af495af | 40 | * If a message of the given index already exists in the map, then do nothing. |
bapowell | 0:a5d13af495af | 41 | * Returns true if a new DATA message was created and added to the map. |
bapowell | 0:a5d13af495af | 42 | */ |
bapowell | 0:a5d13af495af | 43 | bool addDATAToReceive(int msgIndex); |
bapowell | 0:a5d13af495af | 44 | |
bapowell | 0:a5d13af495af | 45 | /** |
bapowell | 0:a5d13af495af | 46 | * Include a DATA message, of the given index, in the UDP map -- for sending to X-Plane. |
bapowell | 0:a5d13af495af | 47 | * If a message of the given index already exists in the map, then do nothing. |
bapowell | 0:a5d13af495af | 48 | * Returns true if a new DATA message was created and added to the map. |
bapowell | 0:a5d13af495af | 49 | */ |
bapowell | 0:a5d13af495af | 50 | bool addDATAToSend(int msgIndex); |
bapowell | 0:a5d13af495af | 51 | |
bapowell | 0:a5d13af495af | 52 | /** |
bapowell | 0:a5d13af495af | 53 | * Return a pointer to the DATA message, of the given index, in the UDP receive map (data received from X-Plane). |
bapowell | 0:a5d13af495af | 54 | * If a message of the given index does not exist in the map, then return NULL. |
bapowell | 0:a5d13af495af | 55 | */ |
bapowell | 0:a5d13af495af | 56 | XPlaneUdpDATA * getReceiveDATA(int msgIndex) const; |
bapowell | 0:a5d13af495af | 57 | |
bapowell | 0:a5d13af495af | 58 | /** |
bapowell | 0:a5d13af495af | 59 | * Return a pointer to the DATA message, of the given index, in the UDP send map (data to send to X-Plane). |
bapowell | 0:a5d13af495af | 60 | * If a message of the given index does not exist in the map, then return NULL. |
bapowell | 0:a5d13af495af | 61 | */ |
bapowell | 0:a5d13af495af | 62 | XPlaneUdpDATA * getSendDATA(int msgIndex) const; |
bapowell | 0:a5d13af495af | 63 | |
bapowell | 0:a5d13af495af | 64 | /** |
bapowell | 0:a5d13af495af | 65 | * Return the float data value, of the given DATA message index, at the given float index (0-7), in the UDP receive map (data received from X-Plane). |
bapowell | 0:a5d13af495af | 66 | * If a message of the given index does not exist in the map, then return -999.999f. |
bapowell | 0:a5d13af495af | 67 | */ |
bapowell | 0:a5d13af495af | 68 | float getReceiveDATAValue(int msgIndex, int floatIndex) const; |
bapowell | 0:a5d13af495af | 69 | |
bapowell | 0:a5d13af495af | 70 | /** |
bapowell | 0:a5d13af495af | 71 | * Set the float data value, of the given DATA message index, at the given float index (0-7), in the UDP send map (data to send to X-Plane). |
bapowell | 0:a5d13af495af | 72 | * If a message of the given index does not exist in the map, then do nothing. |
bapowell | 0:a5d13af495af | 73 | */ |
bapowell | 0:a5d13af495af | 74 | void setSendDATAValue(int msgIndex, int floatIndex, float f); |
bapowell | 0:a5d13af495af | 75 | |
bapowell | 0:a5d13af495af | 76 | /** |
bapowell | 0:a5d13af495af | 77 | * Add an X-Plane DataRef to the queue -- to be sent the next time the |
bapowell | 0:a5d13af495af | 78 | * sendUdp() ticker function is called. |
bapowell | 0:a5d13af495af | 79 | */ |
bapowell | 0:a5d13af495af | 80 | void sendDREF(XPlaneUdpDREF & dref); |
bapowell | 0:a5d13af495af | 81 | |
bapowell | 0:a5d13af495af | 82 | /** |
bapowell | 0:a5d13af495af | 83 | * Start sending UDP data to X-Plane. |
bapowell | 0:a5d13af495af | 84 | */ |
bapowell | 0:a5d13af495af | 85 | void startSendingUdp(); |
bapowell | 0:a5d13af495af | 86 | |
bapowell | 0:a5d13af495af | 87 | /** |
bapowell | 0:a5d13af495af | 88 | * Stop sending UDP data to X-Plane. |
bapowell | 0:a5d13af495af | 89 | */ |
bapowell | 0:a5d13af495af | 90 | void stopSendingUdp(); |
bapowell | 0:a5d13af495af | 91 | |
bapowell | 0:a5d13af495af | 92 | /** |
bapowell | 0:a5d13af495af | 93 | * Utility method to send data via the UDPSocket to the sendHost. |
bapowell | 0:a5d13af495af | 94 | */ |
bapowell | 0:a5d13af495af | 95 | int udpSocketSend(char * buf, int len); |
bapowell | 0:a5d13af495af | 96 | |
bapowell | 0:a5d13af495af | 97 | // Accessors |
bapowell | 0:a5d13af495af | 98 | bool debug() const; |
bapowell | 0:a5d13af495af | 99 | bool reverseByteOrder() const; |
bapowell | 0:a5d13af495af | 100 | XPlaneUdpDATAMap & recvDATAMap(); |
bapowell | 0:a5d13af495af | 101 | XPlaneUdpDATAMap & sendDATAMap(); |
bapowell | 0:a5d13af495af | 102 | |
bapowell | 0:a5d13af495af | 103 | private: |
bapowell | 0:a5d13af495af | 104 | |
bapowell | 0:a5d13af495af | 105 | bool _debug; |
bapowell | 0:a5d13af495af | 106 | bool _debugVerbose; |
bapowell | 0:a5d13af495af | 107 | |
bapowell | 0:a5d13af495af | 108 | //Serial & _serialInOut; |
bapowell | 0:a5d13af495af | 109 | |
bapowell | 0:a5d13af495af | 110 | EthernetNetIf * _eth; // pointer, because don't want instantiated until gather config for it |
bapowell | 0:a5d13af495af | 111 | |
bapowell | 0:a5d13af495af | 112 | // Set up local and remote hosts. |
bapowell | 0:a5d13af495af | 113 | Host _recvHost; // mbed local host |
bapowell | 0:a5d13af495af | 114 | Host _sendHost; // IP address and port to which UDP will be sent |
bapowell | 0:a5d13af495af | 115 | |
bapowell | 0:a5d13af495af | 116 | // UDP socket to use for both binding to local address (to recv data) and to send data to remote host. |
bapowell | 0:a5d13af495af | 117 | UDPSocket _udpSocket; |
bapowell | 0:a5d13af495af | 118 | |
bapowell | 0:a5d13af495af | 119 | int _sendInterval; // milliseconds |
bapowell | 0:a5d13af495af | 120 | Ticker _sendTicker; |
bapowell | 0:a5d13af495af | 121 | |
bapowell | 0:a5d13af495af | 122 | bool _reverseByteOrder; |
bapowell | 0:a5d13af495af | 123 | |
bapowell | 0:a5d13af495af | 124 | XPlaneUdpDATAMap _recvDATAMap; // keyed by DATA message index |
bapowell | 0:a5d13af495af | 125 | XPlaneUdpDATAMap _sendDATAMap; // keyed by DATA message index |
bapowell | 0:a5d13af495af | 126 | |
bapowell | 0:a5d13af495af | 127 | queue<XPlaneUdpDREF> _sendDREFQueue; |
bapowell | 0:a5d13af495af | 128 | |
bapowell | 0:a5d13af495af | 129 | char _udpRecvBuffer[UDP_RECV_BUFFER_SIZE]; |
bapowell | 0:a5d13af495af | 130 | XPlaneUdpDecoder _udpDecoder; |
bapowell | 0:a5d13af495af | 131 | |
bapowell | 0:a5d13af495af | 132 | char _udpSendBuffer[UDP_SEND_BUFFER_SIZE]; |
bapowell | 0:a5d13af495af | 133 | XPlaneUdpEncoder _udpEncoder; |
bapowell | 0:a5d13af495af | 134 | |
bapowell | 0:a5d13af495af | 135 | XPlaneAnalogIn * _xpAnalogIn[6]; |
bapowell | 0:a5d13af495af | 136 | int _xpAnalogInCount; |
bapowell | 0:a5d13af495af | 137 | |
bapowell | 0:a5d13af495af | 138 | /** |
bapowell | 0:a5d13af495af | 139 | * Callback handler for when UDP data has been received. |
bapowell | 0:a5d13af495af | 140 | * Note that this handler is assigned within the setup() method. |
bapowell | 0:a5d13af495af | 141 | */ |
bapowell | 0:a5d13af495af | 142 | void onUDPSocketEvent(UDPSocketEvent e); |
bapowell | 0:a5d13af495af | 143 | |
bapowell | 0:a5d13af495af | 144 | /** |
bapowell | 0:a5d13af495af | 145 | * Ticker function for sending UDP data. |
bapowell | 0:a5d13af495af | 146 | */ |
bapowell | 0:a5d13af495af | 147 | void sendUdp(); |
bapowell | 0:a5d13af495af | 148 | |
bapowell | 0:a5d13af495af | 149 | /** |
bapowell | 0:a5d13af495af | 150 | * Poll analog inputs, and... |
bapowell | 0:a5d13af495af | 151 | */ |
bapowell | 0:a5d13af495af | 152 | void pollAnalogIn(); |
bapowell | 0:a5d13af495af | 153 | }; |
bapowell | 0:a5d13af495af | 154 | |
bapowell | 0:a5d13af495af | 155 | #endif // XPLANEIO_H_INCLUDED |
bapowell | 0:a5d13af495af | 156 | |
bapowell | 0:a5d13af495af | 157 | |
bapowell | 0:a5d13af495af | 158 | |
bapowell | 0:a5d13af495af | 159 | /* Config file: |
bapowell | 0:a5d13af495af | 160 | |
bapowell | 0:a5d13af495af | 161 | debug=Y |
bapowell | 0:a5d13af495af | 162 | debugVerbose=N |
bapowell | 0:a5d13af495af | 163 | |
bapowell | 0:a5d13af495af | 164 | # If mbed_ip_address is not specified, then DHCP will be used. |
bapowell | 0:a5d13af495af | 165 | mbed_ip_address=192 168 10 202 |
bapowell | 0:a5d13af495af | 166 | mbed_ip_netmask=255 255 255 0 |
bapowell | 0:a5d13af495af | 167 | mbed_ip_gateway=192 168 10 99 |
bapowell | 0:a5d13af495af | 168 | mbed_ip_dnssrvr=192 168 10 99 |
bapowell | 0:a5d13af495af | 169 | |
bapowell | 0:a5d13af495af | 170 | # Ethernet link mode: 0 = AutoNegotiate, 1 = HalfDuplex10, 2 = FullDuplex10, 3 = HalfDuplex100, 4 = FullDuplex100 |
bapowell | 0:a5d13af495af | 171 | # Note that AutoNegotiate does not work for 10 Mbit hub. e.g. Use 2 (FullDuplex10) for 10 Mbit hub that does not auto-detect speed. |
bapowell | 0:a5d13af495af | 172 | ethernet_link_mode=0 |
bapowell | 0:a5d13af495af | 173 | |
bapowell | 0:a5d13af495af | 174 | # Local IP port to bind to. X-Plane should be configured to send data to the mbed_ip_address and this port. |
bapowell | 0:a5d13af495af | 175 | recv_port=49000 |
bapowell | 0:a5d13af495af | 176 | |
bapowell | 0:a5d13af495af | 177 | # IP address and port to which UDP data will be sent. |
bapowell | 0:a5d13af495af | 178 | xplane_ip_address=192 168 10 106 |
bapowell | 0:a5d13af495af | 179 | xplane_ip_port=49000 |
bapowell | 0:a5d13af495af | 180 | |
bapowell | 0:a5d13af495af | 181 | # Interval (milliseconds) for sending UDP data to X-Plane. |
bapowell | 0:a5d13af495af | 182 | send_interval=250 |
bapowell | 0:a5d13af495af | 183 | |
bapowell | 0:a5d13af495af | 184 | # Depending on X-Plane host computer (e.g Mac), byte order in UDP packets may need to be reversed. |
bapowell | 0:a5d13af495af | 185 | reverse_byte_order=N |
bapowell | 0:a5d13af495af | 186 | |
bapowell | 0:a5d13af495af | 187 | # Analog Inputs - for sending an analog value to X-Plane. Up to six are supported (# = 1-6). |
bapowell | 0:a5d13af495af | 188 | # ain_#_pin : AnalogIn pin number, 15-20 (p15-20) |
bapowell | 0:a5d13af495af | 189 | # ain_#_scale1 : Scale range 1: input_from input_to output_from output_to |
bapowell | 0:a5d13af495af | 190 | # Note: A gap between range1's input_to and range2's input_from will be seen as deadband; no data will be sent to X-Plane in that case. |
bapowell | 0:a5d13af495af | 191 | # ain_#_scale2 : Scale range 2: input_from input_to output_from output_to |
bapowell | 0:a5d13af495af | 192 | # ain_#_msg_idx : X-Plane DATA message: message index |
bapowell | 0:a5d13af495af | 193 | # ain_#_float_idx : X-Plane DATA message: float index (0-7) within the message |
bapowell | 0:a5d13af495af | 194 | |
bapowell | 0:a5d13af495af | 195 | # Analog Input #1: |
bapowell | 0:a5d13af495af | 196 | ain_1_pin=20 |
bapowell | 0:a5d13af495af | 197 | ain_1_scale1=0.525 0.610 1.0 0.0 |
bapowell | 0:a5d13af495af | 198 | ain_1_scale2=0.615 0.910 0.0 -1.0 |
bapowell | 0:a5d13af495af | 199 | ain_1_msg_idx=8 |
bapowell | 0:a5d13af495af | 200 | ain_1_float_idx=1 |
bapowell | 0:a5d13af495af | 201 | |
bapowell | 0:a5d13af495af | 202 | # Analog Input #2: |
bapowell | 0:a5d13af495af | 203 | ain_2_pin=19 |
bapowell | 0:a5d13af495af | 204 | ain_2_scale1=0.520 0.605 1.0 0.0 |
bapowell | 0:a5d13af495af | 205 | ain_2_scale2=0.615 0.920 0.0 -1.0 |
bapowell | 0:a5d13af495af | 206 | ain_2_msg_idx=8 |
bapowell | 0:a5d13af495af | 207 | ain_2_float_idx=0 |
bapowell | 0:a5d13af495af | 208 | |
bapowell | 0:a5d13af495af | 209 | # Analog Input #3: |
bapowell | 0:a5d13af495af | 210 | ain_3_pin=17 |
bapowell | 0:a5d13af495af | 211 | ain_3_scale1=0.510 0.615 1.0 0.0 |
bapowell | 0:a5d13af495af | 212 | ain_3_scale2=0.620 0.915 0.0 -1.0 |
bapowell | 0:a5d13af495af | 213 | ain_3_msg_idx=8 |
bapowell | 0:a5d13af495af | 214 | ain_3_float_idx=2 |
bapowell | 0:a5d13af495af | 215 | |
bapowell | 0:a5d13af495af | 216 | |
bapowell | 0:a5d13af495af | 217 | # X-Plane DATA |
bapowell | 0:a5d13af495af | 218 | # MsgIdx 8 : 0=elev, 1=ailrn, 2=ruddr |
bapowell | 0:a5d13af495af | 219 | # MsgIdx 13 : 0=elev trim, 1=ailrn trim, 2=ruddr trim, 3=flap handl, 4=flap postn, 5=slat ratio, 6=sbrak handl, 7=sbrak postn |
bapowell | 0:a5d13af495af | 220 | # MsgIdx 25 : 0=throttle command |
bapowell | 0:a5d13af495af | 221 | # MsgIdx 26 : 0=throttle actual |
bapowell | 0:a5d13af495af | 222 | |
bapowell | 0:a5d13af495af | 223 | */ |