Práctica de la compilación del nuevo espacio de trabajo (workspace) y paquete (paquete) de ROS (ejemplo de C++)

El espacio de trabajo de ROS es un directorio que se utiliza para almacenar paquetes de trabajo de ROS.Estos paquetes de trabajo contienen varios archivos de programas de ROS, incluido el código fuente, archivos de configuración y archivos de mensajes. Entonces, la esencia del espacio de trabajo es una carpeta, que se usa para almacenar los paquetes que se presentarán a continuación y los archivos necesarios para construir estos paquetes. Se pueden crear muchos espacios de trabajo de ROS, y todos son independientes entre sí, ejecutando programas específicos en sus respectivos espacios de trabajo, lo que evita que se junten programas no relacionados, y también sigue el concepto de diseño de acoplamiento flexible. Los beneficios son obvios. Poner lo mismo funciones juntas hace que sea fácil de depurar.

1. Espacio de trabajo ROS

Nuevo espacio de trabajo (directorio)

mkdir -p ~/catkin_ws/src
cd ~/catkin_ws/src

Especifique -p para crear varios directorios que no existen, es decir, todos los directorios en esta ruta, si no existen, se crearán. Además, para crear un nuevo espacio de trabajo, generalmente lo creamos en el directorio raíz del usuario actual  ~/

Inicializar espacio de trabajo

catkin_init_workspace
#Creating symlink "/home/yahboom/catkin_ws/src/CMakeLists.txt" pointing to "/opt/ros/melodic/share/catkin/cmake/toplevel.cmake"

La esencia aquí es crear un enlace simbólico que apunte a toplevel.cmake El resultado de esto es hacer que todo el sistema sea visible.

Después de crear e inicializar el espacio de trabajo, cree algunos otros archivos del espacio de trabajo:

cd ~/catkin_ws
catkin_make

El comando catkin_make compilará todos los nodos y mantendrá todas las dependencias actualizadas. Verifiquemos qué directorios se agregan al directorio src : ls

 compilar  desarrollo src

Hay un directorio adicional de compilación y desarrollo . El directorio de compilación es donde catkin almacena bibliotecas y programas ejecutables cuando usamos C++. Si usamos Python, podemos ignorar el contenido de la compilación , y el desarrollo se enfoca principalmente en el archivo setup.bash . , la ejecución de estos archivos hace que el sistema utilice el espacio de trabajo y el código que contiene.
Para configurar con el siguiente comando, agregue (>>) setup.bash a .bashrc :

echo "source ~/catkin_ws/devel/setup.bash" >> ~/.bashrc
source ~/.bashrc

El espacio de trabajo está tan agradablemente recién construido. A continuación, para familiarizarse con un punto completo, use C++ para hacer una compilación y vea qué operaciones relacionadas deben realizarse.

2. Paquete ROS

El nombre de "paquete", el software en Ubuntu también existe en forma de paquete, pero el paquete en ROS es diferente del paquete en Ubuntu. Dado que se trata específicamente del sistema operativo del robot, el "paquete" mencionado más adelante se refiere al paquete ROS, si es un paquete de Ubuntu, indicará específicamente que es un paquete de Ubuntu.
El comando para crear el paquete:

catkin_create_pkg tony_code rospy

Este comando catkin_create_pkg ,  también apareció en el artículo anterior, la introducción de la compilación del sistema operativo del robot ROS Catkin y el uso de comandos comunes , es un comando muy común.

Esto crea con éxito un nuevo paquete llamado tony_code , que contiene archivos CMakeLists.txt y package.xml , y una carpeta src para almacenar el código fuente real. Este paquete depende del paquete rospy existente . Si su paquete también depende de otros paquetes, que se pueden enumerar en la línea de comando.

Una estructura de directorios de este espacio de trabajo es más o menos la siguiente:

|--- catkin_ws /
|------ build /
|------ devel /
| ------ src /
         |---- CMakeLists.txt
         |---- tony_code /
             |- --- CMakeLists.txt  paquete.xml   src
         |---- Otro /
             |---- CMakeLists.txt  paquete.xml   src

Habrá varios CMakeLists.txt aquí que deben distinguirse Además de uno en el directorio src del directorio raíz del espacio de trabajo, cada paquete también tiene un CMakeLists.txt

2.1, CMakeLists.txt

