Skip to content

1302 revise stepper minimal example UI#1336

Draft
Snacj wants to merge 5 commits into
masterfrom
1302-revise-stepper-minimal-example-ui
Draft

1302 revise stepper minimal example UI#1336
Snacj wants to merge 5 commits into
masterfrom
1302-revise-stepper-minimal-example-ui

Conversation

@Snacj
Copy link
Copy Markdown
Collaborator

@Snacj Snacj commented Apr 29, 2026

fix #1302

@Snacj Snacj requested a review from Copilot April 29, 2026 12:12
@Snacj Snacj linked an issue Apr 29, 2026 that may be closed by this pull request
@Snacj
Copy link
Copy Markdown
Collaborator Author

Snacj commented Apr 29, 2026

Needs to be tested on hardware before ready to merge.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the “test_machine_stepper” minimal machine to support a more structured UI by introducing explicit operation modes and typed frequency/acceleration selections, and wiring these through the backend machine API and the Electron control page.

Changes:

  • Add Mode, Frequency, and AccelerationFactor types to the stepper minimal machine API and expose new mutations (SetMode, SetFreq, SetAccFactor).
  • Extend EtherCAT stepper wrappers/modules with start/stop behavior and a new Ready init state.
  • Revamp the Electron stepper control page to use SelectionGroup-based controls for mode/frequency/acceleration.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
machines/src/minimal_machines/test_machine_stepper/new.rs Initialize the new mode field when constructing the machine.
machines/src/minimal_machines/test_machine_stepper/mod.rs Add mode to machine state, emit new structured state, and implement mode-driven behavior.
machines/src/minimal_machines/test_machine_stepper/api.rs Define new enums/state structs and add new API mutations for mode/frequency/acceleration.
ethercat-hal/src/io/stepper_velocity_wago_750_672.rs Add start/stop helpers and adjust frequency setter naming.
ethercat-hal/src/io/stepper_velocity_wago_750_671.rs Add start/stop helpers.
ethercat-hal/src/devices/wago_modules/wago_750_672.rs Introduce InitState::Ready and associated state-machine handling.
ethercat-hal/src/devices/wago_modules/wago_750_671.rs Introduce InitState::Ready and adjust control-byte generation in init states.
electron/src/machines/minimal_machines/testmachinestepper/useTestMachineStepper.ts Update hook to send new mutations and manage optimistic state for new structured fields.
electron/src/machines/minimal_machines/testmachinestepper/testMachineStepperNamespace.ts Add zod schemas/types for mode/frequency/acceleration and update StateEvent shape.
electron/src/machines/minimal_machines/testmachinestepper/TestMachineStepperControlPage.tsx Replace old button UI with selection-group UI for mode/frequency/acceleration.

self.set_enabled(true);
self.stop_motor();
}
Mode::Turn => self.start_motor(),
Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

set_mode sets Mode::Turn by calling start_motor() only. If the machine is currently in Standby (disabled/off), start_motor() in the stepper wrappers is a no-op unless the device is already initialized, so switching Standby → Turn will not start the motor. Consider enabling/initializing first (e.g., call set_enabled(true) before requesting start, or make start_motor able to request a start even when not initialized).

Suggested change
Mode::Turn => self.start_motor(),
Mode::Turn => {
self.set_enabled(true);
self.start_motor();
}

Copilot uses AI. Check for mistakes.
Comment on lines +91 to +95
pub fn get_state(self) -> InitState {
let dev = block_on(self.device.read());

dev.state.clone()
}
Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get_state takes self by value, which consumes the stepper wrapper and makes it unusable after calling this method. This is very likely unintended for a simple read accessor; change it to take &self (and return the cloned state) to avoid accidental moves.

Copilot uses AI. Check for mistakes.
Comment on lines +30 to +32
export const accelerationSchema = z.enum(["Default", "Low", "Mid", "High"]);
export type AccelerationFactor = z.infer<typeof accelerationSchema>;

Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The exported type name AccelerationFaktor mixes languages and differs from the Rust/backend AccelerationFactor, which makes the API surface harder to follow (and forces aliases in consumers). Consider renaming this to AccelerationFactor for consistency across frontend/backend.

Copilot generated this review using guidance from repository custom instructions.
Comment on lines +99 to +100
className: "h-full",
},
Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UI label spelling: the card title uses "Acceleration Faktor". If this UI is intended to be English (other labels are), this should be "Acceleration Factor" for consistency.

Copilot uses AI. Check for mistakes.
Comment on lines 267 to 271
InitState::Enable => {
// set the specific bits of Control Byte C1
let mut c1 = ControlByteC1::new().with_flag(C1Flag::Enable);
if self.desired_stop2_n {
c1 = c1.with_flag(C1Flag::Stop2N);
}
let c1 = ControlByteC1::new().with_flag(C1Flag::Enable);
let c1 = c1.bits();
self.rxpdo.control_byte1 = c1;
Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

InitState::Enable now sets only the Enable bit in control byte C1, but later states (Ready/Running/StartPulse*) always set Stop2N. Previously desired_stop2_n defaulted to true, so Stop2N was always asserted during init. Dropping Stop2N in early init states may change safety/stop behavior and could prevent expected acknowledgements depending on module config; consider restoring Stop2N in Enable (and adjusting the ack condition as your comment suggests).

Copilot uses AI. Check for mistakes.
};
use crate::{AsyncThreadMessage, Machine, MachineMessage};
use control_core::socketio::namespace::NamespaceCacheingLogic;
use core::convert::Into;
Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use core::convert::Into; is unnecessary (Rust prelude already includes Into) and may trigger an unused-import warning. Removing it keeps the module clean and avoids CI lint failures.

Suggested change
use core::convert::Into;

Copilot uses AI. Check for mistakes.
Comment on lines +62 to +64
acceleration_state: AccelerationState {
factor: stepper_velocity_wago750672.acc_range_sel.into(),
},
Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mode: self.mode.clone().into() is an identity conversion (ModeMode) and the .into() adds noise (and is the only reason Into was imported). Prefer assigning the cloned Mode directly.

Copilot uses AI. Check for mistakes.
Comment on lines 5 to 12
import {
useTestMachineStepperNamespace,
StateEvent,
modeSchema,
Mode,
AccelerationFactor as AccelerationFactor,
Frequency,
} from "./testMachineStepperNamespace";
Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

modeSchema is imported but never used in this file. If the Electron project enforces @typescript-eslint/no-unused-vars (it appears to elsewhere), this can fail lint/CI; remove the unused import.

Copilot uses AI. Check for mistakes.
Comment on lines +47 to +52
/**
* Accleration Factor Schema
*/
export const accelerationStateSchema = z.object({
factor: accelerationSchema,
});
Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spelling: "Accleration" is misspelled in the comment. Correcting it helps keep the public-facing schema/docs readable.

Copilot uses AI. Check for mistakes.
if self.desired_stop2_n {
c1 = c1.with_flag(C1Flag::Stop2N);
}
let c1 = ControlByteC1::new().with_flag(C1Flag::Enable);
Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

InitState::SetMode similarly builds C1 without Stop2N, while subsequent states always include it. If Stop2N is meant to be asserted continuously (as in the rest of this state machine), include it here too to avoid an init cycle that momentarily drops the stop bit.

Suggested change
let c1 = ControlByteC1::new().with_flag(C1Flag::Enable);
let c1 = ControlByteC1::new()
.with_flag(C1Flag::Enable)
.with_flag(C1Flag::Stop2N);

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Revise Stepper Minimal Example UI

3 participants