ツールのインストールと初期設定
以下はすべて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/