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

Sort info output by topic name #1804

Open
wants to merge 11 commits into
base: rolling
Choose a base branch
from
9 changes: 7 additions & 2 deletions ros2bag/ros2bag/verb/info.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,21 @@ def add_arguments(self, parser, cli_name): # noqa: D102
'-v', '--verbose', action='store_true',
help='Display request/response information for services'
)
available_sorting_methods = Info().get_sorting_methods()
parser.add_argument(
'--sort', default='name', choices=available_sorting_methods,
help='Configuration for sorting of output. '
'By default sorts by topic name - use this argument to override.')

def main(self, *, args): # noqa: D102
if args.topic_name and args.verbose:
print("Warning! You have set both the '-t' and '-v' parameters. The '-t' parameter "
'will be ignored.')
m = Info().read_metadata(args.bag_path, args.storage)
if args.verbose:
Info().print_output_verbose(args.bag_path, m)
Info().print_output_verbose(args.bag_path, m, args.sort)
else:
if args.topic_name:
Info().print_output_topic_name_only(m)
MichaelOrlov marked this conversation as resolved.
Show resolved Hide resolved
else:
Info().print_output(m)
Info().print_output(m, args.sort)
47 changes: 41 additions & 6 deletions rosbag2_py/src/rosbag2_py/_info.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#include <iostream>
#include <memory>
#include <string>
#include <algorithm>
#include <numeric>

#include "format_bag_metadata.hpp"
#include "format_service_info.hpp"
Expand All @@ -27,6 +29,12 @@
namespace rosbag2_py
{


std::unordered_map<std::string, SortingMethod> stringToSortingMethod = {
{"name", SortingMethod::NAME},
{"type", SortingMethod::TYPE},
{"count", SortingMethod::COUNT}};

class Info
{
public:
Expand All @@ -42,15 +50,29 @@ class Info
return info_->read_metadata(uri, storage_id);
}

void print_output(const rosbag2_storage::BagMetadata & metadata_info)
void print_output(
const rosbag2_storage::BagMetadata & metadata_info, std::string sorting_method)
MichaelOrlov marked this conversation as resolved.
Show resolved Hide resolved
{
rosbag2_py::SortingMethod sort_method = rosbag2_py::stringToSortingMethod[sorting_method];
// Output formatted metadata
std::cout << format_bag_meta_data(metadata_info) << std::endl;
std::cout << format_bag_meta_data(metadata_info, {}, false, false, sort_method) << std::endl;
}

void print_output_topic_name_only(const rosbag2_storage::BagMetadata & metadata_info)
{
for (const auto & topic_info : metadata_info.topics_with_message_count) {
std::vector<size_t> sorted_idx(metadata_info.topics_with_message_count.size());
std::iota(sorted_idx.begin(), sorted_idx.end(), 0);
std::sort(
sorted_idx.begin(),
sorted_idx.end(),
[&metadata_info](size_t i1, size_t i2) {
std::string topic_name_1 = metadata_info.topics_with_message_count[i1].topic_metadata.name;
std::string topic_name_2 = metadata_info.topics_with_message_count[i2].topic_metadata.name;
return topic_name_1 < topic_name_2;
MichaelOrlov marked this conversation as resolved.
Show resolved Hide resolved
}
);
for (auto idx : sorted_idx) {
auto topic_info = metadata_info.topics_with_message_count[idx];
MichaelOrlov marked this conversation as resolved.
Show resolved Hide resolved
if (!rosbag2_cpp::is_service_event_topic(
topic_info.topic_metadata.name,
topic_info.topic_metadata.type))
Expand All @@ -61,7 +83,9 @@ class Info
}

void print_output_verbose(
const std::string & uri, const rosbag2_storage::BagMetadata & metadata_info)
const std::string & uri,
const rosbag2_storage::BagMetadata & metadata_info,
std::string sorting_method)
MichaelOrlov marked this conversation as resolved.
Show resolved Hide resolved
{
std::vector<std::shared_ptr<rosbag2_cpp::rosbag2_service_info_t>> all_services_info;
for (auto & file_info : metadata_info.files) {
Expand All @@ -86,11 +110,21 @@ class Info
}
}

rosbag2_py::SortingMethod sort_method = rosbag2_py::stringToSortingMethod[sorting_method];
// Output formatted metadata and service info
std::cout << format_bag_meta_data(metadata_info, messages_size, true, true);
std::cout << format_bag_meta_data(metadata_info, messages_size, true, true, sort_method);
std::cout << format_service_info(all_services_info, messages_size, true) << std::endl;
}

std::unordered_set<std::string> get_sorting_methods()
{
std::unordered_set<std::string> sorting_methods;
for (auto sorting_method : rosbag2_py::stringToSortingMethod) {
sorting_methods.insert(sorting_method.first);
}
return sorting_methods;
}

protected:
std::unique_ptr<rosbag2_cpp::Info> info_;
};
Expand All @@ -105,5 +139,6 @@ PYBIND11_MODULE(_info, m) {
.def("read_metadata", &rosbag2_py::Info::read_metadata)
.def("print_output", &rosbag2_py::Info::print_output)
.def("print_output_topic_name_only", &rosbag2_py::Info::print_output_topic_name_only)
.def("print_output_verbose", &rosbag2_py::Info::print_output_verbose);
.def("print_output_verbose", &rosbag2_py::Info::print_output_verbose)
.def("get_sorting_methods", &rosbag2_py::Info::get_sorting_methods);
}
69 changes: 57 additions & 12 deletions rosbag2_py/src/rosbag2_py/format_bag_metadata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#include <string>
#include <unordered_map>
#include <vector>
#include <algorithm>
#include <numeric>

