Flight 객체 생성부터 이어서 진행해보겠습니다. 마지막에는 AI로 1일차와 2일차 공부한 내용을 표로 간단하게 정리해봤습니다. 다른 게시물에서 실제 실행까지 해보겠습니다.

바로가기: 수치 확인 · 그래프 확인 · 데이터 활용 · 추가 분석 · 1·2일차 요약표

1. Flight 객체 생성

이를 위해선 앞 서 정의한 로켓이 발사될 환경과 로켓 자체를 구체적으로 명시해야 합니다. 또한 발사 레일의 길이, 발사 레일의 경사각, 발사 레일의 진행 방향도 지정해야 합니다.

test_flight = Flight(
    rocket=calisto, environment=env, rail_length=5.2, inclination=85, heading=0
    )

모든 시뮬레이션 정보는 test_flight 객체에 저장됩니다.

RocketPy에는 시뮬레이션 결과를 확인할 수 있는 두 개의 하위 모듈인 prints와 plots이 있습니다. 각 클래스는 prints와 plots 하위 모듈을 속성으로 가져옵니다. 예시로 Flight 객체의 prints 하위 모듈에 접근하려면 test_flight.prints을 사용할 수 있습니다.

또한 각 클래스에는 앞서 사용했던 test_flight.all_info()나 test_flight.info() 같은 모든 정보에 빠르게 접근할 수 있는 고유한 메서드가 존재합니다.

아래에 소개할 메서드는 모두 all_info나 info()로도 볼 수 있는 결과입니다.

2. 비행 수치 확인 — prints

시뮬레이션의 초기 조건을 확인하는 것부터 시작하는 것이 좋다. 이를 통해 점화 시점의 로켓 상태를 확인할 수 있다.

test_flight.prints.initial_conditions()

또한 발사 장소의 지표면 풍향과 발사대 상태를 확인하는 것도 중요합니다.

test_flight.prints.surface_wind_conditions()

test_flight.prints.launch_rail_conditions()

초기 조건을 확인한 후에는 비행의 처음 중요한 순간인 레일 이탈 상태에서의 조건을 확인할 수 있습니다. 이 시점부터 로켓은 자유롭게 비행하기 시작합니다.

test_flight.prints.out_of_rail_conditions()

다음으로 엔진 연소가 멈추는 시점, 즉 연소 종료 시점을 확인할 수 있습니다. 이 시점부터 로켓은 추진력 없이 비행하게 됩니다.

test_flight.prints.burn_out_conditions()

로켓이 최고 고도에 도달하는 순간인 원지점 조건도 확인할 수 있습니다. 원지점은 해발 고도(ASL)와 지상 고도(AGL) 두 가지 형식으로 표시됩니다.

test_flight.prints.burn_out_conditions()

낙하산이 펼쳐졌는지 확인하려면 다음 방법을 사용할 수 있습니다.

test_flight.prints.events_registered()

시뮬레이션 종료 시점, 특히 충돌 시점의 상황을 이해하기 위해 다음을 사용할 수 있습니다.

test_flight.prints.impact_conditions()

마지막으로 prints.maximum_values()는 비행 중 기록된 다양한 매개변수의 최대값을 요약하여 보여줍니다.

test_flight.prints.maximum_values()

3. 비행 그래프 확인 — plots

test_flight.plot() 모듈을 사용하면 시뮬레이션의 다양한 결과를 확인할 수 있습니다. 예를 들어 로켓의 궤적을 그래프로 나타낼 수 있습니다. 또한 여러 데이터를 동시에 그래프로 표시할 수도 있습니다.

test_flight.plots.trajectory_3d()

다음 방법을 사용하여 3방향의 속도와 가속도를 구할 수 있습니다. 이 그래프에 사용된 기준 좌표계는 절대 좌표계이며, 이는 발사 지점의 기준 좌표계입니다. 모터 연소가 멈추면 가속도가 급격히 감소할 수 있습니다.

로켓의 각위치에 대한 세 가지 매개변수를 그래프로 나타낼 수 있습니다.

  1. Flight Path Angle : 로켓의 속도 벡터와 수평면 사이의 각도. 로켓이 똑바로 위로 올라갈 때 90°이고 로켓이 수평으로 회전할 때 0°
  2. Attitude Angle : 로켓 축과 수평명 사이의 각도
  3. Lateral Attitude Angle : 로켓의 축과 발사 레일을 포함하는 수직면 사이의 각도. 이 각도가 클수록 로켓의 원래 진행 방향에서 벗어나는 정도가 커짐

로켓이 안정적인 상태라면 Flight Path Angle와 Attitude Angle는 서로 비슷해야 합니다.

test_flight.plots.linear_kinematics_data()

test_flight.plots.flight_path_angle_data()

RocketPy에서 로켓의 방향은 오일러 매개변수, 또는 쿼터니언을 통해 결정됩니다. 또한 RocketPy는 쿼터니언을 사용하여 오일러 각도(세차 운동, 장동 운동 및 자전)와 그 변화를 계산합니다. 이러한 모든 정보는 다음 메서드를 통해 접근할 수 있습니다.

test_flight.plots.attitude_data()

로켓의 안정성을 확인하는 데에는 각속도와 각가속도가 특히 중요합니다. 예를 들어, 엔진 연소가 멈추면 각속도와 각가속도가 급격하게 변할 수 있습니다.

test_flight.plots.angular_kinematics_data()

로켓의 비행 거동을 점거하는 데에는 공기역학적 힘과 모멘트 또한 중요합니다. 즉 항력(축 방향)과 양력뿐만 아니라 굽힘 모멘트와 회전 모멘트도 고려됩니다. 양력은 항력에 수직인 두 방향으로 분해됩니다.

test_flight.plots.aerodynamic_forces()

RocketPy는 로켓이 레일을 떠나기 전에 레일 버튼에 가해지는 힘을 그래프로 나타낼 수 있습니다. 이 정보는 레일 버튼과 발사 레일을 설께할 때 유용할 수 있습니다.

test_flight.plots.rail_buttons_forces()

RocketPy는 비행 중 로켓의 운동 에너지와 위치 에너지뿐만 아니라 추력과 항력도 계산합니다.

test_flight.plots.energy_data()

RocketPy는 마하수 레이놀즈 수, 로켓이 받는 총압력 및 동압력, 그리고 로켓의 받음각을 계산하며 이 모든 값은 다음 방법을 통해 얻을 수 있습니다.

test_flight.plots.fluid_mechanics_data()

로켓의 주파수 응답과 함께 안정성 여유를 확인 할 수 있습니다.

test_flight.plots.stability_and_control_data()

4. 결과 데이터 활용

KML로 궤적 내보내기

궤적을 .kml 파일로 내보내면 Google Earth에서 시각화 할 수 있습니다.

from rocketpy.simulation import FlightDataExporter

FlightDataExporter(test_flight).export_kml(
    file_name="trajectory.kml",
    extrude=True,
    altitude_mode="relativetoground",
)

아마 Google Earth 말고 3D 지도를 가져오는 js 라이브러리 등 다른 방식으로도 가능할 것 같습니다. 이 문서에서 KML에 대해 자세히 확인할 수 있습니다.

rocketpy.simulation.flight_data_exporter.FlightDataExporter.export_kml()을 사용할 수 있습니다.

속도 그래프와 원본 데이터 조회

결과를 확인하는 방법도 여러 가지가 있습니다. 첫번째 낙하산이 펼쳐질 때까지 로켓의 속도를 그래프로 나타낼 수 있습니다.

test_flight.speed.plot(0, test_flight.apogee_time)

또는 전체 비행의 속도 배열을 가져 올 수 있습니다. [[time, speed], ...]

test_flight.speed.source

Flight 객체는 시뮬레이션의 모든 결과를 담고 있는 여러 속성을 가지고 있습니다. 자세히 공부하려면이 문서와 이 문서, 이 문서를 보면 됩니다.

