|
14 | 14 |
|
15 | 15 | #include "rosbag2_transport/bag_rewrite.hpp" |
16 | 16 |
|
| 17 | +#include <map> |
17 | 18 | #include <memory> |
18 | 19 | #include <string> |
19 | 20 | #include <unordered_map> |
20 | 21 | #include <unordered_set> |
21 | 22 | #include <utility> |
22 | 23 | #include <vector> |
23 | 24 |
|
24 | | -#include "rosbag2_compression/compression_options.hpp" |
25 | | -#include "rosbag2_compression/sequential_compression_reader.hpp" |
26 | | -#include "rosbag2_compression/sequential_compression_writer.hpp" |
27 | 25 | #include "rosbag2_cpp/reader.hpp" |
28 | | -#include "rosbag2_cpp/readers/sequential_reader.hpp" |
29 | 26 | #include "rosbag2_cpp/writer.hpp" |
30 | | -#include "rosbag2_cpp/writers/sequential_writer.hpp" |
31 | 27 | #include "rosbag2_transport/reader_writer_factory.hpp" |
32 | 28 |
|
33 | 29 | #include "logging.hpp" |
@@ -83,67 +79,29 @@ setup_topic_filtering( |
83 | 79 | > & output_bags) |
84 | 80 | { |
85 | 81 | std::unordered_map<std::string, std::vector<rosbag2_cpp::Writer *>> filtered_outputs; |
86 | | - std::unordered_map<std::string, std::string> input_topics; |
| 82 | + std::map<std::string, std::vector<std::string>> input_topics; |
87 | 83 | std::unordered_map<std::string, YAML::Node> input_topics_qos_profiles; |
88 | 84 |
|
89 | | - // Filter inputs |
90 | | - { |
91 | | - std::unordered_map<std::string, std::unordered_set<std::string>> topic_names_and_types; |
92 | | - std::unordered_set<std::string> unknown_types; |
93 | | - |
94 | | - for (const auto & input_bag : input_bags) { |
95 | | - auto bag_topics_and_types = input_bag->get_all_topics_and_types(); |
96 | | - for (const auto & topic_metadata : bag_topics_and_types) { |
97 | | - const std::string & topic_name = topic_metadata.name; |
98 | | - topic_names_and_types.try_emplace(topic_name); |
99 | | - topic_names_and_types[topic_name].insert(topic_metadata.type); |
100 | | - |
101 | | - // Gather all offered qos profiles from all inputs |
102 | | - input_topics_qos_profiles.try_emplace(topic_name); |
103 | | - YAML::Node & all_offered = input_topics_qos_profiles[topic_name]; |
104 | | - YAML::Node offered_qos_profiles = YAML::Load(topic_metadata.offered_qos_profiles); |
105 | | - for (auto qos : offered_qos_profiles) { |
106 | | - all_offered.push_back(qos); |
107 | | - } |
| 85 | + for (const auto & input_bag : input_bags) { |
| 86 | + auto bag_topics_and_types = input_bag->get_all_topics_and_types(); |
| 87 | + for (const auto & topic_metadata : bag_topics_and_types) { |
| 88 | + const std::string & topic_name = topic_metadata.name; |
| 89 | + input_topics.try_emplace(topic_name); |
| 90 | + input_topics[topic_name].push_back(topic_metadata.type); |
| 91 | + |
| 92 | + // Gather all offered qos profiles from all inputs |
| 93 | + input_topics_qos_profiles.try_emplace(topic_name); |
| 94 | + YAML::Node & all_offered = input_topics_qos_profiles[topic_name]; |
| 95 | + YAML::Node offered_qos_profiles = YAML::Load(topic_metadata.offered_qos_profiles); |
| 96 | + for (auto qos : offered_qos_profiles) { |
| 97 | + all_offered.push_back(qos); |
108 | 98 | } |
109 | 99 | } |
110 | | - |
111 | | - // Filter topics with more than one type |
112 | | - for (const auto & [topic_name, topic_types] : topic_names_and_types) { |
113 | | - if (topic_types.size() > 1) { |
114 | | - ROSBAG2_TRANSPORT_LOG_WARN_STREAM( |
115 | | - "Topic '" << topic_name << "' has multiple types from inputs. " << |
116 | | - "Topics must have a single type, skipping topic."); |
117 | | - } else { |
118 | | - std::string topic_type = *topic_types.begin(); |
119 | | - input_topics[topic_name] = topic_type; |
120 | | - } |
121 | | - } |
122 | | - |
123 | | - input_topics = rosbag2_transport::topic_filter::filter_topics_with_known_type( |
124 | | - input_topics, unknown_types); |
125 | 100 | } |
126 | 101 |
|
127 | | - // Filter to outputs |
128 | 102 | for (const auto & [writer, record_options] : output_bags) { |
129 | | - auto filtered_topics_and_types = input_topics; |
130 | | - if (!record_options.topics.empty()) { |
131 | | - std::vector<std::string> expanded_topics; |
132 | | - for (const std::string & topic : record_options.topics) { |
133 | | - auto expanded_topic = rclcpp::expand_topic_or_service_name( |
134 | | - topic, "dummy_node_name", "/", false); |
135 | | - expanded_topics.push_back(expanded_topic); |
136 | | - } |
137 | | - filtered_topics_and_types = rosbag2_transport::topic_filter::filter_topics( |
138 | | - expanded_topics, input_topics); |
139 | | - } |
140 | | - if (!record_options.regex.empty() || !record_options.exclude.empty()) { |
141 | | - filtered_topics_and_types = rosbag2_transport::topic_filter::filter_topics_using_regex( |
142 | | - filtered_topics_and_types, |
143 | | - record_options.regex, |
144 | | - record_options.exclude, |
145 | | - record_options.all); |
146 | | - } |
| 103 | + rosbag2_transport::TopicFilter topic_filter{record_options}; |
| 104 | + auto filtered_topics_and_types = topic_filter.filter_topics(input_topics); |
147 | 105 |
|
148 | 106 | // Done filtering - set up writer |
149 | 107 | for (const auto & [topic_name, topic_type] : filtered_topics_and_types) { |
|
0 commit comments