// tests/test_rocket_simulator.cpp #include "vendor/catch_amalgamated.hpp" #include "Rocket.h" #include "Stage.h" #include "Motor.h" #include "Airframe.h" #include "FinSet.h" #include "RecoverySystem.h" #include "Environment.h" #include "FlightSimulator.h" #include "FlightState.h" #include "Integrator.h" // Bring Approx into scope using Catch::Approx; TEST_CASE("Rocket and FlightSimulator integration test", "[integration]") { // Setup Environment auto environment = std::make_shared( 101325.0, // surface pressure (Pa) 288.15, // surface temperature (K) 0.0 // launch altitude (m) ); // Setup Rocket auto rocket = std::make_shared("IntegrationTestRocket"); auto stage = std::make_unique("Stage1"); // Motor auto motor = std::make_unique("TestMotor", 0.05, 50.0); // 50g propellant motor->addThrustDataPoint(0.0, 0.0); motor->addThrustDataPoint(0.1, 50.0); motor->addThrustDataPoint(1.5, 50.0); motor->addThrustDataPoint(1.6, 0.0); stage->addMotor(std::move(motor)); // Airframe auto airframe = std::make_unique("Airframe1", 1.5, // length 0.1, // diameter 2.0, // dry mass 0.75 // drag coefficient ); stage->setAirframe(std::move(airframe)); // FinSet auto finset = std::make_unique("TestFins", 3, // 3 fins 0.15, // root chord 0.10, // tip chord 0.10, // span 0.05, // sweep 0.003, // thickness 500.0 // density ); stage->setFinSet(std::move(finset)); // Recovery auto recovery = std::make_unique("MainChute", RecoverySystem::DeploymentType::Apogee, 0.0, // no trigger value needed 1.5, // Cd 2.0 // area ); stage->setRecoverySystem(std::move(recovery)); rocket->addStage(std::move(stage)); rocket->updateMassProperties(); // Setup FlightSimulator FlightSimulator simulator(rocket, environment); SECTION("Full flight simulation runs and reaches apogee") { simulator.run(20.0, 0.01); // Simulate 20 seconds with 10ms step const auto& flightLog = simulator.getFlightLog(); REQUIRE(flightLog.size() > 0); double maxAltitude = 0.0; double landingAltitude = flightLog.back().getPosition()[2]; for (const auto& state : flightLog) { double alt = state.getPosition()[2]; if (alt > maxAltitude) { maxAltitude = alt; } } REQUIRE(maxAltitude > 0.0); // Rocket climbed REQUIRE(landingAltitude <= 1.0); // Rocket landed (near ground) // Optional: check that apogee was reached early in flight size_t apogeeIndex = 0; for (size_t i = 1; i < flightLog.size(); ++i) { if (flightLog[i].getPosition()[2] < flightLog[i-1].getPosition()[2]) { apogeeIndex = i - 1; break; } } REQUIRE(apogeeIndex > 0); // Apogee was found } }