Carrinho de caminhão ROS. Parte 4. Criando uma simulação de robô usando os editores rviz e gazebo

Posts da série:
8. Nós controlamos a partir do telefone-ROS Control, GPS-node
7. Localização do robô: gmapping, AMCL, pontos de referência no mapa da sala
6. Odometria com codificadores de roda, mapa da sala, lidar
5. Trabalhamos em rviz e gazebo: xacro, novos sensores.
4. Crie uma simulação de robô usando os editores rviz e gazebo.
3. Acelere, troque a câmera, conserte a marcha
2. Software
1. Ferro

Continuação de uma série de artigos sobre a criação de um pequeno robô. Desta vez, vamos nos concentrar na criação de uma cópia do robô na simulação, oferecida pelos ambientes ROS visuais rviz e gazebo (doravante denominados "editores"). O trabalho nos editores será realizado em uma máquina virtual, cuja imagem foi fornecida anteriormente para o download da imagem . Como estamos falando de simulação, construção de um modelo, o carrinho de robô em si não é necessário.



Postagens anteriores da série:

1. Parte 3
2. Parte 2
3. Parte 1

Criando arquivos urdf básicos

Em geral, o processo de criação de um robô de maneira simplificada geralmente consiste nos seguintes estágios:

1. Criando um modelo de robô.
2. Testando o modelo em uma simulação.
3. Criando um modelo de robô real.
4. Testando um modelo real.

Ao trabalhar com editores de ROS, que oferecem grandes oportunidades para a construção de modelos e seus testes no mundo virtual, devemos admitir que modelos de robôs reais nem sempre se comportam como seus irmãos incorpóreos. E aqui o tempo para trabalhar com modelos no mundo virtual é adicionado ao tempo necessário para finalizar o modelo real.
Tal presente de tempo, como disse uma pessoa famosa, não pode apenas pagar tudo.

Nesse sentido, em posts anteriores, a sequência da robótica foi interrompida: primeiro, um modelo real do robô foi criado. Agora vamos falar sobre sua virtualização, por assim dizer.

Criar urdf


Para aproveitar totalmente a simulação no Gazebo e testar o robô, você deve primeiro criar um arquivo URDF para o robô.

O arquivo URDF é um tipo de esqueleto no campo da visualização.
Simplificando, um arquivo URDF é um arquivo que descreve um robô.

Como mencionado anteriormente, o trabalho será realizado usando a imagem VMWARE Workstation na qual o ROS (Ubuntu 16.04, ROS-Kinetic) e os editores visuais já estão instalados. Portanto, todas as ações são reproduzíveis neste sistema.

Crie um pacote ROS chamado rosbots_description.

Para fazer isso, você precisa inserir a pasta com catkin_ws / src e executar o comando para criar o pacote no ROS:

roscd; cd ..; cd src; catkin_create_pkg rosbots_description rospy 

* Se ao executar o comando roscd; cd ..; cd src; Se você não gosta de catkin_ws, talvez tenha vários ambientes desse tipo. Para ativar o necessário, vá para a pasta catkin_ws e execute o comando: source devel / setup.bash. Para não se perder, se você estiver trabalhando com uma imagem, é possível acessar esta pasta a partir da raiz: cd ~; cd catkin_ws.

Se tudo correu bem, a pasta rosbots_description será criada.

Por que é tão difícil e não mais fácil criar uma pasta no catkin_ws / src manualmente? E que tipo de rosado é esse?

Você pode criar manualmente uma pasta, mas também precisará gravar manualmente mais dois arquivos com os quais o ROS trabalha: CMakeLists.txt e package.xml.

Eles estão presentes na pasta após a criação:



O ROS deles cria por conta própria. Enquanto não vamos nos debruçar sobre o seu conteúdo.
rospy no final do comando significa criar dependências, suportando python.

Seguindo em frente.

Dentro do pacote rosbots_description recém-criado, crie a pasta urdf e nele o arquivo rosbots.xacro.

 roscd rosbots_description mkdir urdf; cd urdf; touch rosbots.xacro chmod +x rosbots.xacro 

A beleza do sistema ROS é que, em qual pasta do sistema você não estaria localizado, você pode chegar imediatamente ao destino digitando simplesmente seu nome com o comando roscd no início da linha.

Agora coloque o seguinte código no arquivo recém-criado:

rosbots.xacro
 <?xml version="1.0" encoding="utf-8"?> <robot name="rosbots" xmlns:xacro="http://www.ros.org/wiki/xacro"> <link name="base_footprint"/> <joint name="base_joint" type="fixed"> <origin xyz="0 0 0.05" rpy="0 0 0" /> <parent link="base_footprint"/> <child link="base_link" /> </joint> <link name="base_link"> <visual> <geometry> <mesh filename="package://rosbots_description/meshes/base.dae"/> </geometry> <origin xyz="-0.52 -0.4 0.43" rpy="0 0 0"/> </visual> <collision> <geometry> <mesh filename="package://rosbots_description/meshes/base.dae"/> </geometry> <origin xyz="-0.52 -0.4 0.43" rpy="0 0 0"/> </collision> <inertial> <origin xyz="0.0 0 0."/> <mass value="0.5"/> <inertia ixx="0.01" ixy="0.0" ixz="0.0" iyy="0.01" iyz="0.0" izz="0.03" /> </inertial> </link> <joint name="second_level_joint" type="fixed"> <origin xyz="0 0 0.68" rpy="0 0 0" /> <parent link="base_link"/> <child link="base_second_link" /> </joint> <link name="base_second_link"> <visual> <geometry> <mesh filename="package://rosbots_description/meshes/base.dae"/> </geometry> <origin xyz="-0.52 -0.4 0.0" rpy="0 0 0"/> </visual> <collision> <geometry> <mesh filename="package://rosbots_description/meshes/base.dae"/> </geometry> <origin xyz="-0.52 -0.4 0.0" rpy="0 0 0"/> </collision> <!--inertial> <origin xyz="0.01 0 0.7"/> <mass value="1.0"/> <inertia ixx="0.01" ixy="0.0" ixz="0.0" iyy="0.01" iyz="0.0" izz="0.03" /> </inertial--> </link> <joint name="mcu_joint" type="fixed"> <origin xyz="0.02 0.12 0.73" rpy="0 0 0" /> <parent link="base_link"/> <child link="mcu_link" /> </joint> <link name="mcu_link"> <visual> <geometry> <mesh filename="package://rosbots_description/meshes/rasp.dae" scale="0.14 0.14 0.14"/> </geometry> <origin xyz="0.9 -1.25 0" rpy="0 0 1.57"/> </visual> <collision> <geometry> <mesh filename="package://rosbots_description/meshes/rasp.dae" scale="0.14 0.14 0.14"/> </geometry> <origin xyz="0.9 -1.25 0" rpy="0 0 1.57"/> </collision> <!-- inertial> <origin xyz="0.01 0 0"/> <mass value="1.0"/> <inertia ixx="0.019995" ixy="0.0" ixz="0.0" iyy="0.019995" iyz="0.0" izz="0.03675" /> </inertial--> </link> <joint name="mcu_joint_1" type="fixed"> <origin xyz="0.02 0.12 0.83" rpy="0 0 0" /> <parent link="base_link"/> <child link="mcu_link_1" /> </joint> <link name="mcu_link_1"> <visual> <geometry> <mesh filename="package://rosbots_description/meshes/rasp.dae" scale="0.14 0.14 0.14"/> </geometry> <origin xyz="0.9 -1.25 0" rpy="0 0 1.57"/> </visual> <collision> <geometry> <mesh filename="package://rosbots_description/meshes/rasp.dae" scale="0.14 0.14 0.14"/> </geometry> <origin xyz="0.9 -1.25 0" rpy="0 0 1.57"/> </collision> <!-- inertial> <origin xyz="0.01 0 0"/> <mass value="1.0"/> <inertia ixx="0.019995" ixy="0.0" ixz="0.0" iyy="0.019995" iyz="0.0" izz="0.03675" /> </inertial--> </link> <joint name="stand_mcu1_joint" type="fixed"> <origin xyz="0.02 0.25 0.78" rpy="0 0 1.57" /> <parent link="base_link"/> <child link="stand_mcu1_link" /> </joint> <link name="stand_mcu1_link"> <visual> <geometry> <cylinder length="0.1" radius="0.01"/> </geometry> <origin rpy="0.0 0 0" xyz="0 0 0.0"/> </visual> <collision> <geometry> <cylinder length="0.1" radius="0.01"/> </geometry> <origin rpy="0.0 0 0" xyz="0 0 0.0"/> </collision> </link> <joint name="stand_mcu2_joint" type="fixed"> <origin xyz="0.02 -0.1125 0.78" rpy="0 0 1.57" /> <parent link="base_link"/> <child link="stand_mcu2_link" /> </joint> <link name="stand_mcu2_link"> <visual> <geometry> <cylinder length="0.1" radius="0.01"/> </geometry> <origin rpy="0.0 0 0" xyz="0 0 0.0"/> </visual> <collision> <geometry> <cylinder length="0.1" radius="0.01"/> </geometry> <origin rpy="0.0 0 0" xyz="0 0 0.0"/> </collision> </link> <joint name="stand_mcu3_joint" type="fixed"> <origin xyz="0.25 0.25 0.78" rpy="0 0 1.57" /> <parent link="base_link"/> <child link="stand_mcu3_link" /> </joint> <link name="stand_mcu3_link"> <visual> <geometry> <cylinder length="0.1" radius="0.01"/> </geometry> <origin rpy="0.0 0 0" xyz="0 0 0.0"/> </visual> <collision> <geometry> <cylinder length="0.1" radius="0.01"/> </geometry> <origin rpy="0.0 0 0" xyz="0 0 0.0"/> </collision> </link> <joint name="stand_mcu4_joint" type="fixed"> <origin xyz="0.25 -0.1125 0.78" rpy="0 0 1.57" /> <parent link="base_link"/> <child link="stand_mcu4_link" /> </joint> <link name="stand_mcu4_link"> <visual> <geometry> <cylinder length="0.1" radius="0.01"/> </geometry> <origin rpy="0.0 0 0" xyz="0 0 0.0"/> </visual> <collision> <geometry> <cylinder length="0.1" radius="0.01"/> </geometry> <origin rpy="0.0 0 0" xyz="0 0 0.0"/> </collision> </link> <joint name="batery_joint" type="fixed"> <origin xyz="1.2 0.2 0.43" rpy="0 0 1.57" /> <parent link="base_link"/> <child link="batery_link" /> </joint> <link name="batery_link"> <visual> <geometry> <mesh filename="package://rosbots_description/meshes/battery.dae" scale="13.0 6.0 6.0"/> </geometry> <origin xyz="0 4.5 0.05" rpy="1.57 0 1.57"/> </visual> <collision> <geometry> <mesh filename="package://rosbots_description/meshes/battery.dae" scale="13.0 6.0 6.0"/> </geometry> <origin xyz="0 4.5 0.05" rpy="1.57 0 1.57"/> </collision> <!-- inertial> <origin xyz="0.01 0 0"/> <mass value="1.0"/> <inertia ixx="0.01" ixy="0.0" ixz="0.0" iyy="0.01" iyz="0.0" izz="0.03" /> </inertial--> </link> <joint name="stand_1_joint" type="fixed"> <origin xyz="0.5 0.4125 0.58" rpy="0 0 1.57" /> <parent link="base_link"/> <child link="stand_1_link" /> </joint> <link name="stand_1_link"> <visual> <geometry> <cylinder length="0.20" radius="0.03"/> </geometry> <origin rpy="0.0 0 0" xyz="0 0 0.0"/> </visual> <collision> <geometry> <cylinder length="0.20" radius="0.03"/> </geometry> <origin rpy="0.0 0 0" xyz="0 0 0.0"/> </collision> <!--inertial> <origin xyz="0.0 0 0"/> <mass value="1.0"/> <inertia ixx="0.019995" ixy="0.0" ixz="0.0" iyy="0.019995" iyz="0.0" izz="0.03675" /> </inertial--> </link> <joint name="stand_2_joint" type="fixed"> <origin xyz="0.5 -0.2625 0.58" rpy="0 0 1.57" /> <parent link="base_link"/> <child link="stand_2_link" /> </joint> <link name="stand_2_link"> <visual> <geometry> <cylinder length="0.20" radius="0.03"/> </geometry> <origin rpy="0.0 0 0" xyz="0 0 0.0"/> </visual> <collision> <geometry> <cylinder length="0.20" radius="0.03"/> </geometry> <origin rpy="0.0 0 0" xyz="0 0 0.0"/> </collision> <!--inertial> <origin xyz="0.0 0 0"/> <mass value="1.0"/> <inertia ixx="0.019995" ixy="0.0" ixz="0.0" iyy="0.019995" iyz="0.0" izz="0.03675" /> </inertial--> </link> <joint name="wheel_left_joint" type="continuous"> <parent link="base_link"/> <child link="wheel_left_link"/> <origin xyz="0.15 0.4125 0.30" rpy="-1.57 0 0"/> <axis xyz="0 0 1"/> </joint> <link name="wheel_left_link"> <collision> <geometry> <cylinder length="0.20" radius="0.23"/> </geometry> <origin rpy="0.0 0.0 0" xyz="0 0 0.1"/> </collision> <visual name="visual"> <geometry> <!-- cylinder length="0.0206" radius="0.0550"/--> <!--cylinder length="0.20" radius="0.26"/--> <mesh filename="package://rosbots_description/meshes/wheel.dae" scale="8.0 8.0 8.0"/> </geometry> <origin rpy="0.0 0 0" xyz="0 0 0"/> </visual> <inertial> <mass value="0.4" /> <origin xyz="0 0 0" /> <inertia ixx="0.001" ixy="0.0" ixz="0.0" iyy="0.001" iyz="0.0" izz="0.001" /> </inertial> </link> <joint name="wheel_right_joint" type="continuous"> <parent link="base_link"/> <child link="wheel_right_link"/> <origin xyz="0.15 -0.5625 0.30" rpy="-1.57 0 0"/> <axis xyz="0 0 1"/> </joint> <link name="wheel_right_link"> <collision> <geometry> <cylinder length="0.20" radius="0.23"/> </geometry> <origin rpy="0.0 0 0" xyz="0 0 0.195"/> </collision> <visual name="visual"> <geometry> <!--cylinder length="0.20" radius="0.26"/--> <mesh filename="package://rosbots_description/meshes/wheel.dae" scale="8.0 8.0 8.0"/> </geometry> <origin rpy="0.0 0 0" xyz="0 0 0"/> </visual> <inertial> <mass value="0.4" /> <origin xyz="0 0.0 0.3" /> <inertia ixx="0.001" ixy="0.0" ixz="0.0" iyy="0.001" iyz="0.0" izz="0.001" /> </inertial> </link> <joint name="caster_back_joint" type="fixed"> <parent link="base_link"/> <child link="caster_back_link"/> <origin xyz="-0.4 0.1 0.26" rpy="0 0 0"/> </joint> <link name="caster_back_link"> <collision> <geometry> <!-- cylinder length="0.05" radius="0.19"/--> <sphere radius="0.19"/> </geometry> <origin rpy="0 0 0" xyz="0 0 0"/> </collision> <visual> <geometry> <!--cylinder length="0.05" radius="0.19"/--> <sphere radius="0.19"/> </geometry> <origin rpy="0 0 0" xyz="0 0 0"/> </visual> <inertial> <mass value="0.1" /> <origin xyz="0 0 0" /> <inertia ixx="0.001023539" ixy="0.0" ixz="0.0" iyy="0.001023539" iyz="0.0" izz="0.001023539" /> </inertial> </link> <joint name="stand_3_joint" type="fixed"> <origin xyz="-0.4 0.4125 0.58" rpy="0 0 1.57" /> <parent link="base_link"/> <child link="stand_3_link" /> </joint> <link name="stand_3_link"> <visual> <geometry> <cylinder length="0.20" radius="0.03"/> </geometry> <origin rpy="0.0 0 0" xyz="0 0 0.0"/> </visual> <collision> <geometry> <cylinder length="0.20" radius="0.03"/> </geometry> <origin rpy="0.0 0 0" xyz="0 0 0.0"/> </collision> </link> <joint name="stand_4_joint" type="fixed"> <origin xyz="-0.4 -0.2625 0.58" rpy="0 0 1.57" /> <parent link="base_link"/> <child link="stand_4_link" /> </joint> <link name="stand_4_link"> <visual> <geometry> <cylinder length="0.20" radius="0.03"/> </geometry> <origin rpy="0.0 0 0" xyz="0 0 0.0"/> </visual> <collision> <geometry> <cylinder length="0.20" radius="0.03"/> </geometry> <origin rpy="0.0 0 0" xyz="0 0 0.0"/> </collision> </link> </robot> 