Como se mencionó anteriormente, además de un CMakeLists.txt en el espacio de trabajo , cada paquete también tiene uno. Cuando compilamos el paquete, modificamos el CMakeLists.txt en el paquete correspondiente.

Esto es muy simple para los lectores que están familiarizados con Make.Este archivo define cómo compilar el código fuente en el paquete de trabajo.
Revisemos el contenido del archivo CMakeLists.txt en el nuevo paquete tony_code : cat CMakeLists.txt

cmake_minimum_required(VERSIÓN 3.0.2)
proyecto(tony_code)

## Compile como C++11, compatible con ROS Kinetic y versiones posteriores
# add_compile_options(-std=c++11)

## Encuentre macros y bibliotecas de catkin ## si se usa
una lista de COMPONENTES como find_package(catkin COMPONENTES REQUERIDOS xyz) ##, busque también otros paquetes de catkin find_package(catkin COMPONENTES REQUERIDOS   rospy )



## Las dependencias del sistema se encuentran con las convenciones de CMake
# find_package(Sistema de COMPONENTES REQUERIDOS de Boost)


## Descomente esto si el paquete tiene un archivo setup.py. Esta macro garantiza
que se instalen ## módulos y scripts globales declarados en ellos
## Consulte http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html
# catkin_python_setup()

############################################
## Declarar mensajes, servicios y acciones de ROS ##
###################################### #######

## Para declarar y crear mensajes, servicios o acciones dentro de este
## paquete, siga estos pasos:
## * Deje que MSG_DEP_SET sea el conjunto de paquetes cuyos tipos de mensaje usa en
## sus mensajes/servicios/acciones (p. ej., std_msgs, actionlib_msgs, ...).
## * En el archivo package.xml:
## * agregue una etiqueta build_depend para "message_generation"
## * agregue una etiqueta build_depend y una exec_depend para cada paquete en MSG_DEP_SET
## * Si MSG_DEP_SET no está vacío, la siguiente dependencia ha sido extraído
## pero se puede declarar con certeza, no obstante:
## * agregue una etiqueta exec_depend para "message_runtime"
## * En este archivo (CMakeLists.txt):
## * agregar "message_generation" y cada paquete en MSG_DEP_SET a
## find_package(catkin COMPONENTES REQUERIDOS...)
## * agregar "message_runtime" y cada paquete en MSG_DEP_SET a
## catkin_package(CATKIN_DEPENDS...)
## * descomentar las secciones add_*_files a continuación según sea necesario
## y enumere cada archivo .msg/.srv/.action que se procesará
## * elimine el comentario de la entrada de generate_messages a continuación
## * agregue cada paquete en MSG_DEP_SET para generar_mensajes (DEPENDENCIAS ...)

## Generar mensajes en la carpeta 'msg'
# add_message_files(
# FILES
# Message1.msg
# Message2.msg
# )

## Generar servicios en la carpeta 'srv'
# add_service_files(
# FILES
# Service1.srv
# Service2.srv
# )

## Generar acciones en la carpeta 'acción'
# add_action_files(
# FILES
# Action1.action
# Action2.action
# )

## Genere mensajes y servicios agregados con las dependencias enumeradas aquí
# generar_mensajes (
# DEPENDENCIAS
# std_msgs # U otros paquetes que contengan mensajes
#)

############################################
## Declarar parámetros de reconfiguración dinámica de ROS ##
######################################## #####

## Para declarar y crear parámetros de reconfiguración dinámica dentro de este
## paquete, siga estos pasos:
## * En el archivo package.xml:
## * agregue una etiqueta build_depend y exec_depend para "dynamic_reconfigure"
## * En este archivo ( CMakeLists.txt):
## * agregue "dynamic_reconfigure" a
## find_package(catkin COMPONENTES REQUERIDOS ...)
## * elimine el comentario de la sección "generate_dynamic_reconfigure_options" a continuación
## y enumere todos los archivos .cfg que se procesarán

## Genere parámetros de
reconfiguración dinámica en la carpeta ' cfg
'

#################################
## configuración específica del catkin ##
######## ##########################
## La macro catkin_package genera archivos de configuración de cmake para su paquete
## Declara cosas que se pasarán a proyectos dependientes
# # INCLUDE_DIRS: descomente esto si su paquete contiene archivos de encabezado
## LIBRARIES: bibliotecas que crea en este proyecto que los proyectos dependientes también necesitan
## CATKIN_DEPENDS: catkin_packages los proyectos dependientes también necesitan
## DEPENDS: dependencias del sistema de este proyecto que los proyectos dependientes también necesitan
catkin_package (
# INCLUDE_DIRS incluye
# LIBRARIES tony_code
# CATKIN_DEPENDS rospy
# DEPENDE system_lib
)

###########
## Construir ##
###########

## Especifique ubicaciones adicionales de archivos de encabezado
## Las ubicaciones de su paquete deben aparecer antes que otras ubicaciones
include_directories(
# include
  ${catkin_INCLUDE_DIRS}
)

## Declarar una biblioteca C++
# add_library(${PROJECT_NAME}
# src/${PROJECT_NAME}/tony_code.cpp
# )

## Agregue cmake dependencias de destino de la biblioteca
## como ejemplo, es posible que se deba generar código antes de las bibliotecas
## ya sea a partir de la generación de mensajes o de la reconfiguración dinámica
# add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS })

## Declarar un ejecutable de C++
## Con catkin_make, todos los paquetes se construyen dentro de un único contexto de CMake
## El prefijo recomendado garantiza que los nombres de destino en los paquetes no colisionen
# add_executable(${PROJECT_NAME}_node src/tony_code_node.cpp)

## Cambiar el nombre del ejecutable de C++ sin prefijo
## El prefijo recomendado anteriormente provoca nombres de destino largos, lo siguiente cambia el nombre del
## destino a la versión más corta para facilitar el uso del usuario
## Por ejemplo, "rosrun alguien_pkg nodo" en lugar de "rosrun alguien_pkg alguien_pkg_nodo"
# set_target_properties(${PROJECT_NAME}_node PROPIEDADES OUTPUT_NAME nodo PREFIJO "")

## Agregue cmake dependencias de destino del ejecutable
## igual que para la biblioteca anterior
# add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

## Especifique bibliotecas para vincular una biblioteca o destino ejecutable contra
# target_link_libraries(${PROJECT_NAME}_node
# ${catkin_LIBRARIES}
# )

#############
## Instalar ##
#############

# todos los objetivos de instalación deben usar variables de DESTINO catkin
# Ver http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html

## Marque los scripts ejecutables (Python, etc.) para la instalación
## en contraste con setup.py, puede elegir el destino
# catkin_install_python(PROGRAMS
# scripts/my_python_script
# DESTINO ${CATKIN_PACKAGE_BIN_DESTINATION}
# )

## Marque los ejecutables para la instalación
## Consulte http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_executables.html
# install(TARGETS ${PROJECT_NAME}_node
# RUNTIME DESTINO ${CATKIN_PACKAGE_BIN_DESTINATION}
# )

## Marcar bibliotecas para instalación
## Consulte http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_libraries.html
# install(TARGETS ${PROJECT_NAME}
# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
# DESTINO DE LA BIBLIOTECA ${CATKIN_PACKAGE_LIB_DESTINATION}
# DESTINO DE EJECUCIÓN ${CATKIN_GLOBAL_BIN_DESTINATION}
# )

## Marque los archivos de encabezado cpp para la instalación
# install(DIRECTORIO include/${PROJECT_NAME}/
# DESTINO ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
# FILES_MATCHING PATTERN "*.h"
# PATTERN ".svn" EXCLUDE
# )

## Marque otros archivos para la instalación (p. ej., archivos de inicio y bolsa, etc.)
# install(FILES
# # myfile1
# # myfile2
# DESTINO ${CATKIN_PACKAGE_SHARE_DESTINATION}
# )

#############
## Pruebas ##
#############

## Agregar destino de prueba de cpp basado en gtest y vincular bibliotecas
# catkin_add_gtest(${PROJECT_NAME}-test test/test_tony_code.cpp)
# if(TARGET ${PROJECT_NAME}-test)
# target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME} )
# endif()

## Agregar carpetas para ser ejecutadas por python nosetests
# catkin_add_nosetests(test)

