See site in english Voir le site en francais
Website skin:
home  download  forum  link  contact

Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length

Author Topic: Arduino Uno + Orbiter  (Read 100676 times)

0 Members and 1 Guest are viewing this topic.

Offline Mars Bleu

  • Hero Member
  • *****
  • Posts: 638
  • Karma: 33
Reply #25 - 10 November 2013, 14:21:21
Oui, avec une carte programmable, on doit pouvoir faire à peu près ce qu'on veut:
commande de portail automatique ou de chauffage solaire, système d'alarme, etc...
Peut-être même remplacer des cartes déficientes d'une voiture? La seule limite est
l'imagination!

Pour la Uno, il y a seulement 14 entrées/sorties analogiques, plus 6 entrées analogiques.
Or les raccourcis claviers utilisés pour conduire un DG IV ,un Xr2 ou autre sont bien plus nombreux,
surtout si on rajoute quelques mfd. Un registre à décalage est il la seule solution?
Peut-être est il judicieux de partager les fonctions par carte:
                            - carte pour l'émulateur de clavier
                            - carte pour la gestion de displays (altitude, jauge de carburants, com...)
                            - carte pour les mfd
                            - carte pour les manettes des gaz, (main, hover et scram) et leur asservissement aux pilotes auto.


Offline hysot

  • Full Member
  • ***
  • Posts: 120
  • Country: Canada ca
  • Karma: 8
Reply #26 - 10 November 2013, 18:04:57
Pour l'instant je table sur deux cartes, la UNO et je vais acheter une Mega2560 qui dispose de 54 entrees digitales et 12 analogiques. Je montrerais si j'arrive a résoudre mon probleme avec autohotkey  et MFDExtern comment relier plusieurs boutons poussoirs sur une seule entrée analogique.

Post Merge: 11 November 2013, 02:00:43
Voila la suite. Comment interfacer deux MFDs!
On part du principe d'utiliser deux ecrans sur un seul PC, un pour la vu et un pour les MFDs.
On utilisera External MFD pour l'affichage des deux MFDs (veillez a ce qu'il soit active dans l'onglet modules du launch pad orbiter)
On utilisera AutoHotKey pour l'ouverture des deux MFDs et leur placement sur le second ecran ainsi que pour la création des raccourcis clavier.
Enfin comme précédemment on utilisera IDE Arduino pour l’édition et l'upload du sketch ainsi que FLIP pour le changement de firmware.

Avant de commencer, je voudrais parler d'un probleme de conflit entre les raccourcis clavier de AutoHotKey et Orbiter.
Si on configure le raccourcis clavier CTRL+T dans AutoHotKey celui ci viendra en conflit avec le raccourcis T d'Orbiter. Cela marche avec d'autres raccourcis, comme les CTRL+1 a 0 et les raccourcis 1 a 0 et bien d'autres.
La seule solution que j'ai trouve est de n'utiliser que des lettres/chiffres/symbole sans CTRL/SHIFT/ALT avec AutohotKey et de changer les raccourci d'Orbiter pour que toutes les lettres/chiffres/symbole soient accompagnes d'un CTRL/SHIFT/ALT. Pour moins de prise de tête je n'ai utilisez que CTRL+SHIFT (tres peu utilise sur Orbiter, XR2/5)
Vous trouverez ci-dessous mon Keymap.cfg avec les modifications


Code: [Select]
CockpitCamRotateLeft = LEFT ALT
CockpitCamRotateRight = RIGHT ALT
CockpitCamRotateUp = UP ALT
CockpitCamRotateDown = DOWN ALT
CockpitCamDontLean = DOWN CTRL ALT
CockpitCamLeanForward = UP CTRL ALT
CockpitCamLeanLeft = LEFT CTRL ALT
CockpitCamLeanRight = RIGHT CTRL ALT
CockpitResetCam = HOME
PanelShiftLeft = LEFT
PanelShiftRight = RIGHT
PanelShiftUp = UP
PanelShiftDown = DOWN
PanelSwitchLeft = LEFT CTRL
PanelSwitchRight = RIGHT CTRL
PanelSwitchUp = UP CTRL
PanelSwitchDown = DOWN CTRL
TrackCamRotateLeft = LEFT CTRL
TrackCamRotateRight = RIGHT CTRL
TrackCamRotateUp = UP CTRL
TrackCamRotateDown = DOWN CTRL
TrackCamAdvance = PGDOWN
TrackCamRetreat = PGUP
GroundCamTiltLeft = LEFT
GroundCamTiltRight = RIGHT
GroundCamTiltUp = UP
GroundCamTiltDown = DOWN
IncMainThrust = ADD CTRL
DecMainThrust = SUBTRACT CTRL
KillMainRetroThrust = MULTIPLY
OverrideFullMainThrust = ADD
OverrideFullRetroThrust = SUBTRACT
IncHoverThrust = NUMPAD0
DecHoverThrust = DECIMAL
RCSEnable = DIVIDE CTRL
RCSMode = DIVIDE
RCSPitchUp = NUMPAD2
RCSPitchDown = NUMPAD8
RCSYawLeft = NUMPAD1
RCSYawRight = NUMPAD3
RCSBankLeft = NUMPAD4
RCSBankRight = NUMPAD6
RCSUp = NUMPAD2
RCSDown = NUMPAD8
RCSLeft = NUMPAD1
RCSRight = NUMPAD3
RCSForward = NUMPAD6
RCSBack = NUMPAD9
LPRCSPitchUp = NUMPAD2 CTRL
LPRCSPitchDown = NUMPAD8 CTRL
LPRCSYawLeft = NUMPAD1 CTRL
LPRCSYawRight = NUMPAD3 CTRL
LPRCSBankLeft = NUMPAD4 CTRL
LPRCSBankRight = NUMPAD6 CTRL
LPRCSUp = NUMPAD2 CTRL
LPRCSDown = NUMPAD8 CTRL
LPRCSLeft = NUMPAD1 CTRL
LPRCSRight = NUMPAD3 CTRL
LPRCSForward = NUMPAD6 CTRL
LPRCSBack = NUMPAD9 CTRL
NMHoldAltitude =
NMHLevel = L CTRL SHIFT
NMPrograde = A CTRL SHIFT
NMRetrograde = S CTRL SHIFT
NMNormal = SEMICOLON CTRL SHIFT
NMAntinormal = APOSTROPHE CTRL SHIFT
NMKillrot = NUMPAD5
Undock = D CTRL SHIFT
IncElevatorTrim = DELETE
DecElevatorTrim = INSERT
WheelbrakeLeft = COMMA
WheelbrakeRight = PERIOD
HUD = H CTRL
HUDMode = H
HUDReference = R CTRL
HUDTarget = R CTRL ALT
HUDColour = H ALT
IncSimSpeed = T SHIFT
DecSimSpeed = R SHIFT
IncFOV = X SHIFT
DecFOV = Z SHIFT
StepIncFOV = X CTRL
StepDecFOV = Z CTRL
MainMenu = F4
DlgHelp = F1 ALT
DlgCamera = F1 CTRL
DlgSimspeed = F2 CTRL
DlgCustomCmd = F4 CTRL
DlgVisualHelpers = F9 CTRL
DlgRecorder = F5 CTRL
DlgInfo = I CTRL
DlgMap = M CTRL
DlgNavaid = N CTRL
ToggleInfo = I CTRL SHIFT
ToggleFPS = F
ToggleCamInternal = F1
ToggleTrackMode = F2
TogglePanelMode = F8
TogglePlanetarium = F9
ToggleRecPlay = C CTRL
Pause = P CTRL
Quicksave = S CTRL
Quit = Q CTRL
DlgSelectVessel = F3
SelectPrevVessel = F3 CTRL

Pour l'ouverture, le placement des MFDs et la création des raccourcis clavier il va falloir créer un script et le lancer avant de lancer orbiter. Mon script est base sur le script Four MFDs on a 22 inch Monitor.

Code: [Select]
#NoEnv                                  ; Recommended for performance and compatibility with future AutoHotkey releases.
#Warn                                    ; Enable warnings to assist with detecting common errors.
SendMode Input                      ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.


SetKeyDelay,10,30

;Position et taille du MFD1
pltMFD1PosX:=2060
pltMFD1PosY:=418
pltMFD1Width:=600
pltMFD1Height:=600

;Position et taille du MFD2
pltMFD2PosX:=1440
pltMFD2PosY:=418
pltMFD2Width:=600
pltMFD2Height:=600


!i::InitMfds()           ;Appuyez ALT+i pour lancer le script et ouvrir les deux MFDs
pause::suspend           ;Appuyez sur "pause" pour susprendre/activer la prise en compte des raccourcis clavier

