Skip to content

Commit 46801e6

Browse files
committed
Virtual arc for line-line junctions
1 parent 2963e23 commit 46801e6

1 file changed

Lines changed: 64 additions & 1 deletion

File tree

src/emc/motion_planning/motion_planning_9d_userspace.cc

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ extern "C" {
3535
// Access to global pointers (defined in usrmotintf.cc, initialized by milltask)
3636
extern struct emcmot_struct_t *emcmotStruct;
3737
extern struct emcmot_internal_t *emcmotInternal;
38+
3839
}
3940

4041
/**
@@ -445,7 +446,6 @@ static void tpComputeKinkVelocity_9D(TP_STRUCT *tp, TC_QUEUE_STRUCT *queue,
445446

446447
double vel_cap = fmin(prev_tc->maxvel, tc->maxvel);
447448
double dt = tp->cycleTime;
448-
double dt_sq = dt * dt;
449449
// Physical limit starts unconstrained — only jerk/accel physics determine it.
450450
// vel_cap (programmed feed) is applied separately for the backward pass.
451451
double kink_vel = 1e9;
@@ -486,6 +486,7 @@ static void tpComputeKinkVelocity_9D(TP_STRUCT *tp, TC_QUEUE_STRUCT *queue,
486486
// --- Part A: Direction-change limiting ---
487487
// For non-trivkins: joint velocity impulse = v * sum_a(|J[j][a]| * |delta_u[a]|) / dt
488488
// For trivkins (J = identity): simplifies to v * |delta_u[j]| / dt
489+
double dt_sq = dt * dt;
489490
if (delta_mag_sq >= 1e-12) {
490491
for (int j = 0; j < num_joints; j++) {
491492
double projection;
@@ -571,6 +572,68 @@ static void tpComputeKinkVelocity_9D(TP_STRUCT *tp, TC_QUEUE_STRUCT *queue,
571572
}
572573
}
573574

575+
// --- Part C: Virtual arc curvature for line-line junctions ---
576+
// Consecutive small line segments approximate a smooth curve. Compute the
577+
// discrete curvature from three points (start of prev, junction, end of tc)
578+
// and apply per-joint jerk and centripetal acceleration limits.
579+
// This caps kink_vel at the physically safe velocity for the approximated
580+
// curve's curvature, preventing kink_ratio from exceeding geometric limits.
581+
// Ported from planner 0/1 (tp.c:2266-2337) with Jacobian extension.
582+
if (prev_tc->motion_type == TC_LINEAR && tc->motion_type == TC_LINEAR) {
583+
PmCartesian P0 = prev_tc->coords.line.xyz.start;
584+
PmCartesian P1 = prev_tc->coords.line.xyz.end; // junction point
585+
PmCartesian P2 = tc->coords.line.xyz.end;
586+
587+
PmCartesian A, B;
588+
pmCartCartSub(&P1, &P0, &A);
589+
pmCartCartSub(&P2, &P1, &B);
590+
591+
double A_mag, B_mag;
592+
pmCartMag(&A, &A_mag);
593+
pmCartMag(&B, &B_mag);
594+
595+
if (A_mag > 1e-12 && B_mag > 1e-12) {
596+
// kappa = 2*(t_out - t_in) / (|A| + |B|)
597+
// Equals the curvature of the circumscribed circle through P0, P1, P2.
598+
PmCartesian t_in, t_out, delta_t, curv_vec;
599+
pmCartScalMult(&A, 1.0 / A_mag, &t_in);
600+
pmCartScalMult(&B, 1.0 / B_mag, &t_out);
601+
pmCartCartSub(&t_out, &t_in, &delta_t);
602+
pmCartScalMult(&delta_t, 2.0 / (A_mag + B_mag), &curv_vec);
603+
604+
double curv_xyz[3] = {curv_vec.x, curv_vec.y, curv_vec.z};
605+
606+
for (int j = 0; j < num_joints; j++) {
607+
double curv_proj;
608+
if (have_jacobian) {
609+
curv_proj = 0.0;
610+
for (int a = 0; a < 3; a++)
611+
curv_proj += fabs(J[j][a]) * fabs(curv_xyz[a]);
612+
} else {
613+
if (j >= 3) continue; // trivkins: XYZ curvature only
614+
curv_proj = fabs(curv_xyz[j]);
615+
}
616+
if (curv_proj < 1e-15) continue;
617+
618+
// Curvature-change jerk: v^2 * curv_proj / dt <= jerk_limit
619+
double jerk_lim = g_userspace_kins_planner.isEnabled()
620+
? g_userspace_kins_planner.getJointJerkLimit(j) : 1e9;
621+
if (jerk_lim > 0 && jerk_lim < 1e9) {
622+
double v_curv_jerk = sqrt(jerk_lim * dt / curv_proj);
623+
if (v_curv_jerk < kink_vel) kink_vel = v_curv_jerk;
624+
}
625+
626+
// Centripetal acceleration: v^2 * curv_proj <= acc_limit
627+
double acc_lim = g_userspace_kins_planner.isEnabled()
628+
? g_userspace_kins_planner.getJointAccLimit(j) : 1e9;
629+
if (acc_lim > 0 && acc_lim < 1e9) {
630+
double v_curv_acc = sqrt(acc_lim / curv_proj);
631+
if (v_curv_acc < kink_vel) kink_vel = v_curv_acc;
632+
}
633+
}
634+
}
635+
}
636+
574637
// Floor at a small positive value to avoid numerical issues
575638
if (kink_vel < 1e-6) kink_vel = 1e-6;
576639

0 commit comments

Comments
 (0)