$500 млн за строчку кода или стоимость ошибок ПО в космосе +84


Пару месяцев назад на edx.org закончился курс «Введение в космические технологии: Космонавтика и пилотируемые полеты (Introduction to Aerospace Engineering: Astronautics and Human Spaceflight)». Курс вел американский космонавт, на данный момент профессор MIT — Джеффри Алан Хоффман. Как следует из названия, курс довольно простой и общий, тем не менее мне он показался довольно интересным и познавательным.

В одной из частей курса рассматривается вопрос безопасности, и речь, кроме всего прочего, идет о безопасности программного обеспечения. Проф. Хофман приводит интересные примеры проблем с ПО для авиации и космонавтики. В данной статье я чуть-чуть подробнее рассмотрю космические примеры из лекций Хофмана.

Mars Polar Lander


Mars Polar Lander (MPL) 290 килограммовый космический аппарат, запущенный NASA 3 Января 1999 г. для изучения почвы и климата в районе южного полюса Марса. 3 Декабря 1999 г. во время посадки центр управления не смог возобновить с аппаратом связь.


MPL в лаборатории NASA

С раскрытыми посадочными опорами и солнечными панелями MPL был 1.06 м в высоту и имел поперечный размер 3.6 м. Корпус выполнен на основе сотовой алюминиевой конструкции, скреплённой графито-эпоксидными панелями. При посадке три алюминиевые опоры раскрываются из транспортного положения и гасят энергию посадки с помощью разрушаемых алюминиевых вставок, сделанных в виде сот.

Запланированный ход посадки


MPL входит в атмосферу Марса на высоте более 100 км при скорости ~7 км/с. За 3 мин аппарат спускается до высоты 8.8 км и замедляется до скорости 0.5 км/с, после этого он дает сигнал для раскрытия парашюта, которое следует сразу после отделения теплового экрана (heat shield). Когда с помощью парашюта скорость аппарата снижается до 85 м/с, начинает работать радар, который отслеживает особенности поверхности для определения возможного места посадки.

Схема полетной ступени MPL

Через 1 мин после раскрытия парашюта на высоте 1.3 км, когда скорость снижения составляет 80 м/с, спускаемый аппарат отделяется от внешнего кожуха с парашютом (backshell) и начинает посадку на тормозных двигателях. Ожидаемое время снижения, с работающими двигателями, приблизительно 1 мин, за это время аппарат снижается до высоты в 12 м. Затем двигатели выключаются, и аппарат совершает запланированное падение на поверхность. Через 5 мин после касания поверхности аппарат начинает развертывание солнечных панелей и ориентировку антенны, что позволит установить связь с Землей. Затем начинается сеанс передачи данных, сигнализируя о том, что посадка прошла успешно.

Ход развития событий


3 Декабря спускаемый аппарат отстыковался от перелетной ступени (cruise stage) и до момента завершения посадки перешел в запланированный режим радиомолчания. В 20:04:00 UTC, за 6 мин до входа в атмосферу, запрограммированная работа двигателей скорректировала положение аппарата, сориентировав тепловой экран. MPL вошел в атмосферу Марса на скорости 6.9 км/с в 20:10:00 UTC. Возобновление связи ожидалось в 20:39:00 UTC после посадки. Но связь так и не была установлена, и аппарат был объявлен потерянным.

Точная причина потери связи неизвестна, но в отчете по расследованию аварии содержится заключение о том, что наиболее вероятная причина аварии — ошибка в ПО, которое некорректно посчитало вибрации во время раскрытия опор как вибрации от посадки. В результате чего аппарат выключил тормозные двигатели на высоте 40 м, несмотря на то, что было известно, что раскрытие опор может привести к ложным срабатываниям. Техническое задание на ПО не предусматривало этого случая.

