-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Controls interface (v27) and simple_ctrls.py example
- Loading branch information
1 parent
7d38efd
commit 31328ea
Showing
3 changed files
with
153 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
#!/usr/bin/python3 | ||
""" | ||
Simple Controls example that sweeps the control surfaces and periodically puts the gear up/down | ||
""" | ||
import time | ||
import math | ||
from flightgear_python.fg_if import CtrlsConnection | ||
|
||
gear_down_child_state = True | ||
def ctrls_callback(ctrls_data, event_pipe): | ||
global gear_down_child_state | ||
if event_pipe.child_poll(): | ||
gear_down_child, = event_pipe.child_recv() # unpack tuple | ||
# TODO: FG sometimes ignores "once" updates? i.e. if we set `ctrls_data.gear_handle` | ||
# the next callback will still have the old value of `ctrls_data.gear_handle`, not | ||
# the one that we set. To fix this we can just keep our own state of what the value | ||
# should be and set it every time. I still need to figure out a clean way to fix | ||
# this on the backend | ||
gear_down_child_state = gear_down_child | ||
ctrls_data.gear_handle = 'down' if gear_down_child_state else 'up' | ||
# set only the data that we need to | ||
ctrls_data.aileron = math.sin(time.time()) | ||
ctrls_data.elevator = math.sin(time.time()) | ||
ctrls_data.rudder = math.sin(time.time()) | ||
ctrls_data.throttle[0] = (math.sin(time.time()) / 2) + 0.5 | ||
ctrls_data.throttle[1] = (-math.sin(time.time()) / 2) + 0.5 | ||
return ctrls_data # return the whole structure | ||
|
||
""" | ||
Start FlightGear with `--native-ctrls=socket,out,30,,5503,udp --native-ctrls=socket,in,30,,5504,udp` | ||
""" | ||
ctrls_conn = CtrlsConnection(ctrls_version=27) | ||
ctrls_event_pipe = ctrls_conn.connect_rx('localhost', 5503, ctrls_callback) | ||
ctrls_conn.connect_tx('localhost', 5504) | ||
ctrls_conn.start() # Start the Ctrls RX/TX loop | ||
|
||
gear_down_parent = True | ||
time.sleep(2) | ||
while True: | ||
# could also do `ctrls_conn.event_pipe.parent_send` so you just need to pass around `ctrls_conn` | ||
ctrls_event_pipe.parent_send((gear_down_parent,)) # send tuple | ||
gear_down_parent = not gear_down_parent # Flip gear state | ||
time.sleep(10) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
""" | ||
FlightGear Controls Network interface, version 27 | ||
See https://github.com/FlightGear/flightgear/blob/619226e9d069d2a3e8ebf8658fb5441ca8a2c233/src/Network/net_ctrls.hxx | ||
""" | ||
|
||
from construct import Array, Enum, Const, Padding, Int32ub, Float64b, BitStruct, Flag, BitsInteger, Mapping | ||
|
||
RESERVED_SPACE = 25 #: Constant value from define | ||
|
||
FG_MAX_ENGINES = 4 #: Constant value from enum | ||
# FG_MAX_WHEELS = 16 #: Constant value from enum. TODO: Unused? | ||
FG_MAX_TANKS = 8 #: Constant value from enum | ||
|
||
# Big endian | ||
#: Ctrls v27 structure | ||
ctrls_struct = { | ||
'version': Const(27, Int32ub), | ||
'_padding0': Padding(4), # TODO: Not documented, probably due to struct packing | ||
'aileron': Float64b, # -1 ... 1 | ||
'elevator': Float64b, # -1 ... 1 | ||
'rudder': Float64b, # -1 ... 1 | ||
'aileron_trim': Float64b, # -1 ... 1 | ||
'elevator_trim': Float64b, # -1 ... 1 | ||
'rudder_trim': Float64b, # -1 ... 1 | ||
'flaps': Float64b, # 0 ... 1 | ||
'spoilers': Float64b, | ||
'speedbrake': Float64b, | ||
'flaps_power': Enum(Int32ub, unavailable=0, available=1), | ||
'flap_motor_ok': Int32ub, | ||
'num_engines': Int32ub, | ||
'master_bat': Array(FG_MAX_ENGINES, Enum(Int32ub, off=0, on=1)), | ||
'master_alt': Array(FG_MAX_ENGINES, Enum(Int32ub, off=0, on=1)), | ||
'magnetos': Array(FG_MAX_ENGINES, Int32ub), | ||
'starter_power': Array(FG_MAX_ENGINES, | ||
Enum(Int32ub, off=0, on=1) | ||
), | ||
# throttle needs to be moved forward 1 double? | ||
'_padding3': Padding(4), # TODO: Not documented, probably due to struct packing | ||
'throttle': Array(FG_MAX_ENGINES, Float64b), # 0 ... 1 | ||
'mixture': Array(FG_MAX_ENGINES, Float64b), # 0 ... 1 | ||
'condition': Array(FG_MAX_ENGINES, Float64b), # 0 ... 1 | ||
'fuel_pump_power': Array(FG_MAX_ENGINES, | ||
Enum(Int32ub, off=0, on=1) | ||
), | ||
'prop_advance': Array(FG_MAX_ENGINES, Float64b), # 0 ... 1 | ||
'feed_tank_to': Array(4, Int32ub), | ||
'reverse': Array(4, Int32ub), | ||
'engine_ok': Array(FG_MAX_ENGINES, Int32ub), | ||
'mag_left_ok': Array(FG_MAX_ENGINES, Int32ub), | ||
'mag_right_ok': Array(FG_MAX_ENGINES, Int32ub), | ||
'spark_plugs_ok': Array(FG_MAX_ENGINES, Enum(Int32ub, fouled=0, ok=1)), | ||
'oil_press_status': Array(FG_MAX_ENGINES, | ||
Enum(Int32ub, normal=0, low=1, full_fail=2) | ||
), | ||
'fuel_pump_ok': Array(FG_MAX_ENGINES, Int32ub), | ||
'num_tanks': Int32ub, | ||
'fuel_selector': Array(FG_MAX_TANKS, Enum(Int32ub, off=0, on=1)), | ||
'xfer_pump': Array(5, Int32ub), # specifies transfer from array value tank to tank specified by int value | ||
'cross_feed': Enum(Int32ub, off=0, on=1), | ||
'_padding4': Padding(4), # TODO: Not documented, probably due to struct packing | ||
'brake_left': Float64b, | ||
'brake_right': Float64b, | ||
'copilot_brake_left': Float64b, | ||
'copilot_brake_right': Float64b, | ||
'brake_parking': Float64b, | ||
'gear_handle': Enum(Int32ub, up=0, down=1), | ||
'master_avionics': Enum(Int32ub, off=0, on=1), | ||
'comm_1_MHz': Float64b, # TODO: Frequencies are all screwed up. Garbage data | ||
'comm_2_MHz': Float64b, | ||
'nav_1_MHz': Float64b, | ||
'nav_2_MHz': Float64b, | ||
'wind_speed_kt': Float64b, | ||
'wind_dir_deg': Float64b, | ||
'turbulence_norm': Float64b, | ||
'temp_c': Float64b, | ||
'press_inhg': Float64b, | ||
'hground_m': Float64b, # ground elevation | ||
'magvar_deg': Float64b, # local magnetic variation | ||
'icing': Int32ub, | ||
'speedup': Int32ub, # integer speedup multiplier | ||
'freeze': BitStruct( # Default is big-endian | ||
other=BitsInteger((Int32ub.sizeof() * 8) - 3), # Rest of uint32 minus the 3 flags | ||
fuel=Flag, | ||
position=Flag, | ||
master=Flag, | ||
), | ||
'_reserved': Padding(Int32ub.length * RESERVED_SPACE), | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters