Skip to content

Commit

Permalink
Measurement Reader / Writer interface to expose Get/Set of DatatypeIn…
Browse files Browse the repository at this point in the history
…formation as atomic operation.
  • Loading branch information
KerstinKeller committed Oct 27, 2023
1 parent c8dae59 commit 56b9ede
Show file tree
Hide file tree
Showing 10 changed files with 93 additions and 53 deletions.
9 changes: 6 additions & 3 deletions app/meas_cutter/src/measurement_exporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,18 @@ MeasurementExporter::~MeasurementExporter()
void MeasurementExporter::createChannel(const std::string& channel_name, const eCALMeasCutterUtils::ChannelInfo& channel_info)
{
_current_channel_name = channel_name;
eCAL::measurement::base::DataTypeInformation data_type_info;
if (channel_info.format == eCALMeasCutterUtils::SerializationFormat::PROTOBUF)
{
_writer->SetChannelType(channel_name, "proto:" + channel_info.type);
data_type_info.encoding = "proto";
}
else
{
_writer->SetChannelType(channel_name, channel_info.type);
data_type_info.encoding = "";
}
_writer->SetChannelDescription(channel_name, channel_info.description);
data_type_info.name = channel_info.type;
data_type_info.descriptor = channel_info.description;
_writer->SetChannelDataTypeInformation(channel_name, data_type_info);
}

void MeasurementExporter::setData(eCALMeasCutterUtils::Timestamp timestamp, const eCALMeasCutterUtils::MetaData& meta_data, const std::string& payload)
Expand Down
16 changes: 10 additions & 6 deletions app/rec/rec_client_core/include/rec_client_core/topic_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,28 @@
#include <string>
#include <set>
#include <map>
#include <ecal/ecal_types.h>

namespace eCAL
{
namespace rec
{
struct TopicInfo
{
TopicInfo(const std::string& type, const std::string& description)
: type_(type), description_(description), description_quality_(0)
TopicInfo(const eCAL::SDataTypeInformation& tinfo)
: tinfo_(tinfo)
{}

TopicInfo(const std::string& type, const std::string& encoding, const std::string& description)
: tinfo_{ type, encoding, description }
{}

TopicInfo()
: description_quality_(0)
{}

std::string type_;
std::string description_;
eCAL::SDataTypeInformation tinfo_;

int description_quality_;
int description_quality_ = 0;

std::map<std::string, std::set<std::string>> publishers_;
};
Expand Down
4 changes: 2 additions & 2 deletions app/rec/rec_client_core/src/job/hdf5_writer_thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,8 @@ namespace eCAL

for (const auto& topic : topic_info_map_to_set)
{
hdf5_writer_->SetChannelType(topic.first, topic.second.type_);
hdf5_writer_->SetChannelDescription(topic.first, topic.second.description_);
eCAL::measurement::base::DataTypeInformation topic_info{ topic.second.tinfo_.name, topic.second.tinfo_.encoding, topic.second.tinfo_.descriptor };
hdf5_writer_->SetChannelDataTypeInformation(topic.first, topic_info);
}
}
else if (frame)
Expand Down
36 changes: 20 additions & 16 deletions app/rec/rec_client_core/src/monitoring_thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ namespace eCAL
}

// Collect all descriptors
std::map<std::string, std::pair<int, std::pair<std::string, std::string>>> channel_descriptor_map; // ChannelName -> {Type, Descriptor}
std::map<std::string, std::pair<int, std::string>> type_descriptor_map; // Type -> Descriptor (used for topics that we know the type of, but have no other information available)
std::map<std::string, std::pair<int, eCAL::SDataTypeInformation>> channel_descriptor_map; // ChannelName -> {Type, Encoding, Descriptor}
std::map<std::string, std::pair<int, eCAL::SDataTypeInformation>> type_descriptor_map; // Type -> DatatypeInformation (used for topics that we know the type of, but have no other information available)

static const int DESCRIPTION_AVAILABLE_QUALITYBIT = 0x1 << 3; // Having a descriptor at all is the most important thing
static const int INFO_COMES_FROM_CORRECT_TOPIC_QUALITYBIT = 0x1 << 2; // The information comes from the current topic (and has not been borrowed from another topic)
Expand All @@ -84,14 +84,19 @@ namespace eCAL
if (topic_info_map_it == topic_info_map_.end())
{
// Create a new topic entry
topic_info_map_.emplace(topic.tname(), eCAL::rec::TopicInfo("", ""));
topic_info_map_.emplace(topic.tname(), eCAL::rec::TopicInfo("", "", ""));
topic_info_map_it = topic_info_map_.find(topic.tname());
}

