Skip to content

Commit

Permalink
* Updating cluon-rec2fuse to include timestamps
Browse files Browse the repository at this point in the history
Signed-off-by: Christian Berger <christian.berger@gu.se>
  • Loading branch information
chrberger committed Apr 10, 2018
1 parent bf09da2 commit 2eb6a98
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 86 deletions.
27 changes: 4 additions & 23 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,8 @@ cmake_minimum_required(VERSION 3.2)
project(cluon-rec2fuse)

################################################################################
# Defining the relevant versions of OpenDLV Standard Message Set and libcluon.
set(OPENDLV_STANDARD_MESSAGE_SET opendlv-standard-message-set-v0.9.1.odvd)
set(CLUON_COMPLETE cluon-complete-v0.0.68.hpp)
# Defining libcluon.
set(CLUON_COMPLETE cluon-complete-v0.0.70.hpp)

################################################################################
# This project requires C++14 or newer.
Expand Down Expand Up @@ -63,42 +62,24 @@ endif()

################################################################################
# Extract cluon-msc from cluon-complete.hpp.
add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/cluon-msc
add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/cluon-complete.hpp
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_CURRENT_SOURCE_DIR}/src/${CLUON_COMPLETE} ${CMAKE_BINARY_DIR}/cluon-complete.hpp
COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_BINARY_DIR}/cluon-complete.hpp ${CMAKE_BINARY_DIR}/cluon-complete.cpp
COMMAND ${CMAKE_CXX_COMPILER} -o ${CMAKE_BINARY_DIR}/cluon-msc ${CMAKE_BINARY_DIR}/cluon-complete.cpp -std=c++14 -pthread -D HAVE_CLUON_MSC
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/src/${CLUON_COMPLETE})

################################################################################
# Generate opendlv-standard-message-set.{hpp,cpp} from ${OPENDLV_STANDARD_MESSAGE_SET} file.
add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/opendlv-standard-message-set.cpp
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMAND ${CMAKE_BINARY_DIR}/cluon-msc --cpp-sources --cpp-add-include-file=opendlv-standard-message-set.hpp --out=${CMAKE_BINARY_DIR}/opendlv-standard-message-set.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/${OPENDLV_STANDARD_MESSAGE_SET}
COMMAND ${CMAKE_BINARY_DIR}/cluon-msc --cpp-headers --out=${CMAKE_BINARY_DIR}/opendlv-standard-message-set.hpp ${CMAKE_CURRENT_SOURCE_DIR}/src/${OPENDLV_STANDARD_MESSAGE_SET}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/src/${OPENDLV_STANDARD_MESSAGE_SET} ${CMAKE_BINARY_DIR}/cluon-msc)

# Add current build directory as include directory as it contains generated files.
include_directories(SYSTEM ${CMAKE_BINARY_DIR})
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src)

################################################################################
# Gather all object code first to avoid double compilation.
add_library(${PROJECT_NAME}-core OBJECT ${CMAKE_BINARY_DIR}/opendlv-standard-message-set.cpp)
set(LIBRARIES ${LIBRARIES} Threads::Threads)

