Add linear drive calibration demo

This commit is contained in:
Alexander Nozik 2024-06-18 19:25:55 +03:00
parent c63c2db651
commit 8c7c017ab4
2 changed files with 69 additions and 5 deletions

View File

@ -22,6 +22,7 @@ import kotlin.time.DurationUnit
public class StepDrive( public class StepDrive(
context: Context, context: Context,
ticksPerSecond: MutableDeviceState<Double>, ticksPerSecond: MutableDeviceState<Double>,
position: MutableDeviceState<Long> = MutableDeviceState(0),
target: MutableDeviceState<Long> = MutableDeviceState(0), target: MutableDeviceState<Long> = MutableDeviceState(0),
private val writeTicks: suspend (ticks: Long, speed: Double) -> Unit = { _, _ -> }, private val writeTicks: suspend (ticks: Long, speed: Double) -> Unit = { _, _ -> },
) : DeviceConstructor(context) { ) : DeviceConstructor(context) {
@ -30,10 +31,7 @@ public class StepDrive(
public val speed: MutableDeviceState<Double> by property(MetaConverter.double, ticksPerSecond) public val speed: MutableDeviceState<Double> by property(MetaConverter.double, ticksPerSecond)
private val positionState = stateOf(target.value) public val position: DeviceState<Long> by property(MetaConverter.long, position)
public val position: DeviceState<Long> by property(MetaConverter.long, positionState)
//FIXME round to zero problem //FIXME round to zero problem
private val ticker = onTimer(reads = setOf(target, position), writes = setOf(position)) { prev, next -> private val ticker = onTimer(reads = setOf(target, position), writes = setOf(position)) { prev, next ->
@ -46,7 +44,7 @@ public class StepDrive(
else -> return@onTimer else -> return@onTimer
} }
writeTicks(steps, tickSpeed) writeTicks(steps, tickSpeed)
positionState.value += steps position.value += steps
} }
} }

View File

@ -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<Long>,
): 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<Long> = 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<Long>(0L, -1002L..1012L)
val linearStepDrive = LinearStepDrive(context, positionModel)
println(linearStepDrive.calibrate())
}