ROS Beginner (Aviso de artigo longo!

ROS Iniciante

introdução

Este artigo é uma nota para iniciantes do ROS, desde os conceitos básicos até a tentativa de criar servidores e clientes.

Site de referência: http://wiki.ros.org/cn/ROS/Tutorials

1. Crie um espaço de trabalho amentilho

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

2. Sistema de arquivos

Pacote de software: Pacotes, a
Mainifests:package.xmllista de unidades de organização de software do código ROS é uma descrição do pacote de software, definindo dependências e metainformações entre pacotes de software
roscd: permitindo a troca direta de diretórios para um pacote de software ou conjunto de pacotes, ou subdiretório
roscd log: Digite o diretório onde Os arquivos de log do ROS são armazenados
rosls [locationname[/subdir]]: Execute o comando ls diretamente de acordo com o nome do pacote

3. Criar pacote

Especificação do pacote:

1) Deve haver um package.xmlarquivo que forneça metainformações sobre o pacote

2) Deve haver um CMakeLists.txtarquivo

3) Deve ter seu próprio diretório (o que significa que não pode haver pacotes aninhados ou múltiplos no mesmo diretório?

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. Construir o pacote ROS

catkin_makeconstruir com

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

5. Entendendo os nós ROS

Computation Graph é uma rede peer-to-peer composta por processos ROS que podem processar dados em conjunto.
Nós: Um nó é um arquivo executável que pode se comunicar com outros nós através do ROS (usando uma biblioteca cliente).
Mensagens: tipos de dados ROS usados ​​ao assinar ou publicar tópicos.
Tópicos: os nós podem publicar mensagens em tópicos ou receber mensagens assinando tópicos.
Nó mestre (Master): serviço de nomeação do ROS, por exemplo, para ajudar os nós a se descobrirem.
rosout: Equivalente em ROS stdout/stderr(saída padrão/erro padrão)
roscore: nó mestre + rosout+ servidor de parâmetros
rosnode: obtém informações do nó, rosnode listexamina o nó atual, usa rosnode info /rosoutpara visualizar as informações de um nó (aqui, /rosout
rosrunvocê pode executar diretamente um nó com o nome do pacote , como rosrun turtlesim turtlesim_node
redistribuição Nome do nó:rosrun turtlesim turtlesim_node __name:=my_turtle

6. Entenda os tópicos do ROS

Primeiro abra a pequena tartaruga e seus controles de teclado:

rosrun turtlesim turtlesim_node
rosrun turtlesim turtle_teleop_key

turtlesim_nodeOs nós turtle_teleop_keyse comunicam entre si por meio de um tópico do ROS: turtle_teleop_keypublique uma mensagem de pressionamento de teclado no tópico turtlesime, em seguida, assine o tópico para receber a mensagem.
Use para rqt_graphvisualizar o nó e o tópico em execução no momento: rosrun rqt_graph rqt_graph
rostopic: Obtenha as informações do tópico do ROS
rostopic echo [topic]para exibir um determinado Os dados publicados pelo tópico ( rostopic echoeste tópico também está inscrito neste momento)
rostopic listlista todas as mensagens do tópico que foram assinadas e publicadas
: para que os editores e assinantes se comuniquem, eles devem receber e enviar mensagens do mesmo tipo, que ou seja, o tipo de tópico é determinado por Determinado pelo tipo de mensagem publicada nele

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

Por exemplo: rostopic pub -1 /turtle1/cmd_vel geometry_msgs/Twist -- '[2.0, 0.0, 0.0]' '[0.0, 0.0, 1.8]'
-1 significa que apenas uma mensagem é enviada, (-r significa ciclo) seguido do nome do tópico, tipo de mensagem e parâmetros da sintaxe YAML Mensagem: Relata a taxa de publicação de dados: Exibe os dados publicados em um
rostopic hz [topic]determinado
rqt_plottópico nos dados do gráfico de tempo de rolagem (rosrun rqt_plot rqt_plot

7. Entenda os serviços e parâmetros do ROS

Serviços serviço: uma forma de comunicação entre nós. Um nó pode enviar uma solicitação e obter uma resposta
rosservice list: Exibir informações de serviço ativo
rosservice type [service]: Exibir tipo de serviço : Invocar
rosservice call [service] [args]serviço
rosservice type /spawn | rossrv show: Exibir informações de serviço de desova (as informações adicionadas posteriormente podem exibir informações de parâmetro?:
rosparamVamos no servidor de parâmetro ROS (Servidor de parâmetro) para armazenar e manipular dados (usando a sintaxe YAML)
tipos de dados: integer, float, boolean, dicionários e lista: listar
rosparam listnomes de parâmetros
rosparam set [param_name]: definir parâmetros
rosparam get [param_name]: obter parâmetro
rosparam load [file_name] [namespace]: carregar parâmetro do arquivo
rosparam dump [file_name] [namespace]: despejar parâmetro para arquivo
rosparam delete: excluir parâmetro

8. rqt_console e roslaunch

rqt_consoleConectado à estrutura de log do ROS para exibir as informações de saída do nó
rqt_logger_levelPermite alterar o nível de detalhamento das informações de saída quando o nó está em execução, incluindo Debug, Info, Warn e Error

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

Nível de registro: Erro
fatal Avisar informações Depurar Uso :




roslaunch

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

ps O diretório onde o arquivo de inicialização está armazenado não precisa ser chamado de launch. Na verdade, ele não precisa ser colocado no diretório. O comando roslaunch irá procurar automaticamente pelo pacote aprovado e detectar os arquivos de inicialização disponíveis. No entanto, esta prática padrão recomendada é considerada uma prática recomendada
Crie um turtlemimic.launcharquivo de inicialização chamado launch e copie e cole o seguinte:

<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标签闭合)

Execute o arquivo de inicialização: 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 para os dois turtlesim e você verá que ambos estão rodando)
Neste ponto, você pode rqt_graphentender melhor o que o arquivo de inicialização faz (ou execute rqte selecione na janela principal Plugins > Introspection > Node)

9. Use rosa

rosed [package_name] [filename]: edite os arquivos no pacote diretamente pelo nome do pacote sem digitar o
editor de alteração de caminho completo: .bashrcadicione export EDITOR='emacs -nw'ouexport EDITOR='nano -w'

10. Crie mensagens e serviços

msg(mensagem): O arquivo msg é um arquivo de texto usado para descrever os campos da mensagem do ROS. msgEles são usados ​​para gerar código-fonte para mensagens escritas em diferentes linguagens de programação, colocadas no diretório do pacote
srv(serviço): um srvarquivo descreve um serviço. Consiste em duas partes: request (request) e response (response), que são separadas por ------ linhas e armazenadas no srvdiretório do pacote de software.

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

Abra package.xml, verifique se ele contém as duas linhas a seguir e não está comentado

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

No arquivo CMakeLists.txt, find_packageadicione message_generationdependências para as chamadas já existentes: ( aplicável message_generationa msgambos srv)

find_package(catkin REQUIRED COMPONENTS
   roscpp
   rospy
   std_msgs
   message_generation
)

find_packageNOTA: Às vezes , o projeto é compilado mesmo que não seja invocado com todas as dependências . Isso ocorre porque o catkin integra todos os seus projetos, portanto, se o projeto anterior chamar find_package, suas dependências também serão configuradas com o mesmo valor. No entanto, esquecer de chamar significa que seu projeto pode travar facilmente quando construído separadamente.
Garanta dependências ao exportar mensagens:

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

Encontre o bloco de código:

# add_message_files(

#   FILES

#   Message1.msg

#   Message2.msg

# )

Descomente e altere para isto:

add_message_files(
  FILES
  Num.msg
)

Descomente as seguintes linhas: (para garantir que o CMake saiba quando precisa reconfigurar o projeto)

# generate_messages(

#   DEPENDENCIES

#   std_msgs

# )

O acima concluiu a criação da mensagem, agora use rosmsg showo comando para ver se o ROS consegue reconhecê-la,
rosmsg show [message type]
ou seja: rosmsg show beginner_tutorials/Num(o nome do pacote pode ser salvo)
create 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包中复制一个服务)

find_packageObserve que adicionar message_generationdependências
para chamadas no arquivo CMakeLists.txt

# add_service_files(

#   FILES

#   Service1.srv

#   Service2.srv

# )

tornar-se:

add_service_files(
  FILES
  AddTwoInts.srv
)

Veja se pode ser reconhecido: rossrv show <service type>
ou seja: rossrv show beginner_tutorials/AddTwoInts(Você também não pode especificar o nome do pacote)
Recompile o pacote:

roscd beginner_tutorials
cd ../..
catkin_make
cd -

NOTA: Qualquer arquivo .msg no diretório msg irá gerar código para todos os idiomas suportados.

Arquivos de cabeçalho para mensagens C++ serão gerados em ~/catkin_ws/devel/include/beginner_tutorials/.

O script Python será criado em ~/catkin_ws/devel/lib/python2.7/dist-packages/beginner_tutorials/msg.

Os arquivos Lisp aparecem em ~/catkin_ws/devel/share/common-lisp/ros/beginner_tutorials/msg/.

Da mesma forma, qualquer arquivo .srv no diretório srv gerará código para os idiomas suportados. Para C++, o arquivo de cabeçalho será gerado no mesmo diretório que o arquivo de cabeçalho da mensagem. Para Python e Lisp, estará no diretório srv ao lado do diretório msg.

11. Escreva editores e assinantes simples

C++

nó do locutor (editor): transmite mensagens continuamente

roscd beginner_tutorials
mkdir src

Crie um arquivo talker.cpp com o seguinte 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;
}

