From 89fb6d47d0a84e2fdcec821c93504db101690bd1 Mon Sep 17 00:00:00 2001 From: Travis Hunter Date: Tue, 25 Apr 2023 19:11:28 -0600 Subject: [PATCH 1/3] WIP --- gui/SimOptionsWindow.cpp | 51 ++++++++++++++++++++++++++++++++++++++++ gui/SimOptionsWindow.h | 5 ++++ gui/SimOptionsWindow.ui | 2 +- sim/SimulationOptions.h | 23 +++++++++++++++--- 4 files changed, 77 insertions(+), 4 deletions(-) diff --git a/gui/SimOptionsWindow.cpp b/gui/SimOptionsWindow.cpp index 3342b03..49fa931 100644 --- a/gui/SimOptionsWindow.cpp +++ b/gui/SimOptionsWindow.cpp @@ -1,14 +1,65 @@ + +/// \cond +// C headers +// C++ headers +#include +// 3rd party headers +/// \endcond + +// qtrocket headers +#include "QtRocket.h" #include "SimOptionsWindow.h" #include "ui_SimOptionsWindow.h" +#include "sim/SimulationOptions.h" + SimOptionsWindow::SimOptionsWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::SimOptionsWindow) { ui->setupUi(this); + + // populate the combo boxes + QtRocket* qtrocket = QtRocket::getInstance(); + + std::shared_ptr options(new sim::SimulationOptions); + std::vector atmosphereModels = options->getAvailableAtmosphereModels(); + std::vector gravityModels = options->getAvailableGravityModels(); + + for(const auto& i : atmosphereModels) + { + ui->atmosphereModelCombo->addItem(QString::fromStdString(i)); + } + for(const auto& i : gravityModels) + { + ui->gravityModelCombo->addItem(QString::fromStdString(i)); + } } SimOptionsWindow::~SimOptionsWindow() { delete ui; } + +void SimOptionsWindow::on_buttonBox_rejected() +{ + this->close(); +} + + +void SimOptionsWindow::on_buttonBox_accepted() +{ + QtRocket* qtrocket = QtRocket::getInstance(); + + std::shared_ptr options(new sim::SimulationOptions); + + options->setTimeStep(ui->timeStep->text().toDouble()); + options->setGravityModel(ui->gravityModelCombo->currentText().toStdString()); + options->setAtmosphereModel(ui->atmosphereModelCombo->currentText().toStdString()); + qtrocket->setSimulationOptions(options); + + this->close(); + + +} + diff --git a/gui/SimOptionsWindow.h b/gui/SimOptionsWindow.h index 9d160b1..203b918 100644 --- a/gui/SimOptionsWindow.h +++ b/gui/SimOptionsWindow.h @@ -15,6 +15,11 @@ public: explicit SimOptionsWindow(QWidget *parent = nullptr); ~SimOptionsWindow(); +private slots: + void on_buttonBox_rejected(); + + void on_buttonBox_accepted(); + private: Ui::SimOptionsWindow *ui; }; diff --git a/gui/SimOptionsWindow.ui b/gui/SimOptionsWindow.ui index 1cbe0ce..eec5505 100644 --- a/gui/SimOptionsWindow.ui +++ b/gui/SimOptionsWindow.ui @@ -26,7 +26,7 @@ 60 20 261 - 131 + 156 diff --git a/sim/SimulationOptions.h b/sim/SimulationOptions.h index 68cba03..6b3db27 100644 --- a/sim/SimulationOptions.h +++ b/sim/SimulationOptions.h @@ -4,6 +4,7 @@ /// \cond // C headers // C++ headers +#include #include #include #include @@ -32,9 +33,9 @@ class SimulationOptions public: SimulationOptions() { - setTimeStep(0.01); - setGravityModel("Constant Gravity"); - setAtmosphereModel("Constant Atmosphere"); + //setTimeStep(0.01); + //setGravityModel("Constant Gravity"); + //setAtmosphereModel("Constant Atmosphere"); } ~SimulationOptions() = default; SimulationOptions(const SimulationOptions&) = delete; @@ -42,6 +43,22 @@ public: SimulationOptions& operator=(const SimulationOptions&) = delete; SimulationOptions& operator=(SimulationOptions&&) = delete; + std::vector getAvailableGravityModels() + { + std::vector retVal(gravityModels.size()); + std::transform(gravityModels.begin(), gravityModels.end(), std::back_inserter(retVal), + [](auto& i) { return i.first; }); + return retVal; + } + + std::vector getAvailableAtmosphereModels() + { + std::vector retVal(atmosphereModels.size()); + std::transform(atmosphereModels.begin(), atmosphereModels.end(), std::back_inserter(retVal), + [](auto& i) { return i.first; }); + return retVal; + } + void setTimeStep(double t) { timeStep = t; } void setGravityModel(const std::string& model) { From 5d2becd2b4a22b91467198ba20b8bd5e8de5cc40 Mon Sep 17 00:00:00 2001 From: Travis Hunter Date: Tue, 25 Apr 2023 20:35:17 -0600 Subject: [PATCH 2/3] motor model selection working with RSE files --- QtRocket.cpp | 3 --- gui/MainWindow.cpp | 17 +++++++++++++---- gui/MainWindow.h | 5 +++++ gui/MainWindow.ui | 7 +++++++ model/MotorModel.cpp | 17 +++++++++++++++++ model/MotorModel.h | 2 ++ model/Rocket.cpp | 9 +++------ model/Rocket.h | 1 - model/ThrustCurve.cpp | 6 ------ sim/Propagator.cpp | 7 ++++--- sim/Propagator.h | 2 ++ sim/SimulationOptions.h | 16 ++++++++++------ utils/RSEDatabaseLoader.cpp | 17 +++++++++++++++++ utils/RSEDatabaseLoader.h | 4 +++- 14 files changed, 83 insertions(+), 30 deletions(-) diff --git a/QtRocket.cpp b/QtRocket.cpp index 57522af..279b74b 100644 --- a/QtRocket.cpp +++ b/QtRocket.cpp @@ -13,9 +13,6 @@ // qtrocket headers #include "QtRocket.h" #include "gui/MainWindow.h" -#include "sim/ConstantAtmosphere.h" -#include "sim/ConstantGravityModel.h" - // Initialize static member data QtRocket* QtRocket::instance = nullptr; diff --git a/gui/MainWindow.cpp b/gui/MainWindow.cpp index ceec741..69015e1 100644 --- a/gui/MainWindow.cpp +++ b/gui/MainWindow.cpp @@ -90,9 +90,8 @@ void MainWindow::on_testButton2_clicked() double initialVelocityX = initialVelocity * std::cos(initialAngle / 57.2958); double initialVelocityZ = initialVelocity * std::sin(initialAngle / 57.2958); - std::shared_ptr rocket = std::make_shared(); - QtRocket::getInstance()->addRocket(rocket); std::vector initialState = {0.0, 0.0, 0.0, initialVelocityX, 0.0, initialVelocityZ, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; + auto rocket = QtRocket::getInstance()->getRocket(); rocket->setInitialState(initialState); rocket->setMass(mass); rocket->setDragCoefficient(dragCoeff); @@ -111,14 +110,14 @@ void MainWindow::on_loadRSE_button_clicked() "/home", tr("Rocksim Engine Files (*.rse)")); - utils::RSEDatabaseLoader loader(rseFile.toStdString()); + rseDatabase.reset(new utils::RSEDatabaseLoader(rseFile.toStdString())); ui->rocketPartButtons->findChild(QString("databaseFileLine"))->setText(rseFile); QComboBox* engineSelector = ui->rocketPartButtons->findChild(QString("engineSelectorComboBox")); - const std::vector& motors = loader.getMotors(); + const std::vector& motors = rseDatabase->getMotors(); for(const auto& motor : motors) { std::cout << "Adding: " << motor.data.commonName << std::endl; @@ -146,3 +145,13 @@ void MainWindow::on_actionSimulation_Options_triggered() } + +void MainWindow::on_setMotor_clicked() +{ + QString motorName = ui->engineSelectorComboBox->currentText(); + model::MotorModel mm = rseDatabase->getMotorModelByName(motorName.toStdString()); + QtRocket::getInstance()->getRocket()->setMotorModel(mm); + + +} + diff --git a/gui/MainWindow.h b/gui/MainWindow.h index e762480..986f8d5 100644 --- a/gui/MainWindow.h +++ b/gui/MainWindow.h @@ -4,6 +4,7 @@ /// \cond // C headers // C++ headers +#include // 3rd Party headers #include /// \endcond @@ -12,6 +13,7 @@ #include "QtRocket.h" #include "gui/SimOptionsWindow.h" +#include "utils/RSEDatabaseLoader.h" QT_BEGIN_NAMESPACE @@ -47,10 +49,13 @@ private slots: void on_actionSimulation_Options_triggered(); + void on_setMotor_clicked(); + private: Ui::MainWindow* ui; QtRocket* qtRocket; SimOptionsWindow* simOptionsWindow{nullptr}; + std::unique_ptr rseDatabase; }; #endif // MAINWINDOW_H diff --git a/gui/MainWindow.ui b/gui/MainWindow.ui index f1d3b91..b7562a9 100644 --- a/gui/MainWindow.ui +++ b/gui/MainWindow.ui @@ -211,6 +211,13 @@ + + + + Set Motor + + + diff --git a/model/MotorModel.cpp b/model/MotorModel.cpp index 1319a74..80c5c75 100644 --- a/model/MotorModel.cpp +++ b/model/MotorModel.cpp @@ -9,6 +9,7 @@ #include "model/MotorModel.h" #include "utils/math/Constants.h" #include "utils/math/UtilityMathFunctions.h" +#include "utils/Logger.h" namespace model { @@ -69,6 +70,22 @@ double MotorModel::getMass(double simTime) const } } +double MotorModel::getThrust(double simTime) +{ + + if(simTime > thrust.getMaxTime() + ignitionTime) + { + if(!burnOutOccurred) + { + utils::Logger::getInstance()->info("motor burnout occurred: " + std::to_string(simTime)); + burnOutOccurred = true; + } + return 0.0; + } + utils::Logger::getInstance()->info("simTime: " + std::to_string(simTime) + ": thrust: " + std::to_string(thrust.getThrust(simTime))); + return thrust.getThrust(simTime); +} + void MotorModel::setMetaData(const MetaData& md) { data = md; diff --git a/model/MotorModel.h b/model/MotorModel.h index 17524c7..39729d9 100644 --- a/model/MotorModel.h +++ b/model/MotorModel.h @@ -396,11 +396,13 @@ public: void startMotor(double startTime) { ignitionOccurred = true; ignitionTime = startTime; } + void addThrustCurve(const ThrustCurve& tc) { thrust = tc; } // Thrust parameters MetaData data; private: bool ignitionOccurred{false}; + bool burnOutOccurred{false}; double emptyMass; double isp; double maxTime; diff --git a/model/Rocket.cpp b/model/Rocket.cpp index 0a7b854..4946a7c 100644 --- a/model/Rocket.cpp +++ b/model/Rocket.cpp @@ -9,6 +9,8 @@ Rocket::Rocket() : propagator(this) void Rocket::launch() { propagator.setTimeStep(QtRocket::getInstance()->getTimeStep()); + propagator.clearStates(); + mm.startMotor(0.0); propagator.runUntilTerminate(); } @@ -28,10 +30,5 @@ bool Rocket::terminateCondition(const std::pair>& co double Rocket::getThrust(double t) { - return tc.getThrust(t); -} - -void Rocket::setThrustCurve(const ThrustCurve& curve) -{ - tc = curve; + return mm.getThrust(t); } diff --git a/model/Rocket.h b/model/Rocket.h index fb24f8d..67ea9a2 100644 --- a/model/Rocket.h +++ b/model/Rocket.h @@ -114,7 +114,6 @@ private: double mass; /// @todo get rid of this, should be dynamically computed, but is the current rocket mass model::MotorModel mm; /// Current Motor Model - ThrustCurve tc; /// @todo get rid of this, should be returned from the MotorModel }; diff --git a/model/ThrustCurve.cpp b/model/ThrustCurve.cpp index a19cb5f..fd7a803 100644 --- a/model/ThrustCurve.cpp +++ b/model/ThrustCurve.cpp @@ -55,12 +55,6 @@ void ThrustCurve::setIgnitionTime(double t) double ThrustCurve::getThrust(double t) { // calculate t relative to the start time of the motor - static bool burnout{false}; - if(!burnout && t >= (maxTime + ignitionTime)) - { - burnout = true; - utils::Logger::getInstance()->info("Motor burnout at time: " + std::to_string(t)); - } t -= ignitionTime; if(t < 0.0 || t > maxTime) { diff --git a/sim/Propagator.cpp b/sim/Propagator.cpp index d812ee8..7f7d525 100644 --- a/sim/Propagator.cpp +++ b/sim/Propagator.cpp @@ -2,6 +2,7 @@ /// \cond // C headers // C++ headers +#include #include #include #include @@ -97,20 +98,20 @@ double Propagator::getMass() double Propagator::getForceX() { QtRocket* qtrocket = QtRocket::getInstance(); - return - qtrocket->getAtmosphereModel()->getDensity(currentState[3])/ 2.0 * 0.008107 * rocket->getDragCoefficient() * currentState[3]* currentState[3]; + return (currentState[3] >= 0 ? -1.0 : 1.0) * qtrocket->getAtmosphereModel()->getDensity(currentState[2])/ 2.0 * 0.008107 * rocket->getDragCoefficient() * currentState[3]* currentState[3]; } double Propagator::getForceY() { QtRocket* qtrocket = QtRocket::getInstance(); - return -qtrocket->getAtmosphereModel()->getDensity(currentState[3]) / 2.0 * 0.008107 * rocket->getDragCoefficient() * currentState[4]* currentState[4]; + return (currentState[4] >= 0 ? -1.0 : 1.0) * qtrocket->getAtmosphereModel()->getDensity(currentState[2]) / 2.0 * 0.008107 * rocket->getDragCoefficient() * currentState[4]* currentState[4]; } double Propagator::getForceZ() { QtRocket* qtrocket = QtRocket::getInstance(); double gravity = (qtrocket->getGravityModel()->getAccel(currentState[0], currentState[1], currentState[2])).x3; - double airDrag = -qtrocket->getAtmosphereModel()->getDensity(currentState[3]) / 2.0 * 0.008107 * rocket->getDragCoefficient() * currentState[5]* currentState[5]; + double airDrag = (currentState[5] >= 0 ? -1.0 : 1.0) * qtrocket->getAtmosphereModel()->getDensity(currentState[2]) / 2.0 * 0.008107 * rocket->getDragCoefficient() * currentState[5]* currentState[5]; double thrust = rocket->getThrust(currentTime); return gravity + airDrag + thrust; } diff --git a/sim/Propagator.h b/sim/Propagator.h index 613aef5..f483a35 100644 --- a/sim/Propagator.h +++ b/sim/Propagator.h @@ -51,6 +51,8 @@ public: const std::vector>>& getStates() const { return states; } + void clearStates() { states.clear(); } + void setTimeStep(double ts) { timeStep = ts; } void setSaveStats(bool s) { saveStates = s; } diff --git a/sim/SimulationOptions.h b/sim/SimulationOptions.h index 6b3db27..b0aafa4 100644 --- a/sim/SimulationOptions.h +++ b/sim/SimulationOptions.h @@ -33,9 +33,9 @@ class SimulationOptions public: SimulationOptions() { - //setTimeStep(0.01); - //setGravityModel("Constant Gravity"); - //setAtmosphereModel("Constant Atmosphere"); + setTimeStep(0.01); + setGravityModel("Constant Gravity"); + setAtmosphereModel("Constant Atmosphere"); } ~SimulationOptions() = default; SimulationOptions(const SimulationOptions&) = delete; @@ -79,16 +79,20 @@ public: if(model == "Constant Atmosphere") { atmosphereModel = model; - atmosphereModels[gravityModel].reset(new sim::ConstantAtmosphere); + atmosphereModels[atmosphereModel].reset(new sim::ConstantAtmosphere); } else if(model == "US Standard 1976") { atmosphereModel = model; - atmosphereModels[gravityModel].reset(new sim::USStandardAtmosphere); + atmosphereModels[atmosphereModel].reset(new sim::USStandardAtmosphere); } } - std::shared_ptr getAtmosphericModel() { return atmosphereModels[atmosphereModel]; } + std::shared_ptr getAtmosphericModel() + { + auto retVal = atmosphereModels[atmosphereModel]; + return retVal; + } std::shared_ptr getGravityModel() { return gravityModels[gravityModel]; } double getTimeStep() { return timeStep; } diff --git a/utils/RSEDatabaseLoader.cpp b/utils/RSEDatabaseLoader.cpp index cc4f766..3d9eba8 100644 --- a/utils/RSEDatabaseLoader.cpp +++ b/utils/RSEDatabaseLoader.cpp @@ -3,6 +3,7 @@ // C headers // C++ headers #include +#include #include // 3rd party headers @@ -12,6 +13,7 @@ // qtrocket headers #include "utils/RSEDatabaseLoader.h" #include "QtRocket.h" +#include "Logger.h" namespace utils { @@ -33,6 +35,19 @@ RSEDatabaseLoader::RSEDatabaseLoader(const std::string& filename) RSEDatabaseLoader::~RSEDatabaseLoader() {} +model::MotorModel RSEDatabaseLoader::getMotorModelByName(const std::string &name) +{ + + auto mm = std::find_if(motors.begin(), motors.end(), + [&name](const auto& i) { return name == i.data.commonName; }); + if(mm == motors.end()) + { + Logger::getInstance()->error("Unable to locate " + name + " in RSE database"); + return model::MotorModel(); + } + return *mm; +} + void RSEDatabaseLoader::buildAndAppendMotorModel(boost::property_tree::ptree& v) { model::MotorModel::MetaData mm; @@ -70,7 +85,9 @@ void RSEDatabaseLoader::buildAndAppendMotorModel(boost::property_tree::ptree& v) thrustData.push_back(std::make_pair(tdata, fdata)); } + ThrustCurve tc(thrustData); model::MotorModel motorModel; + motorModel.addThrustCurve(tc); motorModel.moveMetaData(std::move(mm)); motors.emplace_back(std::move(motorModel)); } diff --git a/utils/RSEDatabaseLoader.h b/utils/RSEDatabaseLoader.h index 15a3b79..672db5f 100644 --- a/utils/RSEDatabaseLoader.h +++ b/utils/RSEDatabaseLoader.h @@ -23,7 +23,9 @@ public: RSEDatabaseLoader(const std::string& filename); ~RSEDatabaseLoader(); - const std::vector& getMotors() const { return motors; } + std::vector& getMotors() { return motors; } + + model::MotorModel getMotorModelByName(const std::string& name); private: std::vector motors; From fc57b00ec4da72f85d57da42b1821228c2749fd9 Mon Sep 17 00:00:00 2001 From: Travis Hunter Date: Wed, 26 Apr 2023 06:43:46 -0600 Subject: [PATCH 3/3] fix simTime restart to 0.0 --- gui/SimOptionsWindow.cpp | 1 - model/Rocket.cpp | 1 + sim/Propagator.h | 1 + 3 files changed, 2 insertions(+), 1 deletion(-) diff --git a/gui/SimOptionsWindow.cpp b/gui/SimOptionsWindow.cpp index 49fa931..a357db2 100644 --- a/gui/SimOptionsWindow.cpp +++ b/gui/SimOptionsWindow.cpp @@ -20,7 +20,6 @@ SimOptionsWindow::SimOptionsWindow(QWidget *parent) : ui->setupUi(this); // populate the combo boxes - QtRocket* qtrocket = QtRocket::getInstance(); std::shared_ptr options(new sim::SimulationOptions); std::vector atmosphereModels = options->getAvailableAtmosphereModels(); diff --git a/model/Rocket.cpp b/model/Rocket.cpp index 4946a7c..a1c860a 100644 --- a/model/Rocket.cpp +++ b/model/Rocket.cpp @@ -10,6 +10,7 @@ void Rocket::launch() { propagator.setTimeStep(QtRocket::getInstance()->getTimeStep()); propagator.clearStates(); + propagator.setCurrentTime(0.0); mm.startMotor(0.0); propagator.runUntilTerminate(); } diff --git a/sim/Propagator.h b/sim/Propagator.h index f483a35..9e1151b 100644 --- a/sim/Propagator.h +++ b/sim/Propagator.h @@ -52,6 +52,7 @@ public: const std::vector>>& getStates() const { return states; } void clearStates() { states.clear(); } + void setCurrentTime(double t) { currentTime = t; } void setTimeStep(double ts) { timeStep = ts; }