Outils pour utilisateurs

Outils du site


ros_android

Ceci est une ancienne révision du document !


Android

ROS Android

Il existe plusieurs méthodes pour utiliser ROS sur un système Android.

  1. Portage Java de ROS avec le package Android http://wiki.ros.org/android
  2. Avec le NDK d'Android et cross-compilation des libs ROS. http://wiki.ros.org/android_ndk/Tutorials

La deuxième méthode permet d'assurer la compatibilité avec l'ensemble des codes C++ existants et une meilleur performance.

Tutoriel: ROS only

Construction d'un projet de test avec Android Studio et ROS. Ce tuto permet de lancer un noeud ROS sans avoir besoin d'une Android Activity.

Tout d'abord, récupérer (ou cross-compiler) ROS pour les systèmes Android.

(Déziper et) Placer le dossier roscpp_android_ndk à l'endroit voulu (Dans le dossier AndroidStudioProjects par exemple).

Ensuite, récupérer le projet de test sur le Redmine du LAAS. Ce projet peut servir de base à un projet plus conséquent.

https://redmine.laas.fr/projects/lumus/repository cloner le dépot Lumus. Le projet de base est contenu dans le dossier simpleROS.

Le projet test permet de lancer une node ROS sur un dispositif Android. Cette node écoute le topic /chatter et publie sur le topic /a_chatter.

Ouvrir le projet avec Android studio

Dans l'arborescence projet, ouvrir app/cpp/sample_app/src/test.cpp qui contient le code C++ ROS

Modifier les valeurs des adresses ip pour les faire correspondre à votre configuration réseau.

// Set master workstation ip : __master
// Set android device ip : __ip
char *argv[] = {"nothing_important" , "__master:=http://192.168.150.1:11311", "__ip:=192.168.150.10"};

Dans l'arborescence projet, ouvrir External Build Files/Android.mk qui permet de configurer le build des modules NDK du projet (dans notre cas ROS)

Modifier la valeur NDK_MODULES_PATH par celle du dossier qui contient le dossier roscpp_android_ndk. Cette variable référence le dossier contenant les modules NDK de l'application.

Ne pas oublier d'activer l'accès réseu pour le dispositif android. Dans AndroidManifest.xml

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

Ensuite compiler l'application avec Android Studio (CTRL+F9).

Il faut maintenant lancer ROS sur la machine principale.

:!: Ne pas oublier de modifier les variables ROS_MASTER_URI et ROS_IP avec l'adresse IP de votre machine sur le réseau. ROS_MASTER_URI doit être identique à celle que vous avez modifier dans le code précédemment.

:!: La machine principale et l'appareil Android doivent être sur le même réseau. L'application https://play.google.com/store/apps/details?id=ua.com.streamsoft.pingtools&hl=fr permet de tester la connectivité réseau sur Android.

Dans 3 terminaux différents, lancer :

 roscore 

Connecter (USB) votre appareil et lancer l'application depuis Android Studio (SHIFT+F10).

 rostopic pub /chatter std_msgs/String 'Hello!' -r 1 
 rostopic echo /a_chatter 

Si tout fonctionne, la sortie console retourne

data: hello world from android ndk 1
data: hello world from android ndk 2
data: hello world from android ndk 3

Il est possible de surveiller le déroulement de l'application Android sur l'appareil avec Android Monitor sur Android Studio.

Tutoriel: ROS avec une Android Activity

Avant toute chose, il faut s'assurer que la lib ROS/Android est correctement mise en place dans le pprojet. Se réféerer au tuto précédent pour les détails. Exemple de fichier NDK build Android.mk :

LOCAL_PATH := $(call my-dir)
NDK_MODULES_PATH:= $(call my-dir)/../../../../../..

include $(CLEAR_VARS)

LOCAL_MODULE    := ros_main

LOCAL_C_INCLUDES := $(LOCAL_PATH)/src/ros/jniCalls
LOCAL_C_INCLUDES += $(LOCAL_PATH)/src/ros/nativeCode

