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

Rosbag2 py #638

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added rosbag2_py/AMENT_IGNORE
Empty file.
88 changes: 88 additions & 0 deletions rosbag2_py/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
cmake_minimum_required(VERSION 3.5)
project(rosbag2_py)

# Default to C99
if(NOT CMAKE_C_STANDARD)
set(CMAKE_C_STANDARD 99)
endif()

# Default to C++14
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic -Werror)
endif()

find_package(ament_cmake REQUIRED)
find_package(ament_cmake_ros REQUIRED)
find_package(pybind11 REQUIRED)
find_package(python_cmake_module REQUIRED)
find_package(rosbag2_compression REQUIRED)
find_package(rosbag2_cpp REQUIRED)
find_package(rosbag2_storage REQUIRED)

ament_python_install_package(${PROJECT_NAME})

pybind11_add_module(_reader SHARED
src/rosbag2_py/_reader.cpp
)
ament_target_dependencies(_reader PUBLIC
"rosbag2_compression"
"rosbag2_cpp"
)

pybind11_add_module(_storage SHARED
src/rosbag2_py/_storage.cpp
)
ament_target_dependencies(_storage PUBLIC
"rosbag2_cpp"
"rosbag2_storage"
)

pybind11_add_module(_writer SHARED
src/rosbag2_py/_writer.cpp
)
ament_target_dependencies(_writer PUBLIC
"rosbag2_compression"
"rosbag2_cpp"
)

# Install cython modules as sub-modules of the project
install(
TARGETS
_reader
_storage
_writer
DESTINATION "${PYTHON_INSTALL_DIR}/${PROJECT_NAME}"
)

if(BUILD_TESTING)
find_package(ament_lint_auto REQUIRED)
ament_lint_auto_find_test_dependencies()
find_package(ament_cmake_pytest REQUIRED)

