지금 하고 있는 프로젝트에서 unity를 이용해서 진행하기로 하였다.
Unity에 있는 가상 카메라로 카메라 정보를 받아 이를 처리하는 방식인데,, 문제는 Unity는 C#을 베이스로 만들어진 툴이기 때문에 다른 언어로 만든 코드를 script로 넣어줄수가 없었다. 그리고 무엇보다도.. 내가 C#을 다뤄본적이 별로 없어서.. python으로 카메라 이미지를 보내줄 수 있는 방법을 찾아보았다.
우선 여러가지 방법을 찾았다. 그렇지만 기왕 ubuntu환경에서 하기로 한거, 한번 rosbridge를 이용해서 해보려고 한다.
rosbridge는 ros와 다른 tool을 이어주는 말 그대로 bridge이다. IoT를 공부하다보면 bridge기기라는게 나오는데, 센서와 엑추에이터 사이를 이어주는 역할을 해준다.
rosbridge의 경우 나한테 조금은 친숙하다. 마카롱에서 나간 모라이 대회가 똑같이 rosbridge를 통해 ros와 모라이가 통신할 수 있도록 했었다. 이때 디버깅 하면서 조금 공부해 둔게 있기도 하고... 그나마 친숙한 rosbridge를 사용하기로 하였다...
근데..? ROS-Unity통신 관련 자료 왜이리 없냐... 날 너무 힘들게 한 아이.. 그치만 해치웠지.. 후후후...
rosbridge 설치하기
sudo apt-get install ros-noetic-rosbridge-server
rosbridge를 설치해주면 다음은 path를 지정해 주면된다.
source /opt/ros/noetic/setup.bash
그 다음은 로스브릿지 런치파일을 실행해주면 되는데... 이부분은 모라이 할때 단축어 해둔게 있어서 나는 편했다.
roslaunch rosbridge_server rosbridge_websocket.launch
그 다음 내 IP주소를 찾아내야 하는데, 이때 ifconfig를 통해 찾아도 되지만, 나는 그냥 localhost:9090으로 진행하였다.
모라이할 때 실험해보니.. 이게 제일 편하드라고..
자 이렇게 하면 rosbridge의 준비는 끝난다. 이제 unity로 넘어가보자
Unity에서 topic publish해주기
우선, Unity에 ROS# 패키지를 install해주어야 한다. Unity내에서 패키지를 찾아서 Assets에 넣는 방법도 있지만.. 뭔가 지금 내가 사용하고 있는 unity버전이 정상적인 버전은 절대 아닌것같아.. git을 이용한 방법으로 소개를 하겠다... (unity깔다가 내 ubuntu 맛탱이 가버렸다.. 나 우분투에서 한글 안쳐짐.. 이상하게 C드라이브에 접근할 수 있어지고.. 개발 환경도 좀 많이 바뀜.. 뭔가를 단단히 잘못한 듯.. ㅠㅠ)
home에 아래 git을 clone 받아주면 된다.
git clone https://github.com/siemens/ros-sharp.git
clone이 다 받아졌다면 사용하고자 하는 프로젝트 Assets에 드래그 해주면 된다. 쉽죠?
이제 ros에 접근할 수 있게 된다.
여기서 잠깐..!!
Test1/Assets/RosSharp/Scripts/RosBridgeClient/RosCommuncation/에 들어가면 RosConnector.cs파일이 있다.
기본적으로 토픽으로 보낼 모든 센서에 이 RosConnector script를 넣어줘야 하기 때문에, 미리 수정해서 시작하면 편하다.
이 파일을 열어보면, 아래와 같다.
/*
© Siemens AG, 2017-2019
Author: Dr. Martin Bischoff (martin.bischoff@siemens.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
<http://www.apache.org/licenses/LICENSE-2.0>.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
using System;
using System.Threading;
using RosSharp.RosBridgeClient.Protocols;
using UnityEngine;
namespace RosSharp.RosBridgeClient
{
public class RosConnector : MonoBehaviour
{
public int SecondsTimeout = 10;
public RosSocket RosSocket { get; private set; }
public RosSocket.SerializerEnum Serializer;
public Protocol protocol;
public string RosBridgeServerUrl = "ws://192.168.219.169:9090";
public ManualResetEvent IsConnected { get; private set; }
public virtual void Awake()
{
IsConnected = new ManualResetEvent(false);
new Thread(ConnectAndWait).Start();
}
protected void ConnectAndWait()
{
RosSocket = ConnectToRos(protocol, RosBridgeServerUrl, OnConnected, OnClosed, Serializer);
if (!IsConnected.WaitOne(SecondsTimeout * 1000))
Debug.LogWarning("Failed to connect to RosBridge at: " + RosBridgeServerUrl);
}
public static RosSocket ConnectToRos(Protocol protocolType, string serverUrl, EventHandler onConnected = null, EventHandler onClosed = null, RosSocket.SerializerEnum serializer = RosSocket.SerializerEnum.Microsoft)
{
IProtocol protocol = ProtocolInitializer.GetProtocol(protocolType, serverUrl);
protocol.OnConnected += onConnected;
protocol.OnClosed += onClosed;
return new RosSocket(protocol, serializer);
}
private void OnApplicationQuit()
{
RosSocket.Close();
}
private void OnConnected(object sender, EventArgs e)
{
IsConnected.Set();
Debug.Log("Connected to RosBridge: " + RosBridgeServerUrl);
}
private void OnClosed(object sender, EventArgs e)
{
IsConnected.Reset();
Debug.Log("Disconnected from RosBridge: " + RosBridgeServerUrl);
}
}
}
여기서 크게 바꿔줘야 할 부분은 없지만.. 나는 로컬 환경에서 진행하기로 하였으니, IP주소를 조금 바꿔주려고 한다.
코드의 32번째 줄의 ip주소를 아래와 같이 바꿔주면, 앞으로 script import할 때마다 주소를 바꿔주는 수고를 덜 수 있다.
public string RosBridgeServerUrl = "ws://localhost:9090";
여기서 하나!!
IP주소를 공부하다보면 정말 많이 헷갈린다.. ifconfig를 치면 내 IP Address를 알 수 있다는건 코딩을 하는 모두가 아는 사실일 것이다. 그런데..! 사실 ifconfig를 출력해보면 정말 많은 주소들이 뜨고, 그중 무엇을 이용해야하는지는 모르는 경우가 많다.
그렇기 때문에 여기서 한 번 정리해주도록 하겠다.
127.0.0.1과 localhost는 같은 의미이다. 그래서 위에서 localhost:9090으로 해주었지만, 이때 127.0.0.1로 해도 같은 곳에 연결된다. 127.0.0.1은 가장 흔히 사용되는 루프백 주소로, 로컬 호스트를 나타낸다. 이 주소를 사용하면 컴퓨터 자체와 통신하는 데 사용할 수 있다.
반면에 192.로 시작하는 주소는 사설 IP 주소 범위 중 하나이며, 일반적으로 내부 네트워크에서 사용된다. 루프백 주소와 사설 IP 주소의 가장 큰 차이는 사용 목적이다. 루프백 주소는 동일한 기기 내에서의 통신을 위한 것이며, 사설 IP 주소는 여러 기기 간의 내부 네트워크 통신을 위한 거다.
자, 여기서 하나 더! ifconfig를 치면
1: lo:<LOOPBACK~~~~
2: wlp2s0: <BROADCAST~
이런식으로 뜨게 된다.
이렇게 뜰때 우리는 ip주소를 확인할 수 있는데, 하나에 두개가 보여지게 된다. 이때 brd는 broadcasting의 약자로.. inet과 속도 부분에서 큰 차이는 보이지 않는다. 그러나 역시 p-to-p통신보다는 취약하고.. 좀 번거롭다. 그러니 inet 주소를 가져오고 brd주소는 특수한 경우에 사용하면 된다.
여기서 둘!!
이번엔 IP주소에 대해 알아보자.
IP주소에는 크게 두가지 버전이 있다. IPv4(Internet Protocol version 4)와 IPv6(Interent Protocol version 6)
각 버전에는 주소가 할당되는 방식과 주소의 형식에 차이가 있다. 나는 지금 IPv4에 대한 얘기를 하려고 한다.
IPv4는 32비트 주소 공간을 사용해, 보통 4개의 8bit 블록으로 나눠진 10진수로 표현한다.
1. Public Address(공용 주소):
인터넷에서 사용되며, 고유하게 식별된다. 주소 범위는 1.0.0.0에서 223.255.255.255까지이다.
2. Private Address(사설 주소):
내부 네트워크에서 사용된다. 라우터와 NAT(Network Address Translation)을 통해 공용 주소와 통신할 수 있다.
주소 범위에는 세가지가 있다.
10.0.0.0에서 10.255.255.255 - 대규모 기업 등에서 내부 네트워크로 사용하기 적합.
172.16.0.0에서 172.31.255.255 - 중간 규모 기업 혹은 조직에서 내부 네트워크로 사용.
192.168.0.0에서 192.168.255.255 - 가정용 혹은 소규모 비즈니스 네트워크에서 사용.
3. Reserved Address:
특수한 용도로 예약된 주소이다. 대표적으로 0.0.0.0이나, 앞에서 소개한 것처럼 127.0.0.1 혹은 255.255.255.255가 있다.
이것만 알면 당신도 네트워크 할 수 있다..!
장난이고.. 사실 내가 분명 전공 수업때 배운 내용이지만, 간혹 헷갈리는 일이 있어 한 번 정리해 보았다. 이제 안까먹었으면 좋겠다..
자 사담은 여기까지 하고 unity-ros통신을 이어서 진행해 보도록 하겠다.
SampleScence에 Emtpy Object를 추가해주고, 이름은 RosConnecter로 설정해준다.
Inspector에 들어가서 Add Component를 눌러주고 ros를 검색하면 사용가능한 Script 목록이 뜬다. 그 중 RosConnector를 선택해주고 저장해주자. 이렇게 하면 이 프로젝트는 ros와 연결이 되게 된다.
여기까지 RosConnector를 만들어주었다.
자, 내가 하려고 한건 Ros와 Unity사이 통신을 통해 Ros로 Image를 보내주는 것이다.
Camera를 원하는 곳에 설치하고, 화각(Field of View)까지 설정해주자.
헷갈림 방지를 위해 카메라 이름 꼭 변경해주자.
그 다음 똑같이 Add Component를 해주면 되는데, 이때 RosConnector말고 Image Publisher의 Script를 선택해주면 자동으로 RosConnector까지 추가가 된다.
이제 topic이름과 어느카메라인지 다시 설정해주면 준비가 얼추 끝나게 된다.
잘 모르겠다면 아래 사진을 참고해볼까요??

오른쪽의 Inspector를 보고 참고해보자.
이제 Ros로 넘어와보면, rosbridge 터미널에 아래와 같이 연결되었음을 알리는 것을 볼 수 있다.
2023-11-22 19:08:18+0900 [-] [INFO] [1700647698.348819]: Client connected. 1 clients total.
2023-11-22 19:08:18+0900 [-] [INFO] [1700647698.355182]: Client connected. 2 clients total.
2023-11-22 19:08:18+0900 [-] [INFO] [1700647698.358155]: Client connected. 3 clients total.
2023-11-22 19:08:18+0900 [-] [INFO] [1700647698.361318]: Client connected. 4 clients total.
2023-11-22 19:08:18+0900 [-] [INFO] [1700647698.365238]: Client connected. 5 clients total.
이제 topic 잘 들어오는지 확인 해보자. 여러가지 방법이 있지만, 나는 내가 만들어둔 파이썬 코드를 실행해서 카메라가 잘 들어오고 있는지 확인했다.

너무 잘 들어온다... 나처럼 미리 만들어둔 코드가 없는데 지금 당장 잘 들어오는지 확인하고 싶다면, rviz나 rqt를 이용하는 방법이 있다.
지금 Image publish의 Frame Id는 Camera로 되어있기 때문에, rviz에서 frame id 바꿔주고 image add 해주면 볼 수 있다.
다른 방법으로는 rqt_graph와 rqt_image이다.
$ rqt_graph
$ rqt_image_view
위의 두가지 명령어로 토픽이 잘 들어오고 있는지 확인할 수 있다.

아이 이뻐라~
여기서 다 소개하지는 않았지만, 그 외에도 unity 사용법 익히고.. 내 프로젝트에 맞게 통신환경 설정하고.. 무엇보다도 Unity-Ros통신 자료가 많은 편은 아니라.. 고생 좀 했다..
지금은 이렇게 받아온 이미지 처리를 진행중이다.
'자율사물캡스톤디자인 > 자료 조사' 카테고리의 다른 글
Google Colab으로 yolo돌리기 (3) | 2023.11.12 |
---|---|
테슬라 오토파일럿(Autopilot) 기능 (2) | 2023.09.26 |