Merge pull request #11 from cthunter01/development

Add SimulationOptions class to keep track of and encapsulate various …
This commit is contained in:
cthunter01 2023-04-24 20:52:01 -06:00 committed by GitHub
commit 696e81433e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 168 additions and 88 deletions

View File

@ -74,12 +74,9 @@ QtRocket::QtRocket()
logger = utils::Logger::getInstance();
running = false;
atmosphere =
std::make_shared<sim::ConstantAtmosphere>();
gravity =
std::make_shared<sim::ConstantGravityModel>();
// Need to set some sane defaults for Simulation Options
// The default constructor for SimulationOptions will do that for us, so just use that
setSimulationOptions(std::make_shared<sim::SimulationOptions>());
rocket =
std::make_shared<Rocket>();

View File

@ -16,6 +16,7 @@
#include "model/Rocket.h"
#include "sim/AtmosphericModel.h"
#include "sim/GravityModel.h"
#include "sim/SimulationOptions.h"
#include "utils/Logger.h"
/**
@ -37,15 +38,16 @@ public:
void runSim();
std::shared_ptr<sim::GravityModel> getGravityModel() { return gravity; }
std::shared_ptr<sim::AtmosphericModel> getAtmosphereModel() { return atmosphere; }
std::shared_ptr<sim::GravityModel> getGravityModel() { return simOptions->getGravityModel(); }
std::shared_ptr<sim::AtmosphericModel> getAtmosphereModel() { return simOptions->getAtmosphericModel(); }
double getTimeStep() { return simOptions->getTimeStep(); }
std::shared_ptr<Rocket> getRocket() { return rocket; }
void addMotorModels(std::vector<model::MotorModel>& m);
void addRocket(std::shared_ptr<Rocket> r) { rocket = r; }
std::shared_ptr<Rocket> getRocket() { return rocket; }
void setSimulationOptions(std::shared_ptr<sim::SimulationOptions> options) { simOptions = options; }
private:
QtRocket();
@ -63,9 +65,8 @@ private:
utils::Logger* logger;
std::shared_ptr<Rocket> rocket;
std::shared_ptr<sim::AtmosphericModel> atmosphere;
std::shared_ptr<sim::GravityModel> gravity;
std::shared_ptr<sim::SimulationOptions> simOptions;
};

View File

@ -19,7 +19,7 @@
#include "gui/AnalysisWindow.h"
#include "gui/MainWindow.h"
#include "gui/ThrustCurveMotorSelector.h"
#include "gui/SimulationOptions.h"
#include "gui/SimOptionsWindow.h"
#include "model/Rocket.h"
#include "utils/RSEDatabaseLoader.h"
@ -102,32 +102,6 @@ void MainWindow::on_testButton2_clicked()
aWindow.setModal(false);
aWindow.exec();
/*
const std::vector<std::pair<double, std::vector<double>>>& res = rocket.getStates();
for(const auto& i : res)
{
std::cout << i.first << ": " << "(" << i.second[0] << ", " << i.second[1] << ", " << i.second[2] << ")\n";
}
auto& plot = ui->plotWindow;
// generate some data:
QVector<double> tData(res.size()), zData(res.size());
for (int i = 0; i < tData.size(); ++i)
{
tData[i] = res[i].first;
zData[i] = res[i].second[2];
}
// create graph and assign data to it:
plot->addGraph();
plot->graph(0)->setData(tData, zData);
// give the axes some labels:
plot->xAxis->setLabel("time");
plot->yAxis->setLabel("Z");
// set axes ranges, so we see all data:
plot->xAxis->setRange(*std::min_element(std::begin(tData), std::end(tData)), *std::max_element(std::begin(tData), std::end(tData)));
plot->yAxis->setRange(*std::min_element(std::begin(zData), std::end(zData)), *std::max_element(std::begin(zData), std::end(zData)));
plot->replot();
*/
}
void MainWindow::on_loadRSE_button_clicked()
@ -135,7 +109,7 @@ void MainWindow::on_loadRSE_button_clicked()
QString rseFile = QFileDialog::getOpenFileName(this,
tr("Import RSE Database File"),
"/home",
tr("RSE Files (*.rse)"));
tr("Rocksim Engine Files (*.rse)"));
utils::RSEDatabaseLoader loader(rseFile.toStdString());
@ -166,7 +140,7 @@ void MainWindow::on_actionSimulation_Options_triggered()
{
if(!simOptionsWindow)
{
simOptionsWindow = new SimulationOptions(this);
simOptionsWindow = new SimOptionsWindow(this);
}
simOptionsWindow->show();

View File

@ -11,7 +11,7 @@
// qtrocket headers
#include "QtRocket.h"
#include "gui/SimulationOptions.h"
#include "gui/SimOptionsWindow.h"
QT_BEGIN_NAMESPACE
@ -51,6 +51,6 @@ private slots:
Ui::MainWindow* ui;
QtRocket* qtRocket;
SimulationOptions* simOptionsWindow{nullptr};
SimOptionsWindow* simOptionsWindow{nullptr};
};
#endif // MAINWINDOW_H