;Raccourcis clavier du MFD1
q::ClickButton(pltMfd1Handle,"ExtMfd_Button15")      ;Bouton superieur gauche
w::ClickButton(pltMfd1Handle,"ExtMfd_Button13")
e::ClickButton(pltMfd1Handle,"ExtMfd_Button11")
r::ClickButton(pltMfd1Handle,"ExtMfd_Button9")
t::ClickButton(pltMfd1Handle,"ExtMfd_Button7")
y::ClickButton(pltMfd1Handle,"ExtMfd_Button5")       ;Bouton inferieur gauche
u::ClickButton(pltMfd1Handle,"ExtMfd_Button3")       ;Bouton PWR
i::ClickButton(pltMfd1Handle,"ExtMfd_Button2")       ;Bouton SEL
o::ClickButton(pltMfd1Handle,"ExtMfd_Button1")       ;Bouton MENU
p::ClickButton(pltMfd1Handle,"ExtMfd_Button4")       ;Bouton inferieur droit
[::ClickButton(pltMfd1Handle,"ExtMfd_Button6")
]::ClickButton(pltMfd1Handle,"ExtMfd_Button8")
f::ClickButton(pltMfd1Handle,"ExtMfd_Button10")
j::ClickButton(pltMfd1Handle,"ExtMfd_Button12")   
k::ClickButton(pltMfd1Handle,"ExtMfd_Button14")     

;Raccourcis clavier du MFD2
F6::ClickButton(pltMfd2Handle,"ExtMfd_Button15")     ;Bouton superieur gauche
'::ClickButton(pltMfd2Handle,"ExtMfd_Button13")
z::ClickButton(pltMfd2Handle,"ExtMfd_Button11")
x::ClickButton(pltMfd2Handle,"ExtMfd_Button9")
c::ClickButton(pltMfd2Handle,"ExtMfd_Button7")
v::ClickButton(pltMfd2Handle,"ExtMfd_Button5")       ;Bouton inferieur gauche
b::ClickButton(pltMfd2Handle,"ExtMfd_Button3")       ;Bouton PWR
n::ClickButton(pltMfd2Handle,"ExtMfd_Button2")       ;Bouton SEL
m::ClickButton(pltMfd2Handle,"ExtMfd_Button1")       ;Bouton MENU
F12::ClickButton(pltMfd2Handle,"ExtMfd_Button4")     ;Bouton inferieur droit 
F11::ClickButton(pltMfd2Handle,"ExtMfd_Button6")
F10::ClickButton(pltMfd2Handle,"ExtMfd_Button8")
F7::ClickButton(pltMfd2Handle,"ExtMfd_Button10")
=::ClickButton(pltMfd2Handle,"ExtMfd_Button12")   
-::ClickButton(pltMfd2Handle,"ExtMfd_Button14")      ;Bouton superieur droit


InitMfds()
{
    global
    WinActivate,Orbiter 2010 [D3D9Client]
    Send {F4}
    WinActivate, Main
    Sleep 500
    Send {Click 40, 285}
    WinWait, Custom Functions
    Control, ChooseString, External Mfd, ListBox1, Custom
    ControlClick, Button1, Custom
    WinWait,MFD
    WinSetTitle,pltMfd1
    WinMove,pltMfd1,,%pltMfd1PosX%,%pltMfd1PosY%,%pltMfd1Width%,%pltMfd1Height%
    WinGet,pltMfd1Handle,ID,pltMfd1

    WinActivate, Main
    Send {Click}
    WinWait, Custom Functions
    Control, ChooseString, External Mfd, ListBox1, Custom
    ControlClick, Button1, Custom
    WinWait,MFD
    WinSetTitle,pltMfd2
    WinMove,pltMfd2,,%pltMfd2PosX%,%pltMfd2PosY%,%pltMfd2Width%,%pltMfd2Height%
    WinGet,pltMfd2Handle,ID,pltMfd2

    WinClose, Main

    WinActivate,Orbiter 2010 [D3D9Client]
    return   
}

ClickButton(mfdHandle,button)
{
    ControlClick,%button%,ahk_id %mfdHandle%
}

Faites attention que mes deux MFDs s'ouvrent sur un deuxieme ecran et que si vous testez ce script avec un seul ecran vous ne verrez peut etre pas de MFDs s'ouvrir. Modifiez pltMFD1PosX , pltMFD1PosY, pltMFD2PosX, pltMFD2PosY.

J'ai ajoute un raccourci "pause" pour éviter d'entrer en conflit avec les raccourcis clavier de UGCO. Trouver 30 raccourcis clavier qui n’interfèrent pas avec Orbiter, les vaisseaux XR2/5, et UGCO relève de l'impossible. Comme les MFDs sont inutiles avec UGCO (enfin dans mon cas, je n'utilise pas l'Arrow) j'ai décidé de suspendre la prise en compte des raccourcis de mon script lorsque que j'utilise les UMMU. J'ajouterais un bouton poussoir sur mon panel.

Ce script fonctionne avec le client D3D9 d'orbiter, pas avec Orbiter standard ou le client D3D11. Si vous voulez le faire fonctionner sur l'un de ces deux derniers vous devrez modifier les lignes WinActivate,Orbiter 2010 [D3D9Client] du script.
Cette ligne sert a active le fenêtre orbiter. Le titre de la fenêtre doit être correcte sinon ça marche pas. Utilisez AutoIt3 Windows Spy (installe avec AutohotKey) pour trouver le nom de la fenêtre d'Orbiter. Ce logiciel est aussi très pratique pour connaitre la position de la souris. Utilisez le pour trouver la position de vos MFDs par exemple.
Par déduction je dirais:
Orbiter standard >> WinActivate,Orbiter 2010
Orbiter client D3D11 >> WinActivate,Orbiter 2010 [D3D11Client]

Passons maintenant a l'Arduino. Comme Mars Bleu l'a souligne, il va etre difficile de caser tous les interrupteurs du XR2/5 plus les trims, boutons du P/A et les 30 boutons des 2 MFDs. Heureusement il existe une technique qui permet de relier un grand nombre de bouton poussoir a une seule pin analogique de l'Arduino. Les pins digitales ne prennent que les valeurs 0 ou 1 dépendant si elles reçoivent du courant ou non. Les pins analogiques quand a elles peuvent prendre des valeurs entre 0 et 1023 dépendant du courant reçu. C'est a ces pins qu'on relie les potentiomètres qui font varier l’intensité du courant par une augmentation ou réduction de la résistance.
Maintenant au lieu d'un potentiomètre, on peut brancher 15 boutons poussoirs avec chacun une résistance différente.
Voici le schéma du montage:


Valeurs des resistances:
1- 1K Ohms
2- 100 Ohms
3- 100 Ohms
4- 100 Ohms
5- 100 Ohms
6- 220 Ohms
7- 220 Ohms
8- 330 Ohms
9- 330 Ohms
10- 470 Ohms
11- 470 Ohms
12- 680 Ohms
13- 1K Ohms
14- 2.2K Ohms
15- 2.7K Ohms
16- 4.7K Ohms

En espérant qu'il soit assez clair.

Maintenant le sketch. Desole je n'ai pas encore pris le temps de traduire et de bien comprendre le fonctionnement entier du programme (notamment le "debounce"). J'ai simplement repris ce programme trouve sur un forum et changer les valeurs. Mais pour l'utiliser il suffit juste de repérer quelques points.

Code: [Select]
#include <HIDKeyboard.h>

HIDKeyboard keyboard;                    // Initialize HIDKeyboard object


int j = 1; // integer used in scanning the array designating column number
//2-dimensional array for asigning the buttons and there high and low values
int Button[15][3] =  {{1, 928, 933}, // button 1
                     {2, 849, 854}, // button 2
                     {3, 784, 789}, // button 3
                     {4, 727, 733}, // button 4
                     {5, 628, 633}, // button 5
                     {6, 553, 557}, // button 6
                     {7, 467, 473}, // button 7
                     {8, 403, 410}, // button 8
                     {9, 341, 345}, // button 9
                     {10, 294, 299}, // button 10
                     {11, 245, 249}, // button 11
                     {12, 196, 201}, // button 12
                     {13, 135, 140}, // button 13
                     {14, 97, 102}, // button 14
                     {15, 64, 70}, // button 15
};
                     
int analogpin = 0; // analog pin to read the buttons
int label = 0;  // for reporting the button label
int counter = 0; // how many times we have seen new value
long time = 0;  // the last time the output pin was sampled
int debounce_count = 50; // number of millis/samples to consider before declaring a debounced input
int current_state = 0;  // the debounced input value
int ButtonVal;

void setup()
{
  Serial.begin(9600);
  keyboard.begin();                      // Start communication
  delay(2000);                           // Wait for device to be found as a keyboard
 

}

