"Универсализировал" скрипт посадки. Теперь можно пробовать садиться на любых телах=) В принципе, для разных планет никаких значений менять в скрипте не надо, но если очень хочется, то можно.
Пробуем, проверяем, делимся мудростью и впечатлениями. Спасибо.
//Программа посадки беспилотного корабля на поверхность. v 2.0.
///user/Iavasdemsul/
//Формулы:
//Конечная высота h = h0 v0*T 0.5*a*T^2
//Конечная скорость v = v0 a*t
//Текущее ускорение a = F (тяги)/ M - g, или a = PWR * p - g.
//
clearscreen.
//
sas on. //Обязательно нужен SAS, чтоб не вращало наш аппарат.
set navmode to "SURFACE". //переключение в режим Surface.
set sasmode to "STABILITYASSIST". //Включение SAS в режиме стабилизации.
set PWR to 0. //Начальная тяга двигателя.
set lspeed to -1. //Желаемая конечная вертикальная скорость после маневра торможения - с минусом, если скорость падения.
set T to 0. //Начальное значение дельты времени для достижения необходимой скорости, при максимальной тяге.(для отладки - должно уменьшаться или быть постоянным).
set limit to 1. //Начальное значение программного лимита тяги, для компенсации инертности алгоритма сброса скорости.
set TWRlimit to 2. //Лимит TWR для установки лимита тяги. Экспериментально вычисленное оптимальное значение 2.
lock g to body:mu / (body:radius ship:altitude)^2. //Ускорение свободного падения g = GM /(R h_asl)^2.
lock p to limit*ship:maxthrust/ship:mass. //Промежуточная переменная p = max(F тяги)/ M, коэффициент максимальной тяги корабля.
lock deltav to lspeed - ship:verticalspeed. //Промежуточная переменная dV, характеризующая необходимый
//прирост скорости в момент времени до окончания маневра.
//
set laser_module to ship:modulesnamed("laserdistmodule")[0]. //Включение
if not laser_module:getfield("enabled") { //лазера
laser_module:setfield("enabled",true). //из мода LaserDist v.0.9.2.
}
set T_temp to 0. //Объявление
set V_temp to 0. //переменных.
//
set h to 1. //!!!!!!!Высота LaserDist модуля корабля.
//
until ship:status = "LANDED" or ship:status = "SPLASHED" or ship:status = "PRELAUNCH"
{
set delta_T to sessiontime - T_temp. //Дельта времени для вычисления реального ускорения.
set delta to ship:verticalspeed - V_temp. //Дельта скорости за время delta_T
set T_temp to sessiontime. //Присваивание значения для следующей итерации вычисления delta_T
set V_temp to ship:verticalspeed. //То же для delta.
set A to delta/delta_T. //Реальное значение вертикального ускорения для атмосферных планет.
lock drag to A g - (throttle*ship:maxthrust/ship:mass). //Вычисление параметра ускорения, вносимого сопротивлением атмосферы.
if ship:maxthrust <= 0 { hudtext("NO MORE FUEL. R.I.P.", 5, 2, 45, red, false). reboot.}. //Проверка наличия топлива.
if ship:verticalspeed < -1 { lock steering to ship:srfretrograde.}. //Разворот корабля в ретрогрейд, при падении.
set limit to TWRlimit*ship:mass*g/ship:maxthrust. //Расчет программного лимита тяги, для компенсации инертности алгоритма сброса скорости. За опору берется TWRlimit=2.
if limit > 1 {set limit to 1.}. //Для слабых двигателей.
if limit >= 2 {hudtext("NOT ENOUGH THRUST. R.I.P.", 5, 2, 45, red, false). reboot.}. //Для очень слабых!
if laser_module:getfield("Hit") = body:name and vang(ship:facing:forevector,ship:srfretrograde:forevector) < 10 //Проверка наклона аппарата
{ //для считывания данных лазерного дальномера.
lock curr_h to min(alt:radar, laser_module:getfield("Distance") * sin(vang(up:vector,ship:facing:topvector))). //Если аппарат сориентирован по вектору движения и для лазера нет препятствий,
} //то вычисляем минимальное значение из двух - альтиметра и дальномера.
else //
{ //Если нет, то полагаемся только на данные альтиметра.
lock curr_h to alt:radar. //Конструкция необходима для анализа ландшафта и обнаружения сильных перепадов по высоте.
}.
if alt:radar < 50
{ //Лочим положение аппарата при подлете к поверхности для
lock steering to ship:up. //предотвращения наклонов из-за потери ретрогрейда на низких скоростях.
lock curr_h to laser_module:getfield("Distance"). //Ориентируемся только по дальномеру, так как он дает более точный результат по высоте.
}.
if ship:verticalspeed < -1 and drag < g
{
set PWR to ((p-g)^2)*(2*h-2*curr_h-2*ship:verticalspeed*deltav/(p-g))/(p*deltav^2) g/p. //Расчет тяги, при след условиях:
//конечная высота h метров;
//вертикальная скорость отрицательна;
} //T = dV/(p-g), минимальное время для достижения необходимой высоты h и скорости lspeed, при максимальной тяге.
else {set PWR to 0.}.
//
if PWR < 0 {set PWR to 0.}.
if PWR > 1 {set PWR to 1.}.
set T to (deltav)/(PWR * p - g).
lock throttle to PWR.
clearscreen.
Print "LANDING TO " body:name at (5,1).
Print "Grav.acc.(g) " round(g, 2) " m/s^2" at (5,2).
Print "Final Speed " lspeed " m/s" at (5,3).
Print "Final Altitude " round(h, 2) " m" at (5,4).
Print "Ship Velocity " round(ship:velocity:surface:mag) " m/s" at (5,6).
Print "Vertical Speed " round(ship:verticalspeed) " m/s" at (5,7).
Print "Thrust Power " round(PWR * 100, 2) " %" at (5,9).
Print "Engine Thrust " round(limit*ship:maxthrust * PWR, 2) " kN" at (5,10).
Print "Est.Time to Stop " round(-1*T, 2) " s" at (5,11).
Print "Thrust Limit " round(limit*100) " %" at (5,12).
Print "Curr_h " round(curr_h, 2) " m" at (5,15).
Print "Altitude " round(alt:radar, 2) " m" at (5,16).
Print "Laser Distance " round(laser_module:getfield("Distance"), 2) " m" at (5,17).
Print "Real accelerate: " round(A, 2) " m/s^2"at (5,19).
Print "DRAG: " round(drag*ship:mass, 2) " kN" at (5,20).
wait 0.01.
}.
Print "SUCCESSFULLY LANDED TO " body:name "!"at (5,23).
hudtext("LANDED SUCCESSFULLY!", 5, 2, 45, green, false).
set ship:control:pilotmainthrottle to 0.
скачать
xxx.ks Сообщение отредактировал 25 сентября 2016 - 12:57