Carro para camiones ROS. Parte 4. Crear una simulación de robot usando los editores rviz y gazebo

Publicaciones en la serie:
8. Controlamos desde el control del teléfono ROS, nodo GPS
7. Localización de robots: gmapping, AMCL, puntos de referencia en el mapa de la sala
6. Odometría con codificadores de rueda, mapa de habitación, lidar
5. Trabajamos en rviz y gazebo: xacro, nuevos sensores.
4. Cree una simulación de robot utilizando los editores rviz y gazebo.
3. Acelera, cambia la cámara, arregla la marcha
2. Software
1. hierro

Continuación de una serie de artículos sobre la creación de un pequeño robot. Esta vez nos centraremos en crear una copia del robot en la simulación, que es ofrecida por los entornos visuales ROS rviz y gazebo (en adelante, los "editores"). El trabajo en los editores se llevará a cabo en una máquina virtual, cuya imagen se proporcionó previamente para descargar la imagen . Como estamos hablando de simulación, construcción de un modelo, el carro robot no es necesario.



Publicaciones anteriores de la serie:

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

Crear archivos urdf básicos

En general, el proceso de creación de un robot de manera simplificada generalmente consta de las siguientes etapas:

1. Crear un modelo de robot.
2. Probar el modelo en una simulación.
3. Crear un modelo de robot real.
4. Probar un modelo real.

Cuando trabajamos con editores de ROS, que brindan grandes oportunidades tanto para construir modelos como para sus pruebas en el mundo virtual, debemos admitir que los modelos de robots reales no siempre se comportan como sus hermanos incorpóreos. Y aquí el tiempo para trabajar con modelos en el mundo virtual se agrega al tiempo necesario para finalizar el modelo real.
Tal regalo de tiempo, como dijo una persona famosa, no solo puede permitirse todo.

En este sentido, en publicaciones anteriores se interrumpió la secuencia de la robótica: primero, se creó un modelo real del robot. Ahora hablaremos de su virtualización, por así decirlo.

Crear urdf


Para disfrutar plenamente de la simulación en Gazebo y probar el robot, primero debe crear un archivo URDF para el robot.

El archivo URDF es una especie de esqueleto esqueleto en el campo de visualización.
En pocas palabras, un archivo URDF es un archivo que describe un robot.

Como se indicó anteriormente, el trabajo se llevará a cabo utilizando la imagen VMWARE Workstation en la que ROS (Ubuntu 16.04, ROS-Kinetic) y los editores visuales ya están instalados. Por lo tanto, todas las acciones son reproducibles en este sistema.

Cree un paquete ROS llamado rosbots_description.

Para hacer esto, debe ingresar la carpeta con catkin_ws / src y ejecutar el comando para crear el paquete en ROS:

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

* Si al ejecutar el comando roscd; cd ..; cd src; Si no entras en catkin_ws, entonces quizás tengas varios entornos de este tipo. Para activar el necesario, vaya a la carpeta catkin_ws y ejecute el comando: source devel / setup.bash. Para no perderse, si trabaja con la imagen, puede acceder a esta carpeta desde la raíz: cd ~; cd catkin_ws.

Si todo salió bien, se creará la carpeta rosbots_description.

¿Por qué es tan difícil y no tan fácil crear una carpeta en catkin_ws / src manualmente? ¿Y qué tipo de rospy es?

Puede crear manualmente una carpeta, pero también tendrá que escribir manualmente dos archivos más con los que trabaja ROS: CMakeLists.txt y package.xml.

Están presentes en la carpeta después de la creación:



Su ROS crea por su cuenta. Si bien no nos detendremos en sus contenidos.
rospy al final del comando significa crear dependencias, admitiendo python.

Siguiendo adelante.

Dentro del paquete rosbots_description recién creado, cree la carpeta urdf y en él el archivo rosbots.xacro.

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

La belleza del sistema ROS es que en la carpeta del sistema en la que no se ubicaría, puede llegar inmediatamente al objetivo simplemente escribiendo su nombre con el comando roscd al comienzo de la línea.

Ahora ponga el siguiente código en el archivo recién creado:

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> 


Si el código no aparece, todos los archivos se pueden descargar al final de la publicación.

Para el código anterior, también necesitamos celdas (meches), que se cargarán durante el lanzamiento del paquete.

Meches se pueden tomar aquí
y poner la carpeta de meches desempaquetada en rosbots_description.

Si observa el código en detalle, puede descubrir que este es un archivo xml estándar que consta de bloques:
- visual
- colisión
- inercial

Cada bloque describe su parte: visual es la apariencia del robot, no más, colisión e inercia es la física del robot, cómo todo interactuará con el mundo exterior: colisiones, inercia.
articulaciones: elementos que ayudan a determinar el movimiento entre las partes del robot (enlaces). Por ejemplo, el movimiento de la rueda (rueda) afecta al cuadro como un todo (chasis).

origen xyz es la ubicación inicial del objeto a lo largo de los ejes x, y, z.

el enlace padre y el enlace hijo son los enlaces padre e hijo, respectivamente, que surge de qué.
La presencia de tipos también es notable: type = "contínuo", type = "fijo". Esta es una definición de lo que puede y no puede rotar. Entonces las ruedas son continuas. Y, por ejemplo, batery_joint es fijo.
La sangría en el código es tan profundamente significativa como en Python, donde no puede interferir con pestañas y espacios, no llevar. Pero para el paraíso y la visibilidad de un perfeccionista es mejor tenerlos.

El código anterior es esencialmente un modelo de robot.

