Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new functionalities to spy CommandLine interface #99

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions docs/rst/user_manual/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,6 @@ The type of the logs published is defined as follows:
enable: true
domain: 84
topic-name: "FastDdsSpyLogs"
publish-type: false
stdout: true

.. _user_manual_configuration_default:
Expand Down Expand Up @@ -438,5 +437,4 @@ A complete example of all the configurations described on this page can be found
enable: true
domain: 0
topic-name: "FastDdsSpyLogs"
publish-type: false
stdout: true
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,19 @@

#pragma once

#include <iostream>
#include <functional>
#include <iostream>
#include <shared_mutex>
#include <tuple>
#include <unordered_map>

#include <fastcdr/cdr/fixed_size_string.hpp>

#include <fastdds/dds/xtypes/dynamic_types/DynamicType.hpp>

#include <ddspipe_core/types/topic/dds/DdsTopic.hpp>
#include <ddspipe_core/types/dds/Payload.hpp>
#include <ddspipe_core/types/topic/dds/DdsTopic.hpp>
#include <ddspipe_core/types/topic/filter/WildcardDdsFilterTopic.hpp>

#include <fastddsspy_participants/library/library_dll.h>
#include <fastddsspy_participants/model/TopicRateCalculator.hpp>
Expand All @@ -51,7 +53,7 @@ class DataStreamer : public TopicRateCalculator

FASTDDSSPY_PARTICIPANTS_DllAPI
bool activate(
const ddspipe::core::types::DdsTopic& topic_to_activate,
const ddspipe::core::types::WildcardDdsFilterTopic& topic_to_activate,
const std::shared_ptr<CallbackType>& callback);

FASTDDSSPY_PARTICIPANTS_DllAPI
Expand All @@ -67,12 +69,19 @@ class DataStreamer : public TopicRateCalculator
const ddspipe::core::types::DdsTopic& topic,
ddspipe::core::types::RtpsPayloadData& data) override;

FASTDDSSPY_PARTICIPANTS_DllAPI
bool is_topic_type_discovered(
const ddspipe::core::types::WildcardDdsFilterTopic& topic_to_activate) const noexcept;

FASTDDSSPY_PARTICIPANTS_DllAPI
bool is_topic_type_discovered(
const ddspipe::core::types::DdsTopic& topic_to_activate) const noexcept;

protected:

bool is_topic_type_discovered_nts_(
const ddspipe::core::types::WildcardDdsFilterTopic& topic_to_activate) const noexcept;

bool is_topic_type_discovered_nts_(
const ddspipe::core::types::DdsTopic& topic_to_activate) const noexcept;

Expand All @@ -82,10 +91,12 @@ class DataStreamer : public TopicRateCalculator

bool activated_all_ {false};

ddspipe::core::types::DdsTopic activated_topic_;
ddspipe::core::types::WildcardDdsFilterTopic activated_topic_;

std::map<std::string, fastdds::dds::DynamicType::_ref_type> types_discovered_;

std::unordered_map<std::string, std::string> topic_type_discovered_;

mutable std::shared_timed_mutex mutex_;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

#pragma once

#include <ddspipe_core/types/topic/filter/WildcardDdsFilterTopic.hpp>

#include <fastddsspy_participants/library/library_dll.h>
#include <fastddsspy_participants/model/SpyModel.hpp>
#include <fastddsspy_participants/visualization/parser_data.hpp>
Expand Down Expand Up @@ -61,9 +63,21 @@ struct ModelParser
const ddspipe::core::types::Guid& guid) noexcept;

FASTDDSSPY_PARTICIPANTS_DllAPI
static ddspipe::core::types::DdsTopic get_topic(
static std::set<eprosima::ddspipe::core::types::DdsTopic> get_topics(
const SpyModel& model) noexcept;
FASTDDSSPY_PARTICIPANTS_DllAPI
static std::set<eprosima::ddspipe::core::types::DdsTopic> get_topics(
const SpyModel& model,
std::string topic_name) noexcept;
const ddspipe::core::types::WildcardDdsFilterTopic& filter_topic) noexcept;

FASTDDSSPY_PARTICIPANTS_DllAPI
static SimpleTopicData simple_topic_data(
const SpyModel& model,
const ddspipe::core::types::DdsTopic& topic) noexcept;
FASTDDSSPY_PARTICIPANTS_DllAPI
static ComplexTopicData complex_topic_data(
const SpyModel& model,
const ddspipe::core::types::DdsTopic& topic) noexcept;

