设计具有多个运动学约束的到达轨迹

如何使用广义逆运动学来规划一个机械臂的关节空间轨迹?

结合多个约束条件,生成一个轨迹,将夹持器导向放在桌子上的杯子。这些约束保证了夹持器以直线接近杯子,并且夹持器保持在与桌子的安全距离,而不需要事先确定夹持器的姿态。

设置机器人模型

使用KUKA LBR iiwa(7自由度机器人机械手)的模型。importrobot从存储在URDF (Unified Robot description Format)文件中的描述中生成rigidBodyTree模型。

lbr = importrobot('iiwa14.urdf'); % 14 kg payload version
lbr.DataFormat = 'row';
gripper = 'iiwa_link_ee_kuka';

定义杯子的尺寸:

cupHeight = 0.2;
cupRadius = 0.05;
cupPosition = [-0.5, 0.5, cupHeight/2];

在机器人模型中添加一个固定的物体来代表杯子的中心

body = rigidBody('cupFrame');
setFixedTransform(body.Joint, trvec2tform(cupPosition))
addBody(lbr, body, lbr.BaseName);

描述规划问题:

目标是生成一系列满足以下条件的机器人构型:

(1)在主配置中启动

(2)机器人构型无突变

(3)保持夹持器距“桌子”至少5厘米(z = 0)

(4)当杯子靠近时,手爪应该与杯子对齐

(5)用夹持器从杯子中心5厘米处完成

用约束对象来生成满足这些条件的机器人配置。

生成的轨迹由5个构型路标点组成。

第一个路径点q0被设置为home配置。使用repmat在qwaypoint中预分配其余配置。

numWaypoints = 5;
q0 = homeConfiguration(lbr);
qWaypoints = repmat(q0, numWaypoints, 1);

创建一个接受以下约束输入的generalizedinverse运动学求解器:

(1)笛卡尔界限-限制抓手的高度

(2)位置目标-指定杯子相对于夹持器的位置

(3)目标约束-将夹持器对准杯轴

(4)定位目标-在接近杯子时保持抓手的固定方向

(5)关节位置边界-限制路点之间关节位置的变化

gik = generalizedInverseKinematics('RigidBodyTree', lbr, ...
    'ConstraintInputs', {'cartesian','position','aiming','orientation','joint'})
gik = 
  generalizedInverseKinematics with properties:

      NumConstraints: 5
    ConstraintInputs: {1x5 cell}
       RigidBodyTree: [1x1 rigidBodyTree]
     SolverAlgorithm: 'BFGSGradientProjection'
    SolverParameters: [1x1 struct]

创建约束对象

创建作为输入传递给求解器的约束对象。这些对象包含每个约束所需的参数。根据需要在调用求解器之间修改这些参数。

创建一个笛卡尔边界约束,要求夹持器至少高于桌子5厘米(负z方向)。

所有其他值都被赋为inf或-inf

heightAboveTable = constraintCartesianBounds(gripper);
heightAboveTable.Bounds = [-inf, inf; ...
                           -inf, inf; ...
                           0.05, inf]
heightAboveTable = 
  constraintCartesianBounds with properties:

        EndEffector: 'iiwa_link_ee_kuka'
      ReferenceBody: ''
    TargetTransform: [4x4 double]
             Bounds: [3x2 double]
            Weights: [1 1 1]

在杯子相对于夹持器的位置上创建一个约束,公差为5毫米。

distanceFromCup = constraintPositionTarget('cupFrame');
distanceFromCup.ReferenceBody = gripper;
distanceFromCup.PositionTolerance = 0.005
distanceFromCup = 
  constraintPositionTarget with properties:

          EndEffector: 'cupFrame'
        ReferenceBody: 'iiwa_link_ee_kuka'
       TargetPosition: [0 0 0]
    PositionTolerance: 0.0050
              Weights: 1

通过将目标放置在机器人上方,创建一个瞄准约束,要求iiwa_link_ee框架的z轴近似垂直。iiwa_link_ee框架是定向的,这样的约束使夹持器与杯轴对齐。

alignWithCup = constraintAiming('iiwa_link_ee');
alignWithCup.TargetPoint = [0, 0, 100]
alignWithCup = 
  constraintAiming with properties:

         EndEffector: 'iiwa_link_ee'
       ReferenceBody: ''
         TargetPoint: [0 0 100]
    AngularTolerance: 0
             Weights: 1

