» » » Робот-тележка на ROS. Часть 4. Создаем симуляцию робота в rviz и gazebo

 

Робот-тележка на ROS. Часть 4. Создаем симуляцию робота в rviz и gazebo

Автор: admin от 13-09-2019, 22:20, посмотрело: 25

Продолжение цикла статей о создании небольшого робота. В этот раз речь пойдет о создании копии робота в симуляции, которую предлагают визуальные ROS-среды rviz и gazebo (далее «редакторы»). Работа в редакторах будет вестись на виртуальной машине, образ которой был ранее предоставлен для скачивания (образ). Так как речь идет о симуляции, построении модели, сам робот-тележка не понадобится.



Робот-тележка на ROS. Часть 4. Создаем симуляцию робота в rviz и gazebo
Часть 3

2. Часть 2

3. Часть 1



Создание базовых urdf-файлов



Вообще, процесс создания робота упрощенно состоит как правило из следующих стадий:



1. Создание модели робота.

2. Тестирование модели в симуляции.

3. Создание реальной модели робота.

4. Тестирование реальной модели.



Работая с редакторами ROS, которые предоставляют шикарные возможности как по построению моделей и их тестам в виртуальном мире, надо признать, что реальные модели роботов ведут себя не всегда аналогично своим бестелесным братьям. И здесь время на работу с моделями в виртуальном мире складывается со временем, необходимым на доработку реальной модели.

Такое дарение времени, как говорил один известный человек, могут себе позволить не только лишь все.



В связи с этим, в предыдущих постах была нарушена последовательность роботостроения: сначала была создана реальная модель робота. Теперь же речь пойдет о ее виртуализации, так сказать.



Создаем urdf



Для того, чтобы в полной мере насладиться симуляцией в Gazebo и протестировать робота, сперва необходимо создать URDF файл для робота.



URDF файл является своеобразным каркасом-скелетом в области визуализации.

Проще говоря, URDF файл — это файл, описывающий робота.



Как ранее было заявлено, работа будет вестись с использованием образа VMWARE Workstation, на котором уже установлена ROS(Ubuntu 16.04, ROS-Kinetic) и визуальные редакторы. Поэтому все действия воспроизводимы в данной системе.



Создадим пакет ROS с названием rosbots_description.



Для того, чтобы это сделать надо войти в папку с catkin_ws/src и выполнить команду создания пакета в ROS:



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


*Если при выполнении команды roscd; cd ..; cd src; вы не попали в catkin_ws, то возможно у вас несколько сред подобного типа. Для того, чтобы активировать нужную, необходимо зайти в папку catkin_ws и выполнить команду: source devel/setup.bash. Чтобы не заблудиться, если вы работаете с образом, в эту папку можно попасть из корня: cd ~; cd catkin_ws.



Если все прошло успешно, то создастся папка rosbots_description.



Почему так сложно и не проще ли просто создать папку в catkin_ws/src вручную? И что там за rospy?



Вручную создать папку можно, но придется также вручную писать еще два файла, с которыми работает ROS: CMakeLists.txt и package.xml.



Именно они присутствуют в папке после создания:



Робот-тележка на ROS. Часть 4. Создаем симуляцию робота в rviz и gazebo


Их ROS создает самостоятельно. Пока на их содержимом останавливаться не будем.

rospy в конце команды означает создание зависимости, поддержку python.



Движемся дальше.



Внутри вновь созданного пакета rosbots_description создадим папку urdf, а в ней — файл rosbots.xacro.



roscd rosbots_description

mkdir urdf; cd urdf;

touch rosbots.xacro

chmod +x rosbots.xacro


Прелесть системы ROS в том, что в какой папке системы вы бы не находились, можно сразу попасть в целевую, просто набрав ее название с командой roscd в начале строки.



Теперь поместим во вновь созданный файл следующий код:



[spoiler=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"/>
      [leech=https://yadi.sk/d/kCuhB7Mh1MEvXQ]здесь[/leech]

и положить распакованную папку meches в rosbots_description.



Если посмотреть код детально, то можно выяснить, что это стандартный файл xml, состоящий из блоков:

 — visual

 — collision

 — inertial



Каждый блок описывает свою часть: visual — это внешность робота, не более, collision и inertial — это физика робота, как все будет взаимодействовать с внешним миром — столкновения, инерция.

joints — элементы, которые помогают определить движение между частями робота (links). Так например, движение колеса (wheel) влияет на раму в целом (chasis).



origin xyz — это первоначальное расположение объекта по осям x,y,z.



parent link и child link это соответственно родительская и дочерняя связи, что из чего растет.

Также примечательно наличие типов: type=«continuous», type=«fixed». Это определение того, что может вращаться, а что нет. Так колеса имеют тип continuous. А, например, batery_joint — fixed.

Отступы в коде такого же глубоко смысла как в python, где нельзя мешать табы и пробелы, не несут. Но для рая перфекциониста и наглядности лучше их иметь.



Код приведенный выше является по сути моделью робота. 



<h3>Работа в rviz</h3>

Посмотрим что вышло.



Для этого надо создать файл запуска, который будет запускать пакет ROS.



Для этого в ROS служат так называемые launch файлы. Суть launch файла — позволить запустить ноду, команду или несколько нод одной короткой командой без необходимости указывать в ней все аргументы и прочая.



Создадим в rosbots_description папку launch с файлом rviz.launch:



[code]roscd rosbots_description
mkdir launch; cd launch;
touch rviz.launch


*В этот и последующие разы уже нет необходимости создавать ROS-пакет как это делалось ранее. Теперь система сама будет «видеть» файлы внутри пакета. Поэтому мы просто создаем директорию.



Наполним файл содержимым — [spoiler=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>


[/spoiler]

Здесь видно, что при запуске система будет искать описание модели в rosbots.xacro.



Далее запустит 3-и ноды: joint_state_publisher из пакета joint_state_publisher, robot_state_publisher из robot_state_publisher, rviz из rviz. type -это тип ноды, как правило соответствует одноименному Python или С файлу, но указывается без расширения.



Запустим:



В 1-м терминале запустим ROS-мастер:



roscore


Во 2-м:



roslaunch rosbots_description rviz.launch


*Если выдало ошибку
ROS_MASTER_URI [http://192.168.1....:11311] host is not set to this machine
, то надо проверить bashrc — на каком ip запускается ROS:



nano ~/.bashrc


в самом файле bashrc указать ip виртуальной машины (например, такой):



export ROS_MASTER_URI=http://192.168.1.114:11311


далее перечитать bashrc:



source ~/.bashrc или перезагрузиться.

**

Если roslaunch все равно не запускается, то можно попробовать зайти в папку catkin_ws и выполнить: source devel/setup.bash



Погружаемся в Rviz



После выполнения команды, запустится Rviz-редактор и откроется графическая оболочка.

Визуальное представление может отличаться, но в целом вид будет примерно следующим:



Робот-тележка на ROS. Часть 4. Создаем симуляцию робота в rviz и gazebo


Слева в колонке Displays можно наблюдать опции отображения тех или иных элементов, взаимодействующих с нодами ROS, по центру — изображение робота, справа — колонка с камерой вида робота. Сразу надо сказать, что с rviz лучше работать с 3-х колесной мышью, так как все кнопки мыши здесь задействованы. Зажав левую можно повращать пространство в окне с отображением робота, зажав правую — приблизить/отдалить, зажав обе клавиши — перемещать пространство относительно робота.



В основном работа в редакторе ведется в первых двух колонках: Displays и Визуальном представлении робота.



Поработаем с видом робота



Выберем в строке «Fixed Frame» — «base link»:



Робот-тележка на ROS. Часть 4. Создаем симуляцию робота в rviz и gazebo


И добавим Robot Description в Displays:



Нажмем «Add» и в списке выберем «RobotModel»:



Робот-тележка на ROS. Часть 4. Создаем симуляцию робота в rviz и gazebo


Теперь в окне симуляции можно наблюдать робота, который был воспроизведен из модели rviz.xacro:



Робот-тележка на ROS. Часть 4. Создаем симуляцию робота в rviz и gazebo


Отлично. С визуальным представлением все ясно. Теперь необходимо понять как запустить симуляцию, потому как rviz лишь визуализация симуляции, но не сама симуляция.

То есть физика здесь не работает.



Сама симуляция живет в редакторе под названием Gazebo.



Gazebo



Чтобы поместить созданную модель в Gazebo, создадим еще один launch файл — spawn.launch в папке launch проекта. Теперь у нас 2 launch файла!



[spoiler=spawn.launch][code]



скачать.



Продолжение следует.

Источник: Хабр / Интересные публикации

Категория: Веб-разработка

Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь.
Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.

Добавление комментария

Имя:*
E-Mail:
Комментарий:
Полужирный Наклонный текст Подчеркнутый текст Зачеркнутый текст | Выравнивание по левому краю По центру Выравнивание по правому краю | Вставка смайликов Выбор цвета | Скрытый текст Вставка цитаты Преобразовать выбранный текст из транслитерации в кириллицу Вставка спойлера
Введите два слова, показанных на изображении: *