Trabaja en rviz


Veamos que pasó.

Para hacer esto, cree un archivo de inicio que ejecute el paquete ROS.

Para esto, los llamados archivos de lanzamiento se utilizan en ROS. La esencia del archivo de inicio es permitir el inicio de un nodo, comando o varios nodos con un comando breve sin la necesidad de especificar todos los argumentos y otros en él.

Cree una carpeta de inicio en rosbots_description con el archivo rviz.launch:

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

* Esta y otras veces ya no es necesario crear un paquete ROS como se hizo anteriormente. Ahora el sistema mismo "verá" los archivos dentro del paquete. Por lo tanto, solo creamos un directorio.

Rellene el archivo con contenido -
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> 


Aquí puede ver que al iniciar el sistema buscará una descripción del modelo en rosbots.xacro.

A continuación, lanzará 3 nodos: joint_state_publisher del paquete joint_state_publisher, robot_state_publisher de robot_state_publisher, rviz de rviz. type es el tipo de nodo, generalmente corresponde al archivo Python o C del mismo nombre, pero se especifica sin una extensión.

Ejecutar:

En la primera terminal, ejecute el maestro ROS:

 roscore 

En el 2do:

 roslaunch rosbots_description rviz.launch 

* Si ocurrió un error
ROS_MASTER_URI [http: //192.168.1 ....: 11311] host no está configurado en esta máquina
, entonces debe verificar bashrc - en qué ip ROS se está ejecutando:

 nano ~/.bashrc 

especifique la ip de la máquina virtual en el archivo bashrc (por ejemplo, este):

 export ROS_MASTER_URI=http://192.168.1.114:11311 

releer bashrc más adelante:

source ~/.bashrc o reiniciar.
** **
Si roslaunch aún no se inicia, puede intentar ir a la carpeta catkin_ws y ejecutar: source devel / setup.bash

Zambullirse en Rviz


Después de ejecutar el comando, se inicia el editor Rviz y se abre el shell gráfico.
La presentación visual puede variar, pero en general la vista será aproximadamente la siguiente:



A la izquierda en la columna Pantallas, puede observar las opciones de visualización para varios elementos que interactúan con los nodos ROS, en el centro, la imagen del robot, a la derecha, una columna con una cámara similar a un robot. Debo decir de inmediato que es mejor trabajar con un mouse de 3 ruedas con rviz, ya que todos los botones del mouse están involucrados aquí. Manteniendo la izquierda, puede rotar el espacio en la ventana con el robot mostrado, manteniendo la derecha - acercar / alejar, manteniendo presionadas ambas teclas - mover el espacio relativo al robot.

La mayor parte del trabajo en el editor se lleva a cabo en las dos primeras columnas: pantallas y la representación visual del robot.

Trabajemos con la apariencia de un robot.


Seleccionemos "Marco fijo" - "enlace base" en la línea:



Y agregue la descripción del robot a las pantallas:

Haga clic en "Agregar" y seleccione "RobotModel" en la lista:

"

Ahora en la ventana de simulación puede observar el robot que se reprodujo del modelo rviz.xacro:

"

Genial Con una representación visual, todo está claro. Ahora necesita comprender cómo ejecutar la simulación, porque rviz es solo una visualización de la simulación, pero no la simulación en sí.
Es decir, la física no funciona aquí.

La simulación misma vive en un editor llamado Gazebo.

Gazebo


Para colocar el modelo creado en Gazebo, cree otro archivo de inicio: spawn.launch en la carpeta de inicio del proyecto. ¡Ahora tenemos 2 archivos de lanzamiento!

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> 


Aquí también leemos el modelo, luego con argumentos pasamos su ubicación en el espacio a lo largo de los ejes x, y, z. A continuación, ejecute solo un nodo: mybot_spawn desde el paquete gazebo_ros.
* No es necesario reinstalar los paquetes mencionados anteriormente. Si lo desea, puede mirar estos paquetes con el mismo comando: roscd. Por ejemplo roscd gazebo_ros.

Ahora pare el Ros-master en la terminal 1:

 CTRL+C 

Y ejecuta el editor Gazebo:

 roslaunch gazebo_ros empty_world.launch 

En la terminal 2, ejecute el archivo recién creado:

 roslaunch rosbots_description spawn.launch 

Ahora vemos nuestro robot en la simulación del editor Gazebo:



* Si tiene un error: Waiting for service /gazebo/spawn_urdf_model
Esto significa que lanzó el modelo sin iniciar primero Gazebo, violando el orden de lanzamiento.

Vayamos a la simulación del mirador.


Ahora agregue el siguiente código a rosbots.xacro antes de la etiqueta de cierre:

codigo
 <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> 


El simulador Gazebo no se puede cerrar al editar.

Ahora elimine el modelo del editor Gazebo:

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

O simplemente reinicie el editor.

* Gazebo es irritable en una máquina virtual, por lo que incluso después de cerrarlo a veces perdona CTRL + C adicionalmente en el terminal.

Vuelva a colocar el modelo en Gazebo después de editar:

 roslaunch rosbots_description spawn.launch 

Si ahora mira la lista de temas ROS, puede ver que entre ellos hay

 /part2_cmr/cmd_vel 



Ahora intentemos controlar el robot en la simulación ejecutando el control en un terminal separado:

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

Al estar en la ventana con el control en ejecución y presionando las teclas "i", "l", "j", "k", "," en la ventana de terminal, puede observar el movimiento del robot en la simulación del editor Gazebo:



Código - descargar .

Continuará

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


All Articles