새소식

ROS & Robotics/gRPC

로봇을 위한 저지연 통신 구축, gRPC (1) : gRPC를 사용하는 이유, 설치 방법

  • -

Why gRPC ?

 

다른 분야도 마찬가지이지만, 주행 중인 모바일 로봇은 안전상의 이유로 특히 초저지연 통신을 구축할 필요가 있습니다. (장애물 회피 등) 

보통의 개발 로봇의 경우 ROS 1,2를 기반으로 이미지 데이터를 받아오고 이를 처리합니다. 하지만 범용성에 초점을 두고 개발된 ROS 통신 자체의 latency 때문에 상용 로봇 단계로 갈 수록 ROS가 아닌 커스텀 통신 패키지를 사용하여 더 빠른 통신 시스템을 구축하게 됩니다. 

 

gRPC는 프로토콜 버퍼를 직접 정의함으로써 사용자가 원하는 형태로 데이터를 보낼 수 있고, 인터페이스가 쉬우며 HTTP/2 기반으로 속도가 빠르기 때문에 gRPC를 이용하여 로봇 센서 데이터를 송수신하는 것은 다양한 측면에서 이점이 많습니다. 

 

Nvidia의 Triton Inference Server 또한 통신 방법으로 gRPC를 사용하고 있습니다. 

https://docs.nvidia.com/deeplearning/triton-inference-server/user-guide/docs/user_guide/architecture.html

 

Triton Architecture — NVIDIA Triton Inference Server

<!-- # Copyright 2018-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # * Redistributions of

docs.nvidia.com

 

앞으로의 포스팅을 통해서 C++, Python을 이용해 gRPC를 로봇 통신에 이용하는 방법을 다루고자 합니다. 

 

What is gRPC ?

 

gRPC(google remote procedure call)은 구글에서 개발한 원결 프로시저 호출 프레임워크로 서버와 클라이언트 어플리케이션 간의 통신을 위한 패키지입니다. 프로토콜 버퍼(Protocol Buffer)를 주요 인터페이스로 사용하며, 

 

message Person {
  string name = 1;
  int32 id = 2;
  bool has_ponycopter = 3;
}

 

이와 같은 .proto 파일로 메시지 구조와 서비스 인터페이스를 정의합니다. 

프로젝트 내에 proto 폴더를 만들고 원하는 proto 파일들을 넣고 컴파일하면 해당 프로토콜 버퍼를 이용하여 gRPC 서버/클라이언트를 만들 수 있는 파일들이 생성됩니다. 

 

로봇 gRPC 통신에서 C++ 와 Python, 둘 중에 뭘 쓸까 ?

 

결론적으로 말하자면 역시나 로봇 개발을 할 때는 C++가 아직까지는 더 유리하다고 생각합니다. 

동일한 gRPC 통신 환경을 만들었을 때, C++ 와 Python의 통신 속도는 크게 차이가 나지 않았습니다. 같은 proto 파일을 사용하기 때문에 송수신하는 데이터의 양의 차이가 없기 때문입니다. 

 

다만 둘의 가장 큰 차이는 CPU 점유율이었습니다. Python gRPC 패키지의 경우 C++ gRPC 패키지보다 CPU를 약 2~3배 더 사용하게 됩니다. 로봇 개발처럼 자원이 한정적인 경우에는 한 톨의 CPU, 메모리라도 아껴야 하기 때문에 C++를 사용하게 되는 것 같습니다. 

 

C++ 환경 세팅

 

저의 경우에는 데스크탑 PC가 아니라 Jetson Xavier, Orange Pie 등 싱글보드 컴퓨터 위에서 환경 세팅을 진행했습니다. 

**꼭 cmake 3.19 ~ 3.22, gcc 10 이상으로 빌드하기**

 

https://grpc.io/docs/languages/cpp/quickstart/

 

Quick start

This guide gets you started with gRPC in C++ with a simple working example.

grpc.io

 

보통 이 공식 문서를 따르면 설치가 잘 되긴 하는데, 하다 보면 catkin 에서 빌드 할 때 abseil 등 연관 패키지 버전 때문에 빌드가 안 되는 경우가 종종 있습니다. 

 