################################################################################
# Create executable.
add_executable(${PROJECT_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/src/${PROJECT_NAME}.cpp $<TARGET_OBJECTS:${PROJECT_NAME}-core>)
add_executable(${PROJECT_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/src/${PROJECT_NAME}.cpp ${CMAKE_BINARY_DIR}/cluon-complete.hpp)
target_link_libraries(${PROJECT_NAME} ${LIBRARIES})

################################################################################
# Enable unit testing.
#enable_testing()
#add_executable(${PROJECT_NAME}-runner ${CMAKE_CURRENT_SOURCE_DIR}/test/tests-pos-decoder.cpp $<TARGET_OBJECTS:${PROJECT_NAME}-core>)
#target_link_libraries(${PROJECT_NAME}-runner ${LIBRARIES})
#add_test(NAME ${PROJECT_NAME}-runner COMMAND ${PROJECT_NAME}-runner)

################################################################################
# Install executable.
install(TARGETS ${PROJECT_NAME} DESTINATION bin COMPONENT ${PROJECT_NAME})
146 changes: 86 additions & 60 deletions src/cluon-complete-v0.0.68.hpp → src/cluon-complete-v0.0.70.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// This is an auto-generated header-only single-file distribution of libcluon.
// Date: Mon, 09 Apr 2018 19:47:57 +0200
// Version: 0.0.68
// Date: Tue, 10 Apr 2018 21:42:45 +0200
// Version: 0.0.70
//
//
// Implementation of N4562 std::experimental::any (merged into C++17) for C++11 compilers.
Expand Down Expand Up @@ -6296,6 +6296,7 @@ class LIBCLUON_API ToJSONVisitor {
//#include "cluon/cluon.hpp"

#include <cstdint>
#include <map>
#include <sstream>
#include <string>

Expand Down Expand Up @@ -6332,8 +6333,11 @@ class LIBCLUON_API ToCSVVisitor {
* @param delimiter Delimiter character.
* @param withHeader If true, the first line in the output contains the
* column headers.
* @param mask Map describing which fields to render. If empty, all
* fields will be emitted; individual field identifiers
* can be masked setting them to false.
*/
ToCSVVisitor(char delimiter = ';', bool withHeader = true) noexcept;
ToCSVVisitor(char delimiter = ';', bool withHeader = true, const std::map<uint32_t, bool> &mask = {}) noexcept;

protected:
/**
Expand Down Expand Up @@ -6394,6 +6398,7 @@ class LIBCLUON_API ToCSVVisitor {
}

private:
std::map<uint32_t, bool> m_mask{};
std::string m_prefix{};
char m_delimiter{';'};
bool m_withHeader{true};
Expand Down Expand Up @@ -11462,8 +11467,12 @@ inline std::string ToJSONVisitor::encodeBase64(const std::string &input) const n

namespace cluon {

inline ToCSVVisitor::ToCSVVisitor(char delimiter, bool withHeader) noexcept
: ToCSVVisitor::ToCSVVisitor("", delimiter, withHeader, false) {}
inline ToCSVVisitor::ToCSVVisitor(char delimiter, bool withHeader, const std::map<uint32_t, bool> &mask) noexcept
: m_mask(mask)
, m_prefix("")
, m_delimiter(delimiter)
, m_withHeader(withHeader)
, m_isNested(false) {}

inline ToCSVVisitor::ToCSVVisitor(const std::string &prefix, char delimiter, bool withHeader, bool isNested) noexcept
: m_prefix(prefix)
Expand Down Expand Up @@ -11502,120 +11511,133 @@ inline void ToCSVVisitor::postVisit() noexcept {
}

inline void ToCSVVisitor::visit(uint32_t id, std::string &&typeName, std::string &&name, bool &v) noexcept {
(void)id;
(void)typeName;
if (m_fillHeader) {
m_bufferHeader << m_prefix << (!m_prefix.empty() ? "." : "") << name << m_delimiter;
if ((0 == m_mask.count(id)) || m_mask[id]) {
if (m_fillHeader) {
m_bufferHeader << m_prefix << (!m_prefix.empty() ? "." : "") << name << m_delimiter;
}
m_bufferValues << v << m_delimiter;
}
m_bufferValues << v << m_delimiter;
}

inline void ToCSVVisitor::visit(uint32_t id, std::string &&typeName, std::string &&name, char &v) noexcept {
(void)id;
(void)typeName;
if (m_fillHeader) {
m_bufferHeader << m_prefix << (!m_prefix.empty() ? "." : "") << name << m_delimiter;
if ((0 == m_mask.count(id)) || m_mask[id]) {
if (m_fillHeader) {
m_bufferHeader << m_prefix << (!m_prefix.empty() ? "." : "") << name << m_delimiter;
}
m_bufferValues << v << m_delimiter;
}
m_bufferValues << v << m_delimiter;
}

inline void ToCSVVisitor::visit(uint32_t id, std::string &&typeName, std::string &&name, int8_t &v) noexcept {
(void)id;
(void)typeName;
if (m_fillHeader) {
m_bufferHeader << m_prefix << (!m_prefix.empty() ? "." : "") << name << m_delimiter;
if ((0 == m_mask.count(id)) || m_mask[id]) {
if (m_fillHeader) {
m_bufferHeader << m_prefix << (!m_prefix.empty() ? "." : "") << name << m_delimiter;
}
m_bufferValues << +v << m_delimiter;
}
m_bufferValues << +v << m_delimiter;
}

inline void ToCSVVisitor::visit(uint32_t id, std::string &&typeName, std::string &&name, uint8_t &v) noexcept {
(void)id;
(void)typeName;
if (m_fillHeader) {
m_bufferHeader << m_prefix << (!m_prefix.empty() ? "." : "") << name << m_delimiter;
if ((0 == m_mask.count(id)) || m_mask[id]) {
if (m_fillHeader) {
m_bufferHeader << m_prefix << (!m_prefix.empty() ? "." : "") << name << m_delimiter;
}
m_bufferValues << +v << m_delimiter;
}
m_bufferValues << +v << m_delimiter;
}

inline void ToCSVVisitor::visit(uint32_t id, std::string &&typeName, std::string &&name, int16_t &v) noexcept {
(void)id;
(void)typeName;
if (m_fillHeader) {
m_bufferHeader << m_prefix << (!m_prefix.empty() ? "." : "") << name << m_delimiter;
if ((0 == m_mask.count(id)) || m_mask[id]) {
if (m_fillHeader) {
m_bufferHeader << m_prefix << (!m_prefix.empty() ? "." : "") << name << m_delimiter;
}
m_bufferValues << v << m_delimiter;
}
m_bufferValues << v << m_delimiter;
}

inline void ToCSVVisitor::visit(uint32_t id, std::string &&typeName, std::string &&name, uint16_t &v) noexcept {
(void)id;
(void)typeName;
if (m_fillHeader) {
m_bufferHeader << m_prefix << (!m_prefix.empty() ? "." : "") << name << m_delimiter;
if ((0 == m_mask.count(id)) || m_mask[id]) {
if (m_fillHeader) {
m_bufferHeader << m_prefix << (!m_prefix.empty() ? "." : "") << name << m_delimiter;
}
m_bufferValues << v << m_delimiter;
}
m_bufferValues << v << m_delimiter;
}

inline void ToCSVVisitor::visit(uint32_t id, std::string &&typeName, std::string &&name, int32_t &v) noexcept {
(void)id;
(void)typeName;
if (m_fillHeader) {
m_bufferHeader << m_prefix << (!m_prefix.empty() ? "." : "") << name << m_delimiter;
if ((0 == m_mask.count(id)) || m_mask[id]) {
if (m_fillHeader) {
m_bufferHeader << m_prefix << (!m_prefix.empty() ? "." : "") << name << m_delimiter;
}
m_bufferValues << v << m_delimiter;
}
m_bufferValues << v << m_delimiter;
}

inline void ToCSVVisitor::visit(uint32_t id, std::string &&typeName, std::string &&name, uint32_t &v) noexcept {
(void)id;
(void)typeName;
if (m_fillHeader) {
m_bufferHeader << m_prefix << (!m_prefix.empty() ? "." : "") << name << m_delimiter;
if ((0 == m_mask.count(id)) || m_mask[id]) {
if (m_fillHeader) {
m_bufferHeader << m_prefix << (!m_prefix.empty() ? "." : "") << name << m_delimiter;
}
m_bufferValues << v << m_delimiter;
}
m_bufferValues << v << m_delimiter;
}

inline void ToCSVVisitor::visit(uint32_t id, std::string &&typeName, std::string &&name, int64_t &v) noexcept {
(void)id;
(void)typeName;
if (m_fillHeader) {
m_bufferHeader << m_prefix << (!m_prefix.empty() ? "." : "") << name << m_delimiter;
if ((0 == m_mask.count(id)) || m_mask[id]) {
if (m_fillHeader) {
m_bufferHeader << m_prefix << (!m_prefix.empty() ? "." : "") << name << m_delimiter;
}
m_bufferValues << v << m_delimiter;
}
m_bufferValues << v << m_delimiter;
}

inline void ToCSVVisitor::visit(uint32_t id, std::string &&typeName, std::string &&name, uint64_t &v) noexcept {
(void)id;
(void)typeName;
if (m_fillHeader) {
m_bufferHeader << m_prefix << (!m_prefix.empty() ? "." : "") << name << m_delimiter;
if ((0 == m_mask.count(id)) || m_mask[id]) {
if (m_fillHeader) {
m_bufferHeader << m_prefix << (!m_prefix.empty() ? "." : "") << name << m_delimiter;
}
m_bufferValues << v << m_delimiter;
}
m_bufferValues << v << m_delimiter;
}

inline void ToCSVVisitor::visit(uint32_t id, std::string &&typeName, std::string &&name, float &v) noexcept {
(void)id;
(void)typeName;
if (m_fillHeader) {
m_bufferHeader << m_prefix << (!m_prefix.empty() ? "." : "") << name << m_delimiter;
if ((0 == m_mask.count(id)) || m_mask[id]) {
if (m_fillHeader) {
m_bufferHeader << m_prefix << (!m_prefix.empty() ? "." : "") << name << m_delimiter;
}
m_bufferValues << std::setprecision(7) << v << std::setprecision(6) << m_delimiter;
}
m_bufferValues << std::setprecision(7) << v << std::setprecision(6) << m_delimiter;
}

inline void ToCSVVisitor::visit(uint32_t id, std::string &&typeName, std::string &&name, double &v) noexcept {
(void)id;
(void)typeName;
if (m_fillHeader) {
m_bufferHeader << m_prefix << (!m_prefix.empty() ? "." : "") << name << m_delimiter;
if ((0 == m_mask.count(id)) || m_mask[id]) {
if (m_fillHeader) {
m_bufferHeader << m_prefix << (!m_prefix.empty() ? "." : "") << name << m_delimiter;
}
m_bufferValues << std::setprecision(11) << v << std::setprecision(6) << m_delimiter;
}
m_bufferValues << std::setprecision(11) << v << std::setprecision(6) << m_delimiter;
}

inline void ToCSVVisitor::visit(uint32_t id, std::string &&typeName, std::string &&name, std::string &v) noexcept {
(void)id;
(void)typeName;
if (m_fillHeader) {
m_bufferHeader << m_prefix << (!m_prefix.empty() ? "." : "") << name << m_delimiter;
if ((0 == m_mask.count(id)) || m_mask[id]) {
if (m_fillHeader) {
m_bufferHeader << m_prefix << (!m_prefix.empty() ? "." : "") << name << m_delimiter;
}
m_bufferValues << '\"' << v << '\"' << m_delimiter;
}
m_bufferValues << '\"' << v << '\"' << m_delimiter;
}

} // namespace cluon
Expand Down Expand Up @@ -14871,12 +14893,16 @@ int main(int argc, char **argv) {
const std::string PROGRAM{argv[0]}; // NOLINT
auto commandlineArguments = cluon::getCommandlineArguments(argc, argv);
if (1 == argc) {
std::cerr << PROGRAM << " replays a .rec file into an OpenDaVINCI session or to stdout." << std::endl;
std::cerr << "Usage: " << PROGRAM << " [--cid=<OpenDaVINCI session>] recording.rec" << std::endl;
std::cerr << PROGRAM << " replays a .rec file into an OpenDaVINCI session or to stdout; if playing back to an OD4Session using parameter --cid, you can specify the optional parameter --stdout to also playback to stdout." << std::endl;
std::cerr << "Usage: " << PROGRAM << " [--cid=<OpenDaVINCI session> [--stdout]] recording.rec" << std::endl;
std::cerr << "Example: " << PROGRAM << " --cid=111 file.rec" << std::endl;
std::cerr << " " << PROGRAM << " --cid=111 --stdout file.rec" << std::endl;
std::cerr << " " << PROGRAM << " file.rec" << std::endl;
retCode = 1;
}
else {
const bool playBackToStdout = ( (0 != commandlineArguments.count("stdout")) || (0 == commandlineArguments.count("cid")) );

std::string recFile;
for (auto e : commandlineArguments) {
if (recFile.empty() && e.second.empty() && e.first != PROGRAM) {
Expand Down Expand Up @@ -15027,7 +15053,7 @@ int main(int argc, char **argv) {
if (od4 && od4->isRunning()) {
od4->send(std::move(next.second));
}
else {
if (playBackToStdout) {
std::cout << cluon::serializeEnvelope(std::move(next.second));
std::cout.flush();
}
Expand Down
26 changes: 23 additions & 3 deletions src/cluon-rec2fuse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@
*/

#include "cluon-complete.hpp"
#include "opendlv-standard-message-set.hpp"

#define FUSE_USE_VERSION 26
#include <fuse.h>

#include <algorithm>
#include <cstdint>
#include <iostream>
#include <map>
Expand Down Expand Up @@ -170,14 +170,34 @@ int32_t main(int32_t argc, char **argv) {

mapOfFilenames[KEY] = _FILENAME;
if (mapOfEntries.count(KEY) > 0) {
// Extract timestamps.
std::string timeStamps;
{
cluon::ToCSVVisitor csv(';', false, { {1,false}, {2,false}, {3,true}, {4,true}, {5,true}, {6,false} });
env.accept(csv);
timeStamps = csv.csv();
}

cluon::ToCSVVisitor csv(';', false);
gm.accept(csv);
mapOfEntries[KEY] += csv.csv();
mapOfEntries[KEY] += stringtoolbox::split(timeStamps, '\n')[0] + csv.csv();
}
else {
// Extract timestamps.
std::vector<std::string> timeStampsWithHeader;
{
// Skip senderStamp (as it is in file name) and serialzedData.
cluon::ToCSVVisitor csv(';', true, { {1,false}, {2,false}, {3,true}, {4,true}, {5,true}, {6,false} });
env.accept(csv);
timeStampsWithHeader = stringtoolbox::split(csv.csv(), '\n');
}

cluon::ToCSVVisitor csv(';', true);
gm.accept(csv);
mapOfEntries[KEY] += csv.csv();

std::vector<std::string> valuesWithHeader = stringtoolbox::split(csv.csv(), '\n');

mapOfEntries[KEY] += timeStampsWithHeader.at(0) + valuesWithHeader.at(0) + '\n' + timeStampsWithHeader.at(1) + valuesWithHeader.at(1) + '\n';
}
mapOfEntrySizes[KEY] = mapOfEntries[KEY].size();
}
Expand Down

0 comments on commit 2eb6a98

Please sign in to comment.