• 机器人动力学模型与MATLAB仿真


    机器人刚体动力学由以下方程控制!!!

    1. startup_rvc
    2. mdl_puma560
    3. p560.dyn

    提前计算出来这些“disturbance”,然后在控制环路中将它“抵消”(有时候也叫前馈控制

    求出所需要的力矩,其中M项代表克服了机械臂的加速度惯量以及不同连杆之间的惯量影响所需力矩、C项代表了克服科里奥利力和离心力所需力矩、G项代表了克服地球引力力矩。

    Inverse Dynamics叫做反向动力学,它的作用是输入想要的关节速度(qd)、关节加速度(qdd)、关节角度(q),输出为每个关节所需要的力矩(u)。当然也有正向动力学(forward dynamics),它的作用和反向动力学相反,输入关节角度(q)、关节速度(qd)、每个关节的力矩(u),输出为每个关节的加速度(qdd)

    “前馈控制”的例子,它的作用是预先计算出所需的力矩,输入给控制器,“反馈”的存在是为了消除一些误差,例如摩擦力

    1. J=[-sin(q1)-sin(q1+q2) -sin(q1+q2);
    2. cos(q1)+cos(q1+q2) cos(q1+q2)];
    3. d_J=[-dq1*cos(q1)-(dq1+dq2)*cos(q1+q2) -(dq1+dq2)*cos(q1+q2);
    4. -dq1*sin(q1)-(dq1+dq2)*sin(q1+q2) -(dq1+dq2)*sin(q1+q2)];

    1. function torque_out = fcn(u_matrix,q1,q2)
    2. %% Robot Joint and mass parameters
    3. g=9.81;
    4. m1=0.3;
    5. m2=1;
    6. l1=0.2;
    7. l2=0.2;
    8. %% B = M Matrix
    9. B=[ (m1+m2)*l1^2+m2*l2^2+2*m2*l2*l1*cos(q2) (m2*l2^2+m2*l1*l2*cos(q2)) ; (m2*l2^2+m2*l1*l2*cos(q2)) m2*l2^2];
    10. torque_out= B* u_matrix ;
    11. end

    C=[-(m2*l1*l2*sin(q2)*(2*q1dot*q2dot+q2dot^2)) ; -m2*l1*l2*sin(q2)*q1dot^2];

    G=[(m1+m2)*g*l1*cos(q1)+m2*l2*g*cos(q1+q2) ; +m2*g*l2*cos(q1+q2)];

    Minv=[ (m2*l2^2)/(((m1+m2)*l1^2*l2^2*m2)-(m2^2*l1^2*l2^2*cos(q2))) -(m2*l2^2+m2*l1*l2*cos(q2))/(((m1+m2)*l1^2*l2^2*m2)-(m2^2*l1^2*l2^2*cos(q2))) ; -(m2*l2^2+m2*l1*l2*cos(q2))/(((m1+m2)*l1^2*l2^2*m2)-(m2^2*l1^2*l2^2*cos(q2))) ((m1+m2)*l1^2+m2*l2^2+2*m2*l2*l1*cos(q2))/(((m1+m2)*l1^2*l2^2*m2)-(m2^2*l1^2*l2^2*cos(q2)))];

    1. alfa = 6.7;beta = 3.4;
    2. epc = 3.0;eta = 0;
    3. m1 = 1;l1 = 1;
    4. lc1 = 1/2;I1 = 1/12;
    5. g = 9.8;
    6. e1 = m1*l1*lc1-I1-m1*l1^2;
    7. e2 = g/l1;
    8. M = [alfa+2*epc*cos(q2)*eta*sin(q2),beta+epc*cos(q2)+eta*sin(q2);beta+epc*cos(q2)+eta*sin(q2),beta];
    9. C = [(-2*epc*sin(q2)+2*eta*cos(q2))*dq2,(-epc*sin(q2)+eta*cos(q2)*dq2;(epc*sin(q2)-eta*cos(q2)*dq1,0];
    10. G = [epc*e2*cos(q1+q2)+eta*e2*sin(q1+q2)+(alfa-beta+e1)*e2*cos(q1);epc*e2*cos(q1+q2)+eta*e2*sin(q1+q2)];

    1. J=[-sin(q1)-sin(q1+q2) -sin(q1+q2);
    2. cos(q1)+cos(q1+q2) cos(q1+q2)];

    画圆轨迹:

    xc=[1.0-0.2*cos(pi*t) 1.0+0.2*sin(pi*t)]';

    dxc=[0.2*pi*sin(pi*t) 0.2*pi*cos(pi*t)]';

    ddxc=[0.2*pi^2*cos(pi*t) -0.2*pi^2*sin(pi*t)]';

    1. function [xd, yd] = fcn(r, t, w, x, y)
    2. alpha = t*w;
    3. xd = x + r*cos(alpha);
    4. yd = y + r*sin(alpha);
    5. end

    基于力矩的阻抗控制

    动力学模型如下

    阻抗控制模型如下

    把这个阻抗模型得到的加速度带入到机器人动力学模型中,消除加速度ddx非线性项,得到控制律

    基于模型的阻抗控制

    笛卡尔空间的机器人动力学模型可描述为:

    阻抗控制器可设计为:

    ————————————————————————————————

    BA的存在导致系统耦合,如果希望在与环境交互过程中保持线性并解耦,需要测量接触力:

    因此,

    正向动力学

    正运动学:

    雅克比矩阵:

    笛卡尔速度与及速度:

    定义末端实际位置与虚拟平衡位置的偏差:

    阻抗控制目标为:实现末端执行器标架相对于柔顺标架的偏差与末端执行器作用于环境的力旋量之间的二阶期望动态关系!

    刚性机器人在末端空间的动力学方程为:、

    其中:

    1. % 假设的二自由度机器人参数
    2. L1 = 1; % 连杆1的长度
    3. L2 = 1; % 连杆2的长度
    4. % 假设的关节角度(需要实时更新)
    5. q = [pi/4; pi/6]; % 初始关节角度(弧度制)
    6. % 计算末端执行器的位置(在笛卡尔空间中)
    7. % 这是一个简化的例子,实际中可能需要使用更复杂的正向运动学方程
    8. x = L1*cos(q(1)) + L2*cos(q(1) + q(2));
    9. y = L1*sin(q(1)) + L2*sin(q(1) + q(2));
    10. z = 0; % 假设机器人在二维平面上运动
    11. X = [x; y; z];
    12. % 计算雅可比矩阵(简化的例子)
    13. % 这里只考虑了平面情况,并且假设了简化的雅可比矩阵
    14. % 在实际应用中,雅可比矩阵需要根据机器人的实际结构来计算
    15. J = [-L1*sin(q(1)) - L2*sin(q(1) + q(2)), -L2*sin(q(1) + q(2));
    16. L1*cos(q(1)) + L2*cos(q(1) + q(2)), L2*cos(q(1) + q(2))];
    17. % 阻抗控制参数
    18. M_d = diag([1, 1, 1]); % 期望的惯性矩阵
    19. B_d = diag([2, 2, 2]); % 期望的阻尼矩阵
    20. K_d = diag([100, 100, 100]); % 期望的刚度矩阵
    21. % 期望的末端执行器位置、速度和加速度(需要实时更新)
    22. Xd = [1; 1; 0]; % 期望位置
    23. Xdot_d = [0; 0; 0]; % 期望速度
    24. Xddot_d = [0; 0; 0]; % 期望加速度(通常不需要直接指定)
    25. % 外部力(假设为0或根据传感器数据获取)
    26. F_ext = [0; 0; 0];
    27. % 阻抗控制律
    28. % 计算位置误差
    29. e = Xd - X;
    30. % 计算阻抗力
    31. F_impedance = -M_d*Xddot_d - B_d*Xdot_d - K_d*e;
    32. % 将阻抗力从笛卡尔空间转换到关节空间
    33. tau = J' * F_impedance;
    34. % 如果需要添加重力补偿或其他动力学项,可以在这里添加
    35. % 例如:tau = tau + g(q) + ...;
    1. function tau = impedance_control(q, qd, xd_desired, xdot_desired, xddot_desired)
    2. % 机械臂参数
    3. m1 = 1; m2 = 1; % 连杆质量
    4. l1 = 1; l2 = 1; % 连杆长度
    5. % 控制参数
    6. K_d = diag([100, 100]); % 阻抗控制中的刚度系数
    7. D_d = diag([20, 20]); % 阻抗控制中的阻尼系数
    8. % 运动学和动力学矩阵计算
    9. x = forward_kinematics(q, l1, l2);
    10. J = jacobian(q, l1, l2);
    11. M = inertia_matrix(q, m1, m2, l1, l2);
    12. C = coriolis_matrix(q, qd, m1, m2, l1, l2);
    13. g = gravity_vector(q, m1, m2, l1, l2);
    14. % Lambda和mu的计算
    15. Lambda = inv(J' * inv(M) * J);
    16. mu = inv(J') * (C - M * inv(J) * jacobian_dot(q, qd, l1, l2)) * inv(J);
    17. % 误差计算
    18. x_tilde = x - xd_desired;
    19. xdot_tilde = J * qd - xdot_desired;
    20. % 控制律计算
    21. tau = g + J' * (Lambda * xddot_desired + mu * (J * qd)) - J' * Lambda * (K_d * x_tilde + D_d * xdot_tilde);
    22. end
    23. function x = forward_kinematics(q, l1, l2)
    24. x = [l1 * cos(q(1)) + l2 * cos(q(1) + q(2));
    25. l1 * sin(q(1)) + l2 * sin(q(1) + q(2))];
    26. end
    27. function J = jacobian(q, l1, l2)
    28. J = [-l1 * sin(q(1)) - l2 * sin(q(1) + q(2)), -l2 * sin(q(1) + q(2));
    29. l1 * cos(q(1)) + l2 * cos(q(1) + q(2)), l2 * cos(q(1) + q(2))];
    30. end
    31. function J_dot = jacobian_dot(q, qd, l1, l2)
    32. J_dot = [-l1 * cos(q(1)) * qd(1) - l2 * cos(q(1) + q(2)) * (qd(1) + qd(2)), -l2 * cos(q(1) + q(2)) * (qd(1) + qd(2));
    33. -l1 * sin(q(1)) * qd(1) - l2 * sin(q(1) + q(2)) * (qd(1) + q(2)), -l2 * sin(q(1) + q(2)) * (qd(1) + q(2))];
    34. end
    35. function M = inertia_matrix(q, m1, m2, l1, l2)
    36. M11 = m1 * l1^2 + m2 * (l1^2 + 2 * l1 * l2 * cos(q(2)) + l2^2);
    37. M12 = m2 * (l1 * l2 * cos(q(2)) + l2^2);
    38. M21 = M12;
    39. M22 = m2 * l2^2;
    40. M = [M11, M12; M21, M22];
    41. end
    42. function C = coriolis_matrix(q, qd, m1, m2, l1, l2)
    43. C11 = -m2 * l1 * l2 * sin(q(2)) * qd(2);
    44. C12 = -m2 * l1 * l2 * sin(q(2)) * (qd(1) + qd(2));
    45. C21 = m2 * l1 * l2 * sin(q(2)) * qd(1);
    46. C22 = 0;
    47. C = [C11, C12; C21, C22];
    48. end
    49. function g = gravity_vector(q, m1, m2, l1, l2)
    50. g1 = (m1 * l1 + m2 * l1) * 9.81 * cos(q(1)) + m2 * l2 * 9.81 * cos(q(1) + q(2));
    51. g2 = m2 * l2 * 9.81 * cos(q(1) + q(2));
    52. g = [g1; g2];
    53. end

    1. function [q_dot, q_ddot] = robot_dynamics(q, qd, tau)
    2. % 机械臂参数
    3. m1 = 1; m2 = 1; % 连杆质量
    4. l1 = 1; l2 = 1; % 连杆长度
    5. % 计算动力学矩阵
    6. M = inertia_matrix(q, m1, m2, l1, l2);
    7. C = coriolis_matrix(q, qd, m1, m2, l1, l2);
    8. g = gravity_vector(q, m1, m2, l1, l2);
    9. % 动力学方程求解
    10. q_ddot = inv(M) * (tau - C * qd - g);
    11. % 更新关节速度
    12. q_dot = qd;
    13. end
    14. function M = inertia_matrix(q, m1, m2, l1, l2)
    15. M11 = m1 * l1^2 + m2 * (l1^2 + 2 * l1 * l2 * cos(q(2)) + l2^2);
    16. M12 = m2 * (l1 * l2 * cos(q(2)) + l2^2);
    17. M21 = M12;
    18. M22 = m2 * l2^2;
    19. M = [M11, M12; M21, M22];
    20. end
    21. function C = coriolis_matrix(q, qd, m1, m2, l1, l2)
    22. C11 = -m2 * l1 * l2 * sin(q(2)) * qd(2);
    23. C12 = -m2 * l1 * l2 * sin(q(2)) * (qd(1) + qd(2));
    24. C21 = m2 * l1 * l2 * sin(q(2)) * qd(1);
    25. C22 = 0;
    26. C = [C11, C12; C21, C22];
    27. end
    28. function g = gravity_vector(q, m1, m2, l1, l2)
    29. g1 = (m1 * l1 + m2 * l1) * 9.81 * cos(q(1)) + m2 * l2 * 9.81 * cos(q(1) + q(2));
    30. g2 = m2 * l2 * 9.81 * cos(q(1) + q(2));
    31. g = [g1; g2];
    32. end

    1. % 二自由度机器人末端空间阻抗控制仿真程序
    2. % 机械臂参数
    3. m1 = 1; m2 = 1; % 连杆质量
    4. l1 = 1; l2 = 1; % 连杆长度
    5. % 初始状态
    6. q = [pi/4; pi/4]; % 关节角度
    7. qd = [0; 0]; % 关节角速度
    8. x = forward_kinematics(q); % 末端位置
    9. xd = [0; 0]; % 末端速度
    10. % 控制参数
    11. K_d = diag([100, 100]); % 阻抗控制中的刚度系数
    12. D_d = diag([20, 20]); % 阻抗控制中的阻尼系数
    13. % 仿真参数
    14. dt = 0.01; % 仿真时间步长
    15. t_final = 10; % 仿真总时间
    16. time = 0:dt:t_final;
    17. % 期望轨迹
    18. xd_desired = [0.5*sin(0.1*time); 0.5*cos(0.1*time)];
    19. xdot_desired = [0.05*cos(0.1*time); -0.05*sin(0.1*time)];
    20. xddot_desired = [-0.005*sin(0.1*time); -0.005*cos(0.1*time)];
    21. % 数据存储
    22. q_history = zeros(2, length(time));
    23. x_history = zeros(2, length(time));
    24. for i = 1:length(time)
    25. % 前向运动学
    26. x = forward_kinematics(q);
    27. J = jacobian(q);
    28. % 计算Lambda, mu
    29. M = inertia_matrix(q, m1, m2, l1, l2);
    30. C = coriolis_matrix(q, qd, m1, m2, l1, l2);
    31. Lambda = inv(J' * inv(M) * J);
    32. mu = inv(J') * (C - M * inv(J) * jacobian_dot(q, qd)) * inv(J);
    33. % 误差计算
    34. x_tilde = x - xd_desired(:, i);
    35. xdot_tilde = J * qd - xdot_desired(:, i);
    36. % 控制律计算
    37. g = gravity_vector(q, m1, m2, l1, l2);
    38. tau = g + J' * (Lambda * xddot_desired(:, i) + mu * (J * qd)) ...
    39. - J' * Lambda * (K_d * x_tilde + D_d * xdot_tilde);
    40. % 动力学方程求解
    41. qdd = inv(M) * (tau - C * qd - g);
    42. % 状态更新
    43. qd = qd + qdd * dt;
    44. q = q + qd * dt;
    45. % 数据存储
    46. q_history(:, i) = q;
    47. x_history(:, i) = x;
    48. end
    49. % 绘图
    50. figure;
    51. subplot(2, 1, 1);
    52. plot(time, q_history);
    53. title('关节角度随时间变化');
    54. xlabel('时间 (s)');
    55. ylabel('关节角度 (rad)');
    56. legend('q1', 'q2');
    57. subplot(2, 1, 2);
    58. plot(time, x_history);
    59. title('末端位置随时间变化');
    60. xlabel('时间 (s)');
    61. ylabel('末端位置 (m)');
    62. legend('x', 'y');
    63. % 函数定义
    64. function x = forward_kinematics(q)
    65. l1 = 1; l2 = 1;
    66. x = [l1 * cos(q(1)) + l2 * cos(q(1) + q(2));
    67. l1 * sin(q(1)) + l2 * sin(q(1) + q(2))];
    68. end
    69. function J = jacobian(q)
    70. l1 = 1; l2 = 1;
    71. J = [-l1 * sin(q(1)) - l2 * sin(q(1) + q(2)), -l2 * sin(q(1) + q(2));
    72. l1 * cos(q(1)) + l2 * cos(q(1) + q(2)), l2 * cos(q(1) + q(2))];
    73. end
    74. function J_dot = jacobian_dot(q, qd)
    75. l1 = 1; l2 = 1;
    76. J_dot = [-l1 * cos(q(1)) * qd(1) - l2 * cos(q(1) + q(2)) * (qd(1) + qd(2)), -l2 * cos(q(1) + q(2)) * (qd(1) + qd(2));
    77. -l1 * sin(q(1)) * qd(1) - l2 * sin(q(1) + q(2)) * (qd(1) + qd(2)), -l2 * sin(q(1) + q(2)) * (qd(1) + qd(2))];
    78. end
    79. function M = inertia_matrix(q, m1, m2, l1, l2)
    80. M11 = m1 * l1^2 + m2 * (l1^2 + 2 * l1 * l2 * cos(q(2)) + l2^2);
    81. M12 = m2 * (l1 * l2 * cos(q(2)) + l2^2);
    82. M21 = M12;
    83. M22 = m2 * l2^2;
    84. M = [M11, M12; M21, M22];
    85. end
    86. function C = coriolis_matrix(q, qd, m1, m2, l1, l2)
    87. C11 = -m2 * l1 * l2 * sin(q(2)) * qd(2);
    88. C12 = -m2 * l1 * l2 * sin(q(2)) * (qd(1) + qd(2));
    89. C21 = m2 * l1 * l2 * sin(q(2)) * qd(1);
    90. C22 = 0;
    91. C = [C11, C12; C21, C22];
    92. end
    93. function g = gravity_vector(q, m1, m2, l1, l2)
    94. g1 = (m1 * l1 + m2 * l1) * 9.81 * cos(q(1)) + m2 * l2 * 9.81 * cos(q(1) + q(2));
    95. g2 = m2 * l2 * 9.81 * cos(q(1) + q(2));
    96. g = [g1; g2];
    97. end
    1. function impedance_control_simulation()
    2. % 机器人参数
    3. m1 = 1; m2 = 1; % 连杆质量
    4. l1 = 1; l2 = 1; % 连杆长度
    5. % 阻抗控制参数
    6. Kd = diag([10, 10]); % 刚度矩阵
    7. Dd = diag([5, 5]); % 阻尼矩阵
    8. % 期望轨迹:圆形运动
    9. t = linspace(0, 10, 1000); % 时间范围
    10. x_d = [0.5*cos(t); 0.5*sin(t)]; % 期望末端位置
    11. dx_d = [-0.5*sin(t); 0.5*cos(t)]; % 期望末端速度
    12. ddx_d = [-0.5*cos(t); -0.5*sin(t)]; % 期望末端加速度
    13. % 初始化机器人状态
    14. q = [pi/4; pi/4]; % 关节角度
    15. dq = [0; 0]; % 关节速度
    16. % 仿真参数
    17. dt = t(2) - t(1); % 时间步长
    18. % 存储数据用于绘图
    19. q_history = zeros(2, length(t));
    20. dq_history = zeros(2, length(t));
    21. x_history = zeros(2, length(t));
    22. % 开始仿真
    23. for i = 1:length(t)
    24. % 计算当前机器人状态
    25. x = forward_kinematics(q, l1, l2); % 计算当前末端位置
    26. J = jacobian(q, l1, l2); % 计算当前雅可比矩阵
    27. M = inertia_matrix(q, m1, m2, l1, l2); % 计算当前动力学矩阵
    28. C = coriolis_matrix(q, dq, m1, m2, l1, l2); % 计算当前科氏力矩
    29. g = gravity_vector(q, m1, m2, l1, l2); % 计算当前重力矢量
    30. % 计算控制律中的各项
    31. Lambda = inv(J' * inv(M) * J); % 阻抗矩阵
    32. mu = J' * (C - M * inv(J) * (J' * inv(M) * J)) * inv(J); % 阻抗补偿项
    33. Lambda_d = eye(2); % 期望阻抗矩阵(假设为单位矩阵)
    34. F_ext = [0; 0]; % 外部力(暂时设为零向量)
    35. tilde_x = x - x_d(:, i); % 位置误差
    36. dot_tilde_x = J * dq - dx_d(:, i); % 速度误差
    37. % 计算控制力
    38. tau = g + J' * (Lambda * ddx_d(:, i) + mu * dx_d(:, i)) - ...
    39. J' * Lambda * Lambda_d * (Kd * tilde_x + Dd * dot_tilde_x) + ...
    40. J' * (Lambda * Lambda_d^(-1) - eye(2)) * F_ext;
    41. % 使用机器人动力学方程求解关节加速度
    42. q_ddot = inv(M) * (tau - C * dq - g);
    43. % 更新机器人状态
    44. dq = dq + q_ddot * dt; % 更新关节速度
    45. q = q + dq * dt; % 更新关节角度
    46. % 存储数据用于绘图
    47. q_history(:, i) = q;
    48. dq_history(:, i) = dq;
    49. x_history(:, i) = x;
    50. end
    51. % 绘制结果
    52. figure;
    53. subplot(3, 1, 1);
    54. plot(t, q_history);
    55. title('Joint Angles');
    56. xlabel('Time (s)');
    57. ylabel('Angle (rad)');
    58. legend('q1', 'q2');
    59. subplot(3, 1, 2);
    60. plot(t, dq_history);
    61. title('Joint Velocities');
    62. xlabel('Time (s)');
    63. ylabel('Velocity (rad/s)');
    64. legend('dq1', 'dq2');
    65. subplot(3, 1, 3);
    66. plot(x_history(1, :), x_history(2, :), 'b', x_d(1, :), x_d(2, :), 'r--');
    67. title('End Effector Path');
    68. xlabel('X Position (m)');
    69. ylabel('Y Position (m)');
    70. legend('Actual Path', 'Desired Path');
    71. end
    72. function x = forward_kinematics(q, l1, l2)
    73. x = [l1 * cos(q(1)) + l2 * cos(q(1) + q(2));
    74. l1 * sin(q(1)) + l2 * sin(q(1) + q(2))];
    75. end
    76. function J = jacobian(q, l1, l2)
    77. J = [-l1 * sin(q(1)) - l2 * sin(q(1) + q(2)), -l2 * sin(q(1) + q(2));
    78. l1 * cos(q(1)) + l2 * cos(q(1) + q(2)), l2 * cos(q(1) + q(2))];
    79. end
    80. function M = inertia_matrix(q, m1, m2, l1, l2)
    81. M11 = m1 * l1^2 + m2 * (l1^2 + 2 * l1 * l2 * cos(q(2)) + l2^2);
    82. M12 = m2 * (l1 * l2 * cos(q(2)) + l2^2);
    83. M21 = M12;
    84. M22 = m2 * l2^2;
    85. M = [M11, M12; M21, M22];
    86. end
    87. function C = coriolis_matrix(q, dq, m1, m2, l1, l2)
    88. C11 = -m2 * l1 * l2 * sin(q(2)) * dq(2);
    89. C12 = -m2 * l1 * l2 * sin(q(2)) * (dq(1) + dq(2));
    90. C21 = m2 * l1 * l2 * sin(q(2)) * dq(1);
    91. C22 = 0;
    92. C = [C11, C12; C21, C22];
    93. end
    94. function g = gravity_vector(q, m1, m2, l1, l2)
    95. g1 = (m1 * l1 + m2 * l1) * 9.81 * cos(q(1)) + m2 * l2 * 9.81 * cos(q(1) + q(2));
    96. g2 = m2 * l2 * 9.81 * cos(q(1) + q(2));
    97. g = [g1; g2];
    98. end
    1. function impedance_control_simulation()
    2. % 机器人参数
    3. m1 = 1; m2 = 1; % 连杆质量
    4. l1 = 1; l2 = 1; % 连杆长度
    5. % 阻抗控制参数
    6. Kd = [10, 0.2; 0.3, 5]; % 阻抗控制中的期望刚度矩阵
    7. Dd = [5, 0.1; 0.2, 5]; % 阻抗控制中的期望阻尼矩阵
    8. Lambda_d = [0.8, 0.001; 0.002, 0.6]; % 阻抗控制中的期望惯量矩阵
    9. % 期望轨迹:圆形运动
    10. t = linspace(0, 10, 1000); % 时间范围
    11. x_d = [0.5*cos(t); 0.5*sin(t)]; % 期望末端位置
    12. dx_d = [-0.5*sin(t); 0.5*cos(t)]; % 期望末端速度
    13. ddx_d = [-0.5*cos(t); -0.5*sin(t)]; % 期望末端加速度
    14. % 障碍物位置
    15. obstacle_pos = [0.2; 0.2];
    16. obstacle_radius = 0.15; % 障碍物半径
    17. k_spring = 1000; % 弹簧刚度
    18. b_damper = 10; % 阻尼系数
    19. % 初始化机器人状态
    20. q = [pi/4; pi/4]; % 关节角度
    21. dq = [0; 0]; % 关节速度
    22. % 仿真参数
    23. dt = t(2) - t(1); % 时间步长
    24. % 存储数据用于绘图
    25. q_history = zeros(2, length(t));
    26. dq_history = zeros(2, length(t));
    27. x_history = zeros(2, length(t));
    28. F_ext_history = zeros(2, length(t));
    29. % 开始仿真
    30. for i = 1:length(t)
    31. % 计算当前机器人状态
    32. x = forward_kinematics(q, l1, l2); % 计算当前末端位置
    33. J = jacobian(q, l1, l2); % 计算当前雅可比矩阵
    34. M = inertia_matrix(q, m1, m2, l1, l2); % 计算当前动力学矩阵
    35. C = coriolis_matrix(q, dq, m1, m2, l1, l2); % 计算当前科氏力矩
    36. g = gravity_vector(q, m1, m2, l1, l2); % 计算当前重力矢量
    37. % 计算接触力
    38. dist_to_obstacle = norm(x - obstacle_pos);
    39. if dist_to_obstacle < obstacle_radius
    40. penetration_depth = obstacle_radius - dist_to_obstacle;
    41. contact_normal = (x - obstacle_pos) / dist_to_obstacle;
    42. F_ext = k_spring * penetration_depth * contact_normal - b_damper * J * dq;
    43. else
    44. F_ext = [0; 0];
    45. end
    46. % 计算阻抗控制律中的各项
    47. Lambda = inv(J' * inv(M) * J); % 阻抗矩阵
    48. mu = J' * (C - M * inv(J) * (jacobian_dot(q, dq, l1, l2))) * inv(J); % 阻抗补偿项
    49. tilde_x = x - x_d(:, i); % 位置误差
    50. dot_tilde_x = J * dq - dx_d(:, i); % 速度误差
    51. % 计算控制力
    52. tau = g + J' * (Lambda * ddx_d(:, i) + mu * dx_d(:, i)) - ...
    53. J' * Lambda * Lambda_d * (Kd * tilde_x + Dd * dot_tilde_x) + ...
    54. J' * (Lambda / Lambda_d - eye(2)) * F_ext;
    55. % 使用机器人动力学方程求解关节加速度
    56. q_ddot = inv(M) * (tau - C * dq - g + J' * F_ext);
    57. % 更新机器人状态
    58. dq = dq + q_ddot * dt; % 更新关节速度
    59. q = q + dq * dt; % 更新关节角度
    60. % 存储数据用于绘图
    61. q_history(:, i) = q;
    62. dq_history(:, i) = dq;
    63. x_history(:, i) = x;
    64. dx_history(:, i) = J * dq;
    65. F_ext_history(:, i) = F_ext;
    66. % 调试输出
    67. if mod(i, 100) == 0
    68. disp(['Time: ', num2str(t(i)), ' s']);
    69. disp(['End effector position: [', num2str(x(1)), ', ', num2str(x(2)), ']']);
    70. disp(['Distance to obstacle: ', num2str(dist_to_obstacle)]);
    71. disp(['Contact force: [', num2str(F_ext(1)), ', ', num2str(F_ext(2)), ']']);
    72. end
    73. end
    74. % 绘制结果
    75. figure;
    76. subplot(3, 1, 1);
    77. plot(t, x_history);
    78. hold on;
    79. plot(t, x_d, '--');
    80. title('End Effector Position');
    81. xlabel('Time (s)');
    82. ylabel('Position (m)');
    83. legend('x', 'y', 'x_d', 'y_d');
    84. subplot(3, 1, 2);
    85. plot(t, dx_history);
    86. hold on;
    87. plot(t, dx_d, '--');
    88. title('End Effector Velocity');
    89. xlabel('Time (s)');
    90. ylabel('Velocity (m/s)');
    91. legend('dx', 'dy', 'dx_d', 'dy_d');
    92. subplot(3, 1, 3);
    93. plot(x_history(1, :), x_history(2, :), 'b', x_d(1, :), x_d(2, :), 'r--');
    94. hold on;
    95. viscircles(obstacle_pos', obstacle_radius, 'LineStyle', '--');
    96. title('End Effector Path');
    97. xlabel('X Position (m)');
    98. ylabel('Y Position (m)');
    99. legend('Actual Path', 'Desired Path', 'Obstacle');
    100. figure;
    101. plot(t, F_ext_history);
    102. title('Contact Force');
    103. xlabel('Time (s)');
    104. ylabel('Force (N)');
    105. legend('F_x', 'F_y');
    106. end
    107. function x = forward_kinematics(q, l1, l2)
    108. x = [l1 * cos(q(1)) + l2 * cos(q(1) + q(2));
    109. l1 * sin(q(1)) + l2 * sin(q(1) + q(2))];
    110. end
    111. function J = jacobian(q, l1, l2)
    112. J = [-l1 * sin(q(1)) - l2 * sin(q(1) + q(2)), -l2 * sin(q(1) + q(2));
    113. l1 * cos(q(1)) + l2 * cos(q(1) + q(2)), l2 * cos(q(1) + q(2))];
    114. end
    115. function J_dot = jacobian_dot(q, dq, l1, l2)
    116. J_dot = [-l1 * cos(q(1)) * dq(1) - l2 * cos(q(1) + q(2)) * (dq(1) + dq(2)), -l2 * cos(q(1) + q(2)) * (dq(1) + dq(2));
    117. -l1 * sin(q(1)) * dq(1) - l2 * sin(q(1) + q(2)) * (dq(1) + dq(2)), -l2 * sin(q(1) + q(2)) * (dq(1) + dq(2))];
    118. end
    119. function M = inertia_matrix(q, m1, m2, l1, l2)
    120. M11 = m1 * l1^2 + m2 * (l1^2 + 2 * l1 * l2 * cos(q(2)) + l2^2);
    121. M12 = m2 * (l1 * l2 * cos(q(2)) + l2^2);
    122. M21 = M12;
    123. M22 = m2 * l2^2;
    124. M = [M11, M12; M21, M22];
    125. end
    126. function C = coriolis_matrix(q, dq, m1, m2, l1, l2)
    127. C11 = -m2 * l1 * l2 * sin(q(2)) * dq(2);
    128. C12 = -m2 * l1 * l2 * sin(q(2)) * (dq(1) + dq(2));
    129. C21 = m2 * l1 * l2 * sin(q(2)) * dq(1);
    130. C22 = 0;
    131. C = [C11, C12; C21, C22];
    132. end
    133. function g = gravity_vector(q, m1, m2, l1, l2)
    134. g1 = (m1 * l1 + m2 * l1) * 9.81 * cos(q(1)) + m2 * l2 * 9.81 * cos(q(1) + q(2));
    135. g2 = m2 * l2 * 9.81 * cos(q(1) + q(2));
    136. g = [g1; g2];
    137. end

    参考文献:

    平面2R机器人运动学与动力学建模基于平面2R机器人谈谈运动学和动力学建模的应用icon-default.png?t=N7T8https://mp.weixin.qq.com/s/1gQTDHpyUkTMst_OdVFlnw

    MATLAB 中的机械臂算法——动力学系列技术文章icon-default.png?t=N7T8https://mp.weixin.qq.com/s/opQcpv02sysIcz8seg3lkQ

    刚性机器人笛卡尔阻抗控制算法-腾讯云开发者社区-腾讯云机器人阻抗控制是机器人力控制中的一种重要方式。了解机器人的阻抗控制需要首先了解刚性机器人的阻抗控制方法,并且首先需要了解刚性机器人的动力学方程和运动学方程。在本栏中给出的机器人为非冗余机器人,即机器人的关节空间自由度与笛卡尔空间运动自由度是相等的。icon-default.png?t=N7T8https://cloud.tencent.com/developer/article/1753836

    https://zhuanlan.zhihu.com/p/586836394icon-default.png?t=N7T8https://zhuanlan.zhihu.com/p/586836394

    【云+社区年度征文】机器人力控制算法与实际应用详解-腾讯云开发者社区-腾讯云机器人力控制应用在机器人控制任务中的方方面面,其也是衡量一个机器人本体控制水平的衡量标准。机器人力控制兼顾机器人本体特性与人机交互等任务,使得机器人在发挥自身运动灵巧性的同时与人进行友好的交互。可以说机器人的力控制是机器人实际走向人类生活的关键技术。 本文详细阐述机器人的力控制的概念和应用,并且简要给出算法实现步骤。icon-default.png?t=N7T8https://cloud.tencent.com/developer/article/1754382

  • 相关阅读:
    Redis桌面管理工具RedisDesktopManager
    YGG 西班牙 subDAO——Ola GG 正式成立
    排序算法-插入排序详解
    帆软报表决策系统 上传excel文件
    解析Flutter应用在iOS环境中的性能优化技巧
    c语言 编程及答案
    Linux系统IO和标准IO的接口函数
    搜题公众号搭建
    详解HTML5新增的多媒体标签
    数据准备之日志采集发展历程
  • 原文地址:https://blog.csdn.net/weixin_51367832/article/details/139333350