Se o código não aparecer, todos os arquivos poderão ser baixados no final da postagem.

Para o código acima, também precisamos de células (meches), que serão carregadas durante o lançamento do pacote.

Meches pode ser tomado aqui
e coloque a pasta meches descompactada em rosbots_description.

Se você olhar o código em detalhes, poderá descobrir que este é um arquivo xml padrão que consiste em blocos:
- visual
- colisão
- inercial

Cada bloco descreve sua parte: visual é a aparência do robô, nada mais, colisão e inercial é a física do robô, como tudo irá interagir com o mundo exterior - colisões, inércia.
juntas - elementos que ajudam a determinar o movimento entre as partes do robô (links). Por exemplo, o movimento da roda (roda) afeta o quadro como um todo (chassi).

origem xyz é a localização inicial do objeto ao longo dos eixos x, y, z.

o link pai e o link filho são os links pai e filho, respectivamente, que crescem a partir do quê.
A presença de tipos também é digna de nota: type = "contínuo", tipo = "fixo". Esta é uma definição do que pode e não pode girar. Então as rodas são contínuas. E, por exemplo, batery_joint é fixo.
A indentação no código é tão profundamente significativa quanto em python, onde você não pode interferir com guias e espaços, não carrega. Mas para o paraíso e a visibilidade de um perfeccionista, é melhor tê-los.

