[SKKU DT] 26일차 -유니티 미니 프로젝트(로봇 팔 시뮬레이션)

2023. 12. 5. 09:34SKKU DT

728x90
반응형

로봇 팔 말단 집게 블렌더로 모델링

 

 


 

 

Controller 오브젝트 하나 만들고 Robot Controller 스크립트 추가

 

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RobotControllerSW : MonoBehaviour
{
    public float speed = 20f;
    public float maxRotationZ = 5f; // 최대 회전 각도

    public GameObject body2;
    public GameObject body3;
    public GameObject body4;
    public GameObject body5;
    public GameObject body6;
    public GameObject body7;
    float accumulatedRotationZ = 0f; // Accumulated rotation for the Z axis

    void Start()
    {

    }

    void Update()
    {

        if (Input.GetKeyDown(KeyCode.A) || Input.GetKeyDown(KeyCode.D) || Input.GetKeyDown(KeyCode.W) || Input.GetKeyDown(KeyCode.S) || Input.GetKeyDown(KeyCode.J) || Input.GetKeyDown(KeyCode.L) || Input.GetKeyDown(KeyCode.I) || Input.GetKeyDown(KeyCode.K) || Input.GetKeyDown(KeyCode.O) || Input.GetKeyDown(KeyCode.P) || Input.GetKeyDown(KeyCode.E) || Input.GetKeyDown(KeyCode.R))
        {
            accumulatedRotationZ = 0.1f; //초기 속도
        }

        if (Input.GetKey(KeyCode.A))
        {
            accumulatedRotationZ += speed * Time.deltaTime * 0.001f;

            if (accumulatedRotationZ > maxRotationZ)
            {
                accumulatedRotationZ = maxRotationZ;
            }
            Debug.Log(accumulatedRotationZ);
            body2.transform.Rotate(new Vector3(0, 0, accumulatedRotationZ));
        }

        if (Input.GetKey(KeyCode.D))
        {
            accumulatedRotationZ += speed * Time.deltaTime * 0.001f;

            if (accumulatedRotationZ > maxRotationZ)
            {
                accumulatedRotationZ = maxRotationZ;
            }
            Debug.Log(accumulatedRotationZ);
            body2.transform.Rotate(new Vector3(0, 0, -accumulatedRotationZ));
        }

        if (Input.GetKey(KeyCode.W))
        {
            accumulatedRotationZ += speed * Time.deltaTime * 0.001f;

            if (accumulatedRotationZ > maxRotationZ)
            {
                accumulatedRotationZ = maxRotationZ;
            }
            Debug.Log(accumulatedRotationZ);
            body3.transform.Rotate(new Vector3(accumulatedRotationZ, 0, 0));
        }

        if (Input.GetKey(KeyCode.S))
        {
            accumulatedRotationZ += speed * Time.deltaTime * 0.001f;

            if (accumulatedRotationZ > maxRotationZ)
            {
                accumulatedRotationZ = maxRotationZ;
            }
            Debug.Log(accumulatedRotationZ);
            body3.transform.Rotate(new Vector3(-accumulatedRotationZ, 0, 0));
        }

        if (Input.GetKey(KeyCode.J))
        {
            accumulatedRotationZ += speed * Time.deltaTime * 0.001f;

            if (accumulatedRotationZ > maxRotationZ)
            {
                accumulatedRotationZ = maxRotationZ;
            }
            Debug.Log(accumulatedRotationZ);
            body4.transform.Rotate(new Vector3(accumulatedRotationZ, 0, 0));
        }

        if (Input.GetKey(KeyCode.L))
        {
            accumulatedRotationZ += speed * Time.deltaTime * 0.001f;

            if (accumulatedRotationZ > maxRotationZ)
            {
                accumulatedRotationZ = maxRotationZ;
            }
            Debug.Log(accumulatedRotationZ);
            body4.transform.Rotate(new Vector3(-accumulatedRotationZ, 0, 0));
        }

        if (Input.GetKey(KeyCode.I))
        {
            accumulatedRotationZ += speed * Time.deltaTime * 0.001f;

            if (accumulatedRotationZ > maxRotationZ)
            {
                accumulatedRotationZ = maxRotationZ;
            }
            Debug.Log(accumulatedRotationZ);
            body5.transform.Rotate(new Vector3(0, accumulatedRotationZ, 0));
        }

        if (Input.GetKey(KeyCode.K))
        {
            accumulatedRotationZ += speed * Time.deltaTime * 0.001f;

            if (accumulatedRotationZ > maxRotationZ)
            {
                accumulatedRotationZ = maxRotationZ;
            }
            Debug.Log(accumulatedRotationZ);
            body5.transform.Rotate(new Vector3(0, -accumulatedRotationZ, 0));
        }

        if (Input.GetKey(KeyCode.O))
        {
            accumulatedRotationZ += speed * Time.deltaTime * 0.001f;

            if (accumulatedRotationZ > maxRotationZ)
            {
                accumulatedRotationZ = maxRotationZ;
            }
            Debug.Log(accumulatedRotationZ);
            body6.transform.Rotate(new Vector3(accumulatedRotationZ, 0, 0));
        }

        if (Input.GetKey(KeyCode.P))
        {
            accumulatedRotationZ += speed * Time.deltaTime * 0.001f;

            if (accumulatedRotationZ > maxRotationZ)
            {
                accumulatedRotationZ = maxRotationZ;
            }
            Debug.Log(accumulatedRotationZ);
            body6.transform.Rotate(new Vector3(-accumulatedRotationZ, 0, 0));
        }

        if (Input.GetKey(KeyCode.E))
        {
            accumulatedRotationZ += speed * Time.deltaTime * 0.001f;

            if (accumulatedRotationZ > maxRotationZ)
            {
                accumulatedRotationZ = maxRotationZ;
            }
            Debug.Log(accumulatedRotationZ);
            body7.transform.Rotate(new Vector3(0, accumulatedRotationZ, 0));
        }

        if (Input.GetKey(KeyCode.R))
        {
            accumulatedRotationZ += speed * Time.deltaTime * 0.001f;

            if (accumulatedRotationZ > maxRotationZ)
            {
                accumulatedRotationZ = maxRotationZ;
            }
            Debug.Log(accumulatedRotationZ);
            body7.transform.Rotate(new Vector3(0, -accumulatedRotationZ, 0));
        }
    }
}

