Remove model::Stage for now. It'll be good in the future, but makes initial development more complex. Prototype with single stage rocket for now while working out the physics engine

This commit is contained in:
Travis Hunter 2024-03-17 08:13:24 -06:00
parent 63a5b8995f
commit 46eca1136f
10 changed files with 178 additions and 164 deletions

View File

@ -92,7 +92,7 @@ void AnalysisWindow::onButton_plotVelocity_clicked()
void AnalysisWindow::onButton_plotMotorCurve_clicked()
{
std::shared_ptr<model::Rocket> rocket = QtRocket::getInstance()->getRocket();
model::MotorModel& motor = rocket->getCurrentStage()->getMotorModel();
model::MotorModel motor = rocket->getMotorModel();
ThrustCurve tc = motor.getThrustCurve();
@ -122,4 +122,4 @@ void AnalysisWindow::onButton_plotMotorCurve_clicked()
plot->yAxis->setRange(*std::min_element(std::begin(fData), std::end(fData)), *std::max_element(std::begin(fData), std::end(fData)));
plot->replot();
}
}

View File

@ -9,10 +9,9 @@ add_library(model
Propagatable.h
Rocket.cpp
Rocket.h
Stage.cpp
Stage.h
ThrustCurve.cpp
ThrustCurve.h)
ThrustCurve.h
InertiaTensors.h)
target_link_libraries(model PRIVATE
utils)

70
model/InertiaTensors.h Normal file
View File

@ -0,0 +1,70 @@
#ifndef INERTIATENSORS_H
#define INERTIATENSORS_H
#include "utils/math/MathTypes.h"
namespace model
{
/**
* @brief The InertiaTensors class provides a collection of methods to
* deliver some common inertia tensors centered about the center of mass
*/
class InertiaTensors
{
public:
/**
* @brief SolidSphere
* @param radius (meters)
* @return
*/
static Matrix3 SolidSphere(double radius)
{
double xx = 0.4*radius*radius;
double yy = xx;
double zz = xx;
return Matrix3{{xx, 0, 0},
{0, yy, 0},
{0, 0, zz}};
}
/**
* @brief HollowSphere
* @param radius (meters)
* @return
*/
static Matrix3 HollowSphere(double radius)
{
double xx = (2.0/3.0)*radius*radius;
double yy = xx;
double zz = xx;
return Matrix3{{xx, 0, 0},
{0, yy, 0},
{0, 0, zz}};
}
/**
* @brief Tube - The longitudinal axis is the z-axis. Can also be used for a solid cylinder
* when innerRadius = 0.0
* @param innerRadius (meters)
* @param outerRadius (meters)
* @param length (meters)
* @return
*/
static Matrix3 Tube(double innerRadius, double outerRadius, double length)
{
double xx = (1.0/12.0)*(3.0*(innerRadius*innerRadius + outerRadius*outerRadius) + length*length);
double yy = xx;
double zz = (1.0/2.0)*(innerRadius*innerRadius + outerRadius*outerRadius);
return Matrix3{{xx, 0.0, 0.0},
{0.0, yy, 0.0},
{0.0, 0.0, zz}};
}
};
}
#endif // INERTIATENSORS_H

View File

@ -63,7 +63,9 @@ public:
// Set the inertia tensor
void setI(const Matrix3& I) { inertiaTensor = I; }
Matrix3 getI() { return inertiaTensor; }
Matrix3 getCompositeI() { return compositeInertiaTensor; }
void setCm(const Vector3& x) { cm = x; }
// Special version of setCM that assumes the cm lies along the body x-axis
void setCm(double x) { cm = {x, 0.0, 0.0}; }

View File

@ -11,6 +11,7 @@
// qtrocket headers
#include "sim/Aero.h"
#include "sim/StateData.h"
#include "utils/math/MathTypes.h"
namespace model
{
@ -21,14 +22,15 @@ public:
Propagatable() {}
virtual ~Propagatable() {}
virtual double getDragCoefficient() = 0;
virtual void setDragCoefficient(double d) = 0;
virtual bool terminateCondition(const std::pair<double, StateData>&) = 0;
virtual Vector3 getForces(double t) = 0;
virtual Vector3 getTorques(double t) = 0;
virtual double getMass(double t) = 0;
virtual double getThrust(double t) = 0;
private:
virtual Matrix3 getInertiaTensor(double t) = 0;
virtual bool terminateCondition(double t) = 0;
protected:
sim::Aero aeroData;
@ -37,4 +39,4 @@ private:
}
#endif // MODEL_PROPAGATABLE_H
#endif // MODEL_PROPAGATABLE_H

View File

