Service Server & Service Client¶
The first type of ROS communication that we explored was a one-way interaction called messages which are sent over channels called topics. Now we are going to explore a different communication type, which is a two-way interaction via a request from one node to another and a response from that node to the first.
- After completing this exercise, you will have the answers to the following questions:
- How to create a custom messages/services?
- How to use
message_generation
? - How to implement a simple service server?
First, read through the ROS tutorials section on Creating a ROS msg and srv.
Next, navigate to the root of your
fake_sonar_driver
package and create a subdirectory namedsrv
for our custom service. Our service will enable changing the sonar’s field of view (FOV), which is published as part of theRange
message.In the
srv
directory, create a service file namedSetSonarFOV.srv
with the following request and response parts:# Sets . float64 fov_to_set --- float64 set_fov
Make changes in your
package.xml
andCMakeLists.txt
to includemessage_generation
for this service.Test it out:
rossrv show fake_sonar_driver SetSonarFOV
Good Job! It’s now time to learn the steps needed to create a service server (waits for request and comes up with response) and client (makes request for info then waits for response).
Complete the Writing a Simple Service and Client (C++) tutorial.
Now that you know how service server and client are implemented in nodes, let’s add a service server to
fake_sonar_driver_node
.Add the following functionality to our fake sonar node:
- the node advertises a service on topic
/set_sonar_fov
- the service type is
fake_sonar_driver/SetSonarFOV
- the server will check
fov_to_set
field and responds back with the same value inset_fov
field.
- the node advertises a service on topic
Test the server with
rossrv call /sonar_distance 1.4
and show the result to the instructor.Improve the
fake_sonar_driver_node
such that thefov_to_set
value would be updated into the/sonar_distance
topic. The easies way to do this is by definingfield_of_view
as a global variable:#include <...> double field_of_view; bool callback_function_for_server(...) { // set field_of_view here } int main(...) { // use field_of_view here } ...
Would it be awesome to visualize the sonar range and its field of view graphically? In ROS, this is peace of cake:
- Open a new terminal and type:
rviz
- In RViz, click the
add
button on the Displays panel (the one on the left side). - Select the
By topic
tab and double-click on the/sonar_distance
topic.
- Open a new terminal and type:
Open another terminal and change the field of view with the
rossrv call
command. See if you notice any changes in RViz.Present your solution to the instructor. Congratulations, you are now ready to face the challenges in day 3!
Bonus task¶
Currently our fake sonar node has publishers and subscribers laying next to main(). However, to make our code modular, we should restructure it and place the publisher, service server, and callback functions into a separate FakeSonarDriver
class.
- Create the
src/fake_sonar_driver.cpp
andinclude/fake_sonar_driver/fake_sonar_driver.h
files. - Replace the existing while loop with a timer that would update the sine() value in the class.
- The
main()
function should now simply create theFakeSonarDriver
object and spin forever usingros::spin()
.