14
gui/SimOptionsWindow.cpp Normal file
View File

@ -0,0 +1,14 @@
#include "SimOptionsWindow.h"
#include "ui_SimOptionsWindow.h"
SimOptionsWindow::SimOptionsWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::SimOptionsWindow)
{
ui->setupUi(this);
}
SimOptionsWindow::~SimOptionsWindow()
{
delete ui;
}

22
gui/SimOptionsWindow.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef SIMOPTIONSWINDOW_H
#define SIMOPTIONSWINDOW_H
#include <QMainWindow>
namespace Ui {
class SimOptionsWindow;
}
class SimOptionsWindow : public QMainWindow
{
Q_OBJECT
public:
explicit SimOptionsWindow(QWidget *parent = nullptr);
~SimOptionsWindow();
private:
Ui::SimOptionsWindow *ui;
};
#endif // SIMOPTIONSWINDOW_H

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SimulationOptions</class>
<widget class="QMainWindow" name="SimulationOptions">
<class>SimOptionsWindow</class>
<widget class="QMainWindow" name="SimOptionsWindow">
<property name="geometry">
<rect>
<x>0</x>

View File

@ -1,14 +0,0 @@
#include "SimulationOptions.h"
#include "ui_SimulationOptions.h"
SimulationOptions::SimulationOptions(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::SimulationOptions)
{
ui->setupUi(this);
}
SimulationOptions::~SimulationOptions()
{
delete ui;
}

View File

@ -1,22 +0,0 @@
#ifndef SIMULATIONOPTIONS_H
#define SIMULATIONOPTIONS_H
#include <QMainWindow>
namespace Ui {
class SimulationOptions;
}
class SimulationOptions : public QMainWindow
{
Q_OBJECT
public:
explicit SimulationOptions(QWidget *parent = nullptr);
~SimulationOptions();
private:
Ui::SimulationOptions *ui;
};
#endif // SIMULATIONOPTIONS_H

View File

