ami-iit / yarp-openmct

Repo for YARP and OpenMCT integration.
BSD 3-Clause "New" or "Revised" License
6 stars 1 forks source link

Integrate in the Open MCT visualizer the network ping performance #13

Closed nunoguedelha closed 3 years ago

nunoguedelha commented 3 years ago

@nunoguedelha commented on Tue Jul 06 2021


@nunoguedelha commented on Thu Aug 12 2021

Ciao @S-Dafarra , how do you usually evaluate the ping performance of the network when running the walking demo for the XPrize, just doing a ping on the yarp server host and averaging the scores or do you use some script?


@S-Dafarra commented on Thu Aug 12 2021

Ciao @S-Dafarra , how do you usually evaluate the ping performance of the network when running the walking demo for the XPrize, just doing a ping on the yarp server host and averaging the scores or do you use some script?

In the dumbest possible way. We simply run ping 10.0.0.2. We are interested in visually keeping track of the connection status of the icub-head when this is connected via Wi-Fi. Because of external events, the communication may start lagging for example. With the ping we simply keep track of it. We use no scripts


@nunoguedelha commented on Thu Aug 12 2021

An averaged set of 10 pings every second could be way to monitor the performance in a graph, looks fine to you? It can also be parameterizable (1: lenght of the set/batch of pings for computing the average; 2: priod between batches), and with a default value.


@S-Dafarra commented on Fri Aug 13 2021

As you find more appropriate

nunoguedelha commented 3 years ago

Some information on the "ping" command relative to the impact on bandwidth

The smallest ping packet possible (including the Ethernet frame header and the IP + ICMP headers, plus the minimum 32 bytes of the ICMP payload) takes 74 bytes:

image Picture from http://openmaniak.com/ping.php

and the typical size is of 56 bytes, so one ICMP packet per second has a negligible impact on the network.

"ping" utility parameters

We shall use the "ping" unix utility which allows to chose the time interval:

man ping
     ...
     -i wait
             Wait wait seconds between sending each packet.  The default is to wait
             for one second between each packet.  The wait time may be fractional,
             but only the super-user may specify values less than 0.1 second.  This
             option is incompatible with the -f option.
     ...

We shall explicitly set it to 1s, although it is the default, for a better portability.

Since the ping packets exchange have a specific frequency, much lower than the YARP port messages, we cannot use the same synchronous scheduler (`setInterval()) used on the YARP ports data.

Note

The setInterval() function for scheduling a caller is not a part of JavaScript specification. But most environments have the internal scheduler and provide these methods. In particular, they are supported in all browsers and Node.js (https://javascript.info/settimeout-setinterval).

nunoguedelha commented 3 years ago

Generating the "ping" command

Node.js executes its main event loop in a single thread. Asynchronous tasks can be executed in other internal threads or child processes. The child_process module creates new child processes of our main Node.js process. We can execute shell commands through those child processes 1.

The exec Function

The exec() function creates a new shell and executes a given command. The output from the execution is buffered, which means kept in memory, and is available for use in a callback.

The spawn Function

The spawn() function executes a command in a new child process, and streams the returned data without storing it in a buffer, but using instead a Stream API. For commands returning data continuously like the command "ping", this is a simpler and saffer choice.

var ping = spawn('ping',['-i 1','192.168.1.18']); // "ping the Yarp server host" with 1s delay between ICMPs

This function uses a Stream API, so its output of the command is made available via listeners.

ping.stdout.on('data', function (data) {...});
ping.stderr.on('data', function (data) {...});
ping.on('error', function (error) {...});
ping.on('close', function (code) {...});

The stdout object fires a data event when the command writes to that stream. Similarly, the stderr also fires a data event when the command writes to that stream.

Errors are caught by listening for them directly on the object that stores the reference for the command. You will only get an error if child_process fails to run the command.

The close event occurs when the command has finished.

Implemented in commit 09c3ab3397c85779329ee9028b57d36efeefce59 1. https://stackabuse.com/executing-shell-commands-with-node-js/, https://nodejs.org/api/child_process.html

nunoguedelha commented 3 years ago

Create an RPC interface for triggering the ping command

The final intent is to enable the ON/OFF toggling of the ping through a button on the web client control console. For security reasons, system commands cannot be run directly from a browser client page. Thus we create in the telemetry server an RPC interface for triggering those system commands, using the available YarpJS bindings.

nunoguedelha commented 3 years ago

Side note

In the Software Engineering DIC Vertical meeting, @traversaro suggested the solutions proposed in the following links for running a ping from Node.js:

  1. https://stackoverflow.com/questions/4737130/how-to-ping-from-a-node-js-app
  2. https://github.com/nospaceships/node-net-ping

I was actually using the child_process Node.js packet as expplained in this comment, but rather the spawn method rather thanexec.

The node-net-ping packet seems to be quite nice too, but doesn't seem simpler than using spawn, at least so far. On top of that, apparently it doesn't generate periodic pings. Generating a sequence of pings would require using a periodic thread to trigger them.

nunoguedelha commented 3 years ago

I actually implemented the ping in a class such that in the future we can easily switch to using node-to-ping instead of spawn('ping') if necessary. It is something we could try, typically if we have portability issues with the command ping.

nunoguedelha commented 3 years ago

On the RPC interface for triggering the ping command

Notes

Implemented in commit https://github.com/ami-iit/yarp-openmct/pull/24/commits/2427e71f45b39b64301e62e92ee4fc00e7d45547.

nunoguedelha commented 3 years ago

Generate asynchronously the Telemetry samples from the returned data

Realtime and history samples are ready to be sent to the OpenMCT visualizer at request.

Implemented in commit https://github.com/ami-iit/yarp-openmct/pull/24/commits/852ad0b772edf805dd174172afe3314d7bd21c0c.

nunoguedelha commented 3 years ago

Plot the ping measurement on the OpenMCT Visualizer and add the ping ON/OFF button on the console

The steps are listed below:

Further details are added directly to the commits.

Implemented in https://github.com/ami-iit/yarp-openmct/pull/26.

nunoguedelha commented 3 years ago

Implementation completed

nunoguedelha commented 3 years ago

Moved to "done", just for the board overview during the meeting of tomorrow.