This commit is contained in:
Travis Hunter 2024-08-16 18:18:49 -06:00
parent cb1a8c379b
commit 6ddba41dd6
5 changed files with 70 additions and 62 deletions

View File

@ -6,7 +6,7 @@ set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets LinguistTools)

View File

@ -10,59 +10,57 @@
// qtrocket headers
#include "Logger.h"
namespace utils
{
Logger* Logger::instance = nullptr;
Logger* Logger::getInstance()
{
if(!instance)
{
instance = new Logger();
}
return instance;
if(!instance)
{
instance = new Logger();
}
return instance;
}
Logger::Logger()
{
outFile.open("log.txt");
outFile.open("log.txt");
}
Logger::~Logger()
{
outFile.close();
outFile.close();
}
void Logger::log(std::string_view msg, const LogLevel& lvl)
{
std::lock_guard<std::mutex> lck(mtx);
// The fallthrough is intentional. Logging is automatically enabled for
// all levels at or lower than the current level.
switch(currentLevel)
{
case PERF_:
if(lvl == PERF_)
std::lock_guard<std::mutex> lck(mtx);
// The fallthrough is intentional. Logging is automatically enabled for
// all levels at or lower than the current level.
switch(currentLevel)
{
case LogLevel::PERF:
if(lvl == LogLevel::PERF)
{
outFile << "[PERF] " << msg << std::endl;
std::cout << "[PERF] " << msg << "\n";
std::cout << "[PERF] " << msg << "\n";
}
[[fallthrough]];
case DEBUG_:
if(lvl == DEBUG_)
case LogLevel::DEBUG:
if(lvl == LogLevel::DEBUG)
{
outFile << "[DEBUG] " << msg << std::endl;
std::cout << "[DEBUG] " << msg << "\n";
}
[[fallthrough]];
case INFO_:
if(lvl == INFO_)
case LogLevel::INFO:
if(lvl == LogLevel::INFO)
{
outFile << "[INFO] " << msg << std::endl;
std::cout << "[INFO] " << msg << "\n";
}
[[fallthrough]];
case WARN_:
if(lvl == WARN_)
case LogLevel::WARN:
if(lvl == LogLevel::WARN)
{
outFile << "[WARN] " << msg << std::endl;
std::cout << "[WARN] " << msg << "\n";
@ -71,7 +69,7 @@ void Logger::log(std::string_view msg, const LogLevel& lvl)
// Regardless of what level is set, ERROR is always logged, so
// rather than explicitly check for the ERROR case, we just use default case
default:
if(lvl == ERROR_)
if(lvl == LogLevel::ERROR)
{
outFile << "[ERROR] " << msg << std::endl;
std::cout << "[ERROR] " << msg << "\n";
@ -90,4 +88,3 @@ void Logger::log(std::ostream& o, const std::string& msg)
o << msg << std::endl;
}
} // namespace utils

View File

@ -11,22 +11,19 @@
// 3rd party headers
/// \endcond
namespace utils
{
/**
* @todo write docs
*/
class Logger
{
public:
enum LogLevel
enum class LogLevel
{
ERROR_,
WARN_,
INFO_,
DEBUG_,
PERF_
ERROR,
WARN,
INFO,
DEBUG,
PERF
};
static Logger* getInstance();
@ -39,11 +36,11 @@ public:
void setLogLevel(const LogLevel& lvl);
inline void error(std::string_view msg) { log(msg, ERROR_); }
inline void warn(std::string_view msg) { log(msg, WARN_); }
inline void info(std::string_view msg) { log(msg, INFO_); }
inline void debug(std::string_view msg) { log(msg, DEBUG_); }
inline void perf(std::string_view msg) { log(msg, PERF_); }
inline void error(std::string_view msg) { log(msg, LogLevel::ERROR); }
inline void warn(std::string_view msg) { log(msg, LogLevel::WARN); }
inline void info(std::string_view msg) { log(msg, LogLevel::INFO); }
inline void debug(std::string_view msg) { log(msg, LogLevel::DEBUG); }
inline void perf(std::string_view msg) { log(msg, LogLevel::PERF); }
void log(std::ostream& o, const std::string& msg);
@ -58,5 +55,4 @@ private:
Logger();
};
} // namespace utils
#endif // UTILS_LOGGER_H

View File

@ -12,11 +12,7 @@
/// \endcond
// qtrocket headers
#include "sim/DESolver.h"
#include "utils/Logger.h"
#include "utils/math/MathTypes.h"
namespace sim {
#include "Logger.h"
/**
* @brief Runge-Kutta 4th order coupled ODE solver.
@ -28,31 +24,28 @@ namespace sim {
* @tparam Ts
*/
template<typename T>
class RK4Solver : public DESolver<T>
class RK4Solver
{
public:
RK4Solver(std::function<std::pair<T, T>(T&, T&)> func)
RK4Solver(std::function<std::pair<T, T>(T&, T&)> func, double ts=0.1)
{
// This only works for Eigen Vector types.
// TODO: Figure out how to make this slightly more generic, but for now
// we're only using this for Vector3 and Quaternion types
static_assert(std::is_same<T, Vector3>::value
|| std::is_same<T, Quaternion>::value,
"You can only use Vector3 or Quaternion valued functions in RK4Solver");
// static_assert(std::is_same<T, Vector3>::value,
// "You can only use Vector3 or Quaternion valued functions in RK4Solver");
odes = func;
setTimeStep(ts);
}
virtual ~RK4Solver() {}
~RK4Solver() {}
void setTimeStep(double inTs) override { dt = inTs; halfDT = dt / 2.0; }
void setTimeStep(double inTs) { dt = inTs; halfDT = dt / 2.0; }
std::pair<T, T> step(T& state, T& rate) override
std::pair<T, T> step(T& state, T& rate)
{
std::pair<T, T> res;
if(dt == std::numeric_limits<double>::quiet_NaN())
{
utils::Logger::getInstance()->error("Calling RK4Solver without setting dt first is an error");
Logger::getInstance()->error("Calling RK4Solver without setting dt first is an error");
return res;
}
@ -94,6 +87,4 @@ private:
};
} // namespace sim
#endif // SIM_RK4SOLVER_H

View File

@ -1,12 +1,23 @@
#include "MainWindow.h"
/// \cond
// C Headers
// C++ Headers
#include <functional>
#include <utility>
// 3rd party headers
#include <QApplication>
#include <QLocale>
#include <QTranslator>
/// \endcond
#include "MainWindow.h"
#include "Logger.h"
#include "RK4Solver.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
auto* logger = Logger::getInstance();
logger->setLogLevel(Logger::LogLevel::PERF);
QTranslator translator;
const QStringList uiLanguages = QLocale::system().uiLanguages();
@ -17,7 +28,20 @@ int main(int argc, char *argv[])
break;
}
}
logger->debug("Starting MainWindow");
MainWindow w;
w.show();
return a.exec();
}
void test_RK4()
{
auto ode = [](double& x, double& r) -> std::pair<double, double>
{
}
}