UdonLibrary 1.0.0
機械システム研究部 C++ ライブラリ
読み取り中…
検索中…
一致する文字列を見つけられません
PS5 コントローラー

PadPS5クラスを用いることでメインマイコンから PS5 コントローラの情報を取得出来ます。

このクラスはテンプレートクラスになっており、受信クラスを指定します。CAN、I2C、E220、USB、Bluetooth などの通信方式に対応しています。

個別インクルード

インスタンス化

PadPS5クラスはテンプレートクラスになっており、引数に受信クラスを指定することで通信方式を選択できます。

引数に指定した受信クラスをPadPS5クラスが継承するため、受信クラスのメンバ関数をそのまま使用できます。同様にコンストラクタも継承されます。受信クラスのテンプレート引数には Message::PadPS5 が指定されます。

例えば CAN 経由でコントローラの情報を取得する場合、以下のように記述できます。

static Udon::PadPS5<Udon::CanReader> pad{ bus, id };
Teensy用 CANバスクラス
Definition CanBusTeensy.hpp:31
通信経由PS5コントローラークラス
Definition PadPS5.hpp:26

記述が長いため、エイリアスを使用することをお勧めします。

static Udon::CanPadPS5 pad{ bus, id };
その他の通信方式でのエイリアス

‍PC と USB ケーブルで接続すると使用できます。

static SivPadPS5 pad;
// static SivPadPS5 pad{ index }; // 複数コントローラを使用する場合

通信開始 (Optional)

本クラスは通信の管理は行わず、受信クラスから受け取ったデータの解析のみを行います。故に begin メンバ関数はありません。通信の開始処理が必要な受信クラスを使用している場合、通信開始処理を行う必要があります。

void setup()
{
pad.begin(); // 受信クラスに開始処理を行うメンバ関数がある場合
}

PadPS5 クラスに begin メンバ関数がないのに呼び出せているのは、PadPS5 クラスが受信クラスを継承していて、受信クラスの begin メンバ関数を引き継いでいるためです。

更新 (必須)

ループ内で update メンバ関数を呼ぶ必要があります。受信クラスに update メンバ関数が実装されている場合、自動的に呼び出されます。

void loop()
{
pad.update();
}
void update(int deadZone=20) noexcept
更新
Definition PadPS5.hpp:144

遠隔非常停止の実装

ロボコンのルール上、遠隔非常停止を実装する必要があります。他を顧みず実装するなら以下のように記述できます。コントローラが接続されているかは operator bool によって取得できます。

void loop()
{
pad.update();
if (pad and pad.getCross().toggle) // 接続されている、×ボタンを押し非常停止が解除された場合
{
omni.move(stick);
}
else
{
omni.stop();
}
}
Input getCross() const noexcept
×ボタン
Definition PadPS5.hpp:82
bool toggle
トグル値
Definition Input.hpp:58

bool 値を複数扱うと頭が混乱するため、PadPS5 クラスは非常停止を行うべきかを判断するための isEmergencyStop、また逆の動作可能かを判断するための isOperable メンバ関数を提供しています。内部的には上記の処理と同等です。

void loop()
{
pad.update();
if (pad.isOperable())
{
omni.move(stick);
}
else
{
omni.stop();
}
}
bool isOperable() const noexcept
動作可能であるか
Definition PadPS5.hpp:70

ボタン

次のようにボタンの状態を Input オブジェクトとして取得できます。

void loop()
{
pad.update();
Udon::Input input = pad.getTriangle();
Udon::Input input = pad.getCircle();
Udon::Input input = pad.getCross();
Udon::Input input = pad.getSquare();
Udon::Input input = pad.getUp();
Udon::Input input = pad.getRight();
Udon::Input input = pad.getDown();
Udon::Input input = pad.getLeft();
Udon::Input input = pad.getL1();
Udon::Input input = pad.getR1();
Udon::Input input = pad.getL2();
Udon::Input input = pad.getR2();
Udon::Input input = pad.getL3(); // 左スティック押し込み
Udon::Input input = pad.getR3(); // 右スティック押し込み
Udon::Input input = pad.getCreate(); // クリエイトボタン(左上ボタン)
Udon::Input input = pad.getOption(); // オプションボタン(右上ボタン)
Udon::Input input = pad.getTouch();
Udon::Input input = pad.getPs();
}
Input getDown() const noexcept
十字キー下
Definition PadPS5.hpp:94
Input getPs() const noexcept
PSボタン
Definition PadPS5.hpp:130
Input getCircle() const noexcept
○ボタン
Definition PadPS5.hpp:79
Input getRight() const noexcept
十字キー右
Definition PadPS5.hpp:91
Input getLeft() const noexcept
十字キー左
Definition PadPS5.hpp:97
Input getR3() const noexcept
右スティック押し込み
Definition PadPS5.hpp:115
Input getL2() const noexcept
L2ボタン
Definition PadPS5.hpp:106
Input getCreate() const noexcept
クリエイトボタン(左上ボタン)
Definition PadPS5.hpp:118
Input getL3() const noexcept
左スティック押し込み
Definition PadPS5.hpp:112
Input getUp() const noexcept
十字キー上
Definition PadPS5.hpp:88
Input getSquare() const noexcept
□ボタン
Definition PadPS5.hpp:85
Input getTriangle() const noexcept
▵ボタン
Definition PadPS5.hpp:76
Input getR2() const noexcept
R2ボタン
Definition PadPS5.hpp:109
Input getOption() const noexcept
オプションボタン(右上ボタン)
Definition PadPS5.hpp:121
Input getR1() const noexcept
R1ボタン
Definition PadPS5.hpp:103
Input getTouch() const noexcept
タッチパッドボタン
Definition PadPS5.hpp:124
Input getL1() const noexcept
L1ボタン
Definition PadPS5.hpp:100
入力値
Definition Input.hpp:16

