[카테고리:] 생활코딩

  • rviz 12.7 update 실패->성공

    rviz 12.7 update 실패->성공

    osrf/ros:humble-desktop 도커 이미지를 설치하면 rviz 12.6가 설치된다. 가끔 node를 만들어 robot_description을 입력하면, rviz2가 제대로 표시 안할 경우가 있다. moveit_setup_assistant도 기존 설정 파일을 수정하면 robot_model_loader가 실행되지 않을 경우도 있다. 아마 12.6 버전의 문제인 듯 하여 버전을 올려 보기로 했다. 최신 버전은 12.8인데, humble이 사용할 수 있는 가장 최근 버전은 12.7이다. 12.8을 사용하면 display panel이 안보이는 듯 안정적으로 동작하지 않는다.

    now0930@rygen3600:~/ros2/test/ws_root/ws_user$ git clone -b humble https://github.com/ros2/rviz.git
    'rviz'에 복제합니다...
    remote: Enumerating objects: 30445, done.
    remote: Counting objects: 100% (4756/4756), done.
    remote: Compressing objects: 100% (1181/1181), done.
    remote: Total 30445 (delta 3857), reused 4031 (delta 3399), pack-reused 25689
    오브젝트를 받는 중: 100% (30445/30445), 16.45 MiB | 16.27 MiB/s, 완료.
    델타를 알아내는 중: 100% (22231/22231), 완료.
    now0930@rygen3600:~/ros2/test/ws_root/ws_user$ cd rviz/
    now0930@rygen3600:~/ros2/test/ws_root/ws_user/rviz$ git checkout 
    브랜치가 'origin/humble'에 맞게 업데이트된 상태입니다.

    branch를 선택하지 않고, default 값으로 humble에서 12.8을 컴파일 하고 있었다. 잘 동작되지 않아 2일을 날렸다. work space 구조도 각 패키지에 맞도록 세부적으로 나누어야 한다. 섞이면 컴파일 양도 많고, 각 패키지별로 옵션을 설정할 수 없다. workspace에 대한 내용은 여기에 있다. overlay, underlay를 정확하게 이해하지 않고 가 시간 날렸다.

    rviz2 readme를 따라 complie 한다. 컴파일 중 ignition_math6_vendor가 없어 에러로 멈춘다.

    CMake Error at CMakeLists.txt:64 (find_package):
      By not providing "Findignition_math6_vendor.cmake" in CMAKE_MODULE_PATH
      this project has asked CMake to find a package configuration file provided
      by "ignition_math6_vendor", but CMake did not find one.
    
      Could not find a package configuration file provided by
      "ignition_math6_vendor" with any of the following names:
    
        ignition_math6_vendorConfig.cmake
        ignition_math6_vendor-config.cmake
    
      Add the installation prefix of "ignition_math6_vendor" to CMAKE_PREFIX_PATH
      or set "ignition_math6_vendor_DIR" to a directory containing one of the
      above files.  If "ignition_math6_vendor" provides a separate development
      package or SDK, be sure it has been installed.

    apt-cache로 ros-humble-ignition-math6-vendor를 검색하면, 해당 패키지가 설치되어 있다. dpkg로 어떤 파일들이 있는지 보면, 실재 파일은 없는 듯 하다.

    root@rygen3600:/home/ros2_test# dpkg -L ros-humble-ignition-math6-vendor
    /.
    /opt
    /opt/ros
    /opt/ros/humble
    /opt/ros/humble/share
    /opt/ros/humble/share/ignition_math6_vendor
    /opt/ros/humble/share/ignition_math6_vendor/package.xml
    /usr
    /usr/share
    /usr/share/doc
    /usr/share/doc/ros-humble-ignition-math6-vendor
    /usr/share/doc/ros-humble-ignition-math6-vendor/changelog.Debian.gz
    /usr/share/doc/ros-humble-ignition-math6-vendor/copyright
    root@rygen3600:/home/ros2_test# 
    

    ROS Index를 찾아보면 rviz2 github를 찾을 수 있는데, 이를 rviz에 있는 디렉토리에 받아주면 된다. ignition-math6-vendor가 gz_math6_vendor로 바뀐 느낌이다. CMakefile을 보면 project로 ignition_math6_vendor로 자기를 명명한다.

    oot@rygen3600:/home/ros2_test/rviz# ls -alh
    total 92K
    drwxrwxr-x 17 1000 1000 4.0K Aug  8 21:43 .
    drwxrwxr-x  7 1000 1000 4.0K Aug  6 20:45 ..
    drwxrwxr-x  8 1000 1000 4.0K Aug  6 20:45 .git
    drwxrwxr-x  3 1000 1000 4.0K Aug  6 20:45 .github
    -rw-rw-r--  1 1000 1000   55 Aug  6 20:45 .gitignore
    -rw-rw-r--  1 1000 1000   84 Aug  6 20:45 CODEOWNERS
    -rw-rw-r--  1 1000 1000 1.7K Aug  6 20:45 LICENSE
    -rw-rw-r--  1 1000 1000 8.2K Aug  6 20:45 README.md
    drwxr-xr-x 11 root root 4.0K Aug  8 21:49 build
    drwxrwxr-x  2 1000 1000 4.0K Aug  6 20:45 docs
    drwxrwxr-x  5 1000 1000 4.0K Aug  8 21:43 gz_math6_vendor
    drwxr-xr-x  7 root root 4.0K Aug  8 21:49 install
    drwxr-xr-x 10 root root 4.0K Aug  8 21:44 log
    drwxrwxr-x  6 1000 1000 4.0K Aug  6 20:45 rviz2
    drwxrwxr-x  3 1000 1000 4.0K Aug  6 20:45 rviz_assimp_vendor
    drwxrwxr-x  8 1000 1000 4.0K Aug  6 20:45 rviz_common
    drwxrwxr-x  6 1000 1000 4.0K Aug  8 21:53 rviz_default_plugins
    drwxrwxr-x  3 1000 1000 4.0K Aug  6 20:45 rviz_ogre_vendor
    drwxrwxr-x  6 1000 1000 4.0K Aug  6 20:45 rviz_rendering
    drwxrwxr-x  4 1000 1000 4.0K Aug  6 20:45 rviz_rendering_tests
    drwxrwxr-x  7 1000 1000 4.0K Aug  8 20:54 rviz_visual_testing_framework
    root@rygen3600:/home/ros2_test/rviz# 
    root@rygen3600:/home/ros2_test/rviz# cd gz_math6_vendor/
    root@rygen3600:/home/ros2_test/rviz/gz_math6_vendor# ls
    CHANGELOG.rst	CONTRIBUTING.md  package.xml
    CMakeLists.txt	LICENSE		 patches
    root@rygen3600:/home/ros2_test/rviz/gz_math6_vendor# cat CMakeLists.txt 
    cmake_minimum_required(VERSION 3.10)
    project(ignition_math6_vendor)
    
    find_package(ament_cmake_core REQUIRED)
    find_package(ament_cmake_vendor_package REQUIRED)
    
    find_package(ignition-math6 6.9.2 QUIET)
    
    ament_vendor(ignition_math6_vendor
      SATISFIED ${ignition-math6_FOUND}
      VCS_URL https://github.com/ignitionrobotics/ign-math.git
      VCS_VERSION ignition-math6_6.9.2
      PATCHES patches
      CMAKE_ARGS
        -DBUILD_DOCS:BOOL=OFF
      GLOBAL_HOOK
    )
    
    find_package(ament_cmake_test REQUIRED)
    if(BUILD_TESTING)
      find_package(ament_cmake_lint_cmake REQUIRED)
      find_package(ament_cmake_copyright REQUIRED)
      find_package(ament_cmake_xmllint REQUIRED)
    
      ament_lint_cmake()
      ament_copyright()
      ament_xmllint()
    endif()
    
    ament_package()
    
  • ros2 launch gdb

    ros2 launch gdb

    ros2를 gdb를 사용할 수 있다(대박!). 먼저 ros2 run 옵션으로 사용하는 포스트를 찾았다. 이러면 node를 만들 때 전달한 파라미터를 모두 넣어줘야 하여 어렵고 불편하다. 다행히 ros가 죽을 때 어떤 파일을 사용했는지 알려줬다.

    [ERROR] [robot_model_tutorial-1]: process has died [pid 1919, exit code -11, cmd '/home/ros2_test/install/hello_moveit/lib/hello_moveit/robot_model_tutorial --ros-args --params-file /tmp/launch_params_2myb0p1i --params-file /tmp/launch_params_q_86u0o7 --params-file /tmp/launch_params_2dnzqmp1'].

    node를 실행할 때, tmp 디렉토리에 파일로 만들어 이를 args로 전달한다. 다음과 같이 ros run으로 gdb를 붙일 수 있다.

    ros2 run --prefix 'gdb -ex run --args' hello_moveit robot_model_tutorial --ros-args --params-file /tmp/launch_params_2myb0p1i --params-file /tmp/launch_params_q_86u0o7 --params-file /tmp/launch_params_2dnzqmp1

    파라미터 입력이 귀찮으면, launch 옵션에 prefix로 넣어 사용할 수 있다. 단 터미널을 새로 만들어야 한다. 왜 그런지는 잘 모르겠는데, 일단 되니까 패스.

    <사용하는 lanch file>
    from launch import LaunchDescription
    from launch_ros.actions import Node
    from moveit_configs_utils import MoveItConfigsBuilder
    
    
    def generate_launch_description():
        moveit_config = MoveItConfigsBuilder("hello").to_moveit_configs()
    
        my_node = Node(
            package="hello_moveit",
            executable="robot_model_tutorial",
            output="screen",
            parameters=[
                moveit_config.robot_description,
                moveit_config.robot_description_semantic,
                moveit_config.robot_description_kinematics,
            ],
        )
    
        return LaunchDescription([my_node])
    
    <디버그용 lanch file>
    from launch import LaunchDescription
    from launch_ros.actions import Node
    from moveit_configs_utils import MoveItConfigsBuilder
    
    
    def generate_launch_description():
        moveit_config = MoveItConfigsBuilder("hello").to_moveit_configs()
    
        my_node = Node(
            package="hello_moveit",
            executable="robot_model_tutorial",
            prefix ="xterm -e gdb run --args",
            output="screen",
            parameters=[
                moveit_config.robot_description,
                moveit_config.robot_description_semantic,
                moveit_config.robot_description_kinematics,
            ],
        )
    
        return LaunchDescription([my_node])
    

    gdb 기본 사용법은 여기 정리되어 있다.

  • MoveIt2 tutorial 따라하기(setFromIK)

    인터넷에 공개된 MoveIt2 tutorial을 따라하다 보면 많은 사실을 학습할 수 있다. 다만 그대로 따라하면 그 감동이 적어, 내가 마음대로 해보기로 했다. ABB가 인터넷에 공개한 ABB_IRB2400 urdf 파일로 시작했다. 내가 한 삽질을 여기에 끄적인다.

    setup assistant로 urdf 파일을 로딩하고, move_group, kinematics solver, pose 등을 설정하여 움직이는 Manuplator를 프로젝트 이름 + moveit_config 디렉토리에 저장했다. 기본으로 제공된 demo.launch.py을 실행하여 Rviz를 열고, 마우스 버튼으로 robotModel, MarkArray, panel을 추가했다. Planning with Path Constraints 부분에서 막혔는데,

    start_state.setFromIK(joint_model_group, start_pose2);

    를 실행하면

    No kinematics solver instantiated for group '%s

    메세지를 내고 프로그램이 죽는다. RobotState Class를 찾아보니 인자로 제공된 JointModelGroup에서 SolverInstance를 얻지 못하면 error 처리한다.

    01278 bool moveit::core::RobotState::setFromIK(const JointModelGroup* jmg, const geometry_msgs::Pose& pose,
    01279                                          unsigned int attempts, double timeout,
    01280                                          const GroupStateValidityCallbackFn& constraint,
    01281                                          const kinematics::KinematicsQueryOptions& options)
    01282 {
    01283   const kinematics::KinematicsBaseConstPtr& solver = jmg->getSolverInstance();
    01284   if (!solver)
    01285   {
    01286     logError("No kinematics solver instantiated for group '%s'", jmg->getName().c_str());
    01287     return false;
    01288   }
    01289   return setFromIK(jmg, pose, solver->getTipFrame(), attempts, timeout, constraint, options);
    01290 }
    01291 

    JointModelGroup은 moveit setup assistanct가 설정하는 듯 한데, 어떻게 설정하는지 정확하게 설명되어 있지 않았다. moveit setup assistant로 설정할 때 kinematics solver를 선택하는 항목이 있는데, 나는 제대로 선택했는데 문제가 있다.

    제공된 panda_arm 예제가 어떻게 돌아가는지 다시 살펴 보기로 했다. moveit2_tutorial에 panda_arm으로 제공된 항목을 찾아 move_group에 해당하는 부분을 launch 했다. moveit2_tutorial을 설치하면 moveit_resources에 panda_move_config가 있는데 여기 demo.launch.py를 실행해 보았다.

    root@rygen3600:/home/ros2_test#ros2 launch moveit_resources_panda_moveit_config demo.launch.py
    ...
    [move_group-4] [INFO] [1690614580.226886350] [move_group.move_group]: 
    [move_group-4] 
    [move_group-4] ********************************************************
    [move_group-4] * MoveGroup using: 
    [move_group-4] *     - ApplyPlanningSceneService
    [move_group-4] *     - ClearOctomapService
    [move_group-4] *     - CartesianPathService
    [move_group-4] *     - ExecuteTrajectoryAction
    [move_group-4] *     - GetPlanningSceneService
    [move_group-4] *     - KinematicsService
    [move_group-4] *     - MoveAction
    [move_group-4] *     - MotionPlanService
    [move_group-4] *     - QueryPlannersService
    [move_group-4] *     - StateValidationService
    [move_group-4] ********************************************************
    [move_group-4] 

    parameter가 어떻게 제공되는지 알아보기 위해 param list를 확인해 보고, 의심되는 kinematics_solver 값을 확인했다. robot_description에 solver를 설정할 수 있는데, moveit setup assistant가 설정한 값으로 동작하고 있다.

    root@rygen3600:/home/ros2_test/src/hello_moveit/debug# ros2 param get /move_group robot_description_kinematics.panda_arm.kinematics_solver
    String value is: kdl_kinematics_plugin/KDLKinematicsPlugin

    내가 만든 ABB 로봇은 해당 node가 없다. 이제 문제가 무엇인지 알았다. launch할 때 해당 값을 넣어줘야 하는데, 내가 빼먹고 넣어주지 않았다. 이제 panda_arm demo 파일을 보고, 어떻게 설정해야 하는지 알아봐야 한다.

    panda demo를 자세히 보니, 노드를 만들어서 robot_description에 kinematics를 설정해 주었다. 나는 ros run으로 해당 프로그램만 실행해주어 kinematics_solver가 설정되지 않았다. 아래 형식으로 노드를 만들어 준다.

    root@rygen3600:/home/ros2_test# cat src/hello_moveit/launch/my_demo.launch.py 
    from launch import LaunchDescription
    from launch_ros.actions import Node
    from moveit_configs_utils import MoveItConfigsBuilder
    
    
    def generate_launch_description():
        moveit_config = MoveItConfigsBuilder("hello").to_moveit_configs()
    
        # MoveGroupInterface demo executable
        move_group_demo = Node(
            name="my_move_group_interface",
            package="hello_moveit",
            executable="planning",
            output="screen",
            parameters=[
                moveit_config.robot_description,
                moveit_config.robot_description_semantic,
                moveit_config.robot_description_kinematics,
            ],
        )
    
        return LaunchDescription([move_group_demo])
    

    이제 새로운 문제가 있다. orientation constraint를 설정하면 로봇이 제대로 움직이지 않는다. interactive marker는 쉽게 planning 하는데, 프로그램으로 하면 짧은 거리도 planning이 높은 확율로 실패한다.

  • docker 내부 gazebo를 원격으로 실행

    그래픽 드라이버가 있는 PC를 거실로 옮기고, TV에 연결해서 사용했다. 사용할 때는 좋은데, 원격으로 터미널로 접속하여 gazebo를 실행하기 어려웠다.

    172.30.1.71

    • 저사양 PC로 인터넷 겨우 됨.

    172.30.1.9

    • 내부 nvidia 그래픽 카드 설치로 무거운 PC
    • 소음 발열 심함.
    • docker로 172.17.0.1로 gazebo를 실행.

    목표는 172.30.1.71 pc로 ssh 터미널로 172.30.1.9에 접속한 뒤 docker로 실행중인 gazebo를 172.30.1.71 화면으로 띄우기다.

    172.30.1.9에서 sshd_config를 다음과 같이 설정한다.

    $cat /etc/ssh/sshd_config
    ...
    #AllowAgentForwarding yes
    #AllowTcpForwarding yes
    #GatewayPorts no
    X11Forwarding yes
    X11DisplayOffset 10
    X11UseLocalhost  yes
    ...

    X11UseLocalhost no로 설정하면 xauth add 명령어가 실행되지 않는다.

    172.30.1.71에서 ssh로 172.30.1.9로 접속한다.

    $ cat ~/.ssh/config 
    
    Host rygen3600
    	Hostname 172.30.1.9
    	ForwardX11 yes

    docker container를 다음 옵션으로 실행한다.

    nvidia-docker run -it -v /run/user/1000:/run/user/1000 -v /dev:/dev -v /tmp/.X11-unix:/tmp/.X11-unix:ro \
      -v /home/now0930/ros2/test:/home/ros2_test --name foxy\
      --privileged --ipc=host --shm-size=512m --net=host -e DISPLAY=$DISPLAY \
      -e XDG_RUNTIME_DIR=/run/user/1000 --runtime=nvidia \
      osrf/ros:foxy-desktop-custom

    docker container에 접속하여 gazebo를 실행하면

    x11 connection rejected because of wrong authentication.

    에러가 뜬다. docker 외부 계정의 ~/.Xauthority 파일을 docker container root에 복사하면 gazebo가 실행된다.

    빈 화면인데 22 프레임이 나온다.