O código acima é essencialmente um modelo de robô.

Trabalhe na rviz


Vamos ver o que aconteceu.

Para fazer isso, crie um arquivo de inicialização que executará o pacote ROS.

Para isso, os chamados arquivos de inicialização são usados ​​no ROS. A essência do arquivo de inicialização é permitir o lançamento de um nó, comando ou vários nós com um comando curto, sem a necessidade de especificar todos os argumentos e outros nele.

Crie uma pasta de inicialização na rosbots_description com o arquivo rviz.launch:

 roscd rosbots_description mkdir launch; cd launch; touch rviz.launch 

* Este e os tempos subsequentes, não há mais a necessidade de criar um pacote ROS, como foi feito anteriormente. Agora, o próprio sistema "verá" os arquivos dentro do pacote. Portanto, apenas criamos um diretório.

Preencha o arquivo com o conteúdo -
rviz.launch
  <?xml version="1.0"?> <launch> <param name="robot_description" command="cat '$(find rosbots_description)/urdf/rosbots.xacro'"/> <!-- send fake joint values --> <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher"> <param name="use_gui" value="False"/> </node> <!-- Combine joint values --> <node name="robot_state_publisher" pkg="robot_state_publisher" type="state_publisher"/> <!-- Show in Rviz --> <node name="rviz" pkg="rviz" type="rviz" /> </launch> 


