본문 바로가기
프로젝트/류 Ryu

Unity 개발로 시작하는 Digital Twin

by 화릿불 2024. 8. 26.

 

들어가며


앞서 저는 Wear OS를 활용해 Employee가 사용할 애플리케이션을 만들었습니다. 이제는 Administor가 사용할 애플리케이션을 제작해야합니다. 물론 관리자의 경우에도 Wear OS를 이용하여 만들 수 있지만 관리자는 다른 환경에서 다른 작업을 하는 것이 일반적이므로 아예 다른 서비스를 제공할 수 있도록 기획하였습니다. 로봇의 상태를 확인하거나 물류창고 내의 전체적인 로봇들의 움직임 등을 관찰할 수 있는 애플리케이션이 필요하다고 느꼈습니다.

 

이에 저희는 Unity를 활용해 디지털 트윈을 구축하고자 하였고 물류 로봇을 움직이는 ROS2 통신을 통해서 Unity에서도 이를 가상으로 보여주고자 하였습니다. 디지털 트윈은 쉽게 생각하면 현실세계의 정보를 실시간으로 수집해 가상 화면에 반영해 동일하게 보여주는 기술이라고 보면 됩니다.

 

ROS


ROS(Robot Operating System)는 로봇 소프트웨어 개발을 위한 오픈 소스 프레임워크입니다. 이름에서 '운영 체제'를 의미하는 'Operating System'이 포함되어 있지만, 실제로는 운영 체제라기보다는 로봇 애플리케이션 개발을 지원하는 툴킷에 가깝습니다. ROS는 로봇의 하드웨어 추상화, 기기 제어, 통신, 데이터 처리 등을 쉽게 구현할 수 있게 해주는 다양한 도구와 라이브러리를 제공합니다.

 

주요 기능 중 하나는 메시지 기반의 통신 구조를 제공하는 것으로, 여러 소프트웨어 노드가 메시지를 주고받을 수 있게 합니다. 이는 로봇의 센서 데이터 수집, 처리, 제어 신호 전달 등의 작업을 병렬로 수행할 수 있게 해줍니다. 저희는 이 기능을 이용하여 유니티와 통신할 것입니다.

 

그리고 이 메시지 기반 통신 구조는 앞서 우리가 사용했던 MQTT와 여러 면에서 닮아있습니다.

 

비슷한 점


  • Pulbisher - Subscriber 모델
    • 둘 모두 Publisher - Subscriber 모델을 사용하여 통신합니다. 퍼블리셔가 특정 주제(topic)에 메시지를 보내면, 해당 주제를 구독(subscribe)한 서브스크라이버가 메시지를 받는 형태입니다.
  • 비동기 통신
    • 두 시스템 모두 메시지 송수신이 비동기적으로 이루어지며, 이를 통해 각 노드가 독립적으로 작업하게 됩니다.
  • 중앙 노드
    • ROS에서는 roscore가 MQTT는 broker가 중앙 통신 허브 역할을 하며 메시지의 라우팅을 담당하고 있습니다.

다른 점


  • 응용 분야
    • ROS는 주로 로봇 공학에서 사용되며 센서 데이터 처리, 로봇 제어 등 통신 외의 다른 툴킷과 라이브러리를 제공하고 있습니다. 반면 MQTT는 통신의 역할만 수행하며 IoT같은 저전력, 저대역폭에 주로 사용됩니다.
  • 프로토콜
    • ROS는 자체 통신 프로토콜을 사용해 메시지를 보내는 반면 MQTT는 ISO 표준 프로토콜로 네트워크 트래픽을 최소화하도록 설계된 경량 프로토콜입니다.
  • 품질 수준(QoS)
    • MQTT는 Qos(전송 품질 수준)을 지정할 수 있어 메시지 전송의 신뢰성을 설정할 수 있지만 ROS는 그런 기능을 제공하지 않습니다.
  • 메시지 형식
    • ROS는 사용자 정의 메시지 형식을 지원하고 메시지 파일을 통해 정의하지만, MQTT는 텍스트 기반의 JSON형식과 바이너리 데이터를 전송합니다.

 