Цитата из отчета:
«Магнитные сенсоры, установленные на каждой из трех посадочных опор, служат для определения момента касания с землей и выключения посадочных двигателей. Данные, полученные в ходе нескольких тестов, показали, что в датчиках посадки (датчики Холла) возникают ложные срабатывания во время раскрытия опор (в этот момент аппарат спускается на парашюте). Логика программы принимает данные от датчиков как сигнал посадки, если срабатывания возникают в двух последовательных считываниях. Тесты показали, что, возникающие при раскрытии опор, кратковременные сигналы на самом деле достаточно продолжительны, чтобы вызвать ложное срабатывание. Почти всегда одна из трех опор генерировала ложный сигнал, принимаемый программой за сигнал посадки.

ПО, которое должно было игнорировать срабатывания датчиков до момента включения алгоритма определения касания земли, было организованно неправильно, и ложные срабатывания сохранялись в системе. Как только алгоритм определения касания земли включался на высоте 40 м, программа сразу выдавала команду на выключение посадочных двигателей.

На высоте 40 м скорость снижения аппарата составляла приблизительно 13 м/с (47 км/ч), которая без тяги тормозных двигателей, под действием гравитации Марса увеличивалась до 22 м/с (80 км/ч) у поверхности, расчетная скорость снижения 2.4 м/с (9 км/ч). При такой скорости столкновения с поверхностью аппарат не мог уцелеть».

Если посмотреть на алгоритм работы программы, можно заметить, что одна строчка обнуления состояния переменной IndicatorState на первоначальное FALSE могла спасти аппарат, который обошелся NASA в 328 млн долларов.

Схема алгоритма работы ПО

Ariane 5


4 июня 1996 г. был произведен первый запуск новой ракеты-носителя Ariane 5, разработанной Европейским космическим агентством (ESA). Запуск окончился неудачей — ракета разрушилась на 39-й секунде полёта из-за неверной работы бортового программного обеспечения.


Старт первой Ariane 5

Ariane 5 — европейская ракета-носитель семейства Ariane. Запуски происходят с космодрома Куру во Французской Гвиане. Разработка Ariane 5 заняла 10 лет, стоила 7 млрд долларов и предназначалась для замены ракеты-носителя Ariane 4.

Запущенная в 1996 г. ракета-носитель массой 720 т должна была вывести на орбиту четыре спутника массой 1.2 т каждый. Вращаясь каждый по своей орбите, эти спутники формируют тетраэдр, и работают в группе, это был европейский проект Cluster для исследования магнитного поля Земли (позже в 2000 г. четыре новых спутника для программы Cluster-II успешно выведены на орбиту двумя РН «Союз»).

Ход развития событий


Перед описанием инцидента следует заметить, что конструкция навигационной системы (Inertial Reference System — SRI) для Ariane 5 практически идентична конструкции для Ariane 4, в частности в том, что касается программного обеспечения.

Момент старта обозначим H0. Предшествующие старту операции происходили в нормальном режиме вплоть до момента H0 — 7 минут, когда было зафиксировано нарушение «критерия видимости». Поэтому старт был перенесен на час.
В H0 = 12:33:59 UTC был осуществлен запуск, который и происходил штатно вплоть до момента H0 + 37 сек. В последующие секунды произошло резкое отклонение ракеты от заданной траектории, а затем последовал взрыв.


Момент взрыва Ariane 5 во время первого запуска

Итак: в момент H0 + 39 сек. после старта из-за высокой аэродинамической нагрузки вследствие превышения «углом атаки» критической величины произошло отделение стартовых ускорителей ракеты от основной ее ступени, что и послужило основанием для включения системы автоподрыва ракеты.

Изменение угла атаки произошло по причине нештатного вращения сопел твердотопливных ускорителей, такое отклонение сопел ускорителей вызвала команда, выданная бортовым компьютером на основе информации от навигационной системы SRI 2. Часть этой информации на тот момент была некорректной: то, что интерпретировалось как полетные данные, на самом деле, являлось диагностической информацией встроенного компьютера системы SRI 2. Встроенный компьютер SRI 2 передал некорректные данные, потому что диагностировал нештатную ситуацию, «поймав» исключение (exception), выброшенное одним из модулей программного обеспечения. При этом бортовой компьютер не мог переключиться на резервную систему SRI 1, так как она уже прекратила функционировать в течение предшествующего цикла (период в 72 мсек.) по той же причине, что и SRI 2.

Исключение, «выброшенное» одним из модулей ПО SRI, явилось следствием выполнения преобразования данных из 64-разрядного формата с плавающей точкой в 16-разрядное целое со знаком, что привело к «Operand Error». Ошибка произошла в компоненте ПО, предназначенном исключительно для выполнения «регулировки» бортовой инерциальной платформы. Причем — что звучит парадоксально, но этот программный модуль выдает значимые результаты только до момента отрыва ракеты со стартовой площадки. После того, как ракета взлетела, никакого влияния на полет данный модуль не оказывает. Но функция регулировки, в соответствии с установленными для нее требованиями, должна действовать еще 50 сек. после инициации «полетного режима». Такая последовательность основана на требованиях для Ariane 4, но в ней нет необходимости для Ariane 5.

Ошибка «Operand Error» произошла из-за неожиданно большой величины горизонтального наклона BH (Horizontal Bias). Величина BH оказалась много больше, чем ожидалось, потому что траектория полета Ariane 5 существенно отличалась от траектории полета Ariane 4. Финальным же действием, имевшим фатальные последствия, стало прекращение работы встроенного компьютера SPI — соответственно, вся навигационная система перестала функционировать. Возобновить же ее действия оказалось технически невозможно. Всю эту цепь событий удалось полностью воспроизвести с помощью компьютерного моделирования. Результаты моделирования, а так же материалы других исследований и экспериментов позволили экспертам дать заключение, что причины и обстоятельства катастрофы полностью выявлены.


Ariane 5 на стартовом столе перед успешным запуском, Французская Гвиана 2002 г.

Можно найти несколько вариантов устранения досадного бага в ПО Ariane 5 (эти варианты отражены в результатах расследования), но, так или иначе, эта строчка кода обошлась ESA в 500 млн. долларов (стоимость ракеты с грузом).

Хочу так же отметить, что нигде в отчетах не ставится ударение на беспомощность дублирующей системы в Ariane 5 в данном инциденте, хотя в лекциях проф. Хоффмана эта авария упоминается как раз в этом контексте. Имея две идентичные дублирующие друг друга системы SRI 1 и SRI 2, возможно мы сможем обезопасить себя от проблемы с физическим оборудованием в одной из систем, но когда дело доходит до программной ошибки, такое дублирование просто бесполезно. Далее Хоффман говорит о следующем шаге: продублировать ПО, сделав его различным (разные фирмы, разные программисты). Казалось бы, при такой структуре мы обезопасили себя от ошибок, но такие меры усложняют общую систему и создают еще больше мест, где ошибки могут возникнуть, и для примера приводится третий случай.

Space Shuttle


12 апреля 1981 г. с космодрома на мысе Канаверал совершил свой первый испытательный полет многоразовый космический корабль «Колумбия» по программе Space Shuttle.


Подготовка к миссии STS-1 — первому космическому полету шаттла

Ход развития событий


10 апреля 1981 г., примерно за 20 мин до запланированного старта, космонавты и обслуживающий персонал шаттла пытались запустить резервную систему управления полетом, которая дублировала основную четырех-компьютерную систему, но не смогли. Старт был отменён за 16 минут до расчётного времени и был перенесён на двое суток.

Как тут не вспомнить пресловутый комикс

Случилось так, что резервная система управления полетом BFS (Backup Flight Control System) на пятом бортовом компьютере не могла синхронизироваться с основной системой управления полетом PASS (Primary Avionics Software System), которая уже была запущена на четырех других бортовых компьютерах. В ПО был баг — очень маленькая, почти невероятная, очень замысловатая и очень старая ошибка в инициализации PASS.