FILE_LIST := $(wildcard $(LOCAL_PATH)/src/ros/jniCalls/*.cpp)
FILE_LIST += $(wildcard $(LOCAL_PATH)/src/ros/nativeCode/*.cpp)
LOCAL_SRC_FILES := $(FILE_LIST:$(LOCAL_PATH)/%=%)

LOCAL_LDLIBS := -landroid -llog
LOCAL_STATIC_LIBRARIES := roscpp_android_ndk

include $(BUILD_SHARED_LIBRARY)

#import ros ndk with custom directory location
$(call import-add-path, $(NDK_MODULES_PATH) )
$(call import-module,roscpp_android_ndk)

Afin de ne pas bloquer l'execution de l'UI Android il est important de lancer les nodes ROS sur des threads différents. Un exemple de class pour réponder à cette contrainte :

public class ROSThread implements Runnable {
    private Thread m_thread;

    public ROSThread() {
        this.m_thread = new Thread(this);
    }

    public void rosrun(){
        m_thread.start();
    }

    @Override
    public void run() {
        startROSNode();
    }

    //load C/C++ shared library
    static
    {
        System.loadLibrary("ros_main");
    }
    private native void startROSNode();
}

L'implémentation de private native void startROSNode(); est une fonction C++ JNI qui lance le noeud ROS. Exemple :

JNIEXPORT void JNICALL Java_com_laas_simpleAR_ROSThread_startROSNode(JNIEnv* env, jobject obj)
{
    android_main();
    return;
}

On retrouve dans android_main() un noeud ROS habituel :

void android_main() {

    ros::init(...);
    ros::NodeHandle n;
    ros::WallRate loop_rate(100);
    while(ros::ok()){
        ros::spinOnce();
        loop_rate.sleep();
    }
}

Ne pas oublier d'activer l'accès réseu pour le dispositif android. Dans AndroidManifest.xml

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

Liens intéressants - Intégration OpenGL, OpenCV, ROS... etc.

ROS Android et snapdragon (used in Lumus DK50)

RVIZ on Android

Projet original rviz_for_android : https://bitbucket.org/zimmrmn3/rviz-for-android/wiki/Home

Le projet date de ~2012, il a été réalisé par un étudiant chez Willow Garage. Le projet est exclusivement en Java avec utilisation de ROSJava, du binding OpenGL ES Java, et certaines lib sont compilées avec le NDK.

Le projet n'est pas un portage complet sur Android des fonctionnalités de RVIZ sur Desktop.

Page Willow Garage du projet : http://www.willowgarage.com/blog/2012/09/24/rviz-android-0

Installation et Utilisation

- Télécharger l'APK et le serveur python: https://bitbucket.org/zimmrmn3/rviz-for-android/downloads/.

- Télécharger les sources du package ROS tf_throttle: https://github.com/ros-interactive-manipulation/pr2_object_manipulation/tree/groovy-devel/applications/tf_throttle. Cette node permet de limiter la fréquence de publication des tfs pour ne pas saturer le réseau/dispositif Android. Installer le package comme un package ROS classique.http://wiki.ros.org/ROS/Tutorials/CreatingPackage

:!: Pour compiler et installer avec catkin_make des modifications sont à effectuer :

Dans le package :

rm Makefile

Remplacer l'intégralité du contenu de CMakeLists.txt par :

cmake_minimum_required(VERSION 2.8.3)
project(tf_throttle)
find_package(catkin REQUIRED COMPONENTS geometry_msgs roscpp tf)
catkin_package( CATKIN_DEPENDS geometry_msgs roscpp tf)
include_directories(include
  ${catkin_INCLUDE_DIRS}
)
add_executable(tf_throttle src/tf_throttle.cpp)
target_link_libraries(tf_throttle ${catkin_LIBRARIES})

S'assurer que l'on peut correctement lancer la node.

rosrun tf_throttle tf_throttle

- Connecter les machines sur le même réseau. S'assurer que les machines peuvent communiquer (ping, ports… etc.)

- Lancer ROS sur le PC.

export ROS_IP=${IP_PC_SUR_RESEAU_ROS}
export ROS_MASTER_URI=http://${ROS_IP}:11311
roscore

- Lancer le serveur python

chmod +x server.py
./server.py

Le serveur python permet avec des requêtes HTTP d'interagir avec le PC depuis le dispositif Android. Il donne la possibilité de lancer/stopper des des nodes sur le PC distant et de gérer les fichiers URDF pour l'affichage des modèles 3D des robots. Plus d'info ici : Using the Python Server https://bitbucket.org/zimmrmn3/rviz-for-android/wiki/Contributing. C'est également lui qui lance tf_throttle.

- Installer l'application sur un dispositif Android.

adb install rviz_for_android.apk

- Lancer l'application.

- Renseigner l'adresse IP du PC qui a lancé le roscore

http://${IP_PC_SUR_RESEAU_ROS}:11311

- Cliquer sur “Layers” → “Add” et choisir l'objet à afficher

Extensions

Le projet original a été modifié afin de pouvoir être utilisé avec la version Kinetic de ROS, les nouvelles versions d'Android et d'Android Studio. L'utilisation de l'application (compilé avec le projet) a été testé sur le Lumus DK50 (Android 4.0) et un WileyFox Swift (Android 7.0).

Le projet a donné lieu à une modification mineure du tutoriel ROS pour l'utilisation avec Android. http://wiki.ros.org/android/Tutorials/kinetic/Installation%20-%20Android%20Studio%20Development%20Environment
answers.ros https://answers.ros.org/question/273664/ros-and-android-with-kinetic-and-android-studio/?comment=273895#post-id-273895

Le projet modifié se trouve ici : https://redmine.laas.fr/projects/rviz_for_android/repository.

Modifier le fichier local.properties

ndk.dir=/chemin/NDK/Android/
sdk.dir=/home/tristan/Android/Sdk

:!: Si erreurs “AGPBI”, activer multidex qui permet de casser la limite du nombre de méthodes https://developer.android.com/studio/build/multidex.html.

:!: Si UI invisible regarder couleur des textes/backgrounds et compatibilité avec le thème utilisé (Il peut arriver que du texte sombre se retrouve sur un fond noir). Il peut aussi s'agir d'un mauvais “scaling” de l'UI à la taille de l'écran. L'auteur de l'application recommande une tablette de plus de 8 pouces.

:!: L'application est difficilement testable sur simulateur due à l'utilisation d'OpenGL ES 2.0.

Ajout UI et Comportements Caméras

Il est possible d'étendre les interfaces proposées pour ajouter des nouveaux éléments affichables et des comportements caméras spécifiques. Plus d'infos : https://bitbucket.org/zimmrmn3/rviz-for-android/wiki/Contributing

Caméra FPS attachée à une TF

  1. Ajouter une caméra (ou utiliser celle par défaut)
  2. Sélectionner dans “Fixed Frame” la TF de suivi de camera. Cette TF devient l'origine du monde affiché.
  3. Sélectionner dans “Follow” la TF choisie à l'étape précédente. L'application recalcule l'affichage du monde en suivant cette TF.

La caméra est maintenant attachée à la TF. elle est orientée le long de l'axe X (en rouge sur ROS) et son axe Z (en bleu sur ROS) est orienté vers le haut.

:!: A ce jour, les comportements de caméras n'utilisent pas l'interface Camera et le polymorphisme comme il serait normal de faire. Cela à cause du fait que modifier l'objet caméra dans la partie rendu provoque des effets de bords (affichage vide, erreur de matrices modèle … etc). Il est plus facile, avec le code existant, d'utiliser un objet commun Camera lié au rendu et de spécialiser les méthodes de calcul de la matrice de vue. Actuellement pour changer de type de camera il est nécessaire de recompiler l'application en modifiant le type de camera dans les classes VisualizationView et MainActivity.

Publication ROS des capteurs

:!: Activer autorisation GPS et Camera dans les paramètres de l'appareil Android sinon l'application crashera au démarrage.

Topics publiés :

/camera/image (camera 1)
/camera2/image (camera 2 Lumus)
/android/fix (GPS)
/android/imu (IMU)

Il est nécessaire d'avoir un rendu sur l'écran des lunettes pour obtenir les images de la caméra. https://stackoverflow.com/questions/6756888/android-camera-image-size (changer résolution) https://stackoverflow.com/questions/9160221/why-images-resolution-from-camera-picturecallback-is-the-size-of-previewsize (attention au ration avec pictureSize et previewSize)

:!: La partie GPS de l'application a été testée avec succès sur un autre appareil Android que le Lumus (Wiley Fox 7.0). Sur ce dernier, le GPS semble ne pas fonctionner correctement. Sur le site des specs du Lumus, il est écrit “ GPS data is available upon wireless connection to Android smartphone”. Après avoir connecté un smartphone (réseau local avec accès internet partagé), testé les différents modes de localisation l'application ne publie pas sur le topic. Le GPS est pourtant bien activé sur l'appareil. Sur Google Map, le Lumus ne parvient pas non plus à se localiser…

Programmation sur les lunettes Lumus

Attention à la version NDK utilisé. Version NDK 10e à utiliser tant que native_app_glue est utilisé.

ros_android.1523610898.txt.gz · Dernière modification : 2018/04/13 11:14 de tristan