@@ -66,6 +66,7 @@ class RosTopicSubNode : public BT::ConditionNode
66
66
// The callback will broadcast to all the instances of RosTopicSubNode<T>
67
67
auto callback = [this ](const std::shared_ptr<TopicT> msg)
68
68
{
69
+ last_msg = msg;
69
70
broadcaster (msg);
70
71
};
71
72
subscriber = node->create_subscription <TopicT>(topic_name, 1 , callback, option);
@@ -75,6 +76,7 @@ class RosTopicSubNode : public BT::ConditionNode
75
76
rclcpp::CallbackGroup::SharedPtr callback_group;
76
77
rclcpp::executors::SingleThreadedExecutor callback_group_executor;
77
78
boost::signals2::signal<void (const std::shared_ptr<TopicT>)> broadcaster;
79
+ std::shared_ptr<TopicT> last_msg;
78
80
79
81
80
82
};
@@ -173,6 +175,16 @@ class RosTopicSubNode : public BT::ConditionNode
173
175
*/
174
176
virtual NodeStatus onTick (const std::shared_ptr<TopicT>& last_msg) = 0;
175
177
178
+ /* * latch the message that has been processed. If returns false and no new message is
179
+ * received, before next call there will be no message to process. If returns true,
180
+ * the next call will process the same message again, if no new message received.
181
+ *
182
+ * This can be equated with latched vs non-latched topics in ros 1.
183
+ *
184
+ * @return false will clear the message after ticking/processing.
185
+ */
186
+ virtual bool latchLastMessage () const { return false ; }
187
+
176
188
private:
177
189
178
190
bool createSubscriber (const std::string& topic_name);
@@ -260,6 +272,11 @@ template<class T> inline
260
272
sub_instance_ = it->second ;
261
273
}
262
274
275
+ // Check if there was a message received before the creation of this subscriber action
276
+ if (sub_instance_->last_msg )
277
+ {
278
+ last_msg_ = sub_instance_->last_msg ;
279
+ }
263
280
264
281
// add "this" as received of the broadcaster
265
282
signal_connection_ = sub_instance_->broadcaster .connect (
@@ -276,12 +293,18 @@ template<class T> inline
276
293
// First, check if the subscriber_ is valid and that the name of the
277
294
// topic_name in the port didn't change.
278
295
// otherwise, create a new subscriber
296
+ std::string topic_name;
297
+ getInput (" topic_name" , topic_name);
298
+
279
299
if (!sub_instance_)
280
300
{
281
- std::string topic_name;
282
- getInput (" topic_name" , topic_name);
283
301
createSubscriber (topic_name);
284
302
}
303
+ else if (topic_name_ != topic_name)
304
+ {
305
+ sub_instance_.reset ();
306
+ createSubscriber (topic_name);
307
+ }
285
308
286
309
auto CheckStatus = [](NodeStatus status)
287
310
{
@@ -294,8 +317,10 @@ template<class T> inline
294
317
};
295
318
sub_instance_->callback_group_executor .spin_some ();
296
319
auto status = CheckStatus (onTick (last_msg_));
297
- last_msg_ = nullptr ;
298
-
320
+ if (!latchLastMessage ())
321
+ {
322
+ last_msg_.reset ();
323
+ }
299
324
return status;
300
325
}
301
326
0 commit comments