Чтобы сделать шаттл надежным в нем дублируется всё: сенсоры, электроника, система управления, компьютеры, ПО, шины передачи данных, источники питания. По факту, чтобы удовлетворять концепции «отказ — работоспособен, отказ — безопасен» «FO/FS» (Fail – Operational, Fail – Safe) многие компоненты дублировались по 4 раза: или буквально (по 4 комплекта аппаратуры), или эквивалентно (чередующиеся схемы, заменяющие один или более блоков из необходимых четырех).

Цифра четыре выбрана по логичной и интуитивно понятной причине: принцип FO/FS требует, чтобы после первого отказа оборудование сохраняло полную работоспособность, а после второго отказа обеспечивало безопасное возвращение. Для минимального голосования требуется три голоса, таким образом в начальной стадии нужно иметь 4 голоса, чтобы можно было голосовать после одного отказа. На шаттле было 5 бортовых компьютеров, четыре из них имели одинаковое ПО, и работали на всех критически важных стадиях полета. Такой подход идеален при возникновении проблем с компьютерами или с другой аппаратурой (по расчетам, ошибки в системе из трех компьютеров вызывали потерю аппарата в трех случаях из миллиона, а система из четырех компьютеров снижала этот шанс до четырех из миллиарда), но он не годится, если учесть возможность возникновения критического, фатального бага в ПО. Таким образом появилась идея альтернативного ПО на пятом компьютере, которое выполняло бы минимальный функционал ПО на первых четырех.

Разработка ПО для BFS включала в себя те же спецификации, тот же самый язык программирования, тот же самый компилятор и то же самое железо, куда это ПО устанавливалось. Но разрабатывалось оно совершенно другой организацией (Rockwell International для BFS и IBM, Federal Systems Division для PASS) и устанавливалось на разные операционные системы. ОС для PASS была асинхронной и управляемой приоритетом (asynchronous and priority driven – таким образом, наиболее важной задаче всегда моментально дается контроль над компьютером). BFS же, напротив, похож больше на полностью синхронную систему «временных интервалов», где каждому процессу отдается отведенное время для выполнения своего цикла.

К сожалению, синхронная и асинхронная системы плохо объединимы. Чтобы BFS могла синхронизироваться с PASS, PASS должна стать синхронной или эмулировать это для синхронизируемых процессов. Процесс эмуляции был обеспечен с минимальными потерями при разработке. Как только включался самый первый компьютер и запускалась PASS, она пыталась синхронизировать начало всех процессов с данными телеметрии корабля. Эта синхронизация выполнялась путем считывания значения времени с данных телеметрии и расчета фаз телеметрии в соответствии с центральным временем.

В пятницу утром, 10 апреля, стало ясно, что некоторые процессы в PASS обрабатываются не в своей фазе: на один цикл раньше чем остальные процессы PASS и BFS. Предполагая получение «загрязненных» данных, BFS, как и требовалось, полностью перестала «слушать» информацию от PASS, и поэтому не могла синхронизироваться с PASS. Для BFS данные приходящие на цикл раньше были просто нерасчетными «помехами».

Уже в начале полудня, собрав всех экспертов, NASA смогла прояснить характер проблемы. Исправить ошибку в фазировании можно было бы старым дедовским методом: если что-то не работает — выключи и включи снова.



Но этот подход не работает для полностью заправленного и готового к старту космического корабля — бортовые компьютеры играют критически важную роль в обработке информации, идущей «от» и «к» системе подготовки запуска космодрома.

Сведения, собранные экспертами, и факт того, что перезапуск бортовых компьютеров в пятницу ночью устранил проблему, дали руководству NASA достаточно информации, чтобы назначить запуск на утро воскресенья. Но истинные причины ошибки были выявлены вечером воскресенья, спустя 8 часов с момента запуска.

