Giter Club home page Giter Club logo

node-tjbotlib's Introduction

TJBot Library

Node.js library that encapsulates TJBot's capabilities: seeing, listening, speaking, shining, and waving.

This library can be used to create your own recipes for TJBot.

Some of TJBot's capabilities require IBM Cloud services. For example, seeing is powered by the IBM Watson Visual Recognition service. Speaking and listening are powered by the IBM Watson Text to Speech and IBM Watson Speech to Text services.

To use these services, you will need to sign up for a free IBM Cloud account, create instances of the services you need, and download the authentication credentials.

Usage

  1. Install the library using npm.
$ npm install --save tjbot

πŸ’‘ Note: The TJBot library was developed for use on Raspberry Pi. It may be possible to develop and test portions of this library on other Linux-based systems (e.g. Ubuntu), but this usage is not officially supported.

  1. Import the TJBot library.

TJBot is packaged as both an ES6 and a CommonJS module (explained in this guide), which means you may import it using either the ES6 import statement or the CommonJS require method.

For ES6, import TJBot as follows:

import TJBot from 'tjbot';

For CommonJS, import TJBot as follows:

const TJBot = require('tjbot').default;

πŸ’‘ Note: For CommonJS, the TJBot class is exported under a .default reference.

  1. Instantiate the TJBot object.
const tj = new TJBot();
tj.initialize([TJBot.HARDWARE.LED_NEOPIXEL, TJBot.HARDWARE.SERVO, TJBot.HARDWARE.MICROPHONE, TJBot.HARDWARE.SPEAKER]);

This code will configure your TJBot with an LED (Neopixel), servo, microphone, and speaker. The default configuration of TJBot uses English as the main language with a male voice. Here is an example of a TJBot that speaks with a female voice in Japanese:

const tj = new TJBot({ 
    robot: { 
        gender: TJBot.GENDERS.FEMALE 
    }, 
    speak: { 
        language: TJBot.LANGUAGES.SPEAK.JAPANESE 
    }
});

IBM Watson Credentials

If you are using IBM Watson services, store your authentication credentials in a file named ibm-credentials.env. Credentials may be downloaded from the page for your service instance, in the section named "Credentials."

If you are using multiple IBM Watson services, you may combine all of the credentials together in a single file.

The file ibm-credentials.sample.env shows a sample of how credentials are stored.

πŸ’‘ Note: You may also specify the path to the credentials file in the TJBot constructor using the credentialsFile argument. For example, const tj = new TJBot(credentialsFile="/home/pi/my-credentials.env").

Hardware Configuration

The entire list of hardware devices supported by TJBot is defined in TJBot.HARDWARE and includes CAMERA, LED_NEOPIXEL, LED_COMMON_ANODE, MICROPHONE, SERVO, and SPEAKER. Each of these hardware devices may be configured by passing in configuration options to the TJBot constructor as follows.

var configuration = {
    log: {
        level: 'info', // valid levels are 'error', 'warn', 'info', 'verbose', 'debug', 'silly'
    },
    robot: {
        gender: TJBot.GENDERS.MALE, // see TJBot.GENDERS
    },
    converse: {
        assistantId: undefined, // placeholder for Watson Assistant's assistantId
    },
    listen: {
        microphoneDeviceId: 'plughw:1,0', // plugged-in USB card 1, device 0; see 'arecord -l' for a list of recording devices
        inactivityTimeout: -1, // -1 to never timeout or break the connection. Set this to a value in seconds e.g 120 to end connection after 120 seconds of silence
        backgroundAudioSuppression: 0.4, // should be in the range [0.0, 1.0] indicating how much audio suppression to perform
        language: TJBot.LANGUAGES.LISTEN.ENGLISH_US, // see TJBot.LANGUAGES.LISTEN
    },
    wave: {
        servoPin: 7, // default pin is GPIO 7 (physical pin 26)
    },
    speak: {
        language: TJBot.LANGUAGES.SPEAK.ENGLISH_US, // see TJBot.LANGUAGES.SPEAK
        voice: undefined, // use a specific voice; if undefined, a voice is chosen based on robot.gender and speak.language
        speakerDeviceId: 'plughw:0,0', // plugged-in USB card 1, device 0; 'see aplay -l' for a list of playback devices
    },
    see: {
        confidenceThreshold: 0.6,
        camera: {
            height: 720,
            width: 960,
            verticalFlip: false, // flips the image vertically, may need to set to 'true' if the camera is installed upside-down
            horizontalFlip: false, // flips the image horizontally, should not need to be overridden
        },
        language: TJBot.LANGUAGES.SEE.ENGLISH_US,
    },
    shine: {
        // see https://pinout.xyz for a pin diagram
        neopixel: {
            gpioPin: 18, // default pin is GPIO 18 (physical pin 12)
            grbFormat: false // if false, the RGB color format will be used for the LED; if true, the GRB format will be used
        },
        commonAnode: {
            redPin: 19, // default red pin is GPIO 19 (physical pin 35)
            greenPin: 13, // default green pin is GPIO 13 (physical pin 33)
            bluePin: 12 // default blue pin is GPIO 12 (physical pin 32)
        }
    }
};
const tj = new TJBot(configuration);

Capabilities

TJBot has a number of capabilities that you can use to bring it to life. Capabilities are combinations of hardware and Watson services that enable TJBot's functionality. For example, "listening" is a combination of having a speaker and the speech_to_text service. Internally, the _assertCapability() method checks to make sure your TJBot is configured with the right hardware and services before it performs an action that depends on having a capability. Thus, the method used to make TJBot listen, tj.listen(), first checks that your TJBot has been configured with a speaker and the speech_to_text service.

TJBot's capabilities are:

The full list of capabilities can be accessed programatically via TJBot.CAPABILITIES, the full list of hardware components can be accessed programatically via TJBot.HARDWARE, and the full list of Watson services can be accessed programatically via TJBot.SERVICES.

TJBot API

Please see the API docs for documentation of the TJBot API.

πŸ’‘ Please see the Migration Guide for guidance on migrating your code to the latest version of the TJBot API.

Tests

TJBotLib uses the Jest framework for basic testing of the library. These tests may be run from the tjbotlib directory using npm:

npm test

The tests run by this command only covers basic functionality of the library. A separate set of tests (see below) covers hardware-specific behaviors. These tests also do not cover functionality provided by Watson services.

A suite of hardware tests exists in the main TJBot repository in the tests directory.

Contributing

We encourage you to make enhancements to this library and contribute them back to us via a pull request.

License

This project uses the Apache License Version 2.0 software license.

node-tjbotlib's People

Contributors

caskale avatar hiqdare avatar jimbotel avatar jweisz avatar leandrodvd avatar marmotae avatar victordibia avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

node-tjbotlib's Issues

Speech Queue

Delibrate on how TJBot handles speech and queuing.
Currently any requests to speak are discarded if the bot is currently speaking. Upside is that the bot doesn't not start saying things that are no longer useful or important when a user has moved from from context.

Allow for custom URLs to pass to the SDK in tjbot library

The TJ bot library hard-codes the URL to https://stream.watsonplatform.net/speech-to-text/api/ . And in cases where clients are operating services outside of the US-region, it will be necessary to change the URL to gain access to the service. For example, Speech to text services created in this Sydney region will need to use the endpoint https://gateway-syd.watsonplatform.net/speech-to-text/api . Please enable custom URLs to pass to the SDK in this library.

Redesign "capabilities"

We might want to re-work the whole "capabilities" part of tjbotlib to automatically detect which hardware is connected, rather than having it be user specified. That said, we might not actually be able to do this in all cases (e.g. is there a way to tell if an LED or servo are connected to the GPIO pins? How do we detect a microphone? Speaker?)

Add Support for Cathode LEDs

We support Anode and Neopixel LEDs, but not Cathode LEDs. Adding Cathode support would be helpful since Neopixel LEDs are currently more difficult that Cathode LEDs.

Support keyword synomyms for robotname

Due to transcription errors (watson transcribed as whats on), support a list of synonyms that are frequently transcribed for a given keyword.
Extra credit: support local keyword detection (e.g. snowboy)

First contribution: refactoring and improvements

I forked it and changed some items. I will submit a pull request. If my changes are going in a right way I will continue maintain and improving it. I decided to change these points to take this lib more flexible to grow.

Changelog:

  • TJBot have two setup parameters: credentials and config. To use the same logic config.js and samples were refactored to have these two objects and override what is necessary.
  • Moved TJBot.prototype.defaultConfiguration to config.js making it easy to access the list of parameters and setup TJ.
  • Now config.js could have all service parameters. If you don't like to use some service, just keep user and password as blank.
  • For development purpose (minimize the raspberry dependency), the conversation service was tested in Mac using SOX in replacement of ALSA (works but speaker player are throwing an exception). So moved tests to Ubuntu using ALSA. It works fine with little adjusts. Readme updated.
  • Added config.microphone for microphone hardware setup (card/device). It is necessary in some situations.
  • Auto choose voice based on language and gender: Instead of set specific voice manually, in the initialization TJ will get tts voices available and choose one based on preferred language and gender.

Discussion on what to do with IBM cloud services in tjbotlib

Given the churn we've seen in the IBM cloud sdk and now the incorporation of foundation model support into ibm-watson-machine-learning (with a corresponding WML service required in IBM cloud), does it make sense to:

  • continue providing wrappers inside tjbotlib around the Watson APIs? or
  • remove all Watson API stuff from tjbotlib and push it into the recipes, leaving tjbotlib to only abstract the hardware interface (e.g. led, mic, speaker, camera, servo)

how do I keep subsequent tj commands from running into each other

I am having tj bot speak two sentences and then listen for a user response.
The issue I am having is that tj bot is speaking the first sentence and then only one or two words of the second sentence before it is cut off. I observed that the code is continuing and not waiting for the text to speech to play.

Drag and drop interface for TJBot

Recipes/Modules that tie in well with the tjbot lib but allow for drap and drop based programming for TJBot. Good candidates include integration with node-red for mid-level skill, and integration with ScratchX for beginner/entry level.
Some initial Node-red work already done here.

possible tj.listen() issue

This might be an generic issue with using node.js or a problem with the tj.listen(). Here's my scenario. I have a conversation feedback loop: listen(), converse(), speak(), and repeat.
This is all handled through a callback in the listen command.
However, I need to briefly pull out of this feedback loop to play a mini-game with tjbot where I orchestrate all of the commands (listen, speak, wave, and shine) and then return to this feedback loop when completed. What I am finding is that when I stop listening and start listening from another function, the original feedback loop starts processing the utterance instead of the function I had just called.

e.g.)
//main feedback loop
tj.listen(function(msg){
tj.pauseListening();
tj.converse(function(resp){
if (rest == "play game"){
playGameA();
}
tj.resumeListening();
});
});

function playGameA(){
tj.stopListening();
tj.speak("What is your favorite color?");
tj.listen(function(msg){ //this command is being picked up by the main feedback loop above
if (msg == "red"){
doSomething();
}
});
}

tjbot listen doesn't resume after hit the 100MB

When I get the error "Payload exceeds the 104857600 bytes limit" I believe it is expected that tjbot will automatically restart the mic and stt connection and keep listening. This is not happening though.

I found a possible solution. Adding self.stopListening(); to the error handler of _micTextStream inside listen method.

This way I believe the process running the microphone record will stop and all the resources becomes free for a mic restart (the code for mic restart seems to be already in place).

I'll try to send a pull request with this proposed fix.

Left handed TJ

Hi there. I've recently assembled a TJ Bot, and after running somes recipes that uses the arm, I found that no matter how I place the servo, the movements are wrong.
By swapping default servo positions I got it right. Default are:

TJBot.prototype._SERVO_ARM_BACK = 500;
TJBot.prototype._SERVO_ARM_UP = 1400;
TJBot.prototype._SERVO_ARM_DOWN = 2300;

Swapping BACK and DOWN solves the problem, since the arm is in the left side of the bot.

Event Logging :

Allow an application to provide a function that is called whenever an even occurs within the tjbot library. Events in this case can be "listen", "see", "wave", "speak", "conversation turn" etc.

An application can then chose to use this in perhaps visualizing the underlying process the bot is engaging in.
See here as an example of such visualization.

Support sound prompts and prosody

Support prompts that indicate the state of TJBot (e.g. beeps that indicate the bot is listening or stopped listening etc).

Prosody: Allow customization in the way TJBot speaks - e.g. express surprise, high pitch etc.

apikey services

update the libraries for using apikey instead of username / password
I already have this solved, as well as the integration with the node-red node, just give me permission to submit my new branch and the pull request :)

return "result" in SHINE and WAVE methods.

If you check out the shine and wave methods in the Node.js library, they do not return a result. Therefore, the nodes don't output anything.

https://github.com/ibmtjbot/tjbotlib/blob/master/lib/tjbot.js#L905
https://github.com/ibmtjbot/tjbotlib/blob/master/lib/tjbot.js#L1369

Transposing them in Node-Red (as done by Jeancarl Bisson) means that these nodes will not have an output and, so, they cannot chain in sequence. If I have to WAVE or SHINE to draw person attention before SEE something, the only way is to introduce delay nodes and manage parallel flows... a not comfortable solution.
screen shot 2018-02-21 at 8 16 35 am

Is it possibile to "fix" TJBot library introducing a return value?

Mobile App for Wifi Setup and Remote Control

App that enables users connect to and setup their TJBot.

  • Launch bluetooth and listen for incoming connects to setup TJBot

    • Connect with a mobile app via bluetooth
    • Provide wifi credentials to Pi via mobile app
    • Send Pi IP address to mobile
  • Allow controlling of bot from mobile app

    • Setting up watson credentials
    • Hardware control ... wave, change led color,
    • Capability control ... e.g play music, text to speech,

tjbot.js is looking for watson modules in the wrong location

the file node_modules/tjbot/lib/tjbot.js is trying to include Watson modules from:
import AssistantV2 from 'ibm-watson/assistant/v2.js' It appears that there is a missing directory the path (dist). I think it should be: import AssistantV2 from 'ibm-watson/dist/assistant/v2.js' This holds true for all of the watson imports (6).

Feature: TJBot Startup Script

A bootstrap script that prepares a stock rpi with the stuff it needs to β€œbecome” tjbot β€” e.g. installing / configuring alsa, blacklisting certain kernel modules, checking out tjbot code, performing hardware tests to make sure the user hooked up everything on the right pins etc.

  • Install configure alsa

  • Install configure latest nodejs, npm

  • blacklist certain kernel modules (sound/led interference problem)

  • Checkout TJBot code

  • Perform hardware tests .. servo, led, mic, speaker

  • Also check for Raspberry PI version. RPi v2 needs some additional installation steps

upgrade nodejs, npm, node-gyp and gcc.
https://github.com/audstanley/NodeJs-Raspberry-Pi
nodejs/node-gyp#809
https://community.thinger.io/t/starting-with-the-raspberry-pi/36

Integration

Is it possible to integrate and run two or more modules together at once(Tone Analyzer & TTS/STT)

How to specify a customer classifier on tj.see or tj.recognizeObjectsInPhoto

I've trained a custom classifier in my watson visual recognition service, but am not sure the best way to have my tjbot code pick up this classifier when using tj.see or tj.recognizeObjectsInPhoto. Either of those are using the "generic" classifiers and not the custom model i have training in my visual recognition service.

Any help, tips?

Update versions of pigpio and rpi-ws281x-native?

I got my tjbot as a gift last year, but didn't get around to playing with him until now. My 11 year old nephew constructed and wired him without assistance. What an awesome experience for him. I, however, had a little more difficulty due to my late start. :-)

It would appear that the version of node installed with Raspbian Buster won't properly build the pigpio or rpi-ws281x-native modules. In other recipes I tried, I was able to update package.json to reference the latest versions of these. But I can't do that in the tjbot bootstrap module. I was able to fanangle it by building them separately and copying them into the node_modules folder, but that defeats the point of bootstrapping.

Just wanted to make this recommendation on behalf of any new tjbot users that might come along. I appreciate the work you guys have put into this. It's really cool and a great learning tool for him and me.

Thanks a ton!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.