/* * Copyright 2015, LAAS-CNRS * Author: Andrea Del Prete */ #ifndef HPP_CENTROIDAL_DYNAMICS_LOGGER_HH #define HPP_CENTROIDAL_DYNAMICS_LOGGER_HH /* --------------------------------------------------------------------- */ /* --- INCLUDE --------------------------------------------------------- */ /* --------------------------------------------------------------------- */ #include <Eigen/Dense> #include <hpp/centroidal-dynamics/local_config.hh> #include <map> #include <sstream> #include "boost/assign.hpp" namespace centroidal_dynamics { // #define LOGGER_VERBOSITY_ERROR // #define LOGGER_VERBOSITY_WARNING_ERROR // #define LOGGER_VERBOSITY_INFO_WARNING_ERROR // #define LOGGER_VERBOSITY_ALL #define LOGGER_VERBOSITY_ALL #define SEND_MSG(msg, type) getLogger().sendMsg(msg, type, __FILE__, __LINE__) #ifdef LOGGER_VERBOSITY_ERROR #define SEND_DEBUG_MSG(msg) #define SEND_INFO_MSG(msg) #define SEND_WARNING_MSG(msg) #define SEND_ERROR_MSG(msg) SEND_MSG(msg, MSG_TYPE_ERROR) #define SEND_DEBUG_STREAM_MSG(msg) #define SEND_INFO_STREAM_MSG(msg) #define SEND_WARNING_STREAM_MSG(msg) #define SEND_ERROR_STREAM_MSG(msg) SEND_MSG(msg, MSG_TYPE_ERROR_STREAM) #endif #ifdef LOGGER_VERBOSITY_WARNING_ERROR #define SEND_DEBUG_MSG(msg) #define SEND_INFO_MSG(msg) #define SEND_WARNING_MSG(msg) SEND_MSG(msg, MSG_TYPE_WARNING) #define SEND_ERROR_MSG(msg) SEND_MSG(msg, MSG_TYPE_ERROR) #define SEND_DEBUG_STREAM_MSG(msg) #define SEND_INFO_STREAM_MSG(msg) \ #define SEND_WARNING_STREAM_MSG(msg) SEND_MSG(msg, MSG_TYPE_WARNING_STREAM) #define SEND_ERROR_STREAM_MSG(msg) SEND_MSG(msg, MSG_TYPE_ERROR_STREAM) #endif #ifdef LOGGER_VERBOSITY_INFO_WARNING_ERROR #define SEND_DEBUG_MSG(msg) #define SEND_INFO_MSG(msg) SEND_MSG(msg, MSG_TYPE_INFO) #define SEND_WARNING_MSG(msg) SEND_MSG(msg, MSG_TYPE_WARNING) #define SEND_ERROR_MSG(msg) SEND_MSG(msg, MSG_TYPE_ERROR) #define SEND_DEBUG_STREAM_MSG(msg) #define SEND_INFO_STREAM_MSG(msg) SEND_MSG(msg, MSG_TYPE_INFO_STREAM) #define SEND_WARNING_STREAM_MSG(msg) SEND_MSG(msg, MSG_TYPE_WARNING_STREAM) #define SEND_ERROR_STREAM_MSG(msg) SEND_MSG(msg, MSG_TYPE_ERROR_STREAM) #endif #ifdef LOGGER_VERBOSITY_ALL #define SEND_DEBUG_MSG(msg) SEND_MSG(msg, MSG_TYPE_DEBUG) #define SEND_INFO_MSG(msg) SEND_MSG(msg, MSG_TYPE_INFO) #define SEND_WARNING_MSG(msg) SEND_MSG(msg, MSG_TYPE_WARNING) #define SEND_ERROR_MSG(msg) SEND_MSG(msg, MSG_TYPE_ERROR) #define SEND_DEBUG_STREAM_MSG(msg) SEND_MSG(msg, MSG_TYPE_DEBUG_STREAM) #define SEND_INFO_STREAM_MSG(msg) SEND_MSG(msg, MSG_TYPE_INFO_STREAM) #define SEND_WARNING_STREAM_MSG(msg) SEND_MSG(msg, MSG_TYPE_WARNING_STREAM) #define SEND_ERROR_STREAM_MSG(msg) SEND_MSG(msg, MSG_TYPE_ERROR_STREAM) #endif /** Enum representing the different kind of messages. */ enum CENTROIDAL_DYNAMICS_DLLAPI MsgType { MSG_TYPE_DEBUG = 0, MSG_TYPE_INFO = 1, MSG_TYPE_WARNING = 2, MSG_TYPE_ERROR = 3, MSG_TYPE_DEBUG_STREAM = 4, MSG_TYPE_INFO_STREAM = 5, MSG_TYPE_WARNING_STREAM = 6, MSG_TYPE_ERROR_STREAM = 7 }; template <typename T> std::string toString(const T& v) { std::stringstream ss; ss << v; return ss.str(); } template <typename T> std::string toString(const std::vector<T>& v, const std::string separator = ", ") { std::stringstream ss; for (int i = 0; i < v.size() - 1; i++) ss << v[i] << separator; ss << v[v.size() - 1]; return ss.str(); } template <typename T, int n> std::string toString(const Eigen::MatrixBase<T>& v, const std::string separator = ", ") { if (v.rows() > v.cols()) return toString(v.transpose(), separator); std::stringstream ss; ss << v; return ss.str(); } enum CENTROIDAL_DYNAMICS_DLLAPI LoggerVerbosity { VERBOSITY_ALL, VERBOSITY_INFO_WARNING_ERROR, VERBOSITY_WARNING_ERROR, VERBOSITY_ERROR, VERBOSITY_NONE }; /** A simple class for logging messages */ class CENTROIDAL_DYNAMICS_DLLAPI Logger { public: /** Constructor */ Logger(double timeSample = 0.001, double streamPrintPeriod = 1.0); /** Destructor */ ~Logger() {} /** Method to be called at every control iteration * to decrement the internal Logger's counter. */ void countdown(); /** Print the specified message on standard output if the verbosity level * allows it. The file name and the line number are used to identify * the point where sendMsg is called so that streaming messages are * printed only every streamPrintPeriod iterations. */ void sendMsg(std::string msg, MsgType type, const char* file = "", int line = 0); /** Set the sampling time at which the method countdown() * is going to be called. */ bool setTimeSample(double t); /** Set the time period for printing of streaming messages. */ bool setStreamPrintPeriod(double s); /** Set the verbosity level of the logger. */ void setVerbosity(LoggerVerbosity lv); protected: LoggerVerbosity m_lv; /// verbosity of the logger double m_timeSample; /// specify the period of call of the countdown method double m_streamPrintPeriod; /// specify the time period of the stream prints double m_printCountdown; /// every time this is < 0 (i.e. every /// _streamPrintPeriod sec) print stuff /** Pointer to the dynamic structure which holds the collection of streaming * messages */ std::map<std::string, double> m_stream_msg_counters; bool isStreamMsg(MsgType m) { return m == MSG_TYPE_ERROR_STREAM || m == MSG_TYPE_DEBUG_STREAM || m == MSG_TYPE_INFO_STREAM || m == MSG_TYPE_WARNING_STREAM; } bool isDebugMsg(MsgType m) { return m == MSG_TYPE_DEBUG_STREAM || m == MSG_TYPE_DEBUG; } bool isInfoMsg(MsgType m) { return m == MSG_TYPE_INFO_STREAM || m == MSG_TYPE_INFO; } bool isWarningMsg(MsgType m) { return m == MSG_TYPE_WARNING_STREAM || m == MSG_TYPE_WARNING; } bool isErrorMsg(MsgType m) { return m == MSG_TYPE_ERROR_STREAM || m == MSG_TYPE_ERROR; } }; /** Method to get the logger (singleton). */ Logger& getLogger(); } // namespace centroidal_dynamics #endif // HPP_CENTROIDAL_DYNAMICS_LOGGER_HH