void loop()
{
   // If we have gone on to the next millisecond
  if (millis() != time)
  {
    // check analog pin for the button value and save it to ButtonVal
    ButtonVal = analogRead(analogpin);
    if(ButtonVal == current_state && counter >0)
    {
      counter--;
    }
    if(ButtonVal != current_state)
    {
      counter++;
    }
    // If ButtonVal has shown the same value for long enough let's switch it
    if (counter >= debounce_count)
    {
      counter = 0;
      current_state = ButtonVal;
      //Checks which button or button combo has been pressed
      if (ButtonVal > 0)
      {
        ButtonCheck();
      }
    }
    time = millis();
  }
}

void ButtonCheck()
{
  // loop for scanning the button array.
  for(int i = 0; i <= 15; i++)
  {
    // checks the ButtonVal against the high and low vales in the array
    if(ButtonVal >= Button[i][j] && ButtonVal <= Button[i][j+1])
    {
      // stores the button number to a variable
      label = Button[i][0];
      Action();     
    }
  }
}

void Action()
{
  if(label == 1)
  {
    keyboard.pressKey('q');
      delay(40);
      keyboard.releaseKey();
  }
  if(label == 2)
  {
    keyboard.pressKey('w');
      delay(40);
      keyboard.releaseKey();
  }
  if(label == 3)
  {
    keyboard.pressKey('e');
      delay(40);
      keyboard.releaseKey();
  }
  if(label == 4)
  {
    keyboard.pressKey('r');
      delay(40);
      keyboard.releaseKey();
  }
  if(label == 5)
  {
    keyboard.pressKey('t');
      delay(40);
      keyboard.releaseKey();
  }
  if(label == 6)
  {
    keyboard.pressKey('y');
      delay(40);
      keyboard.releaseKey();
  }
  if(label == 7)
  {
    keyboard.pressKey('u');
      delay(40);
      keyboard.releaseKey();
  }
  if(label == 8)
  {
    keyboard.pressKey('i');
      delay(40);
      keyboard.releaseKey();
  }
  if(label == 9)
  {
    keyboard.pressKey('o');
      delay(40);
      keyboard.releaseKey();
  }
  if(label == 10)
  {
    keyboard.pressKey('p');
      delay(40);
      keyboard.releaseKey();
  }
  if(label == 11)
  {
    keyboard.pressKey('[');
      delay(40);
      keyboard.releaseKey();
  }
  if(label == 12)
  {
    keyboard.pressKey(']');
      delay(40);
      keyboard.releaseKey();
  }
  if(label == 13)
  {
    keyboard.pressKey('f');
      delay(40);
      keyboard.releaseKey();
  }
  if(label == 14)
  {
    keyboard.pressKey('j');
      delay(40);
      keyboard.releaseKey();
  }
  if(label == 15)
  {
    keyboard.pressKey('k');
      delay(40);
      keyboard.releaseKey();
  }
 
         
  //Serial.println("Button =:");
  //Serial.println(label);
  //delay(200);
 
 
}

Tout d'abord repérez la partie du code suivante:
Code: [Select]
int Button[15][3] =  {{1, 928, 933}, // button 1
                     {2, 849, 854}, // button 2
                     {3, 784, 789}, // button 3
                     {4, 727, 733}, // button 4
                     {5, 628, 633}, // button 5
                     {6, 553, 557}, // button 6
                     {7, 467, 473}, // button 7
                     {8, 403, 410}, // button 8
                     {9, 341, 345}, // button 9
                     {10, 294, 299}, // button 10
                     {11, 245, 249}, // button 11
                     {12, 196, 201}, // button 12
                     {13, 135, 140}, // button 13
                     {14, 97, 102}, // button 14
                     {15, 64, 70}, // button 15
};

int Button[15][3] va definir le nombre de bouton (15) et le nombre de variable entre crochets (3 : numero du bouton ou label, valeur inf, valeur sup).
Les valeurs inf et sup sont les valeurs lu sur la pin lorsqu'un bouton est presse. Lorsqu'on appuis sur un bouton, un courant avec une certaine résistance va être envoyé a la pin A0 et l'arduino va interpréter ce courant en lui donnant une valeur entre 0 et 1023. Il suffira ensuite de lui dire si la valeur lu sur la pin A0 est comprise entre XXX et XXX' alors le bouton #1 a été appuyé alors faire tel action. Pour connaitre cette valeur il va falloir utiliser un autre sketch. Ce Skecth existe deja dans la banque de donnee du logiciel IDE.
Ouvrez le:

File >> Examples >> 01.Basics >> AnalogReadSerial

Uploadez le sur l'arduino mais gardez le firmware original de l'arduino. Ouvrez le Serial Monitor:

Tools >> Serial Monitor

Maintenant appuyez sur chaque bouton et notez les valeurs lu sur le serial monitor. Notez bien les petits fluctuations.
exemple valeur lu lorsque le bouton #1 est appuyé: 930/931
Comme ses valeurs peuvent être soumises a de légère fluctuation (les résistances sont sensibles au changement de température) il est judicieux de prendre les valeurs 928/933. Vous pouvez toujours augmenter cet intervalle si vous trouvez que ce n'est pas suffisant lors des tests.
Faites cela pour chaque bouton et entrez ces valeurs dans le code.

Enfin reperez le "void Action()"
C'est ici que vous changerez les raccourcis clavier. Referez vous au dossier du firmware HIDKeyboard et aux deux fichiers suivant:
- README
- HIDKeyboard.h


Une video devrait arriver d'ici peu
Bonne semaine :)







Post Merge: 11 November 2013, 07:00:38
Hop!


« Last Edit: 11 November 2013, 07:00:38 by hysot »
hysot

Offline hysot

  • Full Member
  • ***
  • Posts: 120
  • Country: Canada ca
  • Karma: 8
Reply #27 - 22 November 2013, 01:07:48
Avec pas mal de retard la démo des boutons d'un MFD.

<a href="http://www.youtube.com/watch?v=_YVCQeiYRDc" target="_blank">http://www.youtube.com/watch?v=_YVCQeiYRDc</a>

La je bosse sur le regroupement de tous ces bouts de programme et la conception du simpit sur Catia:


hysot

Offline Fast_toche

  • Legend
  • ******
  • Posts: 1329
  • Country: France fr
  • Karma: 34
  • Time is nothing...
Reply #28 - 22 November 2013, 03:00:36
Je te laisse la parole Ma^tre!! :wor:


Offline Mars Bleu

  • Hero Member
  • *****
  • Posts: 638
  • Karma: 33
Reply #29 - 23 November 2013, 13:20:18
Woaow, c'est beau!
La réalisation est soignée, rien à dire  :flower:
On attend la suite.

Ces derniers temps, j'ai cherché à faire un code LUA qui lit le contenu du fichier *.scn
choisi, et charge un ensemble de données qui devront être envoyées à une Arduino
pour initialiser le simpit. Ça donne:
Code: [Select]

-- ******************************************
-- ********read number lines from scn file***
-- ******************************************
function line_read (file)
    number_lines=0
    local g = io.open(file,"r")
    if g ~= nil then
        repeat
            t = g:read()
            number_lines=number_lines+1
        until t == nil
    g:close()
    end
end
-- *****************************************
-- *********end function line_read *********
-- *****************************************

-- *******************************************
-- ********load lines from scn file***********
-- *******************************************
function load_scnfile (file,n)
    slist={}
    local f = io.open(file,"r")
    if f ~= nil then
        for i=1,n do
            t = f:read()
            if t == nil then break end
            slist[i]=t
        end
        f:close()
    end
    return slist
end
-- ******************************************
-- *********end function load_scnfile *******
-- ******************************************

-- *******************************************
-- ***********load ship status****************
-- *******************************************
function load_ship_status (pattern)
    note:set_colour ({r=0.0,g=0.7,b=0.2})
    note:set_text(pattern)
    proc.wait_sysdt(0.2)
    status_array={}
    level_array={}
    for i=1,number_lines-1 do
       s1 = slist[i]
       s2=string.find(s1,pattern)
       if s2==7 then
           for j=i, number_lines-1 do
               if string.match (slist[j], 'RCSMODE')~=nil then
                   note:set_colour ({r=0.8,g=0.4,b=0.8})
                   _,_,aux,status = string.find(slist[j],"(.+) (.+)")
                   status_array[1]=status
                   note:set_text('Mode rcs'..'=>'..status_array[1])
                   proc.wait_sysdt(0.81)
               elseif string.match (slist[j], 'NOSECONE')~=nil then
                   _,_,_,status,level = string.find(slist[j],"(.+) (.+) (.+)")
                   status_array[2]=status
                   level_array[2]=level
                   note:set_text('NOSECONE=>'..status_array[2]..' '..level_array[2])
                   proc.wait_sysdt(1.21)
               elseif string.match (slist[j], 'GEAR')~=nil then
                   _,_,_,status,level = string.find(slist[j],"(.+) (.+) (.+)")
                   status_array[3]=status
                   level_array[3]=level
                   note:set_text('GEAR=>'..status_array[3]..' '..level_array[3])
                   proc.wait_sysdt(1.21)
               elseif string.match (slist[j], 'RADIATOR')~=nil then
                   _,_,_,status,level = string.find(slist[j],"(.+) (.+) (.+)")
                   status_array[4]=status
                   level_array[4]=level
                   note:set_text('RADIATOR=>'..status_array[4]..' '..level_array[4])
                   proc.wait_sysdt(1.21)
               elseif string.match (slist[j], 'HATCH')~=nil then
                   _,_,_,status,level = string.find(slist[j],"(.+) (.+) (.+)")
                   status_array[5]=status
                   level_array[5]=level
                   note:set_text('HATCH=>'..status_array[5]..' '..level_array[5])
                   proc.wait_sysdt(1.21)
               elseif slist[j]=='END' then
                   note:set_colour ({r=0.8,g=0.2,b=0.2})
                   note:set_text(slist[j])
                   proc.wait_sysdt(1.21)
                   flag_out=1
                   break
               end
           end
       end
       if flag_out==1 then
           flag_out=nil
           break
       end
    end
