update
This commit is contained in:
Binary file not shown.
@@ -1,7 +1,9 @@
|
||||
import time
|
||||
import krpc
|
||||
import math
|
||||
|
||||
|
||||
G_EARTH = 9.80665
|
||||
|
||||
def get_surface_speed():
|
||||
conn = krpc.connect(name='Vessel speed')
|
||||
@@ -62,7 +64,31 @@ def vessel_available_thrust():
|
||||
print('Vessel available thrust = %.1f kN' % (thrust / 1000))
|
||||
time.sleep(1)
|
||||
|
||||
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):
|
||||
def get_body_g(local_vessel):
|
||||
try:
|
||||
body = local_vessel.orbit.body
|
||||
g = float(getattr(body, 'surface_gravity', G_EARTH))
|
||||
if g > 0:
|
||||
return g
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
g = float(getattr(local_vessel.flight(), 'surface_gravity', G_EARTH))
|
||||
if g > 0:
|
||||
return g
|
||||
except Exception:
|
||||
pass
|
||||
return G_EARTH
|
||||
|
||||
def auto_land_predictive(
|
||||
bottom_clearance_margin=12,
|
||||
thrust_discount_wait=0.85,
|
||||
host='localhost',
|
||||
port=50000,
|
||||
target_altitude=1.0,
|
||||
target_vspeed=-1.0,
|
||||
safety_margin=3.0,
|
||||
verbose=True):
|
||||
"""预测式自动着陆(suicide burn 思路)。
|
||||
|
||||
关键点:
|
||||
@@ -83,14 +109,46 @@ def auto_land_predictive(bottom_clearance_margin=12, host='localhost', port=5000
|
||||
若需要更精细,可改成取 surface_velocity 向量的径向分量/或用垂直速度替代。
|
||||
|
||||
bottom_clearance_margin = 12 # m:按载具尺寸调整(越大越早开始末端减速)
|
||||
"""
|
||||
try:
|
||||
import math
|
||||
except Exception:
|
||||
math = None
|
||||
|
||||
if krpc is None:
|
||||
raise RuntimeError('krpc 未安装')
|
||||
参数说明:
|
||||
bottom_clearance_margin (float):
|
||||
- 单位:米(m)
|
||||
- 说明:从雷达(bedrock_altitude)读取的高度中减去该几何余量以近似载具最低点到地面的距离。
|
||||
用于避免脚本在实际着陆时因底部结构接触地面而过早判断已着陆。值越大会更早开始末端减速。
|
||||
- 典型值:10~25,根据载具底部高度调整。
|
||||
|
||||
thrust_discount_wait (float):
|
||||
- 单位:无(比例系数)
|
||||
- 说明:在 WAIT 阶段估算可用推力时对 vessel.available_thrust 的折减因子。
|
||||
会用 avail_thrust * thrust_discount_wait 来保守估算用于决定何时点火(补偿推力建立/响应延迟)。
|
||||
- 取值范围:0.0~1.0;越小越保守(更早点火)。默认 0.85。
|
||||
|
||||
host (str) / port (int):
|
||||
- 说明:连接 kRPC 服务的地址和 RPC 端口(用于 krpc.connect)。一般本地运行时用 'localhost' 和 50000。
|
||||
|
||||
target_altitude (float):
|
||||
- 单位:米(m)
|
||||
- 说明:目标的“触地点高度基准”,脚本在计算剩余高度时会把 radar_alt - bottom_clearance_margin 与此值比较。
|
||||
通常设为想要在接触地面时的质心高度(或 0/地面高度上方的偏移)。
|
||||
- 典型值:0~5(例如 3 表示目标在底部余量之上 3m 处被视为触地)。
|
||||
|
||||
target_vspeed (float):
|
||||
- 单位:m/s(竖直速度,负值表示向下)
|
||||
- 说明:期望的着陆竖直速度(向下为负)。脚本会把该值取绝对值作为目标的向下速度(vf_down)。
|
||||
在计算刹车距离和 PID/前馈控制里以该目标速度为参考。
|
||||
- 典型值:-0.5 ~ -1.5(更接近 0 的值更“柔和”但更难实现)。默认为 -1.0。
|
||||
|
||||
safety_margin (float):
|
||||
- 单位:米(m)
|
||||
- 说明:在刹车距离上再加的安全余量,用于补偿模型误差(如空气阻力、推力随时间变化等)。
|
||||
- 典型值:几米(例如 3~10)。默认 5.
|
||||
|
||||
verbose (bool):
|
||||
- 说明:是否打印并记录运行时信息到返回的 status['logs'],用于调试或观察倒计时/燃烧过程。
|
||||
|
||||
返回值:
|
||||
返回一个 dict 格式的状态描述,包含 'result' 字段('failed' / 'landed' / 'touchdown_pending')和 'logs'(运行时消息列表)。
|
||||
"""
|
||||
|
||||
conn = krpc.connect(name='auto_land_predictive', address=host, rpc_port=port)
|
||||
sc = conn.space_center
|
||||
@@ -102,7 +160,7 @@ def auto_land_predictive(bottom_clearance_margin=12, host='localhost', port=5000
|
||||
status = {'result': 'failed', 'logs': []}
|
||||
|
||||
# WAIT 阶段按折减推力估算刹车距离(提前点火,补偿点火/推力建立延迟)
|
||||
thrust_discount_wait = 0.85
|
||||
|
||||
|
||||
# 低空/接地参数(用于“最后几米慢下来”)
|
||||
touchdown_vspeed_tol = 0.6 # m/s:认为“软着陆”的竖直速度容差
|
||||
@@ -112,22 +170,6 @@ def auto_land_predictive(bottom_clearance_margin=12, host='localhost', port=5000
|
||||
# 由于 surface_altitude 近似是“载具质心高度”,末端会偏乐观。
|
||||
# 用 bedrock_altitude(雷达高度)并减去一个底部几何余量,近似得到“最低点离地高度”。
|
||||
|
||||
def _get_g(local_vessel):
|
||||
try:
|
||||
body = local_vessel.orbit.body
|
||||
g = float(getattr(body, 'surface_gravity', 9.81))
|
||||
if g > 0:
|
||||
return g
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
g = float(getattr(local_vessel.flight(), 'surface_gravity', 9.81))
|
||||
if g > 0:
|
||||
return g
|
||||
except Exception:
|
||||
pass
|
||||
return 9.81
|
||||
|
||||
# 使用 body 的 reference_frame 读取 surface speed / vertical_speed(对应 get_surface_speed 思路)
|
||||
try:
|
||||
surface_frame = vessel.orbit.body.reference_frame
|
||||
@@ -152,19 +194,13 @@ def auto_land_predictive(bottom_clearance_margin=12, host='localhost', port=5000
|
||||
v_speed = float(getattr(flight, 'vertical_speed', 0.0))
|
||||
mass = float(getattr(vessel, 'mass', 0.0))
|
||||
avail_thrust = float(getattr(vessel, 'available_thrust', 0.0))
|
||||
g_local = _get_g(vessel)
|
||||
try:
|
||||
situation_name = str(getattr(getattr(vessel, 'situation', None), 'name', ''))
|
||||
except Exception:
|
||||
situation_name = ''
|
||||
g_local = get_body_g(vessel)
|
||||
situation_name = str(getattr(getattr(vessel, 'situation', None), 'name', ''))
|
||||
return alt, radar_alt, srf_speed, v_speed, mass, avail_thrust, g_local, situation_name
|
||||
|
||||
try:
|
||||
# 初始确保不点火
|
||||
try:
|
||||
vessel.control.throttle = 0.0
|
||||
except Exception:
|
||||
pass
|
||||
vessel.control.throttle = 0.0
|
||||
|
||||
# 倒计时/等待点火
|
||||
last_log_t = 0.0
|
||||
@@ -213,18 +249,9 @@ def auto_land_predictive(bottom_clearance_margin=12, host='localhost', port=5000
|
||||
break
|
||||
|
||||
# 确保仍在滑行
|
||||
try:
|
||||
vessel.control.throttle = 0.0
|
||||
except Exception:
|
||||
pass
|
||||
vessel.control.throttle = 0.0
|
||||
time.sleep(0.01)
|
||||
|
||||
# # 点火
|
||||
# try:
|
||||
# vessel.control.activate_next_stage()
|
||||
# except Exception:
|
||||
# pass
|
||||
|
||||
# 燃烧闭环:根据 remaining_alt 反推需要的减速度 -> 油门
|
||||
while True:
|
||||
alt, radar_alt, srf_speed, v_speed, mass, avail_thrust, g_local, situation_name = _read_state()
|
||||
@@ -239,10 +266,7 @@ def auto_land_predictive(bottom_clearance_margin=12, host='localhost', port=5000
|
||||
# 因此要求:LANDED 且竖直速度足够小才结束
|
||||
is_landed = str(situation_name).strip().lower() == 'landed'
|
||||
if is_landed and v_down <= (vf_down + float(touchdown_vspeed_tol)):
|
||||
try:
|
||||
vessel.control.throttle = 0.0
|
||||
except Exception:
|
||||
pass
|
||||
vessel.control.throttle = 0.0
|
||||
status['result'] = 'landed'
|
||||
status['logs'].append('检测到 vessel.situation=LANDED 且竖直速度满足软着陆阈值,着陆完成')
|
||||
if verbose:
|
||||
@@ -251,10 +275,7 @@ def auto_land_predictive(bottom_clearance_margin=12, host='localhost', port=5000
|
||||
|
||||
# 兜底:极低高度 + 速度足够小(防止 situation 迟迟不切换导致卡死)
|
||||
if remaining_alt <= max(0.2, float(target_altitude)) and v_down <= (vf_down + float(touchdown_vspeed_tol)):
|
||||
try:
|
||||
vessel.control.throttle = 0.0
|
||||
except Exception:
|
||||
pass
|
||||
vessel.control.throttle = 0.0
|
||||
status['result'] = 'touchdown_pending'
|
||||
status['logs'].append('达到高度/速度阈值,但 vessel.situation 仍未变为 LANDED')
|
||||
if verbose:
|
||||
@@ -295,10 +316,7 @@ def auto_land_predictive(bottom_clearance_margin=12, host='localhost', port=5000
|
||||
if is_landed and v_down > (vf_down + float(touchdown_vspeed_tol)):
|
||||
throttle = max(throttle, 0.8)
|
||||
|
||||
try:
|
||||
vessel.control.throttle = throttle
|
||||
except Exception:
|
||||
pass
|
||||
vessel.control.throttle = throttle
|
||||
|
||||
if verbose:
|
||||
msg = (
|
||||
|
||||
Reference in New Issue
Block a user