Gazebo: Primeros pasos para generar movimiento a nuestro brazo robótico
En posts anteriores vimos cómo preparar nuestro entorno de trabajo y como crear nuestro robot básico.
En este post veremos cómo construir nuestro primer código de programación, como enlazarlo con nuestro robot y como ejecutarlo en nuestro entorno de simulación.
Nuestro código
Y como siempre hacemos cuando programamos por primera vez en un entorno nuevo, haremos un “Hola Mundo”.
En este caso utilizaremos como lenguaje de programación C++, por lo que deberíamos tener nociones básicas sobre este lenguaje, aunque en el vídeo intentaré explicar aquellos conceptos básicos.
Enlazando las librerías
Para que nuestro código se compile y ejecute de forma correcta, es necesario definir las librerías externas necesarias para nuestro código. Estas librerías se definen en 2 ficheros:
Package.xml
En este fichero definimos tanto las librerías de compilación, como las librerías de ejecución. Para ellos deberemos añadir las siguientes líneas.
<build_dependen>roscpp</build_depend> <build_dependen>gazebo_ros</build_depend> <build_dependen>std_msgs</build_depend> <run_dependen>roscpp</run_depend> <run_dependen>gazebo_ros</run_depend> <run_dependen>std_msgs</run_depend>
Además de lo anterior, es necesario indicar la librería que exportaremos al compilar nuestro código. Para ello tenemos que añadir dentro de “export” la siguiente instrucción:
<gazebo_ros plugin_path=”${prefix}/lib” gazebo_media_path=”${prefix}”/>
CMakeLists.txt
En este fichero indicaremos los parámetros de compilación:
cmake_minimum_required(VERSION 2.8.3) project(miRobot) find_package( catkin REQUIRED COMPONENTS roscpp gazebo_ros gazebo_plugins std_msgs ) find_package(gazebo REQUIRED) catkin_package( DEPENDS roscpp gazebo_ros gazebp_plugins ) link_directories(${GAZEBO_LIBRARY_DIRS}) include_directories(include) include_directories( ${Boost_INCLUDE_DIR} ${catkin_INCLUDE_DIRS} ${GAZEBO_INCLUDE_DIRS} ) add_library(${PROJECT_NAME} codigo/miRobot.cpp) target_link_libraries( ${PROJECT_NAME} ${catkin_LIBRARIES} ${GAZEBO_LIBRARIES} ) add_definitions(-std=c++11)
Código
miRobot.h
#ifndef MIROBOT #define MIROBOT #endif
miRobot.cpp
#include “miRobot.h” #include <gazebo/gazebo.hh> namespace gazebo{ class MiRobot: public ModelPlugin{ virtual void Load (physics::ModelPtr _model, sdf::ElementPtr _sdf){ gzbdg<<”Hola Mundo\r\n”; } } GZ_REGISTER_MOEL_PLUGIN(MiRobot) }
Compilamos nuestro código
Para compilar el código podemos ejecutar el comando
catkin_make –force-cmake
Ojo, deberemos indicar al sistema las rutas de nuestras librerías y aplicaciones de compliación, para ello deberemos ejecutar en nuestro terminal y dentro del espacio de trabajo de catkin:
source /devel/setup.sh
Hola muy buenas tardes, seguí todas la instrucciones que se han recomendado. Sin embargo y al parecer el formato de mi paquete xml que construi es formato 2, por lo que tuve que quitar algunas cosas del package.xml y del CMackeLists.txt para compilar de nuevo el programa de mirobot (así lo he llamado). Pero ademas de todo cuando llego a la parte del escribir el archivo .cpp, no se me reconoce el #include . Se me enviá un mensaje de que el archivo no existe en el directorio. Esto tiene que ver con lo mismo de mi formato de xml? o con que los archivo que cree solo están visualizados con el ditor de C++. …En si quisiera saber como puedo solucionar esta parte…
Hola,
hay varias cuestiones a revisar para corregir el problema, y como no comentas cual es el .h que estás incluyendo tenemos que hacernos la siguiente pregunta. ¿Es uno de tu propia creación o de una librería externa o genérica como el stdio.h?.
En este respecto has de tener en cuenta que las comillas o los “<>” (yo los llamo ángulos, o el menor-mayor) hacen que el comportamiento del #include cambie. En concreto, para los ficheros del propio proyecto se encierran entre comillas y para los del sistema en ángulos.
Otro punto a revisar es si en el fichero CMackeLists.txt has indicado las carpetas del proyecto donde se localiza el código del proyecto. Te animo a que revises mis vídeos de desarrollo de DLL en el que explico un poco como funciona esto del CMake. https://www.youtube.com/watch?v=Cbm_5RH7JQ0
Además de esto, es posible que te falte indicar las rutas donde se localizan otros elementos externos como la librería de ROS. Mi recomendación es que te descargues el proyecto que estoy desarrollando e intentes compilarlo y ejecutarlo para ver si funciona todo correcto y si es así seguiríamos revisando tu código para buscar el error. En mi último vídeo en el que comento como funciona gazebo en una máquina virtual, también descargo mi código y lo ejecuto. https://www.youtube.com/watch?v=WH9nMhaNpOU
Ya me contaras.
source /devel/setup.sh
bash: /devel/setup.sh: No existe el archivo o el directorio
Esto por que sucede?
La verdad no hetrabajado mucho con Linux, por eso es que no se que pasa con estos archivos…
Hola,
¿Tienes el directorio? Fíjate que estas poniendo un / delante de devel, lo que le indica al sistema que se vaya a la raíz y que de ahí busque la carpeta devel y dentro el fichero setup.sh.
Entiendo que esto es incorrecto ya que esa carpeta devel estará dentro de la carpeta que has montado con el espacio de trabajo de catkin. Recuerda que los pasos son:
Tines toda esta información en el post de inicialización http://programacionextrema.es/2016/10/09/simulacion-robots-gazebo-construccion-del-robot/
Ahora si te fijas en esa carpeta, verás que tienes una carpeta devel y dentro el setup.bash, por tanto, la sentencia a ejecutar sería “source devel/setup.sh”. Obviamente has de estar dentro de la carpeta del proyecto.
Coméntame si te ha funcionado.
Hola buena noches Ray.
Pasa que no me copiado los ficheros de github, estoy siguiendo su tutorial
https://www.youtube.com/watch?v=3rYI9rNPOgU&t=326s&list=PLbn89UgVgwTPYfNjrzbUuRAQO-ha66Uat&index=1
Pero pasa que cuando mi package.xml me lo da en formato 2
mirobot
0.0.0
Primer prueba de Robot
<!– Jane Doe –>
marya
GPL
<!– http://wiki.ros.org/mirobot –>
<!– Jane Doe –>
mary
ENTOCES HE PUESTO PARA LAS DEPENDENCIAS LO SIGUIENTE DENTRO DEL manifiesto.xml LO SIGUIENTE:
roscpp
gazebo_ros
std_msgs
roscpp
gazebo_ros
std_msgs
PERO al ejecutar me muestra lo siguiente:
……
CMake Error at /opt/ros/kinetic/share/catkin/cmake/catkin_package.cmake:196 (message):
catkin_package() the catkin package ‘gazebo_plugins’ has been
find_package()-ed but is not listed as a build dependency in the
package.xml
Call Stack (most recent call first):
/opt/ros/kinetic/share/catkin/cmake/catkin_package.cmake:102 (_catkin_package)
mirobot/CMakeLists.txt:109 (catkin_package)
— Configuring incomplete, errors occurred!
See also “/home/marya/robot/build/CMakeFiles/CMakeOutput.log”.
See also “/home/marya/robot/build/CMakeFiles/CMakeError.log”.
Invoking “cmake” failed
marya@marya:~/robot$
ENTONCES HE LISTADO EN EL MANIFIESTO
gazebo_plugins
gazebo_plugins
VUELVO A JECUTAR
pero me arroja lo siguiente:
####
#### Running command: “make -j8 -l8” in “/home/marya/robot/build”
####
[ 50%] Building CXX object mirobot/CMakeFiles/mirobot.dir/codigo/mirobot.cpp.o
/home/marya/robot/src/mirobot/codigo/mirobot.cpp:2:28: fatal error: gazebo/gazebo.hh: No existe el archivo o el directorio
compilation terminated.
mirobot/CMakeFiles/mirobot.dir/build.make:62: fallo en las instrucciones para el objetivo ‘mirobot/CMakeFiles/mirobot.dir/codigo/mirobot.cpp.o’
make[2]: *** [mirobot/CMakeFiles/mirobot.dir/codigo/mirobot.cpp.o] Error 1
CMakeFiles/Makefile2:411: fallo en las instrucciones para el objetivo ‘mirobot/CMakeFiles/mirobot.dir/all’
make[1]: *** [mirobot/CMakeFiles/mirobot.dir/all] Error 2
Makefile:138: fallo en las instrucciones para el objetivo ‘all’
make: *** [all] Error 2
Invoking “make -j8 -l8” failed
marya@marya:~/robot$
EN RESUMEN EL ERROR ES : gazebo/gazebo.hh: No existe el archivo o el directorio
EL CÓDIGO QUE ESTOY UTILIZANDO ES EL SIGUIENTE:
EL CÓDIGO mirobot.h
#ifdef MIROBOT
#define MIROBOT
#endif
EL CÓDIGO DE mirobot.cpp
#include “mirobot.h”
#include
namespace gazebo{
class mirobot: public ModelPlugin{
};
}
No he cambiado nada
Mi CMakeLists.txt es este:
cmake_minimum_required(VERSION 2.8.3)
project(mirobot)
find_package(catkin REQUIRED COMPONENTS
roscpp
gazebo_ros
gazebo_plugins
std_msgs)
find_package(gazebo REQUIRED)
catkin_package(
DEPENDS
roscpp
gazebo_ros
gazebo_plugins
)
link_directories(${GAZEBO_LIBRARY_DIRS})
include_directories(include)
include_directories(
include
${Boots_INCLUDE_DIR}
${catkin_INCLUDE_DIR}
${GAZEBO_INCLUDE_DIR}
)
add_library(${PROJECT_NAME} codigo/mirobot.cpp)
target_link_libraries(
${PROJECT_NAME}
${catkin_LIBRARIES}
${GAZEBO_LIBRARIES}
)
add_definitions(-std=c++11)
ME gustaria poder terminar el tutorial. Solo que no sé en que estoy fallando
dado que estoy seguiendo el tutorial. Pero mi prueba truena cuando intento incluir la libreria #include
Que me puede sugiere hacer para poder continuar con la programcion …
Que pase una excelente noche Ray
Otra de las cosas es que he incluido en el archivo mirobot.world un robot pionero y no el robot del proyecto miRobot que se hace el tutorial. Supuse que esto era posible dadas la licencia GPL.
ME gustaria poder terminar el tutorial. Solo que no sé en que estoy fallando
dado que estoy seguiendo el tutorial. Pero mi prueba truena cuando intento incluir la libreria
#include para que reconozca el ModelPlugin
Hola muy buenos días Ray. He mirado un poco en sus archivos de github y al parecer ha sido un error que tenia en mi CMakeLists.txt. Le agradezco que me haya compartido su información. Continuare con el tutorial. Estaba un poco con la cabeza hecha marañas. Pero ya se ha solucionado el error. De cualquier forma me da gusto conocer su trabajo, y quiero felicitarlo ello. Es usted muy amable por dedicarme su tutorial: Gazebo en Virtualbox: Comprobando que funciona correctamente.
Es un placer. 😉
Hola Ray, muy buenas noches. La verdad es que me cuesta aun programar en c++. Soy muy novata en esto de la programación y entiendo que lo suyo es la programación extrema. Pero estoy intentando contextualizarme en lo de los robot y como es que se pueden simular.
Por ejemplo intente desde la carpeta de código crear un archivo demo.cpp y demo .h, para probar el codigo. El codigo es el siguiente:
ARCHIVO: demo.h
#ifndef DEMO
#define DEMO
#endif
COMIENZA EL CÓDIGO EN C++
demo.cpp:
#include “mirobot.h”
#include “listner.h”// esto es para ver mirobot
#include
#include “ros/ros.h”
#include “std_msgs/Int32.h”
#include
using namespace std;
int main(int argc, char **argv)
{
ros::init(argc, argv,”demo_topic_publisher”);
ros::NodeHandle node_obj;
ros::Publisher number_publisher =
node_obj.advertise(“/numbers”,10);
ros::Rate loop_rate(10);
int number_count = 0;
while (ros::ok())
{
std_msgs::Int32 msg;
msg.data = number_count;
ROS_INFO(“%d”,msg.data);
number_publisher.publish(msg);
ros::spinOnce();
loop_rate.sleep();
++number_count;
}
return 0;
}
En el CMackeLists.txt he incluido el archivo demo. cpp. Pero no tengo idea de como agregarlo a mybot.cpp para poder ver la salida. Me interesa esto por que quiero intentar programar un el robot Pioneer 2xd para crearle un movimiento.
La otra es que desde que empece con los tutoriales de ros es que no comprendo como lograr cargar archivos como el siguiente:
#include “ros/ros.h”
#include “beginner_tutorials/AddTwoInts.h”
bool add(beginner_tutorials::AddTwoInts::Request &req,
beginner_tutorials::AddTwoInts::Response &res)
{
res.sum = req.a + req.b;
ROS_INFO(“request: x=%ld, y=%ld”, (long int)req.a, (long int)req.b);
ROS_INFO(“sending back response: [%ld]”, (long int)res.sum);
return true;
}
int main(int argc, char **argv)
{
ros::init(argc, argv, “add_two_ints_server”);
ros::NodeHandle n;
ros::ServiceServer service = n.advertiseService(“add_two_ints”, add);
ROS_INFO(“Ready to add two ints.”);
ros::spin();
return 0;
}
me podría gustaría que pudiese instruirme al respecto.
Que tenga una excelente noche. Es pero que me pueda ayudar.
Hola,
Antes de nada, el nombre de “Programación extrema” no se debe a que la programación será extrema en el sentido de compleja, sino más bien a la metodología de desarrollo que suelo utilizar https://es.wikipedia.org/wiki/Programaci%C3%B3n_extrema. Obviamente esto no quiere decir que todas las cosas que trate en el canal y el blog sean sencillas, pero siempre intentaré simplificarlas para que nadie se pierda. LO INTENTARÉ 😉
En tu caso concreto, y para la primera duda, si lo que pretendes es arrancar el Gazebo y que ejecute tu código, no vas bien. Date cuenta que el Gazebo ejecuta su propio main, y lo que tú has de hacer es crear una clase que derive de otra que puedas utilizar dentro del SDF de definición del robot. En mi ejemplo yo creo una clase derivada de la clase controlador, y luego en el SDF le digo que la utilice.
Si por el contrario quieres hacer una aplicación propia que se lance aparte del Gazebo y que interactúe con este, tienes un ejemplo en mi vídeo de ejecución de ROS desde una aplicación externa. https://www.youtube.com/watch?v=805DBcv1bEA. Es un vídeo de 25 minutos en el que explico una aplicación C++ para lanzarla junto con Gazebo. Eso sí, hay que tener el listner en Gazebo para poder comunicarte con él.
La segunda también se resuelve con el video anterior. Échale un ojo y si aun así tienes dudas, dime un ejemplo concreto que quieras probar y te preparo un ejemplo para intentar resolverte las dudas.
Un saludo.
Hola,
estos días he preparado unos vídeos que intentan explicar un poco como funciona esto de ROS. Te invito a que les eches un vistazo y comentes si te han servido de utilidad.
https://www.youtube.com/watch?v=oGFXph0W87c