Input オブジェクトは以下の様に定義されており、各ボタンの押された瞬間、離した瞬間等を取得できます。

struct Input
{
bool press; // 押されているか
bool click; // 押された瞬間か
bool release; // 離された瞬間か
bool toggle; // 押すごとに入れ替わる
};
// 三角ボタンが押されているか
const bool trianglePressed = pad.getTriangle().press;
bool press
押されているか
Definition Input.hpp:46

スティック

以下の関数から左右のスティックの値を Vec2 オブジェクトして取得可能です。Vec2 クラスの詳細は こちら

void loop()
{
pad.update();
Udon::Vec2 left = pad.getLeftStick();
Udon::Vec2 right = pad.getRightStick();
}
Vec2 getRightStick() const noexcept
右スティック [x,y: -255~255]
Definition PadPS5.hpp:136
Vec2 getLeftStick() const noexcept
左スティック [x,y: -255~255]
Definition PadPS5.hpp:133
二次元ベクトル
Definition Vector2D.hpp:22

Vec2 オブジェクトは以下の様に定義されており、各スティックの X, Y 軸の傾きを取得できます。スティックの上方向が X 軸の正、右方向が Y 軸の正です。

struct Vec2
{
double x; // -255 ~ 255
double y; // -255 ~ 255
};
// 左スティックのx軸の傾き
const double leftX = pad.getLeftStick().x;
ValueType x
X成分
Definition Vector2D.hpp:28

また、Stick オブジェクトを取得できる関数もあります。Stick オブジェクトとはロボットの移動に必要な入力成分 (移動: 左 X,Y、旋回: 右 X) をまとめたオブジェクトで、このオブジェクトを用いてオムニホイールの出力値を求めたりすることもできます。

Udon::Stick stick = pad.getMoveInfo();
Stick getMoveInfo() const noexcept
ロボットの移動に必要なスティックの情報 Udon::Stick オブジェクト {{x,y},turn} を取得
Definition PadPS5.hpp:140
ロボットの位置
Definition Position.hpp:26

Stick オブジェクトは以下の様に定義されています。

struct Stick
{
Vec2 vector; // 平行移動成分 (左スティック)
double turn; // 旋回成分 (右スティックのX成分)
};
// スティックからオムニの出力値を求める
const std::array<double, 4> omni = pad.getMoveInfo().toOmni();
std::array< double, N > toOmni() const
Definition Position.hpp:161

最終的なスケッチ例 (CAN バス経由)

#include <Udon.hpp>
static Udon::CanPadPS5 pad{ bus, 0x006 };
void setup()
{
Serial.begin(115200);
bus.begin();
}
void loop()
{
bus.update();
pad.update();
if (pad.getCircle().click)
{
Serial.println("circle clicked");
}
delay(1);
}
void update()
バス更新
Definition CanBusTeensy.hpp:89
void begin()
通信開始
Definition CanBusTeensy.hpp:37
bool click
押された瞬間か
Definition Input.hpp:52

メインマイコンと USB ホストシールドが直接接続されている場合

コントローラに内蔵されている LED や、バイブレーションを動作させられます。

#include <Udon.hpp>
void setup()
{
pad.begin();
}
void loop()
{
pad.update();
pad.setLightBar({ 0x38b48b }); // タッチパネルサイドLED (色指定可能)
pad.setMicLed(true); // マイクLED
pad.setPlayerLamp(); // タッチパネル下部LED (5つ)
pad.vibrate(100, 100); // 左右バイブレーションモーター
}