From 5f85d712aaa3ad0c30bcebd4eefeeecb26ec52a4 Mon Sep 17 00:00:00 2001 From: merspieler Date: Sat, 31 Mar 2018 20:54:40 +0200 Subject: [PATCH] Added new implementation of the pushback Signed-off-by: merspieler --- A320-100-CFM.xml | 1 - A320-200-CFM.xml | 1 - A320-200-IAE.xml | 1 - A320-main.xml | 45 +++++++- A320neo-CFM.xml | 1 - A320neo-PW.xml | 1 - Models/A320-100-CFM.xml | 2 +- Models/A320-200-CFM.xml | 2 +- Models/A320-200-IAE.xml | 2 +- Models/A320neo-CFM.xml | 2 +- Models/A320neo-PW.xml | 2 +- Models/Goldhofert-autopush.xml | 130 +++++++++++++++++++++ Nasal/autopush-README.txt | 117 +++++++++++++++++++ Nasal/autopush.nas | 76 +++++++++++++ Nasal/autopush_driver.nas | 113 ++++++++++++++++++ Systems/pushback.xml | 45 -------- gui/dialogs/autopush.xml | 158 ++++++++++++++++++++++++++ gui/dialogs/pushback.xml | 201 +++++++++++++++++++++++++++++++++ 18 files changed, 839 insertions(+), 61 deletions(-) create mode 100644 Models/Goldhofert-autopush.xml create mode 100644 Nasal/autopush-README.txt create mode 100644 Nasal/autopush.nas create mode 100644 Nasal/autopush_driver.nas delete mode 100644 Systems/pushback.xml create mode 100644 gui/dialogs/autopush.xml create mode 100644 gui/dialogs/pushback.xml diff --git a/A320-100-CFM.xml b/A320-100-CFM.xml index 4c179888..7d87dcdc 100644 --- a/A320-100-CFM.xml +++ b/A320-100-CFM.xml @@ -449,7 +449,6 @@ xsi:noNamespaceSchemaLocation="http://jsbsim.sourceforge.net/JSBSim.xsd"> - diff --git a/A320-200-CFM.xml b/A320-200-CFM.xml index 9b8bb8ff..f6f7fb5e 100644 --- a/A320-200-CFM.xml +++ b/A320-200-CFM.xml @@ -449,7 +449,6 @@ xsi:noNamespaceSchemaLocation="http://jsbsim.sourceforge.net/JSBSim.xsd"> - diff --git a/A320-200-IAE.xml b/A320-200-IAE.xml index 6cc6b204..c52cfa98 100644 --- a/A320-200-IAE.xml +++ b/A320-200-IAE.xml @@ -449,7 +449,6 @@ xsi:noNamespaceSchemaLocation="http://jsbsim.sourceforge.net/JSBSim.xsd"> - diff --git a/A320-main.xml b/A320-main.xml index 8b3c955c..1dc3821a 100644 --- a/A320-main.xml +++ b/A320-main.xml @@ -28,10 +28,27 @@ - 5000 - 200 - 500 - 0 + + 1 + + 0.0 + 5000.0 + 200.0 + 25000.0 + 500.0 + + -60.0 + 0.0 + + 5.0 + 5.0 + 5.0 + 0.05 + 1.4 + 7.0 + 0.2 + 2.5 + @@ -231,7 +248,7 @@ dialog-show - pushback + autopush @@ -1455,6 +1472,22 @@ Aircraft/IDG-A32X/Nasal/icing.nas + + Nasal/autopush.nas + + + Nasal/autopush_driver.nas + - + + + + + + + + + + + diff --git a/A320neo-CFM.xml b/A320neo-CFM.xml index f240ddd4..c2344ea8 100644 --- a/A320neo-CFM.xml +++ b/A320neo-CFM.xml @@ -449,7 +449,6 @@ xsi:noNamespaceSchemaLocation="http://jsbsim.sourceforge.net/JSBSim.xsd"> - diff --git a/A320neo-PW.xml b/A320neo-PW.xml index 94da872a..f565b8f2 100644 --- a/A320neo-PW.xml +++ b/A320neo-PW.xml @@ -449,7 +449,6 @@ xsi:noNamespaceSchemaLocation="http://jsbsim.sourceforge.net/JSBSim.xsd"> - diff --git a/Models/A320-100-CFM.xml b/Models/A320-100-CFM.xml index 62bb0afd..4e6fb174 100644 --- a/Models/A320-100-CFM.xml +++ b/Models/A320-100-CFM.xml @@ -316,7 +316,7 @@ Pushback - Models/Airport/Pushback/Goldhofert.xml + Models/Goldhofert-autopush.xml 5.55 0 diff --git a/Models/A320-200-CFM.xml b/Models/A320-200-CFM.xml index 8a1abda1..3b2f71bd 100644 --- a/Models/A320-200-CFM.xml +++ b/Models/A320-200-CFM.xml @@ -348,7 +348,7 @@ Pushback - Models/Airport/Pushback/Goldhofert.xml + Models/Goldhofert-autopush.xml 5.55 0 diff --git a/Models/A320-200-IAE.xml b/Models/A320-200-IAE.xml index 02707e48..bc17b952 100644 --- a/Models/A320-200-IAE.xml +++ b/Models/A320-200-IAE.xml @@ -344,7 +344,7 @@ Pushback - Models/Airport/Pushback/Goldhofert.xml + Models/Goldhofert-autopush.xml 5.55 0 diff --git a/Models/A320neo-CFM.xml b/Models/A320neo-CFM.xml index 96963b37..8b47fce4 100644 --- a/Models/A320neo-CFM.xml +++ b/Models/A320neo-CFM.xml @@ -325,7 +325,7 @@ Pushback - Models/Airport/Pushback/Goldhofert.xml + Models/Goldhofert-autopush.xml 5.55 0 diff --git a/Models/A320neo-PW.xml b/Models/A320neo-PW.xml index 6e76706a..03f9897b 100644 --- a/Models/A320neo-PW.xml +++ b/Models/A320neo-PW.xml @@ -325,7 +325,7 @@ Pushback - Models/Airport/Pushback/Goldhofert.xml + Models/Goldhofert-autopush.xml 5.55 0 diff --git a/Models/Goldhofert-autopush.xml b/Models/Goldhofert-autopush.xml new file mode 100644 index 00000000..1f256db7 --- /dev/null +++ b/Models/Goldhofert-autopush.xml @@ -0,0 +1,130 @@ + + + + Models/Airport/Pushback/Goldhofert.ac + + + + + Models/Airport/Pushback/Goldhofert-warning-light.xml + + -2.908 + 0.260 + 1.326 + 0 + + + + + Models/Airport/Pushback/Goldhofert-warning-light.xml + + -1.781 + 0.260 + 1.326 + 90 + + + + + spin + wheelfl + wheelfr + + gear/gear[0]/rollspeed-ms + -16.3 +
+ -2.8976 + 0 + 0.5809 +
+ + 0 + 1 + 0 + +
+ + + spin + wheelrl + wheelrr + + gear/gear[0]/rollspeed-ms + -16.3 +
+ 2.0501 + 0 + 0.5735 +
+ + 0 + 1 + 0 + +
+ + + select + + + sim/model/pushback/connected + + + + + rotate + + gear/gear/steering-norm + + 70.0 +
+ 0 + 0 + 0 +
+ + 0 + 0 + -1 + +
+ + + translate + + gear/gear[0]/compression-ft + 0.3048 + + 0 + 0 + 1 + + + + + rotate + + orientation/pitch-deg + + 2.0 +
+ 0 + 0 + 0 +
+ + 0 + 1 + 0 + +
+
diff --git a/Nasal/autopush-README.txt b/Nasal/autopush-README.txt new file mode 100644 index 00000000..698db78e --- /dev/null +++ b/Nasal/autopush-README.txt @@ -0,0 +1,117 @@ +AUTOMATIC PUSHBACK FOR FLIGHTGEAR +Version 0.1.1 + +Copyright (c) 2018 Michael Danilov +Some of the code (c) FlightGear +Distribute under the terms of GPLv2. + + +FILES + +Nasal/autopush-README.txt this file +Models/Goldhofert-autopush.xml the animation for FGDATA's Goldhofer +Nasal/autopush.nas basic pushback logic +Nasal/autopush_driver.nas pushback driver +gui/dialogs/autopush.xml GUI dialog + + +INSTALLATION + +Only the minimal working example is covered here. Later you will have +to implement correct steering in your FDM (driving the +"/sim/model/pushback/yaw-deg") and pushback availability +("/sim/model/pushback/available") -- because those are too +aircraft-specific. + +1. Set up the pushback logic. Add the following tags in your set.xml. + Replace the "/fdm/jsbsim/gear/unit[0]/steering/pos-deg" with the + property for the front wheel steering degrees of your aircraft. + + Under : + + + + 1 + + 0.0 + 100.0 + 25.0 + 25000.0 + 0.0 + + -60.0 + 0.0 + + 10.0 + 10.0 + 5.0 + 0.05 + 1.4 + 7.0 + 0.2 + 2.5 + + + + Under : + + + Nasal/autopush.nas + + + Nasal/autopush_driver.nas + + +2. Connect the FDM's external force. + + a) JSBSim: + + a.1. Add the following under of your + JSBSim XML. Change the coordinates under to equal + those of your front bogey. + + + + 0.0 + 0.0 + 0.0 + + + 1.0 + 0.0 + 0.0 + + + + a.2. Add the following under of + your set.xml. + + + + + + + + b) YASim: TODO + +3. Copy the gui/dialogs/autopush.xml from the distribution to your + aircraft's gui/dialogs directory. Add it to the menu (see + FlightGear documentation for editing the menu). + +4. Copy the Models/Goldhofert-autopush.xml to your aircraft's Models/ + directory. Edit all the places marked by "SETTING" to match your + setup. Include it in your Model XML, with offsets equal to the + front wheel's contact point. + +5. Add the following in your Model XML. Change the coordinates under + to equal those of your front bogey. + + + Pushback + Models/Airport/Pushback/Goldhofert-autopush.xml + + 0.0 + 0.0 + 0.0 + + diff --git a/Nasal/autopush.nas b/Nasal/autopush.nas new file mode 100644 index 00000000..f4feb0b2 --- /dev/null +++ b/Nasal/autopush.nas @@ -0,0 +1,76 @@ +# AUTOPUSH +# Basic pushback logic class. +# +# Copyright (c) 2018 Michael Danilov +# Distribute under the terms of GPLv2. + + +var _K_p = nil; +var _K_i = nil; +var _K_d = nil; +var _F_i = nil; +var _int = nil; +var _deltaV_old = nil; +var _t_old = nil; + +var loop = func() { + if(!getprop("/sim/model/pushback/available")){ + stop(); + return; + } + var force = 0.0; + # Rollspeed is only adequate if the wheel is touching the ground. + if(getprop("/gear/gear[0]/wow")){ + var deltaV = + getprop("/sim/model/pushback/target-speed-km_h") - + getprop("/gear/gear[0]/rollspeed-ms") * 3.6; + var dV = deltaV - _deltaV_old; + var t = getprop("/sim/time/elapsed-sec"); + var dt = math.max(t - _t_old, 0.0001); + _int = math.min(math.max(_int + dV * dt, -_F_i), _F_i); + force = (_K_p * deltaV + _K_d * dV / dt + _K_i * _int) * KG2LB; + _deltaV_old = deltaV; + _t_old = t; + var yaw = getprop("/sim/model/pushback/yaw-deg") * D2R; + setprop("/sim/model/pushback/force-x", math.cos(yaw)); + setprop("/sim/model/pushback/force-y", math.sin(yaw)); + } + setprop("/sim/model/pushback/force-lbf", force); +} + +var timer = maketimer(0.026, func{loop()}); + +var start = func() { + _K_p = getprop("/sim/model/pushback/K_p"); + _K_i = getprop("/sim/model/pushback/K_i"); + _K_d = getprop("/sim/model/pushback/K_d"); + _F_i = getprop("/sim/model/pushback/F_i"); + _int = 0.0; + _deltaV_old = 0.0; + _t_old = getprop("/sim/time/elapsed-sec"); + setprop("/sim/model/pushback/connected", 1); + if(!timer.isRunning){ + screen.log.write("(pushback): Release brakes."); + } + timer.start(); +} + +var stop = func() { + if(timer.isRunning){ + screen.log.write("(pushback): Pushback disconnected, bypass pin removed."); + } + timer.stop(); + setprop("/sim/model/pushback/force-lbf", 0.0); + setprop("/sim/model/pushback/connected", 0); +} + +var toggle = func(){ + if( + getprop("/sim/model/pushback/enabled") * + getprop("/sim/model/pushback/available") + ){ + start(); + }else{ + stop(); + } +} diff --git a/Nasal/autopush_driver.nas b/Nasal/autopush_driver.nas new file mode 100644 index 00000000..76126ade --- /dev/null +++ b/Nasal/autopush_driver.nas @@ -0,0 +1,113 @@ +# AUTOPUSH +# Pushback driver class. +# +# Command the pushback to tow/push the aircract facing set heading. +# +# Copyright (c) 2018 Michael Danilov +# Distribute under the terms of GPLv2. + + +# FIXME When facing, acccount for current steering position, to work without dry steering. + + +var _K_V_push = nil; +var _F_V_push = nil; +var _S_min = nil; +var _K_psi_push = nil; +var _K_V_turn = nil; +var _F_V_turn = nil; +var _K_psi_turn = nil; +var _V_min = nil; + +var _turning = nil; +var _sign = nil; +var _target = nil; +var _psi_parking = nil; +var _psi_turn = nil; + +var loop = func() { + if(!getprop("/sim/model/pushback/connected")){ + stop(); + return; + } + var V = 0.0; + var steering = 0.0; + var deltapsi = 0.0; + var psi = getprop("/orientation/heading-deg"); + if(!_turning){ + # Initially follow a straight line parallel to our initial heading. + var (A, S) = courseAndDistance(_target); + S *= NM2M; + # Stop when the bearing flips, guarante against infinite pushing. + if( + (abs(S) < _S_min) + + (abs(saw180(_psi_parking - A - math.min(_sign, 0.0) * 180.0) > 90.0)) + ){ + _turning = 1; + screen.log.write("(pushback): Turning to face heading " ~ int(_psi_turn) ~ "."); + } + deltapsi = saw180(_psi_parking - psi); + V = math.min(math.max(_K_V_push * _sign * (S / _S_min), -_F_V_push), _F_V_push); + steering = math.min(math.max(_K_psi_push * _sign * deltapsi, -1.0), 1.0); + }else{ + # Turn (almost) in place. + deltapsi = saw180(_psi_turn - psi); + V = math.min(math.max(_K_V_turn * _sign * abs(deltapsi), -_F_V_turn), _F_V_turn); + # We are done when the heading error is small. + if(abs(V) < _V_min){ + stop(); + return; + } + steering = math.min(math.max(_K_psi_turn * _sign * deltapsi, -1.0), 1.0); + } + setprop("/sim/model/pushback/target-speed-km_h", V); + setprop("/sim/model/pushback/driver/steer-cmd-norm", steering); +} + +var timer = maketimer(0.051, func{loop()}); + +var start = func() { + _K_V_push = getprop("/sim/model/pushback/driver/K_V_push"); + _F_V_push = getprop("/sim/model/pushback/driver/F_V_push"); + _S_min = getprop("/sim/model/pushback/driver/S_min-m"); + _K_psi_push = getprop("/sim/model/pushback/driver/K_psi_push"); + _K_V_turn = getprop("/sim/model/pushback/driver/K_V_turn"); + _F_V_turn = getprop("/sim/model/pushback/driver/F_V_turn"); + _K_psi_turn = getprop("/sim/model/pushback/driver/K_psi_turn"); + _V_min = getprop("/sim/model/pushback/driver/V_min"); + if(!getprop("/sim/model/pushback/connected")){ + return; + } + towdist = getprop("/sim/model/pushback/driver/tow-distance-m"); + _target = geo.aircraft_position(); + _psi_parking = getprop("/orientation/heading-deg"); + _target.apply_course_distance(_psi_parking, towdist); + _psi_turn = getprop("/sim/model/pushback/driver/face-heading-deg"); + _sign = 1.0 - 2.0 * (towdist < 0.0); + _turning = 0; + timer.start(); + if(_sign < 0.0){ + screen.log.write("(pushback): Pushing back."); + }else{ + screen.log.write("(pushback): Towing."); + } +} + +var stop = func() { + if(timer.isRunning){ + screen.log.write("(pushback): Done."); + } + timer.stop(); + setprop("/sim/model/pushback/target-speed-km_h", 0.0); +} + +# Sawtooth: -180..+180 deg. +var saw180 = func(p) { + while (p <= -180.0){ + p += 360.0; + } + while (p > 180.0){ + p -= 360.0; + } + return p; +} diff --git a/Systems/pushback.xml b/Systems/pushback.xml deleted file mode 100644 index abb72c46..00000000 --- a/Systems/pushback.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - /sim/model/pushback/target-speed-fps - - - - - - /sim/model/pushback/position-norm gt 0.95 - /gear/gear/wow == 1 - gear/unit[0]/wheel-speed-fps lt 50 - - - - - /sim/model/pushback/target-speed-fps - -gear/unit[0]/wheel-speed-fps - - - - systems/pushback/speed-error - /sim/model/pushback/kp - /sim/model/pushback/ki - /sim/model/pushback/kd - systems/pushback/linked - /sim/model/pushback/force - - - - - - systems/pushback/linked == 0 - - external_reactions/pushback/magnitude - - - - diff --git a/gui/dialogs/autopush.xml b/gui/dialogs/autopush.xml new file mode 100644 index 00000000..fa7371a4 --- /dev/null +++ b/gui/dialogs/autopush.xml @@ -0,0 +1,158 @@ + + + + + autopush + vbox + + + hbox + + + + + true + + + + + + + + true + vbox + center + top + + + left + + /sim/model/pushback/enabled + dialog-apply + + nasal + + + + + + hbox + + + + + 0 + 2 + -15 + 15 + /sim/model/pushback/target-speed-km_h + true + + dialog-apply + + + + 16 + /sim/model/pushback/target-speed-km_h + %3.0f + true + + + + + + + + + + hbox + + + + + 0 + 2 + -100 + 100 + /sim/model/pushback/driver/tow-distance-m + + dialog-apply + + + + 16 + /sim/model/pushback/driver/tow-distance-m + %4.0f + true + + + + + + + + hbox + + + + + 0 + 2 + 0 + 360 + /sim/model/pushback/driver/face-heading-deg + + dialog-apply + + + + 16 + /sim/model/pushback/driver/face-heading-deg + %3.0f + true + + + + + hbox + + + + + + + diff --git a/gui/dialogs/pushback.xml b/gui/dialogs/pushback.xml new file mode 100644 index 00000000..8c83c721 --- /dev/null +++ b/gui/dialogs/pushback.xml @@ -0,0 +1,201 @@ + + + + pushback + vbox + + + + + + var pushback_position = aircraft.door.new("sim/model/pushback", 10.0); + pushback_position.setpos(pushback_position.getpos()); + props.globals.getNode("/sim/model/pushback/enabled", 1 ).setBoolValue(1); + props.globals.initNode("/sim/model/pushback/target-speed-fps", 0.0 ); + + + pushback_position.setpos(0); + setprop("/sim/model/pushback/enabled", 0 ); + setprop("/sim/model/pushback/target-speed-fps", 0 ); + setprop("/sim/model/pushback/force", 0); + + + + + hbox + + + + + true + + + + + + + + true + vbox + center + top + + + left + + + + + nasal + + + + + + + + + hbox + + + + + 0 + 2 + -25 + 25 + /sim/model/pushback/target-speed-fps + true + + dialog-apply + + + + 16 + /sim/model/pushback/target-speed-fps + %3.0f + true + + + + + + + + + + hbox + + + + + 0 + 2 + -100 + 100 + /nasal/pushback_driver/tow-distance-m + + dialog-apply + + + + 16 + /nasal/pushback_driver/tow-distance-m + %4.0f + true + + + + + + + + hbox + + + + + 0 + 2 + 0 + 360 + /nasal/pushback_driver/face-heading-deg + + dialog-apply + + + + 16 + /nasal/pushback_driver/face-heading-deg + %3.0f + true + + + + + hbox + + + + + + +