motor model selection working with RSE files

This commit is contained in:
Travis Hunter 2023-04-25 20:35:17 -06:00
parent 89fb6d47d0
commit 5d2becd2b4
14 changed files with 83 additions and 30 deletions

View File

@ -13,9 +13,6 @@
// qtrocket headers // qtrocket headers
#include "QtRocket.h" #include "QtRocket.h"
#include "gui/MainWindow.h" #include "gui/MainWindow.h"
#include "sim/ConstantAtmosphere.h"
#include "sim/ConstantGravityModel.h"
// Initialize static member data // Initialize static member data
QtRocket* QtRocket::instance = nullptr; QtRocket* QtRocket::instance = nullptr;

View File

@ -90,9 +90,8 @@ void MainWindow::on_testButton2_clicked()
double initialVelocityX = initialVelocity * std::cos(initialAngle / 57.2958); double initialVelocityX = initialVelocity * std::cos(initialAngle / 57.2958);
double initialVelocityZ = initialVelocity * std::sin(initialAngle / 57.2958); double initialVelocityZ = initialVelocity * std::sin(initialAngle / 57.2958);
std::shared_ptr<Rocket> rocket = std::make_shared<Rocket>();
QtRocket::getInstance()->addRocket(rocket);
std::vector<double> initialState = {0.0, 0.0, 0.0, initialVelocityX, 0.0, initialVelocityZ, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; std::vector<double> 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->setInitialState(initialState);
rocket->setMass(mass); rocket->setMass(mass);
rocket->setDragCoefficient(dragCoeff); rocket->setDragCoefficient(dragCoeff);
@ -111,14 +110,14 @@ void MainWindow::on_loadRSE_button_clicked()
"/home", "/home",
tr("Rocksim Engine Files (*.rse)")); tr("Rocksim Engine Files (*.rse)"));
utils::RSEDatabaseLoader loader(rseFile.toStdString()); rseDatabase.reset(new utils::RSEDatabaseLoader(rseFile.toStdString()));
ui->rocketPartButtons->findChild<QLineEdit*>(QString("databaseFileLine"))->setText(rseFile); ui->rocketPartButtons->findChild<QLineEdit*>(QString("databaseFileLine"))->setText(rseFile);
QComboBox* engineSelector = QComboBox* engineSelector =
ui->rocketPartButtons->findChild<QComboBox*>(QString("engineSelectorComboBox")); ui->rocketPartButtons->findChild<QComboBox*>(QString("engineSelectorComboBox"));
const std::vector<model::MotorModel>& motors = loader.getMotors(); const std::vector<model::MotorModel>& motors = rseDatabase->getMotors();
for(const auto& motor : motors) for(const auto& motor : motors)
{ {
std::cout << "Adding: " << motor.data.commonName << std::endl; 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);
}

View File

@ -4,6 +4,7 @@
/// \cond /// \cond
// C headers // C headers
// C++ headers // C++ headers
#include <memory>
// 3rd Party headers // 3rd Party headers
#include <QMainWindow> #include <QMainWindow>
/// \endcond /// \endcond
@ -12,6 +13,7 @@
#include "QtRocket.h" #include "QtRocket.h"
#include "gui/SimOptionsWindow.h" #include "gui/SimOptionsWindow.h"
#include "utils/RSEDatabaseLoader.h"
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -47,10 +49,13 @@ private slots:
void on_actionSimulation_Options_triggered(); void on_actionSimulation_Options_triggered();
void on_setMotor_clicked();
private: private:
Ui::MainWindow* ui; Ui::MainWindow* ui;
QtRocket* qtRocket; QtRocket* qtRocket;
SimOptionsWindow* simOptionsWindow{nullptr}; SimOptionsWindow* simOptionsWindow{nullptr};
std::unique_ptr<utils::RSEDatabaseLoader> rseDatabase;
}; };
#endif // MAINWINDOW_H #endif // MAINWINDOW_H

View File

