机械手臂力矩控制的MATLAB实现方案

2025-12-15

机械手臂力矩控制的MATLAB实现方案

1. 机械臂动力学基础

1.1 动力学方程

机械臂的动力学方程通常表示为:

其中:

  • :质量矩阵
  • :科里奥利力和离心力矩阵
  • :重力项
  • :摩擦力项
  • :关节力矩

2. 完整的MATLAB实现

%% 机械臂力矩控制MATLAB程序
% 作者:基于标准机器人动力学控制理论
% 功能:实现机械臂的力矩控制,包括计算动力学、各种控制策略

classdef TorqueControlArm < handle
    properties
        % 机械臂参数
        m1 = 1.0;   m2 = 0.8;   % 连杆质量 [kg]
        l1 = 0.5;   l2 = 0.4;   % 连杆长度 [m]
        lc1 = 0.25; lc2 = 0.2;  % 质心位置 [m]
        I1 = 0.1;   I2 = 0.08;  % 转动惯量 [kg·m²]
        g = 9.81;               % 重力加速度 [m/s²]
        
        % 控制参数
        Kp = diag([150, 100]);  % 比例增益
        Kd = diag([20, 15]);    % 微分增益
        Ki = diag([5, 3]);      % 积分增益
        
        % 状态变量
        q = zeros(2,1);         % 关节角度
        dq = zeros(2,1);        % 关节角速度
        integral_error = zeros(2,1); % 积分误差
        
        % 摩擦力参数
        B = diag([0.5, 0.3]);   % 粘性摩擦系数
        Fc = [0.8; 0.6];        % 库伦摩擦
        
        % 数据记录
        time_history = [];
        torque_history = [];
        position_history = [];
        error_history = [];
    end
    
    methods
        function obj = TorqueControlArm(initial_q)
            % 构造函数
            if nargin > 0
                obj.q = initial_q;
            end
        end
        
        function M = mass_matrix(obj, q)
            % 计算质量矩阵
            m1 = obj.m1; m2 = obj.m2;
            l1 = obj.l1; l2 = obj.l2;
            lc1 = obj.lc1; lc2 = obj.lc2;
            I1 = obj.I1; I2 = obj.I2;
            
            % 动力学参数
            d1 = m1*lc1^2 + m2*l1^2 + I1;
            d2 = m2*lc2^2 + I2;
            d3 = m2*l1*lc2;
            
            c2 = cos(q(2));
            
            M = [d1 + d2 + 2*d3*c2, d2 + d3*c2;
                 d2 + d3*c2,        d2];
        end
        
        function C = coriolis_matrix(obj, q, dq)
            % 计算科里奥利和离心力矩阵
            m2 = obj.m2;
            l1 = obj.l1;
            lc2 = obj.lc2;
            
            h = -m2*l1*lc2*sin(q(2));
            
            C = [h*dq(2), h*dq(1) + h*dq(2);
                 -h*dq(1), 0];
        end
        
        function G = gravity_vector(obj, q)
            % 计算重力项
            m1 = obj.m1; m2 = obj.m2;
            l1 = obj.l1; lc1 = obj.lc1; lc2 = obj.lc2;
            g = obj.g;
            
            c1 = cos(q(1));
            c12 = cos(q(1)+q(2));
            
            G = [m1*g*lc1*c1 + m2*g*(l1*c1 + lc2*c12);
                 m2*g*lc2*c12];
        end
        
        function F = friction(obj, dq)
            % 计算摩擦力
            % 粘性摩擦 + 库伦摩擦
            F = obj.B * dq + obj.Fc .* tanh(10*dq);
        end
        
        function tau_computed = compute_torque(obj, q, dq, ddq)
            % 计算基于模型的前馈力矩
            M = obj.mass_matrix(q);
            C = obj.coriolis_matrix(q, dq);
            G = obj.gravity_vector(q);
            F = obj.friction(dq);
            
            tau_computed = M*ddq + C*dq + G + F;
        end
        
        function [position, orientation] = forward_kinematics(obj, q)
            % 正运动学
            l1 = obj.l1; l2 = obj.l2;
            
            x = l1*cos(q(1)) + l2*cos(q(1)+q(2));
            y = l1*sin(q(1)) + l2*sin(q(1)+q(2));
            
            position = [x; y];
            orientation = q(1) + q(2);  % 末端姿态角
        end
        
        function [q, success] = inverse_kinematics(obj, position)
            % 逆运动学
            l1 = obj.l1; l2 = obj.l2;
            x = position(1); y = position(2);
            
            % 检查是否在工作空间内
            d = sqrt(x^2 + y^2);
            if d > l1 + l2 || d < abs(l1 - l2)
                q = obj.q;  % 保持当前位置
                success = false;
                return;
            end
            
            % 计算关节角度
            c2 = (x^2 + y^2 - l1^2 - l2^2) / (2*l1*l2);
            s2 = sqrt(1 - c2^2);
            
            q2 = atan2(s2, c2);
            q1 = atan2(y, x) - atan2(l2*s2, l1 + l2*c2);
            
            q = [q1; q2];
            success = true;
        end
    end
