본문으로 바로가기

렌틴 조셉의 좋은 소스코드를 만나 Pan/Tilt를 표현하는 URDF와 이를 이용해서 RViz로 시각화하는 예제[바로가기]를 따라해보았었는데요. 그 때 사용한 Pan/Tilt 예제에서 한 발짝 더 가서 Gazebo라는 아이를 이용해서 움직여보기도 할려고 합니다.^^ 뭐 언제나 그렇듯 그저그저 따라하기 수준이지요^^

일단~~~ 지난번[바로가기] 예제에서 몇몇 내용을 추가하거나 바꿔서 시도해볼려구요~~

일단... 폴더 config를 추가하고 거기엔 pan_tilt_control.yaml, 기존의 launch 폴더에는 gazebo_pan_tilt.launch, pan_tilt_gazebo_control.launch를 추가하고, urdf에 있는 pan_tilt.xacro는 수정할 예정입니다. 먼저... pan_tilt.xacro는 

<?xml version="1.0"?>

<robot xmlns:xacro="http://www.ros.org/wiki/xacro" 
    xmlns:sensor="http://playerstage.sourceforge.net/gazebo/xmlschema/#sensor"
    xmlns:controller="http://playerstage.sourceforge.net/gazebo/xmlschema/#controller"
    xmlns:interface="http://playerstage.sourceforge.net/gazebo/xmlschema/#interface"
    name="ex_urdf_pan_tilt">
    

    <xacro:property name="base_link_length" value="0.01" />
    <xacro:property name="base_link_radius" value="0.2" />

    <xacro:property name="pan_link_length" value="0.4" />
    <xacro:property name="pan_link_radius" value="0.04" />

    <xacro:property name="tilt_link_length" value="0.4" />
    <xacro:property name="tilt_link_radius" value="0.04" />


    <xacro:macro name="inertial_matrix" params="mass">
               <inertial>
                       <mass value="${mass}" />
                       <inertia ixx="1." ixy="0.0" ixz="0.0"
                                iyy="1." iyz="0.0"
                                izz="1." />
               </inertial>
    </xacro:macro>

   <xacro:macro name="transmission_block" params="joint_name">
    <transmission name="tran1">
      <type>transmission_interface/SimpleTransmission</type>
      <joint name="${joint_name}">
        <hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
      </joint>
      <actuator name="motor1">
        <hardwareInterface>hardware_interface/PositionJointInterface</hardwareInterface>
        <mechanicalReduction>1</mechanicalReduction>
      </actuator>
    </transmission>
   </xacro:macro>


  <link name="base_link">

    <visual>
      <geometry>
         <cylinder length="${base_link_length}" radius="${base_link_radius}"/>
      </geometry>
      <origin rpy="0 0 0" xyz="0 0 0"/>
      <material name="yellow">
        <color rgba="1 1 0 1"/>
      </material>
    </visual>

    <collision>
      <geometry>
         <cylinder length="${base_link_length+0.02}" radius="0.2"/>
      </geometry>
      <origin rpy="0 0 0" xyz="0 0 0"/>
    </collision>
    <xacro:inertial_matrix mass="1"/>
  </link>

  <gazebo reference="base_link">
    <material>Gazebo/Black</material>
  </gazebo>

  <joint name="pan_joint" type="revolute">
    <parent link="base_link"/>
    <child link="pan_link"/>
    <origin xyz="0 0 0.1"/>
    <axis xyz="0 0 1" />
    <limit effort="300" velocity="0.1" lower="-3.14" upper="3.14"/>
    <dynamics damping="50" friction="1"/>
  </joint>

  <link name="pan_link">
    <visual>
      <geometry>
         <cylinder length="${pan_link_length}" radius="${pan_link_radius}"/>
      </geometry>
      <origin rpy="0 0 0" xyz="0 0 0.09"/>
      <material name="red">
        <color rgba="0 0 1 1"/>
      </material>
    </visual>
    <collision>
      <geometry>
         <cylinder length="${pan_link_length}" radius="${pan_link_radius+0.02}"/>
      </geometry>
      <origin rpy="0 0 0" xyz="0 0 0.09"/>
    </collision>
    <xacro:inertial_matrix mass="1"/>
  </link>

  <gazebo reference="pan_link">
    <material>Gazebo/Blue</material>
  </gazebo>

  <joint name="tilt_joint" type="revolute">
    <parent link="pan_link"/>
    <child link="tilt_link"/>
    <origin xyz="0 0 0.2"/>
    <axis xyz="0 1 0" />
    <limit effort="300" velocity="0.1" lower="-4.71239" upper="-1.570796"/>
    <dynamics damping="50" friction="1"/>
  </joint>

  <link name="tilt_link">
    <visual>
      <geometry>
         <cylinder length="${tilt_link_length}" radius="${tilt_link_radius}"/>
      </geometry>
      <!-- <origin rpy="0 1.570796 0" xyz="0 0 0"/> -->
      <origin rpy="0 0 0" xyz="0 0 0"/>
      <material name="green">
        <color rgba="1 0 0 1"/>
      </material>
    </visual>
    <collision>
      <geometry>
         <cylinder length="${tilt_link_length}" radius="${tilt_link_radius+0.2}"/>
      </geometry>
      <!-- <origin rpy="0 1.570796 0" xyz="0 0 0"/> -->
      <origin rpy="0 0 0" xyz="0 0 0"/>
    </collision>
    <xacro:inertial_matrix mass="1"/>
  </link>

  <gazebo reference="tilt_link">
    <material>Gazebo/Red</material>
  </gazebo>

   <xacro:transmission_block joint_name="pan_joint"/>
   <xacro:transmission_block joint_name="tilt_joint"/>

  <gazebo>
    <plugin name="gazebo_ros_control" filename="libgazebo_ros_control.so">
      <robotNamespace>/ex_urdf_pan_tilt</robotNamespace>
    </plugin>
  </gazebo>


