XPLMNavigation – FlyWithLua

2023年5月6日

参照:FlyWithLua_Manual_en.pdf
https://github.com/nasa/XPlaneConnect/blob/master/xpcPlugin/SDK/CHeaders/XPLM/XPLMNavigation.h

9 XPLMNavigation

Sandy Barbour が提供する XPLMNavigation SDK パーツのすべての機能を使用できます。 詳細については、こちらをご覧ください:

http://www.xsquawkbox.net/xpsdk/mediawiki/XPLMNavigation

Lua で関数を使用する場合は、別のスペルを使用する必要があります。これは、Lua が複数の値を返すためにポインターを必要としないためです。 正しいスペルは、次の関数の説明に示されています。

無線航法施設(NAVAID) 航法援助施設

9.1 XPLMNavigation の関数

nav_reference = XPLMGetFirstNavAid() –ナビ参照

next_nav_reference = XPLMGetNextNavAid( inNavAidRef )— 次のナビ参照

first_nav_reference = XPLMFindFirstNavAidOfType( inType )— 最初のナビ参照

last_nav_reference = XPLMFindLastNavAidOfType( inType )— 最後のナビ参照

nav_reference = XPLMFindNavAid( inNameFragment, inIDFragment, inLat, inLon, inFrequency, inType)
inType以外NULL にすることができる。inLat、inLonは機体の位置。
このルーチンは、navデータベースの多くの検索機能を提供します。
XPLMFindNavAidは、タイプがinType内にあるすべてのnavaidを検索し(複数のタイプを一緒に追加することができます)、次のルールに基づいて見つかったnavaidを返します。
inLat(緯度)とinLon(経度)がNULLでない場合、そのlat/lonに最も近いnavaidが返されます。そうでなければ、最後に見つかったnavaidが返されます。
inFrequencyがNULLでない場合、考慮されるnavaidsはこの周波数と一致する必要があります。これにより、周波数データが公開されていない無線ビーコン(内部マーカーなど)が、修正や空港がスクリーニングされないことに注意してください。
inNameFragmentがNULLでない場合、名前にフラグメントを含むnavaidsのみが返されます。
inIDFragmentがNULLでない場合、IDにフラグメントを含むnavaidのみが返されます。
このルーチンは、いくつかの有用な検索を行う簡単な方法を提供します: *この頻度で最も近いnavaidを見つけます。*最寄りの空港を探してください。* IDが「KBOS」のVORを見つけます。* 名前に「シカゴ」が含まれている最寄りの空港を探します。

outType, outLatitude, outLongitude, outHeight, outFrequency, outHeading, outID, outName = XPLMGetNavAidInfo( inRef )
最後の(inRef)はXPLMFindNavAidの変数名を入れる。outとは出力の意味、

index_count = XPLMCountFMSEntries()

index = XPLMGetDisplayedFMSEntry()

index = XPLMGetDestinationFMSEntry()

XPLMSetDisplayedFMSEntry( inIndex ) 9.1.11 XPLMSetDestinationFMSEntry( inIndex )

outType, outID, outRef, outAltitude, outLat, outLon = XPLMGetFMSEntryInfo( inIndex )

XPLMSetFMSEntryInfo( inIndex, inRef, inAltitude)
XPLMSetFMSEntryLatLon( inIndex, inLat, inLon, inAltitude) 9.1.15 XPLMClearFMSEntry( inIndex )

If you have to use inType or outType, you will have to manage integer values, not strings. You
can use the variables (Lua does not know constants) XPLM_NAV_NOT_FOUND, xplm_Nav_Unknown, xplm_Nav_Airport, xplm_Nav_NDB, xplm_Nav_VOR, xplm_Nav_ILS, xplm_Nav_Localizer, xplm_Nav_GlideSlope, xplm_Nav_OuterMarker, xplm_Nav_MiddleMarker, xplm_Nav_InnerMarker, xplm_Nav_Fix, xplm_Nav_DME and xplm_Nav_LatLon.