Nó do assinante:
crie um arquivo listener.cpp e grave o seguinte conteúdo

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

Adicione estas linhas na parte inferior do arquivo 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)

No final fica assim:

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 teste e assinante

Execute o editor:

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

Execute o assinante:

 rosrun beginner_tutorials listener     # (C++)

13. Escreva serviços e clientes simples

Escrevendo um nó de serviço:
crie um nó de serviço simples add_two_ints_server que receberá dois números inteiros e retornará sua soma.

roscd beginner_tutorials

Crie o arquivo src/add_two_ints_server.cpp no ​​pacote iniciante_tutorials e cole o seguinte nele:

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

Escreva um nó cliente:
Crie um arquivo src/add_two_ints_client.cpp no ​​pacote iniciante_tutorials e cole o seguinte nele:

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

Alterar CMakeLists.txt (adicionar 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. Examine serviços e clientes simples

Execute o serviço:

rosrun beginner_tutorials add_two_ints_server

Execute o cliente:

rosrun beginner_tutorials add_two_ints_client 1 3

15. Gravar e reproduzir dados

Registre os dados no sistema ROS em execução em um arquivo bag e, em seguida, reproduza o processo de operação semelhante reproduzindo os dados
Gravando dados:

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

Basta controlar a pequena tartaruga para se mover por um tempo
Reprodução:

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

Um subconjunto de dados registrados:

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

ps não pode ser perfeitamente imitado, a precisão não é suficiente

16. Leia a mensagem do arquivo bag

Observação: há um tempo antes do comando, portanto, você pode exibir o tempo gasto na execução de cada comando ao mesmo tempo
Reproduza a mensagem imediatamente e visualize a saída em vários terminais:

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

Inscreva-se em outro tópico: rostopic echo /diagnostics_agg | tee topic2.yaml
time rosbag play --immediate demo.bag --topics /topic1 /topic2 /topic3 /topicN(playback, --immediate o mais rápido possível)
ou seja: time rosbag play --immediate demo.bag --topics /obs1/gps/fix /diagnostics_agg
você pode usar ros_readbagfilescripts para extrair tópicos de interesse

17. Introdução ao roswtf

Verificação da instalação:

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

Verifique on-line:

roscd
roswtf

erro:

roscd
ROS_PACKAGE_PATH=bad:$ROS_PACKAGE_PATH roswtf

Finalmente: configure o ambiente ROS no vscode:

Adicionar arquivos no espaço de trabalho (no desenvolvedor): catkin_make -DCMAKE_EXPORT_COMPILE_COMMANDS=Yes
altere c_cpp_propertries.json para:

{
    
    
  "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

}

Você pode encontrar arquivos de cabeçalho como ros.h!

Acho que você gosta

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