{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "USE(ControlsJupyter())" ] }, { "cell_type": "code", "execution_count": null, "outputs": [], "source": [ "class LinearDrive(\n", " context: Context,\n", " state: DoubleRangeState,\n", " mass: Double,\n", " pidParameters: PidParameters,\n", " meta: Meta = Meta.EMPTY,\n", ") : DeviceConstructor(context.request(DeviceManager), meta) {\n", "\n", " val drive by device(VirtualDrive.factory(mass, state))\n", " val pid by device(PidRegulator(drive, pidParameters))\n", "\n", " val start by device(LimitSwitch.factory(state.atStartState))\n", " val end by device(LimitSwitch.factory(state.atEndState))\n", "\n", "\n", " val position by property(state)\n", " var target by mutableProperty(pid.mutablePropertyAsState(Regulator.target, 0.0))\n", "}\n" ], "metadata": { "collapsed": false } }, { "cell_type": "code", "execution_count": null, "outputs": [], "source": [ "import kotlin.time.Duration.Companion.milliseconds\n", "import kotlin.time.Duration.Companion.seconds\n", "\n", "val state = DoubleRangeState(0.0, -5.0..5.0)\n", "\n", "val pidParameters = PidParameters(\n", " kp = 2.5,\n", " ki = 0.0,\n", " kd = -0.1,\n", " timeStep = 0.005.seconds\n", ")\n", "\n", "val device = context.install(\"device\", LinearDrive(context, state, 0.005, pidParameters)).apply {\n", " val clock = context.clock\n", " val clockStart = clock.now()\n", " doRecurring(10.milliseconds) {\n", " val timeFromStart = clock.now() - clockStart\n", " val t = timeFromStart.toDouble(DurationUnit.SECONDS)\n", " val freq = 0.1\n", "\n", " target = 5 * sin(2.0 * PI * freq * t) +\n", " sin(2 * PI * 21 * freq * t + 0.02 * (timeFromStart / pidParameters.timeStep))\n", " }\n", "}" ], "metadata": { "collapsed": false } }, { "cell_type": "code", "execution_count": null, "outputs": [], "source": [ "val maxAge = 10.seconds\n", "\n", "\n", "VisionForge.fragment {\n", " vision {\n", " plotly {\n", " plotNumberState(context, state, maxAge = maxAge) {\n", " name = \"real position\"\n", " }\n", " plotDeviceProperty(device.pid, Regulator.position.name, maxAge = maxAge) {\n", " name = \"read position\"\n", " }\n", "\n", " plotDeviceProperty(device.pid, Regulator.target.name, maxAge = maxAge) {\n", " name = \"target\"\n", " }\n", " }\n", " }\n", "\n", " vision {\n", " plotly {\n", " plotDeviceProperty(device.start, LimitSwitch.locked.name, maxAge = maxAge) {\n", " name = \"start measured\"\n", " mode = ScatterMode.markers\n", " }\n", " plotDeviceProperty(device.end, LimitSwitch.locked.name, maxAge = maxAge) {\n", " name = \"end measured\"\n", " mode = ScatterMode.markers\n", " }\n", " }\n", " }\n", "}" ], "metadata": { "collapsed": false } }, { "cell_type": "code", "execution_count": null, "outputs": [], "source": [ "device.stop()" ], "metadata": { "collapsed": false } }, { "cell_type": "code", "execution_count": null, "outputs": [], "source": [], "metadata": { "collapsed": false } } ], "metadata": { "kernelspec": { "display_name": "Kotlin", "language": "kotlin", "name": "kotlin" }, "language_info": { "name": "kotlin", "version": "1.9.0", "mimetype": "text/x-kotlin", "file_extension": ".kt", "pygments_lexer": "kotlin", "codemirror_mode": "text/x-kotlin", "nbconvert_exporter": "" }, "ktnbPluginMetadata": { "projectDependencies": [ "controls-kt.controls-jupyter.jvmMain" ] } }, "nbformat": 4, "nbformat_minor": 0 }