inType または outType を使用する必要がある場合は、文字列ではなく整数値を管理する必要があります。 変数を使用できます (Lua は定数を認識しません)。

XPLMGetNavAidInfo( inIndex ) からの値 outReg は、スクリプトでは役に立たないため、Lua によって返されません。 9 番目の値が必要な場合は、常に nil の値が得られます。

show last metar and next airport.lua

ファイルのあるところ:https://github.com/X-Friese/FlyWithLua/blob/master/FlyWithLua/Scripts%20(disabled)/show%20last%20metar%20and%20next%20airport.lua

右上のメニューの下に表示される。

Last METAR: Sorry, no METAR, your next airport: JMSDF AB Omura(RJDU) [B738 at 23.7 fps]
前回の METAR: 申し訳ありません、METAR は無し。次の空港: JMSDF AB Omura(RJDU) [B738 at 23.7 fps]
※METARは、気象通報式の一種であり、航空気象情報を英数字によって通報するための書式(フォーマット)である。

-- 画面の上部に最後のメーターが表示され、次の空港も表示されます。さらに、FPS 値も表示されます。

-- FPS 計算にはローカルの DataRef が必要です
local frame_rate_ref = XPLMFindDataRef("sim/operation/misc/frame_rate_period")
local fps = 0

-- If the function calc_metar_and_airport() fails, we provide a dummy text.
-- This is important when Lua starts the script, and the drawing callback starts before the calculation.
-- 関数 calc_metar_and_airport() が失敗した場合、ダミー テキストを提供します。
-- これは、Lua がスクリプトを開始するときに重要であり、計算の前に描画コールバックが開始されます。
local last_metar_and_airport_info = "Something goes wrong!" --"何かがおかしい!"

-- また、文字列の長さをピクセル単位で指定する必要があります
local info_lenght = measure_string(last_metar_and_airport_info)

-- 関数を毎秒作成し、必要な情報を見つけます。
function calc_metar_and_airport()
    -- 最後のメタは事前定義された変数 XSB_METAR 内の文字列であり、オンラインのときにのみ入力されます。
    -- 次の空港の名前と位置を見つけるだけで済みます
    -- nav データベースへのインデックスのみを取得します LATITUDE と LONGITUDE は、飛行機の位置を表す事前定義されたデータリファレンスです。
    -- 検索値 (名前、ID、周波数) を気にしない場合は、nil 引数が使用されます。
    next_airport_index = XPLMFindNavAid(nil, nil, LATITUDE, LONGITUDE, nil, xplm_Nav_Airport)

    -- 見つけた空港の名前を調べてみましょう。すべての変数はローカルである必要があります。
    -- 他のスクリプトとの競合を避けるために変数で Lua を無駄にしません。
    local outID
    local outName

    -- 必要のないすべての出力は、変数 _ (ダミー変数) に送信できます。
    _, _, _, _, _, _, outID, outName = XPLMGetNavAidInfo(next_airport_index)

    -- 最後のステップは、プリント関数が読み取ることができるグローバル変数を作成することです
    fps = 1 / XPLMGetDataf(frame_rate_ref)
    last_metar_and_airport_info = string.format("Last METAR: %s, your next airport: %s (%s) [%s at %2.1f fps]", XSB_METAR,
        outName, outID, PLANE_ICAO, fps)
    info_lenght = measure_string(last_metar_and_airport_info, "Helvetica_12")
end

-- この関数は情報テキストのみを出力します。 フレームごとに計算する必要がある場合は、パフォーマンスが低下します。
function show_metar_and_airport()
    -- 定義済みの変数 SCREEN_WIDTH と SCREEN_HIGHT を使用してテキストを画面の上部に配置できますが、情報の長さをピクセルで指定する必要があります.
    glColor4f(1, 1, 1, 1)
    draw_string_Helvetica_12(SCREEN_WIDTH - info_lenght - 10, SCREEN_HIGHT - 15, last_metar_and_airport_info)
end

-- 関数をコールバックに登録する
do_often("calc_metar_and_airport()")
do_every_draw("show_metar_and_airport()") --ここで出力する。

last_metar_and_airport_info = string.format(“Last METAR: %s, your next airport: %s (%s) [%s at %2.1f fps]”, XSB_METAR, outName, outID, PLANE_ICAO, fps)

この中身は以下の5つからなっている
XSB_METAR = Last METAR: %s,:%sのところに Sorry, no METAR, が入る(航空気象情報)
outName = your next airport: %s (%s):%sJMSDF SB Omura(大村海上自衛隊の名称)が入る
outID = = your next airport: %s (%s):(%s)のところに(RJDU)が入る
PLANE_ICAO = [%s at %2.1f fps]:%sのところに C172 が入る
fps = [%s at %2.1f fps]:%2.1f にfpsの数値が入る ※見本ではinfのところに数値が入る

上のデータをimguiウインドウで表示してみる

--1番目のウインドウの作成
ihd_wnd = float_wnd_create(300, 100, 1, true)
float_wnd_set_position(ihd_wnd, 100, 100)
float_wnd_set_title(ihd_wnd, "Imgui Hello World")
float_wnd_set_imgui_builder(ihd_wnd, "ihd_on_build")
float_wnd_set_onclose(ihd_wnd, "closed_hello_world")

-- 画面の上部に最後のメーターが表示され、次の空港も表示されます。さらに、FPS 値も表示されます。
-- FPS 計算にはローカルの DataRef が必要です
local frame_rate_ref = XPLMFindDataRef("sim/operation/misc/frame_rate_period")
local fps = 0

function ihd_on_build(ihd_wnd, x, y)
  next_airport_index = XPLMFindNavAid(nil, nil, LATITUDE, LONGITUDE, nil, xplm_Nav_Airport)
  local outID
  local outName

  -- 必要のないすべての出力は、変数 _ (ダミー変数) に送信できます。
  _, _, _, _, _, _, outID, outName = XPLMGetNavAidInfo(next_airport_index)

  -- 最後のステップは、プリント関数が読み取ることができるグローバル変数を作成することです
  fps = 1 / XPLMGetDataf(frame_rate_ref)

  imgui.TextUnformatted(string.format("Last METAR: %s,\nyour next airport: %s (%s) \n[%s at %2.1f fps]", XSB_METAR,
    outName, outID, PLANE_ICAO, fps))
end

function closed_hello_world(wnd)
  local _ = wnd   -- Reference to window, which triggered the call.
end

FlyWithLua|15.3 Accessing DataRefs

非常に重要な問題は、DataRef が指すメモリ内の値が特殊なバイト構造を持っていることです。 DataRef 自体は、値の構造 (または長さ) に関係なく、最初のバイトのみを指します。 正しい方法で値にアクセスするのはあなたの役割です。

公式の DataRef リストの 2 列目にバイト構造が表示されます。 int、float、または double のみが見つかった場合、それは DataRef の背後にある単一の値です。 型の後ろに括弧がある場合、それはこの型の配列です。

DataRef の名前ではなく、2 番目の列のみを調べて型を調べます。 たとえば、»sim/cockpit/electrical/battery_array_on« は 8 つの整数値の配列ですが、»sim/weather/cloud_type[2]« は 1 つの整数値であり、2 つの値の配列ではありません。

DataRef へのアクセスが必要な場合は、まず参照を見つける必要があります。 関数 XPLMFindDataRef() を使用して参照を取得します。 例えば:

battery_ref = XPLMFindDataRef(“sim/cockpit/electrical/battery_array_on”) これで、参照アドレスが battery_ref という名前の変数に保存されました。 あなたがしたい場合は

3 番目のバッテリーをオンにするには、次のように DataRef の背後に格納されている値にアクセスする必要があります。

