[ROS] 패키지 소스 빌드 전 의존 패키지 설치하기

ROS를 개발하다보면 여러가지 패키지들을 사용해야 하고, 또한 오픈소스로 공개되어 있는 (주로는 github 등에서 받아오는) 패키지를 받아 빌드하여 사용해야할 경우가 생긴다.

이때 빌드하려는 패키지가 사용하는 의존 패키지들을 설치해줘야 빌드가 제대로 될 수 있는데, 이를 일일이 설치하는 것부터가 일이 되는 경우가 있다. README.md 파일에 이런 패키지들을 설치해야 합니다라고 알려주고 설치방법을 다음과 같이 패키지 리스트와 같이 알려 주는 경우도 있다.

$ sudo apt install package1 package2 ...

ROS에선 이를 쉽게 해결하기 위해서 rosdep 툴을 제공한다. rosdep이 하는 일을 보면, 여러가지 패키지들의 이름을 저장해 놓고, 각 패키지의 이름에 해당하는 시스템 패키지 명을 db로 저장하고 있는 형태이다. 기본적으론 rosdep.yaml 파일을 메인 레포지토리에서 받아와서 사용하고 있으며, 사용자가 이 파일을 수정하여 사용할 수도 있다.

각 패키지의 package.xml 파일엔 이 패키지가 의존하는 패키지들의 리스트가 저장되어 있다 (잘 만들어진 패키지라면…). rosdep은 각 패지키의 package.xml 파일을 읽어와, 의존 패키지 리스트를 만들고, 이를 위에서 설명한 db와 매칭하여 시스템 패키지를 설치하는 과정을 거친다.

따라서 패키지 디렉토리로 이동하여 다음과 같이 입력한다.

$ rosdep install --from-paths . --ignore-src -r -y

이렇게 하면 현재 디렉토리부터 하위 디렉토리를 순환하여 돌아다니며, 의존 패키지들을 자동으로 설치해 준다.

만약 파이썬으로 구성된 패키지이고, 의존 패키지를 requirements.txt 내에 잘 정리해 두었다면, 위와 같은 방법으로 다음과 같이 실행하면 의존 패키지를 pip를 이용하여 설치한다.

$ find -name 'requirements.txt' | xargs -L 1 sudo pip install -U -r

다른 사람이 만들어 놓은 패키지를 잘 이용하는 것도 좋지만, 위와 같은 과정을 잘 익혀두었다가 본인이 만든 패키지를 배포할때도 package.xml, requirements.txt 파일을 잘 정리하여 배포한다면 다른 사람이 별다른 수고없이도 쉽게 사용할 수 있게 된다.

Advertisements

커스텀 메시지를 이용할 경우 catkin 빌드 에러 해결

ROS 패키지를 개발할 때, Topic, Service, Action을 사용할 경우, 기존 정의되어 있는 여러가지 메시지를 사용할 수도 있지만, 편의상 사용자가의 커스텀 메시지를 이용해야 하는 경우가 있다.

이때 Python으로 개발하면 별다른 문제는 없지만, C++로 만든 노드의 경우 catkin 빌드를 하게 되면 커스텀 메시지의 header 파일을 찾을 수 없다는 에러가 나온다.

Errors     << dynamixel_ros_control:make /home/robot/catkin_ws/logs/dynamixel_ros_control/build.make.000.log                                                                        
In file included from /home/robot/catkin_ws/src/dynamixel_ros_control/include/dynamixel_ros_control/dynamixel_hw_interface.h:9:0,                                                   
                 from /home/robot/catkin_ws/src/dynamixel_ros_control/src/dynamixel_ros_control_node.cpp:3:                                                                         
