As was established in the Specification session, a number of basic manoeuvres will be implemented in the MVP. The basic manoeuvres can be realised by pre-programming a sequence that directly sets the control surfaces of the aircraft in FlightGear. For example; if the aircraft should pitch up, one can manipulate the elevator to deflect for a certain amount of time and consequently return it to its origin. The aircraft will commence to pitch up for the time that is set before the elevator is returned to 0 degrees deflection. The pseudo code for such a manoeuvre is depicted below:
1 d e f p i t c h u p : 2 # S e t t h e e l e v a t o r 3 f g [’ / c o n t r o l s / f l i g h t / e l e v a t o r ’] = −0.2 4 # Hold i t i n t h i s p o s i t i o n f o r 2 s e c . 5 t i m e . s l e e p ( 2 . 0 ) 6 # R e l e a s e e l e v a t o r 7 f g [’ / c o n t r o l s / f l i g h t / e l e v a t o r ’] = 0 . 0
The basic manoeuvres for pitching up, pitching down, banking left, banking right, levelling out and more complex manoeuvres, taking off from the ground and following an aircraft are implemented in the MVP. This class furthermore contains an implementation of a Finite State Machine (FSM). A FSM is a computational model based on a hypothetical “machine” which consists of one or more states [84].
FSMs are commonly equipped to organise and represent a flow of executions and states of an agent. The machine can only be in exactly one state at a time and the machine transitions from one state to another state in order to perform different actions. In case of the MVP, the manoeuvres are the states: the aircraft can only perform one action at a time. The implementation of the “pitch up”- manoeuvre in the FSM can be realised with the following pseudo code:
1 d e f p i t c h u p : 2 d e f i n i t i a l i z e : 3 # I n i t i a l i z e manoeuvre b o o l 4 p i t c h u p b o o l e a n = F a l s e 5 6 d e f p i t c h u p : 7 # method t o change b o o l e a n v a l u e 8 p i t c h u p b o o l e a n = True 9 10 d e f f i n i t e s t a t e m a c h i n e : 11 w h i l e True : 12 w h i l e p i t c h u p b o o l e a n == True : 13 # I f manoeuvre b o o l e a n i s t r u e , p e r f o r m manoeuvre 14 f g [’ / c o n t r o l s / f l i g h t / e l e v a t o r ’] = −0.2 15 t i m e . s l e e p ( 2 . 0 ) 16 f g [’ / c o n t r o l s / f l i g h t / e l e v a t o r ’] = 0 . 0 17 # and e x i t l o o p 18 p i t c h u p b o o l e a n = F a l s e 19 20# I n i t i a l i z a t i o n and s t a r t i n g o f t h r e a d 21 m a n o e u v r e t h r e a d = t h r e a d i n g . Thread ( t a r g e t=f i n i t e s t a t e m a c h i n e ) 22 m a n o e u v r e t h r e a d . s t a r t ( )
In the MVP, every manoeuvre is a state the FSM can be in. An elaboration on this structure is required: The FSM is programmed as an infinite loop (denoted in the psuedocode as def finite state machine) that commences when starting the separate thread. Once the thread starts, the infinite loop commences. As long as no action is undertaken by the user, the corresponding boolean will remain False. However, as soon as the user clicks the “Move up” button of the GUI, the button binding will call the pitch up method, changing the boolean to True. In the next iteration of the loop of the FSM, it will encounter the boolean of the if-statement for the manoeuvre to be True. The if-statement will be entered and the manoeuvre is performed. The pitch up boolean is set to False at the end of the manoeuvre. The if-statement will be exited and the loop will be continued. In the MVP, every method that describes a manoeuvre is a state.
The main reason for utilising a FSM in FlightGear is to prevent the Tkinter GUI application from freezing while it waits from a call-back. Directly calling the method that performs the manoeuvre from the Tkinter GUI is possible, however the call-back that the event scheduler of the Tkinter applica- tion requires, needs to be returned within a 4 second time frame. Short manoeuvres can be realised by directly binding the method call to the Tkinter GUI, but longer manoeuvres (such as the take-off manoeuvre) requires more time to finish. This will delay the call-back to the Tkinter module, causing it to freeze. The FSM allows the GUI to work with “flagging” instead of waiting for a function to be completed; it “delegates” the workload to another method by simply changing only the Boolean and then returning the call-back.
The discovery of a functioning autopilot in FlightGear provided inspiration of the realisation of the more difficult manoeuvres that require a control loop of some sort. Upon further investigation of the internal workings of the autopilot of the aircraft it turned out that the autopilot systems are based on an universal type of controller; a Proportional-Integral- Derivative (PID) controller. A PID controller includes a feedback mechanism and is widely used in different fields such as thermostats, governing of industrial equipment and also auto-pilot systems for aircraft [85]. A PID controller works by monitoring a current value and a desired value and attempting to minimize the difference between these two values. The difference between the desired value and the current value is the ‘error value’. The PID controller
attempts to apply a correction on the output signal in order to minimize the error value by means of proportional, integral and derivative terms. A block diagram of a PID controller is depicted in figure 5.7 [86]
Figure 5.7:Block diagram of a PID controller
Implementations of PID and PI controllers are performed throughout the autopilot script of the F-14B aircraft. As an example, the file f-14-AFCS.xml of the F-14B describes the functions of the autopilot. As an illustration, the vertical speed mode of the autopilot of the F-14B is depicted below:
1 <!−−V e r t i c a l Speed Hold−−> 2 <pid−c o n t r o l l e r> 3 <name>V e r t i c a l S p e e d</name> 4 <debug>f a l s e</debug> 5 <e n a b l e> 6 <prop>/ a u t o p i l o t / l o c k s / a l t i t u d e</prop> 7 <v a l u e>v e r t i c a l−speed−h o l d</v a l u e> 8 </e n a b l e> 9 <i n p u t> 10 <prop>/ v e l o c i t i e s / v e r t i c a l−s p e e d f p s</prop> 11 </i n p u t> 12 <r e f e r e n c e>
13 <prop>/ a u t o p i l o t / s e t t i n g s / v e r t i c a l−speed−fpm</prop> 14 <s c a l e>0 . 0 1 6 6 7</s c a l e> 15 </r e f e r e n c e> 16 <o u t p u t> 17 <prop>/ c o n t r o l s / f l i g h t / e l e v a t o r−t r i m</prop> 18 </o u t p u t> 19 <c o n f i g> 20 <Kp>
21 <prop>sim / model / f−14b/ s y s t e m s / a f c s / vs−pid−p g a i n</prop>
22 </Kp> 23 <b e t a>0 . 1</b e t a> 24 <Ti>1 0 . 0</Ti> 25 <Td>0 . 0 0 0 0 1</Td> 26 <u min>−0.15</u min> 27 <u max>0 . 1 5</u max> 28 </c o n f i g> 29</pid−c o n t r o l l e r>
Depending on the quality and complexity of the work by the author of the model, various autopilot functions are available. The direction based manoeuvres as described in the Specification phase can be realised using various autopilot functions. The basic manoeuvres can be altered in the following way:
1 d e f p i t c h u p : 2 # S e t t h e v a l u e f o r t h e p i t c h a n g l e 3 f g [’ / a u t o p i l o t / s e t t i n g s / t a r g e t−p i t c h−deg ’] = 10 4 # S e t t h e a u t o p i l o t i n p i t c h h o l d mode 5 f g [’ / a u t o p i l o t / l o c k s / a l t i t u d e ’] = ’ p i t c h−h o l d ’ 6 # E x i t t h e manoeuvre 7 p i t c h u p b o o l e a n = F a l s e
By setting the appropriate value for the pitch angle for the autopilot and after that engaging the au- topilot in pitch-mode, the aircraft will commence to pitch with 10 degrees and will maintain this pitch angle until the user says otherwise. Consequently, the same can be down for the pitch down method, adapting the pitch angle to -10 instead of 10 will result in a pitch down of the aircraft with a 10 degree negative angle (without speed hold).
A more difficult manoeuvre like following an aircraft can be established by making smart use of the autopilot. Theoretically, all modes of the autopilot (in this case heading mode, vertical mode and speed mode) can be equipped to follow a certain aircraft. One can “copy” the heading, altitude and current speed of the adversary and “paste” it inside the autopilot of the UCAV. If this is done continuously, the autopilot forces the UCAV to maintain the identical heading, altitude and speed as the adversary, which results in the UCAV following and mimicking the adversary’s behaviour and manoeuvres. Flight- Gear houses a ”target-tracking”-function that enables the passing of adversary values inside the UCAVs autopilot. The Property Tree browser can be used to determine the working of this function.
Figure 5.8:Property Tree browser at the target tracking functionality
As can be seen from figure 5.10, the target tracking function can be enabled and disabled, the distance between the aircraft (similar to loitering distance in circling UAVs) can be set, the minimum speed the following aircraft should maintain (this should be set to above stall speed of that certain aircraft), the target location in the property tree and the update period.
By enabling the target tracking function, the parameters heading, altitude and speed are routed to- wards the autopilot of the UCAV. The target-root should be set to the aircraft that the user desires to follow: in figure 5.8 it is set to an AI aircraft, however, in a multiplayer session the path of the target-root should be set to/ai/models/multiplayer or with multiple multiplayer players in one session, the denomination of that player. In the case that there are 5 players inside the server, the first player is denoted as /ai/models/multiplayer, the second as /ai/models/multiplayer[1] and so forth until the last player ‘n’ (ai/models/multiplayer[n]). To determine which player is denoted by which index in the brackets, the Property Tree browser can be utilised to browse to the path of that multiplayer (ai/mod- els/multiplayer[n]) and look up the callsign of the pilot. To enable the target tracking function, the following pseudo code can be used:
1 d e f e n g a g e f o l l o w i n g : 2 w h i l e s e l f . e n g a g e f o l l o w i n g b o o l e a n : 3 # Enable t a r g e t t r a c k i n g w i t h s p e c i f i c t a r g e t and s e t a u t o p i l o t a c c o r d i n g l y 4 f g [’ / a u t o p i l o t / t a r g e t−t r a c k i n g / e n a b l e ’] = ’ 1 ’ 5 f g [’ / a u t o p i l o t / t a r g e t−t r a c k i n g / t a r g e t−r o o t ’] = ’ a i / models / m u l t i p l a y e r ’ 6 f g [’ / a u t o p i l o t / l o c k s / a l t i t u d e ’] = ’ a l t i t u d e h o l d ’ 7 f g [’ / a u t o p i l o t / l o c k s / h e a d i n g ’] = ’ dg−h e a d i n g−h o l d ’ 8 # e x i t manoeuvre 9 e n g a g e f o l l o w i n g b o o l e a n = F a l s e
This enables the target-tracking function and selects the proper aircraft to follow. The values for head- ing, altitude and speed are continuously routed to the autopilot of the UCAV. By setting the autopilot in’altitude-hold’ and ’dg-heading-hold’, the autopilot will try to reach the altitude of the adversary and maintains the same heading as the adversary, effectively following the adversary at the given distance as defined as ’goal-range-nm’, which is the distance the UCAV should keep with respect to the aircraft that it is following in nautical miles.
To recap, the autopilot functionality (consisting of PID-controllers) has been utilised to fulfil basic manoeuvres (up, down, left and right) and a more difficult ”following-function”. These manoeuvres are coupled to the user interface so that the user can select an action and the Python script will manipulate FlightGears autopilot settings to achieve the manoeuvre.