</robot>

와 같이 구성합니다.. 구동되는 joint를 transmission으로 지정하고 움직이는 hardware는 심플하게 잡습니다. 그리고, link의 색상들을 지정하고, gazebo_ros_control을 사용하도록 합니다.^^

<launch>

  <!-- these are the arguments you can pass this launch file, for example paused:=true -->
  <arg name="paused" default="false"/>
  <arg name="use_sim_time" default="true"/>
  <arg name="gui" default="true"/>
  <arg name="headless" default="false"/>
  <arg name="debug" default="false"/>

  <!-- We resume the logic in empty_world.launch -->
  <include file="$(find gazebo_ros)/launch/empty_world.launch">
    <arg name="debug" value="$(arg debug)" />
    <arg name="gui" value="$(arg gui)" />
    <arg name="paused" value="$(arg paused)"/>
    <arg name="use_sim_time" value="$(arg use_sim_time)"/>
    <arg name="headless" value="$(arg headless)"/>
  </include>

  <!-- Load the URDF into the ROS Parameter Server -->
  <param name="robot_description" command="$(find xacro)/xacro --inorder '$(find ex_urdf)/urdf/pan_tilt.xacro'" /> 

  <!-- Run a python script to the send a service call to gazebo_ros to spawn a URDF robot -->
  <node name="urdf_spawner" pkg="gazebo_ros" type="spawn_model" respawn="false" output="screen"
    args="-urdf -model ex_urdf_pan_tilt -param robot_description"/> 


</launch>

그리고 gazebo_pan_tilt.launch를 구성합니다. 

<launch>
  <!-- Launch Gazebo  -->
  <include file="$(find ex_urdf)/launch/gazebo_pan_tilt.launch" />   

  <!-- Load joint controller configurations from YAML file to parameter server -->
  <rosparam file="$(find ex_urdf)/config/pan_tilt_control.yaml" command="load"/>

  <!-- load the controllers -->
  <node name="controller_spawner" pkg="controller_manager" type="spawner" respawn="false"
    output="screen" ns="/ex_urdf_pan_tilt" args="joint_state_controller
                      joint1_position_controller
                      joint2_position_controller"/>

  <!-- convert joint states to TF transforms for rviz, etc -->
  <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher"
    respawn="false" output="screen">
    <remap from="/joint_states" to="/ex_urdf_pan_tilt/joint_states" />
  </node>

</launch>

그걸 이용해서 pan_tilt_gazebo_control.launch에서 각 조인트를 움직일 수 있는 부분을 추가합니다. 여기서 rosparam에서 사용할려는 pan_tilt_control.yaml은

ex_urdf_pan_tilt:
  # Publish all joint states -----------------------------------
  joint_state_controller:
    type: joint_state_controller/JointStateController
    publish_rate: 50  
  
  # Position Controllers ---------------------------------------
  joint1_position_controller:
    type: position_controllers/JointPositionController
    joint: pan_joint
    pid: {p: 100.0, i: 0.01, d: 10.0}
  joint2_position_controller:
    type: position_controllers/JointPositionController
    joint: tilt_joint
    pid: {p: 100.0, i: 0.01, d: 10.0}

이렇게 구성됩니다.^^

이제... roslaunch 명령으로 gazebo_pan_tilt.launch만 실행하면 위 그림처럼 gazebo가 실행됩니다.^^ 이제 다시~~ pan_tilt_gazebo.launch를 roslaunch로 실행한 후

위 그림처럼 rostopic list를 보면 joint1_position_controller라는 아이가 보입니다....