ROS2


ROS는 공식문서를 보면 알겠지만 굉장히 다양한 버전을 제공합니다. 현재는 ROS2로 넘어오면서 사용 구조나 방식이 약간 바뀌긴 했습니다. 이는 공식 문서를 참고하면 좋을 것 같습니다.

 

https://docs.ros.org/en/jazzy/index.html

 

ROS 2 Documentation — ROS 2 Documentation: Jazzy documentation

© Copyright 2024, Open Robotics.

docs.ros.org

 

위 문서를 통해 Windows, Mac OS, Linux 등 다양한 환경에 ROS를 설치하고 사용할 수 있도록 지원하고 있습니다.

저희 프로젝트의 경우 라즈베리파이5를 사용하고 있는데 라즈베리파이5는 현재 Ubuntu 24와 Ubuntu 23 버전을 지원하고 있는데 23 버전은 ROS를 지원하지 않기 때문에 24 버전을 사용하게 되었고, Ubuntu 24.04는 ROS2 jazzy 버전만 사용할 수 있습니다. 이처럼 사용하고 있는 환경의 제약에 의해서 특정 버전을 사용하게 될 수도 있습니다.

 

공식문서에서는 Installation, Trouble Shooting 등 항목에 대해서 매뉴얼을 제공하고 있기 때문에 위 과정을 천천히 따라하시면 충분히 설치하실 수 있을 것입니다.

 

ROS는 기본적으로 동일 네트워크 내에서만 동작하도록 되어 있습니다. 물론 포트 개방을 통해서 외부 네트워크에서도 접속하거나 통신할 수 있습니다. 또한, 기왕이면 서로 다른 장치에서 ROS 통신을 할 때 같은 버전의 ROS 사용을 권장하지만 상황이 여의치 않다면 다른 버전의 ROS로도 통신은 가능합니다. 가령 jazzy 버전과 foxy 버전 사이의 통신이 가능한 것입니다. 이 때는 포트포워딩과 같은 작업을 거친 후 네트워크가 열려있는지 확인하고 사용하시면 될 것 같습니다.

 

ROS#


기본적으로 Unity는 ROS를 지원하지 않지만 외부 패키지를 이용하여 사용할 수 있습니다.

 

GitHub - siemens/ros-sharp: ROS# is a set of open source software libraries and tools in C# for communicating with ROS from .NET applications, in particular Unity3D

 

GitHub - siemens/ros-sharp: ROS# is a set of open source software libraries and tools in C# for communicating with ROS from .NET

ROS# is a set of open source software libraries and tools in C# for communicating with ROS from .NET applications, in particular Unity3D - siemens/ros-sharp

github.com

 

위 깃허브 레포지토리는 유니티에서 ROS를 쉽게 사용할 수 있도록 해주는 ROS# 패키지이며 파일을 다운로드 받아 원하는 프로젝트에 넣어서 사용하면 됩니다.

 

저는 위 레포를 클론하여 제 프로젝트에 복사해 넣었습니다. 필요한 내용은 ros-sharp 내용이므로 해당 폴더만 넣어주어도 무방합니다. 하지만 자동으로 패키지를 임포트 해주지 않기 때문에 수동 임포트가 필요하며 꼭 프로젝트의 Assets 폴더에 추가하셔야 합니다.

 

ROS#는 사용에 대한 위키를 제공하고 있습니다.

Home

 

Home

ROS# is a set of open source software libraries and tools in C# for communicating with ROS from .NET applications, in particular Unity3D - siemens/ros-sharp

github.com

 

필요하다면 해당 위키를 따라가시면서 공부해도 좋지만 버전이 맞지 않으니 버전에 맞춰서 잘 사용할 수 있도록 유의해야 합니다.

 

Unity & ROS2


저희는 ROS2를 사용하는 로봇과 관리자 애플리케이션은 서로 다른 네트워크를 사용할 것으로 가정했기 때문에 포트 개방 및 네트워크 연결을 진행해야 했습니다. ROS는 이러한 작업도 rosbridge_websocket을 통해 지원해 줍니다.

 

