From 033c6aeb8e8b1bb2642997eb36050bea8a7b2ca8 Mon Sep 17 00:00:00 2001 From: SOOBEEN HAN Date: Thu, 6 Nov 2025 15:28:16 +0900 Subject: [PATCH] =?UTF-8?q?=20=EB=A1=9C=EB=B4=87=EC=A2=8C=ED=91=9C=20?= =?UTF-8?q?TCP=EC=A0=84=EB=8B=AC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Main/HybridInverseKinematicsNode.cs | 4 - .../HybridIK/Scripts/Main/RobotController.cs | 35 ++- .../Right_NearFarInteractor.prefab | 4 + Assets/Scenes/HDRobo_Main.unity | 248 +++++++++++++++-- Assets/Scripts/AppManager.cs | 43 ++- Assets/Scripts/Model/ProgramModel.cs | 166 ++++++----- Assets/Scripts/Presenter/ProgramPresenter.cs | 163 +++++++---- Assets/Scripts/Presenter/SplashPresenter.cs | 1 - Assets/Scripts/View/InteractionView.cs | 259 +++++++++++++----- Assets/Scripts/View/ProgramView.cs | 21 +- ...lete XR Origin Set Up Hands Variant.prefab | 8 + ProjectSettings/TagManager.asset | 1 + 12 files changed, 681 insertions(+), 272 deletions(-) diff --git a/Assets/HybridIK/Scripts/Main/HybridInverseKinematicsNode.cs b/Assets/HybridIK/Scripts/Main/HybridInverseKinematicsNode.cs index ceca452..cf7853a 100644 --- a/Assets/HybridIK/Scripts/Main/HybridInverseKinematicsNode.cs +++ b/Assets/HybridIK/Scripts/Main/HybridInverseKinematicsNode.cs @@ -150,10 +150,6 @@ public class HybridInverseKinematicsNode : MonoBehaviour nodes[i].jointTransform.localRotation = newRotations[i]; //Debug.Log($"관절 {i}의 목표 회전을 {newRotations[i]}로 설정했습니다."); } - - // Handle위치 매 프레임마다 업데이트 - //targetTransform.localPosition = nodes[0].jointTransform.localPosition; - //targetTransform.localRotation = nodes[0].jointTransform.localRotation; } #region DebugDraw diff --git a/Assets/HybridIK/Scripts/Main/RobotController.cs b/Assets/HybridIK/Scripts/Main/RobotController.cs index a6ea082..5a97734 100644 --- a/Assets/HybridIK/Scripts/Main/RobotController.cs +++ b/Assets/HybridIK/Scripts/Main/RobotController.cs @@ -40,12 +40,19 @@ public class RobotController : MonoBehaviour } } - private void Update() + private void FixedUpdate() { - //OnPoseUpdateRequest?.Invoke();// TODO. κ ƴ ϱ OnPoseUpdateRequest?.Invoke(); } + private void LateUpdate() + { + if (kinematicsNode != null && kinematicsNode.enabled == false) + { + UpdateHandleToEndPoint(); + } + } + public void SetMotorState(bool isOn) { isMotorOn = isOn; @@ -83,8 +90,6 @@ public class RobotController : MonoBehaviour { // x, y, z, rx, ry, rz => endpoint // j1, ..., j6 => 6 ȸ - // kinematicsNode.targetTransform.localPosition = new Vector3(robotData.x, robotData.y, robotData.z); - // kinematicsNode.targetTransform.localRotation = new Quaternion(robotData.rx, robotData.ry, robotData.rz, 0); if (robotData == null) { return; // Ͱ ƹ͵ @@ -102,11 +107,25 @@ public class RobotController : MonoBehaviour kinematicsNode.SetJointTargetRotations(list_jAngle); } - public void Movement() + private void UpdateHandleToEndPoint() { - movementPosition.x = Convert.ToSingle(Math.Round(-1 * kinematicsNode.targetTransform.localPosition.x * 1000, 2)); - movementPosition.y = Convert.ToSingle(Math.Round(-1 * kinematicsNode.targetTransform.localPosition.z * 1000, 2)); - movementPosition.z = Convert.ToSingle(Math.Round(kinematicsNode.targetTransform.localPosition.y * 1000, 2)); + if (kinematicsNode == null || kinematicsNode.targetTransform == null || + kinematicsNode.nodes == null || kinematicsNode.nodes.Count == 0) + { + return; + } + + Transform endPoint = kinematicsNode.nodes[kinematicsNode.nodes.Count - 1].jointTransform; + if (endPoint == null) return; + + kinematicsNode.targetTransform.position = endPoint.position; + kinematicsNode.targetTransform.rotation = endPoint.rotation; + } + + public Transform GetEndPoint() + { + Transform endPoint = kinematicsNode.nodes[kinematicsNode.nodes.Count - 1].jointTransform; + return endPoint; } void OnDestroy() diff --git a/Assets/Samples/XR Interaction Toolkit/3.2.1/Starter Assets/Prefabs/Interactors/Right_NearFarInteractor.prefab b/Assets/Samples/XR Interaction Toolkit/3.2.1/Starter Assets/Prefabs/Interactors/Right_NearFarInteractor.prefab index 3f44b47..b7bb93d 100644 --- a/Assets/Samples/XR Interaction Toolkit/3.2.1/Starter Assets/Prefabs/Interactors/Right_NearFarInteractor.prefab +++ b/Assets/Samples/XR Interaction Toolkit/3.2.1/Starter Assets/Prefabs/Interactors/Right_NearFarInteractor.prefab @@ -5,6 +5,7 @@ PrefabInstance: m_ObjectHideFlags: 0 serializedVersion: 2 m_Modification: + serializedVersion: 3 m_TransformParent: {fileID: 0} m_Modifications: - target: {fileID: 1722882099693224055, guid: 3df3e1220f2164f448701a6de8084f92, type: 3} @@ -92,4 +93,7 @@ PrefabInstance: value: 0 objectReference: {fileID: 0} m_RemovedComponents: [] + m_RemovedGameObjects: [] + m_AddedGameObjects: [] + m_AddedComponents: [] m_SourcePrefab: {fileID: 100100000, guid: 3df3e1220f2164f448701a6de8084f92, type: 3} diff --git a/Assets/Scenes/HDRobo_Main.unity b/Assets/Scenes/HDRobo_Main.unity index 3e641de..9a63829 100644 --- a/Assets/Scenes/HDRobo_Main.unity +++ b/Assets/Scenes/HDRobo_Main.unity @@ -13038,8 +13038,8 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 445093996} serializedVersion: 2 - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: -1.27, y: 1.406, z: -0.054} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: -1.27, y: 1.4059997, z: -0.05400002} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: @@ -27091,7 +27091,7 @@ Transform: m_GameObject: {fileID: 930691783} serializedVersion: 2 m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalPosition: {x: 0, y: -0.031, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 m_Children: [] @@ -27116,8 +27116,8 @@ BoxCollider: m_ProvidesContacts: 0 m_Enabled: 1 serializedVersion: 3 - m_Size: {x: 0.11687246, y: 0.3, z: 0.27486545} - m_Center: {x: -0.091563776, y: 0, z: 0.065199405} + m_Size: {x: 0.019788742, y: 0.27946773, z: 0.27486545} + m_Center: {x: -0.043021917, y: 0.01026614, z: 0.065199405} --- !u!1001 &933198679 PrefabInstance: m_ObjectHideFlags: 0 @@ -30401,17 +30401,6 @@ Transform: m_CorrespondingSourceObject: {fileID: 4106791946970566897, guid: 04e2e84adfe5ce6408a6777431fcb927, type: 3} m_PrefabInstance: {fileID: 1042269393} m_PrefabAsset: {fileID: 0} ---- !u!114 &1045947015 stripped -MonoBehaviour: - m_CorrespondingSourceObject: {fileID: 8629926924687228403, guid: 77e7c27b2c5525e4aa8cc9f99d654486, type: 3} - m_PrefabInstance: {fileID: 1928531730} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 0} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 25a07ef133a37d140a87cdf1f1c75fdf, type: 3} - m_Name: - m_EditorClassIdentifier: --- !u!4 &1046609852 stripped Transform: m_CorrespondingSourceObject: {fileID: -1450917681278090710, guid: 681c1cadbb14b604d9438dc819da8e9a, type: 3} @@ -37485,7 +37474,6 @@ MonoBehaviour: view: {fileID: 1243479632} tcpView: {fileID: 1456747455} robotController: {fileID: 806304512143720359} - interactionView: {fileID: 0} pointManagerView: {fileID: 1568384461} pathLineView: {fileID: 1568384459} popupView: {fileID: 1313589743} @@ -37946,13 +37934,21 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 9abda78e6c8fdb34a925ac2483efc48b, type: 3} m_Name: m_EditorClassIdentifier: - popupPanel: {fileID: 1313589737} - titleText: {fileID: 331501807} - messageText: {fileID: 827370641} - confirmButton: {fileID: 618711572} - cancelButton: {fileID: 1352558441} - option1Button: {fileID: 1755737344} - option2Button: {fileID: 196844229} + confirmPopupPanel: {fileID: 1587487535} + modifyPopupPanel: {fileID: 1102828141} + deletePopupPanel: {fileID: 345423593} + optionPopupPanel: {fileID: 1551209702} + confirmButton: + - {fileID: 618711572} + - {fileID: 453392322} + cancelButton: + - {fileID: 1352558441} + - {fileID: 1512808852} + - {fileID: 2008415897} + moveButton: {fileID: 1755737344} + deleteButton: + - {fileID: 1817951602} + - {fileID: 196844229} --- !u!1001 &1315555405 PrefabInstance: m_ObjectHideFlags: 0 @@ -39130,6 +39126,9 @@ GameObject: serializedVersion: 6 m_Component: - component: {fileID: 1340190238} + - component: {fileID: 1340190241} + - component: {fileID: 1340190240} + - component: {fileID: 1340190239} m_Layer: 0 m_Name: endTarget m_TagString: Untagged @@ -39152,6 +39151,183 @@ Transform: m_Children: [] m_Father: {fileID: 6476108356885335244} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &1340190239 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1340190237} + m_Enabled: 0 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0ad34abafad169848a38072baa96cdb2, type: 3} + m_Name: + m_EditorClassIdentifier: + m_InteractionManager: {fileID: 0} + m_Colliders: [] + m_InteractionLayers: + m_Bits: 1 + m_DistanceCalculationMode: 1 + m_SelectMode: 1 + m_FocusMode: 1 + m_CustomReticle: {fileID: 0} + m_AllowGazeInteraction: 0 + m_AllowGazeSelect: 0 + m_OverrideGazeTimeToSelect: 0 + m_GazeTimeToSelect: 0.5 + m_OverrideTimeToAutoDeselectGaze: 0 + m_TimeToAutoDeselectGaze: 3 + m_AllowGazeAssistance: 0 + m_FirstHoverEntered: + m_PersistentCalls: + m_Calls: [] + m_LastHoverExited: + m_PersistentCalls: + m_Calls: [] + m_HoverEntered: + m_PersistentCalls: + m_Calls: [] + m_HoverExited: + m_PersistentCalls: + m_Calls: [] + m_FirstSelectEntered: + m_PersistentCalls: + m_Calls: [] + m_LastSelectExited: + m_PersistentCalls: + m_Calls: [] + m_SelectEntered: + m_PersistentCalls: + m_Calls: [] + m_SelectExited: + m_PersistentCalls: + m_Calls: [] + m_FirstFocusEntered: + m_PersistentCalls: + m_Calls: [] + m_LastFocusExited: + m_PersistentCalls: + m_Calls: [] + m_FocusEntered: + m_PersistentCalls: + m_Calls: [] + m_FocusExited: + m_PersistentCalls: + m_Calls: [] + m_Activated: + m_PersistentCalls: + m_Calls: [] + m_Deactivated: + m_PersistentCalls: + m_Calls: [] + m_StartingHoverFilters: [] + m_StartingSelectFilters: [] + m_StartingInteractionStrengthFilters: [] + m_AttachTransform: {fileID: 0} + m_SecondaryAttachTransform: {fileID: 0} + m_UseDynamicAttach: 1 + m_MatchAttachPosition: 1 + m_MatchAttachRotation: 1 + m_SnapToColliderVolume: 1 + m_ReinitializeDynamicAttachEverySingleGrab: 1 + m_AttachEaseInTime: 0 + m_MovementType: 1 + m_PredictedVisualsTransform: {fileID: 0} + m_VelocityDamping: 1 + m_VelocityScale: 1 + m_AngularVelocityDamping: 1 + m_AngularVelocityScale: 1 + m_TrackPosition: 1 + m_SmoothPosition: 0 + m_SmoothPositionAmount: 1.34 + m_TightenPosition: 0.068 + m_TrackRotation: 1 + m_SmoothRotation: 0 + m_SmoothRotationAmount: 1.57 + m_TightenRotation: 0.077 + m_TrackScale: 1 + m_SmoothScale: 0 + m_SmoothScaleAmount: 8 + m_TightenScale: 0.1 + m_ThrowOnDetach: 0 + m_ThrowSmoothingDuration: 0 + m_ThrowSmoothingCurve: + serializedVersion: 2 + m_Curve: + - serializedVersion: 3 + time: 1 + value: 1 + inSlope: 0 + outSlope: 0 + tangentMode: 0 + weightedMode: 0 + inWeight: 0 + outWeight: 0 + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + m_ThrowVelocityScale: 0 + m_ThrowAngularVelocityScale: 0 + m_ForceGravityOnDetach: 0 + m_RetainTransformParent: 1 + m_StartingSingleGrabTransformers: [] + m_StartingMultipleGrabTransformers: [] + m_AddDefaultGrabTransformers: 1 + m_FarAttachMode: 0 + m_LimitLinearVelocity: 0 + m_LimitAngularVelocity: 0 + m_MaxLinearVelocityDelta: 10 + m_MaxAngularVelocityDelta: 20 +--- !u!114 &1340190240 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1340190237} + m_Enabled: 0 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d0a1302d0d134fa8a2a5b3bf4aec3c20, type: 3} + m_Name: + m_EditorClassIdentifier: + m_PermittedDisplacementAxes: -1 + m_ConstrainedAxisDisplacementMode: 1 + m_TwoHandedRotationMode: 1 + m_AllowOneHandedScaling: 1 + m_AllowTwoHandedScaling: 1 + m_OneHandedScaleSpeed: 0.5 + m_ThresholdMoveRatioForScale: 0.01 + m_ClampScaling: 1 + m_MinimumScaleRatio: 0.25 + m_MaximumScaleRatio: 2 + m_ScaleMultiplier: 0.25 +--- !u!54 &1340190241 +Rigidbody: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1340190237} + serializedVersion: 4 + m_Mass: 0.0000001 + m_Drag: 0 + m_AngularDrag: 0.05 + m_CenterOfMass: {x: 0, y: 0, z: 0} + m_InertiaTensor: {x: 1, y: 1, z: 1} + m_InertiaRotation: {x: 0, y: 0, z: 0, w: 1} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ImplicitCom: 1 + m_ImplicitTensor: 1 + m_UseGravity: 0 + m_IsKinematic: 1 + m_Interpolate: 1 + m_Constraints: 0 + m_CollisionDetection: 1 --- !u!1001 &1344165365 PrefabInstance: m_ObjectHideFlags: 0 @@ -47070,6 +47246,7 @@ GameObject: - component: {fileID: 1568384459} - component: {fileID: 1568384461} - component: {fileID: 1568384462} + - component: {fileID: 1568384463} m_Layer: 5 m_Name: Canvas m_TagString: Untagged @@ -47084,7 +47261,7 @@ MonoBehaviour: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1568384454} - m_Enabled: 1 + m_Enabled: 0 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3} m_Name: @@ -47304,7 +47481,26 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: c1b136fe9693203418aa8d9bacb7cfcf, type: 3} m_Name: m_EditorClassIdentifier: - interactor: {fileID: 1045947015} + isGrabbingRobot: 0 +--- !u!114 &1568384463 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1568384454} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 7951c64acb0fa62458bf30a60089fe2d, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreReversedGraphics: 0 + m_CheckFor2DOcclusion: 0 + m_CheckFor3DOcclusion: 0 + m_BlockingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RaycastTriggerInteraction: 1 --- !u!1 &1570547337 GameObject: m_ObjectHideFlags: 0 diff --git a/Assets/Scripts/AppManager.cs b/Assets/Scripts/AppManager.cs index 36eaed9..bda90f7 100644 --- a/Assets/Scripts/AppManager.cs +++ b/Assets/Scripts/AppManager.cs @@ -1,3 +1,4 @@ +using System; using System.Collections; using System.Collections.Generic; using System.IO; @@ -48,6 +49,13 @@ public class AppManager : MonoBehaviour model = new ProgramModel(hostip, tcpPort, udpPort, robotController); await model.InitializeAsync(); + if (view == null || tcpView == null || robotController == null || + pointManagerView == null || popupView == null || pathLineView == null) + { + Debug.LogError("AppManager νͿ [Static Views] Ҵ ", this); + return; + } + isModelAndStaticViewsReady = true; TryCreatePresenter(); } @@ -64,15 +72,32 @@ public class AppManager : MonoBehaviour { if (presenter != null) return; - presenter = new ProgramPresenter( - model, - view, - tcpView, - interactionView, - pointManagerView, - popupView, - pathLineView - ); + if (!isModelAndStaticViewsReady || interactionView == null) + { + string log = "Presenter ... ("; + log += "Model&StaticView: " + (isModelAndStaticViewsReady ? "Ready" : "Waiting") + ", "; + log += "InteractionView: " + (interactionView != null ? "Ready" : "Waiting") + ")"; + Debug.Log(log); + return; + } + + try + { + presenter = new ProgramPresenter( + model, + view, + tcpView, + interactionView, + pointManagerView, + popupView, + pathLineView + ); + } + catch (Exception e) + { + Debug.LogError($"Presenter ڿ ߻: {e.Message}\n{e.StackTrace}"); + return; // + } presenter.RegisterControlledRobot(robotController); _ = presenter.UpdateMotorStateAsync(); diff --git a/Assets/Scripts/Model/ProgramModel.cs b/Assets/Scripts/Model/ProgramModel.cs index 720cb2f..4c62f48 100644 --- a/Assets/Scripts/Model/ProgramModel.cs +++ b/Assets/Scripts/Model/ProgramModel.cs @@ -6,11 +6,13 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Net.Http; +using System.Net.Mail; using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; using UdpClientLib; +using UnityEditor.PackageManager; using UnityEngine; public interface IProgramModel @@ -23,7 +25,8 @@ public class ProgramModel : IProgramModel private string tcpBaseUrl; private string udpBaseUrl; HttpClient httpClient = new HttpClient(); - private SingleUdpClient udpClientForHttp; + private SingleTcpClient tcpClient; + private SingleUdpClient udpClient; public UdpClientManager manager = new UdpClientManager(); private List allProgramsCache = new List(); @@ -34,14 +37,22 @@ public class ProgramModel : IProgramModel private readonly object lockObject = new object(); private bool hasNewData; public bool IsMoving; + public bool isError; private Vector3 startMovementPosition; - public CancellationTokenSource cancellationTokenSource; public ProgramModel(string hostip, int tcpPort, int udpPort, RobotController robotController) { tcpBaseUrl = $"http://{hostip}:{tcpPort}"; udpBaseUrl = $"http://{hostip}:{udpPort}"; - udpClientForHttp = manager.AddClient("Udp-client2", hostip, udpPort); + _ = HandleAsyncWork(hostip, tcpPort, udpPort); + } + + public async Task HandleAsyncWork(string hostip, int tcpPort, int udpPort) + { + tcpClient = new SingleTcpClient(); + await tcpClient.ConnectAsync("Tcp-Client", hostip, tcpPort); + udpClient = manager.AddClient("Udp-client", hostip, udpPort); + manager.PrintStatus(); } public async Task InitializeAsync() @@ -49,7 +60,8 @@ public class ProgramModel : IProgramModel await LoadAllPrograms(); hasNewData = false; IsMoving = false; - cancellationTokenSource = new CancellationTokenSource(); + isError = false; + return; } @@ -118,7 +130,7 @@ public class ProgramModel : IProgramModel string jsonString = JsonConvert.SerializeObject(newJob); HttpContent jsonPayload = new StringContent(jsonString, Encoding.UTF8, "application/json"); - + string requestUri = $"{tcpBaseUrl}/project/jobs/create_job"; try { @@ -177,6 +189,20 @@ public class ProgramModel : IProgramModel } } + public async Task GetRobotToolNum() + { + string requestUri = $"{tcpBaseUrl}/project/rgen"; + + HttpResponseMessage result = await httpClient.GetAsync(requestUri); + string jsonResponse = await result.Content.ReadAsStringAsync(); + + JObject data = JObject.Parse(jsonResponse); + + int toolNum = (int)data.SelectToken("tool_no"); + + return toolNum; + } + public async Task GetTCPAsync(CancellationToken token) { while (!token.IsCancellationRequested) @@ -276,8 +302,7 @@ public class ProgramModel : IProgramModel return false; } - // DTO( ü) - // ( RobotData index, α׷ ID  ޴ ʿ) + // ü var payload = new { programId = CurrentProgram.ProgramId, @@ -329,7 +354,7 @@ public class ProgramModel : IProgramModel HttpResponseMessage result = await httpClient.PostAsync(requestUri, content); if (result.IsSuccessStatusCode) { - // , ޸(CurrentProgram) + // , ޸𸮿 CurrentProgram.DeleteStep(index); return true; } @@ -342,50 +367,26 @@ public class ProgramModel : IProgramModel } } - // ǽð κ TCP ̵ - public async Task StreamPoseUdpAsync(RobotData pose) - { - try - { - byte[] udpPacket = ConvertPoseToPacket(pose); - - if (udpClientForHttp != null) - { - await udpClientForHttp.SendBytesAsync(udpPacket); - } - else - { - Debug.LogWarning("UDP Ŭ̾Ʈ ʾҽϴ."); - } - } - catch (Exception e) - { - Debug.LogWarning($"UDP Ʈ : {e.Message}"); - } - } - // Ÿ ̵ - public async Task MoveToPoseTcpAsync(RobotData pose) + public async Task MoveToPoseTcpAsync(Vector3 position) { try { - string jsonString = $"{{\"pose_tg\":{{\"crd\":\"robot\",\"_type\":\"Pose\",\"mechinfo\":1,\"x\":{pose.x},\"y\":{pose.y},\"z\":{pose.z}, \"rx\":{pose.rx}, \"ry\":{pose.ry}, \"rz\":{pose.rz}}}}}"; - HttpContent jsonPayload = new StringContent(jsonString, Encoding.UTF8, "application/json"); + startMovementPosition.x = Convert.ToSingle(Math.Round(-1 * position.x * 1000, 2)); + startMovementPosition.y = Convert.ToSingle(Math.Round(-1 * position.z * 1000, 2)); + startMovementPosition.z = Convert.ToSingle(Math.Round(position.y * 1000, 2)); - HttpResponseMessage result = await httpClient.PostAsync("/project/robot/move_to_pose_manual", jsonPayload); + string jsonResponse = await tcpClient.SendPostRequestAsync("/project/robot/move_to_pose_manual", $"{{\"pose_tg\":{{\"crd\":\"robot\",\"_type\":\"Pose\",\"mechinfo\":1,\"x\":{startMovementPosition.x},\"y\":{startMovementPosition.y},\"z\":{startMovementPosition.z}, \"rx\":{robotData.rx}, \"ry\":{robotData.ry}, \"rz\":{robotData.rz}}}}}"); - if (result.IsSuccessStatusCode) + if (jsonResponse.Contains("200")) { Debug.Log("TCP POST (Move) "); - - this.startMovementPosition = new Vector3(pose.x, pose.y, pose.z); - this.IsMoving = true; + IsMoving = true; return true; } else { - string errorResponse = await result.Content.ReadAsStringAsync(); - Debug.LogError($"TCP POST (Move) ({result.StatusCode}): {errorResponse}"); + Debug.LogError($"TCP POST (Move) "); return false; } } @@ -399,74 +400,71 @@ public class ProgramModel : IProgramModel // TCP POST ̵ üũ public async Task StartMovementCheckLoopAsync(CancellationToken token) { - while (!token.IsCancellationRequested) + try { - if (IsMoving) + while (!token.IsCancellationRequested) { - try + if (IsMoving) { - await udpClientForHttp.SendFilledBytesAsync(new Dictionary { { 2, 0x20 } }); + await udpClient.SendFilledBytesAsync(new Dictionary { { 2, 0x20 } }); + await Task.Delay(100); RobotData currentPose = null; - lock (lockObject) - { - currentPose = this.robotData; - } + lock (lockObject) { currentPose = this.robotData; } if (currentPose != null) { bool isApproximatelyX = Mathf.Approximately(startMovementPosition.x, Convert.ToSingle(Math.Round(currentPose.x, 2))); bool isApproximatelyY = Mathf.Approximately(startMovementPosition.y, Convert.ToSingle(Math.Round(currentPose.y, 2))); bool isApproximatelyZ = Mathf.Approximately(startMovementPosition.z, Convert.ToSingle(Math.Round(currentPose.z, 2))); - if (isApproximatelyX && isApproximatelyY && isApproximatelyZ) { - IsMoving = false; // Ϸ - Debug.Log("TCP Move: ǥ Ϸ."); + IsMoving = false; } } - await Task.Delay(100, token); // 100ms Ȯ } - catch (TaskCanceledException) + else { - Debug.Log("Movement Check Ǿϴ."); - break; + await Task.Delay(500, token); } - catch (Exception e) - { - Debug.Log($"Movement Check : {e.Message}"); - IsMoving = false; // ߻ ߴ - await Task.Delay(1000, token); - } - } - else - { - // (IsMoving = false 1ʰ ) - await Task.Delay(1000, token); } } - } - - private byte[] ConvertPoseToPacket(RobotData pose) - { - using (MemoryStream stream = new MemoryStream()) + catch (TaskCanceledException) { - using (BinaryWriter writer = new BinaryWriter(stream)) - { - writer.Write(pose.x); - writer.Write(pose.y); - writer.Write(pose.z); - writer.Write(pose.rx); - writer.Write(pose.ry); - writer.Write(pose.rz); - } - return stream.ToArray(); + Debug.Log("MovementCheckLoopAsync Canceled."); + } + catch (Exception e) + { + Debug.LogError($"MovementCheckLoopAsync Error: {e.Message}\n{e.StackTrace}"); } } - void OnDestroy() + //private async Task GetMovementState() + //{ + // while (!cancellationTokenSource.Token.IsCancellationRequested) + // { + // try + // { + // var jsonResponse = await tcpClient.SendGetRequestAsync("/project/rgen"); + // var pasrsingJsonResponse = HttpResponseParser.ExtractJsonFromHttpResponse(jsonResponse); + // var tempRobotData = JsonConvert.DeserializeObject(pasrsingJsonResponse, new JsonSerializerSettings { CheckAdditionalContent = false }); + + // jsonResponse = await tcpClient.SendGetRequestAsync($"/logManager/search?cat_p=E&id_min={Convert.ToInt32(tempRobotData.eid_last_err) - 3}&id_max={tempRobotData.eid_last_err}"); + // pasrsingJsonResponse = HttpResponseParser.ExtractJsonFromHttpResponse(jsonResponse); + // tempRobotData = JsonConvert.DeserializeObject(pasrsingJsonResponse, new JsonSerializerSettings { CheckAdditionalContent = false }); + + // isError = tempRobotData != null && tempRobotData.code != null && (tempRobotData.code.Contains("228") || tempRobotData.code.Contains("6037")); + // Debug.Log(isError); + // await Task.Delay(100); + // } + // catch (System.Exception) + // { + // } + // } + //} + + public async Task GetMovingState() { - cancellationTokenSource?.Cancel(); - cancellationTokenSource?.Dispose(); + return await tcpClient.SendGetRequestAsync("/project/robot/moving_to_pose_manual"); } } \ No newline at end of file diff --git a/Assets/Scripts/Presenter/ProgramPresenter.cs b/Assets/Scripts/Presenter/ProgramPresenter.cs index fddf738..fc2f1f6 100644 --- a/Assets/Scripts/Presenter/ProgramPresenter.cs +++ b/Assets/Scripts/Presenter/ProgramPresenter.cs @@ -1,10 +1,13 @@ using System; using System.Collections.Generic; using System.Net.Sockets; +using System.Threading; using System.Threading.Tasks; using UnityEngine; using UnityEngine.UIElements; using UnityEngine.XR.ARSubsystems; +using UnityEngine.XR.Interaction.Toolkit; +using UnityEngine.XR.Interaction.Toolkit.Interactors; public enum PopupState { @@ -29,10 +32,13 @@ public class ProgramPresenter private PathLineView pathLineView; private PopupView popupView; + private Transform popPos; private PopupState currentPopupState = PopupState.None; private RobotData pendingPointData; // ˾â ٸ ӽ private int activePointIndex = -1; // / Ʈ ε + private CancellationTokenSource dragLoopCts; + private RobotData latestTargetPose; // 䰡 ֽ ǥ private bool IsDragging = false; public ProgramPresenter(ProgramModel model, ProgramView view, TCPView tcpView, @@ -56,21 +62,44 @@ public class ProgramPresenter this.interactionView.OnRobotGrabbed += HandleRobotGrabbed; this.interactionView.OnRobotReleased += HandleRobotReleased; - //this.interactionView.OnPointClicked += HandlePointClicked; + this.interactionView.OnPointClicked += HandlePointClicked; this.interactionView.OnPointDragStart += HandlePointDragStart; this.interactionView.OnPointDragUpdate += HandlePointDragUpdate; this.interactionView.OnPointDragEnd += HandlePointDragEnd; - //this.popupView.OnPopupResponse += HandlePopupResponse; + this.popupView.OnPopupResponse += HandlePopupResponse; } public void RegisterControlledRobot(RobotController robot) { this.controlledRobot = robot; this.controlledRobot.OnPoseUpdateRequest += HandleGETPose; - //this.controlledRobot.OnPoseUpdateReceive += HandlePOSTPose; + popPos = controlledRobot.GetEndPoint(); } + //void Update() + //{ + // if (isDragging && currentInteractor != null) + // { + // communicationScript.isMoving = false; + // // 1) Ray Interactor: 3D Raycast Ʈ Ʈ ״ + // if (currentInteractor is XRRayInteractor ray && + // ray.TryGetCurrent3DRaycastHit(out RaycastHit hit)) + // { + // dragPosition = hit.point; + // } + // else + // { + // // 2) Direct Interactor Ǵ Ray Ʈ : Ʈѷ(Ǵ attachTransform) ġ + // var t = currentInteractor.transform; + // var attach = currentInteractor.GetAttachTransform(null); + // dragPosition = attach != null ? attach.position : t.position; + // } + + // uiController?.UpdateCoordinates(dragPosition); // UI :contentReference[oaicite:2]{index=2} + // } + //} + public async Task UpdateMotorStateAsync() { try @@ -147,8 +176,6 @@ public class ProgramPresenter private void HandleAddPoint() { - //// δ UI ǥ κ Ʈ ǥ ޾ƿ; - //// ⼭ ÷ ǥ //Vector3 newPoint = new Vector3(Random.Range(-1f, 1f), Random.Range(0f, 1f), Random.Range(-1f, 1f)); //model.AddPointToCurrentProgram(newPoint); @@ -168,10 +195,6 @@ public class ProgramPresenter // --- ǽð ȭ(->3d) --- private void HandleGETPose() { - //Debug.Log($"⵿ȭ : {interactionView.isGrabbingRobot}"); - //if (interactionView.isGrabbingRobot) - // return; // 3d -> ̸ - RobotData data = model.GetLatestRobotData(); if (data != null) { @@ -186,8 +209,8 @@ public class ProgramPresenter RobotData targetPose = new RobotData(); targetPose.x = Convert.ToSingle(Math.Round(-1 * newWorldPos.x * 1000, 2)); - targetPose.y = Convert.ToSingle(Math.Round(-1 * newWorldPos.z * 1000, 2)); // Unity Z -> Robot Y - targetPose.z = Convert.ToSingle(Math.Round(newWorldPos.y * 1000, 2)); // Unity Y -> Robot Z + targetPose.y = Convert.ToSingle(Math.Round(-1 * newWorldPos.z * 1000, 2)); + targetPose.z = Convert.ToSingle(Math.Round(newWorldPos.y * 1000, 2)); Vector3 eulerAngles = newWorldRot.eulerAngles; @@ -200,23 +223,45 @@ public class ProgramPresenter private async void HandleRobotGrabbed(Vector3 newWorldPos, Quaternion newWorldRot) { - // controlledRobot.EnableIK(); + //if (!IsDragging) return; + //this.latestTargetPose = ConvertPoseToRobotData(newWorldPos, newWorldRot); - RobotData newPose = ConvertPoseToRobotData(newWorldPos, newWorldRot); + //await model.MoveToPoseTcpAsync(newWorldPos); - await model.StreamPoseUdpAsync(newPose); + try + { + if (!IsDragging) + { + Debug.LogWarning("HandleRobotGrabbed: 'IsDragging' false ߴܵ."); + return; + } + + this.latestTargetPose = ConvertPoseToRobotData(newWorldPos, newWorldRot); + + await model.MoveToPoseTcpAsync(newWorldPos); + } + catch (Exception e) + { + Debug.LogError($"HandleRobotGrabbed : {e.Message}\n{e.StackTrace}"); + } } // --- Ʈ ߰ --- private void HandleRobotReleased(RobotData pose) { IsDragging = false; - //controlledRobot.DisableIK(); - interactionView.isGrabbingRobot = false; - HandleGETPose(); - //pendingPointData = pose; // ӽ - //currentPopupState = PopupState.ConfirmAddPoint; // - //popupView.ShowConfirmPopup("ġ Ȯ", " ġ Ʈ Ͻðڽϱ?"); // ˾ û + StopDragMoveLoop(); + controlledRobot.DisableIK(); + pendingPointData = pose; // ӽ + currentPopupState = PopupState.ConfirmAddPoint; // + popupView.ShowConfirmPopup(popPos); // ˾ û + } + + private void StopDragMoveLoop() + { + dragLoopCts?.Cancel(); + dragLoopCts?.Dispose(); + dragLoopCts = null; } // --- Ʈ Ŭ --- @@ -224,7 +269,7 @@ public class ProgramPresenter { activePointIndex = index; // ε currentPopupState = PopupState.MoveOrDelete; // - popupView.ShowOptionPopup("Ʈ ۾", " Ͻðڽϱ?", " ̵", ""); // ˾ û + popupView.ShowOptionPopup(popPos); // ˾ û } // --- Ʈ 巡 --- @@ -233,40 +278,45 @@ public class ProgramPresenter private void HandlePointDragStart(int index) { IsDragging = true; - controlledRobot.EnableIK(); activePointIndex = index; - originalDragPose = model.CurrentProgram.GetStepPose(index); - //interactionView.ShowDragArrow(GetPositionFromPose(originalDragPose)); - interactionView.ShowGhostRobot(originalDragPose); + if (index > -1) // (Ʈ ) + { + originalDragPose = model.CurrentProgram.GetStepPose(index); + interactionView.ShowGhostRobot(originalDragPose); + } } - private async void HandlePointDragUpdate(int index, Vector3 newWorldPos) + private async void HandlePointDragUpdate(int index, Vector3 newWorldPos, Quaternion newWorldRot) { - ////if (!IsDragging) return; - //RobotData newPose = ConvertVectorToRobotData(newWorldPos); + if (!IsDragging) return; + RobotData newPose = ConvertPoseToRobotData(newWorldPos, newWorldRot); + await model.MoveToPoseTcpAsync(newWorldPos); - //// Ʈ κ, Ʈ, ǽð ̵ - ////interactionView.ShowGhostRobot(newPose); - ////pointManagerView.UpdatePointPosition(index, newPose); - ////pathLineView.DrawPath(GetFullPathOfProgramWithTempChange(index, newPose)); // ӽ ׸ + // Ʈ κ, Ʈ, ǽð ̵ + interactionView.ShowGhostRobot(newPose); + pointManagerView.UpdatePointPosition(index, newPose); + //pathLineView.DrawPath(GetFullPathOfProgramWithTempChange(index, newPose)); // ӽ ׸ - //await model.StreamPoseToRobotUdpAsync(newWorldPos); + //await model.StreamPoseUdpAsync(newPose); } private void HandlePointDragEnd(int index) { IsDragging = false; - //interactionView.HideDragArrow(); - //interactionView.HideGhostRobot(); + StopDragMoveLoop(); // + controlledRobot.DisableIK(); - //// ( κ ġ ̵ - 5ܰ) - //// robotController.SetRobotPosition(newPose); + interactionView.HideDragArrow(); + interactionView.HideGhostRobot(); - //pendingPointData = ConvertVectorToRobotData(GetLastDragPosition()); // ӽ - //currentPopupState = PopupState.ConfirmModifyPoint; // - //popupView.ShowConfirmPopup("ġ ", " ġ Ʈ Ͻðڽϱ?"); // ˾ û + // κ ġ ̵ + // robotController.SetRobotPosition(newPose); + + //pendingPointData = ConvertPoseToRobotData(GetLastDragPosition()); // ӽ + currentPopupState = PopupState.ConfirmModifyPoint; // + popupView.ShowConfirmPopup(popPos); } @@ -277,47 +327,47 @@ public class ProgramPresenter switch (currentPopupState) { + // Ȯ/ case PopupState.ConfirmAddPoint: - if (response == PopupResponse.Confirm) // Ȯ + if (response == PopupResponse.InsConfirm) { await model.SavePointToProgramAsync(pendingPointData); RedrawSceneFromModel(); // } break; - // 巡 Ȯ/ + // Ȯ/ case PopupState.ConfirmModifyPoint: - if (response == PopupResponse.Confirm) // Ȯ + if (response == PopupResponse.ModConfirm) { // ġ - // 巡װ ġ α׷ await model.SavePointToProgramAsync(pendingPointData, activePointIndex); RedrawSceneFromModel(); } - else // + else if (response == PopupResponse.Cancel) { pointManagerView.UpdatePointPosition(activePointIndex, originalDragPose); // ġ RedrawSceneFromModel(); // ġ } break; - // ̵/ + // ̵/ case PopupState.MoveOrDelete: - if (response == PopupResponse.Option1) // ̵ + if (response == PopupResponse.Move) { RobotData targetPose = model.CurrentProgram.GetStepPose(activePointIndex); - //await model.StartMovement(targetPose); + //await model.MoveToPoseTcpAsync(targetPose); } - else if (response == PopupResponse.Option2) // + else if (response == PopupResponse.Delete) { currentPopupState = PopupState.ConfirmDelete; - popupView.ShowConfirmPopup(" Ȯ", " Ʈ Ͻðڽϱ?"); + popupView.ShowConfirmPopup(popPos); } break; // case PopupState.ConfirmDelete: - if (response == PopupResponse.Confirm) + if (response == PopupResponse.DelConfirm) { await model.DeletePointFromProgramAsync(activePointIndex); RedrawSceneFromModel(); @@ -333,13 +383,13 @@ public class ProgramPresenter // Model ¸ о View(Ʈ, ) ħ private void RedrawSceneFromModel() { - //if (model.CurrentProgram == null) return; + if (model.CurrentProgram == null) return; - //// (RobotProgram.Steps (List) List ȯϴ ) - //List poses = model.CurrentProgram.GetAllStepPoses(); + //(RobotProgram.Steps (List) List ȯϴ + List poses = model.CurrentProgram.GetAllStepPoses(); - //pointManagerView.RedrawPoints(poses); // Ʈ ٽ ׸ - //pathLineView.DrawPath(poses); // ٽ ׸ + pointManagerView.RedrawPoints(poses); // Ʈ ٽ ׸ + pathLineView.DrawPath(poses); // ٽ ׸ } private void Destroy() @@ -352,7 +402,6 @@ public class ProgramPresenter this.view.OnAddPointClicked -= HandleAddPoint; this.tcpView.OnTCPupdateRequested -= HandleTCPViewUpdate; this.controlledRobot.OnPoseUpdateRequest -= HandleGETPose; - //this.controlledRobot.OnPoseUpdateReceive -= HandlePOSTPose; this.interactionView.OnRobotGrabbed -= HandleRobotGrabbed; this.interactionView.OnRobotReleased -= HandleRobotReleased; this.interactionView.OnPointDragStart -= HandlePointDragStart; diff --git a/Assets/Scripts/Presenter/SplashPresenter.cs b/Assets/Scripts/Presenter/SplashPresenter.cs index b1be803..5886fa2 100644 --- a/Assets/Scripts/Presenter/SplashPresenter.cs +++ b/Assets/Scripts/Presenter/SplashPresenter.cs @@ -6,7 +6,6 @@ public class SplashPresenter : MonoBehaviour [SerializeField] private string NextScene; public void OnEnterBtnClicked() { - Debug.Log("ưŬ"); SceneManager.LoadScene(NextScene); } } diff --git a/Assets/Scripts/View/InteractionView.cs b/Assets/Scripts/View/InteractionView.cs index bc64e21..81cea8f 100644 --- a/Assets/Scripts/View/InteractionView.cs +++ b/Assets/Scripts/View/InteractionView.cs @@ -1,26 +1,14 @@ using System; +using System.Threading; +using System.Threading.Tasks; using UnityEngine; using UnityEngine.XR.Interaction.Toolkit; +using UnityEngine.XR.Interaction.Toolkit.Interactables; using UnityEngine.XR.Interaction.Toolkit.Interactors; -// Presenter InteractionView ϱ ̽ public interface IInteractionView { - event Action OnRobotGrabbed; - // VR Ʈѷ κ Ҵ ߻ - event Action OnRobotReleased; - // VR Ʈѷ Ư Ʈ Ŭ ߻ - event Action OnPointClicked; - // VR Ʈѷ Ʈ 巡 // ߻ - event Action OnPointDragStart; - event Action OnPointDragUpdate; // (Ʈ ε, ǥ) - event Action OnPointDragEnd; - // Presenter ȣ Լ - void ShowGhostRobot(RobotData pose); - void HideGhostRobot(); - void ShowDragArrow(Vector3 position); - void HideDragArrow(); } public class InteractionView : MonoBehaviour, IInteractionView @@ -29,10 +17,12 @@ public class InteractionView : MonoBehaviour, IInteractionView public event Action OnRobotReleased; public event Action OnPointClicked; public event Action OnPointDragStart; - public event Action OnPointDragUpdate; + public event Action OnPointDragUpdate; public event Action OnPointDragEnd; - private XRBaseInteractor interactor; + [SerializeField]private NearFarInteractor nearFarInteractor; + private XRBaseInteractor baseInteractor; + private IXRRayProvider rayProvider; private bool isInitialized = false; private bool isGrabbingPoint = false; @@ -42,41 +32,57 @@ public class InteractionView : MonoBehaviour, IInteractionView void Start() { - // Ray Interactor Direct Interactor ó ֵ XRBaseInteractor - interactor = GetComponent(); - if (interactor == null) + nearFarInteractor = GetComponent(); + + if (nearFarInteractor == null) { - Debug.LogError("InteractionView requires an XRBaseInteractor (Ray or Direct) on the same GameObject.", this); + Debug.LogError("InteractionView: 'nearFarInteractor' Ҵ ʾҽϴ", this); return; } + + baseInteractor = nearFarInteractor as XRBaseInteractor; + rayProvider = nearFarInteractor as IXRRayProvider; + + if (baseInteractor == null) + { + Debug.LogError("NearFarInteractor XRBaseInteractor ȯ ϴ.", this); + return; + } + + InitializeInteraction(); } - // --- ǽð Ʈ Update --- void Update() { - if (isInitialized) + if (!isInitialized || rayProvider == null) { - if (isGrabbingPoint) + if (nearFarInteractor == null) { - Vector3 currentControllerPosition = interactor.attachTransform.position; - OnPointDragUpdate?.Invoke(currentGrabbedPointIndex, currentControllerPosition); + nearFarInteractor = GetComponentInChildren(true); + baseInteractor = nearFarInteractor as XRBaseInteractor; + rayProvider = nearFarInteractor as IXRRayProvider; } - else if(isGrabbingRobot) + if (nearFarInteractor != null && nearFarInteractor.gameObject.activeInHierarchy) { - Vector3 currentHandleTransform = interactor.attachTransform.position; - Quaternion currentControllerRotation = interactor.attachTransform.rotation; - OnRobotGrabbed?.Invoke(currentHandleTransform, currentControllerRotation); + InitializeInteraction(); } } else { - if (interactor == null) + Vector3 currentTargetPosition = Vector3.zero; + Quaternion currentTargetRotation = Quaternion.identity; + + currentTargetPosition = rayProvider.rayEndPoint; + currentTargetRotation = baseInteractor.attachTransform.rotation; + + + if (isGrabbingPoint) { - interactor = GetComponentInChildren(true); + OnPointDragUpdate?.Invoke(currentGrabbedPointIndex, currentTargetPosition, currentTargetRotation); } - if (interactor != null && interactor.gameObject.activeInHierarchy) + else if (isGrabbingRobot) { - InitializeInteraction(); + OnRobotGrabbed?.Invoke(currentTargetPosition, currentTargetRotation); } } } @@ -84,22 +90,23 @@ public class InteractionView : MonoBehaviour, IInteractionView private void InitializeInteraction() { // XRI ̺Ʈ - interactor.selectEntered.AddListener(HandleGrabStart); - interactor.selectExited.AddListener(HandleGrabEnd); - - // 'Ŭ' Ϸ interactor.activated ̺Ʈ ؾ + baseInteractor.selectEntered.AddListener(HandleGrabStart); + baseInteractor.selectExited.AddListener(HandleGrabEnd); + //interactor.activated.AddListener(OnActivated); + //interactor.deactivated.AddListener(OnDeactivated); isInitialized = true; AppManager.Instance.RegisterView(this); - Debug.Log("InteractionView ʱȭ Ϸ. Interactor ̺Ʈ ."); } private void OnDestroy() { - if (interactor != null) + if (baseInteractor != null) { - interactor.selectEntered.RemoveListener(HandleGrabStart); - interactor.selectExited.RemoveListener(HandleGrabEnd); + baseInteractor.selectEntered.RemoveListener(HandleGrabStart); + baseInteractor.selectExited.RemoveListener(HandleGrabEnd); + //interactor.activated.RemoveListener(OnActivated); + //interactor.deactivated.RemoveListener(OnDeactivated); } } @@ -108,48 +115,157 @@ public class InteractionView : MonoBehaviour, IInteractionView // "" ư private void HandleGrabStart(SelectEnterEventArgs args) { - // Ʈ GameObject grabbedGO = args.interactableObject.transform.gameObject; - //// "Ʈ" Ȯ (RobotPoint ũƮ Ž) + // "Ʈ" Ȯ //RobotPoint point = grabbedGO.GetComponent(); //if (point != null) //{ // isGrabbingPoint = true; + // isGrabbingRobot = false; // currentGrabbedPointIndex = point.pointIndex; - // // Presenter "巡 " ̺Ʈ + // // (Presenter HandlePointDragStart ȣ) // OnPointDragStart?.Invoke(currentGrabbedPointIndex); //} - // "κ" Ȯ - if (grabbedGO.CompareTag("RobotArm")) + // 2. "κ ڵ" Ȯ + if (grabbedGO.CompareTag("RobotArm")) { + isGrabbingPoint = false; isGrabbingRobot = true; + + // (κ ü -1 ε Presenter ˸) + currentGrabbedPointIndex = -1; + + // (κ ⵵ "PointDragStart" ̺Ʈ Ͽ Presenter ˸) + OnPointDragStart?.Invoke(currentGrabbedPointIndex); } + + //if (!enableSelectToDrag) return; + //BeginDrag(args.interactorObject); } // "" ư private void HandleGrabEnd(SelectExitEventArgs args) { - // "Ʈ" ִ ̾ٸ - if (isGrabbingPoint) - { - // Presenter "巡 " ̺Ʈ (˾ Ʈſ) - OnPointDragEnd?.Invoke(currentGrabbedPointIndex); - } - // "κ" ִ ̾ٸ - else if (isGrabbingRobot) - { - // Presenter "κ " ̺Ʈ (˾ Ʈſ) - RobotData currentPose = GetCurrentRobotPoseFromController(); - OnRobotReleased?.Invoke(currentPose); - } + //if (!enableSelectToDrag) return; + //EndDrag(); + //// "Ʈ" ִ ̾ٸ + //if (isGrabbingPoint) + //{ + // // Presenter "巡 " ̺Ʈ (˾ Ʈſ) + // OnPointDragEnd?.Invoke(currentGrabbedPointIndex); + //} + //// "κ" ִ ̾ٸ + //else if (isGrabbingRobot) + //{ + // // Presenter "κ " ̺Ʈ (˾ Ʈſ) + // RobotData currentPose = GetCurrentRobotPoseFromController(); + // OnRobotReleased?.Invoke(currentPose); + //} // ʱȭ isGrabbingPoint = false; + isGrabbingRobot = false; currentGrabbedPointIndex = -1; } + // ---- Drag lifecycle ---- + //private void BeginDrag(IXRInteractor interactor) + //{ + // currentInteractor = interactor; + // isDragging = true; + + // startPosition = transform.position; + // //pathLine.enabled = true; + + // uiController?.UpdateStatus("巡 ..."); + // if (communicationScript != null) communicationScript.isMoving = false; + + // // 巡 + // StartDragMoveLoop(); + //} + + //private void EndDrag() + //{ + // if (!isDragging) return; + // isDragging = false; + // uiController?.UpdateStatus("Ϸ!"); + // communicationScript.isMoving = false; + // // + // StopDragMoveLoop(); + + // currentInteractor = null; + //} + + //private void StopDragMoveLoop() + //{ + // if (dragLoopCts != null) + // { + // dragLoopCts.Cancel(); + // dragLoopCts.Dispose(); + // dragLoopCts = null; + // } + //} + + + //private void StartDragMoveLoop() + //{ + // StopDragMoveLoop(); // ߺ + // dragLoopCts = new CancellationTokenSource(); + // _ = DragMoveLoopAsync(dragLoopCts.Token); + //} + + //private async Task DragMoveLoopAsync(CancellationToken token) + //{ + // // 巡 100ms ֱ + // while (!token.IsCancellationRequested && isDragging) + // { + // try + // { + // // κ ̵ ƴ϶( ) ֽ dragPosition + // if (communicationScript != null && !communicationScript.isMoving) + // { + // await MovingTask(); // ο StratMovement(dragPosition) ȣ isMoving :contentReference[oaicite:4]{index=4} + // } + + // await Task.Delay(10, token); // 100ms ֱ + // } + // catch (TaskCanceledException) { /* */ } + // } + //} + + //// ---- Per-frame ---- + //void Update() + //{ + // if (isDragging && currentInteractor != null) + // { + // communicationScript.isMoving = false; + // // 1) Ray Interactor: 3D Raycast Ʈ Ʈ ״ + // if (currentInteractor is XRRayInteractor ray && + // ray.TryGetCurrent3DRaycastHit(out RaycastHit hit)) + // { + // dragPosition = hit.point; + // } + // else + // { + // // 2) Direct Interactor Ǵ Ray Ʈ : Ʈѷ(Ǵ attachTransform) ġ + // var t = currentInteractor.transform; + // var attach = currentInteractor.GetAttachTransform(null); + // dragPosition = attach != null ? attach.position : t.position; + // } + + // uiController?.UpdateCoordinates(dragPosition); // UI :contentReference[oaicite:2]{index=2} + // } + //} + + //private async Task MovingTask() + //{ + // if (communicationScript == null) return; + // bool ok = await communicationScript.StratMovement(dragPosition); // ȣ ״ :contentReference[oaicite:3]{index=3} + // if (ok) communicationScript.isMoving = true; + //} + private RobotData GetCurrentRobotPoseFromController() { // View Presenter ȯ (ConvertVrToRobotPose) Ƿ, @@ -159,8 +275,23 @@ public class InteractionView : MonoBehaviour, IInteractionView } // --- Presenter ȣ Լ --- - public void ShowGhostRobot(RobotData pose) { /* κ2 Ȱȭ ġ */ } - public void HideGhostRobot() { /* κ2 Ȱȭ */ } - public void ShowDragArrow(Vector3 position) { /* 巡׿ ȭǥ UI Ȱȭ ġ */ } - public void HideDragArrow() { /* 巡׿ ȭǥ UI Ȱȭ */ } + public void ShowGhostRobot(RobotData pose) + { + /* κ2 Ȱȭ ġ */ + } + + public void HideGhostRobot() + { + /* κ2 Ȱȭ */ + } + + public void ShowDragArrow(Vector3 position) + { + /* 巡׿ ȭǥ UI Ȱȭ ġ */ + } + + public void HideDragArrow() + { + /* 巡׿ ȭǥ UI Ȱȭ */ + } } diff --git a/Assets/Scripts/View/ProgramView.cs b/Assets/Scripts/View/ProgramView.cs index 9e931ea..7f29de5 100644 --- a/Assets/Scripts/View/ProgramView.cs +++ b/Assets/Scripts/View/ProgramView.cs @@ -23,7 +23,7 @@ public interface IProgramView public class ProgramView : MonoBehaviour, IProgramView { // --- UI --- - [SerializeField] private Button loadIconButton; + //[SerializeField] private Button loadIconButton; [SerializeField] private Button loadProgramButton; //[SerializeField] private Button saveProgramButton; //[SerializeField] private Button addPointButton; // UI ġ ư @@ -68,13 +68,12 @@ public class ProgramView : MonoBehaviour, IProgramView backspaceButton.onClick.AddListener(HandleBackspace); createProgramButton.onClick.AddListener(HandleCreateClick); - loadIconButton.onClick.AddListener(HandleLoadIconClick); + //loadIconButton.onClick.AddListener(HandleLoadIconClick); closeProgramListButton.onClick.AddListener(HideProgramList); programSelectPanel.SetActive(true); programNewPanel.SetActive(true); programListPanel.SetActive(false); - loadProgramButton.gameObject.SetActive(false); programIdText.text = string.Empty; } @@ -97,11 +96,6 @@ public class ProgramView : MonoBehaviour, IProgramView OnCreateProgramClicked?.Invoke(inputId); } - private void HandleLoadIconClick() - { - loadProgramButton.gameObject.SetActive(true); - } - // Presenter ȣ ޽ ǥ Լ public void ShowMessage(string message) { @@ -112,21 +106,10 @@ public class ProgramView : MonoBehaviour, IProgramView { if (programId == null) { - //currentProgramIdText.text = "No Program Loaded"; - //endpointListText.text = ""; Debug.Log("No Program Loaded"); return; } Debug.Log($" α׷: {programId}.job"); - - //currentProgramIdText.text = "Current: " + program.programId; - - //System.Text.StringBuilder sb = new System.Text.StringBuilder(); - //for (int i = 0; i < program.endpointPositions.Count; i++) - //{ - // sb.AppendLine($"P{i + 1}: {program.endpointPositions[i].ToString("F2")}"); - //} - //endpointListText.text = sb.ToString(); } public void ShowProgramList(List programIds) diff --git a/Assets/VRTemplateAssets/Prefabs/Setup/Complete XR Origin Set Up Hands Variant.prefab b/Assets/VRTemplateAssets/Prefabs/Setup/Complete XR Origin Set Up Hands Variant.prefab index 03ec3b0..c200677 100644 --- a/Assets/VRTemplateAssets/Prefabs/Setup/Complete XR Origin Set Up Hands Variant.prefab +++ b/Assets/VRTemplateAssets/Prefabs/Setup/Complete XR Origin Set Up Hands Variant.prefab @@ -682,6 +682,8 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: c1b136fe9693203418aa8d9bacb7cfcf, type: 3} m_Name: m_EditorClassIdentifier: + interactor: {fileID: 0} + isGrabbingRobot: 0 --- !u!1 &7917674758240283208 stripped GameObject: m_CorrespondingSourceObject: {fileID: 657184242222895507, guid: d6878e1999eb4b44a9f5a263af86c185, type: 3} @@ -699,6 +701,8 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: c1b136fe9693203418aa8d9bacb7cfcf, type: 3} m_Name: m_EditorClassIdentifier: + interactor: {fileID: 0} + isGrabbingRobot: 0 --- !u!4 &7917674758240283209 stripped Transform: m_CorrespondingSourceObject: {fileID: 657184242222895506, guid: d6878e1999eb4b44a9f5a263af86c185, type: 3} @@ -731,6 +735,8 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: c1b136fe9693203418aa8d9bacb7cfcf, type: 3} m_Name: m_EditorClassIdentifier: + interactor: {fileID: 0} + isGrabbingRobot: 0 --- !u!114 &8053059486601427065 stripped MonoBehaviour: m_CorrespondingSourceObject: {fileID: 810019319561094050, guid: d6878e1999eb4b44a9f5a263af86c185, type: 3} @@ -764,3 +770,5 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: c1b136fe9693203418aa8d9bacb7cfcf, type: 3} m_Name: m_EditorClassIdentifier: + interactor: {fileID: 0} + isGrabbingRobot: 0 diff --git a/ProjectSettings/TagManager.asset b/ProjectSettings/TagManager.asset index b97216a..d694b72 100644 --- a/ProjectSettings/TagManager.asset +++ b/ProjectSettings/TagManager.asset @@ -6,6 +6,7 @@ TagManager: tags: - Anchor - RobotArm + - Point layers: - Default - TransparentFX