CSV 저장과 샘플링 간격

rocketpy.simulation.flight_data_exporter.FlightDataExporter.export_data() API를 사용해서 RocketPy의 시뮬레이션 결과에서 선택한 비행 속성을 CSV로 내보낼 수 있습니다.

from rocketpy.simulation import FlightDataExporter

exporter = FlightDataExporter(test_flight)
exporter.export_data(
    "calisto_flight_data.csv",
    "angle_of_attack",
    "mach_number",
)

import pandas as pd

pd.read_csv("calisto_flight_data.csv")

다른 샘플링 속도로 데이터를 내보내려면 time_step 인수를 사용할 수 있습니다. 이 기능은 동일한 데이터를 1초 간격으로 샘플링하여 내보냅니다. 비행 데이터는 새로운 샘플링 속도에 맞춰 보간됩니다.

exporter.export_data(
    "calisto_flight_data.csv",
    "angle_of_attack",
    "mach_number",
    time_step=1.0,
)

pd.read_csv("calisto_flight_data.csv")

FlightDataExporter.export_data는 속성 이름을 전달하지 않고 전체 비행 솔류션을 내보내는 편리한 방법도 제공합니다. 참고

5. 그림·그래프 저장

RocketPy에서 생성된 그래프와 그림을 저장할 수 도 있습니다. 다음은 로켓 글림을 .png로 저장하는 예제입니다.

calisto.draw(filename="calisto_drawing.png")

특정 RocketPy 그래프를 저장하고 싶다면 rocketpy.Function 타입의 모든 RocketPy 속성은 해당 그래프를 이미지 파일로 저장하게 합니다. 예를 들어 로켓의 속도 그래프와 궤적 그래프를 .jpg로 저장할 수 있습니다.

test_flight.speed.plot(filename="speed_plot.jpg")
test_flight.plots.trajectory_3d(filename="trajectory_plot.jpg")

.eps, .jpg, .jpeg, .pdf, .pgf, .png, .ps, .raw, .rgba, .svg, .svgz, .tif, .tiff, .webp 를 지원합니다.

filename 인수는 선택 사항입니다.

6. 추가 분석

시뮬레이션 결과를 활용하면 다양한 분석을 수행할 수 있습니다. 몬테 카를로 시뮬레이션도 가능합니다.

아래는 여러 분석에 대한 코드만 첨부하겠습니다.

질량에 따른 최고고도·레일 이탈 속도

# Apogee as a Function of Mass
from rocketpy.utilities import apogee_by_mass

apogee_by_mass(
    flight=test_flight, min_mass=5, max_mass=20, points=10, plot=True
    )

# Out of Rail Speed as a Function of Mass
from rocketpy.utilities import liftoff_speed_by_mass

liftoff_speed_by_mass(
    flight=test_flight, min_mass=5, max_mass=20, points=10, plot=True
    )

핀 위치에 따른 동적 안정성 비교

# Dynamic Stability Analysis
# Helper class
from rocketpy import Function
import copy

# Prepare a copy of the rocket
calisto2 = copy.deepcopy(calisto)

# Prepare Environment Class
custom_env = Environment()
custom_env.set_atmospheric_model(type="custom_atmosphere", wind_v=-5)

# Simulate Different Static Margins by Varying Fin Position
simulation_results = []

for factor in [-0.5, -0.2, 0.1, 0.4, 0.7]:
    # Modify rocket fin set by removing previous one and adding new one
    calisto2.aerodynamic_surfaces.pop(-1)

    fin_set = calisto2.add_trapezoidal_fins(
        n=4,
        root_chord=0.120,
        tip_chord=0.040,
        span=0.100,
        position=-1.04956 * factor,
    )
    # Simulate
    test_flight = Flight(
        rocket=calisto2,
        environment=custom_env,
        rail_length=5.2,
        inclination=90,
        heading=0,
        max_time_step=0.01,
        max_time=5,
        terminate_on_apogee=True,
        verbose=False,
    )
    # Store Results
    static_margin_at_ignition = calisto2.static_margin(0)
    static_margin_at_out_of_rail = calisto2.static_margin(test_flight.out_of_rail_time)
    static_margin_at_steady_state = calisto2.static_margin(test_flight.t_final)
    simulation_results += [
        (
            test_flight.attitude_angle,
            "{:1.2f} c | {:1.2f} c | {:1.2f} c".format(
                static_margin_at_ignition,
                static_margin_at_out_of_rail,
                static_margin_at_steady_state,
            ),
        )
    ]

Function.compare_plots(
    simulation_results,
    lower=0,
    upper=1.5,
    xlabel="Time (s)",
    ylabel="Attitude Angle (deg)",
)

1·2일차 전체 내용 요약표

두 글에서 다룬 함수·메서드·속성·입력값과 중간의 팁을 주제별로 정리했습니다.

수치는 본문의 예시값이며, 실제 기체의 권장 설계값을 뜻하지 않습니다.

  • [보충]: 의미를 명확히 하기 위한 설명.
  • [정정]: 본문의 오타 또는 코드와 설명의 불일치를 바로잡은 내용.
  • [코드 대조]: 두 글의 코드 흐름을 연결해 확인한 주의점.

API 관련 정정·보충은 2026-10-04에 확인한 RocketPy 1.13.0 공식 문서·구현을 기준으로 하며, 본문에서 아직 공부하지 않은 내용은 마지막 표에 따로 남겼습니다.

요약표 바로가기

화면이 좁으면 표를 좌우로 스크롤해 볼 수 있습니다.

01. 전체 흐름과 클래스

단계 클래스·도구 하는 일 / 다음 단계와의 관계
공부 목적 OpenRocket → RocketPy 기반 GUI OpenRocket을 사용하던 동아리에서 더 상세한 시뮬레이션을 다루기 위해 RocketPy를 학습하고, 코드 입력을 돕는 GUI를 만들려는 계획. Python 및 MATLAB 연동이 언급됨.
1. 환경 정의 Environment 발사 위치·날짜·날씨·바람을 저장. 환경 설정, 대기 모델.
2. 모터 정의 Motor 계열 고체 SolidMotor, 하이브리드 HybridMotor, 액체 LiquidMotor. 두 글에서는 고체 모터만 상세히 다룸. 모터 입력값.
3. 로켓 뼈대 정의 Rocket 모터를 제외한 기체의 질량·관성·반지름·항력 곡선을 입력. 기체와 항력.
4. 로켓 조립 add_motor() → 공력 부품 → 낙하산 → 레일 버튼 모터 객체를 먼저 만들고 로켓에 연결. 공력 부품은 추가 메서드에서 생성과 부착을 함께 할 수 있음. 공력 부품, 낙하산, 레일.
5. 조립 검토 draw(), plots.static_margin(), all_info() 부품 위치·정적 여유·전체 정보를 확인한 뒤 시뮬레이션. 안정성, 관성.
6. 비행 실행 Flight 환경과 조립한 로켓, 발사 레일 조건을 받아 시뮬레이션을 실행하고 결과를 저장. 실행 인수.
7. 결과 확인 prints, plots, info(), all_info() 수치·그래프·주요 사건을 확인. 수치, 그래프, 해석 팁.
8. 저장·추가 분석 FlightDataExporter, Function, rocketpy.utilities CSV·KML·이미지 저장, 질량 변화 및 동적 안정성 비교. 내보내기, 그림 저장, 질량 분석, 동적 분석.
기본 import from rocketpy import Environment, SolidMotor, Rocket, Flight 필요할 때 Function, from rocketpy.simulation import FlightDataExporter, apogee_by_mass, liftoff_speed_by_mass를 추가로 불러옴.

02. 발사 위치·날짜·날씨 확인

