Diferenzas

Isto amosa as diferenzas entre a revisión seleccionada e a versión actual da páxina.

Enlazar a esta vista de comparación

inv:por-clasificar:ros [2013/03/27 10:55] (actual)
Liña 1: Liña 1:
 +====== Instalación y configuración de ROS (26 dic) ====== ​
 +Cada versión de ROS soporta un máximo de tres versiones de ubuntu, por lo que conviene tener claro qué versión vamos a instalar.
 +Para Ubuntu 12.10 debemos instalar ROS groovy.
  
 +==== Ubuntu 12.10 ====
 +== Instalación de ROS Groovy ==
 +Añadir los repositorios de ros-groovy para ubuntu 12.10 (a 12 dic 2012)
 +<​code>​
 +sudo sh -c 'echo "deb http://​packages.ros.org/​ros/​ubuntu quantal main" > /​etc/​apt/​sources.list.d/​ros-latest.list'​
 +wget http://​packages.ros.org/​ros.key -O - | sudo apt-key add -
 +sudo apt-get update
 +sudo apt-get upgrade
 +</​code>​
 +
 +Instalar con apt-get (todas las dependencias se instalan automáticamente).
 +<​code>​
 +sudo apt-get install ros-groovy-desktop-full
 +</​code>​
 +
 +Instalar también otras herramientas que facilitan el trabajo con ROS.
 +<​code>​
 +sudo apt-get install python-rosinstall python-rosdep
 +</​code>​
 +
 +== Configuración de ROS Groovy ==
 +Configuración inicial:
 +<​code>​
 +sudo rosdep init
 +rosdep update
 +source /​opt/​ros/​groovy/​setup.bash
 +</​code>​
 +
 +Creamos nuestro espacio de trabajo (se recomienda para no ensuciar la instalación base)
 +<​code>​
 +cd /opt/ros
 +mkdir rosws
 +sudo chmod -R 775 /​opt/​ros/​rosws
 +sudo chown user:user /​opt/​ros/​rosws
 +rosws init /​opt/​ros/​rosws /​opt/​ros/​groovy
 +</​code>​
 +
 +Añadimos el script de configuración al bashrc
 +<​code>​
 +echo "​source /​opt/​ros/​rosws/​setup.bash"​ >> ~/.bashrc
 +. ~/.bashrc
 +</​code>​
 +
 +
 +== Instalación de stacks desde repositorios ==
 +Para instalar cualquier stack desde repositorios:​
 +<​code>​
 +roscd
 +roslocate info STACKNAME | rosws merge -
 +source setup.sh
 +rosws update STACKNAME
 +rosmake STACKNAME
 +</​code>​
 +
 +Un ejemplo de instalación del stack ROSARIA.
 +Este stack es un wrapper de [[http://​robots.mobilerobots.com/​wiki/​ARIA|ARIA]] para ROS que nos permite acceder al sonar y odometría de todos los robots de MobileRobots/​ActivMedia.
 +<​code>​
 +roscd
 +roslocate info ROSARIA | rosws merge -
 +source setup.sh
 +rosws update ROSARIA
 +rosmake ROSARIA
 +</​code>​
 +
 +
 +
 +====== Tutoriales de ROS ====== ​
 +[[http://​www.ros.org/​doc/​api/​rosinstall/​html/​rosws_tutorial.html|Tutorial de la herramienta rosws]] ​
 +
 +
 +====== Crear un paquete ROS ======
 +
 +En este tutorial mostraremos cómo crear un paquete de software para ROS. A modo de ejemplo, crearemos un paquete ficticio con un único nodo ROS, que se encargará de las siguientes tareas:
 +
 +  - Abrir un sensor ficticio.
 +  - Leer los datos que proporciona el sensor de forma periódica.
 +  - Publicar los datos a través del sistema de intercambio de mensajes ROS. El programa que se encargue de esto recibirá el nombre de //​publisher//​.
 +
 +Nuestro sensor ficticio proporcionará la posición 3D de un objeto y la marca temporal asociada a cada dato:
 +
 +<​code>​
 +timestamp x y z
 +</​code>​
 +
 +Antes de comenzar el tutorial, debemos descargarnos los fuentes que utilizaremos en el paquete {{:​inv:​sensorfakesources.zip|}}
 +  * SensorFake.cpp y SensorFake.h:​ librería de interacción con el sensor.
 +  * SensorFake_Publisher.cpp:​ //​publisher//​.
 +
 +
 +==== Diseño del paquete ROS ====
 +
 +Al tratarse de un paquete sencillo, proponemos un diseño que no complique en exceso ni la implementación ni el mantenimiento del mismo. Nuestro paquete constará de los siguientes archivos:
 +
 +  - Librería para el manejo del sensor. Proporcionará las funciones típicas: conexión, lectura, desconexión,​ etc. Debería ser totalmente independiente de ROS.
 +  - Nodo ROS encargado de comunicarse con el sensor (a través de su librería) y transmitir los datos a través del sistema de mensajes ROS.
 +
 +Para paquetes más complejos, se recomienda encarecidamente utilizar un [[http://​www.sharprobotica.com/​2010/​04/​developing-well-designed-packages-for-robot-operating-system-ros-part-i/​|diseño más adecuado]].
 +
 +
 +==== Creación del paquete ====
 +
 +Nos situamos en la carpeta donde queramos crear nuestro paquete. Por ejemplo:
 +<​code>​
 +${HOME}/ros
 +</​code>​
 +
 +Creamos el paquete. El nombre del paquete será //​sensor_fake//​ y dependerá de //roscpp//.
 +<​code>​
 +roscreate-pkg sensor_fake roscpp
 +</​code>​
 +
 +La salida del comando debería ser algo como:
 +
 +<​code>​
 +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 +WARNING: current working directory is not on ROS_PACKAGE_PATH!
 +Please update your ROS_PACKAGE_PATH environment variable.
 +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 +Created package directory /​home/​citius_robot/​ros_pruebas/​sensor_fake
 +Created include directory /​home/​citius_robot/​ros_pruebas/​sensor_fake/​include/​sensor_fake
 +Created cpp source directory /​home/​citius_robot/​ros_pruebas/​sensor_fake/​src
 +Created package file /​home/​citius_robot/​ros_pruebas/​sensor_fake/​Makefile
 +Created package file /​home/​citius_robot/​ros_pruebas/​sensor_fake/​manifest.xml
 +Created package file /​home/​citius_robot/​ros_pruebas/​sensor_fake/​CMakeLists.txt
 +Created package file /​home/​citius_robot/​ros_pruebas/​sensor_fake/​mainpage.dox
 +
 +Please edit sensor_fake/​manifest.xml and mainpage.dox to finish creating your package
 +</​code>​
 +
 +Esto nos indica: ​ 1) que el paquete creado no está en la variable de entorno //​ROS_PACKAGE_PATH//​ (solución en la siguiente sección), 2) que se ha creado correctamente la estructura de directorios y ficheros de configuración del paquete.
 +
 +Si nos desplazamos a la carpeta correspondiente (//​${HOME}/​ros_pruebas/​sensor_fake//​),​ observamos la estructura del paquete:
 +
 +  * include: directorio para ficheros "​.h"​.
 +  * * sensor_fake:​ directorio para ficheros "​.h"​ de la librería que se encarga de la interacción con el sensor.
 +  * src: directorio para ficheros "​.cpp"​
 +  * mainpage.dox:​ fichero para generacion de documentación con Doxygen.
 +  * CMakeLists.txt:​ configuración de la compilación con CMake [[http://​www.ros.org/​wiki/​rosbuild/​CMakeLists|(enlace)]].
 +  * manifest.xml:​ información sobre el paquete [[http://​ros.org/​wiki/​Manifest|(enlace)]].
 +
 +==== Añadiendo el paquete al workspace ====
 +
 +**Desde ${HOME}/​ros**,​ añadimos el paquete al workspace de ROS. 
 +<​code>​
 +rosws set sensor_fake
 +</​code>​
 +
 +Alternativamente,​ podemos ejecutar:
 +<​code>​
 +rosstack profile && rospack profile
 +</​code>​
 +
 +
 +Cerramos el terminal y lo abrimos de nuevo, para que se recarguen las variables de entorno correspondientes. A continuación,​ ejecutamos:
 +<​code>​
 +rospack profile
 +</​code>​
 +En este punto, ROS debería ser capaz de encontrar nuestro paquete. Lo comprobamos mediante:
 +<​code>​
 +rospack find sensor_fake
 +</​code>​
 +
 +Comprobamos que todo funciona correctamente ejecutando una compilación de prueba:
 +
 +<​code>​
 +rosmake sensor_fake
 +</​code>​
 +
 +Cuya salida debería ser algo como:
 +
 +<​code>​
 +[ rosmake ] rosmake starting... ​                                                                                                                
 +[ rosmake ] Packages requested are: ['​sensor_fake'​] ​                                                                                            
 +[ rosmake ] Logging to directory /​home/​david/​.ros/​rosmake/​rosmake_output-20121115-180018 ​                                                       ​
 +[ rosmake ] Expanded args ['​sensor_fake'​] to:
 +['​sensor_fake'​] ​                                                                                  
 +[rosmake-0] Starting >>>​ roslang [ make ]                                                                                                       
 +[rosmake-0] Finished <<<​ roslang ​ No Makefile in package roslang ​                                                                               ​
 +[rosmake-0] Starting >>>​ roscpp [ make ]                                                                                                        ​
 +[rosmake-0] Finished <<<​ roscpp ​ No Makefile in package roscpp ​                                                                                 ​
 +[rosmake-0] Starting >>>​ sensor_fake [ make ]                                                                                                   
 +[rosmake-0] Finished <<<​ sensor_fake [PASS] [ 5.56 seconds ]                                                                                    ​
 +[ rosmake ] Results: ​                                                                                                                           ​
 +[ rosmake ] Built 3 packages with 0 failures. ​                                                                                                 ​
 +[ rosmake ] Summary output to directory ​                                                                                                        
 +[ rosmake ] /​home/​david/​.ros/​rosmake/​rosmake_output-20121115-180018  ​
 +</​code>​
 +
 +
 +==== Importación a Eclipse ====
 +
 +Si queremos importar este paquete a un proyecto Eclipse, podemos seguir las instrucciones que se encuentran en: [[http://​www.ros.org/​wiki/​IDEs#​Eclipse]]
 +
 +==== Compilación de la librería para interacción con sensor_fake ====
 +
 +En primer lugar, copiamos el archivo //​SensorFake.cpp//​ en //​${HOME}/​ros/​sensor_fake/​src//​ y el archivo //​SensorFake.h//​ en //​${HOME}/​ros/​sensor_fake/​include/​sensor_fake//​ (fuentes: {{:​inv:​sensorfakesources.zip|}}). A continuación,​ modificamos el //​CMakeLists.txt//​ para que los compile como una librería dinámica.
 +
 +<​code>​
 +#common commands for building c++ executables and libraries ​ -> Añadimos el comando debajo de este comentario
 +rosbuild_add_library(${PROJECT_NAME} src/​SensorFake.cpp)
 +#Esto indica que queremos compilar SensorFake.cpp como una librería dinámica. Esta librería tendrá el mismo nombre que el proyecto
 +# (sensor_fake)
 +</​code>​
 +
 +
 +
 +
 +Compilamos:
 +
 +<​code>​
 +rosmake sensor_fake
 +</​code>​
 +
 +**Nota importante**:​ SensorFake.cpp asume que el SensorFake.h está en //​include/​sensor_fake//,​ al hacer:
 +
 +<​code>​
 +#include "​sensor_fake/​SensorFake.h"​
 +</​code>​
 +
 +De no se así (por ejemplo, si le hemos dado otro nombre al paquete), debemos modificar este //​include//​.
 +
 +Si la compilación es satisfactoria,​ //rosmake// nos habrá creado una nueva carpeta //​${HOME}/​ros/​sensor_fake/​lib//,​ que contendrá la librería compilada //​libsensor_fake.so//​.
 +
 +==== Definición de los mensajes ROS ====
 +
 +Ahora debemos definir los mensajes que nuestro paquete va a utilizar para comunicarse con ROS. Para ello, creamos la carpeta //​${HOME}/​ros/​sensor_fake/​msg//​ y copiamos en ella el archivo de definición del mensaje (//​XYZ.msg//​). A continuación,​ modificamos el archivo //​CMakeLists.txt//​ para que compile la definición del mensaje.
 +<​code>​
 +#uncomment if you have defined messages
 +rosbuild_genmsg() ​     #---> Descomentamos esta línea
 +</​code>​
 +
 +Compilamos:
 +
 +<​code>​
 +rosmake sensor_fake
 +</​code>​
 +
 +Si la compilación es correcta, //rosmake// habrá creado dos nuevas carpetas: 1) //​${HOME}/​ros/​sensor_fake/​msg_gen//​ y 2) //​${HOME}/​ros/​sensor_fake/​src/​sensor_fake///​. Estas carpetas ​ contienen las clases necesarias para el manejo del mensaje generado.
 +
 +==== Compilación del //​publisher//​ ====
 +
 +Ahora estamos en disposición de escribir un programa que lea los datos de nuestro //​sensor_fake//​ y los publique en ROS (utilizando
 +el tipo de mensaje generado en el apartado anterior). En primer lugar, copiamos el archivo //​SensorFake_Publisher.cpp//​ en //​${HOME}/​ros/​sensor_fake/​src//​ (fuentes: {{:​inv:​sensorfakesources.zip|}}). A continuación,​ modificamos el //​CMakeLists.txt//​ para enlazar la librería //​{HOME}/​ros/​sensor_fake/​lib/​libsensor_fake.so//​ y compilar el //​publisher//​ como ejecutable.
 +
 +<​code>​
 +#common commands for building c++ executables and libraries ​ ## -> Ya estaba!
 +rosbuild_add_library(${PROJECT_NAME} src/​SensorFake.cpp) ​  ## -> Ya estaba!
 +rosbuild_add_executable(SensorFake_Publisher src/​SensorFake_Publisher.cpp)
 +target_link_libraries(SensorFake_Publisher ${PROJECT_NAME})
 +</​code>​
 +
 +
 +Si la compilación es satisfactoria,​ //rosmake// habrá creado el ejecutable //​${HOME}/​ros/​sensor_fake/​bin/​SensorFake_Publisher//​.
 +
 +==== Ejecución del nodo ROS ====
 +Finalmente, probamos nuestro paquete. Para ello, abrimos un terminal y ejecutamos el servidor ROS:
 +
 +<​code>​
 +roscore
 +</​code>​
 +
 +En otro terminal, ejecutamos nuestro //​publisher//​ (nodo ROS):
 +
 +<​code>​
 +rosrun sensor_fake SensorFake_Publisher
 +</​code>​
 +
 +La salida debería ser algo como:
 +
 +<​code>​
 +Hello, I am the SensorFake_Publisher
 +Time 1353001026.799379:​ Sending x [0] y [5] z [10]
 +Time 1353001026.899426:​ Sending x [1] y [6] z [11]
 +Time 1353001026.999419:​ Sending x [2] y [7] z [12]
 +</​code>​
 +
 +En otro terminal, ejecutamos un //​listener//​ de ROS, que recibirá los mensajes de nuestro //​publisher//​ y los mostrará por pantalla.
 +
 +<​code>​
 +rostopic echo /​SensorFake_Topic
 +</​code>​
 +
 +
 +La salida debería ser algo como:
 +<​code>​
 +header: ​
 +  seq: 31
 +  stamp: ​
 +    secs: 1353001134
 +    nsecs: 532552707
 +  frame_id: ''​
 +timestamp: ​
 +  secs: 1353001134
 +  nsecs: 532516000
 +x: 1
 +y: 6
 +z: 11
 +---
 +header: ​
 +  seq: 32
 +  stamp: ​
 +    secs: 1353001134
 +    nsecs: 632531208
 +  frame_id: ''​
 +timestamp: ​
 +  secs: 1353001134
 +  nsecs: 632489000
 +x: 2
 +y: 7
 +z: 12
 +---
 +</​code>​
 +
 +
 +==== Compartir el paquete ====
 +
 +Si queremos compartir el paquete (por ejemplo, enviarlo por email), debemos borrar la carpeta //​${HOME}/​ros/​sensor_fake/​build//​. En el ordenador destino, copiamos el paquete (por ejemplo, en //​${HOME}/​ros//​) y ejecutamos los pasos de la Sección "​Añadiendo el paquete al workspace"​.
 +
 +
 +
 +
 +====== Stage + AMCL + RVIZ ======
 +
 +En este tutorial veremos:
 +  - Cómo simular un robot con Stage.
 +  - Cómo ejecutar el algoritmo de localización AMCL. Este algoritmo estimará la posición del robot sobre un mapa en base a la información del simulador.
 +  - Cómo visualizar todos los datos con el //rviz//.
 +
 +Para ello, necesitamos instalar:
 +  - Stack Stage: //sudo apt-get install ros-groovy-stage//​
 +  - Nodos AMCL y map_server(stack Navigation): ​ //sudo apt-get install ros-groovy-navigation//​
 +  - Nodo rviz: //sudo apt-get install ros-groovy-rviz//​
 +
 +
 +==== Archivos de configuración ====
 +
 +En primer lugar, debemos descargar ​ el archivo {{:​inv:​world.zip|}}. Podemos descomprimir este archivo en cualquier lugar a nuestro gusto (en adelante, llamaremos //​${WORLD_PATH}//​ a esta carpeta). En particular, nos van a interesar los siguientes archivos:
 +
 +  - //​${WORLD_PATH}/​citius/​plantabajacitius.yaml//:​ archivo descriptor del mapa que utilizaremos en este tutorial.
 +  - //​${WORLD_PATH}/​citius/​plantabajacitius.pgm//:​ imagen que representa dicho mapa.
 +  - //​${WORLD_PATH}/​citius/​plantabajacitius.world//:​ archivo "​world"​ del Stage (utiliza el archivo plantabajacitius.pgm).
 +
 +A continuación,​ descargamos el archivo {{:​inv:​amcl_diff_stage.launch.zip|}} y lo extraemos en la carpeta "​examples"​ del nodo AMCL. Para localizar la carpeta del nodo AMCL, hacemos:
 +
 +<​code>​roscd amcl</​code>​
 +  ​
 +Este archivo contiene los parámetros que se le pasarán al AMCL. Podemos modificar los parámetros editando el archivo.
 +
 +Finalmente, descargamos el archivo {{:​inv:​stage_amcl.rviz.zip|}} y lo extraemos en una carpeta a nuestro gusto (en adelante, //​${RVIZ_CONFIG}//​). Este archivo contiene parámetros de configuración para adaptar el //rviz// (visualizador) a las necesidades de este ejemplo.
 +
 +
 +==== Ejecución de los nodos (uno por terminal) ====
 +
 +Arrancamos el //​roscore//:​
 +
 +<​code>​roscore</​code>​
 +
 +Ejecutamos el simulador Stage con un archivo "​world"​. Por ejemplo:
 +
 +<​code>​
 +rosrun stage stageros ${WORLD_PATH}/​citius/​plantabajacitius.world
 +</​code>​
 +
 +Ejecutamos el map_server:
 +
 +<​code>​
 +rosrun map_server map_server ${WORLD_PATH}/​citius/​plantabajacitius.yaml
 +</​code>​
 +
 +Ejecutamos el AMCL con el archivo de configuración descargado:
 +
 +<​code>​
 +roslaunch amcl amcl_diff_stage.launch
 +</​code>​
 +
 +AMCL expone un servicio (global_localization) mediante el cual se puede activar el proceso de localización global del robot.
 +En otro terminal, hacemos:
 +
 +<​code>​
 +rosservice call /​global_localization
 +</​code>​
 +
 +Comprobamos con la herramienta //rxgraph// que todos los nodos están: 1) levantados, 2) comunicándose correctamente. A continuación,​ podemos visualizar el resultado de los diferentes nodos utilizando la herramienta //rviz//:
 +
 +<​code>​
 +rosrun rviz rviz ${RVIZ_CONFIG}/​stage_amcl.rviz
 +</​code>​
 +
 +Deberíamos ver algo como: {{ :​inv:​rviz_localization.png?​500 |}}:
 +
 +Ahora podemos mover el robot (pestaña teleop) por el entorno para que se localice.
 +
 +
 +====== Rosbag ======
 +
 +Rosbag es una herramienta para grabar, reproducir y modificar logs con los mensajes que recibe el nodo roscore (pose, medidas del láser, transformaciones geométricas,​ etc.). En terminología ROS, a estos archivos de log se les conoce como bags.
 +
 +==== Rosbag record ====
 +
 +==== Rosbag play ====
 +
 +==== Rosbag filter ====
 +
 +Rosbag nos permite generar nuevos archivos bag a partir de un bag ya existente. Presentamos aquí algunos ejemplos:
 +
 +Generar un bag que sólo contenga mensajes "/​RosAria/​pose":​
 +<​code>​
 +rosbag filter original.bag filtrado.bag ​ 'topic == "/​RosAria/​pose"' ​
 +</​code>​
 +
 +Generar un bag que sólo contenga mensajes "/​RosAria/​pose"​ y "/​tf":​
 +<​code>​
 +rosbag filter original.bag filtrado.bag ​ 'topic == "/​RosAria/​pose" ​ or topic =="/​tf"'​
 +</​code>​
 +
 +Generar un bag que contenga todos los mensajes excepto el "/​RosAria/​pose":​
 +<​code>​
 +rosbag filter original.bag filtrado.bag ​ 'topic != "/​RosAria/​pose"'​
 +</​code>​
 +
 +
 +==== Creación de un controlador básico ====
 +
 +
 +Descargar el siguiente paquete: {{:​inv:​basicsample.zip|}}. Compilar y ejecutar. ​
 +
 +Para probar el código con el Stage necesitamos hacer un re-mapping de los topics como si fuera el robot real:
 +
 +<​code>​
 +<​launch>​
 +  <node pkg="​stage"​ type="​stageros"​ name="​stage"​ output="​screen"​ args="​$(find stage)/​world/​citius/​plantabajacitius.world">//​RUTA AL ARCHIVO WORLD
 + <remap from="/​base_scan"​ to="/​scan"/>​
 +    <remap from="/​odom"​ to="/​RosAria/​pose"/>​
 +    <remap from="/​base_laser_link"​ to="/​laser"/>​
 +  </​node>​
 +  <arg name="​map_file"​ default="​$(find stage)/​world/​citius/​plantabajacitius.yaml"​ /> //RUTA AL MAPA
 +  <node name="​map_server"​ pkg="​map_server"​ type="​map_server"​ args="​$(arg map_file)"​ />
 +</​launch>​
 +</​code>​
  • inv/por-clasificar/ros.txt
  • Última modificación: 2013/03/27 10:55
  • (edición externa)