Make feed override control the WASM trajectory
This commit is contained in:
@@ -6,7 +6,7 @@ const SEGMENT_INT_OFFSET = SEGMENT_DOUBLES * 2;
|
||||
const QUEUE_HEADER_BYTES = 32;
|
||||
const STATE_POSITION_BYTES = 72;
|
||||
const MOTION_QUEUE_SCHEMA = "sim_motion_queue_state.v1";
|
||||
const DEFAULT_CONTROLS = Object.freeze({ profile: 0, lookahead: 1, acceleration_limit: 1e9, jerk_limit: 1e12, paused: false });
|
||||
const DEFAULT_CONTROLS = Object.freeze({ profile: 0, lookahead: 1, acceleration_limit: 1e9, jerk_limit: 1e12, feed_override: 1, paused: false });
|
||||
const MOTION_ERROR_REASONS = Object.freeze({
|
||||
[-600]: "wasm_motion_invalid_argument", [-601]: "wasm_motion_nonfinite_value", [-602]: "wasm_motion_limit_range",
|
||||
[-603]: "wasm_motion_invalid_state", [-604]: "wasm_motion_queue_full", [-605]: "wasm_motion_paused",
|
||||
@@ -53,9 +53,10 @@ function controls(value = {}) {
|
||||
lookahead: value.lookahead ?? DEFAULT_CONTROLS.lookahead,
|
||||
acceleration_limit: value.acceleration_limit ?? DEFAULT_CONTROLS.acceleration_limit,
|
||||
jerk_limit: value.jerk_limit ?? DEFAULT_CONTROLS.jerk_limit,
|
||||
feed_override: value.feed_override ?? DEFAULT_CONTROLS.feed_override,
|
||||
paused: value.paused ?? DEFAULT_CONTROLS.paused,
|
||||
};
|
||||
if (![0, 1].includes(result.profile) || !Number.isSafeInteger(result.lookahead) || result.lookahead < 1 || !Number.isFinite(result.acceleration_limit) || result.acceleration_limit <= 0 || !Number.isFinite(result.jerk_limit) || result.jerk_limit <= 0 || typeof result.paused !== "boolean") throw new Error("wasm_motion_controls_invalid");
|
||||
if (![0, 1].includes(result.profile) || !Number.isSafeInteger(result.lookahead) || result.lookahead < 1 || !Number.isFinite(result.acceleration_limit) || result.acceleration_limit <= 0 || !Number.isFinite(result.jerk_limit) || result.jerk_limit <= 0 || !Number.isFinite(result.feed_override) || result.feed_override < 0 || result.feed_override > 2 || typeof result.paused !== "boolean") throw new Error("wasm_motion_controls_invalid");
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -101,19 +102,22 @@ 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).
|
||||
// sim_motion_command layout is segment (216 bytes), id (4), tag (4), flags (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 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" };
|
||||
}
|
||||
|
||||
reset() {
|
||||
if (!this.available) return this.read();
|
||||
const previousFeedOverride = this.controls.feed_override;
|
||||
this.core.HEAPU8.fill(0, this.queue, this.queue + this.queueSize);
|
||||
const result = call(this.core, "sim_motion_init", "number", ["number", "number", "number"], [this.queue, this.cycleTime, this.velocityLimit]);
|
||||
if (result !== 0) throw new Error(`wasm_motion_reset_${result}`);
|
||||
this.controls = controls();
|
||||
this.setFeedOverride(previousFeedOverride);
|
||||
return this.read();
|
||||
}
|
||||
|
||||
@@ -144,6 +148,15 @@ export class WasmMotionQueue {
|
||||
return this.read();
|
||||
}
|
||||
|
||||
setFeedOverride(feedOverride) {
|
||||
const next = controls({ ...this.controls, feed_override: feedOverride });
|
||||
if (!this.available) { this.controls = next; return this.read(); }
|
||||
const result = optionalCall(this.core, "sim_motion_set_feed_override", "number", ["number", "number"], [this.queue, next.feed_override]);
|
||||
if (result !== null && result !== 0) throw new Error(`wasm_motion_feed_override_${result}`);
|
||||
this.controls = next;
|
||||
return this.read();
|
||||
}
|
||||
|
||||
setPaused(paused) {
|
||||
const next = controls({ ...this.controls, paused: Boolean(paused) });
|
||||
if (!this.available) { this.controls = next; return this.read(); }
|
||||
@@ -158,11 +171,13 @@ export class WasmMotionQueue {
|
||||
const current = this.read();
|
||||
if (current.status !== "verified") throw new Error("wasm_motion_abort_state");
|
||||
const previous = this.core.HEAPU8.slice(this.queue, this.queue + this.queueSize);
|
||||
const previousFeedOverride = this.controls.feed_override;
|
||||
const headerOffset = this.queueCapacity * this.commandCapacity;
|
||||
const stateOffset = headerOffset + QUEUE_HEADER_BYTES;
|
||||
const previousView = new DataView(previous.buffer, previous.byteOffset, previous.byteLength);
|
||||
const nextId = previousView.getUint32(headerOffset + 8, true);
|
||||
this.reset();
|
||||
this.setFeedOverride(previousFeedOverride);
|
||||
const bytes = new Uint8Array(this.queueSize);
|
||||
const view = new DataView(bytes.buffer);
|
||||
// sim_motion_queue stores commands first, followed by its 32-byte header.
|
||||
@@ -239,6 +254,7 @@ export class WasmMotionQueue {
|
||||
this.setProfile(nextControls.profile);
|
||||
this.setLookahead(nextControls.lookahead);
|
||||
this.setDynamics(nextControls.acceleration_limit, nextControls.jerk_limit);
|
||||
this.setFeedOverride(nextControls.feed_override);
|
||||
this.setPaused(nextControls.paused);
|
||||
this.core.HEAPU8.set(bytes, this.queue);
|
||||
const actual = this.read();
|
||||
|
||||
Reference in New Issue
Block a user