set(_PYTHON_EXECUTABLE "${PYTHON_EXECUTABLE}")
if(WIN32 AND "${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
set(_PYTHON_EXECUTABLE "${PYTHON_EXECUTABLE_DEBUG}")
endif()
set(pythonpath "${CMAKE_CURRENT_BINARY_DIR}/rosbag2_py;${CMAKE_CURRENT_SOURCE_DIR}")
if(NOT WIN32)
string(REPLACE ";" ":" pythonpath "${pythonpath}")
endif()
ament_add_pytest_test(test_sequential_reader_py "test/test_sequential_reader.py"
PYTHON_EXECUTABLE "${_PYTHON_EXECUTABLE}"
APPEND_ENV "PYTHONPATH=${pythonpath}"
APPEND_LIBRARY_DIRS "${_append_library_dirs}"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/resources"
)
ament_add_pytest_test(test_sequential_writer_py "test/test_sequential_writer.py"
PYTHON_EXECUTABLE "${_PYTHON_EXECUTABLE}"
APPEND_ENV "PYTHONPATH=${pythonpath}"
APPEND_LIBRARY_DIRS "${_append_library_dirs}"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/resources"
)
endif()

ament_package()
38 changes: 38 additions & 0 deletions rosbag2_py/package.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>rosbag2_py</name>
<version>0.2.4</version>
<description>Python API for rosbag2</description>
<maintainer email="[email protected]">Jacob Perron</maintainer>
<maintainer email="[email protected]">ROS Tooling Working Group</maintainer>
<license>Apache License 2.0</license>

<author email="[email protected]">Mabel Zhang</author>

<buildtool_depend>ament_cmake_ros</buildtool_depend>

<depend>pybind11_vendor</depend>
<depend>python_cmake_module</depend>
<depend>rosbag2_compression</depend>
<depend>rosbag2_cpp</depend>
<depend>rosbag2_storage</depend>

<exec_depend>rpyutils</exec_depend>

<test_depend>ament_lint_auto</test_depend>
<test_depend>ament_lint_common</test_depend>
<test_depend>python3-pytest</test_depend>
<test_depend>rcl_interfaces</test_depend>
<test_depend>rclpy</test_depend>
<test_depend>rosbag2_converter_default_plugins</test_depend>
<test_depend>rosbag2_storage_default_plugins</test_depend>
<test_depend>rosbag2_storage</test_depend>
<test_depend>rosidl_runtime_py</test_depend>
<test_depend>rpyutils</test_depend>
<test_depend>std_msgs</test_depend>

<export>
<build_type>ament_cmake</build_type>
</export>
</package>
2 changes: 2 additions & 0 deletions rosbag2_py/pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[pytest]
junit_family=xunit2
31 changes: 31 additions & 0 deletions rosbag2_py/resources/talker/metadata.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
rosbag2_bagfile_information:
version: 4
storage_identifier: sqlite3
relative_file_paths:
- talker.db3
duration:
nanoseconds: 4531096768
starting_time:
nanoseconds_since_epoch: 1585866235112411371
message_count: 20
topics_with_message_count:
- topic_metadata:
name: /topic
type: std_msgs/msg/String
serialization_format: cdr
offered_qos_profiles: "- history: 3\n depth: 0\n reliability: 1\n durability: 2\n deadline:\n sec: 2147483647\n nsec: 4294967295\n lifespan:\n sec: 2147483647\n nsec: 4294967295\n liveliness: 1\n liveliness_lease_duration:\n sec: 2147483647\n nsec: 4294967295\n avoid_ros_namespace_conventions: false"
message_count: 10
- topic_metadata:
name: /rosout
type: rcl_interfaces/msg/Log
serialization_format: cdr
offered_qos_profiles: "- history: 3\n depth: 0\n reliability: 1\n durability: 1\n deadline:\n sec: 2147483647\n nsec: 4294967295\n lifespan:\n sec: 10\n nsec: 0\n liveliness: 1\n liveliness_lease_duration:\n sec: 2147483647\n nsec: 4294967295\n avoid_ros_namespace_conventions: false"
message_count: 10
- topic_metadata:
name: /parameter_events
type: rcl_interfaces/msg/ParameterEvent
serialization_format: cdr
offered_qos_profiles: "- history: 3\n depth: 0\n reliability: 1\n durability: 2\n deadline:\n sec: 2147483647\n nsec: 4294967295\n lifespan:\n sec: 2147483647\n nsec: 4294967295\n liveliness: 1\n liveliness_lease_duration:\n sec: 2147483647\n nsec: 4294967295\n avoid_ros_namespace_conventions: false"
message_count: 0
compression_format: ""
compression_mode: ""
Binary file added rosbag2_py/resources/talker/talker.db3
Binary file not shown.
Binary file added rosbag2_py/resources/talker/talker.db3-shm
Binary file not shown.
Empty file.
42 changes: 42 additions & 0 deletions rosbag2_py/rosbag2_py/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Copyright 2020 Open Source Robotics Foundation, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from rpyutils import add_dll_directories_from_env

# Since Python 3.8, on Windows we should ensure DLL directories are explicitly added
# to the search path.
# See https://docs.python.org/3/whatsnew/3.8.html#bpo-36085-whatsnew
with add_dll_directories_from_env('PATH'):
from rosbag2_py._reader import \
SequentialCompressionReader, \
SequentialReader
from rosbag2_py._storage import \
ConverterOptions, \
StorageFilter, \
StorageOptions, \
TopicMetadata
from rosbag2_py._writer import \
SequentialCompressionWriter, \
SequentialWriter

__all__ = [
'ConverterOptions',
'SequentialCompressionReader',
'SequentialCompressionWriter',
'SequentialReader',
'SequentialWriter',
'StorageFilter',
'StorageOptions',
'TopicMetadata',
]
120 changes: 120 additions & 0 deletions rosbag2_py/src/rosbag2_py/_reader.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
// Copyright 2020 Open Source Robotics Foundation, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <pybind11/pybind11.h>
#include <pybind11/stl.h>

#include <memory>
#include <string>
#include <vector>

#include "rosbag2_compression/sequential_compression_reader.hpp"
#include "rosbag2_cpp/converter_options.hpp"
#include "rosbag2_cpp/readers/sequential_reader.hpp"
#include "rosbag2_cpp/reader.hpp"
#include "rosbag2_cpp/storage_options.hpp"
#include "rosbag2_storage/storage_filter.hpp"
#include "rosbag2_storage/topic_metadata.hpp"

namespace rosbag2_py
{

template<typename T>
class Reader
{
public:
Reader()
: reader_(std::make_unique<rosbag2_cpp::Reader>(std::make_unique<T>()))
{
}

void open(
rosbag2_cpp::StorageOptions & storage_options,
rosbag2_cpp::ConverterOptions & converter_options)
{
reader_->open(storage_options, converter_options);
}

bool has_next()
{
return reader_->has_next();
}

/// Return a tuple containing the topic name, the serialized ROS message, and
/// the timestamp.
pybind11::tuple read_next()
{
const auto next = reader_->read_next();
rcutils_uint8_array_t rcutils_data = *next->serialized_data.get();
std::string serialized_data(rcutils_data.buffer,
rcutils_data.buffer + rcutils_data.buffer_length);
return pybind11::make_tuple(
next->topic_name, pybind11::bytes(serialized_data), next->time_stamp);
}

/// Return a mapping from topic name to topic type.
std::vector<rosbag2_storage::TopicMetadata> get_all_topics_and_types()
{
return reader_->get_all_topics_and_types();
}

void set_filter(const rosbag2_storage::StorageFilter & storage_filter)
{
return reader_->set_filter(storage_filter);
}

void reset_filter()
{
reader_->reset_filter();
}

protected:
std::unique_ptr<rosbag2_cpp::Reader> reader_;
};
} // namespace rosbag2_py

PYBIND11_MODULE(_reader, m) {
m.doc() = "Python wrapper of the rosbag2_cpp reader API";

pybind11::class_<rosbag2_py::Reader<rosbag2_cpp::readers::SequentialReader>>(
m, "SequentialReader")
.def(pybind11::init())
.def("open", &rosbag2_py::Reader<rosbag2_cpp::readers::SequentialReader>::open)
.def("read_next", &rosbag2_py::Reader<rosbag2_cpp::readers::SequentialReader>::read_next)
.def("has_next", &rosbag2_py::Reader<rosbag2_cpp::readers::SequentialReader>::has_next)
.def(
"get_all_topics_and_types",
&rosbag2_py::Reader<rosbag2_cpp::readers::SequentialReader>::get_all_topics_and_types)
.def("set_filter", &rosbag2_py::Reader<rosbag2_cpp::readers::SequentialReader>::set_filter)
.def("reset_filter", &rosbag2_py::Reader<rosbag2_cpp::readers::SequentialReader>::reset_filter);

pybind11::class_<rosbag2_py::Reader<rosbag2_compression::SequentialCompressionReader>>(
m, "SequentialCompressionReader")
.def(pybind11::init())
.def("open", &rosbag2_py::Reader<rosbag2_compression::SequentialCompressionReader>::open)
.def(
"read_next", &rosbag2_py::Reader<rosbag2_compression::SequentialCompressionReader>::read_next)
.def("has_next", &rosbag2_py::Reader<rosbag2_compression::SequentialCompressionReader>::has_next)
.def(
"get_all_topics_and_types",
&rosbag2_py::Reader<
rosbag2_compression::SequentialCompressionReader
>::get_all_topics_and_types)
.def(
"set_filter",
&rosbag2_py::Reader<rosbag2_compression::SequentialCompressionReader>::set_filter)
.def(
"reset_filter",
&rosbag2_py::Reader<rosbag2_compression::SequentialCompressionReader>::reset_filter);
}
Loading