kerbal.ruвики сборки «Оператор»
Оператор / Вики / Автоматика

kOS: готовые рецепты

Четыре рабочих скрипта kOS с разбором построчно: взлёт, циркуляризация, вывод спутника с заданным наклонением, посадка на Муну.

Готовые скрипты под сборку «Оператор». Все конструкции — базовые (LOCK, WAIT UNTIL, UNTIL, STAGE, NODE), проверены на kOS 1.6. Если ещё не читал kOS: основы — начни оттуда.

Файлы кладём в Ships/Script/, запускаем из терминала RUNPATH("0:/ascent.ks").

Перед первым прогоном любого скрипта — быстрое сохранение. Всегда.

1. Взлёт с гравитационным разворотом

ascent.ks — вертикальный старт, плавный завал по корню высоты, автоотделение ступеней, отсечка на заданном апоцентре.

// ascent.ks — взлёт до заданного апоцентра
SET targetAp TO 90000.   // целевой апоцентр, м
SET azimuth  TO 90.      // курс: 90 = на восток
SET turnEnd  TO 45000.   // высота окончания разворота, м

CLEARSCREEN.
SAS OFF.

// автоступень: тяга пропала -> отделяем и продолжаем следить
WHEN MAXTHRUST < 0.1 THEN {
  WAIT 0.5.
  STAGE.
  PRESERVE.
}

LOCK pitch TO 90 - 90 * SQRT(MIN(1, SHIP:ALTITUDE / turnEnd)).
LOCK STEERING TO HEADING(azimuth, pitch).
LOCK THROTTLE TO 1.
STAGE.

UNTIL SHIP:APOAPSIS > targetAp {
  PRINT "Ap " + ROUND(SHIP:APOAPSIS / 1000, 1) + " км  тангаж " + ROUND(pitch, 1) + "   " AT (0, 3).
  WAIT 0.1.
}

LOCK THROTTLE TO 0.
PRINT "Апоцентр набран, ждём космос.".
WAIT UNTIL SHIP:ALTITUDE > 70000.
PRINT "Вне атмосферы. Запускай circ.ks".

Разбор:

  • WHEN ... THEN { } — фоновый триггер, проверяется каждый физический тик. PRESERVE. внутри означает «оставь триггер жить после срабатывания», иначе он отработает один раз. WAIT 0.5. перед STAGE даёт двигателю догореть.
  • LOCK pitch TO 90 - 90 * SQRT(...) — весь профиль разворота одной строкой. На нуле высоты корень равен нулю, тангаж 90° (вертикаль); к turnEnd корень равен единице, тангаж 0° (горизонт). Корень даёт быстрый завал внизу и пологий вверху — именно то, что нужно.
  • MIN(1, ...) не даёт выражению уйти за горизонт, если апоцентр набирается позже turnEnd.
  • LOCK вычисляется заново при каждом обращении, поэтому одной строки хватает на весь подъём — цикл только печатает телеметрию.

Профиль под ракету подбирается двумя числами: turnEnd больше — разворот пологий (для слабых ракет), меньше — агрессивный.

2. Циркуляризация в апоцентре

circ.ks — считает импульс по вис-вива, ставит узел манёвра и исполняет его.

// circ.ks — круговая орбита на высоте апоцентра
SET mu TO SHIP:BODY:MU.
SET r  TO SHIP:BODY:RADIUS + SHIP:APOAPSIS.

SET vNow  TO SQRT(mu * (2 / r - 1 / SHIP:ORBIT:SEMIMAJORAXIS)).
SET vCirc TO SQRT(mu / r).
SET dv    TO vCirc - vNow.

SET nd TO NODE(TIME:SECONDS + ETA:APOAPSIS, 0, 0, dv).
ADD nd.
PRINT "dV узла: " + ROUND(dv, 1) + " м/с".

// грубая оценка длительности прожига: a = F/m
SET acc  TO SHIP:AVAILABLETHRUST / SHIP:MASS.
SET tBurn TO dv / acc.

SET dv0 TO nd:DELTAV.               // запомнили исходный вектор
LOCK STEERING TO nd:DELTAV.
WAIT UNTIL nd:ETA <= tBurn / 2 + 15.
WAIT UNTIL nd:ETA <= tBurn / 2.

LOCK THROTTLE TO 1.
UNTIL VDOT(dv0, nd:DELTAV) < 0 {    // вектор развернулся -> перелёт
  IF nd:DELTAV:MAG < 5 { LOCK THROTTLE TO 0.1. }
  WAIT 0.
}
LOCK THROTTLE TO 0.
REMOVE nd.
UNLOCK STEERING.
PRINT "Орбита: " + ROUND(SHIP:APOAPSIS/1000,1) + " / " + ROUND(SHIP:PERIAPSIS/1000,1) + " км".