함수·입력값 본문 예시 / 사용 형태 의미·주의점
Environment(...) env = Environment(latitude=35.5721, longitude=129.1822, elevation=53) 본문에서 사용한 UNIST 위치 예시. 단위는 위도·경도 °, 고도 m.
latitude, longitude 35.5721, 129.1822 발사 장소의 위도와 경도.
elevation 53 발사 장소의 해발 고도(ASL). 지면으로부터의 높이(AGL)와 구분.
import datetime datetime.date.today() + datetime.timedelta(days=1) 내일 날짜 계산. [정정] 본문의 datetime.data.today()는 datetime.date.today(). days=1은 하루를 더한다는 뜻.
env.set_date(...) env.set_date((tomorrow.year, tomorrow.month, tomorrow.day, hour_in_UTC_time)) [정정] env.set_data()가 아니라 set_date(). 날짜 튜플은 (년, 월, 일, 시)의 4개 값이며 hour_in_UTC_time을 먼저 정해야 함.
생성자의 date date=datetime.datetime.now(datetime.timezone.utc) [정정·보충] import datetime 방식에 맞춘 현재 UTC 시각. date를 넣는 것만으로 GFS가 선택되는 것은 아니므로 대기 모델도 설정.
날짜의 시간대 기본 UTC [보충] 한국 시각을 직접 넣는다면 timezone="Asia/Seoul"을 명시하거나 UTC로 변환. 시간대 없는 현지 시각을 UTC로 오해하지 않도록 주의.
env.set_atmospheric_model(...) type="forecast", file="GFS" 대기 모델을 선택하고 자료를 반영. 반환값은 None. [정정] 본문 설명의 set_atmosperic_model 철자에 주의.
env.info() 괄호를 붙여 호출 날씨 정보와 플롯 확인. [정정] env.info만 적으면 메서드 참조일 뿐 실행되지 않음.

날짜·시간대와 메서드 표기는 Environment 공식 문서 및 첫 시뮬레이션 예제와 대조했습니다.

03. 대기 모델 선택과 데이터 소스

type file에 넣는 값 dictionary / 기억할 점
"standard_atmosphere" 사용하지 않음 국제표준대기(ISA). dictionary도 사용하지 않음.
"custom_atmosphere" 사용하지 않음 pressure, temperature, wind_u, wind_v를 직접 지정. dictionary도 사용하지 않음.
"wyoming_sounding" 와이오밍 대학교 관측 텍스트 페이지 URL dictionary는 사용하지 않음. 본문에서는 포항·오산·제주 고산·흑산도 등의 관측 지점을 언급하며, 포항 STNM=47138, 2026-10-02 12 UTC 자료 URL을 예시로 사용. 관측 지점·시각을 확인.
"windy" "ECMWF", "GFS", "ICON", "ICONEU" dictionary는 사용하지 않음.
"forecast" 로컬 파일 경로, OPeNDAP URL, 열린 netCDF4.Dataset, 또는 "AIGFS", "GFS", "NAM", "RAP", "HRRR", "HIRESW" 사용자 변수명 매핑 딕셔너리 또는 파일 구조에 맞는 내장 매핑 사용. 단축어는 최신 예보를 가져오는 용도.
"reanalysis" 로컬 파일 경로, OPeNDAP URL, 열린 netCDF4.Dataset 과거 대기 상태의 재해석 자료. 사용자 매핑 또는 내장 매핑 사용.
"ensemble" 로컬 파일 경로, OPeNDAP URL, 열린 netCDF4.Dataset, 또는 "GEFS" 앙상블 예보. 사용자 매핑 또는 내장 매핑 사용.
공통 type 규칙 문자열, 대소문자 구분 없음 file과 dictionary의 의미는 선택한 type에 따라 달라짐.
dictionary dict 또는 str netCDF 변수명을 RocketPy의 표준 이름에 대응시킴. 본문 내장 매핑 예: "ECMWF", "GFS", "MERRA2", "RAP", "HRRR".
국내 자료 활용 GFS / 관측 사운딩 / 현장 측정·기상청 자료 현장 자료는 custom_atmosphere 입력으로 정리할 수 있음. LDAPS·RDAPS로 대체하는 방안은 본문의 검토 아이디어이며 연동 방법은 아직 확인하지 않음.

04. 대기 프로필의 입력 형식·단위·바람 부호

매개변수 의미·단위 생략 시 / 본문 팁
pressure 고도에 따른 기압, Pa 사용자 대기에서 생략하면 ISA 기압 사용.
temperature 고도에 따른 온도, K 생략하면 ISA 온도 사용. 20℃는 293.15 K.
wind_u 동서 방향 풍속, m/s. 동쪽으로 이동하면 양수 생략하면 0. 서쪽에서 불어오는 서풍의 성분이 양수.
wind_v 남북 방향 풍속, m/s. 북쪽으로 이동하면 양수 생략하면 0. 남쪽에서 불어오는 남풍의 성분이 양수.
북서풍 4 m/s 예시 wind_u=2.83, wind_v=-2.83 남동쪽으로 이동하므로 동(+), 남(-). 각 성분 크기는 4 × cos(45°) ≈ 2.83.
상수로 입력한 날씨 temperature=293.15, wind_u=2.83, wind_v=-2.83 [보충] 지상에서 측정한 값을 상수로 넣으면 전 고도에 같은 값을 적용하는 가정이 됨.
pressure_conversion_factor 외부 기압 단위를 Pa로 환산 forecast, reanalysis, ensemble에 사용. "mbar", "hPa", "Pa" 또는 사용자 단위의 양의 정수·실수 계수.
변환 계수 None 기본값, 모델 이름에서 단위 자동 감지 본문 예: ERA5/ECMWF/MERRA2 재해석은 주로 hPa, 온라인 GFS/NAM/RAP/HRRR은 주로 Pa. 감지되지 않으면 파일의 단위 속성을 확인하는 흐름.
네 프로필에 공통으로 가능한 형식 데이터 형태 주의점
float 하나의 상수 고도와 무관한 일정한 값.
string CSV 파일 경로 헤더 최대 1줄, 2열. 1열은 해발 기하학적 고도(m), 2열은 해당 기압·온도·풍속 값.
array [(고도, 값), ...] 형태의 리스트 또는 NumPy 2차원 배열 고도는 m, 값의 단위는 각각 Pa / K / m/s.
callable 고도 하나를 받아 해당 값을 반환하는 함수 입력 고도 역시 ASL m. 낙하산 트리거의 AGL 높이와 혼동하지 않기.

05. 고체 모터의 가정과 SolidMotor 입력값

구분 핵심 내용 기억할 점
모터 종류 rocketpy.SolidMotor, rocketpy.HybridMotor, rocketpy.LiquidMotor 전체 조립·비행 흐름은 공통. 하이브리드·액체 모터 상세는 후속 학습.
형상 가정 가운데 구멍이 뚫린 원통형 BATES 그레인 이 형상을 기준으로 추진제 소모와 질량 중심 이동을 계산.
배기 가정 연소 중 배기 속도·비추력이 일정 본문 해석: F(t) = ṁ(t) × ve에서 ve를 상수로 두어 질량 변화를 계산. 세부 구현 확인은 후속 학습으로 남겨 둠.
추력 곡선 시간에 따른 추력 F(t) .eng(RASP), .rse(RockSim), .csv, 상수 또는 함수 입력을 본문에서 소개. 상세 추력 소스 문서는 아직 미학습.
매개변수 본문 예시값 의미·단위 / 주의점
thrust_source "../data/motors/cesaroni/Cesaroni_M1670.eng" 추력 데이터. 실행 위치에서 상대 경로가 실제 파일을 가리켜야 함.
dry_mass 1.815 추진제를 제외한 모터 케이스·노즐 등의 질량, kg. 기체의 mass와 구분.
dry_inertia (0.125, 0.125, 0.002) (I11, I22, I33), kg·m². 모터 건조 질량 중심 기준이며 좌표계 원점 기준이 아님.
nozzle_radius 33 / 1000 = 0.033 노즐 출구 반지름, m.
throat_radius 11 / 1000 = 0.011 노즐 목의 반지름, m.
grain_number 5 그레인 개수.
grain_density 1815 추진제 밀도, kg/m³.
grain_outer_radius 33 / 1000 = 0.033 그레인 바깥 반지름, m. 본문의 “외경”이라는 표현과 구분.
grain_initial_inner_radius 15 / 1000 = 0.015 초기 구멍 반지름, m. 본문의 “내경”이라는 표현과 구분.
grain_initial_height 120 / 1000 = 0.120 그레인 초기 높이, m.
grain_separation 5 / 1000 = 0.005 그레인 사이 간격, m.
grains_center_of_mass_position 0.397 모터 좌표계에서 추진제 전체 질량 중심 위치, m.
center_of_dry_mass_position 0.317 모터 좌표계에서 모터 건조 질량 중심 위치, m.
nozzle_position 0 모터 좌표계에서 노즐 출구 위치, m.
burn_time 3.9 예제의 연소 시간, s.
coordinate_system_orientation "nozzle_to_combustion_chamber" 모터 좌표의 양의 방향을 노즐 → 연소실로 지정. 로켓 좌표계와 별도로 정의.
example_solid.info() 텍스트 중심 요약 모터 입력과 계산된 정보를 확인.
example_solid.all_info() 전체 정보 확인 텍스트·그림·플롯을 함께 확인.

