From 8c7c017ab420c0625fec6e71da53e2458cd49f73 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Tue, 18 Jun 2024 19:25:55 +0300 Subject: [PATCH] Add linear drive calibration demo --- .../controls/constructor/devices/StepDrive.kt | 8 +-- .../jvmMain/kotlin/LinearDriveCalibration.kt | 66 +++++++++++++++++++ 2 files changed, 69 insertions(+), 5 deletions(-) create mode 100644 demo/constructor/src/jvmMain/kotlin/LinearDriveCalibration.kt diff --git a/controls-constructor/src/commonMain/kotlin/space/kscience/controls/constructor/devices/StepDrive.kt b/controls-constructor/src/commonMain/kotlin/space/kscience/controls/constructor/devices/StepDrive.kt index be32f07..ab33e39 100644 --- a/controls-constructor/src/commonMain/kotlin/space/kscience/controls/constructor/devices/StepDrive.kt +++ b/controls-constructor/src/commonMain/kotlin/space/kscience/controls/constructor/devices/StepDrive.kt @@ -22,6 +22,7 @@ import kotlin.time.DurationUnit public class StepDrive( context: Context, ticksPerSecond: MutableDeviceState, + position: MutableDeviceState = MutableDeviceState(0), target: MutableDeviceState = MutableDeviceState(0), private val writeTicks: suspend (ticks: Long, speed: Double) -> Unit = { _, _ -> }, ) : DeviceConstructor(context) { @@ -30,10 +31,7 @@ public class StepDrive( public val speed: MutableDeviceState by property(MetaConverter.double, ticksPerSecond) - private val positionState = stateOf(target.value) - - public val position: DeviceState by property(MetaConverter.long, positionState) - + public val position: DeviceState by property(MetaConverter.long, position) //FIXME round to zero problem private val ticker = onTimer(reads = setOf(target, position), writes = setOf(position)) { prev, next -> @@ -46,7 +44,7 @@ public class StepDrive( else -> return@onTimer } writeTicks(steps, tickSpeed) - positionState.value += steps + position.value += steps } } diff --git a/demo/constructor/src/jvmMain/kotlin/LinearDriveCalibration.kt b/demo/constructor/src/jvmMain/kotlin/LinearDriveCalibration.kt new file mode 100644 index 0000000..1a2d5e9 --- /dev/null +++ b/demo/constructor/src/jvmMain/kotlin/LinearDriveCalibration.kt @@ -0,0 +1,66 @@ +package space.kscience.controls.demo.constructor + +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.ensureActive +import space.kscience.controls.constructor.DeviceConstructor +import space.kscience.controls.constructor.MutableDeviceState +import space.kscience.controls.constructor.device +import space.kscience.controls.constructor.devices.LimitSwitch +import space.kscience.controls.constructor.devices.StepDrive +import space.kscience.controls.constructor.models.MutableRangeState +import space.kscience.controls.manager.DeviceManager +import space.kscience.dataforge.context.Context + +private val ticksPerSecond = MutableDeviceState(3000.0) + +class LinearStepDrive( + context: Context, + drive: StepDrive, + atStart: LimitSwitch, + atEnd: LimitSwitch, +):DeviceConstructor(context){ + val drive by device(drive) + val atStart by device(atStart) + val atEnd by device(atEnd) +} + + +fun LinearStepDrive( + context: Context, + position: MutableRangeState, +): LinearStepDrive = LinearStepDrive( + context = context, + drive = StepDrive(context, ticksPerSecond, position), + atStart = LimitSwitch(context, position.atStart), + atEnd = LimitSwitch(context, position.atEnd) +) + +suspend fun LinearStepDrive.calibrate(step: Long = 10): ClosedRange = coroutineScope{ + do{ + ensureActive() + drive.target.value += step + } while (!atEnd.locked.value) + + val end = drive.position.value + + do{ + ensureActive() + drive.target.value -= step + } while (!atStart.locked.value) + + val start = drive.position.value + + return@coroutineScope start..end +} + +suspend fun main() = coroutineScope { + val context = Context{ + plugin(DeviceManager) + } + + val positionModel = MutableRangeState(0L, -1002L..1012L) + + val linearStepDrive = LinearStepDrive(context, positionModel) + + println(linearStepDrive.calibrate()) +} \ No newline at end of file