@ -211,6 +211,13 @@
<item row="1" column="0"> <item row="1" column="0">
<widget class="QComboBox" name="engineSelectorComboBox"/> <widget class="QComboBox" name="engineSelectorComboBox"/>
</item> </item>
<item row="1" column="1">
<widget class="QPushButton" name="setMotor">
<property name="text">
<string>Set Motor</string>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
<widget class="QPushButton" name="getTCMotorData"> <widget class="QPushButton" name="getTCMotorData">

View File

@ -9,6 +9,7 @@
#include "model/MotorModel.h" #include "model/MotorModel.h"
#include "utils/math/Constants.h" #include "utils/math/Constants.h"
#include "utils/math/UtilityMathFunctions.h" #include "utils/math/UtilityMathFunctions.h"
#include "utils/Logger.h"
namespace model 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) void MotorModel::setMetaData(const MetaData& md)
{ {
data = md; data = md;

View File

@ -396,11 +396,13 @@ public:
void startMotor(double startTime) { ignitionOccurred = true; ignitionTime = startTime; } void startMotor(double startTime) { ignitionOccurred = true; ignitionTime = startTime; }
void addThrustCurve(const ThrustCurve& tc) { thrust = tc; }
// Thrust parameters // Thrust parameters
MetaData data; MetaData data;
private: private:
bool ignitionOccurred{false}; bool ignitionOccurred{false};
bool burnOutOccurred{false};
double emptyMass; double emptyMass;
double isp; double isp;
double maxTime; double maxTime;

View File

@ -9,6 +9,8 @@ Rocket::Rocket() : propagator(this)
void Rocket::launch() void Rocket::launch()
{ {
propagator.setTimeStep(QtRocket::getInstance()->getTimeStep()); propagator.setTimeStep(QtRocket::getInstance()->getTimeStep());
propagator.clearStates();
mm.startMotor(0.0);
propagator.runUntilTerminate(); propagator.runUntilTerminate();
} }
@ -28,10 +30,5 @@ bool Rocket::terminateCondition(const std::pair<double, std::vector<double>>& co
double Rocket::getThrust(double t) double Rocket::getThrust(double t)
{ {
return tc.getThrust(t); return mm.getThrust(t);
}
void Rocket::setThrustCurve(const ThrustCurve& curve)
{
tc = curve;
} }

View File

@ -114,7 +114,6 @@ private:
double mass; /// @todo get rid of this, should be dynamically computed, but is the current rocket mass double mass; /// @todo get rid of this, should be dynamically computed, but is the current rocket mass
model::MotorModel mm; /// Current Motor Model model::MotorModel mm; /// Current Motor Model
ThrustCurve tc; /// @todo get rid of this, should be returned from the MotorModel
}; };

View File

@ -55,12 +55,6 @@ void ThrustCurve::setIgnitionTime(double t)
double ThrustCurve::getThrust(double t) double ThrustCurve::getThrust(double t)
{ {
// calculate t relative to the start time of the motor // 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; t -= ignitionTime;
if(t < 0.0 || t > maxTime) if(t < 0.0 || t > maxTime)
{ {

View File

@ -2,6 +2,7 @@
/// \cond /// \cond
// C headers // C headers
// C++ headers // C++ headers
#include <cmath>
#include <chrono> #include <chrono>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
@ -97,20 +98,20 @@ double Propagator::getMass()
double Propagator::getForceX() double Propagator::getForceX()
{ {
QtRocket* qtrocket = QtRocket::getInstance(); 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() double Propagator::getForceY()
{ {
QtRocket* qtrocket = QtRocket::getInstance(); 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() double Propagator::getForceZ()
{ {
QtRocket* qtrocket = QtRocket::getInstance(); QtRocket* qtrocket = QtRocket::getInstance();
double gravity = (qtrocket->getGravityModel()->getAccel(currentState[0], currentState[1], currentState[2])).x3; 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); double thrust = rocket->getThrust(currentTime);
return gravity + airDrag + thrust; return gravity + airDrag + thrust;
} }

View File

@ -51,6 +51,8 @@ public:
const std::vector<std::pair<double, std::vector<double>>>& getStates() const { return states; } const std::vector<std::pair<double, std::vector<double>>>& getStates() const { return states; }
void clearStates() { states.clear(); }
void setTimeStep(double ts) { timeStep = ts; } void setTimeStep(double ts) { timeStep = ts; }
void setSaveStats(bool s) { saveStates = s; } void setSaveStats(bool s) { saveStates = s; }

View File

@ -33,9 +33,9 @@ class SimulationOptions
public: public:
SimulationOptions() SimulationOptions()
{ {
//setTimeStep(0.01); setTimeStep(0.01);
//setGravityModel("Constant Gravity"); setGravityModel("Constant Gravity");
//setAtmosphereModel("Constant Atmosphere"); setAtmosphereModel("Constant Atmosphere");
} }
~SimulationOptions() = default; ~SimulationOptions() = default;
SimulationOptions(const SimulationOptions&) = delete; SimulationOptions(const SimulationOptions&) = delete;
@ -79,16 +79,20 @@ public:
if(model == "Constant Atmosphere") if(model == "Constant Atmosphere")
{ {
atmosphereModel = model; atmosphereModel = model;
atmosphereModels[gravityModel].reset(new sim::ConstantAtmosphere); atmosphereModels[atmosphereModel].reset(new sim::ConstantAtmosphere);
} }
else if(model == "US Standard 1976") else if(model == "US Standard 1976")
{ {
atmosphereModel = model; atmosphereModel = model;
atmosphereModels[gravityModel].reset(new sim::USStandardAtmosphere); atmosphereModels[atmosphereModel].reset(new sim::USStandardAtmosphere);
} }
} }
std::shared_ptr<sim::AtmosphericModel> getAtmosphericModel() { return atmosphereModels[atmosphereModel]; } std::shared_ptr<sim::AtmosphericModel> getAtmosphericModel()
{
auto retVal = atmosphereModels[atmosphereModel];
return retVal;
}
std::shared_ptr<sim::GravityModel> getGravityModel() { return gravityModels[gravityModel]; } std::shared_ptr<sim::GravityModel> getGravityModel() { return gravityModels[gravityModel]; }
double getTimeStep() { return timeStep; } double getTimeStep() { return timeStep; }

View File

@ -3,6 +3,7 @@
// C headers // C headers
// C++ headers // C++ headers
#include <iostream> #include <iostream>
#include <algorithm>
#include <cmath> #include <cmath>
// 3rd party headers // 3rd party headers
@ -12,6 +13,7 @@
// qtrocket headers // qtrocket headers
#include "utils/RSEDatabaseLoader.h" #include "utils/RSEDatabaseLoader.h"
#include "QtRocket.h" #include "QtRocket.h"
#include "Logger.h"
namespace utils { namespace utils {
@ -33,6 +35,19 @@ RSEDatabaseLoader::RSEDatabaseLoader(const std::string& filename)
RSEDatabaseLoader::~RSEDatabaseLoader() 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) void RSEDatabaseLoader::buildAndAppendMotorModel(boost::property_tree::ptree& v)
{ {
model::MotorModel::MetaData mm; model::MotorModel::MetaData mm;
@ -70,7 +85,9 @@ void RSEDatabaseLoader::buildAndAppendMotorModel(boost::property_tree::ptree& v)
thrustData.push_back(std::make_pair(tdata, fdata)); thrustData.push_back(std::make_pair(tdata, fdata));
} }
ThrustCurve tc(thrustData);
model::MotorModel motorModel; model::MotorModel motorModel;
motorModel.addThrustCurve(tc);
motorModel.moveMetaData(std::move(mm)); motorModel.moveMetaData(std::move(mm));
motors.emplace_back(std::move(motorModel)); motors.emplace_back(std::move(motorModel));
} }

View File

@ -23,7 +23,9 @@ public:
RSEDatabaseLoader(const std::string& filename); RSEDatabaseLoader(const std::string& filename);
~RSEDatabaseLoader(); ~RSEDatabaseLoader();
const std::vector<model::MotorModel>& getMotors() const { return motors; } std::vector<model::MotorModel>& getMotors() { return motors; }
model::MotorModel getMotorModelByName(const std::string& name);
private: private:
std::vector<model::MotorModel> motors; std::vector<model::MotorModel> motors;