/home/robot/catkin_ws/src/dynamixel_ros_control/include/dynamixel_ros_control/dynamixel_motor.h:11:48: fatal error: dynamixel_ros_control/HomingAction.h: No such file or directory 
compilation terminated.                                                                                                                                                             
make[2]: *** [CMakeFiles/dynamixel_ros_control_node.dir/src/dynamixel_ros_control_node.cpp.o] Error 1                                                                               
make[1]: *** [CMakeFiles/dynamixel_ros_control_node.dir/all] Error 2                                                                                                                
make: *** [all] Error 2    

몇번 빌드를 반복하다보면 에러 없이 빌드 되는 경우도 있지만 마땅한 해결 방법은 아니다. 몇번 골치를 썩다가 wiki의 투토리얼을 다시금 살펴보니 해결책이 나와있었다. 하지만 패키지를 만들때 생성되는 CMakeList.txt 파일엔 이 내용이 반영되어 있지 않아 혼란이 있는 듯 하다.

Writing a Simple Publisher and Subscriber (C++) 페이지를 보면 중간쯤 다음과 같이 입력하라고 나온다.

노드를 빌드하기 전, 노드에 의존 항목을 추가하여 위와 같은 에러를 방지하려는듯 하다. 따라서 CMakeList.txt 파일에 다음과 같이 입력하면 된다.

add_executable(${PROJECT_NAME}_node
  src/dynamixel_ros_control_node.cpp
  src/dynamixel_hw_interface.cpp
  src/dynamixel_motor.cpp
)

add_dependencies(${PROJECT_NAME}_node ${PROJECT_NAME}_generate_messages_cpp)
target_link_libraries(${PROJECT_NAME}_node
  ${catkin_LIBRARIES}
)

이제 다시 catkin 빌드를 할 때, 관련 에러는 발생하지 않는다.

imu_complementary_filter를 이용한 IMU 자세 추정

IMU를 이용한 자세추정 방법은 보통 보상 필터를 많이 사용한다. 3축 가속도 센서와 3축 자이로스코프를 사용하고, 3축 지자기 센서를 이용하여 보정한다. 가속도 센서는 3축의 가속도 값 (m/s^2)을 두번 적분하여 위치를 구할수 있으나 회전 및 진동 등에 의해서 값이 변하는 단점이 있고, 자이로스코프는 3축의 각속도 (rad/s)를 한번 적분하여 회전각을 알아낼수 있지만 각 축에 포함된 화이트 노이즈 덕분에 시간이 흐를수록 값이 변한다 (일명 드리프트 현상).

따라서 각각의 센서가 가지는 장점을 뽑아서 사용하자는게 보상필터이고, 간단하게는 Low-pass filter, High-pass filter를 사용하거나, 두개의 Band-pass filter를 사용하는게 일반적이다. 이게 바로 보상 (complementary) 필터이다.

직접 구현해서 사용하는 것도 방법이긴하나, 이미 많이 알려진 알고리즘이고 ROS에 패키지로도 존재하므로 쉽게 사용이 가능하다.

사용할 패키지는 imu_complementary_filter이다. 사용 방법은 연결된 링크의 wiki 페이지에 자알~ 되어있다. 논문을 기반으로 개발된 것 같고, 간단한(?) 블록 다이러그램은 다음과 같다.

Ref: https://www.mdpi.com/1424-8220/15/8/19302

설치는 다음과 같이 하고,

$ sudo apt install ros-kinetic-imu-complementary-filter

사용은 다음과 같이,

$ rosrun imu_complementary_filter complementary_filter_node

complementary_filter_node는 /imu/data_raw (sensor_msgs/Imu)를 Subscribe 한다. 사용하려는 IMU가 위 토픽을 Publish 한다면 고맙게 사용할 수 있고, 토픽 이름이 다르다면 다음과 같이 실행하면 끝!,

$ rosrun imu_complementary_filter complementary_filter_node /imu/data:=/<your_topic_name>

결과로는 imu/data (sensor_msgs/Imu)를 Publish 한다. 결과를 살펴보면 입력 데이터에 Orientation 값이 계산되어 나옴을 확인할 수 있다.