Qt
bluetooth
JetsonTX1

Jetson TX1でPS3コントローラーを無線で利用する


ツールのインストールと初期設定

以下はすべてJetsonのコンソールで行う。

依存関係をインストールしておく。

$ sudo apt-get install libusb-dev

ペアリング用ツールのソースコードをダウンロードして、コンパイルする。

$ wget http://www.pabr.org/sixlinux/sixpair.c

$ gcc -o sixpair sixpair.c -lusb

PS3コントローラーをJetsonに接続し、sixpairを実行する。

$ sudo ./sixpair 

Current Bluetooth master: 00:04:4b:79:99:55
Setting master bd_addr to 00:04:4b:79:99:55

qtsixaをビルドする。

$ git clone https://github.com/falkTX/qtsixa.git

$ cd qtsixa

依存関係のインストール。

$ sudo apt install python-qt4 pyqt4-dev-tools qt4-designer libjack-jackd2-dev libbluetooth-dev

ビルド&インストール。

$ make

$ sudo make install

ペアリングする。

USBケーブルを抜いて、PS3コントローラを無線状態にする。

PS3コントローラーの後ろのリセットボタンを長押しして初期化する。

その後、下記コマンドを実行。

 $ sudo sixad -start &

sixad-bin[5850]: started
sixad-bin[5850]: sixad started, press the PS button now

PSボタンを押す。以下のメッセージが出て、PS3コントローラーが震えればペアリング成功。

sixad-sixaxis[6027]: Connected 'PLAYSTATION(R)3 Controller (04:98:F3:90:88:3A)' [Battery 04]

以下のコマンドを実行し、ボタンを押して何らかの出力があればOK。

$ sudo cat /dev/input/js0

sixadを起動時に常駐するようにする。

$ sudo vi /etc/rc.local

一番下に追加
sudo sixad -start &


検出処理

Qtでの使用例。


joystick.h

#include <thread>

#include <QObject>

class JoyStick : public QObject
{
Q_OBJECT

public:
explicit JoyStick(std::string dev);
~JoyStick();
enum ButtonEvent{
Up = 4, Down = 6, Left = 7, Right = 5, Triangle = 12, X = 14, Square = 15, Circle = 13,
L1 = 10, L2 = 8, L3 = 1, R1 = 11, R2 = 9, R3 = 2, Start = 0, Select = 3, PS = 16
};
enum AXISEvent{
LStick_X = 0, LStick_Y, RStick_X, RStick_Y, Acc_X, Acc_Y, Acc_Z,
UpPressure = 8, RightPressure, DownPressure, LeftPressure, L2Pressure, R2Pressure,
L1Pressure, R1Pressure, TrianglePressure, CirclePressure, XPressure, SquarePressure
};

private:
void polling();
void checkButton(unsigned char number, short value, ButtonEvent event);
void checkAxis(unsigned char number, short value, AXISEvent event);
int fd;
std::thread th;

signals:
void buttonPushed(ButtonEvent event);
void buttonReleased(ButtonEvent event);
void axisValueChanged(AXISEvent event, short value);
};



joystick.cpp

#include <fcntl.h>

#include <unistd.h>
#include <linux/joystick.h>

JoyStick::JoyStick(std::string dev)
{
fd = open(dev.c_str(), O_RDONLY);
if(fd != -1)
{
// using non-blocking mode
fcntl(fd, F_SETFL, O_NONBLOCK);

th = std::thread(&JoyStick::polling, this);
th.detach();
}
}

JoyStick::~JoyStick()
{
if(fd != -1) close(fd);
}

void JoyStick::checkButton(unsigned char number, short value, ButtonEvent event) {
if(number == event)
{
if(value == 1)
{
emit buttonPushed(event);
}
else
{
emit buttonReleased(event);
}
}
}

void JoyStick::checkAxis(unsigned char number, short value, AXISEvent event) {
if(number == event)
{
emit axisValueChanged(event, value);
}
}

void JoyStick::polling()
{
while(true)
{
js_event js;
read(fd, &js, sizeof(js_event));
switch (js.type & ~JS_EVENT_INIT)
{
case JS_EVENT_AXIS:
checkAxis(js.number, js.value, AXISEvent::LStick_Y);
checkAxis(js.number, js.value, AXISEvent::RStick_Y);
break;
case JS_EVENT_BUTTON:
checkButton(js.number, js.value, ButtonEvent::Up);
checkButton(js.number, js.value, ButtonEvent::Down);
checkButton(js.number, js.value, ButtonEvent::Left);
checkButton(js.number, js.value, ButtonEvent::Right);
checkButton(js.number, js.value, ButtonEvent::Triangle);
checkButton(js.number, js.value, ButtonEvent::X);
checkButton(js.number, js.value, ButtonEvent::Square);
checkButton(js.number, js.value, ButtonEvent::Circle);
checkButton(js.number, js.value, ButtonEvent::L1);
checkButton(js.number, js.value, ButtonEvent::L2);
checkButton(js.number, js.value, ButtonEvent::L3);
checkButton(js.number, js.value, ButtonEvent::R1);
checkButton(js.number, js.value, ButtonEvent::R2);
checkButton(js.number, js.value, ButtonEvent::R3);
checkButton(js.number, js.value, ButtonEvent::Start);
checkButton(js.number, js.value, ButtonEvent::Select);
checkButton(js.number, js.value, ButtonEvent::PS);
break;
default:
break;
}
usleep(1000);
}
}



参考サイト

http://booting-rpi.blogspot.com/2012/08/dualshock-3-and-raspberry-pi.html

https://github.com/dusty-nv/turbo2

https://qiita.com/KurokoSin/items/f0f2de392d52821e7fa6

https://www.usagi1975.com/27jul172303/