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>
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
#!/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()
|
||||
Reference in New Issue
Block a user