1

I'm trying to create an input field on the tablet of Pepper robot which allows user to input their email address by voice. I use a speech recognition box to get the letter that user says and raise an event so that Javascript can catch it and modify the text. But it seems that "document.getElementById("abc").value" never get what is currently on the screen but the defaut value.

Example: I say "1", it shows "hello1" (Totally good). Then I say "2", it shows "hello2" (Expecting "hello12")

Here is my JS code:

var session = new QiSession(function(session) {
            // "Connection esterblished!";
          }, function() {
            // "Could not connect to the robot";
          });

// Subscribe to ALMemory Service   
session.service("ALMemory").then(function(ALMemory) {
  // "ALMemory proxy subscription successful!";  
  ALMemory.getData('voice_input').then(function(voice_input){  
        document.getElementById("abc").value += voice_input;        
  });

});

HTML code:

<input type="text" name="email" id="abc" value="hello">

Is there anything to do with the "session"? Because even if I use a global variable to store the voice inputs, I can only modify the value of this variable but cannot get the current value of this variable inside the fonction(what I can get is the initialized value).

2 Answers2

0

Unfortunately, I was unable to find proper public documentation on the JavaScript API. However, this is what I could find.

It appears you are using promises as event listeners. Promises fire once, while event listeners fire repeatedly. You are using what they refer to as calls (promises) instead of signals (events). If you have documentation on signals, I would use them instead, because they more closely resemble what you are trying to do. Otherwise, you could do something like this:

var session = new QiSession(function(session) {
    // "Connection esterblished!";
    // Subscribe to ALMemory Service
    session.service("ALMemory").then(function(ALMemory) {
        // "ALMemory proxy subscription successful!";
        function getVoice() {
            ALMemory.getData('voice_input').then(function(voice_input){
                document.getElementById("abc").value += voice_input;
                getVoice();
            });
        }
        getVoice();
    });
}, function() {
    // "Could not connect to the robot";
});

First, I moved the service subscriber into the callback for QiSession's successful connection, because that is usually where session would be defined in an async function call. When ALMemory has been subscribed to, it defines and calls getVoice, which retrieves the user's speech, appends to the field, and then runs getVoice again to queue another listen. You may want to add a conditional to stop it eventually. It may also be worth looking into async/await if Pepper supports this, because then you can do this easily with a while loop.

  • Thank you, I tested your method but when I say "1", it goes "hello111111111111....". Well, do you mean there's something wrong with the listener? But my problem is that it does listen (you can take a look at my example again), but "document.getElementById("abc").value" never gets what is currently on the screen. It gets the defaut value all the time("hello" in my case) even if a letter has already been caught and displayed on the screen(ex. "hello1"). – user10819593 Nov 04 '19 at 09:50
  • Sorry, I must have misunderstood the question. I have a suspicion that the renderer used for web pages is mistakenly reading the value from the *attribute* rather than from the *actual* input text. Could you try removing the value attribute from the text box in your HTML? – sploders101 Nov 05 '19 at 18:15
  • Yes, I removed the value attribute. But unfortunately, the problem persistes. – user10819593 Nov 06 '19 at 15:20
0

There is nothing wrong with document.getElementById(). The problem is that you must react to voice input, and not only get the current voice input. This is done by subscribing to the ALMemory event. Here is the tutorial's snippet roughly adapted to your case (but not tested):

session.service("ALMemory").then(function (ALMemory) {
  ALMemory.subscriber("voice_input").then(function (subscriber) {
    subscriber.signal.connect(function (state) {
      document.getElementById("abc").value += voice_input;
    });
  });
});

Please note that to work, you must publish an event on the "voice_input" key, using ALMemory.raiseEvent.

Victor Paléologue
  • 2,025
  • 1
  • 17
  • 27