⌨️

Futabaのトラックパッドの制御ロジックについて

2024/11/22に公開

これはなに?

どうもキーボードを作るうさぎです。

ここでは私が設計したFutabaというキーボードに搭載しているマルチタッチトラックパッドの制御ロジックを解説します。こんな記事、誰にも需要ないと思いますが、自分への備忘録も兼ねて解説していきます。

トラックパッドで実現している機能

Futabaに搭載しているトラックパッドには以下の操作に対応しています。

  • 1本指でのカーソル移動
  • 2本指での上下左右スクロール
  • 3本指・4本指での上下左右スワイプジェスチャ
  • 1から3本指までのタップとドラッグ&ドロップ

残念ながら指を開いたり、閉じたりするピンチ操作には非対応です。OS上はトラックパッドではなくマウスとして見えるため、ピンチ操作に対する重要性が低いのではないかという理由で実装を見送っています。

また、コントローラーICからジェスチャ情報を取得することもできますが、いまいち使い勝手が良くなかったため、すべての操作を独自実装で実現しています。

トラックパッドの状態管理

トラックパッドに採用している Azoteq社の iqs550 というコントローラーからは、様々な情報を取得することができますが、トラックパッドの制御に使用している情報は以下の3種類です。

  • 何本の指が触れているか
  • 指がどれくらい移動したか
  • トラックパッドに触れる強さはどれくらいか

これらの情報をもとに以下のような状態遷移を行い、各種機能を実現しています。

遷移図上の各状態は以下の処理を行います。

  • touch :
    指が触れただけの状態でまだ処理が未確定の状態。
  • move :
    触れた指の本数によりそれぞれ以下の処理を行う。途中で指の本数が変わった場合は切り替わる。
    • 1本の場合はカーソル移動
    • 2本の場合はスクロール
  • swipe :
    スワイプジェスチャ実行に備え、指の移動量を積算する。
  • swipe_fire :
    swipe状態で積算した移動量と触れていた指の本数に基づき、任意のキー入力を行う
  • press :
    マウスのボタン入力とカーソル移動を同時に行う。触れた指の本数によって入力するボタンが異なる。
    • 1本の場合はマウスの左ボタン
    • 2本の場合はマウスの右ボタン
    • 3本の場合はマウスの真ん中(ホイール)ボタン
  • wait :
    ドラッグを継続するための待ち時間。この時間中はマウスのボタン入力が維持されます。
    (トラックパッド端まで指を動かした場合用)

touch 状態から press 状態に移行する条件に一定時間以内に指を離したというものがありますが、これは弱い力でトラックパッドにタップした場合でもタップ入力を発火するためのものです。

また、この遷移図を素直に実装するとダブルタップしようとしても、 press 状態から wait 状態に移行するため、ダブルタップしずらくなってしまいます。そのため、presswaitpresswait と連続して変化した場合は一瞬キー入力を無効化することでダブルタップとして認識させるようにしています。もちろん、トリプルタップも問題なしです。

ここまで説明した機能のコードはこちらにあります。
必要に応じて自由にカスタマイズしてください。

https://github.com/geek-rabb1t/qmk_firmware/blob/7ea2afdc219e18f63c52eb62ee78c2fd672cc4ea/keyboards/futaba/futaba_azoteq_iqs5xx_driver.c#L236-L324

カーソル制御

もともと、カーソルの移動速度を制御しようなんて発想がなかったため、トラックパッドの出力をそのまま使っていたんですが、mass さんの以下のポストを見て、あ、カーソルの移動速度ってファームウェアで制御できるんだ!って気付き、制御を追加しました。

https://x.com/mass_0X00/status/1858173528408989869

当初はmass さんの実装(これはトラックボールの制御用)をほぼそのまま使って制御していたんですが、どうにもカーソルが飛ぶような挙動が発生し、違和感を覚えました。

そこで、いくつか試行錯誤を繰り返して、以下のような実装にしました。

https://github.com/geek-rabb1t/qmk_firmware/blob/7ea2afdc219e18f63c52eb62ee78c2fd672cc4ea/keyboards/futaba/futaba_azoteq_iqs5xx_driver.c#L347-L363

これは 以下の2つの処理を実行しています。

  • トラックパッドのカーソル移動量をそのまま使用せず、直前の移動量との平均をとる。
  • カーソルの移動速度に応じて、0.5倍 - 2.0倍 の間でカーソルの移動速度を増やす。

素直にそのまま実装しているわけではないので、わかりにくいかもしれませんが、やっていることはこれだけです。

まず、移動量の平均を使用するのは、トラックパッドに指を置いただけで、カーソルが微妙にブレる問題を抑止するためです。なんせ、横幅65mm しかないのに、解像度が 2048 もありますからね。指の震えや、無意識レベルの力の変化でカーソルが移動してしまいます。実装するまでは直前だけじゃ足りないかと思っていましたが、後述の処理と組み合わせたことで、意外にも一つ前の情報だけで抑止できました。

もう一つの移動速度の増加ですが、トラックパッド上で1ピクセルだけ移動するような細かい操作を行う際に、標準の出力では敏感すぎました。一方で、大きく動かしたいときには移動量が足らないという問題も発生しました。これらを解決するために、ゆっくり動かしたときにはよりゆっくりと、早く動かしたときにはより早くカーソルが動く仕組みは不可欠でした。そこで実装方法を試行錯誤した結果、カーソルの移動速度に応じて移動速度を変更する仕組みを採用しました。

おわりに

解説内容は記事投稿時のものです。
状態が増えたり、コードが整理されて別物になっているかもしれませんが、基本的な考え方としては利用できると思います。

Futabaに採用したトラックパッドはもともとTPS65という名前で販売されていたモジュールですが、ディスコンになってしまったため同じ形状になるように基板設計しています。そちらについても解説記事を書ければと思っています。

この記事はFutabaで書きました。
以上、自作キーボード界にトラックパッドを広げたいうさぎさんでした。

Discussion