// Evaluate the quality of the current descriptor information
int this_topic_info_quality = 0;
auto tdatatype = topic.tdatatype();
eCAL::SDataTypeInformation topic_info;
topic_info.name = tdatatype.name();
topic_info.encoding = tdatatype.encoding();
topic_info.descriptor = tdatatype.desc();

if (!topic.tdesc().empty())
if (!topic_info.descriptor.empty())
{
this_topic_info_quality |= DESCRIPTION_AVAILABLE_QUALITYBIT;
}
Expand All @@ -114,7 +119,7 @@ namespace eCAL
}
}

if (!topic.ttype().empty())
if (!topic_info.name.empty())
{
this_topic_info_quality |= TYPE_AVAILABLE_QUALITYBIT;
}
Expand All @@ -125,35 +130,35 @@ namespace eCAL
if (channel_descriptor_map_it == channel_descriptor_map.end())
{
// Save the new descriptor
channel_descriptor_map.emplace(topic.tname(), std::make_pair(this_topic_info_quality, std::make_pair(topic.ttype(), topic.tdesc())));
channel_descriptor_map.emplace(topic.tname(), std::make_pair(this_topic_info_quality, topic_info));
}
else
{
if(channel_descriptor_map_it->second.first < this_topic_info_quality)
{
// If the old descriptor has a lower quality than the current descriptor, we may overwrite it!
channel_descriptor_map_it->second = std::make_pair(this_topic_info_quality, std::make_pair(topic.ttype(), topic.tdesc()));
channel_descriptor_map_it->second = std::make_pair(this_topic_info_quality, topic_info);
}
}
}

// Update the type_descriptor_map (can of course only work if we have the type information available)
if (!topic.ttype().empty())
if (!topic_info.name.empty())
{
int quality_for_other_channels = (this_topic_info_quality & ~INFO_COMES_FROM_CORRECT_TOPIC_QUALITYBIT);

auto type_descriptor_map_it = type_descriptor_map.find(topic.ttype());
auto type_descriptor_map_it = type_descriptor_map.find(topic_info.name);
if (type_descriptor_map_it == type_descriptor_map.end())
{
// Save the new descriptor
type_descriptor_map.emplace(topic.ttype(), std::make_pair(quality_for_other_channels, topic.tdesc()));
type_descriptor_map.emplace(topic_info.name, std::make_pair(quality_for_other_channels, topic_info));
}
else
{
if(type_descriptor_map_it->second.first < quality_for_other_channels)
{
// If the old descriptor has a lower quality than the current descriptor, we may overwrite it!
type_descriptor_map_it->second = std::make_pair(quality_for_other_channels, topic.tdesc());
type_descriptor_map_it->second = std::make_pair(quality_for_other_channels, topic_info);
}
}
}
Expand All @@ -166,18 +171,17 @@ namespace eCAL
if ((channel_descriptor_entry_it != channel_descriptor_map.end())
&& (channel_descriptor_entry_it->second.first >= topic_info_map_entry.second.description_quality_))
{
topic_info_map_entry.second.type_ = channel_descriptor_entry_it->second.second.first;
topic_info_map_entry.second.description_ = channel_descriptor_entry_it->second.second.second;
topic_info_map_entry.second.tinfo_ = channel_descriptor_entry_it->second.second;
topic_info_map_entry.second.description_quality_ = channel_descriptor_entry_it->second.first;
}

