Skip to content

Commit af19ccd

Browse files
committed
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. (cherry picked from commit 8fbbefc)
1 parent 1c3d9e9 commit af19ccd

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
{
@@ -135,6 +136,26 @@ MessageTypeSupport::ConstSharedPtr BabelFishSubscription::get_message_type_suppo
135136

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

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

ros_babel_fish/test/message_decoding.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,33 @@ TEST_F( MessageDecodingTest, arrayTests )
270270
ASSERT_EQ( msg_subarrays_fixed.elementName(), "ros_babel_fish_test_msgs/msg/TestSubArray" );
271271
}
272272

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

0 commit comments

Comments
 (0)