06. Rocket 뼈대와 항력 곡선

매개변수 본문 예시값 의미·주의점
radius 127 / 2000 = 0.0635 m 로켓 반지름. 직경 127 mm를 반지름 m로 바꾼 값.
mass 14.426 kg 모터 전체를 제외한 기체 질량. 모터 건조 질량이나 추진제를 중복해서 더하지 않기.
inertia (6.321, 6.321, 0.034) kg·m² 모터 없는 기체의 질량 중심 기준 (I11, I22, I33).
6개 관성 성분 (I11, I22, I33, I12, I13, I23) 비대칭 기체 등의 관성곱까지 입력할 때 사용.
power_off_drag "../data/rockets/calisto/powerOffDragCurve.csv" 모터가 꺼져 있을 때의 항력 계수 곡선.
power_on_drag "../data/rockets/calisto/powerOnDragCurve.csv" 모터가 작동 중일 때의 항력 계수 곡선.
center_of_mass_without_motor 0 로켓 좌표계에서 모터 없는 기체의 질량 중심 위치.
coordinate_system_orientation "tail_to_nose" 로켓 좌표의 양의 방향이 꼬리 → 노즈. 부품의 position 부호를 이 기준에 맞춤.
항력 관련 항목 정리 본문 팁·범위
두 곡선을 나누는 이유 배기가스가 기체 후방 유동과 항력에 영향을 줌 본문은 모터 작동 중 항력 계수가 더 낮아지는 경우를 설명.
작동 중 곡선이 없는 경우 두 인수에 동일한 항력 곡선을 사용할 수 있음 동일하게 취급하는 가정임을 기억.
CSV 입력 1열 마하수, 2열 항력 계수 Cd 본문 예시는 마하 0.0–1.0의 데이터. 0.0 → 0.0, 0.5 → 0.38118499, 1.0 → 0.62744566 등. 전체 숫자열은 1일차 원문 CSV에 있음.
함수 입력 마하수를 받아 항력 계수를 반환하는 함수 파일 경로 대신 함수로도 곡선 정의 가능.
더 정밀한 항력 자료 CFD 또는 풍동 데이터 본문에서 정밀한 곡선을 얻기 위한 방법으로 소개.
대안 도구 RASAero II 로켓 형상을 정의한 뒤 AeroPlots에서 확인하는 방법을 소개. PyRASAero는 후속 조사 대상으로만 언급.

07. 모터·노즈콘·날개·보트테일 추가

메서드 본문 입력값 역할·주의점
calisto.add_motor(...) example_solid, position=-1.255 만들어 둔 모터를 기체에 추가. [정정] 앞에서 생성한 변수는 example_solid이므로 본문의 example_motor와 이름을 맞춰야 함.
calisto.add_nose(...) length=0.55829, kind="von karman", position=1.278 노즈콘 생성·추가. 길이와 위치는 m. [보충] 위치 기준점은 노즈 끝.
calisto.add_trapezoidal_fins(...) n=4, root_chord=0.120, tip_chord=0.060, span=0.110 사다리꼴 날개 세트. 개수, 뿌리 시위·끝 시위·스팬(m)을 지정. 반환된 날개 세트를 fin_set에 저장.
날개 위치·기울기 position=-1.04956, cant_angle=0.5 위치 m, 캔트각 °. [보충] 위치 기준점은 날개 뿌리 시위의 앞전.
날개 단면 지정 airfoil=("../data/airfoils/NACA0012-radians.txt", "radians") 받음각별 양력 계수 데이터와 각도 단위를 전달.
Rocket.add_elliptical_fins(...) 본문에서는 airfoil 옵션만 소개 타원형 날개 추가. [정정] 사다리꼴 메서드 철자는 add_trapezoidal_fins; add_trapezolidal_fins가 아님.
calisto.add_tail(...) top_radius=0.0635, bottom_radius=0.0435, length=0.060, position=-1.194656 보트테일·직경 변화 부품 추가. 치수와 위치는 m. [보충] 위치 기준점은 노즈 쪽 끝.
Rocket.add_surfaces(...) 본문에서 좌표 참고 링크로 소개 이미 정의한 공력 부품을 추가하는 일반 메서드. 개별 부품의 기준점을 확인하는 데 참고.
calisto.draw() 조립한 로켓 그림 부품 배치가 의도한 형상과 맞는지 확인. 모터·부품의 기준점과 좌표 방향을 혼동하지 않기.

부품 기준점에 대한 보충은 좌표계 안내와 Rocket API를 참고했습니다.

airfoil 항목 데이터 형식 기억할 점
None 별도의 단면 데이터 없음 핀을 평판으로 취급.
(path, units) 데이터 파일 경로 + "radians" 또는 "degrees" 파일 첫 열의 각도 단위와 units가 일치해야 함.
데이터 열 1열 받음각, 2열 양력 계수 Cl 기체 항력 파일의 (Mach, Cd)와 구분. 단면 형상 좌표 (x, y)를 그대로 넣는 데이터가 아님.
본문 CSV 예 받음각 0–0.20943951 rad, 해당 Cl 값 예: 0 → 0, 0.017453293 → 0.11, 0.157079633 → 0.8527. 전체 숫자열은 1일차 원문 CSV에 있음.
데이터 참고처 Airfoil Tools 본문에서 소개한 자료 출처. 사용할 파일이 받음각·양력 계수 데이터인지 확인.

08. 낙하산 추가와 예제 설정

calisto.add_parachute(...) 인수 Main 예시 Drogue 예시 의미·주의점
name "Main" "Drogue" 결과에서 구분할 이름. 반환된 객체를 각각 main, drogue에 저장.
cd_s 10.0 1.0 항력 계수 × 기준 면적, Cd × S, 단위 m².
trigger 800 "apogee" 하강 중 AGL 800 m 조건 / 최고점 이후 하강 시작 조건. 실제 완전 전개 시각은 lag만큼 늦음.
sampling_rate 105 105 센서·트리거 확인 빈도, Hz. [보충] 확인 간격은 1/105 s ≈ 9.52 ms.
lag 1.5 1.5 트리거 발생부터 낙하산 완전 전개까지 지연, s. 선택 입력.
noise (0, 8.3, 0.5) (0, 8.3, 0.5) 압력 센서 노이즈. [보충] (평균 Pa, 표준편차 Pa, 시간 상관계수) 순서. 선택 입력.
radius 1.5 1.5 [보충] 팽창한 낙하산 형상의 반지름, m. 기체 radius와 구분.
height 1.5 1.5 [보충] 팽창한 낙하산 형상의 높이, m. 사출 고도가 아님.
porosity 0.0432 0.0432 [보충] 캐노피의 열린 면적 비율, 0–1. 하강 시 부가 질량 계산에 반영되며 cd_s를 바꾸는 인수는 아님.

