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

Record and play multiple topics #27

Merged

Conversation

anhosi
Copy link
Contributor

@anhosi anhosi commented Aug 29, 2018

This PR is based on PR #26.

This extends both the recording and replaying to support multiple topics at the same time.

  • The required meta data (topic and type) is also stored in the storage

Current limitation:

  • Same as in Allow an arbitrary topic to be recorded #26 the topics to record must be present at start. Discovery for new topics will be added later.
    Known issue
  • The after_write_action argument of Rosbag2::record is used only for the tests. We should be able to remove it soon, but will do so in a separate PR.

This was referenced Aug 30, 2018
@Martin-Idel-SI Martin-Idel-SI force-pushed the feature/record_and_play_multiple_topics branch from 3936546 to b9e6b22 Compare September 4, 2018 08:27
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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alphabet

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

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)
Copy link
Collaborator

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);
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

double whitespace?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

// 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));
Copy link
Collaborator

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?

Copy link
Contributor Author

@anhosi anhosi Sep 4, 2018

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) {
Copy link
Collaborator

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?

Copy link
Contributor Author

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.

#include <memory>
#include <string>

#include "rcutils/types.h"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alphabet

Copy link
Contributor Author

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;
Copy link
Collaborator

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.

Copy link
Contributor Author

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.

Copy link
Contributor Author

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) {
Copy link
Collaborator

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

Copy link
Contributor Author

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)
Copy link
Collaborator

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right. This is still used by the write_integration_test which is massively rewritten in #31. So I would prefer to address this in #31 to avoid an unecessary rebase.

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) {
Copy link
Collaborator

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?

Copy link
Contributor Author

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.

botteroa-si and others added 24 commits September 5, 2018 09:05
- 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.
@anhosi anhosi force-pushed the feature/record_and_play_multiple_topics branch from b9e6b22 to 3eaee5b Compare September 5, 2018 14:19
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,
Copy link
Collaborator

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,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const ref

@Karsten1987 Karsten1987 merged commit c23d188 into ros2:master Sep 5, 2018
@anhosi anhosi deleted the feature/record_and_play_multiple_topics branch September 5, 2018 17:00
Martin-Idel-SI pushed a commit to bosch-io/rosbag2 that referenced this pull request Nov 26, 2018
- 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
Martin-Idel-SI added a commit to bosch-io/rosbag2 that referenced this pull request Nov 26, 2018
- make option available in RecordOptions
- set to 100ms for now
Martin-Idel-SI added a commit to bosch-io/rosbag2 that referenced this pull request Nov 26, 2018
Martin-Idel-SI added a commit to bosch-io/rosbag2 that referenced this pull request Nov 26, 2018
anhosi pushed a commit to bosch-io/rosbag2 that referenced this pull request Nov 30, 2018
- 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
anhosi pushed a commit to bosch-io/rosbag2 that referenced this pull request Nov 30, 2018
- make option available in RecordOptions
- set to 100ms for now
anhosi pushed a commit to bosch-io/rosbag2 that referenced this pull request Nov 30, 2018
anhosi pushed a commit to bosch-io/rosbag2 that referenced this pull request Nov 30, 2018
anhosi added a commit to bosch-io/rosbag2 that referenced this pull request Nov 30, 2018
botteroa-si pushed a commit to bosch-io/rosbag2 that referenced this pull request Dec 6, 2018
- use set for subscribed topics instead of vector
- perform the asynchronous call only when discovery is needed
botteroa-si pushed a commit to bosch-io/rosbag2 that referenced this pull request Dec 6, 2018
botteroa-si added a commit to bosch-io/rosbag2 that referenced this pull request Dec 6, 2018
anhosi pushed a commit to bosch-io/rosbag2 that referenced this pull request Dec 6, 2018
- 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
anhosi pushed a commit to bosch-io/rosbag2 that referenced this pull request Dec 6, 2018
- make option available in RecordOptions
- set to 100ms for now
anhosi pushed a commit to bosch-io/rosbag2 that referenced this pull request Dec 6, 2018
anhosi pushed a commit to bosch-io/rosbag2 that referenced this pull request Dec 6, 2018
anhosi added a commit to bosch-io/rosbag2 that referenced this pull request Dec 6, 2018
anhosi added a commit to bosch-io/rosbag2 that referenced this pull request Dec 6, 2018
- use set for subscribed topics instead of vector
- perform the asynchronous call only when discovery is needed
anhosi added a commit to bosch-io/rosbag2 that referenced this pull request Dec 6, 2018
anhosi pushed a commit to bosch-io/rosbag2 that referenced this pull request Dec 6, 2018
anhosi added a commit to bosch-io/rosbag2 that referenced this pull request Dec 6, 2018
- naming of methods
- emphasize similarity between first subscription and discovery loop
Karsten1987 pushed a commit that referenced this pull request Dec 7, 2018
* 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
james-rms pushed a commit to james-rms/rosbag2 that referenced this pull request Nov 17, 2022
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>
james-rms pushed a commit to james-rms/rosbag2 that referenced this pull request Nov 17, 2022
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>
james-rms pushed a commit to james-rms/rosbag2 that referenced this pull request Nov 18, 2022
…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>
james-rms pushed a commit to james-rms/rosbag2 that referenced this pull request Nov 18, 2022
…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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants