# 4.7.2 Моделирование поворотно-наклонной головки

Общая модель этого робота находится в файле *box\_robot\_with\_pan\_tilt\_head.xacro* в каталоге *rbx2\_description/urdf/box\_robot*. Этот файл почти такой же, как и файл *box\_robot\_with\_kinect.xacro*, который мы рассматривали ранее, хотя на этот раз мы  включили файл *box\_pan\_tilt\_head.urdf.xacro* вместо файла *kinect.urdf.xacro*. Сам файл box\_pan\_tilt\_head.urdf.xacro включает в себя *kinect.urdf.xacro*, а также ссылки и совместные определения сервоприводов и скобок. Таким образом, мы можем прикрепить камеру к кронштейну для наклона головы. Файл *box\_pan\_tilt\_head.urdf.xacro* также включает в себя другой файл под названием dynamixel\_box\_hardware.xacro. Этот файл определяет ряд свойств для хранения размеров сервоприводов и различных типов кронштейнов Dynamixel. Он также определяет коллекцию макросов, которые моделируют сервоприводы и скобки с помощью простых коробок. (Ниже мы будем использовать сетки для Pi Robot).

Мы не будем просматривать файлы серво URDF/Xacro построчно, как мы это делали с другими компонентами, так как это займет слишком много места. Основная идея заключается в том, что мы определяем связь для каждого сервопривода и кронштейна, а также стыки между ними. Однако, давайте, по крайней мере, посмотрим на пару блоков XML, которые иллюстрируют, как моделировать *revolute jointints*. Ссылаясь на файл *box\_pan\_tilt\_head.urdf.xacro*, следующие строки определяют шарнир *head\_pan* и соединение в терминах AX12 сервопривода и F3 кронштейна:

```
<dynamixel_AX12_fixed parent="head_base" name="head_pan_servo">
    <origin xyz="-0.012 0 ${-AX12_WIDTH/2}" rpy="${M_PI/2} 0 ${-M_PI/2}"/>
</dynamixel_AX12_fixed>

<bioloid_F3_head_revolute parent="head_pan_servo" name="head_pan_bracket"
joint_name="head_pan" ulimit="2.53" llimit="-2.53" vlimit="1.571" color="$ 
{color}">
    <origin xyz="0 ${AX12_WIDTH/2 + 0.005} 0.012" rpy="${-PI/2} ${PI/2} $ 
{PI}" />
        <axis xyz="0 0 -1" />
    </bioloid_F3_head_revolute>
```

Макрос под названием *dynamixel\_AX12\_fixed* находится в файле *dynamixel\_box\_hardware.xacro* и выглядит следующим образом:

```
<macro name="dynamixel_AX12_fixed" params="parent name *origin"> 
      <joint name="${name}_joint" type="fixed">
            <xacro:insert_block name="origin" /> 
            <parent link="${parent}_link"/> 
            <child link="${name}_link" />
      </joint>
      
      <link name="${name}_link"> 
            <inertial>
                  <mass value="0.00001" />
                  <origin xyz="0 0 0" />
                  <inertia ixx="1.0" ixy="0.0" ixz="0.0"
                  iyy="1.0" iyz="0.0" 
izz="1.0" />       </inertial>
      
      <visual>
            <origin xyz="0 0 0 " rpy="0 0 0" /> 
            <geometry>
                  <box size="${AX12_HEIGHT} ${AX12_WIDTH} ${AX12_DEPTH}"/> 
            </geometry>
            <material name="Black"/> 
      </visual>

      <collision>
            <origin xyz="0 0 -0.01241" rpy="0 0 0" />
            <geometry>
                  <box size="${AX12_HEIGHT} ${AX12_WIDTH} ${AX12_DEPTH}"/> 
            </geometry>
      </collision>
    </link>
</macro>
```

Этот макрос достаточно прямолинейный, он определяет ссылку как box с теми же размерами сервопривода *AX-12* и определяет фиксированный стык между собой и родителем, которым в данном случае является *head\_base\_link*.&#x20;

Второй приведенный выше макрос, *bioloid\_F3\_head\_revolute*, выполняет работу по фактическому панорамированию головы. Этот макрос также определен в файле *dynamixel\_box\_head\_hardware.xacro* и выглядит следующим образом:

```
    <macro name="bioloid_F3_head_revolute" params="parent name joint_name llimit 
ulimit color *origin *axis">
    <joint name="${joint_name}_joint" type="revolute">
    <insert block name="origin"/>
    <insert block name="axis"/>
    <parent link="${parent}_link"/>
    <limit lower="${llimit}" upper="${ulimit}" velocity="${vlimit}" 
effort="1.0" />
    <child link="${name}_link" /> 
</joint>

<link name="${name}_link"> 
    <inertial>
        <mass value="0.00001" /> 
        <origin xyz="0 0 0" /> 
        <inertia ixx="1.0" ixy="0.0"
ixz="0.0"         iyy="1.0" iyz="0.0" 
izz="1.0" />      </inertial>
<visual>
<origin xyz="0 0 0 " rpy="0 0 0" /> <geometry>
<box size="${F3_DEPTH} ${F3_WIDTH} ${F3_HEIGHT}"/> </geometry>
<material name="${color}"/>
</visual>

<collision>
    <origin xyz="0 0 0" rpy="0 0 0" /> 
    <geometry>
        <box size="${F3_DEPTH} ${F3_WIDTH} ${F3_HEIGHT}"/> </geometry>
      </collision>
    </link>
</macro>
```

Обратите внимание, что в этом случае тип соединения (выделенный жирным шрифтом выше) является реверсивным, а не фиксированным. Абсолютный шарнир принимает параметры нижней и верхней границы вращения, указанные в радиусах. Они задаются для конкретного шарнира путем передачи значений *${llimit}* и *${ulimit}* в коде выше. Сервопривод AX-12 имеет рабочий диапазон 300 градусов, то есть *150* градусов по обе стороны от центра. Значение 2.53 радиана, которое передается для нижней и верхней границ в приведенном выше определении *bioloid\_F3\_head\_revolute*, составляет около *145* градусов - всего чуть меньше, чем полный диапазон, поэтому мы не заставляем сервопривод работать в собственных пределах.&#x20;

Стык также принимает параметры скорости и усилия, которые являются ограничениями его динамики, которые должны соблюдаться реальным серворегулятором. Ограничение скорости в *1.571* радиан в секунду эквивалентно примерно *90* градусам в секунду, что является умеренно быстрым, особенно если сервопривод панорамирует камеру. Несмотря на то, что для отображения синтаксиса мы установили значение *1.0*, ни пакет dynamixel\_motor, ни arbotix не используют это значение.

Еще одним ключевым свойством *revolute joint* является этот тег *\<axis>*, также выделенный жирным шрифтом выше. Компоненты xyz тега осей обычно равны *0* или *1* и определяют ось вращения шарнира. Эти параметры передаются в качестве аргумента блока, называемого осью, аналогично тому, как мы передаем исходные параметры. В случае шарнира головки мы передаем значения *"0 0 -1"*, которые определяют вращение в отрицательном направлении *z*. В следующем разделе мы покажем, как определяются эти компоненты оси.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://normadii.gitbook.io/translate-book/4.7-dobavlenie-golovki-panoramirovaniya-i-naklona/4.7.2-modelirovanie-povorotno-naklonnoi-golovki.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