end
-- ****************************************
-- *******end function load_ship_status ***
-- ****************************************

note = oapi.create_annotation()
note:set_pos (0.35,0.1,0.8,0.95)
note:set_colour ({r=0.9,g=0.5,b=0.2})

data_path = 'Scenarios/XR2 Ravenstar/essailua.scn'
ship = ':XR2Ravenstar'

intro = 'LUA challenge:\n\
Launch LUA and\
use data extracted from the file.\
Try to print them on the screen.\n'

note:set_text(ship)
proc.wait_sysdt(0.2)

note:set_text(intro)
proc.wait_sysdt(0.2)



note:set_colour ({r=0.9,g=0.5,b=0.2})




-- ******************************************
-- ***********begin call functions **********
-- ******************************************

sfirst = line_read (data_path)

slist = load_scnfile (data_path,number_lines)

lstatus = load_ship_status (ship)

-- ******************************************
-- ************ end call functions **********
-- ******************************************


note:set_text('End program')
proc.wait_sysdt(1)
note:set_text('  ')
proc.wait_sysdt(1)

Pour l'instant, ça charge seulement l'état des RCS, nosecone, gear, radiator et hatch.
(Pas la peine de surcharger, chacun aura compris le bout de code, non?). C'est encore expérimental,
avec l'impression à l'écran pour savoir si ça charge correctement.
Il manque aussi le code permettant d'envoyer status_array={} et  level_array={}
à une Arduino par un port USB. Je suis déjà dessus.

Pour appeler un script LUA depuis un *.scn, c'est dans BEGIN ENVIRONMENT, mettre
SCRIPT "chemin de fichier dans le dossier Script"/"nom du script lua".


Offline antoo

  • Legend
  • ******
  • Posts: 3659
  • Country: France fr
  • Karma: 179
  • MSFS ❤️
Reply #30 - 23 November 2013, 15:10:58
Impressionnant, tu est :top: surtout n'abandonnes pas :bave: !

Humm tu l'as acheté Catia :) ?

---------------------------------------------------------------------------------------------------
"ET C´EST PARTI!!" Youri Gagarine au lancement de vostok 1 le 12 avril 1961

Offline hysot

  • Full Member
  • ***
  • Posts: 120
  • Country: Canada ca
  • Karma: 8
Reply #31 - 23 November 2013, 16:28:46
Super Mars Bleu! Je suppose que tu peux faire le même chose pour le carburant? et afficher tes réserve sur un écran?
Car mon probleme pour le moment c'est l'affichage de ce genre de données (Carburant APU, Moteur, Scram, quantite LOX)


J'ai garde des relations de ma formation universitaire >> Version étudiant.

hysot

Offline antoo

  • Legend
  • ******
  • Posts: 3659
  • Country: France fr
  • Karma: 179
  • MSFS ❤️
Reply #32 - 23 November 2013, 16:40:24
Ah ok :)... ben moi...

---------------------------------------------------------------------------------------------------
"ET C´EST PARTI!!" Youri Gagarine au lancement de vostok 1 le 12 avril 1961

Offline hysot

  • Full Member
  • ***
  • Posts: 120
  • Country: Canada ca
  • Karma: 8
Reply #33 - 23 November 2013, 17:06:24
Ok je viens de tester ton code et de comprendre aussi ce qu'il fait.
Il marche donc c'est deja super :)

J'ai vu qu'a la fin de ton script il y a un chemin de fichier scenario. J'ai donc change ca pour que ca colle avec le scenario que j'utilise.

Code: [Select]
data_path = 'Scenarios/Scenarios/XR5 Vanguard/In Orbit.scn'
ship = ':XR5Vanguard'

Par contre je ne dois pas avoir fait les choses comme il faut pour appeler le script depuis le scenario car je dois le lancer manuellement depuis le terminal MFD.

Code: [Select]
BEGIN_ENVIRONMENT
  System Sol
  Date MJD 51984.6216048103
  SCRIPT Script/test.lua
END_ENVIRONMENT

J'ai meme essaye sans le ".lua" et ca ne marche pas non plus.
Un probleme que je vois a ton script c'est que si tu a un relance la simu depuis le scenario Current state, ca ne marchera plus.






« Last Edit: 23 November 2013, 18:22:26 by hysot »
hysot

Offline Mars Bleu

  • Hero Member
  • *****
  • Posts: 638
  • Karma: 33
Reply #34 - 24 November 2013, 09:38:52
Dans le début du fichier scénario, le script LUA est appelé par la ligne SCRIPT Demos/nom_du_script
Cette ligne se retrouve automatiquement dans (current scenario.scn)
Code: [Select]
BEGIN_ENVIRONMENT
  System Sol
  Date MJD 51984.6055217260
  SCRIPT Demos/nom_du_script
END_ENVIRONMENT

Le dossier Demos n'est bien sûr pas une obligation, le mieux sera peut-être de mette les scripts LUA
liés à un simpit dans un dossier ... Simpit  :)



Quote
Je suppose que tu peux faire le même chose pour le carburant? et afficher tes réserve sur un écran?
Car mon probleme pour le moment c'est l'affichage de ce genre de données (Carburant APU, Moteur, Scram, quantite LOX)

Oui, tout ça est parfaitement lisible. J'ai même idée d'aller voir dans le fichier Xr2 RavenstarPrefs (celui du Xr5
est fait pareil) pour fixer les rate consumption de l'engin.
Il y a aussi des lignes concernant le niveau de puissance des moteurs. Ça pourrait servir pour un asservissement
des manettes des gaz.
Par contre, je n'ai pas encore de solution pour des paramètres comme t° scramjet, ou hull temperature.
Peut-être en demandant gentiment à Doug Beachy?


Offline nulentout

  • Legend
  • ******
  • Posts: 3356
  • Country: France fr
  • Karma: 242
Reply #35 - 25 November 2013, 12:30:48
Coucou les copains,
Hé bé, il s'en passe des choses dans l'espace OrbitoArduino,
Bon, je n'ai pas du tout l'intention de me refaire un autre tableau de bord pour piloter.
Mais cette philosophie de programmation qui délègue une bonne partie du travail au compilateur me semble très séduisante.
Bien que n'ayant aucune véritable intention de créer une "application utile", juste pour le plaisir j'ai commandé sur Internet une carte Arduino UNO pour faire "joujou" avec.  :)
Naturellement j'ai commencé par me cogner un peu pour installer les logiciels de base, mais c'est une étape incontournable. Il semble que ma carte soit maintenant reconnue comme un périphérique série sur COM3.
Comme je ne veux pas trop me disperser, je vais suspendre mes errances pour le moment, car je désire terminer le tutoriel que je suis en train de faire sur GEMINI. Mais dès qu'il sera mis en ligne je rebrancherais cette petite carte très séduisante sur la ligne USB.  :music:
Quoi qu'il en soit, félicitations pour ces posts très très formateurs.

La sagesse est un trésor ... tellement bien caché.

Offline nulentout

  • Legend
  • ******
  • Posts: 3356
  • Country: France fr
  • Karma: 242
