跳到正文

Wiki

Harmonic机械臂物理仿真

约 3 分钟阅读

使用 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与差速底盘控制