Fix oscillation drone
This commit is contained in:
parent
700d60ca27
commit
9137a98af3
4 changed files with 66 additions and 12 deletions
14
drone.lua
14
drone.lua
|
|
@ -130,6 +130,20 @@ local PARAMS = {
|
|||
pas = 0.5, mini = 0, maxi = 10 },
|
||||
{ chemin = "CALIB.ATTENTE_NIVEAU", label = "attente calib mot. (s)",
|
||||
pas = 0.5, mini = 0.5, maxi = 5 },
|
||||
{ chemin = "ASSIETTE_PLAFOND", label = "autorite assiette",
|
||||
pas = 0.05, mini = 0.05, maxi = 1 },
|
||||
{ chemin = "PID.tangage.kp", label = "assiette T kp", pas = 0.25,
|
||||
mini = 0 },
|
||||
{ chemin = "PID.tangage.ki", label = "assiette T ki", pas = 0.05,
|
||||
mini = 0 },
|
||||
{ chemin = "PID.tangage.kd", label = "assiette T kd", pas = 0.25,
|
||||
mini = 0 },
|
||||
{ chemin = "PID.roulis.kp", label = "assiette R kp", pas = 0.25,
|
||||
mini = 0 },
|
||||
{ chemin = "PID.roulis.ki", label = "assiette R ki", pas = 0.05,
|
||||
mini = 0 },
|
||||
{ chemin = "PID.roulis.kd", label = "assiette R kd", pas = 0.25,
|
||||
mini = 0 },
|
||||
{ chemin = "V_MONTEE_MAX", label = "v montee max (b/s)",
|
||||
pas = 0.5, mini = 0.5 },
|
||||
{ chemin = "V_DESCENTE_MAX", label = "v descente max (b/s)",
|
||||
|
|
|
|||
12
lib/conf.lua
12
lib/conf.lua
|
|
@ -82,10 +82,18 @@ return {
|
|||
alt = { kp = 1.2 }, -- erreur alt -> v cible (1/s)
|
||||
montee = { kp = 40, ki = 60, kd = 5 }, -- v -> delta rpm
|
||||
descente = { kp = 40, ki = 60, kd = 5 },
|
||||
tangage = { kp = 4, ki = 0.5, kd = 8 },
|
||||
roulis = { kp = 4, ki = 0.5, kd = 8 },
|
||||
-- gains d'ASSIETTE: toujours lus ici (editables en direct page
|
||||
-- PARAM), JAMAIS remplaces par les calibrations pid/pidmath
|
||||
tangage = { kp = 2, ki = 0.2, kd = 3 },
|
||||
roulis = { kp = 2, ki = 0.2, kd = 3 },
|
||||
},
|
||||
|
||||
-- Autorite maximale de la correction d'assiette (et du trim), en
|
||||
-- FRACTION du rpm de sustentation courant: l'autorite suit le
|
||||
-- point de fonctionnement du drone (20 rpm comme 200 rpm) au lieu
|
||||
-- d'etre figee a VMAX/2.
|
||||
ASSIETTE_PLAFOND = 0.5,
|
||||
|
||||
------------------------------------------------------------------
|
||||
-- Ecrans (faces des deux Create_DisplayLink sur le PC)
|
||||
------------------------------------------------------------------
|
||||
|
|
|
|||
18
lib/ihm.lua
18
lib/ihm.lua
|
|
@ -333,16 +333,25 @@ function Ihm.nouveau(conf, materiel, journal)
|
|||
------------------------------------------------------------------
|
||||
-- PAGE PARAMS (edition tactile; surcharges dans drone.etat)
|
||||
------------------------------------------------------------------
|
||||
local defilParams = 0
|
||||
local function dessinerPageParams(ctx)
|
||||
texte(1, 2, "surcharges sauvees dans drone.etat", colors.lightGray)
|
||||
local params = ctx.params or {}
|
||||
local parPage = H - 3
|
||||
local maxDefil = math.max(0, #params - parPage)
|
||||
if defilParams > maxDefil then defilParams = maxDefil end
|
||||
texte(1, 2, ("surcharges dans drone.etat (%d-%d/%d)"):format(
|
||||
defilParams + 1, math.min(defilParams + parPage, #params),
|
||||
#params), colors.lightGray)
|
||||
bouton(L - 9, 2, "^", { type = "defilparam", sens = -1 })
|
||||
bouton(L - 4, 2, "v", { type = "defilparam", sens = 1 })
|
||||
local y = 3
|
||||
for i2, p in ipairs(ctx.params or {}) do
|
||||
for i2 = defilParams + 1, math.min(defilParams + parPage, #params) do
|
||||
local p = params[i2]
|
||||
texte(1, y, ("%-24s"):format(p.label))
|
||||
texte(26, y, tostring(p.valeur), colors.yellow)
|
||||
bouton(L - 9, y, "-", { type = "param", idx = i2, sens = -1 })
|
||||
bouton(L - 4, y, "+", { type = "param", idx = i2, sens = 1 })
|
||||
y = y + 1
|
||||
if y > H then break end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -389,6 +398,9 @@ function Ihm.nouveau(conf, materiel, journal)
|
|||
if z.action.type == "page" then
|
||||
page = z.action.valeur
|
||||
return { type = "redessiner" }
|
||||
elseif z.action.type == "defilparam" then
|
||||
defilParams = math.max(0, defilParams + z.action.sens * 4)
|
||||
return { type = "redessiner" }
|
||||
end
|
||||
return z.action
|
||||
end
|
||||
|
|
|
|||
|
|
@ -39,7 +39,17 @@ function Pilotage.nouveau(conf, etat, materiel, Pid, journal)
|
|||
if v < mini then return mini elseif v > maxi then return maxi end
|
||||
return v
|
||||
end
|
||||
local gains = etat.pid or conf.PID
|
||||
|
||||
-- Gains: montee/descente viennent des calibrations (etat.pid),
|
||||
-- l'assiette vient TOUJOURS de la conf (reference vive: la page
|
||||
-- PARAM agit immediatement)
|
||||
local gains = {
|
||||
alt = conf.PID.alt,
|
||||
montee = (etat.pid and etat.pid.montee) or conf.PID.montee,
|
||||
descente = (etat.pid and etat.pid.descente) or conf.PID.descente,
|
||||
tangage = conf.PID.tangage,
|
||||
roulis = conf.PID.roulis,
|
||||
}
|
||||
|
||||
local pidMontee = Pid.nouveau(gains.montee, -VMAX, VMAX, 20)
|
||||
local pidDescente = Pid.nouveau(gains.descente, -VMAX, VMAX, 20)
|
||||
|
|
@ -168,12 +178,14 @@ function Pilotage.nouveau(conf, etat, materiel, Pid, journal)
|
|||
end
|
||||
|
||||
function p.reglerGains(nouveaux)
|
||||
gains = nouveaux
|
||||
etat.pid = nouveaux
|
||||
gains.alt = nouveaux.alt or gains.alt
|
||||
gains.montee = nouveaux.montee or gains.montee
|
||||
gains.descente = nouveaux.descente or gains.descente
|
||||
-- seuls les gains verticaux sont persistes: l'assiette reste
|
||||
-- pilotee par la conf / page PARAM
|
||||
etat.pid = { montee = gains.montee, descente = gains.descente }
|
||||
pidMontee:reglerGains(gains.montee)
|
||||
pidDescente:reglerGains(gains.descente)
|
||||
pidTangage:reglerGains(gains.tangage)
|
||||
pidRoulis:reglerGains(gains.roulis)
|
||||
end
|
||||
|
||||
function p.reglerFacteurProp(f)
|
||||
|
|
@ -196,14 +208,22 @@ function Pilotage.nouveau(conf, etat, materiel, Pid, journal)
|
|||
-- la cargaison); le PID reste centre sur la dynamique.
|
||||
local function appliquerHelices(base, tangage, roulis, dt,
|
||||
anglesCibles, adapter)
|
||||
-- autorite d'assiette proportionnelle au point de fonctionnement
|
||||
local plafond = math.max(2,
|
||||
conf.ASSIETTE_PLAFOND * (p.rpmSustentation() + rpmAdapt))
|
||||
pidTangage.borneMin, pidTangage.borneMax = -plafond, plafond
|
||||
pidRoulis.borneMin, pidRoulis.borneMax = -plafond, plafond
|
||||
|
||||
local corrTangage = SIGNE_TANGAGE
|
||||
* pidTangage:calculer(anglesCibles.tangage or 0, tangage, dt)
|
||||
local corrRoulis = SIGNE_ROULIS
|
||||
* pidRoulis:calculer(anglesCibles.roulis or 0, roulis, dt)
|
||||
if adapter then
|
||||
local taux = conf.ADAPTATION.TAUX_TRIM * dt
|
||||
trimTangage = trimTangage + taux * corrTangage
|
||||
trimRoulis = trimRoulis + taux * corrRoulis
|
||||
trimTangage = borner(trimTangage + taux * corrTangage,
|
||||
-plafond, plafond)
|
||||
trimRoulis = borner(trimRoulis + taux * corrRoulis,
|
||||
-plafond, plafond)
|
||||
end
|
||||
for role, s in pairs(SIGNES) do
|
||||
materiel.reglerRsc(role, borner(base
|
||||
|
|
|
|||
Loading…
Reference in a new issue