.. Cover Letter

공부#Robotics#자율주행/(ROS2)주행로봇

URDF, XACRO 마스터 하기 ! (ADDBOT Rviz에서 구현하기) (1/2)

BrainKimDu 2023. 2. 6. 20:55

이 글은 pinkLab의 pinkwink강사님의 강의자료를 참고하여 작성되었습니다.
https://pinkwink.kr/

 

PinkWink

한 변두리 공학도의 블로그입니다. 재미있어 보이는 것들을 모두 기초스럽게 접근하는 블로그이며... 그보다 더욱 소중한 우리 아가 미바뤼의 발자취를 남겨두는 블로그이기도 합니다.

pinkwink.kr


다음의 과제가 주어졌습니다.

다음의 로봇(ADDBOT)에 대한 meshes 파일을 줄테니

urdf를 이용해서 이대로 만들어주시고, rviz에 띄워주세요.

이런식으로..



아 그리고 작성하는 시점부터 galactic의 지원이 종료되어
22.04 humble로 올라온 상태입니다.
다른 글이지만
https://kimbrain.tistory.com/entry/3-%EC%9A%B0%EB%B6%84%ED%88%AC-2204%EC%97%90-ROS2-Humble-%EC%84%A4%EC%B9%98%ED%95%98%EA%B3%A0-rviz%EC%99%80-gazebo%EA%B9%8C%EC%A7%80-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0

 

3. 우분투 22.04에 ROS2 Humble 설치하고 rviz와 gazebo까지 설치하기

https://docs.ros.org/en/humble/Installation.html Installation — ROS 2 Documentation: Humble documentation Binary packages Binaries are only created for the Tier 1 operating systems listed in REP-2000. Given the nature of Rolling, this list may be updated

kimbrain.tistory.com


여기를 가시면 humble을 설치하실 수 있습니다.



일단 이를 진행하기 위해서는 패키지를 우선 만들어야합니다.
패키지부터 만들도록 하죠.

urdf 마스터하기 라는 이름 그대로
urdf_master 라는 ws를 하나 만들어줍시다.

mkdir urdf_master
cd urdf_master
mkdir src
cd src


이 상태에서

ros2 pkg create --build-type ament_cmake Addbot_description

패키지를 만드는 명령어로 패키지를 하나 만듭시다.


안뜨면 당황하지 말고 ros환경을 불러옵니다.
bashrc에 다음을 등록해놓았습니다.

alias humble="source /opt/ros/humble/setup.bash; ros_domain; echo \"ROS2 Humble is activated.\""
source /opt/ros/humble/setup.bash

여튼 이 명령어입니다.
저는 humble입니다.
환경을 불러오는걸 모르겠다 하시면 조금만 밑으로 내리세요.


일단 컴파일이 끝나면 다음처럼 뜨게됩니다.


naming 규칙이 있는가 봅니다. 다음부터 지키면 되죠..

(작성하는 지금은 Addbot으로 수정되었습니다.)

gedit ~/.bashrc

bashrc를 열어서 환경을 새로 등록해줍시다.
어.. 저는 VScode보다는 gedit이 편한거 같아요. 빨리열려서 좋네요.

다음을 입력합니다.

alias urdfmaster="humble; source ~/urdf_master/install/local_setup.bash; echo \"urdf_master workspace is activated.\""


다음부터 이 환경을 불러올 수 있게됩니다.


이제 파일을 수정해야합니다.
다시 src에서 패키지 안으로 들어옵니다.


launch 와 rviz 그리고 urdf 폴더를 만든 상태에서 code .으로 VSCode를 실행합니다.

그리고 과제를 위해 받은

해당 파일을 ADDBOT_description에 옮깁니다.
이런 느낌으로 생긴 파일입니다.

visual에는

collision에는

다음의 파일들이 들어있습니다.
그러면 이런느낌쓰로 만들어져 있으면 됩니다.



이제 이상태에서

우선 CMakeList.txt를 수정합시다.

install(
  DIRECTORY
    launch
    meshes
    rviz
    urdf
  DESTINATION share/${PROJECT_NAME}
)

다음을 추가합니다.




package.xml에는 다음을 추가합니다.

  <depend>xacro</depend>
  <depend>joint_state_publisher</depend>
  <depend>joint_state_publisher_gui</depend>
  <depend>robot_state_publisher</depend>


이런 느낌입니다.

그러나 저는 pinkLab의 pinkWink님의 강의자료를 참고하고 있으니 라이센스 부분을 수정합니다.





launch 폴더에
view_robot.launch.py 파일을 하나 만듭니다.
보통 여기까지는 파일을 가져온다고 합니다.

import os
from os import environ

from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument, Shutdown
from launch.substitutions import PathJoinSubstitution, Command, LaunchConfiguration
from launch_ros.substitutions import FindPackageShare
from launch_ros.actions import Node

