Wiki

Clone wiki

robobo-programming / native / robobo-apps

Developing Robobo Apps

The easiest way to natively programm the Robobo robot is to create a Robobo App. A Robobo App is no more than an Android App that uses the Robobo Framework and some GUI utilities that we have created in order to facilitate the configuration of the robot from the app, the selection of a rob, etc.

Again, the easiety way to create a Robobo App is to use our example project and modify it. You can clone the robobo-java-example-app repository from GitHub, or download the code.

robobo-java-example-app contains an example Android Studio (3.0) project preconfigured with all the dependencies required to create a Robobo App, plus some example code to control the behaiour of the robot.

It is important to note here that any Robobo App will share the same startup activity, that will be very similar to the startup activity of the offial Robobo App. This activity is loaded automatically, and it is in charge of providing access to the setup utilities of the robot, as well as providing a GUI to select the robobo base to use. Only when the user chicks the Start button is when the particular robobo behaviour of the App starts running. It is, only when the app is executing the robot, thus it is showing the face of the Robobo, is when the user code is running.

app

In order to create new apps that implement new behaviours (automous or not), like games, mascot-like behaviors, labirinth solving algorithms, etc., for the Robobo, the way to go is to create what we call a behaviour module and add that new module (or modules) to the list of modules loaded by the Robobo Framework in the application.

To create new behaviour module programmers must implement the abstract class ABehaviourModule.java. The details of how to extend ABehaviourModule.java to create new robot behaviours is detailed here.

A example behaviour module is provided in RoboboExample.zip. You can just start by modifying the provided example before writing your own behaviours.

The example provided implements just a simple app (behaviour) that makes the robot react to touch events and obstacles:

The onStartBehaviour() method contains all the needed modules declaration and the setup of the listeners, also, the interval of the runStep() method is configured at the end.

@Override
    protected void startBehaviour() throws InternalErrorException {

        robModule = getRobobo().getModuleInstance(IRobInterfaceModule.class).getRobInterface();

        //the emotion module allows us to change the face of the robot
        emotionModule = getRobobo().getModuleInstance(IEmotionModule.class);

        //the touch module allows the reaction to touch events like tap or fling
        touchModule = getRobobo().getModuleInstance(ITouchModule.class);

        //the TTS module allows the robot to speak
        ttsModule = getRobobo().getModuleInstance(ISpeechProductionModule.class);

        soundModule = getRobobo().getModuleInstance(IEmotionSoundModule.class);



        //startBehavour is the place to setup our modules and resources, like for example
        //suscribing some listeners to modules events
        //it's very important to perform only 'quick' operations in the listeners, if you need
        //to perform heavy processing, like for example image processing or network access, you
        //should execute the processing in a separate thread that you can start from the listener

        //lets make the robot react to taps by temporarily changing its face and make some 'noise'
        touchListener = new ITouchListener() {
            @Override
            public void tap(Integer x, Integer y) {
                //let's complain a little bit
                soundModule.playSound(IEmotionSoundModule.OUCH_SOUND);
                emotionModule.setTemporalEmotion(Emotion.ANGRY, 1500, Emotion.NORMAL);
            }

            @Override
            public void touch(Integer x, Integer y) {

            }

            @Override
            public void fling(TouchGestureDirection dir, double angle, long time, double distance) {
                //let's make a little noise
                soundModule.playSound(IEmotionSoundModule.PURR_SOUND);
                emotionModule.setTemporalEmotion(Emotion.IN_LOVE, 15000, Emotion.NORMAL);
            }

            @Override
            public void caress(TouchGestureDirection dir) {

            }
        };

        touchModule.suscribe(touchListener);


        //if needed you can change the default execution period of the runStep() code
        //by default it is 50 ms, and has a minimum allowed value of 10 ms
        this.setPeriod(100); //100ms --> 10 times per second

    }

The shutdownBehaviour() method is used to unsuscribe the listeners.

    @Override
    protected void stopBehaviour()  throws InternalErrorException{

        touchModule.unsuscribe(touchListener);

    }

