Skip to content

Commit 8fbbefc

Browse files
authored
Add a deserialize method to Subscription (#19)
* Add a deserialize method to Subscription to enable users to use a SerializedMessage and deserialize later. * Catch exceptions when deserializing.
1 parent 2e6a9ec commit 8fbbefc

3 files changed

Lines changed: 50 additions & 0 deletions

File tree

ros_babel_fish/include/ros_babel_fish/detail/babel_fish_subscription.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ class BabelFishSubscription : public rclcpp::SubscriptionBase
7171
void handle_dynamic_message( const rclcpp::dynamic_typesupport::DynamicMessage::SharedPtr &message,
7272
const rclcpp::MessageInfo &message_info ) override;
7373

74+
bool deserialize( const rclcpp::SerializedMessage &serialized, CompoundMessage &out ) const;
75+
7476
private:
7577
RCLCPP_DISABLE_COPY( BabelFishSubscription )
7678

ros_babel_fish/src/detail/babel_fish_subscription.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include <rcl/rcl.h>
1010
#include <rclcpp/node.hpp>
11+
#include <rclcpp/serialization.hpp>
1112

1213
namespace ros_babel_fish
1314
{
@@ -132,6 +133,26 @@ MessageTypeSupport::ConstSharedPtr BabelFishSubscription::get_message_type_suppo
132133

133134
std::string BabelFishSubscription::get_message_type() const { return type_support_->name; }
134135

136+
bool BabelFishSubscription::deserialize( const rclcpp::SerializedMessage &serialized,
137+
CompoundMessage &out ) const
138+
{
139+
auto type_erased = createContainer( *type_support_ );
140+
if ( !type_erased ) {
141+
return false;
142+
}
143+
144+
rclcpp::SerializationBase serializer( &type_support_->type_support_handle );
145+
try {
146+
serializer.deserialize_message( &serialized, type_erased.get() );
147+
} catch ( const std::exception &e ) {
148+
RBF2_ERROR_STREAM( "Failed to deserialize message of type '" << type_support_->name
149+
<< "': " << e.what() );
150+
return false;
151+
}
152+
out = CompoundMessage( *type_support_, std::move( type_erased ) );
153+
return true;
154+
}
155+
135156
rclcpp::dynamic_typesupport::DynamicMessageType::SharedPtr
136157
BabelFishSubscription::get_shared_dynamic_message_type()
137158
{

ros_babel_fish/test/message_decoding.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,33 @@ TEST_F( MessageDecodingTest, arrayTests )
274274
ASSERT_EQ( test_array.uint16s[4], msg_uint16s[4] );
275275
}
276276

277+
TEST_F( MessageDecodingTest, deserializeSerializedMessage )
278+
{
279+
using namespace std::chrono_literals;
280+
rclcpp::GuardCondition::SharedPtr cond = std::make_shared<rclcpp::GuardCondition>();
281+
rclcpp::WaitSet set;
282+
set.add_guard_condition( cond );
283+
284+
std::shared_ptr<rclcpp::SerializedMessage> serialized_message;
285+
auto subscription = fish.create_subscription(
286+
*node, "/test_message_decoding/test_message", 1,
287+
std::function<void( std::shared_ptr<rclcpp::SerializedMessage> )>(
288+
[&serialized_message, &cond]( std::shared_ptr<rclcpp::SerializedMessage> msg ) {
289+
serialized_message = std::move( msg );
290+
cond->trigger();
291+
} ) );
292+
ASSERT_NE( subscription, nullptr );
293+
ASSERT_EQ( set.wait( 5s ).kind(), rclcpp::WaitResultKind::Ready );
294+
ASSERT_NE( serialized_message, nullptr );
295+
296+
CompoundMessage result;
297+
ASSERT_TRUE( subscription->deserialize( *serialized_message, result ) );
298+
299+
ASSERT_TRUE( result.isValid() );
300+
ASSERT_EQ( result.name(), "ros_babel_fish_test_msgs/msg/TestMessage" );
301+
EXPECT_TRUE( MESSAGE_CONTENT_EQUAL( test_message, result ) );
302+
}
303+
277304
int main( int argc, char **argv )
278305
{
279306
testing::InitGoogleTest( &argc, argv );

0 commit comments

Comments
 (0)