@ -1,5 +1,14 @@
/// \cond
// C headers
// C++ headers
// 3rd party headers
/// \endcond
// qtrocket headers
#include "model/MotorModel.h"
#include "utils/math/Constants.h"
#include "utils/math/UtilityMathFunctions.h"
namespace model
{
@ -33,7 +42,7 @@ double MotorModel::getMass(double simTime) const
// If thrustTime is equal to a data point that we have, then just return
// the mass at that time. Otherwise it fell between two points and we
// will interpolate
if(i->first == thrustTime)
if(utils::math::floatingPointEqual(i->first, thrustTime))
{
// return empty mass + remaining propellant mass
return emptyMass + i->second;
@ -53,6 +62,7 @@ double MotorModel::getMass(double simTime) const
return currentMass;
}
// motor has burned out
else
{
return emptyMass;

View File

@ -1,14 +1,14 @@
#include "Rocket.h"
#include "QtRocket.h"
Rocket::Rocket() : propagator(this)
{
propagator.setTimeStep(0.01);
//propagator.set
}
void Rocket::launch()
{
propagator.setTimeStep(QtRocket::getInstance()->getTimeStep());
propagator.runUntilTerminate();
}
@ -19,6 +19,7 @@ void Rocket::setMotorModel(const model::MotorModel& motor)
bool Rocket::terminateCondition(const std::pair<double, std::vector<double>>& cond)
{
// Terminate propagation when the z coordinate drops below zero
if(cond.second[2] < 0)
return true;
else

View File

@ -12,7 +12,7 @@ SOURCES += \
QtRocket.cpp \
gui/AboutWindow.cpp \
gui/AnalysisWindow.cpp \
gui/SimulationOptions.cpp \
gui/SimOptionsWindow.cpp \
gui/ThrustCurveMotorSelector.cpp \
gui/qcustomplot.cpp \
main.cpp \
@ -47,7 +47,7 @@ HEADERS += \
gui/AnalysisWindow.h \
gui/RocketTreeView.h \
gui/MainWindow.h \
gui/SimulationOptions.h \
gui/SimOptionsWindow.h \
gui/ThrustCurveMotorSelector.h \
gui/qcustomplot.h \
model/MotorCase.h \
@ -63,6 +63,7 @@ HEADERS += \
sim/GravityModel.h \
sim/Propagator.h \
sim/RK4Solver.h \
sim/SimulationOptions.h \
sim/SphericalGeoidModel.h \
sim/SphericalGravityModel.h \
sim/StateData.h \
@ -85,7 +86,7 @@ FORMS += \
gui/AboutWindow.ui \
gui/AnalysisWindow.ui \
gui/MainWindow.ui \
gui/SimulationOptions.ui \
gui/SimOptionsWindow.ui \
gui/ThrustCurveMotorSelector.ui
TRANSLATIONS += \

96
sim/SimulationOptions.h Normal file
View File

@ -0,0 +1,96 @@
#ifndef SIMULATIONOPTIONS_H
#define SIMULATIONOPTIONS_H
/// \cond
// C headers
// C++ headers
#include <map>
#include <memory>
#include <string>
#include <vector>
// 3rd party headers
/// \endcond
// qtrocket headers
#include "sim/GravityModel.h"
#include "sim/SphericalGravityModel.h"
#include "sim/ConstantGravityModel.h"
#include "sim/AtmosphericModel.h"
#include "sim/ConstantAtmosphere.h"
#include "sim/USStandardAtmosphere.h"
namespace sim
{
/**
* @brief The SimulationOptions class holds the available simulation options and environmental models
*/
class SimulationOptions
{
public:
SimulationOptions()
{
setTimeStep(0.01);
setGravityModel("Constant Gravity");
setAtmosphereModel("Constant Atmosphere");
}
~SimulationOptions() = default;
SimulationOptions(const SimulationOptions&) = delete;
SimulationOptions(SimulationOptions&&) = delete;
SimulationOptions& operator=(const SimulationOptions&) = delete;
SimulationOptions& operator=(SimulationOptions&&) = delete;
void setTimeStep(double t) { timeStep = t; }
void setGravityModel(const std::string& model)
{
if(model == "Constant Gravity")
{
gravityModel = model;
gravityModels[gravityModel].reset(new sim::ConstantGravityModel);
}
else if(model == "Spherical Gravity")
{
gravityModel = model;
gravityModels[gravityModel].reset(new sim::SphericalGravityModel);
}
}
void setAtmosphereModel(const std::string& model)
{
if(model == "Constant Atmosphere")
{
atmosphereModel = model;
atmosphereModels[gravityModel].reset(new sim::ConstantAtmosphere);
}
else if(model == "US Standard 1976")
{
atmosphereModel = model;
atmosphereModels[gravityModel].reset(new sim::USStandardAtmosphere);
}
}
std::shared_ptr<sim::AtmosphericModel> getAtmosphericModel() { return atmosphereModels[atmosphereModel]; }
std::shared_ptr<sim::GravityModel> getGravityModel() { return gravityModels[gravityModel]; }
double getTimeStep() { return timeStep; }
private:
std::map<std::string, std::shared_ptr<sim::AtmosphericModel>> atmosphereModels{
{"Constant Atmosphere", std::shared_ptr<sim::AtmosphericModel>()},
{"US Standard 1976", std::shared_ptr<sim::AtmosphericModel>()}};
std::map<std::string, std::shared_ptr<GravityModel>> gravityModels{
{"Constant Gravity", std::shared_ptr<sim::GravityModel>()},
{"Spherical Gravity", std::shared_ptr<sim::GravityModel>()}};
double timeStep{0.01};
std::string gravityModel{"Constant Gravity"}; /// Constant Gravity Model is the default
std::string atmosphereModel{"Constant Atmosphere"}; /// Constant Atmosphere Model is the default
};
}
#endif // SIMULATIONOPTIONS_H

View File

@ -19,7 +19,7 @@ namespace math
* places to ignore
*
* This is derived from the example on cppreference.com: https://en.cppreference.com/w/cpp/types/numeric_limits/epsilon
* The default ulp of 8 with a numeric_limits<double>::epsilon() of ~2e-16, so ulp of 8 yields 12
* The default ulp of 4 with a numeric_limits<double>::epsilon() of ~2e-16, so ulp of 4 yields 12
* significant figures. A ulp of 10 yields 6 significant figures.
* @param a the first double to compare
* @param b the second double to compare