[ROS2] 커스텀 인터페이스 생성/사용하기

Dierslair·2023년 2월 5일
0

ros2

목록 보기
1/1

Launch Ubuntu-focal with Multipass

Multipass 가 없는 경우 설치

$ brew install --cask multipass

VM (ubuntu 20.04) 생성

dierslair@macbook $ multipass lanuch focal -n ros2-focal -c 4 -m 2G -d 20G
# -c (--cpus) : 할당할 CPU 코어 갯수
# -m (--memory) : 할당할 메모리 용량
# -d (--disk) : 할당할 디스크 용량
# -n (--name) : 인스턴스 이름

ROS2 설치

  • 생성한 VM 진입
dierslair@macbook $ multipass shell ros2-focal
  • ros2-foxy 설치 : 아래 스크립트를 VM 에서 실행하면 간단
#!/bin/bash

sudo apt update && sudo apt install locales

sudo locale-gen en_US en_US.UTF-8
sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8
export LANG=en_US.UTF-8

# check locale
locale

sudo apt install software-properties-common -y
sudo add-apt-repository universe

sudo apt update && sudo apt install curl
sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg

echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null

sudo apt update
sudo apt upgrade

# install ros2
sudo apt install ros-foxy-ros-base python3-argcomplete -y
sudo apt install ros-dev-tools -y

echo 'source /opt/ros/foxy/setup.bash' >> ~/.bashrc
source /opt/ros/foxy/setup.bash

(Optional) 워크스페이스 마운트

  • VM에서 코드를 작성하려면 vim을 사용해야 하므로 불편함.
  • macOS 쪽의 디렉터리와 VM 안의 디렉터리를 마운트하여 코드 작성은 macOS에서, ROS2 빌드는 VM에서 하는 것이 편리
# VM 종료
dierslair@macbook $ multipass stop ros2-focal

# 워크스페이스 생성
dierslair@macbook $ mkdir -p ~/Documents/ros2_ws

# VM에 마운트
dierslair@macbook $ multipass mount --type native ~/Documents/ros2_ws ros2-focal:/user/ubuntu/ros2_ws

# VM 재시작
dierslair@macbook $ multipass start ros2-focal

프로젝트 생성

# VM 진입
dierslair@macbook $ multipass shell ros2-focal

# 패키지 생성
ubuntu@ros2-focal $ cd ~/ros2_ws
ubuntu@ros2-focal $ mkdir src
ubuntu@ros2-focal $ ros2 pkg create --build-type ament_cmake more_interfaces

커스텀 타입 선언

# ~/ros2_ws/src/more_interfaces/msg/AddressBook.msg
bool FEMALE = true
bool MALE = false

string first_name
string last_name
bool gender
uint8 age
string address

테스트용 노드 작성

  • ~/ros2_ws/src/more_interfaces/src/publisher_address_book.cpp 생성
#include <chrono>
#include <memory>

#include "rclcpp/rclcpp.hpp"
#include "more_interfaces/msg/AddressBook.hpp"

using namespace std::chrono_literals;

class AddressBookPublisher : public rclcpp::Node
{
public:
	AddressBookPublisher() : Node("address_book_publisher")
    {
    	this->publisher_ = this->create_publisher<more_interfaces::msg::AddressBook>("address_book", 10);
        
        // 람다 사용
        auto publish_msg = [this]() -> void {
        	auto message = more_interfaces::msg::AddressBook();
            message.first_name = "John";
            message.last_name = "Doe";
            message.age = 30;
            message.gender = message.MALE;
            message.address = "unknown";
            
            std::cout << "Publishing Contact\nFirst: " << message.first_name << " Last: " << message.last_name << std::endl;
            
            this->publisher_->publish(message);
        };
        
        # 매 1초마다 msg 발신
        this->timer_ = this->create_wall_timer(1s, publish_msg);
    }

private:
	rclcpp::Publisher<more_interfaces::msg::AddressBook>::SharedPtr publisher_;
    rclcpp::TimerBase::SharedPtr timer_;
};

int main(int argc, char** argv)
{
	rclcpp::init(argc, argv);
    rclcpp::spin(std::make_shared<AddressBookPublisher>());
    rclcpp::shutdown();

	return 0;
}

package.xml 수정

<!-- 추가 -->
<buildtool_depend>rosidl_default_generators</buildtool_depend>
<exec_depend>rosidl_default_runtime</exec_depend>
<member_of_group>rosidl_interface_packages</member_of_group>

CMakeList.txt 수정

# dependencies
find_package(rclcpp REQUIRED)
find_package(rosidl_default_generators REQUIRED)

# 커스텀 메시지
set(msg_files
  "msg/AddressBook.msg")

# 인터페이스 생성
rosidl_generate_interfaces(${PROJECT_NAME}
  ${msg_files})

ament_export_dependencies(rosidl_default_runtime)

# address_book_publisher 추가
add_executable(address_book_publisher src/publisher_address_book.cpp)
ament_target_dependencies(address_book_publisher rclcpp)

# 같은 패키지 내의 소스에게 인터페이스 노출
rosidl_target_interfaces(address_book_publisher
  ${PROJECT_NAME} "rosidl_typesupport_cpp")

install(TARGETS
  address_book_publisher
  DESTINATION lib/${PROJECT_NAME})

빌드 / 확인

ubuntu@ros2-focal $ cd ~/ros2_ws

# resolve dependencies
ubuntu@ros2-focal $ rosdep install -i --from-path src --rosdistro foxy -y

# execute build
ubuntu@ros2-focal $ colcon build --packages-select more_interfaces
Starting >>> more_interfaces
Finished <<< more_interfaces [15.9s]

Summary: 1 package finished [16.4s]

# install packages
ubuntu@ros2-focal $ . install/local_setup.bash

# show interface info
ubuntu@ros2-focal $ ros2 interface show more_interfaces/msg/AddressBook
bool FEMALE=true
bool MALE=false

string first_name
string last_name
bool gender
uint8 age
string address

# run publisher
ubuntu@ros2-focal $ ros2 run more_interfaces address_book_publisher

# (other terminal) 발행 메시지 확인
ubuntu@ros2-focal $ ros2 topic echo /address_book
profile
Java/Kotlin Backend Developer

0개의 댓글