LinuxCNCでジョイスティック代わりにトラックボールを使う
経緯
我が家のNCフライスは,設置場所が想定以上に狭く,Z軸の調整用ハンドルが天井に当たってしまい,場合によっては接触して異音の原因となることがあった.調整用ハンドルを除去すれば問題は解決するが,エンドミルの位置決めなど,目視での軸移動が必要な際に不便であるのは必至であった.
そこで,Z軸調整の代替を目的としたジョイスティックを導入する.調整用ハンドルと同様に360度回転可能で,左右にひねれば上下し,材料にぶつかれば感触がフィードバックする機構があれば良い.しかし,現実的にはぶつかった感触を知るのは難しいので,前者の2つをサポートしてれば良い.
市販されている機器の中では,Kensington社が販売しているトラックボールのスクロールリング機能が,求めている機構と最も近い.幸い,4000円以下の廉価なモデルでもスクロールリングが備わっており,これをジョイスティックとして利用することにした.
XY軸移動用にトラックボールは役に立ちそうだが,一方の軸だけを動かす用途には向いていないだろう.アバウトな位置設定用として上手く利用したい.
▲Z軸当たってる
参考
Movement for atomic step(s) by mouse scroll wheel? - LinuxCNC
LinuxCNC Documentation Wiki: Simple Remote Pendant
Joystick D-pad - LinuxCNC
Index of /docs/html/man/man9
Basic HAL Tutorial
やたらと多ボタンなアナログコントローラをLinuxCNC2.5.1用に - Shimalith Web
使用したモデル
Kensington社のOrbitTrackball with Scroll Ring 72337JP
https://www.kensington.com/ja/jp/4493/72337jp/orbit-scroll-ring-trackball
https://www.amazon.co.jp/gp/product/B004QE4JXA/ref=oh_aui_detailpage_o00_s00?ie=UTF8&psc=1
購入時は3800円程度.トラックボール・スクロールリングの他,ボタンは2つのみ.
普段使いのマウスとしてはちょっとボタンが少なすぎるかも.LinuxCNCが提供しているDebian環境では特に問題も起きずに認識した.
▲LinuxCNCのShow Hal Configurationで見たトラックボールの状態(loadrt後).トラックボールだと各軸の座標が浮動小数ではない?(参考:Shimalith氏のページでのアナログパッドは浮動小数点を返している)
設定したい機能
トラックボール | XY軸移動に対応 |
スクロールリング | Z軸移動に対応 |
左クリック | ジョイスティック有効 |
右クリック | ジョイスティック無効 |
HAL
LinuxCNCではHALと呼ばれる,ちょっとした設定記述用言語が用意されている.これは,ワイヤードロジックっぽい感じで書かねばならず,C言語というよりかはHDL系の言語に近い.
例えば,クリックでスイッチのON/OFFを切り替える場合,if文で現在と過去のマウスボタンの状態を見てスイッチを変えましょう,というわけにはいかず,まずマウスボタンの現在の状態を2入力and素子で受け取り,その出力をnot素子を通してもう一方のand入力に接続することで過去の状態を取得する.ほとんどデジタル電子回路である.
LinuxCNC側の設定
トラックボールを検出するには,まず
$ less /proc/bus/input/devices
にて,デバイスの名前を確認する.これはhalコードでデバイスを指定するときに必要になる.今回のデバイスは「Eagle」が含まれており,これを利用する.
Xがマウスとして認識した場合には回避する必要があるらしいが,当環境では発生しなかったため,設定は割愛する.(参考:Movement for atomic step(s) by mouse scroll wheel?には書いてある)
次に認識したデバイスを一般ユーザーでも扱えるようにするために,udevの設定を変更する.
$ sudo echo '' >> /etc/udev/rules.d/99-rtai.rules $ sudo echo 'SUBSYSTEM=="input", MODE="0660", GROUP="plugdev"' >> /etc/udev/rules.d/99-rtai.rules
以上の設定が済めば,halrunコマンドの後に動作を確認する.
$ halrun halrun : loadusr -W hal_input -KRAL Eagle halrun :
halrunに何も言われなければOK.
MANを読め,みたいなことを言われたら,上のudevの設定が上手く行っていない可能性あり.その場合,rootで実行すれば成功する.
その他の設定のポイントを以下に示す.
- 各軸の移動とトラックボール・スクロールリングの移動を対応するには,input.0-rel-?-positionとaxis.?.jog-countsを接続すれば良いが,整数型から浮動小数点型に型変換する必要があるため,conv-floats-32を通して接続する必要がある.
- ジョイスティックの有効無効を左クリックと右クリックに対応させるにはRS型フリップフロップを用いて対応している.また,jog-enableを切り替えるとトラックボールのボタンが効かなくなる恐れがあるため,jog-scaleを変更し,左クリックが押されるとjogscale=0.1,右クリックが押されるとjogscale=0に設定される.
- 左クリックはbtn-mouse~を使用する.
halコード
# load remote joystick loadusr -W hal_input -KRAL Eagle # define components loadrt conv_float_s32 count=3 loadrt and2 count=2 loadrt not count=2 loadrt mux2 count=3 # set clock addf conv-float-s32.0 servo-thread addf conv-float-s32.1 servo-thread addf conv-float-s32.2 servo-thread addf and2.0 servo-thread addf and2.1 servo-thread addf not.0 servo-thread addf not.1 servo-thread addf mux2.0 servo-thread addf mux2.1 servo-thread addf mux2.2 servo-thread # setting joystick setp axis.0.jog-vel-mode 0 setp axis.1.jog-vel-mode 0 setp axis.2.jog-vel-mode 0 setp axis.0.jog-enable 1 setp axis.1.jog-enable 1 setp axis.2.jog-enable 1 # connecting as RS-FF; Q --> muxer.sel net rsff-sb and2.0.in0 <= input.0.btn-mouse-not net rsff-rb and2.1.in0 <= input.0.btn-right-not net rsff-nand-s and2.0.out => not.0.in net rsff-nand-r and2.1.out => not.1.in net rsff-qb not.1.out => and2.0.in1 net rsff-q not.0.out => and2.1.in1 mux2.0.sel mux2.1.sel mux2.2.sel # set muxer and connects for changing jog-scale setp mux2.0.in0 0 setp mux2.0.in1 0.01 setp mux2.1.in0 0 setp mux2.1.in1 0.01 setp mux2.2.in0 0 setp mux2.2.in1 0.01 net x-jog-scale mux2.0.out => axis.0.jog-scale net y-jog-scale mux2.1.out => axis.1.jog-scale net z-jog-scale mux2.2.out => axis.2.jog-scale # connecting moving trackballs with positioning axes, through float casting net x-float conv-float-s32.0.in <= input.0.rel-y-position net x-s32 conv-float-s32.0.out => axis.0.jog-counts net y-float conv-float-s32.1.in <= input.0.rel-x-position net y-s32 conv-float-s32.1.out => axis.1.jog-counts net z-float conv-float-s32.2.in <= input.0.rel-wheel-position net z-s32 conv-float-s32.2.out => axis.2.jog-counts
- 入力信号をnet文で2回以上使用するとエラーが出る.出力が複数にわたる場合(例えばRS-FFのQ端子)には,スペース区切りで複数指定可能.(参考:Basic HAL)
- 動作確認後,直感的な動作では無かったため,rel-x-positionとrel-y-positionを入れ替えた.
- RS-FFのR=S=1は禁止だから,同時に押すとどうなるのか気になるが,ソフトが落ちることは無かった.不定な動作になりそうだが.
動作確認
X軸Y軸の対応が直感的では無かったため修正したが,おおむね期待通り動作した,ジョイスティックだとトップスピードで軸移動するっぽいのが少し不安.
Z軸のスクロールリングは,1周で約80ノッチに相当しており,現在は,0.8mm/周で運用している.感覚的な不具合があれば追記したい.
▲適当に動かせば適当に動いてくれる