−− find out the reference
battery_ref = XPLMFindDataRef(“sim/ cockpit / electrical / battery_array_on”)
−− f i l l a table with the values from the DataRef
battery_array = XPLMGetDatavi( battery_ref , 0, 8)
−− change the value representing the third battery
battery_array [2] = 1
−− write the values back to X−Plane
XPLMSetDatavi( battery_ref , battery_array , 0, 8)

battery_ref = XPLMFindDataRef(“sim/ cockpit / electrical / battery_array_on”) battery_array = XPLMGetDatavi( battery_ref , 0, 8)

−− change the value representing the third battery

battery_array [2] = 1

−− write the values back to X−Plane

XPLMSetDatavi( battery_ref , battery_array , 0, 8)

このコードでは、battery_array[2] を変更して 3 番目のバッテリーをオンにします。 X-Plane の配列はすべて、レベル 1 (Lua のように) ではなく、レベル 0 (C/C++ のように) から始まります。 最後の値はbattery_array[7]です。 関数 XPLMGetDatavi() と XPLMSetDatavi() では、引数は »0, 8« で、位置 0 から開始して 8 つの値を取得/設定します。

すべてのバッテリーを 1 つのテーブルに入れて変更を加え、最後のステップですべてを X-Plane に書き戻すことができます。 値の取得と設定の間には、好きなだけコードを記述できます。 ただし、すべてを取得/設定する必要はありません。 3 番目の値にのみアクセスしたい場合は、代わりに次のようなコードを記述します。

— find out the reference
battery_ref = XPLMFindDataRef(“sim/ cockpit / electrical / battery_array_on”)
— fill a table with the values from the DataRef
battery_array = XPLMGetDatavi( battery_ref , 2, 1)
−− change the value representing the third battery
battery_array [2] = 1
−− write the values back to X−Plane
XPLMSetDatavi( battery_ref , battery_array , 2, 1)

単一の値にアクセスする場合でも、テーブルを使用することに注意してください。 DataRef が配列を指している場合は、「array-function」を使用する必要があります。

最新のコードを使用してアクセスする場合、FlyWithLua は常に単一の値に変換されます。 同じコードを最新のスタイルで記述すると、次のようになります。

−− define the connection to the third battery
dataref(“third_battery_on”, “sim/cockpit/electrical/battery_array_on”, “writable”, 2)
−− change the value of the third battery
third_battery_on = 1

最新のコード スタイルは短くなりますが、Lua テーブルに対して完全な配列を一度に取得/設定することは不可能です。

18.25 msgx, msgy = XPLMGetMouseLocationGlobal() 18 FLOATING WINDOWS

Returns the current mouse location in global desktop boxels. Unlike XPLMGetMouseLoca- tion(), the bottom left of the main X-Plane window is not guaranteed to be (0, 0)—instead, the origin is the lower left of the entire global desktop space. In addition, this routine gives the real mouse location when the mouse goes to X-Plane windows other than the primary display. Thus, it can be used with both pop-out windows and secondary monitors.

This is the mouse location function to use with modern windows (i.e., those created by XPLM- CreateWindowEx()).

Pass NULL to not receive info about either parameter.
“msgx” Name of variable to get global x mouse location of the created window. “msgy” Name of variable to get global y mouse location of the created window.

18.26 ssWidth, ssHeight = XPLMGetScreenSize()

This routine returns the size of the main X-Plane OpenGL window in pixels. This number can be used to get a rough idea of the amount of detail the user will be able to see when drawing in 3-d.

“ssWidth” Name of variable to get screen size width. “ssHeight” Name of variable to get screen size height.

18.27 bLeft, bTop, bRight, bBottom = XPLMGetScreenBoundsGlobal()

This routine returns the bounds of the “global” X-Plane desktop, in boxels. Unlike the non- global version XPLMGetScreenSize(), this is multi-monitor aware. There are three primary consequences of multimonitor awareness.