낙하산 형상·노이즈·지연 인수의 보충 설명은 Parachute API와 대조했습니다.

09. 낙하산 트리거 함수와 상태 벡터

항목 입력·조건 해석·팁
숫자 trigger 예: 800 AGL 기준 하강 고도 조건. 상승 중 같은 고도를 지날 때 여는 의미가 아님.
문자열 trigger "apogee" 최고점에 도달하고 하강을 시작할 때의 사출 조건.
함수 trigger trigger(p, h, y) 펼쳐야 하면 True, 아니면 False. 시뮬레이션 중 sampling_rate에 맞춰 반복 평가.
p 압력, Pa 낙하산에 지정한 노이즈가 반영된 압력 신호.
h 지면으로부터의 높이, m 노이즈가 반영된 압력으로부터 얻은 AGL 높이. y[2]의 ASL 좌표와 구분.
y 전체 [x, y, z, vx, vy, vz, e0, e1, e2, e3, w1, w2, w3] 위치 3개 + 속도 3개 + 쿼터니언 4개 + 각속도 3개인 13성분 상태 벡터.
y[0:3], y[3:6] 위치 / 속도 y[5]는 수직 속도 vz. 하강 시 음수.
y[6:10], y[10:13] e0–e3 / w1–w3 자세를 나타내는 쿼터니언 / 기체 각속도.
drogue_trigger(p, h, y) return True if y[5] < 0 else False 하강 시작 시 Drogue 사출.
main_trigger(p, h, y) return True if y[5] < 0 and h < 800 else False 하강 중이고 AGL 800 m 아래일 때 Main 사출.
사용자 함수 연결 add_parachute(trigger=main_trigger, ...) [보충] 함수를 정의한 뒤 trigger 인수로 넘겨야 사용됨. 본문의 숫자·문자열 트리거와 사용자 함수는 대안 관계.
실제 장치 로직 연계 C/C++ 로직을 Python에서 호출 가능한 형태로 연결 실제 사출 로직을 시뮬레이션에 반영하는 아이디어. 단순히 C/C++ 파일을 import한다는 뜻은 아님.

10. 레일 버튼

함수·인수 본문 예시값 의미·팁
calisto.set_rail_buttons(...) 결과를 rail_buttons에 저장 레일 가이드를 레일 버튼으로 모델링. 시뮬레이션에서는 선택 사항이지만 레일 이탈 속도·동작을 현실적으로 계산하는 데 중요.
upper_button_position 0.0818 m 로켓 좌표계에서 위쪽 버튼 위치.
lower_button_position -0.618 m 로켓 좌표계에서 아래쪽 버튼 위치.
angular_position 45° 기체 중심축 둘레의 버튼 배치 각도. 발사 레일의 경사각·방위각과 구분.
확인할 결과 out_of_rail_conditions(), rail_buttons_forces() 레일 이탈 상태와 레일 위에서 버튼에 작용한 힘을 함께 확인.

11. 정적 여유와 조립 검증 — 꼭 기억할 팁

확인 항목 함수·기준 의미·주의점
정적 여유 그래프 calisto.plots.static_margin() 항상 확인. 점화 시 한 값만 보지 말고 시간에 따른 변화를 확인.
특정 시각의 값 calisto.static_margin(t) 시각 t의 정적 여유. 2일차에서는 calisto2.static_margin(...)으로 비교. [보충] 이 함수의 CP는 마하 0 기준이므로 비행 중 마하수 변화까지 반영한 안정성 여유와 구분.
단위 c caliber, 기체 직경 단위 [보충] 질량 중심(CG/CoM)과 압력 중심(CP)의 축 방향 간격을 기체 직경으로 나눈 값. 정상적인 양의 여유는 CG가 CP보다 노즈 쪽에 있음을 뜻함.
음수인 정적 여유 static_margin < 0 공력적으로 불안정한 구성. 본문은 시뮬레이션 실패 가능성도 경고하므로 부품 위치·질량 중심·좌표계를 먼저 점검.
지나치게 큰 정적 여유 값이 클수록 무조건 좋다는 해석 금지 본문은 과도한 안정성 역시 실패 가능성을 경고. 바람에 대한 강한 복원 반응으로 진행 방향이 꺾이거나 진동할 수 있다는 설명을 덧붙임.
적정 범위의 판단 두 글에는 공통으로 적용할 수치 범위가 없음 [보충] 임의의 상·하한을 이 표에서 추가하지 않음. 정적 여유와 함께 바람·레일 이탈 상태·자세 응답을 검토.
자동 경고 UnstableRocketWarning 조립한 로켓으로 비행을 만들 때 모터 점화 시점의 정적 여유가 음수이면 경고. 경고는 시뮬레이션 전체의 안정성 보장이 아님.
자동 검사 예외 GenericSurface가 포함된 기체 해당 부품의 양력 계수 미분값이 CP 계산에 반영되지 않아 정적 여유 검사가 생략됨. 경고가 없다는 것만으로 안정적이라 판단하면 안 됨.
형상 확인 calisto.draw() 실제로 노즈·핀·테일·모터가 의도한 위치인지 점검. 잘못된 원점·축 방향은 안정성 계산까지 바꿈.
전체 정보 확인 calisto.all_info() 질량·관성·공력·안정성 정보와 그래프를 함께 검토.
GUI 개발 관점 Exceptions and Warnings 사용자 입력 오류와 불안정 경고를 GUI에서 처리할 수 있도록 예외·경고 체계를 후속 학습할 필요가 있다는 본문 메모.

정적 여유 단위와 자동 검사 범위는 Rocket API, 과대·음수 값 주의는 공식 첫 시뮬레이션 안내를 참고했습니다.

12. 관성 텐서와 회전 특성

항목 뜻·사용법 해석할 때의 조건
I11, I22 기체·모터 중심축에 수직인 두 축의 회전 관성 피치·요 방향의 회전에 대한 저항을 나타냄.
I33 기체·모터 중심축 주위 회전 관성 롤 방향의 회전에 대한 저항을 나타냄.
I12, I13, I23 관성 텐서의 비대각 성분 필요한 경우 6성분 관성 입력에 포함.
calisto.get_inertia_tensor_at_time(0.5) t=0.5 s에서 각 성분을 평가한 rocketpy.mathutils.Matrix 반환 메서드의 기준점은 로켓의 건조 질량 중심. 기체 입력 inertia 및 순간 전체 질량 중심과 구분.
calisto.get_inertia_tensor_derivative_at_time(0.5) 해당 시각의 관성 텐서 시간 미분 [정정] 설명 문장의 get_inertia_tensor_derivation_at_time이 아니라 derivative가 올바른 이름.
I11 = I22 두 횡축의 회전 관성이 같음 본문은 축대칭 기체의 특징으로 설명. [보충] 이 등식 하나만으로 모든 형상·질량 분포의 축대칭을 증명할 수는 없음.
비대각 성분이 모두 0 해당 기준점에서 좌표축이 관성 주축과 일치하는 형태 [보충] 외력·공력에 의한 회전까지 없어지는 것은 아니므로 “뒤틀림이나 쏠림이 전혀 없다”는 보장으로 읽지 않기.
I33이 상대적으로 작음 같은 축 방향 토크에 대해 롤 방향으로 더 쉽게 회전 본문에서 소개한 회전 용이성의 비교. [보충] 이것만으로 비행 안정성을 확정할 수 없음.
기준점과 축 정렬 CoM·건조 CoM·좌표 원점을 구분 본문의 대칭성 해석에는 질량 중심과 축 정렬 조건이 붙음. 반환된 텐서의 기준점을 먼저 확인해야 함.

