@@ -1765,7 +1765,7 @@ STATIC int tpComputeOptimalVelocity(TP_STRUCT const * const tp, TC_STRUCT * cons
17651765
17661766 // Find the reachable velocity of tc, moving backwards in time
17671767 double vs_back = pmSqrt (pmSq (tc -> finalvel ) + 2.0 * acc_this * tc -> target );
1768- if (GET_TRAJ_PLANNER_TYPE () == 1 || GET_TRAJ_PLANNER_TYPE () == 2 ){
1768+ if (GET_TRAJ_PLANNER_TYPE () == 1 ){
17691769 double vs_back2 ;
17701770 if (findSCurveVSpeedWithEndSpeed (tc -> target * 2.0 , tc -> finalvel , acc_this , emcmotStatus -> jerk , & vs_back2 ) == 1 )
17711771 vs_back = vs_back2 ;
@@ -1890,7 +1890,7 @@ STATIC int tpRunOptimization(TP_STRUCT * const tp) {
18901890 tp_debug_print ("Segment %d, type %d not finalized, continuing\n" ,tc -> id ,tc -> motion_type );
18911891 // use worst-case final velocity that allows for up to 1/2 of a segment to be consumed.
18921892
1893- if (GET_TRAJ_PLANNER_TYPE () == 1 || GET_TRAJ_PLANNER_TYPE () == 2 )
1893+ if (GET_TRAJ_PLANNER_TYPE () == 1 )
18941894 prev1_tc -> finalvel = fmin (prev1_tc -> maxvel , tpCalculateOptimizationSCurveInitialVel (tp ,tc ));
18951895 else
18961896 prev1_tc -> finalvel = fmin (prev1_tc -> maxvel , tpCalculateOptimizationInitialVel (tp ,tc ));
@@ -2506,7 +2506,7 @@ STATIC double estimateParabolicBlendPerformance(
25062506 double target_vel_next = tpGetMaxTargetVel (tp , nexttc );
25072507
25082508 double v_net = 0.0 ;
2509- if (GET_TRAJ_PLANNER_TYPE () == 1 || GET_TRAJ_PLANNER_TYPE () == 2 )
2509+ if (GET_TRAJ_PLANNER_TYPE () == 1 )
25102510 tpComputeBlendSCurveVelocity (tc , nexttc , target_vel_this , target_vel_next , & v_this , & v_next , & v_net );
25112511 else
25122512 tpComputeBlendVelocity (tc , nexttc , target_vel_this , target_vel_next , & v_this , & v_next , & v_net );
@@ -2715,8 +2715,7 @@ STATIC int tcUpdateDistFromSCurveAccel(TC_STRUCT *const tc, double acc, double j
27152715{
27162716 // If the resulting velocity is less than zero, than we're done. This
27172717 // causes a small overshoot, but in practice it is very small.
2718- //double v_next = vel_desired;//velocity(tc->cycle_time, acc, jerk); //tc->currentvel + acc * tc->cycle_time; double velocity(double t, double a, double j);
2719- double v_next = vel_desired ;//velocity(tc->cycle_time, acc, jerk);
2718+ double v_next = vel_desired ;
27202719
27212720 // update position in this tc using trapezoidal integration
27222721 // Note that progress can be greater than the target after this step.
@@ -2754,11 +2753,11 @@ STATIC int tcUpdateDistFromSCurveAccel(TC_STRUCT *const tc, double acc, double j
27542753 tc -> progress = bisaturate (tc -> progress , tcGetTarget (tc , TC_DIR_FORWARD ), tcGetTarget (tc , TC_DIR_REVERSE ));
27552754 }
27562755 }
2757- tc -> currentvel = v_next ;// v_next;
2756+ tc -> currentvel = v_next ;
27582757 tc -> currentacc = acc ;
27592758
27602759 // Check if we can make the desired velocity
2761- tc -> on_final_decel = dec ;//(fabs(vel_desired - tc->currentvel) < TP_VEL_EPSILON) && (acc < 0.0); //dec && (acc < 0.0);
2760+ tc -> on_final_decel = dec ;
27622761
27632762 return TP_ERR_OK ;
27642763}
@@ -2816,25 +2815,45 @@ int tpCalculateSCurveAccel(TP_STRUCT const * const tp, TC_STRUCT * const tc, TC_
28162815
28172816 nextSpeed (tc -> currentvel , tc -> currentacc , tc -> cycle_time , tc_target_vel , maxaccel , maxjerk , & req_v , & req_a , & req_j );
28182817 double dlen1 = finishWithSpeedDist (tc -> currentvel , tc_finalvel , tc -> currentacc , maxaccel , maxjerk );
2819- double dlen2 = finishWithSpeedDist (saturate (req_v , tc_target_vel ), tc_finalvel , saturate (req_a , maxaccel ), maxaccel , maxjerk );
2818+
2819+ // When velocity exceeds target, correct acceleration
2820+ // Since velocity is limited to target, acceleration should be 0 (maintain speed) or decel
2821+ double v_for_dlen2 = req_v ;
2822+ double a_for_dlen2 = req_a ;
2823+ if (req_v > tc_target_vel ) {
2824+ v_for_dlen2 = tc_target_vel ;
2825+ a_for_dlen2 = 0 ;
2826+ }
2827+ double dlen2 = finishWithSpeedDist (v_for_dlen2 , tc_finalvel , a_for_dlen2 , maxaccel , maxjerk );
28202828 double moveL = sc_distance (tc -> cycle_time , tc -> currentvel , tc -> currentacc , req_j );
2821- double error = fabs (dx ) - dlen1 ; //误差
2822- * pos_error = error ;
28232829
2830+ // margin = remaining distance - decel distance
2831+ // margin > 0: can continue accelerating
2832+ // margin <= 0: must decelerate
2833+ double margin = dx - dlen1 ;
2834+ * pos_error = margin ;
28242835
2825- if (tc -> currentvel < 1e-6 && dx > TP_POS_EPSILON && dx < 1e-4 ){
2826- //nextSpeed(tc->currentvel, tc->currentacc, tc->cycle_time, tc_target_vel, maxaccel, maxjerk, &req_v, &req_a, &req_j);
2836+ // Handle special case: position overshoot or reached endpoint
2837+ if (dx <= TP_POS_EPSILON ) {
2838+ nextSpeed (tc -> currentvel , tc -> currentacc , tc -> cycle_time , tc_finalvel , maxaccel , maxjerk , & req_v , & req_a , & req_j );
2839+ res = 1 ;
2840+ }
2841+ else if (tc -> currentvel < 1e-6 && dx > TP_POS_EPSILON && dx < 1e-4 ){
2842+ // Very low velocity and close to target
28272843 res = 1 ;
28282844 }else {
2829- //fabs(fabs(pos_err) - decLen) <= 0.000001 || fabs(pos_err) - moveL * dir <= decLen2 || fabs(pos_err) <= decLen
2830- if (fabs (error ) <= 0.0001 || dx - moveL <= dlen2 || dx < dlen1 ){
2845+ // Decel conditions:
2846+ // 1. margin <= 0: decel distance >= remaining distance
2847+ // 2. dx - moveL <= dlen2: if we continue accel, next cycle remaining <= decel dist
2848+ int need_decel = (margin <= TP_POS_EPSILON ) || (dx - moveL <= dlen2 );
2849+
2850+ if (need_decel ){
28312851 nextSpeed (tc -> currentvel , tc -> currentacc , tc -> cycle_time , tc_finalvel , maxaccel , maxjerk , & req_v , & req_a , & req_j );
28322852 }else {
28332853 if (tc_finalvel > TP_VEL_EPSILON || tc_target_vel > TP_VEL_EPSILON )
28342854 res = 0 ;
28352855 }
28362856 }
2837- //}
28382857
28392858 maxnewvel = req_v ;
28402859 maxnewacc = req_a ;
@@ -2848,8 +2867,7 @@ int tpCalculateSCurveAccel(TP_STRUCT const * const tp, TC_STRUCT * const tc, TC_
28482867 maxnewaccel = saturate (maxnewaccel , maxaccel );
28492868 * acc = maxnewaccel ;
28502869 * vel_desired = maxnewvel ;
2851- * jerk = maxnewjerk ;//(maxnewaccel - tc->currentacc) / dt;
2852- //*vel_desired = tc->currentvel + velocity(dt, *acc, *jerk);
2870+ * jerk = maxnewjerk ;
28532871
28542872 return res ;
28552873}
@@ -3470,7 +3488,7 @@ STATIC int tpUpdateCycle(TP_STRUCT * const tp,
34703488
34713489 if (mode == NULL ) planner_type = 0 ;
34723490
3473- if (planner_type != 1 && planner_type != 2 ){
3491+ if (planner_type != 1 ){
34743492 // If the slowdown is not too great, use velocity ramping instead of trapezoidal velocity
34753493 // Also, don't ramp up for parabolic blends
34763494 if (tc -> accel_mode && tc -> term_cond == TC_TERM_COND_TANGENT ) {
@@ -3739,8 +3757,21 @@ STATIC int tpHandleSplitCycle(TP_STRUCT * const tp, TC_STRUCT * const tc,
37393757 switch (tc -> term_cond ) {
37403758 case TC_TERM_COND_TANGENT :
37413759 nexttc -> cycle_time = tp -> cycleTime - tc -> cycle_time ;
3742- nexttc -> currentvel = tc -> term_vel ;
3743- tp_debug_print ("Doing tangent split\n" );
3760+ // In S-curve mode, use actual current velocity instead of expected term_vel
3761+ // S-curve can't change velocity instantly, term_vel is just desired value
3762+ if (GET_TRAJ_PLANNER_TYPE () == 1 ) {
3763+ nexttc -> currentvel = tc -> currentvel ;
3764+ // Inherit acceleration, but limit to nexttc's allowed range
3765+ // Important for line-to-arc transitions where arc has lower tangential accel
3766+ double maxacc_next = tcGetTangentialMaxAccel (nexttc );
3767+ nexttc -> currentacc = saturate (tc -> currentacc , maxacc_next );
3768+ tp_debug_print ("Doing tangent split (S-curve): vel=%f, acc=%f (limited by %f)\n" ,
3769+ nexttc -> currentvel , nexttc -> currentacc , maxacc_next );
3770+ } else {
3771+ // Trapezoidal: can use term_vel (assumes instant velocity change)
3772+ nexttc -> currentvel = tc -> term_vel ;
3773+ tp_debug_print ("Doing tangent split (trapezoidal): vel=%f\n" , nexttc -> currentvel );
3774+ }
37443775 break ;
37453776 case TC_TERM_COND_PARABOLIC :
37463777 break ;
@@ -3799,7 +3830,7 @@ STATIC int tpHandleRegularCycle(TP_STRUCT * const tp,
37993830 double target_vel_this = tpGetRealTargetVel (tp , tc );
38003831 double target_vel_next = tpGetRealTargetVel (tp , nexttc );
38013832
3802- if (mode != -5 && ( GET_TRAJ_PLANNER_TYPE () == 1 || GET_TRAJ_PLANNER_TYPE () == 2 ) )
3833+ if (mode != -5 && GET_TRAJ_PLANNER_TYPE () == 1 )
38033834 tpComputeBlendSCurveVelocity (tc , nexttc , target_vel_this , target_vel_next , & v_this , & v_next , NULL );
38043835 else
38053836 tpComputeBlendVelocity (tc , nexttc , target_vel_this , target_vel_next , & v_this , & v_next , NULL );
0 commit comments