This commit is contained in:
2026-01-15 00:13:31 +08:00
parent 915335ecc5
commit fe2ebd6a70
+26 -18
View File
@@ -62,7 +62,7 @@ def vessel_available_thrust():
print('Vessel available thrust = %.1f kN' % (thrust / 1000))
time.sleep(1)
def auto_land_predictive(host='localhost', port=50000, target_altitude=0.5, target_vspeed=-2.0, safety_margin=5.0, verbose=True):
def auto_land_predictive(bottom_clearance_margin=12, host='localhost', port=50000, target_altitude=0.5, target_vspeed=-2.0, safety_margin=5.0, verbose=True):
"""预测式自动着陆(suicide burn 思路)。
关键点:
@@ -81,6 +81,8 @@ def auto_land_predictive(host='localhost', port=50000, target_altitude=0.5, targ
注:这里 v 取“相对地表速度”的标量(surface speed),更贴近你提到的 get_surface_speed。
若需要更精细,可改成取 surface_velocity 向量的径向分量/或用垂直速度替代。
bottom_clearance_margin = 12 # m:按载具尺寸调整(越大越早开始末端减速)
"""
try:
import math
@@ -100,13 +102,15 @@ def auto_land_predictive(host='localhost', port=50000, target_altitude=0.5, targ
status = {'result': 'failed', 'logs': []}
# WAIT 阶段按折减推力估算刹车距离(提前点火,补偿点火/推力建立延迟)
thrust_discount_wait = 0.9
thrust_discount_wait = 0.85
# 低空/接地参数(用于“最后几米慢下来”)
touchdown_vspeed_tol = 0.6 # m/s:认为“软着陆”的竖直速度容差
low_altitude_pid_switch = 10.0 # m:低于该高度切换到竖直速度控制
vspeed_p_gain = 1.2 # 比例增益:越大越积极(建议 0.6~2.0)
low_altitude_ff_gain = 0.3 # 低空前馈增益:按“需要的减速距离/剩余距离”做额外加速度
# 由于 surface_altitude 近似是“载具质心高度”,末端会偏乐观。
# 用 bedrock_altitude(雷达高度)并减去一个底部几何余量,近似得到“最低点离地高度”。
def _get_g(local_vessel):
try:
@@ -140,9 +144,10 @@ def auto_land_predictive(host='localhost', port=50000, target_altitude=0.5, targ
ap = None
def _read_state():
"""从接口读取状态:alt, surface_speed(标量), vertical_speed, mass, available_thrust, g, situation_name"""
"""从接口读取状态:alt(surface_altitude), radar_alt(bedrock_altitude), surface_speed, vertical_speed, mass, available_thrust, g, situation_name"""
flight = vessel.flight(surface_frame) if surface_frame is not None else vessel.flight()
alt = float(getattr(flight, 'surface_altitude', 0.0))
radar_alt = float(getattr(flight, 'bedrock_altitude', alt))
srf_speed = float(getattr(flight, 'speed', 0.0))
v_speed = float(getattr(flight, 'vertical_speed', 0.0))
mass = float(getattr(vessel, 'mass', 0.0))
@@ -152,7 +157,7 @@ def auto_land_predictive(host='localhost', port=50000, target_altitude=0.5, targ
situation_name = str(getattr(getattr(vessel, 'situation', None), 'name', ''))
except Exception:
situation_name = ''
return alt, srf_speed, v_speed, mass, avail_thrust, g_local, situation_name
return alt, radar_alt, srf_speed, v_speed, mass, avail_thrust, g_local, situation_name
try:
# 初始确保不点火
@@ -164,8 +169,10 @@ def auto_land_predictive(host='localhost', port=50000, target_altitude=0.5, targ
# 倒计时/等待点火
last_log_t = 0.0
while True:
alt, srf_speed, v_speed, mass, avail_thrust, g_local, situation_name = _read_state()
remaining_alt = max(0.0, alt - float(target_altitude))
alt, radar_alt, srf_speed, v_speed, mass, avail_thrust, g_local, situation_name = _read_state()
# 用“雷达高度-底部余量”近似最低点离地高度
alt_eff = max(0.0, float(radar_alt) - float(bottom_clearance_margin))
remaining_alt = max(0.0, alt_eff - float(target_altitude))
# v:使用 surface speed(标量)作为“需要刹掉的速度”
v = max(0.0, float(srf_speed))
@@ -192,7 +199,7 @@ def auto_land_predictive(host='localhost', port=50000, target_altitude=0.5, targ
if verbose and now - last_log_t > 0.2:
last_log_t = now
msg = (
f'WAIT alt={alt:.1f} rem={remaining_alt:.1f} '
f'WAIT alt={alt:.1f} radar={radar_alt:.1f} alt_eff={alt_eff:.1f} rem={remaining_alt:.1f} '
f'srf_speed={srf_speed:.2f} vs={v_speed:.2f} '
f'a_max_up={a_max_up:.2f} braking={braking_dist:.1f} thr_disc={thrust_discount_wait:.2f} '
f'countdown={(countdown if countdown is not None else float("nan")):.2f}'
@@ -212,16 +219,17 @@ def auto_land_predictive(host='localhost', port=50000, target_altitude=0.5, targ
pass
time.sleep(0.01)
# 点火
try:
vessel.control.activate_next_stage()
except Exception:
pass
# # 点火
# try:
# vessel.control.activate_next_stage()
# except Exception:
# pass
# 燃烧闭环:根据 remaining_alt 反推需要的减速度 -> 油门
while True:
alt, srf_speed, v_speed, mass, avail_thrust, g_local, situation_name = _read_state()
remaining_alt = max(0.0, alt - float(target_altitude))
alt, radar_alt, srf_speed, v_speed, mass, avail_thrust, g_local, situation_name = _read_state()
alt_eff = max(0.0, float(radar_alt) - float(bottom_clearance_margin))
remaining_alt = max(0.0, alt_eff - float(target_altitude))
# BURN 阶段以“竖直下降速度”为控制对象:下降为负,统一转成向下为正的标量 v_down
v_down = max(0.0, -float(v_speed))
@@ -254,7 +262,7 @@ def auto_land_predictive(host='localhost', port=50000, target_altitude=0.5, targ
break
# 低空策略:切换到“竖直速度跟踪”以确保最后几米把速度压到目标值
if alt <= float(low_altitude_pid_switch):
if alt_eff <= float(low_altitude_pid_switch):
# 低空:比例 + 前馈(用当前速度估算“需要多少距离才能刹到目标速度”)
# a_p:把竖直速度拉向目标
a_p = float(vspeed_p_gain) * max(0.0, (v_down - vf_down))
@@ -280,7 +288,7 @@ def auto_land_predictive(host='localhost', port=50000, target_altitude=0.5, targ
throttle = max(0.0, min(1.0, float(throttle)))
# 低空兜底:高度<5m 且仍很快 -> 满油门
if alt < 5.0 and v_down > 10.0:
if alt_eff < 5.0 and v_down > 10.0:
throttle = 1.0
# 若已经触发 LANDED 但竖直速度仍偏大,避免油门过低导致“硬砸/反弹”
@@ -294,7 +302,7 @@ def auto_land_predictive(host='localhost', port=50000, target_altitude=0.5, targ
if verbose:
msg = (
f'BURN alt={alt:.1f} rem={remaining_alt:.1f} '
f'BURN alt={alt:.1f} radar={radar_alt:.1f} alt_eff={alt_eff:.1f} rem={remaining_alt:.1f} '
f'srf_speed={srf_speed:.2f} vs={v_speed:.2f} '
f'v_down={v_down:.2f} vf_down={vf_down:.2f} '
f'a_req_up={a_req_up:.2f} throttle={throttle:.2f} '
@@ -322,6 +330,6 @@ def auto_land_predictive(host='localhost', port=50000, target_altitude=0.5, targ
return status
if __name__ == "__main__":
xxx = auto_land_predictive()
xxx = auto_land_predictive(bottom_clearance_margin=20)
print(xxx)
print('done')