@ -1,51 +1,79 @@
// qtrocket headers
#include "Rocket.h"
#include "QtRocket.h"
#include "InertiaTensors.h"
namespace model
{
Rocket::Rocket()
: topPart("NoseCone", InertiaTensors::SolidSphere(1.0), 1.0, {0.0, 0.0, 1.0})
{
// A rocket needs at least one stage. Upon creation, we need to create at least one stage
currentStage.reset(new Stage("sustainer"));
stages.push_back(currentStage);
}
void Rocket::launch()
double Rocket::getMass(double t)
{
currentStage->getMotorModel().startMotor(0.0);
double mass = mm.getMass(t);
mass += topPart.getCompositeMass(t);
return mass;
}
void Rocket::setMotorModel(const model::MotorModel& motor)
Matrix3 Rocket::getInertiaTensor(double)
{
currentStage->setMotorModel(motor);
return topPart.getCompositeI();
}
bool Rocket::terminateCondition(const std::pair<double, StateData>& cond)
bool Rocket::terminateCondition(double)
{
// Terminate propagation when the z coordinate drops below zero
if(cond.second.position[2] < 0)
if(state.position[2] < 0)
return true;
else
return false;
}
double Rocket::getThrust(double t)
Vector3 Rocket::getForces(double t)
{
return currentStage->getMotorModel().getThrust(t);
// Get thrust
// Assume that thrust is always through the center of mass and in the rocket's Z-axis
Vector3 forces{0.0, 0.0, mm.getThrust(t)};
// Get gravity
auto gravityModel = QtRocket::getInstance()->getEnvironment()->getGravityModel();
Vector3 gravity = gravityModel->getAccel(state.position)*getMass(t);
forces += gravity;
// Calculate aero forces
return forces;
}
double Rocket::getMass(double t)
Vector3 Rocket::getTorques(double t)
{
double totalMass = 0.0;
for(const auto& stage : stages)
{
totalMass += stage->getMass(t);
}
return totalMass;
return Vector3{0.0, 0.0, 0.0};
}
double Rocket::getThrust(double t)
{
return mm.getThrust(t);
}
void Rocket::launch()
{
mm.startMotor(0.0);
}
void Rocket::setMotorModel(const model::MotorModel& motor)
{
mm = motor;
}
} // namespace model

View File

@ -13,10 +13,13 @@
/// \endcond
// qtrocket headers
#include "model/Part.h"
#include "sim/Propagator.h"
#include "model/MotorModel.h"
#include "model/Stage.h"
#include "model/Propagatable.h"
// Not yet
//#include "model/Stage.h"
namespace model
{
@ -45,19 +48,30 @@ public:
*/
void launch();
Vector3 getForces(double t) override;
Vector3 getTorques(double t) override;
/**
* @brief getMass returns current rocket mass
* @param t current simulation time
* @return mass in kg
*/
double getMass(double t) override;
/**
* @brief terminateCondition returns true or false, whether the passed-in time/state matches the terminate condition
* @param cond time/state pair
* @return true if the passed-in time/state satisfies the terminate condition
*/
bool terminateCondition(double t) override;
Matrix3 getInertiaTensor(double t) override;
/**
* @brief getThrust returns current motor thrust
* @param t current simulation time
* @return thrust in Newtons
*/
double getThrust(double t) override;
double getThrust(double t);
/**
* @brief getMass returns current rocket
* @param t current simulation time
* @return mass in kg
*/
double getMass(double t) override;
/**
* @brief setMotorModel
@ -65,18 +79,18 @@ public:
*/
void setMotorModel(const model::MotorModel& motor);
/**
* @brief getMotorModel
*/
MotorModel getMotorModel() { return mm; }
/**
* @brief Returns the current motor model.
* @return The current motor model
*/
//const model::MotorModel& getCurrentMotorModel() const { return mm; }
/**
* @brief terminateCondition returns true or false, whether the passed-in time/state matches the terminate condition
* @param cond time/state pair
* @return true if the passed-in time/state satisfies the terminate condition
*/
bool terminateCondition(const std::pair<double, StateData>& cond) override;
/**
* @brief setName sets the rocket name
@ -84,20 +98,17 @@ public:
*/
void setName(const std::string& n) { name = n; }
double getDragCoefficient() override { return 1.0; }
void setDragCoefficient(double d) override { }
double getDragCoefficient() { return 1.0; }
void setDragCoefficient(double d) { }
void setMass(double m) { }
std::shared_ptr<Stage> getCurrentStage() { return currentStage; }
private:
std::string name; /// Rocket name
std::vector<std::shared_ptr<Stage>> stages;
std::shared_ptr<Stage> currentStage;
//model::MotorModel mm; /// Current Motor Model
model::MotorModel mm; /// Current Motor Model
model::Part topPart;
};

View File

@ -1,26 +0,0 @@
/// \cond
// C headers
// C++ headers
// 3rd party headers
/// \endcond
// qtrocket headers
#include "Stage.h"
namespace model
{
Stage::Stage(const std::string& inName)
: name(inName)
{}
Stage::~Stage()
{}
void Stage::setMotorModel(const model::MotorModel& motor)
{
mm = motor;
}
} // namespace model