catkin 환경에서 gRPC를 사용하고 싶고 CMakeLists.txt에서 컴퓨터에 설치된 gRPC dependency를 맞춰주기 번거롭고 어렵다고 생각하신다면 

 

https://github.com/CogRob/catkin_grpc

 

GitHub - CogRob/catkin_grpc: Integrates gRPC into Catkin/ROS ecosystem.

Integrates gRPC into Catkin/ROS ecosystem. Contribute to CogRob/catkin_grpc development by creating an account on GitHub.

github.com

 

이 catkin_grpc라는 패키지를 사용하는 것을 적극 추천드립니다. 이 패키지를 워크스페이스 안에 함께 넣고 빌드하면 gRPC를 catkin 패키지로 사용할 수 있게 됩니다. 간편하다는 이점이 있지만, ROS 1 환경에서만 사용 가능합니다. 

 

catkin_grpc 사용법은 

https://github.com/CogRob/catkin_grpc_examples

 

GitHub - CogRob/catkin_grpc_examples: Examples for grpc ROS package.

Examples for grpc ROS package. Contribute to CogRob/catkin_grpc_examples development by creating an account on GitHub.

github.com

 

이 예제를 참고하세요😀

 

Troubleshooting

 

catkin_grpc를 함께 빌드해서 사용하다 보면, 뭔가 어디에 걸려서 잘 안 될 때가 있습니다. 자세히 살펴보면

        std::unique_ptr<Server> server(builder.BuildAndStart());

 

여기서 멈춰 있을 가능성이 높습니다. 

https://github.com/grpc/grpc/issues/21213

 

ServerBuilder::BuildAndStart hangs on Ubuntu 19.10 · Issue #21213 · grpc/grpc

What version of gRPC and what language are you using? Tested on v1.24.x and v1.25.x C++ language What operating system (Linux, Windows,...) and version? Ubuntu 19.10 What runtime / compiler are you...

github.com

 

catkin_ws/build/grpc_build/src/core/lib/debug/trace.cc

 

이 위치에 

// void TraceFlagList::Add(TraceFlag* flag) {
//   flag->next_tracer_ = root_tracer_;
//   root_tracer_ = flag;
// }

void TraceFlagList::Add(TraceFlag* flag) {
  for (TraceFlag* t = root_tracer_; t != nullptr; t = t->next_tracer_) {
    if (t == flag) {
      return;
    }
  }
  flag->next_tracer_ = root_tracer_;
  root_tracer_ = flag;
}

 

Add 함수를 다음과 같이 바꿔 주면 문제가 해결되는 경우가 종종 있습니다. 

 

Python 환경 세팅

 

https://grpc.io/docs/languages/python/quickstart/

 

Quick start

This guide gets you started with gRPC in Python with a simple working example.

grpc.io

 

공식 python quick start 문서를 보면, 

python 3.7 이상을 요구하는데 python 3.6 에서도 정상 작동 하기는 했습니다. 

다만 ROS Melodic 의 경우 기본이 Python 2 를 사용하기 때문에 일반적으로 shebang을 써서 python3를 사용하게 되는데요, 이때 grpc가 Python 2 경로를 참조하게 되어 package not found 에러가 뜨는 경우가 종종 있습니다. 

#!/usr/bin/env python3

import sys
import os
print(sys.path)

# 현재 사용 중인 Python 인터프리터 경로 출력
print("Python Interpreter Path:", sys.executable)

# PYTHONPATH 환경 변수 출력
print("PYTHONPATH:", os.getenv('PYTHONPATH'))
sys.path.remove('/home/nvidia/{user_name}/devel/lib/python2.7/dist-packages')​

 

이와 같이 파이썬 path 를 강제로(?) 편집해주면 정상적으로 grpc 패키지를 불러올 수 있습니다. 

 

다음 포스팅에서는 gRPC 패키지를 사용하여 데이터를 송수신하는 방법을 다뤄보도록 하겠습니다. 

 

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.