Fix motors parser
This commit is contained in:
parent
eb3121aed4
commit
23c66d9703
@ -32,11 +32,11 @@ public class TypedDeviceProperty<T : Any>(
|
||||
converter: MetaConverter<T>,
|
||||
) : TypedReadOnlyDeviceProperty<T>(property, converter), DeviceProperty {
|
||||
|
||||
// override var value: MetaItem<*>?
|
||||
// get() = property.value
|
||||
// set(arg) {
|
||||
// property.value = arg
|
||||
// }
|
||||
override var value: MetaItem<*>?
|
||||
get() = property.value
|
||||
set(arg) {
|
||||
property.value = arg
|
||||
}
|
||||
|
||||
public override var typedValue: T?
|
||||
get() = value?.let { converter.itemToObject(it) }
|
||||
|
@ -40,7 +40,7 @@ public abstract class AbstractPort(
|
||||
*/
|
||||
protected fun receive(data: ByteArray) {
|
||||
scope.launch {
|
||||
logger.debug { "[${this@AbstractPort}] RECEIVED: ${data.decodeToString()}" }
|
||||
logger.debug { "${this@AbstractPort} RECEIVED: ${data.decodeToString()}" }
|
||||
incoming.send(data)
|
||||
}
|
||||
}
|
||||
@ -49,7 +49,7 @@ public abstract class AbstractPort(
|
||||
for (data in outgoing) {
|
||||
try {
|
||||
write(data)
|
||||
logger.debug { "[${this@AbstractPort}] SENT: ${data.decodeToString()}" }
|
||||
logger.debug { "${this@AbstractPort} SENT: ${data.decodeToString()}" }
|
||||
} catch (ex: Exception) {
|
||||
if (ex is CancellationException) throw ex
|
||||
logger.error(ex) { "Error while writing data to the port" }
|
||||
|
@ -9,7 +9,7 @@ plugins {
|
||||
|
||||
kotlin{
|
||||
explicitApi = null
|
||||
useFx(ru.mipt.npm.gradle.FXModule.CONTROLS)
|
||||
useFx(ru.mipt.npm.gradle.FXModule.CONTROLS, configuration = ru.mipt.npm.gradle.DependencyConfiguration.IMPLEMENTATION)
|
||||
}
|
||||
|
||||
val ktorVersion: String by rootProject.extra
|
||||
|
@ -3,6 +3,7 @@ package ru.mipt.npm.devices.pimotionmaster
|
||||
import hep.dataforge.context.Global
|
||||
import hep.dataforge.control.controllers.DeviceManager
|
||||
import hep.dataforge.control.controllers.installing
|
||||
import javafx.beans.property.SimpleBooleanProperty
|
||||
import javafx.beans.property.SimpleIntegerProperty
|
||||
import javafx.beans.property.SimpleStringProperty
|
||||
import javafx.scene.Parent
|
||||
@ -27,20 +28,29 @@ class PiMotionMasterView : View() {
|
||||
|
||||
override val root: Parent = borderpane {
|
||||
top {
|
||||
hbox {
|
||||
form {
|
||||
val host = SimpleStringProperty("127.0.0.1")
|
||||
val port = SimpleIntegerProperty(10024)
|
||||
val virtual = SimpleBooleanProperty(false)
|
||||
fieldset("Address:") {
|
||||
field("Host:") {
|
||||
textfield(host)
|
||||
textfield(host){
|
||||
enableWhen(virtual.not())
|
||||
}
|
||||
}
|
||||
field("Port:") {
|
||||
textfield(port)
|
||||
}
|
||||
field("Virtual device:") {
|
||||
checkbox(property = virtual)
|
||||
}
|
||||
}
|
||||
|
||||
button("Connect") {
|
||||
action {
|
||||
if(virtual.get()){
|
||||
controller.context.launchPiDebugServer(port.get(), listOf("1", "2"))
|
||||
}
|
||||
controller.motionMaster.connect(host.get(), port.get())
|
||||
}
|
||||
}
|
||||
|
@ -10,12 +10,9 @@ import hep.dataforge.control.controllers.*
|
||||
import hep.dataforge.control.ports.*
|
||||
import hep.dataforge.meta.*
|
||||
import hep.dataforge.names.NameToken
|
||||
import hep.dataforge.values.Null
|
||||
import hep.dataforge.values.asValue
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.takeWhile
|
||||
import kotlinx.coroutines.flow.toList
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import tornadofx.*
|
||||
@ -32,10 +29,13 @@ class PiMotionMasterDevice(
|
||||
context.coroutineContext + SupervisorJob(context.coroutineContext[Job])
|
||||
)
|
||||
|
||||
val address: DeviceProperty by writingVirtual(Null) {
|
||||
info = "The port for TCP connector"
|
||||
}
|
||||
private var address: Meta? = null
|
||||
|
||||
val connected by readingBoolean(false, descriptorBuilder = {
|
||||
info = "True if the connection address is defined and the device is initialized"
|
||||
}) {
|
||||
address != null
|
||||
}
|
||||
|
||||
val timeout: DeviceProperty by writingVirtual(200.asValue()) {
|
||||
info = "Timeout"
|
||||
@ -43,8 +43,7 @@ class PiMotionMasterDevice(
|
||||
|
||||
var timeoutValue: Duration by timeout.duration()
|
||||
|
||||
private val connector = PortProxy { portFactory(address.value.node ?: Meta.EMPTY, context) }
|
||||
|
||||
private val connector = PortProxy { portFactory(address ?: error("The device is not connected"), context) }
|
||||
|
||||
/**
|
||||
* Name-friendly accessor for axis
|
||||
@ -63,11 +62,13 @@ class PiMotionMasterDevice(
|
||||
info = "Connect to specific port and initialize axis"
|
||||
}) { portSpec ->
|
||||
//Clear current actions if present
|
||||
if (address.value != null) {
|
||||
if (address != null) {
|
||||
stop()
|
||||
}
|
||||
//Update port
|
||||
address.value = portSpec
|
||||
address = portSpec.node
|
||||
connected.invalidate()
|
||||
connector.open()
|
||||
//Initialize axes
|
||||
if (portSpec != null) {
|
||||
val idn = identity.read()
|
||||
@ -84,6 +85,17 @@ class PiMotionMasterDevice(
|
||||
}
|
||||
}
|
||||
|
||||
val disconnect: DeviceAction by acting({
|
||||
info = "Disconnect the program from the device if it is connected"
|
||||
}) {
|
||||
connector.close()
|
||||
if (address != null) {
|
||||
stop()
|
||||
}
|
||||
address = null
|
||||
connected.invalidate()
|
||||
}
|
||||
|
||||
fun connect(host: String, port: Int) {
|
||||
scope.launch {
|
||||
connect(Meta {
|
||||
@ -126,7 +138,16 @@ class PiMotionMasterDevice(
|
||||
withTimeout(timeoutValue) {
|
||||
sendCommandInternal(command, *arguments)
|
||||
val phrases = connector.receiving().withDelimiter("\n")
|
||||
phrases.takeWhile { it.endsWith(" \n") }.toList() + phrases.first()
|
||||
var lastLineFlag = false
|
||||
phrases.transformWhile { line ->
|
||||
if (lastLineFlag) {
|
||||
false
|
||||
} else {
|
||||
emit(line)
|
||||
lastLineFlag = !line.endsWith(" \n")
|
||||
true
|
||||
}
|
||||
}.toList()
|
||||
}
|
||||
} catch (ex: Throwable) {
|
||||
logger.warn { "Error during PIMotionMaster request. Requesting error code." }
|
||||
|
@ -1,7 +1,7 @@
|
||||
package ru.mipt.npm.devices.pimotionmaster
|
||||
|
||||
import hep.dataforge.context.Context
|
||||
import hep.dataforge.context.Global
|
||||
import hep.dataforge.control.ports.Port
|
||||
import io.ktor.network.selector.ActorSelectorManager
|
||||
import io.ktor.network.sockets.aSocket
|
||||
import io.ktor.network.sockets.openReadChannel
|
||||
@ -19,7 +19,8 @@ val exceptionHandler = CoroutineExceptionHandler { _, throwable ->
|
||||
}
|
||||
|
||||
@OptIn(KtorExperimentalAPI::class, InternalAPI::class)
|
||||
fun CoroutineScope.launchPiDebugServer(port: Int, virtualPort: Port): Job = launch(exceptionHandler) {
|
||||
fun Context.launchPiDebugServer(port: Int, axes: List<String>): Job = launch(exceptionHandler) {
|
||||
val virtualDevice = PiMotionMasterVirtualDevice(this@launchPiDebugServer, axes)
|
||||
val server = aSocket(ActorSelectorManager(Dispatchers.IO)).tcp().bind(InetSocketAddress("localhost", port))
|
||||
println("Started virtual port server at ${server.localAddress}")
|
||||
|
||||
@ -31,7 +32,7 @@ fun CoroutineScope.launchPiDebugServer(port: Int, virtualPort: Port): Job = laun
|
||||
val output = socket.openWriteChannel()
|
||||
|
||||
val sendJob = launch {
|
||||
virtualPort.receiving().collect {
|
||||
virtualDevice.receiving().collect {
|
||||
//println("Sending: ${it.decodeToString()}")
|
||||
output.writeAvailable(it)
|
||||
output.flush()
|
||||
@ -43,7 +44,7 @@ fun CoroutineScope.launchPiDebugServer(port: Int, virtualPort: Port): Job = laun
|
||||
input.read { buffer ->
|
||||
val array = buffer.moveToByteArray()
|
||||
launch {
|
||||
virtualPort.send(array)
|
||||
virtualDevice.send(array)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -61,10 +62,8 @@ fun CoroutineScope.launchPiDebugServer(port: Int, virtualPort: Port): Job = laun
|
||||
|
||||
fun main() {
|
||||
val port = 10024
|
||||
val virtualDevice = PiMotionMasterVirtualDevice(Global, listOf("1", "2"))
|
||||
val virtualPort = VirtualPort(virtualDevice, Global)
|
||||
runBlocking(Dispatchers.Default) {
|
||||
val serverJob = launchPiDebugServer(port, virtualPort)
|
||||
val serverJob = Global.launchPiDebugServer(port, listOf("1", "2"))
|
||||
readLine()
|
||||
serverJob.cancel()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user