Let’s go!

  • 22회 2, 3회 리뷰

    • 상과 선 수에 따른 전압강하 계산
    • 철손, 동손, 출력이 주어졌을 경우, 변압기 효율
    • 역률에 따른 전압 강하
  • 22년 1회 리뷰

    주요 키워드

    • XOR과 XNOR을 구분할 수 있는지?
    • NAND 게이트를 NOR 게이트로 변경할 수 있는지?
    • 네트웍 변압기 사용 조건
    • 단락 전류 = 3WCE를 어떻게 유도
    • 변압기 결선에 따른 극성 변화
    • 공칭 전압이 주어졌을 경우, 최대 전압은 차단기 최대 사용 전압과 일치
    • 영상, 정상, 역상이 주어졌을 경우, A, B, C상을 구할 수 있는지? 23년 2회 기출.
    • A, B, C상이 주어졌을 경우, 영상, 정상, 역상을 구할 수 있는지?
    • 역률이 주어졌을 경우, 전압 변동율을 계산할 수 있는지?
    • 진상, 지상을 알고 있는지?
  • ros2 moveit TF 표시

    ros2 moveit TF 표시

    moveit_setup_assistant를 사용하면 대상이 되는 package에서 urdf를 추출한 다음, 필요한 설정 파일을 만든 후 package+moveit_config 디렉토리에 생성한 파일을 저장한다. lanch 디렉토리에 demo.launch.py 파일이 있는데, 코드에는 별 내용은 없고, 같은 디렉토리 launch 파일들을 실행한다. 최소한 어느 부분을 실행해야 rviz에서 로봇이 제대로 보일지 궁금했다

    demo.launch.py 파일이 다음을 실행한다.

    • static_virtual_joint_tfs
    • robot_state_publisher
    • move_group
    • rviz
    • ros2_contol_node + controller spawners

    robot_state_publisher만 실행하면 로봇이 정확하게 보일 줄 알았다. robot_state_publisher가 입력으로 robot_description을 받아들이고, TF는 robot_description에 있는 링크, 조인트 관계만 읽어들여 알아낼 줄 알았다. move_group은 path를 찾을 때 사용하므로 당장 필요해 보이지 않았다.

    from launch import LaunchDescription
    from moveit_configs_utils import MoveItConfigsBuilder
    from launch_ros.actions import Node
    from moveit_configs_utils.launches import generate_rsp_launch, generate_moveit_rviz_launch
    from launch.actions import (
            DeclareLaunchArgument,
            IncludeLaunchDescription,
            )
    from launch.substitutions import LaunchConfiguration
    import os
    from ament_index_python.packages import get_package_share_directory
    from launch.launch_description_sources import PythonLaunchDescriptionSource
    
    
    def generate_launch_description():
        moveit_config = MoveItConfigsBuilder("abb_irb2400", package_name="hello_moveit_config").to_moveit_configs()
        #dict2 = moveit_config.to_dict()
        #for key, val in (dict2.items()):
        #    print(key, ":", val) 
        ld = LaunchDescription()
        ld.add_action(DeclareLaunchArgument("publish_frequency", default_value="15.0"))
    
        rsp_node = Node(
                name = "rsp_node",
                executable = "robot_state_publisher",
                #prefix = "xterm -e gdb run --args",
                package = "robot_state_publisher",
                output = "both",
                respawn = True,
                #namespace = 'my_robot',
                parameters=[
                    moveit_config.robot_description,
                    {
                        "publish_frequency": LaunchConfiguration("publish_frequency"),
                        },
                    #moveit_config.robot_description_semantic,
                    #moveit_config.robot_description_kinematics,
                    ],
                )
        ld.add_action(rsp_node)
        return ld

    launch를 실행하면 tf가 제대로 표시되지 않는다. tf_static은 정확하게 표시된다.

    root@rygen3600:/home/ros2_test/ws_root/ws_user# ros2 topic list 
    /attached_collision_object
    /clicked_point
    /display_planned_path
    /goal_pose
    /initialpose
    /joint_states
    /parameter_events
    /planning_scene
    /planning_scene_world
    /recognized_object_array
    /robot_description
    /rosout
    /rviz_moveit_motion_planning_display/robot_interaction_interactive_marker_topic/feedback
    /rviz_moveit_motion_planning_display/robot_interaction_interactive_marker_topic/update
    /tf
    /tf_static
    /trajectory_execution_event
    /visualization_marker_array
    root@rygen3600:/home/ros2_test/ws_root/ws_user# ros2 topic echo /tf
    
    
    ^Croot@rygen3600:/home/ros2_test/ws_root/ws_user# ros2 topic echo /tf_static 
    transforms:
    - header:
        stamp:
          sec: 1691830604
          nanosec: 3856748
        frame_id: base_link
      child_frame_id: base
      transform:
        translation:
          x: 0.0
          y: 0.0
          z: 0.0
        rotation:
          x: 0.0
          y: 0.0
          z: 0.0
          w: 1.0
    - header:
        stamp:
          sec: 1691830604
          nanosec: 3856748
        frame_id: link_6
      child_frame_id: tool0
      transform:
        translation:
          x: 0.0
          y: 0.0
          z: 0.0
        rotation:
          x: 0.0
          y: 0.0
          z: 0.0
          w: 1.0
    ---
    

    왜 이런지 한참 고민하다, 결국 control node와 controller spawner가 실행되어야 TF가 제대로 표시됨을 알았다.

    root@rygen3600:/home/ros2_test/ws_root/ws_user# ros2 topic echo /tf
    ...
    - header:
        stamp:
          sec: 1691830991
          nanosec: 709634293
        frame_id: base_link
      child_frame_id: link_1
      transform:
        translation:
          x: 0.0
          y: 0.0
          z: 0.0
        rotation:
          x: 0.0
          y: 0.0
          z: 0.0
          w: 1.0
    - header:
        stamp:
          sec: 1691830991
          nanosec: 709634293
        frame_id: link_1
      child_frame_id: link_2
      transform:
        translation:
          x: 0.1
          y: 0.0
          z: 0.615
        rotation:
          x: 0.0
          y: 0.0
          z: 0.0
          w: 1.0
    - header:
        stamp:
          sec: 1691830991
          nanosec: 709634293
        frame_id: link_2
      child_frame_id: link_3
      transform:
        translation:
          x: 0.0
          y: 0.0
          z: 0.705
        rotation:
          x: 0.0
          y: 0.0
          z: 0.0
          w: 1.0
    

    최소 2개 node가 필요하다. robot_state_publisher와 controller node.이거 알아낸다고 별 짓을 다했다. 다수 로봇을 처리하려면 namespace로 할당하여 불러야 할텐데, 잘 안된다.

  • 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 기본 사용법은 여기 정리되어 있다.