FASTDDSSPY_PARTICIPANTS_DllAPI
static std::vector<SimpleTopicData> topics(
Expand All @@ -72,9 +86,9 @@ struct ModelParser
static std::vector<ComplexTopicData> topics_verbose(
const SpyModel& model) noexcept;
FASTDDSSPY_PARTICIPANTS_DllAPI
static ComplexTopicData topics(
static std::vector<ComplexTopicData> topics_verbose(
const SpyModel& model,
const std::string& topic_name) noexcept;
const ddspipe::core::types::WildcardDdsFilterTopic& filter_topic) noexcept;
};

} /* namespace participants */
Expand Down
41 changes: 36 additions & 5 deletions fastddsspy_participants/src/cpp/model/DataStreamer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,14 @@ bool DataStreamer::activate_all(
}

bool DataStreamer::activate(
const ddspipe::core::types::DdsTopic& topic_to_activate,
const ddspipe::core::types::WildcardDdsFilterTopic& topic_to_activate,
const std::shared_ptr<CallbackType>& callback)
{
if (!is_topic_type_discovered(topic_to_activate))
{
EPROSIMA_LOG_WARNING(FASTDDSSPY_DATASTREAMER,
"Type <" << topic_to_activate.type_name <<
"> for topic <" << topic_to_activate.topic_name() << "> is not discovered.");
"> for topic <" << topic_to_activate.topic_name << "> is not discovered.");
return false;
}

Expand Down Expand Up @@ -117,12 +117,13 @@ void DataStreamer::add_data(
}
else
{
if (!(activated_topic_ == topic))
if (!(activated_topic_.matches(topic)))
{
// If not all activated, and this is not the activated topic skip
EPROSIMA_LOG_WARNING(
EPROSIMA_LOG_INFO(
FASTDDSSPY_DATASTREAMER,
"Not all activated, and this is not the activated topic.");
"Received data for topic '" << topic << "'. Note: This topic is not activated. " <<
"Not all topics activated.");
return;
}
}
Expand All @@ -142,13 +143,43 @@ void DataStreamer::add_data(
{
dyn_type = it->second;
}

auto map_it = topic_type_discovered_.find(topic.m_topic_name);
if (map_it == topic_type_discovered_.end())
{
topic_type_discovered_[topic.m_topic_name] = topic.type_name;
}
}

// This should be called without mutex taken
// Here should only arrive if it must call callback. Otherwise must return somewhere before
(*callback_)(topic, dyn_type, data);
}

bool DataStreamer::is_topic_type_discovered(
const ddspipe::core::types::WildcardDdsFilterTopic& filter_topic) const noexcept
{
std::shared_lock<std::shared_timed_mutex> _(mutex_);
return is_topic_type_discovered_nts_(filter_topic);
}

bool DataStreamer::is_topic_type_discovered_nts_(
const ddspipe::core::types::WildcardDdsFilterTopic& filter_topic) const noexcept
{
ddspipe::core::types::DdsTopic topic;
for (const auto& it : topic_type_discovered_)
{
topic.m_topic_name = it.first;
topic.type_name = it.second;
if (filter_topic.matches(topic) == true)
{
return true;
}
}

return false;
}

