ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Dear ROS developers,

If you want a solution in C++, check out THIS. Pieces of code for illustrating the solution:

struct ActivationFuture
{
  std::shared_future<std::shared_ptr<bica_msgs::srv::ActivateComponent_Response_<std::allocator<void>>>> future;
  std::string component;
};

class MyNode : public rclcpp::Node
{
  rclcpp::Service<bica_msgs::srv::ActivateComponent>::SharedPtr activation_service_; 
  std::vector<ActivationFuture> pending_act_futures_;

  void
  MyNode::activateDependency(const std::string & dep)
  {
    auto client = this->create_client<bica_msgs::srv::ActivateComponent>("/" + dep + "/activate");

    if (!client->wait_for_service(100ms)) {
      RCLCPP_ERROR(get_logger(), "Service %s is not available.",
        client->get_service_name());
      return;
    }

    auto request = std::make_shared<bica_msgs::srv::ActivateComponent::Request>();
    request->activator = get_name();

    auto future = client->async_send_request(request);
    pending_act_futures_.push_back(ActivationFuture{future, dep});
  }

  bool
  MyNode::ok()
  {
    if (rclcpp::ok()) {
      while(!pending_act_futures_.empty()) {
        auto pending_future = pending_act_futures_.back();
        if ((rclcpp::spin_until_future_complete(this->get_node_base_interface(), pending_future.future)) !=
          rclcpp::executor::FutureReturnCode::SUCCESS)
        {
          RCLCPP_WARN(get_logger(), "Component [%s] failed to activate", pending_future.component.c_str());
        }
        pending_act_futures_.pop_back();
      }
    }

    return rclcpp::ok();
  }

  void
  MyNode::execute()
  {
    while (this->ok()) {
      rclcpp::spin_some(this->get_node_base_interface());
      rate_.sleep();
    }
}

The bad thing is that you need a different vector for each type of future. Any ideas?

I hope it helps!!!