started adding support for logging matrices and used it
diff --git a/aos/common/common.gyp b/aos/common/common.gyp
index c0ab74d..1f6a274 100644
--- a/aos/common/common.gyp
+++ b/aos/common/common.gyp
@@ -46,12 +46,11 @@
'type': 'static_library',
'variables': {
'print_field_cc': '<(SHARED_INTERMEDIATE_DIR)/print_field.cc',
- 'queue_primitives_h': '<(SHARED_INTERMEDIATE_DIR)/aos/queue_primitives.h',
+ 'queue_primitives_h': '<(SHARED_INTERMEDIATE_DIR)/aos_queue_primitives/aos/queue_primitives.h',
},
'sources': [
'queue_types.cc',
'<(print_field_cc)',
- '<(queue_primitives_h)',
],
'dependencies': [
'<(AOS)/build/aos.gyp:logging_interface',
@@ -91,6 +90,11 @@
'message': 'Generating queue_primitives.h',
},
],
+ 'direct_dependent_settings': {
+ 'include_dirs': [
+ '<(SHARED_INTERMEDIATE_DIR)/aos_queue_primitives',
+ ],
+ },
'hard_dependency': 1,
},
{
diff --git a/aos/common/logging/logging.gyp b/aos/common/logging/logging.gyp
index e230e47..0139784 100644
--- a/aos/common/logging/logging.gyp
+++ b/aos/common/logging/logging.gyp
@@ -24,6 +24,26 @@
],
'export_dependent_settings': [
'<(AOS)/build/aos.gyp:logging',
+ '<(AOS)/common/common.gyp:die',
+ ],
+ },
+ {
+ 'target_name': 'matrix_logging',
+ 'type': 'static_library',
+ 'sources': [
+ 'matrix_logging.cc',
+ ],
+ 'dependencies': [
+ '<(AOS)/build/aos.gyp:logging',
+ '<(AOS)/common/common.gyp:die',
+ '<(AOS)/common/common.gyp:queue_types',
+ '<(EXTERNALS):eigen',
+ ],
+ 'export_dependent_settings': [
+ '<(AOS)/build/aos.gyp:logging',
+ '<(AOS)/common/common.gyp:die',
+ '<(AOS)/common/common.gyp:queue_types',
+ '<(EXTERNALS):eigen',
],
},
],
diff --git a/aos/common/logging/logging_impl.h b/aos/common/logging/logging_impl.h
index 3d5b387..11b28b0 100644
--- a/aos/common/logging/logging_impl.h
+++ b/aos/common/logging/logging_impl.h
@@ -42,7 +42,7 @@
// The struct that the code uses for making logging calls.
struct LogMessage {
enum class Type : uint8_t {
- kString, kStruct,
+ kString, kStruct, kMatrix
};
int32_t seconds, nseconds;
@@ -63,6 +63,13 @@
// The message string and then the serialized structure.
char serialized[LOG_MESSAGE_LEN - sizeof(type) - sizeof(string_length)];
} structure;
+ struct {
+ // The type ID of the element type.
+ uint32_t type;
+ int rows, columns;
+ char
+ data[LOG_MESSAGE_LEN - sizeof(type) - sizeof(rows) - sizeof(columns)];
+ } matrix;
};
};
static_assert(shm_ok<LogMessage>::value, "it's going in a queue");
@@ -102,9 +109,12 @@
void LogNext(log_level level, const char *format, ...)
__attribute__((format(LOG_PRINTF_FORMAT_TYPE, 2, 3)));
-// Will take a structure and log it.
+// Takes a structure and log it.
template <class T>
void DoLogStruct(log_level, const ::std::string &, const T &);
+// Takes a matrix and logs it.
+template <class T>
+void DoLogMatrix(log_level, const ::std::string &, const T &);
// Represents a system that can actually take log messages and do something
// useful with them.
@@ -144,6 +154,12 @@
virtual void LogStruct(log_level level, const ::std::string &message,
size_t size, const MessageType *type,
const ::std::function<size_t(char *)> &serialize);
+ // Similiar to LogStruct, except for matrixes.
+ // type_id is the type of the elements of the matrix.
+ // data points to rows*cols*type_id.Size() bytes of data in row-major order.
+ virtual void LogMatrix(log_level level, const ::std::string &message,
+ uint32_t type_id, int rows, int cols,
+ const void *data);
// These functions call similar methods on the "current" LogImplementation or
// Die if they can't find one.
@@ -154,12 +170,17 @@
size_t size, const MessageType *type,
const ::std::function<size_t(char *)> &serialize,
int levels);
+ static void DoLogMatrix(log_level level, const ::std::string &message,
+ uint32_t type_id, int rows, int cols,
+ const void *data);
// Friends so that they can access the static Do* functions.
friend void VLog(log_level, const char *, va_list);
friend void LogNext(log_level, const char *, ...);
template <class T>
friend void DoLogStruct(log_level, const ::std::string &, const T &);
+ template <class T>
+ friend void DoLogMatrix(log_level, const ::std::string &, const T &);
LogImplementation *next_;
};
diff --git a/aos/common/logging/matrix_logging-tmpl.h b/aos/common/logging/matrix_logging-tmpl.h
new file mode 100644
index 0000000..8d18f67
--- /dev/null
+++ b/aos/common/logging/matrix_logging-tmpl.h
@@ -0,0 +1,18 @@
+#include "aos/common/logging/logging_impl.h"
+
+#include <functional>
+
+#include "aos/queue_primitives.h"
+
+namespace aos {
+namespace logging {
+
+template <class T>
+void DoLogMatrix(log_level level, const ::std::string &message,
+ const T &matrix) {
+ LogImplementation::DoLogMatrix(level, message, TypeID<typename T::Scalar>::id,
+ matrix.rows(), matrix.cols(), matrix.data());
+}
+
+} // namespace logging
+} // namespace aos
diff --git a/aos/common/logging/matrix_logging.cc b/aos/common/logging/matrix_logging.cc
new file mode 100644
index 0000000..cd30509
--- /dev/null
+++ b/aos/common/logging/matrix_logging.cc
@@ -0,0 +1 @@
+#include "aos/common/logging/matrix_logging.h"
diff --git a/aos/common/logging/matrix_logging.h b/aos/common/logging/matrix_logging.h
new file mode 100644
index 0000000..6efaa06
--- /dev/null
+++ b/aos/common/logging/matrix_logging.h
@@ -0,0 +1,36 @@
+#ifndef AOS_COMMON_LOGGING_MATRIX_LOGGING_H_
+#define AOS_COMMON_LOGGING_MATRIX_LOGGING_H_
+
+#include <string>
+
+#include "Eigen/Dense"
+
+#include "aos/common/logging/logging.h"
+#include "aos/common/die.h"
+
+namespace aos {
+namespace logging {
+
+// Logs the contents of a matrix and a constant string.
+// matrix must be an instance of an Eigen matrix (or something similar).
+#define LOG_MATRIX(level, message, matrix) \
+ do { \
+ static const ::std::string kAosLoggingMessage( \
+ LOG_SOURCENAME ": " STRINGIFY(__LINE__) ": " message); \
+ ::aos::logging::DoLogMatrix(level, kAosLoggingMessage, matrix); \
+ /* so that GCC knows that it won't return */ \
+ if (level == FATAL) { \
+ ::aos::Die("DoLogStruct(FATAL) fell through!!!!!\n"); \
+ } \
+ } while (false)
+
+template <class T>
+void DoLogMatrix(log_level level, const ::std::string &message,
+ const T &matrix);
+
+} // namespace logging
+} // namespace aos
+
+#include "aos/common/logging/matrix_logging-tmpl.h"
+
+#endif // AOS_COMMON_LOGGING_MATRIX_LOGGING_H_
diff --git a/aos/common/logging/queue_logging.cc b/aos/common/logging/queue_logging.cc
index eefb4ac..021da7c 100644
--- a/aos/common/logging/queue_logging.cc
+++ b/aos/common/logging/queue_logging.cc
@@ -1,6 +1,6 @@
-#include "aos/common/logging/logging_impl.h"
+#include "aos/common/logging/queue_logging.h"
-#include "aos/common/die.h"
+#include "aos/common/logging/logging_impl.h"
#include "aos/common/queue_types.h"
namespace aos {
diff --git a/aos/common/logging/queue_logging.h b/aos/common/logging/queue_logging.h
index 191d4c7..ff0167a 100644
--- a/aos/common/logging/queue_logging.h
+++ b/aos/common/logging/queue_logging.h
@@ -7,10 +7,13 @@
#include <string>
#include "aos/common/logging/logging.h"
+#include "aos/common/die.h"
namespace aos {
namespace logging {
+// Logs the contents of a structure (or Queue message) and a constant string.
+// structure must be an instance of one of the generated queue types.
#define LOG_STRUCT(level, message, structure) \
do { \
static const ::std::string kAosLoggingMessage( \
@@ -18,9 +21,7 @@
::aos::logging::DoLogStruct(level, kAosLoggingMessage, structure); \
/* so that GCC knows that it won't return */ \
if (level == FATAL) { \
- fprintf(stderr, "DoLogStruct(FATAL) fell through!!!!!\n"); \
- printf("see stderr\n"); \
- abort(); \
+ ::aos::Die("DoLogStruct(FATAL) fell through!!!!!\n"); \
} \
} while (false)