Del contenido del texto CMakeLists.txt , también entendemos aproximadamente que se usa para describir la información de configuración para construir uno o más proyectos de software Al editar la configuración, CMake puede generar automáticamente scripts de construcción basados ​​en la información de configuración del proyecto para compilar , pruebe e instale el elemento de software.
De acuerdo con sus propias necesidades, elimine los comentarios si necesita usarlos. Por ejemplo, en la configuración, debe agregar el directorio del archivo de encabezado y luego abrir include_directories

Al usar opencv , debe incluir el archivo de encabezado /usr/local/include/opencv/cv.h . Incluimos su directorio: include_directories(/usr/local/include) Agregar al llamar a la función:  #include "opencv/cv.h"

Otras configuraciones se explicarán más adelante cuando sean necesarias. 

2.2, paquete.xml 

Este archivo package.xml contiene la metainformación del paquete de trabajo, como el nombre del paquete, el número de versión, las dependencias, etc.
Revisemos el contenido de este archivo: cat package.xml

<?xml version="1.0"?>
<package format="2">
  <name>tony_code</name>
  <version>0.0.0</version>
  <description>The tony_code package</description>

  <!-- One maintainer tag required, multiple allowed, one person per tag -->
  <!-- Example:  -->
  <!-- <maintainer email="[email protected]">Jane Doe</maintainer> -->
  <maintainer email="[email protected]">yahboom</maintainer>


  <!-- One license tag required, multiple allowed, one license per tag -->
  <!-- Commonly used license strings: -->
  <!--   BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 -->
  <license>TODO</license>


  <!-- Url tags are optional, but multiple are allowed, one per tag -->
  <!-- Optional attribute type can be: website, bugtracker, or repository -->
  <!-- Example: -->
  <!-- <url type="website">http://wiki.ros.org/tony_code</url> -->


  <!-- Author tags are optional, multiple are allowed, one per tag -->
  <!-- Authors do not have to be maintainers, but could be -->
  <!-- Example: -->
  <!-- <author email="[email protected]">Jane Doe</author> -->


  <!-- The *depend tags are used to specify dependencies -->
  <!-- Dependencies can be catkin packages or system dependencies -->
  <!-- Examples: -->
  <!-- Use depend as a shortcut for packages that are both build and exec dependencies -->
  <!--   <depend>roscpp</depend> -->
  <!--   Note that this is equivalent to the following: -->
  <!--   <build_depend>roscpp</build_depend> -->
  <!--   <exec_depend>roscpp</exec_depend> -->
  <!-- Use build_depend for packages you need at compile time: -->
  <!--   <build_depend>message_generation</build_depend> -->
  <!-- Use build_export_depend for packages you need in order to build against this package: -->
  <!--   <build_export_depend>message_generation</build_export_depend> -->
  <!-- Use buildtool_depend for build tool packages: -->
  <!--   <buildtool_depend>catkin</buildtool_depend> -->
  <!-- Use exec_depend for packages you need at runtime: -->
  <!--   <exec_depend>message_runtime</exec_depend> -->
  <!-- Use test_depend for packages you need only for testing: -->
  <!--   <test_depend>gtest</test_depend> -->
  <!-- Use doc_depend for packages you need only for building documentation: -->
  <!--   <doc_depend>doxygen</doc_depend> -->
  <buildtool_depend>catkin</buildtool_depend>
  <build_depend>rospy</build_depend>
  <build_export_depend>rospy</build_export_depend>
  <exec_depend>rospy</exec_depend>


  <!-- The export tag contains other, unspecified, tags -->
  <export>
    <!-- Other tools can request additional information be placed here -->

  </export>
</package>

Este archivo contiene un conjunto de metadatos sobre el nuevo paquete. Introduzcamos los nodos respectivamente:

nombre : El nombre del paquete, ¡este nodo no se puede modificar! !
versión : el número de versión del paquete
descripción : una breve descripción de la funcionalidad del paquete
mantenedor : el mantenedor del paquete y la persona que corrige el error, varias personas
licencia : la licencia
url : la URL del paquete
autor : el autor de el paquete
buildtool_depend : la herramienta de compilación, en ROS, es básicamente catkin
build_depend :
exportación de dependencia : información requerida por otras herramientas que no sean catkin

3. Compilar C++

Con el conocimiento anterior, usamos C++ para escribir el nodo más simple, luego lo compilamos y nos familiarizamos con todo el proceso y los errores encontrados.

3.1, Crear un nuevo paquete mínimo

