カスタムコマンドの作成 – FlyWithLua

2023年7月24日

カスタムコマンドで何ができるか。他のコマンドと同じように自分で好きなように動かすことが出来るコマンドを作成することができるようになる。
一般的にはX-Planeに必要なコマンドはほとんど作成されているので、必要ないような気もするが、それでもカスタムコマンドを作成する必要はどんなときにあるのか。これを理解しておく必要がある。

OBS計器を例題としてカスタムコマンドを作って見る

このコマンドができたら、キー等に登録してそのキーを使ってOBSを回すことができる。5つのパラメーターを設定することができる。特に3番目のパラメーターが大事に成る。

OBSの方向を大きくするカスタムコマンドを作成します。
小さなスクリプトを作成して、Custom_Command_Test.luaという名前を付けましょう。

require("radio")
create_command("FlyWithLua/testing/increase_OBS",
               "This command increases the OBS value by one degree.",
               "OBS1 = OBS1 + 1",
               "",
               "")

最初のオプションは下の画像でもわかるようにコマンドパス名、2番目がキーボード、ジョイスティックに表示されるコマンドの説明、3番目が実際に実行するためのスクリプトになる。
OBS1は「require(“radio”)」から読み込まれた関数になる。

X-Planeを起動し「DataRefTool」で確認するとコマンドが作成されていることがわかる。

キーボード設定にもカスタムコマンドが表示される。

これはOBSの回転を1度増やすコマンドになる。下の「Actuate(作動)」ボタンで確認できるし、キー、ジョイスティックに割り当てることもできるようになる。

このように、実行の仕方がわかればカスタムコマンドを作成して自由にコマンドを作ることができる。

さらに詳しく説明すると:
最初の引数は一意のコマンド名です。この例では、FlyWithLua/testing/increase_OBSと名付けます。sim/…という名前を付けては駄目!。そうしないと、FlyWithLuaはエラーメッセージで停止します。

2番目の引数は、コマンドの説明です。ユーザーは、コマンドが何をしているのかを推測するためにこれらの説明(および名前)しか持っていないため、短くて正確な説明を提供するようにする。

3番目の引数は、Luaコードを含む文字列です。このコードは、コマンドの開始時に一度実行されます。サンプルコマンドは、割り当てられたボタンを押すたびに値が1つ増加することがわかります。

4番目と5番目の引数は、Luaコードを含む文字列で、4番目の引数はボタン(またはキー)が長押しされている間実行されるスクリプトを入れる、5番目はコマンドが終了したとき(ボタンまたはキーが解放される)に実行されるスクリプトを入れる。
この最初の例では、両方とも空です。このように何もしたくない場合は、空の文字列にする、つまり””は必ず入れる必要がある。そうしないと、引数が欠落しているというエラーメッセージが表示される。

この最後の2つを推測するかもしれませんが、最後の2つの議論はより重要です。
割り当てられたボタンを何度も押すと、最後には360°よりも高い値が表示されます。360°に達すると、OBS機器の回転を0°に交換する必要があります。360°を超える値は役に立ちません。

この状態は360になったら、0にOBSの値が成らなければならないのに360.1になるということです。
これを「DataRefTool」で確認することができる。
以下のdataref値は359.36545になっているのでワンクリックすると360度を超える。

この状態を設定して確かめるためには、カスタムコマンドで作成したコマンドをキーに割当てます。
キーをワンクリックしてみると、360.36545とオーバーした値が表示される。本当はここで0に戻って回転するのが本当です。計器は問題なく動いているが、dataref値は下の画面のように間違った値を表示している。カスタムコマンドで作成した通りにプラスを続けているからです。

更に本来の動きを確認するために、左下にあるOBSノブを回して確認すると、ちゃんと0になることがわかります。0丁度にはなっていないが360過ぎたら0から始まることはわかると思う。これが本来の値です。