위 명령처럼 실행하면 살짝~ gazebo의 pan_tilt가 움직이는 것이 보이실 겁니다.^^



댓글을 달아 주세요

  1. BlogIcon 핑구야 날자 2017.03.30 07:28 신고

    오늘도 잘 보고 갑니다 미세 먼지가 많으니 조심하세요

  2. ROS정복 2017.04.20 16:56

    ostopic list를 보면 joint1_position_controller라는 아이가 저는 보이지 않네요 ㅠㅠ 왜그럴까요?

    /clock
    /gazebo/link_states
    /gazebo/model_states
    /gazebo/parameter_descriptions
    /gazebo/parameter_updates
    /gazebo/set_link_state
    /gazebo/set_model_state
    /joint_states
    /rosout
    /rosout_agg

    • BlogIcon PinkWink 2017.04.20 19:05 신고

      http://wiki.ros.org/ros_control
      혹시.. ros_control이 설치되어 있나요?

    • ROS정복 2017.04.21 11:18

      깔았는데도 position_controller 라는 아이가 안보이네요 ㅠㅠ

    • BlogIcon PinkWink 2017.04.21 17:35 신고

      흠.. 잘 모르겠네요.ㅠㅠ. (도움이 되지를 못하네요...)

    • acacia13 2017.08.18 22:22

      roslaunch ex_urdf pan_tilt_gazebo_control.launch로 실행할 경우 gazebo까지 잘 실행되나 joint1_position_controller가 안보이고,
      본문대로 roslaunch ex_urdf_pan_tilt pan_tilt_gazebo_control.launch 로 실행할 경우 ex_urdf_pan_tilt 패키지 네임이 없다고 하네요...

    • BlogIcon PinkWink 2017.08.20 00:26 신고

      혹시 source devel/setup.bash를 실행해보고 시도해 보셨나요?

    • acacia13 2017.08.25 13:27

      넹 그거는 해봤어용
      혹시 몰라서 워크스페이스 디렉토리에서 catkin_make도 다시 돌려보고 해도 그대로였어요...

    • BlogIcon PinkWink 2017.08.25 14:57 신고

      아 그리고 joint1_position_controller도 찾아서 설치(다운로드)하셔야 하는데 하셨나요?

  3. 2018.03.13 09:49

    비밀댓글입니다

  4. BlogIcon Jacob 2018.11.14 16:15

    안녕하세요. 덕분에 쉽게 가제보로 pan/tilt 제어를 해봤어요.
    감사합니다.

    'ROS 정복'님이 막힌 부분에서 저도 안됐는데
    몇개 패키지를 설치하면 됩니다.

    sudo apt install ros-kinetic-gazebo-ros-control

    sudo apt-get install ros-kinetic-position-controllers



    저도 따라서 한 거 관련으로 정리를 해서 제 홈페이지에 올려보려고요.
    저는 추가적으로 xtion 센서를 부착하고, 최종 목표로는 moveit으로 제어하는 것을 생각하고 있습니다.


    질문이 하나 있는데

    1. 실제 모터에 이것을 적용하기 위해서는 어떤 정보가 필요한지 궁금합니다. (현재 모터의 각도, 속도, 모터에 특정 각도로 회전하라는 명령)
    Servo motor면 가능한건가요? (3줄 짜리, 위치 명령만 내리는)
    로보티즈의 다이나믹셀 모터같은 류만 사용가능한가요?
    아니면 모터에 엔코더를 달아서 직접 정보를 만들어서 ROS쪽에 보내야할까요?


    감사합니다.

  5. BlogIcon Jacob 2018.11.14 16:36

    제가 좀 검색좀 해봤는데

    https://github.com/ros-controls/ros_control/wiki/hardware_interface

    http://gazebosim.org/tutorials/?tut=ros_control

    모터의 pos,vel,effort를 읽을 수 있어야 하며, cmd 모터 명령을 내릴 수 있어야 한다고 하는군요.

    • BlogIcon PinkWink 2018.11.15 20:23 신고

      일단, 제 개인적 의견으론 확실히 다이나믹셀일듯해요 시작은 그렇게^^.

    • Jacob 2018.11.16 00:44

      안녕하세요.

      답변 감사합니다.
      다이나믹셀이 제일 쉽게 해볼 수 있을 것같습니다.

      ---

      핑크님 글로 공부하고, ros_control을 활용해서 pan과 tilt를 제어해봤습니다.

      https://passionbull.net/2018/11/robot/ros-pan-tilt-study/

      감사합니다.

    • BlogIcon PinkWink 2018.11.19 23:49 신고

      우와 멋집니다. 저도 요즘 ROS를 다시 공부하기 시작했답니다. ^^

  6. ikjunerd 2020.08.21 16:06

    정말 감사합니다. 덕분에 쉽게 가제보 모델링 했어요 ~!