You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ROS2中Controller Manager未加载控制器参数的问题排查与解决

问题:ROS2 Controller Manager未加载控制器配置参数

我为移动机器人开发了若干控制器,编译过程无报错,但运行后执行指令ros2 param list /controller_manager,仅显示默认参数,看不到arm_position_controller、shovel_position_controller等自定义控制器的相关配置。以下是相关文件:

控制器launch文件

from launch import LaunchDescription
from launch_ros.actions import Node
from ament_index_python.packages import get_package_share_directory
from launch.substitutions import Command
import os

def generate_launch_description():
    # Path to URDF file
    urdf_file = os.path.join(get_package_share_directory('localisation_sim_task'), 'urdf', 'load_vehicle.urdf')

    # Path to the controllers configuration (params.yaml)
    params_file = os.path.join(get_package_share_directory('localisation_sim_task'), 'config', 'params.yaml')

    robot_description = Command(['xacro ', urdf_file])

    return LaunchDescription([
        # Robot state publisher to publish the URDF
        Node(
            package='robot_state_publisher',
            executable='robot_state_publisher',
            name='robot_state_publisher',
            output='screen',
            parameters=[{'robot_description': robot_description}],
        ),

        # Start ros2_control_node with the controllers from params.yaml
        Node(
            package='controller_manager',
            executable='ros2_control_node',
            parameters=[params_file],
            output='screen',
        ),

        # Load and start the arm position controller
        Node(
            package='controller_manager',
            executable='spawner',
            arguments=['arm_position_controller'],
            output='screen',
        ),

        # Load and start the shovel position controller
        Node(
            package='controller_manager',
            executable='spawner',
            arguments=['shovel_position_controller'],
            output='screen',
        ),

        # Start custom node for controlling the arm and shovel
        Node(
            package='localisation_sim_task',
            executable='arm_shovel_controller',
            name='arm_shovel_controller',
            output='screen',
        ),

        # Start steering velocity controller
        Node(
            package='localisation_sim_task',
            executable='steering_velocity_controller',
            name='steering_velocity_controller',
            output='screen',
        ),
    ])

控制器节点CPP文件

#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/float64.hpp"

class ArmShovelController : public rclcpp::Node {
public:
    ArmShovelController() : Node("arm_shovel_controller") {
        arm_pub_ = this->create_publisher<std_msgs::msg::Float64>("/arm_position_controller/command", 10);
        shovel_pub_ = this->create_publisher<std_msgs::msg::Float64>("/shovel_position_controller/command", 10);

        // Publish commands to move the arm and shovel
        timer_ = this->create_wall_timer(
            std::chrono::milliseconds(100), std::bind(&ArmShovelController::publish_commands, this));
    }

private:
    void publish_commands() {
        auto arm_msg = std_msgs::msg::Float64();
        auto shovel_msg = std_msgs::msg::Float64();

        // Example positions
        arm_msg.data = 0.5;  // Example: move the arm to 0.5 radians
        shovel_msg.data = 0.2;  // Example: move the shovel to 0.2 radians

        arm_pub_->publish(arm_msg);
        shovel_pub_->publish(shovel_msg);
    }

    rclcpp::Publisher<std_msgs::msg::Float64>::SharedPtr arm_pub_;
    rclcpp::Publisher<std_msgs::msg::Float64>::SharedPtr shovel_pub_;
    rclcpp::TimerBase::SharedPtr timer_;
};

int main(int argc, char **argv) {
    rclcpp::init(argc, argv);
    rclcpp::spin(std::make_shared<ArmShovelController>());
    rclcpp::shutdown();
    return 0;
}

params.yaml参数文件

arm_position_controller:
  ros__parameters:
    type: position_controllers/JointPositionController  # Define the type of the controller
    joint: arm_joint
    command_interfaces:
      - position
    state_interfaces:
      - position
      - velocity

shovel_position_controller:
  ros__parameters:
    type: position_controllers/JointPositionController  # Define the type of the controller
    joint: shovel_joint
    command_interfaces:
      - position
    state_interfaces:
      - position
      - velocity

steering_velocity_controller:
  ros__parameters:
    type: velocity_controllers/JointVelocityController  # Define the type of the controller
    joint: steering_joint
    command_interfaces:
      - velocity
    state_interfaces:
      - velocity

运行后ros2 param list /controller_manager输出:

qos_overrides./parameter_events.publisher.depth
qos_overrides./parameter_events.publisher.durability
qos_overrides./parameter_events.publisher.history
qos_overrides./parameter_events.publisher.reliability
use_sim_time

原因分析
  1. params.yaml结构不符合ROS2 Control规范:ROS2 Control要求所有控制器配置必须嵌套在controller_manager节点的ros__parameters字段下,当前配置直接将控制器作为顶级键,导致controller_manager无法识别并加载这些参数。
  2. 缺少controller_manager必需的更新频率参数:controller_manager需要指定update_rate参数来控制硬件接口的更新频率,当前配置中未包含该参数,这也会导致配置加载异常。
  3. Spawner节点时序问题:Spawner节点可能在controller_manager完全加载配置前就执行,导致控制器加载失败(即使参数正确,也可能出现这类问题)。

解决步骤

1. 修改params.yaml结构

将所有控制器配置嵌套到controller_manager.ros__parameters下,并添加update_rate参数:

controller_manager:
  ros__parameters:
    update_rate: 100  # 硬件接口更新频率,单位Hz,必须指定

    arm_position_controller:
      type: position_controllers/JointPositionController
      joint: arm_joint
      command_interfaces:
        - position
      state_interfaces:
        - position
        - velocity

    shovel_position_controller:
      type: position_controllers/JointPositionController
      joint: shovel_joint
      command_interfaces:
        - position
      state_interfaces:
        - position
        - velocity

    steering_velocity_controller:
      type: velocity_controllers/JointVelocityController
      joint: steering_joint
      command_interfaces:
        - velocity
      state_interfaces:
        - velocity

2. 调整Launch文件中的Spawner节点

给Spawner节点添加--wait参数,让其等待controller_manager的服务可用后再加载控制器,避免时序问题:

# 加载并启动机械臂位置控制器
Node(
    package='controller_manager',
    executable='spawner',
    arguments=['arm_position_controller', '--wait'],
    output='screen',
),

# 加载并启动铲斗位置控制器
Node(
    package='controller_manager',
    executable='spawner',
    arguments=['shovel_position_controller', '--wait'],
    output='screen',
),

3. 验证配置

  • 重新编译包:colcon build --packages-select localisation_sim_task
  • 刷新环境变量:source install/setup.bash
  • 启动launch文件:ros2 launch localisation_sim_task <你的launch文件名>.launch.py
  • 检查参数:执行ros2 param list /controller_manager,此时应能看到所有控制器的相关参数
  • 检查控制器状态:执行ros2 control list_controllers,确认控制器处于active状态

内容的提问来源于stack exchange,提问作者Macedon971

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 20:56:01