翻訳作業場トップページ このドキュメントは $FG_ROOT/Docs/Readme.Joysticks.htmlの日本語訳です。 ジョイスティック・キーボードの設定方法 †version 0.9.8.1 13/10/2005 Author John Check (FlightGear1.9.1添付バージョン) この文書はFlightGear0.7.7以降を対象として書かれています。
ジョイスティックがあなたのOS上で正常に認識され、動作しているという前提で書いています。この文書はLinuxユーザーの視点で書かれていますが、しかしこの情報は他のプラットフォームでも有効です。 いくつかの歴史 †初期のFGFSのジョイスティックの軸(Axis)/ボタン(button)と、キーバインディングはハードコードされていました。もしデフォルトのジョイスティックの設定を使用しない、もしくは違うキーバインディングを使いたい場合、ソースコードを修正して再コンパイルする必要がありました。 最も重要な事: †私は、ジョイスティックとキーボードについては後で書くつもりです。
訳者注:以降、joystick.xmlとkeyboard.xmlについての解説が主体となります。 XMLについて †あなたがこれを疑問に思っている時のために、XMLは「eXtensible Markup Language」と書いておきます。 さて、FGFSの場合では、私たちはあなたがジョイスティック/キーボードを構成するために必要とするタグを定義しました。XMLは階層的に組織化された構造を記述するのに適しています。FGFSで使用しているプロパティツリーのような、外部のアプリケーションへの内容です。あなたは、FGFSのためにXMLファイルを設定するには、以下の開始タグと終了タグをペアで記述しなければなりません。 <PropertyList> <!-- HTMLと同じように、<!-- -->で囲った部分はコメントです。 --> </PropertyList> [Help]>[Joystick Information]の情報からジョイスティックの情報を集める †注意:この項は原文が現状に追いついていないため、sambarが追加したものです。 今まではjs_demoでしかジョイスティックの情報を得ることが出来ませんでしたが、1.9.0ではもっと楽な方法があります。現在の段階ではまだ限られた情報しか得られませんが、いずれ改善されるでしょう。
これは、WindowsVista(x64)でCH Products製のヨークとラダーをジョイスティックに繋いだときの物です。WindowsVistaやXPでは、現在ジョイスティックの自動認識が正常に機能せず、日本語環境では「Joystick#0: Microsoft PC *W***C*X*e*B*b*N *h」と表示されることがあります。対処法は後述します。 幸運にも文字化けせずに、接続したジョイスティックの名前を検出できた場合は、それを元に自動で認識できるので、 読み込んだファイル名を確認して、正しいジョイスティック定義ファイルを読み込んでいるか確認してください。 もし正しいジョイスティック定義ファイルを読み込まず、デフォルトのジョイスティック定義ファイルを読み込んでいる場合 †
<PropertyList> <name>Saitek X45</name> <name>Saitek Saitek X45</name> <name>Saitek X45 Flight Controller USB</name> <name>Saitek X45 Flight Control Stick </name> <name>Saitek Saitek X45 Flight Control Stick </name> <!--ここまで元々ある行--> <name>Saitek X45 Flight Controller</name> <!--ここが追加した行 --> 「Joystick#0: Microsoft PC *W***C*X*e*B*b*N *h」と文字化けして表示された時の対処法 †$FGROOT/Joysticks.xmlを以下の要領で修正し、読み込むべきジョイスティック定義ファイルを手動で指定すると良いでしょう。 <js n="0" include="Input/Joysticks/Saitek/ST290-Pro.xml"/> もし適切なジョイスティック定義ファイルが見当たらない場合には「ジョイスティック定義ファイルが無い場合」を読んでください。 ジョイスティック定義ファイルが無い場合 †$FGROOT/input/Joysticks/Default/four-axis-joystick.xml内の<name>タグを、先ほどの[Joystick Information]で取得した自分のジョイスティック名に書き換えれば、「一応」飛べるようになります。 ただし、ジョイスティック名が文字化けしていた場合には、このファイルは「とりあえず」何もしないでおき、$FGROOT/Joysticks.xmlを以下のように書き換えてください。 <js n="0" include="Input/Joysticks/Default/four-axis-joystick.xml"/> そして、画面上の「Aileron」「Elevator」「Throttle」「Rudder」の数値を監視しながら、色々な軸を操作してください。 js_demoを使用して、ジョイスティックの出力をどのプロパティに割り当てるか決める †FlightGearには、かつてjs_demoユーティリティが同梱されていました。(1.9.0以降は同梱されていませんが、toshiさんのご好意により、FlightGear JPにアップロードされています) js_demoの典型的な出力 Joystick test program. ~~~~~~~~~~~~~~~~~~~~~~ Joystick 1 not detected <!-- ジョイスティック番号は0から始まります --> Joystick 2 not detected +--------------JS.0--------------+ | Btns Ax:0 Ax:1 Ax:2 | +--------------------------------+ | 0000 +0.0 +0.0 -1.0 | js_demoの内部では、button0は2進数で1の位、button1は2の位、button2は4の位・・・と扱われますが、画面上では16進数で表されます。
・・・といった要領で8000(button 15)まで続きます。 (訳注:16進数で表示されることを強調するため、0014から000aに変更) デフォルトでのジョイスティックのプロパティ †
じゃあ、今度は何をするか †先ほど集めたUSBジョイスティック(orジョイスティックポート)からの出力が何であるか分かったので、あなたは多分FGInputを今すぐ使いたいと思っているでしょう。もしこれ以前のFGFSのバージョンでジョイスティックを設定するのに慣れているなら、あなたは「コマンドマネージャ」セクションまでスキップできます。 「生」のジョイスティックの値を修正する †これらのコンセプトは、ジョイスティックバインディングに理由付けする事です。 軸のプロパティに対する修正順序はこのようになっています。
別の表現をすれば、下記のようになります。 cooked_value = (( raw_value > dead-band ) + offset) * factor 軸のプロパティは以下の通りです。 dead-band †-1 0 1 ............... -1 | | 1 ^ dead-band このエリア内の信号は無視されます。どんな信号も無視される範囲を作成することによってノイズや、品質の悪い電圧計/可変抵抗を補います。dead-bandは0位置に依存します。 offset †-1 0 1 ............. -1 ^ 1 offset 軸の操作範囲を広げたい場合に使用します。スロットル等、0が最小値になる場合で、ラダー等とは違ってセンターが無い場合に使用します。標準的には-1.0を使用します。 tolerance †ジョイスティックのジッターの補償に使われて、toleranceの本質は「gate」です。 factor †軸の操作量に対する「倍数」です。この値が小さいと、FGFS上での操作限界に達しないコントロールしかできなくなります。 コマンドマネージャ: †以前のFGFSはジョイスティックの出力で直接プロパティマネージャーを操作していました。FGFS v0.7.7以降は、操作した時にイベントを発生させてコマンドを実行するように変更されました。バインディングは効果があるようなコマンドを「指定しなければなりません」。都合が良いことに、コマンドのリストは大体2種類に分けられます。 (訳注:nasalスクリプトを組み込んだ場合、大抵飛行機の制御に使われるので、とりあえず後者に分類します) 描画・ファイル関連 †
飛行機の制御 †
バインディング †一つのコマンドを<binding> </binding>で束ねることで、1つのボタン/軸に複数のコマンドを割り当てる事ができます。 ジョイスティックの軸 †これはXMLでのジョイスティックの軸の設定サンプルです: <axis n="0"> <!-- 設定したい軸の番号を指定します --> <desc>Aileron</desc> <!-- 軸の概要について (無くても可) --> <binding> <!-- バインディングを開始します。 --> <command>property-scale</command> <!-- コマンドを指定します --> <property>/controls/flight/aileron</property> <!-- 割り当てたいプロパティを指定します --> </binding> <!-- バインディングタグを閉じます --> </axis> <!-- axisタグを閉じます --> 先ほど、プロパティツリーが階層構造であると書いたことを覚えていますか? 注意深い人なら、構造を保つにはタグを入れ子にする必要がある事に気付くでしょう。 --prop:/input/joysticks/js[0]/axis[0]/binding/command=property-scale --prop:/input/joysticks/js[0]/axis[0]/binding/property=/controls/flight/aileron コマンドラインオプションで階層構造を表現するためにどのようにパスを使用しているか見てみましょう。 本題に戻りましょう。"property-scale"コマンドは"offset"、"factor"の値を認識します。以下の例では"type"の値で、double形(倍精度浮動小数)を指定しています。 <axis n="2"> <desc>Throttle</desc> <!-- 下記の「dead-bandについての重要事項」も見てください --> <binding> <command>property-scale</command> <property>/controls/engines/engine[0]/throttle</property> <offset type="double">-1.0</offset> <factor type="double">-0.5</factor> </binding> </axis> もしくは --prop:/input/joysticks/js[0]/axis[2]/binding/command=property-scale --prop:/input/joysticks/js[0]/axis[2]/binding/property=/controls/engines/engine[0]/throttle --prop:/input/joysticks/js[0]/axis[2]/binding/offset=-1.0 --prop:/input/joysticks/js[0]/axis[2]/binding/factor=-0.5 dead-bandについての重要事項 †あなたは、先述の「ジョイスティックの値を修正する」セクションに書かれていた通り、dead-bandがコマンドマネージャの外で実行されることを思い出してください。 --prop:/input/joysticks/js[0]/axis[2]/dead-band=0.005 ジョイスティックのボタンのプロパティ †ボタンは本来ブーリアン型(true,falseの2つの値だけで表すデータ形式で、少しの事に使うことができます。これによって、瞬間的な動作、繰り替えし動作、普通の切り替え操作に使うことが出来ます。簡単にそれらができるように、ボタンの機能を変更するいくつかのタグがあります。 <repeatable> †
<step> †
<value> †
<mod-up> †
このサンプルは、XMLでのジョイスティックのボタンの宣言です。 <button n="1"> <!-- どのボタンかを指定します --> <desc>Elevator trim up</desc> <!-- ボタンの概要(必須ではありません) --> <repeatable>true</repeatable> <!-- Ok, repeatableの指定はコマンドマネージャの外でも可能です --> <binding> <!-- バインディングを開始します--> <command>property-adjust</command> <!-- コマンドを指定します。--> <property>/controls/flight/elevator-trim</property> <!-- 操作するプロパティを指定します--> <step type="double">0.001</step> </binding> </button> コマンドラインでは、以下のようになります。 --prop:/input/joysticks/js[0]/button[1]/repeatable=true <-- 見ての通り'binding'はありません --> --prop:/input/joysticks/js[0]/button[1]/binding/command=property-adjust --prop:/input/joysticks/js[0]/button[1]/binding/property=/controls/flight/elevator-trim --prop:/input/joysticks/js[0]/button[1]/binding/step=0.001 これは多少高度な設定例で、ボタン4を押した時に左車輪だけブレーキをかけ、ボタンを離すと自動的にブレーキが解除されます。 <button n="4"> <desc>Left brake</desc> <binding> <command>property-assign</command> <property>/controls/gear/brake-left</property> <value type="double">1.0</value> <!-- ブレーキは1.0に設定されます --> </binding> <mod-up> <!-- パーキングブレーキではないので、ボタンを離したら解除される必要があります --> <binding> <command>property-assign</command> <property>/controls/gear/brake-left</property> <value type="double">0.0</value> <!-- 1.0 がONで、0.0 がオフです --> </binding> </mod-up> </button> 初めのバインディングは簡単です:ボタンを押したら、property-assignコマンドが左ブレーキのプロパティ(この例では、/controls/gear/brake-left)の持つ値を1.0(この場合、フルブレーキ)に設定します。 コマンドラインのオプションで同じことをするなら: --prop:/input/joysticks/js[0]/button[4]/binding/command=property-assign --prop:/input/joysticks/js[0]/button[4]/binding/property=/controls/gear/brake-left --prop:/input/joysticks/js[0]/button[4]/binding/value=1.0 --prop:/input/joysticks/js[0]/button[4]/mod-up/binding/command=property-assign --prop:/input/joysticks/js[0]/button[4]/mod-up/binding/property=/controls/gear/brake-left --prop:/input/joysticks/js[0]/button[4]/mod-up/binding/value=0.0 各コンテキスト中に複数のバインディングを含むことができることを覚えておいてください。ここに、ボタン0が押された時に左右両方のブレーキを掛け、ボタンを離すと両方のブレーキが解除される、高度な例を挙げます。 <button n="0"> <desc>Brakes</desc> <binding> <command>property-assign</command> <property>/controls/gear/brake-left</property> <value type="double">1.0</value> </binding> <binding> <command>property-assign</command> <property>/controls/gear/brake-right</property> <value type="double">1.0</value> </binding> <mod-up> <binding> <command>property-assign</command> <property>/controls/gear/brake-left</property> <value type="double">0.0</value> </binding> <binding> <command>property-assign</command> <property>/controls/gear/brake-right</property> <value type="double">0.0</value> </binding> </mod-up> </button> これをXMLを使わず、同じことをコマンドラインオプションでやろうとするとこうなります。 --prop:/input/joysticks/js[0]/button[0]/binding[0]/command=property-assign --prop:/input/joysticks/js[0]/button[0]/binding[0]/property=/controls/gear/brake-left --prop:/input/joysticks/js[0]/button[0]/binding[0]/value=1.0 --prop:/input/joysticks/js[0]/button[0]/binding[1]/command=property-assign --prop:/input/joysticks/js[0]/button[0]/binding[1]/property=/controls/gear/brake-right --prop:/input/joysticks/js[0]/button[0]/binding[2]/value=1.0 --prop:/input/joysticks/js[0]/button[0]/mod-up/binding[0]/command=property-assign --prop:/input/joysticks/js[0]/button[0]/mod-up/binding[0]/property=brakes[0] --prop:/input/joysticks/js[0]/button[0]/mod-up/binding[0]/value=0.0 --prop:/input/joysticks/js[0]/button[0]/mod-up/binding[1]/command=property-assign --prop:/input/joysticks/js[0]/button[0]/mod-up/binding[1]/property=brakes[1] --prop:/input/joysticks/js[0]/button[0]/mod-up/binding[1]/value=0.0 デジタルHATスイッチ †多くのジョイスティックにはHATスイッチが付いています。これは軸というより、単に4つ(or8つ)のボタンですが、FGFSでは各軸の末端にそれぞれ仮想的なボタンを与えていて、これらの仮想ボタンは"low"と"high"の下位のプロパティを通して指定することができるので、一般のボタンのプロパティのどれでも受け入れることができます。 たとえば、あなたがちょうど表示方向をコントロールしたいならば、あなたは/sim/view/axes/long と /sim/view/axes/latのために、2本の軸を割り当てる事ができます。 <axis n="5"> <binding> <command>property-adjust/command> <property>/sim/view/axes/lat</property> <step>2.0</step> </binding> </axis> <axis n="6"> <binding> <command>property-adjust</command> <property>/sim/view/axes/long</property> <step>2.0</step> </binding> </axis> もしくは --prop:/input/joysticks/js/axis[5]/binding/command=property-scale --prop:/input/joysticks/js/axis[5]/binding/property=/sim/view/axes/lat --prop:/input/joysticks/js/axis[5]/binding/step=2.0 --prop:/input/joysticks/js/axis[6]/binding/command=property-scale --prop:/input/joysticks/js/axis[6]/binding/property=/sim/view/axes/long --prop:/input/joysticks/js/axis[5]/binding/step=2.0 (訳注:この記述、特にプロパティ名は古いです。) 他にも、垂直/水平に2Dパネルをスクロールするために、ボタンとしてHATスイッチを使用したいなら、あなたは<high>と<low>を使用できます。 下記の例は、<high>と<low>を使って、軸をエレベータートリムの調整に使用する場合です。 <axis n="1"> <low> <repeatable>true</repeatable> <binding> <command>property-adjust</command> <property>/controls/flight/elevator-trim</property> <step type="double">0.001</step> </binding> </low> <high> <repeatable>true</repeatable> <binding> <command>property-adjust</command> <property>/controls/flight/elevator-trim</property> <step type="double">-0.001</step> </binding> </high> </axis> --prop:/input/joysticks/js/axis[1]/low/repeatable=true --prop:/input/joysticks/js/axis[1]/low/binding/command=property-adjust --prop:/input/joysticks/js/axis[1]/low/binding/property=/controls/flight/elevator-trim --prop:/input/joysticks/js/axis[1]/low/binding/step=0.001 --prop:/input/joysticks/js/axis[1]/high/repeatable=true --prop:/input/joysticks/js/axis[1]/high/binding/command=property-adjust --prop:/input/joysticks/js/axis[1]/high/binding/property=/controls/flight/elevator-trim --prop:/input/joysticks/js/axis[1]/high/binding/step=-0.001 下のコマンドラインオプションで、リピート間隔を設定できます。リピート間隔を0.05秒にした場合、1秒間に20回繰り返されます。それには、下のオプションを追加してください。 --prop:/input/joysticks/js/axis[1]/interval-sec=0.05 あなたは、いくつかの軸をブレーキに割り当てる事ができます。そのためには、0.0(ブレーキ無し)と1.0の間の位置を使うことができます(フルブレーキ) キーボードの設定 †キーボードのキーバインディングは、以下の例のようにジョイスティックのボタンのバインディングとほとんど同じです(コンテキストは/input/keyboardです): <key n="1"> <name>Ctrl-A</name> <desc>Toggle autopilot altitude lock.</desc> <binding> <command>property-toggle</command> <property>/autopilot/locks/altitude</property> </binding> </key> あなたはまず、いくつかの事に気が付くでしょう。 最初に、インデックス(<key n="m">)で、あなたがバインディングする主要なコードを指定します。この例では、1は<name>で指定しているように、Ctrl+Aに相当します。 --prop:/input/keyboard/key[1]/binding/command=property-toggle --prop:/input/keyboard/key[1]/binding/property=/autopilot/locks/altitude ('propaty-toggle'コマンドは、trueとfalseの切り替えを行います。従って、プロパティ値以外の物は要りません。)インデックスを省略しないでください!!! 2つ目は、キーの方がジョイスティックのボタンよりも多くの修飾が出来ます。"mod-up"(キーを離した時に作動)に加えて、キーの場合は"mod-alt", "mod-ctrl", "mod-shift"
を使う事ができます。 <key n="49"> <name>1</name> <mod-shift> <desc>Look back left</desc> <binding> <command>property-assign</command> <property>/sim/view/goal-offset</property> <value type="double">135</value> </binding> </mod-shift> </key> この例では、'1'キーとShiftキーを同時に押した場合に、左後ろを見るように視界を切り替えます。 FightGearの使っているinputモジュールは、controlとshiftの同時押しを自動で取得するよう試みます。 --メモ: 32より小さいキーコードはコントロールキャラクタを暗に含むので、以前はctrl-Aのバインディングに入れ子の"mod-ctrl"要素を使う必要はありませんでした。(翻訳自信なし) また、新しい入力モジュールは、キーボードのkey-upイベントを検出できるので、タッチに敏感なブレーキ等もジョイスティックと同じように記述できます。 <key n="44"> <name>,</name> <desc>Left brake</desc> <binding> <command>property-assign</command> <property>/controls/gear/brake-left</property> <value type="double">1.0</value> </binding> <mod-up> <binding> <command>property-assign</command> <property>/controls/gear/brake-left</property> <value type="double">0.0</value> </binding> </mod-up> </key> 今度は、別の方法でブレーキの設定のバインディングをします。この例では、<mod-up>タグが無いので、パーキングブレーキのように働きます。 <key n="66"> <name>B</name> <desc>Toggle parking brake on or off</desc> <binding> <command>property-toggle</command> <property>/controls/gear/brake-parking</property> </binding> </key> nasalスクリプトの使い方 †注意:この項はsambarが勝手に追加したものです。 FlightGearには、Nasal というスクリプト言語が実装されていて、ジョイスティックやキーボードの設定ファイルに組み込んだり、あるいは設定ファイルから呼び出したりしてスクリプトを実行する事ができます。 これは、ボタン5にギアダウンを割り当てる時の設定です。(Input/Joysticks/CH/pro-yoke-usb.xmlより) <button n="5"> <desc>Gear down</desc> <repeatable>false</repeatable> <binding> <command>nasal</command> <!--ここで、nasalを使用しますよ〜、と宣言 --> <script>controls.gearDown(1)</script> <!-- <script>と、</script>の間に実行したいスクリプトを書いてください。 </binding> <mod-up> <binding> <command>nasal</command> <script>controls.gearDown(0)</script> </binding> </mod-up> </button> これは、$FGROOT/nasal/controls.nas内のgearDown関数に、ボタンを押した時に1、ボタンを離したら0を引数として与えて実行しています。 var gearDown = func(v) { if (v < 0) { setprop("/controls/gear/gear-down", 0); } elsif (v > 0) { setprop("/controls/gear/gear-down", 1); } } この関数では、与えた引数が正なら車輪を下げ、負なら車輪を上げます。なお、ゼロなら何もせず現状を維持します。 つまり、この例では"property-assign"を使って、同じ動作をさせるバインディングは以下のようにも書けます。 <button n="5> <desc>Gear down</desc> <repeatable>false</repeatable> <binding> <command>property-assign</command> <property>/controls/gear/gear-down</property> <value>1<value> </binding> </button> なお、「どちらのアプローチで書くのが良いか」については残念ながら「やりたい事次第」としかお答えできませんが、例えば「エレベータにGリミッターを付け加えたい」場合など、やや複雑な処理をしたい場合には後者のアプローチの方が良いでしょう。 翻訳開始 2009/03/22 sambar |