|
|
@@ -12,7 +12,9 @@ |
|
|
* 3) 发送模式只影响本段 f_end(完成=止速;后续且不停表=下一段目标) |
|
|
* 3) 发送模式只影响本段 f_end(完成=止速;后续且不停表=下一段目标) |
|
|
* 4) PlanSeg / ChangeFreq 共用规划入口,便于后期动态改频 |
|
|
* 4) PlanSeg / ChangeFreq 共用规划入口,便于后期动态改频 |
|
|
* |
|
|
* |
|
|
* 【运行节拍】TIM3 1ms:RefreshProfile 改频;脉冲 UPDATE ISR 只计 s_done。 |
|
|
|
|
|
|
|
|
* 【运行节拍】TIM3 1ms:RefreshProfile 改频。 |
|
|
|
|
|
* 加速:t=0 起正向走 t_acc;减速:按 t_decel_start(反向规划)或 remain<=dec_n 进入。 |
|
|
|
|
|
* 脉冲 UPDATE ISR 只计 s_done。 |
|
|
*/ |
|
|
*/ |
|
|
#include "plsr_run_control.h" |
|
|
#include "plsr_run_control.h" |
|
|
#include "plsr_path_plan.h" |
|
|
#include "plsr_path_plan.h" |
|
|
@@ -67,6 +69,8 @@ static uint8_t s_follow_cont; |
|
|
static uint32_t s_chain_freq; |
|
|
static uint32_t s_chain_freq; |
|
|
static uint8_t s_chain_valid; |
|
|
static uint8_t s_chain_valid; |
|
|
static uint8_t s_pwm_on; |
|
|
static uint8_t s_pwm_on; |
|
|
|
|
|
static uint8_t s_dec_armed; /* 1=已按剩余脉冲进入减速时间轴 */ |
|
|
|
|
|
static uint32_t s_dec_t0_ms; /* 进入减速时的段内时间 */ |
|
|
|
|
|
|
|
|
/* 本段由策略层解析后的加减速时间(段内只用这两份,不再读 wait) */ |
|
|
/* 本段由策略层解析后的加减速时间(段内只用这两份,不再读 wait) */ |
|
|
static uint16_t s_run_accel_ms; |
|
|
static uint16_t s_run_accel_ms; |
|
|
@@ -662,6 +666,8 @@ static void PlsrRunControlEnterDecel(uint32_t from_hz, uint32_t remain_pulses) |
|
|
|
|
|
|
|
|
PlsrRunControlEnterPhase(PH_DECEL, from_hz); |
|
|
PlsrRunControlEnterPhase(PH_DECEL, from_hz); |
|
|
f_end = s_accel_plan.f_end; |
|
|
f_end = s_accel_plan.f_end; |
|
|
|
|
|
s_dec_armed = 1U; |
|
|
|
|
|
s_dec_t0_ms = s_seg_elapsed_ms; |
|
|
|
|
|
|
|
|
if (remain_pulses == 0U) |
|
|
if (remain_pulses == 0U) |
|
|
{ |
|
|
{ |
|
|
@@ -749,12 +755,78 @@ static void PlsrRunControlEnterDecel(uint32_t from_hz, uint32_t remain_pulses) |
|
|
static void PlsrRunControlRefreshProfile(uint8_t do_start) |
|
|
static void PlsrRunControlRefreshProfile(uint8_t do_start) |
|
|
{ |
|
|
{ |
|
|
uint32_t next; |
|
|
uint32_t next; |
|
|
|
|
|
uint32_t remain; |
|
|
|
|
|
uint32_t t_rel; |
|
|
|
|
|
uint8_t has_dec; |
|
|
|
|
|
|
|
|
|
|
|
remain = 0U; |
|
|
|
|
|
if (s_target > s_done) |
|
|
|
|
|
{ |
|
|
|
|
|
remain = (uint32_t)(s_target - s_done); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
has_dec = ((s_accel_plan.t_dec_ms > 0U) && |
|
|
|
|
|
(s_accel_plan.dec_n > 0U) && |
|
|
|
|
|
(s_accel_plan.f_tgt != s_accel_plan.f_end)) ? 1U : 0U; |
|
|
|
|
|
|
|
|
|
|
|
if (has_dec != 0U) |
|
|
|
|
|
{ |
|
|
|
|
|
/* |
|
|
|
|
|
* 减速进点 = 反向规划(与加速对称): |
|
|
|
|
|
* 1) 时间:elapsed >= t_decel_start(t_acc + t_const,规划已算好) |
|
|
|
|
|
* 2) 脉冲:remain <= dec_n(从段末反推,防止脉冲先耗尽) |
|
|
|
|
|
* 二者谁先到谁触发;斜坡形状仍用 t_dec 时间轴,与加速 t_acc 对称。 |
|
|
|
|
|
*/ |
|
|
|
|
|
if (s_dec_armed == 0U) |
|
|
|
|
|
{ |
|
|
|
|
|
if ((s_seg_elapsed_ms >= s_accel_plan.t_decel_start_ms) || |
|
|
|
|
|
(remain <= s_accel_plan.dec_n)) |
|
|
|
|
|
{ |
|
|
|
|
|
s_dec_armed = 1U; |
|
|
|
|
|
if (s_seg_elapsed_ms >= s_accel_plan.t_decel_start_ms) |
|
|
|
|
|
{ |
|
|
|
|
|
/* 按规划时刻进:与 FreqAtSegTime 同一时间原点 */ |
|
|
|
|
|
s_dec_t0_ms = s_accel_plan.t_decel_start_ms; |
|
|
|
|
|
} |
|
|
|
|
|
else |
|
|
|
|
|
{ |
|
|
|
|
|
/* 脉冲域先到:从当前时刻起跑减速斜坡 */ |
|
|
|
|
|
s_dec_t0_ms = s_seg_elapsed_ms; |
|
|
|
|
|
} |
|
|
|
|
|
PlsrRunControlEnterPhase(PH_DECEL, s_accel_plan.f_tgt); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (s_dec_armed != 0U) |
|
|
|
|
|
{ |
|
|
|
|
|
t_rel = s_seg_elapsed_ms - s_dec_t0_ms; |
|
|
|
|
|
next = PlsrAccelCurveFreqOnRampMs(s_accel_plan.f_tgt, |
|
|
|
|
|
s_accel_plan.f_end, |
|
|
|
|
|
t_rel, |
|
|
|
|
|
s_accel_plan.t_dec_ms, |
|
|
|
|
|
s_accel_plan.mode); |
|
|
|
|
|
} |
|
|
|
|
|
else if ((s_accel_plan.t_acc_ms > 0U) && |
|
|
|
|
|
(s_seg_elapsed_ms < s_accel_plan.t_acc_ms) && |
|
|
|
|
|
(s_accel_plan.f_cur != s_accel_plan.f_tgt)) |
|
|
|
|
|
{ |
|
|
|
|
|
/* 加速:从 t=0 正向规划 */ |
|
|
|
|
|
next = PlsrAccelCurveFreqOnRampMs(s_accel_plan.f_cur, |
|
|
|
|
|
s_accel_plan.f_tgt, |
|
|
|
|
|
s_seg_elapsed_ms, |
|
|
|
|
|
s_accel_plan.t_acc_ms, |
|
|
|
|
|
s_accel_plan.mode); |
|
|
|
|
|
} |
|
|
|
|
|
else |
|
|
|
|
|
{ |
|
|
|
|
|
next = s_accel_plan.f_tgt; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
else |
|
|
|
|
|
{ |
|
|
|
|
|
next = PlsrAccelCurveFreqAtSegTime(&s_accel_plan, s_seg_elapsed_ms); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
/* |
|
|
|
|
|
* 1ms 改频:段内统一时间轴;t_decel_start_ms 由规划反向算出, |
|
|
|
|
|
* 减速为 f_tgt→f_end 直线,自然落到止速,末拍不再强行对齐。 |
|
|
|
|
|
*/ |
|
|
|
|
|
next = PlsrAccelCurveFreqAtSegTime(&s_accel_plan, s_seg_elapsed_ms); |
|
|
|
|
|
if (next < 1U) |
|
|
if (next < 1U) |
|
|
{ |
|
|
{ |
|
|
next = 1U; |
|
|
next = 1U; |
|
|
@@ -858,6 +930,8 @@ static void PlsrRunControlPlanSeg(uint32_t total, uint32_t f_from, |
|
|
|
|
|
|
|
|
s_approach_from = f_start; |
|
|
s_approach_from = f_start; |
|
|
s_decel_from = s_accel_plan.f_tgt; |
|
|
s_decel_from = s_accel_plan.f_tgt; |
|
|
|
|
|
s_dec_armed = 0U; |
|
|
|
|
|
s_dec_t0_ms = 0U; |
|
|
if (s_pwm_on == 0U) |
|
|
if (s_pwm_on == 0U) |
|
|
{ |
|
|
{ |
|
|
s_cur_freq = f_start; |
|
|
s_cur_freq = f_start; |
|
|
@@ -902,6 +976,8 @@ static void PlsrRunControlFinishAll(void) |
|
|
s_follow_cont = 0U; |
|
|
s_follow_cont = 0U; |
|
|
s_chain_valid = 0U; |
|
|
s_chain_valid = 0U; |
|
|
s_chain_freq = 0U; |
|
|
s_chain_freq = 0U; |
|
|
|
|
|
s_dec_armed = 0U; |
|
|
|
|
|
s_dec_t0_ms = 0U; |
|
|
s_act_armed = 0U; |
|
|
s_act_armed = 0U; |
|
|
s_act_expire_req = 0U; |
|
|
s_act_expire_req = 0U; |
|
|
s_act_cut_pending = 0U; |
|
|
s_act_cut_pending = 0U; |
|
|
@@ -1030,6 +1106,8 @@ void PlsrRunControlInit(void) |
|
|
s_seg_elapsed_ms = 0U; |
|
|
s_seg_elapsed_ms = 0U; |
|
|
s_approach_from = 0U; |
|
|
s_approach_from = 0U; |
|
|
s_decel_from = 0U; |
|
|
s_decel_from = 0U; |
|
|
|
|
|
s_dec_armed = 0U; |
|
|
|
|
|
s_dec_t0_ms = 0U; |
|
|
s_act_armed = 0U; |
|
|
s_act_armed = 0U; |
|
|
s_act_expire_req = 0U; |
|
|
s_act_expire_req = 0U; |
|
|
s_act_cut_pending = 0U; |
|
|
s_act_cut_pending = 0U; |
|
|
@@ -1083,6 +1161,8 @@ void PlsrRunControlStop(void) |
|
|
s_follow_cont = 0U; |
|
|
s_follow_cont = 0U; |
|
|
s_chain_valid = 0U; |
|
|
s_chain_valid = 0U; |
|
|
s_chain_freq = 0U; |
|
|
s_chain_freq = 0U; |
|
|
|
|
|
s_dec_armed = 0U; |
|
|
|
|
|
s_dec_t0_ms = 0U; |
|
|
s_act_armed = 0U; |
|
|
s_act_armed = 0U; |
|
|
s_act_expire_req = 0U; |
|
|
s_act_expire_req = 0U; |
|
|
s_act_cut_pending = 0U; |
|
|
s_act_cut_pending = 0U; |
|
|
|