Спомняте ли си как през 2016 г. служителят на НАСА Крис Хари публикува сорс кода за мисията „Apollo 11“ в GitHub? Можете да го изучавате, да го изтегляте и да го променяте. Е, и, разбира се, да го използвате, за да полетите до Луната за свои собствени цели. Става дума за изходния код на командния модул Comanche 055 и лунния модул Luminary 099. Това е „живият“ код от 1969 г. с коментарите на инженерите.
Така. Ако днес отворите този проект, ще ви стане ясно защо той все още се смята за еталон. Той е жив пример за истинска инженерна школа, в която всяко решение е продиктувано от строга практическа необходимост. Днес философията на програмирането се е променила, така че е особено интересно да разгледаме как се е променил подходът към писането на код за повече от 50 години.
Кодът е вграден в хардуера
Apollo Guidance Computer е специализиран бордови компютър, предназначен за специфичните задачи на полета. Той има оперативна памет с феритни ядра и постоянна памет, реализирана по технологията core rope. Само че по онова време обемът на паметта се е измервал в думи, а не в гигабайти. Така например обемът на оперативната памет бил 2 048 думи, а на постоянната памет – 36 864 думи (в стандартни единици това са около 70 килобайта). Процесорът работи с тактова честота около 1 MHz и извършва няколко десетки хиляди операции в секунда, което е достатъчно за непрекъснатото изчисляване на ориентацията, скоростта и траекторията.
Постоянната памет не може да бъде „записана“ в обичайния смисъл на думата – тя се създава ръчно на етапа на сглобяване. Програмата е била буквално втъкана в хардуера: ако един проводник премине през магнитен пръстен, имаме единица, ако премине извън пръстена, се получава нула. Този метод прави системата невероятно устойчива: тя не се страхува нито от безумните вибрации при изстрелването, нито от космическата радиация, нито от температурните разлики. Но има и един недостатък – кодът се превръща в монолит. След като блокът е бил запълнен със защитна смес, нито един бит в програмата не е можел да бъде променен. Ако в кода се открие грешка, целият модул е трябвало да бъде изтъкан наново.

Строгите ограничения на паметта и изчислителните ресурси определят цялата архитектура на системата. Програмата се разделя на компактни подпрограми, използват се повторно части от кода и всеки бит се използва възможно най-икономично. За съхранение на данните се използват строго фиксирани области от паметта, а структурата на програмите е подчинена на изискванията за предсказуемост и детерминизъм на изпълнението. Дори аритметичните операции и работата с вектори са били оптимизирани на ниво отделни инструкции, за да не се губят излишни машинни цикли.
Разработката е извършена, като е взето предвид, че системата трябва да работи в реално време и да бъде стабилна при претоварване. Програмистите са знаели точно кои части от кода се изпълняват най-често и колко време отнемат, и са адаптирали логиката към тези ограничения. Резултатът е система, която може едновременно да извършва навигационни изчисления, да контролира ориентацията на кораба и да обработва данните от сензорите без прекъсване. Именно този подход осигурява стабилна работа по време на кацането, когато изчислителното натоварване се увеличава драстично, а ресурсите остават същите.
Разпределителят на задачите е в състояние да жертва излишното

В основата на системата стои програма за планиране, която разпределя задачите според строго определени приоритети. На всяка програма предварително се определя нивото на важност, а компютърът постоянно следи за това ключовите процеси първи да получават ресурси. За съхраняване на текущото състояние се използват т.нар. core sets – фиксирани области от паметта от по 12 думи – а за изчисленията с вектори се отделят отделни работни области.
Когато оперативната памет започва да не достига, системата освобождава ресурсите, като спира второстепенните задачи и оставя само това, което е необходимо в момента. Именно такава ситуация възниква по време на спускането към повърхността на Луната, когато допълнителното натоварване от радара води до серия от предупреждения.
Сигналите с номера 1201 и 1202 сигнализират за претоварване на изчислителя. Първият показва недостига на области от основните набори, а вторият – липсата на свободни области от паметта за изчисления. Причината беше, че радарът за близост остава активен в режим на движение. Неговите блокове за генериране на данни създават поток от прекъсвания, които се получават от броячите на ъгли и отнемат процесорно време. В резултат на това около 15% от изчислителните ресурси са изразходвани за обработка на ненужни сигнали.

Въпреки това изчислителят продължава да изпълнява основните задачи на управлението на траекторията. Екипажът получил потвърждение, че кацането може да бъде продължено. Успехът на мисията до голяма степен се дължи на тази организация на работата: системата не спря да работи в този случай на претоварване, а намали обема на второстепенните операции, запазвайки ресурсите за критичните функции.
Командите звучат като човешки език
Астронавтите комуникират с бордовия компютър чрез устройството DSKY – панел с малък цифров дисплей и клавиатура с бутони. Цялото управление се основава на оригинална командна система от две числа, наречени „Глагол“ и „Съществително“. Първото число („Глаголът“) задава задачата – какво точно да се направи, а второто число („Съществителното“) обозначава данните, за които се отнася действието. Например една комбинация от числа ще накара системата да покаже параметрите на работата на двигателя, а друга ще задейства сложно изчисление на приближаването към друг модул. Този формат е изключително прост и избягва объркването: всяка двойка цифри отговаря строго на една конкретна операция.

Подобна схема дава възможност на екипажа да контролира изцяло кораба, без да се налага да се запознава с вътрешната работа на програмния код. Всяка команда се въвежда само с няколко натискания на клавишите, а резултатът веднага се изобразява на светещите цифрови индикатори. За много стандартни операции не е било необходимо да се въвеждат дори данни – един кратък код е бил достатъчен, за да може системата веднага да започне изпълнението. Благодарение на това взаимодействието на човека с машината остава изключително бързо и предвидимо дори в най-напрегнатите моменти на полета, когато нямаше време за дълги размисли.
Този метод на управление е създаден от инженерите в лабораторията на Масачузетския технологичен институт специално за условията на пилотиран космически полет. Основната цел била човекът да може мигновено да дава заповеди и да получава ясни отговори без излишни движения. Тази логика може да се проследи в самия код: всички команди и тяхната цел са написани възможно най-прозрачно. Програмистите са направили всичко възможно, за да изключат напълно всякакви двусмислици, които биха могли да доведат до грешка в реално време.
Какво имаме днес

Маргарет Хамилтън, ръководител на екипа за разработване на софтуера за полетите „Аполо“ в Масачузетския технологичен институт, изисква кодът да бъде ясен, предвидим и лесен за разбор в критични ситуации. Всъщност благодарение на нейната работа програмирането в този проект започна да се възприема като строга инженерна дисциплина, а не като спомагателна част от разработката.
Днес софтуерът за критичните системи често заема гигабайти памет и е изграден върху голям брой готови компоненти. Разработчиците активно използват библиотеки, модули на трети страни и многостепенни архитектури, което наистина ускорява разработката. Заедно с това обаче нараства и цялостната сложност на системата: появяват се много зависимости, междинни слоеве и скрити връзки между частите на кода.
Всеки такъв слой добавя нови места за възможни сривове. В резултат на това голяма част от времето се изразходва не за основната логика, а за анализиране на начина, по който отделните компоненти взаимодействат помежду си. Ако в системата възникне грешка, нейният източник може да бъде на всяко ниво, а търсенето на причината се превръща в дълъг и невинаги предвидим процес.
Това е особено очевидно при сложните инженерни проекти, включително космическите технологии. По време на фазата на тестване тези системи понякога се държат нестабилно и откриването на причините отнема много време именно поради присъщата им сложност. При нормални условия тези решения работят сравнително добре, но при отклонение от нормалните сценарии поведението им става по-трудно предвидимо.

На този фон предимствата на подхода Apollo са особено очевидни. Ограничените ресурси наложиха съсредоточаване само върху това, което е най-необходимо, и предварително обмисляне на архитектурата. Приоритетите на задачите, разпределението на ресурсите и поведението на системата при претоварване са вградени непосредствено, а не са добавени по-късно. Това прави системата по-предсказуема и устойчива в критични ситуации.
Не по-малко важно е и отношението към самия код. Той е написан по такъв начин, че друг инженер да може да разбере логиката без дълго вникване. Ясната структура, точните коментари и липсата на ненужни усложнения опростяват поддръжката и намаляват риска от грешки при преработката. Този подход има пряко въздействие върху надеждността на цялата система.
Историята на „Аполо 11“ показва съвсем ясно, че при критични задачи програмирането е пълноценна инженерна работа, при която са важни не само функциите, но и предсказуемостта на поведението. И в този смисъл опитът от миналото остава актуален: дори при днешните възможности прекомерната сложност може да бъде източник на проблеми.
Кодът все още е достъпен под формата на open source и може да бъде разгледан директно. Това е рядка възможност да се види как е изградена системата, от която е зависел изходът на дадена мисия, и да се разберат решенията, които са я подтикнали.
Всичко важно от света на технологиите, директно в пощата ти.
С абонирането приемате нашите Условия и Политика за поверителност. Може да се отпишете с един клик по всяко време.
Коментирайте статията в нашите Форуми. За да научите първи най-важното, харесайте страницата ни във Facebook, и ни последвайте в Google Новини, TikTok, Telegram и Viber или изтеглете приложението на Kaldata.com за Android, iPhone, Huawei, Google Chrome, Microsoft Edge и Opera!