Files
HDRobotics/Assets/HybridIK/Scripts/Main/RobotManager.cs

240 lines
8.1 KiB
C#
Raw Normal View History

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RobotManager : MonoBehaviour
{
public static RobotManager Instance { get; private set; }
UIManager uiManager => UIManager.Instance;
[Header("MQTT Settings")]
[SerializeField] private MqttManager mqttManager;
[Header("Robot Config")]
[SerializeField] private TextAsset robotIDconfig;
[SerializeField] private TextAsset robotActionTopics;
[SerializeField] private HybridInverseKinematicsNode hybridIKNode;
[Header("UI Settings")]
[Tooltip("<22><> <20>κ<EFBFBD><CEBA><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> UI <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>")]
[SerializeField] private GameObject robotUIPrefab;
[Tooltip("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> UI<55><49><EFBFBD><EFBFBD> <20><>ġ<EFBFBD><C4A1> <20>θ<EFBFBD> Canvas")]
[SerializeField] private Transform uiParentCanvas;
// --- MQTT Topic <20><><EFBFBD><EFBFBD> ---
private RobotIDConfig idConfigData;
private RobotActionTopics actionTopicsData;
// --- <20>κ<EFBFBD> <20><><EFBFBD><EFBFBD> ---
private readonly Dictionary<string, RobotController> robotRegistry = new Dictionary<string, RobotController>();// <20>κ<EFBFBD> ID<49><44> Ű<><C5B0> <20>Ͽ<EFBFBD> <20><><EFBFBD><EFBFBD>
private string targetRobotId; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>κ<EFBFBD> ID (<28><><EFBFBD><EFBFBD> = <20><><EFBFBD><EFBFBD>)
private Dictionary<string, GameObject> robotUIs = new Dictionary<string, GameObject>();
// --- <20>κ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ---
private RobotController selectedRobot; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD>õ<EFBFBD> <20>κ<EFBFBD>
private Transform RecordingHandleTarget; // Handle(<28><><EFBFBD><EFBFBD> <20>κ<EFBFBD>)<29><> Transform
public static event Action<RobotController> OnRobotSelected; // <20>κ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>̺<EFBFBD>Ʈ
private void Awake()
{
if (Instance == null)
{
Instance = this;
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject);
}
InitializeRobotRegistry();
ManageConfig();
}
// <20>̺<EFBFBD>Ʈ <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
private void OnEnable()
{
MqttManager.OnMessageReceived += HandleMessage; // <20>޽<EFBFBD><DEBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>̺<EFBFBD>Ʈ <20><><EFBFBD><EFBFBD>
UIController.OnTransformSendUIClicked += HandlePublishTransformCommand;
UIController.OnKeyframesSendUIClicked += HandlePublishKeyframeListCommand;
}
private void OnDisable()
{
MqttManager.OnMessageReceived -= HandleMessage;
UIController.OnTransformSendUIClicked -= HandlePublishTransformCommand;
UIController.OnKeyframesSendUIClicked -= HandlePublishKeyframeListCommand;
}
void Start()
{
InstantiateRobotUIs();
}
private void InitializeRobotRegistry()
{
RobotController[] allRobots = FindObjectsByType<RobotController>(FindObjectsSortMode.None); // <20><>Ȱ<EFBFBD><C8B0>ȭ <20><> <20><> <20><><EFBFBD><EFBFBD> ã<><C3A3>
foreach (var robot in allRobots)
{
if (!robotRegistry.ContainsKey(robot.robotId))
{
robotRegistry.Add(robot.robotId, robot);
}
else
{
Debug.LogWarning($"<22>κ<EFBFBD> ID {robot.robotId}<7D><> <20>ߺ<EFBFBD><DFBA>Ǿ<EFBFBD><C7BE><EFBFBD><EFBFBD>ϴ<EFBFBD>. ù <20><>° <20>κ<EFBFBD><CEBA><EFBFBD> <20><><EFBFBD>ϵ˴ϴ<CBB4>.");
}
}
}
private void InstantiateRobotUIs()
{
if (robotUIPrefab == null || uiParentCanvas == null)
{
Debug.LogError("Robot UI Prefab <20>Ǵ<EFBFBD> UI Parent Canvas<61><73> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʾҽ<CABE><D2BD>ϴ<EFBFBD>.");
return;
}
foreach (var entry in robotRegistry)
{
RobotController robot = entry.Value;
// '<27><><EFBFBD><EFBFBD> <20>κ<EFBFBD><><C6AE>)'<27><> <20><><EFBFBD>ؼ<EFBFBD><D8BC><EFBFBD> UI<55><49> <20><><EFBFBD><EFBFBD>
if (!robot.isLocallyControlled)
{
GameObject uiInstance = Instantiate(robotUIPrefab, uiParentCanvas);
uiInstance.name = $"UI_{robot.robotId}";
// <20><><EFBFBD><EFBFBD> UI Prefab<61><62> <20><>Ȱ<EFBFBD><C8B0>ȭ
robotUIPrefab.SetActive(false);
UIController uiController = uiInstance.GetComponent<UIController>();
if (uiController != null)
{
uiController.Initialize(this, uiManager);
robotUIs.Add(robot.robotId, uiInstance);
}
uiInstance.SetActive(false);
}
}
}
public void SelectRobot(string robotId)
{
if (robotRegistry.TryGetValue(robotId, out RobotController robot))
{
selectedRobot = robot;
targetRobotId = robotId; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>κ<EFBFBD> ID <20><><EFBFBD><EFBFBD>
Debug.Log($"<22>κ<EFBFBD> '{robotId}' <20><><EFBFBD>õ<EFBFBD>. <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>κ<EFBFBD> ID<49><44> <20><><EFBFBD><EFBFBD>.");
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Handle Target <20><><EFBFBD><EFBFBD>
RecordingHandleTarget = GameObject.FindWithTag("Handle")?.transform;
// <20><><EFBFBD><EFBFBD> UI <20><>Ȱ<EFBFBD><C8B0>ȭ
foreach (var ui in robotUIs.Values) ui.SetActive(false);
// <20><><EFBFBD>õ<EFBFBD> <20>κ<EFBFBD><CEBA><EFBFBD> UI<55><49> Ȱ<><C8B0>ȭ
if (robotUIs.TryGetValue(robotId, out GameObject selectedUI))
{
selectedUI.SetActive(true);
}
OnRobotSelected?.Invoke(selectedRobot); // UIManager<65><72> HandleRobotSelected <20>̺<EFBFBD>Ʈ ȣ<><C8A3>
SubscribeToTopic(new string[] { $"robots/{targetRobotId}/ {actionTopicsData.Topic1}" }); // Topic1: state
HandlePublishTransformCommand(); // <20><><EFBFBD><EFBFBD> <20><> <20><> <20><> <20><><EFBFBD><EFBFBD>ȭ
}
}
#region Publishing Logic
private void ManageConfig()
{
idConfigData = JsonUtility.FromJson<RobotIDConfig>(robotIDconfig.text);
actionTopicsData = JsonUtility.FromJson<RobotActionTopics>(robotActionTopics.text);
}
// <20><><EFBFBD><EFBFBD> <20>κ<EFBFBD><CEBA><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ͽ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>κ<EFBFBD><CEBA><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> (UI <20><><EFBFBD><EFBFBD><EFBFBD>ؼ<EFBFBD>)
public void HandlePublishTransformCommand()
{
Debug.Log("TransformSendUI <20>̺<EFBFBD>Ʈ <20><><EFBFBD><EFBFBD><EFBFBD>Ǿ<EFBFBD> HandlePublishTransformCommand <20>ҷ<EFBFBD><D2B7><EFBFBD>");
Vector3 commandPosition = RecordingHandleTarget.transform.localPosition;
List<Vector3> commandJoints = hybridIKNode.GetCurrentJointPositions();
List<Quaternion> commandRotations = hybridIKNode.GetCurrentJointRotations();
string topic = $"robots/{targetRobotId}/{actionTopicsData.Topic2}"; // Topic2: command
Debug.Log($"topic: {topic}");
IKData data = new IKData
{
robotId = targetRobotId, // <20>κ<EFBFBD> ID (<28><><EFBFBD><EFBFBD> = <20><><EFBFBD><EFBFBD>)
position = commandPosition,
nodesPosition = new List<Vector3>(commandJoints),
nodesRotation = new List<Quaternion>(commandRotations)
};
string json = JsonUtility.ToJson(data, true);
mqttManager.PublishMessage(topic, json);
Debug.Log($"<22><>ġ <20><><EFBFBD><EFBFBD>ȭ <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>: {json}");
}
public void HandlePublishKeyframeListCommand()
{
Debug.Log("ListSendUI <20>̺<EFBFBD>Ʈ <20><><EFBFBD><EFBFBD><EFBFBD>Ǿ<EFBFBD> HandlePublishKeyframeListCommand <20>ҷ<EFBFBD><D2B7><EFBFBD>");
IReadOnlyList<IKData> keyframePositions = UIManager.Instance.KeyframePositions;
//List<Vector3> commandJoints = hybridIKNode.GetJointPositionsForKeyframe();
// <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20>޽<EFBFBD><DEBD><EFBFBD><EFBFBD><EFBFBD> publish
if (keyframePositions.Count > 0)
{
string topic = $"robots/{targetRobotId}/{actionTopicsData.Topic2}"; // Topic2: command
Debug.Log($"topic: {topic}");
IKDataListWrapper wrapper = new IKDataListWrapper
{
robotId = targetRobotId,
keyFrameList = new List<IKData>(keyframePositions),
//nodesList = commandJoints
};
string json = JsonUtility.ToJson(wrapper, true);
mqttManager.PublishMessage(topic, json);
Debug.Log($"Ű<><C5B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ʈ <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>: {json}");
}
}
private void HandleMessage(string topic, string message)
{
string[] topicLevels = topic.Split('/');
if (topicLevels.Length < 3) return;
string robotId = topicLevels[1];
string messageType = topicLevels[2];
// ID<49><44> <20>ش<EFBFBD><D8B4>ϴ<EFBFBD> <20>κ<EFBFBD><CEBA><EFBFBD> <20>ִ<EFBFBD><D6B4><EFBFBD> Ȯ<><C8AE>
if (!robotRegistry.TryGetValue(robotId, out RobotController targetRobot))
{
return;
}
//HandleStateUpdate(targetRobot, message); // TODO. <20><><EFBFBD><EFBFBD> Ʈ<><C6AE><EFBFBD><EFBFBD> <20><>ġ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ -> <20><><EFBFBD><EFBFBD> <20>κ<EFBFBD><CEBA><EFBFBD><EFBFBD><EFBFBD> <20><>ư Ŭ<><C5AC><EFBFBD>ϸ<EFBFBD> <20><><EFBFBD><EFBFBD>ȭ <20>ϱ<EFBFBD><CFB1><EFBFBD>.
}
private void HandleStateUpdate(RobotController twinRobot, string message) // <20><><EFBFBD><EFBFBD> <- <20><><EFBFBD><EFBFBD>
{
IKData data = JsonUtility.FromJson<IKData>(message);
twinRobot.transform.localPosition = data.position;
}
#endregion
#region Subscribing Logic
private void SubscribeToTopic(string[] topics)
{
// MqttManager<65><72><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
mqttManager.SubscribeToTopics(topics);
}
#endregion
}