Skip to content

Commit 4093962

Browse files
author
Luca Toniolo
committed
reinstated cubic for planner type 2
1 parent 014fd81 commit 4093962

File tree

1 file changed

+11
-38
lines changed

1 file changed

+11
-38
lines changed

src/emc/motion/control.c

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

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

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

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

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

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

14251399
/* Fill cubic buffer if needed (may need multiple points per cycle) */
@@ -1495,7 +1469,6 @@ static void get_pos_cmds(long period)
14951469
break;
14961470

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

0 commit comments

Comments
 (0)