ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange |
1 | initial version |
Based on your code, the request to service
is processed at ros::spinOnce()
, and client.call()
is waiting the response from service
. Then a deadlock happens and your program gets stuck at client.call()
as you found.
Using two different nodes, or two processes, is the best way to implement this example because the purpose of ServiceServer
is to provide service to any clients. If you still require to implement this example in a node, I would suggest you create a thread to handle either ros::spinOnce()
or client.call
.
2 | No.2 Revision |
Based on your code, the request to service
is processed at ros::spinOnce()
, and client.call()
is waiting the response from service
. Then a deadlock happens and your program gets stuck at client.call()
as you found.
Using two different nodes, or two processes, is the best way to implement this example because the purpose of ServiceServer
is to provide service to any clients. If you still require to implement this example in a node, I would suggest you create a thread to handle either ros::spinOnce()
or client.call
.
#include<thread>
void spin_wrapper()
{
ros::spin();
}
...
int main(int argc, char *argv[])
{
...
//create and start a thread
std::thread spin_thread(spin_wrapper);
//send request
if(client.call(srv))
{
ROS_INFO("Sum: %ld", (long int)srv.response.sum);
}
else
{
ROS_ERROR("Failed to call service add_two_ints");
return 1;
}
//ros::spinOnce();
}
Note that thread
works since C++11 so your CMakeLists.txt
file should add add_compile_options(-std=c++11)
to enable the function.
3 | No.3 Revision |
Based on your code, the request to service
is processed at ros::spinOnce()
, and client.call()
is waiting the response from service
. Then a deadlock happens and your program gets stuck at client.call()
as you found.
Using two different nodes, or two processes, is the best way to implement this example because the purpose of ServiceServer
is to provide service to any clients. If you still require to implement this example in a node, I would suggest you create a thread to handle either ros::spinOnce()
or client.call
.
#include<thread>
void spin_wrapper()
{
ros::spin();
}
...
int main(int argc, char *argv[])
{
...
//create and start a thread
std::thread spin_thread(spin_wrapper);
//send request
if(client.call(srv))
{
ROS_INFO("Sum: %ld", (long int)srv.response.sum);
}
else
{
ROS_ERROR("Failed to call service add_two_ints");
return 1;
}
//ros::spinOnce();
}
Note that thread
works since C++11 so your CMakeLists.txt
file should add add_compile_options(-std=c++11)
to enable the function.
Update
Thank @”gvdhoorn“ for better solutions of multi-threaded spinners.
I update the solution using ros::AsyncSpinner
.
int main(int argc, char *argv[])
{
...
//create and start a thread
ros::AsyncSpinner spinner(1); // Use 1 thread
spinner.start();
//send request
if(client.call(srv))
{
ROS_INFO("Sum: %ld", (long int)srv.response.sum);
}
else
{
ROS_ERROR("Failed to call service add_two_ints");
return 1;
}
//ros::spinOnce();
}
4 | No.4 Revision |
Based on your code, the request to service
is processed at ros::spinOnce()
, and client.call()
is waiting the response from service
. Then a deadlock happens and your program gets stuck at client.call()
as you found.
Using two different nodes, or two processes, is the best way to implement this example because the purpose of ServiceServer
is to provide service to any clients. If you still require to implement this example in a node, I would suggest you create a thread to handle either ros::spinOnce()
or client.call
.
#include<thread>
void spin_wrapper()
{
ros::spin();
}
...
int main(int argc, char *argv[])
{
...
//create and start a thread
std::thread spin_thread(spin_wrapper);
//send request
if(client.call(srv))
{
ROS_INFO("Sum: %ld", (long int)srv.response.sum);
}
else
{
ROS_ERROR("Failed to call service add_two_ints");
return 1;
}
//ros::spinOnce();
}
Note that thread
works since C++11 so your CMakeLists.txt
file should add add_compile_options(-std=c++11)
to enable the function.
Update
Thank @”gvdhoorn“ @gvdhoorn for better solutions of multi-threaded spinners.
I update the solution using ros::AsyncSpinner
.
int main(int argc, char *argv[])
{
...
//create and start a thread
ros::AsyncSpinner spinner(1); // Use 1 thread
spinner.start();
//send request
if(client.call(srv))
{
ROS_INFO("Sum: %ld", (long int)srv.response.sum);
}
else
{
ROS_ERROR("Failed to call service add_two_ints");
return 1;
}
//ros::spinOnce();
}
5 | No.5 Revision |
Based on your code, the request to service
is processed at ros::spinOnce()
, and client.call()
is waiting the response from service
. Then a deadlock happens and your program gets stuck at client.call()
as you found.
Using two different nodes, or two processes, is the best way to implement this example because the purpose of ServiceServer
is to provide service to any clients. If you still require to implement this example in a node, I would suggest you create a thread to handle either ros::spinOnce()
or client.call
.
#include<thread>
void spin_wrapper()
{
ros::spin();
}
...
int main(int argc, char *argv[])
{
...
//create and start a thread
std::thread spin_thread(spin_wrapper);
//send request
if(client.call(srv))
{
ROS_INFO("Sum: %ld", (long int)srv.response.sum);
}
else
{
ROS_ERROR("Failed to call service add_two_ints");
return 1;
}
//ros::spinOnce();
}
Note that thread
works since C++11 so your CMakeLists.txt
file should add add_compile_options(-std=c++11)
to enable the function.
Update
Update
Thank @gvdhoorn for better solutions of multi-threaded spinners.
I update the solution using ros::AsyncSpinner
.
int main(int argc, char *argv[])
{
...
//create and start a thread
ros::AsyncSpinner spinner(1); // Use 1 thread
spinner.start();
//send request
if(client.call(srv))
{
ROS_INFO("Sum: %ld", (long int)srv.response.sum);
}
else
{
ROS_ERROR("Failed to call service add_two_ints");
return 1;
}
//ros::spinOnce();
}
6 | No.6 Revision |
Based on your code, the request to service
is processed at ros::spinOnce()
, and client.call()
is waiting the response from service
. Then a deadlock happens and your program gets stuck at client.call()
as you found.
Using two different nodes, or two processes, is the best way to implement this example because the purpose of ServiceServer
is to provide service to any clients. If you still require to implement this example in a node, I would suggest you create a thread to handle either ros::spinOnce()
or client.call
.
#include<thread>
void spin_wrapper()
{
ros::spin();
}
...
int main(int argc, char *argv[])
{
...
//create and start a thread
std::thread spin_thread(spin_wrapper);
//send request
if(client.call(srv))
{
ROS_INFO("Sum: %ld", (long int)srv.response.sum);
}
else
{
ROS_ERROR("Failed to call service add_two_ints");
return 1;
}
//ros::spinOnce();
}
Note that thread
works since C++11 so your CMakeLists.txt
file should add add_compile_options(-std=c++11)
to enable the function.
Update
Thank @gvdhoorn for better solutions of multi-threaded spinners.
I update the solution using ros::AsyncSpinner
.
.
int main(int argc, char *argv[])
{
{
...
//create and start a thread
ros::AsyncSpinner spinner(1); // Use 1 thread
spinner.start();
//send request
if(client.call(srv))
{
{
ROS_INFO("Sum: %ld", (long int)srv.response.sum);
}
else
{
ROS_ERROR("Failed to call service add_two_ints");
return 1;
}
//ros::spinOnce();
}