(!) Please ask about problems and questions regarding this tutorial on answers.ros.org. Don't forget to include in your question the link to this page, the versions of your OS & ROS, and also add appropriate tags.

Writing a dynamic_reconfigure client with roslibjs

Description: This tutorial shows you how to interface with nodes using dynamic_reconfigure parameters using service calls from roslibjs.

Keywords: roslibjs, web interface, teleoperation, Robot Web Tools, dynamic_reconfigure

Tutorial Level: BEGINNER

Getting Started

This tutorial involves writing a single HTML file, which will contain the HTML and JavaScript needed to communicate with ROS over rosbridge. To begin, create a file dynarec.html with your favorite text editor.

You will also need a node that implements a dynamic_reconfigure server. For that we will use the pid package.

The HTML Code

   1 <!DOCTYPE html>
   2 <html>
   3 <head>
   4 <meta charset="utf-8" />
   5 
   6 <script type="text/javascript" src="http://static.robotwebtools.org/EventEmitter2/current/eventemitter2.min.js"></script>
   7 <script type="text/javascript" src="http://static.robotwebtools.org/roslibjs/current/roslib.min.js"></script>
   8 
   9 <script type="text/javascript">
  10     // Connecting to ROS
  11     // -----------------
  12 
  13     var ros = new ROSLIB.Ros({
  14         url : 'ws://localhost:9090'
  15     });
  16 
  17     ros.on('connection', function() {
  18         console.log('Connected to websocket server.');
  19     });
  20 
  21     ros.on('error', function(error) {
  22         console.log('Error connecting to websocket server: ', error);
  23     });
  24 
  25     ros.on('close', function() {
  26         console.log('Connection to websocket server closed.');
  27     });
  28 
  29     // Setting dynamic_reconfigurable parameters using ROS services
  30     // -----------------
  31 
  32     var dynaRecClient = new ROSLIB.Service({
  33         ros : ros,
  34         name : '/left_wheel_pid/set_parameters',
  35         serviceType : 'dynamic_reconfigure/Reconfigure'
  36     });
  37 
  38     var request = new ROSLIB.ServiceRequest({
  39         config: {
  40             bools: [
  41                 // {name: '', value: false}
  42             ],
  43             ints: [
  44                 // {name: '', value: 0}
  45             ],
  46             strs: [
  47                 // {name: '', value: ''}
  48             ],
  49             doubles: [
  50                 {name: 'Kp_scale', value: 10.0},
  51                 {name: 'Kp', value: 0.1},
  52                 {name: 'Ki_scale', value: 0.1},
  53                 {name: 'Ki', value: 0.2},
  54                 {name: 'Kd_scale', value: 1.0},
  55                 {name: 'Kd', value: 0.3},
  56             ],
  57             groups: [
  58                 // {name: '', state: false, id: 0, parent: 0}
  59             ]
  60         }
  61     });
  62 
  63     dynaRecClient.callService(request, function(result) {
  64         console.log('Result for service call on '
  65             + dynaRecClient.name
  66             + ': '
  67             + JSON.stringify(result, null, 2));
  68     });
  69 </script>
  70 </head>
  71 
  72 <body>
  73   <h1>Simple dynamic_reconfigure example using roslibjs</h1>
  74   <p>Check your Web Console for output.</p>
  75 </body>
  76 </html>

Code Explanation

Now that we have an example, let's look at each piece.

   6 <script type="text/javascript" src="http://static.robotwebtools.org/EventEmitter2/current/eventemitter2.min.js"></script>
   7 <script type="text/javascript" src="http://static.robotwebtools.org/roslibjs/current/roslib.min.js"></script>

We first need to import all of the required JavaScript files for the application, including EventEmitter2 and roslibjs. Here, we use the Robot Web Tools CDN. The files can also be downloaded directly from their GitHub repos.

  13     var ros = new ROSLIB.Ros({
  14         url : 'ws://localhost:9090'
  15     });

Next, we need to create a Ros node object to communicate with a rosbridge v2.0 server. In this example, the script will connect to localhost on the default port of 9090.

The ROSLIB.Ros docs details ROSLIB.Ros constructor options and available functions.

  17     ros.on('connection', function() {
  18         console.log('Connected to websocket server.');
  19     });

This adds a listener for a connection event to the ros object. The following two blocks do the same for error and close events. This way, we can monitor the connection to the rosbridge server.

  32     var dynaRecClient = new ROSLIB.Service({
  33         ros : ros,
  34         name : '/left_wheel_pid/set_parameters',
  35         serviceType : 'dynamic_reconfigure/Reconfigure'
  36     });

In order to set dynamic_reconfigure parameters, we must use a ROS service call. First, we need to create a ROSLIB.Service object. The ros field gets set to the name of the ROSLIB.Ros object (which in this case is simply called ros). The name field should be set to the name of the node running the dynamic_reconfigure server followed by /set_parameters. The serviceType field is always set to dynamic_reconfigure/Reconfigure. Check out the service definition here.

Also, check out the ROSLIB.Service docs for all ROSLIB.Service options.

  38     var request = new ROSLIB.ServiceRequest({
  39         config: {
  40             bools: [
  41                 // {name: '', value: false}
  42             ],
  43             ints: [
  44                 // {name: '', value: 0}
  45             ],
  46             strs: [
  47                 // {name: '', value: ''}
  48             ],
  49             doubles: [
  50                 {name: 'Kp_scale', value: 10.0},
  51                 {name: 'Kp', value: 0.1},
  52                 {name: 'Ki_scale', value: 0.1},
  53                 {name: 'Ki', value: 0.2},
  54                 {name: 'Kd_scale', value: 1.0},
  55                 {name: 'Kd', value: 0.3},
  56             ],
  57             groups: [
  58                 // {name: '', state: false, id: 0, parent: 0}
  59             ]
  60         }
  61     });

Here, we form the service request to update the dynamic_reconfigure parameters with our values. For the pid node, there are six parameters, and they are all of the double type. Nevertheless, there are examples of the bool, int, string, and group parameters which are left commented out. Depending on the specific dynamic_reconfigure node, these fields will differ.

  63     dynaRecClient.callService(request, function(result) {
  64         console.log('Result for service call on '
  65             + dynaRecClient.name
  66             + ': '
  67             + JSON.stringify(result, null, 2));
  68     });

The dynamic_reconfigure parameters are updated using the service call dynaRecClient.callService and is passed two parameters: the ROSLIB.ServiceRequest and a callback function. The callback function will be called when the ROS service responds. In this example, the topic name is printed along with the current contents of the dynamically-reconfigurable parameters.

The ROSLIB.ServiceRequest docs and ROSLIB.ServiceResponse docs outline the available parameters for ROSLIB.ServiceRequest and ROSLIB.ServiceResponse objects.

Running the Example

At this point we are ready to run the example. To do so, you will need to have installed the following packages:

  • ros-kinetic-ros-base (basic ROS installation)
  • ros-kinetic-rosbridge-server (rosbridge_server)

  • ros-kinetic-pid (pid)

To begin, we will run servo_sim.launch from the pid package. To do so, run the following in a terminal:

  • roslaunch pid servo_sim.launch

Next, we can launch the rosbridge v2.0 server with the following:

  • roslaunch rosbridge_server rosbridge_websocket.launch

Finally, you are now ready to bring up your HTML page in a web browser. You can open up the file directly in the browser without running a web server. The data outputted happens in the Web Console. Instructions to view the Web Console depends on the browser:

Wiki: roslibjs/Tutorials/Writing a dynamic_reconfigure client with roslibjs (last edited 2018-05-14 20:46:11 by RicardoAngeli)