ami-iit/yarp-openmct

No data is displayed in the visualiser client plots for any of the telemetry entries

nunoguedelha opened this issue · 3 comments

When testing a previously working commit 45035b8 on main branch, the plots usually displaying the samples received on the visualiser are not displaying anything, although the plot view is flowing forward (Local Clock selected instead of Fixed Timespan).

How to Reproduce

  1. Add the iCubGazeboV3 to the Gazebo world,
  2. Run the wholebodydynamics module as usual,
  3. Run the Open-MCT Telemetry server and client as usual,
  4. On the client browser, navigate to http:<your-machine-IP-address>:8080,
  5. Click on any telemetry entry on the left pane, (e.g. Legacy IMU sensor measurements),
  6. Change time Conductor clock setting from Fixed Timespan to Local Clock,
  7. Check the plot output. Should display no data points.

Error Log

We also get a warning on the process console:

{ status: 'OK', message: 'Opem-MCT static server process started.' }
ICubTelemetry History Server listening on http://192.168.1.70:8081/history
ICubTelemetry Realtime Server listening on ws://192.168.1.70:8081/realtime
Control Console Server listening on http://192.168.1.70:3000
(node:39941) UnhandledPromiseRejectionWarning: Error: spawn yarp ENOENT
    at Process.ChildProcess._handle.onexit (internal/child_process.js:269:19)
    at onErrorNT (internal/child_process.js:467:16)
    at processTicksAndRejections (internal/process/task_queues.js:82:21)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:39941) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:39941) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
[OPEN-MCT STATIC SERVER] stderr: Debugger listening on ws://127.0.0.1:55525/e9429927-70a4-4cc3-905e-924d440169f3
For help, see: https://nodejs.org/en/docs/inspector

...related to a spawned YARP command, probably the yarp name list.

  • All the relevant ports required for receiving the telemetry data appear disconnected.
  • Even after connecting one of the ports...
    yarp connect /icubSim/inertial /yarpjs/inertial:i
    
    the problem persists.
  • After the connection mentioned above is restored, we can break inside the respective registered "onRead" callback and verify that the callbacks icubtelemetry.processOrDropYarpData[i] are still inactive, i.e. set to the dummy value (id,data) => {}.
  • This means that ICubTelemetry.prototype.connectTelemSrcToNotifier(id) was never called for any of the ports.
  • We realise that the calling function connectPortsAndStartNotifier isn't called either.
  • Actually never reach the Promise "resolve" callback in
    configHandler.matchRegexpYarpPortNames().then(connectPortsAndStartNotifier);
  • So, the processing in ConfigHandler.prototype.matchRegexpYarpPortNames or some processing scheduled there never ends.
  • The spawned yarp name list
    let procHdl = this.spawn('yarp', ['name', 'list', prefix.toString()]);

    fails in

    Causing the error message Error: spawn yarp ENOENT and the warning UnhandledPromiseRejectionWarning mentioned in the issue description. Actually we had missed the handling of this error, which would directly reveal the source of the error to be at this point.

On handling errors in async functions

  • We can use .catch in order to handle .reject or thrown errors1.
  • Every time a an error is handled in a .catch, an eventual subsequent .then() is treated normally as if there was no error.
  • We should place a .catch exactly where we wish to handle the error, and rethrow errors we cannot handle.
  • A .catch can be placed at the end of a sequence of cascaded .then to catch any error which occurred in between, which was the approach used in
    configHandler.matchRegexpYarpPortNames().then(connectPortsAndStartNotifier).catch((errorMessage) => {
    console.error(errorMessage);
    });
  • For browsers we should use unhandledrejection event handler or alert in order to inform the user.

References

https://javascript.info/promise-error-handling

Footnotes

  1. If an error is not handled, a UnhandledPromiseRejectionWarning warning is thrown.

Error Analysis

spawn yarp ENOENT ocurs when the executable or command in question (here yarp) is not found in the working folder. yarp should be found from anywhere, unless the environment of the child process was corrupted. That environment is by default inherited from the parent, but we can always do:

spawn('<command_executable>', ['command_param_1', 'command_param_2'],{
    env: {
        PATH: process.env.PATH
    }
});

Not Reproducible

The issue was occuring on Webstorm. Running once from the terminal with npm start worked without issues, after which the issue was no more reproducible from Webstorm.