そのため、最後の引数を使用して、コマンドが停止したときにクリーンアップ「0」にすることができます。
最後の””に以下のように入れる。この5番目のコマンドが停止したときの意味がここでは分かりにくい。
しかし、問題なく動作するので、理解できるまで保留とする。

require("radio")
create_command("FlyWithLua/testing/increase_OBS",
               "This command increases the OBS value by one degree.",
               "OBS1 = OBS1 + 1",
               "",
               "OBS1 = OBS1 % 360")

これによって、カスタムコマンドでも359の次は0になることを確認できる。

OBS1 % 360、の%は剰余の演算子になる。OBS1が360になったとき、最後の360で剰余すると余りは「0」になるということである。したがって、360°は0°になり、計器の次のターンが開始できることになる。

ボタンを押している間、フレームごとに実行され続ける

3番目の引数は1つずつクリックする必要があった。
4番目にこの引数を入れるとクリックしている間、回転させ続けることが出来るように成る。
4番目はキーを押し続ける間実行する引数だからである。

require("radio")
create_command("FlyWithLua/testing/increase_OBS",
    "This command increases the OBS value by one degree.",
    "",
    "OBS1 = OBS1 + 1",
    "OBS1 = OBS1 % 360")

これでキーを押している間、OBSは変化し続けることになる。非常に便利で使う確率が多いと思える。

これはフレームを1つしか押すことができないため、小さなステップを踏むことができなくなる。
つまり細かく1クリックずつクリックしたい場合もあるだろうということ。長押しして時間が来たら連続して回し続ける、時間がくるまでは1クリックで連続しないということになる。

require("radio")
local obs_up_time = 1
local ops_up_value = 1
create_command("FlyWithLua/testing/increase_OBS",
    "This command increases the OBS value by one degree.",
    "obs_up_time = os.clock()\n obs_up_value = OBS1",
    "OBS1 = 5 * (os.clock() - obs_up_time) + obs_up_value",
    "OBS1 = OBS1 % 360")

local obs_up_time = 1
local ops_up_value = 1

これにより、スクリプトがより高速になり、他のスクリプトとの競合が少なくなります。 値は必要ですが、現時点では不明であるため、1をランダムな値として使用します。

Lua関数os.clock()を使用します(FlyWithLuaではなく純粋なLuaです)。
関数os.clock()は、Luaエンジンが実行されている時間を秒単位で返します。
コマンドが開始されると、実際の値と時間をローカル変数に保存します。 文字列内にnが含まれる特殊文字のバックスラッシュに注意してください。
2行のコードを区切るために改行文字を作成します。 それを手放すと、FlyWithLuaはエラーメッセージを表示して動作を停止します。
次に、フレームごとにボタンまたはキーを押したままにして、秒単位の時間に5を掛けてOBSの値を増やします。5の値を変更して、ニーズに合わせて変更できます。

require("radio")
local obs_up_time = 1
local ops_up_value = 1
create_command("FlyWithLua/testing/increase_OBS",
    "This command increases the OBS value by one degree.",
    "obs_up_time = os.clock() + 2\n obs_up_value = OBS1\n OBS1 = obs_up_value + 1",
    "if os.clock() > obs_up_time then\n OBS1 = 10 * (os.clock() - obs_up_time) + obs_up_value\n end",
    "OBS1 = OBS1 % 360")

これで、2秒が経過したかどうかを確認するifステートメントができました。 2秒が過ぎたら連続回転に入ることになる。
その場合、値の乗数を10(または必要な値)に増やします。 コマンドの開始時に2秒が追加されます(3番目の引数)。 これにより、必要な計算を減らすことができます。

os.clock() os.time() の違い

LuaでCPU時間を求めるにはos.clock()を使う。プログラムの処理時間を計測する場合などに使う。
os.time()もあるが、ミリ秒ではなく秒数が返されるため、1秒以下の処理時間を計測するような場合はos.clock()を使用することになる。