Dans Apollo 14, au début de la descente du module lunaire sur la lune, les astronautes ont vu le bouton abort stage clignoter de manière intermittente; un astronaute l'a gentiment tapoté, et il s'est éteint. |
Le problème viendrait d'un signal parasite dans l'interface logique de l'abort. |
Le bouton Abort Stage est le bouton qui permet de se séparer de l'étage de descente avant de retourner au module de commande, tandis que le bouton Abort avorte simplement la mission, et permet de revenir au module de commande avec l'étage de descente. Le bouton Abort Stage est ignoré avant la descente motorisée, car il est alors encore temps de revenir au module de commande avec l'étage de descente. |
Mais, dans la descente motorisée, le signal parasite d'abort pourrait ordonner la séparation des deux étages du module lunaire sans qu'elle ait été demandée par les astronautes en appuyant sur le bouton Abort Stage. Cela signifie que, si une solution n'est pas trouvée pour ce problème, la mission ne peut être menée à terme, et doit être immédiatement avortée. |
Les astronautes ont donc rapporté ce problème à Houston et demandé de l'aide pour résoudre ce problème. Houston a appelé les ingénieurs du MIT pour qu'ils conçoivent une solution pour ce problème, permettant de réaliser la descente motorisée sans qu'elle soit interrompue par un abort non désiré. |
L'équipe du MIT a donc rapidement mis au point une modification pour résoudre ce problème, et l'a envoyée à Houston. |
Houston a ensuite télémétré cette solution magique au module lunaire, laquelle consistait en séquences de touches que les astronautes devaient taper sur le clavier de l'AGC...mais pas immédiatement, au moment adéquat, comme expliqué dans un lien. Lien vers l'explication de la résolution de l'abort dans Apollo 14 |
Juste après la mise à feu du moteur, un bit en mémoire, appelé "LETABORT", est positionné dans un délai rapide de 0,2 seconde; à partir de ce moment, si rien n'est fait, le signal parasite d'abort peut ordonner la séparation des deux étages du module lunaire. |
Si les astronautes attendent que le moteur soit mis à feu, le bit LETABORT sera positionné très rapidement, et cela prendra du temps aux astronautes pour taper la séquence pour razer le bit LETABORT, et, dans l'intervalle, le signal parasite pourrait commander la séparation des étages. Donc, juste après le début de la routine d'allumage, les astronautes doivent taper une commande pour changer le numéro de programme de P63 (qui est un programme de la descente motorisée) en P71 (qui n'est pas un programme de la descente motorisée), de sorte que la commande d'abort stage ne soit pas prise en compte lorsque le bit LETABORT sera positionné. Selon la description du problème, la commande qu'Edgar Mitchell devait taper était: VERB 21 NOUN 01 ENTER 1010 ENTER 107 ENTER |
La description du problème établit que, parce que le programme enregistré dans MODREG a été changé pour un programme qui n'appartient pas à la descente motorisée, la routine d'allumage ne va pas mettre le moteur à pleine poussée après 26 secondes comme elle le devrait normalement. En conséquence la procédure a suivre est d'attendre 26 secondes après le début de la routine d'allumage... |
... et de mettre manuellement la commande de poussée au maximum afin de faire ce que la routine d'allumage aurait du faire normalement si le programme courant n'avait pas été changé... |
...c'est à dire mettre le moteur à pleine poussée. |
Puis Mitchell doit taper une commande pour positionner un bit ZOOMFLAG, ce qui aurait normalement dû être fait par la routine d'allumage (si le programme courant était resté P63), afin de commander logiquement la pleine poussée. Cette commande est: VERB 25 NOUN 7 ENTER 101 ENTER 200 ENTER, 1 ENTER Notez que l'adresse "101" est spécifiée sous forme de trois chiffres en octal, alors que la documentation du DSKY spécifie qu'une adresse machine doit obligatoirement être spécifiée sous forme de 5 chiffres en octal. Le masque de bit "200" est aussi spécifié sous forme de 3 chiffres en octal, alors qu'un masque de bit doit normalement être spécifié sous forme de 5 chiffres en octal, car il y a 15 bits dans un mot, et chaque chiffre octal code 3 bits du mot. Mitchell tape ensuite une commande pour remettre le bit LETABORT à 0, qui est: VERB 25 NOUN 7 ENTER 105 ENTER 400 ENTER, 0 ENTER Finalement Mitchell doit encore rentrer une commande pour remettre le numéro de programme à P63 (programme normal de la descente motorisée), qui est: VERB 21 NOUN 01 ENTER 1010 ENTER 77 ENTER Après que le programme d'allumage normal ait été restauré, le LGC est sensé avoir à nouveau le contrôle de la poussée. |
Finalement la description du problème dit que Shepard remet la manette de contrôle du contrôle de poussée au minimum, de manière à laisser le programme de guidage reprendre le contrôle de la poussée, disent-ils (après la phase de ralentissement, le programme de guidage doit diminuer la poussée). Mais c'est complètement absurde, ce n'est pas ce qu'il doit faire, car le contrôle manuel de la poussée et le contrôle automatique par le LGC ne sont pas cumulatifs, mais exclusifs; ce n'est pas l'un et l'autre, mais l'un ou l'autre. |
La poussée est contrôlée par soit la manette de contrôle, soit le LGC, mais pas les deux en même temps. Quand la manette de contrôle a le contrôle de la poussée, le LGC n'a aucun contrôle dessus (interrupteur de contrôle de mode de la poussée sur la position "MAN"), et, quand le LGC a le contrôle de la poussée, la manette de contrôle n'a aucune action dessus (interrupteur de contrôle de mode de la poussée sur la position "AUTO"). |
Shepard ne doit absolument pas mettre le contrôle manuel de poussée au minimum, mais simplement changer l'interrupteur de mode de contrôle de la poussée de Manuel vers Auto, de manière à redonner le contrôle de la poussée au LGC (auquel cas la manette de contrôle n'est pas du tout prise en compte). |
S'il se contente de mettre le contrôle manuel de poussée au minimum, la poussée restera au minimum, car le LGC n'aura pas le contrôle de la poussée, comme l'interrupteur de mode de contrôle de la poussée reste sur la position "MAN", ce qui signifie que la descente motorisée ne pourra pas se produire normalement. |
En réalité, c'est complètement absurde. En effet, le fait que la routine d'allumage positionne le bit LETABORT, qui fait partie de son traitement, montre qu'elle tourne normalement. Une fois que la routine d'allumage est lancée, il est évident qu'elle va faire son traitement normal complet, et qu'elle ne va pas tester le numéro de programme courant pour ne pas faire une partie de son traitement. Ce que les astronautes auraient donc dû faire est d'attendre que le moteur démarre, et ils auraient alors su à ce moment que le bit LETABORT avait été positionné, et puis simplement taper la commande pour razer le bit LETABORT, suivie de la commande pour restaurer le numéro de programme à P63. Cela aurait fait trois séquences de touches au total, au lieu de quatre, et Shepard n'aurait pas eu à contrôler manuellement la poussée, ce qui aurait été fait automatiquement par la routine de guidage. Le fait que la routine d'allumage n'aurait pas automatiquement contrôlé la poussée est une excuse que les ingénieurs ont inventée pour justifier le fait que Shepard aurait dû contrôler manuellement la poussée, ce qui a permis de créer une anomalie avec Shepard ne redonnant pas le contrôle de la poussée au LGC à la fin de la maneuvre, avec la conséquence que la descente motorisée ne pourrait pas se produire normalement. |
Cette complication inutile est donc une bonne blague de la part des ingénieurs. |
Si les astronautes avaient été capables de modifier le programme dans la core rope memory, ils auraient empêché la routine d'allumage de positionner le bit LETABORT, et, de cette manière, le module lunaire aurait été protégé contre un abort stage non désiré commandé par le signal parasite après le début de la routine d'allumage, sans que les astronautes aient à faire cette procédure compliquée (qui en plus se termine anormalement). |
Mais cela aurait supposé que les astronautes soient capables de modifier le programme dans la core rope memory. La core rope memory était programmée par des ouvrières qui faisaient passer des fils à travers des tores de ferrite ou les faisaient contourner, suivant des instructions qui leur étaient données. Chaque fil représentait un bit. Après leur travail, la core rope memory était testée pour voir si elle avait été correctement tissée. S'il y avait ne serait-ce qu'une seule erreur dans un fil de bit, ce fil devait être complètement retiré et retissé. |
Nous imaginons mal les astronautes faire ce travail dans le module lunaire. La seule ressource qui leur restait était d'appliquer une procédure qui n'était pas parfaite, n'offrait pas une garantie totale de succès, et qui de plus était inutilement compliquée, telle que décrite. |
Et ce n'est pas tout, car la description du problème donne d'autres détails qui sont totalement délirants. Ils disent que la routine a corrigé la hauteur calculée avec seulement une portion de la différence entre la hauteur mesurée par le radar et celle mesurée par les accéléromètres, qu'ils appellent "DeltaH". |
Mais il n'y a rien de tel que la hauteur mesurée par les accéléromètres. Les accéléromètres ne donnent pas directement la hauteur courante. La hauteur calculée est précisément mise à jour à partir de la lecture des accéléromètres (une première intégration pour mettre à jour la vitesse verticale à partir de la lecture de l'accéléromètre vertical, et une seconde pour mettre à jour la hauteur courante à partir de la vitesse verticale). |
Ils disent ensuite qu'à 50000 pieds, ils ajoutent 0% de cette portion, et 35% de cette portion à 10000 pieds. Vous m'expliquerez comment on peut augmenter de 0%! Et combien de cette portion ajoutent-ils entre ces deux hauteurs? |
Je vais maintenant expliquer pourquoi cela n'a pas de sens de corriger la hauteur calculée avec seulement 35% de la différence avec la hauteur obtenue à partir du radar. Un accéléromètre n'est pas parfait, il y a toujours une légère erreur de biais. Pour mettre à jour la hauteur calculée, cette erreur passe à travers une double intégration, et cette double intégration tend à faire diverger cette erreur. Si la hauteur calculée est corrigée avec seulement 35% de la différence avec la hauteur obtenue par le radar, qui est plus précise, seulement 35% de cette erreur est compensé, il en reste 65% dans la hauteur calculée. |
Ensuite, ils disent que, si le registre de programme ne contenait pas P63, la routine de mise à jour penserait que le programme courant était P66 et incorporerait les 35% du DeltaH; alors la routine ne vérifie même pas la hauteur courante? Ils disent que le problème sur le radar d'alunissage aurait été provoqué par un bit d'échelle qui aurait changé 38 secondes avant que l'une des procédures de masquage d'abort soit entrée; vous m'expliquerez le rapport entre un problème avec le radar d'alunissage et l'entrée d'une procédure de masquage d'abort! Tout ceci n'est qu'une suite d'absurdités! |
Je me suis intéressé à la manière dont l'abort était traité dans le programme de l'AGC, et comment le bit LETABORT était pris en compte, quelle différence cela faisait entre ce bit mis à 1 ou à 0 lorsqu'un abort était demandé. Dans le programme entier de l'AGC, il n'y a qu'un programme unique ou ce bit est pris en compte (à part sa mise à zéro au début du programme de descente), c'est à dire dans le traitement des programmes P70 et P71 (LEM LM DPS Abort, and LEM LM DPS abort). Et je montre ici l'unique séquence dans laquelle ce bit est testé. Je vais détailler cette séquence, pas à pas. |
Cette séquence teste si le bit LETABORT (correspondant à LETABBIT) est positionné. S'il l'est, le résultat ne sera pas nul, sinon l'instruction BZF LANDISP (branchement si l'accumulateur est nul) fait un branchement à LANDISP, ce qui correspond au traitement de R10, selon le commentaire. |
Donc, si le bit LETABORT est mis, nous continuons en séquence. MODREG contient le numéro de programme courant; l'instruction "CS MODREG" place le contenu négatif de MODREG dans l'accumulateur, ce qui signifie que, si le programme courant est P71, l'accumulateur contient à présent -71. L'instruction "AD 1DEC71" ajoute 71 à l'accumulateur, ce qui signifie que, si le programme courant est P71, l'accumulateur contient à présent 0. L'instruction "BZF LANDISP" fait un branchement à LANDISP si l'accumulateur est nul, autrement dit si le programme courant est P71, selon ce qui a été dit. |
Donc, si le programme courant n'est pas P71, le programme continue en séquence. L'instruction "READ CHAN30" lit le contenu du canal 30. |
Le canal 30 est décrit dans le manuel technique du module lunaire. Les deux bits intéressants sont le premier bit, qui est positionné si un abort utilisant le moteur de descente a été demandé (en appuyant sur le bouton ABORT), et le quatrième bit, qui est positionné si un abort utilisant le moteur de remontée a été demandé (en appuyant sur le bouton ABORT STAGE). |
L'instruction "COM" complémente tous les bits de la valeur lue dans le canal 30 (c'est à dire que les bits à 1 sont mis à 0, et vice versa); le résultat est mis dans le registre L par l'instruction "TS L". A présent le premier bit de l'accumulateur est à 0 si un abort a été demandé, et le quatrième bit est à 0 si la demande a été faite avec le bouton ABORT STAGE. L'instruction "MASK BIT4" ne garde que le quatrième bit de l'accumulateur, et met les autres bits à 0, et donc, l'accumulateur est à présent nul si une demande d'abort a été faite avec le bouton ABORT STAGE. L'instruction "CCS A" teste l'accumulateur, et exécute la première instruction suivante si l'accumulateur est positif, et la seconde instruction suivante si l'accumulateur est nul. Donc, si un abort a été demandé avec le bouton ABORT STAGE, c'est la seconde instruction suivante "CS MODREG" qui est exécutée, l'instruction suivante est sautée. |
Le programme continue donc en séquence. MODREG contient le numéro de programme courant; l'instruction "CS MODREG" place le contenu négatif de MODREG dans l'accumulateur, ce qui signifie que, si le programme courant est P70, l'accumulateur contient à présent -70. L'instruction "AD 1DEC70" ajoute 70 à l'accumulateur, ce qui signifie que, si le programme courant est P70, l'accumulateur contient à présent 0. L'instruction "BZF LANDISP" fait un branchement à LANDISP si l'accumulateur est nul, autrement dit si le programme courant est P70, selon ce qui a été dit. |
Le programme continue donc en séquence si le programme courant n'était pas P70. Le contenu du canal 30 a été mis dans le registre L APRES avoit été complémenté (c'est à dire les bits à 1 mis à 0, et vice versa). Cela signifie que le premier bit de L contient 0 si un abort a été demandé. L'instruction "CA L" place le contenu de L dans l'accumulateur; cela signifie que le premier bit de l'accumulateur est 0 si un abort a été demandé. L'instruction "MASK BIT1" ne garde que le premier bit dans l'accumulateur, et met les autres bits à zéro; comme le premier bit était à 0 en cas de demande d'abort, cela signifie que l'accumulateur est nul après cette instruction dans ce cas. |
L'instruction "CCS A" teste l'accumulateur, et exécute la première instruction suivante si l'accumulateur est positif, et la seconde instruction suivante s'il est nul. Cela signifie que, si un abort a été demandé, c'est la seconde instruction suivante "TCF LANDISP" qui est exécutée, comme l'accumulateur est nul couramment (contrairement à ce que dit le commentaire). En d'autres termes, si un abort a été demandé avec le bouton ABORT, Le programme fera le traitement de R10 (LANDISP). Donc, si les boutons ABORT et ABORT STAGE sont simultanément appuyés (et le bit LETABORT positionné), il n'y aura pas d'abort de fait. |
Donc, si le bouton ABORT STAGE a été appuyé, et le bit LETABORT est positionné, le programme continue à l'étiquette P70A. Dedans nous trouvons cette séquence d'instructions. L'instruction "DCA CNTABTAD" charge le contenu de CNTABTAD, c'est à dire la double adresse de CONTABRT, dans la paire de registres A,L. La double adresse de CONTABRT signifie son adresse dans sa banque de mémoire, et sa banque de mémoire. L'instruction DTCB échange la paire de registres A,L avec la paire de registres Z,BB. Donc, après cette instruction, Z contient l'adresse de CONTABRT, et BB sa banque de mémoire. Z est le compteur de programme, c'est à dire l'adresse de l'instruction courante à exécuter, et BB est le registre de banque de mémoire; cela signifie que la prochaine instruction qui est exécutée après DTCB est l'instruction à l'étiquette CONTABRT. Mais, comme CONTABRT est dans la même banque de mémoire, cela aurait été nettement plus simple de remplacer cette séquence avec la seule instruction "TCF CONTABRT". Une complication inutile qui gaspille de l'espace mémoire. La séquence entre DTCB et CONTABRT est sautée; elle contient deux déclarations de valeurs (1DEC70 and 1DEC71) qui ne sont pas nécessaires, car ces valeurs auraient pu être directement utilisées sans ces déclarations. |
Dans cette séquence, que nous trouvons plus loin dans le programme, l'instruction "CAF ABRTJADR" charge le contenu de ABRTJADR, c'est à dire l'instruction "TCF ABRTJASK", dans l'accumulateur. L'instruction "TS BRUPT" place l'accumulateur dans le registre BRUPT, ce qui signifie que BRUPT contient maintenant l'instruction "TCF ABRTJASK". L'instruction "RESUME" fait un retour d'une interruption; la documentation dit que l'instruction mise dans BRUPT est alors exécutée, ce qui signifie que l'instruction "TCF ABRTJASK" est exécutée, et cette instruction fait un saut à ABRTJASK. Mais ABRTJASK suit immédiatement cette séquence, ce qui signifie que cette séquence est inutile; une fois de plus un gaspillage d'instructions. |
Puis suit une séquence d'instructions jouant avec des variables, faisant manifestement un travail inutile. Nous trouvons cette séquence d'instructions; cette séquence est aussi utilisée dans le programme d'allumage du moteur, "burn baby burn", (je la détaillerai quand je parlerai de ce programme), et elle permet d'allumer le moteur de descente. Mais le moteur de descente est déjà couramment allumé, et donc cette séquence est inutile, et une fois de plus un gaspillage d'instructions. |
Puis nous trouvons cette séquence d'instructions. Cette séquence permet de faire un redémarrage de l'ordinateur. Mais c'est seulement à faire en cas de situation bloquée, et l'AGC n'est pas couramment bloqué, et cette séquence est donc inutile (une fois de plus). |
Puis nous trouvons une séquence d'instructions utilisant des macro-instructions, et nous y trouvons ce que nous trouvons aussi dans d'autres programmes: Des lignes avec deux macro-instructions sur la même ligne, ce qui est illégal, et aurait du être rejeté par le compilateur. |
Finalement le programme finit par basculer dans le programme de remontée, mais après avoir fait plein d'instructions inutiles, et même utilisé des instructions illégales. |
Mais le problème est que le bouton Abort Stage ne marchera pas dans la descente, ce qui signifie que, s'il n'est pas possible de se poser sur la lune (des cratères partout), le module lunaire s'écrasera sur la lune lorsque le carburant sera épuisé, comme le retour au module de commande est impossible. |
Certains pensent que, puisqu'il n'était pas possible de faire un abort avec l'AGC, l'AGS (Abort Guidance System), l'ordinateur secondaire, plus simple que l'AGC, pouvait être utilisé à cette fin. Mais l'AGS était seulement prévu d'être utilisé pour la remontée, pas pour la descente. Et l'AGS utilise aussi le bouton ABORT STAGE pour la séparation des étages, et il a donc le même problème avec le signal parasite dans l'interface d'abort. |
Et aussi l'AGS n'est pas immédiatement prêt à être utiliser après qu'il ait pris la main, il a besoin de préparation. Sa documentation dit qu'il a besoin d'au moins 30 minutes de préparation avant le décollage, ce qui exclut de l'utiliser pour faire l'abort lorsque le LEM vole au-dessus de la surface lunaire pour trouver un endroit sûr où poser le LEM. |
Mais le meilleur est que le bouton ABORT STAGE était directement une entrée du LGC. |
Et le bouton ABORT STAGE déclenchait directement le système explosif, l'AGC ne pouvait pas l'empêcher de le faire. Dans les canaux qui permettaient à l'AGC de communiquer avec le LGC, il n'y avait pas de bit qui permettait à l'AGC d'autoriser ou d'empêcher la séparation des étages. En fait, tout ce que le bit LETABORT faisait était de permettre au programme de descente d'être remplacé par le programme de remontée. |
Mais, si le bouton ABORT STAGE séparait les deux étages, et l'AGC restait dans le programme de descente parce que la remise à zéro de LETABORT empêchait l'AGC de passer au programme de remontée, c'était pire que si l'AGC était passé au programme de remontée, car le programme de remontée aurait au moins permis de retourner au module de commande. |
Alors que, si l'AGC continue de contrôler le moteur de descente alors qu'en fait celui-ci s'est séparé du module lunaire, sûr que le module lunaire va faire la descente sur la lune...mais l'alunissage va être un peu brutal! |
Il est plus qu'évident que cette résolution du problème de l'abort n'était rien d'autre qu'un bon gag de la part des ingénieurs de la NASA. |
Il y a une autre mission dans laquelle les ingénieurs de la NASA ont créé un problème absurde. C'est la mission Apollo 11, dans laquelle la fameuse alarme 1202 s'est produite. |
Initialement le commutateur radar est sur la position LGC, et, dans cette position, tout se passe bien, l'AGC recevait des impulsions radar normales. |
Mais Buzz Aldrin aurait mis ce commutateur radar sur la position "SLEW". Le dialogue dit que ce serait à cause d'une indication erronée de la check list, mais il aurait donné une autre explication, suggérant ce que cela aurait été de sa propre initiative. |
Dans cette position, le rapport de mission dit que deux signaux déphasés à haute fréquence auraient créé des impulsions rapides artificielles, lesquelles n'avaient rien à voir avec l'entrée radar normale; comme la création de ces impulsions rapides était interne, et non externe, cela aurait pu être testé sur terre, et les ingénieurs n'ont donc pas pu l'ignorer, cela ne pouvait qu'être intentionnel. |
Le problème est que, contrairement aux autres ordinateurs, le processeur de l'AGC comptait lui-même ces impulsions, avec ce qu'ils appellent des "instructions cachées", c'est à dire des instructions qui s'exécutaient indépendamment du programme courant, mais qui empêchent une instruction du programme courant de s'exécuter à chaque fois qu'une instruction "cachée" s'exécute. |
Cela signifie que le temps d'exécution de la tâche périodique de guidage n'était pas déterminé, il pouvait varier selon la fréquence des impulsions matérielles que l'AGC devait compter. Quand l'AGC recevait des impulsions normales, la tâche de guidage pouvait encore finir à temps. |
Mais, quand l'AGC a commencé de recevoir les impulsions radar très rapides, il a commencé à prendre trop de temps pour compter ces impulsions radar, ce qui signifie que la routine de guidage prenait plus de temps pour finir son travail périodique, à cause de la trop grande perturbation des impulsions radar rapides. |
La conséquence est que la tâche de guidage, à cause de ces perturbations exagérées, ne pouvait plus terminer son travail à temps, et il y a eu une accumulation des tâches de guidage en attente d'exécution, comme elle était automatiquement relancée toutes les deux secondes. |
Le résultat a été qu'il y a eu un moment où toutes les ressources disponibles ont été épuisées, et, à ce moment, l'ordinateur a du être redémarré, avec la lampe de l'alarme 1202 s'allumant. Il est évident qu'avec un ordinateur fonctionnant de manière si erratique, il ne pouvait plus faire son travail normal. |
Ce qui est ironique est que cette situation aurait parfaitement pu être évitée. En effet, aucun processeur normal ne compte lui-même des impulsions matérielles. Dans tous les systèmes normaux (et cela inclut celui de la fusée Saturn), les impulsions matérielles sont toujours comptées par des compteurs électroniques, et un compteur électronique est relativement aisé à faire avec des transistors, comme ce schéma le montre, et même un électronicien débutant peut en faire un. |
Et le compte d'impulsions du compteur électronique peut être lu par le processeur avec une opération IO. |
Et précisément, l'AGC avait une instruction IO, ce qui signifie qu'il aurait parfaitement pu lire le compte d'impulsions depuis un compteur électronique les comptant. |
Donc, au lieu d'utiliser la procédure standard, c'est à dire de faire compter les impulsions par un compteur, et lire le compte d'impulsions depuis celui-ci avec une opération IO, ce qui aurait garanti que le temps d'exécution de la tâche de guidage serait resté constant, et qu'il n'aurait pas été accru par les impulsions radar, quelle que soit la fréquence de ces impulsions radar... |
...L'AGC comptait lui-même ces impulsions radar (avec des "instructions cachées", ce qui était une spécificité unique de l'AGC), ce qui signifie que, plus les impulsions radar étaient rapides, et plus la tâche de guidage était ralentie, ce qui pouvait avoir un effet critique lorsque ces impulsions radar étaient très rapides. |
Et le problème de l'alarme 1202 aurait pu immédiatement cesser si le sol avait dit aux astronautes de remettre le commutateur radar sur la position "LGC"; mais non, le sol leur a juste dit d'ignorer le problème et de continuer, avec la conséquence que l'alarme 1202 (et 1201) pouvait se reproduire. |
En d'autres termes, aussi bien dans la mission Apollo 14 que dans la mission Apollo 11, les ingénieurs ont créé une situation insensée qui n'aurait jamais du se produire, qui était gérée de manière aberrante, et jamais les ingénieurs n'auraient créé ce type de situation dans des missions normales, ils n'auraient jamais pris de tels risques insensés. |
La seule conclusion possible est que les ingénieurs nous envoient des signes très clairs que les missions n'étaient pas réelles. |
Cette partie parle des intervalles entre les occurences de l'alarme 1202 qui s'est produite dans la descente d'Apollo 11. Lorsque le commutateur radar était sur la sélection SLEW, une interférence entre deux sources déphasées de même haute fréquence produisait des impulsions très rapides, qui n'ont rien à voir avec l'entrée radar normale. Parce que le processeur de l'AGC comptait lui-même ces impulsions rapides, au lieu de les faire compter par un circuit externe, il prenait trop de temps à les compter, et la tâche périodique de guidage ne pouvait plus terminer son travail à temps. La conséquence est que, lorsque les routines de guidage retardées avaient épuisé toutes les ressources disponibles, l'ordinateur ne pouvait plus tourner et devait être redémarré; c'est alors que l'alarme 1202 était affichée (ou cela pouvait aussi être l'alarme 1201 qui était du même type). Comme les impulsions arrivent continuent d'arriver à la même fréquence, aussi longtemps que c'était le même programme qui tournait dans la routine de guidage, les routines de guidage étaient retardées au même rythme, ce qui signifie que l'intervalle entre les alarmes 1202 devrait rester constant, ou presque. C'est ce que nous allons vérifier. La première alarme 1202 arrive alors que le programme P63 tourne, et c'est au temps 102:38:22 La deuxième alarme 1202 arrive avec le même programme au temps 102:39:02. Il y a 40 secondes de différence avec l'alarme 1202 précédente. Puis il a un changement de programme au temps 102:41:32, deux minutes et 30 secondes (150 secondes) plus tard, avec le même programme tournant, et sans qu'il y ait production d'alarme 1202, alors que, logiquement, comme il y a eu 40 secondes entre les deux alarmes précédentes, il aurait du y avoir au moins 3 autres alarmes 1202. Puis il y a une alarme 1201 (même type que 1202) au temps 102:42:18, c'est à dire 46 secondes après le début du programme P64. Au temps 102:42:43, il y a une alarme 1202, c'est à dire 25 secondes après la précédente alarme 1201, alors qu'il y a eu 46 secondes entre le début du programme P64 et la précédente alarme 1201. Puis, au temps 102:42:58, il y a une autre alarme 1202, c'est à dire 15 secondes après la précédente alarme 1202; il y a une claire accélération de ces alarmes. Au temps 102:43:22, il y a un changement de programme à P66, 24 secondes après la précédente alarme 1202, alors qu'il y a eu seulement 15 secondes entre les deux alarmes 1202 précédentes. Et finalement, au temps time 102:45:40, il y a la coupure du moteur, sans qu'il se produise une autre alarme 1202. Alors qu'avons nous vu avec les exemples précédents? Que, alors que l'alarme 1202 devrait se produire à des intervalles réguliers aussi longtemps que le même programme tourne dans la routine périodique de guidage, c'est loin d'être le cas; nous observons une irrégularité importante. |
Lorsque l'alarme 1202 se produisait, une procédure spéciale "BAILOUT" était automatiquement appelée. Le code de cette procédure est documenté, j'en donne un lien dans la description de cette vidéo. Bien sûr, je me suis intéressé à son traitement, et je n'ai pas été déçu, car il est rempli de surprises, et une pierre de plus ajoutée à l'édifice du canular lunaire. |
Cette description est un peu technique, et peut être difficile à suivre pour les non programmeurs, mais je pense que ceux qui ont quelque expérience de la programmation l'apprécieront. |
Accrochez vous bien quand même, car c'est de la haute voltige! |
Ceci est le point d'entrée de la procédure BAILOUT. Le première instruction qui est exécutée, "INHINT", inhibe toutes les interruptions, ce qui signifie en particulier que l'affichage est gelé, et le clavier ne répond pas. |
L'instruction "CA Q" place le contenu du registre Q dans l'accumulateur, et l'instruction "TS ALMCADR" place le contenu de l'accumulateur dans la variable ALMCADR. Le registre Q contient l'adresse retour de la procédure BAILOUT; en d'autres termes, ce couple d'instructions place l'adresse retour de Bailout dans la variable ALMCADR. L'AGC n'a pas de pile, ce qui signifie que, à chaque fois qu'une procédure est appelée par une autre procédure, le contenu de Q est remplacé par l'adresse de retour de la nouvelle procédure. |
L'instruction INDEX a pour effet que son opérande est ajouté à l'opérande de l'instruction suivante. Le couple d'instructions "INDEX Q", "CAF 0", fait donc que le contenu du registre Q plus zéro est placé dans l'acculumateur; en d'autres termes le contenu de Q est placé dans l'accumulateur. Remarquez que c'était plus simplement fait par une instruction précédente "CA Q", et, de plus, c'est même inutile, car l'accumulateur contenait encore le contenu du registre Q, comme il n'a pas été modifié entre temps. C'est donc un couple d'instructions qui est complètement inutile, et aurait pu être évité. |
L'instruction "TC BORTENT" appelle la procédure "BORTENT"; l'adresse de retour, c'est à dire l'adresse de l'instruction qui suit cette instruction, est placée dans le registre Q. |
Donc, à présent, l'exécution reprend depuis l'étiquette BORTENT. Le première instruction de cette procédure, "TS L", place le contenu de l'accumulateur dans le registre L; l'accumulateur contient encore l'adresse retour de la procédure BAILOUT. |
L'instruction "CA BBANK" place le contenu de la variable BBANK dans l'accumulateur. Le couple d'instructions "EXTEND" et "ROR SUPERBNK" fait un OU de l'accumulateur (qui contient couramment la variable BBANK) avec une variable I/O SUPERBNK. Pour en faire quoi? |
L'instruction "TS ALMCADR" place le contenu de l'accumulateur dans la variable "ALMCADR". Rappelez vous que cette variable avait déjà été initialisée avec une autre valeur (l'adresse de retour de la procédure BAILOUT), et elle n'a pas été utilisée entre temps; ce qui signifie que l'initialisation précédente était inutile. |
L'instruction "CA Q" place le contenu du registre Q dans l'accumulateur, et l'instruction "TS ITEMP1" place le contenu de l'accumulateur dans la variable ITEMP1. Le registre Q contient couramment l'adresse retour de la procédure "BORTENT", et cela signifie donc que l'adresse retour de BORTENT est placée dans la variable ITEMP1. |
L'instruction "CCS FAILREG" place le contenu décrémenté de FAILREG dans l'accumulateur, mais ne modifie pas FAILREG; elle teste le contenu courant de FAILREG, et saute l'instruction suivante plus grand que zéro. L'instruction suivante "TCF CHKFAIL2" est exécutée si le contenu courant de FAILREG est plus grand que zéro, et elle saute à l'étiquette CHKFAIL2. |
Les deux instructions suivantes "LXCH FAILREG" et "TCF PROGALARM" sont exécutées seulement si le contenu courant de FAILREG était nul. L'instruction "LXCH FAILREG" échange le contenu de FAILREG avec le registre L, ce qui signifie que FAILREG n'est pas nul après cette instruction, comme le registre L avait un contenu non nul avant l'échange (il contenait l'adresse retour de BAILOUT). L'instruction "TCF PROGALARM" saute à l'étiquette PROGALARM, ce qui signifie que l'instruction suivante n'est pas exécutée après cette instruction. |
Si nous arrivons sur cette étiquette "CHKFAIL2", cela signifie que la variable FAILREG était plus grande que zéro (sinon l'instruction "TCF PROGALARM" l'aurait sautée). Le même test est fait qu'à l'étiquette "CHKFAIL1", avec le même résultat. Mais, puisque nous sommes arrivés ici parce que FAILREG était plus grand que zéro, nécessairement l'instruction suivante "TCF FAIL3" ne sera pas sautée, et cette instruction saute à l'étiquette FAIL3. |
Cela signifie aussi que les deux instructions suivantes "LXCH FAILREG" et "TCF MULTEXIT" ne seront jamais exécutées, et sont donc totalement inutiles. Et les deux instructions précédentes sont également inutiles, comme l'instruction suivante a "FAIL3" comme étiquette. |
L'instruction "CA FAILREG" place le contenu de FAILREG dans l'accumulateur. FAILREG est couramment non nul, ce qui signifie que l'accumulateur n'est pas nul après cette instruction. L'instruction "MASK POSMAX" réalise un ET de l'accumulateur avec POSMAX; le nom POSMAX laisse suggérer qu'il contient des bits tous à 1, auquel cas il laisserait l'accumulateur inchangé, donc toujours non nul. |
L'instruction "CCS A" décrémente l'accumulateur, mais le teste avant qu'il ne soit décrémenté. L'instruction suivante "TCF MULTFAIL" est exécutée si l'accumulateur était plus grand que zéro (avant l'instruction CCS), et donc elle devrait logiquement être exécutée, elle permet de sauter à l'étiquette MULTFAIL. |
Les deux instructions suivantes "LXCH FAILREG" et "TCF MULTEXIT" sont seulement exécutées si l'accumulateur était nul avant l'instruction "CCS", et ne devraient pas logiquement être exécutées. L'instruction "LXCH FAILREG" échange le contenu de FAILREG avec le registre L. L'instruction "LXCH FAILREG" précédente n'a pas été exécutée si nous arrivons ici, car une instruction "TCF PROGALARM" suit l'instruction "LXCH FAILREG" précédente, et PROGALARM est après cette nouvelle instruction "LXCH FAILREG". Cela signifie que le registre L contient encore l'adresse de retour de BAILOUT, et FAILREG est donc non nul après cette instruction. |
L'instruction "CS DSPTAB" place le contenu négatif de DSPTAB dans l'accumulateur, l'instruction "MASK OCT40400" fait un ET de l'accumulateur avec une variable, OCT40400, et l'instruction "ADS DSPTAB" ajoute le contenu de DSPTAB à l'accumulateur. Notez que, puisque la variable DSPTAB est utilisée deux fois dans ces trois instructions, il aurait été possible de le faire avec deux instructions seulement, en n'utilisant DSPTAB qu'une seule fois. |
Nous arrivons maintenant à l'étiquette "MULTEXIT". L'instruction "XCH ITEMP1" échange le contenu de la variable ITEMP1 avec l'accumulateur. Souvenez vous que l'adresse retour de la procédure BORTENT avait précédemment été placée dans ITEMP1. Cela signifie donc que l'accumulateur contient maintenant l'adresse retour de BORTENT. L'instruction "RELINT" autorise à nouveau les interruptions qui avaient été inhibées au début de BAILOUT. L'instruction "INDEX A" a pour effet que l'accumulateur est ajouté à l'opérande de l'instruction suivante. Cela signifie que l'instruction suivante "TC 1" appelle l'adresse correspondant au contenu de l'accumulateur plus un, donc l'adresse retour de BORTENT plus un, comme l'accumulateur contient couramment l'adresse retour de BORTENT. Cela signifie que la prochaine instruction qui sera exécutée après cette instruction sera l'instruction qui est juste après l'instruction qui suit l'appel à BORTENT. Remarquez que cette instruction aurait du être un "TCF" (saut), et non un "TC" (appel de sous-programme) comme il n'y aura pas de retour après cette instruction. |
Il peut aussi y avoir un saut à l'étiquette MULTFAIL. L'instruction CA L" place le contenu du registre L dans l'accumulateur, l'instruction "AD BIT15" ajoute BIT15 à l'accumulateur; le nom de BIT15 suggère qu'il a son bit 15 à 1, et donc l'accumulateur contient maintenant une valeur non nulle; l'instruction "TS FAILREG" place le contenu de l'accumulateur dans FAILREG. Finalement l'instruction "TCF MULTEXIT" fait un saut à l'étiquette "MULTEXIT", qui provoque une sortie de BORTENT, alors quelle est l'utilité de changer à nouveau FAILREG, puisqu'il ne sera plus utilisé dans la procédure BORTENT? |
Les deux dernières instructions de MULTEXIT appellent l'adresse de l'instruction qui suit l'instruction qui est juste après l'appel à BORTENT (TC BORTENT). Cela signifie que l'instruction qui suit "TC BORTENT" ne sera jamais exécutée. Cette instruction "OCT 40400" n'est même pas une instruction, puisque c'est juste une valeur et non une instruction, et il est donc normal qu'elle ne soit pas exécutée. Mais, dans ce cas, pourquoi ne pas juste la supprimer, et faire directement un retour à l'instruction suivant "TC BORTENT", ce qui aurait pu être fait avec le couple d'instructions "INDEX A" et "CAF 0" à la fin de MULTEXIT? Cela aurait économisé une instruction inutile. Et, encore mieux, le couple d'instructions "INDEX A" et "CAF 0" aurait été plus efficacement remplacé par l'unique instruction "RETURN" qui fait un retour à l'adresse contenue dans le registre Q (dans lequel l'adresse retour de BORTENT est placée quand BORTENT est appelé). Donc encore un gaspillage d'instructions car un couple d'instructions aurait pu être remplacé par une instruction unique. Au total cela fait deux instructions inutiles. Et la première instruction qui est exécutée après le retour de BORTENT est l'instruction "INHINT", qui inhibe les instructions à nouveau, lesquelles avaient été autorisées juste avant le retour de BORTENT. Alors, pourquoi autoriser les interruptions si c'est pour les inhiber à nouveau juste après? |
Le couple d'instructions "CA TWO" et "ADD Z" ajoute le contenu du compteur de programme (c'est à dire l'adresse de l'instruction suivante, soit l'adresse de "TS BRUPT") à une variable TWO, qui, comme son nom l'indique, contient la valeur 2, et place le résultat dans l'accumulateur; autrement dit, c'est l'adresse de "TS BRUPT" plus 2 qui est mise dans l'accumulateur, et cela correspond à l'adresse de l'instruction "TC POSTJUMP", l'instruction qui est deux mots après "TS BRUPT"; pour conclure, c'est l'adresse de "TC POSTJUMP", juste après l'instruction "RESUME", qui est mise dans l'accumulateur; l'instruction "TS BRUPT" place l'accumulateur dans le registre BRUPT. L'instruction "RESUME" permet de retourner depuis une interruption, et exécute d'abord l'instruction qui est placée dans BRUPT. Mais BRUPT ne contient pas une instruction, mais une adresse, et une adresse ne peut être exécutée comme une instruction. Comme il y a un retour depuis une interruption, le traitement s'arrête ici, et ce qui a été exécuté n'a pas de sens. |
Et cette procédure ne réalise en fait rien de significatif, elle est juste là pour le show. |
Et pourquoi les ingénieurs se seraient-ils souciés d'écrire un programme qui a du sens pour un ordinateur dont la mémoire ne fonctionnait même pas? |
De toute façon, cela ne signifie pas que les astronautes étaient foutus dans leur descente sur la lune, car ils pouvaient encore sauter en parachute avant que le module lunaire ne s'écrase sur la lune. Il y a une croix rouge lunaire très efficace sur la lune, qui est capable de les accueillir, et de prendre soin d'eux quand ils se posent sur la lune. |