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: Le tableau de commande de Mars Bleu  (Read 42040 times)

0 Members and 2 Guests are viewing this topic.

Offline jacquesmomo

  • Le budget !!!
  • Legend
  • ******
  • Posts: 7408
  • Country: France fr
  • Karma: 598
  • Plus on rate, plus on a de chances de réussir !..
Reply #75 - 03 July 2017, 08:19:37
(...)
 Ça a l'air simple comme ça, mais c'est plus compliqué qu'il n'y paraît.
:trucdeouf: hébé...

Mes add-ons sont là !

Offline Mars Bleu

  • Hero Member
  • *****
  • Posts: 638
  • Karma: 33
Reply #76 - 03 July 2017, 08:39:34
@ Jacquesmomo, ne t'inquiètes pas, si j'ai réussi à faire fonctionner tout ça,
alors tout le monde peut le faire!!

@Antoo,  j'espère que ton projet avance bien.

@ tous les lecteurs, j'espère que la balade vous plaît.


Offline antoo

  • Legend
  • ******
  • Posts: 3659
  • Country: France fr
  • Karma: 179
  • MSFS ❤️
Reply #77 - 03 July 2017, 21:14:32
Quote
@Antoo,  j'espère que ton projet avance bien.

Oui, vous aurez des news serieuses et photos demain soir :) .

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

Offline Mars Bleu

  • Hero Member
  • *****
  • Posts: 638
  • Karma: 33
Reply #78 - 08 October 2017, 19:25:12
Il est grand temps que je continue d'exposer mes élucubrations, les dernières exposées ici remontant à une date déjà
lointaine. C'est que cet été, je n'ai pas eu tellement de plages temporelles propices pour développer, ni faire des
montages électroniques.
Par dessus le marché, lorsque j'ai voulu démarrer mon système, plus grand chose ne fonctionnait. C'était assez
frustrant. Maintenant que j'ai repris la main, je peux continuer.

Je vous parlais dans un précédent post de....

          Envoi de raccourcis clavier par mouvement de switch ou bouton poussoir

La UNO ne pas être vue comme un clavier sans quelques dispositions préalables. Voir les posts de Hysot à ce sujet. La librairie HIDKeyboard doit être "included". La doc qui l'accompagne montre l'utilisation par envoi de chaîne de caractère direct: par exemple,  keyboard.pressKey (CTRL, "a").

Mais je ne voulais pas avoir une structure pleine de if{}/else{}, ni de switch/case. Pour ça, il fallait faire un tableau, et utiliser la commande keyboard.pressKey() avec des paramètres.

Après quelques recherches et essais pas toujours réussis, j'ai fini par mettre au point le bout de code suivant:

En en-tête pour charger la librairie:

# include<HIDKeyboard.h>
HIDKeyboard keyboard;


Dans les déclarations:

const byte XrModifier[]={0,0,0,0,1,4,1,1,1,1,1,4,0,1,1,1};
const char XrKey[]={32,32,32,103,98,114,121,92,118,103,117,111,32,111,107,97}


XrModifier[] contient les caractères de contrôle: 0, pas de caractère de contrôle
                       1 correspond à CTRL
                       4 correspond à ALT

XrKey[] contient les codes ASCII des lettres à envoyer pour correspondre aux raccourcis clavier.

Le bout de code formant la fonction:

void keyboard_command(byte start, byte offset, unsigned int command);
{
   for( byte i=start;i<16;i++)
      {
         if(bitRead(command, i)==1)
            {
               keyboard.pressKey(XrModifier[i+offset], XrKey[i+offset];
               temporelease();
            }
      }
}


 Pour les raccourcis APU, cette fonction est appelée par:

keyboard_command(3,0,(PISOreg[0]^previousPISOreg[0]));


J'ai inséré cette fonction dans le programme principal tournant dans la UNO: téléversement, puis flashouillage pour la transformer en clavier. L'essai montre que le script Lua se fige dès qu'on ouvre le port de communication.

Normal!! Si la UNO est en keyboard, alors elle ne peut pas reçevoir de données. La carte UNO n'est donc pas le bon dispositif. En fait, il faut une Arduino qui permette d'envoyer des codes clavier sans être en permanence en mode clavier.
La carte Leonardo est tout à fait recommandée, car j'ai pu l'insérer sur son support en remplacement de la UNO. Petit inconvénient, elle a encore moins de mémoire disponible que la UNO (Il faudra compacter davantage le code!!!). Il existe heureusement la possibilité d'utiliser une DUE dont la mémoire est bien plus spacieuse, et la cadence d'horloge bien plus rapide. Mais il faudra lui faire un support adapté, et prévoir un interface pour que son 3.3volts d'entrées/sorties puisse travailler sans dégâts pour elle avec le 5 volts des circuits environnants.

Dans un prochain post, je vous parlerai de l'adaptation de mon petit bout de code à la carte Leonardo.
Ça va permettre à mon système de commander le Xr2 par les raccourcis clavier, tout en commandant les
lumineux présents sur mon tableau de commande. Mais ça va se compliquer un peu! :badfinger:


Offline jacquesmomo

  • Le budget !!!
  • Legend
  • ******
  • Posts: 7408
  • Country: France fr
  • Karma: 598
  • Plus on rate, plus on a de chances de réussir !..
Reply #79 - 09 October 2017, 00:04:44
Je suis toujours ça avec intéressement.... :applause:

Mes add-ons sont là !

Offline Mars Bleu

  • Hero Member
  • *****
  • Posts: 638
  • Karma: 33
Reply #80 - 09 October 2017, 22:46:05
Merci, Jacquesmomo!!
Et j'ai encore plein de trucs à exposer.


Offline Mars Bleu

  • Hero Member
  • *****
  • Posts: 638
  • Karma: 33
Reply #81 - 22 October 2017, 16:06:16
En effet, ça se complique dans la mesure où on va avoir deux façons d'envoyer un raccourci clavier. :wonder:
Premier mode: le changement d'état d'un switch provoque l'envoi d'un caractère.
Deuxième mode: l'appui sur un bouton-poussoir va lancer l'envoi d'un caractère, mais son retour à la position
initiale (on relâche le BP) ne va rien faire du tout.

Voici la nouvelle version, tenant compte de la syntaxe Leonardo, et de la possibilité switch/BP.



// Ce code commande un raccourci clavier pour  orbiter en fonction des bits de command
// J'ai ajouté un switch de sécurité: s'il est sur 1, alors l'envoi de caractère est autorisé
// s'il est sur 0, alors pas d'envoi de caractère.
// Avec le BP sur pin 3, je peux envoyer une commande de mouvement de gear sur changement d'état
// Ceci se fait avec la transmission de la variable XORdifference, modulée par switch_mode_mask
//
// Ici, c'est l'essai de ALT L (MAIN yaw vers la droite) sur la case 2 en mode BP
// On peut donc envoyer des caractères de contrôle d'Orbiter en mode switch ou en BP en fonction de APU_aux et switch_mode_mask

const byte secuSwitch=2;
const byte BP=3;
const byte led=13;
byte APU_aux;
byte secuSwitchstatus=0;

unsigned int var;
unsigned int old_var;
unsigned int switch_mode_mask;//si bit à 1, on est en mode"switch", si bit à 0, on est en mode "BP"

unsigned int XORdifference;
const byte xrmodifier[]={0,0,130,0,128,130,128,128,128,128,128,130,0,128,128,128};
const byte xrkey[]={32,32,108,103,98,114,121,92,118,103,117,111,32,111,107,97};
//Les deux lignes ci-dessus sont le tableau des raccourcis clavier auxquels on va s'adresser
//Les xrmodifier:128=>CTRL, et 130=>ALT. Pour info, 129=>SHIFT. Pas de modifier=>0.
//Les xrkey sont les codes ASCII des raccourcis clavier.

void setup()
{
pinMode(secuSwitch,INPUT);
pinMode(BP,INPUT);
pinMode(led,OUTPUT);
APU_aux=4;//commande MAIN yaw vers la droite
switch_mode_mask=8;//paramétrage en mode "switch"ou mode "BP"
}
void loop()

 {
   var=APU_aux*digitalRead(BP);
   XORdifference=(var^old_var);

   keyboard_command(3,0,XORdifference,switch_mode_mask);//appel de la fonction d'envoi de clavier, à installer.
   delay(50);
   old_var=var;
 }//End loop

//La fonction générant le raccourci clavier:
void keyboard_command(byte start,byte offset,unsigned int command,unsigned int switchModeMask)
    {
        secuSwitchstatus=digitalRead(secuSwitch);//ce secuSwitchstatus est là pour éviter un incident d'inaccessibilité
        digitalWrite(led, secuSwitchstatus);//signalisation de l'état de secuSwitchstatus sur la led 13 de la Leonardo
        boolean Switch_or_BP;   //variable booléenne  pour savoir si on est en mode Switch ou BP
        Keyboard.begin();
           for (byte i=start+offset;i<16+offset;i++)
            {
                Switch_or_BP=bitRead(switchModeMask,i);
                if ((bitRead(command,i)==1)&&(secuSwitchstatus==HIGH))
                    {
                         boolean bitvar=bitRead(var,i);//valeur pour transmettre l'état du bit de rang i de la variable globale var
                         xr_presskey(xrmodifier[ i ],xrkey[ i ],Switch_or_BP,bitvar);
                     }
             }
         Keyboard.end();
      }

//L'envoi des caractères:
 void xr_presskey(byte xrmodifier,byte xrkey,boolean SwitchOrBP,boolean bitVarStatus
 {
    if((SwitchOrBP==1)|(bitVarStatus==1&SwitchOrBP==0))
    {
    Keyboard.press(xrmodifier);
    Keyboard.press(xrkey);
    delay(20);
    }
    if((SwitchOrBP==1)|(bitVarStatus==0&SwitchOrBP==0))
    {   
    Keyboard.releaseAll();
    }
  }




En faisant varier la valeur de command, on va pouvoir définir l'envoi des raccourcis claviers. Et voilà!!

ATTENTION: Prévoir un dispositif d'arrêt d'urgence en hardware.

J'ai eu des ennuis de reprise en main de la Leonardo qui était partie à envoyer CTRL U toute les 5 secondes. Pour le Xr2 dans Orbiter, ça revenait à manœuvrer la porte de soute Baydoors, mais pour l'IDE Arduino, c'était le déclenchement d'un téléversement toute les 5 secondes. Du coup, plus moyen de changer le sketch tournant à l'intérieur.
J'ai fini par trouver: il faut laisser se faire un téléversement d'un sketch, mettons Fichier\Exemple\01.Basics\Blink. Avant qu'un nouveau CTRL U soit envoyé, il faut activer une nouvelle fenêtre, par exemple l'utilitaire Bloc Note qui recevra les caractères envoyés par la Leonardo, le temps que le téléversement se fasse. C'est comme ça que j'ai réussi à reprendre la main.
Pour éviter de nouveaux ennuis, j'ai installé un switch de sécurité en hardware. En cas de perte de contrôle par envoi intempestif de caractères par la Leonardo, la manœuvre du switch permettra de reprendre la main plus rapidement et plus facilement.
Par la suite, ayant maîtrisé l'affaire, j'ai pu retirer cette disposition de précaution.

Dans un prochain post, je vais m’employer à faire une petite vidéo pour montrer le fonctionnement de tout ça.
Je ne promets rien pour les délais, car j'ai encore beaucoup à faire pour rendre mes prototypes un peu jolis
à voir.

« Last Edit: 22 October 2017, 16:12:27 by Mars Bleu »

Offline Mars Bleu

  • Hero Member
  • *****
  • Posts: 638
  • Karma: 33
Reply #82 - 25 November 2017, 19:29:58
Afin de montrer que tout ce qui précède est fonctionnel, voici le lien de la vidéo promise dernièrement.
Je n'en suis qu'à moitié satisfait quant à la qualité, mais en l'état actuel des choses, pas moyen de
faire mieux :(. (Je sais que je devrais aller faire un stage chez Tex...)
Le lien:
https://www.youtube.com/watch?v=jycjemN2I5U

Je suis preneur de conseils pour les prises de vues, l'intégration de vidéos entre elles. Et aussi
de mettre une vidéo directement dans un post. Dans ce domaine, j'ai encore pas mal à apprendre.

Nous allons pouvoir passer à une autre partie du cockpit: il s'agit de l'équilibre du Xr2, et de
l'orientation des moteurs. Ça sera plus simple que la gestion des auxiliaires APU, vous verrez.

A +
Mars Bleu


Offline antoo

  • Legend
  • ******
  • Posts: 3659
  • Country: France fr
  • Karma: 179
  • MSFS ❤️
Reply #83 - 27 November 2017, 12:42:28
Génial! Que c'est grisant  :love: !

A+

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

Offline Mars Bleu

  • Hero Member
  • *****
  • Posts: 638
  • Karma: 33
Reply #84 - 28 November 2017, 12:54:30
Oui! Il est toujours très plaisant de voir le simpit s'amplifier,
et gagner de nouvelles fonctions.


Offline Mars Bleu

  • Hero Member
  • *****
  • Posts: 638
  • Karma: 33
Reply #85 - 16 December 2017, 10:13:47
La gestion des auxiliaires APU étant opérationnelle, nous allons pouvoir passer à un nouveau TP.
Il n'est pas très spectaculaire, mais excellent au niveau de l'exercice, vous verrez.

J'ai choisi de m'occuper de:

           Bargraphs pour la gestion de l'orientation des moteurs principaux et l'équilibre du vaisseau


On a la possibilité d'orienter les moteurs principaux, et SCRAM (gimbal), ainsi que de manœuvrer la masse d'équilibrage (rentrée atmosphérique).

L'initialisation se fait aussi à partir des données extraites du scn, et transmises à la UNO par des fonctions encadrées par les fonctions "widdernix" du script Lua. Dans le cockpit original dessiné par Altea Aerospace, on a des indicateurs à aiguille dont la gamme n'est pas la même pour tous les moteurs.

Pour des raisons économiques, j'ai préféré utiliser des bargraphs de 15 leds, pilotables par un mot de 16 bits. Quinze leds, c'est bien pour avoir une position centrale, avec le 8° bit allumé, et 7 bits éteints de chaque côté. L'ennui, c'est que j'avais à ma disposition uniquement des bargraphs de 20 leds. Pour arriver à mes fins, j'ai pris une scie, et coupé le plus proprement possible mes quatre bargraphs afin d'obtenir des bargraphs de 15 leds. Le résultat est tout à fait satisfaisant. J'ai installé tout cela avec ses résistances de protection de 1KΩ par led, plus un trimmer 0 à 1KΩ par bargraph.
En effet, pour des raisons de luminosité, cette disposition était la meilleure. J'ai terminé l'ensemble en faisant un câblage rampant pour relier les bargraphs aux connecteurs 2x13 pôles.



On est encore un peu dans du provisoire qui va durer, mais c'est fonctionnel. Vous voyez qu'il y a des câbles disponibles(p.ex.sur la nappe 3). Pour l'instant, je ne sais pas s'ils vont servir.

Le tableau (provisoire qui dure) de commande:




Pour la gestion logicielle, j'associe les mémoires:    SIPOreg[6] à Pitch Main dir
                                                                          SIPOreg[7] à Yaw Main
                                                                          SIPOreg[8] à Pitch SCRAM dir
                                                                          SIPOreg[9] à Center Gravity shift


On doit connaître le temps de transit d'un bout à l'autre de la gamme de mouvement de l'appareil considéré. On en tire une équation du premier degré donnant la position par rapport à un point central. Un peu de maths, les gars!

J'ai mesuré:      pitch main dir:    5 secondes, soit 5000 ms pour une amplitude de ±0,017455
                       main yaw:          7.2 secondes, soit 7200 ms pour une amplitude de ± 0,12987
                       pitch scram dir:  6 secondes, soit 6000 ms pour une amplitude de ± 0,087156
                       gravity shift:      70 secondes, soit 70000 ms pour une amplitude de ±4,115


Comme j'ai besoin de la durée de référence, et qu'on s'aperçoit que 70000 ne peut pas être codé sur deux octets (unsigned int), j'ai décidé d'y mettre un coefficient de 1.25 plus petit. Ce qui fait qu'on aura 70/1,25=56. D'où:

                    Gravity shift   56 1,25 secondes, soit 56000 1,25ms pour une amplitude de ±4,115
                    Or 56000 tient dans deux octets (65535>56000): ça tombe bien.

On en tire les équations suivantes, avec level tiré de scn (à la bonne ligne):

   main pitch dir:       value=143225,43*level+2500
   main yaw:             value=27720,027*level+3600
   scram pitch dir:     value=34421,038*level+3000
   gravityshift:          value=6804,3842*level+28000

Ces calculs sont faits par le script Lua et envoyés par USB vers le sketch Arduino dans respectivement les cases Position[16 à 19], où les valeurs pourront être modifiées par appui sur les boutons-poussoirs de commande.

Dans un prochain post je vous ferai part des codes Lua et C++ nécessaires au bon fonctionnement de ce dispositif. Bonne lecture!


Offline Mars Bleu

  • Hero Member
  • *****
  • Posts: 638
  • Karma: 33
Reply #86 - 06 January 2018, 16:07:06
Et voici la suite....

J'ai choisi d'appeler la fonction gérant l'équilibrage du vaisseau

                          balance_bargraph_management()

Cette fonction contient plusieurs actions distinctes:

- filtration des actions commandées par les boutons poussoirs, en passant par la valeur Transit_balance_status.
Cette filtration est rendue nécessaire pour gérer l'action des BP de centrage.

- en fonction des valeurs des bits de Transit_balance_status, action sur les valeurs Position[16 à 19], tout en
tenant compte des différentes vitesses de transit (gimbal/gravity shift)

- allumage des leds des bargraphs concernés, en fonction des valeurs Position[16 à 19] venant d'être modifiées.

- rendre clignotante la led du bargraph Gravity shift pendant un transit, et gérer la led de discordance, allumée
si on veut faire un mouvement alors que l'APU est arrêté.

-envoi des raccourcis clavier.

Pour des raisons de compacité et de rapidité, j'ai préféré utiliser les fonctions bitwise ou les bitWrite plutôt que des if{}/else{}.

Donc, plutôt que de faire:


if  i=1
     {
        j=128
     }
Else if i=2
     {
        j=130
     }
   
Qui est lisible et propre,  j'ai écrit:

        j=128*(i==1)+130*(i==2)

C'est plus vilain, et ça se complique vite, au risque d'être indépannable si on a des problèmes. L'idée est de bien faire marcher et de refermer la boîte en espérant ne plus avoir à l'ouvrir! Avec pleinpleinplein de commentaires mis pour s'y retrouver.


              Filtration des actions par Transit_balance_status

Il faut tenir compte, bien entendu de l'action sur les boutons poussoirs, mais aussi tenir compte de l'action spécifique des BP de centrage, en maintenant un "appui centrage", une fois celui-ci initié jusqu'à ce que l'on se retrouve en position médiane pour les valeurs Position[16 à 19]

Pour la Leonardo, ça fait:

void balance_bargraph_management()
{
   Transit_balance_status=(PISOreg[2]&255)|(Transit_balance_status&128&(128*((Position[18]<27985)|(Position[18]>28015))))|(Transit_balance_status&64&(64*((Position[15]<2470)|(Position[15]>2530)|(Position[16]<3570)|(Position[16]>3630)|(Position[17]<2970)|(Position[17]>3030))));//élaboration des autorisations de mouvement.Vous avez vu comme ça pique les yeux, une ligne pareille? :arg:
 
  if (( Transit_balance_status&128)==128)
   {   //Si ordre de centrage Gravityshift, simulation d'appui BP mouvement gravityshift, jusqu'à être à environ 28000
      Transit_balance_status=Transit_balance_status|(32*(Position[18]<27985))|(16*(Position[18]>28015));
   }
  if (( Transit_balance_status&64)==64)
   {   //Si ordre de centrage gimbal, simulation d'appui BP mouvement gimbal, jusqu'à être à environ respectivement 2500, 3600 et 3000
           Transit_balance_status=Transit_balance_status|((8*(Position[16]<3570))|(4*(Position[16]>3630))|(2*(Position[15]<2470))|(Position[15]>2530)|(2*(Position[17]<2970))|(Position[17]>3030));

        }



                  Action sur les valeurs Position[16 à 19]

Dans une boucle, on scrute le temps passé depuis le dernier passage par là, pour changer les valeurs Position[16 à 19]. Il a fallu rajouter tout un tas de modérateurs pour tenir compte des différences de vitesse existant entre chaque auxiliaire. Par exemple, il a fallu réduire d'un facteur de 0.8 le "passage du temps" pour Gravity shift, de façon à pouvoir faire 70000 avec 56000, et tenir compte de la marche de l'APU.

                      Attention les yeux!


 for(byte i=15;i<20;i=i+2)//lecture de Transit_balance_status en vue mouvements gimbal et gravity shift
  {
   if (bitRead(Transit_balance_status, i-15)==1)
   {
                  Position[i-(i>15)]=Position[i-(i>15)]-((((millis()-mem_time)/(4+(i>17)))*4*(1+9*((i>17)*(bitRead(Transit_balance_status,7)==1)*(abs(Position[18]-(refPosition[18]/2))>700))))*(i>15|bitRead(Transit_balance_status,6)==0|Position[i ]>(refPosition[i ]/2)+30)*APUrunning);//décrémentation en général
              // décrémentation de Position[15, 16, ou 18]              coefficient de 0.8 pour Gravityshift    si proche centre Gravityshift, ralentissement mvt pour approche centre        inhibition mvt si: NON(i=15&digit 64 allumé&Position[15]<2530)
                if(Position[i-(i>15)]<50)//si dépassement position(à 50 ms près),...
                {
                  Position[i-(i>15)]=50;//recalage à la valeur min, c'est à dire pas loin de zéro, ceci afin d'éviter de passer <0
                }
      if(i<16)
      {
          Position[i+2]=Position[i+2]-((millis()-mem_time)*(i>15|bitRead(Transit_balance_status,6)==0|Position[i+2]>(refPosition[i+2]/2)+30)*APUrunning);//décrémentation pour SCRAM PITCH
                 // décrémentation de Position[17]                 inhibition de mvt si: NON(i=15&digit 64 allumé&Position[17]<3030)             et lié à marche APU
                 // cette inhibition de mvt ajoutée pour pouvoir centrer gimbal pitch MAIN et SCRAM même si décalage à cause d'un différentiel de fin de course

                    if(Position[i+2]<50)//si dépassement position(à 50 ms près),...
                      {
                        Position[i+2]=50;//recalage à la valeur min, c'est à dire loin de zéro, ceci afin d'éviter de passer <0
                      }
      }
   }
   if (bitRead(Transit_balance_status, i-14)==1)
   {
                Position[i-(i>15)]=Position[i-(i>15)]+((((millis()-mem_time)/(4+(i>17)))*4*(1+9*((i>17)*(bitRead(Transit_balance_status,7)==1)*(abs(Position[18]-(refPosition[18]/2))>700))))*(i>15|bitRead(Transit_balance_status,6)==0|Position[i ]<(refPosition[i ]/2)-30)*APUrunning);//incrémentation en général
              // incrémentation de Position[15, 16, ou 18]              coefficient de 0.8 pour Gravityshift    si proche centre Gravityshift, ralentissement mvt pour approche centre        inhibition mvt si: NON(i=15&digit 64 allumé&Position[15]>2470)


                if(Position[i-(i>15)]>refPosition[i-(i>15)]-50)//si dépassement refposition(à 50 ms près),...
                {
                  Position[i-(i>15)]=refPosition[i-(i>15)]-50;//recalage à la valeur max à 50 ms près
                }
      if(i<16)
      {
          Position[i+2]=Position[i+2]+((millis()-mem_time)*(i>15|bitRead(Transit_balance_status,6)==0|Position[i+2]<(refPosition[i+2]/2)-30)*(APUrunning));//incrémentation pour SCRAM PITCH
                 // incrémentation de Position[17]                 inhibition de mvt si: NON(i=15&digit 64 allumé&Position[17]>2970)             et lié à marche APU
                 // cette inhibition de mvt ajoutée pour pouvoir centrer gimbal pitch MAIN et SCRAM même si décalage à cause d'un différentiel de fin de course

                    if(Position[i+2]>refPosition[i+2]-50)//si dépassement refposition(à 50 ms près),...
                      {
                        Position[i+2]=refPosition[i+2]-50;//recalage à la valeur max à 50 ms près
                      }
        }
   }
  }//next i


Allez, on a presque fini!

                             Allumage des leds des bargraphs concernés:

Pour savoir quelle led de chaque bargraph allumer, j'ai mis:

  // boucle d'allumage des digits pour affichage de la position gimbal et gravity shift
  float barval=0;//barval pour BARgraph VALue
  for(byte i=15;i<19;i++)
  {
    barval=Position[i ];
    barval=(barval*15)/refPosition[i ];
    byte rank=barval;
    SIPOreg[i-9]=0;
    bitSet (SIPOreg[i-9], rank);
  }//next i



Mais il faut encore gérer le clignotement des leds du bargraph COGshift pour montrer qu'on est en mouvement:


// ligne ci-dessous: bargraph gravity shift: clignotement si appui BP, fixe si pas d'appui BP, ou arrivé en fin de course
  SIPOreg[9]=SIPOreg[9]&(((Onehz-32768)*((Transit_balance_status&48)>0))|((~(32767*((Transit_balance_status&48)>0)))|(32767*(Position[18]<60))|(32767*(Position[18]>(refPosition[18]-60)))));
//                         clignotement: -si BP fwd ou aft pressés            fixe: -si BP fwd ou aft NON pressé       OU -fin de course basse  OU    -fin de course haute
  bitWrite(SIPOreg[9],15,(((Transit_balance_status&255)>0)&(~APUrunning)));//Si commande mouvement gimbal ou gravity shift et APU offline, alors led rouge de discordance





Il reste encore:

                      envoi des raccourcis clavier

  keyboard_command(0,16,8,(PISOreg[2]^previousPISOreg[2])&255,PISOreg[2]&255,0);//appel de la fonction d'envoi de clavier start=0;offset=16;width=8,Status=état des BP,0 cad mode BP partout


Ça, c'était encore le plus simple.


En regardant bien, ça n'est pas si bien compliqué. On gère les ordres de centrage, puis les mouvements
contenus dans les valeurs Position[16 à 19] (décrémentation ou incrémentation). Une fois tous ces calculs
faits, on calcule quelles leds des bargraphs on allume, avant d'envoyer les raccourcis claviers pour que
Orbiter puisse suivre les variations qu'on a effectuées sur le simpit.

Je vous laisse digérer tout ceci, avant de vous parler d'un nouveau TP à propos d'un tableau de commande pour un docking réussi en orbite.

A bientôt
Mars Bleu


Offline jacquesmomo

  • Le budget !!!
  • Legend
  • ******
  • Posts: 7408
  • Country: France fr
  • Karma: 598
  • Plus on rate, plus on a de chances de réussir !..
Reply #87 - 06 January 2018, 18:35:37
Stupéfiant.....
incroyable... une fois
amazing !
Tiguidou !


Mes add-ons sont là !

Offline Mars Bleu

  • Hero Member
  • *****
  • Posts: 638
  • Karma: 33
Reply #88 - 06 January 2018, 20:13:56
Quote
Stupéfiant.....

incroyable...une fois

amazing!

Tiguidou!

C'est un peu tout ça, mais pour le produire, c'était , et puis .Mais surtout ça

 :merci:@ Jacquesmomo


Offline nerofox

  • Sr. Member
  • ****
  • Posts: 366
  • Country: France fr
  • Karma: 23
Reply #89 - 06 January 2018, 23:24:05
chapeau bas pour la compacité du code  :wor:, malgré les commentaires je pense que tu sera le seul a pouvoir maintenir un tel programme  :badfinger:


Offline Mars Bleu

  • Hero Member
  • *****
  • Posts: 638
  • Karma: 33
Reply #90 - 07 January 2018, 17:45:27
pour le...
Quote
chapeau bas

Pour la maintenance, j'espère pouvoir m'y retrouver.  :wonder:
Mais en principe, je ne dois plus avoir à tripoter là dedans.

Sinon, en ce moment, je patauge bien dans les échanges de données Arduino->Lua. J'ai du mal à ne
pas faire planter le script...


Offline Maverik09

  • Full Member
  • ***
  • Posts: 73
  • Karma: 3
Reply #91 - 08 January 2018, 03:04:50
Et bien, tout cela me semble d'une complexité incroyable...
Hâte de voir le résultat final !!
Bonne continuation

J'ai appris à employer le mot “impossible” avec la plus grande prudence.
-Wernher Von Braun -

Offline Mars Bleu

  • Hero Member
  • *****
  • Posts: 638
  • Karma: 33
Reply #92 - 08 January 2018, 23:53:33
Merci, Maverick09.
Mais même si cela peut paraître compliqué, en fait, c'est parce qu'il
commence à y avoir pas mal de choses à gérer. Il faut diviser les gros trucs
en morceaux simples. Bon. N'empêche que parfois, je galère bien!  :wall:


Offline antoo

  • Legend
  • ******
  • Posts: 3659
  • Country: France fr
  • Karma: 179
  • MSFS ❤️
Reply #93 - 09 January 2018, 01:15:49
Mais tu te débrouilles quand même très bien !

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

Offline Mars Bleu

  • Hero Member
  • *****
  • Posts: 638
  • Karma: 33
Reply #94 - 11 January 2018, 23:23:45
Merci, Antoo!
Au fait, j'espère que tu avances bien dans ton énorme projet...


Offline antoo

  • Legend
  • ******
  • Posts: 3659
  • Country: France fr
  • Karma: 179
  • MSFS ❤️
Reply #95 - 24 January 2018, 00:46:33
Salut,

Ma foi ça avance, mais doucement. Là à l'instant où j'ecris ces mots, mon frere travaille sur les dll du shuttlePB :D .
A+

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

Offline Mars Bleu

  • Hero Member
  • *****
  • Posts: 638
  • Karma: 33
Reply #96 - 03 February 2018, 11:16:06
@ Antoo: l'essentiel est d'aller dans la bonne direction. Bravo pour ce grand projet.


Abordons maintenant la conception et la programmation d'un panneau essentiel pour une approche, et
un appontage réussi, le...... :hurle:tadaaaa...

                                                  Docking panel


      Pour réaliser un appontage dans de bonnes conditions, j'ai choisi d'avoir quatre joysticks.
L'idéal aurait été d'avoir seulement un joystick permettant d'orienter l'engin dans les 6 directions
de l'espace (+x;-x;+y;-y;+z;-z). Deux de ces joysticks auraient reproduit ce qui existe sur les
engins réels. Mais ça aurait été trop de boulot de micromécanique à réaliser. Je n'ai malheureusement 
un budget extensible à l'infini...
Plutôt que d'avoir à gérer le commutateur ROT/LIN, j'ai préféré avoir une option automatique, en
fonction du joystick actionné (un commut de moins,  :badfinger:!). D'où l'ensemble de 4 joysticks.
A cet ensemble, il faut rajouter le KILLROT, le commutateur RCS ON/OFF, celui de RCS à 100% ou
à 30%, le gros coup-de-poing rouge pour le UNDOCK sécurisé par un commutateur "Undock Armed",
et les lumineux associés. Total, 9 dispositifs de commande représentant 16 switches (ah bé, ça tombe
bien pour tenir dans un unsigned int)  et 10 lumineux de signalisation.

La réalisation en mode provisoire qui va durer un petit peu:





Ce qui a été délicat dans la construction de ce panel a été la mise au point de l'implantation des composants
 sur la plaque à pastilles de cuivre. Il a fallu faire des changements, et des parties de soudage/dessoudage
/ressoudage très laborieuses.

La plaque à pastilles in situ:



Trois parties figurent sur cette plaque:

         1°, la liaison entre l'ensemble des switches du panel, et les nappes de câbles en provenance
de la plaque portant les circuits d'élaboration de signal située derrière le panneau "craft balance"
         2°, la liaison entre la nappe de câbles en provenance du module SIPO et les leds de signalisation.
J'ai placé un trimmer variant de 0 à 1Kohm sur le retour vers GND de façon à pouvoir régler
 la luminosité des 5 leds associées (RCS On/ Mismatch/ Off), Translation/Rotation Mode)
         3°, afin d'alléger mon sketch Arduino, j'ai eu l'idée d'utiliser les switches dispos sur mes commutateurs,
et autre coup-de-poing pour avoir une signalisation complémentaire régie par de la logique combinatoire
assez rudimentaire. Par exemple, on peut régler la puissance des RCS (Normal=>100%/Low=>30%). Si
le lumineux "Normal" est allumé, alors, le lumineux "Low" sera éteint, et vice versa. En Bool, ça fait:
Normal=NON(Low). Donc, un circuit intégré 74HCT04 contenant 6 portes NON fait largement l'affaire, puisque
j'ai besoin de seulement trois portes NON.


Une fois tout ceci assemblé, connecté, et essayé, j'ai pu passer à l'amplification de mon sketch, avec l'écriture
de la fonction "docking_management()" qui va gérer les lumineux du panel, et l'envoi des caractères de contrôle
nécessaires à un appontage réussi.

Mais j'en parlerai dans un prochain post. Bonne lecture!

« Last Edit: 03 February 2018, 13:52:53 by Mars Bleu »

Offline antoo

  • Legend
  • ******
  • Posts: 3659
  • Country: France fr
  • Karma: 179
  • MSFS ❤️
Reply #97 - 03 February 2018, 16:44:06
Je sens que Mars Bleu va nous construire un truc grandiose !

Bravo, ça démarre tès fort. J'ai hâte de voir tous ces éléments s'assembler !

A+

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

Offline Mars Bleu

  • Hero Member
  • *****
  • Posts: 638
  • Karma: 33
Reply #98 - 26 February 2018, 14:34:35
Me voici pour la suite. Ça va être un peu aride, mais nécessaire pour animer et piloter ce nouveau panel.

La mise au point de l'envoi des caractères de contrôle,et de la gestion des lumineux se fait par la fonction suivante:

                                   Contrôle du docking panel:




void Docking_panel_management()
    {
      boolean rotlin=((Miscstatus&3)>0);//variable locale booléenne qui permet de savoir si on est RCS ON ou OFF: FALSE si RCS est OFF         
      boolean RCSrot=((Miscstatus&1)==1);//lumineux allumé en mode "ROTATION"

      boolean RCSlin=((Miscstatus&2)==2);//lumineux allumé en mode "TRANSLATION"
      boolean RCSmismatch=(bitRead(PISOreg[1],6))^rotlin;//variable locale booléenne déterminant si discordance entre commut et état logique venant du SCN
      boolean RCSgreenled=(rotlin==0);
      boolean RCSyellowled=(rotlin==1);
// préparation des variables nécessaires pour les raccourcis claviers liés aux joysticks d'arrimage:
unsigned int joystick_switches=(PISOreg[2]&16128)+(PISOreg[1]&63);
unsigned int joystick_status=((PISOreg[2]^previousPISOreg[2])&16128)+((PISOreg[1]^previousPISOreg[1])&63);

if ((bitRead(PISOreg[1],6))^(bitRead(previousPISOreg[1],6))//si manoeuvre switch RCS ON/OFF...
   {
      Miscstatus=(Miscstatus&65532)+((1+(((Miscstatus&3)<2)==0))*bitRead(PISOreg[1],6));//le dernier bit de Miscstatus suit l'état du commutateur RCS ON/OFF
      if (RCSmismatch==1)// si, de surcroît pas de discordance...
         {
            keyboard_command(6,24,16,16384,0,65535);// envoi de "CTRL /" pour changer RCS  On<->Off
         }
   }
if ((bitRead(PISOreg[1],6))&&(RCSmismatch==0))//à condition que RCS sur "ON" et discordance éteinte....
   {
      if (((PISOreg[1]&63)!=0)&&((PISOreg[2]&16128)==0)&&(RCSlin==1))//si manoeuvre joystick ROT sans manoeuvre joystick LIN et  en mode LIN
         {                                                 //=>les deux derniers bits réglés à : 01 <=>mode ROT
           bitSet(Miscstatus,0);
           bitClear(Miscstatus,1);
           keyboard_command(6,24,16,64,0,65535);//envoi de "/" pour être en mode ROT
         }
      if (((PISOreg[2]&16128)!=0)&&((PISOreg[1]&63)==0)&&(RCSrot==1))//si manoeuvre joystick LIN sans manoeuvre joystick ROT et en mode ROT
         {                                                 //=>les deux derniers bits réglés à : 10 <=>mode LIN
           bitSet(Miscstatus,1);
           bitClear(Miscstatus,0);
           keyboard_command(6,24,16,64,0,65535);// envoi de "/" pour être en mode LIN
         }
      if (joystick_status!=0)//toujours à condition que RCS sur "ON" et discordance éteinte....
         {                        // envoi des raccourcis clavier de commande des RCS
             keyboard_command(0,24,16,joystick_status,joystick_switches,0);
         }
      if (((bitRead(PISOreg[1],7))^(bitRead(previousPISOreg[1],7)))&(bitRead(PISOreg[1],7)))//toujours à condition que RCS sur "ON" et discordance éteinte....
         {        // envoi KILLROT
           keyboard_command(7,24,16,128,0,65535);
         }
   }
 if (((bitRead(PISOreg[2],15))^(bitRead(previousPISOreg[2],15)))&(bitRead(PISOreg[2],15)))//si UNDOCK...
      {
          keyboard_command(14,24,16,32768,0,65535);//envoi de CTRL d
      }

Contrôle des leds de signalisation du panel:
  bitWrite(SIPOreg[3],0,RCSgreenled);//led verte RCS "OFF"
  bitWrite(SIPOreg[3],1,RCSmismatch);//led rouge RCS mismatch
  bitWrite(SIPOreg[3],2,RCSyellowled);//led jaune RCS "ON"
  bitWrite(SIPOreg[3],3,RCSrot);//led jaune mode ROTATION
  bitWrite(SIPOreg[3],4,RCSlin);//led jaune mode TRANSLATION
  bitWrite(SIPOreg[3],5,((Miscstatus&3)>0)&(bitRead(PISOreg[2],14))==0);//led verte RCS "normal", allumage conditionné à: RCS sur "ON"
 bitWrite(SIPOreg[3],6,((Miscstatus&3)>0)&(bitRead(PISOreg[2],14))==1);//led jaune RCS "low", allumage conditionné à: RCS sur "ON"
//Changement des "modifiers" relatifs aux commandes joystick selon RCS Normal/low:

      if (((bitRead(PISOreg[2],14))^(bitRead(previousPISOreg[2],14)))&((bitRead(PISOreg[1],6))&&(RCSmismatch==0)))
      {
          for(byte i=24;i<36;i++)
          {
              xrmodifier[i+(2*(i>29))]=128*(bitRead(PISOreg[2],14));
          }
      }
}//fin de la fonction dédiée au contrôle du docking panel



Les essais au sol, puis en orbite ont permis les dernières mises au point. L'appontage à l'ISS a montré que l'ergonomie de mon panneau est tout à fait satisfaisante. La commutation automatique entre le mode rotation et le mode translation est un vrai plus pour les approches finales.


A bientôt pour un nouveau rendez vous! :salut:


Offline jacquesmomo

  • Le budget !!!
  • Legend
  • ******
  • Posts: 7408
  • Country: France fr
  • Karma: 598
  • Plus on rate, plus on a de chances de réussir !..
Reply #99 - 26 February 2018, 14:43:22
ça va être sympa tout ça...

Dis-moi... tu as commencé ton "tableau de commande" il y a combien de temps déjà ??  :wonder:

Mes add-ons sont là !