#ifdef _WIN32
#include <time.h>
Expand Down Expand Up @@ -115,7 +117,8 @@ void format_topics_with_type(
const std::unordered_map<std::string, uint64_t> & messages_size,
bool verbose,
std::stringstream & info_stream,
int indentation_spaces)
int indentation_spaces,
const rosbag2_py::SortingMethod sort_method = rosbag2_py::SortingMethod::NAME)
{
if (topics.empty()) {
info_stream << std::endl;
Expand All @@ -139,13 +142,29 @@ void format_topics_with_type(
info_stream << std::endl;
};

std::vector<size_t> sorted_idx(topics.size());
std::iota(sorted_idx.begin(), sorted_idx.end(), 0);
std::sort(
sorted_idx.begin(),
sorted_idx.end(),
[&topics, sort_method](size_t i1, size_t i2) {
if (sort_method == rosbag2_py::SortingMethod::TYPE) {
return topics[i1].topic_metadata.type < topics[i2].topic_metadata.type;
}
if (sort_method == rosbag2_py::SortingMethod::COUNT) {
return topics[i1].message_count < topics[i2].message_count;
}
return topics[i1].topic_metadata.name < topics[i2].topic_metadata.name;
MichaelOrlov marked this conversation as resolved.
Show resolved Hide resolved
}
);

size_t number_of_topics = topics.size();
size_t i = 0;
// Find first topic which isn't service event topic
while (i < number_of_topics &&
rosbag2_cpp::is_service_event_topic(
topics[i].topic_metadata.name,
topics[i].topic_metadata.type))
topics[sorted_idx[i]].topic_metadata.name,
topics[sorted_idx[i]].topic_metadata.type))
{
i++;
}
Expand All @@ -155,15 +174,15 @@ void format_topics_with_type(
return;
}

print_topic_info(topics[i]);
print_topic_info(topics[sorted_idx[i]]);
for (size_t j = ++i; j < number_of_topics; ++j) {
if (rosbag2_cpp::is_service_event_topic(
topics[j].topic_metadata.name, topics[j].topic_metadata.type))
topics[sorted_idx[j]].topic_metadata.name, topics[sorted_idx[j]].topic_metadata.type))
{
continue;
}
indent(info_stream, indentation_spaces);
print_topic_info(topics[j]);
print_topic_info(topics[sorted_idx[j]]);
}
}

Expand Down Expand Up @@ -212,7 +231,8 @@ void format_service_with_type(
const std::unordered_map<std::string, uint64_t> & messages_size,
bool verbose,
std::stringstream & info_stream,
int indentation_spaces)
int indentation_spaces,
const rosbag2_py::SortingMethod sort_method = rosbag2_py::SortingMethod::NAME)
{
if (services.empty()) {
info_stream << std::endl;
Expand All @@ -238,11 +258,27 @@ void format_service_with_type(
info_stream << std::endl;
};

print_service_info(services[0]);
std::vector<size_t> sorted_idx(services.size());
std::iota(sorted_idx.begin(), sorted_idx.end(), 0);
std::sort(
sorted_idx.begin(),
sorted_idx.end(),
[&services, sort_method](size_t i1, size_t i2) {
if (sort_method == rosbag2_py::SortingMethod::TYPE) {
return services[i1]->service_metadata.type < services[i2]->service_metadata.type;
}
if (sort_method == rosbag2_py::SortingMethod::COUNT) {
return services[i1]->event_message_count < services[i2]->event_message_count;
}
return services[i1]->service_metadata.name < services[i2]->service_metadata.name;
}
MichaelOrlov marked this conversation as resolved.
Show resolved Hide resolved
);

print_service_info(services[sorted_idx[0]]);
auto number_of_services = services.size();
for (size_t j = 1; j < number_of_services; ++j) {
indent(info_stream, indentation_spaces);
print_service_info(services[j]);
print_service_info(services[sorted_idx[j]]);
}
}

Expand All @@ -255,7 +291,8 @@ std::string format_bag_meta_data(
const rosbag2_storage::BagMetadata & metadata,
const std::unordered_map<std::string, uint64_t> & messages_size,
bool verbose,
bool only_topic)
bool only_topic,
const SortingMethod sort_method)
{
auto start_time = metadata.starting_time.time_since_epoch();
auto end_time = start_time + metadata.duration;
Expand Down Expand Up @@ -288,14 +325,22 @@ std::string format_bag_meta_data(
std::endl;
info_stream << "Topic information: ";
format_topics_with_type(
metadata.topics_with_message_count, messages_size, verbose, info_stream, indentation_spaces);
metadata.topics_with_message_count,
messages_size, verbose, info_stream,
indentation_spaces,
sort_method);

if (!only_topic) {
info_stream << "Service: " << service_info_list.size() << std::endl;
info_stream << "Service information: ";
if (!service_info_list.empty()) {
format_service_with_type(
service_info_list, messages_size, verbose, info_stream, indentation_spaces + 2);
service_info_list,
messages_size,
verbose,
info_stream,
indentation_spaces + 2,
sort_method);
}
}

Expand Down
13 changes: 12 additions & 1 deletion rosbag2_py/src/rosbag2_py/format_bag_metadata.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,22 @@
namespace rosbag2_py
{

/**
* \brief Available sorting methods for info output.
*/
enum class SortingMethod
{
NAME,
TYPE,
COUNT,
};

MichaelOrlov marked this conversation as resolved.
Show resolved Hide resolved
std::string format_bag_meta_data(
const rosbag2_storage::BagMetadata & metadata,
const std::unordered_map<std::string, uint64_t> & messages_size = {},
bool verbose = false,
bool only_topic = false);
bool only_topic = false,
const SortingMethod sort_method = SortingMethod::NAME);

} // namespace rosbag2_py

Expand Down
Loading