Бортовые компьютеры используют очередь таймера (timer queue) операционной системы как часы, первая запись — это желаемое время старта (start time) следующего процесса, при выполнении сотен процессов в любую секунду, первая запись показывает всегда довольно точное настоящее время (current time) (всегда немного спешит, но всегда достаточно точно). Полученное время всегда абсолютно одинаково для всех резервных бортовых компьютеров. Когда запускается самый первый компьютер — нет активных вычислений, это единственный момент когда очередь пуста. И т. к. нет других рабочих компьютеров, первому разрешалось использовать свои часы для определения времени.

Но очередь не была пустой, как предполагалось. За два года до запуска, произошло изменение в подпрограмме инициализации шины данных, которая выполнялась до расчета времени старта. Эта подпрограмма вставляла значение задержки (delay) времени в очередь таймера. Это изменение прошло незамеченным: в конце концов, каким образом инициализация шины связана с определением фаз для телеметрии. Более того, эта задержка времени была достаточно маленькой, чтобы первая запись в очереди была близка к настоящему времени. Но через год (за год до запуска) было внесено еще одно изменение, чтобы исправить возможную перегрузку процессора, время задержки было чуть-чуть увеличено. И этого было достаточно, чтобы появилась 1/67 вероятность того, что при включении первого бортового компьютера, в своих расчетах времени старта, используя чуть-чуть идущее вперед время очереди таймера, он мог получить результат, когда время старта было в прошлом. Тогда операционная система переносила начало процесса на один цикл (как происходит с будильником, когда он заведен на «прошлое», он пропускает 12 часовой цикл, так чтобы он мог зазвонить в «будущем»), что в итоге приводило к тому, что почти все процессы выполнялись с опозданием на цикл.

Тестирование могло обнаружить эту ошибку, но вероятность ошибки появлялась только на поздних этапах тестирования, когда система проверялась целиком, но даже тогда, большинство тестов не требовало инициализации с нуля. И даже в тестах, где это требовалось, нужна была лаборатория с довольно точными моделями PASS, BFS и телеметрии. И даже при соблюдении всех выше перечисленных условий, при возникновении ошибки, возникало искушение, все перезапустить и… никогда не повторить ошибку, и никогда не быть уверенным, не была ли это проблема в лабораторной установке. Вероятно именно это и произошло в одной из лабораторий NASA примерно за 4 месяца до полета.

И все же, в день, когда первый бортовой компьютер был включен, за 30 часов до запланированного запуска, проблема дала о себе знать.

Вся информация о баге на шаттле взята из статьи Джона Гармана (зам начальника департамента космического ПО в NASA). В ней он так же пишет: «Идеальная надежность не обеспечивается, потому что в проектах всегда приходится торговаться за время и стоимость. Обслуживание систем программного обеспечения непосредственно на месте, накопление больших изменений и добавлений на стадиях разработки, и переконфигурация ПО, чтобы оно подходило на аппараты или миссии, которые никогда полностью не идентичны — это проблемы, которые стоят перед нами сегодня. Легко сказать: «Не нарушай правила». Это невозможно без инвертирования относительной позиции ПО во встроенных системах — а это неправильно! ПО может быть и «душа» самых сложных систем, но все равно это всего лишь часть поддерживающей оболочки, … очень гибкая часть».


Посадка шаттла на поверхность высохшего озера Роджерс

Стоимость данной ошибки в ПО 0 долларов (безусловно, затраты на перенос запуска были и возможно немалые, но в свете предыдущих рассмотренных аварий, когда происходила полная потеря космического аппарата до завершения им запланированной миссии, затратами на переподготовку старта я пренебрегу, тем более, что мне не удалось найти подходящих данных).

Но хотелось бы заметить, что данная ошибка отодвинула время старта на два дня: с 10 апреля на 12 апреля, и, по-моему, нельзя было выбрать более удачную дату для первого запуска шаттла, ведь в этот же самый день, ровно 20 лет назад Юрий Гагарин совершил свой полет в космос. Как тут не вспомнить слова одной черепахи о том, что «случайности не случайны».




К сожалению, не доступен сервер mySQL