Overview · 프로젝트 소개
DM100은 총 발사 질량 100톤 로켓이 상승하고, 약 37 km에서 단을 분리한 뒤, 1단이 원래 발사장으로 돌아와 착륙하는 과정을 계산하는 2차원 개념 시뮬레이션입니다. 비행 궤적만 그리는 데서 나아가 질량·공력·추진 계통·관측 지연·제어·성공 판정을 연결하고, 결과를 로컬 웹 화면에서 확인할 수 있게 만들었습니다.
이 프로젝트의 핵심은 물리적으로 계산한 비행 상태와 명시적인 성공 기준을 함께 다루는 것입니다. 같은 조건으로 실행을 반복할 수 있도록 입력을 고정하고, 성공한 사례뿐 아니라 실패 이유와 연료 잔량도 결과에 남깁니다. 머신러닝 학습 대신 모델 기반 귀환 유도와 PID 계열 자세 피드백 제어를 사용했습니다.
구현은 Python 3.12, NumPy/SciPy, FastAPI/Uvicorn, HTML/CSS/JavaScript, Matplotlib와 FFmpeg로 구성합니다. 계산과 영상 생성은 사용자 컴퓨터에서 수행됩니다.
Problem · 문제 정의
로켓 회수에서는 착륙 위치 하나만 맞추면 충분하지 않습니다. 단 분리 때의 속도와 회전, 변화하는 질량과 관성, 귀환 중 공력, 제동에 필요한 연료, 접지 순간 발의 속도를 함께 만족해야 합니다. 한 항목을 개선하는 제어가 다른 항목의 허용 범위를 넘길 수도 있습니다.
목표를 세 부분으로 나눴습니다.
- 임무 완료: 상승 후 지정 고도와 상태에서 안전하게 단을 분리하고 귀환 절차를 수행하기.
- 비행 안전: 동압·하중·받음각·각속도·각가속도와 구동기 제한을 만족하기.
- 착륙: 원래 발사장에 첫 발이 닿을 때 위치·발의 속도·자세·연료 기준을 만족하기.
계산 오류와 정상적으로 계산된 실패 비행을 구분해 보여줍니다. 입력을 허용했다고 해서 성공을 보장하지 않으며, 실제 결과 상태로 판정합니다.
Approach · 접근 방법
기체를 평면 이동 두 축과 회전 한 축으로 모델링하고, 발사부터 첫 접지까지 하나의 비행 상태로 이어갑니다. 발사장 기준 수평 위치와 고도, 속도, 자세와 각속도에 더해 추진제·구동기·공급 계통·출렁임 상태를 포함한 19개 상태를 적분합니다.
상승 유도는 공기 흐름과 정렬하며 단 분리 조건에 접근합니다. 분리 후에는 저동압 구간의 RCS 자세 전환, 유한 시간 연소를 고려한 귀환 예측, 재진입 전 제동, 수평 정렬, 수직 종말 착륙을 연결합니다. 귀환 예측에는 축약 모델을 쓰고, 성공 여부는 전체 시뮬레이션의 실제 상태로 따로 평가합니다.
기본 물리 적분 간격은 0.010초, 제어 주기는 0.020초입니다. 접지 부근은 사건 검출과 더 작은 적분 간격으로 처리하여 지면을 통과한 뒤 위치를 임의로 보정하는 방식에 의존하지 않습니다.
Architecture · 시스템 구조
운용 입력 · 기체 제원
→ 입력 검증 · 날씨/편차 설정
→ 19상태 물리 환경 ↔ 항법 추정 · 귀환 유도 · 자세 제어
→ 임무 / 비행 안전 / 착륙 판정
→ 비행 기록 · 그래프 · 결과표
→ 저장한 궤적의 선택 MP4 재생
물리 계층은 고도별 대기와 중력, 공기 상대 운동의 힘, 가변 질량·질량중심·관성, 엔진과 착륙 발의 운동을 계산합니다. 계통 계층은 추진제 공급·헬륨 가압·축약 출렁임·단 분리 충격량을 연결합니다. 유도·제어 계층은 관측값에서 명령을 만들고, 결과 계층은 실제 비행 상태를 기준으로 각 요구사항을 평가합니다.
로컬 FastAPI 앱은 입력 검증, 비행 계산 작업, 진행 상태, 결과 조회와 영상 생성 기능을 제공합니다. 비행과 영상은 별도 작업으로 처리하며, 영상 생성 시 기존 궤적을 재사용해 비행 결과가 바뀌지 않게 했습니다.
Design Decisions · 설계 판단
분리 전후의 물리 상태를 보존했습니다. 단 분리 때 선형·각운동량과 기존 내부 운동을 이어받고, 1단 질량중심 기준으로 좌표를 바꿉니다. 분리 직후 속도와 각속도를 0으로 초기화하면 중요한 제어 문제가 사라지므로 기존 운동 상태를 이어받도록 처리했습니다.
추력과 추진제 소비를 같은 공급 유량으로 계산했습니다. 액체 수집 버퍼는 주 추진제의 일부로 취급해 질량을 이중 집계하지 않습니다. 공급이 부족하면 연료 소비와 실제 추력이 함께 감소하고, RCS 추진제가 소진되면 해당 토크를 사용할 수 없습니다.
제어기에 주는 정보와 평가에 쓰는 실제 상태를 구분했습니다. 항법 추정은 지연된 위치·속도 관측, 명령 이력, 공칭 기체 제원과 예보 기본풍을 사용합니다. 숨겨진 실제 바람·추력·관성 편차는 제어기에 직접 제공하지 않습니다. 자세·추진제 등 일부 측정과 안전 인터록에는 이상화된 관측을 가정하며, 그 범위도 명세에 기록했습니다.
첫 발 접지를 착륙 평가 시점으로 정했습니다. 질량중심 속도만으로 판단하면 회전에 따른 발의 운동을 놓칠 수 있어 발의 수직·수평속도를 따로 계산합니다. 접지 이후 안정적으로 서 있는지와 다리의 접촉 강도는 현재 모델의 평가 범위에서 제외했습니다.
Implementation · 구현 과정
- 물리와 보존 관계 구현: 질량 분배와 좌표계를 정의하고 추력·공력·중력·회전 운동을 결합했습니다. 연료 소모와 장치 전개·단 분리에 따른 질량중심과 관성 변화를 반영했습니다.
- 공급·가압·출렁임 연결: 액체 수집과 버퍼, 폐쇄형 헬륨 재고, 재점화 조건과 지연, 비선형 평면 출렁임 모델을 상태에 포함했습니다. 모델 범위를 벗어나면 명시적인 실패로 기록합니다.
- 상승과 회수 제어 구성: 공기 흐름을 고려한 상승, 엔진 종료와 자세 전환, 단 분리 조건 검사, 귀환 연소 예측과 재진입 제동, 종말 착륙을 연결했습니다. 엔진 짐벌·RCS·핀의 명령과 응답 제한을 함께 적용했습니다.
- 조건별 검증 구성: 날씨·기체 편차·관측 및 명령 지연을 입력으로 선언하고, 비행 전 전체 조합을 검증했습니다. 고정 회귀 조건과 결과의 요구사항 통과 여부를 보존합니다.
- 로컬 실험 UI 완성: 영어·한국어 전환, 실행 진행 상태, 궤적·측정값·실패 항목, 선택 영상 생성을 구현했습니다. 폼을 수정해도 이미 계산한 결과의 입력값이 바뀌지 않게 했습니다.
Experiments · 실험과 검증
저장된 최종 검증 기록에는 알려진 조건 286개의 전체 비행 회귀 검사가 있습니다. 비행 성공은 임무 완료·비행 안전·착륙·연료 보존 검사를 모두 통과해야 인정합니다.
| 시험군 | 통과 / 검사 | 해석 |
|---|---|---|
| 개발 조건 | 205 / 205 | 개발 중 사용한 조건의 회귀 검사 |
| 이전 평가 조건 재검사 | 72 / 72 | 이미 관측한 조건의 회귀 검사 |
| 보조 검사 | 9 / 9 | 실제 돌풍 노출 및 적분 간격 절반 조건 |
본 검사 277개와 보조 검사 9개는 구분해 기록합니다. 286/286은 알려진 조건에서의 회귀 결과이며, 새로운 독립 평가나 허용 입력 범위의 모든 조합에 대한 성공률을 의미하지 않습니다.
별도로 v1.0.0 문서는 물리·보존 법칙·유도·성공 판정·로컬 API/UI를 다루는 자동 검사 748개 통과를 보고합니다. 이 수치는 286개 전체 비행과 다른 종류의 검사입니다. 아래 비행 수치는 저장된 실행 결과와 모델 명세를 근거로 정리했습니다.
Results · 결과
286개 회귀 비행에서 관측된 최악값을 선언한 기준과 함께 비교했습니다. 여러 열의 값은 서로 다른 비행에서 나온 극값일 수 있습니다.
| 항목 | 기록된 최악값 | 판정 기준 |
|---|---|---|
| 첫 접지 질량중심 위치 오차 | 0.839 m | 2 m 이하 |
| 발의 수직 / 수평속도 | 1.2551 / 0.202 m/s | 1.5 / 0.5 m/s 이하 |
| 접지 자세 / 각속도 | 0.0212° / 0.0226°/s | 3° / 0.5°/s 이하 |
| 최대 동압 | 28.949 kPa | 30 kPa 이하 |
| 접지 전 최대 각가속도 | 3.780°/s² | 5°/s² 이하 |
| 최소 잔여 주 / RCS 추진제 | 2,958 / 95.875 kg | 주 추진제 양수 / RCS 비음수 |
극값은 README의 보수적 반올림을 사용했습니다. 기록된 로컬 UI 무풍 비행은 405.709초에 첫 접지했고, 발의 수직속도 1.005 m/s, 잔여 주 추진제 5,796 kg, 잔여 RCS 추진제 262.546 kg을 기록했습니다. 아래 그림은 그 비행의 실제 저장 궤적과 계산값입니다.

