Add z-direction calibration action to sangaboard
This commit is contained in:
parent
f68515b17d
commit
274f698fab
4 changed files with 74 additions and 27 deletions
|
|
@ -166,8 +166,14 @@ class BaseStage(lt.Thing):
|
||||||
)
|
)
|
||||||
"""Used to convert coordinates between the program frame and the hardware frame."""
|
"""Used to convert coordinates between the program frame and the hardware frame."""
|
||||||
|
|
||||||
calibration_required: bool = lt.setting(default=False)
|
@lt.property
|
||||||
"""Whether calibration of the stage z axis is required."""
|
def calibration_required(self) -> bool:
|
||||||
|
"""Whether the stage requires calibration.
|
||||||
|
|
||||||
|
Currently the only calibration method for the stage is the z-gear rotation
|
||||||
|
direction in the sangaboard stage.
|
||||||
|
"""
|
||||||
|
return False
|
||||||
|
|
||||||
def update_position(self) -> None:
|
def update_position(self) -> None:
|
||||||
"""Update the position property from the stage."""
|
"""Update the position property from the stage."""
|
||||||
|
|
@ -538,8 +544,3 @@ class BaseStage(lt.Thing):
|
||||||
This method provides the interface expected by the camera_stage_mapping.
|
This method provides the interface expected by the camera_stage_mapping.
|
||||||
"""
|
"""
|
||||||
self.move_absolute(x=xyz_pos[0], y=xyz_pos[1], z=xyz_pos[2])
|
self.move_absolute(x=xyz_pos[0], y=xyz_pos[1], z=xyz_pos[2])
|
||||||
|
|
||||||
@lt.action
|
|
||||||
def mark_calibration_complete(self) -> None:
|
|
||||||
"""Mark stage calibration as complete."""
|
|
||||||
self.calibration_required = False
|
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,37 @@ class SangaboardThing(BaseStage):
|
||||||
)
|
)
|
||||||
"""Used to convert coordinates between the program frame and the hardware frame."""
|
"""Used to convert coordinates between the program frame and the hardware frame."""
|
||||||
|
|
||||||
|
z_axis_calibrated: bool = lt.setting(default=False, readonly=True)
|
||||||
|
|
||||||
|
@lt.property
|
||||||
|
def calibration_required(self) -> bool:
|
||||||
|
"""Whether the stage requires calibration.
|
||||||
|
|
||||||
|
Return False only if z-direction has been calibrated.
|
||||||
|
"""
|
||||||
|
return not self.z_axis_calibrated
|
||||||
|
|
||||||
|
@lt.action
|
||||||
|
def calibrate_z_direction(
|
||||||
|
self, positive_motion: Literal["clockwise", "anti-clockwise"]
|
||||||
|
) -> None:
|
||||||
|
"""Calibrate the z motor direction based on the gear rotation direction.
|
||||||
|
|
||||||
|
Positive z motion should turn the exposed gear anti-clockwise. Calling this
|
||||||
|
action marks the z motor as calibrated.
|
||||||
|
|
||||||
|
:param positive_motion: The direction the gear moved during pisitive z motion.
|
||||||
|
"""
|
||||||
|
if positive_motion == "clockwise":
|
||||||
|
# Wrong direction, mark as such.
|
||||||
|
self.invert_axis_direction(axis="z")
|
||||||
|
elif positive_motion != "anti-clockwise":
|
||||||
|
raise ValueError(
|
||||||
|
"Motion should be reported as either 'clockwise' or 'anti-clockwise'."
|
||||||
|
)
|
||||||
|
# Set z_axis_calibrated to true once this function is called.
|
||||||
|
self.z_axis_calibrated = True
|
||||||
|
|
||||||
def _hardware_update_position(self) -> None:
|
def _hardware_update_position(self) -> None:
|
||||||
"""Read position from the stage and set internal attribute _hardware_position.
|
"""Read position from the stage and set internal attribute _hardware_position.
|
||||||
|
|
||||||
|
|
@ -236,6 +267,3 @@ class SangaboardThing(BaseStage):
|
||||||
self._sangaboard.query(f"{led_command} {on_brightness}")
|
self._sangaboard.query(f"{led_command} {on_brightness}")
|
||||||
else:
|
else:
|
||||||
self._sangaboard.query(f"{led_command} 0")
|
self._sangaboard.query(f"{led_command} 0")
|
||||||
|
|
||||||
calibration_required: bool = lt.setting(default=True)
|
|
||||||
"""By default, Sangaboard stage will require calibration of z direction."""
|
|
||||||
|
|
|
||||||
|
|
@ -21,13 +21,13 @@
|
||||||
src="/direction_AC.png"
|
src="/direction_AC.png"
|
||||||
alt="Anti-clockwise"
|
alt="Anti-clockwise"
|
||||||
class="dir-image clickable"
|
class="dir-image clickable"
|
||||||
@click="selectDir"
|
@click="reportDirection('anti-clockwise')"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="uk-button uk-button-default uk-width-1-1 uk-button-primary"
|
class="uk-button uk-button-default uk-width-1-1 uk-button-primary"
|
||||||
type="button"
|
type="button"
|
||||||
@click="selectDir"
|
@click="reportDirection('anti-clockwise')"
|
||||||
>
|
>
|
||||||
Anti-clockwise
|
Anti-clockwise
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -39,13 +39,13 @@
|
||||||
src="/direction_CW.png"
|
src="/direction_CW.png"
|
||||||
alt="Clockwise"
|
alt="Clockwise"
|
||||||
class="dir-image clickable"
|
class="dir-image clickable"
|
||||||
@click="triggerClockwise"
|
@click="reportDirection('clockwise')"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="uk-button uk-button-default uk-width-1-1 uk-button-primary"
|
class="uk-button uk-button-default uk-width-1-1 uk-button-primary"
|
||||||
type="button"
|
type="button"
|
||||||
@click="triggerClockwise"
|
@click="reportDirection('clockwise')"
|
||||||
>
|
>
|
||||||
Clockwise
|
Clockwise
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -68,7 +68,7 @@ export default {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
async mounted() {
|
||||||
this.checkCalibrationState();
|
this.checkCalibrationState();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -92,20 +92,25 @@ export default {
|
||||||
}
|
}
|
||||||
this.invokeAction("stage", "jog", { stop: true });
|
this.invokeAction("stage", "jog", { stop: true });
|
||||||
},
|
},
|
||||||
// Once a direction is selected, advance
|
/**
|
||||||
selectDir() {
|
* Report the direction to the microscope then advance to next pane in wizard.
|
||||||
this.invokeAction("stage", "mark_calibration_complete").then(() => {
|
*/
|
||||||
this.$emit("advance");
|
async reportDirection(direction) {
|
||||||
});
|
await this.invokeAction("stage", "calibrate_z_direction", { positive_motion: direction });
|
||||||
},
|
this.$emit("advance");
|
||||||
// If motor moves clockwise, invert z direction, then progress to next step
|
|
||||||
triggerClockwise() {
|
|
||||||
this.invokeAction("stage", "invert_axis_direction", { axis: "z" }).then(() => {
|
|
||||||
this.selectDir();
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
async checkCalibrationState() {
|
async checkCalibrationState() {
|
||||||
const needsCal = await this.readThingProperty("stage", "calibration_required");
|
let needsCal = await this.readThingProperty("stage", "calibration_required");
|
||||||
|
if (needsCal) {
|
||||||
|
// If it needs calibration check the relevant calibration action exists.
|
||||||
|
const actions = this.thingDescription("stage").actions;
|
||||||
|
if (!("calibrate_z_direction" in actions)) {
|
||||||
|
console.error(
|
||||||
|
"Stage is requesting calibration but has no 'calibrate_z_direction' action",
|
||||||
|
);
|
||||||
|
needsCal = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
this.$emit("awaiting-user", needsCal);
|
this.$emit("awaiting-user", needsCal);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -133,4 +133,17 @@ export const componentOverrides = {
|
||||||
"cameraCalibrationSettings.vue": {
|
"cameraCalibrationSettings.vue": {
|
||||||
props: { cameraUri: "" },
|
props: { cameraUri: "" },
|
||||||
},
|
},
|
||||||
|
"zMotorDirectionStep.vue": {
|
||||||
|
mocks: {
|
||||||
|
thingDescription: () => ({
|
||||||
|
properties: {
|
||||||
|
test_property_1: {},
|
||||||
|
test_property_2: {},
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
calibrate_z_direction: {},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue