オンラインマップのリアルタイム位置表示とナビゲーション
1510字程度約5分
概要
オンラインマップのリアルタイム位置表示とナビゲーションは、双方向 Navi WebSocket を起動し、現在位置と向きをオンラインマップへ送信します。また、マップ側から受け取ったウェイポイントを順番にたどって移動します。
コントローラー
待受アドレス
デフォルトは
0.0.0.0です。通常は変更しないでください。待受ポート
リアルタイム位置表示で使用するポートです。マップサイト側の設定と同じ値にしてください。
到達許容範囲
ウェイポイントに到達したかどうかを判定する許容範囲です。通常は変更不要です。
サンプリング間隔
スクリーンショットによる位置推定の最小間隔です。最低値は 0.05 秒に制限されます。
小さくすると更新頻度は上がりますが、負荷が増え、安定性が下がる可能性があります。
方向推論バックエンド
方向モデルに使用する推論バックエンドを選択します。通常は変更不要です。
デバッグモード
意味が分からない場合は変更しないでください。
マップサイト関連インターフェース
注意
このセクションは更新が遅れる場合があります。
関連情報
マップサイトの座標はゲーム座標へ変更されています。以下の内容はまだ完全には更新されていません。
オンラインマップは WebSocket でナビゲーションサービスと通信します。デフォルトアドレスは ws://127.0.0.1:14514 です。マップサイトは「リアルタイム位置表示」を有効にした後にのみ接続し、異常切断時は 2 秒ごとに自動再接続します。
すべてのメッセージは UTF-8 エンコードの JSON テキストです。各 WebSocket テキストフレームには 1 つの JSON オブジェクトが入ります。
座標系
ピクセル座標を使用します。原点は画像左上、pixelX は右方向、pixelY は下方向に増加します。現在の位置表示座標系は 11264 × 11264 です。
マップサイトから送信されるメッセージ
| メッセージタイプ | 用途 |
|---|---|
navi-route-set | ウェイポイントを含むルートを設定し、必要に応じてすぐ開始する |
navi-route-start | 現在のルートを開始または再開する |
navi-route-stop | 現在のルートを一時停止する |
navi-route-clear | 現在のルートを消去する |
navi-route-set
{
"type": "navi-route-set",
"sourceWidth": 11264,
"sourceHeight": 11264,
"start": true,
"waypoints": [
{ "pixelX": 5700.125, "pixelY": 8800.5 },
{ "pixelX": 5800, "pixelY": 9000 }
]
}| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
sourceWidth | number | はい | 座標ソースの幅 |
sourceHeight | number | はい | 座標ソースの高さ |
start | boolean | はい | true は設定後すぐ開始、false はルート設定のみ |
waypoints | array | はい | ウェイポイント一覧。少なくとも 1 つ必要 |
送信前に隣接する重複ウェイポイントは自動で削除され、座標は最大 3 桁の小数に丸められます。
残り 3 つのコマンドは type フィールドのみを必要とし、追加パラメータはありません。
サーバーから送信されるメッセージ
| メッセージタイプ | 用途 |
|---|---|
navi-state | リアルタイム位置、向き、ルート状態を送信する |
navi-route-ack | ルートコマンドを確認し、ルート状態を返す |
navi-error | 業務エラーを返す |
navi-state
{
"type": "navi-state",
"version": 1,
"position": { "pixelX": 5788, "pixelY": 8902, "sourceWidth": 11264, "sourceHeight": 11264 },
"angle": 123.4,
"route": { "status": "running", "currentIndex": 2, "waypoints": [...] }
}| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
position | object/null | いいえ | 現在位置。null の場合は位置矢印を非表示にする |
position.pixelX | number | はい | X ピクセル座標 |
position.pixelY | number | はい | Y ピクセル座標 |
position.sourceWidth | number | 推奨 | 座標ソースの幅。未指定時は地図画像の幅へフォールバック |
position.sourceHeight | number | 推奨 | 座標ソースの高さ。未指定時は地図画像の高さへフォールバック |
angle | number/null | いいえ | 向きの角度(度) |
route | object/null | いいえ | ルート状態。省略時は前回状態を保持 |
マップサイトは version が 1 のメッセージのみ処理します。不明なバージョンは無視されます。
navi-route-ack
{
"type": "navi-route-ack",
"message": "ルートを設定しました",
"route": { "status": "running", "currentIndex": 1, "waypoints": [...] }
}message フィールドはユーザーへ直接表示されます。route.status には以下の値を推奨します。
| 状態 | 意味 |
|---|---|
idle | ルートなし |
ready | ルート設定済み、未開始 |
running | ナビゲーション中 |
stopped | 一時停止中 |
completed | 完了 |
error | 実行エラー |
navi-error
{
"type": "navi-error",
"message": "ウェイポイントが空です",
"code": "EMPTY_WAYPOINTS"
}message はユーザーへ表示されます。code は機械可読エラーコードです(現在マップサイトでは読み取りません)。
典型的なやり取り
マップサイト -> サーバー:navi-route-set(ルートを設定して開始)
サーバー -> マップサイト:navi-route-ack(status = running)
サーバー -> マップサイト:navi-state(位置とルート進捗を継続送信)
マップサイト -> サーバー:navi-route-stop
サーバー -> マップサイト:navi-route-ack(status = stopped)
マップサイト -> サーバー:navi-route-start
サーバー -> マップサイト:navi-route-ack(status = running)
マップサイト -> サーバー:navi-route-clear
サーバー -> マップサイト:navi-route-ack(status = idle)サーバーは認識できない追加フィールドを無視してください。マップサイトは解析できない JSON や未知のメッセージタイプを無視し、それを理由に自分から接続を閉じることはありません。
サードパーティ位置情報インターフェース
nte_coordinate_api は NTE キャラクターのワールド座標を受動的に読み取るインターフェースです。外部座標に基づくナビゲーション方式で利用できます。連携側はネットワーク通信を監視して生の 3D 座標を取得するため、MaaNTE 内蔵のスクリーンショット位置推定に依存しません。
インポート
from nte_coordinate_api import CoordinateCaptureモジュールは CoordinateCapture クラスのみを公開します。
CoordinateCapture
CoordinateCapture(
interface: str | None = None,
packet_filter: str = "tcp port 30031 or udp",
)座標キャプチャインスタンスを作成します。作成時点ではキャプチャは開始されないため、その後 start() を呼び出してください。
| パラメータ | 型 | デフォルト | 説明 |
|---|---|---|---|
interface | str | None | None | パケットキャプチャに使用するネットワークインターフェース名。None はシステム既定、文字列は指定インターフェースを使用します。無効な名前では start() が例外を投げる場合があります。 |
packet_filter | str | "tcp port 30031 or udp" | BPF フィルター式。範囲を広げるほど座標解析器へ渡るパケットが増えます。ゲームのプロトコルやポートを明確に理解していない限り、既定値のままにしてください。 |
capture = CoordinateCapture(interface="Ethernet")
capture = CoordinateCapture(packet_filter="udp")メソッド
start()
start() -> Noneバックグラウンドのネットワークキャプチャを開始します。成功後、インスタンスはネットワークデータを継続的に解析し、直近の有効なキャラクターワールド座標を保存します。
- ノンブロッキングで、繰り返し呼び出せます。
- すでに開始済みの場合、再度呼び出しても新しいキャプチャスレッドは作成されません。
close()を呼ぶまでバックグラウンドで座標を更新し続けます。
起こり得る例外:
| 例外 | 説明 |
|---|---|
RuntimeError | 必要な Python パケットキャプチャ依存関係が不足しています。 |
OSError | ネットワークインターフェース、キャプチャドライバー、または BPF フィルターの初期化に失敗しました。 |
| その他の下位例外 | ネットワークキャプチャ実装から送出されます。 |
業務入口で起動例外を捕捉することを推奨します。
try:
capture.start()
except Exception as exc:
logger.error("座標キャプチャを開始できません: %s", exc)read()
read(
max_age: float = 1.0,
) -> tuple[float, float, float] | None直近の有効座標を返します。
| パラメータ | 型 | デフォルト | 説明 |
|---|---|---|---|
max_age | float | 1.0 | 返却を許可する座標キャッシュの最大経過時間(秒)。直近座標の取得時刻がこの値以内なら座標を返し、超えていれば None を返します。 |
よく使う値:
| 値 | 用途 |
|---|---|
0.2 | リアルタイム性を重視する場合 |
1.0 | 既定値。通常のナビゲーション向け |
2.0 | 短い通信間隔の空きに耐えたい場合 |
有効な座標がある場合、戻り値は (x, y, z) で、すべて float です。
| インデックス | 名前 | 説明 |
|---|---|---|
0 | x | 生のワールド座標 X |
1 | y | 生のワールド座標 Y |
2 | z | 生のワールド座標 Z。通常は高さ |
これらはゲーム通信に含まれる生の 3D 座標です。API は平行移動、回転、拡大縮小、投影、地図標定を行いません。
以下の場合は None を返します。
- まだ
start()を呼んでいない。 - 開始後に有効座標を受信していない。
- 直近座標が
max_ageを超えている。 - 転送やインスタンス切り替えで移動データが一時中断した。
- ネットワークストリームが変化し、新しい移動ストリームがまだ確認されていない。
- 現在のパケットに認識可能な座標がない。
read() はノンブロッキングです。None はインスタンス停止を意味せず、必ずしもエラーでもありません。
coordinate = capture.read(max_age=0.5)
if coordinate is None:
return
x, y, z = coordinateclose()
close() -> Noneバックグラウンドキャプチャを停止し、関連リソースを解放します。
- 未開始でも安全に繰り返し呼び出せます。
- 開始済みの場合は停止してバックグラウンドキャプチャ終了を待ちます。
- 呼び出し後、インスタンスは新しい座標を受け取りません。
close() は直近のキャッシュ座標を能動的には消去しません。キャッシュが期限切れになるまでは、閉じる前の最後の座標を read() で取得できる場合があります。
try/finally で確実にリソースを解放してください。
capture = CoordinateCapture()
try:
capture.start()
# 座標を使用
finally:
capture.close()完全な例
import time
from nte_coordinate_api import CoordinateCapture
capture = CoordinateCapture(
interface=None,
packet_filter="tcp port 30031 or udp",
)
try:
capture.start()
while True:
coordinate = capture.read(max_age=1.0)
if coordinate is not None:
x, y, z = coordinate
print(f"x={x:.2f}, y={y:.2f}, z={z:.2f}")
time.sleep(0.1)
finally:
capture.close()状態とライフサイクル
インスタンスには公開された状態プロパティはありません。呼び出し側はメソッド結果から現在の状態を判断してください。
| 操作結果 | 意味 |
|---|---|
start() が正常に返る | バックグラウンドキャプチャが開始済み、または以前から開始済み。 |
start() が例外を送出する | キャプチャを正常に開始できなかった。 |
read() が座標を返す | 期限切れでない有効座標が現在存在する。 |
read() が None を返す | リアルタイム性要件を満たす有効座標が現在存在しない。 |
close() が正常に返る | キャプチャリソースが解放済み。 |
推奨ライフサイクル:
インスタンス作成 -> start() -> read() を複数回 -> close()スレッドセーフ性
- バックグラウンドキャプチャスレッドが直近座標を更新します。
read()は他のスレッドから呼び出せます。- 直近座標の読み取りと更新は同期保護されています。
- 複数スレッドから同時に
start()やclose()を呼ぶことは推奨しません。 - 1 つのインスタンスのライフサイクルは 1 つの業務コンポーネントが管理してください。
座標の連続性
通常移動中は、座標はキャラクター位置に合わせて継続更新されます。
以下の操作により、一時的に None が返ることがあります。
- 転送。
- マップやインスタンスの切り替え。
- キャラクター切り替え。
- ネットワーク再接続。
- ゲーム側の移動タイムスタンプ初期化。
- ゲームが新しいネットワークストリームへ切り替わる。
インターフェースは有効な移動ストリームの再認識を試みます。呼び出し側は、一度 None が返っただけで即座に破棄・再作成するのではなく、必要に応じて復帰を待ってください。
使用制限
- このインターフェースはネットワーク通信を読み取るだけで、パケットを送信または変更しません。
- 呼び出し側には指定ネットワークインターフェースへアクセスする権限が必要です。
- システムに利用可能なパケットキャプチャドライバーが必要です。
- 返される座標は生のワールド座標であり、任意の地図ピクセル座標系と直接一致する保証はありません。
- 座標変換と標定は呼び出し側で実装してください。
