Build Cartographer on ROS1 Noetic

Melodic에선 패키지로 잘 제공되는 Cartographer가 Noetic에선 바이너리 패키지로 제공되지 않는다. 귀찮게도 소스를 받아서 빌드해야 하는데, 다음과 같은 과정으로 설치하면 깔끔하게 처리 가능.

필요한 툴 설치

$ sudo apt-get install -y python3-wstool python3-rosdep ninja-build stow

워크스페이스에 디렉토리를 만들고 필요한 소스를 받아온다.

$ cd ~/catkin_ws/src
$ mkdir cartographer
$ cd cartographer
$ git clone https://github.com/cartographer-project/cartographer.git
$ git clone https://github.com/cartographer-project/cartographer_ros.git

빌드에 필요한 패키지를 자동으로 설치한다.

$ pwd
/home/<user-name>/catkin_ws/src/cartgrapher
$ rosdep install --from-paths . --ignore-src -r -y

libabseil 설치.

$ cd catrographer/scripts
$ ./install_abseil.sh

이제 빌드하면 에러없이 정상적으로 빌드 가능.

$ catkin build

끝.!

Using Gazebo11 with ROS1 Melodic

Gazebo 11이 지난 달에 릴리즈 되었습니다. 이 버전이 Gazebo의 마지막 릴리즈 버전이고, 이후론 지원 기간까지 새로운 기능보단, 주로 버그 수정 등만 지원됩니다. 새로운 Ignition Gazebo가 나올 예정인데, 이는 Ignition Robotics라는 곳에서 업데이트 등을 지원할 예정입니다.

현재의 ROS의 최근 LTS 버전은 Melodic으로, 공식적으론 Gazebo 9만 지원합니다. 따라서 Gazebo 11을 사용하기 위해선 ROS와 연동하기 위한 패키지들을 새로 빌드해줘야 합니다.


ROS1 Melodic이 설치된 상태에서, Gazebo 11을 설치하려면 패키지의 의존성 등을 고려하여 다음과 같이 입력합니다.

$ sudo apt install gazebo11 libgazebo11 gazebo11-common libgazebo11-dev 

이러면, Gazebo 9은 자동으로 제거가 되고, Gazebo 11이 설치됩니다.

이제 ROS와 연동하기 위한 gazebo_ros_pkgs를 새로 받아 빌드합니다.

catkin workspace 내에서 작업해야 하므로,

$ cd ~/catkin_ws/src
$ git clone https://github.com/ros-simulation/gazebo_ros_pkgs.git
$ cd gazebo_ros_pkgs
$ git checkout melodic-devel
$ catkin build 

빌드가 완료되면, 예전과 같이 정상적으로 ROS1과 연동하여 사용이 가능합니다. 플러그인도 사용 가능.

$ roslaunch gazebo_ros empty_world.launch

위와 같이 설치를 하게 되면, ros-melodic-desktop-full의 의존성이 깨지므로, apt를 사용할때 autoremove로 ROS 패키지들을 자동으로 지우게끔 유도하게 되는데 이를 해결하려면,

$ sudo apt install ros-melodic-perception ros-melodic-desktop ros-melodic-ros-control ros-melodic-ros-controllers

와 같이 각각의 패키지들을 설치하면 해결되고, 그 외의 패키지는 필요없는 것들이니 지워도 무방합니다.

끝.

[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 파일을 잘 정리하여 배포한다면 다른 사람이 별다른 수고없이도 쉽게 사용할 수 있게 된다.

커스텀 메시지를 이용할 경우 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 값이 계산되어 나옴을 확인할 수 있다.