로봇의 각 관절마다 (A, D), (W, S), (J, L), (I, K), (O, P), (E, R), (G, H) 키를 이용해서 조작 가능하게 설정.

 

accumulatedRotationZ += speed * Time.deltaTime * 0.001f;

관절 이동을 계속 누르면 가속도가 붙어 점점 빨라지는데, 0.001f를 곱하여 최대한 천천히 유저가 느끼지 못하게 빨라지도록 설정.

 

같은 기능의 반복으로 코드 최적화 필요.

 

 


 

 

Articulation Body 컴포넌트의 사용법을 찾아보았지만 정보가 많지 않아 적용하기 쉽지 않았다.

 

 

Canvas와 BodyUI 오브젝트, 스크립트 추가로 로봇의 회전각을 시각화 하는 UI 추가.

 

 

Gripper의 동작을 제어하는 스크립트 적용, Coroutine 사용.

using System.Collections;
using UnityEngine;

public class GripperControl : MonoBehaviour
{
    private bool isMoving = false;

    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.G) && !isMoving)
        {
            StartCoroutine(MoveGripper(0.000066f, 3f));
        }
        else if (Input.GetKeyDown(KeyCode.H) && !isMoving)
        {
            StartCoroutine(MoveGripper(0.0003f, 3f));
        }
    }

    IEnumerator MoveGripper(float targetPosition, float duration)
    {
        isMoving = true;

        Vector3 startPosition = transform.localPosition;
        Vector3 target = new Vector3(0f, 0.000319f, targetPosition);

        float elapsedTime = 0f;

        while (elapsedTime < duration)
        {
            transform.localPosition = Vector3.Lerp(startPosition, target, elapsedTime / duration);
            elapsedTime += Time.deltaTime;
            yield return null;
        }

        // 보정을 위해 마지막에 명시적으로 위치를 설정
        transform.localPosition = target;

        isMoving = false;
    }
}

 

 


 

 

해야할 일

  • 관절 각도 표시 최적화
  • 로봇에 Articulation Body 물리 적용 or Rigid Body 물리 적용
  • 메테리얼, 텍스쳐 적용
  • 오브젝트 복제 후 공장 느낌 표현
728x90
반응형