-------------------------------------------------------------------- -- lib/conf.lua : fichier de configuration utilisateur (drone.conf) -- Cree le fichier avec des valeurs par defaut commentees s'il -- n'existe pas; avertit tant que `verifie` n'est pas passe a true. -------------------------------------------------------------------- local Conf = {} local CHEMIN = "drone.conf" local MODELE = [[ -- drone.conf : parametres utilisateur du quadricoptere. -- RELIRE ET AJUSTER chaque valeur, puis passer verifie a true. -- NB: les mappages (gimbal, joystick, typewriter, capteurs, RSC) -- ne sont PAS ici: ils sont calibres en jeu et stockes dans drone.etat. return { verifie = false, -- passer a true apres relecture ------------------------------------------------------------------ -- Altitudes (plan de l'altitude sensor du PC central) ------------------------------------------------------------------ Y_VOL = 90, -- altitude de croisiere du mode auto Y_MINI = 70, -- plancher de securite: en dessous, la -- descente exige un sol POSABLE detecte -- (evite d'atterrir dans un ocean) ------------------------------------------------------------------ -- Assiette ------------------------------------------------------------------ ANGLE_MAX = 1.5, -- inclinaison max toleree hors mode drone (deg) ANGLE_DRONE_MAX = 15, -- inclinaison commandee max en mode drone (deg) ------------------------------------------------------------------ -- Sol ------------------------------------------------------------------ DIST_SOL = 1.2, -- optical sensor: distance <= => au sol -- (15.5 = aucun bloc detecte) VITESSE_ATTERRISSAGE = 1.0, -- descente du mode atterrissage (blocs/s) BLOCS_INTERDITS = { -- blocs sur lesquels ne PAS se poser ["minecraft:water"] = true, ["minecraft:lava"] = true, }, ------------------------------------------------------------------ -- Position reelle affichee = position GPS + ces offsets ------------------------------------------------------------------ OFFSET_X = 0, OFFSET_Y = 0, OFFSET_Z = 0, ------------------------------------------------------------------ -- Regulation (cascade altitude -> vitesse verticale -> rpm) ------------------------------------------------------------------ VITESSE_RAMPE = 3.0, -- rampe de consigne d'altitude (blocs/s) VITESSE_RSC_MAX = 256, -- borne des rotation speed controllers V_MONTEE_MAX = 3.0, -- vitesse verticale max en montee (b/s) V_DESCENTE_MAX = 2.0, -- vitesse verticale max en descente (b/s) -- Feedforward de sustentation: le rpm d'equilibre est calcule -- depuis le poids et la poussee, le PID ne corrige qu'autour. -- Transport a charge variable: POIDS est le poids A VIDE; la -- charge est estimee en vol (adaptation) et la poussee est -- corrigee par la pression mesuree (elle diminue avec l'altitude). POIDS = 32000, -- poids A VIDE du drone (pixelNewton) POUSSEE_HELICE_MAX = 10000, -- poussee d'UNE helice a -- VITESSE_RSC_MAX et PRESSION_REF (pN) POUSSEE_EXPOSANT = 1, -- poussee ~ rpm^exp (1 lineaire, 2 carre) PRESSION_REF = 1.0, -- pression a laquelle POUSSEE_HELICE_MAX -- est mesuree (getAirPressure) RATIO_CHARGE_MAX = 0.60, -- poids total max = ratio * 4 * poussee -- de reference (alerte SURCHARGE au dela) -- Adaptation en vol (le drone se pese et se trime en stationnaire) ADAPTATION = { TAUX_POIDS = 0.05, -- vitesse de transfert vers le -- feedforward (1/s); petit = stable TAUX_TRIM = 0.05, -- idem pour le trim d'assiette SEUIL_DESEQUILIBRE = 15, -- |trim| (rpm) declenchant l'alerte -- "chargement desequilibre" }, PID = { -- gains par defaut (remplaces par calib) 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 }, }, ------------------------------------------------------------------ -- Ecrans (faces des deux Create_DisplayLink sur le PC) ------------------------------------------------------------------ ECRANS = { conduite = "front", -- vitesse, altitudes, invites carburant = "back", -- reserve + autonomie estimee }, ------------------------------------------------------------------ -- Carburant (2 cuves create:fluid_tank sur le reseau) ------------------------------------------------------------------ CARBURANT = { CAPACITE_TANK = 8000, -- mB par cuve, si tanks() ne donne pas -- la capacite SEUIL_ALERTE = 0.15, -- alerte sous ce ratio de reserve PERIODE = 5, -- periode d'echantillonnage (s) LISSAGE = 0.1, -- apprentissage glissant de la conso -- (EMA: 0.1 = lent et stable, 0.5 = reactif) }, ------------------------------------------------------------------ -- Moteur (sortie redstone bottom: 15=arret, 14=mini, 0=maxi) -- Le moteur est dimensionne pour suffire; en cas de surcharge -- malgre tout, les PROPULSEURS sont reduits en priorite + alerte. ------------------------------------------------------------------ MOTEUR = { STRESS_HAUT = 0.90, -- au dela: augmenter le moteur STRESS_BAS = 0.60, -- en deca: reduire le moteur (economie) SURCHARGE = 0.98, -- au dela: reduire les propulseurs + alerte PERIODE = 1.0, -- periode de l'asservissement (s) BOOST = 4.0, -- pre-boost a pleine puissance lors des -- changements de regime exigeants (s) }, ------------------------------------------------------------------ -- Navigation (modes auto / position, points enregistres) ------------------------------------------------------------------ NAV = { SEUIL_ARRIVEE = 2.0, -- distance a la cible consideree atteinte VITESSE_GPS_MIN = 0.5, -- vitesse mini pour estimer le cap (b/s) MAX_POINTS = 10, -- points nommes enregistrables }, ------------------------------------------------------------------ -- Calibration (voir README) ------------------------------------------------------------------ CALIB = { AMPLITUDE = 4, -- pid: hauteur des echelons de test (blocs) TOL_DEPASSEMENT = 0.0, -- pid: depassement tolere (0 = strict) BANDE = 0.3, -- pid: bande de convergence (blocs) DELAI_STABLE = 2.0, -- pid: duree dans la bande = converge (s) TIMEOUT = 25, -- pid: duree max d'un echelon (s) MAX_ITER = 6, -- pid: essais par direction IMPULSION_PAS = 16, -- rsc: increment de vitesse (rpm) RPM_MANUEL = 10, -- rsc manuel: vitesse de reperage (rpm) IMPULSION_SEUIL = 0.8, -- rsc/gimbal: variation d'angle declarante (deg) JOYSTICK_SEUIL = 8, -- joystick: niveau declarant une face (0..15) }, } ]] function Conf.charger(journal) if not fs.exists(CHEMIN) then local f = fs.open(CHEMIN, "w") f.write(MODELE) f.close() journal.alerte(CHEMIN .. " cree avec les valeurs par defaut: A PERSONNALISER") end local chargeur, err = loadfile(CHEMIN) if not chargeur then error("drone.conf invalide: " .. tostring(err), 0) end local conf = chargeur() if type(conf) ~= "table" then error("drone.conf doit retourner une table", 0) end if conf.verifie ~= true then journal.alerte("drone.conf non verifie: relire les parametres puis passer verifie a true") end return conf end -- Empreinte des parametres dont dependent les gains PID calibres. -- Si elle change, la calibration PID est invalidee. function Conf.empreintePid(conf) return textutils.serialize({ vmax = conf.VITESSE_RSC_MAX, rampe = conf.VITESSE_RAMPE, angle = conf.ANGLE_MAX, poids = conf.POIDS, poussee = conf.POUSSEE_HELICE_MAX, exposant = conf.POUSSEE_EXPOSANT, vmont = conf.V_MONTEE_MAX, vdesc = conf.V_DESCENTE_MAX, }) end return Conf