Principiante de ROS (¡Advertencia de artículo largo!

ROS Principiante

introducción

Este artículo es una nota para los principiantes de ROS, desde conceptos básicos hasta intentar crear servidores y clientes.

Sitio web de referencia: http://wiki.ros.org/cn/ROS/Tutorials

1. Crea un espacio de trabajo de amento

mkdir -p ~/catkin_ws/src
cd ~/catkin_ws/
catkin_make(编译)
source devel/setup.bash

2. Sistema de archivos

Paquete de software: Paquetes, la
Mainifests:package.xmllista de unidades de organización de software del código ROS es una descripción del paquete de software, que define dependencias y metainformación entre paquetes de software
roscd: permite el cambio directo de directorios a un paquete de software o conjunto de paquetes, o subdirectorio
roscd log: Ingrese el directorio donde Los archivos de registro de ROS se almacenan
rosls [locationname[/subdir]]: ejecute el comando ls directamente de acuerdo con el nombre del paquete

3. Crear paquete

Especificación del paquete:

1) Debe haber un package.xmlarchivo que proporcione metainformación sobre el paquete

2) Debe haber un CMakeLists.txtarchivo

3) Debe tener su propio directorio (lo que significa que no puede haber paquetes anidados o múltiples en el mismo directorio).

cd ~/catkin_ws/src
catkin_create_pkg beginner_tutorials std_msgs rospy roscpp
(catkin_create_pkg <package_name> [depend1] [depend2] [depend3] ...)
cd ~/catkin_ws
catkin_make
source ~/catkin_ws/devel/setup.bash(将这个工作空间添加到ROS环境中,似乎只对该终端生效)
rospack查看依赖关系:(rosdep有问题 = =
rospack depends1 beginner_tutorials(查看一级依赖
rospack depends1 rospy(依赖包自己的依赖关系
rospack depends beginner_tutorials(递归的检查出所有依赖关系

4. Cree el paquete ROS

catkin_makeconstruir con

cd ~/catkin_ws/
catkin_make(得到的build目录是构建空间的默认位置,devel是开发空间的默认位置,可以存放可执行文件和库

5. Comprender los nodos ROS

Computation Graph es una red peer-to-peer compuesta por procesos ROS que pueden procesar datos de forma conjunta.
Nodos: un nodo es un archivo ejecutable que puede comunicarse con otros nodos a través de ROS (utilizando una biblioteca cliente).
Mensajes: tipos de datos ROS utilizados al suscribirse o publicar temas.
Temas: los nodos pueden publicar mensajes en temas o recibir mensajes suscribiéndose a temas.
Nodo maestro (Master): el servicio de nombres de ROS, por ejemplo, para ayudar a los nodos a descubrirse entre sí.
rosout: Equivalente en ROS stdout/stderr(salida estándar/error estándar)
roscore: nodo maestro + rosout+ servidor de parámetros
rosnode: obtener información del nodo, rosnode listmirar el nodo actual, usar rosnode info /rosoutpara ver la información de un nodo (aquí, /rosout
rosrunpuede ejecutar directamente un nodo con el nombre del paquete , como rosrun turtlesim turtlesim_node
el nombre del nodo de redistribución:rosrun turtlesim turtlesim_node __name:=my_turtle

6. Comprender los temas de ROS

Primero abre la tortuguita y sus controles de teclado:

rosrun turtlesim turtlesim_node
rosrun turtlesim turtle_teleop_key

turtlesim_nodeLos nodos turtle_teleop_keyse comunican entre sí a través de un tema de ROS: turtle_teleop_keypublique un mensaje de teclado sobre el tema turtlesimy luego suscríbase al tema para recibir el mensaje.
Use para rqt_graphver el nodo y el tema que se están ejecutando actualmente: rosrun rqt_graph rqt_graph
rostopic: Obtenga la información del tema de ROS
rostopic echo [topic]para mostrar un cierto Los datos publicados por el tema ( rostopic echoeste tema también está suscrito en este momento)
rostopic listenumera todos los mensajes del tema que se han suscrito y publicado
: para que los editores y los suscriptores se comuniquen, deben recibir y enviar mensajes del mismo tipo, que es decir, el tipo de tema está determinado por Determinado por el tipo de mensaje publicado en él

rostopic type [topic](查看话题的消息类型
rosmsg show [消息类型](查看消息的详细信息
rostopic pub [topic] [msg_type] [args](把数据发布到当前某个正在广播的话题上

Por ejemplo: rostopic pub -1 /turtle1/cmd_vel geometry_msgs/Twist -- '[2.0, 0.0, 0.0]' '[0.0, 0.0, 1.8]'
-1 significa que solo se envía un mensaje, (-r significa ciclo) seguido del nombre del tema, el tipo de mensaje y los parámetros de la sintaxis YAML Mensaje: informe la tasa de publicación de datos: muestra los datos publicados en un
rostopic hz [topic]tema
rqt_plotdeterminado en los datos del gráfico de tiempo de desplazamiento (rosrun rqt_plot rqt_plot

7. Comprender los servicios y parámetros de ROS

Servicios servicio: una forma de comunicación entre nodos. Un nodo puede enviar una solicitud y obtener una respuesta
rosservice list: Mostrar información de servicio activo
rosservice type [service]: Ver tipo de servicio:
rosservice call [service] [args]Invocar servicio
rosservice type /spawn | rossrv show: Mostrar información de servicio de desove (¿la información agregada más tarde puede mostrar información de parámetros?:
rosparamPermítanos ingresar al servidor de parámetros ROS (Servidor de parámetros) para almacenar y manipular datos (usando la sintaxis YAML)
tipos de datos: entero, flotante, booleano, diccionarios y lista: enumerar
rosparam listnombres de parámetros
rosparam set [param_name]: establecer parámetros
rosparam get [param_name]: obtener parámetro
rosparam load [file_name] [namespace]: cargar parámetro desde archivo
rosparam dump [file_name] [namespace]: volcar parámetro a archivo
rosparam delete: eliminar parámetro

8. rqt_console y roslaunch

rqt_consoleConectado al marco de registro de ROS para mostrar la información de salida del nodo.
rqt_logger_levelNos permite cambiar el nivel de detalle de la información de salida cuando el nodo se está ejecutando, incluidos Depuración, Información, Advertencia y Error.

rosrun rqt_console rqt_console
rosrun rqt_logger_level rqt_logger_level
rosrun turtlesim turtlesim_node(启动turulesim

Nivel de registro:
Fatal
Error
Warn
Info
Debug
Use roslaunch:

roscd beginner_tutorials(切换道之前构建的软件包目录下
mkdir launch
cd launch

ps El directorio donde se almacena el archivo de inicio no tiene que llamarse launch. De hecho, no tiene que estar ubicado en el directorio. El comando roslaunch buscará automáticamente el paquete pasado y detectará los archivos de inicio disponibles. Sin embargo, esta práctica estándar recomendada se considera una mejor práctica.
Cree un turtlemimic.launcharchivo de lanzamiento llamado lanzamiento y copie y pegue lo siguiente:

<launch>(标签)

  <group ns="turtlesim1">(ns:namespace)
    <node pkg="turtlesim" name="sim" type="turtlesim_node"/>
  </group>(分组1)

  <group ns="turtlesim2">
    <node pkg="turtlesim" name="sim" type="turtlesim_node"/>
  </group>(分组2)(两个分组节点名相同sim,可以同时启动两个turtlesim模拟器,避免命名冲突

  <node pkg="turtlesim" name="mimic" type="mimic">
    <remap from="input" to="turtlesim1/turtle1"/>
    <remap from="output" to="turtlesim2/turtle1"/>
  </node>(启动模仿节点,让turtlesim2模仿turtlesim1)

</launch>(使得launch文件的XML标签闭合)

Ejecute el archivo de inicio: roslaunch beginner_tutorials turtlemimic.launch
rostopic pub /turtlesim1/turtle1/cmd_vel geometry_msgs/Twist -r 1 -- '[2.0, 0.0, 0.0]' '[0.0, 0.0, -1.8]'(Emita comandos a los dos Turtlesim, y podrá ver que ambos están funcionando)
En este punto, puede rqt_graphcomprender mejor lo que hace el archivo de inicio (o ejecutar rqty seleccionar en la ventana principal Plugins > Introspection > Node)

9. Usa rosa

rosed [package_name] [filename]: edite los archivos en el paquete directamente por el nombre del paquete sin escribir el
editor de cambio de ruta completo: .bashrcagregue export EDITOR='emacs -nw'oexport EDITOR='nano -w'

10. Crea mensajes y servicios

msg(mensaje): El archivo msg es un archivo de texto que se utiliza para describir los campos del mensaje ROS. msgSe utilizan para generar código fuente para mensajes escritos en diferentes lenguajes de programación, ubicados en el directorio del paquete
srv(servicio): un srvarchivo describe un servicio. Consta de dos partes: solicitud (solicitud) y respuesta (respuesta), que están separadas por líneas ------ y almacenadas en el srvdirectorio del paquete de software.

roscd beginner_tutorials
mkdir msg
echo "int64 num" > msg/Num.msg(创建了一个只有一行的msg文件)

Abra package.xml, asegúrese de que contiene las siguientes dos líneas y no está comentado

<build_depend>message_generation</build_depend>(构建需要)
<exec_depend>message_runtime</exec_depend>(运行需要)

En el archivo CMakeLists.txt, find_packageagregue message_generationdependencias para las llamadas que ya existen: ( aplicable message_generationa msgambos srv)

find_package(catkin REQUIRED COMPONENTS
   roscpp
   rospy
   std_msgs
   message_generation
)

find_packageNOTA: A veces , el proyecto se compila incluso si no se invoca con todas las dependencias . Esto se debe a que catkin integra todos sus proyectos juntos, por lo que si el proyecto anterior llama a find_package, sus dependencias también se configuran con el mismo valor. Sin embargo, olvidarse de llamar significa que su proyecto puede colapsar fácilmente cuando se construye por separado.
Asegure las dependencias al exportar mensajes:

catkin_package(
  ...
  CATKIN_DEPENDS message_runtime ...
  ...)

Encuentra el bloque de código:

# add_message_files(

#   FILES

#   Message1.msg

#   Message2.msg

# )

Descoméntalo y cámbialo por esto:

add_message_files(
  FILES
  Num.msg
)

Descomente las siguientes líneas: (para asegurarse de que CMake sepa cuándo necesita reconfigurar el proyecto)

# generate_messages(

#   DEPENDENCIES

#   std_msgs

# )

Lo anterior ha completado la creación del mensaje, ahora use rosmsg showel comando para ver si ROS puede reconocerlo,
rosmsg show [message type]
es decir: rosmsg show beginner_tutorials/Num(el nombre del paquete se puede guardar)
crear src:

roscd beginner_tutorials
mkdir srv
roscp:将文件从一个包复制到另一个包
roscp [package_name] [file_to_copy_path] [copy_path]
roscp rospy_tutorials AddTwoInts.srv srv/AddTwoInts.srv(从rospy_tutorials包中复制一个服务)

Tenga en cuenta que find_packageagregar message_generationdependencias para llamadas en el archivo CMakeLists.txt

# add_service_files(

#   FILES

#   Service1.srv

#   Service2.srv

# )

convertirse en:

add_service_files(
  FILES
  AddTwoInts.srv
)

Vea si se puede reconocer: rossrv show <service type>
es decir: rossrv show beginner_tutorials/AddTwoInts(Tampoco puede especificar el nombre del paquete)
Vuelva a compilar el paquete:

roscd beginner_tutorials
cd ../..
catkin_make
cd -

NOTA: Cualquier archivo .msg en el directorio msg generará código para todos los idiomas admitidos.

Los archivos de encabezado para los mensajes de C++ se generarán en ~/catkin_ws/devel/include/beginner_tutorials/.

El script de Python se creará en ~/catkin_ws/devel/lib/python2.7/dist-packages/beginner_tutorials/msg.

Los archivos Lisp aparecen en ~/catkin_ws/devel/share/common-lisp/ros/beginner_tutorials/msg/.

De manera similar, cualquier archivo .srv en el directorio srv generará código para los idiomas admitidos. Para C++, el archivo de encabezado se generará en el mismo directorio que el archivo de encabezado del mensaje. Para Python y Lisp, estará en el directorio srv al lado del directorio msg.

11. Escriba editores y suscriptores simples

C++

nodo hablador (editor): mensajes de difusión continua

roscd beginner_tutorials
mkdir src

Cree un archivo talker.cpp con el siguiente texto:

#include "ros/ros.h"(一个头文件,包含了ROS系统中常见的公共部分所需的头文件)
#include "std_msgs/String.h"(引用了std_msgs中的std_msg/String消息)
#include <sstream>

int main(int argc, char **argv){

  ros::init(argc, argv, "talker");(初始化ROS,使得ROS可以通过命令行进行名称重映射,给节点指定名称)(名称必须是基本名称,不能有/)

  ros::NodeHandle n;(为这个进程的节点创建句柄。创建的第一个NodeHandle实际上将执行节点的初始化,而最后一个被销毁的NodeHandle将清除节点所使用的任何资源。)

  ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);(告诉主节点我们要在chatter的话题上发布一个类型是std_msgs/String的消息,主节点会告诉订阅了chatter1的节点,第二个参数表示缓存队列大小为1000,越界则会丢弃旧消息)
(NodeHandle::advertise()返回一个ros::Publisher对象,它有2个目的:其一,它包含一个publish()方法,可以将消息发布到创建它的话题上;其二,当超出范围时,它将自动取消这一宣告操作)

  ros::Rate loop_rate(10);(指定循环的频率,记录上次调用sleep到现在有多长时间,并且休眠正确的时间)

  int count = 0;
  while (ros::ok()){
(ros:ok返回false的情况:
	收到SIGINT信号(Ctrl+C)
	被另一个同名的节点踢出了网络
	ros::shutdown()被程序的另一部分调用
	所有的ros::NodeHandles都已被销毁 )
    std_msgs::String msg;

    std::stringstream ss;
    ss << "hello world " << count;
    msg.data = ss.str();

    ROS_INFO("%s", msg.data.c_str());
    chatter_pub.publish(msg);(把这个信息广播给了任何已连接的节点

    ros::spinOnce();(回调)

    loop_rate.sleep();(使用ros::Rate在剩下的时间内睡眠,以让我们达到10Hz的发布速率??)
    ++count;
  }

  return 0;
}

Nodo de suscriptor:
cree un archivo listener.cpp y escriba el siguiente contenido

#include "ros/ros.h"
#include "std_msgs/String.h"

void chatterCallback(const std_msgs::String::ConstPtr& msg){
  ROS_INFO("I heard: [%s]", msg->data.c_str());
}(回调函数,智能指针传递消息)

int main(int argc, char **argv){

  ros::init(argc, argv, "listener");

  ros::NodeHandle n;

  ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);(通过主节点订阅话题,第二个参数是队列大小,该对象被析构时自动取消订阅)

  ros::spin();(启动了一个自循环,它会尽可能快地调用消息回调函数)

  return 0;
}

Agregue estas líneas en la parte inferior del archivo CMakeLists.txt:

add_executable(talker src/talker.cpp)
target_link_libraries(talker ${catkin_LIBRARIES})
add_dependencies(talker beginner_tutorials_generate_messages_cpp)(为可执行目标添加依赖项到消息生成目标,确保在使用此包之前生成了该包的消息头)

add_executable(listener src/listener.cpp)
target_link_libraries(listener ${catkin_LIBRARIES})
add_dependencies(listener beginner_tutorials_generate_messages_cpp)

Al final se ve así:

cmake_minimum_required(VERSION 2.8.3)
project(beginner_tutorials)

## Find catkin and any catkin packages

find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs genmsg)

## Declare ROS messages and services

add_message_files(FILES Num.msg)
add_service_files(FILES AddTwoInts.srv)

## Generate added messages and services

generate_messages(DEPENDENCIES std_msgs)

## Declare a catkin package

catkin_package()

## Build talker and listener

include_directories(include ${catkin_INCLUDE_DIRS})

add_executable(talker src/talker.cpp)
target_link_libraries(talker ${catkin_LIBRARIES})
add_dependencies(talker beginner_tutorials_generate_messages_cpp)

add_executable(listener src/listener.cpp)
target_link_libraries(listener ${catkin_LIBRARIES})
add_dependencies(listener beginner_tutorials_generate_messages_cpp)

Compilar:

cd ~/catkin_ws
catkin_make

12. Editor de prueba y suscriptor

Ejecute el editor:

roscore
cd ~/catkin_ws
source ./devel/setup.bash(请确保调用catkin_make后已经source过工作空间的setup.*sh文件)
rosrun beginner_tutorials talker      # (C++)

Ejecute el suscriptor:

 rosrun beginner_tutorials listener     # (C++)

13. Escribe servicios y clientes simples

Escritura de un nodo de servicio:
cree un nodo de servicio simple add_two_ints_server que recibirá dos enteros y devolverá su suma.

roscd beginner_tutorials

Cree el archivo src/add_two_ints_server.cpp en el paquete begin_tutorials y pegue lo siguiente en él:

#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;
}(该函数提供了AddTwoInts服务,它接受srv文件中定义的请求(request)和响应(response)类型,并返回一个布尔值)

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;
}

Escriba un nodo de cliente:
cree un archivo src/add_two_ints_client.cpp en el paquete begin_tutorials y pegue lo siguiente en él:

#include "ros/ros.h"
#include "beginner_tutorials/AddTwoInts.h"
#include <cstdlib>

int main(int argc, char **argv){
  ros::init(argc, argv, "add_two_ints_client");
  if (argc != 3){
    ROS_INFO("usage: add_two_ints_client X Y");
    return 1;
  }

  ros::NodeHandle n;

  ros::ServiceClient client = n.serviceClient<beginner_tutorials::AddTwoInts>("add_two_ints");(为add_two_ints服务创建一个客户端。ros::ServiceClient对象的作用是在稍后调用服务)

  beginner_tutorials::AddTwoInts srv;(实例化一个服务类)

  srv.request.a = atoll(argv[1]);
  srv.request.b = atoll(argv[2]);(为两个成员赋值)

  if (client.call(srv)){
    ROS_INFO("Sum: %ld", (long int)srv.response.sum);
  }
  else{
    ROS_ERROR("Failed to call service add_two_ints");
    return 1;
  }

  return 0;
}

Cambiar CMakeLists.txt (agregar código):

add_executable(add_two_ints_server src/add_two_ints_server.cpp)
target_link_libraries(add_two_ints_server ${catkin_LIBRARIES})
add_dependencies(add_two_ints_server beginner_tutorials_gencpp)

add_executable(add_two_ints_client src/add_two_ints_client.cpp)
target_link_libraries(add_two_ints_client ${catkin_LIBRARIES})
add_dependencies(add_two_ints_client beginner_tutorials_gencpp)

Compilar:

cd ~/catkin_ws
catkin_make

14. Examinar servicios y clientes simples

Ejecute el servicio:

rosrun beginner_tutorials add_two_ints_server

Ejecute el cliente:

rosrun beginner_tutorials add_two_ints_client 1 3

15. Datos de grabación y reproducción

Grabe los datos en el sistema ROS en ejecución en un archivo bag y luego reproduzca el proceso de operación similar reproduciendo los datos
Grabación de datos:

roscore
rosrun turtlesim turtlesim_node
rosrun turtlesim turtle_teleop_key(又打开了小乌龟)
mkdir ~/bagfiles
cd ~/bagfiles
rosbag record -a(-a表明所有发布的话题都积累在一个bag文件中)

Solo controla a la tortuguita para que se mueva por un rato
Reproducción:

rosbag info <your bagfile>(查看bag中的记录,bag名字似乎和时间有关)
rosbag play <your bagfile>(先结束key的进程)
rosbag play -r 2 <your bagfile>(-r可以改变消息发布的频率)(-s可以指定开始时间,使不从头开始)

Un subconjunto de datos registrados:

rosbag record命令支持只录制特定的话题到bag文件中,这样就可以只录制用户感兴趣的话题
rosbag record -O subset /turtle1/cmd_vel /turtle1/pose
(-O参数告诉rosbag record将数据记录到名为subset.bag的文件中,而后面的topic参数告诉rosbag record只能订阅这两个指定的话题)

ps no se puede imitar perfectamente, la precisión no es suficiente

16. Lee el mensaje del archivo bag

Nota: hay un tiempo delante del comando, por lo que puede mostrar el tiempo empleado en ejecutar cada comando al mismo tiempo.
Reproduzca el mensaje inmediatamente y vea el resultado en múltiples terminales:

time rosbag info demo.bag  (手动检查所有已发布的话题,以及向每个话题发布了多少消息)
rostopic echo /obs1/gps/fix | tee topic1.yaml(订阅/obs1/gps/fix话题并复读该话题上发布的所有内容,同时用tee命令转储到一个yaml格式的文件中以便之后查看)

Suscríbase a otro tema: rostopic echo /diagnostics_agg | tee topic2.yaml
time rosbag play --immediate demo.bag --topics /topic1 /topic2 /topic3 /topicN(reproducción, --inmediato lo más rápido posible)
, es decir: time rosbag play --immediate demo.bag --topics /obs1/gps/fix /diagnostics_agg
puede usar ros_readbagfilescripts para extraer temas de interés

17. Introducción a roswtf

Comprobación de la instalación:

roswtf可以检查系统并尝试发现问题(首先确保ros没有运行)
roscd rosmaster
roswtf

Revisa en linea:

roscd
roswtf

error:

roscd
ROS_PACKAGE_PATH=bad:$ROS_PACKAGE_PATH roswtf

Finalmente: configure el entorno ROS en vscode:

Agregue archivos en el espacio de trabajo (en desarrollo): catkin_make -DCMAKE_EXPORT_COMPILE_COMMANDS=Yes
cambie c_cpp_propertries.json a:

{
    
    
  "configurations": [
    {
    
    
      "browse": {
    
    
        "databaseFilename": "",
        "limitSymbolsToIncludedHeaders": true
      },
      "includePath": [
        "/home/nova/catkin_ws/devel/include/**",
        "/opt/ros/kinetic/include/**",
        "/home/nova/catkin_ws/src/beginner_tutorials/include/**",
        "/home/nova/catkin_ws/src/try0/include/**",
        "/usr/include/**"
      ],
      "name": "ROS",
      "intelliSenseMode": "gcc-x64",
      "compilerPath": "/usr/bin/gcc",
      "cStandard": "c11",
      "cppStandard": "c++17",
      "compileCommands": "${workspaceFolder}/build/compile_commands.json"
    }
  ],
  "version": 4

}

Puede encontrar archivos de encabezado como ros.h!

Supongo que te gusta

Origin blog.csdn.net/m0_51653236/article/details/119042894
Recomendado
Clasificación