LightGlueBridgeBehaviour.cs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. using LightGlue.Unity.Config;
  2. using LightGlue.Unity.Networking;
  3. using LightGlue.Unity.Python;
  4. using LightGlue.Unity.Sdk.Core;
  5. using UnityEngine;
  6. namespace LightGlue.Unity.Sdk.Unity
  7. {
  8. /// <summary>
  9. /// SDK 原型版:供第三方/当前工程直接挂在场景中的桥接组件。
  10. /// 内部持有 LightGlueClient,并在 Unity 生命周期中驱动它。
  11. /// </summary>
  12. public sealed class LightGlueBridgeBehaviour : MonoBehaviour
  13. {
  14. [Header("配置管理")]
  15. [Tooltip("是否从NetworkConfigManager自动加载网络配置")]
  16. public bool autoLoadNetworkConfig = true;
  17. [Header("Hardware UDP (input: hardware -> Unity)")]
  18. public string hardwareBindIp = "192.168.0.105";
  19. public int hardwarePort = 12346;
  20. public float hardwareTimeoutSeconds = 2.0f;
  21. public int maxQueuedFrames = 2;
  22. [Header("Hardware Control UDP (Unity -> Hardware)")]
  23. public string hardwareControlIp = "192.168.0.106";
  24. public int hardwareControlPort = 8888;
  25. [Header("Python Output Mode")]
  26. public LightGlueClient.TransferMode transferMode = LightGlueClient.TransferMode.Stdin;
  27. [Header("Python UDP (legacy mode: Unity -> Python)")]
  28. public string pythonIp = "127.0.0.1";
  29. public int pythonPort = 12347;
  30. [Header("Python Process (stdin mode: Unity -> Python)")]
  31. public PythonProcessController pythonProcessController;
  32. [Header("Python Result Receiver (Python -> Unity)")]
  33. public bool enableResultReceiver = true;
  34. public string pythonResultBindIp = "127.0.0.1";
  35. public int pythonResultPort = 12348;
  36. public int maxResultQueueSize = 10;
  37. [Header("Image Transmission Config")]
  38. [Tooltip("图像传输配置(可由 UI 写入)")]
  39. public ImageTransmissionConfig transmissionConfig;
  40. /// <summary>
  41. /// 最新的算法结果(每帧由 TryGetLatestResult 刷新)
  42. /// </summary>
  43. public LightGlueResult LatestResult { get; private set; }
  44. private LightGlueClient _client;
  45. private void Start()
  46. {
  47. if (autoLoadNetworkConfig)
  48. {
  49. TryLoadNetworkConfig();
  50. }
  51. var options = new LightGlueClient.Options
  52. {
  53. HardwareBindIp = hardwareBindIp,
  54. HardwarePort = hardwarePort,
  55. HardwareTimeoutSeconds = hardwareTimeoutSeconds,
  56. MaxQueuedFrames = maxQueuedFrames,
  57. HardwareControlIp = hardwareControlIp,
  58. HardwareControlPort = hardwareControlPort,
  59. Mode = transferMode,
  60. PythonIp = pythonIp,
  61. PythonPort = pythonPort,
  62. PythonController = pythonProcessController,
  63. EnableResultReceiver = enableResultReceiver,
  64. PythonResultBindIp = pythonResultBindIp,
  65. PythonResultPort = pythonResultPort,
  66. MaxResultQueueSize = maxResultQueueSize
  67. };
  68. _client = new LightGlueClient(options);
  69. try
  70. {
  71. _client.Start();
  72. }
  73. catch
  74. {
  75. // 端口冲突等错误已经在 client 内部打 log,这里防止异常中断游戏。
  76. }
  77. if (transmissionConfig != null)
  78. {
  79. _client.SetTransmissionConfig(transmissionConfig);
  80. }
  81. }
  82. private void TryLoadNetworkConfig()
  83. {
  84. try
  85. {
  86. var config = NetworkConfigManager.LoadConfig();
  87. if (config != null && config.Validate())
  88. {
  89. hardwareBindIp = config.hardwareBindIp;
  90. hardwarePort = config.hardwarePort;
  91. hardwareTimeoutSeconds = config.hardwareTimeoutSeconds;
  92. pythonIp = config.pythonIp;
  93. pythonPort = config.pythonPort;
  94. pythonResultBindIp = config.pythonResultBindIp;
  95. pythonResultPort = config.pythonResultPort;
  96. hardwareControlIp = config.hardwareControlIp;
  97. hardwareControlPort = config.hardwareControlPort;
  98. Debug.Log($"[SDK][Bridge] Loaded network config: hardware={hardwareBindIp}:{hardwarePort}, python={pythonIp}:{pythonPort}, result={pythonResultBindIp}:{pythonResultPort}, hwCtrl={hardwareControlIp}:{hardwareControlPort}");
  99. }
  100. }
  101. catch (System.Exception ex)
  102. {
  103. Debug.LogWarning($"[SDK][Bridge] Load NetworkConfig failed, use Inspector values. {ex.Message}");
  104. }
  105. }
  106. private void Update()
  107. {
  108. if (_client == null) return;
  109. _client.Tick();
  110. if (enableResultReceiver && _client.TryGetLatestResult(out var result))
  111. {
  112. LatestResult = result;
  113. }
  114. }
  115. private void OnDisable()
  116. {
  117. if (_client != null)
  118. {
  119. _client.Dispose();
  120. _client = null;
  121. }
  122. }
  123. /// <summary>
  124. /// 供 UI 调用:更新图像传输配置(Unity->Python)。
  125. /// </summary>
  126. public void SetTransmissionConfig(ImageTransmissionConfig config)
  127. {
  128. transmissionConfig = config;
  129. if (_client != null)
  130. {
  131. _client.SetTransmissionConfig(config);
  132. }
  133. }
  134. /// <summary>
  135. /// 供 UI 调用:下发硬件图像参数(0x40 协议)。
  136. /// </summary>
  137. public void ApplyHardwareConfig(ImageTransmissionConfig config)
  138. {
  139. if (_client != null)
  140. {
  141. _client.ApplyHardwareConfig(config);
  142. }
  143. }
  144. /// <summary>
  145. /// 获取最新 JPEG 图(拷贝),方便外部 Viewer 使用。
  146. /// </summary>
  147. public byte[] GetLatestJpeg()
  148. {
  149. return _client != null ? _client.GetLatestJpegCopy() : null;
  150. }
  151. }
  152. }