Reply #36 - 25 November 2013, 15:35:51
Coucou les copains,
Narf narf narf ... je n'ai pas résisté. Les démangeaisons étaient trop fortes et j'ai craqué !  :arg:
J'ai rebranché la ligne USB vers la carte, je voulais tester rapidos l'écriture d'un programme, le compiler, le transférer et vérifier que ça fonctionne.  :wonder:
Mon programme est élémentaire. Je déclare la broche 13 comme sortie, car c'est sur elle qu'est branchée la petite DEL sur la carte Arduino. Puis j'ai réalisé un programme en boucle qui allume pendant un dixième de seconde, puis temporise pendant deux secondes. J'ai téléporté le résultat de la compilation et Hop ... fonctionnement du premier coup.  :flower:
Je suis ravi, car cette première expérience montre qu'en moins d'une heure j'ai téléchargé le programme de développement, celui qui transforme l'USB en COM, installé le tout, écrit un programme et logé ce dernier dans la puce Arduine.
Mais je reste totalement dubitatif. En effet, si j'avais réalisé ce programme en binaire sur un microcontrôleur il totaliserait environ 80 octets, et encore je suis large. (Déclaration des vecteurs incluse)
Sur Arduino, le compilateur indique 1076 octets sur 32256  :eek: ... c'est peu crédible, car il ne serait possible que de faire 32 fois plus, c'est à dire absolument rien.
Sauf si on ne peut écrire que par granules de cette taille.
Qu'en est-il ? Un Arduinaute aurait-il la réponse ?

La sagesse est un trésor ... tellement bien caché.

Offline hysot

  • Full Member
  • ***
  • Posts: 120
  • Country: Canada ca
  • Karma: 8
Reply #37 - 25 November 2013, 17:27:58
Content de t'avoir entrainer a essayer une Arduino!
Pour la taille des programmes oui tu n'as que ça mais il y a une époque avoir un ordinateur de 8-bits était un luxe :D
Je pense qu'il faut savoir optimiser. Si tu veux plus gros tu as la Mega qui monte a 127k

hysot

Offline Mars Bleu

  • Hero Member
  • *****
  • Posts: 638
  • Karma: 33
Reply #38 - 25 November 2013, 19:15:51
Il va y avoir de plus en plus d'arduinautes!!

J'ai amélioré mon code LUA d'initialisation. Désormais, on pourra lire le fichier scn
du vaisseau focusé, si c'est un Xr2, un Xr5, ou un ShuttleA.
 
Pour appeler le script LUA:
Code: [Select]
BEGIN_ENVIRONMENT
    System Sol
    Date MJD 51984,6704617905
    Script Simpit/Init_simpit
END_ENVIRONMENT


Le script LUA:
Code: [Select]
-- ******************************************
-- ********read number lines from scn file***
-- ******************************************
function line_read (file)
    number_lines=0
    local g = io.open(file,"r")
    if g ~= nil then
        repeat
            t = g:read()
            number_lines=number_lines+1
        until t == nil
    g:close()
    end
end
-- *****************************************
-- *********end function line_read *********
-- *****************************************

-- *******************************************
-- ********load lines from scn file***********
-- *******************************************
function load_scnfile (file,n)
    slist={}
    local f = io.open(file,"r")
    if f ~= nil then
        for i=1,n do
            t = f:read()
            if t == nil then break end
            slist[i]=t
        end
        f:close()
    end
    return slist
end
-- ******************************************
-- *********end function load_scnfile *******
-- ******************************************

-- *******************************************
-- ***********load ship status****************
-- *******************************************
function load_ship_status (pattern)
    status_array={}
    level_array={}
    for i=1,number_lines-1 do
       s1 = slist[i]
       _,_,name,classname = string.find (s1, "(.-):(.+)")
       if (classname=='XR2Ravenstar') and (ship=='XR2Ravenstar') then
           status_array[1]=v:get_rcsmode()
           note:set_text('Mode rcs'..'=>'..status_array[1])
           proc.wait_sysdt(0.81)
           main_fuel=v:get_propellanthandle(0)
           level_array[1]=v:get_propellantmass(main_fuel)
           note:set_text('Main fuel=>'..level_array[1]..'kg')
           proc.wait_sysdt(0.81)
           rcs_fuel=v:get_propellanthandle(1)
           level_array[2]=v:get_propellantmass(rcs_fuel)
           note:set_text('Rcs fuel=>'..level_array[2]..'kg')
           proc.wait_sysdt(0.81)
           scram_fuel=v:get_propellanthandle(2)
           level_array[3]=v:get_propellantmass(scram_fuel)
           note:set_text('Scram fuel=>'..level_array[3]..'kg')
           proc.wait_sysdt(0.81)
           for j=i, number_lines-1 do           
               if string.match (slist[j], 'APU_FUEL_QTY')~=nil then
                   _,_,aux,level = string.find(slist[j],"(.+) (.+)")
                   level_array[4]=level*268
                   note:set_text('APU fuel'..'=>'..level_array[4]..'kg')
                   proc.wait_sysdt(0.81)
               elseif string.match (slist[j], 'APU_STATUS')~=nil then
                   _,_,aux,status = string.find(slist[j],"(.+) (.+)")
                   status_array[4]=status
                   note:set_text('Status APU'..'=>'..status_array[4])
                   proc.wait_sysdt(1.81)
               elseif string.match (slist[j], 'NOSECONE')~=nil then
                   _,_,_,status,level = string.find(slist[j],"(.+) (.+) (.+)")
                   status_array[5]=status
                   level_array[5]=level
                   note:set_text('NOSECONE=>'..status_array[5]..' '..level_array[5])
                   proc.wait_sysdt(0.81)
               elseif string.match (slist[j], 'GEAR')~=nil then
                   _,_,_,status,level = string.find(slist[j],"(.+) (.+) (.+)")
                   status_array[6]=status
                   level_array[6]=level
                   note:set_text('GEAR=>'..status_array[6]..' '..level_array[6])
                   proc.wait_sysdt(0.81)
               elseif string.match (slist[j], 'RADIATOR')~=nil then
                   _,_,_,status,level = string.find(slist[j],"(.+) (.+) (.+)")
                   status_array[7]=status
                   level_array[7]=level
                   note:set_text('RADIATOR=>'..status_array[7]..' '..level_array[7])
                   proc.wait_sysdt(0.81)
               elseif string.match (slist[j], 'HATCH')~=nil then
                   _,_,_,status,level = string.find(slist[j],"(.+) (.+) (.+)")
                   status_array[8]=status
                   level_array[8]=level
                   note:set_text('HATCH=>'..status_array[8]..' '..level_array[8])
                   proc.wait_sysdt(0.81)
               elseif string.match (slist[j], 'LOX_QTY')~=nil then
                   _,_,aux,level = string.find(slist[j],"(.+) (.+)")
                   level_array[9]=level*364
                   note:set_text('LOX quantity'..'=>'..level_array[9]..'kg')
                   proc.wait_sysdt(0.81)
               elseif slist[j]=='END' then
                   note:set_colour ({r=0.8,g=0.2,b=0.2})
                   note:set_text(slist[j])
                   proc.wait_sysdt(0.81)
                   flag_out=1
                   break
               end
           end
       elseif (classname=='XR5Vanguard') and (ship=='XR5Vanguard') then
           note:set_text('XR5Vanguard not implemented, simpit not activated')
           proc.wait_sysdt(2.01)
           break
       elseif (classname=='ShuttleA') and (ship=='ShuttleA') then
           note:set_text('ShuttleA not implemented, simpit not activated')
           proc.wait_sysdt(2.01)
           break
       elseif (i== number_lines-1) then
           note:set_text('vessel not implemented, simpit not activated')
           proc.wait_sysdt(2.01)
           break
       end
       if flag_out==1 then
           flag_out=nil
           break
       end
    end
end
-- ****************************************
-- *******end function load_ship_status ***
-- ****************************************

note = oapi.create_annotation()
note:set_pos (0.35,0.1,0.8,0.95)
note:set_colour ({r=0.9,g=0.5,b=0.2})

data_path = 'Scenarios/(Current state).scn'
intro = 'Load scn data'

note:set_text(intro)
proc.wait_sysdt(1.2)

note:set_colour ({r=0.9,g=0.0,b=0.0})

v=vessel.get_focusinterface()                --get vessel handle
ship=v:get_classname()                       --know vessel class


-- ******************************************
-- ***********begin call functions **********
-- ******************************************

sfirst = line_read (data_path)

slist = load_scnfile (data_path,number_lines)

lstatus = load_ship_status (ship)

-- ******************************************
-- ************ end call functions **********
-- ******************************************


note:set_text('End of program')
proc.wait_sysdt(1)
note:set_text('  ')
proc.wait_sysdt(1)


Offline hysot

  • Full Member
  • ***
  • Posts: 120
  • Country: Canada ca
  • Karma: 8
Reply #39 - 25 November 2013, 19:29:43
Super Merci!
J'ai pas encore essaye mais c'est sur le même principe que l'autre? défilement des paramètres du vaisseau?

hysot

Offline nulentout

  • Legend
  • ******
  • Posts: 3356
  • Country: France fr
  • Karma: 242