runStep() is configured to check the ir sensors periodically and change emotions if too close to an object:

    @Override
    protected void runStep() {

        //as you can see in the documentation the majority of the Robobo framework works by
        //using listeners to events, the best place to setup the listeners is the startBehaviour()
        //method

        //anyway, if need to execute some periodic task like checking the state of a sensor
        //or something like that, runStep() is the place to put that code

        //below you can seen an example where we are checking the values of the IR sensors
        //and changing the face of the robot if there is an obstacle to close to the robot

        int newState = 0; //normal by default
        for(IRSensorStatus irSensor : robModule.getLastStatusIRs()) {
            if (irSensor.getDistance() < 1000) {
                newState = 1; //some obstacle is to close!
            }
        }

        if (newState != this.state) { //state changed since last time

            this.state = newState;

            switch(state) {
                case 0: //normal state
                    this.emotionModule.setCurrentEmotion(Emotion.NORMAL);
                    break;
                case 1: //too close to obstacle
                    this.soundModule.playSound(IEmotionSoundModule.ANGRY_SOUND);
                    this.emotionModule.setCurrentEmotion(Emotion.ANGRY);
                    break;

            }
        }


    }
A very important step, on order to run a behaviour module, is to add a reference to it in the modules.properties file. This file configures the modules that the robot is going to load on startup, is importante to add the new behaviour modules and the end of file, and not modify the list of previous modules, because they will be required by the App.

robobo.module.0=com.mytechia.robobo.framework.remote_control.remotemodule.RemoteControlModule
robobo.module.2=com.mytechia.robobo.rob.DummyRobInterfaceModule
#robobo.module.2=com.mytechia.robobo.rob.BluetoothRobInterfaceModule
robobo.module.3=com.mytechia.robobo.rob.movement.DefaultRobMovementModule
robobo.module.4=com.mytechia.robobo.framework.hri.speech.production.android.AndroidSpeechProductionModule
robobo.module.6=com.mytechia.robobo.framework.hri.emotion.DefaultEmotionModule
robobo.module.7=com.mytechia.robobo.framework.hri.sound.emotionSound.android.AndroidEmotionSoundModule
robobo.module.8=com.mytechia.robobo.framework.hri.vision.basicCamera.opencv.OpenCVCameraModule
robobo.module.9=com.mytechia.robobo.framework.hri.vision.faceDetection.android.AndroidFaceDetectionModule
robobo.module.11=com.mytechia.robobo.framework.hri.touch.android.AndroidTouchModule
robobo.module.12=com.mytechia.robobo.framework.hri.sound.soundDispatcherModule.TarsosDSP.TarsosDSPSoundDispatcherModule
robobo.module.13=com.mytechia.robobo.framework.hri.sound.pitchDetection.TarsosDSP.TarsosDSPPitchDetectionModule
robobo.module.14=com.mytechia.robobo.framework.sensing.battery.android.AndroidBatteryModule
robobo.module.15=com.mytechia.robobo.framework.sensing.brightness.android.AndroidBrightnessModule
robobo.module.16=com.mytechia.robobo.framework.sensing.orientation.android.AndroidOrientationModule
robobo.module.17=com.mytechia.robobo.framework.sensing.accel.android.AndroidAccelerationModule
robobo.module.18=com.mytechia.robobo.framework.hri.sound.noteGeneration.android.AndroidNoteGenerationModule
robobo.module.19=com.mytechia.robobo.framework.hri.vision.blobTracking.opencv.OpenCVBlobTrackingModule
robobo.module.20=com.mytechia.robobo.framework.hri.sound.clapDetection.tarsosDSP.TarsosDSPClapDetectionModule
robobo.module.21=com.mytechia.robobo.framework.hri.sound.noteDetection.TarsosDSP.TarsosDSPNoteDetectionModule
robobo.module.22=robobo.example.com.roboboexample.ExampleBehaviourModule
The order of definition is relevant, as it is the order in which the modules are loaded and there might be dependencies between them. For example, a few of the sound modules are dependent with the SoundDispatcherModule. The developer should add its behavior module at the end of the file to access to the rest of the modules correctly.

Once added to the modules.properties you can just run the app from Android Studio, or build the new apk file, and run it in an Android smartphone. As previously mentioned, the app will show the tyipical Robobo startup activity, with the list to select a Robobo base and the setup options to change language and calibrate the camera.

app

One the user presses Start, the robot will start by starting-up the Robobo Framework and thus loading all the modules, including the user's behaviour modules.

If you want to change the name of the App, you should look in app/src/main/res/values/strings.xml, and if you want to change the icon of the App, you must add the new icons and reference them in the example's AndroidManifest.xml file.

Updated