Robotics StackExchange | Archived questions

how to call services periodically using a wall_timer

Dear Community,

I'm an inexperienced coder and new to ROS, please understand...

I want to figure out why I cannot call a service (by sending a request and waiting for a response) from a node's wall_timer. I've attached a text file outlining two simple methods that yielded different, undesirable results. I hope they sufficiently describe the error I'm having. If not please let me know. I am not necessarily looking for a solution, rather for an explanation of what could be causing this issue from occurring. My knowledge of ROS and C++ is limited so maybe it is really obvious to you...

Thanks to anyone taking the time to help me out!

The issue:

Calling a service periodically, using a rclcpp::wall_timer:

Wall Timer Callback Function:

void connection::timercallback() { // 1. create a request auto testrequest = networklibrary::createrequest(1,1,1,1);

// 2. print a confirmation and the contents of the request to cmd line
network_library::print_string(" 2. sending a request asynchronously");
network_library::print_message(test_request);

// 3. send the request asynchronously, create a shared_future to store response
auto result = test_client->async_send_request(test_request);

//4. print a confirmation that the request has been sent
network_library::print_string(" 4. the request has been sent...");

// 5.1 use the shared_future::get() function to "get" the resulting response from server
//network_library::print_message(result.get()); // 6 print result

// 5.2 use the rclcpp::spin_until_future_complete() function to receive the result
if (rclcpp::spin_until_future_complete(shared_from_this(), result) == rclcpp::executor::FutureReturnCode::SUCCESS) {
    network_library::print_message(result); // 6 print result
}

}

Generates the following results at runtime (copied from command line):

Results from CLIENT:

Result using method 5.1:

ostfalia@ros:~/devws/src$ ros2 run client main [INFO] [1667311571.935233573] [rclcpp]: PRINTING STRING: 2. sending a request asynchronously [INFO] [1667311571.935259523] [rclcpp]: PRINTING REQUEST: requesttojoin=1, requesttoleave=1, requesttoupdatestatus=1, requestmyaddress=1 [INFO] [1667311571.935283763] [rclcpp]: PRINTING STRING: 4. the request has been sent...

//NOTE: nothing else happens. No other processes continue to function on the client node, no errors are returned.

Result using method 5.2:

ostfalia@ros:~/devws/src$ ros2 run client main [INFO] [1667311356.481893614] [rclcpp]: PRINTING STRING: 2. sending a request asynchronously [INFO] [1667311356.481949266] [rclcpp]: PRINTING REQUEST: requesttojoin=1, requesttoleave=1, requesttoupdatestatus=1, requestmyaddress=1 [INFO] [1667311356.482006749] [rclcpp]: PRINTING STRING: 4. the request has been sent... terminate called after throwing an instance of 'std::runtime_error' what(): Node has already been added to an executor.

Results from the SERVER:

Result using method 5.1/5.2 (both are identical):

ostfalia@ros:~/devws/src$ ros2 run server main [INFO] [1667311356.482242917] [rclcpp]: PRINTING STRING: request: [INFO] [1667311356.482344470] [rclcpp]: PRINTING REQUEST: requesttojoin=1, requesttoleave=1, requesttoupdatestatus=1, requestmyaddress=1 [INFO] [1667311356.482358398] [rclcpp]: PRINTING STRING: response: [INFO] [1667311356.482366973] [rclcpp]: PRINTING RESPONSE: letjoin=1, letleave=0, letupdatestatus=0, assignaddress=0 ^C[INFO] [1667311554.420049898] [rclcpp]: signalhandler(signalvalue=2) ostfalia@ros:~/devws/src$ ros2 run server main [INFO] [1667311571.935411564] [rclcpp]: PRINTING STRING: request: [INFO] [1667311571.935473490] [rclcpp]: PRINTING REQUEST: requesttojoin=1, requesttoleave=1, requesttoupdatestatus=1, requestmyaddress=1 [INFO] [1667311571.935481638] [rclcpp]: PRINTING STRING: response: [INFO] [1667311571.935489331] [rclcpp]: PRINTING RESPONSE: letjoin=1, letleave=0, letupdatestatus=0, assignaddress=0

Essentially it shows that calling the spinuntilfuture_complete() function (5.2) results in a runtime error and in the other configuration (5.1) the .get() never returns and the client node doesn't get anywhere.

Asked by ros_newb on 2022-11-01 09:47:31 UTC

Comments

how to call services periodically using a wall_timer

This may help: https://docs.ros.org/en/foxy/How-To-Guides/Using-callback-groups.html

Asked by ravijoshi on 2022-11-02 07:41:40 UTC

Answers