Preserve motion queue ABI for feed override
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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" };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user