end

3. 控制策略实现

%% 各种力矩控制策略
classdef TorqueControllers < handle
    methods (Static)
        
        function tau = computed_torque_control(robot, q_des, dq_des, ddq_des, q, dq)
            % 计算力矩控制
            % 基于模型的前馈 + PD反馈
            
            % 计算前馈力矩
            tau_ff = robot.compute_torque(q_des, dq_des, ddq_des);
            
            % 计算反馈力矩
            error = q_des - q;
            error_deriv = dq_des - dq;
            
            tau_fb = robot.Kp * error + robot.Kd * error_deriv;
            
            tau = tau_ff + tau_fb;
        end
        
        function tau = pd_control_with_gravity_comp(robot, q_des, dq_des, q, dq)
            % PD控制 + 重力补偿
            error = q_des - q;
            error_deriv = dq_des - dq;
            
            tau_pd = robot.Kp * error + robot.Kd * error_deriv;
            tau_gravity = robot.gravity_vector(q);
            
            tau = tau_pd + tau_gravity;
        end
        
        function tau = impedance_control(robot, q, dq, F_des, F_ext)
            % 阻抗控制
            % F_des: 期望的末端力
            % F_ext: 测量的外部力
            
            % 计算雅可比矩阵
            J = robot.jacobian(q);
            
            % 阻抗关系
            M_d = diag([2, 2]);     % 期望惯量
            B_d = diag([20, 20]);   % 期望阻尼
            K_d = diag([200, 200]); % 期望刚度
            
            % 计算参考轨迹调整
            F_error = F_des - F_ext;
            ddx_ref = M_d \ (F_error - B_d * (J*dq) - K_d * (robot.forward_kinematics(q) - robot.x_des));
            
            % 转换为关节空间控制
            tau = robot.compute_torque(q, dq, J\ddx_ref) + J' * F_des;
        end
        
        function tau = adaptive_control(robot, q_des, dq_des, ddq_des, q, dq, param_estimate)
            % 自适应控制
            % param_estimate: 参数估计值
            
            % 计算回归矩阵
            Y = robot.regressor(q, dq, ddq_des);
            
            % 控制律
            error = q_des - q;
            error_deriv = dq_des - dq;
            
            tau = Y * param_estimate + robot.Kp * error + robot.Kd * error_deriv;
        end
    end
end

4. 主控制程序

%% 主控制程序 - 机械臂力矩控制仿真
function main_torque_control()
    close all; clear; clc;
    
    fprintf('机械臂力矩控制仿真程序\n');
    
    % 创建机械臂对象
    robot = TorqueControlArm([0; pi/4]);
    
    % 仿真参数
    dt = 0.001;           % 采样时间 [s]
    T = 5.0;              % 总仿真时间 [s]
    steps = round(T/dt);
    
    % 期望轨迹 - 圆形轨迹
    t = linspace(0, T, steps);
    radius = 0.3;
    center = [0.4; 0.2];
    
    x_des = center(1) + radius * cos(2*pi*t/T);
    y_des = center(2) + radius * sin(2*pi*t/T);
    
    % 初始化记录数组
    time_vec = zeros(1, steps);
    q_history = zeros(2, steps);
    q_des_history = zeros(2, steps);
    torque_history = zeros(2, steps);
    error_history = zeros(2, steps);
    position_history = zeros(2, steps);
    
    % 主控制循环
    for k = 1:steps
        time_vec(k) = (k-1)*dt;
        
        % 生成期望轨迹
        current_pos_des = [x_des(k); y_des(k)];
        
        % 逆运动学得到期望关节角度
        [q_des, success] = robot.inverse_kinematics(current_pos_des);
        
        if ~success
            fprintf('第 %.2f 秒: 轨迹点不可达\n', time_vec(k));
            continue;
        end
        
        % 计算期望速度和加速度(数值微分)
        if k == 1
            dq_des = zeros(2,1);
            ddq_des = zeros(2,1);
        elseif k == 2
            dq_des = (q_des - q_des_history(:,k-1)) / dt;
            ddq_des = zeros(2,1);
        else
            dq_des = (q_des - q_des_history(:,k-1)) / dt;
            ddq_des = (q_des - 2*q_des_history(:,k-1) + q_des_history(:,k-2)) / (dt^2);
        end
        
        % 计算控制力矩
        tau = TorqueControllers.computed_torque_control(robot, q_des, dq_des, ddq_des, robot.q, robot.dq);
        
        % 模拟机械臂动力学
        [q_new, dq_new] = robot.dynamics_update(tau, dt);
        
        % 更新机器人状态
        robot.q = q_new;
        robot.dq = dq_new;
        
        % 记录数据
        q_history(:,k) = robot.q;
        q_des_history(:,k) = q_des;
        torque_history(:,k) = tau;
        error_history(:,k) = q_des - robot.q;
        
        % 记录末端位置
        position_history(:,k) = robot.forward_kinematics(robot.q);
    end
    
    % 绘制结果
    plot_results(time_vec, q_history, q_des_history, torque_history, error_history, position_history, [x_des; y_des]);
end

%% 机械臂动力学更新函数
function [q_new, dq_new] = dynamics_update(robot, tau, dt)
    % 使用欧拉积分更新动力学
    
    % 计算加速度
    M = robot.mass_matrix(robot.q);
    C = robot.coriolis_matrix(robot.q, robot.dq);
    G = robot.gravity_vector(robot.q);
    F = robot.friction(robot.dq);
    
    ddq = M \ (tau - C*robot.dq - G - F);
    
    % 积分得到新状态
    dq_new = robot.dq + ddq * dt;
    q_new = robot.q + dq_new * dt;
end

%% 结果可视化函数
function plot_results(time_vec, q_history, q_des_history, torque_history, error_history, position_history, desired_trajectory)
    figure('Position', [100, 100, 1200, 800]);
    
    % 1. 关节角度跟踪
    subplot(2,3,1);
    plot(time_vec, q_history(1,:), 'b-', 'LineWidth', 2); hold on;
    plot(time_vec, q_des_history(1,:), 'r--', 'LineWidth', 2);
    plot(time_vec, q_history(2,:), 'g-', 'LineWidth', 2);
    plot(time_vec, q_des_history(2,:), 'm--', 'LineWidth', 2);
    legend('关节1实际', '关节1期望', '关节2实际', '关节2期望');
    xlabel('时间 [s]'); ylabel('关节角度 [rad]');
    title('关节角度跟踪'); grid on;
    
    % 2. 跟踪误差
    subplot(2,3,2);
    plot(time_vec, error_history(1,:), 'r-', 'LineWidth', 2); hold on;
    plot(time_vec, error_history(2,:), 'b-', 'LineWidth', 2);
    legend('关节1误差', '关节2误差');
    xlabel('时间 [s]'); ylabel('跟踪误差 [rad]');
    title('跟踪误差'); grid on;
    
    % 3. 控制力矩
    subplot(2,3,3);
    plot(time_vec, torque_history(1,:), 'r-', 'LineWidth', 2); hold on;
    plot(time_vec, torque_history(2,:), 'b-', 'LineWidth', 2);
    legend('关节1力矩', '关节2力矩');
    xlabel('时间 [s]'); ylabel('控制力矩 [Nm]');
    title('控制力矩'); grid on;
    
    % 4. 末端轨迹跟踪
    subplot(2,3,4);
    plot(desired_trajectory(1,:), desired_trajectory(2,:), 'r--', 'LineWidth', 2); hold on;
    plot(position_history(1,:), position_history(2,:), 'b-', 'LineWidth', 1.5);
    legend('期望轨迹', '实际轨迹');
    xlabel('X [m]'); ylabel('Y [m]');
    title('末端执行器轨迹跟踪'); grid on; axis equal;
    
    % 5. 关节角速度
    subplot(2,3,5);
    dq_actual = diff(q_history, 1, 2) / (time_vec(2)-time_vec(1));
    plot(time_vec(1:end-1), dq_actual(1,:), 'r-', 'LineWidth', 2); hold on;
    plot(time_vec(1:end-1), dq_actual(2,:), 'b-', 'LineWidth', 2);
    legend('关节1角速度', '关节2角速度');
    xlabel('时间 [s]'); ylabel('角速度 [rad/s]');
    title('关节角速度'); grid on;
    
    % 6. 力矩-角度相图
    subplot(2,3,6);
    scatter(q_history(1,:), torque_history(1,:), 20, time_vec, 'filled');
    colorbar;
    xlabel('关节1角度 [rad]'); ylabel('关节1力矩 [Nm]');
    title('力矩-角度关系'); grid on;
    
    % 性能指标计算
    rmse_error = sqrt(mean(error_history.^2, 2));
    max_torque = max(abs(torque_history), [], 2);
    
    fprintf('\n=== 控制性能指标 ===\n');
    fprintf('关节1 RMSE误差: %.4f rad\n', rmse_error(1));
    fprintf('关节2 RMSE误差: %.4f rad\n', rmse_error(2));
    fprintf('关节1最大力矩: %.2f Nm\n', max_torque(1));
    fprintf('关节2最大力矩: %.2f Nm\n', max_torque(2));
end

% 运行主程序
main_torque_control();

5. 高级功能扩展

%% 高级功能:力控和柔顺控制
function force_control_example()
    % 力控制示例
    
    robot = TorqueControlArm([0; pi/4]);
    
    % 环境参数 - 假设在y=0.5处有平面
    wall_position = 0.5;
    wall_stiffness = 5000; % 环境刚度 [N/m]
    
    % 力控制参数
    desired_force = 10; % 期望接触力 [N]
    Kf = 0.5;          % 力控制增益
    
    % 仿真
    dt = 0.001; T = 3.0;
    steps = round(T/dt);
    
    for k = 1:steps
        t = (k-1)*dt;
        
        % 获取当前末端位置
        current_pos = robot.forward_kinematics(robot.q);
        
        % 检测接触
        if current_pos(2) >= wall_position
            % 计算接触力
            penetration = current_pos(2) - wall_position;
            contact_force = wall_stiffness * penetration;
            
            % 力控制
            force_error = desired_force - contact_force;
            
            % 调整期望位置
            delta_y = Kf * force_error * dt;
            desired_pos = current_pos + [0; -delta_y];
            
            % 位置控制维持接触力
            [q_des, ~] = robot.inverse_kinematics(desired_pos);
        else
            % 自由空间运动
            desired_pos = [0.4 + 0.2*sin(2*pi*t/T); 0.3];
            [q_des, ~] = robot.inverse_kinematics(desired_pos);
        end
        
        % 计算控制力矩
        tau = TorqueControllers.pd_control_with_gravity_comp(robot, q_des, [0;0], robot.q, robot.dq);
        
        % 更新动力学
        [q_new, dq_new] = robot.dynamics_update(tau, dt);
        robot.q = q_new;
        robot.dq = dq_new;
    end
end

参考代码 针对机械手臂力矩控制的matlab程序 www.3dddown.com/csa/63853.html

6. 说明

  1. 完整的动力学模型:包含质量矩阵、科里奥利力、重力和摩擦力
  2. 多种控制策略:计算力矩控制、PD+重力补偿、阻抗控制、自适应控制
  3. 轨迹生成:支持各种期望轨迹生成
  4. 性能分析:提供详细的性能指标和可视化
  5. 扩展性:易于添加新的控制算法和机械臂模型