创建关节位置边界约束。根据前面的配置设置此约束的Bounds属性,以限制关节位置的变化。

limitJointChange = constraintJointBounds(lbr)
limitJointChange = 
  constraintJointBounds with properties:

     Bounds: [7x2 double]
    Weights: [1 1 1 1 1 1 1]

为夹持器创建一个方位约束,公差为一度。这个约束要求夹持器的方向与TargetOrientation属性指定的值相匹配。使用这个约束来固定夹具的方向在最后接近杯子。

fixOrientation = constraintOrientationTarget(gripper);
fixOrientation.OrientationTolerance = deg2rad(1)
fixOrientation = 
  constraintOrientationTarget with properties:

             EndEffector: 'iiwa_link_ee_kuka'
           ReferenceBody: ''
       TargetOrientation: [1 0 0 0]
    OrientationTolerance: 0.0175
                 Weights: 1

找到一个指向杯子的配置

这种配置应该将夹持器放置在与杯子的一段距离,以便最终接近可以与夹持器正确对齐。

intermediateDistance = 0.3;

约束对象有一个Weights属性,它决定了求解器如何处理冲突的约束。将约束的权重设置为0将禁用约束。对于此配置,禁用关节位置边界和方向约束。

limitJointChange.Weights = zeros(size(limitJointChange.Weights));
fixOrientation.Weights = 0;

将杯子的目标位置放在夹持架上。杯子应在指定的距离上位于夹持器的z轴上。

distanceFromCup.TargetPosition = [0,0,intermediateDistance];

使用gik求解器求解满足输入约束的机器人构型。必须指定所有的输入约束。将该配置设置为第二个路径点。

[qWaypoints(2,:),solutionInfo] = gik(q0, heightAboveTable, ...
                       distanceFromCup, alignWithCup, fixOrientation, ...
                       limitJointChange);

找到沿直线移动抓手到杯子的构型

重新启用关节位置约束和方向约束

limitJointChange.Weights = ones(size(limitJointChange.Weights));
fixOrientation.Weights = 1;

不需要与杯对齐约束,因为方向约束使其冗余。

alignWithCup.Weights = 0;

定义方向约束以保持基于前面配置的方向(qWaypoints(2,:)))。

得到了机器人模型从抓手到底座的转换。将齐次变换转换为四元数。

fixOrientation.TargetOrientation = ...
    tform2quat(getTransform(lbr,qWaypoints(2,:),gripper));

定义每个路点的杯子和夹持器之间的距离

finalDistanceFromCup = 0.05;
distanceFromCupValues = linspace(intermediateDistance, finalDistanceFromCup, numWaypoints-1);

定义每个路点之间关节位置的最大允许变化

maxJointChange = deg2rad(10);

为每个剩余的路径点调用求解器。

