Wiki
機械臂物理模擬
本文由簡體中文內容確定性轉換,並受版本化術語表保護。
本節使用 Gazebo Fortress 與 gz_ros2_control 0.7.21。前面的介面與控制器繼續使用,反饋改由物理模擬提供。
1.環境與版本約定
先完成環境準備與原始碼地圖的 Humble 安裝與 ROS 2 軟體源配置。下面安裝 Fortress 模擬器及 ROS 整合包;已經安裝對應元件時,可以直接檢查版本與包路徑。
1.1.安裝 Fortress 模擬器
按 Fortress 官方 Ubuntu 安裝說明 配置 OSRF 軟體源。以下命令用於 Ubuntu 22.04(jammy);若系統已配置同一軟體源,無需重複新增。
sudo apt-get update
sudo apt-get install -y curl ca-certificates gnupg lsb-release
curl -fsSL https://packages.osrfoundation.org/gazebo.gpg -o /tmp/gazebo-key.gpg
sudo install -m 644 /tmp/gazebo-key.gpg /usr/share/keyrings/pkgs-osrf-archive-keyring.gpg
printf 'deb [arch=%s signed-by=/usr/share/keyrings/pkgs-osrf-archive-keyring.gpg] https://packages.osrfoundation.org/gazebo/ubuntu-stable jammy main\n' \
"$(dpkg --print-architecture)" | sudo tee /etc/apt/sources.list.d/gazebo-stable.list > /dev/null
sudo apt-get update
sudo apt-get install -y ignition-fortress
1.2.安裝 ROS 整合包並檢查
sudo apt-get install -y ros-humble-ros-gz ros-humble-gz-ros2-control
source /opt/ros/humble/setup.bash
ign gazebo --versions
ros2 pkg prefix ros_gz_sim
ros2 pkg prefix ros_gz_bridge
ros2 pkg prefix gz_ros2_control
ign gazebo --versions 應能找到 Fortress 對應的 Gazebo Sim 6,三個 ROS 包都應返回有效安裝路徑。外掛安裝方式參考 Humble gz_ros2_control 文件。
本章不使用 Gazebo Classic 的 libgazebo_ros2_control.so。Fortress 環境中啟動命令仍可能是 ign gazebo;ROS 包名採用 ros_gz_sim、gz_ros2_control,按實際安裝介面執行。
在 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/mini_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="gz_ros2_control-system" name="gz_ros2_control::GazeboSimROS2ControlPlugin">
<parameters>$(find learn_control_hardware)/config/controllers.yaml</parameters>
</plugin>
</gazebo>
</robot>
2.1.兩種外掛分別負責什麼
硬體標籤中的 gz_ros2_control/GazeboSimSystem 連線關節狀態與命令介面;gazebo 標籤中的系統外掛負責把控制框架接入模擬過程,並按 parameters 路徑讀取 YAML。
模擬外掛會在模擬程序中建立管理器,因此本章不另外啟動 mini.launch.py 中的獨立 ros2_control_node。同一機器人啟動兩個管理器會造成資源與名稱衝突。
2.2.模型為什麼需要慣量
物理引擎需要質量與慣量;只有 visual 的 link 可能在模型轉換時被丟棄。例如,base_link 缺少有效慣量時,模型轉換可能導致其子關節找不到父座標系。應補齊有效的質量與慣量,並重新檢查模型轉換日誌。即使 RViz 能顯示模型,也不能保證它已經是有效的物理模型。
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('learn_control_hardware'))
gui = LaunchConfiguration('gui')
model = LaunchConfiguration('model')
controller = LaunchConfiguration('controller')
description = ParameterValue(Command(['xacro ', model]), value_type=str)
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' / 'mini_gz.urdf.xacro')),
DeclareLaunchArgument('controller', default_value='forward_position_controller'),
IncludeLaunchDescription(PythonLaunchDescriptionSource(
str(Path(get_package_share_directory('ros_gz_sim')) / 'launch' / 'gz_sim.launch.py')),
launch_arguments={'gz_args': 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.02']),
Node(package='controller_manager', executable='spawner',
arguments=['joint_state_broadcaster', '-c', '/controller_manager',
'--controller-manager-timeout', '60']),
Node(package='controller_manager', executable='spawner',
arguments=[controller, '-c', '/controller_manager',
'--controller-manager-timeout', '60']),
])
3.1.完整啟動過程
启动 Fortress world
→ robot_state_publisher 发布展开的机器人描述
→ ros_gz_sim/create 请求生成机器人
→ 模型中的系统插件加载控制管理器
→ spawner 等待服务并激活控制器
→ /clock 桥接到 ROS,使用仿真时间
create 返回請求成功,還應繼續檢查模型是否真正生成、外掛是否載入、控制器是否 active。不能只憑一個 OK 判斷整條鏈路成功。
4.編譯執行
停止前面的獨立 mini 例項:
cd ~/ros2_control_humble_ws
colcon build --symlink-install --packages-select learn_control_hardware
source install/setup.bash
ros2 launch learn_control_hardware sim.launch.py gui:=false
上面的 gui:=false 只執行模擬服務,適合先檢查後臺鏈路。在 Ubuntu 圖形桌面中需要 Gazebo 視窗時,將啟動引數改為 gui:=true。兩種方式使用相同的模型和控制器;啟動前先停止上一套例項。
另一個終端:
source /opt/ros/humble/setup.bash
source ~/ros2_control_humble_ws/install/setup.bash
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
4.1.執行結果與檢查方法
兩個關節的反饋應逐漸接近 0.3、-0.2 rad。檢查控制器是否 active、/clock 是否前進,以及 /joint_states 中的名稱和數值是否對應。使用 GUI 時,還應觀察模型關節是否按目標運動。
position 介面在模擬後端中具有自己的執行方式。即使模型位於物理引擎中,也不能把預設位置執行器響應直接當成真實電機的效能。
5.對應底層原始碼
閱讀 gz_ros2_control/gz_ros2_control/src/gz_ros2_control_plugin.cpp、gz_ros2_control/gz_ros2_control/src/gz_system.cpp,尋找模擬更新回撥、管理器呼叫和關節資料訪問。再與獨立 ros2_control_node 對照。
返回 Humble 總覽 · 上一篇:Joint-Trajectory-Controller · 下一篇:DiffBot與差速底盤控制