add limit readers
This commit is contained in:
parent
984e7f12ef
commit
811477a636
@ -73,6 +73,7 @@ public class VirtualDrive(
|
|||||||
|
|
||||||
// compute new value based on velocity and acceleration from the previous step
|
// compute new value based on velocity and acceleration from the previous step
|
||||||
positionState.value += velocity * dtSeconds + force / mass * dtSeconds.pow(2) / 2
|
positionState.value += velocity * dtSeconds + force / mass * dtSeconds.pow(2) / 2
|
||||||
|
propertyChanged(Drive.position, positionState.value)
|
||||||
|
|
||||||
// compute new velocity based on acceleration on the previous step
|
// compute new velocity based on acceleration on the previous step
|
||||||
velocity += force / mass * dtSeconds
|
velocity += force / mass * dtSeconds
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package space.kscience.controls.constructor
|
package space.kscience.controls.constructor
|
||||||
|
|
||||||
|
import kotlinx.coroutines.flow.launchIn
|
||||||
|
import kotlinx.coroutines.flow.onEach
|
||||||
import space.kscience.controls.api.Device
|
import space.kscience.controls.api.Device
|
||||||
import space.kscience.controls.spec.DeviceBySpec
|
import space.kscience.controls.spec.DeviceBySpec
|
||||||
import space.kscience.controls.spec.DevicePropertySpec
|
import space.kscience.controls.spec.DevicePropertySpec
|
||||||
@ -28,6 +30,13 @@ public class VirtualLimitSwitch(
|
|||||||
context: Context,
|
context: Context,
|
||||||
public val lockedState: DeviceState<Boolean>,
|
public val lockedState: DeviceState<Boolean>,
|
||||||
) : DeviceBySpec<LimitSwitch>(LimitSwitch, context), LimitSwitch {
|
) : DeviceBySpec<LimitSwitch>(LimitSwitch, context), LimitSwitch {
|
||||||
|
|
||||||
|
init {
|
||||||
|
lockedState.valueFlow.onEach {
|
||||||
|
propertyChanged(LimitSwitch.locked, it)
|
||||||
|
}.launchIn(this)
|
||||||
|
}
|
||||||
|
|
||||||
override val locked: Boolean get() = lockedState.value
|
override val locked: Boolean get() = lockedState.value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,6 +62,7 @@ public class PidRegulator(
|
|||||||
lastPosition = drive.position
|
lastPosition = drive.position
|
||||||
|
|
||||||
drive.force = pidParameters.kp * delta + pidParameters.ki * integral + pidParameters.kd * derivative
|
drive.force = pidParameters.kp * delta + pidParameters.ki * integral + pidParameters.kd * derivative
|
||||||
|
propertyChanged(Regulator.position, drive.position)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,10 +32,10 @@ public class DoubleRangeState(
|
|||||||
/**
|
/**
|
||||||
* A state showing that the range is on its lower boundary
|
* A state showing that the range is on its lower boundary
|
||||||
*/
|
*/
|
||||||
public val atStartState: DeviceState<Boolean> = map(MetaConverter.boolean) { it == range.start }
|
public val atStartState: DeviceState<Boolean> = map(MetaConverter.boolean) { it <= range.start }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A state showing that the range is on its higher boundary
|
* A state showing that the range is on its higher boundary
|
||||||
*/
|
*/
|
||||||
public val atEndState: DeviceState<Boolean> = map(MetaConverter.boolean) { it == range.endInclusive }
|
public val atEndState: DeviceState<Boolean> = map(MetaConverter.boolean) { it >= range.endInclusive }
|
||||||
}
|
}
|
@ -9,11 +9,10 @@ import space.kscience.controls.api.propertyMessageFlow
|
|||||||
import space.kscience.controls.constructor.DeviceState
|
import space.kscience.controls.constructor.DeviceState
|
||||||
import space.kscience.controls.manager.clock
|
import space.kscience.controls.manager.clock
|
||||||
import space.kscience.dataforge.context.Context
|
import space.kscience.dataforge.context.Context
|
||||||
import space.kscience.dataforge.meta.ListValue
|
import space.kscience.dataforge.meta.*
|
||||||
import space.kscience.dataforge.meta.Meta
|
|
||||||
import space.kscience.dataforge.meta.Null
|
|
||||||
import space.kscience.dataforge.meta.Value
|
|
||||||
import space.kscience.plotly.Plot
|
import space.kscience.plotly.Plot
|
||||||
|
import space.kscience.plotly.bar
|
||||||
|
import space.kscience.plotly.models.Bar
|
||||||
import space.kscience.plotly.models.Scatter
|
import space.kscience.plotly.models.Scatter
|
||||||
import space.kscience.plotly.models.TraceValues
|
import space.kscience.plotly.models.TraceValues
|
||||||
import space.kscience.plotly.scatter
|
import space.kscience.plotly.scatter
|
||||||
@ -33,7 +32,7 @@ public fun Plot.plotDeviceProperty(
|
|||||||
propertyName: String,
|
propertyName: String,
|
||||||
extractValue: Meta.() -> Value = { value ?: Null },
|
extractValue: Meta.() -> Value = { value ?: Null },
|
||||||
pointsNumber: Int = 400,
|
pointsNumber: Int = 400,
|
||||||
coroutineScope: CoroutineScope = device,
|
coroutineScope: CoroutineScope = device.context,
|
||||||
configuration: Scatter.() -> Unit = {},
|
configuration: Scatter.() -> Unit = {},
|
||||||
): Job = scatter(configuration).run {
|
): Job = scatter(configuration).run {
|
||||||
val clock = device.context.clock
|
val clock = device.context.clock
|
||||||
@ -43,7 +42,8 @@ public fun Plot.plotDeviceProperty(
|
|||||||
}.launchIn(coroutineScope)
|
}.launchIn(coroutineScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun Plot.plotDeviceState(
|
|
||||||
|
public fun Plot.plotNumberState(
|
||||||
context: Context,
|
context: Context,
|
||||||
state: DeviceState<out Number>,
|
state: DeviceState<out Number>,
|
||||||
pointsNumber: Int = 400,
|
pointsNumber: Int = 400,
|
||||||
@ -54,4 +54,17 @@ public fun Plot.plotDeviceState(
|
|||||||
x.strings = (x.strings + clock.now().toString()).takeLast(pointsNumber)
|
x.strings = (x.strings + clock.now().toString()).takeLast(pointsNumber)
|
||||||
y.numbers = (y.numbers + it).takeLast(pointsNumber)
|
y.numbers = (y.numbers + it).takeLast(pointsNumber)
|
||||||
}.launchIn(context)
|
}.launchIn(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun Plot.plotBooleanState(
|
||||||
|
context: Context,
|
||||||
|
state: DeviceState<Boolean>,
|
||||||
|
pointsNumber: Int = 400,
|
||||||
|
configuration: Bar.() -> Unit = {},
|
||||||
|
): Job = bar(configuration).run {
|
||||||
|
val clock = context.clock
|
||||||
|
state.valueFlow.onEach {
|
||||||
|
x.strings = (x.strings + clock.now().toString()).takeLast(pointsNumber)
|
||||||
|
y.values = (y.values + it.asValue()).takeLast(pointsNumber)
|
||||||
|
}.launchIn(context)
|
||||||
}
|
}
|
@ -13,9 +13,10 @@ import space.kscience.controls.spec.doRecurring
|
|||||||
import space.kscience.controls.spec.name
|
import space.kscience.controls.spec.name
|
||||||
import space.kscience.controls.spec.write
|
import space.kscience.controls.spec.write
|
||||||
import space.kscience.controls.vision.plotDeviceProperty
|
import space.kscience.controls.vision.plotDeviceProperty
|
||||||
import space.kscience.controls.vision.plotDeviceState
|
import space.kscience.controls.vision.plotNumberState
|
||||||
import space.kscience.dataforge.context.Context
|
import space.kscience.dataforge.context.Context
|
||||||
import space.kscience.dataforge.context.request
|
import space.kscience.dataforge.context.request
|
||||||
|
import space.kscience.plotly.models.ScatterMode
|
||||||
import space.kscience.visionforge.VisionManager
|
import space.kscience.visionforge.VisionManager
|
||||||
import space.kscience.visionforge.html.VisionPage
|
import space.kscience.visionforge.html.VisionPage
|
||||||
import space.kscience.visionforge.plotly.PlotlyPlugin
|
import space.kscience.visionforge.plotly.PlotlyPlugin
|
||||||
@ -40,7 +41,7 @@ public fun main() {
|
|||||||
val deviceManager = context.request(DeviceManager)
|
val deviceManager = context.request(DeviceManager)
|
||||||
val visionManager = context.request(VisionManager)
|
val visionManager = context.request(VisionManager)
|
||||||
|
|
||||||
val state = DoubleRangeState(0.0, -100.0..100.0)
|
val state = DoubleRangeState(0.0, -5.0..5.0)
|
||||||
|
|
||||||
val pidParameters = PidParameters(
|
val pidParameters = PidParameters(
|
||||||
kp = 2.5,
|
kp = 2.5,
|
||||||
@ -79,14 +80,37 @@ public fun main() {
|
|||||||
) {
|
) {
|
||||||
vision {
|
vision {
|
||||||
plotly {
|
plotly {
|
||||||
plotDeviceState(context, state){
|
plotNumberState(context, state) {
|
||||||
name = "value"
|
name = "real position"
|
||||||
}
|
}
|
||||||
plotDeviceProperty(device["pid"], Regulator.target.name){
|
plotDeviceProperty(device["pid"], Regulator.position.name) {
|
||||||
|
name = "read position"
|
||||||
|
}
|
||||||
|
|
||||||
|
plotDeviceProperty(device["pid"], Regulator.target.name) {
|
||||||
name = "target"
|
name = "target"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vision {
|
||||||
|
plotly {
|
||||||
|
// plotBooleanState(context, state.atStartState) {
|
||||||
|
// name = "start"
|
||||||
|
// }
|
||||||
|
// plotBooleanState(context, state.atEndState) {
|
||||||
|
// name = "end"
|
||||||
|
// }
|
||||||
|
plotDeviceProperty(device["start"], LimitSwitch.locked.name) {
|
||||||
|
name = "start measured"
|
||||||
|
mode = ScatterMode.markers
|
||||||
|
}
|
||||||
|
plotDeviceProperty(device["end"], LimitSwitch.locked.name) {
|
||||||
|
name = "end measured"
|
||||||
|
mode = ScatterMode.markers
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}.start(false)
|
}.start(false)
|
||||||
|
Loading…
Reference in New Issue
Block a user