Files
KSP_project/scripts/guanghan_windows.py
T
ArmorandClaude 34072782ba chore: add project scripts, handover docs, and format guide
- guanghan_windows.py: Windows launcher script
- inject_lightbox: lightbox injection utilities
- handover docs: future missions proposal, vehicle creation guide, format guide

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-17 14:48:20 +08:00

101 lines
3.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python
"""广寒计划发射窗口计算
广寒基地往返标准 LLO,每月有 2 个标准窗口。
地月转移耗时 5 天。给定任意时间,计算最近的地球出发发射窗口
及对应的月球着陆窗口。
"""
import math
import sys
from datetime import datetime, timedelta, timezone
MOON_PERIOD = timedelta(days=27.32166) # 月球自转周期
TRANSIT_DAYS = timedelta(days=5) # 地月转移耗时
# 参考着陆窗口(UTC)—— 发射窗口 = 着陆窗口 − 5 天地月转移
# 基于 2024 年 10 月精确窗口校准
REF_LANDING_A = datetime(2024, 10, 21, 4, 55, tzinfo=timezone.utc)
REF_LANDING_B = datetime(2024, 10, 29, 3, 15, tzinfo=timezone.utc)
REF_LAUNCH_A = REF_LANDING_A - TRANSIT_DAYS
REF_LAUNCH_B = REF_LANDING_B - TRANSIT_DAYS
def parse_dt(s: str) -> datetime:
"""解析用户输入的日期时间字符串,自动补全缺失部分。"""
s = s.strip()
formats = [
"%Y-%m-%d %H:%M",
"%Y-%m-%d %H",
"%Y-%m-%d",
"%Y/%m/%d %H:%M",
"%Y/%m/%d %H",
"%Y/%m/%d",
]
for fmt in formats:
try:
return datetime.strptime(s, fmt).replace(tzinfo=timezone.utc)
except ValueError:
continue
raise ValueError(f"无法解析日期: {s}(支持格式: YYYY-MM-DD HH:MM 或 YYYY/MM/DD")
def next_occurrences(ref: datetime, period: timedelta, after: datetime, count: int = 3):
"""计算从 after 之后最近的 count 个窗口(以 ref 为相位零点)。"""
n = math.floor((after - ref) / period) # 已完成周期数(floor确保负数时正确)
results = []
for i in range(1, count + 1):
results.append(ref + (n + i) * period)
return results
def guanghan_windows(target: datetime, count: int = 4):
"""返回最近 count 个广寒发射/着陆窗口。
以着陆窗口为相位零点,发射窗口 = 着陆窗口 − 5 天地月转移。
"""
landing_a = next_occurrences(REF_LANDING_A, MOON_PERIOD, target, count)
landing_b = next_occurrences(REF_LANDING_B, MOON_PERIOD, target, count)
# 合并着陆窗口,去重排序
all_landings = sorted(set(landing_a + landing_b))
lines = []
lines.append(f"查询时间: {target.strftime('%Y-%m-%d %H:%M UTC')}")
lines.append(f"参考着陆窗 A: {REF_LANDING_A.strftime('%Y-%m-%d %H:%M UTC')}")
lines.append(f"参考着陆窗 B: {REF_LANDING_B.strftime('%Y-%m-%d %H:%M UTC')}")
lines.append(f"月球周期: {MOON_PERIOD.days}.{MOON_PERIOD.seconds/3600:.2f} 天")
lines.append(f"地月转移: 5 天")
lines.append("")
header = f"{'#':<4} {'发射 (UTC)':<22} {'着陆 (UTC)':<22} {'距现在':>10}"
lines.append(header)
lines.append("-" * len(header))
for i, landing in enumerate(all_landings[:count], 1):
launch = landing - TRANSIT_DAYS
delta = launch - target
if delta.days >= 0:
delta_str = f"{delta.days}d {delta.seconds // 3600}h"
else:
delta_str = f"已过"
lines.append(f"{i:<4} {launch.strftime('%Y-%m-%d %H:%M'):<22} {landing.strftime('%Y-%m-%d %H:%M'):<22} {delta_str:>10}")
return "\n".join(lines)
def main():
if len(sys.argv) < 2:
print("用法: python guanghan_windows.py <日期时间>")
print("示例: python guanghan_windows.py '2024-07-20'")
print(" python guanghan_windows.py '2024-08-15 12:00'")
sys.exit(1)
target = parse_dt(sys.argv[1])
print(guanghan_windows(target))
if __name__ == "__main__":
main()