성과는 발사·분리·회수를 끝까지 연결한 계산 모델, 반복 가능한 입력과 판정, 그리고 사람이 결과를 탐색할 수 있는 실험 화면을 갖춘 점입니다.
Failure Analysis · 실패 분석과 한계
비행 실패는 입력 오류·프로그램 실행 오류와 구분하며, 공급 부족, 계통·출렁임 모델 범위 초과, 안전 요구사항 위반, 착륙 기준 미달 등을 결과에 남깁니다. 기록된 최종 회귀 시험군에는 실패가 없지만, 이 사실만으로 이전 개발 과정의 실패나 임의의 새 조건에 대한 성공을 주장하지 않습니다.
검증 범위에도 명확한 경계가 있습니다. 현재 모델은 2차원 평면 이동과 회전이며 3차원 6자유도 모델이 아닙니다. 2단의 500 kg 탑재체·700 km 원궤도 도달은 가정이고, 2단 비행을 직접 적분하거나 궤도 진입을 검증하지 않았습니다. 연속 스로틀, 축약 공급·공력 모델, 일부 이상적인 측정에도 가정이 있습니다.
실물 부품 보정, 접촉 강도, 접지 후 안정 기립, 열·피로·진동과 실제 비행 인증은 다루지 않습니다. 이 작업에서 얻은 설계 관점은 좋은 궤적과 신뢰할 수 있는 검증은 별개의 산출물이라는 점입니다. 이후 평가를 확장한다면 새로운 조건을 사전에 분리하고, 모델 정밀도와 관측 가정의 영향을 함께 확인할 수 있습니다.
Demo · 시연
로컬 UI에서 날씨와 정상 기체 편차를 선택하고 비행을 실행하면, 임무·안전·착륙 판정과 그래프·측정값·실패 항목을 확인할 수 있습니다. 성공한 비행은 저장된 기록으로 MP4를 선택 생성할 수 있습니다.

이 영상은 짧은 단 분리 시연입니다. 전체 발사·귀환·착륙 검증은 위 비행 기록과 그래프를 기준으로 확인할 수 있습니다. 영상의 2단 이동은 시각적 연출이며 궤도 계산 결과가 아닙니다.
직접 실행하려면 Python 3.12 환경에서 저장소의 README에 따라 설치한 뒤 python -m powered_landing_guidance.local_app을 실행합니다. 계산과 영상 생성은 로컬에서 수행하며, 영상 생성은 비행 계산보다 시간이 더 걸릴 수 있습니다.
Source Code · 소스코드와 재현 자료
회귀 실행기는 과거 로컬 산출물이 없어도 선언된 입력으로 다시 실행할 수 있도록 구성했습니다. 결과 해석은 저장소의 모델 가정과 시험군 구성을 함께 읽는 것을 전제로 합니다.
View Full Source on GitHub

