試験運用中なLinux備忘録・旧記事

はてなダイアリーで公開していた2007年5月-2015年3月の記事を保存しています。

PSX-CV02上のPlayStation 2コントローラの振動機能をGNU/Linux上で用いるための試行錯誤(Linux 2.6.31.5時点・第3回)

PSX-CV02上のPlayStation 2コントローラの振動機能をGNU/Linux上で用いるための試行錯誤(Linux 2.6.31.5時点・第2回)」の続き。

fftestコマンドによる振動のテスト

PSX-CV02上のPlayStation 2コントローラの振動機能をGNU/Linux上で用いるための試行錯誤(Linux 2.6.31.5時点・第1回)」「PSX-CV02上のPlayStation 2コントローラの振動機能をGNU/Linux上で用いるための試行錯誤(Linux 2.6.31.5時点・第2回)」の変更を加え、pantherlordドライバでの初期化が正常に終了した状態でfftestでの動作テストを行ってみた。コントローラは「I」のポートに入れている。
(「PSX-CV02上のPlayStation 2コントローラの振動機能をGNU/Linux上で用いるための試行錯誤(Linux 2.6.31.5時点・第2回)」に書いたように)HID_QUIRK_MULTI_INPUTによりデバイスが2つに分かれ、fftestで引数に指定するデバイスも2つになっているが、/dev/input/by-id/以下のシンボリックリンクは1つしかないので、別の方法でデバイス名を得ることにした。色々調べたところ/sys/class/input/js[番号]/device/内のディレクトevent[数字]の名前を用いることでジョイパッドデバイスの番号からイベントデバイスの番号が得られることが分かり

$ fftest /dev/input/$(ls -d /sys/class/input/js0/device/event* | sed 's:/sys/class/input/js[0-9]*/device/\(event[0-9]*\)/:\1:')

のようにすることとなった。js1の場合は上の「js0」の部分を「js1」にする。
実行すると下のように表示されて入力待ちとなる。

Force feedback test program.
HOLD FIRMLY YOUR WHEEL OR JOYSTICK TO PREVENT DAMAGES

Device /dev/input/event[数字] opened
Axes query:
Effects: Periodic Rumble
Number of simultaneous effects: 16
Upload effects[1]: Invalid argument
Upload effects[2]: Invalid argument
Upload effects[3]: Invalid argument
Enter effect number, -1 to exit

「Invalid argument」というのが気になったが

  • フォースフィードバックには振動以外の種類がある
  • pantherloadドライバは振動(FF_RUMBLE)のみサポートする(「Effects:」の行からも分かるように0番のFF_PERIODICも同様にサポートするが、振動の機能が用いられる)
  • 1から3番の効果は振動以外の種類の効果がソース内で指定されている

ということから、振動のテストには問題はない。0,4,5番についてはサポートされているために特にメッセージは表示されていない。
この状態で0,4,5のいずれかを入力してEnterを押すと、それぞれの番号に応じた設定により振動をテストする。終了するには「-1」を入れる。
安全のため、振動のテストをするときにはコントローラを手にしっかりと持っておくのがよい。
(2010/5/31)GTK+を用いた振動テストのGUIツールを「GNU/Linux上の振動対応ジョイパッドデバイスの振動テストを行うGUIツールを作成」で作成した。

結果
  • 0番:強弱両方の作動装置による振動
  • 4番:強いほうのみの...
  • 5番:弱いほうのみの...

となり、振動機能が動作することを確認できた。
4番と5番のテストでは振動する作動装置(actuator)が異なり、fftestのソースを変更しながらテストした限りでは、4番のほうは強さが可変

[struct ff_effect型構造体].u.rumble.strong_magnitude

の値を変化させることでこれよりも強くも弱くもできるが、5番のほうは

[struct ff_effect型構造体].u.rumble.weak_magnitude

0のときに止まるか0以外のときに動くかのどちらかのみで強さは一定のようだった(ハードウェア仕様的に強さの変更ができずにON/OFFのみになっていると思われる)。他の類似デバイス向けのドライバであるsmartjoyplus(hid-sjoy.c)では振動させるときの処理としてこの値は0か0以外かをチェックして0か1かを渡すだけにしていたりするようで(「right = (right != 0);」の行)、pantherlordドライバでは
[引用]ファイル名: /usr/src/linux-2.6.31.5-1mnb/drivers/hid/hid-pl.c より

static int hid_plff_play(struct input_dev *dev, void *data,
			 struct ff_effect *effect)
{
	struct hid_device *hid = input_get_drvdata(dev);
	struct plff_device *plff = data;
	int left, right;

	left = effect->u.rumble.strong_magnitude;
	right = effect->u.rumble.weak_magnitude;
	debug("called with 0x%04x 0x%04x", left, right);

	left = left * 0x7f / 0xffff;
	right = right * 0x7f / 0xffff;
(以下略)

strong_magnitudeとweak_magnitudeのそれぞれに0x7fを掛けている部分があるが、結局デバイス側が0か0以外かでON/OFFを切り替えているだけなので、デバイスによっては(値を変化させることに)意味はないが、このままでも動作に問題はないので、ここは修正しない。
strong_magnitudeのほうの処理については「0x7f」を掛けるというのが値としてどうなのかという点は気になったが、試しに0xffにしてみたところ、fftestの振動は強くなったが、(ユーザがプログラム側で指定する)strong_magnitudeの値をある程度大きくするとそれ以上は振動が強くならなくなってしまい、strong_magnitudeの上限値である0xffffまでの実際の強さの変化が分かる値としては0x7fが適切であるという印象があるので、ここも変更はしない。
strong_magnitudeやweak_magnitudeの上限についてはstruct ff_rumble_effect型の定義から符号なし16bitと分かるため、0xffff(65535)となる。fftestの4番の設定では(ソースを見ると)strong_magnitudeが0x8000(32768)という中間の値になっているため、弱く感じるかもしれないが、それでドライバ側の調整としては良いと言える。

(「PSX-CV02上の PlayStation 2コントローラの振動機能をGNU/Linux上で用いるための試行錯誤(Linux 2.6.31.5時点・第4回)」に続く)

関連記事:

使用したバージョン:

  • Linux 2.6.31.5-1mnb
  • input-utils(jstestやfftestなどのパッケージ) 20061008