diff --git a/gui/AnalysisWindow.cpp b/gui/AnalysisWindow.cpp index 8b8fbda..65d5d6f 100644 --- a/gui/AnalysisWindow.cpp +++ b/gui/AnalysisWindow.cpp @@ -92,7 +92,7 @@ void AnalysisWindow::onButton_plotVelocity_clicked() void AnalysisWindow::onButton_plotMotorCurve_clicked() { std::shared_ptr 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(); -} \ No newline at end of file +} diff --git a/model/CMakeLists.txt b/model/CMakeLists.txt index d3a8f14..bf9be41 100644 --- a/model/CMakeLists.txt +++ b/model/CMakeLists.txt @@ -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) diff --git a/model/InertiaTensors.h b/model/InertiaTensors.h new file mode 100644 index 0000000..e0d09dc --- /dev/null +++ b/model/InertiaTensors.h @@ -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 diff --git a/model/Part.h b/model/Part.h index 42fe0bc..9e63cf2 100644 --- a/model/Part.h +++ b/model/Part.h @@ -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}; } diff --git a/model/Propagatable.h b/model/Propagatable.h index 434665b..02e50c8 100644 --- a/model/Propagatable.h +++ b/model/Propagatable.h @@ -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&) = 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 \ No newline at end of file +#endif // MODEL_PROPAGATABLE_H diff --git a/model/Rocket.cpp b/model/Rocket.cpp index f81cd5d..032be0b 100644 --- a/model/Rocket.cpp +++ b/model/Rocket.cpp @@ -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& 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 diff --git a/model/Rocket.h b/model/Rocket.h index d0c3bb4..22a2fb2 100644 --- a/model/Rocket.h +++ b/model/Rocket.h @@ -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& 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 getCurrentStage() { return currentStage; } - private: std::string name; /// Rocket name - std::vector> stages; - std::shared_ptr currentStage; - //model::MotorModel mm; /// Current Motor Model + model::MotorModel mm; /// Current Motor Model + model::Part topPart; }; diff --git a/model/Stage.cpp b/model/Stage.cpp deleted file mode 100644 index af7c593..0000000 --- a/model/Stage.cpp +++ /dev/null @@ -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 diff --git a/model/Stage.h b/model/Stage.h deleted file mode 100644 index bf61a40..0000000 --- a/model/Stage.h +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef SIM_STAGE_H -#define SIM_STAGE_H - -/// \cond -// C headers -// C++ headers -#include -#include - -// 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& 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 topPart; - - model::MotorModel mm; - Vector3 motorModelPosition; // position of motor cg w.r.t. the stage c.g. -}; - -} // namespace model - -#endif // SIM_STAGE_H diff --git a/sim/Propagator.cpp b/sim/Propagator.cpp index 1ad0634..699d61b 100644 --- a/sim/Propagator.cpp +++ b/sim/Propagator.cpp @@ -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; }