Wiki
Harmonic機械臂物理仿真
本文由簡體中文內容確定性轉換,並受版本化術語表保護。
使用 Gazebo Harmonic 和 gz_ros2_control。模型和控制器繼續使用,硬件後端由仿真關節替代。
1.安裝與檢查
sudo apt-get update
sudo apt-get install -y ros-jazzy-ros-gz ros-jazzy-gz-ros2-control
source /opt/ros/jazzy/setup.bash
gz sim --versions
ros2 pkg prefix ros_gz_sim
ros2 pkg prefix gz_ros2_control
應能找到 Harmonic 對應的 Gazebo Sim 8。使用 Jazzy 對應的 ROS 軟件源和 vendor 依賴,不混入 Fortress 或 Gazebo Classic 插件。
在硬件包 package.xml 的 export 之前增加:
<exec_depend>gz_ros2_control</exec_depend>
<exec_depend>ros_gz_sim</exec_depend>
<exec_depend>ros_gz_bridge</exec_depend>
2.示例 1:完整仿真模型
保存 urdf/two_joint_gz.urdf.xacro:
<?xml version="1.0"?>
<robot name="mini" xmlns:xacro="http://www.ros.org/wiki/xacro">
<link name="world"/>
<link name="base_link">
<inertial><mass value="1"/><inertia ixx="0.005" ixy="0" ixz="0" iyy="0.005" iyz="0" izz="0.007"/></inertial>
<visual><geometry><box size="0.2 0.2 0.1"/></geometry></visual>
</link>
<joint name="world_fixed" type="fixed"><parent link="world"/><child link="base_link"/></joint>
<link name="link1">
<inertial><origin xyz="0 0 0.2"/><mass value="1"/>
<inertia ixx="0.0135" ixy="0" ixz="0" iyy="0.0135" iyz="0" izz="0.00042"/>
</inertial>
<visual><origin xyz="0 0 0.2"/><geometry><box size="0.05 0.05 0.4"/></geometry></visual>
<collision><origin xyz="0 0 0.2"/><geometry><box size="0.05 0.05 0.4"/></geometry></collision>
</link>
<joint name="joint1" type="revolute">
<parent link="base_link"/><child link="link1"/>
<origin xyz="0 0 0.05"/><axis xyz="0 1 0"/>
<limit lower="-1" upper="1" effort="20" velocity="2"/>
</joint>
<link name="link2">
<inertial><origin xyz="0 0 0.2"/><mass value="1"/>
<inertia ixx="0.0135" ixy="0" ixz="0" iyy="0.0135" iyz="0" izz="0.00042"/>
</inertial>
<visual><origin xyz="0 0 0.2"/><geometry><box size="0.05 0.05 0.4"/></geometry></visual>
<collision><origin xyz="0 0 0.2"/><geometry><box size="0.05 0.05 0.4"/></geometry></collision>
</link>
<joint name="joint2" type="revolute">
<parent link="link1"/><child link="link2"/>
<origin xyz="0 0 0.4"/><axis xyz="0 1 0"/>
<limit lower="-1" upper="1" effort="20" velocity="2"/>
</joint>
<ros2_control name="MiniSystem" type="system">
<hardware><plugin>gz_ros2_control/GazeboSimSystem</plugin></hardware>
<joint name="joint1">
<command_interface name="position"/>
<state_interface name="position"><param name="initial_value">0.0</param></state_interface>
<state_interface name="velocity"/>
</joint>
<joint name="joint2">
<command_interface name="position"/>
<state_interface name="position"><param name="initial_value">0.0</param></state_interface>
<state_interface name="velocity"/>
</joint>
</ros2_control>
<gazebo>
<plugin filename="libgz_ros2_control-system.so" name="gz_ros2_control::GazeboSimROS2ControlPlugin">
<parameters>$(find jazzy_control_hardware)/config/controllers.yaml</parameters>
</plugin>
</gazebo>
</robot>
2.1.兩個插件名稱的意義
hardware/plugin 聲明 GazeboSimSystem 作為硬件實現;gazebo/plugin 將框架接入仿真更新,並讀取控制器配置。接口名稱仍為 joint1/position 等。
質量與慣量影響模型是否能轉換和參與物理計算。RViz 能顯示 visual,不能證明物理模型已經有效。
3.示例 2:完整仿真啓動文件
保存 launch/sim.launch.py:
from pathlib import Path
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument, IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch.substitutions import Command, LaunchConfiguration, PythonExpression
from launch_ros.actions import Node
from launch_ros.parameter_descriptions import ParameterValue
def generate_launch_description():
share = Path(get_package_share_directory('jazzy_control_hardware'))
model = LaunchConfiguration('model')
controller = LaunchConfiguration('controller')
config = LaunchConfiguration('config')
gui = LaunchConfiguration('gui')
description = ParameterValue(Command(['xacro ', model]), value_type=str)
gz_args = PythonExpression(["'-r -v 2 empty.sdf' if '", gui,
"' == 'true' else '-s -r -v 2 empty.sdf'"])
return LaunchDescription([
DeclareLaunchArgument('gui', default_value='false'),
DeclareLaunchArgument('model', default_value=str(share / 'urdf' / 'two_joint_gz.urdf.xacro')),
DeclareLaunchArgument('controller', default_value='forward_position_controller'),
DeclareLaunchArgument('config', default_value=str(share / 'config' / 'controllers.yaml')),
IncludeLaunchDescription(PythonLaunchDescriptionSource(
str(Path(get_package_share_directory('ros_gz_sim')) / 'launch' / 'gz_sim.launch.py')),
launch_arguments={'gz_args': gz_args}.items()),
Node(package='ros_gz_bridge', executable='parameter_bridge',
arguments=['/clock@rosgraph_msgs/msg/Clock[gz.msgs.Clock'], output='screen'),
Node(package='robot_state_publisher', executable='robot_state_publisher',
parameters=[{'robot_description': description, 'use_sim_time': True}]),
Node(package='ros_gz_sim', executable='create',
arguments=['-topic', '/robot_description', '-name', 'learning_robot', '-z', '0.10']),
Node(package='controller_manager', executable='spawner',
arguments=['joint_state_broadcaster', '-c', '/controller_manager',
'--param-file', config, '--controller-manager-timeout', '60']),
Node(package='controller_manager', executable='spawner',
arguments=[controller, '-c', '/controller_manager', '--param-file', config,
'--controller-manager-timeout', '60']),
])
3.1.啓動過程
世界啓動後,create 請求生成模型;模型插件創建管理器;spawner 等待服務並分別提供參數文件;bridge 將 /clock 從 Gazebo 傳到 ROS。
本章不再啓動 two_joint.launch.py 的獨立管理器。create 返回請求成功後,仍要查看模型與控制器狀態,不能只看一個 OK。
4.編譯運行
cd ~/ros2_control_jazzy_ws
colcon build --symlink-install --packages-select jazzy_control_hardware
source install/setup.bash
ros2 launch jazzy_control_hardware sim.launch.py gui:=false
在圖形桌面中改為 gui:=true 即可打開 Gazebo 窗口。無界面與有界面運行使用相同控制鏈路。
另一個已 source 的終端:
ros2 control list_controllers
ros2 topic echo /clock --once
ros2 topic pub --once /forward_position_controller/commands \
std_msgs/msg/Float64MultiArray "{data: [0.3, -0.2]}"
ros2 topic echo /joint_states
預期反饋接近 [0.3,-0.2],/clock 持續增加。position 接口具有仿真後端規定的響應方式,不應直接當成真實電機性能。
源碼:gz_ros2_control/gz_ros2_control/src/gz_system.cpp。安裝組合參考 Jazzy 官方仿真文檔。
返回 Jazzy 總覽 · 上一篇:Joint-Trajectory-Controller · 下一篇:DiffBot與差速底盤控制