File robot_logger.hpp

namespace robot_interfaces
template<typename Action, typename Observation>
class RobotLogger
#include <robot_logger.hpp>

Log robot data (observations, actions, status) to file.

Logs for each time step the time index, timestamp, and the values Observation, Action, and Status. The data is written to a text file, one line per time step with values separated by spaces. This format can easily be read e.g. with NumPy or Pandas.

There are different ways of using the logger:

  1. Using start() and stop_and_save(): The logger runs a thread in which it copies all data to an internal buffer while the robot is running. When calling stop_and_save() the content of the buffer is stored to a file (either binary or text). This is the recommended method for most applications.

  2. Using write_current_buffer() or write_current_buffer_binary(): Call this to log data that is currently held in the robot data time series. For this method, the logger doesn’t use an own buffer, so no data is copied while the robot is running. However, the possible time span for logging is limited by the size of the robot data time series.

  3. Using start_continous_writing() and stop_continous_writing(): Deprecated! Run the logger in the background and write blocks of data directly to the log file while the robot is running (i.e. no buffering in memory is needed). This has the advantage that arbitrary time spans can be logged independent of the buffer size of the time series. Further in case of a software crash not all data will be lost but only the data since the last block was written. However, the permanent writing to a file puts some load on the system and may cause delays in the real-time critical robot code, thus causing the robot to shut down if timing constraints are violated. This method only supports uncompressed CSV as logfile format.

Template Parameters
  • Action – Type of the robot action. Must derive from Loggable.

  • Observation – Type of the robot observation. Must derive from Loggable.

Public Types

enum class Format

Enumeration of possible log file formats.

Values:

enumerator BINARY
enumerator CSV
enumerator CSV_GZIP
typedef RobotLogEntry<Action, Observation> LogEntry

Public Functions

inline RobotLogger(std::shared_ptr<robot_interfaces::RobotData<Action, Observation>> robot_data, size_t buffer_limit, int block_size = 100)

Initialize logger.

Parameters
  • robot_data – Pointer to the robot data instance.

  • block_size – Block size for writing data to the file when running the logger in the background.

RobotLogger(RobotLogger&&) = default
inline virtual ~RobotLogger()
inline void start()

Start logging using an internal buffer.

The buffer is limited by the buffer_limit argument of the constructor. If the limit is reached, the logger stops automatically.

If the logger is already running, this is a noop.

inline void stop()

Stop logging.

If the logger is already stopped, this is a noop.

inline void reset()

Clear the log buffer.

inline void stop_and_save(const std::string &filename, Format log_format)

Stop logging and save logged messages to a file.

Parameters

filename – Path to the output file. Existing files will be overwritten.

inline void start_continous_writing(const std::string &filename)

Start a thread to continuously log to file in the background.

Deprecated:

Parameters

filename – The name of the log file. Existing files will be overwritten!

inline void stop_continous_writing()

Stop logging that was started with start_continous_writing().

Does nothing if logger is not currently running.

Deprecated:

inline void save_current_robot_data(const std::string &filename, long int start_index = 0, long int end_index = -1)

Write current content of robot data to CSV log file.

Write data of the time steps [start_index, end_index) to a log file. This assumes that the specified range is completely included in the active robot data buffer. If this is not the case, only the time steps which are still held in the buffer will be logged.

With the default values for start_index and end_index, the whole content of the current buffer is logged.

Parameters
  • filename – Path to the log file. Existing files will be overwritten!

  • start_index – Time index at which to start logging. If not specified, the whole buffer is logged.

  • end_index – Time index at which to stop logging. This is exclusive, i.e. the specified time index itself will not be part of the log. If set to a negative value (default) or a value greater than the newest time index, the newest time index is used instead (see newest_timeindex()).

Throws

std::runtime_error – If called while the logger thread is running. In case the logger thread was started via start(), it needs to be stopped by calling stop() before write_current_buffer() can be used.

inline void save_current_robot_data_binary(const std::string &filename, long int start_index = 0, long int end_index = -1)

Like save_current_robot_data but using binary file format.

inline void write_current_buffer(const std::string &filename, long int start_index = 0, long int end_index = -1)
inline void write_current_buffer_binary(const std::string &filename, long int start_index = 0, long int end_index = -1)

Private Functions

inline std::vector<std::string> construct_header() const

To get the title of the log file, describing all the information that will be logged in it.

Returns

header The title of the log file.

inline void append_names_to_header(const std::string &identifier, const std::vector<std::string> &field_name, const std::vector<std::vector<double>> &field_data, std::vector<std::string> &header) const

Fills in the name information of each field to be logged according to the size of the field.

Parameters
  • identifier – The structure the field corresponds to

  • field_name – The name of the field

  • field_data – The field data

  • &header – Reference to the header of the log file

inline void write_header_to_file(const std::string &filename) const

Write CSV header to the log file.

This overwrites existing files!

inline void write_header_to_stream(std::ostream &output) const

Write CSV header to the output stream.

inline void append_robot_data_to_file(const std::string &filename, long int start_index, long int block_size)

Writes a block of time steps to the log file.

Parameters
  • start_index – Time index marking the beginning of the block.

  • block_size – Number of time steps that are written to the log file.

inline void append_logger_buffer(std::ostream &output_stream) const

Appends the logger buffer as plain text (CSV) to an output stream.

Parameters

output_stream – Output stream to which the log is written.

inline void append_field_data_to_file(const std::vector<std::vector<double>> &field_data, std::ostream &output_stream) const

Appends the data corresponding to every field at the same time index to the log file.

Parameters

field_data – The field data

inline void save_buffer_binary(const std::string &filename) const

Save content of the internal buffer to a binary file.

Parameters

filename – Path/name of the output file.

inline void save_buffer_text(const std::string &filename, bool use_gzip = false) const

Save content of the internal buffer to a CSV file.

Parameters
  • filename – Path/name of the output file

  • use_gzip – If true, the output file is gzip-compressed.

inline void loop()

Writes everything to the log file.

It dumps all the data corresponding to block_size_ number of time indices at one go.

inline void buffer_loop()

Get observations from logger_data_ and add them to the buffer.

Private Members

std::thread thread_
std::shared_ptr<robot_interfaces::RobotData<Action, Observation>> logger_data_
std::vector<LogEntry> buffer_
size_t buffer_limit_
int block_size_
long int index_
std::atomic<bool> stop_was_called_
std::atomic<bool> enabled_
std::string output_file_name_