From 6033dcd47ad30731449679f2c6628d9d50fe85e8 Mon Sep 17 00:00:00 2001 From: wangdequan Date: Mon, 31 Aug 2026 06:36:53 +0800 Subject: [PATCH] Preserve motion queue ABI for feed override --- wasm-core/include/sim_motion_queue.h | 5 +++-- wasm-core/src/sim_motion_queue.c | 6 +++--- wasm-core/tests/sim_motion_queue_test.c | 2 +- web/worker/wasm-motion-queue.mjs | 6 +++--- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/wasm-core/include/sim_motion_queue.h b/wasm-core/include/sim_motion_queue.h index 41a9dbf..b7faf16 100644 --- a/wasm-core/include/sim_motion_queue.h +++ b/wasm-core/include/sim_motion_queue.h @@ -30,10 +30,11 @@ typedef struct sim_motion_command { sim_posemath_segment segment; uint32_t id; uint32_t tag; - uint32_t flags; } sim_motion_command; -#define SIM_MOTION_COMMAND_FLAG_RAPID 1u +/* The high tag bit is reserved for Rapid blocks so the command ABI remains + compatible with existing checkpoints and WASM clients. */ +#define SIM_MOTION_COMMAND_TAG_RAPID (UINT32_C(1) << 31) typedef struct sim_motion_state { sim_posemath_pose position; diff --git a/wasm-core/src/sim_motion_queue.c b/wasm-core/src/sim_motion_queue.c index 518d581..ee109e7 100644 --- a/wasm-core/src/sim_motion_queue.c +++ b/wasm-core/src/sim_motion_queue.c @@ -184,11 +184,11 @@ static double planned_velocity(const sim_motion_queue *queue, uint32_t offset) { uint32_t index; if (queue == NULL || offset >= queue->count) return 0.0; index = (queue->head + offset) % SIM_MOTION_QUEUE_CAPACITY; - velocity = queue->commands[index].segment.velocity * (meta == NULL || (queue->commands[index].flags & SIM_MOTION_COMMAND_FLAG_RAPID) != 0u ? 1.0 : meta->feed_override); + velocity = queue->commands[index].segment.velocity * (meta == NULL || (queue->commands[index].tag & SIM_MOTION_COMMAND_TAG_RAPID) != 0u ? 1.0 : meta->feed_override); if (meta == NULL || meta->profile == SIM_MOTION_PROFILE_EXACT_STOP) return velocity; for (index = 1; index <= meta->lookahead && offset + index < queue->count; ++index) { uint32_t next = (queue->head + offset + index) % SIM_MOTION_QUEUE_CAPACITY; - const double next_velocity = queue->commands[next].segment.velocity * ((queue->commands[next].flags & SIM_MOTION_COMMAND_FLAG_RAPID) != 0u ? 1.0 : meta->feed_override); + const double next_velocity = queue->commands[next].segment.velocity * ((queue->commands[next].tag & SIM_MOTION_COMMAND_TAG_RAPID) != 0u ? 1.0 : meta->feed_override); if (next_velocity < velocity) velocity = next_velocity; } return velocity; @@ -232,7 +232,7 @@ int sim_motion_step(sim_motion_queue *queue) { command = &queue->commands[queue->head]; length = segment_length(&command->segment); if (length <= 0.0) { queue->state.status = SIM_MOTION_ERR_GEOMETRY; return queue->state.status; } - queue->state.active_id = command->id; queue->state.active_tag = command->tag; queue->state.motion_type = command->segment.motion_type; + queue->state.active_id = command->id; queue->state.active_tag = command->tag & ~SIM_MOTION_COMMAND_TAG_RAPID; queue->state.motion_type = command->segment.motion_type; desired_velocity = planned_velocity(queue, 0); acceleration = (desired_velocity - meta->current_velocity) / queue->cycle_time; if (acceleration > meta->current_acceleration + meta->jerk_limit * queue->cycle_time) acceleration = meta->current_acceleration + meta->jerk_limit * queue->cycle_time; diff --git a/wasm-core/tests/sim_motion_queue_test.c b/wasm-core/tests/sim_motion_queue_test.c index 6b86862..a3dc6e0 100644 --- a/wasm-core/tests/sim_motion_queue_test.c +++ b/wasm-core/tests/sim_motion_queue_test.c @@ -60,7 +60,7 @@ int main(void) { assert(override_state.position.tran.x > 0.049 && override_state.position.tran.x < 0.051); assert(override_state.velocity > 0.49 && override_state.velocity < 0.51); sim_motion_reset(&override_queue); - override_command.flags = SIM_MOTION_COMMAND_FLAG_RAPID; + override_command.tag = SIM_MOTION_COMMAND_TAG_RAPID; assert(sim_motion_enqueue(&override_queue, &override_command, 0) == SIM_MOTION_OK); assert(sim_motion_step(&override_queue) == SIM_MOTION_OK); assert(sim_motion_read_state(&override_queue, &override_state) == SIM_MOTION_OK); diff --git a/web/worker/wasm-motion-queue.mjs b/web/worker/wasm-motion-queue.mjs index ae8ebf5..4498e3a 100644 --- a/web/worker/wasm-motion-queue.mjs +++ b/web/worker/wasm-motion-queue.mjs @@ -102,10 +102,10 @@ export class WasmMotionQueue { [...poseToArray(segment.start), ...poseToArray(segment.end), Number(segment.center?.x ?? 0), Number(segment.center?.y ?? 0), Number(segment.center?.z ?? 0), Number(segment.normal?.x ?? 0), Number(segment.normal?.y ?? 0), Number(segment.normal?.z ?? 0), Number(segment.velocity ?? 0), Number(segment.acceleration ?? 0)].forEach((value, index) => { doubles[base + index] = value; }); ints[this.command / 4 + SEGMENT_INT_OFFSET] = Number(segment.motion_type ?? 1); ints[this.command / 4 + SEGMENT_INT_OFFSET + 1] = Number(segment.turn ?? 0); - // sim_motion_command layout is segment (216 bytes), id (4), tag (4), flags (4). + // sim_motion_command layout is segment (216 bytes), id (4), tag (4). // Keep the WASM switchkins mode in the tag field; the C queue assigns id. - ints[this.command / 4 + SEGMENT_INT_OFFSET + 3] = Number(segment.kinematics_mode ?? segment.tag ?? 0); - ints[this.command / 4 + SEGMENT_INT_OFFSET + 4] = segment.kind === "rapid" ? 1 : 0; + const tag = Number(segment.kinematics_mode ?? segment.tag ?? 0) & 0x7fffffff; + ints[this.command / 4 + SEGMENT_INT_OFFSET + 3] = tag | (segment.kind === "rapid" ? 0x80000000 : 0); const result = call(this.core, "sim_motion_enqueue", "number", ["number", "number", "number"], [this.queue, this.command, 0]); return result === 0 ? { status: "verified", source_line: segment.source_line ?? null } : { status: "error", code: `wasm_motion_enqueue_${result}`, reason: MOTION_ERROR_REASONS[result] ?? `wasm_motion_enqueue_${result}`, message_key: MOTION_ERROR_REASONS[result] ?? `wasm_motion_enqueue_${result}`, source: "linuxcnc-wasm-motion" }; }