로봇/ROS

URDF를 이용해 만든 로봇에 Unity 자동차 연결하기 (4)

with-RL 2023. 9. 17. 18:50

이번 포스팅은 URDF를 이용해 만든 로봇에 Unity 자동차 연결하기 (3) 과정을 통해서 만들어진 Unity 로봇에 카메라를 부착하고 ROS와 연동해 보는 과정입니다.

 

이 포스트는 다음 과정을 완료한 후에 참고하시길 바랍니다.

1. Unity 로봇에 카메라 부착하기

  • 'Car' Object를 선택하고 마우스 메뉴버튼을 누른 후 'Create Empty'를 선택합니다.

  • 생성된 'Empty' Object를 다음과 같이 설정합니다.
    ◦ Name: Camera
    ◦ Position: 0, 0, 0.1
    ◦ Rotation: 0, 0, 0
    ◦ Scale: 0.03, 0.03, 0.01

  • 'Camera' Object를 선택하고 마우스 메뉴 버튼을 누른 후 '3D Object >> Cube'를 선택합니다.

  • 'Cube' Object의 Material을 'Assets >> Materials >> Red'로 변경합니다.

  • 'Cube' Object를 선택하고 메뉴버튼을 누른 후 'Camera'를 선택합니다.

  • 생성된 'Camera' Object를 선택 후 아래와 같이 설정합니다.
    ◦ Position: 0, 3, 0
    ◦ Rotation: 0, 0, 0
    ◦ Scale: 1, 1, 1
    ◦ AudioListener: 비활성화

  • 'Assets >> Scripts >> 2WD Car' 선택 후 마우스 메뉴버튼을 누르고 'Create >> Render Texture'를 선택합니다.

  • 'Render Texture'를 다음과 같이 설정합니다.
     Name: ImageRawTexture
    'Camera' Object의 'Target Texture': ImageRawTexture

  • 'Assets >> Scripts >> 2WD Car'를 선택하고 마우스 메뉴버튼을 클릭 후 'Create >> C# Script'를 선택합니다.

  • C# Script 이름을 ImageRawPublisher로 변경하고 아래와 같이 편집합니다.
using System;
using System.Text;
using UnityEngine;
using Unity.Robotics.ROSTCPConnector;
using Unity.Robotics.ROSTCPConnector.MessageGeneration;
using RosMessageTypes.Sensor;
using RosMessageTypes.Std;

public class ImageRawPublisher : MonoBehaviour
{
    [SerializeField] private RenderTexture renderTexture = null;
    [SerializeField] private string topicName = "img_raw";
    [SerializeField] private float publishFrequency = 0.1f;

    ROSConnection ros;
    private float timeElapsed = 0.0f;


    private void Start()
    {
        ros = ROSConnection.GetOrCreateInstance();
        ros.RegisterPublisher<ImageMsg>(topicName);
    }

    private void FixedUpdate()
    {
        timeElapsed += Time.deltaTime;

        if (timeElapsed >= publishFrequency)
        {
            Texture2D texture = new Texture2D(renderTexture.width, renderTexture.height, TextureFormat.RGBA32, false);
            RenderTexture.active = renderTexture;
            texture.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0, false);

            ImageMsg img_raw = texture.ToImageMsg(new HeaderMsg());
            ros.Publish(topicName, img_raw);


            timeElapsed = 0;
        }
    }
}

  • 'Car' Object를 선택하고 'ImageRawPublisher'를 등록하고 아래 내용을 설정합니다.
    Publisher Texture: ImageRawTexture

  • 장애물을 만들기 위해서 '2WD Car' Scene을 선택하고 마우스 메뉴버튼을 누른 후 '3D Object >> Cube'를 선택합니다.

  • Cube을 아래와 같이 설정합니다.
    ◦ Position: 0, 0.5, 2.5
    ◦ Rotation: 0, 0, 0
    ◦ Scale: 1, 1, 1

2. ROS와 Unity 연동하기

  • ROS의 첫 번째 터미널에서 아래 명령을 실행해서 'unity.launch.py'를 실행합니다.
$ cd ~/Workspace/ros_ws
$ source install/setup.bash
$ ros2 launch car_tutorial unity.launch.py
  • Unity의 Play 버튼을 눌러서 실행합니다.

  • ROS의 Rivz 화면에서 Unity의 카메라의 화면이 보이는 것을 확인할 수 있습니다.

  • ROS의 두 번째 터미널에서 아래 명령을 실행해서 'teleop_twist_keyboard'를 실행합니다.
$ ros2 run teleop_twist_keyboard teleop_twist_keyboard
  • ROS에서 키보드를 누르면 자동차가 움직이면서 카메라의 화면이 변경되는 것을 확인할 수 있습니다.