Files
XRLib/Assets/Scripts/Simulator/Components/AGV/AGVManager.cs

276 lines
12 KiB
C#
Raw Normal View History

2025-11-04 11:02:02 +09:00
using Cysharp.Threading.Tasks;
using System;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.SocialPlatforms;
using UVC.Core;
using UVC.Data;
using UVC.Data.Core;
using UVC.Data.Mqtt;
2025-12-08 10:59:29 +09:00
using Simulator.Config;
2025-11-04 11:02:02 +09:00
using UVC.Pool;
namespace Simulator.Data.Transport
{
public enum AGVDataType
{
Moving,
2026-02-03 11:40:26 +09:00
LoadingStart,
LoadingEnd,
UnLoadingStart,
UnLoadingEnd,
Idle
2025-11-04 11:02:02 +09:00
}
public class AGVManager : SingletonScene<AGVManager>
{
private readonly Dictionary<string, string> prefabPaths = new Dictionary<string, string>()
{
{"agv","prefabs/agv"},
2025-12-08 10:59:29 +09:00
{"afl","prefabs/afl"},
{"forkLift","prefabs/forkLift"}
2025-11-04 11:02:02 +09:00
};
private GameObjectPool<AGV>? agvPool;
public GameObjectPool<AGV> AGVPool
{
get
{
if (agvPool == null)
{
//Debug.LogError("Pool is not initialized. Please call InitializePoolAsync first.");
}
return agvPool!;
}
}
2025-12-08 10:59:29 +09:00
private GameObjectPool<AGV>? aflPool;
public GameObjectPool<AGV> AFLPool
{
get
{
if (aflPool == null)
{
//Debug.LogError("Pool is not initialized. Please call InitializePoolAsync first.");
}
return aflPool!;
}
}
private GameObjectPool<AGV>? forkLiftPool;
public GameObjectPool<AGV> ForkLiftPool
{
get
{
if (forkLiftPool == null)
{
//Debug.LogError("Pool is not initialized. Please call InitializePoolAsync first.");
}
return forkLiftPool!;
}
}
2025-11-04 11:02:02 +09:00
private DataMapper agvMoveMapper;
private DataMapper agvLoadMapper;
private DataMapper agvUnLoadMapper;
2025-12-08 10:59:29 +09:00
private Dictionary<string, AGV> agvMap = new Dictionary<string, AGV>();
2025-11-04 11:02:02 +09:00
protected override void Init()
{
InitializeAGVPoolAsync().ContinueWith(() =>
{
var agvMoveDataMask = new DataMask();
agvMoveDataMask.ObjectName = "agv"; // AGV 객체의 이름을 설정합니다.
agvMoveDataMask.ObjectIdKey = "component_id"; // AGV의 고유 식별자로 사용할 키를 설정합니다.
agvMoveDataMask["component_id"] = "";
2025-12-08 10:59:29 +09:00
agvMoveDataMask["component_type"] = "";
2025-11-04 11:02:02 +09:00
agvMoveDataMask["event_name"] = "";
agvMoveDataMask["timestamp"] = new DateTime();
agvMoveDataMask["data"] = new DataMask()
{
["from_node"] = "",
["to_node"] = "",
["timing"] = new DataMask()
{
["duration"] = new DataMask()
{
["real_seconds"] = 0.0f
}
}
};
agvMoveMapper = new DataMapper(agvMoveDataMask);
var agvLoadDataMask = new DataMask();
agvLoadDataMask.ObjectName = "agv"; // AGV 객체의 이름을 설정합니다.
agvLoadDataMask.ObjectIdKey = "component_id"; // AGV의 고유 식별자로 사용할 키를 설정합니다.
agvLoadDataMask["component_id"] = "";
2025-12-08 10:59:29 +09:00
agvLoadDataMask["component_type"] = "";
2025-11-04 11:02:02 +09:00
agvLoadDataMask["event_name"] = "";
agvLoadDataMask["timestamp"] = new DateTime();
agvLoadDataMask["data"] = new DataMask()
{
["from_node"] = "",
["to_node"] = "",
2026-02-03 11:40:26 +09:00
["entity_ids"] = new DataMask()
{
["entity_id"] = ""
}
2025-11-04 11:02:02 +09:00
};
agvLoadMapper = new DataMapper(agvLoadDataMask);
var agvUnLoadDataMask = new DataMask();
agvUnLoadDataMask.ObjectName = "agv"; // AGV 객체의 이름을 설정합니다.
agvUnLoadDataMask.ObjectIdKey = "component_id"; // AGV의 고유 식별자로 사용할 키를 설정합니다.
agvUnLoadDataMask["component_id"] = "";
2025-12-08 10:59:29 +09:00
agvUnLoadDataMask["component_type"] = "";
2025-11-04 11:02:02 +09:00
agvUnLoadDataMask["event_name"] = "";
agvUnLoadDataMask["timestamp"] = new DateTime();
agvUnLoadDataMask["data"] = new DataMask()
{
2025-12-08 10:59:29 +09:00
["component"] = "",
2025-11-04 11:02:02 +09:00
["entity_ids"] = new List<string>(),
};
agvUnLoadMapper = new DataMapper(agvUnLoadDataMask);
});
2025-12-08 10:59:29 +09:00
InitializeAFLPoolAsync().ContinueWith(() => { });
InitializeForkLiftPoolAsync().ContinueWith(() => { });
2025-11-04 11:02:02 +09:00
}
2025-12-08 10:59:29 +09:00
public void SpawnAGV(List<AGVData> datas, string type)
2025-11-04 11:02:02 +09:00
{
foreach (var data in datas)
{
2025-12-08 10:59:29 +09:00
switch (type)
{
2025-12-11 18:26:09 +09:00
case "agv":
2026-02-03 11:40:26 +09:00
if (data.initial_node == null)
{
return;
}
2025-12-08 10:59:29 +09:00
var agv = agvPool.GetItem($"{data.name}");
agv.data = data;
agv.UpdatePosition(AGVNodeManager.Instance.GetNodePosition(data.initial_node));
agvMap.Add(data.name, agv);
2026-02-03 11:40:26 +09:00
agv.dataType = AGVDataType.Idle;
PlayerPropertyDataBase.Instance.CollectSpawnAGV(agv);
2025-12-08 10:59:29 +09:00
break;
case "afl":
var afl = aflPool.GetItem($"{data.name}");
afl.data = data;
afl.UpdatePosition(AGVNodeManager.Instance.GetNodePosition(data.initial_node));
agvMap.Add(data.name, afl);
2026-02-03 11:40:26 +09:00
afl.dataType = AGVDataType.Idle;
PlayerPropertyDataBase.Instance.CollectSpawnAGV(afl);
2025-12-08 10:59:29 +09:00
break;
case "forklift":
var forkLift = forkLiftPool.GetItem($"{data.name}");
forkLift.data = data;
forkLift.UpdatePosition(AGVNodeManager.Instance.GetNodePosition(data.initial_node));
agvMap.Add(data.name, forkLift);
2026-02-03 11:40:26 +09:00
forkLift.dataType = AGVDataType.Idle;
PlayerPropertyDataBase.Instance.CollectSpawnAGV(forkLift);
2025-12-08 10:59:29 +09:00
break;
}
2025-11-11 09:42:47 +09:00
}
}
public void InitAGV(List<AGVData> datas)
{
foreach (var data in datas)
{
2025-11-04 11:02:02 +09:00
DataRepository.Instance.MqttReceiver.AddTopic($"simulation/{SimulationConfig.SimulationCode}/components/+/{data.name}/+/moving");
var mqttConfigAGVMoving = new MqttSubscriptionConfig($"simulation/{SimulationConfig.SimulationCode}/components/+/{data.name}/+/moving");
mqttConfigAGVMoving.SetDataMapper(agvMoveMapper);
mqttConfigAGVMoving.SetHandler((value) => OnUpdateData(value, AGVDataType.Moving));
DataRepository.Instance.MqttReceiver.Add(mqttConfigAGVMoving);
DataRepository.Instance.MqttReceiver.AddTopic($"simulation/{SimulationConfig.SimulationCode}/components/+/{data.name}/+/loading_end");
var mqttConfigAGVLoading = new MqttSubscriptionConfig($"simulation/{SimulationConfig.SimulationCode}/components/+/{data.name}/+/loading_end");
mqttConfigAGVLoading.SetDataMapper(agvLoadMapper);
2026-02-03 11:40:26 +09:00
mqttConfigAGVLoading.SetHandler((value) => OnUpdateData(value, AGVDataType.LoadingEnd));
DataRepository.Instance.MqttReceiver.Add(mqttConfigAGVLoading);
DataRepository.Instance.MqttReceiver.AddTopic($"simulation/{SimulationConfig.SimulationCode}/components/+/{data.name}/+/loading_start");
var mqttConfigAGVLoadingStart = new MqttSubscriptionConfig($"simulation/{SimulationConfig.SimulationCode}/components/+/{data.name}/+/loading_start");
mqttConfigAGVLoadingStart.SetDataMapper(agvLoadMapper);
mqttConfigAGVLoadingStart.SetHandler((value) => OnUpdateData(value, AGVDataType.LoadingStart));
2025-11-04 11:02:02 +09:00
DataRepository.Instance.MqttReceiver.Add(mqttConfigAGVLoading);
DataRepository.Instance.MqttReceiver.AddTopic($"simulation/{SimulationConfig.SimulationCode}/components/+/{data.name}/+/unloading_end");
var mqttConfigAGVUnLoading = new MqttSubscriptionConfig($"simulation/{SimulationConfig.SimulationCode}/components/+/{data.name}/+/unloading_end");
mqttConfigAGVUnLoading.SetDataMapper(agvUnLoadMapper);
2026-02-03 11:40:26 +09:00
mqttConfigAGVUnLoading.SetHandler((value) => OnUpdateData(value, AGVDataType.UnLoadingEnd));
2025-11-04 11:02:02 +09:00
DataRepository.Instance.MqttReceiver.Add(mqttConfigAGVUnLoading);
2026-02-03 11:40:26 +09:00
DataRepository.Instance.MqttReceiver.AddTopic($"simulation/{SimulationConfig.SimulationCode}/components/+/{data.name}/+/unloading_start");
var mqttConfigAGVUnLoadingStart = new MqttSubscriptionConfig($"simulation/{SimulationConfig.SimulationCode}/components/+/{data.name}/+/unloading_start");
mqttConfigAGVUnLoadingStart.SetDataMapper(agvUnLoadMapper);
mqttConfigAGVUnLoadingStart.SetHandler((value) => OnUpdateData(value, AGVDataType.UnLoadingStart));
DataRepository.Instance.MqttReceiver.Add(mqttConfigAGVUnLoadingStart);
2025-11-04 11:02:02 +09:00
}
}
public void OnUpdateData(IDataObject data, AGVDataType type)
{
if (data == null) return;
DataObject? obj = data as DataObject;
if (obj == null) return;
2025-12-08 10:59:29 +09:00
var componentName = obj.GetString("component_id");
AGV agv = agvMap[componentName];
2025-11-04 11:02:02 +09:00
switch (type)
{
case AGVDataType.Moving:
agv.SetTargetPosition(obj);
2026-02-03 11:40:26 +09:00
agv.dataType = AGVDataType.Moving;
2025-11-04 11:02:02 +09:00
break;
2026-02-03 11:40:26 +09:00
case AGVDataType.LoadingEnd:
2025-11-04 11:02:02 +09:00
agv.LoadEntity(obj);
2026-02-03 11:40:26 +09:00
agv.dataType = AGVDataType.Idle;
break;
case AGVDataType.LoadingStart:
agv.dataType = AGVDataType.LoadingStart;
break;
case AGVDataType.UnLoadingEnd:
agv.dataType = AGVDataType.Idle;
2025-11-04 11:02:02 +09:00
break;
2026-02-03 11:40:26 +09:00
case AGVDataType.UnLoadingStart:
agv.dataType = AGVDataType.UnLoadingStart;
2025-11-04 11:02:02 +09:00
break;
}
}
private async UniTask InitializeAGVPoolAsync()
{
if (agvPool != null) return;
var prefab = await Resources.LoadAsync<GameObject>(prefabPaths["agv"]) as GameObject;
if (prefab == null)
{
Debug.LogError($"Prefab not found at path: {prefabPaths["agv"]}");
return;
}
agvPool = new GameObjectPool<AGV>(prefab, transform);
}
2025-12-08 10:59:29 +09:00
private async UniTask InitializeAFLPoolAsync()
{
if (aflPool != null) return;
var prefab = await Resources.LoadAsync<GameObject>(prefabPaths["afl"]) as GameObject;
if (prefab == null)
{
Debug.LogError($"Prefab not found at path: {prefabPaths["afl"]}");
return;
}
aflPool = new GameObjectPool<AGV>(prefab, transform);
}
private async UniTask InitializeForkLiftPoolAsync()
{
if (forkLiftPool != null) return;
var prefab = await Resources.LoadAsync<GameObject>(prefabPaths["forkLift"]) as GameObject;
if (prefab == null)
{
Debug.LogError($"Prefab not found at path: {prefabPaths["forkLift"]}");
return;
}
forkLiftPool = new GameObjectPool<AGV>(prefab, transform);
}
2025-11-04 11:02:02 +09:00
}
}