클래스에서 매개변수 사용하기 (C++)
목표: C++을 사용하여 ROS 매개변수를 사용하는 클래스를 생성하고 실행합니다.
배경
Nodes 를 만들 때 런치 파일에서 설정할 수 있는 매개변수를 추가해야 할 때가 있습니다.
이 튜토리얼에서는 C++ 클래스에서 이러한 매개변수를 생성하고 런치 파일에서 설정하는 방법을 보여줍니다.
전제 조건
이전 튜토리얼에서는 작업 공간을 만드는 방법 및 패키지를 만드는 방법 을 배웠습니다. 또한 ROS 2 시스템에서 매개변수 에 대한 기능을 배웠습니다.
작업
1 패키지 생성
새 터미널을 열고 ROS 2 설치를 소스로 지정 하여 ros2 명령이 작동하도록합니다.
이전 튜토리얼에서 만든 이전 디렉토리 에서 생성한 ros2_ws 디렉토리로 이동합니다.
패키지는 워크스페이스의 루트가 아닌 src 디렉토리에서 생성해야 합니다.
ros2_ws/src 로 이동하고 새로운 패키지를 만듭니다.
ros2 pkg create --build-type ament_cmake --license Apache-2.0 cpp_parameters --dependencies rclcpp
터미널에서 패키지 cpp_parameters 와 필요한 모든 파일 및 폴더를 확인하는 메시지가 표시됩니다.
--dependencies 인수는 package.xml 및 CMakeLists.txt 에 필요한 종속성 라인을 자동으로 추가합니다.
1.1 package.xml 업데이트
패키지 생성 중에 --dependencies 옵션을 사용했으므로 package.xml 또는 CMakeLists.txt 에 종속성을 수동으로 추가할 필요가 없습니다.
그러나 항상 package.xml 에 설명, 유지 관리자 이메일 및 이름, 라이선스 정보를 추가하십시오.
<description>C++ parameter tutorial</description>
<maintainer email="you@email.com">Your Name</maintainer>
<license>Apache License 2.0</license>
2 C++ 노드 작성
ros2_ws/src/cpp_parameters/src 디렉토리 내에서 cpp_parameters_node.cpp 라는 새 파일을 만들고 다음 코드를 붙여 넣습니다.
#include <chrono>
#include <functional>
#include <string>
#include <rclcpp/rclcpp.hpp>
using namespace std::chrono_literals;
class MinimalParam : public rclcpp::Node
{
public:
MinimalParam()
: Node("minimal_param_node")
{
this->declare_parameter("my_parameter", "world");
timer_ = this->create_wall_timer(
1000ms, std::bind(&MinimalParam::timer_callback, this));
}
void timer_callback()
{
std::string my_param = this->get_parameter("my_parameter").as_string();
RCLCPP_INFO(this->get_logger(), "Hello %s!", my_param.c_str());
std::vector<rclcpp::Parameter> all_new_parameters{rclcpp::Parameter("my_parameter", "world")};
this->set_parameters(all_new_parameters);
}
private:
rclcpp::TimerBase::SharedPtr timer_;
};
int main(int argc, char ** argv)
{
rclcpp::init(argc, argv);
rclcpp::spin(std::make_shared<MinimalParam>());
rclcpp::shutdown();
return 0;
}
2.1 코드 검토
패키지 종속성을 나타내는 #include 문이 파일 맨 위에 있습니다.
다음 코드 조각에서 클래스와 생성자를 만듭니다.
이 생성자의 첫 번째 줄은 my_parameter 라는 이름과 기본 값이 world 인 매개변수를 선언합니다.
매개변수 유형은 기본 값에서 유추되므로 이 경우 문자열 유형으로 설정됩니다.
다음으로 timer_ 은 1000ms의 주기로 설정되어 있으며, 이로 인해 timer_callback 함수가 1초에 한 번 호출됩니다.
class MinimalParam : public rclcpp::Node
{
public:
MinimalParam()
: Node("minimal_param_node")
{
this->declare_parameter("my_parameter", "world");
timer_ = this->create_wall_timer(
1000ms, std::bind(&MinimalParam::timer_callback, this));
}
timer_callback 함수의 첫 줄은 노드에서 매개 변수 my_parameter 를 가져와 my_param 에 저장합니다.
그 다음으로 RCLCPP_INFO 함수는 이벤트가 로그에 기록되도록 합니다.
그런 다음 set_parameters 함수는 매개 변수 my_parameter 를 기본 문자열 값인 world 로 다시 설정합니다.
사용자가 매개 변수를 외부에서 변경한 경우에도 항상 원래 값으로 재설정됨을 보장합니다.
void timer_callback()
{
std::string my_param = this->get_parameter("my_parameter").as_string();
RCLCPP_INFO(this->get_logger(), "Hello %s!", my_param.c_str());
std::vector<rclcpp::Parameter> all_new_parameters{rclcpp::Parameter("my_parameter", "world")};
this->set_parameters(all_new_parameters);
}
마지막으로 timer_ 를 선언합니다.
private:
rclcpp::TimerBase::SharedPtr timer_;
MinimalParam 클래스 뒤에는 main 함수가 있습니다.
여기서 ROS 2가 초기화되고 MinimalParam 클래스의 인스턴스가 생성되며 rclcpp::spin 함수가 노드에서 데이터를 처리하기 시작합니다.
int main(int argc, char ** argv)
{
rclcpp::init(argc, argv);
rclcpp::spin(std::make_shared<MinimalParam>());
rclcpp::shutdown();
return 0;
}
2.1.1 (선택 사항) ParameterDescriptor 추가
선택적으로 매개변수에 대한 설명을 설정할 수 있습니다. 설명을 사용하면 매개변수와 해당 제약 조건(읽기 전용으로 만들기, 범위 지정 등)을 지정할 수 있습니다. 그러려면 생성자의 코드를 다음과 같이 변경해야 합니다.
// ...
class MinimalParam : public rclcpp::Node
{
public:
MinimalParam()
: Node("minimal_param_node")
{
auto param_desc = rcl_interfaces::msg::ParameterDescriptor{};
param_desc.description = "This parameter is mine!";
this->declare_parameter("my_parameter", "world", param_desc);
timer_ = this->create_wall_timer(
1000ms, std::bind(&MinimalParam::timer_callback, this));
}
나머지 코드는 동일합니다.
노드를 실행한 후에는 ros2 param describe /minimal_param_node my_parameter 를 실행하여 유형 및 설명을 볼 수 있습니다.
2.2 실행 파일 추가
이제 CMakeLists.txt 파일을 엽니다. find_package(rclcpp REQUIRED) 종속성 아래에 다음 코드를 추가합니다.
add_executable(minimal_param_node src/cpp_parameters_node.cpp)
ament_target_dependencies(minimal_param_node rclcpp)
install(TARGETS
minimal_param_node
DESTINATION lib/${PROJECT_NAME}
)
3 빌드 및 실행
빌드하기 전에 루트 디렉토리에서(ros2_ws) rosdep 를 실행하여 누락된 종속성을 확인하는 것이 좋습니다.
rosdep install -i --from-path src --rosdistro humble -y
다시 작업 공간 루트인 ros2_ws 로 이동하고 새 패키지를 빌드합니다.
colcon build --packages-select cpp_parameters
새 터미널에서 설정 파일을 다시 소스화합니다.
source install/setup.bash
이제 노드를 실행합니다.
ros2 run cpp_parameters minimal_param_node
터미널은 다음과 같은 메시지를 1초에 한 번씩 반환해야 합니다.
[INFO] [minimal_param_node]: Hello world!
이제 매개변수의 기본값을 볼 수 있지만 직접 설정할 수 있어야 합니다. 이를 수행하는 두 가지 방법이 있습니다.
3.1 콘솔을 통한 변경
이 부분은 매개변수에 대한 튜토리얼 에서 얻은 지식을 사용하여 방금 만든 노드에 적용합니다.
노드가 실행 중인지 확인합니다..
ros2 run cpp_parameters minimal_param_node
다른 터미널을 열고 다시 ros2_ws 내에서 설정 파일을 소스화하고 다음 줄을 입력합니다.
ros2 param list
여기에서 사용자 정의 매개변수 my_parameter 를 볼 수 있습니다.
변경하려면 콘솔에서 다음 줄을 실행하면 됩니다.
ros2 param set /minimal_param_node my_parameter earth
Set parameter successful 출력을 받았다면 변경이 잘 이루어진 것입니다.
다른 터미널을 보면 출력이 [INFO] [minimal_param_node]: Hello earth! 로 변경되었음을 볼 수 있습니다.
3.2 런치 파일을 통한 변경
매개변수를 런치 파일에서 설정할 수도 있지만 먼저 런치 디렉토리를 추가해야 합니다.
ros2_ws/src/cpp_parameters/ 디렉토리 내에서 새 디렉토리인 launch 를 만듭니다.
그 안에 cpp_parameters_launch.py 라는 새 파일을 만듭니다.
from launch import LaunchDescription
from launch_ros.actions import Node
def generate_launch_description():
return LaunchDescription([
Node(
package="cpp_parameters",
executable="minimal_param_node",
name="custom_minimal_param_node",
output="screen",
emulate_tty=True,
parameters=[
{"my_parameter": "earth"}
]
)
])
여기에서 우리는 노드 minimal_param_node 를 시작할 때 my_parameter 를 earth 로 설정합니다.
아래의 두 줄을 추가하여 출력이 콘솔에 인쇄되도록했습니다.
output="screen",
emulate_tty=True,
이제 CMakeLists.txt 파일을 엽니다.
이전에 추가한 줄 아래에 다음 코드를 추가합니다.
install(
DIRECTORY launch
DESTINATION share/${PROJECT_NAME}
)
터미널에서 작업 공간 루트인 ros2_ws 로 이동하고 새 패키지를 빌드합니다.
colcon build --packages-select cpp_parameters
그런 다음 설정 파일을 새 터미널에서 소스화합니다.
source install/setup.bash
이제 방금 만든 런치 파일을 사용하여 노드를 실행합니다.
ros2 launch cpp_parameters cpp_parameters_launch.py
터미널은 다음과 같은 메시지를 1초에 한 번씩 반환해야 합니다:
[INFO] [custom_minimal_param_node]: Hello earth!
요약
매개변수를 설정할 수 있는 사용자 지정 매개변수를 가진 노드를 만들어 보았습니다. 이 매개변수는 런치 파일이나 명령 행에서 설정할 수 있습니다. 종속성, 실행 파일 및 런치 파일을 패키지 구성 파일에 추가하여 빌드 및 실행하고 매개변수를 확인하는 방법을 살펴보았습니다.