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 },
|
pas = 0.5, mini = 0, maxi = 10 },
|
||||||
{ chemin = "CALIB.ATTENTE_NIVEAU", label = "attente calib mot. (s)",
|
{ chemin = "CALIB.ATTENTE_NIVEAU", label = "attente calib mot. (s)",
|
||||||
pas = 0.5, mini = 0.5, maxi = 5 },
|
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)",
|
{ chemin = "V_MONTEE_MAX", label = "v montee max (b/s)",
|
||||||
pas = 0.5, mini = 0.5 },
|
pas = 0.5, mini = 0.5 },
|
||||||
{ chemin = "V_DESCENTE_MAX", label = "v descente max (b/s)",
|
{ 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)
|
alt = { kp = 1.2 }, -- erreur alt -> v cible (1/s)
|
||||||
montee = { kp = 40, ki = 60, kd = 5 }, -- v -> delta rpm
|
montee = { kp = 40, ki = 60, kd = 5 }, -- v -> delta rpm
|
||||||
descente = { kp = 40, ki = 60, kd = 5 },
|
descente = { kp = 40, ki = 60, kd = 5 },
|
||||||
tangage = { kp = 4, ki = 0.5, kd = 8 },
|
-- gains d'ASSIETTE: toujours lus ici (editables en direct page
|
||||||
roulis = { kp = 4, ki = 0.5, kd = 8 },
|
-- 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)
|
-- 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)
|
-- PAGE PARAMS (edition tactile; surcharges dans drone.etat)
|
||||||
------------------------------------------------------------------
|
------------------------------------------------------------------
|
||||||
|
local defilParams = 0
|
||||||
local function dessinerPageParams(ctx)
|
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
|
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(1, y, ("%-24s"):format(p.label))
|
||||||
texte(26, y, tostring(p.valeur), colors.yellow)
|
texte(26, y, tostring(p.valeur), colors.yellow)
|
||||||
bouton(L - 9, y, "-", { type = "param", idx = i2, sens = -1 })
|
bouton(L - 9, y, "-", { type = "param", idx = i2, sens = -1 })
|
||||||
bouton(L - 4, y, "+", { type = "param", idx = i2, sens = 1 })
|
bouton(L - 4, y, "+", { type = "param", idx = i2, sens = 1 })
|
||||||
y = y + 1
|
y = y + 1
|
||||||
if y > H then break end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -389,6 +398,9 @@ function Ihm.nouveau(conf, materiel, journal)
|
||||||
if z.action.type == "page" then
|
if z.action.type == "page" then
|
||||||
page = z.action.valeur
|
page = z.action.valeur
|
||||||
return { type = "redessiner" }
|
return { type = "redessiner" }
|
||||||
|
elseif z.action.type == "defilparam" then
|
||||||
|
defilParams = math.max(0, defilParams + z.action.sens * 4)
|
||||||
|
return { type = "redessiner" }
|
||||||
end
|
end
|
||||||
return z.action
|
return z.action
|
||||||
end
|
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
|
if v < mini then return mini elseif v > maxi then return maxi end
|
||||||
return v
|
return v
|
||||||
end
|
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 pidMontee = Pid.nouveau(gains.montee, -VMAX, VMAX, 20)
|
||||||
local pidDescente = Pid.nouveau(gains.descente, -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
|
end
|
||||||
|
|
||||||
function p.reglerGains(nouveaux)
|
function p.reglerGains(nouveaux)
|
||||||
gains = nouveaux
|
gains.alt = nouveaux.alt or gains.alt
|
||||||
etat.pid = nouveaux
|
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)
|
pidMontee:reglerGains(gains.montee)
|
||||||
pidDescente:reglerGains(gains.descente)
|
pidDescente:reglerGains(gains.descente)
|
||||||
pidTangage:reglerGains(gains.tangage)
|
|
||||||
pidRoulis:reglerGains(gains.roulis)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function p.reglerFacteurProp(f)
|
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.
|
-- la cargaison); le PID reste centre sur la dynamique.
|
||||||
local function appliquerHelices(base, tangage, roulis, dt,
|
local function appliquerHelices(base, tangage, roulis, dt,
|
||||||
anglesCibles, adapter)
|
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
|
local corrTangage = SIGNE_TANGAGE
|
||||||
* pidTangage:calculer(anglesCibles.tangage or 0, tangage, dt)
|
* pidTangage:calculer(anglesCibles.tangage or 0, tangage, dt)
|
||||||
local corrRoulis = SIGNE_ROULIS
|
local corrRoulis = SIGNE_ROULIS
|
||||||
* pidRoulis:calculer(anglesCibles.roulis or 0, roulis, dt)
|
* pidRoulis:calculer(anglesCibles.roulis or 0, roulis, dt)
|
||||||
if adapter then
|
if adapter then
|
||||||
local taux = conf.ADAPTATION.TAUX_TRIM * dt
|
local taux = conf.ADAPTATION.TAUX_TRIM * dt
|
||||||
trimTangage = trimTangage + taux * corrTangage
|
trimTangage = borner(trimTangage + taux * corrTangage,
|
||||||
trimRoulis = trimRoulis + taux * corrRoulis
|
-plafond, plafond)
|
||||||
|
trimRoulis = borner(trimRoulis + taux * corrRoulis,
|
||||||
|
-plafond, plafond)
|
||||||
end
|
end
|
||||||
for role, s in pairs(SIGNES) do
|
for role, s in pairs(SIGNES) do
|
||||||
materiel.reglerRsc(role, borner(base
|
materiel.reglerRsc(role, borner(base
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue