Avro
PILOTE PRO
- Messages
- 1 946
- Réactions
- 271
Bonjour,
j'ai acheté un CDU version 3 à un membre du forum, Julien. C'est un CDU version 3 pour le 737 mais il ressemble beaucoup à celui qui équipe le MD-80 de l'éditeur Rotate sous X-Plane 11.
En regardant les Datarefs du MD-80, je vois que Rotate a bien fait les choses puisque les variables utiles sont bien présentes. Il n'y a plus qu'à faire !
J'utilise l'excellent système, OCUSBMapper, élaboré par Pikitanga et qui remplace avantageusement SIOC.
Il y a un plugin à télécharger ici :
La procédure d'installation est bien décrite dans cette même page.
Ensuite, il faudra créer un dossier portant le nom du script .lua inclus dans ce même dossier. Le scrip complet est joint à cet article. Renommez-le pour enlever l'extension .txt.
Je vous explique mon code car cela peut vous permettre de réaliser la même opération pour un autre appareil.
Cette variable est utile pour gérer le CDU Captain ou First Officer
Nous définissions les couleurs du texte utilisables pour notre CDU. Dans mon cas, je n'utiliserai que la couleur verte : color_green = "5"
Je défini les datarefs utiles. Il existe deux types de datarefs, celles utiles pour gérer le CDU lui même : find_dataref("pikitanga/ocusbmapper/cdu/input/button") et celles propres à mon avion : find_dataref("Rotate/md80/electrical/battery_on")
Ma première variable détectera quelle est la touche appuyée et la seconde va lire dans les données de mon avion si la batterie de mon MD-80 est sur ON.
Les 14 lignes envoyées au CDU sont stockées dans les variables cduDR_dspl_line0 à cduDR_dspl_line13
Gestion de la couleur paramétrée par ligne.
Les led sur le CDU, si je passe la variable cduDR_led_exec à la valeur 1, elle s'allume sur le CDU
Je récupère dans les variables MD80_cdu_DR_line_0 à MD80_cdu_DR_line_13 les valeurs que je peux lire aussi dans mon cockpit virtuel.
Je lis aussi l'état de deux valeurs dans mon appareil : la led Exec est-elle allumé : MD80_led_exec, ai-je appuyé sur le bouton de test de mes annonciateurs : MD80_led_test.
Si je clique sur un bouton du CDU (voir plus haut la variable cduDR_button), je déclencherai une action dans X-Plane par l'une des commandes ci-dessus.
Pour l'instant, ce n'est qu'une déclaration de variable nous allons voir ce mécanisme ci-dessous
Nous définissons des fonctions. Nous verrons plus loin ce qui les déclenchent. Cette fonction gère l'affichage des leds. La première condition vérifie que l'utilisateur a cliqué sur le bouton de test des annonciateurs et que la batterie est bien sur ON. Dans ce cas, toutes les leds du CDU s'allument. Le second test vérifie que la led EXEC doit être allumé.
Ces conditions vérifient l'appui sur une touche du CDU cduDR_button[0] == 88 alors elle indique au MD-80 de déclencher la commande MD80cduFL5.
Toutes mes lignes doivent être en vert sur fond noir.
J'affiche simplement sur le CDU les données lues sur les variables du MD-80 en substituant les $ (pas compris pourquoi) par des tirets (à défaut d'avoir réussi à mettre des ▯.
Certaines lignes du MD-80 comportent que 24 caractères qui sont plus gros. Je ne sais pas simuler ce changement de taille. J'ai donc décidé de modifier à la vollée, ces lignes trop courtes pour aligner l'ensemble à l'aide de la fonction xlarge. Si ma ligne ne fait pas 30 caractères, c'est qu'elle en fait 24 et j'applique xlarge (voir ci-dessous).
Si la batterie est sur off, pas d'affichage sur le CDU
La fonction qui tue : Je trouve la position du premier espace dans la chaîne puis je reconstitue la chaine de caractère de 0 à la position trouvée auquel j'ajoute 6 espaces puis, je rajoute le reste de la chaine. Vous remarquerez que je ne l'ai pas fait pour cduDR_dspl_line13 (qui est commentée) car d'après mes tests, ce n'était ni utile ni souhaitable.
before_physics est la fonction qui est exécutée avant tout autre chose. C'est donc là que nous faisons appel aux fonctions gérant notre CDU.
En définitve, un CDU n'est pas très difficile à gérer. Le programme est long mais c'est surtout car, il y a beacoup de boutons. J'ai aussi commencer à interfacer le MCP OC de type Boeing mais c'est bien plus complexe à réaliser.
j'ai acheté un CDU version 3 à un membre du forum, Julien. C'est un CDU version 3 pour le 737 mais il ressemble beaucoup à celui qui équipe le MD-80 de l'éditeur Rotate sous X-Plane 11.
En regardant les Datarefs du MD-80, je vois que Rotate a bien fait les choses puisque les variables utiles sont bien présentes. Il n'y a plus qu'à faire !
J'utilise l'excellent système, OCUSBMapper, élaboré par Pikitanga et qui remplace avantageusement SIOC.
Il y a un plugin à télécharger ici :
OCUSBMapper
v1.7.2 A big thanks to Kuikueg for all his help with mapping the Opencockpits MCP & EFIS. A big thanks to j9murphy for all his help with mapping the COM & NAV & ATC modules. A big thanks to bruceboock for all his help with mapping the USBOutputs card. A big thanks to DLH2906 & HeL...
forums.x-plane.org
Ensuite, il faudra créer un dossier portant le nom du script .lua inclus dans ce même dossier. Le scrip complet est joint à cet article. Renommez-le pour enlever l'extension .txt.
Je vous explique mon code car cela peut vous permettre de réaliser la même opération pour un autre appareil.
Code:
--*************************************************************************************--
--** CONSTANTS **--
--*************************************************************************************--
CDU_DEVICE = 0
Cette variable est utile pour gérer le CDU Captain ou First Officer
Code:
--*************************************************************************************--
--** LOCAL VARIABLES **--
--*************************************************************************************--
local color_black = "0"
local color_blue = "1"
local color_cyan = "2"
local color_dark_gray = "3"
local color_gray = "4"
local color_green = "5"
local color_light_gray = "6"
local color_magenta = "7"
local color_orange = "8"
local color_pink = "9"
local color_red = "A"
local color_white = "B"
local color_yellow = "C"
Nous définissions les couleurs du texte utilisables pour notre CDU. Dans mon cas, je n'utiliserai que la couleur verte : color_green = "5"
Code:
--*************************************************************************************--
--** FIND CUSTOM DATAREFS **--
--*************************************************************************************--
-- buttons
cduDR_button = find_dataref("pikitanga/ocusbmapper/cdu/input/button")
battery = find_dataref("Rotate/md80/electrical/battery_on")
Je défini les datarefs utiles. Il existe deux types de datarefs, celles utiles pour gérer le CDU lui même : find_dataref("pikitanga/ocusbmapper/cdu/input/button") et celles propres à mon avion : find_dataref("Rotate/md80/electrical/battery_on")
Ma première variable détectera quelle est la touche appuyée et la seconde va lire dans les données de mon avion si la batterie de mon MD-80 est sur ON.
Code:
-- display
cduDR_dspl_line0 = find_dataref("pikitanga/ocusbmapper/cdu" .. CDU_DEVICE .. "/output/dspl/line0")
cduDR_dspl_line1 = find_dataref("pikitanga/ocusbmapper/cdu" .. CDU_DEVICE .. "/output/dspl/line1")
...
cduDR_dspl_line12 = find_dataref("pikitanga/ocusbmapper/cdu" .. CDU_DEVICE .. "/output/dspl/line12")
cduDR_dspl_line13 = find_dataref("pikitanga/ocusbmapper/cdu" .. CDU_DEVICE .. "/output/dspl/line13")
Les 14 lignes envoyées au CDU sont stockées dans les variables cduDR_dspl_line0 à cduDR_dspl_line13
Code:
-- color
cduDR_color_line0 = find_dataref("pikitanga/ocusbmapper/cdu" .. CDU_DEVICE .. "/output/color/line0")
cduDR_color_line1 = find_dataref("pikitanga/ocusbmapper/cdu" .. CDU_DEVICE .. "/output/color/line1")
...
cduDR_color_line12 = find_dataref("pikitanga/ocusbmapper/cdu" .. CDU_DEVICE .. "/output/color/line12")
cduDR_color_line13 = find_dataref("pikitanga/ocusbmapper/cdu" .. CDU_DEVICE .. "/output/color/line13")
Gestion de la couleur paramétrée par ligne.
Code:
-- leds hardware
cduDR_led_ofst = find_dataref("pikitanga/ocusbmapper/cdu/output/led/ofst")
cduDR_led_msg = find_dataref("pikitanga/ocusbmapper/cdu/output/led/msg")
cduDR_led_exec = find_dataref("pikitanga/ocusbmapper/cdu/output/led/exec")
cduDR_led_dspy = find_dataref("pikitanga/ocusbmapper/cdu/output/led/dspy")
cduDR_led_fail = find_dataref("pikitanga/ocusbmapper/cdu/output/led/fail")
Les led sur le CDU, si je passe la variable cduDR_led_exec à la valeur 1, elle s'allume sur le CDU
Code:
-- Display MD80
MD80_cdu_DR_line_0 = find_dataref("Rotate/md80/instruments/cdu_line_01")
MD80_cdu_DR_line_1 = find_dataref("Rotate/md80/instruments/cdu_line_02")
...
MD80_cdu_DR_line_12 = find_dataref("Rotate/md80/instruments/cdu_line_13")
MD80_cdu_DR_line_13 = find_dataref("Rotate/md80/instruments/cdu_line_14")
Je récupère dans les variables MD80_cdu_DR_line_0 à MD80_cdu_DR_line_13 les valeurs que je peux lire aussi dans mon cockpit virtuel.
Code:
-- Led MD80 sim
MD80_led_exec = find_dataref("Rotate/md80/fms/exec_pending")
MD80_led_test = find_dataref("Rotate/md80/test/annun_digital_click")
Je lis aussi l'état de deux valeurs dans mon appareil : la led Exec est-elle allumé : MD80_led_exec, ai-je appuyé sur le bouton de test de mes annonciateurs : MD80_led_test.
Code:
--*************************************************************************************--
--** FIND CUSTOM COMMANDS **--
--*************************************************************************************--
MD80cduA = find_command("rotate/md80/cdu/Cdu_A")
MD80cduB = find_command("rotate/md80/cdu/Cdu_B")
...
MD80cduY = find_command("rotate/md80/cdu/Cdu_Y")
MD80cduZ = find_command("rotate/md80/cdu/Cdu_Z")
MD80cdu0 = find_command("rotate/md80/cdu/Cdu_0")
MD80cdu1 = find_command("rotate/md80/cdu/Cdu_1")
...
MD80cdu8 = find_command("rotate/md80/cdu/Cdu_8")
MD80cdu9 = find_command("rotate/md80/cdu/Cdu_9")
MD80cduBAR = find_command("rotate/md80/cdu/Cdu_BAR")
MD80cduBLNK = find_command("rotate/md80/cdu/Cdu_BLNK")
MD80cduCLB = find_command("rotate/md80/cdu/Cdu_CLB")
MD80cduCLR = find_command("rotate/md80/cdu/Cdu_CLR")
MD80cduCRZ = find_command("rotate/md80/cdu/Cdu_CRZ")
MD80cduDEAR = find_command("rotate/md80/cdu/Cdu_DEAR")
MD80cduDEL = find_command("rotate/md80/cdu/Cdu_DEL")
MD80cduDES = find_command("rotate/md80/cdu/Cdu_DES")
MD80cduDIR = find_command("rotate/md80/cdu/Cdu_DIR")
MD80cduEXEC = find_command("rotate/md80/cdu/Cdu_EXEC")
MD80cduFIX = find_command("rotate/md80/cdu/Cdu_FIX")
MD80cduFL1 = find_command("rotate/md80/cdu/Cdu_FL1")
MD80cduFL2 = find_command("rotate/md80/cdu/Cdu_FL2")
...
MD80cduFL5 = find_command("rotate/md80/cdu/Cdu_FL5")
MD80cduFL6 = find_command("rotate/md80/cdu/Cdu_FL6")
MD80cduFR1 = find_command("rotate/md80/cdu/Cdu_FR1")
MD80cduFR2 = find_command("rotate/md80/cdu/Cdu_FR2")
...
MD80cduFR5 = find_command("rotate/md80/cdu/Cdu_FR5")
MD80cduFR6 = find_command("rotate/md80/cdu/Cdu_FR6")
MD80cduHOLD = find_command("rotate/md80/cdu/Cdu_HOLD")
MD80cduINIT = find_command("rotate/md80/cdu/Cdu_INIT")
MD80cduLEGS = find_command("rotate/md80/cdu/Cdu_LEGS")
MD80cduMENU = find_command("rotate/md80/cdu/Cdu_MENU")
MD80cduNEXT = find_command("rotate/md80/cdu/Cdu_NEXT")
MD80cduPREV = find_command("rotate/md80/cdu/Cdu_PREV")
MD80cduPROG = find_command("rotate/md80/cdu/Cdu_PROG")
MD80cduPTO = find_command("rotate/md80/cdu/Cdu_PTO")
MD80cduRTE = find_command("rotate/md80/cdu/Cdu_RTE")
MD80cduSIGNO = find_command("rotate/md80/cdu/Cdu_SIGNO")
MD80cduSPC = find_command("rotate/md80/cdu/Cdu_SPC")
Si je clique sur un bouton du CDU (voir plus haut la variable cduDR_button), je déclencherai une action dans X-Plane par l'une des commandes ci-dessus.
Pour l'instant, ce n'est qu'une déclaration de variable nous allons voir ce mécanisme ci-dessous
Code:
--*************************************************************************************--
--** SYSTEM FUNCTIONS **--
--*************************************************************************************--
function cdu_leds()
if MD80_led_test == 1 and battery == 2 then
cduDR_led_exec[0] = 1
cduDR_led_ofst[0] = 1
cduDR_led_msg[0] = 1
cduDR_led_dspy[0] = 1
cduDR_led_fail[0] = 1
end
if MD80_led_test == 0 and battery < 2 then
cduDR_led_exec[0] = 0
cduDR_led_ofst[0] = 0
cduDR_led_msg[0] = 0
cduDR_led_dspy[0] = 0
cduDR_led_fail[0] = 0
end
if MD80_led_exec == 1 then
cduDR_led_exec[0] = 1
end
if MD80_led_exec == 0 then
cduDR_led_exec[0] = 0
end
end
Nous définissons des fonctions. Nous verrons plus loin ce qui les déclenchent. Cette fonction gère l'affichage des leds. La première condition vérifie que l'utilisateur a cliqué sur le bouton de test des annonciateurs et que la batterie est bien sur ON. Dans ce cas, toutes les leds du CDU s'allument. Le second test vérifie que la led EXEC doit être allumé.
Code:
function cdu_buttons()
if cduDR_button[0] ~= 0 then
-- clr
if cduDR_button[0] == 1 then
MD80cduCLR:once()
end
-- slash
if cduDR_button[0] == 2 then
MD80cduBAR:once()
end
-- delete
if cduDR_button[0] == 3 then
MD80cduDEL:once()
end
-- space
if cduDR_button[0] == 4 then
MD80cduSPC:once()
end
-- Z
if cduDR_button[0] == 5 then
MD80cduZ:once()
end
...
-- ls_5l
if cduDR_button[0] == 88 then
MD80cduFL5:once()
end
end
end
Ces conditions vérifient l'appui sur une touche du CDU cduDR_button[0] == 88 alors elle indique au MD-80 de déclencher la commande MD80cduFL5.
Code:
function cdu_dspl_lines()
cduDR_color_line0 = "555555555555555555555555555555"
cduDR_color_line1 = "555555555555555555555555555555"
...
cduDR_color_line12 = "555555555555555555555555555555"
cduDR_color_line13 = "555555555555555555555555555555"
Toutes mes lignes doivent être en vert sur fond noir.
Code:
if battery == 2 then
-- string.gsub: replace $ by -
cduDR_dspl_line0 = string.gsub(MD80_cdu_DR_line_0,"%$","-")
cduDR_dspl_line1 = string.gsub(MD80_cdu_DR_line_1,"%$","-")
...
cduDR_dspl_line12 = string.gsub(MD80_cdu_DR_line_12,"%$","-")
cduDR_dspl_line13 = string.gsub(MD80_cdu_DR_line_13,"%$","-")
J'affiche simplement sur le CDU les données lues sur les variables du MD-80 en substituant les $ (pas compris pourquoi) par des tirets (à défaut d'avoir réussi à mettre des ▯.
Code:
-- if length is less than 30, add spaces after first string found (function xlarge)
if string.len(cduDR_dspl_line1) < 30 then
cduDR_dspl_line1 = xlarge(cduDR_dspl_line1)
end
if string.len(cduDR_dspl_line2) < 30 then
cduDR_dspl_line2 = xlarge(cduDR_dspl_line2)
end
...
if string.len(cduDR_dspl_line12) < 30 then
cduDR_dspl_line12 = xlarge(cduDR_dspl_line12)
end
-- if string.len(cduDR_dspl_line13) < 30 then
-- cduDR_dspl_line13 = xlarge(cduDR_dspl_line13)
-- end
Certaines lignes du MD-80 comportent que 24 caractères qui sont plus gros. Je ne sais pas simuler ce changement de taille. J'ai donc décidé de modifier à la vollée, ces lignes trop courtes pour aligner l'ensemble à l'aide de la fonction xlarge. Si ma ligne ne fait pas 30 caractères, c'est qu'elle en fait 24 et j'applique xlarge (voir ci-dessous).
Code:
else
cduDR_dspl_line0 = " "
cduDR_dspl_line1 = " "
cduDR_dspl_line12 = " "
cduDR_dspl_line13 = " "
end
end
Si la batterie est sur off, pas d'affichage sur le CDU
Code:
function xlarge(s)
local deb = string.find(s, "%s")
local res = string.sub(s, 0, deb) .. " " .. string.sub(s, deb+1)
return res
end
La fonction qui tue : Je trouve la position du premier espace dans la chaîne puis je reconstitue la chaine de caractère de 0 à la position trouvée auquel j'ajoute 6 espaces puis, je rajoute le reste de la chaine. Vous remarquerez que je ne l'ai pas fait pour cduDR_dspl_line13 (qui est commentée) car d'après mes tests, ce n'était ni utile ni souhaitable.
Code:
--*************************************************************************************--
--** XLUA EVENT CALLBACKS **--
--*************************************************************************************--
function before_physics()
cdu_leds()
cdu_buttons()
cdu_dspl_lines()
end
before_physics est la fonction qui est exécutée avant tout autre chose. C'est donc là que nous faisons appel aux fonctions gérant notre CDU.
En définitve, un CDU n'est pas très difficile à gérer. Le programme est long mais c'est surtout car, il y a beacoup de boutons. J'ai aussi commencer à interfacer le MCP OC de type Boeing mais c'est bien plus complexe à réaliser.