no way to compare when less than two revisions

Diferenzas

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


inv:por-clasificar:ros [2013/03/27 10:55] (actual) – creado - edición externa 127.0.0.1
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>