# 嵌套任务队列和信号发生器

{% embed url="<https://www.bilibili.com/video/BV1d97nzmEHj/>" %}

## 嵌套任务队列

您可以合并多个串口命令作为一个任务队列：

* 令牌是T\_TASK\_QUEUE（'**q**'）
* 使用'**q**'来开始任务队列
* 添加串口指令做为子命令
* 使用'**:**'来添加延迟时间（**必须**）
* 添加 '**>**' 来结束子命令

例如：***`qksit:1000>m 8 0 8 -30 8 0:500>`*** 将使机器人坐下然后移动肩关节。

## 对每个关节使用三角函数生成角度值，以组成平滑且周期性的运动

### 关节舵机旋转角度计算函数

```cpp
JointAngle[index]= signalGenerator(amplitude, midpoint, freq, phase, resolution, frame)
```

* 令牌是T\_SIGNAL\_GEN（'**o**'）
* 命令格式是：**o** 分辨率, 速度，关节序号1， 中位角度值，幅度， 频率，相位，关节序号2， 中位角度值， 幅度， 频率，相位，......\
  例如：o 1 0, 0 40 -20 4 0, 1 -30 20 4 30, 8 -70 10 4 60, 12 -10 10 4 0, 15 10 0 4 0
* 分辨率决定了它是如何增加到 360 ：t += 分辨率
* 速度定义了过渡速度。它将朝着目标角度移动\[1\~125]度。0 表示最大速度
* 频率定义了关节在一个循环中可以振荡的周期数。
* 相位取值范围是-120 到 120。比如相位=30 表示平移 Pi/2。因为120 是一个完整周期（2Pi）。
* 使用逗号或空格来分隔数字，使用逗号分组可以更清晰地表示一个关节的参数（frame）

### 代码实现计算公式

```cpp
for (int t = 0; t < 360; t += resolution)  
  angle = midpoint + 
         round(amp * sin(2.0 * M_PI * ((t + phase * 3 / freq) / (360.0 / freq))));
```

* 运动的迭代器从 0 循环到 360
* 例如，头的俯仰(对应关节序号1)/偏航角(对应关节序号0)可以绑定形成利萨如图形\
  `qksit:100>o 1 8, 0 0 30 4 0, 1 -30 30 4 30:100>o 1 0, 0 0 30 4 0, 1 -30 30 4 15:100>o 1 0, 0 0 30 4 0, 1 -30 30 8 30:100>o 1 8, 0 0 30 8 0, 1 -30 30 4 30:100>o 1 8, 0 0 30 4 0, 1 -30 30 16 30:100>o 1 0, 0 0 30 32 0, 1 -30 30 8 0:100>Wash face:qksit:100>i0 20 1 0 8 -70 12 0 15 10:0>o1 0, 0 40 -20 4 0, 1 -30 20 4 30, 8 -70 10 4 60, 12 -10 10 4 0, 15 10 0 4 0:100>m0 0 1 -20 2 0:0>ksit:0`

{% hint style="info" %}
详细实现，请参考 OpenCatEsp32/src/OpenCat.h 和 reaction.h 中的源代码。
{% endhint %}


---

# 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://docs.petoi.com/chinese/api/chuan-kou-xie-yi/qian-tao-ren-wu-dui-lie-he-xin-hao-fa-sheng-qi.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.