First, if the user is running X-Plane in full-screen on two or more monitors (typically configured using one full-screen window per monitor), the global desktop will be sized to include all X- Plane windows.

Second, the origin of the screen coordinates is not guaranteed to be (0, 0). Suppose the user has two displays side-by-side, both running at 1080p. Suppose further that they’ve configured their OS to make the left display their “primary” monitor, and that X-Plane is running in full-screen on their right monitor only. In this case, the global desktop bounds would be the rectangle from (1920, 0) to (3840, 1080). If the user later asked X-Plane to draw on their primary monitor as well, the bounds would change to (0, 0) to (3840, 1080).

Finally, if the usable area of the virtual desktop is not a perfect rectangle (for instance, because the monitors have different resolutions or because one monitor is configured in the operating system to be above and to the right of the other), the global desktop will include any wasted space. Thus, if you have two 1080p monitors, and monitor 2 is configured to have its bottom left touch monitor 1’s upper right, your global desktop area would be the rectangle from (0, 0) to (3840, 2160).

Note that popped-out windows (windows drawn in their own operating system windows, rather than “floating” within X-Plane) are not included in these bounds.

“bLeft” Name of variable for the left bounds of the “global” X-Plane desktop, in boxels. “bTop” Name of variable for the top bounds of the “global” X-Plane desktop, in boxels. “bRight” Name of variable for the right bounds of the “global” X-Plane desktop, in boxels. “bBottom” Name of variable for the bottom bounds of the “global” X-Plane desktop, in boxels.

18.28 tOS = XPLMGetAllMonitorBoundsOS()

18 FLOATING WINDOWS

This routine immediately calls you back with the bounds (in pixels) of each monitor within the operating system’s global desktop space. Note that unlike XPLMGetAllMonitorBounds- Global(), this may include monitors that have no X-Plane window on them.

Note that this function’s monitor indices match those provided by XPLMGetAllMonitorBound- sGlobal(), but the coordinates are different (since the X-Plane global desktop may not match the operating system’s global desktop, and one X-Plane boxel may be larger than one pixel).

This function returns the following values in a lua multi-dimensional table (an element for each monitor):

int MonitorIndex; int inLeft; int inTop; int inRight; int inBottom;

To access the values in FWL, use the following format: tOS[x].yyyy, where x = monitor number, and yyyy is table member.

Example for monitor 1: tOS[1].inLeft; tOS[1].inBottom; monitor 2: tOS[2].inLeft; tOS[2].inBottom

18.29 tGB = XPLMGetAllMonitorBoundsGlobal()

このルーチンは、X-Plane グローバル デスクトップ スペース内の各全画面 X-Plane ウィンドウの境界 (ボクセル単位) を直ちに呼び出します。 モニターが X-Plane ウィンドウで「覆われていない」場合、この方法ではその境界を取得できないことに注意してください。 同様に、X-Plane ウィンドウのみ (全画面モードではない) を備えたモニターは含まれません。

If X-Plane is running in full-screen and your monitors are of the same size and configured contiguously in the OS, then the combined global bounds of all full-screen monitors will match the total global desktop bounds, as returned by XPLMGetScreenBoundsGlobal(). (Of course, if X-Plane is running in windowed mode, this will not be the case. Likewise, if you have differently sized monitors, the global desktop space will include wasted space.)

Note that this function’s monitor indices match those provided by XPLMGetAllMonitorBound- sOS(), but the coordinates are different (since the X-Plane global desktop may not match the operating system’s global desktop, and one X-Plane boxel may be larger than one pixel due to 150% or 200% scaling).

This function returns the following values in a lua multi-dimensional table (an element for each monitor):

int MonitorIndex; int inLeft; int inTop; int inRight; int inBottom;

To access the values in FWL, use the following format: tOS[x].yyyy, where x = monitor number, and yyyy is table member.

Example for monitor 1: tOS[1].inLeft; tOS[1].inBottom; monitor 2: tOS[2].inLeft; tOS[2].inBottom