diff --git a/QtRocket.h b/QtRocket.h index 0a388b2..0f56c6a 100644 --- a/QtRocket.h +++ b/QtRocket.h @@ -11,6 +11,8 @@ #include "sim/AtmosphericModel.h" #include "sim/GravityModel.h" +#include "model/MotorModel.h" + /** * @brief The QtRocket class is the master controller for the QtRocket application. * It is the singleton that controls the interaction of the various components of @@ -43,6 +45,9 @@ private: static std::mutex mtx; static QtRocket* instance; + // Motor "database(s)" + std::vector motorModels; + utils::Logger* logger; std::shared_ptr rocket; diff --git a/gui/MainWindow.cpp b/gui/MainWindow.cpp index d2d1ff2..6e72e3e 100644 --- a/gui/MainWindow.cpp +++ b/gui/MainWindow.cpp @@ -6,6 +6,8 @@ #include "sim/RK4Solver.h" #include "model/Rocket.h" +#include "utils/RSEDatabaseLoader.h" + #include #include @@ -56,6 +58,7 @@ void MainWindow::on_testButton1_clicked() plot->yAxis->setRange(0, 1); plot->replot(); + utils::RSEDatabaseLoader("Aerotech.rse"); } diff --git a/model/MotorModel.h b/model/MotorModel.h index c4cda9e..8f54b9c 100644 --- a/model/MotorModel.h +++ b/model/MotorModel.h @@ -9,14 +9,18 @@ #include #include "Thrustcurve.h" -#include "MotorCase.h" class MotorModel { public: MotorModel(); + MotorModel(const MotorModel&) = default; + MotorModel(MotorModel&&) = default; ~MotorModel(); + MotorModel& operator=(const MotorModel&) = default; + MotorModel& operator=(MotorModel&&) = default; + void setDataFromJsonString(const std::string& jsonString); enum class AVAILABILITY @@ -31,7 +35,8 @@ public: CAR, NAR, TRA, - UNC + UNC, + UNK }; enum class MOTORTYPE @@ -44,8 +49,12 @@ public: struct MotorAvailability { MotorAvailability(const AVAILABILITY& a) : availability(a) {} + MotorAvailability(MotorAvailability&&) = default; MotorAvailability() : MotorAvailability(AVAILABILITY::REGULAR) {} + MotorAvailability& operator=(const MotorAvailability&) = default; + MotorAvailability& operator=(MotorAvailability&&) = default; + AVAILABILITY availability{AVAILABILITY::REGULAR}; std::string str() { @@ -59,8 +68,12 @@ public: struct CertOrg { CertOrg(const CERTORG& c) : org(c) {} + CertOrg(CertOrg&&) = default; CertOrg() : CertOrg(CERTORG::UNC) {} + CertOrg& operator=(const CertOrg&) = default; + CertOrg& operator=(CertOrg&&) = default; + CERTORG org{CERTORG::UNC}; std::string str() { @@ -72,16 +85,22 @@ public: return std::string("National Association of Rocketry"); else if(org == CERTORG::TRA) return std::string("Tripoli Rocketry Association, Inc."); - else // Uncertified + else if(org == CERTORG::UNC) return std::string("Uncertified"); + else // UNK - Unknown + return std::string("Unkown"); } }; struct MotorType { MotorType(const MOTORTYPE& t) : type(t) {} + MotorType(MotorType&&) = default; MotorType() : MotorType(MOTORTYPE::SU) {} + MotorType& operator=(const MotorType&) = default; + MotorType& operator=(MotorType&&) = default; + MOTORTYPE type; std::string str() { @@ -95,7 +114,8 @@ public: }; -private: +// TODO: make these private. Public just for testing +//private: // Needed for boost serialize friend class boost::serialization::access; template @@ -112,16 +132,16 @@ private: int diameter{0}; std::string impulseClass; // 'A', 'B', '1/2A', 'M', etc std::string infoUrl{""}; - int length; - std::string manufacturer; + double length{0.0}; + std::string manufacturer{""}; double maxThrust{0.0}; std::string motorIdTC{""}; // 24 character hex string used by thrustcurve to ID a motor std::string propType{""}; // black powder, etc double propWeight{0.0}; bool sparky{false}; - double totalImpulse; - double totalWeight; + double totalImpulse{0.0}; + double totalWeight{0.0}; MotorType type{MOTORTYPE::SU}; std::string lastUpdated{""}; diff --git a/model/Thrustcurve.h b/model/Thrustcurve.h index 5b76a78..6a4408c 100644 --- a/model/Thrustcurve.h +++ b/model/Thrustcurve.h @@ -20,6 +20,8 @@ public: * for all requested times. */ Thrustcurve(); + Thrustcurve(const Thrustcurve&) = default; + Thrustcurve(Thrustcurve&&) = default; ~Thrustcurve(); Thrustcurve& operator=(const Thrustcurve& rhs) @@ -31,7 +33,14 @@ public: ignitionTime = rhs.ignitionTime; } return *this; + } + Thrustcurve& operator=(Thrustcurve&& rhs) + { + thrustCurve = std::move(rhs.thrustCurve); + maxTime = std::move(rhs.maxTime); + ignitionTime = std::move(rhs.ignitionTime); + return *this; } /** diff --git a/qtrocket.pro b/qtrocket.pro index b71fb95..d8c0aaf 100644 --- a/qtrocket.pro +++ b/qtrocket.pro @@ -31,6 +31,7 @@ SOURCES += \ utils/BinMap.cpp \ utils/CurlConnection.cpp \ utils/Logger.cpp \ + utils/RSEDatabaseLoader.cpp \ utils/ThreadPool.cpp \ utils/ThrustCurveAPI.cpp \ utils/math/Quaternion.cpp \ @@ -63,6 +64,7 @@ HEADERS += \ utils/BinMap.h \ utils/CurlConnection.h \ utils/Logger.h \ + utils/RSEDatabaseLoader.h \ utils/TSQueue.h \ utils/ThreadPool.h \ utils/ThrustCurveAPI.h \ diff --git a/utils/RSEDatabaseLoader.cpp b/utils/RSEDatabaseLoader.cpp new file mode 100644 index 0000000..696a539 --- /dev/null +++ b/utils/RSEDatabaseLoader.cpp @@ -0,0 +1,104 @@ +#include "RSEDatabaseLoader.h" + +#include + +#include +#include + +namespace utils { + +RSEDatabaseLoader::RSEDatabaseLoader(const std::string& filename) + : motors(), + tree() +{ + boost::property_tree::read_xml(filename, tree); + + // Get the first engine + for(boost::property_tree::ptree::value_type& v : tree.get_child("engine-database.engine-list")) + { + buildAndAppendMotorModel(v.second); + } + +} + +RSEDatabaseLoader::~RSEDatabaseLoader() +{} + +void RSEDatabaseLoader::buildAndAppendMotorModel(boost::property_tree::ptree& v) +{ + MotorModel mm; + mm.availability = MotorModel::MotorAvailability(MotorModel::AVAILABILITY::REGULAR); + mm.avgThrust = v.get(".avgThrust", 0.0); + mm.burnTime = v.get(".burn-time", 0.0); + mm.certOrg = MotorModel::CertOrg(MotorModel::CERTORG::UNK); + mm.commonName = v.get(".code", ""); + + // mm.delays = extract vector from csv list + + // mm.designation = What is this? + + // This is in the form of dia="18.", or dia="38." + { + std::string dia = v.get(".dia", ""); + dia = dia.substr(0, dia.length() - 1); + mm.diameter = std::stoi(dia); + } + // impulse class is the motor letter designation. extract from the first character + // of the commonName since it isn't given explicity in the RSE file + mm.impulseClass = mm.commonName[0]; + + // infoUrl not present in RSE file + mm.infoUrl = ""; + mm.length = v.get(".len", 0.0); + mm.manufacturer = v.get(".mfg", ""); + mm.maxThrust = v.get(".peakThrust", 0.0); + mm.propWeight = v.get(".propWt", 0.0); + mm.totalImpulse = v.get(".Itot", 0.0); + + { + std::string type = v.get(".Type"); + MotorModel::MotorType mt(MotorModel::MOTORTYPE::SU); + if(type.compare("reloadable") == 0) + { + mt = MotorModel::MOTORTYPE::RELOAD; + } + else if(type.compare("hybrid") == 0) + { + mt = MotorModel::MOTORTYPE::HYBRID; + } + else + { + // single use, which is default + } + mm.type = mt; + } + + // Now get the thrust data + std::vector> thrustData; + for(boost::property_tree::ptree::value_type& w : v.get_child("data")) + { + double tdata = w.second.get(".t"); + double fdata = w.second.get(".f"); + thrustData.push_back(std::make_pair(tdata, fdata)); + } + std::cout << "\n--------------------------------------------\n"; + std::cout << "name: " << mm.commonName << std::endl; + std::cout << "length: " << mm.length << std::endl; + std::cout << "manufacturer: " << mm.manufacturer << std::endl; + std::cout << "maxThrust: " << mm.maxThrust << std::endl; + std::cout << "propWeight: " << mm.propWeight << std::endl; + std::cout << "totalImpulse: " << mm.totalImpulse << std::endl; + std::cout << "--------------------------------------------\n"; + /* + std::cout << "thrust data:\n"; + for(const auto& i : thrustData) + { + std::cout << "(" << i.first << ", " << i.second << ")\n"; + } + */ + + motors.emplace_back(std::move(mm)); +} + + +} // namespace utils diff --git a/utils/RSEDatabaseLoader.h b/utils/RSEDatabaseLoader.h new file mode 100644 index 0000000..19be9c7 --- /dev/null +++ b/utils/RSEDatabaseLoader.h @@ -0,0 +1,30 @@ +#ifndef UTILS_RSEDATABASELOADER_H +#define UTILS_RSEDATABASELOADER_H + +#include "model/MotorModel.h" + +#include +#include + +#include + +namespace utils { + +class RSEDatabaseLoader +{ +public: + RSEDatabaseLoader(const std::string& filename); + ~RSEDatabaseLoader(); + +private: + + std::vector motors; + + void buildAndAppendMotorModel(boost::property_tree::ptree& v); + + boost::property_tree::ptree tree; +}; + +} // namespace utils + +#endif // UTILS_RSEDATABASELOADER_H