|
|
|
@@ -67,11 +67,11 @@ static uint32_t PlsrAccelCurveIsqrt64(uint64_t val) |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 起跳频率:f = sqrt(f_from^2 + 2a),a = df*1000/t_ms。 |
|
|
|
* f_from=0 → sqrt(2a);超过 f_to 钳到 f_to。 |
|
|
|
* 起跳频率(原始):f = sqrt(f_from^2 + 2a),a = df*1000/t_ms。 |
|
|
|
* 不钳到 f_to,供与目标频比较;f_from=0 → sqrt(2a)。 |
|
|
|
*/ |
|
|
|
static uint32_t PlsrAccelCurveJumpFreq(uint32_t f_from, uint32_t f_to, |
|
|
|
uint32_t t_ms) |
|
|
|
static uint32_t PlsrAccelCurveJumpFreqRaw(uint32_t f_from, uint32_t f_to, |
|
|
|
uint32_t t_ms) |
|
|
|
{ |
|
|
|
uint32_t df; |
|
|
|
uint32_t a_hz_s; |
|
|
|
@@ -89,7 +89,7 @@ static uint32_t PlsrAccelCurveJumpFreq(uint32_t f_from, uint32_t f_to, |
|
|
|
df = PlsrAccelCurveAbsDiff(f_from, f_to); |
|
|
|
if (df == 0U) |
|
|
|
{ |
|
|
|
return f_to; |
|
|
|
return (f_from >= 1U) ? f_from : f_to; |
|
|
|
} |
|
|
|
if (df <= 4294967U) |
|
|
|
{ |
|
|
|
@@ -112,6 +112,18 @@ static uint32_t PlsrAccelCurveJumpFreq(uint32_t f_from, uint32_t f_to, |
|
|
|
{ |
|
|
|
f = 1U; |
|
|
|
} |
|
|
|
return PlsrAccelCurveClampFreq(f); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 起跳频率:f = sqrt(f_from^2 + 2a),a = df*1000/t_ms。 |
|
|
|
* f_from=0 → sqrt(2a);超过 f_to 钳到 f_to。 |
|
|
|
*/ |
|
|
|
static uint32_t PlsrAccelCurveJumpFreq(uint32_t f_from, uint32_t f_to, |
|
|
|
uint32_t t_ms) |
|
|
|
{ |
|
|
|
uint32_t f = PlsrAccelCurveJumpFreqRaw(f_from, f_to, t_ms); |
|
|
|
|
|
|
|
if (f > f_to) |
|
|
|
{ |
|
|
|
f = f_to; |
|
|
|
@@ -179,13 +191,22 @@ static uint32_t PlsrAccelCurveRampTimeMs(uint32_t f_from, |
|
|
|
return t; |
|
|
|
} |
|
|
|
|
|
|
|
uint32_t PlsrAccelCurveResolveStartHz(uint32_t f_cfg, |
|
|
|
uint32_t f_tgt, |
|
|
|
uint32_t default_spd, |
|
|
|
uint32_t accel_ms, |
|
|
|
uint32_t decel_ms) |
|
|
|
/** |
|
|
|
* 按「默认起/止速、目标、起跳」三分支解析边界频率: |
|
|
|
* 1) 默认速 > 目标 → 用默认速(再减速到目标 / 出口用止速) |
|
|
|
* 2) 默认速 < 目标 且 目标 < 起跳 → 用目标 |
|
|
|
* 3) 默认速 < 目标 且 目标 > 起跳 → 用起跳 |
|
|
|
* 起跳 = sqrt(f_cfg^2+2a)(不先钳到目标,便于与目标比较)。 |
|
|
|
*/ |
|
|
|
static uint32_t PlsrAccelCurveResolveBoundHz(uint32_t f_cfg, |
|
|
|
uint32_t f_tgt, |
|
|
|
uint32_t default_spd, |
|
|
|
uint32_t accel_ms, |
|
|
|
uint32_t decel_ms, |
|
|
|
uint8_t is_start) |
|
|
|
{ |
|
|
|
uint32_t t_acc; |
|
|
|
uint32_t t_ms; |
|
|
|
uint32_t jump; |
|
|
|
|
|
|
|
f_cfg = PlsrAccelCurveClampFreq(f_cfg); |
|
|
|
f_tgt = PlsrAccelCurveClampFreq(f_tgt); |
|
|
|
@@ -194,10 +215,40 @@ uint32_t PlsrAccelCurveResolveStartHz(uint32_t f_cfg, |
|
|
|
return 1U; |
|
|
|
} |
|
|
|
|
|
|
|
/* 起速 0 或非 0:都用 JumpFreq = sqrt(f_cfg^2 + 2a) */ |
|
|
|
t_acc = PlsrAccelCurveRampTimeMs(f_cfg, f_tgt, default_spd, |
|
|
|
accel_ms, decel_ms); |
|
|
|
return PlsrAccelCurveJumpFreq(f_cfg, f_tgt, t_acc); |
|
|
|
/* 默认起/止速 > 目标:用默认速 */ |
|
|
|
if (f_cfg > f_tgt) |
|
|
|
{ |
|
|
|
return f_cfg; |
|
|
|
} |
|
|
|
|
|
|
|
if (is_start != 0U) |
|
|
|
{ |
|
|
|
t_ms = PlsrAccelCurveRampTimeMs(f_cfg, f_tgt, default_spd, |
|
|
|
accel_ms, decel_ms); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
t_ms = PlsrAccelCurveRampTimeMs(f_tgt, f_cfg, default_spd, |
|
|
|
accel_ms, decel_ms); |
|
|
|
} |
|
|
|
jump = PlsrAccelCurveJumpFreqRaw(f_cfg, f_tgt, t_ms); |
|
|
|
|
|
|
|
/* 目标 < 起跳 → 用目标;目标 > 起跳 → 用起跳 */ |
|
|
|
if (f_tgt < jump) |
|
|
|
{ |
|
|
|
return f_tgt; |
|
|
|
} |
|
|
|
return jump; |
|
|
|
} |
|
|
|
|
|
|
|
uint32_t PlsrAccelCurveResolveStartHz(uint32_t f_cfg, |
|
|
|
uint32_t f_tgt, |
|
|
|
uint32_t default_spd, |
|
|
|
uint32_t accel_ms, |
|
|
|
uint32_t decel_ms) |
|
|
|
{ |
|
|
|
return PlsrAccelCurveResolveBoundHz(f_cfg, f_tgt, default_spd, |
|
|
|
accel_ms, decel_ms, 1U); |
|
|
|
} |
|
|
|
|
|
|
|
uint32_t PlsrAccelCurveResolveEndHz(uint32_t f_cfg, |
|
|
|
@@ -206,28 +257,8 @@ uint32_t PlsrAccelCurveResolveEndHz(uint32_t f_cfg, |
|
|
|
uint32_t accel_ms, |
|
|
|
uint32_t decel_ms) |
|
|
|
{ |
|
|
|
uint32_t t_dec; |
|
|
|
|
|
|
|
f_cfg = PlsrAccelCurveClampFreq(f_cfg); |
|
|
|
f_tgt = PlsrAccelCurveClampFreq(f_tgt); |
|
|
|
if (f_tgt < 1U) |
|
|
|
{ |
|
|
|
return 1U; |
|
|
|
} |
|
|
|
|
|
|
|
/* |
|
|
|
* 止速 0 或 1:按落地频率估计,避免 1Hz 拖尾。 |
|
|
|
*/ |
|
|
|
if (f_cfg <= 1U) |
|
|
|
{ |
|
|
|
t_dec = PlsrAccelCurveRampTimeMs(f_tgt, 0U, default_spd, |
|
|
|
accel_ms, decel_ms); |
|
|
|
return PlsrAccelCurveJumpFreq(0U, f_tgt, t_dec); |
|
|
|
} |
|
|
|
|
|
|
|
t_dec = PlsrAccelCurveRampTimeMs(f_tgt, f_cfg, default_spd, |
|
|
|
accel_ms, decel_ms); |
|
|
|
return PlsrAccelCurveJumpFreq(f_cfg, f_tgt, t_dec); |
|
|
|
return PlsrAccelCurveResolveBoundHz(f_cfg, f_tgt, default_spd, |
|
|
|
accel_ms, decel_ms, 0U); |
|
|
|
} |
|
|
|
|
|
|
|
/** 直线:进度千分比 → 形状千分比 */ |
|
|
|
@@ -828,7 +859,8 @@ static uint32_t PlsrAccelCurveFitPeak(uint32_t total_pulses, |
|
|
|
peak = f_cur - mid; |
|
|
|
n_a = PlsrAccelCurvePulsesForModeRamp(f_cur, peak, a_dec, mode); |
|
|
|
} |
|
|
|
n_d = PlsrAccelCurvePulsesForModeRamp(peak, f_end, a_dec, mode); |
|
|
|
n_d = PlsrAccelCurvePulsesForModeRamp(peak, f_end, |
|
|
|
(f_end > peak) ? a_acc : a_dec, mode); |
|
|
|
|
|
|
|
if ((n_a + n_d) <= total_pulses) |
|
|
|
{ |
|
|
|
@@ -938,14 +970,22 @@ void PlsrAccelCurvePlan(PlsrAccelPlan_t *plan, |
|
|
|
|
|
|
|
if (f_cur > f_peak) |
|
|
|
{ |
|
|
|
/* 入口高于峰值:首相为减速,用 a_dec(与 rampTimeMs 减速分支一致) */ |
|
|
|
/* 入口高于目标:首相减速到目标(谷底左侧 \) */ |
|
|
|
acc_n = PlsrAccelCurvePulsesForModeRamp(f_cur, f_peak, a_dec, m); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
acc_n = PlsrAccelCurvePulsesForModeRamp(f_cur, f_peak, a_acc, m); |
|
|
|
} |
|
|
|
dec_n = PlsrAccelCurvePulsesForModeRamp(f_peak, f_end, a_dec, m); |
|
|
|
/* 第二相:目标→出口;出口更高用 a_acc(谷底右侧 /),否则用 a_dec */ |
|
|
|
if (f_end > f_peak) |
|
|
|
{ |
|
|
|
dec_n = PlsrAccelCurvePulsesForModeRamp(f_peak, f_end, a_acc, m); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
dec_n = PlsrAccelCurvePulsesForModeRamp(f_peak, f_end, a_dec, m); |
|
|
|
} |
|
|
|
|
|
|
|
if (total_pulses == 0U) |
|
|
|
{ |
|
|
|
@@ -977,7 +1017,14 @@ void PlsrAccelCurvePlan(PlsrAccelPlan_t *plan, |
|
|
|
{ |
|
|
|
acc_n = PlsrAccelCurvePulsesForModeRamp(f_cur, f_peak, a_acc, m); |
|
|
|
} |
|
|
|
dec_n = PlsrAccelCurvePulsesForModeRamp(f_peak, f_end, a_dec, m); |
|
|
|
if (f_end > f_peak) |
|
|
|
{ |
|
|
|
dec_n = PlsrAccelCurvePulsesForModeRamp(f_peak, f_end, a_acc, m); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
dec_n = PlsrAccelCurvePulsesForModeRamp(f_peak, f_end, a_dec, m); |
|
|
|
} |
|
|
|
if (acc_n > total_pulses) |
|
|
|
{ |
|
|
|
acc_n = total_pulses; |
|
|
|
@@ -1121,7 +1168,9 @@ uint32_t PlsrAccelCurveFreqAtPulse(const PlsrAccelPlan_t *plan, |
|
|
|
rising = (plan->f_end >= plan->f_tgt) ? 1U : 0U; |
|
|
|
if (plan->mode == PLSR_ACCEL_LINEAR) |
|
|
|
{ |
|
|
|
f = PlsrAccelCurveFreqKinematic(plan->f_tgt, plan->a_dec, |
|
|
|
uint32_t a_use = (rising != 0U) ? plan->a_acc : plan->a_dec; |
|
|
|
|
|
|
|
f = PlsrAccelCurveFreqKinematic(plan->f_tgt, a_use, |
|
|
|
n, rising, plan->f_end); |
|
|
|
} |
|
|
|
else |
|
|
|
@@ -1131,16 +1180,17 @@ uint32_t PlsrAccelCurveFreqAtPulse(const PlsrAccelPlan_t *plan, |
|
|
|
uint32_t tramp = 0U; |
|
|
|
uint32_t t_us = 0U; |
|
|
|
uint32_t i; |
|
|
|
uint32_t a_use = (rising != 0U) ? plan->a_acc : plan->a_dec; |
|
|
|
|
|
|
|
f = plan->f_tgt; |
|
|
|
if (plan->mode == PLSR_ACCEL_S) |
|
|
|
{ |
|
|
|
PlsrAccelCurveSTimeParams(plan->f_tgt, plan->f_end, plan->a_dec, |
|
|
|
PlsrAccelCurveSTimeParams(plan->f_tgt, plan->f_end, a_use, |
|
|
|
&tj, &ta, &tramp); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
PlsrAccelCurveSineTimeParams(plan->f_tgt, plan->f_end, plan->a_dec, |
|
|
|
PlsrAccelCurveSineTimeParams(plan->f_tgt, plan->f_end, a_use, |
|
|
|
&tramp); |
|
|
|
} |
|
|
|
for (i = 0U; i < n; i++) |
|
|
|
@@ -1153,7 +1203,7 @@ uint32_t PlsrAccelCurveFreqAtPulse(const PlsrAccelPlan_t *plan, |
|
|
|
if (plan->mode == PLSR_ACCEL_S) |
|
|
|
{ |
|
|
|
f = PlsrAccelCurveSFreqAtTime(plan->f_tgt, plan->f_end, |
|
|
|
plan->a_dec, tj, ta, tramp, t_us); |
|
|
|
a_use, tj, ta, tramp, t_us); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
@@ -1233,10 +1283,11 @@ void PlsrAccelPulseRtBeginDec(PlsrAccelPulseRt_t *rt, |
|
|
|
rt->f0 = plan->f_tgt; |
|
|
|
rt->f1 = plan->f_end; |
|
|
|
rt->f = plan->f_tgt; |
|
|
|
rt->a = plan->a_dec; |
|
|
|
rt->n = 0U; |
|
|
|
rt->n_total = plan->dec_n; |
|
|
|
rt->rising = (plan->f_end >= plan->f_tgt) ? 1U : 0U; |
|
|
|
/* 谷底右侧爬升用 a_acc,正常减速用 a_dec */ |
|
|
|
rt->a = (rt->rising != 0U) ? plan->a_acc : plan->a_dec; |
|
|
|
rt->mode = plan->mode; |
|
|
|
rt->active = (plan->dec_n > 0U) && (plan->f_tgt != plan->f_end) ? 1U : 0U; |
|
|
|
PlsrAccelPulseRtSetupTimeProfile(rt); |
|
|
|
|