More python!
This commit is contained in:
committed by
Jason Watkins
parent
b6233ab5d7
commit
04897b878e
@@ -1,4 +1,5 @@
|
|||||||
import socket
|
import socket
|
||||||
|
import struct
|
||||||
|
|
||||||
class XPlaneConnect:
|
class XPlaneConnect:
|
||||||
'''XPlaneConnect (XPC) facilitates communication to and from the XPCPlugin.'''
|
'''XPlaneConnect (XPC) facilitates communication to and from the XPCPlugin.'''
|
||||||
@@ -24,79 +25,192 @@ class XPlaneConnect:
|
|||||||
self.socket.bind(server)
|
self.socket.bind(server)
|
||||||
|
|
||||||
# Set timeout
|
# Set timeout
|
||||||
timeout_ms = 500
|
timeout_us = 500
|
||||||
self.socket.settimeout(timeout_ms / 1000)
|
self.socket.settimeout(timeout_ms / 1000000)
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
self.close()
|
self.close()
|
||||||
|
|
||||||
def close():
|
def close(self):
|
||||||
'''Closes the underlying UDP socket'''
|
'''Closes the underlying UDP socket'''
|
||||||
if self.socket is not None:
|
if self.socket is not None:
|
||||||
self.socket.close()
|
self.socket.close()
|
||||||
self.socket = None
|
self.socket = None
|
||||||
|
|
||||||
def send_udp(msg):
|
def send_udp(self, msg):
|
||||||
pass
|
'''Sends a message over the underlying UDP socket.'''
|
||||||
|
msg_len = len(msg)
|
||||||
|
msg[4] = msg_len
|
||||||
|
|
||||||
def read_udp():
|
# Preconditions
|
||||||
pass
|
if(msg_len <= 0): # Require message length greater than 0.
|
||||||
|
raise RuntimeError("send_udp: message length must be psoitive >0")
|
||||||
|
|
||||||
|
# Code
|
||||||
|
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) # TODO: Why?
|
||||||
|
|
||||||
|
self.socket.send(msg)
|
||||||
|
|
||||||
|
def read_udp(self, recv_addr = None):
|
||||||
|
if recv_addr is None:
|
||||||
|
recv_addr = (self.xp_ip, self.xp_port)
|
||||||
|
|
||||||
|
return self.socket.recv(5000) # TODO: Validate that this matches the behavior of the C version
|
||||||
|
|
||||||
# Configuration
|
# Configuration
|
||||||
def set_conn(rec_port):
|
def set_conn(self, rec_port):
|
||||||
pass
|
msg = struct.pack("!4sH", ("CONN", rec_port))
|
||||||
|
self.send_udp(msg)
|
||||||
|
|
||||||
def pause_sim(state):
|
def pause_sim(self, pause):
|
||||||
pass
|
'''Pauses or unpauses the X-Plane simulation'''
|
||||||
|
pause_val = 0
|
||||||
|
if pause:
|
||||||
|
pause_val = 1
|
||||||
|
|
||||||
|
msg = struct.pack("4sBB", ("SIMU", pause_val, 0))
|
||||||
|
self.send_udp(msg)
|
||||||
|
|
||||||
# UDP Data
|
# UDP Data
|
||||||
def parse_data(msg, dataRef):
|
def parse_data(self, data):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def read_data(msg, dataRef):
|
def read_data(self):
|
||||||
pass
|
buf = self.read_udp()
|
||||||
|
if buf[0] != 0:
|
||||||
|
return self.parse_data(buf)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
def send_data(msg, dataRef, rows):
|
def send_data(self, dataRef):
|
||||||
pass
|
'''Sends X-Plane data over the underlying UDP socket.'''
|
||||||
|
msg = struct.pack("4s", "DATA")
|
||||||
|
for row in dataRef:
|
||||||
|
struct.pack_into("!I", msg, len(msg), row[0])
|
||||||
|
for i in range(8):
|
||||||
|
struct.pack_into("!f", msg, len(msg), row[1][i])
|
||||||
|
self.send_udp(msg)
|
||||||
|
|
||||||
# Position
|
# Position
|
||||||
def parse_pos(msg, resultArray, gear):
|
def parse_pos(self, data):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def read_pos(resultArray, gear):
|
def read_pos(self, resultArray, gear):
|
||||||
pass
|
buf = self.read_udp()
|
||||||
|
if buf[0] != 0:
|
||||||
|
return self.parse_pos(buf)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
def send_pos(ACNum, numArgs, valueArray):
|
def send_pos(self, ac_num, values):
|
||||||
pass
|
# Preconditions
|
||||||
|
if len(values) < 1:
|
||||||
|
raise RuntimeError("send_pos: Must have at least one argument")
|
||||||
|
|
||||||
|
# Header and Aircraft num
|
||||||
|
msg = struct.pack("!4sB", ("POSI", ac_num))
|
||||||
|
|
||||||
|
# States
|
||||||
|
for i in range(7):
|
||||||
|
val = -998.5 # TODO: Why?
|
||||||
|
if i < len(values):
|
||||||
|
val = values[i]
|
||||||
|
struct.pack_into("!f", msg, len(msg), val)
|
||||||
|
|
||||||
|
# Send
|
||||||
|
self.send_udp(msg)
|
||||||
|
#}
|
||||||
# Controls
|
# Controls
|
||||||
def parse_ctrl(msg, resultArray, gear):
|
def parse_ctrl(self, data):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def read_ctrol(resultArray, gear):
|
def read_ctrol(self, resultArray, gear):
|
||||||
pass
|
buf = self.read_udp()
|
||||||
|
if buf[0] != 0:
|
||||||
|
return self.parse_ctrl(buf)
|
||||||
|
else:
|
||||||
|
return float("NaN")
|
||||||
|
|
||||||
def send_pos(numArgs, valueArray):
|
def send_ctrol(self, values):
|
||||||
pass
|
# Preconditions
|
||||||
|
if len(values) < 1:
|
||||||
|
raise RuntimeError("send_ctrl: Must have at least one argument")
|
||||||
|
|
||||||
|
# Header
|
||||||
|
msg = struct.pack("!4s", "CTRL")
|
||||||
|
|
||||||
|
# States
|
||||||
|
for i in range(6):
|
||||||
|
val = -998.5 # TODO: Why?
|
||||||
|
if i < len(values):
|
||||||
|
val = values[i]
|
||||||
|
struct.pack_into("!f", msg, len(msg), val)
|
||||||
|
|
||||||
|
# Send
|
||||||
|
self.send_udp(msg)
|
||||||
|
|
||||||
# DREF Manipulation
|
# DREF Manipulation
|
||||||
def read_dref(resultArray):
|
def read_dref(self, resultArray):
|
||||||
|
buf = self.read_udp()
|
||||||
|
if buf[0] != 0:
|
||||||
|
return self.parse_dref(buf)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def parse_dref(self, data):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def parse_dref(msg, dataRef, length_of_dref, values):
|
def send_dref(self, data_ref, values):
|
||||||
|
'''Sends X-Plane dref over the underlying UDP socket.'''
|
||||||
|
msg_len = 7 + len(data_ref) + len(values) * 4
|
||||||
|
|
||||||
|
# Header
|
||||||
|
msg = struct.pack("4s", "DREF")
|
||||||
|
|
||||||
|
# DRef
|
||||||
|
struct.pack_into("B", msg, len(msg), len(data_ref))
|
||||||
|
struct.pack_into(str(len(data_ref)) + "B", msg, len(msg), data_ref) # TODO: Verify byte order (should be network order?)
|
||||||
|
|
||||||
|
# Values
|
||||||
|
struct.pack_into("B", msg, len(msg), len(values))
|
||||||
|
struct.pack_into(str(len(values)) + "f", msg, len(msg), values) # TODO: Verify byte order (should be network order?)
|
||||||
|
|
||||||
|
self.send_udp(msg)
|
||||||
|
|
||||||
|
def request_dref(self, dref_array, resultArray):
|
||||||
|
'''Requests drefs and reads the response.'''
|
||||||
|
self.send_request(dref_array)
|
||||||
|
for i in range(80):
|
||||||
|
size = self.read_dref(resultArray)
|
||||||
|
if size != -1:
|
||||||
|
return size
|
||||||
|
|
||||||
|
return -1
|
||||||
|
|
||||||
|
def parse_getd(self, msg, dref_array, dref_sizes):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def send_dref(dataRef, length_of_dref, values):
|
def send_request(self, dref_array):
|
||||||
|
'''Sends a request over the underlying UDP socket.'''
|
||||||
|
# Header
|
||||||
|
msg = struct.pack("4s", "GETD");
|
||||||
|
|
||||||
|
# Number of values;
|
||||||
|
struct.pack_into("B", msg, len(msg), len(dref_array))
|
||||||
|
|
||||||
|
# The Rest
|
||||||
|
for dref in dref_array:
|
||||||
|
struct.pack_into("B", msg, len(msg), len(dref_array))
|
||||||
|
struct.pack_into("100B", msg, len(msg), dref_array)
|
||||||
|
|
||||||
|
self.send_udp(msg)
|
||||||
|
|
||||||
|
def parse_request(self, data):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def request_dref(dref_array, dref_sizes, list_len, resultArray):
|
def read_request(self, data_ref, array_sizes, recv_addr):
|
||||||
pass
|
buf = self.read_udp()
|
||||||
|
if buf[0] != 0:
|
||||||
def parse_getd(msg, dref_array, dref_sizes):
|
return self.parse_request(buf)
|
||||||
pass
|
else:
|
||||||
|
return None
|
||||||
def parse_request(msg, result_array, array_sizes):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def read_request(data_ref, array_sizes, recv_addr):
|
|
||||||
pass
|
|
||||||
Reference in New Issue
Block a user