Skip to content

Commit

Permalink
rosbag2_storage: set MCAP as default plugin (#1160)
Browse files Browse the repository at this point in the history
switches the default storage plugin from `sqlite3` to `mcap`.

## Reason for change

Benchmarks suggest that MCAP can support higher write throughput than the `sqlite3` plugin in its default configuration, while also bringing the following other benefits:

* Append-only write behavior ensures that only the last few messages written can be corrupted in the case of a power outage or recorder crash. This is similar to the corruption guarantees offered by SQLite3 in [WAL mode](https://sqlite.org/wal.html), which is what is used in the `resilient` SQLite storage plugin preset.
* Ability to enable chunk compression, which should be more space-efficient than message compression for bags with many small messages. This also enables reader to use the message index, unlike file-level compression.
* Record message schemas to the bag by default, enabling applications outside the ROS 2 workspace to read message content.

## Benchmarks
Read the benchmarking analysis that lead to this conclusion [here](https://mcap.dev/performance-comparison/rosbag2-plugin-comparison.html).

### `rosbag2_performance_benchmarking`

There is a set of pre-existing benchmarks in the rosbag2 repo here: https://github.com/ros2/rosbag2/tree/rolling/rosbag2_performance/rosbag2_performance_benchmarking

We've run these in an attempt to compare the performance of MCAP against SQLite on these metrics, but at this point the results appear to be pure noise. A full analysis of why will be published to mcap.dev shortly, but for now the news is that we have not succeeded in producing a statistically significant difference in results between MCAP and SQLite.


## TODO
- [x] #1112
- [x] ros-tooling/rosbag2_storage_mcap#61
- [x] ros-tooling/rosbag2_storage_mcap#63
- [x] #1185
- [x] Parametrize `rosbag2_tests`
  • Loading branch information
james-rms authored Dec 22, 2022
1 parent 47dff03 commit c488567
Show file tree
Hide file tree
Showing 8 changed files with 10 additions and 21 deletions.
2 changes: 0 additions & 2 deletions ros2bag/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@
<test_depend>launch_testing_ros</test_depend>
<test_depend>python3-pytest</test_depend>
<test_depend>rosbag2_storage_default_plugins</test_depend>
<!-- TODO: remove dependency when rosbag2_storage_default_plugins depends on MCAP -->
<test_depend>rosbag2_storage_mcap</test_depend>
<test_depend>rosbag2_test_common</test_depend>

<export>
Expand Down
18 changes: 8 additions & 10 deletions ros2bag/test/test_record_qos_profiles.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,32 +84,30 @@ def test_qos_simple(self):
output_path = Path(self.tmpdir.name) / 'ros2bag_test_basic'
arguments = ['record', '-a', '--qos-profile-overrides-path', profile_path.as_posix(),
'--output', output_path.as_posix()]
expected_string_regex = re.compile(
r'\[rosbag2_storage]: Opened database .* for READ_WRITE')
expected_output = 'Listening for topics...'
with self.launch_bag_command(arguments=arguments) as bag_command:
bag_command.wait_for_output(
condition=lambda output: expected_string_regex.search(output) is not None,
condition=lambda output: expected_output in output,
timeout=OUTPUT_WAIT_TIMEOUT)
bag_command.wait_for_shutdown(timeout=SHUTDOWN_TIMEOUT)
assert bag_command.terminated
matches = expected_string_regex.search(bag_command.output)
assert matches, ERROR_STRING_MSG.format(expected_string_regex.pattern, bag_command.output)
matches = expected_output in bag_command.output
assert matches, ERROR_STRING_MSG.format(expected_output, bag_command.output)

def test_incomplete_qos_profile(self):
profile_path = PROFILE_PATH / 'incomplete_qos_profile.yaml'
output_path = Path(self.tmpdir.name) / 'ros2bag_test_incomplete'
arguments = ['record', '-a', '--qos-profile-overrides-path', profile_path.as_posix(),
'--output', output_path.as_posix()]
expected_string_regex = re.compile(
r'\[rosbag2_storage]: Opened database .* for READ_WRITE')
expected_output = 'Listening for topics...'
with self.launch_bag_command(arguments=arguments) as bag_command:
bag_command.wait_for_output(
condition=lambda output: expected_string_regex.search(output) is not None,
condition=lambda output: expected_output in output,
timeout=OUTPUT_WAIT_TIMEOUT)
bag_command.wait_for_shutdown(timeout=SHUTDOWN_TIMEOUT)
assert bag_command.terminated
matches = expected_string_regex.search(bag_command.output)
assert matches, ERROR_STRING_MSG.format(expected_string_regex.pattern, bag_command.output)
matches = expected_output in bag_command.output
assert matches, ERROR_STRING_MSG.format(expected_output, bag_command.output)

def test_incomplete_qos_duration(self):
profile_path = PROFILE_PATH / 'incomplete_qos_duration.yaml'
Expand Down
3 changes: 0 additions & 3 deletions rosbag2_cpp/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@
<depend>shared_queues_vendor</depend>

<test_depend>rosbag2_storage_default_plugins</test_depend>
<!-- TODO: remove dependency when rosbag2_storage_default_plugins depends on MCAP -->
<test_depend>rosbag2_storage_mcap</test_depend>

<test_depend>ament_cmake_gmock</test_depend>
<test_depend>ament_lint_auto</test_depend>
<test_depend>ament_lint_common</test_depend>
Expand Down
2 changes: 0 additions & 2 deletions rosbag2_py/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@
<test_depend>rcl_interfaces</test_depend>
<test_depend>rclpy</test_depend>
<test_depend>rosbag2_storage_default_plugins</test_depend>
<!-- TODO: remove dependency when rosbag2_storage_default_plugins depends on MCAP -->
<test_depend>rosbag2_storage_mcap</test_depend>
<test_depend>rosbag2_test_common</test_depend>
<test_depend>rosidl_runtime_py</test_depend>
<test_depend>std_msgs</test_depend>
Expand Down
2 changes: 1 addition & 1 deletion rosbag2_storage/src/rosbag2_storage/default_storage_id.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace rosbag2_storage

std::string get_default_storage_id()
{
return "sqlite3";
return "mcap";
}

} // namespace rosbag2_storage
1 change: 1 addition & 0 deletions rosbag2_storage_default_plugins/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<buildtool_depend>ament_cmake</buildtool_depend>

<!-- Default plugins -->
<exec_depend>rosbag2_storage_mcap</exec_depend>
<exec_depend>rosbag2_storage_sqlite3</exec_depend>

<export>
Expand Down
2 changes: 0 additions & 2 deletions rosbag2_tests/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@
<test_depend>rosbag2_compression_zstd</test_depend>
<test_depend>rosbag2_cpp</test_depend>
<test_depend>rosbag2_storage_default_plugins</test_depend>
<!-- TODO(mcap): remove when mcap is added to default plugins -->
<test_depend>rosbag2_storage_mcap</test_depend>
<test_depend>rosbag2_storage</test_depend>
<test_depend>rosbag2_test_common</test_depend>
<test_depend>std_msgs</test_depend>
Expand Down
1 change: 0 additions & 1 deletion rosbag2_transport/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
<test_depend>rosbag2_compression_zstd</test_depend>
<test_depend>rosbag2_test_common</test_depend>
<test_depend>rosbag2_storage_default_plugins</test_depend>
<test_depend>rosbag2_storage_mcap</test_depend>
<test_depend>test_msgs</test_depend>

<export>
Expand Down

0 comments on commit c488567

Please sign in to comment.