Create: Computing AgesDoc Brass
Périphériques

Brûleur à air chaud

Le brûleur sous un ballon de Create Aeronautics : l'air chaud qu'il donne, le remplissage de son ballon, et comment un ordinateur le pilote.

Il faut Create Aeronautics

Le brûleur à air chaud est un bloc de Create Aeronautics. Sans ce mod, il n'y a pas de brûleur, et peripheral.find("hot_air_burner") renvoie nil.

Le brûleur à air chaud (Hot Air Burner : Create Aeronautics n'est pas traduit, le bloc garde son nom anglais en jeu) se place sous un ballon et le remplit d'air chaud : c'est ce qui soulève un navire de Create Aeronautics. Un ordinateur relié au brûleur lit l'air chaud qu'il produit et le remplissage de son ballon, et surtout il règle la quantité d'air chaud que donne le brûleur : c'est ainsi qu'un pilote automatique monte, tient sa hauteur ou garde un navire à plat.

Son type de périphérique est hot_air_burner. Contre l'ordinateur, il s'appelle par sa face ("top"...) ; sur un Câble de données (Mini-ordinateur et plus récents), il reçoit un nom comme hot_air_burner@4,70,-2. Un navire en a souvent plusieurs : peripheral.list("hot_air_burner") donne tous leurs noms.

Brass
local bruleur = peripheral.find("hot_air_burner")
print(bruleur.output() .. " m3 d'air chaud, signal " .. bruleur.signal())

Chaque méthode relit le bloc quand on l'appelle. Quand le brûleur a disparu, l'appel arrête le programme avec burner removed (pour amount et set_amount) ou sensor removed (pour les autres) ; quand son chunk n'est pas chargé, avec peripheral is not loaded. Comme les capteurs, il a un read() qui renvoie toutes ses mesures dans une table (voir sensor.read()) : output, signal, amount, filled et capacity.

Méthodes
bruleur.output()L'air chaud que donne le brûleur en ce moment, en m³ : son débit multiplié par son signal de redstone, divisé par 15. 0 quand la flamme est éteinte.
bruleur.signal()Le signal de redstone le plus fort que reçoit le brûleur, de 0 (flamme éteinte) à 15 (pleine flamme).
bruleur.amount()Le débit réglé sur le panneau du brûleur (« Max Hot Air Output »), en m³ : l'air chaud qu'il demande à pleine flamme. Entre 5 et le maximum du serveur (500 par défaut, configuration serveur hot_air_burner_max). Un brûleur neuf commence au maximum.
bruleur.set_amount(m3)Règle le débit du brûleur, comme si l'on tournait son panneau, et renvoie la valeur retenue.
bruleur.filled()La quantité d'air chaud dans le ballon au-dessus du brûleur en ce moment, en m³. Elle s'approche peu à peu de la cible (la somme des productions de ses brûleurs, au plus la capacité) : elle suit donc chaque changement de débit avec retard.
bruleur.capacity()Le volume du ballon au-dessus du brûleur, en m³ : le nombre de blocs d'air qu'il enferme. nil sans ballon, comme pour filled.

Comment vole un ballon

Un programme ne pilote bien un ballon que s'il sait comment il se comporte. Cinq choses à savoir :

1. Le ballon est l'air sous un toit étanche. Le brûleur cherche tout droit vers le haut (jusqu'à 80 blocs par défaut, configuration serveur hot_air_burner_max_range) le premier bloc étanche à l'air, comme une enveloppe à air chaud (Hot Air Envelope). Le ballon est chaque couche d'air sous ce toit qui est fermée sur ses quatre côtés. Une coupe d'enveloppe à l'envers, ouverte en bas, fonctionne : le brûleur se place sous l'ouverture. Sa capacité est le nombre de blocs d'air à l'intérieur, un bloc d'air valant 1 m³ : une pièce de 3 blocs de large, 3 de long et 2 de haut contient 18 m³.

2. Le débit est une cible, pas un flux. Le panneau de réglage du brûleur (de 5 à 500 m³ par défaut) indique la quantité d'air chaud que le brûleur veut dans son ballon, pas ce qu'il souffle chaque seconde. Le brûleur demande débit × signal / 15 : tout à un signal de redstone de 15, un tiers à 5. Plusieurs brûleurs sous le même ballon additionnent leurs demandes.

3. Jamais plus que la capacité. Le ballon tend vers la somme des demandes, mais s'arrête à sa capacité : le reste est perdu. Un brûleur réglé à 500 sous un ballon de 18 ne le remplit pas mieux qu'un brûleur réglé à 18.

4. Le gaz est lent. L'air chaud ne saute pas à sa cible : il s'en approche peu à peu. Loin de la cible, il lui faut environ 9 secondes pour combler les deux tiers de l'écart, tout près une ou deux secondes. Un navire répond donc plusieurs secondes après un changement. Un programme qui pousse fort chaque fois que la hauteur n'est pas bonne la dépassera, encore et encore : il doit être doux et surveiller la vitesse de montée (voir Maintien d'altitude d'un dirigeable).