반환 기준점과 정확한 메서드명은 관성 텐서 공식 설명과 대조했습니다. 해석 조건에 관한 보충은 관성 성분으로 단정할 수 있는 범위를 제한한 것입니다.

13. Flight 생성과 실행 조건

인수·기능 기본 비행 예시 동적 안정성 비교 예시 / 의미
Flight(...) 결과를 test_flight에 저장 객체 생성 시 시뮬레이션 실행. 이후 수치·그래프·속성을 이 객체에서 조회.
rocket calisto 비교 예제에서는 복사·수정한 calisto2.
environment env 비교 예제에서는 custom_env.
rail_length 5.2 두 예제 모두 발사 레일 길이 5.2 m.
inclination 85 비교 예제는 90. [보충] 수평면에 대한 레일 경사각(°), 90°이면 수직.
heading 0 두 예제 모두 북쪽 0°. [보충] 북쪽 기준 방위각(°), 90°는 동쪽.
max_time_step 기본 예제에서 미지정 비교 예제의 0.01은 수치 적분 시간 간격의 최댓값, s. 모든 계산·출력 간격이 반드시 0.01 s라는 뜻은 아님.
max_time 기본 예제에서 미지정 비교 예제는 최대 5 s까지 계산.
terminate_on_apogee 기본 예제에서 미지정 비교 예제는 True: 최고점에 도달하면 종료. 이 설정으로는 최고점 이후 낙하산 하강·착지 전체를 볼 수 없음.
verbose 기본 예제에서 미지정 비교 예제는 False: 상세 실행 출력 비활성화.
test_flight.info() 주요 수치 결과를 빠르게 확인 아래 prints 항목들을 묶어 확인하는 용도.
test_flight.all_info() 수치와 그래프를 포함한 전체 정보 개별 prints·plots를 하나씩 호출하는 대신 전체 결과 확인.

실행 인수의 단위와 종료 조건은 Flight API로 확인했습니다.

14. 비행 수치 조회 — test_flight.prints

아래 메서드는 모두 test_flight.prints. 뒤에 붙여 호출합니다.

메서드 확인하는 시점·정보 확인 목적·팁
initial_conditions() 시뮬레이션 초기·점화 시점 상태 다른 결과를 해석하기 전에 초기 조건부터 확인.
surface_wind_conditions() 발사 장소 지표면 바람 발사 방향과 바람의 관계 확인.
launch_rail_conditions() 레일 길이·경사각·방위각 의도한 발사대 설정인지 확인.
out_of_rail_conditions() 레일 이탈 시점 상태 이때부터 자유 비행. 이탈 속도·안정성 등을 검토.
burn_out_conditions() 모터 연소 종료 시점 이후에는 모터 추력 없이 비행.
apogee_conditions() 최고고도와 그때의 상태 ASL·AGL을 구분. [정정] 2일차의 최고점 설명 아래 중복된 burn_out_conditions() 대신 사용.
events_registered() 낙하산 사출·전개 관련 사건 어느 낙하산이 언제 작동했는지 확인. 트리거 발생과 완전 전개를 구분.
impact_conditions() 시뮬레이션 종료·지면 충돌 조건 착지 상태 확인. 최고점이나 제한 시간에 조기 종료했다면 지면 충돌까지 계산한 결과와 구분.
maximum_values() 비행 중 여러 값의 최댓값 최고 속도·마하수·동압 등 주요 극값을 한 번에 점검.

최고점 메서드 정정은 공식 수치 결과 예제를 기준으로 했습니다.

15. 비행 그래프 조회 — test_flight.plots

아래 메서드는 모두 test_flight.plots. 뒤에 붙여 호출합니다. [정정] 본문 설명의 test_flight.plot()이 아니라 복수형 plots 속성입니다.

메서드 표시하는 내용 읽을 때의 팁
trajectory_3d() 3차원 비행 궤적 전체 경로와 발사 방향에서 벗어난 정도 확인.
linear_kinematics_data() 세 방향 속도·가속도 발사 장소의 절대 좌표계 기준. 모터 연소 종료 때 가속도가 급격히 감소할 수 있음.
flight_path_angle_data() 비행경로각·자세각·측면 자세각 진행 방향과 기체 축 방향의 관계를 비교.
attitude_data() 쿼터니언과 오일러 각에 의한 자세 정보 세차·장동·자전 및 자세 변화 확인.
angular_kinematics_data() 각속도·각가속도 안정성 판단에 중요. 연소 종료 무렵 급격한 변화가 있을 수 있음.
aerodynamic_forces() 공력과 모멘트 항력(축 방향), 두 수직 방향으로 분해한 양력, 굽힘·회전 모멘트 확인.
rail_buttons_forces() 레일 이탈 전 버튼에 가해지는 힘 버튼·발사 레일 설계와 하중 검토에 참고.
energy_data() 운동·위치 에너지와 추력·항력에 의한 일률 [정정] 힘 그 자체뿐 아니라 힘이 에너지를 전달·소모하는 속도인 power를 표시하는 항목.
fluid_mechanics_data() 마하수·레이놀즈 수·총압·동압·받음각 비행 중 공기역학적 상태 확인.
stability_and_control_data() 안정성 여유와 주파수 응답 정적 여유와 실제 자세 응답을 함께 검토.

에너지·일률의 구분은 공식 그래프 안내를 참고했습니다.

16. 고도·각도·안정성 결과를 읽는 기준

개념 정의 본문 팁 / 혼동하기 쉬운 점
ASL 해수면 기준 고도 Environment.elevation과 최고고도의 ASL 표시가 이 기준.
AGL 발사 장소 지면 기준 높이 낙하산 숫자 트리거 및 h의 기준. [보충] 같은 발사 지면을 기준으로 비교할 때 AGL = ASL − elevation.
Flight Path Angle 속도 벡터와 수평면 사이의 각도 수직 상승은 90°, 수평 이동은 0°. 기체가 어느 쪽을 향하는지와는 구분.
Attitude Angle 기체 축과 수평면 사이의 각도 비행경로각과 비슷한지 함께 확인.
Lateral Attitude Angle 기체 축과 발사 레일을 포함하는 수직면 사이의 각도 클수록 원래 발사 방향의 수직면에서 더 벗어나 있음을 뜻함.
비행경로각 ≈ 자세각 본문에서 소개한 안정적인 비행의 확인 단서 [보충] 바람이 있으면 지면 기준 속도와 공기 상대 속도가 다르므로, 두 각도의 근접성만으로 안정성을 보장하지는 않음. 받음각·각속도도 함께 확인.
Euler parameters / 쿼터니언 e0, e1, e2, e3로 자세 표현 [보충] Euler parameters는 쿼터니언을 가리키며, 세차·장동·자전의 Euler angles와 구분.
연소 종료 전후 선가속도·각속도·각가속도 변화 급격한 변화가 보이면 연소 종료 시각과 대조. 변화 자체만으로 오류라고 단정하지 않기.
정적 안정성 vs 동적 응답 정적 여유와 시간에 따른 자세 변화 핀 위치·바람·회전 관성의 영향을 함께 검토하는 것이 2일차 비교 실험의 목적.

17. 결과 속성·CSV·KML 내보내기

