mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Vehicles - Add Auto-Throttle to Planes (#8275)
* Add auto throttle to planes * add newline * clarify things * Use a better deltaTime value. Takes into account game pause * add coment * Add auto throttle cancellation on user input * misc fixes
This commit is contained in:
parent
be8a50c8a9
commit
0f7376f60c
@ -1,4 +1,4 @@
|
||||
|
||||
PREP(autoThrottle);
|
||||
PREP(speedLimiter);
|
||||
PREP(startEngine);
|
||||
PREP(setVehicleStartDelay);
|
@ -19,11 +19,16 @@ GVAR(isSpeedLimiter) = false;
|
||||
// Conditions: specific
|
||||
if !(ACE_player == driver vehicle ACE_player &&
|
||||
{vehicle ACE_player isKindOf 'Car' ||
|
||||
{vehicle ACE_player isKindOf 'Tank'}}) exitWith {false};
|
||||
{vehicle ACE_player isKindOf 'Tank'} ||
|
||||
{vehicle ACE_player isKindOf 'Plane'}}) exitWith {false};
|
||||
|
||||
GVAR(isUAV) = false;
|
||||
// Statement
|
||||
[ACE_player, vehicle ACE_player] call FUNC(speedLimiter);
|
||||
if (vehicle ACE_player isKindOf 'Plane') then {
|
||||
[ACE_player, vehicle ACE_player] call FUNC(autoThrottle);
|
||||
} else {
|
||||
[ACE_player, vehicle ACE_player] call FUNC(speedLimiter);
|
||||
};
|
||||
true
|
||||
};
|
||||
|
||||
|
98
addons/vehicles/functions/fnc_autoThrottle.sqf
Normal file
98
addons/vehicles/functions/fnc_autoThrottle.sqf
Normal file
@ -0,0 +1,98 @@
|
||||
#include "script_component.hpp"
|
||||
/*
|
||||
* Author: Brandon (TCVM)
|
||||
* Toggle speed limiter for Driver in Plane. Uses a simple PID controller to manage thrust
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Driver <OBJECT>
|
||||
* 1: Vehicle <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [player, car] call ace_vehicles_fnc_autoThrottle
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#define PID_P 1
|
||||
#define PID_I 0.3
|
||||
#define PID_D 0
|
||||
#define EPSILON 0.001
|
||||
|
||||
params ["_driver", "_vehicle"];
|
||||
|
||||
if (GVAR(isSpeedLimiter)) exitWith {
|
||||
[localize LSTRING(Off)] call EFUNC(common,displayTextStructured);
|
||||
playSound "ACE_Sound_Click";
|
||||
GVAR(isSpeedLimiter) = false;
|
||||
};
|
||||
|
||||
[localize LSTRING(On)] call EFUNC(common,displayTextStructured);
|
||||
playSound "ACE_Sound_Click";
|
||||
GVAR(isSpeedLimiter) = true;
|
||||
|
||||
// Convert forward speed to KM/H. `speed _vehicle` isnt accurate enough for this controller to work well, so its easier to use M/S. The system assumes it is KM/H so we need the conversion
|
||||
GVAR(speedLimit) = (((velocityModelSpace _vehicle) select 1) * 3.6) max 5;
|
||||
|
||||
[{
|
||||
params ["_args", "_idPFH"];
|
||||
_args params ["_driver", "_vehicle", "_autothrottleParameters"];
|
||||
_autothrottleParameters params ["_lastVelocity", "_integralValue", "_lastTime", "_lastThrottleValue", "_throttleLogValue"];
|
||||
|
||||
// this will take into account game being pausesd
|
||||
private _deltaTime = CBA_missionTime - _lastTime;
|
||||
|
||||
if (_driver != driver _vehicle) then {
|
||||
GVAR(isSpeedLimiter) = false;
|
||||
};
|
||||
|
||||
if (_throttleLogValue == 0) then {
|
||||
_throttleLogValue = 1;
|
||||
};
|
||||
|
||||
private _currentThrottle = (airplaneThrottle _vehicle) ^ _throttleLogValue;
|
||||
if (_lastThrottleValue != -1 && { EPSILON < abs (_currentThrottle - _lastThrottleValue) }) then {
|
||||
// player/script has moved throttle, stop limiting speed
|
||||
// ARMA will allow an increment of one throttle unit per frame, so if there is a difference between our known throttle value and actual throttle value, the player must of changed it
|
||||
[localize LSTRING(Off)] call EFUNC(common,displayTextStructured);
|
||||
playSound "ACE_Sound_Click";
|
||||
GVAR(isSpeedLimiter) = false;
|
||||
};
|
||||
|
||||
if (!GVAR(isSpeedLimiter)) exitWith {
|
||||
[_idPFH] call CBA_fnc_removePerFrameHandler;
|
||||
};
|
||||
|
||||
if (_deltaTime == 0) exitWith {};
|
||||
|
||||
private _forwardVelocity = (velocityModelSpace _vehicle) select 1;
|
||||
// convert from KM/H to M/S
|
||||
private _velocityError = (GVAR(speedLimit) / 3.6) - _forwardVelocity;
|
||||
|
||||
// strictly speaking this would work better if this error was time to zero acceleration. I can't find the acceleration values in config, however, so this works instead
|
||||
private _errorDiff = _velocityError - _lastVelocity;
|
||||
|
||||
private _p = PID_P * _velocityError;
|
||||
private _i = _integralValue + (PID_I * _errorDiff * _deltaTime);
|
||||
private _d = PID_D * _errorDiff / _deltaTime;
|
||||
|
||||
private _outputBeforeSaturation = _p + _i + _d;
|
||||
private _throttle = 0 max (_outputBeforeSaturation min 1);
|
||||
|
||||
// if we are saturated, we clamp the integral value to avoid integral windup
|
||||
if (_outputBeforeSaturation != _throttle) then {
|
||||
// saturated
|
||||
_i = _integralValue;
|
||||
_throttle = 0 max ((_p + _d) min 1);
|
||||
};
|
||||
|
||||
_vehicle setAirplaneThrottle _throttle;
|
||||
|
||||
_autothrottleParameters set [0, _d];
|
||||
_autothrottleParameters set [1, _i];
|
||||
_autothrottleParameters set [2, CBA_missionTime];
|
||||
_autothrottleParameters set [3, _throttle];
|
||||
|
||||
}, 0, [_driver, _vehicle, [0, 0, CBA_missionTime, -1, getNumber (configOf _vehicle >> "throttleToThrustLogFactor")]]] call CBA_fnc_addPerFrameHandler;
|
||||
|
Loading…
Reference in New Issue
Block a user