Ros2 service client call from non-ros class
Hi there,
My ROS2 knowledge is not sufficient to get over a problem, and I'm in need of some guidance.
I'm trying to one-shot a service call to a Ros2 service server using the c++ client code via not ros2-related c++ code, and (maybe I'm wrong) i see no use of having a running and spinning node in main() , instead I'd like to have the service client initialize , construct the request and send it (waiting for the feedback) and then continue with the rest of the C++ program. At some (unknown) time in the future that same class will shoot another request to the same service . There's no way that i know when the class will be called again so i can't use timers , and for my use case an event-driven service call would fit perfectly.
I checked quite literally every single post that pops up as result in google/ros answers / most if not all the documentation available on the topic, getting a shared_from_this() outside of the constructor, casting pointer between my custom class that inherits :node from the shared ptr, and a whole lot of random attempts of combinations and i can't get it working. I wrote a simple example to paint the issue i have that i can't resolve.
P.s. last resort option that I'd very much like to avoid is just fork a thread and go std::system(ros2 service call etc);
The example is purely to visualize what i am trying to achieve, and it's not meant to be used as actual working code.
Using the latest Ros2 Foxy 0.9.2-1focal.20230317.211418 amd64 on Ubuntu 20.04.6. Thanks to everyone who's willing to help.
class ProblemExampleClassA : public rclcpp::Node {
public:
explicit ProblemExampleClassA() : Node("problem_example") {
client_ = this->create_client<std_srvs::srv::Empty>("/service_target");
};
std::shared_ptr<ProblemExampleClassA> ptr = std::static_pointer_cast<ProblemExampleClassA>(shared_from_this()); // currently bashing my head with this
void something_to_call(std::string asd, std::string dsa) {
std::cout << asd << dsa << std::endl;
//i have two std:strings that i need to send via the request, but for the purpose of this i'm using the empty srv
auto client_future = this->client_->async_send_request(); //etc service logics
};
private:
rclcpp::Client<std_srvs::srv::Empty>::SharedPtr client_;
void callback(rclcpp::Client<std_srvs::srv::Empty>::SharedFuture future) {
auto status = future.wait_for(1s);
if ( status == std::future_status::ready ) {
RCLCPP_INFO(this->get_logger(), "Callback called back!");
};
};
};
class ProblemExampleNonRosClassB { // non-ros class
public:
explicit ProblemExampleNonRosClassB() {};
//whatever
void random_func() {
ProblemExampleClassA classa;
//how to call classa.something_to_call();
//continue with the program from here onwards, but return to this class in the future if needed
};
};