From 36190eac0b874f9b56dbf0549c1cbecfa6bb99a1 Mon Sep 17 00:00:00 2001 From: merspieler Date: Sun, 20 Oct 2019 09:33:14 +0000 Subject: [PATCH 1/2] Updated autopush Signed-off-by: merspieler --- A320-main.xml | 5 +++ Nasal/autopush.nas | 8 ++-- Nasal/autopush_driver.nas | 39 +++++++++++------ Nasal/autopush_route.nas | 91 +++++++++++++++++++++++---------------- 4 files changed, 89 insertions(+), 54 deletions(-) diff --git a/A320-main.xml b/A320-main.xml index 3edc46ea..2d4ee012 100644 --- a/A320-main.xml +++ b/A320-main.xml @@ -37,6 +37,11 @@ 5.5 0.03 + 8.0 + 0.03 + 1.0 + 0.03 + 1.0 diff --git a/Nasal/autopush.nas b/Nasal/autopush.nas index b16dd6d0..02b7f13f 100644 --- a/Nasal/autopush.nas +++ b/Nasal/autopush.nas @@ -8,7 +8,6 @@ # Distribute under the terms of GPLv2. -var _enabled = 0; var _K_p = nil; var _F_p = nil; var _K_i = nil; @@ -134,10 +133,9 @@ var _stop = func() { setlistener("/sim/model/autopush/enabled", func(p) { var enabled = p.getValue(); - if ((enabled > _enabled) and getprop("/sim/model/autopush/available")) { + if ((enabled) and getprop("/sim/model/autopush/available")) { _start(); - } else if (enabled < _enabled) { + } else { _stop(); } - _enabled = enabled; -}); +}, 1, 0); diff --git a/Nasal/autopush_driver.nas b/Nasal/autopush_driver.nas index 931befcc..a8c1cbb1 100644 --- a/Nasal/autopush_driver.nas +++ b/Nasal/autopush_driver.nas @@ -15,14 +15,19 @@ var _F_V = nil; var _R_turn_min = nil; var _D_stop = nil; var _K_psi = nil; +var _F_psi = nil; +var _K_psidot = nil; +var _F_psidot = nil; var _debug = nil; +var _psi = nil; +var _time = nil; var _route = nil; var _route_reverse = nil; var _push = nil; var _sign = nil; -var _to_wp = 1; +var _to_wp = 0; var _is_last_wp = 0; var _is_reverse_wp = 0; @@ -45,12 +50,17 @@ var _loop = func() { stop(); return; } - var psi = getprop("/orientation/heading-deg") + _push * 180.0; var (A, D) = courseAndDistance(_route[_to_wp]); D *= NM2M; var (psi_leg, D_leg) = courseAndDistance(_route[_to_wp - 1], _route[_to_wp]); var deltapsi = geo.normdeg180(A - psi_leg); - var deltaA = geo.normdeg180(A - psi); + var psi = getprop("/orientation/heading-deg") + _push * 180.0; + var deltaA = math.min(math.max(_K_psi * geo.normdeg180(A - psi), -_F_psi), _F_psi); + var time = getprop("/sim/time/elapsed-sec"); + var dt = time - _time; + var minus_psidot = (dt > 0.002) * math.min(math.max(_K_psidot * (_psi - psi) / dt, -_F_psidot), _F_psidot); + _psi = psi; + _time = time; # TODO Either use _K_V and total remaining distance or turn radius to calculate speed. # TODO Make slider input override speed. var V = _F_V; @@ -69,12 +79,11 @@ var _loop = func() { _advance_wp(); } } - + var steering = math.min(math.max(_sign * (deltaA + minus_psidot), -1.0), 1.0); if (_debug > 1) { - print("autopush_driver to_wp " ~ _to_wp ~ ", psi_target " ~ geo.normdeg(A) ~ ", deltapsi " ~ deltapsi ~ ", deltapsi_steer " ~ _sign * deltaA); + print("autopush_driver to_wp " ~ _to_wp ~ ", A " ~ geo.normdeg(A) ~ ", deltaA " ~ deltaA ~ ", minus_psidot " ~ minus_psidot); } setprop("/sim/model/autopush/target-speed-km_h", _sign * V); - steering = math.min(math.max(_sign * _K_psi * deltaA, -1.0), 1.0); setprop("/sim/model/autopush/steer-cmd-norm", steering); } @@ -100,7 +109,7 @@ var start = func() { if ((_route == nil) or size(_route) < 2) { gui.popupTip("Pushback route empty or invalid"); return; - }else{ + } else { autopush_route.done(); } _K_V = getprop("/sim/model/autopush/driver/K_V"); @@ -108,12 +117,18 @@ var start = func() { _R_turn_min = getprop("/sim/model/autopush/min-turn-radius-m"); _D_stop = getprop("/sim/model/autopush/stopping-distance-m"); _K_psi = getprop("/sim/model/autopush/driver/K_psi"); + _F_psi = getprop("/sim/model/autopush/driver/F_psi"); + _K_psidot = getprop("/sim/model/autopush/driver/K_psidot"); + _F_psidot = getprop("/sim/model/autopush/driver/F_psidot"); _debug = getprop("/sim/model/autopush/debug") or 0; - if (_to_wp == 1) { + if (!_to_wp) { var (psi_park, D_park) = courseAndDistance(_route[0], _route[1]); _push = (abs(geo.normdeg180(getprop("/orientation/heading-deg") - psi_park)) > 90.0); _sign = 1.0 - 2.0 * _push; + _advance_wp(); + _psi = 0.0; } + _time = getprop("/sim/time/elapsed-sec"); _timer.start(); var endsign = _sign; for (ii = _to_wp; ii < size(_route_reverse); ii += 1) { @@ -123,9 +138,9 @@ var start = func() { } var (psi_twy, D_twy) = courseAndDistance(_route[size(_route) - 2], _route[size(_route) - 1]); if (endsign < 0.0) { - screen.log.write("(pushback): Push back facing " ~ int(geo.normdeg(psi_twy + 180.0 - magvar())) ~ "."); + screen.log.write("(pushback): Push back facing " ~ math.round(geo.normdeg(psi_twy + 180.0 - magvar()), 1.0) ~ "."); } else { - screen.log.write("(pushback): Tow facing " ~ int(geo.normdeg(psi_twy - magvar())) ~ "."); + screen.log.write("(pushback): Tow facing " ~ math.round(geo.normdeg(psi_twy - magvar()), 1.0) ~ "."); } } @@ -136,7 +151,5 @@ var pause = func() { var stop = func() { pause(); - _to_wp = 1; - _is_last_wp = 0; - _is_reverse_wp = 0; + _to_wp = 0; } diff --git a/Nasal/autopush_route.nas b/Nasal/autopush_route.nas index 27ac59f5..b67c6072 100644 --- a/Nasal/autopush_route.nas +++ b/Nasal/autopush_route.nas @@ -15,15 +15,25 @@ var _user_point_modes = dynarr.dynarr.new(4); # Modes: 0 = Bezier node, 1 = Bezi var _route = []; var _route_hdg = []; var _route_reverse = []; -var _view_index = nil; +var _top_view_index = nil; +var _top_view_heading_offset_deg = 180.0; +var _reset_view_index = nil; +var _view_z_offset = nil; +var _view_pitch_offset_deg = nil; +var _view_heading_offset_deg = nil; var _user_point_models = []; var _waypoint_models = []; var _N = 0; var _show = 0; -var _view_changed_or_external = 0; var _R_turn_min = 0; var _invalid = 0; +# Make top-down view point north in old FG. +var __fg_version = num(string.replace(getprop("/sim/version/flightgear"),".","")); +if (__fg_version < 201920) { + _top_view_heading_offset_deg = 94.5; +} + var _add = func(pos) { if (_N) { @@ -77,11 +87,11 @@ var _stop = func(fail = 0) { _listener = nil; if (!fail) { settimer(func() { - _reset_view(); + _finalize_top_view(); gui.popupTip("Done"); }, 1.0); } else { - _reset_view(); + _finalize_top_view(); } } } @@ -129,31 +139,36 @@ var _clear_waypoint_models = func() { setsize(_waypoint_models, 0); } -var _set_view = func() { - if (!getprop("/sim/current-view/internal")){ - _view_changed_or_external = 1; +var top_view = func() { + if (_view_listener != nil) { return; } - _view_index = getprop("/sim/current-view/view-number"); - # While "Chase View Without Yaw" would have looked better, only "Model View" resets its z-offset back to normal by itself. - setprop("/sim/current-view/view-number", view.indexof("Model View")); + _top_view_index = view.indexof("Chase View Without Yaw"); + _reset_view_index = getprop("/sim/current-view/view-number"); + setprop("/sim/current-view/view-number", _top_view_index); + _view_pitch_offset_deg = getprop("/sim/current-view/pitch-offset-deg"); + _view_heading_offset_deg = getprop("/sim/current-view/heading-offset-deg"); + _view_z_offset = getprop("/sim/current-view/z-offset-m"); setprop("/sim/current-view/z-offset-m", -500.0); + setprop("/sim/current-view/heading-offset-deg", _top_view_heading_offset_deg); setprop("/sim/current-view/pitch-offset-deg", 90.0); - setprop("/sim/current-view/heading-offset-deg", 0.0); - _view_changed_or_external = 0; _view_listener = setlistener("/sim/current-view/name", func { - _view_changed_or_external = 1; - }); + _finalize_top_view(); + }, 0, 0); } -var _reset_view = func() { - if (!_view_changed_or_external) { - setprop("/sim/current-view/view-number", _view_index); - } - if (_view_listener != nil) { - removelistener(_view_listener); - _view_listener = nil; +var _finalize_top_view = func() { + if (_view_listener == nil) { + return; } + removelistener(_view_listener); + _view_listener = nil; + # Go back to the view to restore settings, in case user has switched away. + setprop("/sim/current-view/view-number", _top_view_index); + setprop("/sim/current-view/z-offset-m", _view_z_offset); + setprop("/sim/current-view/heading-offset-deg", _view_heading_offset_deg); + setprop("/sim/current-view/pitch-offset-deg", _view_pitch_offset_deg); + setprop("/sim/current-view/view-number", _reset_view_index); if (!_show) { _clear_user_point_models(); _clear_waypoint_models(); @@ -238,20 +253,24 @@ var _calculate_bezier = func(user_points) { len += user_points[i].distance_to(user_points[i + 1]); } - var step = _R_turn_min / len; + if (len < _R_turn_min) { + route.add(geo.Coord.new(user_points[PNumber - 1])) + } else { + var step = _R_turn_min / len; - for (var i = step; i < 1 - step; i+= step) { - # start iterating from 1 cause we don't need to iterate over Pn - for (var j = 1; j < PNumber; j += 1) { - for (var k = 0; k < PNumber - j; k += 1) { - pointList[j][k] = geo.Coord.new(pointList[j - 1][k]); - var dist = pointList[j - 1][k].distance_to(pointList[j - 1][k + 1]); - var course = pointList[j - 1][k].course_to(pointList[j - 1][k + 1]); - pointList[j][k].apply_course_distance(course, dist * i); + for (var i = step; i < 1 - step; i+= step) { + # start iterating from 1 cause we don't need to iterate over Pn + for (var j = 1; j < PNumber; j += 1) { + for (var k = 0; k < PNumber - j; k += 1) { + pointList[j][k] = geo.Coord.new(pointList[j - 1][k]); + var dist = pointList[j - 1][k].distance_to(pointList[j - 1][k + 1]); + var course = pointList[j - 1][k].course_to(pointList[j - 1][k + 1]); + pointList[j][k].apply_course_distance(course, dist * i); + } } + pointList[PNumber - 1][0].set_alt(geo.elevation(pointList[PNumber - 1][0].lat(),pointList[PNumber - 1][0].lon())); + route.add(geo.Coord.new(pointList[PNumber - 1][0])); } - pointList[PNumber - 1][0].set_alt(geo.elevation(pointList[PNumber - 1][0].lat(),pointList[PNumber - 1][0].lon())); - route.add(geo.Coord.new(pointList[PNumber - 1][0])); } } @@ -317,21 +336,21 @@ var _check_turn_radius = func() { setlistener("/sim/model/autopush/route/show", func(p) { var show = p.getValue(); if (_listener == nil) { - if (show > _show) { + if (show) { _place_user_point_models(); _place_waypoint_models(); - } else if (show < _show) { + } else { _clear_user_point_models(); _clear_waypoint_models(); } } _show = show; -}); +}, 1, 0); var enter = func() { clear(); - _set_view(); + top_view(); _R_turn_min = getprop("/sim/model/autopush/min-turn-radius-m"); var wp = geo.aircraft_position(); var H = geo.elevation(wp.lat(), wp.lon()); From 3b6b6dd3b178b2613bdaa49f17e030580a1165e1 Mon Sep 17 00:00:00 2001 From: merspieler Date: Thu, 24 Oct 2019 03:34:02 +0000 Subject: [PATCH 2/2] Move autopush config to own file Signed-off-by: merspieler --- A320-main.xml | 34 +----------------------------- AircraftConfig/autopush-config.xml | 30 ++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 33 deletions(-) create mode 100644 AircraftConfig/autopush-config.xml diff --git a/A320-main.xml b/A320-main.xml index 2d4ee012..11175d12 100644 --- a/A320-main.xml +++ b/A320-main.xml @@ -15,39 +15,7 @@ - - 0 - 0 - - 1 - - - - 1.0 - 0.0 - 0.5 - 0.15 - 0.25 - 0.1 - 0.0 - 0.0 - 0.0 - 15 - 5.0 - - 5.5 - 0.03 - 8.0 - 0.03 - 1.0 - 0.03 - 1.0 - - - - - false - + Wing diff --git a/AircraftConfig/autopush-config.xml b/AircraftConfig/autopush-config.xml new file mode 100644 index 00000000..0e9926c0 --- /dev/null +++ b/AircraftConfig/autopush-config.xml @@ -0,0 +1,30 @@ + + + + 1.0 + 0.0 + 15 + 5.0 + + 1 + + false + 0.0 + 0.5 + 0.15 + 0.25 + 0.1 + 0.0 + 0.0 + + 5.5 + 0.03 + 1.0 + 0.03 + 1.0 + + + + + 0 +