<fix>위치 정보 수정/삭제 완료
This commit is contained in:
@@ -48,6 +48,7 @@ public class BoxController : MonoBehaviour
|
||||
// 로봇 팔을 부모로 설정하여 따라다니게 함
|
||||
attachParent = other.transform;
|
||||
transform.SetParent(attachParent);
|
||||
transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity);
|
||||
|
||||
// 부착된 동안 물리적 충돌이나 중력을 무시하도록 Rigidbody를 Kinematic으로 설정
|
||||
if (rb != null)
|
||||
|
||||
@@ -524,6 +524,9 @@ public class ProgramModel : IProgramModel
|
||||
|
||||
public async Task<string> GetMovingState()
|
||||
{
|
||||
return await tcpClient.SendGetRequestAsync("/project/robot/moving_to_pose_manual");
|
||||
string jsonResponse = await tcpClient.SendGetRequestAsync("/project/robot/moving_to_pose_manual");
|
||||
string parsingJsonResponse = HttpResponseParser.ExtractJsonFromHttpResponse(jsonResponse);
|
||||
|
||||
return parsingJsonResponse;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading;
|
||||
@@ -76,6 +77,9 @@ public class ProgramPresenter
|
||||
this.controlledRobot = robot;
|
||||
this.controlledRobot.OnPoseUpdateRequest += HandleGETPose;
|
||||
popPos = controlledRobot.GetEndPoint();
|
||||
|
||||
if (controlledRobot != null)
|
||||
controlledRobot.StartCoroutine(UpdateRobotMovingStateCoroutine());
|
||||
}
|
||||
|
||||
public async Task UpdateMotorStateAsync()
|
||||
@@ -96,6 +100,37 @@ public class ProgramPresenter
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator UpdateRobotMovingStateCoroutine()
|
||||
{
|
||||
var waitForOneSecond = new WaitForSeconds(1.0f);
|
||||
while (true)
|
||||
{
|
||||
Task<string> getTask = model.GetMovingState();
|
||||
|
||||
yield return new WaitUntil(() => getTask.IsCompleted);
|
||||
|
||||
try
|
||||
{
|
||||
if (getTask.IsFaulted)
|
||||
{
|
||||
throw getTask.Exception.InnerException;
|
||||
}
|
||||
|
||||
string currentState = getTask.Result;
|
||||
|
||||
if (pointManagerView.movingAlert != null)
|
||||
{
|
||||
pointManagerView.movingAlert.SetActive(currentState == "1");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogWarning($"로봇 moving 상태 업데이트 실패: {e.Message}");
|
||||
}
|
||||
yield return waitForOneSecond;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnApplicationStart()
|
||||
{
|
||||
if (controlledRobot != null)
|
||||
@@ -220,7 +255,7 @@ public class ProgramPresenter
|
||||
|
||||
this.latestTargetPose = ConvertPoseToRobotData(newWorldPos, newWorldRot);
|
||||
|
||||
await model.MoveToPoseTcpAsync(newWorldPos);
|
||||
await model.MoveToPoseTcpAsync(newWorldPos);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -232,9 +267,10 @@ public class ProgramPresenter
|
||||
private void HandleRobotReleased(RobotData pose)
|
||||
{
|
||||
IsDragging = false;
|
||||
pendingPointData = pose; // 임시 저장
|
||||
pendingPointData = this.latestTargetPose; // 임시 저장
|
||||
currentPopupState = PopupState.ConfirmAddPoint; // 상태 설정
|
||||
popupView.ShowConfirmPopup(popPos); // 팝업 요청
|
||||
|
||||
_ = WaitForRobotToStopAndShowPopup(currentPopupState);
|
||||
}
|
||||
|
||||
private void StopDragMoveLoop()
|
||||
@@ -245,11 +281,11 @@ public class ProgramPresenter
|
||||
}
|
||||
|
||||
// --- 포인트 클릭 ---
|
||||
private void HandlePointClicked(int index)
|
||||
private void HandlePointClicked(int index, Vector3 newWorldPos)
|
||||
{
|
||||
activePointIndex = index; // 인덱스 저장
|
||||
currentPopupState = PopupState.MoveOrDelete; // 상태 설정
|
||||
popupView.ShowOptionPopup(popPos); // 팝업 요청
|
||||
popupView.ShowOptionPopup(newWorldPos); // 팝업 요청
|
||||
}
|
||||
|
||||
// --- 포인트 드래그 ---
|
||||
@@ -283,7 +319,7 @@ public class ProgramPresenter
|
||||
RedrawTemporaryPath(index, latestTargetPose);
|
||||
}
|
||||
|
||||
private void HandlePointDragEnd(int index)
|
||||
private async void HandlePointDragEnd(int index)
|
||||
{
|
||||
IsDragging = false;
|
||||
|
||||
@@ -291,10 +327,14 @@ public class ProgramPresenter
|
||||
interactionView.HideGhostRobot();
|
||||
|
||||
pendingPointData = this.latestTargetPose;
|
||||
currentPopupState = PopupState.ConfirmModifyPoint; // 상태 설정
|
||||
popupView.ShowConfirmPopup(popPos);
|
||||
}
|
||||
|
||||
Vector3 popupWorldPos = ConvertRobotDataToVector3(pendingPointData);
|
||||
await model.MoveToPoseTcpAsync(popupWorldPos);
|
||||
|
||||
currentPopupState = PopupState.ConfirmModifyPoint; // 상태 설정
|
||||
|
||||
popupView.ShowModifyPopup(popPos);
|
||||
}
|
||||
|
||||
// --- 팝업 응답 통합 핸들러 ---
|
||||
private async void HandlePopupResponse(PopupResponse response)
|
||||
@@ -307,7 +347,7 @@ public class ProgramPresenter
|
||||
case PopupState.ConfirmAddPoint:
|
||||
if (response == PopupResponse.InsConfirm)
|
||||
{
|
||||
await model.SavePointToProgramAsync(pendingPointData);
|
||||
await model.SavePointToProgramAsync(pendingPointData, -1);
|
||||
RedrawSceneFromModel(); // 뷰 갱신
|
||||
}
|
||||
break;
|
||||
@@ -323,27 +363,23 @@ public class ProgramPresenter
|
||||
else if (response == PopupResponse.Cancel)
|
||||
{
|
||||
pointManagerView.UpdatePointPosition(activePointIndex, originalDragPose); // 원위치
|
||||
RedrawSceneFromModel(); // 경로 원위치
|
||||
RedrawTemporaryPath(activePointIndex, originalDragPose); // 경로 원위치
|
||||
}
|
||||
break;
|
||||
|
||||
// 여기로 이동/삭제
|
||||
case PopupState.MoveOrDelete:
|
||||
RobotData targetPose = model.CurrentProgram.GetStepPose(activePointIndex);
|
||||
Vector3 pos = ConvertRobotDataToVector3(targetPose);
|
||||
if (response == PopupResponse.Move)
|
||||
{
|
||||
RobotData targetPose = model.CurrentProgram.GetStepPose(activePointIndex);
|
||||
Vector3 pos = ConvertRobotDataToVector3(targetPose);
|
||||
|
||||
// 알림 UI 표시
|
||||
pointManagerView.movingAlert.SetActive(true);
|
||||
|
||||
await model.MoveToPoseTcpAsync(pos);
|
||||
Debug.Log($"이동 중? : { await model.GetMovingState()}"); // TODO. 어떤 값을 받아오는지.
|
||||
}
|
||||
else if (response == PopupResponse.Delete)
|
||||
{
|
||||
popupView.ShowDeletePopup(pos);
|
||||
currentPopupState = PopupState.ConfirmDelete;
|
||||
popupView.ShowConfirmPopup(popPos);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -362,10 +398,42 @@ public class ProgramPresenter
|
||||
activePointIndex = -1;
|
||||
}
|
||||
|
||||
private async Task WaitForRobotToStopAndShowPopup(PopupState nextState)
|
||||
{
|
||||
while (await model.GetMovingState() == "1")
|
||||
{
|
||||
Debug.Log("로봇이 멈추기를 기다리는 중...");
|
||||
await Task.Delay(100);
|
||||
}
|
||||
|
||||
Debug.Log("로봇 정지 완료. 팝업 표시.");
|
||||
currentPopupState = nextState;
|
||||
|
||||
Vector3 popupWorldPos = Vector3.zero;
|
||||
|
||||
if (nextState == PopupState.ConfirmAddPoint)
|
||||
{
|
||||
popupWorldPos = ConvertRobotDataToVector3(pendingPointData);
|
||||
popupView.ShowConfirmPopupFromPoint(popupWorldPos); // (새 포인트 위치)
|
||||
}
|
||||
}
|
||||
|
||||
private async Task WaitForRobotToStop()
|
||||
{
|
||||
Debug.Log("로봇 이동 완료 대기 중...");
|
||||
await Task.Delay(200); // (명령이 전달될 최소 시간)
|
||||
while (await model.GetMovingState() == "1")
|
||||
{
|
||||
await Task.Delay(100);
|
||||
}
|
||||
Debug.Log("로봇 정지 완료.");
|
||||
}
|
||||
|
||||
// Model의 현재 상태를 읽어 모든 View를 새로 고침
|
||||
private void RedrawSceneFromModel()
|
||||
private async void RedrawSceneFromModel()
|
||||
{
|
||||
if (model.CurrentProgram == null) return;
|
||||
await model.LoadProgram(model.CurrentProgram.ProgramId);
|
||||
|
||||
// RobotProgram.Steps (List<RobotMoveStep>)를 List<RobotData>로 변환
|
||||
List<RobotData> poses = model.CurrentProgram.GetAllStepPoses();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
@@ -15,7 +16,7 @@ public class InteractionView : MonoBehaviour, IInteractionView
|
||||
{
|
||||
public event Action<Vector3, Quaternion> OnRobotGrabbed;
|
||||
public event Action<RobotData> OnRobotReleased;
|
||||
public event Action<int> OnPointClicked;
|
||||
public event Action<int, Vector3> OnPointClicked;
|
||||
public event Action<int> OnPointDragStart;
|
||||
public event Action<int, Vector3, Quaternion> OnPointDragUpdate;
|
||||
public event Action<int> OnPointDragEnd;
|
||||
@@ -30,11 +31,18 @@ public class InteractionView : MonoBehaviour, IInteractionView
|
||||
[SerializeField]
|
||||
[Tooltip("드래그용 마우스 이미지")]
|
||||
private GameObject dragArrow;
|
||||
[SerializeField] private float clickTimeThreshold = 0.5f;
|
||||
[SerializeField] private float dragMovementThreshold = 0.05f;
|
||||
private Coroutine clickOrDragCoroutine = null;
|
||||
private Vector3 startGrabPosition;
|
||||
|
||||
private bool isInitialized = false;
|
||||
private bool isGrabbingPoint = false;
|
||||
private int currentGrabbedPointIndex = -1;
|
||||
|
||||
Vector3 currentTargetPosition = Vector3.zero;
|
||||
Quaternion currentTargetRotation = Quaternion.identity;
|
||||
|
||||
public bool isGrabbingRobot = false;
|
||||
|
||||
void Start()
|
||||
@@ -76,21 +84,29 @@ public class InteractionView : MonoBehaviour, IInteractionView
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector3 currentTargetPosition = Vector3.zero;
|
||||
Quaternion currentTargetRotation = Quaternion.identity;
|
||||
|
||||
currentTargetPosition = rayProvider.rayEndPoint;
|
||||
currentTargetRotation = baseInteractor.attachTransform.rotation;
|
||||
|
||||
if (isGrabbingRobot)
|
||||
{
|
||||
OnRobotGrabbed?.Invoke(currentTargetPosition, currentTargetRotation);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isGrabbingPoint)
|
||||
{
|
||||
OnPointDragUpdate?.Invoke(currentGrabbedPointIndex, currentTargetPosition, currentTargetRotation);
|
||||
}
|
||||
else if (isGrabbingRobot)
|
||||
else if (clickOrDragCoroutine != null)
|
||||
{
|
||||
OnRobotGrabbed?.Invoke(currentTargetPosition, currentTargetRotation);
|
||||
float distance = Vector3.Distance(startGrabPosition, currentTargetPosition);
|
||||
|
||||
if (distance > dragMovementThreshold)
|
||||
{
|
||||
StartDragMode();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,8 +126,6 @@ public class InteractionView : MonoBehaviour, IInteractionView
|
||||
{
|
||||
baseInteractor.selectEntered.RemoveListener(HandleGrabStart);
|
||||
baseInteractor.selectExited.RemoveListener(HandleGrabEnd);
|
||||
//interactor.activated.RemoveListener(OnActivated);
|
||||
//interactor.deactivated.RemoveListener(OnDeactivated);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,7 +142,13 @@ public class InteractionView : MonoBehaviour, IInteractionView
|
||||
isGrabbingRobot = false;
|
||||
currentGrabbedPointIndex = point.pointIndex;
|
||||
|
||||
OnPointDragStart?.Invoke(currentGrabbedPointIndex);
|
||||
// 타이머 시작
|
||||
startGrabPosition = rayProvider.rayEndPoint;
|
||||
if (clickOrDragCoroutine != null)
|
||||
StopCoroutine(clickOrDragCoroutine);
|
||||
clickOrDragCoroutine = StartCoroutine(ClickOrDragTimer());
|
||||
|
||||
//OnPointDragStart?.Invoke(currentGrabbedPointIndex);
|
||||
}
|
||||
else if (grabbedGO.CompareTag("RobotArm"))
|
||||
{
|
||||
@@ -142,21 +162,57 @@ public class InteractionView : MonoBehaviour, IInteractionView
|
||||
|
||||
private void HandleGrabEnd(SelectExitEventArgs args)
|
||||
{
|
||||
if (isGrabbingPoint)
|
||||
{
|
||||
OnPointDragEnd?.Invoke(currentGrabbedPointIndex);
|
||||
}
|
||||
else if (isGrabbingRobot)
|
||||
if (isGrabbingRobot)
|
||||
{
|
||||
OnRobotReleased?.Invoke(new RobotData());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (clickOrDragCoroutine != null)
|
||||
{
|
||||
StopCoroutine(clickOrDragCoroutine);
|
||||
clickOrDragCoroutine = null;
|
||||
|
||||
OnPointClicked?.Invoke(currentGrabbedPointIndex, currentTargetPosition);
|
||||
}
|
||||
else if (isGrabbingPoint)
|
||||
{
|
||||
OnPointDragEnd?.Invoke(currentGrabbedPointIndex);
|
||||
}
|
||||
}
|
||||
|
||||
// 상태 초기화
|
||||
clickOrDragCoroutine = null;
|
||||
isGrabbingPoint = false;
|
||||
isGrabbingRobot = false;
|
||||
currentGrabbedPointIndex = -1;
|
||||
}
|
||||
|
||||
// 클릭/드래그 구분하는 타이머 코루틴
|
||||
private IEnumerator ClickOrDragTimer()
|
||||
{
|
||||
yield return new WaitForSeconds(clickTimeThreshold);
|
||||
|
||||
if (clickOrDragCoroutine != null)
|
||||
{
|
||||
Debug.Log("시간 초과로 드래그 시작 (OnPointDragStart)");
|
||||
StartDragMode();
|
||||
}
|
||||
}
|
||||
|
||||
// 타이머 중지하고 드래그 모드로 전환
|
||||
private void StartDragMode()
|
||||
{
|
||||
if (clickOrDragCoroutine != null)
|
||||
{
|
||||
StopCoroutine(clickOrDragCoroutine);
|
||||
clickOrDragCoroutine = null;
|
||||
}
|
||||
|
||||
isGrabbingPoint = true;
|
||||
OnPointDragStart?.Invoke(currentGrabbedPointIndex);
|
||||
}
|
||||
|
||||
// 로봇 좌표계(mm)를 Unity 월드 좌표계(m)로 변환
|
||||
private Vector3 ConvertRobotDataToVector3(RobotData pose)
|
||||
{
|
||||
|
||||
@@ -17,6 +17,11 @@ public class PointManagerView : MonoBehaviour, IPointManagerView
|
||||
[Tooltip("반투명 로봇 모델의 IK")]
|
||||
public HybridInverseKinematicsNode kinematicsNode;
|
||||
|
||||
void Start()
|
||||
{
|
||||
movingAlert.SetActive(false);
|
||||
}
|
||||
|
||||
private Vector3 ConvertRobotDataToVector3(RobotData pose)
|
||||
{
|
||||
float x = Convert.ToSingle(pose.x / -1000.0); // mm -> m
|
||||
|
||||
@@ -50,27 +50,38 @@ public class PopupView : MonoBehaviour, IPopupView
|
||||
optionPopupPanel.SetActive(false);
|
||||
}
|
||||
|
||||
public void ShowConfirmPopup(Transform popPose)
|
||||
public void ShowConfirmPopupFromRobot(Transform popPose)
|
||||
{
|
||||
confirmPopupPanel.transform.SetPositionAndRotation(popPose.position, Quaternion.identity);
|
||||
confirmPopupPanel.transform.position = popPose.position;
|
||||
confirmPopupPanel.transform.LookAt(Camera.main.transform);
|
||||
confirmPopupPanel.SetActive(true);
|
||||
}
|
||||
|
||||
public void ShowConfirmPopupFromPoint(Vector3 popPose)
|
||||
{
|
||||
confirmPopupPanel.transform.position = popPose;
|
||||
confirmPopupPanel.transform.LookAt(Camera.main.transform);
|
||||
confirmPopupPanel.SetActive(true);
|
||||
}
|
||||
|
||||
public void ShowModifyPopup(Transform popPose)
|
||||
{
|
||||
modifyPopupPanel.transform.SetPositionAndRotation(popPose.position, Quaternion.identity);
|
||||
modifyPopupPanel.transform.position = popPose.position;
|
||||
modifyPopupPanel.transform.LookAt(Camera.main.transform);
|
||||
modifyPopupPanel.SetActive(true);
|
||||
}
|
||||
|
||||
public void ShowDeletePopup(Transform popPose)
|
||||
public void ShowDeletePopup(Vector3 popPose)
|
||||
{
|
||||
deletePopupPanel.transform.SetPositionAndRotation(popPose.position, Quaternion.identity);
|
||||
deletePopupPanel.transform.position = popPose;
|
||||
deletePopupPanel.transform.LookAt(Camera.main.transform);
|
||||
deletePopupPanel.SetActive(true);
|
||||
}
|
||||
|
||||
public void ShowOptionPopup(Transform popPose)
|
||||
public void ShowOptionPopup(Vector3 popPose)
|
||||
{
|
||||
optionPopupPanel.transform.SetPositionAndRotation(popPose.position, Quaternion.identity);
|
||||
optionPopupPanel.transform.position = popPose;
|
||||
optionPopupPanel.transform.LookAt(Camera.main.transform);
|
||||
optionPopupPanel.SetActive(true);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user