ROS Iniciante
Diretório de artigos
- ROS Iniciante
-
-
- introdução
- 1. Crie um espaço de trabalho amentilho
- 2. Sistema de arquivos
- 3. Criar pacote
- 4. Construir o pacote ROS
- 5. Entendendo os nós ROS
- 6. Entenda os tópicos do ROS
- 7. Entenda os serviços e parâmetros do ROS
- 8. rqt_console e roslaunch
- 9. Use rosa
- 10. Crie mensagens e serviços
- 11. Escreva editores e assinantes simples
- 12. Editor de teste e assinante
- 13. Escreva serviços e clientes simples
- 14. Examine serviços e clientes simples
- 15. Gravar e reproduzir dados
- 16. Leia a mensagem do arquivo bag
- 17. Introdução ao roswtf
- Finalmente: configure o ambiente ROS no vscode:
-
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.xml
lista 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.xml
arquivo que forneça metainformações sobre o pacote
2) Deve haver um CMakeLists.txt
arquivo
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_make
construir 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 list
examina o nó atual, usa rosnode info /rosout
para visualizar as informações de um nó (aqui, /rosout
rosrun
você 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_node
Os nós turtle_teleop_key
se comunicam entre si por meio de um tópico do ROS: turtle_teleop_key
publique uma mensagem de pressionamento de teclado no tópico turtlesim
e, em seguida, assine o tópico para receber a mensagem.
Use para rqt_graph
visualizar 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 echo
este tópico também está inscrito neste momento)
rostopic list
lista 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_plot
tó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?:
rosparam
Vamos 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 list
nomes 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_console
Conectado à estrutura de log do ROS para exibir as informações de saída do nó
rqt_logger_level
Permite 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.launch
arquivo 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_graph
entender melhor o que o arquivo de inicialização faz (ou execute rqt
e 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: .bashrc
adicione 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. msg
Eles 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 srv
arquivo descreve um serviço. Consiste em duas partes: request (request) e response (response), que são separadas por ------ linhas e armazenadas no srv
diretó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_package
adicione message_generation
dependências para as chamadas já existentes: ( aplicável message_generation
a msg
ambos srv
)
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
message_generation
)
find_package
NOTA: À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 show
o 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_package
Observe que adicionar message_generation
dependê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_readbagfile
scripts 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!