for k = 3:numWaypoints
    % Update the target position.
    distanceFromCup.TargetPosition(3) = distanceFromCupValues(k-1);
    % Restrict the joint positions to lie close to their previous values.
    limitJointChange.Bounds = [qWaypoints(k-1,:)' - maxJointChange, ...
                               qWaypoints(k-1,:)' + maxJointChange];
    % Solve for a configuration and add it to the waypoints array.
    [qWaypoints(k,:),solutionInfo] = gik(qWaypoints(k-1,:), ...
                                         heightAboveTable, ...
                                         distanceFromCup, alignWithCup, ...
                                         fixOrientation, limitJointChange);
end

可视化生成的轨迹

在路径点之间插值生成一个平滑的轨迹。使用pchip避免过冲,可能会违反机器人的关节极限。

framerate = 15;
r = rateControl(framerate);
tFinal = 10;
tWaypoints = [0,linspace(tFinal/2,tFinal,size(qWaypoints,1)-1)];
numFrames = tFinal*framerate;
qInterp = pchip(tWaypoints,qWaypoints',linspace(0,tFinal,numFrames))';

计算每个内插配置的夹持器位置

gripperPosition = zeros(numFrames,3);
for k = 1:numFrames
    gripperPosition(k,:) = tform2trvec(getTransform(lbr,qInterp(k,:), ...
                                                    gripper));
end

展示机器人的初始配置以及桌子和杯子

figure;
show(lbr, qWaypoints(1,:), 'PreservePlot', false);
hold on
exampleHelperPlotCupAndTable(cupHeight, cupRadius, cupPosition);
p = plot3(gripperPosition(1,1), gripperPosition(1,2), gripperPosition(1,3));

 动画操作手和绘图抓手的位置

hold on
for k = 1:size(qInterp,1)
    show(lbr, qInterp(k,:), 'PreservePlot', false);
    p.XData(k) = gripperPosition(k,1);
    p.YData(k) = gripperPosition(k,2);
    p.ZData(k) = gripperPosition(k,3);
    waitfor(r);
end
hold off

 如果需要将生成的配置保存到mat文件中以备后续使用,执行以下命令:

save('lbr_trajectory.mat', 'tWaypoints', 'qWaypoints');

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
运动学(Inverse Kinematics)是机器人学中的一种技术,它是研究如何将末端执行器的空间位置和方向转换为机器人各关节的运动学参数的问题。通俗地说,就是根据机器人末端执行器的位置和方向,计算出机器人各个关节的运动参数,以实现末端执行器的精确定位。 逆运动学广泛应用于机器人运动控制、虚拟现实、计算机动画等领域。在这些领域中,我们往往需要控制机器人或模拟人体的运动,例如让机器人手臂抓取物体、让人物模型做出某些动作等。这时,我们需要通过逆运动学算法来计算出机器人各关节的运动学参数,从而实现所需要的运动。 逆运动学算法的核心思想是:先设定末端执行器的目标位置和方向,然后计算出机器人各个关节的运动学参数,使机器人能够达到目标位置和方向。由于逆运动学问题是一种非线性问题,因此通常需要使用数值计算方法来求解。 逆运动学算法的实现方式很多,其中比较常用的方法有:解析法、数值法和优化法。解析法是指通过代数运算求解逆运动学问题的方法,它通常适用于关节数较少、几何形状规则的机器人,例如SCARA机器人等。数值法是指通过数值计算求解逆运动学问题的方法,它通常适用于关节数较多、几何形状复杂的机器人,例如人形机器人等。优化法是指通过搜索算法求解逆运动学问题的方法,它可以应用于任何类型的机器人,但计算复杂度较高。 除了以上三种方法,还有一些基于约束的逆运动学算法,例如Jacobian矩阵法、Pseudo-Inverse方法等。这些算法通过定义一些约束条件来求解逆运动学问题,通常可以获得较好的求解效果。 逆运动学算法的实现需要考虑一些问题,例如奇异性问题、多解性问题、收敛性问题等。奇异性问题是指机器人某些位置和方向无法通过逆运动学算法求解,多解性问题是指机器人在某些位置和方向有多个解,收敛性问题是指逆运动学算法是否能够收敛到正确的解。因此,在实际应用中,需要根据具体情况选择适合的逆运动学算法,并对算法进行优化和改进。 在逆运动学的研究中,还有一些重要的问题需要考虑,包括运动规划、碰撞检测和实时性等。运动规划是指如何计算出机器人的轨迹,使其在规定时间内完成所需的运动。碰撞检测是指如何避免机器人碰到障碍物或其他物体。实时性是指如何使机器人的运动控制实时响应,以保证其精确度和稳定性。 逆运动学算法在机器人领域中的应用非常广泛,例如在工业生产、医疗卫生、军事防卫和探索科学等领域都有着重要的应用。其中比较典型的应用包括机器人装配、机器人焊接、机器人喷涂、机器人抓取和机器人手术等。逆运动学算法也广泛应用于虚拟现实领域,例如在计算机动画、游戏开发、虚拟现实模拟和交互设计等方面都有着广泛的应用。 逆运动学算法的研究和应用面临着一些挑战,例如机器人的自适应性、多机器人协作和人机交互等问题。机器人的自适应性是指机器人能够根据环境和任务的变化而自动调整其运动策略和控制参数。多机器人协作是指多个机器人在同一环境中协作完成任务,需要考虑机器人之间的通信、协调和协作方式等问题。人机交互是指如何使机器人与人类进行有效的交互,需要考虑人类语言、姿态、表情等因素,以及机器人的语音识别、视觉识别和动作控制等技术。 总之,逆运动学是机器人学中的一个重要问题,它关系到机器人和虚拟人物的运动控制、动作设计等方面。随着机器人技术和虚拟现实技术的发展,逆运动学算法也在不断发展和完善,将为人类带来更多的便利和惊喜。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值