Skip to content

Commit 57fbeee

Browse files
Merge pull request #52 from tony-p/fix/delayed-subscription
Fix delayed subscription missing first message and change topic name
2 parents b82d850 + 47d60b9 commit 57fbeee

File tree

1 file changed

+29
-4
lines changed

1 file changed

+29
-4
lines changed

behaviortree_ros2/include/behaviortree_ros2/bt_topic_sub_node.hpp

+29-4
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ class RosTopicSubNode : public BT::ConditionNode
6666
// The callback will broadcast to all the instances of RosTopicSubNode<T>
6767
auto callback = [this](const std::shared_ptr<TopicT> msg)
6868
{
69+
last_msg = msg;
6970
broadcaster(msg);
7071
};
7172
subscriber = node->create_subscription<TopicT>(topic_name, 1, callback, option);
@@ -75,6 +76,7 @@ class RosTopicSubNode : public BT::ConditionNode
7576
rclcpp::CallbackGroup::SharedPtr callback_group;
7677
rclcpp::executors::SingleThreadedExecutor callback_group_executor;
7778
boost::signals2::signal<void (const std::shared_ptr<TopicT>)> broadcaster;
79+
std::shared_ptr<TopicT> last_msg;
7880

7981

8082
};
@@ -173,6 +175,16 @@ class RosTopicSubNode : public BT::ConditionNode
173175
*/
174176
virtual NodeStatus onTick(const std::shared_ptr<TopicT>& last_msg) = 0;
175177

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+
176188
private:
177189

178190
bool createSubscriber(const std::string& topic_name);
@@ -260,6 +272,11 @@ template<class T> inline
260272
sub_instance_ = it->second;
261273
}
262274

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+
}
263280

264281
// add "this" as received of the broadcaster
265282
signal_connection_ = sub_instance_->broadcaster.connect(
@@ -276,12 +293,18 @@ template<class T> inline
276293
// First, check if the subscriber_ is valid and that the name of the
277294
// topic_name in the port didn't change.
278295
// otherwise, create a new subscriber
296+
std::string topic_name;
297+
getInput("topic_name", topic_name);
298+
279299
if(!sub_instance_)
280300
{
281-
std::string topic_name;
282-
getInput("topic_name", topic_name);
283301
createSubscriber(topic_name);
284302
}
303+
else if(topic_name_ != topic_name)
304+
{
305+
sub_instance_.reset();
306+
createSubscriber(topic_name);
307+
}
285308

286309
auto CheckStatus = [](NodeStatus status)
287310
{
@@ -294,8 +317,10 @@ template<class T> inline
294317
};
295318
sub_instance_->callback_group_executor.spin_some();
296319
auto status = CheckStatus (onTick(last_msg_));
297-
last_msg_ = nullptr;
298-
320+
if (!latchLastMessage())
321+
{
322+
last_msg_.reset();
323+
}
299324
return status;
300325
}
301326

0 commit comments

Comments
 (0)