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_driverpackage and create a subdirectory namedsrvfor our custom service. Our service will enable changing the sonar’s field of view (FOV), which is published as part of theRangemessage.In the
srvdirectory, create a service file namedSetSonarFOV.srvwith the following request and response parts:# Sets . float64 fov_to_set --- float64 set_fov
Make changes in your
package.xmlandCMakeLists.txtto includemessage_generationfor 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_setfield and responds back with the same value inset_fovfield.
- the node advertises a service on topic
Test the server with
rossrv call /sonar_distance 1.4and show the result to the instructor.Improve the
fake_sonar_driver_nodesuch that thefov_to_setvalue would be updated into the/sonar_distancetopic. The easies way to do this is by definingfield_of_viewas 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
addbutton on the Displays panel (the one on the left side). - Select the
By topictab and double-click on the/sonar_distancetopic.
- Open a new terminal and type:
Open another terminal and change the field of view with the
rossrv callcommand. 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.cppandinclude/fake_sonar_driver/fake_sonar_driver.hfiles. - Replace the existing while loop with a timer that would update the sine() value in the class.
- The
main()function should now simply create theFakeSonarDriverobject and spin forever usingros::spin().