if (!topic_info_map_entry.second.type_.empty())
if (!topic_info_map_entry.second.tinfo_.name.empty())
{
auto type_descriptor_entry_it = type_descriptor_map.find(topic_info_map_entry.second.type_);
auto type_descriptor_entry_it = type_descriptor_map.find(topic_info_map_entry.second.tinfo_.name);
if ((type_descriptor_entry_it != type_descriptor_map.end())
&& (type_descriptor_entry_it->second.first >= topic_info_map_entry.second.description_quality_))
{
topic_info_map_entry.second.description_ = type_descriptor_entry_it->second.second;
topic_info_map_entry.second.tinfo_ = type_descriptor_entry_it->second.second;
topic_info_map_entry.second.description_quality_ = type_descriptor_entry_it->second.first;
}
}
Expand Down
7 changes: 5 additions & 2 deletions contrib/ecalhdf5/include/ecal/measurement/omeasurement.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,11 @@ namespace eCAL
inline OChannel<T> OMeasurement::Create(const std::string& channel) const
{
static T msg;
meas->SetChannelType(channel, eCAL::message::GetTypeName(msg));
meas->SetChannelDescription(channel, eCAL::message::GetDescription(msg));
measurement::base::DataTypeInformation datatype_info;
datatype_info.name = eCAL::message::GetTypeName(msg);
datatype_info.encoding = eCAL::message::GetEncoding(msg);
datatype_info.descriptor = eCAL::message::GetDescription(msg);
meas->SetChannelDataTypeInformation(channel, datatype_info);
// Construct a channel based
return OChannel<T>{meas, channel};
}
Expand Down
37 changes: 26 additions & 11 deletions contrib/ecalhdf5/include/ecalhdf5/eh5_writer.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,21 @@ namespace eCAL
{
namespace eh5
{
/**
* To be removed soon-ish
**/
std::string CombinedTopicEncodingAndType(const std::string& topic_encoding_, const std::string& topic_type_)
{
if (topic_encoding_.empty())
{
return topic_type_;
}
else
{
return topic_encoding_ + ":" + topic_type_;
}
}

/**
* @brief Hdf5 based Writer implementation
**/
Expand Down Expand Up @@ -122,20 +137,20 @@ namespace eCAL
void SetOneFilePerChannelEnabled(bool enabled) override { return measurement.SetOneFilePerChannelEnabled(enabled); }

/**
* @brief Set description of the given channel
*
* @param channel_name channel name
* @param description description of the channel
**/
void SetChannelDescription(const std::string& channel_name, const std::string& description) override { return measurement.SetChannelDescription(channel_name, description); }

/**
* @brief Set type of the given channel
* @brief Set data type information of the given channel
*
* @param channel_name channel name
* @param type type of the channel
* @param info datatype info of the channel
*
* @return channel type
**/
void SetChannelType(const std::string& channel_name, const std::string& type) override { return measurement.SetChannelType(channel_name, type); }
virtual void SetChannelDataTypeInformation(const std::string& channel_name, const measurement::base::DataTypeInformation& info) override
{

measurement.SetChannelType(channel_name, CombinedTopicEncodingAndType(info.encoding, info.name));
measurement.SetChannelDescription(channel_name, info.descriptor);
}


/**
* @brief Set measurement file base name (desired name for the actual hdf5 files that will be created)
Expand Down
16 changes: 5 additions & 11 deletions contrib/measurement/base/include/ecal/measurement/base/writer.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,20 +137,14 @@ namespace eCAL
virtual void SetOneFilePerChannelEnabled(bool enabled) = 0;

/**
* @brief Set description of the given channel
*
* @param channel_name channel name
* @param description description of the channel
**/
virtual void SetChannelDescription(const std::string& channel_name, const std::string& description) = 0;

/**
* @brief Set type of the given channel
* @brief Set data type information of the given channel
*
* @param channel_name channel name
* @param type type of the channel
* @param info datatype info of the channel
*
* @return channel type
**/
virtual void SetChannelType(const std::string& channel_name, const std::string& type) = 0;
virtual void SetChannelDataTypeInformation(const std::string & channel_name, const DataTypeInformation& info) = 0;

/**
* @brief Set measurement file base name (desired name for the actual hdf5 files that will be created)
Expand Down
4 changes: 4 additions & 0 deletions contrib/message/include/ecal/msg/message.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ namespace eCAL
//// unfortunately, we need an actual object for this :/
//template<typename T>
//std::string GetTypeName(const T& message);

//// unfortunately, we need an actual object for this :/
//template<typename T>
//std::string GetEncoding(const T& message);

//// unfortunately, we need an actual object for this :/
//template<typename T>
Expand Down
8 changes: 7 additions & 1 deletion contrib/message/include/ecal/msg/proto/message.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,13 @@ namespace eCAL
// unfortunately, we need an actual object for this :/
inline std::string GetTypeName(const google::protobuf::Message& message)
{
return("proto:" + message.GetTypeName());
return(message.GetTypeName());
}

// unfortunately, we need an actual object for this :/
inline std::string GetEncoding(const google::protobuf::Message& /*message*/)
{
return("proto");
}

// unfortunately, we need an actual object for this :/
Expand Down
9 changes: 8 additions & 1 deletion contrib/message/include/ecal/msg/string/message.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,22 @@ namespace eCAL
// unfortunately, we need an actual object for this :/
inline std::string GetTypeName(const std::string& /*message*/)
{
return("base:std::string");
return("std::string");
}

// unfortunately, we need an actual object for this :/
inline std::string GetEncoding(const std::string& /*message*/)
{
return("base");
}

// unfortunately, we need an actual object for this :/
inline std::string GetDescription(const std::string& /*message*/)
{
return("");
}


inline bool Serialize(const std::string& message, std::string& buffer)
{
buffer = message;
Expand Down

0 comments on commit 56b9ede

Please sign in to comment.