Blending for group motion

Blending is to blend movements so the motion and paths can be linked smoothly without a velocity drop. The details can be found in Blend movements. In this section, we blend circular and linear motion including MoveCircularAbsolute, MoveCircularRelative, MoveCircularAdditive, MoveLinearAbsolute, MoveLinearRelative.

Code

In the blending sample, we interleave circular and linear functions. MoveCircularAbsolute is the first one. Its BufferMode can be mcAborting, mcBuffered, or mcCancel, because the blending mode in the first motion command doesn't affect anything. Other circular and linear functions use velocity blending modes.

In KINGSTAR 4.2, linear functions supports velocity and path blending. Path blending have one transition mode: mcCornerDistance, which inserts a transition curve to link the paths of two moves. The transition curve's size is defined by TransitionParameter. Circular functions supports only velocity blending, but the design of circular functions requires you to use transition mode, so you need to apply a transition mode to circular functions. For further details about how blending works, see Blend movements.

 

In GroupMotion.cpp, add the following code:

Copy

Blending

VOID BlendSample(int Group)
{
    RtPrintf("Blend multi-axis moves.\n\n");

    /*Following errors affects the end positions, so the actual end positions will be
      different from the commanded ones.*/

    /*------Circular Absolute------*/
    RtPrintf("------Circular Absolute------\n\n");

    //Starting positions: (0, 0, 0).
    //End positions: (0, 200, 200).

    const int LENGTH = 3;   //The length of the Position array.
    double CircAbsAuxPoints[LENGTH] = { -200, 0, 0 };
    double CircAbsEndPoints[LENGTH] = { 0, 200, 200 };
    double TransitionParam = 10;

    //Display the starting positions.
    RtPrintf("Circular Absolute starting positions:\n\n");
    GetAGroupPosition(Group);

    /*We lower the velocity to 360, because the end positions are not far. If the velocity is high
      and the distance is short, the axis will brake sharply. This may damage the axis.*/
    KsCommandStatus absCircMove = WaitForCommand(30, TRUE, MoveCircularAbsolute(Group, mcRadius,
        LENGTH, CircAbsAuxPoints, CircAbsEndPoints, mcShortPath, 360, 3600, 3600, 360000,
        mcAxisCoordSystem, mcAborting, mcNone, NULL));
    if (absCircMove.Error)
        RtPrintf("MoveCircularAbsolute failed: %d\n\n", absCircMove.ErrorId);

    //Wait a few cycles to get the correct end positions.
    Sleep(5);

    //Display the end positions.
    RtPrintf("Circular Absolute end positions:\n\n");
    GetAGroupPosition(Group);

    /*------Linear Absolute------*/
    RtPrintf("------Linear Absolute------\n\n");

    //Starting positions: (0, 200, 200).
    //End positions: (-600, 400, 400).

    double LinearAbsEndPositions[LENGTH] = { -600, 400, 400 };

    //Display the starting positions.
    RtPrintf("Linear Absolute starting positions:\n\n");
    GetAGroupPosition(Group);

    /*When you use blending in MoveLinear functions, you must use TransitionMode and
      TransitionParameter. If you set them to mcNone and NULL in a blending mode,
      an error will occur.*/
    KsCommandStatus absoluteMove = WaitForCommand(30, TRUE, MoveLinearAbsolute(Group, LENGTH,
        LinearAbsEndPositions, 260, 2600, 2600, 260000, mcAxisCoordSystem, mcBlendingLow,
        mcCornerDistance, &TransitionParam));
    if (absoluteMove.Error)
        RtPrintf("MoveLinearAbsolute failed: %d\n\n", absoluteMove.ErrorId);

    //Wait a few cycles to get the correct end positions.
    Sleep(5);

    //Display the end positions.
    RtPrintf("Linear Absolute end positions:\n\n");
    GetAGroupPosition(Group);

    /*------Circular Relative------*/
    RtPrintf("------Circular Relative------\n\n");

    //Relative uses distance, so Relative Points are distance, not positions.
    //Both AuxPoints and EndPoints are counted from the starting position.
    //Starting positions: (-600, 400, 400).
    //Center of the circle: (-600, 400, 400) + (-300, 0, 0) = (-900, 400, 400).
    //End positions: (-600, 400, 400) + (-300, 0, 300) = (-900, 400, 700).

    double CircRelAuxPoints[LENGTH] = { -300, 0, 0 };
    double CircRelEndPoints[LENGTH] = { -300, 0, 300 };

    RtPrintf("Circular Relative starting positions:\n\n");
    GetAGroupPosition(Group);

    /*When you use blending in MoveCircular functions, you must use TransitionMode and
      TransitionParameter, even if MoveCircular has not supported them in KINGSTAR 4.1 yet.
      If you set them to mcNone and NULL in a blending mode, an error will occur.*/
    KsCommandStatus relCircMove = WaitForCommand(30, TRUE, MoveCircularRelative(Group, mcCenter,
        LENGTH, CircRelAuxPoints, CircRelEndPoints, mcShortPath, 300, 3000, 3000, 300000,
        mcAxisCoordSystem, mcBlendingNext, mcCornerDistance, &TransitionParam));
    if (relCircMove.Error)
        RtPrintf("MoveCircularRelative failed: %d\n\n", relCircMove.ErrorId);

    //Wait a few cycles to get the correct end positions.
    Sleep(5);

    //Display the end positions.
    RtPrintf("Circular Relative end positions:\n\n");
    GetAGroupPosition(Group);

    /*------Linear Relative------*/
    RtPrintf("------Linear Relative------\n\n");
    
    //Starting positions: (-900, 400, 700).
    //End positions: (-900, 400, 700) + (-100, -900, -400) = (-1000, -500, 300).

    double Distance[LENGTH] = { -100, -900, -400 };

    //Display the starting positions.
    RtPrintf("Linear Relative starting positions:\n\n");
    GetAGroupPosition(Group);

    KsCommandStatus relativeMove = WaitForCommand(30, TRUE, MoveLinearRelative(Group, LENGTH,
        Distance, 250, 2500, 2500, 250000, mcAxisCoordSystem, mcBlendingHigh,
        mcCornerDistance, &TransitionParam));

    if (relativeMove.Error)
        RtPrintf("MoveLinearRelative failed: %d\n\n", relativeMove.ErrorId);

    //Wait a few cycles to get the correct end positions.
    Sleep(5);

    //Display the end positions.
    RtPrintf("Linear Relative end positions:\n\n");
    GetAGroupPosition(Group);

    /*------Circular Additive------*/
    RtPrintf("------Circular Additive------\n\n");

    //Additive uses distance, so Additive Points are distance, not positions.
    //Both AuxPoints and EndPoints are counted from the starting position.
    //Starting positions: (-1000, -500, 300).
    //Border point of the circle: (-1000, -500, 300) + (0, 0, 600) = (-1000, -500, 900).
    //End positions: (-1000, -500, 300) + (0, -300, 0) = (-1000, -800, 300).

    double AuxPoints[LENGTH] = { 0, 0, 600 };
    double EndPoints[LENGTH] = { 0, -300, 0 };

    //Display the starting positions.
    RtPrintf("Circular Additive starting positions:\n\n");
    GetAGroupPosition(Group);

    KsCommandStatus addCircMove = WaitForCommand(30, TRUE, MoveCircularAdditive(Group, mcBorder,
        LENGTH, AuxPoints, EndPoints, mcShortPath, 280, 2800, 2800, 280000, mcAxisCoordSystem,
        mcBlendingPrevious, mcCornerDistance, &TransitionParam));
    if (addCircMove.Error)
        RtPrintf("MoveCircularAdditive failed: %d\n\n", addCircMove.ErrorId);

    //Wait a few cycles to get the correct end positions.
    Sleep(5);

    //Display the end positions.
    RtPrintf("Circular Additive end positions:\n\n");
    GetAGroupPosition(Group);

    RtPrintf("------End of the blending moves------\n\n");
}

 

Output: