该实例演示了如何在闭环控制下仿真机器人的关节空间运动。
从机器人库中加载ABB IRB-120Tloadrobot
函数。
机器人= loadrobot (“abbIrb120T”,“DataFormat”,“列”,“重力”[0 0 -9.81]);numJoints =元素个数(homeConfiguration(机器人));
定义仿真参数,包括仿真轨迹的时间范围,初始状态为(联合配置;jointVelocity]
,关节空间设定点。
%设置仿真参数tSpan = 0:0.01:0.5;q0 = 0 (numJoints, 1);q0(2) =π/ 4;偏离中心的东西qd0 = 0 (numJoints, 1);initialState = [q0;qd0];%建立联合控制目标targetJointPosition = [pi/2 pi/3 pi/6 2*pi/3 -pi/2 -pi/3]';targetJointVelocity = 0 (numJoints, 1);targetJointAcceleration = 0 (numJoints, 1);
想象目标位置。
显示(机器人,targetJointPosition)
XLim: [-1 1] YLim: [-1 1] XScale: 'linear' YScale: 'linear' gridlinstyle: '-' Position:[0.1300 0.1100 0.7750 0.8150]单位:'normalized'显示所有属性
使用一个jointSpaceMotionModel
对象,仿真了该模型在多种控制器下的闭环运动。这个例子比较了其中一些。每个实例使用导数
函数来计算状态导数。这里,状态是2n -元素的向量(联合配置;关节速度)
,在那里n关节的数量是否相关rigidBodyTree
目的。
计算 - 扭矩控制使用逆动态计算来补偿机器人动态。基于二阶响应,控制器驱动每个接头的闭环错误动态。
创建一个jointSpaceMotionModel
并指定机器人模型。设置“MotionType”
来“ComputedTorqueControl”
.使用时更新错误动态updateErrorDynamicsFromStep
并分别指定所需的沉降时间和超调量。或者,您可以直接在对象中设置阻尼比和固有频率。
computedTorqueMotion = jointSpaceMotionModel (“RigidBodyTree”,机器人,“MotionType”,“ComputedTorqueControl”);updateErrorDynamicsFromStep (computedTorqueMotion, 0.2, 0.1);
这个运动模型需要提供位置、速度和加速度。
qDesComputedTorque = [targetJointPosition;targetJointVelocity;targetJointAcceleration];
要查看该控制器在Simulink中的实际示例,请参见金宝app使用机器人操作机块进行安全轨迹跟踪控制的例子。
采用独立的关节控制,将每个关节建模为具有二阶跟踪响应的单独系统。这种类型的模型是一种理想化的行为,在响应较慢或动力学对合成轨迹没有显著影响时使用最好。在这些情况下,它的行为将与计算扭矩控制相同,但计算开销更小。
创建另一个joinSpaceMotionModel
使用“IndependentJointMotion”
运动类型。
IndepJointMotion = jointSpaceMotionModel (“RigidBodyTree”,机器人,“MotionType”,“IndependentJointMotion”);updateErrorDynamicsFromStep (IndepJointMotion, 0.2, 0.1);
这个运动模型需要提供位置、速度和加速度。
qDesIndepJoint = [targetJointPosition;targetJointVelocity;targetJointAcceleration];
比例导数控制,或PD控制,结合重力补偿与比例和导数增益。尽管相对于其他封闭形式的模型更简单,PD控制器对于所有正增益值都是稳定的,这使得它成为一个理想的选择。这里PD增益设为n——- - - - - -n矩阵,n关节的数量是否相关rigidBodyTree
目的。对于这个机器人,n= 6。此外,PD控制不需要加速度剖面,所以它的状态向量只是一个2n关节构型和关节速度的元向量。
pdMotion = jointSpaceMotionModel (“RigidBodyTree”,机器人,“MotionType”,“PDControl”);pdMotion。Kp =诊断接头(300 * (1,6);pdMotion。Kd =诊断接头(10 * 1 (1,6);
这个运动模型需要提供位置和速度。
qdespd = [targetjointposition;targetjointvelocity];
的导数
函数输出状态导数,它可以用常微分方程(ODE)求解器如积分ODE45.
.对于每个运动模型,ODE求解器输出a米-元素列向量覆盖tspan
和2 -米2的矩阵n每个时刻的元素状态向量。
计算每个运动模型的轨迹,使用最合适的ODE求解器为每个系统。
[tComputedTorque, yComputedTorque] =数值(@ (t, y)导数(computedTorqueMotion y qDesComputedTorque) tSpan, initialState);[tIndepJoint, yIndepJoint] =数值(@ (t, y)导数(IndepJointMotion y qDesIndepJoint) tSpan, initialState);(兼总经理,yPD) = ode15s (@ (t, y)导数(pdMotion y qDesPD) tSpan, initialState);
模拟完成后,并排比较结果。每个图在顶部显示关节位置,在底部显示速度。虚线表示参考轨迹,实线显示模拟响应。
计算转矩控制图次要情节(2,1,1)情节(tComputedTorque, yComputedTorque (:, 1: numJoints))%接头位置持有所有情节(tComputedTorque targetJointPosition *(1,长度(tComputedTorque)),“——”)%联合定位点标题(“计算扭矩运动:关节位置”)Xlabel(“时间(s)”) ylabel (“位置(rad)”次要情节(2,1,2)情节(tComputedTorque, yComputedTorque (:, numJoints + 1:结束)%连接速度标题(“联合速度”)Xlabel(“时间(s)”) ylabel (“速度(rad / s)”)
在下面的图中,使用独立的关节控制来确认所计算的力矩运动在某些简化的假设下是等效的。
%独立关节运动figure subplot(2,1,1) plot(tIndepJoint,yIndepJoint(:,1: numnodes)) hold所有情节(tIndepJoint targetJointPosition *(1,长度(tIndepJoint)),“——”)标题(“独立关节运动:位置”)Xlabel(“时间(s)”) ylabel (“位置(rad)”次要情节(2,1,2);情节(tIndepJoint yIndepJoint (:, numJoints + 1:结束)标题(“联合速度”)Xlabel(“时间(s)”) ylabel (“速度(rad / s)”)
最后,PD控制器使用相当激进的增益来实现类似的上升时间,但与其他方法不同的是,单个关节的行为不同,因为每个关节和相关的机构有轻微不同的动态特性,这些动态特性没有被控制器补偿。
% PD与重力补偿figure subplot(2,1,1) plot(tPD,yPD(:,1: numnodes)) hold所有情节(兼总经理,targetJointPosition *(1,长度(兼总经理)),“——”)标题('PD控制关节运动:位置')Xlabel(“时间(s)”) ylabel (“位置(rad)”) subplot(2,1,2) plot(tPD,yPD(:, numnodes +1:end))“联合速度”)Xlabel(“时间(s)”) ylabel (“速度(rad / s)”)
为了查看这种行为在3-D中是什么样子,下面的示例帮助实时绘制机器人运动。第三个输入是每个样本之间的帧数。
exampleHelperRigidBodyTreeAnimation(机器人yComputedTorque 1);
exampleHelperRigidBodyTreeAnimation(机器人yIndepJoint 1);
exampleHelperRigidBodyTreeAnimation(机器人yPD 1);