로봇 운영체제: ROS Gazebo 플러그인으로 로봇 제어
Gazebo 플러그인은 일반적인 ROS 설치와 함께 번들로 제공됩니다.플러그인은 차속 구동이나 슬라이딩 구동, 카메라, 깊이 카메라, IMU와 같은 센서와 같은 다양한 실행기를 지원한다.플러그인은 내부에서 컨트롤러 노드를 통해 통신하기 때문에 공개할 필요가 없습니다.반대로 그들은 관련 주제를 발표할 것이다. 예를 들어
/cmd_vel
로봇에게 선형과 각도 운동 명령을 보내거나 /odom
이것은 시뮬레이션이 시작된 이래 로봇의 위치를 나타낸다.본고는 가제보 플러그인에 대한 실천 세미나입니다.플러그인의 기능을 이해하게 될 것입니다. ROS2의 diff drive 플러그인을 사용하여 4륜 로봇을 제어하는 방법을 알게 될 것입니다.
이 글은 최초로 나의 블로그admantium.com에 나타났다.
베란다 플러그인
나의 로봇 프로젝트에서 나는 지역 사회의 다른 몇 개의 로봇 프로젝트를 검사했다.나는 왜 일부 항목이 컨트롤러 노드를 생성하지 않았는지 곤혹스러웠지만, 위에서 언급한 주제
/cmd_vel
와 /odom
는 여전히 발표되었다.내 가설은 이 로봇들의 플러그인이 자동으로 컨트롤러를 작동시킨다는 것이다.공식 테라스 파일을 보면 다음과 같은 단락을 찾을 수 있습니다.Previous versions of Gazebo utilized controllers. These behaved in much the same way as plugins but were statically compiled into Gazebo. Plugins are more flexible and allow users to pick and choose what functionality to include in their simulations.
자료 출처: official Gazebo documentation.
플러그인은 plugin development guide 의 약정에 따라 C++ 라이브러리입니다.이 플러그인들은 센서, 시스템, 시각, 세계 등 기본 클래스를 계승하고
Load
함수를 공개한다.다음은 플러그인 개발 안내서의 한 예이다.#include <gazebo/gazebo.hh>
namespace gazebo
{
class WorldPluginTutorial : public WorldPlugin {
public: WorldPluginTutorial() : WorldPlugin() {
printf("Hello World!\n");
}
public: void Load(physics::WorldPtr _world, sdf::ElementPtr _sdf) { }
};
GZ_REGISTER_WORLD_PLUGIN(WorldPluginTutorial)
}
일단 컴파일이 완료되면 플러그인은 로봇의 URDF 모델을 통해 불러와야 한다.<?xml version="1.0"?>
<sdf version="1.4">
<world name="default">
<plugin name="hello_world" filename="libhello_world.so"/>
</world>
</sdf>
미리 만들어진 플러그인을 사용할 때 URDF 모델에 추가하기만 하면 됩니다.ROS2 플러그인
플러그인은 ROS2가 탄생한 이후 꾸준히 변환되고 있습니다.status page에 따르면 카메라 등 각 플러그인이 하나의 소프트웨어 패키지에 통합되었다.참고로, 우리는 우리가 선택한 플러그인을 선택하여 우리의 원형과 호환시킬 수 있습니다.
우리는 로봇의 이동 방식을 제어하고 싶다.플러그인은 차속 구동, 미끄럼 구동, 아크만 구동과 삼륜 등 네 가지 다른 회전 원리를 지원한다.나의 RADU 로봇은 4륜 자동차로 활주 구동으로 제어할 수 있다.따라서
ros_diff_drive
플러그인을 사용할 것입니다.diff drive 플러그인 사용
로봇의 물리적 모형을 사용하는 것 외에 플러그인을 사용하는 것은 수동으로 컨트롤러 노드를 추가하는 것보다 훨씬 간단하다.사실, 당신은
<plugin>
라벨을 추가하기만 하면 됩니다!다음은 완전한 예입니다.
<plugin name="wheel_drive_controller" filename="libgazebo_ros_diff_drive.so">
<!-- wheels -->
<num_wheel_pairs>2</num_wheel_pairs>
<left_joint>base_link_left_wheel_frontside</left_joint>
<left_joint>base_link_left_wheel_backside</left_joint>
<right_joint>base_link_right_wheel_frontside</right_joint>
<right_joint>base_link_right_wheel_backside</right_joint>
<!-- kinematics -->
<wheel_separation>0.4</wheel_separation>
<wheel_diameter>0.1</wheel_diameter>
<max_wheel_torque>20.0</max_wheel_torque>
<max_wheel_acceleration>10.0</max_wheel_acceleration>
<!-- odometry -->
<odometry_source>world</odometry_source>
<odometry_frame>odom</odometry_frame>
<robot_base_frame>base_link</robot_base_frame>
<!-- topic & re remappings -->
<ros>
<namespace>/</namespace>
<argument>/cmd_vel:=cmd_vel</argument>
<argument>/odom:=odom</argument>
</ros>
<publish_odom>true</publish_odom>
<publish_odom_tf>true</publish_odom_tf>
<update_rate>100.0</update_rate>
</plugin>
이 성명은 4개의 구성 블록으로 구성되어 있다.모든 블록의 표시는 반드시 자명해야 하기 때문에 나는 단지 간단하게 설명할 뿐이다.발코니를 가동하고 로봇을 제어하다
로봇 설명에 이 플러그인이 있으면 Gazebo와 Requires 노드를 시작할 수 있습니다.우리는 세 개의 노드인 가즈보, 관절 상태 컨트롤러, 로봇 상태 발표기를 명확하게 가동하고 로봇을 생성해야 한다.마지막으로 플러그인에 추가 컨트롤러 노드를 만듭니다.
다음은 시작 파일입니다.
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.actions import IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch_ros.actions import Node
from time import sleep
import xacro
package_name = 'radu_bot'
world_file = 'living_room3.sdf'
def generate_launch_description():
pkg_gazebo_ros = get_package_share_directory('gazebo_ros')
pkg_radu_simulation = get_package_share_directory(package_name)
rviz_config_path = os.path.join(pkg_radu_simulation, 'config/urdf_config.rviz')
robot_description_path = os.path.join(
pkg_radu_simulation,
"urdf",
"gazebo.xacro",
)
robot_description = {"robot_description": xacro.process_file(robot_description_path).toxml()}
print("MODEL %s" % robot_description['robot_description'])
sleep(3)
joint_state_publisher_node = Node(
package='joint_state_publisher',
executable='joint_state_publisher',
name='joint_state_publisher'
)
robot_state_publisher_node = Node(
package="robot_state_publisher",
executable="robot_state_publisher",
output="both",
parameters=[robot_description],
)
gazebo_node = IncludeLaunchDescription(
PythonLaunchDescriptionSource(
os.path.join(pkg_gazebo_ros, 'launch', 'gazebo.launch.py'),
)
)
robot_spawner = Node(
package='gazebo_ros',
executable='spawn_entity.py',
name='urdf_spawner',
output='screen',
arguments=["-topic", "/robot_description", "-entity", "radu_bot", "-x", "-3.0", "-y", "-1.5"])
print("STARTING ALL NODES")
sleep(3)
world_arg = DeclareLaunchArgument(
'world',
default_value=[os.path.join(pkg_radu_simulation, 'worlds', world_file), ''],
description='SDF world file')
no_sim_time = DeclareLaunchArgument(
'use_sim_time',
default_value='false',
description='Use simulation (Gazebo) clock if true')
return LaunchDescription([
world_arg,
no_sim_time,
joint_state_publisher_node,
robot_state_publisher_node,
gazebo_node,
robot_spawner
])
ros2 launch radu_bot control.launch.py
를 사용하여 부팅한 다음 사용 가능한 노드를 확인할 수 있습니다.$> ros2 node list
/gazebo
/joint_state_publisher
/robot_state_publisher
/wheel_drive_controller
마지막 노드wheel_drive_controller
는 우리가 로봇을 제어할 수 있는 주제cmd_vel
를 구독했다.$> ros2 node info /wheel_drive_controller
/wheel_drive_controller
Subscribers:
/clock: rosgraph_msgs/msg/Clock
/cmd_vel: geometry_msgs/msg/Twist
/parameter_events: rcl_interfaces/msg/ParameterEvent
Publishers:
/odom: nav_msgs/msg/Odometry
/parameter_events: rcl_interfaces/msg/ParameterEvent
/rosout: rcl_interfaces/msg/Log
/tf: tf2_msgs/msg/TFMessage
Service Servers:
/wheel_drive_controller/describe_parameters: rcl_interfaces/srv/DescribeParameters
/wheel_drive_controller/get_parameter_types: rcl_interfaces/srv/GetParameterTypes
/wheel_drive_controller/get_parameters: rcl_interfaces/srv/GetParameters
/wheel_drive_controller/list_parameters: rcl_interfaces/srv/ListParameters
/wheel_drive_controller/set_parameters: rcl_interfaces/srv/SetParameters
/wheel_drive_controller/set_parameters_atomically: rcl_interfaces/srv/SetParametersAtomically
Service Clients:
Action Servers:
Action Clients:
로봇을 제어하기 위해서 우리는 teleop_twist_keyboard
명령을 실행하여 키보드 키를 /cmd_vel
메시지로 전환시켰다.$> ros2 run teleop_twist_keyboard teleop_twist_keyboard --ros-args --remap cmd_vel:=/cmd_vel
This node takes keypresses from the keyboard and publishes them
as Twist messages. It works best with a US keyboard layout.
---------------------------
Moving around:
u i o
j k l
m , .
그러나 로봇을 움직일 때 이상하게 나타난다. 바퀴가 Y축을 따라 회전한다!이 문제를 해결하려면 관절에 현식
<axis>
과 <limit>
표시를 추가해야 한다.<xacro:macro name="wheel_joint" params="name parent child xyz ">
<joint name="${name}" type="continuous">
<parent link="${parent}" />
<child link="${child}" />
<origin xyz="${xyz}" rpy="1.570796 0 0"/>
<axis rpy="0 0 0" xyz="0 0 1"/>
<limit effort="1" velocity="1"/>
<joint_properties damping="1.0" friction="1.0"/>
</joint>
</xacro:macro>
그리고 로봇이 평온하게 움직인다.결론
기나긴 개발 여정이 마침내 끝났다. 마지막으로 베란다의 RADU 로봇 모형이 정확하고 모의 세계에서 이동할 수 있다.이 목표를 실현하기 위해서 우리는 세 가지 다른 주제를 배워야 한다.우선 테라스와 호환되는 URDF 모델은 어떤 추가 물리적 특성을 필요로 하는가.그 다음으로 우리는 ROS 시스템에 제어 노드를 늘려야 한다. 이 노드들은 로봇의 관절을 노출시켜 작용력, 속도 또는 위치를 조종하고 이 노드들을
cmd_vel
명령으로 전환시켜 시뮬레이션에서의 변경을 해야 한다.셋째, 플러그인은 두 번째 부분의 중임을 맡고 규범을 정확하게 설정하고 연결 상태/로봇 상태 연결을 추가하기 시작한다.이를 바탕으로 로봇은 현재 베란다에 영상카메라와 깊이카메라를 설치해 시뮬레이션을 할 수 있다.
Reference
이 문제에 관하여(로봇 운영체제: ROS Gazebo 플러그인으로 로봇 제어), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/admantium/robot-operating-system-controlling-a-robot-with-the-ros-gazebo-plugins-2jio텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)