151 const std::
string & instance_name, const Config & config, Context context, const rclcpp::QoS & qos)
152: BT::ConditionNode(instance_name, config),
154 logger_(context.getChildLogger(
auto_apms_util::toSnakeCase(instance_name))),
158 this->modifyPortsRemapping(context_.copyAliasedPortValuesToOriginalPorts(
this));
160 if (
const BT::Expected<std::string> expected_name = context_.getTopicName(
this)) {
166 dynamic_client_instance_ =
true;
173 if (topic_name.empty()) {
174 throw exceptions::RosNodeError(
175 context_.getFullyQualifiedTreeNodeName(
this) +
" - Argument topic_name is empty when trying to create a client.");
179 if (publisher_ && topic_name_ == topic_name)
return true;
181 rclcpp::Node::SharedPtr node = context_.nh_.lock();
183 throw exceptions::RosNodeError(
184 context_.getFullyQualifiedTreeNodeName(
this) +
185 " - The weak pointer to the ROS 2 node expired. The tree node doesn't "
186 "take ownership of it.");
189 publisher_ = node->template create_publisher<MessageT>(topic_name, qos_);
190 topic_name_ = topic_name;
192 logger_,
"%s - Created publisher for topic '%s'.", context_.getFullyQualifiedTreeNodeName(
this).c_str(),
197 logger_,
"%s - Waiting for at least one subscriber to connect to topic '%s'...",
198 context_.getFullyQualifiedTreeNodeName(
this).c_str(), topic_name_.c_str());
200 const auto start_time = context_.getCurrentTime();
201 while (rclcpp::ok() && publisher_->get_subscription_count() == 0) {
202 if ((context_.getCurrentTime() - start_time) > context_.registration_options_.wait_timeout) {
204 logger_,
"%s - Timeout waiting for subscriber to connect to topic '%s' after %.2f seconds.",
205 context_.getFullyQualifiedTreeNodeName(
this).c_str(), topic_name_.c_str(),
206 context_.registration_options_.wait_timeout.count());
209 rclcpp::sleep_for(std::chrono::milliseconds(5));
212 if (publisher_->get_subscription_count() > 0) {
214 logger_,
"%s - At least one subscriber found.", context_.getFullyQualifiedTreeNodeName(
this).c_str(),
215 topic_name_.c_str());
216 }
else if (context_.registration_options_.allow_unreachable) {
218 logger_,
"%s - No subscriber connected to topic '%s', but continuing as allow_unreachable is true.",
219 context_.getFullyQualifiedTreeNodeName(
this).c_str(), topic_name_.c_str());
221 throw exceptions::RosNodeError(
222 context_.getFullyQualifiedTreeNodeName(
this) +
" - No subscriber connected to topic '" + topic_name_ +
223 "' after waiting for " + std::to_string(context_.registration_options_.wait_timeout.count()) +
" seconds.");