-
Notifications
You must be signed in to change notification settings - Fork 4.9k
add foxy packages for rosbag2, dummy reader/writer #14461
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
Open
AviaAv
wants to merge
18
commits into
realsenseai:record-playback
Choose a base branch
from
AviaAv:rec-play
base: record-playback
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+94,788
−7
Open
Changes from 1 commit
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
60f150a
add foxy packages for rosbag2, dummy reader/writer
AviaAv 2a64bb8
fix copyright, change cmake files
AviaAv 0ca6b6e
moved rosbag2 targets into realsense-file
AviaAv 29aa073
Update CMakeLists.txt
AviaAv f3dbe94
move fetchContent location
AviaAv 9ea4319
enable rosbag2 by default to compile on GHA
AviaAv 46753f7
replace logging files on rcutils version with rolling
AviaAv a4d39c3
use _GNU_SOURCE if glibc is used
AviaAv 49dfa55
fix function usage, add compile flag properly
AviaAv 297dbf7
try change cmake version
AviaAv 72dfb04
add compile options
AviaAv 3b1bf90
Revert "add compile options"
AviaAv d74db81
Update CMakeLists.txt
AviaAv 5321105
Update CMakeLists.txt
AviaAv c2be875
try fix link issues
AviaAv 892044c
Update CMakeLists.txt
AviaAv 1d9d189
remove some files
AviaAv f7665e0
sqlite3 moved to a separate file
AviaAv File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,161 @@ | ||
| // License: Apache 2.0. See LICENSE file in root directory. | ||
| #include "ros2_reader.h" | ||
| #include <rsutils/string/from.h> | ||
| #include <algorithm> | ||
| #include <cstring> | ||
| #include <src/source.h> // for frame_source & stream_to_frame_types | ||
|
|
||
| namespace librealsense { | ||
| using namespace device_serializer; | ||
|
|
||
| static std::string to_string_buffer( const rosbag2_storage::SerializedBagMessage & msg ) | ||
| { | ||
| if( ! msg.serialized_data || ! msg.serialized_data->buffer ) return {}; | ||
| return std::string( reinterpret_cast< char * >( msg.serialized_data->buffer ), msg.serialized_data->buffer_length ); | ||
| } | ||
|
|
||
| ros2_reader::ros2_reader( std::shared_ptr< rosbag2_storage::storage_interfaces::ReadOnlyInterface > storage ) | ||
| : _storage( std::move( storage ) ) | ||
| { | ||
| if( _storage ) | ||
| _file = _storage->get_relative_file_path(); | ||
| reset(); | ||
| } | ||
|
|
||
| device_snapshot ros2_reader::query_device_description( const nanoseconds & ) | ||
| { | ||
| // Minimal empty snapshot; advanced device description reconstruction can be added later | ||
| return device_snapshot(); | ||
| } | ||
|
|
||
| void ros2_reader::reset() | ||
| { | ||
| _messages.clear(); | ||
| _cursor = 0; | ||
| if( ! _storage ) return; | ||
| while( _storage->has_next() ) | ||
| { | ||
| auto m = _storage->read_next(); | ||
| _messages.push_back( *m ); | ||
| } | ||
| if( ! _messages.empty() ) | ||
| { | ||
| auto first_ts = _messages.front().time_stamp; | ||
| auto last_ts = _messages.back().time_stamp; | ||
| if( last_ts > first_ts ) | ||
| _duration = nanoseconds( static_cast< uint64_t >( last_ts - first_ts ) ); | ||
| } | ||
| _initialized = true; | ||
| } | ||
|
|
||
| void ros2_reader::seek_to_time( const nanoseconds & t ) | ||
| { | ||
| if( _messages.empty() ) return; | ||
| int64_t target = static_cast< int64_t >( t.count() ); | ||
| _cursor = 0; | ||
| while( _cursor < _messages.size() && _messages[ _cursor ].time_stamp < target ) | ||
| ++_cursor; | ||
| } | ||
|
|
||
| std::shared_ptr< serialized_data > ros2_reader::parse_frame( std::string const & topic, const rosbag2_storage::SerializedBagMessage & msg ) | ||
| { | ||
| auto sid = ros_topic::get_stream_identifier( topic ); | ||
| frame_additional_data add{}; | ||
| add.timestamp = double( msg.time_stamp ) / 1e6; // ns -> ms | ||
| add.frame_number = 0; // will try to parse later from metadata message if present | ||
| add.fisheye_ae_mode = false; | ||
|
|
||
| auto size = msg.serialized_data->buffer_length; | ||
| // allocate frame | ||
| frame_source fs( 32 ); | ||
| fs.init( nullptr ); | ||
| frame_interface * fi = fs.alloc_frame( { sid.stream_type, sid.stream_index, librealsense::frame_source::stream_to_frame_types( sid.stream_type ) }, size, std::move( add ), true ); | ||
| if( ! fi ) | ||
| return std::make_shared< serialized_invalid_frame >( nanoseconds( msg.time_stamp ), sid ); | ||
| std::memcpy( const_cast< uint8_t * >( fi->get_frame_data() ), msg.serialized_data->buffer, size ); | ||
| frame_holder fh{ fi }; | ||
| return std::make_shared< serialized_frame >( nanoseconds( msg.time_stamp ), sid, std::move( fh ) ); | ||
| } | ||
|
|
||
| std::shared_ptr< serialized_data > ros2_reader::parse_option( std::string const & topic, const rosbag2_storage::SerializedBagMessage & msg ) | ||
| { | ||
| auto sid = ros_topic::get_sensor_identifier( topic ); | ||
| std::string payload = to_string_buffer( msg ); | ||
| float value = 0.f; | ||
| try { value = std::stof( payload ); } catch(...) {} | ||
| // option id from topic name | ||
| rs2_option opt_id = RS2_OPTION_COUNT; | ||
| try | ||
| { | ||
| std::string opt_name = ros_topic::get_option_name( topic ); | ||
| std::replace( opt_name.begin(), opt_name.end(), '_', ' ' ); | ||
| if( ! try_parse( opt_name, opt_id ) ) | ||
| return nullptr; | ||
| } | ||
| catch(...) { return nullptr; } | ||
|
|
||
| auto option = std::make_shared< const_value_option >( "Recorded option", value ); | ||
| return std::make_shared< serialized_option >( nanoseconds( msg.time_stamp ), sid, opt_id, option ); | ||
| } | ||
|
|
||
| std::shared_ptr< serialized_data > ros2_reader::parse_notification( std::string const & topic, const rosbag2_storage::SerializedBagMessage & msg ) | ||
| { | ||
| auto sid = ros_topic::get_sensor_identifier( topic ); | ||
| std::string payload = to_string_buffer( msg ); | ||
| // very simple parse key=value; pairs (only category/severity/description/timestamp extracted) | ||
| rs2_notification_category category = RS2_NOTIFICATION_CATEGORY_UNKNOWN_ERROR; | ||
| rs2_log_severity severity = RS2_LOG_SEVERITY_INFO; | ||
| std::string description; | ||
| uint64_t ts_val = msg.time_stamp; | ||
| size_t pos = 0; | ||
| while( pos < payload.size() ) | ||
| { | ||
| auto semi = payload.find( ';', pos ); | ||
| std::string part = payload.substr( pos, semi == std::string::npos ? std::string::npos : semi - pos ); | ||
| auto eq = part.find( '=' ); | ||
| if( eq != std::string::npos ) | ||
| { | ||
| std::string key = part.substr( 0, eq ); | ||
| std::string val = part.substr( eq + 1 ); | ||
| if( key == "category" ) try_parse( val, category ); | ||
| else if( key == "severity" ) try_parse( val, severity ); | ||
| else if( key == "description" ) description = val; | ||
| else if( key == "timestamp" ) { try { ts_val = std::stoull( val ); } catch(...) {} } | ||
| } | ||
| if( semi == std::string::npos ) break; | ||
| pos = semi + 1; | ||
| } | ||
| notification n( category, 0, severity, description ); | ||
| n.timestamp = ts_val; | ||
| return std::make_shared< serialized_notification >( nanoseconds( msg.time_stamp ), sid, n ); | ||
| } | ||
|
|
||
| std::shared_ptr< serialized_data > ros2_reader::parse_message( const rosbag2_storage::SerializedBagMessage & msg ) | ||
| { | ||
| std::string topic = msg.topic_name; | ||
| if( topic.find( "/option/" ) != std::string::npos && topic.find( "/value" ) != std::string::npos ) | ||
| return parse_option( topic, msg ); | ||
| if( topic.find( "/notification/" ) != std::string::npos ) | ||
| return parse_notification( topic, msg ); | ||
|
|
||
| // frame data topics end with /data and contain raw bytes | ||
| if( topic.find( "/data" ) != std::string::npos && topic.find( "/tf" ) == std::string::npos && topic.find( "/metadata" ) == std::string::npos ) | ||
| return parse_frame( topic, msg ); | ||
|
|
||
| return nullptr; // ignore others | ||
| } | ||
|
|
||
| std::shared_ptr< serialized_data > ros2_reader::read_next_data() | ||
| { | ||
| if( _cursor >= _messages.size() ) | ||
| return std::make_shared< serialized_end_of_file >(); | ||
| while( _cursor < _messages.size() ) | ||
| { | ||
| auto & m = _messages[ _cursor++ ]; | ||
| auto data = parse_message( m ); | ||
| if( data ) return data; | ||
| } | ||
| return std::make_shared< serialized_end_of_file >(); | ||
| } | ||
|
|
||
| } // namespace librealsense | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| // License: Apache 2.0. See LICENSE file in root directory. | ||
| #pragma once | ||
| #include <core/serialization.h> | ||
| #include <rosbag2_storage/storage_interfaces/read_only_interface.hpp> | ||
| #include <rosbag2_storage/serialized_bag_message.hpp> | ||
| #include <memory> | ||
| #include <unordered_map> | ||
| #include <vector> | ||
|
|
||
| #include <media/ros/ros_file_format.h> | ||
| #include <src/core/frame-interface.h> | ||
| #include <src/core/stream-profile-interface.h> | ||
| #include <src/option.h> | ||
|
|
||
| namespace librealsense { | ||
|
|
||
| class frame_source; // forward declaration | ||
|
|
||
| class ros2_reader : public device_serializer::reader | ||
| { | ||
| public: | ||
| explicit ros2_reader( std::shared_ptr< rosbag2_storage::storage_interfaces::ReadOnlyInterface > storage ); | ||
|
|
||
| device_serializer::device_snapshot query_device_description( const device_serializer::nanoseconds & ) override; | ||
| std::shared_ptr< device_serializer::serialized_data > read_next_data() override; | ||
| void seek_to_time( const device_serializer::nanoseconds & ) override; // linear seek | ||
| device_serializer::nanoseconds query_duration() const override { return _duration; } | ||
| void reset() override; // rewind to beginning | ||
| void enable_stream( const std::vector< device_serializer::stream_identifier > & ) override {} | ||
| void disable_stream( const std::vector< device_serializer::stream_identifier > & ) override {} | ||
| const std::string & get_file_name() const override { return _file; } | ||
| std::vector< std::shared_ptr< device_serializer::serialized_data > > fetch_last_frames( const device_serializer::nanoseconds & ) override { return {}; } | ||
|
|
||
| private: | ||
| std::shared_ptr< device_serializer::serialized_data > parse_message( const rosbag2_storage::SerializedBagMessage & ); | ||
| std::shared_ptr< device_serializer::serialized_data > parse_frame( std::string const & topic, const rosbag2_storage::SerializedBagMessage & ); | ||
| std::shared_ptr< device_serializer::serialized_data > parse_option( std::string const & topic, const rosbag2_storage::SerializedBagMessage & ); | ||
| std::shared_ptr< device_serializer::serialized_data > parse_notification( std::string const & topic, const rosbag2_storage::SerializedBagMessage & ); | ||
|
|
||
| device_serializer::nanoseconds _duration{}; | ||
| std::shared_ptr< rosbag2_storage::storage_interfaces::ReadOnlyInterface > _storage; | ||
| std::string _file; | ||
| bool _initialized = false; | ||
| std::vector< rosbag2_storage::SerializedBagMessage > _messages; // in-memory list (simple implementation) | ||
| size_t _cursor = 0; | ||
| }; | ||
|
|
||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Why not full realsense copyrights like on other files?