De acuerdo con la introducción anterior, cree un nuevo paquete, aquí el nombre es mínimo

cd ~/catkin_ws/src
catkin_create_pkg minimal rospy

3.2 Código C++

Después de crear el paquete, creamos un archivo C++ en el directorio src bajo el paquete mínimo

cd minimal/src
gedit minimal.cpp

El contenido de minimal.cpp es el siguiente

#include <ros/ros.h>

int main(int argc,char **argv)
{
    ros::init(argc,argv,"minimal");
    ros::NodeHandle n;
    ros::spin();
    return 0;
}

Este es el nodo ROS más simple escrito en C++, incluido un archivo de encabezado ROS.
ros::init(argc,argv,"minimal"); Inicialice el nodo y asígnele el nombre minimal, que es equivalente al espacio de nombres
ros::NodeHandle n; Cree un identificador de nodo para crear temas, servicios y acciones. En Python, no hay necesidad de crear explícitamente un identificador de nodo de esta manera, porque la interfaz Python de ROS puede implementar implícitamente
ros::spin(); ha estado esperando la programación de ROS. Si es fácil de entender, como el procesamiento de la función de devolución de llamada al suscribirse, siempre será El significado de la suscripción cíclica. Por supuesto, encontrará una función como ros::spinOnce(); en la etapa posterior , lo que significa lo mismo, pero generalmente se coloca en un bucle.

3.3 Modificar CMakeLists.txt

Luego se modifica el archivo de configuración.Todavía es necesario prestar atención aquí.Se utiliza el archivo CMakeLists.txt bajo el paquete mínimo .

cd ~/catkin_ws/src/minimal
gedit CMakeLists.txt

Modifique los siguientes tres lugares y elimine los comentarios para que sea efectivo:

find_package(catkin REQUIRED rospy)

add_executable(minimal src/minimal.cpp)

target_link_libraries(minimal ${catkin_LIBRARIES})

3.4, compilar

Después de configurar, empezamos a compilar:

cd ~/catkin_ws
catkin_make

Al compilar aquí, debe tener en cuenta que debe volver al directorio raíz del espacio de trabajo para compilar.
Aunque se han modificado tres lugares, la compilación aún informa el siguiente error. No se puede encontrar el archivo de encabezado ros/ros.h . Este es un error muy común:

Escaneo de dependencias del objetivo mínimo
[ 50 %] Construcción del objeto CXX minimal/CMakeFiles/minimal.dir/src/minimal.cpp.o
/home/yahboom/catkin_ws/src/minimal/src/minimal.cpp:1:10: error fatal : ros/ros.h: No existe tal archivo o directorio
 #include <ros/ros.h>
          ^~~~~~~~~~~
compilación terminada.
minimal/CMakeFiles/minimal.dir/build.make:62: receta para el objetivo 'minimal/CMakeFiles/minimal.dir/src/minimal.cpp.o' falló
make[2]: *** [minimal/CMakeFiles/minimal. dir/src/minimal.cpp.o] Error 1
CMakeFiles/Makefile2:431: receta para el objetivo 'minimal/CMakeFiles/minimal.dir/all' falló
make[1]: *** [minimal/CMakeFiles/minimal.dir/ all] Error 2
Makefile: 140: receta para el objetivo 'all' falló
en hacer:
Error al invocar "make -j2 -l2"

3.5, manejo de errores de compilación

Para el error de compilación anterior, también se introdujo anteriormente. Aquí hay archivos de encabezado, por lo que debe abrir include_directories

incluir_directorios(incluir ${catkin_INCLUDE_DIRS}) 

Luego vuelva a compilar, aún hay error, inicie el administrador de nodos roscore , se puede iniciar normalmente, por lo que la configuración de la variable de entorno no es un problema. La razón es que aquí se usa C++ , por lo que se necesita este paquete de dependencia roscpp , y la modificación es la siguiente:

find_package(catkin COMPONENTES REQUERIDOS rospy roscpp) 

Luego vuelve a compilar sin ningún problema. Como se muestra en la imagen:

De esta forma, el programa ejecutable mínimo compilado se coloca en ~/catkin_ws/devel/lib/minimal/minimal

Supongo que te gusta

Origin blog.csdn.net/weixin_41896770/article/details/132273124
Recomendado
Clasificación