bool DataStreamer::is_topic_type_discovered(
const ddspipe::core::types::DdsTopic& topic) const noexcept
{
Expand Down
136 changes: 76 additions & 60 deletions fastddsspy_participants/src/cpp/visualization/ModelParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ ComplexEndpointData ModelParser::readers(
/*
* This is an auxiliary function that is used to get topics endpoint database
*/
std::set<eprosima::ddspipe::core::types::DdsTopic> get_topics(
std::set<eprosima::ddspipe::core::types::DdsTopic> ModelParser::get_topics(
const SpyModel& model) noexcept
{
std::set<eprosima::ddspipe::core::types::DdsTopic> result;
Expand All @@ -308,91 +308,63 @@ std::set<eprosima::ddspipe::core::types::DdsTopic> get_topics(
return result;
}

ddspipe::core::types::DdsTopic ModelParser::get_topic(
/*
* This is an auxiliary function that is used to get topics endpoint database that match with a regex topic_name
*/
std::set<eprosima::ddspipe::core::types::DdsTopic> ModelParser::get_topics(
const SpyModel& model,
std::string topic_name) noexcept
const ddspipe::core::types::WildcardDdsFilterTopic& filter_topic) noexcept
{

std::set<eprosima::ddspipe::core::types::DdsTopic> result;
for (const auto& endpoint : model.endpoint_database_)
{
if (endpoint.second.active && endpoint.second.topic.m_topic_name == topic_name)
if (endpoint.second.active && filter_topic.matches(endpoint.second.topic))
{
return endpoint.second.topic;
result.insert(endpoint.second.topic);
}
}
ddspipe::core::types::DdsTopic topic;
return topic;
return result;
}

std::vector<SimpleTopicData> ModelParser::topics(
const SpyModel& model) noexcept
SimpleTopicData ModelParser::simple_topic_data(
const SpyModel& model,
const ddspipe::core::types::DdsTopic& topic) noexcept
{
std::vector<SimpleTopicData> result;
SimpleTopicData result;

std::set<eprosima::ddspipe::core::types::DdsTopic> endpoints_topics = get_topics(model);
for (const auto& topic : endpoints_topics)
int datawriters = 0;
int datareaders = 0;
for (const auto& endpoint : model.endpoint_database_)
{
int datawriters = 0;
int datareaders = 0;
for (const auto& endpoint : model.endpoint_database_)
if (endpoint.second.active && endpoint.second.topic.m_topic_name == topic.m_topic_name)
{
if (endpoint.second.active && endpoint.second.topic.m_topic_name == topic.m_topic_name)
if (endpoint.second.is_reader())
{
datareaders++;
}
if (endpoint.second.is_writer())
{
if (endpoint.second.is_reader())
{
datareaders++;
}
if (endpoint.second.is_writer())
{
datawriters++;
}
datawriters++;
}
}
result.push_back({
model.get_ros2_types() ? utils::demangle_if_ros_topic(topic.m_topic_name) : topic.m_topic_name,
model.get_ros2_types() ? utils::demangle_if_ros_type(topic.type_name) : topic.type_name,
datawriters,
datareaders,
{
model.get_topic_rate(topic),
"Hz"
}
});
}

return result;
}

std::vector<ComplexTopicData> ModelParser::topics_verbose(
const SpyModel& model) noexcept
{
std::vector<ComplexTopicData> result;

std::set<eprosima::ddspipe::core::types::DdsTopic> endpoints_topics = get_topics(model);
for (const auto& topic : endpoints_topics)
{
result.push_back(topics(model, topic.m_topic_name));
}
result.name = model.get_ros2_types() ? utils::demangle_if_ros_topic(topic.m_topic_name) : topic.m_topic_name;
result.type = model.get_ros2_types() ? utils::demangle_if_ros_type(topic.type_name) : topic.type_name;
result.datawriters = datawriters;
result.datareaders = datareaders;
result.rate.rate = model.get_topic_rate(topic);
result.rate.unit = "Hz";

return result;
}

ComplexTopicData ModelParser::topics(
ComplexTopicData ModelParser::complex_topic_data(
const SpyModel& model,
const std::string& topic_name) noexcept
const ddspipe::core::types::DdsTopic& topic) noexcept
{
ComplexTopicData result;

// Lets check if topic exists
auto topic = get_topic(model, topic_name);

// If topic not found, return an empty Daa
if (topic.m_topic_name != topic_name)
{
result.name = "";
return result;
}

// Topic found, fill its information
result.name = model.get_ros2_types() ? utils::demangle_if_ros_topic(topic.m_topic_name) : topic.m_topic_name;
result.type = model.get_ros2_types() ? utils::demangle_if_ros_type(topic.type_name) : topic.type_name;
Expand All @@ -418,6 +390,50 @@ ComplexTopicData ModelParser::topics(
return result;
}

std::vector<SimpleTopicData> ModelParser::topics(
const SpyModel& model) noexcept
{
std::vector<SimpleTopicData> result;

std::set<eprosima::ddspipe::core::types::DdsTopic> endpoints_topics = get_topics(model);
for (const auto& topic : endpoints_topics)
{
result.push_back(simple_topic_data(model, topic));
}

return result;
}

std::vector<ComplexTopicData> ModelParser::topics_verbose(
const SpyModel& model) noexcept
{
std::vector<ComplexTopicData> result;

std::set<eprosima::ddspipe::core::types::DdsTopic> endpoints_topics = get_topics(model);
for (const auto& topic : endpoints_topics)
{
result.push_back(complex_topic_data(model, topic));
}

return result;
}

std::vector<ComplexTopicData> ModelParser::topics_verbose(
const SpyModel& model,
const ddspipe::core::types::WildcardDdsFilterTopic& filter_topic) noexcept
{
std::vector<ComplexTopicData> result;

// Lets check if topic exists
std::set<eprosima::ddspipe::core::types::DdsTopic> topics = get_topics(model, filter_topic);
for (const auto& topic : topics)
{
result.push_back(complex_topic_data(model, topic));
}

return result;
}

} /* namespace participants */
} /* namespace spy */
} /* namespace eprosima */
Loading
Loading