실행 인자 프로그래밍(C++)

두부김치·2024년 2월 21일
1

ROS2

목록 보기
28/29

1. 실행 인자

C++ 프로그램 실행 시 가장 먼저 호출되는 main 함수는 두 개의 매개변수를 가진다. 먼저 첫 번째 매개변수인 argc 는 argument count의 약자로 넘겨받은 인자들의 개수를 담고 있다. 두 번째 매개변수인 argv는 argument vector의 약자로 문자열, 포인터, 배열 타입으로 넘겨받은 인자들을 저장하고 있다.

ROS2에서 실행 인자는 크게 두 가지로 분류된다. 첫 번째는 --ros-args가 붙은 인자들로 ROS2 API와 관련된 옵션(remapping, parameter 등)을 변경할 수 있다. 두 번재는 --ros-args 가 붙지 않은 인자들로 일반적으로 사용하는 사용자 정의 실행 인자라고 생각하면 된다.

예를 들어 액션 프로그래밍 (C++) 에서 살펴보았던 checker 노드 실행시 하기와 같은 명령어를 통해 namespace 와 액션 목표값을 100으로 설정할 수 있었다. -g 100 으로 표기된 부분은 사용자 정의 실행인자 이고, --ros-args -r __ns:=/demo 으로 표기된 부분은 rclcpp::init 함수의 인자로 넘겨진다.

$ ros2 run topic_service_action_rclcpp_example checker -g 100 --ros-args  -r __ns:=/demo
goal_total_sum : 100
$ ros2 node list
/demo/checker

2. 실행 인자 코드

checker 노드를 실행시키는 main 함수의 전체 코드를 살펴보자.

#include <cstdio>
#include <memory>
#include <string>
#include <utility>

#include "rclcpp/rclcpp.hpp"
#include "rcutils/cmdline_parser.h"

#include "checker/checker.hpp"


void print_help()
{
  printf("For Node node:\n");
  printf("node_name [-h]\n");
  printf("Options:\n");
  printf("\t-h Help           : Print this help function.\n");
}

int main(int argc, char * argv[])
{
  if (rcutils_cli_option_exist(argv, argv + argc, "-h")) {
    print_help();
    return 0;
  }

  rclcpp::init(argc, argv);

  float goal_total_sum = 50.0;
  char * cli_option = rcutils_cli_get_option(argv, argv + argc, "-g");
  if (nullptr != cli_option) {
    goal_total_sum = std::stof(cli_option);
  }
  printf("goal_total_sum : %2.f\n", goal_total_sum);

  auto checker = std::make_shared<Checker>(goal_total_sum);

  rclcpp::spin(checker);

  rclcpp::shutdown();

  return 0;
}

먼저 헤더 파일을 살펴보면 rcuils의 cmdline_parser가 포함되어 있다. 해당 라이브러리를 사용하면 main문의 인자를 쉽게 확인할 수 있다.

#include "rcutils/cmdline_parser.h"

main 함수 안을 보면 가장 먼저 rcutils_cli_option_exist 함수를 이용하여 -h 인자가 있는지 확인한다. 만약 -h 인자가 있다면 print_help 함수를 출력하고 main 함수를 빠져나가게 된다. 이를 통해 사용자가 해당 노드를 처음 사용하게 될 때 필요한 정보를 제공해 줄 수 있다.

  if (rcutils_cli_option_exist(argv, argv + argc, "-h")) {
    print_help();
    return 0;
  }

rclcpp::init함수로 main 함수로 넘겨받은 argc, argv 인자를 넘겨주어 "--ros-args" 인자를 rclcpp가 확인할 수 있도록 해주는 코드를 확인할 수 있다.

rclcpp::init(argc, argv);

rcutils_cli_get_option 함수는 실행 인자를 확인하고 그 값을 문자열 포인터로 반환해주는 역할을 한다. 해당 함수를 이용하여 사용자는 쉽게 여려 개의 실행 인자를 파싱할 수 있고, 문자열 포인터를 원하는 변수 타입으로 변경하여 생성될 클래스의 인자로 넘겨줄 수 있다.

 float goal_total_sum = 50.0;
  char * cli_option = rcutils_cli_get_option(argv, argv + argc, "-g");
  if (nullptr != cli_option) {
    goal_total_sum = std::stof(cli_option);
  }
  printf("goal_total_sum : %2.f\n", goal_total_sum);

  auto checker = std::make_shared<Checker>(goal_total_sum);

3. ROS2의 파라미터와 실행 인자

이전 강의에서 알아본 ROS 2 파라미터와 이번 강의에서 알아본 실행 인자의 차이점은 무엇일까. 그 기준은 변수가 런타임에서 사용자 혹은 다른 프로그램에 의해 변경되어야할 값인지 확인해 보는 것이다. 만약 그렇다면 ROS 2 파라미터 서버에 변수를 등록하고, 서비스 통신을 이용해 값을 변경해가며 프로그램의 옵션을 변경할 수 있게 한다. 만약 그렇지 않다면 실행 인자를 사용하여 변수의 값을 초기화하고, 노드 생성시 필요한 옵션을 설정할 수 있도록 한다.

여기까지 실행 인자 프로그래밍에 대해 알아보았다. 다음 시간에는 런치 프로그래밍 코드를 분석해보겠다.

profile
Robotics

0개의 댓글