5. La portance faiblit avec la hauteur. L'air chaud du ballon soulève le navire, mais de moins en moins à mesure que l'air se raréfie (voir altitude_sensor.pressure()). Un navire se stabilise donc à la hauteur où sa portance égale son poids : donnez-lui plus d'air chaud et il monte vers un nouvel équilibre, moins et il redescend vers un autre. Chaque navire a aussi un plafond, où même un ballon plein ne peut plus le porter plus haut.

Allumer la flamme. La flamme suit la redstone, et seulement la redstone : le brûleur prend le signal le plus fort autour de lui, à nouveau chaque fois qu'un bloc voisin change. Aucune méthode ne l'allume : c'est l'ordinateur qui lui donne de la redstone.

  • un brûleur contre l'ordinateur : rs.set("top", 15) (la face où il se trouve) ;
  • un brûleur plus loin : une Liaison de redstone posée contre lui, pilotée avec link.set (voir link et Liaison de redstone) ;
  • une flamme toujours allumée : un levier ou un bloc de redstone contre le brûleur.

Pourquoi l'ordinateur règle le débit. La redstone n'a que 15 crans. Le débit va de 5 à 500 par pas de 1 (à la main, le panneau avance par pas de 5), et l'ordinateur peut le changer sur chaque brûleur à tout moment. Le montage habituel : toutes les flammes à 15, et l'on pilote avec le débit seul. Le brûleur demande alors exactement son débit.

La flamme

#

bruleur.output()

→ number

L'air chaud que donne le brûleur en ce moment, en m³ : son débit multiplié par son signal de redstone, divisé par 15. 0 quand la flamme est éteinte.

Renvoie
number
l'air chaud que demande le brûleur en ce moment, en m³

C'est la part du brûleur dans la cible du ballon (voir « Comment vole un ballon » plus haut), pas un flux par seconde. Les Lunettes d'ingénieur montrent le même nombre (« Hot Air output »).

Brass
local bruleur = peripheral.find("hot_air_burner")
print(bruleur.amount(), bruleur.signal(), bruleur.output())

Avec un débit de 120 et un signal de 10, il affiche 120, 10 et 80.

Voir aussi hot_air_burner.amount() hot_air_burner.signal()

#

bruleur.signal()

→ number

Le signal de redstone le plus fort que reçoit le brûleur, de 0 (flamme éteinte) à 15 (pleine flamme).

Renvoie
number
la puissance de redstone qui allume le brûleur, de 0 à 15

Un brûleur sans redstone ne donne rien, quel que soit son débit : vérifiez-le en premier quand un navire ne monte pas.

Brass
for _, nom in ipairs(peripheral.list("hot_air_burner")) do
  local bruleur = peripheral.wrap(nom)
  if bruleur.signal() == 0 then
    print(nom .. " n'est pas allumé : donnez-lui de la redstone")
  end
end

Un brûleur qui touche l'ordinateur est allumé par l'ordinateur lui-même :

Brass
rs.set("top", 15)   -- le brûleur est posé sur l'ordinateur

Le brûleur lit son nouveau signal quand la sortie de l'ordinateur change, à la fin du tick du programme.

Voir aussi hot_air_burner.output()

Le débit

#

bruleur.amount()

→ number

Le débit réglé sur le panneau du brûleur (« Max Hot Air Output »), en m³ : l'air chaud qu'il demande à pleine flamme. Entre 5 et le maximum du serveur (500 par défaut, configuration serveur hot_air_burner_max). Un brûleur neuf commence au maximum.

Renvoie
number
le débit réglé sur le brûleur, en m³
Brass
local bruleur = peripheral.find("hot_air_burner")
print("réglé à " .. bruleur.amount() .. " m3")

Voir aussi hot_air_burner.set_amount()

#

bruleur.set_amount(m3)

→ number

Règle le débit du brûleur, comme si l'on tournait son panneau, et renvoie la valeur retenue.

Paramètres
m3 number
le nouveau débit, un nombre entier de m³
Renvoie
number
le débit retenu, entre 5 et le maximum du serveur

La valeur est gardée entre 5 et le maximum du serveur (500 par défaut), et n'importe quel entier entre les deux convient, plus fin que les pas de 5 du panneau. Le nombre doit être entier : bruleur.set_amount(12.5) arrête le programme avec bad argument #1 to 'set_amount' (number has no integer representation). Arrondissez donc vos calculs avec math.floor.

Brass
local bruleur = peripheral.find("hot_air_burner")
print(bruleur.set_amount(42))
print(bruleur.set_amount(2))
print(bruleur.set_amount(100000))

Sur un serveur aux réglages par défaut, cela affiche 42, puis 5 (le minimum), puis 500 (le maximum). Cette dernière astuce trouve le maximum du serveur sans le connaître : demandez beaucoup trop, et lisez ce qui a été retenu.

