SoftBank Robotics documentation What's new in NAOqi 2.5?

QiMessaging JavaScript 1.0

Warning

Version 1.0 of the library is now deprecated. Please see How to migrate from version 1.0 to 2.

Introduction

QiMessaging provides JavaScript bindings to use QiMessaging services (modules) in a web browser. It allows you to build HTML5 applications for your robot.

The library was designed to be asynchronous. Most function calls return a Deferred object, as specified by jQuery, but reimplemented to avoid shipping the whole library. Socket.IO is used to provide bidirectional communication between the robot and the browser. You may want to get more familiar with these libraries before going further.

Getting started

The client page requires the inclusion of QiMessaging which is hosted on the robot.

<script src="/libs/qimessaging/1.0/qimessaging.js"></script>

QiSession

The bindings provide only one class: QiSession. This object connects to the robot and gets proxies to services.

If the page is hosted on the robot, the constructor does not need any argument. If the page is not served by the robot, you may pass the hostname or IP of the robot you want to connect to (e.g. "192.168.0.5", "nao.local", etc.).

var session = new QiSession();

Once the connection is established, two methods are available: socket() and service().

socket()

This function will return the underlying Socket.Io object. It is used to deal with low-level socket events.

session.socket().on('connect', function () {
  console.log('QiSession connected!');
  // now you can start using your QiSession
}).on('disconnect', function () {
  console.log('QiSession disconnected!');
});

service()

You can call this function to get a JavaScript proxy to any service, also known as modules. Services are JavaScript bound objects providing corresponding NAOqi APIs through Calls and Signals.

In case of success, this method calls the done() callback with an object corresponding to the requested service. Otherwise, the fail() callback is triggered.

session.service("ALTextToSpeech").done(function (tts) {
  // tts is a proxy to the ALTextToSpeech service
}).fail(function (error) {
  console.log("An error occurred:", error);
});

Using services

Services are JavaScript object exposing methods and signals.

Calls

Service calls are only JavaScript function calls returning Deferred promises. They are entirely asynchronous. As previously explained, done() and fail() callbacks will be triggered upon successful completion or not.

tts.getLanguage().done(function (lang) {
  console.log("I speak " + lang);
}).fail(function (error) {
  console.log("An error occurred: " + error);
});

Signals

Signals are JavaScript objects inside a service, that provide two methods, connect() and disconnect(), respectively to subscribe and unsubscribe. The first one will return an id that must be used by the second one for unregistration.

The example below connects to a signal, and once fired, disconnects.

var signalLink;
var serviceDirectory;

function onServiceAdded(serviceId, serviceName)
{
  console.log("New service", serviceId, serviceName);
  serviceDirectory.serviceAdded.disconnect(signalLink);
}

session.service("ServiceDirectory").done(function (sd) {
  serviceDirectory = sd;
  serviceDirectory.serviceAdded.connect(onServiceAdded).done(function (link) {
    signalLink = link;
  }).fail(function (error) {
    console.log("An error occurred: " + error);
  });
});

Compatibility between Signals and ALMemory

ALMemory events cannot be directly used as QiMessaging signals. An extra step is needed, where ALMemory events are converted to signals using ALMemory::subscriber.

session.service("ALMemory").done(function (ALMemory) {
  ALMemory.subscriber("FrontTactilTouched").done(function (subscriber) {
    // subscriber.signal is a signal associated to "FrontTactilTouched"
    subscriber.signal.connect(function (state) {
      console.log(state == 1 ? "You just touched my head!" : "Bye bye!");
    });
  });
});

How to migrate from version 1.0 to 2

JavaScript SDK is now available. The former 1.0 version is now deprecated and no longer maintained. You are strongly encouraged to port your code to the new library. This quick guide will help you transition.

Library inclusion

You must first change the qimessaging.js inclusion.

<!-- QiMessaging 1.0 -->
<script src="/libs/qimessaging/1.0/qimessaging.js"></script>
<!-- QiMessaging 2 -->
<script src="/libs/qimessaging/2/qimessaging.js"></script>

QiSession creation

Considering a QiSession connected to host with the connected and disconnected callbacks registered,

var host = "192.168.0.1";

function connected() {
  console.log("connected");
}

function disconnected() {
  console.log("disconnected");
}

here is the session creation in 1.0 and how it translates into version 2:

// QiMessaging 1.0
var session = new QiSession(host);
session.socket().on("connect", connected);
session.socket().on("disconnect", disconnected);
// QiMessaging 2
QiSession(function(session) {
   connected();
}, disconnected, host);

The first callback will be fired once the QiSession is connected, and the second one upon its disconnection.

Please note the created QiSession is not returned anymore, but given to the first callback instead. This prevents using the session before it is actually connected.

As in 1.0, the host parameter still defaults to window.location.host if not given. It cannot accept any protocol, ie. 192.168.0.1 and not http://192.168.0.1.

Removal of socket()

The socket() method of QiSession was removed, so as to ease backward compatibility maintenance.

Deferred and Promise

In version 2, jQuery-like Deferred were removed in favor of native ECMAScript 6 Promise/A+, which are now widely available.

If you are currently developing for an older browser, you can use a polyfill such as:

<script src="https://www.promisejs.org/polyfills/promise-6.0.0.min.js"></script>

As jQuery’s Deferred do not implement Promises/A+, you will also have to adapt your API calls as follows:

// QiMessaging 1.0
proxy.method().done(success).fail(error);
// QiMessaging 2
proxy.method().then(success, error);

Binary buffer serialization

Binary data used to be serialized as base64 strings. Buffers are now received as Array of unsigned bytes, which also means atob() shouldn’t be called anymore.