控制器管理器(Controller Manager)、YAML配置文件、控制器(Controllers)以及硬件接口(Hardware Interface)lauch之间的关系,它们共同协作以实现对机器人硬件的控制,以下是一些理解和解释。
他们是如何通信,最简单的理解就是控制器要读取的东西放在state_interface指针里,写给底层写的放在command interface里,控制器和底层的hardware interface是同一个变量,硬件里会定时更新和读取数据,控制器也定时读取,底层和控制器操作的是同一个指针所以可以获取消息。
官方源码:https://github.com/ros-controls/ros2_controllers
官方的图是这样的
一、各者之间的流程和介绍
1. 控制器管理器(Controller Manager)
控制器管理器是ROS 2控制系统的核心组件之一,它负责加载、卸载、配置和切换控制器。它充当了控制器与硬件接口之间的中介,确保命令正确地从控制器传递到硬件,并且状态信息从硬件反馈给控制器。
功能:加载/卸载控制器、配置控制器、激活/停用控制器。
启动方式:通常通过launch文件启动,并指定控制器管理器使用的硬件接口和控制器配置。
2. YAML配置文件
YAML配置文件用于定义控制器管理器的行为和参数,包括哪些控制器应该被加载,每个控制器的具体配置参数,以及硬件接口的相关配置。
控制器列表:列出要加载的控制器名称和类型。
控制器参数:为每个控制器提供特定的参数,如关节名称、控制模式等。
硬件接口配置:定义硬件接口的参数,例如通信协议、设备地址等
controller_manager:
ros__parameters:
update_rate: 500 # 控制器管理器的更新频率
joint_state_broadcaster:
type: joint_state_broadcaster/JointStateBroadcaster
my_position_controller:
type: my_position_controller/MyPositionController
joints:
- joint1
- joint2
- joint3
state_joints:
- joint1
- joint2
- joint3
interface_name: position
hardware_interface:
ros__parameters:
joints:
- name: joint1
command_interface: position
state_interface: position
- name: joint2
command_interface: position
state_interface: position
- name: joint3
command_interface: position
state_interface: position
3. 控制器(Controllers)
控制器实现了具体的控制逻辑,如位置控制、速度控制或力矩控制。它们通过命令接口向硬件发送命令,并通过状态接口接收硬件的状态信息。
定义:控制器类继承自 controller_interface::ControllerInterface,并实现必要的生命周期方法(如 on_init, on_configure, on_activate, update 等)。
加载:由控制器管理器根据YAML配置文件中的定义加载。
4. 硬件接口(Hardware Interface)
硬件接口负责与物理硬件通信,读取传感器数据并向执行器发送命令。它是控制器与实际硬件之间的桥梁。
定义:硬件接口类继承自 hardware_interface::SystemInterface 或更具体的接口(如 hardware_interface::JointStateInterface),并实现 read 和 write 方法。
配置:硬件接口的参数在YAML配置文件中定义,并在启动时由控制器管理器传递给硬件接口实例。
5. Launch文件
Launch文件用于启动整个系统,包括控制器管理器、控制器和硬件接口
from launch import LaunchDescription
from launch_ros.actions import Node
from launch.actions import DeclareLaunchArgument, IncludeLaunchDescription
from launch.substitutions import Command, FindExecutable, PathJoinSubstitution
from launch.conditions import IfCondition
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch_ros.substitutions import FindPackageShare
def generate_launch_description():
# 定义机器人描述参数
robot_description_content = Command(
[
PathJoinSubstitution([FindExecutable(name="xacro")]),
" ",
PathJoinSubstitution(
[FindPackageShare("my_robot"), "urdf", "robot.urdf.xacro"]
),
]
)
robot_description = {"robot_description": robot_description_content}
# 加载控制器管理器节点
controller_manager_node = Node(
package="controller_manager",
executable="ros2_control_node",
parameters=[robot_description,
PathJoinSubstitution([FindPackageShare("my_robot"), "config", "controllers.yaml"])],
output="both",
)
# 启动关节状态广播器
joint_state_broadcaster_spawner = Node(
package="controller_manager",
executable="spawner",
arguments=["joint_state_broadcaster", "--controller-manager", "/controller_manager"],
)
# 启动位置控制器
position_controller_spawner = Node(
package="controller_manager",
executable="spawner",
arguments=["my_position_controller", "-c", "/controller_manager"],
)
# 返回启动描述
return LaunchDescription([
controller_manager_node,
joint_state_broadcaster_spawner,
position_controller_spawner,
])
parameters 里面是机器人描述文件,yaml控制器文件
基本的链路是这样
自己写的yaml----->传递给官方库里的yaml(这也对应着里面的名字和参数)
这是forward_command_controller_parameters里面的yaml配置
这是生成的代码
这个和我们配置这个是对应的
初始化完成大概是这个样子
二、示例
只给关键部分和流程帮助大家理解
一个小车的常用控制流程是这样的
hardware interface
hareware_interface就可以理解为控制电机不同的方式,如果不管硬件,软件这些东西都是相同的都需要获取信息,发布信息
看到一个介绍是这样的:理解了之后确实是这样
1.gazebo仿真
如果要使用gazebo仿真
设置了这个之后gazebo就可以控制和接收信息了
这就是gazebo的控制器配置,有哪些控制器
变量名:
命名空间/类名
argument