Skip to content

Commit 7c7b73d

Browse files
committed
reinstated cubic for planner type 2
1 parent 1e0a9dc commit 7c7b73d

1 file changed

Lines changed: 11 additions & 38 deletions

File tree

src/emc/motion/control.c

Lines changed: 11 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,6 @@ static unsigned long last_period = 0;
6161
/* servo cycle time */
6262
static double servo_period;
6363

64-
/* Planner type 2: joint-space velocity feedforward via finite differences.
65-
* Correct for ALL kinematics (trivkins, tilting pivot, etc.) unlike the
66-
* previous direction-vector decomposition which assumed joints = XYZ axes. */
67-
static double p2_prev_pos[EMCMOT_MAX_JOINTS];
68-
static double p2_prev_vel[EMCMOT_MAX_JOINTS];
69-
static double p2_prev_acc[EMCMOT_MAX_JOINTS];
70-
static int p2_ff_init = 0;
71-
7264
extern struct emcmot_status_t *emcmotStatus;
7365

7466
// *pcmd_p[0] is shorthand for emcmotStatus->carte_pos_cmd.tran.x
@@ -1216,7 +1208,6 @@ static void get_pos_cmds(long period)
12161208
/* run traj planner code depending on the state */
12171209
switch ( emcmotStatus->motion_state) {
12181210
case EMCMOT_MOTION_FREE:
1219-
p2_ff_init = 0; /* Reset feedforward state when leaving coord mode */
12201211
/* in free mode, each joint is planned independently */
12211212
/* initial value for flag, if needed it will be cleared below */
12221213
SET_MOTION_INPOS_FLAG(1);
@@ -1366,61 +1357,44 @@ static void get_pos_cmds(long period)
13661357
}
13671358

13681359
if (emcmotStatus->planner_type == 2) {
1369-
/* Planner type 2 (Ruckig): bypass cubic interpolator.
1370-
* Joint velocity/acceleration/jerk feedforward computed from
1371-
* finite differences of IK output — correct for ALL kinematics. */
1360+
/* Planner type 2 (Ruckig): use cubic interpolation to smooth
1361+
* directional discontinuities at bezier-to-line split boundaries.
1362+
* The cubic [1,4,1]/6 waypoint filter spreads single-sample
1363+
* direction jumps over 3 samples, eliminating jerk spikes. */
13721364
EmcPose current_pos = emcmotStatus->carte_pos_cmd;
13731365

13741366
result = kinematicsInverse(&current_pos, positions, &iflags, &fflags);
13751367
if (result == 0) {
1376-
double inv_dt = 1.0 / servo_period;
1377-
13781368
for (joint_num = 0; joint_num < NO_OF_KINS_JOINTS; joint_num++) {
13791369
if (!isfinite(positions[joint_num])) {
13801370
reportError(_("kinematicsInverse gave non-finite joint location on joint %d"),
13811371
joint_num);
13821372
SET_MOTION_ERROR_FLAG(1);
13831373
emcmotInternal->enabling = 0;
1384-
p2_ff_init = 0;
13851374
break;
13861375
}
13871376
joint = &joints[joint_num];
13881377
joint->coarse_pos = positions[joint_num];
1389-
joint->pos_cmd = positions[joint_num];
1390-
1391-
if (p2_ff_init) {
1392-
double vel = (positions[joint_num] - p2_prev_pos[joint_num]) * inv_dt;
1393-
double acc = (vel - p2_prev_vel[joint_num]) * inv_dt;
1394-
joint->vel_cmd = vel;
1395-
joint->acc_cmd = acc;
1396-
joint->jerk_cmd = (acc - p2_prev_acc[joint_num]) * inv_dt;
1397-
p2_prev_vel[joint_num] = vel;
1398-
p2_prev_acc[joint_num] = acc;
1399-
} else {
1400-
joint->vel_cmd = 0.0;
1401-
joint->acc_cmd = 0.0;
1402-
joint->jerk_cmd = 0.0;
1403-
p2_prev_vel[joint_num] = 0.0;
1404-
p2_prev_acc[joint_num] = 0.0;
1405-
}
1406-
p2_prev_pos[joint_num] = positions[joint_num];
14071378
}
1408-
p2_ff_init = 1;
14091379

1410-
/* Still feed the cubic so it stays primed if we switch planner types */
1380+
/* Feed cubic interpolator */
14111381
while (cubicNeedNextPoint(&(joints[0].cubic))) {
14121382
for (joint_num = 0; joint_num < NO_OF_KINS_JOINTS; joint_num++) {
14131383
cubicAddPoint(&(joints[joint_num].cubic), positions[joint_num]);
14141384
}
14151385
}
1386+
/* Get smoothed position with analytical vel/acc/jerk */
1387+
for (joint_num = 0; joint_num < NO_OF_KINS_JOINTS; joint_num++) {
1388+
joint = &joints[joint_num];
1389+
joint->pos_cmd = cubicInterpolate(&(joint->cubic), 0,
1390+
&(joint->vel_cmd), &(joint->acc_cmd), &(joint->jerk_cmd));
1391+
}
14161392
} else {
14171393
reportError(_("kinematicsInverse failed"));
14181394
SET_MOTION_ERROR_FLAG(1);
14191395
emcmotInternal->enabling = 0;
1420-
p2_ff_init = 0;
14211396
}
14221397
} else {
1423-
p2_ff_init = 0;
14241398
/* Planner type 0 and 1: use cubic interpolator as before */
14251399

14261400
/* Fill cubic buffer if needed (may need multiple points per cycle) */
@@ -1496,7 +1470,6 @@ static void get_pos_cmds(long period)
14961470
break;
14971471

14981472
case EMCMOT_MOTION_TELEOP:
1499-
p2_ff_init = 0; /* Reset feedforward state when leaving coord mode */
15001473
ext_offset_teleop_limit = axis_calc_motion(servo_period);
15011474
if (!ext_offset_teleop_limit) {
15021475
ext_offset_coord_limit = 0; //in case was set in prior coord motion

0 commit comments

Comments
 (0)