rosbridge_websocket


rosbridge_websocket은 ROS와 웹 기술을 통합하여 웹 애플리케이션에서 ROS 네트워크에 쉽게 접근할 수 있도록 하는 기술입니다. 이를 통해 웹 기반 클라이언트가 직접 ROS 메시지를 송수신하고, 서비스를 호출하며, 파라미터를 조작할 수 있도록 해줍니다.

 

저는 로봇과 동일한 환경으로 테스트 환경을 만들기 위해 Ubuntu 24.04 버전과 ROS2 jazzy 버전을 설치하여 사용하였습니다. 아래 내용은 유니티에서 더미데이터를 받아 사용해보기 위해 PC에 Ubuntu Linux를 설치해 해당 환경에서 rosbridge_webscoket을 사용하기 위한 과정입니다. 그 외 linux 환경이라도 아래 내용대로 따라하시면 됩니다.

 

mkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src

ROS2는 공식 매뉴얼대로 이미 설치되었다고 가정하고 시작하겠습니다.

먼저 워크스페이스를 만들고 해당 환경에서 rosbridge_websocket을 다운받아 사용할 수 있도록 하겠습니다.

 

git clone <https://github.com/RobotWebTools/rosbridge_suite.git> // 없어도됨 -b ros2

그 다음 git을 통해 필요한 파일들을 받아 와야 합니다. 뒤에 주석으로 처리된 부분은 깃허브에는 특정 버전을 위한 브랜치가 만들어져있기 때문에 해당하는 버전에 맞춰서 클론해주시면 된다는 의미입니다. ROS2의 경우 대개 특정 브랜치를 잡지 않고 받아도 되는 것으로 확인했습니다.

 

cd ~/ros2_ws
rosdep install --from-paths src --ignore-src -r -y

깃을 받은 이후 위 과정을 진행하는데 만약 rosdep이 없다는 에러가 뜬다면 rosdep을 설치해 준 후 초기화 과정을 거쳐야합니다. 이 과정은 아래와 같습니다.

 

sudo apt install python3-rosdep

sudo rosdep init
rosdep update

rosdep 패키지를 설치한 후 ros 패키지 의존성 정보를 초기화 및 업데이트하여 ros 패키지의 의존성 목록을 최신 상태로 유지해줍니다.

 

colcon build

이후 빌드를 시작합니다.

 

source /opt/ros/jazzy/setup.bash
source ~/ros2_ws/install/local_setup.bash

빌드 후 각각 ros2와 rosbridge_websocket을 사용하기 위해 ROS 실행에 필요한 환경, 변수들을 위한 설정 파일을 로드하는 과정입니다. 터미널이 실행될 때 자동으로 실행되도록 bash에 등록하셔도 됩니다. 이 과정은 아래와 같습니다.

 

echo "source /opt/ros/jazzy/setup.bash" >> ~/.bashrc
echo "~/ros2_ws/install/local_setup.bash" >> ~/.bashrc
ros2 launch rosbridge_server rosbridge_websocket_launch.xml

rosbridge_websocket을 사용하기 위해 파일을 실행해 줍니다.

 

아무 문제 없이 실행이 된다면 좋겠지만 문제가 발생할 수 있습니다.

 

특히나 대부분이 패키지가 제대로 설치되지 않아서 발생하는 문제는 패키지 설치 하나를 끝내도 다른 패키지 설치를 요구할 것입니다. 이 때는 전체적인 패키지를 다시 설치하는 것을 권장합니다. 그 과정은 아래와 같습니다.

 

sudo apt remove ros-<version>-rosbridge-server ros-<version>-rosbridge-library
sudo apt install ros-<version>-rosbridge-server ros-<version>-rosbridge-library

중간에 <version> 은 본인이 설치한 ROS 버전을 넣어주면 됩니다.

 

위 과정을 마친 후 다시 위에 ‘colcon build’ 과정으로 돌아가서 다시 과정을 따라 내려오시면 됩니다.

 

sudo ufw allow 9090/tcp