Разбор:

  • Формула вис-вива: скорость в точке на радиусе r при большой полуоси a равна sqrt(mu * (2/r − 1/a)). Для круговой орбиты a = r, отсюда vCirc. Разница и есть нужный импульс — целиком по прогрейду.
  • NODE(время_UT, радиальный, нормальный, прогрейд) — узел манёвра создаётся, ADD вешает его на траекторию. Дальше его видно в карте, как обычный узел.
  • nd:DELTAV — оставшийся вектор узла, он же направление прожига. Классический критерий «хватит»: скалярное произведение VDOT исходного и текущего вектора стало отрицательным, то есть остаток развернулся на 180° — значит проскочили.
  • Дросселирование до 0.1 на последних 5 м/с убирает перелёт на мощных ступенях.
  • Оценка tBurn через постоянное ускорение занижает время для длинных прожигов (масса падает). Для орбитальных манёвров в пару сотен м/с точности хватает.

3. Спутник на заданную высоту и наклонение

Основа сети связи — см. Созвездия и покрытие и Связь: как работает CommNet. Наклонение задаётся азимутом старта.

// sat.ks — вывод на орбиту с заданным наклонением
SET targetInc TO 63.4.     // наклонение, градусы
SET targetAp  TO 500000.   // высота орбиты, м

SET c TO COS(targetInc) / COS(SHIP:LATITUDE).
IF ABS(c) > 1 {
  PRINT "С этой широты такое наклонение недостижимо.".
} ELSE {
  SET azimuth TO ARCSIN(c).            // восходящая ветвь, курс на северо-восток
  PRINT "Азимут старта: " + ROUND(azimuth, 2) + " градусов".
  PRINT "Целевой апоцентр: " + ROUND(targetAp / 1000) + " км".
}

Разбор:

  • Сферическая формула: sin(азимут) = cos(наклонение) / cos(широта). С мыса КЦК (широта ≈ 0°) достижимо любое наклонение; чем севернее старт, тем уже коридор.
  • В kOS все тригонометрические функции работают в градусах, конвертировать не нужно.
  • ABS(c) > 1 — проверка физической достижимости: наклонение не может быть меньше широты старта.
  • ARCSIN даёт азимут восходящей ветви. Для нисходящей (ретроградное движение по широте) бери 180 - azimuth.
  • Для полярной орбиты (targetInc = 90) получится ровно azimuth = 0 — прямо на север.

Практика: запусти sat.ks на стартовом столе, подставь напечатанный азимут и высоту в azimuth и targetAp скрипта ascent.ks, отработай взлёт, затем circ.ks в апоцентре. Получается повторяемый запуск ретранслятора: три-четыре одинаковых пуска — и покрытие готово.

4. Посадка на Муну

land.ks — торможение по вертикальной скорости на безатмосферном теле. Простой релейный алгоритм: держим скорость снижения ниже допустимой, допустимая падает с высотой.

// land.ks — мягкая посадка (безатмосферное тело)
SAS OFF.
GEAR ON.
LOCK STEERING TO SRFRETROGRADE.
WAIT 10.                                    // дать развернуться

LOCK maxDown TO -5 - 0.05 * ALT:RADAR.      // допустимая скорость снижения

UNTIL SHIP:STATUS = "LANDED" OR SHIP:STATUS = "SPLASHED" {
  IF SHIP:VERTICALSPEED < maxDown {
    LOCK THROTTLE TO 1.
  } ELSE {
    LOCK THROTTLE TO 0.
  }
  IF ALT:RADAR < 100 { LOCK STEERING TO UP. }
  PRINT "h " + ROUND(ALT:RADAR) + " м  Vy " + ROUND(SHIP:VERTICALSPEED, 1) + "   " AT (0, 3).
  WAIT 0.
}

LOCK THROTTLE TO 0.
UNLOCK STEERING.
PRINT "Сели.".

Разбор:

  • SRFRETROGRADE — ретроградное относительно поверхности, то есть «против движения». Гасит и горизонтальную составляющую.
  • maxDown линейно зависит от радарной высоты ALT:RADAR: на 1000 м допускается −55 м/с, на 100 м уже −10 м/с, у самой поверхности −5 м/с.
  • Ниже 100 м руль переключается на UP (вертикаль) — иначе на почти нулевой горизонтальной скорости SRFRETROGRADE начинает дёргаться.
  • WAIT 0. — уступить один физический тик, самый частый способ крутить управляющий цикл.
  • Скрипт релейный: тяга либо 1, либо 0. Топлива тратит больше оптимума, зато не переворачивает аппарат. Для тяжёлых посадочных модулей ограничь тягу двигателя в редакторе процентов до 60.

Дальше: остальные слои автоматизации — MechJeb, будильники, повторяющиеся рейсы — в статье Автоматика полётов и рутина.

Связанные статьи