def generate_launch_description():
    ld = LaunchDescription()

    environ['QT_AUTO_SCREEN_SCALE_FACTOR'] = '0'
    rviz_config_file = PathJoinSubstitution([
        FindPackageShare('Addbot_description'),
        'rviz',
        'view_robot.rviz'
        # 안해도 오류는 없는데, 저장된 설정을 가져옵니다. 이런 느낌이다.
    ])

    rviz_node = Node(
        package='rviz2',
        executable='rviz2',
        name='rviz2',
        output='screen',
        arguments=['-d', rviz_config_file],
        on_exit=Shutdown()
    )

    rsp_node = Node(
    # sudo apt install ros-humble-robot-state-publisher라는 패키지
    # 반드시 있어야하며, urdf를 입력받아야한다.
        package='robot_state_publisher',
        executable='robot_state_publisher',
        name='robot_state_publisher',
        output='screen',
        parameters=[{
            'ignore_timestamp': False,
            'robot_description':
                Command([
                    'xacro ',
                    PathJoinSubstitution([
                        FindPackageShare('Addbot_description'),
                        'urdf',
                        'Addbot.urdf.xacro',
                    ]),
                ]),
        }]
    )

    jsp_gui_node = Node(
        package='joint_state_publisher_gui',
        executable='joint_state_publisher_gui',
        name='joint_state_publisher',
        output='screen'
    )

	#rviz에서 urdf를 보고 싶으니 추가를 한다고 이해
    ld.add_action(rviz_node)
    ld.add_action(rsp_node)
    ld.add_action(jsp_gui_node)

    return ld



그리고 미리 계산되어있는 이너샤(관성)를 추가하자.
있으면 편하다고 하시니 일단 올리긴 합니다..
urdf에
common이라는 폴더를 만들고
inertia_macro.urdf.xacro 를 만들자.

<?xml version="1.0"?>
<robot xmlns:xacro="http://wiki.ros.org/xacro">
    <xacro:macro name="cylinder_inertia" params="m r h">
        <inertia ixx="${m*(3*r*r+h*h)/12}" ixy="0" ixz="0" iyy="${m*(3*r*r+h*h)/12}" iyz="0" izz="${m*r*r/2}" />
    </xacro:macro>

    <xacro:macro name="box_inertia" params="m x y z">
        <inertia ixx="${m*(y*y+z*z)/12}" ixy="0" ixz="0" iyy="${m*(x*x+z*z)/12}" iyz="0" izz="${m*(x*x+y*y)/12}" />
    </xacro:macro>

    <xacro:macro name="sphere_inertia" params="m r">
        <inertia ixx="${2*m*r*r/5}" ixy="0" ixz="0" iyy="${2*m*r*r/5}" iyz="0" izz="${2*m*r*r/5}" />
    </xacro:macro>
</robot>


이제 준비작업은 모두 끝났습니다..
이대로 빌드를 한 번 하고 진행하도록하겠습니다..

이름을 좀더 잘지을걸

뭐 여튼 기초공사가 마무리된 상태
여기서까지 구축되면 urdf정도는 손쉽게 만들어 줄 수 있습니다.


그전에 xacro에 대해 알 필요가 있습니다..
URDF를 보완한 친구다. 변수라는 개념을 추가할 수 있고, 다른 xacro를 포함할 수 있습니다.

<!-- This is a comment in Xacro -->

여기 안에 들어간 내용은 모두 주석이라고 생각하면됩니다.
그러니 코드에 주석을 달아놓으면 잘 보세요.


우선은 urdf폴더에서 ADDBOT_urdf.xacro라는 파일을 하나 만듭니다.
이 친구가 메인 뼈대를 담당하는 친구가 될 것입니다.

시작합시다.

urdf 를 왜 쓸까요? -> TF(좌표)를 해석하기 위해서 사용합니다.
즉 주행로봇의 좌표가 필요합니다.

만약 급하다면 크기가 비슷한 원통형으로 설정해도 됩니다.
가제보에서 충돌(collision)을 봐야하기 때문입니다.

우선은 base_footprint라는 놈부터 시작합니다.

그러면 3가지를 먼저 그리게 됩니다.
base_footprint와 base_link
그려봅시다.
그리고 이 둘의 관절 base_link_fixed_joint 를 추가합시다.

총 3개의 값이 들어갑니다.
보이는값, 충돌, 이너샤




