@@ -3884,22 +3884,22 @@ extern "C" void checkFeedOverride(TP_STRUCT *tp)
38843884 } else if (g_recompute_cursor == 1 && active) {
38853885 if (active->term_cond == TC_TERM_COND_TANGENT &&
38863886 active->shared_9d .profile .valid ) {
3887- // Active segment: profile exit is the truth (branch may have changed it)
3888- prev_exit_vel = profileExitVelUnscaled (&active->shared_9d .profile );
3889- prev_exit_feed_scale = active->shared_9d .profile .computed_feed_scale ;
3887+ // If a pending branch exists, its exit velocity is the future truth
3888+ int bv = __atomic_load_n (&active->shared_9d .branch .valid , __ATOMIC_ACQUIRE);
3889+ if (bv && active->shared_9d .branch .profile .valid &&
3890+ active->shared_9d .branch .profile .computed_feed_scale > 0.001 ) {
3891+ prev_exit_vel = profileExitVelUnscaled (&active->shared_9d .branch .profile );
3892+ prev_exit_feed_scale = active->shared_9d .branch .feed_scale ;
3893+ } else {
3894+ prev_exit_vel = profileExitVelUnscaled (&active->shared_9d .profile );
3895+ prev_exit_feed_scale = active->shared_9d .profile .computed_feed_scale ;
3896+ }
38903897 }
38913898 }
38923899
38933900 int recomputed = 0 ;
38943901 int i = g_recompute_cursor;
3895- double budget_us = g_handoff_config.servo_cycle_time_sec * 0.5e6 ; // half the servo cycle
3896- double tick_start = etime_user ();
38973902 for (; i < queue_len; i++) {
3898- // Time-budget check: after the minimum, stop if budget exhausted
3899- if (recomputed >= RECOMPUTE_MIN_PER_TICK) {
3900- double elapsed_us = (etime_user () - tick_start) * 1e6 ;
3901- if (elapsed_us >= budget_us) break ;
3902- }
39033903
39043904 TC_STRUCT *tc = tcqItem_user (queue, i);
39053905 if (!tc || tc->target < 1e-9 ) {
@@ -3916,15 +3916,22 @@ extern "C" void checkFeedOverride(TP_STRUCT *tp)
39163916 double profile_feed = tc->shared_9d .profile .computed_feed_scale ;
39173917 if (tc->shared_9d .profile .valid &&
39183918 fabs (profile_feed - feed_scale) < 0.005 ) {
3919- // Already correct — propagate actual profile exit velocity
3920- if (tc->term_cond == TC_TERM_COND_TANGENT) {
3921- prev_exit_vel = profileExitVelUnscaled (&tc->shared_9d .profile );
3922- prev_exit_feed_scale = tc->shared_9d .profile .computed_feed_scale ;
3923- } else {
3924- prev_exit_vel = 0.0 ;
3925- prev_exit_feed_scale = 1.0 ;
3919+ // Feed matches — but check if entry velocity also matches
3920+ double expected_v0 = prev_exit_vel * prev_exit_feed_scale;
3921+ double profile_v0 = tc->shared_9d .profile .v [0 ];
3922+ double v0_delta = fabs (profile_v0 - expected_v0);
3923+ if (v0_delta < 0.5 ) {
3924+ // Both feed and entry velocity match — genuinely up-to-date
3925+ if (tc->term_cond == TC_TERM_COND_TANGENT) {
3926+ prev_exit_vel = profileExitVelUnscaled (&tc->shared_9d .profile );
3927+ prev_exit_feed_scale = tc->shared_9d .profile .computed_feed_scale ;
3928+ } else {
3929+ prev_exit_vel = 0.0 ;
3930+ prev_exit_feed_scale = 1.0 ;
3931+ }
3932+ continue ;
39263933 }
3927- continue ;
3934+ // Fall through to recompute — entry velocity is stale
39283935 }
39293936
39303937 double v_entry = prev_exit_vel;
@@ -4048,7 +4055,6 @@ extern "C" void checkFeedOverride(TP_STRUCT *tp)
40484055 g_recompute_first_batch_done = true ;
40494056 // Update throughput estimate (EMA, alpha=0.3)
40504057 g_segments_per_tick = 0.7 * g_segments_per_tick + 0.3 * recomputed;
4051-
40524058 }
40534059
40544060 // Advance or finish
@@ -4083,6 +4089,7 @@ extern "C" void checkFeedOverride(TP_STRUCT *tp)
40834089
40844090 // Adaptive throttling: ensure profiles computed when buffer is thin
40854091 ensureProfilesOnLowBuffer (tp);
4092+
40864093}
40874094
40884095/* *
@@ -4175,8 +4182,17 @@ int computeRuckigProfiles_9D(TP_STRUCT *tp, TC_QUEUE_STRUCT *queue, int optimiza
41754182 // the profile to overshoot the segment end.
41764183 if (tc->active ) {
41774184 if (tc->term_cond == TC_TERM_COND_TANGENT && tc->shared_9d .profile .valid ) {
4178- prev_exit_vel = profileExitVelUnscaled (&tc->shared_9d .profile );
4179- prev_exit_feed_scale = tc->shared_9d .profile .computed_feed_scale ;
4185+ // If a pending branch exists, its exit velocity reflects the
4186+ // new feed — use it instead of the stale main profile.
4187+ int bv = __atomic_load_n (&tc->shared_9d .branch .valid , __ATOMIC_ACQUIRE);
4188+ if (bv && tc->shared_9d .branch .profile .valid &&
4189+ tc->shared_9d .branch .profile .computed_feed_scale > 0.001 ) {
4190+ prev_exit_vel = profileExitVelUnscaled (&tc->shared_9d .branch .profile );
4191+ prev_exit_feed_scale = tc->shared_9d .branch .feed_scale ;
4192+ } else {
4193+ prev_exit_vel = profileExitVelUnscaled (&tc->shared_9d .profile );
4194+ prev_exit_feed_scale = tc->shared_9d .profile .computed_feed_scale ;
4195+ }
41804196 } else {
41814197 prev_exit_vel = 0.0 ;
41824198 prev_exit_feed_scale = 1.0 ;
0 commit comments