Reply #40 - 25 November 2013, 22:07:05
Content de t'avoir entrainer a essayer une Arduino!
Pour la taille des programmes oui tu n'as que ça mais il y a une époque avoir un ordinateur de 8-bits était un luxe :D
Je pense qu'il faut savoir optimiser. Si tu veux plus gros tu as la Mega qui monte a 127k
Ben optimiser je veux bien ... mais mon programme ne comporte que 4 instructions plus la directive de configuration de la sortie 13 soit cinq lignes. Je ne vois pas vraiment ce que l'on peut réduire. De toute façon je ne comprends pas pourquoi avec si peu de source on peut aboutir à autant de programme objet. Je pense que la raison est ailleurs. C'est la façon dont travaille le compilateur. Du reste, je me suis "amusé" à dupliquer quatre fois les mêmes séquences. le programme est donc quatre fois plus long pour le source. Et bien le programme objet à pratiquement pas augmenté en taille. Probablement qu'une fois les subroutines chargées, il se contente d'y faire plusieurs fois appel et ne duplique pas le code.

« Last Edit: 25 November 2013, 22:13:37 by nulentout »
La sagesse est un trésor ... tellement bien caché.

Offline hysot

  • Full Member
  • ***
  • Posts: 120
  • Country: Canada ca
  • Karma: 8
Reply #41 - 25 November 2013, 22:20:36
Excuse moi je me suis mal exprime, si un programme devient trop lourd pour l'arduino, il y a peut être possibilité de l'optimiser.

hysot

Offline hysot

  • Full Member
  • ***
  • Posts: 120
  • Country: Canada ca
  • Karma: 8
Reply #42 - 25 November 2013, 22:47:53
Du reste, je me suis "amusé" à dupliquer quatre fois les mêmes séquences. le programme est donc quatre fois plus long pour le source. Et bien le programme objet à pratiquement pas augmenté en taille. Probablement qu'une fois les subroutines chargées, il se contente d'y faire plusieurs fois appel et ne duplique pas le code.

C'est bon a savoir. J'ai assemble mes différents bout de code poste ici (pour les 2 Mfds, inter/led APU, inter/Leds Cone) et j'arrive a 6K. J'ai encore de la marge sachant que ce programme sera utilise sur la Mega et non plus sur la Uno qui elle servira a émuler un joystick

hysot

Offline Mars Bleu

  • Hero Member
  • *****
  • Posts: 638
  • Karma: 33
Reply #43 - 25 November 2013, 23:07:55
Quote
J'ai pas encore essaye mais c'est sur le même principe que l'autre? défilement des paramètres du vaisseau?
Oui.


Offline nulentout

  • Legend
  • ******
  • Posts: 3356
  • Country: France fr
  • Karma: 242
Reply #44 - 26 November 2013, 08:46:23
Coucou les copains,
Pour revenir à mon interrogation j'ai effectué l'expérience suivante : J'ai réalisé un programme vide, c'est à dire uniquement la déclaration des deux blocs void SETUP et void loop. Une fois compilé ce programme "sans instruction" fait déjà 466 octets. Donc le compilateur met en place une foule de servitudes dès le début auxquelles il doit ensuite faire appel. C'est la raison pour laquelle un programme dérisoire est boulimique en octets. Par contre, ensuite le taux d'expansion doit diminuer significativement. C'est une hypothèse de ma part.

La sagesse est un trésor ... tellement bien caché.

Offline hysot

  • Full Member
  • ***
  • Posts: 120
  • Country: Canada ca
  • Karma: 8
Reply #45 - 26 November 2013, 09:08:40
J'espere que tu n'es pas anglophobe, voici ce qu'un mec a fait pour voir ce que contenait ces 466 octets:
http://forum.arduino.cc/index.php/topic,5680.0.html

hysot

Offline hysot

  • Full Member
  • ***
  • Posts: 120
  • Country: Canada ca
  • Karma: 8
Reply #46 - 26 November 2013, 09:17:04
Il va y avoir de plus en plus d'arduinautes!!

J'ai amélioré mon code LUA d'initialisation. Désormais, on pourra lire le fichier scn
du vaisseau focusé, si c'est un Xr2, un Xr5, ou un ShuttleA.
 
Pour appeler le script LUA:
Code: [Select]
BEGIN_ENVIRONMENT
    System Sol
    Date MJD 51984,6704617905
    Script Simpit/Init_simpit
END_ENVIRONMENT


Le script LUA:
Code: [Select]
-- ******************************************
-- ********read number lines from scn file***
-- ******************************************
function line_read (file)
    number_lines=0
    local g = io.open(file,"r")
    if g ~= nil then
        repeat
            t = g:read()
            number_lines=number_lines+1
        until t == nil
    g:close()
    end
end
-- *****************************************
-- *********end function line_read *********
-- *****************************************

-- *******************************************
-- ********load lines from scn file***********
-- *******************************************
function load_scnfile (file,n)
    slist={}
    local f = io.open(file,"r")
    if f ~= nil then
        for i=1,n do
            t = f:read()
            if t == nil then break end
            slist[i]=t
        end
        f:close()
    end
    return slist
end
-- ******************************************
-- *********end function load_scnfile *******
-- ******************************************

-- *******************************************
-- ***********load ship status****************
-- *******************************************
function load_ship_status (pattern)
    status_array={}
    level_array={}
    for i=1,number_lines-1 do
       s1 = slist[i]
       _,_,name,classname = string.find (s1, "(.-):(.+)")
       if (classname=='XR2Ravenstar') and (ship=='XR2Ravenstar') then
           status_array[1]=v:get_rcsmode()
           note:set_text('Mode rcs'..'=>'..status_array[1])
           proc.wait_sysdt(0.81)
           main_fuel=v:get_propellanthandle(0)
           level_array[1]=v:get_propellantmass(main_fuel)
           note:set_text('Main fuel=>'..level_array[1]..'kg')
           proc.wait_sysdt(0.81)
           rcs_fuel=v:get_propellanthandle(1)
           level_array[2]=v:get_propellantmass(rcs_fuel)
           note:set_text('Rcs fuel=>'..level_array[2]..'kg')
           proc.wait_sysdt(0.81)
           scram_fuel=v:get_propellanthandle(2)
           level_array[3]=v:get_propellantmass(scram_fuel)
           note:set_text('Scram fuel=>'..level_array[3]..'kg')
           proc.wait_sysdt(0.81)
           for j=i, number_lines-1 do           
               if string.match (slist[j], 'APU_FUEL_QTY')~=nil then
                   _,_,aux,level = string.find(slist[j],"(.+) (.+)")
                   level_array[4]=level*268
                   note:set_text('APU fuel'..'=>'..level_array[4]..'kg')
                   proc.wait_sysdt(0.81)
               elseif string.match (slist[j], 'APU_STATUS')~=nil then
                   _,_,aux,status = string.find(slist[j],"(.+) (.+)")
                   status_array[4]=status
                   note:set_text('Status APU'..'=>'..status_array[4])
                   proc.wait_sysdt(1.81)
               elseif string.match (slist[j], 'NOSECONE')~=nil then
                   _,_,_,status,level = string.find(slist[j],"(.+) (.+) (.+)")
                   status_array[5]=status
                   level_array[5]=level
                   note:set_text('NOSECONE=>'..status_array[5]..' '..level_array[5])
                   proc.wait_sysdt(0.81)
               elseif string.match (slist[j], 'GEAR')~=nil then
                   _,_,_,status,level = string.find(slist[j],"(.+) (.+) (.+)")
                   status_array[6]=status
                   level_array[6]=level
                   note:set_text('GEAR=>'..status_array[6]..' '..level_array[6])
                   proc.wait_sysdt(0.81)
               elseif string.match (slist[j], 'RADIATOR')~=nil then
                   _,_,_,status,level = string.find(slist[j],"(.+) (.+) (.+)")
                   status_array[7]=status
                   level_array[7]=level
                   note:set_text('RADIATOR=>'..status_array[7]..' '..level_array[7])
                   proc.wait_sysdt(0.81)
               elseif string.match (slist[j], 'HATCH')~=nil then
                   _,_,_,status,level = string.find(slist[j],"(.+) (.+) (.+)")
                   status_array[8]=status
                   level_array[8]=level
                   note:set_text('HATCH=>'..status_array[8]..' '..level_array[8])
                   proc.wait_sysdt(0.81)
               elseif string.match (slist[j], 'LOX_QTY')~=nil then
                   _,_,aux,level = string.find(slist[j],"(.+) (.+)")
                   level_array[9]=level*364
                   note:set_text('LOX quantity'..'=>'..level_array[9]..'kg')
                   proc.wait_sysdt(0.81)
               elseif slist[j]=='END' then
                   note:set_colour ({r=0.8,g=0.2,b=0.2})
                   note:set_text(slist[j])
                   proc.wait_sysdt(0.81)
                   flag_out=1
                   break
               end
           end
       elseif (classname=='XR5Vanguard') and (ship=='XR5Vanguard') then
           note:set_text('XR5Vanguard not implemented, simpit not activated')
           proc.wait_sysdt(2.01)
           break
       elseif (classname=='ShuttleA') and (ship=='ShuttleA') then
           note:set_text('ShuttleA not implemented, simpit not activated')
           proc.wait_sysdt(2.01)
           break
       elseif (i== number_lines-1) then
           note:set_text('vessel not implemented, simpit not activated')
           proc.wait_sysdt(2.01)
           break
       end
       if flag_out==1 then
           flag_out=nil
           break
       end
    end
