最后送上1994年小斯坦利·R·莫勒对阿兰·科伦姆普(登月舱计算机降落制导软件主设计师)的的访谈……这月是狗屎运登上去的哦
几个月以前我在sci.space.tech发布了一个讯息,想要征询有关登月舱计算机及
其软件的信息。我很快从阿兰·科伦姆普那里得到了回复,他是阿波罗登月舱载计
算机降落软件的主设计师。他还编写了数字自动驾驶仪的方向控制系统。他邀请
我给他打个电话,而我很快就照做了。我想我将在这里总结一下我对这1.25个
小时之中他给予我的有趣信息的理解。
阿兰是大约300位参与设计登月舱软件系统的工作人员之一,这项工作持续了7年
,总花销相当于四千六百万的1967年的美元。在阿波罗的岁月里,他在麻省理
工学院Draper实验室作为研究生进行工作。
登月舱和指令舱拥有一模一样的星载计算机,其大小接近于鞋盒的尺寸。每一台
都都包含有总计大小为36K、14位字的存储空间。这意味着总存储空间差不多等于
Commodore-64计算机上的64K字节。登月舱计算机拥有11.7毫秒的“内存周
期时间”。但是,几乎所有中央处理器的操作都要求至少两个时钟周期,所以实
际有效的内存周期是23.4毫秒,也就是说这台计算机的运行速度只有43千赫兹
(0.043兆赫)!要知道最初的IBM的PC-XT运行速度为4.77兆赫,而最新的
电脑(指1994年,译者注)能运行到66兆赫。今天最快的电脑可以达到300兆赫。
登月舱计算机可能只能达到一部口袋计算器的速度。在这台计算机中,数据都以双
精度14位字存储(亦即总计28位)。第15和16位是数据的符号位(正负号)和奇
偶校验位(为了确保芯片与时钟脉冲总是同步)。所有计算都是定点数计算(而不
是浮点数)。星载程序,名为“LUMINARY”(意为发光天体,或知识渊博的人),存储于只
读的磁芯线存储器中。这一存储器需要花费数月时间来制造(程序打印出来有10厘
米厚)。因此软件必须在发射前几个月就定稿。LUMINARY 版本99 将阿波罗11
号成功降落在月球上。版本209则是最终版本。
计算机也配备了差不多2K、14位字大小的一小块可擦写区域,用来临时存储
变量。这种计算机整个都是用或非门集成电路制作的,这是可靠性很高的一类
门电路。
阿兰、他的朋友唐·埃里斯、以及另外差不多300个人用高级计算机语言编写了
他们的程序。这种语言叫做MAC(麻省理工学院代数编译器)。然后他们通过手工将
它转变为汇编语言,最后他们将会把结果做成打孔卡(当时可没有终端机或文字
编辑器)。偶然地,后来航天飞机的软件是使用一种名为HAL/S的语言编写的,
这个语言是以哈尔·蓝宁的名字命名的。哈尔·蓝宁就是MAC的作者,而HAL/S
则是MAC的一个改进版本。
LUMINARY程序包含有很子程序,这些子程序通过优先级来调配。也就是说,这些子
程序根据各自的优先级轮流得到执行。每个程序都会将数据从那非常小的(大小为2K)
可擦写区域里移进移出。最大的调试挑战就是保证这些程序不要在不恰当的时间擦掉或
“覆盖”另一个程序的数据。如果太多的任务都在请求计算机处理,它就会简单地推迟
或直接扔掉它正在执行的工作,发布一个警报,然后开始执行新的工作。
这种恐怖的警报在阿波罗11号登月(第一次登月)之中发生了。如果你去听登月
着陆的录音,你就会听到飞船通讯员(译者注:指挥中心里负责与飞船通讯的人
员)说“1201警报”和“1202警报”。宇航员的工作清单错误地要求宇航员在
开始下降之前打开交汇雷达。而后,主管雷达的程序开始请求超出计算机空闲
时间的工作时长。雷达的电源没能恰当地与登月舱主电源同步。
结果,由于两个电源不断获得和失去同步,交汇雷达向登月舱计算机产生出许
多虚假的输入信号。作为对这些信号的回应,计算机推迟了它的一些制导计算,
同时还把其他尚未完成的任务扔在一边。这种情况导致计算机在着陆期间发布了
很多警报。制导程序用来将登月舱以最小燃料消耗带到目标着陆区。在正常下
降中,制导会每两秒发布一次命令。用于确保登月舱稳定的转向命令则是每十分
之一秒发布一次。在着陆期间有11分钟的制导段。尽管着陆取得了成功,在制导
段中却有整整一分钟的制导命令由于交汇雷达而从来没有发出!
为了调试程序,在麻省理工学院的程序员们配备了一台作为登月舱模拟器的175型
IBM360大型机。阿兰和他的同事们将在这台模拟器上测试他们的软件,它如同真
的登月舱一样通过登月舱的动力学模型与他们的软件协同工作。这台IBM360会打
印出系统输出在真正的登月舱上,星载计算机带有一台数字显示器和一个键盘。在着陆期间,
计算机将会显示一个定期更新的数据。位于右侧的登月舱“领航员”将不断地
读出数据的更新值,而不会操作控制器。位于左边、实际操作控制器的指挥官将
在窗子上画的十字线上找到这个数值。计算机试图达到的目标降落点就是从窗子
的这个位置上能看到的那个地点。指挥官将通过点击手动控制器来指定新的着陆
地点,从而实现“驾驶”登月舱。
通过这种方式,尼尔·阿姆斯特朗小心地操纵登月舱避开了一个布满大众轿车尺寸
的巨石的陨石坑,而在仅剩30秒燃料的情况下将登月舱降落到了地面。点击一下
手动控制器将会把降落点移动几度。阿兰在程序中编写为向左/向右2度,向上/向下
(即向前/向后)0.5度。后来在宇航员的要求下,他将这两个方向都改成了一度。
指挥官还可以通过点击另一个手动控制器来以一英尺每秒增加或减少下降速度。
!!!接下来这个绝对是人品的表现!!!
LUMINARY从来就没有完全正确过。阿兰告诉了我一系列可以轻易阻止第一次
登月着陆并可能导致灾难的事件。阿兰当时是登月舱降落制导程序的主设计师。
制导程序通过旋转、倾斜登月舱并控制降落发动机的流量来操纵登月舱。无论
什么时候计算机命令发动机增大或减小推力,发动机(和登月舱)都会在一个
短暂的延迟之后作出反应阿兰的降落程序需要一个子函数来精确估计新的推力大小,这可以通过读取登月舱
加速度计测量到的速度的导数来实现。他写了这样一个简短的推力估计子函数,它可以处理,也
就是补偿发动机的延迟时间。根据TRW公司的写满对程序员有用信息的“接口控制
文档”,这个延迟时间是0.3秒。就是说,不管计算机请求的推力是多大,登月舱的
降落发动机都需要花费0.3秒来实现这个推力。这个推力估计子程序的最终版本,也
就是实际放进登月舱里的那个版本,是由阿兰的朋友唐·埃里斯编写的。埃里斯非常
热衷于这项编程挑战,他找到了一个方法,使得只需要补偿0.3秒之中的0.2秒就够了。
IBM360模拟器显示埃里斯的程序工作地十分漂亮。他的程序装载在阿波罗11号
和12号上,这艘飞船都成功着陆了。然而,后来,这两次着陆期间获得的遥测
数据显示出现了严重的问题。发动机的推力时大时小,整个飞船堪堪处于稳定状态。(就是说几乎失去稳定性,然后乱飞着掉下去)
一个人从约翰逊宇航中心打电话给阿兰,并告诉他登月舱的发动机实际上并不是
那种0.3秒延迟的发动机。它在阿波罗11号发射前的一段时间里已经得到了改进,
实际的延迟时间是0.075秒。对接口控制文档中这一数据的修正工作完全被忽视了。
一旦这个差异被发现了,IBM360模拟器就被重新编程以恰当地模拟这种实际中的
更快的发动机。唐·埃里斯的这个程序,当在模拟器上带着0.2秒补偿运行时,显示
出真实飞行中出现过的推力骤变。
!!!!这人品无敌鸟!!!!!
但是这里才是最有意思的事情:模拟器还显示,
如果阿兰·科伦姆普选择“纠正”唐·埃里斯的程序而根据文档所写、补偿全部0.3秒,
登月舱就会失去稳定性,那么阿波罗11号就根本不可能完成着陆了。完完全全是因为运
气,唐·埃里斯以极高的创造性编写了这个推力估计子程序,堪堪使登月舱停留在稳
定包线之内并实现了成功着陆。
阿兰的降落程序叫做“P64”,它会定期运算一个多项式函数来描述最优降落轨迹。
这个多项式会平滑地融合登月舱当前位置和当前速度矢量,计
算出目标点位置和到达目标点时的速度矢量。P64的所谓“目标点”就位于着陆点的上方很
近的位置。(当登月舱以很小的垂直降落速度到达目标点时,P64就会停止执行,
同时着陆段就会转由一个名为“P66”的程序来处理)而后计算机就会使登月舱沿
这条轨迹飞行。轨迹每两秒重新计算一次。
一个灾难出现的机会就在这里。很多sci.space.tech的读者都有足够的数学
知识,能够理解高阶多项式拟合所可能产生的“抖动”。这种现象是不受欢
迎的。在可以想象的条件下,P64所计算的多项式函数可能会低垂下来,
跑到月面之下,再从月面下升起来,然后降落到目标点上。如果在实际着陆
中计算得到了这样的轨迹,而登月舱又被允许去跟随这条轨迹,那么登月舱
就会坠毁。
在程序中,完全没有任何逻辑代码用来探测和防止这种状态。他们也从未找到
任何编程解决方案。一个这种灾难可能发生的典型场景如下。如果登月舱偏离
了轨道,离开了计算机中所存储的地形模型,又飞过了一个较深的陨石坑,那么
着陆雷达可能会让计算机误以为登月舱比原先估计的距平均月面的高度要高。这将
会导致新计算出的多项式轨迹剧烈下滑,无意中与实际月面相交,然后再升出月
面,这样的轨迹会导引着登月舱栽到月球表面上。阿兰说这个问题可能可以被一
个敏锐的航天员挽救。他需要将降落点重新定位到当前燃料所能到达的范围之外
(至少他得要把目标点定位到那里并维持一阵子)。
如果登月舱的降落发动机在月面之上一英里的地方耗尽了燃料,计算机会怎么做?
计算机完全不会启动任何自动解决方案。阿兰说宇航员将很简单地按一个中止按
钮,这将使登月舱抛掉降落级,并点燃上升发动机,返回指令舱。
我想要感谢阿兰科伦姆普,感谢他花费时间来为我解释这些事情。听他讲述
这些事情是非常有意思的。我希望sci.space.tech的读者们能够喜欢我对阿
兰的评述所作的纪录。