<?xml version="1.0"?>
<robot name="ADDbot" xmlns:xacro="http://www.ros.org/wiki/xacro">
    <xacro:property name="wheel_diameter" value="0.068"/>
    <xacro:property name="wheel_speration" value="0.180"/>
    <!-- 가장 상위의 footprint  -->
    <link name="base_footprint"/>
    <!-- base_link  -->
    <link name="base_link">
        <visual>
        <!-- 원점의 위치로 정의합니다.  -->
            <origin xyz="0 0 0" rpy="0 0 0"/>
            <geometry>
                <!-- meshes에서 visual 파일을 불러온다. -->
                <mesh filename="package://ADDBOT_description/meshes/visual/base_link.dae" scale="1 1 1"/>
            </geometry>
        </visual>
        <collision>
            <origin xyz="0 0 0" rpy="0 0 0"/>
            <geometry>
                <!-- meshes에서 collision 파일을 불러온다. -->
                <mesh filename="package://ADDBOT_description/meshes/collision/base_link.stl" scale="1 1 1"/>
            </geometry>
        </collision>
        <inertial>
            <!-- 관성에 대한 표시 위치는 임의로 지정한 것인가? 실행을 해봐야 알 것 같다. -->
            <origin xyz="-0.02 0 0.028" rpy="0 0 0"/>
            <mass value="2.0"/>
            <inertia ixx="0.000213" ixy="0" ixz="0" iyy="0.007034" iyz="0" izz="0.008104"/>
            <!--<inertia ixx="0.01" ixy="0" ixz="0" iyy="0.01" iyz="0" izz="0.01"/> -->
        </inertial>
    </link>

    <joint name="base_link_fixed_joint" type="fixed">
            <parent link="base_footprint"/>
            <child link="base_link"/>
            <origin xyz="0 0 ${wheel_diameter/2}" rpy="0 0 0"/>
    </joint>


</robot>


일단 여까지 하고 빌드하고 실행해봅시다.
질문으로 남겨두었고 내일 해결을 하겠지만 왜
joint를 제거하면 실행이 안될까요? 이부분은 질문을 하고 적도록 하겠습니다.


(답변 : base_link 를 가장 신경써야한다. 두바퀴의 중심에 구성을 한다. x, y : 바퀴 중심의 중심 , base_footprint : base_link[:, :, 0] 로 본다.
둘은 중첩되서 보인다.
(그다음은 베이스로부터 카메라와 라이다 위치가 중요, 사이즈) (편집됨) 
(TF에서는 조인트의 오리진이 제일 중요함 , 베이스링크의 x좦와 왼쪽 오른쪽 휠이 같은 방향을 봐야한다.  링크의 오리진을 수전하면된다.)
링크와 링크 사이에는 무조건 조인트가 들어간다.
 
r  (roll) : X축을 중심으로 도는 회전p (pitch) : y축을 중심으로 도는 회전y (yaw) : z축을 중심으로 도는 회전
 
 
colcon build
urdfmaster
ros2 launch Addbot_description view_robot.launch.py

일단 몸체를 로딩완료 했습니다.




혹시 나오지 않는다면 왼쪽에 있는 설정을 그대로 따라하시면됩니다.


add에서 TF를 선택한 경우 다음처럼 나오게 됩니다.
겹처보이니 다시 진행합시다.

<?xml version="1.0"?>
<robot name="ADDbot" xmlns:xacro="http://www.ros.org/wiki/xacro">
    <xacro:property name="wheel_diameter" value="0.068"/>
    <xacro:property name="wheel_speration" value="0.180"/>
    <!-- 가장 상위의 footprint  -->
    <link name="base_footprint"/>
    <!-- base_link  -->
    <link name="base_link">
        <visual>
        <!-- 원점의 위치로 정의합니다.  -->
            <origin xyz="0 0 0" rpy="0 0 0"/>
            <geometry>
                <!-- meshes에서 visual 파일을 불러온다. -->
                <mesh filename="package://ADDBOT_description/meshes/visual/base_link.dae" scale="1 1 1"/>
            </geometry>
        </visual>
        <collision>
            <origin xyz="0 0 0" rpy="0 0 0"/>
            <geometry>
                <!-- meshes에서 collision 파일을 불러온다. -->
                <mesh filename="package://ADDBOT_description/meshes/collision/base_link.stl" scale="1 1 1"/>
            </geometry>
        </collision>
        <inertial>
            <!-- 관성에 대한 표시 위치는 임의로 지정한 것인가? 실행을 해봐야 알 것 같다. -->
            <origin xyz="-0.02 0 0.028" rpy="0 0 0"/>
            <mass value="2.0"/>
            <!--<inertia ixx="0.000213" ixy="0" ixz="0" iyy="0.007034" iyz="0" izz="0.008104"/> -->
            <inertia ixx="0.01" ixy="0" ixz="0" iyy="0.01" iyz="0" izz="0.01"/> 
        </inertial>
    </link>

    <joint name="base_link_fixed_joint" type="fixed">
            <parent link="base_footprint"/>
            <child link="base_link"/>
            <origin xyz="-0.3 0 ${wheel_diameter/2}" rpy="0 0 0"/>
            <!-- 수정된 부분 -->
    </joint>


</robot>

 


그림은 이상하지만 거리를 벌릴 수 있었다.



잠깐 여기까지 진행하고 다음 글에서 진행해야할 것같습니다.