end
-- ****************************************
-- *******end function load_ship_status ***
-- ****************************************

note = oapi.create_annotation()
note:set_pos (0.35,0.1,0.8,0.95)
note:set_colour ({r=0.9,g=0.5,b=0.2})

data_path = 'Scenarios/(Current state).scn'
intro = 'Load scn data'

note:set_text(intro)
proc.wait_sysdt(1.2)

note:set_colour ({r=0.9,g=0.0,b=0.0})

v=vessel.get_focusinterface()                --get vessel handle
ship=v:get_classname()                       --know vessel class


-- ******************************************
-- ***********begin call functions **********
-- ******************************************

sfirst = line_read (data_path)

slist = load_scnfile (data_path,number_lines)

lstatus = load_ship_status (ship)

-- ******************************************
-- ************ end call functions **********
-- ******************************************


note:set_text('End of program')
proc.wait_sysdt(1)
note:set_text('  ')
proc.wait_sysdt(1)

Penses tu que tu pourrais nous faire un petit tuto pour nous expliquer comment fonctionne ton script? pour moi ça reste du charabia
Si tu as le temps bien sure!

hysot

Offline Mars Bleu

  • Hero Member
  • *****
  • Posts: 638
  • Karma: 33
Reply #47 - 26 November 2013, 18:23:48
Vois dans ta MP pour les explications. C'est peut-être pas la peine d'embêter
tout le monde avec ça.
Pour l'instant, il n'y a rien d'opérationnel; c'est juste du commencement de prémice de
début d'investigation  :siffle:

Je regarde pour les réservoirs additionnels de carburant... (Pfff! Y a du taff! :badsmile:)

« Last Edit: 26 November 2013, 18:30:01 by Mars Bleu »

Offline hysot

  • Full Member
  • ***
  • Posts: 120
  • Country: Canada ca
  • Karma: 8
Reply #48 - 27 November 2013, 20:38:38
Bon finalement pas besoin de cette modification (voir spoiler) ca marche tres bien sans  :badsmile:

Spoiler  :
Si tu me le permets Mars Bleu j'aimerais ajouter des details sur l'utilisation de ton script qui fonctionne tres bien  :top:

Faites bien attention au nom donne a votre vaisseau. Dans le script vous trouverez ce genre de ligne de code pour le XR2, XR5 et la shuttle A

Code: [Select]
if (classname=='XR2Ravenstar') and (ship=='XR2Ravenstar') then
Code: [Select]
elseif (classname=='XR5Vanguard') and (ship=='XR5Vanguard') then
Code: [Select]
elseif (classname=='ShuttleA') and (ship=='ShuttleA') then
ship=='XR2Ravenstar' appelle votre vaisseau par son nom (celui que vous lui avez donne) comme tout bon maitre. Le soucis c'est que si, comme moi, vous testez le script sur le scenario 5 - On Approach to ISS fournis de base avec le XR2, son nom sera "XR2_01" et le script vous renverra la lignes suivante:

Quote
vessel not implemented, simpit not activated

Pour ajuster cela, deux solutions s'offre a vous:

- Modifier le script en remplacant "XR2Ravenstar" (juste pour ship et non pour classname!) par le nom de votre vaisseau ("XR2_01" ou "MontFalHusse" ou peu importe le nom de votre vaiseau si vous l'utilisez dans un scenario perso)

- Modifier le scenario en remplacant "XR2_01" ou  "MontFalhusse" par "XR2Ravenstar". Attention vous devez le remplacer a 3 endroits:

ici:
Code: [Select]
BEGIN_FOCUS
  Ship [b]XR2Ravenstar[/b]
END_FOCUS

ici:
Code: [Select]
BEGIN_CAMERA
  TARGET [b]XR2Ravenstar[/b]
  MODE Cockpit
  FOV 40.00
END_CAMERA

et enfin la
Code: [Select]
[b]XR2Ravenstar[/b]:XR2Ravenstar
  STATUS Orbiting Earth
  RPOS -5162407.29 -3388968.28 2699300.62
  RVEL -4399.314 6283.349 -519.496
  AROT -20.92 -43.26 103.28
  PRPLEVEL 0:0.604 1:0.938
  IDS 0:199 100
  NAVFREQ 588 466 84 114
  XPDR 193
  SECONDARY_HUD 2
[...]
END

Voila

« Last Edit: 29 November 2013, 01:10:17 by hysot »
hysot

Offline Mars Bleu

  • Hero Member
  • *****
  • Posts: 638
  • Karma: 33
Reply #49 - 02 December 2013, 20:54:48
J'ai amélioré le code LUA d'initialisation:
 -chaque type de vaisseau fait l'objet d'une fonction individuelle.
 -on peut avoir plusieurs vaisseaux du même type, c'est celui qui est focusé qui sera chargé.
 -inventaire de la cargaison du Xr2.

Voilà la dernière version:
Code: [Select]
-- ******************************************
-- ********read number lines from scn file***
-- ******************************************
function line_read (file)
    number_lines=0
    local g = io.open(file,"r")
    if g ~= nil then
        repeat
            t = g:read()
            number_lines=number_lines+1
        until t == nil
    g:close()
    end
end
-- *****************************************
-- *********end function line_read *********
-- *****************************************

-- *******************************************
-- ********load lines from scn file***********
-- *******************************************
function load_file (file,n)
    slist={}
    local f = io.open(file,"r")
    if f ~= nil then
        for i=1,n do
            t = f:read()
            if t == nil then break end
            slist[i]=t
        end     
        f:close()
    end
    return slist
end
-- ******************************************
-- *********end function load_scnfile *******
-- ******************************************

-- *******************************************
-- ***********load xr2 status****************
-- *******************************************
function load_xr2_status (pattern)
    status_array={}
    level_array={}
    flag_out=0
    main_fuel_tank=0
    scram_fuel_tank=0
    lox_tank=0
    nb_tank_main_fuel=0
    nb_tank_scram_fuel=0
    nb_tank_lox=0
    name_ship=""
    for i=1,40 do
        status_array[i]=""
        level_array[i]=""
    end
    for i=1,number_lines-1 do
       s1 = slist[i]
       _,_,name,classname = string.find (s1, "(.-):(.+)")
--***************************************************************************
--*****************************************************Begin Xr2 settings****
--***************************************************************************
       if (classname=='XR2Ravenstar')  and (name==name_ship_focused) then
           name_ship=name
           status_array[1]=v:get_rcsmode()
           note:set_text('Mode rcs'..'=>'..status_array[1])
           proc.wait_sysdt(0.31)
           main_fuel=v:get_propellanthandle(0)
           level_array[1]=v:get_propellantmass(main_fuel)
           note:set_text('Main fuel=>'..level_array[1]..'kg')
           proc.wait_sysdt(0.31)
           rcs_fuel=v:get_propellanthandle(1)
           level_array[2]=v:get_propellantmass(rcs_fuel)
           note:set_text('Rcs fuel=>'..level_array[2]..'kg')
           proc.wait_sysdt(0.31)
           scram_fuel=v:get_propellanthandle(2)
           level_array[3]=v:get_propellantmass(scram_fuel)
           note:set_text('Scram fuel=>'..level_array[3]..'kg')
           proc.wait_sysdt(0.31)
           for j=i, number_lines-1 do           
               if string.match (slist[j], 'APU_FUEL_QTY')~=nil then
                   _,_,aux,level = string.find(slist[j],"(.+) (.+)")
                   level_array[4]=level*268
                   note:set_text('APU fuel'..'=>'..level_array[4]..'kg')
                   proc.wait_sysdt(0.41)
               elseif string.match (slist[j], 'APU_STATUS')~=nil then
                   _,_,aux,status = string.find(slist[j],"(.+) (.+)")
                   status_array[4]=status
                   note:set_text('Status APU'..'=>'..status_array[4])
                   proc.wait_sysdt(0.41)
               elseif string.match (slist[j], 'NOSECONE')~=nil then
                   _,_,_,status,level = string.find(slist[j],"(.+) (.+) (.+)")
                   status_array[20]=status
                   level_array[20]=level
                   note:set_text('NOSECONE=>'..status_array[20]..' '..level_array[20])
                   proc.wait_sysdt(0.41)
               elseif string.match (slist[j], 'GEAR')~=nil then
                   _,_,_,status,level = string.find(slist[j],"(.+) (.+) (.+)")
                   status_array[21]=status
                   level_array[21]=level
                   note:set_text('GEAR=>'..status_array[21]..' '..level_array[21])
                   proc.wait_sysdt(0.41)
               elseif string.match (slist[j], 'RADIATOR')~=nil then
                   _,_,_,status,level = string.find(slist[j],"(.+) (.+) (.+)")
                   status_array[22]=status
                   level_array[22]=level
                   note:set_text('RADIATOR=>'..status_array[22]..' '..level_array[22])
                   proc.wait_sysdt(0.41)
               elseif string.match (slist[j], 'HATCH')~=nil then
                   _,_,_,status,level = string.find(slist[j],"(.+) (.+) (.+)")
                   status_array[23]=status
                   level_array[23]=level
                   note:set_text('HATCH=>'..status_array[23]..' '..level_array[23])
                   proc.wait_sysdt(0.41)
               elseif string.match (slist[j], 'LOX_QTY')~=nil then
                   _,_,aux,level = string.find(slist[j],"(.+) (.+)")
                   level_array[24]=level*364
                   note:set_text('LOX quantity'..'=>'..level_array[24]..'kg')
                   proc.wait_sysdt(0.41)
               elseif slist[j]=='END' then
                   flag_out=1
                   break
               end                      --Endif du Xr2
           end                          --Next j
--***************************************************************
--************************************End Xr2 settings***********
--***************************************************************
--************************************Begin Xr2 payload setting**
--***************************************************************

       elseif(classname=='XR2PayloadCHM') then
           CHM_set=0
           CHM_capacity=0
           CHM_i=i
           lpayload=xr2_payload_setting(main_fuel_tank, nb_tank_main_fuel, CHM_capacity,CHM_set,CHM_i)
       elseif(classname=='XR2PayloadMainFuel') then
           main_fuel_set=4
           main_fuel_max_capacity=3350
           main_fuel_i=i
           lpayload=xr2_payload_setting(main_fuel_tank, nb_tank_main_fuel, main_fuel_max_capacity, main_fuel_set,main_fuel_i)
       elseif(classname=='XR2PayloadSCRAMFuel') then
           scram_fuel_set=6
           scram_fuel_max_capacity=3350
           scram_fuel_i=i
           lpayload=xr2_payload_setting(scram_fuel_tank, nb_tank_scram_fuel, scram_fuel_max_capacity, scram_fuel_set,scram_fuel_i)
       elseif(classname=='XR2PayloadLOX') then
           lox_set=9
           lox_max_capacity=10545
           lox_i=i
           lpayload=xr2_payload_setting(lox_tank, nb_tank_lox, lox_max_capacity, lox_set, lox_i)
       elseif(classname=='XR2PayloadLOX_Half') then
           lox_set=9
           lox_max_capacity=5272.5
           lox_i=i
           lpayload=xr2_payload_setting(lox_tank, nb_tank_lox, lox_max_capacity, lox_set, lox_i)
       elseif(classname=='XR2PayloadEmptyLOX') then
           lox_set=9
           lox_max_capacity=0
           lox_i=i
           lpayload=xr2_payload_setting(lox_tank, nb_tank_lox, lox_max_capacity, lox_set, lox_i)
--********************************************************
--*****************************End Xr2 payload setting****
--********************************************************
       end
    end                                 --Next i
    data_path = 'Config/XR2RavenstarPrefs.cfg'--******************* begin init xr2 prefs*****************
    number_lines=0
    sfirst = line_read (data_path)
    slist = load_file (data_path,number_lines)
    lprefs= load_prefs()                      --******************** end init xr2 prefs******************

    for i=5,15 do                           
        note:set_text('level_array['..i..']='..level_array[i]..'Slot='..status_array[i])  --****status payload on screen*********
        proc.wait_sysdt(1.01)
    end
end
-- ****************************************
-- *******end function load_xr2_status ***
-- ****************************************

-- ***********************************************
-- *********** Xr2 payload setting ***************
-- ***********************************************
function xr2_payload_setting (payload_tank, nb_tank_payload,payload_max_capacity,payload_set,payload_i)
    for k=payload_i, number_lines-1 do
        if string.match (slist[k], 'ATTACHED')~=nil then
            _,_,attached,slot,carrier = string.find(slist[k],"(.+):(.+),(.+)")
        elseif (string.match (slist[k], 'PRPLEVEL')~=nil or classname=='XR2PayloadEmptyLOX') and name_ship_focused==carrier then
            if classname~='XR2PayloadEmptyLOX' then
                _,_,aux,level = string.find(slist[k],"(.+):(.+)")
            elseif classname=='XR2PayloadEmptyLOX' then
                level=0
            end
            carrier=""
            payload_tank=level*payload_max_capacity+payload_tank
            nb_tank_payload=nb_tank_payload+1
            level_array[payload_set+nb_tank_payload]=level*payload_max_capacity
            status_array[payload_set+nb_tank_payload]=slot+1
            flag_out=1
            if payload_set==4 then                                 
                nb_tank_main_fuel=nb_tank_payload
            elseif payload_set==6 then
                nb_tank_scram_fuel=nb_tank_payload
            elseif payload_set==9 then
                nb_tank_lox=nb_tank_payload
            end
            break
        elseif (classname=='XR2PayloadCHM') and (name_ship_focused==carrier) then
            carrier=""
            level_array[9]=1
            status_array[9]=1
            flag_out=1
            break   
        elseif slist[k]=='END' then
            break
        end
    end
end
-- ****************************************
-- ******* end function payload setting ***
-- ****************************************

-- ****************************************
-- ********** begin load xr2 prefs ************
-- ****************************************
function load_prefs()
    for i=1,number_lines-1 do
       s1=slist[i]
       _,_,pref,value = string.find (s1, "(.-)=(.+)")
       if pref=='APUFuelBurnRate' then
           note:set_text(pref..'=>'..value)
           proc.wait_sysdt(0.5)
       elseif pref=='CoolantHeatingRate' then
           note:set_text(pref..'=>'..value)
           proc.wait_sysdt(0.5)
       end
    end
end
-- ****************************************
-- ************ end load xr2 prefs ************
-- ****************************************


-- ****************************************
-- ********** begin program ***************
-- ****************************************
note = oapi.create_annotation()
note:set_pos (0.35,0.1,0.8,0.95)
note:set_colour ({r=0.9,g=0.5,b=0.2})

data_path = 'Scenarios/(Current state).scn'
intro = 'Load scn data'

note:set_text(intro)
proc.wait_sysdt(0.5)

note:set_colour ({r=0.9,g=0.0,b=0.0})

v=vessel.get_focusinterface()
ship=v:get_classname()
name_ship_focused=v:get_name()



-- ******************************************************
-- ***********begin call functions for scn file**********
-- ******************************************************

sfirst = line_read (data_path)

slist = load_file (data_path,number_lines)


if  ship=='XR2Ravenstar' then
    lstatus = load_xr2_status (ship)
elseif ship=='Xr5Vanguard' then
    note:set_text('Toward function loop load of XR5Vanguard')
    proc.wait_sysdt(2.01)
elseif ship=='ShuttleA' then
    note:set_text('Toward function loop load of ShuttleA')
    proc.wait_sysdt(2.01)
else
    note:set_text('vessel not implemented, simpit not activated')
    proc.wait_sysdt(2.01)
end
-- ******************************************************
-- ************ end call functions for scn file**********
-- ******************************************************





note:set_text('End of program')
proc.wait_sysdt(1)
note:set_text('  ')
proc.wait_sysdt(1)

Tout ça ne sert à rien si on ne peut pas envoyer les tableaux Status_array[] et Level_array[]
vers les cartes Arduino par l'intermédiaire d'un ou plusieurs ports USB. Les  premiers essais
ne sont pas très encourageants.
D'après ce que j'ai compris, il faut la librairie luars232.dll à placer dans le dossier Scripts d'Orbiter.
Ensuite, on devrait l'appeler par:

Code: [Select]
rs232 = require("luars232)
Mais ça ne marche pas; le script s'arrête. J'ai essayé avec la commande "dofile" au lieu de"require".
Pas mieux.
En utilisant debug.traceback(), j'obtiens des indications:
            Stack traceback:
   -Script/Simpit/Widdeernix_light.lua:23:in main chunk
   -[C]:in function'dofile'
   -Script\oapi_init.lua:27:in function'run'
   -[String"line"]:1:in main chunk

Mais ça, c'est la ligne avant l'essai d'exécution de "require("luars232)"

Si quelqu'un a une idée pour charger cette librairie ou une autre, je suis preneur.

Mars Bleu