Dronecode Devマニュアル抜粋&翻訳 - Mixing and Actuators

#この記事は
前回の [Flight Tasks](https://qiita.com/sakaeda11/items/b471a6e80d0254571557) に引き続き、
Dronecode本家サイトの[Mixing and Actuators](https://dev.px4.io/master/en/concept/mixing.html)と[Custom Payload Mixers](https://dev.px4.io/master/en/concept/custom_mixer_payload.html)ページの抜粋・翻訳です。

※主に自分の理解用に書いています。

（今回は単なるグーグル翻訳がほとんどです。。おいおいちゃんと理解して整理していきます。)
そもそもMixer(ミキサー)っていうのが聞き慣れ無い概念ですが、[SlideShare:ドローンの仕組み](https://www.slideshare.net/ssuser8b64a9/abc2015s/5)をみてなんとなく理解しました。


# Mixing and Actuators
- Mixingとはコマンド(例えば右折しろ）を、アクチュエータ(モーター等)の操作コマンドに変換することを言う
- PX4ではMixingロジックを実際のコントロールから分離している。
    - 再利用性が向上する

## Control Pipeline
- コントローラは(-1〜+1などに)正規化された値をMixerに送信し、Mixerはそれに応じてそれぞれのアクチュエータを設定します。
- UARTやUAVCAN、PWMなどの出力ドライバーはそれをアクチュエータに即した値に変換します。

![mermaid_mixer_control_pipeline.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124098/a07044b3-a0d9-e7eb-7d30-ebff4169d7fa.png)



## Control Groups
- PX4には「コントロール(インプット)グループ」と「アウトプットグループ」がある。
- コントロール(インプット)グループの例
    - 姿勢
    - ジンバル
- アウトプットグループの例
    - 物理バス(8つのPWM出力など)

- シンプルな機体では、コントロール(入力)0番(ロール)はそのままアウトプット0番(補助翼)に接続される
- マルチコプターでは、コントロール(入力)0番(ロール)は4つすべてのモーターに接続される

### Control Group #0 (Flight Control)
- 0: roll (-1..1)
- 1: pitch (-1..1)
- 2: yaw (-1..1)
- 3: throttle (0..1 normal range, -1..1 for variable pitch / thrust reversers)
- 4: flaps (-1..1)
- 5: spoilers (-1..1)
- 6: airbrakes (-1..1)
- 7: landing gear (-1..1)

### Control Group #1 (Flight Control VTOL/Alternate)
>略

### Control Group #2 (Gimbal)
>略

### Control Group #3 (Manual Passthrough)
- 0: RC roll
- 1: RC pitch
- 2: RC yaw
- 3: RC throttle
- 4: RC mode switch (Passthrough of RC channel mapped by RC_MAP_FLAPS)
- 5: RC aux1 (Passthrough of RC channel mapped by RC_MAP_AUX1)
- 6: RC aux2 (Passthrough of RC channel mapped by RC_MAP_AUX2)
- 7: RC aux3 (Passthrough of RC channel mapped by RC_MAP_AUX3)


### Control Group #6 (First Payload)
>略

## Virtual Control Groups
> Virtual Control GroupsはVTOLのためのものなので、ここでは略

## Output Groups/Mapping
- 出力グループは(FMU PWMや、IP PWM、UAV CANなどの)一つの出力バスで、複数(通常8つ)の(-1〜+1)に正規化されたコマンドポートを持つ。
- コマンドポートはmixerを通してスケーリングされる

- mixerファイルは、マッピングされるべきそのアウトプットグループ(物理バス)を明示的には示していません。しかし、Mixerの目的はそのファイル名から推測され、システムの初期化スクリプト(startup scripts)で適切な物理バスにマッピングされます。


> 補足：
> - MAIN出力用の物理バスは常に同じとは限らないため、このアプローチが必要です。
>    - MAIN出力用の物理バスは、フライトコントローラがIOボードを持つか持たないかやモータコントロールにUAVCANを用いているかなどによって変わります。
> - デバイスの抽象化によって、スタートアップスクリプトはMixerファイルをその基盤に適切なデバイスドライバーにロードします。
> - UAVCANが利用可能な場合、Main Mixerは`/dev/uavcan/esc/`にロードされます。
>    - そうでない場合は`/dev/pwm_outpot0`にロードされます。
>    - `/dev/pwm_outpot0`デバイスはI/O boardとともにコントローラ上のIO driverにマッピングされます。
>    - board上のFMU driverはマッピングされません。
> - aux mixerファイルは、I/Oボードを持つPixhawkコントローラ上のFMU driverにマッピングされている、 `/dev/pwm_output1`デバイスにロードされます。

多数のコントロール(フライトコントロールや荷重などの入力)グループと多数のアウトプットグループ(バス)があるため、あるコントロールグループは複数のアウトプットグループにコマンドを送る事ができる様になっています。

![mermaid_mixer_inputs_outputs.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124098/b7e96204-1468-fefe-5bc3-2a07644337c7.png)

> 補足
> - 実際には、スタートアップスクリプトはmixersを一つのデバイス(アウトプットグループ)にロードしています。
> - これは技術的制約ではなくそういう設定です。
>    - Main mixerを複数のドライバーにロードすることはできますし、UAVCANとmain pinの両方に同じ信号をもたせる事もできます。

## PX4 Mixer Definitions
- Mixerは以下の**syntax**を用いたプレインテキストとして記述されます。
- 事前定義された機体用ファイルは[ROMFS/px4fmu_common/mixers](https://github.com/PX4/Firmware/tree/master/ROMFS/px4fmu_common/mixers)にあります。
    - これらはテストや、カスタムする際の元として利用できます。

### Mixer File Names
- Mixerファイルのファイル名は`XXXX.main.mix`というようなフォーマットになります。
    - この場合は`MAIN`アウトプット用のmixerファイルであることを示します。
    - AUXアウトプット用のmixerファイルの場合は`XXXX.aux.mix`となります。

### Mixer Loading
- ファームウェア内のデフォルトのミキサーファイルは[px4fmu_common/init.d/airframes/](https://github.com/PX4/Firmware/tree/master/ROMFS/px4fmu_common/init.d/airframes)に定義されています
    - これらはSDカード上の`/etc/mixers/`ディレクトリにある同名のmixerファイルによって上書きされます。
    - (SDカードのmixerファイルは優先的に読み込まれます)

- PX4は`XXXX.main.mix`というmixerファイルをMAINアウトプットに、`YYYY.aux.mix`というmixerファイルをAUXアウトプットにロードします。
    - プレフィックス(XXXXやYYYY部分)は機体や機体構成によって変わります。
- 一般的に、MAINとAUXアウトプットはMAINとAUX PWMアウトプットに対応しますが、UAVCANバスが有効な場合はそちらにロードされます。
- プレフィックスがXXXXなMAIN mixerのファイル名は、`set MIXER XXXX`(というコマンド?)によって機体構成に設定されています。
    - 例えば[airframes/10015_tbs_discovery](https://github.com/PX4/Firmware/blob/master/ROMFS/px4fmu_common/init.d/airframes/10015_tbs_discovery)では`set MIXER quad_w`(コマンド？)を呼び出し、`quadw._main.mix`をmain mixerファイルとしてロードしています。

- **YYYY**のプレフィクスで始まるAUX mixerのファイル名は機体設定やデフォルトに依存します。
    - ロードされるAUXファイルを明示的に指定するための**MIXER_AUX**を利用できます。
        - 例えば、機体構成において、`set MIXER_AUX vtol_AAERT` コマンドによって**vtol_AAERT.aux.mix**がロードされるようになります。
    - マルチコプターや固定翼機はデフォルトで**pass.aux.mix**をロードします。(上記MIXER_AUXを使わない場合)
        - **pass.aux.mix**は、ユーザが定義する4つのRCチャンネル値をAUXアウトプットの最初の4つに受け渡す、RCパススルーmixerです。
        - RCチャンネル値は[RC_MAP_AUXx/RC_MAP_FLAPS](https://dev.px4.io/master/en/advanced/parameter_reference.html#RC_MAP_AUX1)パラメータによって設定されます。
    - (一部省略)
    
※これらMixerファイルのローディング処理は[ROMFS/px4fmu_common/init.d/rc.interface](https://github.com/PX4/Firmware/blob/master/ROMFS/px4fmu_common/init.d/rc.interface)に実装されています。

### Loading a Custom Mixer
PX4はSDカードの`/etc/mixers/`ディレクトリから優先度に基づき適切なファイル名のmixerファイルを読み込みます。その後、ファームウェアのバージョンを読み込みます。

フライトコントローラのSDカードの`/etc/mixers`ディレクトリに通常のmixerと同名でファイルを置くとカスタムしたmixerを読み込ませることができます。

一般的な方法としては、既存機体のAUX mixerファイルを上書き/置き換えます。(大抵はRCパススルーmixerの`pass.aux.mix`を書き換えます)
詳細は上記の**mixer loading**を読んでください。

> 補足：
> 実行時にmixer読み込みコマンドを使って手動でロードさせることもできます。(最輝度をせず読み込ませられます)
> 例えば、`/etc/mixers/test_mixer.mix`を**MAIN PWM**出力にロードさせたい場合は、以下のコマンドを実行します。

`mixer load /dev/pwm_output0 /fs/microsd/etc/mixers/test_mixer.mix`

### Syntax (Mixerファイルの構文)
Mixerファイルは、
- テキストファイルです
- 複数のMixer定義を記述します
    - 「一つまたは複数の入力」と「一つまたは複数の出力」間のマッピングの定義

mixer定義には以下の4種類があります。
1. multirotor mixer：+(十字)またはx(斜め十字)構成で、4つか6つか8つのローター(回転翼)用のmixerです。
2. helicopter mixer：ヘリコプターの斜板サーボおよびメインモーターESCのmixerです。(テールローター(尾部回転翼)の出力定義はsumming mixerとして分離しています。)
3. summing mixer：ゼロまたは複数のコントロール入力を統合し、一つのアクチュエータ出力に変換するmixerです。入力はスケーリングされ、ミキシング関数は出力スケーラーを適用する前に結果を合計します。
4. null mixer：(ファイルセーフモード出ない場合に)出力がゼロのアクチュエータ出力を一つ生成するmixerです。

> 補足：
> multirotor mixerやhelicopter mixerはそれぞれのタイプ(マルチコプターやヘリコプター)に利用し、summing mixerはサーボやアクチュエータのコントロールに利用し、null mixerは通常利用時ゼロ出力させるために利用します。
> (たとえば、パラシュートではゼロ出力ですが、フェイルセーフ時には特別な値を持っている可能性があります。)
> VTOL mixerは他のmixerを組み合わせたものです。

それぞれのmixerから生成される出力の数は、mixerタイプと設定に寄ります。例えばmultirotor mixerは構成によって4,6,8のいずれかの数を出力しますが、summing mixerやnull mixerが生成する出力は1つだけです。

各ファイルでは複数のmixerを指定できます。出力順序(アクチュエータへのmixerの割当のこと)は、Mixer定義を読み取るデバイスに固定です。PWMデバイスの出力順序は宣言の順序と一致します。

例えば、multilotor mixerをクアッドコプター用に定義し、次にnull mixergミキサー、その次に2つのsumming mixerという順で定義した場合、最初の4つの出力はクワッドに割り当てられ、次に空の出力が割り当てられ、その次の2つの出力が割り当てます。

それぞれのmixer定義は以下の形式の行で始まります。

```
<tag>: <mixer arguments>
```
*tag*は以下のmixerタイプを選択します。

**R**: Multirotor mixer
**H**: Helicopter mixer
**M**: Summing mixer
**Z**: Null mixer

いくつかのmixer定義は上記のmixerタイプに続く**O**や**S**などの複数の*tag*から構成されます。

> 単一の大文字で始まり、その後にコロンが続く行以外は無視されます（なので、説明文を定義に自由に入れ込むことができます）。

#### Summing Mixer
Summing mixerは、アクチュエータとサーボ制御に使用されます。

シンプルなsumming mixerは、ゼロか複数の制御入力を単一のアクチュエータ出力に組み合わせます。
入力はスケーリングされ、ミキシング関数は出力スケーラーを適用する前に結果を合計します。

シンプルなミキサーの定義は以下のように始まります。

```
M: <control count>
O: <-ve scale> <+ve scale> <offset> <lower limit> <upper limit>
```
もし`control count`がゼロの場合、合計は実質的にゼロであり、ミキサーは`lower limit`と`upper limit`によって制約された`offset`である固定値を出力します。

上記二行目は、上で説明したスケーラーパラメーターを使用して出力スケーラーを定義します。
計算は浮動小数点演算として実行されますが、定義ファイルに格納されている値は10000倍にスケーリングされます。つまり、オフセット-0.5は-5000としてエンコードされます。

続いて、制御入力とそのスケーリングを説明する次の形式の`control count`があります。

```
S: <group> <index> <-ve scale> <+ve scale> <offset> <lower limit> <upper limit>
```
> なお、**S**の行は必ず**O**の行の後になります。

`group`の値は、スケーラーが読み取るコントロールグループを識別し、`index`の値は、そのグループ内のオフセットを識別します。これらの値は、ミキサー定義を読み取るデバイスに固有です。

複合的な車両の制御に利用する場合、0番目のミキサーグループは車両姿勢制御グループであり、0〜3番目のインデックス値は通常、それぞれロール、ピッチ、ヨー、および推力です。

行の残りのフィールドは、前述のようにパラメーターを使用してコントロールスケーラーを構成します。
計算は浮動小数点演算として実行されますが、定義ファイルに格納されている値は10000倍にスケーリングされます。つまり、オフセット-0.5は-5000としてエンコードされます。

[こちら](https://dev.px4.io/master/en/airframes/adding_a_new_frame.html#mixer-file)は典型的なミキサーファイルの例です。

#### Null Mixer
null mixerはコントロールを消費せず、常にゼロの値を持つ単一のアクチュエーター出力を生成します。

通常、null mixerは、アクチュエーターの出力の特定のパターンを実現するために、ミキサーのコレクションのプレースホルダーとして使用されます。
また、フェールセーフデバイスに使用される出力の値を制御するためにも使用できます。(通常の使用では出力は0です。フェイルセーフの間、ミキサーは無視され、代わりにフェイルセーフ値が使用されます)

null mixerの定義の形式は次のとおりです

```
Z:
```

#### Multirotor Mixer
multirotor mixerは、4つの制御入力（ロール、ピッチ、ヨー、推力）を組み合わせて、モーター速度コントローラーを駆動するためのアクチュエーター出力のセットにします。

ミキサーの定義は、次の形式の1行です

```
R: <geometry> <roll scale> <pitch scale> <yaw scale> <idlespeed>
```

`geometry`としてサポートされるものには以下があります。

4x - quadrotor in X configuration
4+ - quadrotor in + configuration
6x - hexacopter in X configuration
6+ - hexacopter in + configuration
8x - octocopter in X configuration
8+ - octocopter in + configuration

ロール、ピッチ、ヨーの各スケール値は、推力制御に対するロール、ピッチ、ヨー制御のスケーリングを決定します

計算は浮動小数点演算として実行されますが、定義ファイルに格納されている値は10000倍にスケーリングされます。つまり、係数0.5は5000としてエンコードされます。

ロール、ピッチ、およびヨー入力は-1.0〜1.0の範囲であることが期待され、推力入力は0.0〜1.0の範囲です。各アクチュエータの出力は、-1.0〜1.0の範囲です

Idlespeedの範囲は0.0〜1.0です。アイドル速度はモーターの最大速度に関連し、すべての制御入力がゼロのときにモーターが回転するように命令される速度です。

アクチュエータが飽和する場合、飽和しているアクチュエータ値が1.0になるように、すべてのアクチュエータ値が再スケーリングされます。


#### Helicopter Mixer
helicopter mixerは、3つの制御入力（ロール、ピッチ、推力）を4つの出力（斜板サーボとメインモーターのESC設定）に組み合わせます。

helicopter mixerの最初の出力は、メインモーターのスロットル設定で、次の出力は斜板サーボです。シンプルなミキサーを追加することで、テールローターを制御できます。

推力制御入力は、主モーター設定と斜板の集合ピッチの両方に使用されます。スロットルカーブとピッチカーブを使用します。どちらも5つのポイントで構成されています。

>スロットルカーブとピッチカーブは、「スラスト」スティックの入力位置をスロットル値とピッチ値に（別々に）マッピングします。これにより、飛行特性をさまざまなタイプの飛行に合わせて調整できます。曲線がどのように調整されるかについての説明は、この[ガイド](https://www.rchelicopterfun.com/rc-helicopter-radios.html)にあります（*Programmable Throttle Curves and Programmable Pitch Curves*を検索してください）。

ミキサーの定義は以下のように始まります。

```
H: <number of swash-plate servos, either 3 or 4>
T: <throttle setting at thrust: 0%> <25%> <50%> <75%> <100%>
P: <collective pitch at thrust: 0%> <25%> <50%> <75%> <100%>
```

T: スロットルカーブのポイントを定義します。 
P：ピッチカーブのポイントを定義します。両方の曲線には、0〜10000の範囲の5つのポイントが含まれています。単純な線形動作の場合、曲線の5つの値は0 2500 5000 7500 10000である必要があります。

この後に、次の形式で各斜板サーボの行が3つまたは4つ続きます。

```
S: <angle> <arm length> <scale> <offset> <lower limit> <upper limit>
```

`angle`は度単位で、0度は鼻(ヘリコプターの進行方向側の先端のこと？)の方向です。上から見ると、正の角度は時計回りです。

`arm length`は、10000が1に等しい正規化された長さです。すべてのサーボアームが同じ長さの場合、値は10000でなければなりません。アームの長さが大きいほど、サーボのたわみ量が減少し、アームが短いほど、サーボのたわみが増加します。

サーボ出力は、`scale`/10000でスケーリングされます。スケーリング後、`offset`が適用されます。オフセットは-10000から+10000の間でなければなりません。`lower limit`と`upper limit`は、サーボ範囲全体で-10000および+10000である必要があります。

summing mixerを追加することにより、テールローターをコントローラーにすることができます。

```
M: 1
S: 0 2  10000  10000      0 -10000  10000
```

これによってテールローターの設定がヨーコマンドに直接マッピングされます。これは、サーボ制御のテールローターと専用モーターを備えたテールローターの両方で機能します。

以下にブレード130ヘリコプターミキサーの例を挙げます。

```
H: 3
T:      0   3000   6000   8000  10000
P:    500   1500   2500   3500   4500
# Swash plate servos:
S:      0  10000  10000      0  -8000   8000
S:    140  13054  10000      0  -8000   8000
S:    220  13054  10000      0  -8000   8000

# Tail servo:
M: 1
S: 0 2  10000  10000      0 -10000  10000
```

- スロットル曲線はわずかに急な勾配から始まり、推力50％で6000（0.6）に到達します。
- 傾斜が緩やかであり、100％の推力で10000（1.0）に達します。 
- ピッチカーブは線形ですが、範囲全体を使用するわけではありません。
- スロットルが0％の場合、集合ピッチ設定はすでに500（0.05）です。
- 最大スロットルでは、コレクティブピッチはわずか4500（0.45）です。
- このタイプのヘリコプターに高い値を使用すると、ブレードが停止します。
- このヘリコプターの斜板サーボは、0、140、220度の角度で配置されています。
- サーボアームの長さが等しくありません。
- 2番目と3番目のサーボは、最初のサーボと比較して1.3054の比率で長いアームを持っています。
- サーボは機械的に拘束されているため、-8000および8000に制限されています。


#### VTOL Mixer

VTOLシステムは、マルチローター出力にmultirotor mixerを使用し、固定翼アクチュエーター（およびチルトローターVTOLの場合はチルトサーボ）にsumming mixerを使用します。

VTOL車両のミキサーシステムは、すべてのアクチュエーターがIOまたはFMUポートのいずれかに接続されている単一のミキサーに組み合わせるか、IO用とAUX用の別々のミキサーファイルに分割できます。
分割する場合は、すべてのマルチコプターモーターを1つのポートに配置し、すべてのサーボと固定翼モーターをもう1つのポートに配置することをお勧めします。


# Custom Payload Mixers

このトピックでは、カスタムペイロード（電磁グリッパーなど）をプログラムで制御するためのカスタムミキサーを追加する方法を示します。

このトピックは、既存のコントロールグループ定義がないペイロードタイプをサポートする開発者を対象としています（たとえば、ジンバルにはコントロールグループがありますが、グリッパーにはありません）。すでにミキシングとアクチュエーターを読んでいるはずです。

## Payload Mixer Example

ペイロードミキサーは、コントロールグループ＃6（最初のペイロード）の任意の関数値を特定の出力にマップする加算ミキサーです。次に、選択したコントロールグループ関数にuORBトピックを発行すると、それらの値が指定した出力にマップされます。 

この例では、RCパススルーミキサー（pass.aux.mix）に基づいてカスタムミキサーを作成します。 このミキサーは通常、大型マルチコプターのAUX PWMポートにロードされます。 ユーザー定義の4つのRCチャネル（RC_MAP_AUXx / RC_MAP_FLAPSパラメーターを使用して設定）の値を介して、AUX PWM出力の最初の4つの出力に渡されます。

```
# Manual pass through mixer for servo outputs 1-4

# AUX1 channel (select RC channel with RC_MAP_AUX1 param)
M: 1
S: 3 5  10000  10000      0 -10000  10000

# AUX2 channel (select RC channel with RC_MAP_AUX2 param)
M: 1
S: 3 6  10000  10000      0 -10000  10000

# AUX3 channel (select RC channel with RC_MAP_AUX3 param)
M: 1
S: 3 7  10000  10000      0 -10000  10000

# FLAPS channel (select RC channel with RC_MAP_FLAPS param)
M: 1
S: 3 4  10000  10000      0 -10000  10000
```

>ファイルは、4つの加算ミキサー（4つの出力用）を定義します。
> - M：1は、1つの制御入力（次のS行）によって定義される出力を示します。 
> - S：3nは、入力が制御グループ3（手動パススルー）のn <> th <>入力であることを示します。 したがって、S：3 5の場合、入力は「RC aux1」と呼ばれます（これはパラメーターRC_MAP_AUX1で設定されたRCチャネルにマップされます）。 
> - セクション宣言の順序は、物理バスに割り当てられたときの出力の順序を定義します（たとえば、3番目のセクションはAUX3に割り当てられる場合があります）。

まず、ミキサーファイルをコピーして、SDカードの`/etc/mixers/pass.aux.mix`に配置します（「[Mixing and Actuators > Loading a Custom Mixer](https://dev.px4.io/master/en/concept/mixing.html#loading_custom_mixer)」を参照してください。

ペイロードコントロールグループ関数の入力がある最初のセクションを削除します：



これを:

```
# AUX1 channel (control group 3, RC CH5) (select RC channel with RC_MAP_AUX1 param)
M: 1
S: 3 5  10000  10000      0 -10000  10000
```

このように変更します：

```
# Payload 1 (control group 6) channel 1
M: 1
S: 6 1  10000  10000      0 -10000  10000
```

この出力はファイルの最初の位置にあるため、最初のAUX PWM出力にマップされます（UAVCANが有効になっていない場合）。 この出力は、ペイロード制御グループ（6）の出力1への更新を尊重します。

制御グループ6もコードで定義する必要があります（忘れがちです！）

`/msg/actuator_controls.msg`のTOPICS定義に`actuator_controls_6`を追加します。ols.msg:

```
# TOPICS actuator_controls actuator_controls_0 actuator_controls_1 actuator_controls_2 actuator_controls_3 actuator_controls_6
```

- Increase NUM_ACTUATOR_CONTROL_GROUPS to 7 in the same file.
- Subscribe to the additional control group in the output library (/src/lib/mixer_module/mixer_module.cpp#L52) in the MixingOutput constructor. It should look like this:

- 同じファイルでNUM_ACTUATOR_CONTROL_GROUPSを7に増やします。
- MixingOutputコンストラクターの出力ライブラリー（[/src/lib/mixer_module/mixer_module.cpp#L52](https://github.com/PX4/Firmware/blob/master/src/lib/mixer_module/mixer_module.cpp#L52)）の追加のコントロールグループにサブスクライブします。

次のようになります。

```
  {&interface, ORB_ID(actuator_controls_0)},
  {&interface, ORB_ID(actuator_controls_1)},
  {&interface, ORB_ID(actuator_controls_2)},
  {&interface, ORB_ID(actuator_controls_3)},
```

```
  {&interface, nullptr},
  {&interface, nullptr},
  {&interface, ORB_ID(actuator_controls_6)},
```

グループ6に出力を配置するには、アクチュエータ制御グループ6を公開します。まず、パブリケーションを作成する必要があります。これは、PX4モジュールが初期化されるときに1回発生します（このパターンがすでに使用されている場所を探します）。

```
uORB::Publication<actuator_controls_s> _actuator_controls_pub{ORB_ID(actuator_controls_6)};
```

そして、このようなファーストメッセージを公開する必要があります

```
actuator_controls_s _act_controls{};
_act_controls.timestamp = hrt_absolute_time();
// set the first output to 50% positive (this would rotate a servo halfway into one of its directions)
_act_controls.control[0] = 0.5f;
_actuator_controls_pub.publish(_act_controls);
```