SCurve Motion offers a smoother acceleration profile compared to Trapezoidal Motion, utilizing a "Jerk Percent" parameter to fine-tune how acceleration phases are shaped, allowing precise control over motion transitions and peak accelerations.
š¹ What is SCurve Motion?
S-Curve Motion initiates a point-to-point motion using an āSā shaped velocity profile similar to that shown below.
This move type generates a motion that takes the same time as a trapezoidal move but allows the acceleration to have smoother transitions.
This comes at the expense of requiring larger peak accelerations and decelerations. The total move time is always the same as the equivalent trapezoidal move.
- Note
- You can change the velocity, acceleration, and deceleration of a moveSCurve that is executing on the fly simply by calling the function again with different parameters.
š¹ SCurve Motion Overview
Jerk % | Notes | Acceleration | Velocity |
0% |
Acceleration is always constant. This is the same as a Trapezoidal move profile.
Peak Acceleration is specified by the user.
| | |
50% |
Acceleration is ramping 50% of the time and constant for 50% of the time.
Peak Acceleration is 133% of the value specified by the user.
| | |
100% |
Acceleration is ramping 100% of the time and is never constant.
Peak Acceleration is 200% of the value specified by the user.
| | |
![Image](https://support.roboticsys.com/assets/0 (21).png)
Jerk Percent
The Jerk percent is a parameter (from 0 to 100.0) which provides an easy way to change the acceleration profile without changing the move time. In most systems, there is a practical limit to acceleration, as it is proportional to the current in most motor types. Be sure to know the acceleration limitations to your system before trying a move SCurve profile.
Maximum Acceleration
Changing the Jerk Percent will change the max acceleration given by this formula:
![Image](https://support.roboticsys.com/assets/7.png)
Where,
max_accel: the maximum acceleration (or decel) for a point-to-point profile.
accel: the specified acceleration (or decel) from the application code.
jerk_percent: the specified jerk percentage (0 to 100.0) from the application code.
š¹ Multi-Axis SCurve Motion Overview
All Point to Point methods can be used for coordinated motion on multiaxis objects. It is important that you set up your arrays appropriately for a multiaxis object. See the examples below on how to structure your arrays for Multi-Axis SCurve Motion.
EXAMPLE 1 - Three Axis Multi-Axis XYZ with MoveSCurve()
The position data for all three axes are combined into the array. The time array is shared for all axes. This is why you need 3x as many position points than you need time points. See the example below:
Axis1 ā relativePosition[0] = 10; velocity[0] = 10; acceleration[0] = 100; deceleration[0] = 100; jerkPCT[0] = 50;\ Axis2 ā relativePosition[1] = 10; velocity[1] = 10; acceleration[1] = 100; deceleration[1] = 100; jerkPCT[0] = 50;\ Axis3 ā relativePosition[2] = 10; velocity[2] = 10; acceleration[2] = 100; deceleration[2] = 100; jerkPCT[0] = 50;
multiAxis.MoveSCurve(relativePosition, velocity, acceleration, deceleration,
jerkPCT);
- Note
- The jerkPCT in the example above is a double-precision percent value and NOT a double-precision decimal value.
-
The values passed to the function MoveSCurve() will be multiplied internally by the specified user units (AKA: counts per unit). The reason for this is to avoid creating an extra input array. We simply just use the same array you have passed to the function. Therefore, the values passed to the function might not be the same ones once the function has been triggered.
š Sample Code
Basic SCurve Motion
- C#
public const double POSITION = 2;
public const double VELOCITY = 200;
public const double ACCELERATION = 100;
public const double DECELERATION = 100;
public const double JERK_PERCENT = 50;
- C++
const double POSITION_0 = 0;
const double POSITION_1 = 0.5;
const double VELOCITY = 1;
const double ACCELERATION = 10;
const double DECELERATION = 10;
const double JERK_PERCENT = 50;
const double FINAL_VELOCITY = 0.5;
std::cout << "SCurve Motion:" << std::endl;
std::cout << "Moving to position: " << POSITION_1 << std::endl;
std::cout << "Motion Complete" << std::endl;
std::cout << "Moving back to position: " << POSITION_0 << std::endl;
std::cout << "Motion Complete\n" << std::endl;
Multi-Axis SCurve Motion
- C#
const int NUM_OF_AXES = 2;
double[] positions1 = new double[NUM_OF_AXES] { 5, 10 };
double[] positions2 = new double[NUM_OF_AXES] { 15, 15 };
double[] velocities1 = new double[NUM_OF_AXES] { 1000, 1000 };
double[] velocities2 = new double[NUM_OF_AXES] { 1000, 1000 };
double[] accelerations = new double[NUM_OF_AXES] { 500, 500 };
double[] decelerations = new double[NUM_OF_AXES] { 500, 500 };
double[] jerkPercent = new double[NUM_OF_AXES] { 50, 50 };
Axis axis0 = controller.
AxisGet(Constants.X_AXIS_NUMBER);
Axis axis1 = controller.
AxisGet(Constants.Y_AXIS_NUMBER);
multi.
MoveSCurve(positions1, velocities1, accelerations, decelerations, jerkPercent);
Assert.That(axis0.
CommandPositionGet(), Is.EqualTo(positions1[0]),
"The first axis in the multi axis object should be commanded to move to the firt element of the array");
Assert.That(axis1.
CommandPositionGet(), Is.EqualTo(positions1[1]),
"The second axis in the multi axis object should be commanded to move to the second element of the array");
multi.
MoveTrapezoidal(positions2, velocities2, accelerations, decelerations);
Assert.That(axis0.
CommandPositionGet(), Is.EqualTo(positions2[0]),
"The first axis in the multi axis object should be commanded to move to the firt element of the array");
Assert.That(axis1.
CommandPositionGet(), Is.EqualTo(positions2[1]),
"The second axis in the multi axis object should be commanded to move to the second element of the array");
- C++
const int AXIS_COUNT = 2;
const int AXIS_X = 0;
const int AXIS_Y = 1;
const int MOTION_COUNT = 1;
const double USER_UNITS = 1048576;
const double START_POSITION[AXIS_COUNT] = { 0, 0 };
const double END_POSITION[AXIS_COUNT] = { 1, 2 };
const double VELOCITY[AXIS_COUNT] = { 1, 2 };
const double ACCELERATION[AXIS_COUNT] = { 10, 20 };
const double DECELERATION[AXIS_COUNT] = { 10, 20 };
const double JERK_PERCENTAGE[AXIS_COUNT] = { 0, 0 };
USE_HARDWARE = false;
if (USE_HARDWARE)
{
}
else
{
}
try
{
printf("\nMotionStart...");
multiAxisXY->
MoveSCurve(END_POSITION, VELOCITY, ACCELERATION, DECELERATION, JERK_PERCENTAGE);
PrintResult(axisX, axisY);
printf("\nMotionStart...");
multiAxisXY->
MoveSCurve(START_POSITION, VELOCITY, ACCELERATION, DECELERATION, JERK_PERCENTAGE);
PrintResult(axisX, axisY);
printf("\nTrapezoidal Motion Done\n");
}
{
printf("\n%s\n", err.text);
return -1;
}
return 0;
Motion: Modify
This sample application demonstrates how to use change the velocity parameter of a motion that is partially complete.
- C#
axis.
MoveSCurve(20, Constants.VELOCITY, Constants.ACCELERATION, Constants.DECELERATION, Constants.JERK_PERCENT);
{
axis.
MoveSCurve(20, Constants.VELOCITY * 10, Constants.ACCELERATION, Constants.DECELERATION, Constants.JERK_PERCENT);
}