함수·속성 사용 형태 결과·주의점
test_flight.speed rocketpy.Function 형태의 비행 속도 값·그래프·원본 데이터로 접근하는 예시 속성.
test_flight.speed.plot(...) plot(0, test_flight.apogee_time) [정정] 0초부터 최고점 시각까지의 속도 그래프. 첫 낙하산의 실제 전개 시각까지와 반드시 같지는 않음.
test_flight.speed.source 속성에 직접 접근 전체 비행 속도 데이터 [[time, speed], ...]. 메서드처럼 괄호를 붙이지 않음.
test_flight.apogee_time 최고점에 도달한 시각, s 그래프 구간 끝으로 사용.
FlightDataExporter(test_flight) exporter = FlightDataExporter(test_flight) 내보낼 비행 객체를 감싸는 전용 exporter. import 위치는 rocketpy.simulation.
exporter.export_data(...) exporter.export_data("calisto_flight_data.csv", "angle_of_attack", "mach_number") 시간과 선택한 비행 속성을 CSV로 내보냄. 받음각·마하수를 문자열 속성명으로 지정.
time_step time_step=1.0 기존 결과를 1 s 간격으로 보간하여 저장. [보충] 시뮬레이션을 1 s 간격으로 다시 계산하는 옵션이 아님.
속성명을 생략한 export_data exporter.export_data("calisto_flight_data.csv") 전체 상태 해를 내보냄. Flight.solution_array 참고. 모든 파생 그래프·물리량을 자동으로 전부 넣는다는 의미와 구분.
import pandas as pd / pd.read_csv(...) pd.read_csv("calisto_flight_data.csv") 내보낸 CSV를 표로 읽어 확인.
FlightDataExporter(test_flight).export_kml(...) file_name="trajectory.kml" 비행 궤적을 KML로 내보내 Google Earth에서 시각화.
extrude True [보충] 궤적과 지면을 연결하는 표시를 설정.
altitude_mode "relativetoground" 지면 상대 고도로 해석하는 모드. ASL·AGL 구분과 연결해서 이해.
exporter의 전체 경로 rocketpy.simulation.flight_data_exporter.FlightDataExporter 본문에서 제시한 export_data()·export_kml() API 경로.
지도 연동 아이디어 KML을 지원하는 다른 3D 지도·JavaScript 도구 Google Earth 외의 시각화도 검토할 수 있다는 본문 메모이며, 실제 연동 구현은 다루지 않음.

내보내기 예제는 공식 결과 활용 안내, KML 항목은 본문의 KML Reference를 참고합니다.

18. 그림·그래프 저장

대상 함수·인수 결과·팁
로켓 형상 그림 calisto.draw(filename="calisto_drawing.png") 조립한 로켓의 그림 저장.
속도 그래프 test_flight.speed.plot(filename="speed_plot.jpg") Function 속성의 그래프 저장.
3차원 궤적 test_flight.plots.trajectory_3d(filename="trajectory_plot.jpg") 궤적 그림 저장. KML 내보내기와 용도가 다름.
filename 선택 인수 본문에서 다룬 그래프·그림에 파일 이름을 지정. [보충] 생략하면 화면에 표시. KML의 인수명 file_name과 구분.
본문에 나열된 형식 .eps, .jpg, .jpeg, .pdf, .pgf, .png, .ps, .raw, .rgba, .svg, .svgz, .tif, .tiff, .webp 저장할 형식에 맞는 확장자를 사용.

19. 질량 변화에 따른 최고고도·레일 이탈 속도

함수·인수 본문 예시 분석하는 내용
apogee_by_mass(...) from rocketpy.utilities import apogee_by_mass 질량에 따른 최고고도 변화. [보충] 입력 질량은 모터를 제외한 기체 질량(kg), 출력 고도는 AGL(m).
liftoff_speed_by_mass(...) from rocketpy.utilities import liftoff_speed_by_mass 질량에 따른 레일 이탈 속도 변화. 이름을 점화 직후 속도로 오해하지 않기.
공통 flight flight=test_flight 분석에 사용할 비행 조건.
min_mass, max_mass 5, 20 비교할 질량 범위, kg.
points 10 범위 내 비교 지점 수.
plot True 비교 그래프 표시.
반환·활용 질량에 따른 결과를 담은 Function [보충] 함수 이름만 보는 대신 최고고도·레일 이탈 속도를 각각 확인. 질량 증가가 어떤 결과를 만드는지는 실제 실행 결과로 판단.
입력 기체의 변경 [보충·구현 확인] 두 함수는 flight.rocket.mass를 직접 변경 확인한 1.13.0 구현은 원래 질량을 복구하지 않음. 원본 보존이 필요하면 분석용 비행 객체를 복사해서 전달. 예제가 정상 완료되면 원래 기체도 마지막 질량 20 kg인 상태가 될 수 있음.

질량 기준과 반환값은 RocketPy utilities 구현·설명과 대조했습니다.

20. 동적 안정성 비교 코드의 전체 흐름

순서 코드·속성 하는 일 / 본문 값
1. 도구 준비 from rocketpy import Function, import copy 여러 자세 응답을 비교할 도구와 복사 도구를 불러옴.
2. 기체 복사 calisto2 = copy.deepcopy(calisto) 원래 calisto와 별도로 수정할 로켓을 만듦.
3. 비교 환경 custom_env = Environment() 별도 환경 객체 생성. [보충] 앞서 만든 UNIST의 env를 복사하는 코드가 아님.
4. 바람 설정 custom_env.set_atmospheric_model(type="custom_atmosphere", wind_v=-5) 남쪽 방향 성분이 5 m/s인 바람. 앞선 북서풍 예제와 다른 조건.
5. 결과 목록 simulation_results = [] 각 경우의 자세 함수와 범례를 저장할 빈 리스트.
6. 위치 변화 계수 factor가 [-0.5, -0.2, 0.1, 0.4, 0.7]을 순회 핀 위치를 바꾸는 실험.
7. 기존 부품 제거 calisto2.aerodynamic_surfaces.pop(-1) 공력 부품 목록의 마지막 부품 제거. 기존 핀인지 반드시 확인해야 함. 아래 주의사항 참고.
8. 새 핀 추가 calisto2.add_trapezoidal_fins(...) n=4, root_chord=0.120, tip_chord=0.040, span=0.100, position=-1.04956 * factor. 길이·위치는 m.
9. 비행 실행 Flight(rocket=calisto2, environment=custom_env, ...) 레일 5.2 m, 수직 90°, 북쪽 0°, max_time_step=0.01, max_time=5, terminate_on_apogee=True, verbose=False.
10. 점화 시 정적 여유 calisto2.static_margin(0) static_margin_at_ignition에 저장.
11. 레일 이탈 시 정적 여유 calisto2.static_margin(test_flight.out_of_rail_time) static_margin_at_out_of_rail에 저장. out_of_rail_time은 레일 이탈 시각.
12. 종료 시 정적 여유 calisto2.static_margin(test_flight.t_final) 본문 변수명은 static_margin_at_steady_state. [정정] t_final은 계산 종료 시각이지 정상 상태임을 보장하는 값이 아님.
13. 비교 데이터 저장 (test_flight.attitude_angle, 범례 문자열) attitude_angle은 시간에 따른 자세각 함수. 이를 simulation_results에 누적.
14. 범례 작성 "{:1.2f} c | {:1.2f} c | {:1.2f} c".format(...) 점화 / 레일 이탈 / 종료 시 정적 여유를 소수점 둘째 자리까지, 단위 c로 표시.
15. 그래프 비교 Function.compare_plots(simulation_results, ...) lower=0, upper=1.5: 0–1.5 s 구간. xlabel="Time (s)", ylabel="Attitude Angle (deg)".
이 예제를 이어서 실행할 때의 주의점 이유·확인 방법
[코드 대조] pop(-1)은 첫 반복에서 테일을 제거함 1일차의 공력 부품 추가 순서가 노즈 → 핀 → 테일이므로 마지막 부품은 테일. 이 구성 순서를 연결하면 기존 핀을 남긴 채 새 핀을 추가하게 됨. 제거할 핀을 실제 객체·목록에서 확인해야 함.
앞의 질량 분석을 실행한 뒤 복사하면 질량도 달라질 수 있음 위의 두 질량 분석 함수가 같은 calisto를 수정하므로, 그 뒤의 copy.deepcopy(calisto)는 이미 변경된 기체를 복사할 수 있음. 비교 실험의 기준 질량을 먼저 확인.
원래 핀과 비교용 핀의 형상이 다름 1일차는 tip_chord=0.060, span=0.110, cant_angle=0.5, airfoil 지정. 비교용은 0.040, 0.100이며 캔트각·airfoil을 지정하지 않음. 원래 기체와 결과를 비교할 때 위치만 달라졌다고 해석하지 않기.
factor는 스팬이 아니라 위치를 변경함 코드에서 span=0.100은 고정이고 position에만 factor가 곱해짐. 음수 factor는 위치 부호도 바꾸므로 draw()로 확인.
test_flight 변수가 반복마다 덮어써짐 반복문 뒤의 test_flight는 마지막 비교 조건의 비행임. 앞의 기본 비행 결과를 다시 조회·내보낼 때 혼동 주의.
5초 계산과 1.5초 표시 구간을 구분 max_time=5는 계산 시간 제한, upper=1.5는 비교 그래프에 표시할 범위.
종료 시각과 정상 상태를 구분 t_final까지 응답이 충분히 수렴했는지는 그래프로 확인해야 함. 변수명만으로 정상 상태라고 판단하지 않기.
정적 여유 하나로 동적 안정성을 단정하지 않기 자세각의 시간 변화, 각속도·각가속도, 바람 및 회전 관성의 영향을 함께 검토.

