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; using Simulator.Config; using UVC.Pool; namespace Simulator.Data.Transport { public enum AGVDataType { Moving, Loading, UnLoading } public class AGVManager : SingletonScene { private readonly Dictionary prefabPaths = new Dictionary() { {"agv","prefabs/agv"}, {"afl","prefabs/afl"}, {"forkLift","prefabs/forkLift"} }; private GameObjectPool? agvPool; public GameObjectPool AGVPool { get { if (agvPool == null) { //Debug.LogError("Pool is not initialized. Please call InitializePoolAsync first."); } return agvPool!; } } private GameObjectPool? aflPool; public GameObjectPool AFLPool { get { if (aflPool == null) { //Debug.LogError("Pool is not initialized. Please call InitializePoolAsync first."); } return aflPool!; } } private GameObjectPool? forkLiftPool; public GameObjectPool ForkLiftPool { get { if (forkLiftPool == null) { //Debug.LogError("Pool is not initialized. Please call InitializePoolAsync first."); } return forkLiftPool!; } } private DataMapper agvMoveMapper; private DataMapper agvLoadMapper; private DataMapper agvUnLoadMapper; private Dictionary agvMap = new Dictionary(); protected override void Init() { InitializeAGVPoolAsync().ContinueWith(() => { var agvMoveDataMask = new DataMask(); agvMoveDataMask.ObjectName = "agv"; // AGV 객체의 이름을 설정합니다. agvMoveDataMask.ObjectIdKey = "component_id"; // AGV의 고유 식별자로 사용할 키를 설정합니다. agvMoveDataMask["component_id"] = ""; agvMoveDataMask["component_type"] = ""; 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"] = ""; agvLoadDataMask["component_type"] = ""; agvLoadDataMask["event_name"] = ""; agvLoadDataMask["timestamp"] = new DateTime(); agvLoadDataMask["data"] = new DataMask() { ["from_node"] = "", ["to_node"] = "", ["entity_ids"] = new List(), }; agvLoadMapper = new DataMapper(agvLoadDataMask); var agvUnLoadDataMask = new DataMask(); agvUnLoadDataMask.ObjectName = "agv"; // AGV 객체의 이름을 설정합니다. agvUnLoadDataMask.ObjectIdKey = "component_id"; // AGV의 고유 식별자로 사용할 키를 설정합니다. agvUnLoadDataMask["component_id"] = ""; agvUnLoadDataMask["component_type"] = ""; agvUnLoadDataMask["event_name"] = ""; agvUnLoadDataMask["timestamp"] = new DateTime(); agvUnLoadDataMask["data"] = new DataMask() { ["component"] = "", ["entity_ids"] = new List(), }; agvUnLoadMapper = new DataMapper(agvUnLoadDataMask); }); InitializeAFLPoolAsync().ContinueWith(() => { }); InitializeForkLiftPoolAsync().ContinueWith(() => { }); } public void SpawnAGV(List datas, string type) { foreach (var data in datas) { switch (type) { case "agv": var agv = agvPool.GetItem($"{data.name}"); agv.data = data; agv.UpdatePosition(AGVNodeManager.Instance.GetNodePosition(data.initial_node)); agvMap.Add(data.name, agv); 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); 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); break; } } } public void InitAGV(List datas) { foreach (var data in datas) { 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); mqttConfigAGVLoading.SetHandler((value) => OnUpdateData(value, AGVDataType.Loading)); 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); mqttConfigAGVUnLoading.SetHandler((value) => OnUpdateData(value, AGVDataType.UnLoading)); DataRepository.Instance.MqttReceiver.Add(mqttConfigAGVUnLoading); } } public void OnUpdateData(IDataObject data, AGVDataType type) { if (data == null) return; DataObject? obj = data as DataObject; if (obj == null) return; var componentName = obj.GetString("component_id"); AGV agv = agvMap[componentName]; /* Debug.Log(obj.GetString("component_id")); Debug.Log(obj.GetString("component_type")); switch (componenttype) { case "agv": agv = agvPool.GetItem(obj.GetString("component_id")!); break; case "afl": agv = aflPool.GetItem(obj.GetString("component_id")!); break; case "forklift": agv = forkLiftPool.GetItem(obj.GetString("component_id")!); break; } */ switch (type) { case AGVDataType.Moving: agv.SetTargetPosition(obj); break; case AGVDataType.Loading: agv.LoadEntity(obj); break; case AGVDataType.UnLoading: break; } } private async UniTask InitializeAGVPoolAsync() { if (agvPool != null) return; var prefab = await Resources.LoadAsync(prefabPaths["agv"]) as GameObject; if (prefab == null) { Debug.LogError($"Prefab not found at path: {prefabPaths["agv"]}"); return; } agvPool = new GameObjectPool(prefab, transform); } private async UniTask InitializeAFLPoolAsync() { if (aflPool != null) return; var prefab = await Resources.LoadAsync(prefabPaths["afl"]) as GameObject; if (prefab == null) { Debug.LogError($"Prefab not found at path: {prefabPaths["afl"]}"); return; } aflPool = new GameObjectPool(prefab, transform); } private async UniTask InitializeForkLiftPoolAsync() { if (forkLiftPool != null) return; var prefab = await Resources.LoadAsync(prefabPaths["forkLift"]) as GameObject; if (prefab == null) { Debug.LogError($"Prefab not found at path: {prefabPaths["forkLift"]}"); return; } forkLiftPool = new GameObjectPool(prefab, transform); } } }