Skip to content

Commit c23d188

Browse files
anhosiKarsten1987
authored andcommitted
Record and play multiple topics (ros2#27)
* ros2GH-61 Read topic directly from message when playing and allow to play multiple topics * ros2GH-61 Add test for SqliteStorage and update old ones * ros2GH-62 Extend function to poll for any number of specified topics * ros2GH-62 Allow subscription to several topics * ros2GH-61 Obtain the topic name directly from the database - Uses a JOIN instead of mapping the topic_id to the name in code * ros2GH-61 Cache read row in result iterator This allows repeated dereferencing on same row without quering the database again. * ros2GH-62 Change demo-record to allow specifying multiple topics * ros2GH-62 Add test to write non-string topic + refactoring * ros2GH-62 Add test for subscription to multiple topics * ros2GH-62 Cleanup * ros2GH-62 Simplify test setup * ros2GH-61 Cleanup * ros2GH-61 consolidate storage integration test * ros2GH-62 Consolidate write integration tests * ros2GH-61 enhance read integration test to check multiple topics * ros2GH-62 Improve rosbag integration test * ros2GH-62: Polish rosbag2_rosbag_node_test * ros2GH-62 Fix cpplint * ros2GH-62 Fix memory leak in rosbag helper * ros2GH-62 Cleanup of subscriptions * ros2GH-62 do not use flaky timers in rosbag2_write_integration_test * ros2GH-62 Use rmw_serialize_message_t consistently in test helper classes * ros2GH-73 Use test_msgs in read_integration_test * ros2GH-26 Cleanup: fix alphabetic orderung
1 parent bdd7fd1 commit c23d188

23 files changed

+629
-395
lines changed

rosbag2/CMakeLists.txt

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -75,40 +75,43 @@ if(BUILD_TESTING)
7575
find_package(ament_cmake_gtest REQUIRED)
7676
find_package(ament_cmake_gmock REQUIRED)
7777
find_package(ament_lint_auto REQUIRED)
78+
find_package(test_msgs REQUIRED)
7879
ament_lint_auto_find_test_dependencies()
7980

8081
ament_add_gmock(rosbag2_write_integration_test
8182
test/rosbag2/rosbag2_write_integration_test.cpp
82-
test/rosbag2/rosbag2_test_fixture.hpp
83-
test/rosbag2/test_helpers.hpp
84-
src/rosbag2/typesupport_helpers.cpp
83+
test/rosbag2/test_memory_management.cpp
8584
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
8685
if(TARGET rosbag2_write_integration_test)
8786
target_link_libraries(rosbag2_write_integration_test librosbag2)
8887
endif()
8988

9089
ament_add_gmock(rosbag2_read_integration_test
9190
test/rosbag2/rosbag2_read_integration_test.cpp
92-
test/rosbag2/rosbag2_test_fixture.hpp
93-
test/rosbag2/test_helpers.hpp
94-
src/rosbag2/typesupport_helpers.cpp
91+
test/rosbag2/test_memory_management.cpp
9592
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
9693
if(TARGET rosbag2_read_integration_test)
9794
target_link_libraries(rosbag2_read_integration_test librosbag2)
95+
ament_target_dependencies(rosbag2_read_integration_test
96+
test_msgs
97+
)
9898
endif()
9999

100100
ament_add_gmock(rosbag2_typesupport_helpers_test
101101
test/rosbag2/rosbag2_typesupport_helpers_test.cpp
102102
src/rosbag2/typesupport_helpers.cpp
103103
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
104104
if(TARGET rosbag2_typesupport_helpers_test)
105-
ament_target_dependencies(rosbag2_typesupport_helpers_test rcl Poco ament_index_cpp
106-
rosidl_generator_cpp)
105+
ament_target_dependencies(rosbag2_typesupport_helpers_test
106+
ament_index_cpp
107+
Poco
108+
rcl
109+
rosidl_generator_cpp
110+
)
107111
endif()
108112

109113
ament_add_gmock(rosbag2_integration_test
110114
test/rosbag2/rosbag2_integration_test.cpp
111-
test/rosbag2/test_helpers.hpp
112115
src/rosbag2/typesupport_helpers.cpp
113116
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
114117
if(TARGET rosbag2_integration_test)
@@ -117,14 +120,19 @@ if(BUILD_TESTING)
117120

118121
ament_add_gmock(rosbag2_rosbag_node_test
119122
test/rosbag2/rosbag2_rosbag_node_test.cpp
120-
src/rosbag2/typesupport_helpers.cpp
121-
src/rosbag2/generic_subscription.cpp
123+
test/rosbag2/test_memory_management.cpp
122124
src/rosbag2/generic_publisher.cpp
125+
src/rosbag2/generic_subscription.cpp
123126
src/rosbag2/rosbag2_node.cpp
124-
test/rosbag2/test_helpers.hpp
127+
src/rosbag2/typesupport_helpers.cpp
125128
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
126129
if(TARGET rosbag2_rosbag_node_test)
127-
ament_target_dependencies(rosbag2_rosbag_node_test rclcpp Poco ament_index_cpp std_msgs)
130+
ament_target_dependencies(rosbag2_rosbag_node_test
131+
ament_index_cpp
132+
Poco
133+
rclcpp
134+
std_msgs
135+
)
128136
endif()
129137
endif()
130138

rosbag2/include/rosbag2/rosbag2.hpp

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,37 +16,54 @@
1616
#define ROSBAG2__ROSBAG2_HPP_
1717

1818
#include <functional>
19+
#include <map>
1920
#include <memory>
2021
#include <string>
22+
#include <vector>
2123

2224
#include "rclcpp/rclcpp.hpp"
2325

2426
#include "rosbag2_storage/storage_interfaces/read_only_interface.hpp"
27+
#include "rosbag2_storage/storage_interfaces/read_write_interface.hpp"
2528
#include "rosbag2/visibility_control.hpp"
2629

2730
namespace rosbag2
2831
{
2932

33+
class GenericPublisher;
34+
class GenericSubscription;
35+
class Rosbag2Node;
36+
3037
class Rosbag2
3138
{
3239
public:
3340
ROSBAG2_PUBLIC
3441
void record(
3542
const std::string & file_name,
36-
const std::string & topic_name,
37-
std::function<void(void)> after_write_action = nullptr);
43+
std::vector<std::string> topic_names,
44+
std::function<void(std::string)> after_write_action = nullptr);
3845

3946
ROSBAG2_PUBLIC
40-
void play(const std::string & file_name, const std::string & topic_name);
47+
void play(const std::string & file_name);
4148

4249
ROSBAG2_PUBLIC
43-
std::string get_topic_type(
44-
const std::string & topic_name, const std::shared_ptr<rclcpp::Node> & node);
50+
std::map<std::string, std::string> get_topics_with_types(
51+
const std::vector<std::string> & topic_names, std::shared_ptr<rclcpp::Node> node);
4552

46-
ROSBAG2_PUBLIC
47-
std::string get_topic_type(
48-
std::shared_ptr<rosbag2_storage::storage_interfaces::ReadOnlyInterface> storage,
49-
const std::string & topic);
53+
private:
54+
void prepare_publishers(
55+
std::shared_ptr<Rosbag2Node> node,
56+
std::shared_ptr<rosbag2_storage::storage_interfaces::ReadOnlyInterface> storage);
57+
58+
std::shared_ptr<rosbag2::GenericSubscription>
59+
create_subscription(
60+
const std::function<void(std::string)> & after_write_action,
61+
std::shared_ptr<rosbag2_storage::storage_interfaces::ReadWriteInterface> storage,
62+
std::shared_ptr<Rosbag2Node> & node,
63+
const std::string & topic_name, const std::string & topic_type) const;
64+
65+
std::vector<std::shared_ptr<GenericSubscription>> subscriptions_;
66+
std::map<std::string, std::shared_ptr<GenericPublisher>> publishers_;
5067
};
5168

5269
} // namespace rosbag2

rosbag2/package.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
<test_depend>ament_lint_auto</test_depend>
2323
<test_depend>ament_lint_common</test_depend>
24+
<test_depend>test_msgs</test_depend>
2425

2526
<export>
2627
<build_type>ament_cmake</build_type>

rosbag2/src/rosbag2/demo_play.cpp

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,10 @@
2020

2121
int main(int argc, const char ** argv)
2222
{
23-
if (argc < 2) {
24-
std::cerr << "\nThe name of the topic to play to must be given as parameter!\n";
25-
return 0;
26-
}
27-
std::string topic_name = argv[1];
28-
2923
rclcpp::init(argc, argv);
3024

3125
rosbag2::Rosbag2 rosbag2;
32-
rosbag2.play("test.bag", topic_name);
26+
rosbag2.play("test.bag");
3327

3428
rclcpp::shutdown();
3529

rosbag2/src/rosbag2/demo_record.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#include <cstdio>
1616
#include <string>
17+
#include <vector>
1718

1819
#include "rclcpp/rclcpp.hpp"
1920

@@ -22,10 +23,14 @@
2223
int main(int argc, const char ** argv)
2324
{
2425
if (argc < 2) {
25-
std::cerr << "\nThe name of the topic to record must be given as parameter!\n";
26+
std::cerr << "\nThe names of topics to record must be given as parameter!\n";
2627
return 0;
2728
}
28-
std::string topic_name = argv[1];
29+
std::vector<std::string> topics;
30+
31+
for (int i = 1; i < argc; i++) {
32+
topics.emplace_back(argv[i]);
33+
}
2934

3035
// TODO(anhosi): allow output file to be specified by cli argument and do proper checking if
3136
// file already exists
@@ -35,7 +40,7 @@ int main(int argc, const char ** argv)
3540
rclcpp::init(argc, argv);
3641

3742
rosbag2::Rosbag2 rosbag2;
38-
rosbag2.record(filename, topic_name);
43+
rosbag2.record(filename, topics);
3944

4045
rclcpp::shutdown();
4146

rosbag2/src/rosbag2/generic_subscription.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ std::shared_ptr<rmw_serialized_message_t> GenericSubscription::create_serialized
4848
return borrow_serialized_message(0);
4949
}
5050

51-
5251
void GenericSubscription::handle_message(
5352
std::shared_ptr<void> & message, const rmw_message_info_t & message_info)
5453
{

0 commit comments

Comments
 (0)