Aqui você pode ver que, na inicialização, o sistema procurará uma descrição do modelo em rosbots.xacro.

A seguir, serão lançados 3 nós: joint_state_publisher do pacote joint_state_publisher, robot_state_publisher de robot_state_publisher, rviz de rviz. type é o tipo de nó, geralmente corresponde ao arquivo Python ou C com o mesmo nome, mas é especificado sem uma extensão.

Execute:

No 1º terminal, execute o mestre do ROS:

 roscore 

No segundo:

 roslaunch rosbots_description rviz.launch 

* Se ocorreu um erro
O host ROS_MASTER_URI [http: //192.168.1 ....: 11311] não está definido para esta máquina
, verifique o bashrc - no qual o ROS IP está sendo executado:

 nano ~/.bashrc 

especifique o ip da máquina virtual no próprio arquivo bashrc (por exemplo, este):

 export ROS_MASTER_URI=http://192.168.1.114:11311 

leia novamente o bashrc:

source ~/.bashrc ou reinicialize.
**
Se o roslaunch ainda não iniciar, você pode tentar ir para a pasta catkin_ws e executar: source devel / setup.bash

Mergulhando em Rviz


Após a execução do comando, o editor Rviz é iniciado e o shell gráfico é aberto.
A apresentação visual pode variar, mas em geral a visualização será aproximadamente da seguinte maneira:



À esquerda na coluna Monitores, é possível observar as opções de exibição de vários elementos que interagem com os nós ROS, no centro - a imagem do robô à direita - uma coluna com uma visão da câmera do robô. Devo dizer imediatamente que é melhor trabalhar com um mouse de 3 rodas com rviz, pois todos os botões do mouse estão envolvidos aqui. Mantendo a esquerda pressionada, você pode girar o espaço na janela com o robô exibido, mantendo pressionada a direita - aumentar / diminuir o zoom, mantendo as duas teclas - mover o espaço em relação ao robô.

A maior parte do trabalho no editor é realizada nas duas primeiras colunas: Monitores e a representação visual do robô.

Vamos trabalhar com a aparência de um robô


Vamos selecionar "Quadro fixo" - "link base" na linha:



E adicione a descrição do robô aos displays:

Clique em "Adicionar" e selecione "RobotModel" na lista:

"

Agora, na janela de simulação, você pode observar o robô que foi reproduzido a partir do modelo rviz.xacro:

"

Ótimo. Com uma representação visual, tudo está claro. Agora você precisa entender como executar a simulação, porque o rviz é apenas uma visualização da simulação, mas não a simulação em si.
Ou seja, a física não funciona aqui.

A simulação em si vive em um editor chamado Gazebo.

Gazebo


Para colocar o modelo criado no Gazebo, crie outro arquivo de inicialização - spawn.launch na pasta de inicialização do projeto. Agora temos 2 arquivos de lançamento!

spawn.launch
 <?xml version="1.0" encoding="UTF-8"?> <launch> <param name="robot_description" command="cat '$(find rosbots_description)/urdf/rosbots.xacro'" /> <arg name="x" default="0"/> <arg name="y" default="0"/> <arg name="z" default="0.5"/> <node name="mybot_spawn" pkg="gazebo_ros" type="spawn_model" output="screen" args="-urdf -param robot_description -model rosbots -x $(arg x) -y $(arg y) -z $(arg z)" /> </launch> 


Aqui também lemos o modelo, depois com argumentos passamos sua localização no espaço ao longo dos eixos x, y, z. Em seguida, execute apenas um nó - mybot_spawn no pacote gazebo_ros.
* Não há necessidade de reinstalar os pacotes mencionados acima. Se desejar, você pode olhar para esses pacotes com o mesmo comando: roscd. Por exemplo, roscd gazebo_ros.

Agora pare o Ros-master no terminal 1:

 CTRL+C 

E execute o editor Gazebo:

 roslaunch gazebo_ros empty_world.launch 

No terminal 2, execute o arquivo recém-criado:

 roslaunch rosbots_description spawn.launch 

Agora vemos nosso robô na simulação do editor Gazebo:



* Se você tiver um erro: Waiting for service /gazebo/spawn_urdf_model
Isso significa que você lançou o modelo sem iniciar o Gazebo, violando a ordem de lançamento.

Vamos para a simulação do gazebo.


Agora adicione o seguinte código ao rosbots.xacro antes da tag de fechamento:

código
 <gazebo> <plugin name="differential_drive_controller" filename="libgazebo_ros_diff_drive.so"> <legacyMode>false</legacyMode> <alwaysOn>true</alwaysOn> <publishWheelTF>true</publishWheelTF> <publishTf>1</publishTf> <publishWheelJointState>true</publishWheelJointState> <updateRate>100.0</updateRate> <leftJoint>wheel_left_joint</leftJoint> <rightJoint>wheel_right_joint</rightJoint> <wheelSeparation>1.1</wheelSeparation> <wheelDiameter>0.52</wheelDiameter> <wheelAcceleration>1.0</wheelAcceleration> <torque>20</torque> <commandTopic>/part2_cmr/cmd_vel</commandTopic> <odometryTopic>odom</odometryTopic> <odometryFrame>odom</odometryFrame> <robotBaseFrame>base_link</robotBaseFrame> </plugin> </gazebo> 


O Simulator Gazebo não pode ser fechado durante a edição.

Agora exclua o modelo do editor Gazebo:

 rosservice call /gazebo/delete_model "model_name: 'rosbots'" 

Ou apenas reinicie o editor.

* O Gazebo é irritadiço em uma máquina virtual; portanto, mesmo depois de fechá-lo, às vezes perdoamos CTRL + C adicionalmente no terminal.

Substitua o modelo no Gazebo após a edição:

 roslaunch rosbots_description spawn.launch 

Se você agora examinar a lista de tópicos do ROS, poderá ver que, dentre eles, existem

 /part2_cmr/cmd_vel 



Agora vamos tentar controlar o robô na simulação executando o controle em um terminal separado:

 rosrun teleop_twist_keyboard teleop_twist_keyboard.py /cmd_vel:=/part2_cmr/cmd_vel 

Estando na janela com o controle em execução e pressionando as teclas “i”, “l”, “j”, “k”, “,” na janela do terminal, é possível observar o movimento do robô na simulação do editor Gazebo:



Código - download .

Para ser continuado.

Source: https://habr.com/ru/post/pt467241/


All Articles