View File

@ -1,75 +0,0 @@
#ifndef SIM_STAGE_H
#define SIM_STAGE_H
/// \cond
// C headers
// C++ headers
#include <string>
#include <memory>
// 3rd party headers
/// \endcond
// qtrocket headers
#include "model/MotorModel.h"
#include "model/Part.h"
#include "model/Propagatable.h"
namespace model
{
class Stage : public Propagatable
{
public:
Stage(const std::string& inName);
virtual ~Stage();
/**
* @brief setMotorModel
* @param motor
*/
void setMotorModel(const model::MotorModel& motor);
/**
* @brief Returns the current motor model.
* @return The current motor model
*/
model::MotorModel& getMotorModel() { return mm; }
virtual double getMass(double t) override
{
if(topPart)
{
return topPart->getCompositeMass(t) + mm.getMass(t);
}
else
return 0.0;
}
virtual double getDragCoefficient() override { return 1.0 ;}
virtual void setDragCoefficient(double d) override {}
virtual bool terminateCondition(const std::pair<double, StateData>& cond) override
{
// Terminate propagation when the z coordinate drops below zero
if(cond.second.position[2] < 0)
return true;
else
return false;
}
virtual double getThrust(double t) override { return mm.getThrust(t); }
private:
std::string name;
std::shared_ptr<Part> topPart;
model::MotorModel mm;
Vector3 motorModelPosition; // position of motor cg w.r.t. the stage c.g.
};
} // namespace model
#endif // SIM_STAGE_H

View File

@ -153,7 +153,7 @@ void Propagator::runUntilTerminate()
{
states.push_back(std::make_pair(currentTime, nextState));
}
if(object->terminateCondition(std::make_pair(currentTime, currentState)))
if(object->terminateCondition(currentTime))
break;
currentTime += timeStep;
@ -175,23 +175,26 @@ double Propagator::getMass()
double Propagator::getForceX()
{
QtRocket* qtrocket = QtRocket::getInstance();
return (currentState.velocity[0] >= 0 ? -1.0 : 1.0) * qtrocket->getEnvironment()->getAtmosphericModel()->getDensity(currentState.position[2])/ 2.0 * 0.008107 * object->getDragCoefficient() * currentState.velocity[0]* currentState.velocity[0];
return 0.0;
//QtRocket* qtrocket = QtRocket::getInstance();
//return (currentState.velocity[0] >= 0 ? -1.0 : 1.0) * qtrocket->getEnvironment()->getAtmosphericModel()->getDensity(currentState.position[2])/ 2.0 * 0.008107 * object->getDragCoefficient() * currentState.velocity[0]* currentState.velocity[0];
}
double Propagator::getForceY()
{
QtRocket* qtrocket = QtRocket::getInstance();
return (currentState.velocity[1] >= 0 ? -1.0 : 1.0) * qtrocket->getEnvironment()->getAtmosphericModel()->getDensity(currentState.position[2]) / 2.0 * 0.008107 * object->getDragCoefficient() * currentState.velocity[1]* currentState.velocity[1];
return 0.0;
//QtRocket* qtrocket = QtRocket::getInstance();
//return (currentState.velocity[1] >= 0 ? -1.0 : 1.0) * qtrocket->getEnvironment()->getAtmosphericModel()->getDensity(currentState.position[2]) / 2.0 * 0.008107 * object->getDragCoefficient() * currentState.velocity[1]* currentState.velocity[1];
}
double Propagator::getForceZ()
{
QtRocket* qtrocket = QtRocket::getInstance();
double gravity = (qtrocket->getEnvironment()->getGravityModel()->getAccel(currentState.position[0], currentState.position[1], currentState.position[2]))[2];
double airDrag = (currentState.velocity[2] >= 0 ? -1.0 : 1.0) * qtrocket->getEnvironment()->getAtmosphericModel()->getDensity(currentState.position[2]) / 2.0 * 0.008107 * object->getDragCoefficient() * currentState.velocity[2]* currentState.velocity[2];
double thrust = object->getThrust(currentTime);
return gravity + airDrag + thrust;
return 0.0;
//QtRocket* qtrocket = QtRocket::getInstance();
//double gravity = (qtrocket->getEnvironment()->getGravityModel()->getAccel(currentState.position[0], currentState.position[1], currentState.position[2]))[2];
//double airDrag = (currentState.velocity[2] >= 0 ? -1.0 : 1.0) * qtrocket->getEnvironment()->getAtmosphericModel()->getDensity(currentState.position[2]) / 2.0 * 0.008107 * object->getDragCoefficient() * currentState.velocity[2]* currentState.velocity[2];
//double thrust = object->getThrust(currentTime);
//return gravity + airDrag + thrust;
}
double Propagator::getTorqueP() { return 0.0; }