Inutile de demander plus que ce que contient le ballon : le haut utile est la capacité du ballon (divisée par signal / 15 quand la flamme n'est pas pleine). Ceci garde un ballon exactement plein, sans rien perdre :

Brass
local bruleur = peripheral.find("hot_air_burner")
local cap = bruleur.capacity()
if cap then
  bruleur.set_amount(cap)
end

Voir aussi hot_air_burner.amount() hot_air_burner.capacity()

Le ballon

#

bruleur.filled()

→ number|nil

La quantité d'air chaud dans le ballon au-dessus du brûleur en ce moment, en m³. Elle s'approche peu à peu de la cible (la somme des productions de ses brûleurs, au plus la capacité) : elle suit donc chaque changement de débit avec retard.

Renvoie
number|nil
l'air chaud dans le ballon du brûleur en ce moment, en m³ ; nil sans ballon

nil quand le brûleur n'a pas de ballon : rien d'étanche au-dessus de lui, ou un brûleur jamais allumé (il ne cherche son ballon que tant que sa flamme brûle). Plusieurs brûleurs sous le même ballon lisent tous le même nombre.

Brass
local bruleur = peripheral.find("hot_air_burner")
local chaud = bruleur.filled()
if chaud == nil then
  print("pas de ballon au-dessus de ce brûleur")
else
  print(string.format("%.1f m3 d'air chaud", chaud))
end

Voir aussi hot_air_burner.capacity()

#

bruleur.capacity()

→ number|nil

Le volume du ballon au-dessus du brûleur, en m³ : le nombre de blocs d'air qu'il enferme. nil sans ballon, comme pour filled.

Renvoie
number|nil
le volume du ballon du brûleur, en m³ ; nil sans ballon

Avec filled, elle dit à quel point le ballon est plein :

Brass
local bruleur = peripheral.find("hot_air_burner")
local cap = bruleur.capacity()
if cap then
  print("plein à " .. math.floor(bruleur.filled() / cap * 100) .. " %")
end

Une jauge de ballon pour la passerelle du navire : l'enveloppe se remplit par le haut, comme l'air chaud. Le dessin prend la table que renvoie read() ; on l'essaie ici avec une mesure tapée à la main, un ballon de 18 m³ qui en contient 12,4 :

Brass
local function jauge(b)
  gfx.clear("black")
  term.clear()
  local cx, cy, r = 70, 70, 50
  local part = b.filled / b.capacity
  gfx.circle(cx, cy, r, "orange", true)
  -- cache la partie pas encore remplie : l'air chaud monte en haut
  local vide = math.floor(2 * r * (1 - part))
  if vide > 0 then
    gfx.rect(cx - r, cy + r - vide + 1, 2 * r + 1, vide, "black", true)
  end
  gfx.circle(cx, cy, r, "light_gray", 2)
  gfx.line(cx - 12, cy + r, cx - 8, cy + r + 22, "brown")
  gfx.line(cx + 12, cy + r, cx + 8, cy + r + 22, "brown")
  gfx.rect(cx - 10, cy + r + 22, 21, 12, "brown", true)
  if b.signal > 0 then
    gfx.triangle(cx - 4, cy + r + 21, cx + 4, cy + r + 21, cx, cy + r + 12, "yellow", true)
  end
  term.set_cursor(26, 3)
  term.write("BALLON")
  term.set_cursor(26, 5)
  term.write(string.format("%.1f / %d m3", b.filled, b.capacity))
  term.set_cursor(26, 6)
  term.write("plein à " .. math.floor(part * 100) .. " %")
  term.set_cursor(26, 9)
  term.write("BRÛLEUR")
  term.set_cursor(26, 11)
  term.write("débit " .. b.amount .. ", signal " .. b.signal)
  term.set_cursor(26, 12)
  term.write("produit " .. b.output .. " m3")
end

jauge({output = 18, signal = 15, amount = 18, filled = 12.4, capacity = 18})
Écran
Écran

En jeu, appelez jauge(bruleur.read()) dans une boucle, après avoir vérifié que capacity n'est pas nil.

Voir aussi hot_air_burner.filled() hot_air_burner.set_amount()

Une manette des gaz qui ne gaspille rien

Un petit programme complet : un Levier analogique à gauche de l'ordinateur devient la manette des gaz d'un ballon. Le brûleur est posé sur l'ordinateur, qui l'allume ; les 16 positions du levier se répartissent entre le débit minimal et un ballon plein, pour qu'aucun cran ne soit perdu au-delà de la capacité. Le programme dort jusqu'à ce que le levier bouge.

Brass
local bruleur = peripheral.wrap("top")
rs.set("top", 15)   -- allume la flamme
sleep(1)            -- le temps que le brûleur trouve son ballon

while true do
  local gaz = rs.get("left")   -- de 0 à 15
  local haut = bruleur.capacity() or 500
  local debit = bruleur.set_amount(math.floor(5 + (haut - 5) * gaz / 15))
  print("gaz " .. gaz .. " : " .. debit .. " m3")
  os.pull_event("redstone")
end

Pour un navire entier, la même idée pilote chaque brûleur dans une boucle sur peripheral.list("hot_air_burner"), et un capteur remplace le levier : Maintien d'altitude d'un dirigeable tient une hauteur et garde le navire à plat, pas à pas, et le programme intégré balloon est le pilote automatique complet.