robotemi/sdk

User discovery is show activity

fabiola29 opened this issue · 0 comments

Hi I'm making an application that manages the user's activities in particular I give a path and the robot must find the person and notify him of the activity. I did it by implementing the service as shown in the following code using the sdk methods and it seems correct to me but I don't know which permissions to activate on the robot I have robot themes with OS 16400 launcher and Robox OS 128.12.


`public class SearchingUserService extends Service  implements OnDetectionStateChangedListener,
        OnUserInteractionChangedListener,
        OnDetectionDataChangedListener,
        OnGoToLocationStatusChangedListener
{

    private Robot robot;
    SharedPreferences savedPath;
    private int pathIndex= 0;
    private List<String> path = new ArrayList<>();
    private volatile int detectionState = 0; //Changed from stateDetection to detectionState
    private volatile  int detectionAngle;
    private List<String> locations;
    private int interactionCounter = 0;
    private String taskInfo;

    private static final int REQUEST_CODE_START_DETECTION_WITH_DISTANCE = 6;


    @Override
    public void onCreate() {
        super.onCreate();

        //--------------Robot Instance--------------
        robot = Robot.getInstance();
        locations = robot.getLocations();
        //locationListSize = locations.lastIndexOf(locations);


        //--------------Path--------------

        // Recupero del percorso salvato dalle SharedPreferences
        savedPath = getSharedPreferences("savedPath_file", Context.MODE_PRIVATE);
        path = new Gson().fromJson(savedPath.getString("savedPath_file", null), new TypeToken<List<String>>() {}.getType());
        Log.d("SearchingTaskService", "Saved Path:" + path);


        //--------------Robot Listeners--------------
        robot.addOnDetectionDataChangedListener(this);
        robot.addOnUserInteractionChangedListener(this);
        robot.addOnDetectionStateChangedListener(this);
        robot.addOnGoToLocationStatusChangedListener(this);

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d("SearchingTaskService", "Service starting ");
        Log.d("SearchingTaskService", "TASK_INFO: "+intent.getStringExtra(TASK_INFO));

        taskInfo = intent.getStringExtra(TASK_INFO);
        //robot.setDetectionModeOn(true);
        startDetection();

        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();

        robot.removeOnDetectionDataChangedListener(this);
        robot.removeOnUserInteractionChangedListener(this);
        robot.removeOnDetectionStateChangedListener(this);
        robot.removeOnGoToLocationStatusChangedListener(this);
        try{
            Intent intentService = new Intent(getApplicationContext(), TemiTask.class);
            getApplicationContext().stopService(intentService);
        } catch (Exception e){
            Log.e("NotificationActivity", "Exception: "+e);
        }
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) { return null; }



    /*-------------------------------------- User Quest functions --------------------------------------*/


    /*Questo metodo avvia il processo di rilevamento, che sembra coinvolgere un percorso
      predefinito che il robot deve seguire. Usa anche il metodo goTo() per spostarsi
      tra le posizioni specificate.
    */
    private void startDetection() {
        if (requestPermissionIfNeeded(Permission.SETTINGS, REQUEST_CODE_START_DETECTION_WITH_DISTANCE)) {
            return;
        }
        pathIndex = 0;
        goTo(pathIndex);
        Log.d("StartDetection", "detectionMode: "+robot.isDetectionModeOn());
        //detecting(); TODO: erase if the process works
    }


    /* Questo metodo sembra gestire il rilevamento effettivo. Imposta il robot in modalità di
      rilevamento e quindi fa ruotare il robot in incrementi di 45 gradi fino a quando non
      rileva un utente o compie una rotazione completa di 360 gradi. Quando un utente viene
      rilevato o il robot completa la rotazione, vengono intraprese azioni di conseguenza.*/
    private void detecting(){
        if (!robot.isDetectionModeOn()){
            robot.setDetectionModeOn(true);
            Log.d("Detecting", "Mode: "+robot.isDetectionModeOn());
        }

        detectionAngle = 0;
        ScheduledExecutorService scheduleTaskExecutor = Executors.newScheduledThreadPool(1);

        scheduleTaskExecutor.scheduleAtFixedRate(new Runnable() {

            @Override
            public void run() {
                try{
                    if (detectionState != OnDetectionStateChangedListener.DETECTED && detectionAngle<360) {
                        turnBy();
                        detectionAngle = detectionAngle + 45;
                    } else if (detectionState == OnDetectionStateChangedListener.DETECTED){
                        detectionAngle = 360;
                    }
                } catch (Exception e){
                    Log.d("Robot", "Exception: "+ e);
                }finally {

                }
                if (detectionAngle == 360) {
                    if(detectionState != OnDetectionStateChangedListener.DETECTED) {
                        Log.d("Detecting...", "No user detected, going to the next position in the path");
                        pathIndex = pathIndex + 1;
                        goTo(pathIndex);
                        //TODO: Check if it does work, if not move if-statement outside of scheduleTaskExecutor!
                    }
                    Log.d("detectingProces", "Stop turning around, ScheduleTaskExecutor stopped");
                    scheduleTaskExecutor.shutdown();

                }


            }
        },0,5000, TimeUnit.MILLISECONDS);
    }

    /* Questo metodo fa ruotare il robot di 45 gradi. Sembrerebbe essere utilizzato all'interno
    di detecting() per far girare il robot in modo incrementale.*/
    private void turnBy(){
        if (detectionState != OnDetectionStateChangedListener.DETECTED) {
            robot.turnBy(45);
            Log.d("TurnBy", "Robot turning around");
        }
    }

    /*Questo metodo muove il robot verso una posizione specifica nell'elenco delle posizioni.
    L'indice specificato corrisponde all'elemento nell'elenco delle posizioni da raggiungere.*/
    private void goTo(int index){
        if (path != null && index < path.size()){
            Log.d("goTo", "going to:"+path.get(index));
            robot.goTo(path.get(index));
        } else { robot.goTo("home base");}
    }

    @CheckResult
    private boolean requestPermissionIfNeeded(Permission permission, int requestCode) {
        if (robot.checkSelfPermission(permission) == Permission.GRANTED) {
            return false;
        }
        robot.requestPermissions(Collections.singletonList(permission), requestCode);
        return true;
    }

    /*Questo metodo gestisce le interazioni dell'utente con il robot. In particolare,
     sembra arrestare il movimento del robot e disattiva la modalità di rilevamento
      quando un utente sta interagendo.*/

    private void interacting(){
        Log.d("Interaction", "Temi is interacting with a user");
        if ( detectionState == OnDetectionStateChangedListener.DETECTED){
            robot.stopMovement();
            robot.setDetectionModeOn(false);


        }


    }

    //--------------------------------------Temi Listeners--------------------------------------

    @Override
    public void onUserInteraction(boolean isInteracting) {
        if (isInteracting && interactionCounter<1){
            interactionCounter++;
            interacting();
        }

    }

    @Override
    public void onDetectionDataChanged(@NotNull DetectionData detectionData) {

    }

    @Override
    public void onDetectionStateChanged(int state) {
        Log.d("DetectionActivity", "onDetectionStateChanged - State:"+state);
        if(state == OnDetectionStateChangedListener.DETECTED){
            //robot.stopMovement();
            //TODO: Restrict to once detectionStateChange to trigger NotificationActivity and the Speak request
            Log.d("onDetectionStateChanged", "User detected");
            detectionState = state;
            robot.speak(TtsRequest.create("Hello, you have a saved event", true));
            robot.beWithMe();

            Intent notificationIntent = new Intent(this, NotificationActivity.class);
            notificationIntent.putExtra(TASK_INFO, taskInfo);
            notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

            String toastText = String.format("Starting NotificationsActivity");
            Toast.makeText(this, toastText, Toast.LENGTH_SHORT).show();
            startActivity(notificationIntent);
            //Stop Service
            Intent intentService = new Intent(getApplicationContext(),TemiTask.class);
            getApplicationContext().stopService(intentService);

        } else if (state == IDLE){
            detectionState = state;
            Log.d("onDetectionStateChanged", "Nobody detected");
            //robot.turnBy(45);
        } else if(state == OnDetectionStateChangedListener.LOST){
            detectionState = state;
            robot.turnBy(45);
            robot.turnBy(-90);
        }

    }

    @Override
    public void onGoToLocationStatusChanged(@NotNull String location, String status, int descriptionId, @NotNull String description) {
        try{
            if (pathIndex < path.size()) {
                Log.d("onGoToLocationStatus", "Location: " + location);
                Log.d("onGoToLocationStatus", "PathLocation: " + path.get(pathIndex));
            }
        } catch (Exception e){
            Log.e("onGoToLocationStatus", "Exception: "+e);

        }

        switch (status) {
            case OnGoToLocationStatusChangedListener.START:
                break;

            case OnGoToLocationStatusChangedListener.CALCULATING:
                break;

            case OnGoToLocationStatusChangedListener.GOING:
                break;

            case OnGoToLocationStatusChangedListener.COMPLETE:

                try{//if the Location is the same as the location in the path(index) then detecting() will star
                    if (pathIndex < path.size()) {
                        Log.d("onGoToLocationStatus", "COMPLETE");
                        Log.d("onGoToLocationStatus", "Location: "+location+" PathLocation: "+path.get(pathIndex));

                        if(location.equals(path.get(pathIndex))){
                            Log.d("onGoToLocationStatus", "Detecting...");
                            detecting();
                        } else {
                            Log.d("onGoToLocationStatus", "Location doesn't match...");
                            //TODO: See if condition is met, if not then place detecting() outside, and see why the condition won't be fulfilled
                        }
                        if (location.equals("home base") && detectionState==0){
                            rescheduleTask();
                        }
                    }
                } catch (Exception e){
                    Log.e("onGoToLocationStatus", "Exception: "+e);
                }

                if (location.equals("home base") && detectionState==0){
                    rescheduleTask();
                }
                break;

            case OnGoToLocationStatusChangedListener.ABORT:
                break;
        }
    }

    private void rescheduleTask() {

    }
}
`

In the Manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.temi1">

    <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />

    <uses-feature android:name="android.hardware.camera" />

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.Temi1">

        <meta-data
            android:name="com.robotemi.sdk.metadata.SKILL"
            android:value="@string/app_name" />

        <meta-data
            android:name="com.robotemi.sdk.metadata.ACTIONS"
            android:value="home.welcome, home.dance, home.sleep" />

        <meta-data
            android:name="com.robotemi.sdk.metadata.KIOSK"
            android:value="TRUE" />

        <meta-data
            android:name="@string/metadata_permissions"
            android:value="com.robotemi.permission.face_recognition, com.robotemi.permission.map, com.robotemi.permission.settings, com.robotemi.permission.sequence" />

        <activity
            android:name=".views.activity.MainActivity"
            android:exported="true"
            android:screenOrientation="landscape"
            android:windowSoftInputMode="adjustPan">

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <receiver android:name=".TaskBroadcastReceiver.TaskBroadcastReceiver"
            android:enabled="true"
            android:exported="false">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>

        <service android:name=".Services.SearchingUserService"/>
        <activity android:name=".views.activity.NotificationActivity" />


    </application>

</manifest>