기본적으로 웹소켓은 9090포트로 제공되며 외부 네트워크에 전송, 전달 받기 위해 해당 포트를 열어두는 작업이 필요할 수 있습니다.

 

이제 ROS2로 다른 장치와 통신할 준비가 완료되었습니다.

 

Unity code


기본적으로 ROS#는 다양한 클래스를 지원하고 있습니다.

 

각 센서로부터 받아들일 수 있는 Subscriber, Publisher 들과 웹소켓과 통신하기 위한 RosSocket 등을 제공하고 있습니다. 미리 구현된 클래스, 스크립트를 상속하거나 그대로 사용하셔도 괜찮지만 저희의 경우 로봇이 움직이기 위해서 제공받는 ROS2 TFMessage를 직접 받아서 파싱하여 사용하고자 아예 스크립트를 제작하여 사용하였습니다.

 

using RosSharp.RosBridgeClient;
using RosSharp.RosBridgeClient.MessageTypes.Tf2;
using System.Linq;
    
public class RosTestSubscriber : MonoBehaviour
{
    private void Start()
    {
        // ROS WebSocket 서버의 URL
        string rosBridgeUrl = "ws://URL:PORT";
        rosSocket = new RosSocket(new RosSharp.RosBridgeClient.Protocols.WebSocketNetProtocol(rosBridgeUrl));

        // 토픽 구독
        rosSocket.Subscribe<TFMessage>(topicName, ReceiveMessage);
    }
}

기본적으로 제공하는 Unity Subscriber나 그 외 Subscriber들을 상속하여 사용하고자 하였으나 이미 구현된 rosSocket.Subscribe<Message> 등에 대한 형변환을 제공하지 않아 저희가 필요한 TFMessage를 직접 받는 소켓을 구성하여 사용하도록 하였습니다.

 

private void ReceiveMessage(TFMessage message)
{

    if (message.transforms.Count() > 0)
    {
        // 첫 번째 TransformStamped 메시지 추출
        TransformStamped transform = message.transforms[0];

        // 위치 데이터 추출
        targetPosition = new UnityEngine.Vector3(
            (float)transform.transform.translation.x,
            (float)transform.transform.translation.y,
            (float)transform.transform.translation.z);

        // 회전 데이터 추출
        targetRotation = new UnityEngine.Quaternion(
            (float)transform.transform.rotation.x,
            (float)transform.transform.rotation.y,
            (float)transform.transform.rotation.z,
            (float)transform.transform.rotation.w);

        // 이동 및 회전 시작
        isMoving = true;
        isRotating = true;
    }
}

저희의 TFMessage의 경우 목표점이 되는 Point의 x,y,z 좌표와 그 때의 회전각 x,y,z,w 를 메시지로 받기 때문에 이를 파싱하여 사용하기 위해 한번의 프로세싱을 거쳐야했습니다.

 

위에 Start 부분에서 초기화로 구독과 함께 콜백 함수를 ReceiveMessage로 설정하였기 때문에 웹소켓으로부터 메시지를 수신하면 해당 함수가 실행되게 됩니다.

 

ROS2 통신을 위한 구현은 이게 끝이며 이제 데이터들을 필요한 형태로 가공하고 자유롭게 사용하면 됩니다.

 

글을 마무리하며


유니티에서 외부 패키지를 활용한 개발은 처음이었는데 특히나 잘 모르는 ROS에 대해서 공부하면서 기존에 알고 있던 지식과 비교하고 검증하는 시간을 가질 수 있었습니다. 많은 레퍼런스들을 참고하며 검증하는 과정을 통해 어떤 기술이 왜 적용되어야 하는지 어떻게 적용되어야 하는지 생각해 볼 수 있는 시간이었던 것 같습니다.

 

'프로젝트 > 류 Ryu' 카테고리의 다른 글

Digital Twin에서의 이슈들  (0) 2024.08.26
Wear OS에서 dotenv 파일 및 내부 DB 활용하기  (0) 2024.08.11
Wear OS에서 MQTT 통신하기  (0) 2024.08.11