#ifndef PLSR_PLANNER_H #define PLSR_PLANNER_H #include "plsr_platform.h" #include typedef enum { PLSR_BOUNDARY_STOP = 0, PLSR_BOUNDARY_NEXT_FRESH, PLSR_BOUNDARY_NEXT_CARRY, PLSR_BOUNDARY_WAIT_TIME, PLSR_BOUNDARY_WAIT_SIGNAL, PLSR_BOUNDARY_WAIT_EXT, PLSR_BOUNDARY_JUMP, PLSR_BOUNDARY_EXT_CUT } PLSR_BOUNDARY_ACTION; /* A block is self-contained: the planner must not read live Modbus state. */ typedef struct { uint32_t entryHz; // 本块起点频率:启动速度,或上一段 carry 过来的速度 uint32_t cruiseHz; // 本块目标巡航频率(段频率) uint32_t exitHz; // 本块终点频率:停止速度,或下一段 cruise(同向连续) uint32_t pulseBudget; // 本块要发的脉冲总数 uint32_t referenceSpeedHz; // 默认速度,用来折算加减速时间 T∝|Δf|/f_ref uint16_t accelerationTimeMs; // 从 0 爬到默认速度所配的加速时间(ms) uint16_t decelerationTimeMs; // 从默认速度降到 0 所配的减速时间(ms) uint16_t curveMode; // 0 线性,1 S 曲线,2 正弦 uint8_t pulseOutput; // 脉冲输出通道 0..3 PLSR_BOUNDARY_ACTION boundary; // 块结束后怎么走:停 / 下一段重起 / carry / WAIT / 跳转 / EXT切断 } PLSR_MOTION_BLOCK; typedef struct { PLSR_PLATFORM_TIMER_SETTING setting; uint32_t requestedFrequencyHz;//用于诊断的频率 uint32_t repeatCount;//这一档连续多少个脉冲。斜坡多半 1;匀速可以是剩下的全部(例如 5000) } PLSR_STREAM_ITEM; typedef enum { PLSR_PLANNER_OK = 0, PLSR_PLANNER_CLIPPED, PLSR_PLANNER_DONE, PLSR_PLANNER_INVALID } PLSR_PLANNER_STATUS; typedef enum { PLSR_PLANNER_PHASE_ENTRY = 0, PLSR_PLANNER_PHASE_STEADY, PLSR_PLANNER_PHASE_EXIT, PLSR_PLANNER_PHASE_COMPLETE } PLSR_PLANNER_PHASE; typedef struct { uint32_t pulseCount; uint32_t actualFrequencyHz; PLSR_PLANNER_PHASE phase; uint8_t deadlineInProfile; } PLSR_PLANNER_TIME_PREDICTION; typedef struct { PLSR_MOTION_BLOCK block; // 本块输入:起/巡/终速度、预算、加减速时间、曲线、通道 uint64_t phasePulses; // 起点相位,已实际输出的脉冲累计,冷启动为 0 uint32_t startHz; // 实际起始频率(appliedHz,0 抬成 1) uint32_t peakHz; // 实际峰值,预算不足时低于 cruise uint32_t endHz; // 实际终点:停止速度、carry 或 clip 后可达值 uint32_t entryPulses; // 加速段脉冲数 uint32_t steadyPulses; // 匀速段脉冲数,三角轮廓为 0 uint32_t exitPulses; // 减速段脉冲数 uint32_t generatedPulses; // 已交给调用方的脉冲总数(按脉冲计,非项数) uint32_t rampRelativePulse; // 当前斜坡内已走脉冲序号,0 为斜坡第一项 uint32_t rampPulseCount; // 当前斜坡总脉冲数 uint32_t rampFromHz; // 当前斜坡起点频率 uint32_t rampToHz; // 当前斜坡终点频率 uint32_t rampDurationMs; // 当前斜坡折算持续时间(ms) uint32_t lastRampHz; // 上一斜坡脉冲量化后的实际频率,禁止加减速倒退 uint64_t rampTotalAreaQ32; // 当前斜坡 x=0~1 的总面积(Q32) uint64_t rampAreaStepQ32; // 每个脉冲的面积整数商:totalArea / N uint64_t rampTargetAreaQ32; // 到当前脉冲结束必须达到的累计面积 uint64_t rampBoundaryQ32; // 上一脉冲结束时的归一化时间边界 x uint64_t rampActualTimeQ32; // 已按量化后 actualHz 走过的归一化时间(闭环) uint64_t rampLastPhaseStepQ32; // 上一脉冲相位步长,供后续预测边界 uint64_t rampFirstBoundaryQ32; // 第 1 个斜坡脉冲的精确边界(二分) uint64_t rampSecondBoundaryQ32; // 第 2 个斜坡脉冲的精确边界(二分),其后改预测 uint32_t rampAreaRemainder; // totalArea % N,余数往各脉冲面积上摊 uint32_t rampRemainderAccumulator; // 摊余数累加器,满 N 则目标面积 +1 uint8_t rampKind; // 0 无斜坡/匀速,1 加速,2 减速 uint8_t clipped; // 预算不足已裁峰/终点,结果仍可执行 uint8_t active; // 是否还可 Generate,吐完或失败清 0 } PLSR_PLANNER_CONTEXT; PLSR_PLANNER_STATUS PlsrPlannerBegin(PLSR_PLANNER_CONTEXT *context, const PLSR_MOTION_BLOCK *block, uint32_t appliedHz, uint64_t phasePulses); uint16_t PlsrPlannerGenerate(PLSR_PLANNER_CONTEXT *context, PLSR_STREAM_ITEM *output, uint16_t capacity); uint8_t PlsrPlannerPredictTime( const PLSR_PLANNER_CONTEXT *context, uint32_t elapsedUs, PLSR_PLANNER_TIME_PREDICTION *prediction); #endif /* PLSR_PLANNER_H */