107 lines
3.1 KiB
C++
107 lines
3.1 KiB
C++
// 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<Environment>(
|
|
101325.0, // surface pressure (Pa)
|
|
288.15, // surface temperature (K)
|
|
0.0 // launch altitude (m)
|
|
);
|
|
|
|
// Setup Rocket
|
|
auto rocket = std::make_shared<Rocket>("IntegrationTestRocket");
|
|
|
|
auto stage = std::make_unique<Stage>("Stage1");
|
|
|
|
// Motor
|
|
auto motor = std::make_unique<Motor>("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<Airframe>("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<FinSet>("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<RecoverySystem>("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
|
|
}
|
|
}
|