-
Notifications
You must be signed in to change notification settings - Fork 260
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
Record and play multiple topics #27
Record and play multiple topics #27
Conversation
3936546
to
b9e6b22
Compare
rosbag2/CMakeLists.txt
Outdated
src/rosbag2/typesupport_helpers.cpp | ||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) | ||
if(TARGET rosbag2_typesupport_helpers_test) | ||
ament_target_dependencies(rosbag2_typesupport_helpers_test rcl Poco ament_index_cpp |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
alphabet
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
rosbag2/CMakeLists.txt
Outdated
src/rosbag2/rosbag2_node.cpp | ||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) | ||
if(TARGET rosbag2_rosbag_node_test) | ||
ament_target_dependencies(rosbag2_rosbag_node_test rclcpp Poco ament_index_cpp std_msgs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
alphabet
{ | ||
return borrow_serialized_message(0); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
double whitespace?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
rosbag2/src/rosbag2/rosbag2.cpp
Outdated
// without the sleep_for() many messages are lost. | ||
std::this_thread::sleep_for(std::chrono::milliseconds(500)); | ||
publisher->publish(message->serialized_data.get()); | ||
std::this_thread::sleep_for(std::chrono::milliseconds(50)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't they be published according to their timestamp?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes and they will (in the future). We are currently working on that but it is not in scope for this PR.
} | ||
|
||
void Rosbag2::play(const std::string & file_name, const std::string & topic_name) | ||
void Rosbag2::play(const std::string & file_name) | ||
{ | ||
rosbag2_storage::StorageFactory factory; | ||
auto storage = factory.open_read_only(file_name, "sqlite3"); | ||
|
||
if (storage) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens in the else case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nothing 😁. The storage factory already complains if the storage cannot be loaded.
If we want to have more elaborate error handling I would postpone that until the rosbag2_transport
has been introduced as we would have a CLI integration then. Then it would be easier to think about feedback to the user.
rosbag2/src/rosbag2/rosbag2_node.hpp
Outdated
#include <memory> | ||
#include <string> | ||
|
||
#include "rcutils/types.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
alphabet
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed.
size_t expected_messages_number, std::string topic) | ||
{ | ||
auto node = rclcpp::Node::make_shared("node_" + topic); | ||
std::vector<typename T::_data_type> messages; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This maybe deserves a bit of documentation. The _data_type
field is only available for primitives messages types whose single field is called data
. Otherwise the variable is called like the field name:
https://github.com/ros2/rosidl/blob/master/rosidl_generator_cpp/resource/msg__struct.hpp.em#L199-L204
So this test can not easily be transformed into a complex msg type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For this particular test it is sufficient. But I agree that we probably should add a test for a complex type. That way we can probably replace the std_msgs
test dependency with test_msgs
which looks less surprising.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We changed the read_integration_test
to use also complex messages from test_msgs
.
}); | ||
subscriptions_.push_back(subscription); | ||
|
||
while (messages_received < expected_messages_number) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can this resolve in an endless loop in case there is no network connection etc? This should maybe timeout
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In principle yes, but the test framework takes care of that so we do not need to "clutter" the test with timeout handling.
std::shared_ptr<rosbag2_storage::SerializedBagMessage> serialize_message(std::string message) | ||
template<typename MessageT> | ||
std::shared_ptr<rosbag2_storage::SerializedBagMessage> serialize_message( | ||
std::string topic, typename MessageT::_data_type message) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
some comment as above. I believe _data_type
is not defined for every message type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
auto statement = database_->prepare_statement("SELECT name, type FROM topics ORDER BY id;"); | ||
auto query_results = statement->execute_query<std::string, std::string>(); | ||
|
||
for (auto result : query_results) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should there be a notification or similar in case no results for found for this query?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could only happen if the bag is empty, i.e. contains no messages. Here the result will simply be empty which should not hurt.
I am not sure how we want to handle empty bags. Currently it would be opened, the play would initialize some things, loop over an empty list and shutdown => no harm there. So I propose to discuss this on a new issue.
…play multiple topics
- Uses a JOIN instead of mapping the topic_id to the name in code
This allows repeated dereferencing on same row without quering the database again.
b9e6b22
to
3eaee5b
Compare
class Rosbag2 | ||
{ | ||
public: | ||
ROSBAG2_PUBLIC | ||
void record( | ||
const std::string & file_name, | ||
const std::string & topic_name, | ||
std::function<void(void)> after_write_action = nullptr); | ||
std::vector<std::string> topic_names, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const std::vector<> &
void Rosbag2::record( | ||
const std::string & file_name, | ||
const std::string & topic_name, | ||
std::function<void(void)> after_write_action) | ||
std::vector<std::string> topic_names, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const ref
- this allows new topics to be discovered also after startup. - as a consquence, ros2 bag record won't throw any exception anymore if the specified topics are not available at startup - each time the recorder subscribes to a new topic, this will be logged to console
- make option available in RecordOptions - set to 100ms for now
- this allows new topics to be discovered also after startup. - as a consquence, ros2 bag record won't throw any exception anymore if the specified topics are not available at startup - each time the recorder subscribes to a new topic, this will be logged to console
- make option available in RecordOptions - set to 100ms for now
- use set for subscribed topics instead of vector - perform the asynchronous call only when discovery is needed
- this allows new topics to be discovered also after startup. - as a consquence, ros2 bag record won't throw any exception anymore if the specified topics are not available at startup - each time the recorder subscribes to a new topic, this will be logged to console
- make option available in RecordOptions - set to 100ms for now
- use set for subscribed topics instead of vector - perform the asynchronous call only when discovery is needed
- naming of methods - emphasize similarity between first subscription and discovery loop
* GH-27 Implement discovery for new topics after startup - this allows new topics to be discovered also after startup. - as a consquence, ros2 bag record won't throw any exception anymore if the specified topics are not available at startup - each time the recorder subscribes to a new topic, this will be logged to console * GH-27 Provide polling frequency as option - make option available in RecordOptions - set to 100ms for now * GH-27 Stop topic polling if subscription setup is complete * GH-27 Minor refactoring for readability * GH-27 Fix build after rebase * GH-145 add no-discovery option to ros2 bag record * GH-27 Refactor subscribing mechanism - use set for subscribed topics instead of vector - perform the asynchronous call only when discovery is needed * GH-27 Expose polling-interval as cli option * GH-27 Minor refactoring * GH-27 Refactor recorder - naming of methods - emphasize similarity between first subscription and discovery loop * small touch ups * remove launch from function name
Addressing feedback from ros/rosdistro#32534 (comment) Make mcap available as a shared library in the mcap_vendor package. It does not depend on lz4/zstd shared libraries but pulls them in directly using FetchContent. mcap itself is also fetched directly from git instead of using conan to pull in the dependency. Closes ros2#26, closes ros2#27 Signed-off-by: Jacob Bandes-Storch <jacob@foxglove.dev>
Addressing feedback from ros/rosdistro#32534 (comment) Make mcap available as a shared library in the mcap_vendor package. It does not depend on lz4/zstd shared libraries but pulls them in directly using FetchContent. mcap itself is also fetched directly from git instead of using conan to pull in the dependency. Closes ros2#26, closes ros2#27 Signed-off-by: Jacob Bandes-Storch <jacob@foxglove.dev> Signed-off-by: James Smith <james@foxglove.dev>
…ooling/rosbag_storage_mcap#28) Addressing feedback from ros/rosdistro#32534 (comment) Make mcap available as a shared library in the mcap_vendor package. It does not depend on lz4/zstd shared libraries but pulls them in directly using FetchContent. mcap itself is also fetched directly from git instead of using conan to pull in the dependency. Closes ros2#26, closes ros2#27 Signed-off-by: Jacob Bandes-Storch <jacob@foxglove.dev> Signed-off-by: James Smith <james@foxglove.dev>
…ooling/rosbag2_storage_mcap#28) Addressing feedback from ros/rosdistro#32534 (comment) Make mcap available as a shared library in the mcap_vendor package. It does not depend on lz4/zstd shared libraries but pulls them in directly using FetchContent. mcap itself is also fetched directly from git instead of using conan to pull in the dependency. Closes ros2#26, closes ros2#27 Signed-off-by: Jacob Bandes-Storch <jacob@foxglove.dev> Signed-off-by: James Smith <james@foxglove.dev>
This PR is based on PR #26.
This extends both the recording and replaying to support multiple topics at the same time.
Current limitation:
Known issue
after_write_action
argument ofRosbag2::record
is used only for the tests. We should be able to remove it soon, but will do so in a separate PR.