부품 제거 문제는 두 글의 부품 추가 순서와 Components.pop() 구현을 대조한 결과입니다. 여기서는 기존 예제 코드를 수정하지 않고 실행 전 주의점으로 남겼습니다.

21. 복사해서 사용할 때 먼저 확인할 오타·해석 정리

원문 위치·표현 요약에서 사용한 올바른 형태·해석
1일차 datetime.data.today() datetime.date.today()
1일차 env.set_data(...) env.set_date(...)
1일차 날짜 튜플의 중복 tomorrow.month (tomorrow.year, tomorrow.month, tomorrow.day, hour_in_UTC_time)의 4개 값
import datetime 뒤의 datetime.now() datetime.datetime.now(...); UTC 기준이면 datetime.datetime.now(datetime.timezone.utc)
1일차 set_atmosperic_model set_atmospheric_model
1일차 env.info 실행하려면 env.info()
1일차 add_motor(example_motor, ...) 앞에서 생성한 example_solid과 변수 이름 일치시키기
1일차 add_trapezolidal_fins add_trapezoidal_fins
1일차 get_inertia_tensor_derivation_at_time get_inertia_tensor_derivative_at_time
1일차 그레인 “외경·내경” 표현 해당 인수 이름의 radius는 지름이 아닌 반지름
1일차 sampling_rate의 “주기” 표현 값의 단위는 Hz인 빈도. 주기는 그 역수
2일차 최고점 설명 아래 burn_out_conditions() apogee_conditions()
2일차 test_flight.plot() test_flight.plots 속성의 개별 메서드 호출
2일차 energy_data()의 추력·항력 표현 에너지와 함께 추력·항력의 일률(power)을 확인하는 그래프
2일차 speed.plot(0, apogee_time) 최고점까지의 구간. 낙하산 전개 지연까지 포함하는 구간이 아님
2일차 코드 펜스의 pytohn Python 구문 강조를 위한 언어 이름은 python. 본문의 코드 펜스에도 반영함.
2일차 pop(-1) / static_margin_at_steady_state 마지막 부품 제거 / 종료 시 정적 여유. 기존 핀 제거·정상 상태 판정과 각각 구분

22. 본문에서 남겨 둔 후속 학습과 참고 자료

주제 현재 두 글에서 다룬 범위 후속 학습·참고 링크
실제 실행과 GUI 설정·조회 코드와 GUI 개발 목적을 소개 실제 실행 결과는 다른 게시물에서 다룰 계획. 이 요약의 예시 수치도 새로운 실행 결과는 아님.
기본 시뮬레이션 전체 환경 → 모터 → 로켓 → 비행 → 결과 활용 First Simulation
고체 모터 가정·구현 BATES·일정 배기 속도와 입력값 SolidMotor 사용법, 생성자 API
추력 소스 상세 지원 형식을 소개하고 상세 학습은 보류 Thrust Source
하이브리드·액체 모터 클래스 이름과 동일한 전체 흐름만 소개 각 모터의 입력·탱크 등 상세 설정은 아직 다루지 않음.
좌표계·부품 위치 모터·기체 좌표 방향과 위치값을 소개 Positions and Coordinate Systems, 레일 위치
Rocket 상세 API 뼈대·부품·낙하산·레일·관성 텐서 사용 Rocket 사용법, Rocket 생성자
낙하산·트리거 상세 숫자·문자열·3인수 함수 예제 Trigger Details, add_parachute
예외·경고 처리 음수 정적 여유 경고와 GenericSurface 예외 Exceptions and Warnings; GUI 입력·실행 오류 처리 관점의 추가 공부가 필요하다는 메모.
전체 비행 속성·함수 활용 speed, 배열 접근, 그래프·CSV 저장, 함수 비교 Flight, Function API, Function 사용법
몬테 카를로 분석 가능하다는 소개와 링크만 제시 본문의 몬테 카를로 자료; 절차·실행 결과는 미정리.
외부 도구·국내 자료 RASAero II, Airfoil Tools, KML 소개 PyRASAero·LDAPS/RDAPS·다른 JavaScript 3D 지도 연동은 가능성을 검토할 후속 항목.

23. 원문 내용 → 요약표 대조

원문 범위 대응하는 요약표 반영 상태
1일차: 학습 목적·네 클래스·정의 순서 01 전체 흐름 정리 완료
1일차: 발사 위치·날짜·날씨 조회 02 환경 설정 정리 완료, 실행 오타 별도 표시
1일차: 7종 대기 모델·데이터 소스·매핑·단위·바람 예시 03–04 대기 설정 정리 완료, LDAPS/RDAPS는 미확인 아이디어로 구분
1일차: 모터 종류·물리 가정·모든 생성 인수·정보 조회 05 고체 모터 정리 완료, 하이브리드·액체 상세는 후속 학습
1일차: 기체 질량·관성·좌표·항력 곡선·외부 도구 06 기체와 항력 정리 완료
1일차: 모터·노즈·핀·테일·단면 데이터·그림 확인 07 공력 부품 정리 완료
1일차: Main/Drogue·사출 조건·상태 벡터·C/C++ 연계 08–09 낙하산 정리 완료
1일차: 레일 버튼과 현실적인 이탈 조건 10 레일 버튼 정리 완료
1일차: 음수·과대 정적 여유·경고 예외·GUI 관점 11 안정성 정리 완료
1일차: 관성 텐서·시간 미분·대칭성과 회전 해석 12 관성 정리 완료, 단정하기 어려운 해석에 조건 추가
2일차: Flight 생성·공통 조회 방식 13 비행 실행 정리 완료
2일차: 초기·바람·레일·연소 종료·최고점·낙하산·충돌·최댓값 14 수치 조회 정리 완료, 최고점 메서드 정정
2일차: 모든 결과 플롯·좌표계·고도·자세 해석 15 그래프, 16 해석 정리 완료
2일차: KML·속도 Function·배열·선택 CSV·보간·전체 해 17 결과 내보내기 정리 완료
2일차: 그림 저장 예제·선택 인수·14종 확장자 18 그림 저장 정리 완료
2일차: 질량별 최고고도·이탈 속도 분석 19 질량 분석 정리 완료
2일차: 복사·환경·핀 위치 변경·비행·3시점 정적 여유·비교 그래프 20 동적 분석 정리 완료, 연결 실행 시 주의점 표시
두 글: 오타·미학습 메모·확장 아이디어 21 정정, 22 후속 학습 미학습·미확인 항목을 완료된 지식과 구분
1일차의 긴 CSV 숫자 예제 06 항력, 07 airfoil 열의 의미·단위·대표값을 요약하고 전체 숫자열은 기존 본문에 보존