From f0d16ce632bf62cbc82129261b8bd4178f367740 Mon Sep 17 00:00:00 2001 From: Trent Houliston Date: Wed, 3 Oct 2018 20:38:55 +1000 Subject: [PATCH 01/54] Added empty Script tuner module --- src/client/components/app/install.tsx | 2 ++ .../components/script_tuner/controller.ts | 5 +++ src/client/components/script_tuner/icon.svg | 7 ++++ .../components/script_tuner/install.tsx | 32 +++++++++++++++++++ src/client/components/script_tuner/model.ts | 16 ++++++++++ src/client/components/script_tuner/network.ts | 16 ++++++++++ .../script_tuner/script_line/view.tsx | 0 .../script_tuner/script_line/view_model.ts | 0 src/client/components/script_tuner/style.css | 0 src/client/components/script_tuner/view.tsx | 18 +++++++++++ .../components/script_tuner/view_model.ts | 0 11 files changed, 96 insertions(+) create mode 100644 src/client/components/script_tuner/controller.ts create mode 100644 src/client/components/script_tuner/icon.svg create mode 100644 src/client/components/script_tuner/install.tsx create mode 100644 src/client/components/script_tuner/model.ts create mode 100644 src/client/components/script_tuner/network.ts create mode 100644 src/client/components/script_tuner/script_line/view.tsx create mode 100644 src/client/components/script_tuner/script_line/view_model.ts create mode 100644 src/client/components/script_tuner/style.css create mode 100644 src/client/components/script_tuner/view.tsx create mode 100644 src/client/components/script_tuner/view_model.ts diff --git a/src/client/components/app/install.tsx b/src/client/components/app/install.tsx index d89224a0..3147b9e3 100644 --- a/src/client/components/app/install.tsx +++ b/src/client/components/app/install.tsx @@ -4,6 +4,7 @@ import { installChart } from '../chart/install' import { installDashboard } from '../dashboard/install' import { installLocalisation } from '../localisation/install' import { withRobotSelectorMenuBar } from '../menu_bar/view' +import { installScriptTuner } from '../script_tuner/install' import { installVision } from '../vision/install' import { installVisualMesh } from '../visual_mesh/install' @@ -23,6 +24,7 @@ export function installNav() { installDashboard({ nav, appModel, nusightNetwork, menu }) installLocalisation({ nav, appModel, nusightNetwork, menu }) + installScriptTuner({ nav, appModel, nusightNetwork, menu }) installChart({ nav, appModel, nusightNetwork, menu }) installVision({ nav, appModel, nusightNetwork, Menu: menu }) installVisualMesh({ nav, appModel, nusightNetwork, Menu: menu }) diff --git a/src/client/components/script_tuner/controller.ts b/src/client/components/script_tuner/controller.ts new file mode 100644 index 00000000..8faf27fc --- /dev/null +++ b/src/client/components/script_tuner/controller.ts @@ -0,0 +1,5 @@ +export class ScriptTunerController { + static of() { + return new ScriptTunerController() + } +} diff --git a/src/client/components/script_tuner/icon.svg b/src/client/components/script_tuner/icon.svg new file mode 100644 index 00000000..7fe5b3b4 --- /dev/null +++ b/src/client/components/script_tuner/icon.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/src/client/components/script_tuner/install.tsx b/src/client/components/script_tuner/install.tsx new file mode 100644 index 00000000..3533de44 --- /dev/null +++ b/src/client/components/script_tuner/install.tsx @@ -0,0 +1,32 @@ +import * as React from 'react' +import { ComponentType } from 'react' + +import { NavigationConfiguration } from '../../navigation' +import { NUsightNetwork } from '../../network/nusight_network' +import { AppModel } from '../app/model' + +import { ScriptTunerController } from './controller' +import Icon from './icon.svg' +import { ScriptTunerModel } from './model' +import { ScriptTunerNetwork } from './network' +import { ScriptTuner } from './view' + +export function installScriptTuner({ nav, appModel, nusightNetwork, menu }: { + nav: NavigationConfiguration, + appModel: AppModel, + nusightNetwork: NUsightNetwork, + menu: ComponentType +}) { + const model = ScriptTunerModel.of(appModel.robots) + nav.addRoute({ + path: '/scripts', + exact: true, + Icon, + label: 'Scripts', + Content: () => { + const network = ScriptTunerNetwork.of(nusightNetwork) + const controller = ScriptTunerController.of() + return + }, + }) +} diff --git a/src/client/components/script_tuner/model.ts b/src/client/components/script_tuner/model.ts new file mode 100644 index 00000000..2cad22bc --- /dev/null +++ b/src/client/components/script_tuner/model.ts @@ -0,0 +1,16 @@ +import { computed } from 'mobx' +import { observable } from 'mobx' + +import { RobotModel } from '../robot/model' + +export class ScriptTunerModel { + @observable private robotModels: RobotModel[] + + constructor(robotModels: RobotModel[]) { + this.robotModels = robotModels + } + + static of(robots: RobotModel[]): ScriptTunerModel { + return new ScriptTunerModel(robots) + } +} diff --git a/src/client/components/script_tuner/network.ts b/src/client/components/script_tuner/network.ts new file mode 100644 index 00000000..144d1155 --- /dev/null +++ b/src/client/components/script_tuner/network.ts @@ -0,0 +1,16 @@ +import { Network } from '../../network/network' +import { NUsightNetwork } from '../../network/nusight_network' + +export class ScriptTunerNetwork { + constructor(private network: Network) { + } + + static of(nusightNetwork: NUsightNetwork): ScriptTunerNetwork { + const network = Network.of(nusightNetwork) + return new ScriptTunerNetwork(network) + } + + destroy() { + this.network.off() + } +} diff --git a/src/client/components/script_tuner/script_line/view.tsx b/src/client/components/script_tuner/script_line/view.tsx new file mode 100644 index 00000000..e69de29b diff --git a/src/client/components/script_tuner/script_line/view_model.ts b/src/client/components/script_tuner/script_line/view_model.ts new file mode 100644 index 00000000..e69de29b diff --git a/src/client/components/script_tuner/style.css b/src/client/components/script_tuner/style.css new file mode 100644 index 00000000..e69de29b diff --git a/src/client/components/script_tuner/view.tsx b/src/client/components/script_tuner/view.tsx new file mode 100644 index 00000000..e2266f57 --- /dev/null +++ b/src/client/components/script_tuner/view.tsx @@ -0,0 +1,18 @@ +import { observer } from 'mobx-react' +import * as React from 'react' +import { ComponentType } from 'react' + +import { ScriptTunerController } from './controller' +import { ScriptTunerModel } from './model' +import { ScriptTunerNetwork } from './network' + +export type ScriptTunerProps = { + controller: ScriptTunerController + menu: ComponentType<{}> + model: ScriptTunerModel + network: ScriptTunerNetwork +} + +export const ScriptTuner = observer(({ controller, menu, model, network }: ScriptTunerProps) => { + return
Hello!
+}) diff --git a/src/client/components/script_tuner/view_model.ts b/src/client/components/script_tuner/view_model.ts new file mode 100644 index 00000000..e69de29b From ef4c63d6f2d9023e4bf179a2e6d61cd866cc3501 Mon Sep 17 00:00:00 2001 From: Trent Houliston Date: Sat, 6 Oct 2018 08:30:16 +0200 Subject: [PATCH 02/54] Adding things --- .../components/script_tuner/balance/view.tsx | 6 +++++ .../components/script_tuner/controller.ts | 13 +++++++++-- .../components/script_tuner/controls/view.tsx | 6 +++++ .../view.tsx => editor/line/controller.ts} | 0 .../script_tuner/editor/line/view.tsx | 6 +++++ .../script_tuner/editor/line/view_model.ts | 6 +++++ .../components/script_tuner/editor/view.tsx | 6 +++++ .../script_tuner/editor/view_model.ts | 2 ++ .../components/script_tuner/install.tsx | 2 +- .../script_tuner/script_line/view_model.ts | 0 src/client/components/script_tuner/style.css | 22 +++++++++++++++++++ src/client/components/script_tuner/view.tsx | 10 ++++++++- .../components/script_tuner/view_model.ts | 2 ++ .../components/script_tuner/viewer/view.tsx | 6 +++++ 14 files changed, 83 insertions(+), 4 deletions(-) create mode 100644 src/client/components/script_tuner/balance/view.tsx create mode 100644 src/client/components/script_tuner/controls/view.tsx rename src/client/components/script_tuner/{script_line/view.tsx => editor/line/controller.ts} (100%) create mode 100644 src/client/components/script_tuner/editor/line/view.tsx create mode 100644 src/client/components/script_tuner/editor/line/view_model.ts create mode 100644 src/client/components/script_tuner/editor/view.tsx create mode 100644 src/client/components/script_tuner/editor/view_model.ts delete mode 100644 src/client/components/script_tuner/script_line/view_model.ts create mode 100644 src/client/components/script_tuner/viewer/view.tsx diff --git a/src/client/components/script_tuner/balance/view.tsx b/src/client/components/script_tuner/balance/view.tsx new file mode 100644 index 00000000..80259f12 --- /dev/null +++ b/src/client/components/script_tuner/balance/view.tsx @@ -0,0 +1,6 @@ +import { observer } from 'mobx-react' +import * as React from 'react' + +export const Balance = observer(() => { + return <>Balance +}) diff --git a/src/client/components/script_tuner/controller.ts b/src/client/components/script_tuner/controller.ts index 8faf27fc..9602eab2 100644 --- a/src/client/components/script_tuner/controller.ts +++ b/src/client/components/script_tuner/controller.ts @@ -1,5 +1,14 @@ +import { action } from 'mobx' + +import { ScriptTunerNetwork } from './network' + export class ScriptTunerController { - static of() { - return new ScriptTunerController() + + constructor(private network: ScriptTunerNetwork) { + // TODO need to add an autorunner that if we are connected to the robot we need to send it update packets + } + + static of(network: ScriptTunerNetwork) { + return new ScriptTunerController(network) } } diff --git a/src/client/components/script_tuner/controls/view.tsx b/src/client/components/script_tuner/controls/view.tsx new file mode 100644 index 00000000..87dddb30 --- /dev/null +++ b/src/client/components/script_tuner/controls/view.tsx @@ -0,0 +1,6 @@ +import { observer } from 'mobx-react' +import * as React from 'react' + +export const Controls = observer(() => { + return <>Controls +}) diff --git a/src/client/components/script_tuner/script_line/view.tsx b/src/client/components/script_tuner/editor/line/controller.ts similarity index 100% rename from src/client/components/script_tuner/script_line/view.tsx rename to src/client/components/script_tuner/editor/line/controller.ts diff --git a/src/client/components/script_tuner/editor/line/view.tsx b/src/client/components/script_tuner/editor/line/view.tsx new file mode 100644 index 00000000..65f5f3ea --- /dev/null +++ b/src/client/components/script_tuner/editor/line/view.tsx @@ -0,0 +1,6 @@ +import { observer } from 'mobx-react' +import * as React from 'react' + +export const Controls = observer(({ controller, menu, model, network }: ScriptTunerProps) => { + return <>Controls +}) diff --git a/src/client/components/script_tuner/editor/line/view_model.ts b/src/client/components/script_tuner/editor/line/view_model.ts new file mode 100644 index 00000000..d62e6003 --- /dev/null +++ b/src/client/components/script_tuner/editor/line/view_model.ts @@ -0,0 +1,6 @@ + +// Show an individual script line editor +// The view will be a simple line chart +// When hovering over a point in the chart it will show the valid positions based on RPM +// When scrolling the mouse wheel it will move up/down based limited by the surrounding points +// It will also show the current position of the robots limb diff --git a/src/client/components/script_tuner/editor/view.tsx b/src/client/components/script_tuner/editor/view.tsx new file mode 100644 index 00000000..8900a2a0 --- /dev/null +++ b/src/client/components/script_tuner/editor/view.tsx @@ -0,0 +1,6 @@ +import { observer } from 'mobx-react' +import * as React from 'react' + +export const Editor = observer(() => { + return <>Editor +}) diff --git a/src/client/components/script_tuner/editor/view_model.ts b/src/client/components/script_tuner/editor/view_model.ts new file mode 100644 index 00000000..820c7842 --- /dev/null +++ b/src/client/components/script_tuner/editor/view_model.ts @@ -0,0 +1,2 @@ + +// TODO map out each of the limbs into script line diff --git a/src/client/components/script_tuner/install.tsx b/src/client/components/script_tuner/install.tsx index 3533de44..0d943cd2 100644 --- a/src/client/components/script_tuner/install.tsx +++ b/src/client/components/script_tuner/install.tsx @@ -25,7 +25,7 @@ export function installScriptTuner({ nav, appModel, nusightNetwork, menu }: { label: 'Scripts', Content: () => { const network = ScriptTunerNetwork.of(nusightNetwork) - const controller = ScriptTunerController.of() + const controller = ScriptTunerController.of(network) return }, }) diff --git a/src/client/components/script_tuner/script_line/view_model.ts b/src/client/components/script_tuner/script_line/view_model.ts deleted file mode 100644 index e69de29b..00000000 diff --git a/src/client/components/script_tuner/style.css b/src/client/components/script_tuner/style.css index e69de29b..d1390636 100644 --- a/src/client/components/script_tuner/style.css +++ b/src/client/components/script_tuner/style.css @@ -0,0 +1,22 @@ + +.container { + display: grid; + grid-template-columns: 70% 30%; + grid-template-rows: 50% 50%; +} + +.viewer { + +} + +.balance { + +} + +.editor { + +} + +.controls { + +} diff --git a/src/client/components/script_tuner/view.tsx b/src/client/components/script_tuner/view.tsx index e2266f57..8f1fe4ff 100644 --- a/src/client/components/script_tuner/view.tsx +++ b/src/client/components/script_tuner/view.tsx @@ -5,6 +5,7 @@ import { ComponentType } from 'react' import { ScriptTunerController } from './controller' import { ScriptTunerModel } from './model' import { ScriptTunerNetwork } from './network' +import * as style from './style.css' export type ScriptTunerProps = { controller: ScriptTunerController @@ -14,5 +15,12 @@ export type ScriptTunerProps = { } export const ScriptTuner = observer(({ controller, menu, model, network }: ScriptTunerProps) => { - return
Hello!
+ return ( +
+
3d Robot View
+
Scripts Bar
+
Balance View
+
Controls
+
+ ) }) diff --git a/src/client/components/script_tuner/view_model.ts b/src/client/components/script_tuner/view_model.ts index e69de29b..c97bd197 100644 --- a/src/client/components/script_tuner/view_model.ts +++ b/src/client/components/script_tuner/view_model.ts @@ -0,0 +1,2 @@ + +// Timeline point is on this diff --git a/src/client/components/script_tuner/viewer/view.tsx b/src/client/components/script_tuner/viewer/view.tsx new file mode 100644 index 00000000..0165ef94 --- /dev/null +++ b/src/client/components/script_tuner/viewer/view.tsx @@ -0,0 +1,6 @@ +import { observer } from 'mobx-react' +import * as React from 'react' + +export const Viewer = observer(({ controller, menu, model, network }: ScriptTunerProps) => { + return <>Viewer +}) From c178ae13619ae6e1f3a6d009b106d75120c4d486 Mon Sep 17 00:00:00 2001 From: Trent Houliston Date: Sat, 6 Oct 2018 08:40:12 +0200 Subject: [PATCH 03/54] I don't know how grids work! --- src/client/components/script_tuner/balance/view.tsx | 8 ++++++-- src/client/components/script_tuner/controls/view.tsx | 8 ++++++-- .../components/script_tuner/editor/line/view.tsx | 8 ++++++-- src/client/components/script_tuner/editor/view.tsx | 8 ++++++-- src/client/components/script_tuner/view.tsx | 12 ++++++++---- src/client/components/script_tuner/viewer/view.tsx | 8 ++++++-- 6 files changed, 38 insertions(+), 14 deletions(-) diff --git a/src/client/components/script_tuner/balance/view.tsx b/src/client/components/script_tuner/balance/view.tsx index 80259f12..5dcd2c26 100644 --- a/src/client/components/script_tuner/balance/view.tsx +++ b/src/client/components/script_tuner/balance/view.tsx @@ -1,6 +1,10 @@ import { observer } from 'mobx-react' import * as React from 'react' -export const Balance = observer(() => { - return <>Balance +type BalanceProps = { + className?: string +} + +export const Balance = observer(({ className }: BalanceProps) => { + return
Balance
}) diff --git a/src/client/components/script_tuner/controls/view.tsx b/src/client/components/script_tuner/controls/view.tsx index 87dddb30..396ca360 100644 --- a/src/client/components/script_tuner/controls/view.tsx +++ b/src/client/components/script_tuner/controls/view.tsx @@ -1,6 +1,10 @@ import { observer } from 'mobx-react' import * as React from 'react' -export const Controls = observer(() => { - return <>Controls +type ControlsProps = { + className?: string +} + +export const Controls = observer(({ className }: ControlsProps) => { + return
Controls
}) diff --git a/src/client/components/script_tuner/editor/line/view.tsx b/src/client/components/script_tuner/editor/line/view.tsx index 65f5f3ea..a2fd382d 100644 --- a/src/client/components/script_tuner/editor/line/view.tsx +++ b/src/client/components/script_tuner/editor/line/view.tsx @@ -1,6 +1,10 @@ import { observer } from 'mobx-react' import * as React from 'react' -export const Controls = observer(({ controller, menu, model, network }: ScriptTunerProps) => { - return <>Controls +type EditorProps = { + className?: string +} + +export const Editor = observer(({ className }: EditorProps) => { + return <>Editor }) diff --git a/src/client/components/script_tuner/editor/view.tsx b/src/client/components/script_tuner/editor/view.tsx index 8900a2a0..78f118cf 100644 --- a/src/client/components/script_tuner/editor/view.tsx +++ b/src/client/components/script_tuner/editor/view.tsx @@ -1,6 +1,10 @@ import { observer } from 'mobx-react' import * as React from 'react' -export const Editor = observer(() => { - return <>Editor +type EditorProps = { + className?: string +} + +export const Editor = observer(({ className }: EditorProps) => { + return
Editor
}) diff --git a/src/client/components/script_tuner/view.tsx b/src/client/components/script_tuner/view.tsx index 8f1fe4ff..3dfa10c4 100644 --- a/src/client/components/script_tuner/view.tsx +++ b/src/client/components/script_tuner/view.tsx @@ -2,10 +2,14 @@ import { observer } from 'mobx-react' import * as React from 'react' import { ComponentType } from 'react' +import { Balance } from './balance/view' import { ScriptTunerController } from './controller' +import { Controls } from './controls/view' +import { Editor } from './editor/view' import { ScriptTunerModel } from './model' import { ScriptTunerNetwork } from './network' import * as style from './style.css' +import { Viewer } from './viewer/view' export type ScriptTunerProps = { controller: ScriptTunerController @@ -17,10 +21,10 @@ export type ScriptTunerProps = { export const ScriptTuner = observer(({ controller, menu, model, network }: ScriptTunerProps) => { return (
-
3d Robot View
-
Scripts Bar
-
Balance View
-
Controls
+ + + +
) }) diff --git a/src/client/components/script_tuner/viewer/view.tsx b/src/client/components/script_tuner/viewer/view.tsx index 0165ef94..893bf1ab 100644 --- a/src/client/components/script_tuner/viewer/view.tsx +++ b/src/client/components/script_tuner/viewer/view.tsx @@ -1,6 +1,10 @@ import { observer } from 'mobx-react' import * as React from 'react' -export const Viewer = observer(({ controller, menu, model, network }: ScriptTunerProps) => { - return <>Viewer +type ViewerProps = { + className?: string +} + +export const Viewer = observer(({ className }: ViewerProps) => { + return
Viewer
}) From 459b8d94f9d5553fa1e1fd14cd0526333793c4a9 Mon Sep 17 00:00:00 2001 From: Josephus Paye II Date: Mon, 22 Oct 2018 19:31:51 +1100 Subject: [PATCH 04/54] Initial attempt at line editor --- .../script_tuner/editor/line/controller.ts | 11 +++ .../script_tuner/editor/line/style.css | 23 ++++++ .../script_tuner/editor/line/view.tsx | 77 +++++++++++++++++-- .../script_tuner/editor/line/view_model.ts | 63 ++++++++++++++- .../components/script_tuner/editor/style.css | 20 +++++ .../components/script_tuner/editor/view.tsx | 22 +++++- src/client/components/script_tuner/model.ts | 39 ++++++++++ src/client/components/script_tuner/style.css | 2 +- src/client/components/script_tuner/view.tsx | 2 +- 9 files changed, 249 insertions(+), 10 deletions(-) create mode 100644 src/client/components/script_tuner/editor/line/style.css create mode 100644 src/client/components/script_tuner/editor/style.css diff --git a/src/client/components/script_tuner/editor/line/controller.ts b/src/client/components/script_tuner/editor/line/controller.ts index e69de29b..4e832c36 100644 --- a/src/client/components/script_tuner/editor/line/controller.ts +++ b/src/client/components/script_tuner/editor/line/controller.ts @@ -0,0 +1,11 @@ +import { action } from 'mobx' + +import { ScriptTunerModel } from '../../model' + +export class LineEditorController { + static of() { + return new LineEditorController() + } + + // actions here +} diff --git a/src/client/components/script_tuner/editor/line/style.css b/src/client/components/script_tuner/editor/line/style.css new file mode 100644 index 00000000..a8c6352b --- /dev/null +++ b/src/client/components/script_tuner/editor/line/style.css @@ -0,0 +1,23 @@ +.lineEditor { + border: 1px solid #777; + background-color: white; + font-family: monospace; + margin-bottom: 4px; +} + +.lineEditor:last-child { + margin-bottom: 0; +} + +.lineEditorSvg { + user-select: none; +} + +.lineEditorText { + font-size: 0.25px; + fill: #999; +} + +.lineEditorDraggable { + cursor: move; +} diff --git a/src/client/components/script_tuner/editor/line/view.tsx b/src/client/components/script_tuner/editor/line/view.tsx index a2fd382d..88896d64 100644 --- a/src/client/components/script_tuner/editor/line/view.tsx +++ b/src/client/components/script_tuner/editor/line/view.tsx @@ -1,10 +1,77 @@ import { observer } from 'mobx-react' import * as React from 'react' +import { Component } from 'react' +import { ComponentType } from 'react' -type EditorProps = { - className?: string +import { Servo } from '../../model' + +import { LineEditorController } from './controller' +import * as style from './style.css' +import { LineEditorViewModel } from './view_model' + +type LineEditorProps = { + className?: string, + servo: Servo, + controller: LineEditorController } -export const Editor = observer(({ className }: EditorProps) => { - return <>Editor -}) +@observer +export class LineEditor extends Component { + render() { + const viewModel = LineEditorViewModel.of(this.props.servo) + + return
+ + + + { + viewModel.points.map((point, index) => { + const position = index - 1 + return + + { position } + + }) + } + + { + viewModel.svgLineSegments.map((segment, index) => { + return + }) + } + + { + viewModel.svgPoints.map((point, index) => { + return + { `(${point.x}, ${point.y})` } + + }) + } + +
+ } +} diff --git a/src/client/components/script_tuner/editor/line/view_model.ts b/src/client/components/script_tuner/editor/line/view_model.ts index d62e6003..52beb653 100644 --- a/src/client/components/script_tuner/editor/line/view_model.ts +++ b/src/client/components/script_tuner/editor/line/view_model.ts @@ -1,6 +1,67 @@ - // Show an individual script line editor // The view will be a simple line chart // When hovering over a point in the chart it will show the valid positions based on RPM // When scrolling the mouse wheel it will move up/down based limited by the surrounding points // It will also show the current position of the robots limb + +import { computed } from 'mobx' +import { createTransformer } from 'mobx-utils' + +import { Servo } from '../../model' + +export class LineEditorViewModel { + constructor(private servo: Servo) { + } + + static of = createTransformer((servo: Servo): LineEditorViewModel => { + return new LineEditorViewModel(servo) + }) + + @computed + get points() { + return this.servo.data.concat().sort((a, b) => { + if (a.time < b.time) { + return -1 + } else if (a.time > b.time) { + return 1 + } else { + return 0 + } + }) + } + + @computed + get svgLineSegments() { + return this.points + .map((point, index) => { + // Create a blank line segment for the last data point. + // This is removed in the .slice() call below. + if (index === this.points.length - 1) { + return { + x1: 0, + x2: 0, + y1: 0, + y2: 0, + } + } + + return { + x1: point.time, + x2: this.points[index + 1].time, + y1: Math.PI - point.angle, + y2: Math.PI - this.points[index + 1].angle, + } + }) + .slice(0, this.points.length - 1) + } + + @computed + get svgPoints() { + return this.points.map(point => { + return { + x: point.time, + y: Math.PI - point.angle, + } + }) + } +} diff --git a/src/client/components/script_tuner/editor/style.css b/src/client/components/script_tuner/editor/style.css new file mode 100644 index 00000000..ddaab074 --- /dev/null +++ b/src/client/components/script_tuner/editor/style.css @@ -0,0 +1,20 @@ +.editor { + background-color: #DDD; + display: flex; + flex-direction: column; + max-height: 100%; + overflow: hidden; +} + +.editorHeader { + background-color: #777; + padding: 0 4px; + color: white; + font-size: 13px; +} + +.editorLines { + padding: 4px; + flex-grow: 1; + overflow: auto; +} diff --git a/src/client/components/script_tuner/editor/view.tsx b/src/client/components/script_tuner/editor/view.tsx index 78f118cf..f0760ece 100644 --- a/src/client/components/script_tuner/editor/view.tsx +++ b/src/client/components/script_tuner/editor/view.tsx @@ -1,10 +1,28 @@ import { observer } from 'mobx-react' import * as React from 'react' +import { ScriptTunerController } from '../controller' +import { ScriptTunerModel } from '../model' + +import { LineEditorController } from './line/controller' +import { LineEditor } from './line/view' +import * as style from './style.css' + type EditorProps = { className?: string + controller: ScriptTunerController + model: ScriptTunerModel } -export const Editor = observer(({ className }: EditorProps) => { - return
Editor
+export const Editor = observer(({ className, controller, model }: EditorProps) => { + const lineEditorController = LineEditorController.of() + + return
+
Editor
+
+ { + model.servos.map((servo, index) => ) + } +
+
}) diff --git a/src/client/components/script_tuner/model.ts b/src/client/components/script_tuner/model.ts index 2cad22bc..e45b4077 100644 --- a/src/client/components/script_tuner/model.ts +++ b/src/client/components/script_tuner/model.ts @@ -3,14 +3,53 @@ import { observable } from 'mobx' import { RobotModel } from '../robot/model' +export interface Servo { + data: ScriptData[] +} + +export interface ScriptData { + time: number, + angle: number, + pGain: number, + iGain: number, + dGain: number, + torque: number, +} + export class ScriptTunerModel { @observable private robotModels: RobotModel[] + @observable servos: Servo[] constructor(robotModels: RobotModel[]) { this.robotModels = robotModels + this.servos = [ + this.makeSampleServo(), + this.makeSampleServo(), + this.makeSampleServo(), + ] } static of(robots: RobotModel[]): ScriptTunerModel { return new ScriptTunerModel(robots) } + + private makeSampleServo(): Servo { + const data = [] + const period = 10 + + for (let i = 0; i < 31; i++) { + const theta = (2 * Math.PI * i) / period + + data.push({ + time: i, + angle: Math.sin(theta), + pGain: 0, + iGain: 0, + dGain: 0, + torque: 0, + }) + } + + return { data } + } } diff --git a/src/client/components/script_tuner/style.css b/src/client/components/script_tuner/style.css index d1390636..cd25276f 100644 --- a/src/client/components/script_tuner/style.css +++ b/src/client/components/script_tuner/style.css @@ -1,8 +1,8 @@ - .container { display: grid; grid-template-columns: 70% 30%; grid-template-rows: 50% 50%; + width: 100%; } .viewer { diff --git a/src/client/components/script_tuner/view.tsx b/src/client/components/script_tuner/view.tsx index 3dfa10c4..0d480ca1 100644 --- a/src/client/components/script_tuner/view.tsx +++ b/src/client/components/script_tuner/view.tsx @@ -23,7 +23,7 @@ export const ScriptTuner = observer(({ controller, menu, model, network }: Scrip
- +
) From e1f8690e84cfcb9d7f32e742663fdb97aa4cb4f1 Mon Sep 17 00:00:00 2001 From: Josephus Paye II Date: Mon, 22 Oct 2018 19:49:24 +1100 Subject: [PATCH 05/54] Rename ScriptData => Frame --- .../components/script_tuner/editor/line/view_model.ts | 2 +- src/client/components/script_tuner/model.ts | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/client/components/script_tuner/editor/line/view_model.ts b/src/client/components/script_tuner/editor/line/view_model.ts index 52beb653..f329cb6f 100644 --- a/src/client/components/script_tuner/editor/line/view_model.ts +++ b/src/client/components/script_tuner/editor/line/view_model.ts @@ -19,7 +19,7 @@ export class LineEditorViewModel { @computed get points() { - return this.servo.data.concat().sort((a, b) => { + return this.servo.frames.concat().sort((a, b) => { if (a.time < b.time) { return -1 } else if (a.time > b.time) { diff --git a/src/client/components/script_tuner/model.ts b/src/client/components/script_tuner/model.ts index e45b4077..e8914ad5 100644 --- a/src/client/components/script_tuner/model.ts +++ b/src/client/components/script_tuner/model.ts @@ -4,10 +4,10 @@ import { observable } from 'mobx' import { RobotModel } from '../robot/model' export interface Servo { - data: ScriptData[] + frames: Frame[] } -export interface ScriptData { +export interface Frame { time: number, angle: number, pGain: number, @@ -34,13 +34,13 @@ export class ScriptTunerModel { } private makeSampleServo(): Servo { - const data = [] + const frames = [] const period = 10 for (let i = 0; i < 31; i++) { const theta = (2 * Math.PI * i) / period - data.push({ + frames.push({ time: i, angle: Math.sin(theta), pGain: 0, @@ -50,6 +50,6 @@ export class ScriptTunerModel { }) } - return { data } + return { frames } } } From c298799d07fc7e2178741c33260a5ead317370ce Mon Sep 17 00:00:00 2001 From: Josephus Paye II Date: Wed, 28 Nov 2018 08:24:13 +1100 Subject: [PATCH 06/54] Minor style and data changes --- .../components/script_tuner/editor/line/style.css | 7 ++++--- .../components/script_tuner/editor/line/view.tsx | 13 +++++++------ src/client/components/script_tuner/model.ts | 10 +++++----- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/client/components/script_tuner/editor/line/style.css b/src/client/components/script_tuner/editor/line/style.css index a8c6352b..3c03e125 100644 --- a/src/client/components/script_tuner/editor/line/style.css +++ b/src/client/components/script_tuner/editor/line/style.css @@ -1,7 +1,4 @@ .lineEditor { - border: 1px solid #777; - background-color: white; - font-family: monospace; margin-bottom: 4px; } @@ -10,7 +7,11 @@ } .lineEditorSvg { + font-family: monospace; user-select: none; + border: 1px solid #777; + background-color: white; + height: 200px; } .lineEditorText { diff --git a/src/client/components/script_tuner/editor/line/view.tsx b/src/client/components/script_tuner/editor/line/view.tsx index 88896d64..3c249292 100644 --- a/src/client/components/script_tuner/editor/line/view.tsx +++ b/src/client/components/script_tuner/editor/line/view.tsx @@ -22,17 +22,18 @@ export class LineEditor extends Component { return
- + { viewModel.points.map((point, index) => { - const position = index - 1 + const position = index return - + { position } }) @@ -48,7 +49,7 @@ export class LineEditor extends Component { y2={segment.y2} stroke='black' - strokeWidth='0.005' + strokeWidth='0.01' /> }) } @@ -65,7 +66,7 @@ export class LineEditor extends Component { fill='orange' r='0.08' stroke='black' - strokeWidth='0.005' + strokeWidth='0.01' > { `(${point.x}, ${point.y})` } diff --git a/src/client/components/script_tuner/model.ts b/src/client/components/script_tuner/model.ts index e8914ad5..239b44c6 100644 --- a/src/client/components/script_tuner/model.ts +++ b/src/client/components/script_tuner/model.ts @@ -23,9 +23,9 @@ export class ScriptTunerModel { constructor(robotModels: RobotModel[]) { this.robotModels = robotModels this.servos = [ - this.makeSampleServo(), - this.makeSampleServo(), - this.makeSampleServo(), + this.makeSampleServo(15), + this.makeSampleServo(30), + this.makeSampleServo(60), ] } @@ -33,11 +33,11 @@ export class ScriptTunerModel { return new ScriptTunerModel(robots) } - private makeSampleServo(): Servo { + private makeSampleServo(length: number = 30): Servo { const frames = [] const period = 10 - for (let i = 0; i < 31; i++) { + for (let i = 0; i <= length; i++) { const theta = (2 * Math.PI * i) / period frames.push({ From d290d7da2876c0072cf283f3e90f43368423c1a0 Mon Sep 17 00:00:00 2001 From: Josephus Paye II Date: Wed, 28 Nov 2018 11:54:39 +1100 Subject: [PATCH 07/54] Add a scrollable timeline ruler at the top --- .../script_tuner/editor/line/style.css | 9 --- .../script_tuner/editor/line/view.tsx | 5 +- .../components/script_tuner/editor/style.css | 2 +- .../script_tuner/editor/timeline/style.css | 28 ++++++++ .../script_tuner/editor/timeline/view.tsx | 41 ++++++++++++ .../components/script_tuner/editor/view.tsx | 64 ++++++++++++++++--- src/client/components/script_tuner/style.css | 5 +- src/client/components/script_tuner/view.tsx | 2 +- 8 files changed, 129 insertions(+), 27 deletions(-) create mode 100644 src/client/components/script_tuner/editor/timeline/style.css create mode 100644 src/client/components/script_tuner/editor/timeline/view.tsx diff --git a/src/client/components/script_tuner/editor/line/style.css b/src/client/components/script_tuner/editor/line/style.css index 3c03e125..d5f06322 100644 --- a/src/client/components/script_tuner/editor/line/style.css +++ b/src/client/components/script_tuner/editor/line/style.css @@ -1,9 +1,5 @@ .lineEditor { - margin-bottom: 4px; -} -.lineEditor:last-child { - margin-bottom: 0; } .lineEditorSvg { @@ -14,11 +10,6 @@ height: 200px; } -.lineEditorText { - font-size: 0.25px; - fill: #999; -} - .lineEditorDraggable { cursor: move; } diff --git a/src/client/components/script_tuner/editor/line/view.tsx b/src/client/components/script_tuner/editor/line/view.tsx index 3c249292..624f731f 100644 --- a/src/client/components/script_tuner/editor/line/view.tsx +++ b/src/client/components/script_tuner/editor/line/view.tsx @@ -32,10 +32,7 @@ export class LineEditor extends Component { { viewModel.points.map((point, index) => { const position = index - return - - { position } - + return }) } diff --git a/src/client/components/script_tuner/editor/style.css b/src/client/components/script_tuner/editor/style.css index ddaab074..5ba9989d 100644 --- a/src/client/components/script_tuner/editor/style.css +++ b/src/client/components/script_tuner/editor/style.css @@ -13,7 +13,7 @@ font-size: 13px; } -.editorLines { +.editorBody { padding: 4px; flex-grow: 1; overflow: auto; diff --git a/src/client/components/script_tuner/editor/timeline/style.css b/src/client/components/script_tuner/editor/timeline/style.css new file mode 100644 index 00000000..5c81190e --- /dev/null +++ b/src/client/components/script_tuner/editor/timeline/style.css @@ -0,0 +1,28 @@ +.timeline { + box-sizing: border-box; + display: block; + flex-shrink: 0; + height: 21px; + padding: 0 4px; + line-height: 0; + background-color: #AAA; + border-bottom: 1px solid #999; + overflow-x: scroll; + overflow-y: hidden; +} + +/* Hide the scrollbar, not using overflow:hidden so we can programmatically scroll the timeline */ +.timeline::-webkit-scrollbar { + height: 0; + background: transparent; +} + +.timelineSvg { + box-sizing: border-box; + height: 20px; +} + +.timelineText { + font-size: 10px; + fill: white; +} diff --git a/src/client/components/script_tuner/editor/timeline/view.tsx b/src/client/components/script_tuner/editor/timeline/view.tsx new file mode 100644 index 00000000..508687dc --- /dev/null +++ b/src/client/components/script_tuner/editor/timeline/view.tsx @@ -0,0 +1,41 @@ +import { observer } from 'mobx-react' +import * as React from 'react' + +import * as style from './style.css' + +type TimelineProps = { + className?: string, + length: number +} + +@observer +export class Timeline extends React.Component { + render() { + const height = 20 + const cellWidth = 32 + const width = this.props.length * cellWidth + const cells = new Array(Math.ceil(width / cellWidth)).fill(0) + + return
+ + + + + { + cells.map((_, i) => + + { i } + ) + } + + + +
+ } +} diff --git a/src/client/components/script_tuner/editor/view.tsx b/src/client/components/script_tuner/editor/view.tsx index f0760ece..042799b4 100644 --- a/src/client/components/script_tuner/editor/view.tsx +++ b/src/client/components/script_tuner/editor/view.tsx @@ -1,5 +1,7 @@ +import * as classNames from 'classnames' import { observer } from 'mobx-react' import * as React from 'react' +import * as ReactDOM from 'react-dom' import { ScriptTunerController } from '../controller' import { ScriptTunerModel } from '../model' @@ -7,6 +9,7 @@ import { ScriptTunerModel } from '../model' import { LineEditorController } from './line/controller' import { LineEditor } from './line/view' import * as style from './style.css' +import { Timeline } from './timeline/view' type EditorProps = { className?: string @@ -14,15 +17,56 @@ type EditorProps = { model: ScriptTunerModel } -export const Editor = observer(({ className, controller, model }: EditorProps) => { - const lineEditorController = LineEditorController.of() +@observer +export class Editor extends React.Component { + props: EditorProps + timelineRef: React.RefObject + bodyRef: React.RefObject - return
-
Editor
-
- { - model.servos.map((servo, index) => ) - } + constructor(props: EditorProps) { + super(props) + this.props = props + this.timelineRef = React.createRef() + this.bodyRef = React.createRef() + } + + render() { + const { className, controller, model } = this.props + const lineEditorController = LineEditorController.of() + + return
+
Editor
+ +
+ { + model.servos.map((servo, index) => ) + } +
-
-}) + } + + componentDidMount() { + const timelineElement = ReactDOM.findDOMNode(this.timelineRef.current!) as HTMLDivElement + const bodyElement = this.bodyRef.current! + + timelineElement.addEventListener('scroll', this.onTimelineScroll, { passive: true }) + bodyElement.addEventListener('scroll', this.onBodyScroll, { passive: true }) + } + + componentWillUnmount() { + const timelineElement = ReactDOM.findDOMNode(this.timelineRef.current!) as HTMLDivElement + const bodyElement = this.bodyRef.current! + + timelineElement.removeEventListener('scroll', this.onTimelineScroll) + bodyElement.removeEventListener('scroll', this.onBodyScroll) + } + + onTimelineScroll = (event: UIEvent) => { + this.bodyRef.current!.scrollLeft = (event.currentTarget as HTMLDivElement).scrollLeft + } + + onBodyScroll = (event: UIEvent) => { + const timelineElement = ReactDOM.findDOMNode(this.timelineRef.current!) as HTMLDivElement + timelineElement.scrollLeft = (event.currentTarget as HTMLDivElement).scrollLeft + } +} diff --git a/src/client/components/script_tuner/style.css b/src/client/components/script_tuner/style.css index cd25276f..3bd6d419 100644 --- a/src/client/components/script_tuner/style.css +++ b/src/client/components/script_tuner/style.css @@ -1,6 +1,6 @@ .container { display: grid; - grid-template-columns: 70% 30%; + grid-template-columns: 50% 30% 20%; grid-template-rows: 50% 50%; width: 100%; } @@ -14,7 +14,8 @@ } .editor { - + grid-column-start: 1; + grid-column-end: span 3; } .controls { diff --git a/src/client/components/script_tuner/view.tsx b/src/client/components/script_tuner/view.tsx index 0d480ca1..c95fd940 100644 --- a/src/client/components/script_tuner/view.tsx +++ b/src/client/components/script_tuner/view.tsx @@ -23,8 +23,8 @@ export const ScriptTuner = observer(({ controller, menu, model, network }: Scrip
- +
) }) From 5dfd750b46140cb449b797611792adaa2f199486 Mon Sep 17 00:00:00 2001 From: Josephus Paye II Date: Wed, 28 Nov 2018 12:18:25 +1100 Subject: [PATCH 08/54] WIP: Remove viewBox and draw using a basic scale with a cell size multiplier --- .../script_tuner/editor/line/style.css | 2 +- .../script_tuner/editor/line/view.tsx | 36 +++++++++------- .../script_tuner/editor/line/view_model.ts | 41 ++++++------------- .../script_tuner/editor/timeline/view.tsx | 9 +++- src/client/components/script_tuner/model.ts | 4 +- 5 files changed, 45 insertions(+), 47 deletions(-) diff --git a/src/client/components/script_tuner/editor/line/style.css b/src/client/components/script_tuner/editor/line/style.css index d5f06322..48f87f29 100644 --- a/src/client/components/script_tuner/editor/line/style.css +++ b/src/client/components/script_tuner/editor/line/style.css @@ -5,7 +5,7 @@ .lineEditorSvg { font-family: monospace; user-select: none; - border: 1px solid #777; + /*border: 1px solid #777;*/ background-color: white; height: 200px; } diff --git a/src/client/components/script_tuner/editor/line/view.tsx b/src/client/components/script_tuner/editor/line/view.tsx index 624f731f..8637b78d 100644 --- a/src/client/components/script_tuner/editor/line/view.tsx +++ b/src/client/components/script_tuner/editor/line/view.tsx @@ -15,24 +15,32 @@ type LineEditorProps = { controller: LineEditorController } +function scale(num: number, inMin: number, inMax: number, outMin: number, outMax: number) { + return (num - inMin) * (outMax - outMin) / (inMax - inMin) + outMin +} + @observer export class LineEditor extends Component { render() { const viewModel = LineEditorViewModel.of(this.props.servo) + const cellWidth = 32 + const width = viewModel.points.length * cellWidth return
- + { viewModel.points.map((point, index) => { - const position = index - return + const position = index * cellWidth + return }) } @@ -40,13 +48,13 @@ export class LineEditor extends Component { viewModel.svgLineSegments.map((segment, index) => { return }) } @@ -56,14 +64,14 @@ export class LineEditor extends Component { return { `(${point.x}, ${point.y})` } diff --git a/src/client/components/script_tuner/editor/line/view_model.ts b/src/client/components/script_tuner/editor/line/view_model.ts index f329cb6f..0d1dddbe 100644 --- a/src/client/components/script_tuner/editor/line/view_model.ts +++ b/src/client/components/script_tuner/editor/line/view_model.ts @@ -19,40 +19,25 @@ export class LineEditorViewModel { @computed get points() { - return this.servo.frames.concat().sort((a, b) => { - if (a.time < b.time) { - return -1 - } else if (a.time > b.time) { - return 1 - } else { - return 0 - } - }) + return this.servo.frames.concat().sort((a, b) => a.time - b.time) } @computed get svgLineSegments() { - return this.points - .map((point, index) => { - // Create a blank line segment for the last data point. - // This is removed in the .slice() call below. - if (index === this.points.length - 1) { - return { - x1: 0, - x2: 0, - y1: 0, - y2: 0, - } - } + const segments = [] - return { - x1: point.time, - x2: this.points[index + 1].time, - y1: Math.PI - point.angle, - y2: Math.PI - this.points[index + 1].angle, - } + for (let i = 0; i < this.points.length - 1; i++) { + const point = this.points[i] + + segments.push({ + x1: point.time, + x2: this.points[i + 1].time, + y1: Math.PI - point.angle, + y2: Math.PI - this.points[i + 1].angle, }) - .slice(0, this.points.length - 1) + } + + return segments } @computed diff --git a/src/client/components/script_tuner/editor/timeline/view.tsx b/src/client/components/script_tuner/editor/timeline/view.tsx index 508687dc..b9b5bd1d 100644 --- a/src/client/components/script_tuner/editor/timeline/view.tsx +++ b/src/client/components/script_tuner/editor/timeline/view.tsx @@ -17,12 +17,17 @@ export class Timeline extends React.Component { const cells = new Array(Math.ceil(width / cellWidth)).fill(0) return
- + { - cells.map((_, i) => + cells.map((_, i) => Date: Thu, 29 Nov 2018 11:27:16 +1100 Subject: [PATCH 09/54] Add EditorViewModel with cell timeline width, height, scale, and cell width This allows for drawing the timeline and line editors at the same scale --- .../script_tuner/editor/line/style.css | 3 +- .../script_tuner/editor/line/view.tsx | 45 ++++++++-------- .../script_tuner/editor/line/view_model.ts | 53 +++++++++++++++---- .../script_tuner/editor/timeline/style.css | 2 +- .../script_tuner/editor/timeline/view.tsx | 38 +++++++------ .../components/script_tuner/editor/view.tsx | 21 +++++++- .../script_tuner/editor/view_model.ts | 10 +++- src/client/components/script_tuner/model.ts | 2 +- 8 files changed, 122 insertions(+), 52 deletions(-) diff --git a/src/client/components/script_tuner/editor/line/style.css b/src/client/components/script_tuner/editor/line/style.css index 48f87f29..b45006a7 100644 --- a/src/client/components/script_tuner/editor/line/style.css +++ b/src/client/components/script_tuner/editor/line/style.css @@ -5,9 +5,8 @@ .lineEditorSvg { font-family: monospace; user-select: none; - /*border: 1px solid #777;*/ + border: 1px solid #AAA; background-color: white; - height: 200px; } .lineEditorDraggable { diff --git a/src/client/components/script_tuner/editor/line/view.tsx b/src/client/components/script_tuner/editor/line/view.tsx index 8637b78d..27e5199a 100644 --- a/src/client/components/script_tuner/editor/line/view.tsx +++ b/src/client/components/script_tuner/editor/line/view.tsx @@ -4,6 +4,7 @@ import { Component } from 'react' import { ComponentType } from 'react' import { Servo } from '../../model' +import { EditorViewModel } from '../view_model' import { LineEditorController } from './controller' import * as style from './style.css' @@ -13,45 +14,46 @@ type LineEditorProps = { className?: string, servo: Servo, controller: LineEditorController -} - -function scale(num: number, inMin: number, inMax: number, outMin: number, outMax: number) { - return (num - inMin) * (outMax - outMin) / (inMax - inMin) + outMin + editorViewModel: EditorViewModel } @observer export class LineEditor extends Component { render() { - const viewModel = LineEditorViewModel.of(this.props.servo) - const cellWidth = 32 - const width = viewModel.points.length * cellWidth + const viewModel = LineEditorViewModel.of({ + servo: this.props.servo, + editorViewModel: this.props.editorViewModel, + }) return
- + // Vertical grid lines + + + { + // Horizontal grid lines viewModel.points.map((point, index) => { - const position = index * cellWidth - return + const x = index * viewModel.cellWidth + return }) } { + // The main plot line viewModel.svgLineSegments.map((segment, index) => { return { } { + // Points on the main plot line viewModel.svgPoints.map((point, index) => { return { stroke='black' strokeWidth='1' > - { `(${point.x}, ${point.y})` } + { point.label } }) } diff --git a/src/client/components/script_tuner/editor/line/view_model.ts b/src/client/components/script_tuner/editor/line/view_model.ts index 0d1dddbe..d9a4e754 100644 --- a/src/client/components/script_tuner/editor/line/view_model.ts +++ b/src/client/components/script_tuner/editor/line/view_model.ts @@ -8,15 +8,41 @@ import { computed } from 'mobx' import { createTransformer } from 'mobx-utils' import { Servo } from '../../model' +import { EditorViewModel } from '../view_model' + +type LineEditorViewModelOptions = { + servo: Servo, + editorViewModel: EditorViewModel +} export class LineEditorViewModel { - constructor(private servo: Servo) { + private servo: Servo + private editorViewModel: EditorViewModel + + constructor(options: LineEditorViewModelOptions) { + this.servo = options.servo + this.editorViewModel = options.editorViewModel } - static of = createTransformer((servo: Servo): LineEditorViewModel => { - return new LineEditorViewModel(servo) + static of = createTransformer((options: LineEditorViewModelOptions): LineEditorViewModel => { + return new LineEditorViewModel(options) }) + @computed + get cellWidth() { + return this.editorViewModel.cellWidth * this.editorViewModel.scaleX + } + + @computed + get width() { + return this.points.length * this.cellWidth + } + + @computed + get height() { + return this.editorViewModel.height + } + @computed get points() { return this.servo.frames.concat().sort((a, b) => a.time - b.time) @@ -30,10 +56,10 @@ export class LineEditorViewModel { const point = this.points[i] segments.push({ - x1: point.time, - x2: this.points[i + 1].time, - y1: Math.PI - point.angle, - y2: Math.PI - this.points[i + 1].angle, + x1: point.time * this.cellWidth, + x2: this.points[i + 1].time * this.cellWidth, + y1: this.scaleY(Math.PI - point.angle), + y2: this.scaleY(Math.PI - this.points[i + 1].angle), }) } @@ -44,9 +70,18 @@ export class LineEditorViewModel { get svgPoints() { return this.points.map(point => { return { - x: point.time, - y: Math.PI - point.angle, + x: point.time * this.cellWidth, + y: this.scaleY(Math.PI - point.angle), + label: `(${point.time}, ${point.angle.toFixed(2)})`, } }) } + + scaleY(value: number) { + return this.scale(value, -Math.PI, Math.PI, -this.height / 2, this.height / 2) + } + + scale(num: number, inMin: number, inMax: number, outMin: number, outMax: number) { + return (num - inMin) * (outMax - outMin) / (inMax - inMin) + outMin + } } diff --git a/src/client/components/script_tuner/editor/timeline/style.css b/src/client/components/script_tuner/editor/timeline/style.css index 5c81190e..6ad110c9 100644 --- a/src/client/components/script_tuner/editor/timeline/style.css +++ b/src/client/components/script_tuner/editor/timeline/style.css @@ -3,7 +3,7 @@ display: block; flex-shrink: 0; height: 21px; - padding: 0 4px; + padding: 0 5px; line-height: 0; background-color: #AAA; border-bottom: 1px solid #999; diff --git a/src/client/components/script_tuner/editor/timeline/view.tsx b/src/client/components/script_tuner/editor/timeline/view.tsx index b9b5bd1d..93b1c621 100644 --- a/src/client/components/script_tuner/editor/timeline/view.tsx +++ b/src/client/components/script_tuner/editor/timeline/view.tsx @@ -5,20 +5,23 @@ import * as style from './style.css' type TimelineProps = { className?: string, + cellWidth: number, + scaleX: number, length: number } @observer export class Timeline extends React.Component { render() { - const height = 20 - const cellWidth = 32 - const width = this.props.length * cellWidth - const cells = new Array(Math.ceil(width / cellWidth)).fill(0) + const length = this.props.length + 1 // How many points on the timeline + const scaleX = this.props.scaleX + const cellWidth = this.props.cellWidth // Space between each point on the timeline + const width = length * cellWidth * scaleX // Full width of the timeline + const height = 20 // Height of the timeline + const cells = new Array(Math.ceil(length * scaleX)).fill(0) // The cells on the timeline return
{ { - cells.map((_, i) => - - { i } - ) + cells.map((_, i) => { + const isPrimaryCell = i % scaleX === 0 + return + + { isPrimaryCell && + { i / scaleX } + } + + }) } diff --git a/src/client/components/script_tuner/editor/view.tsx b/src/client/components/script_tuner/editor/view.tsx index 042799b4..1733da7b 100644 --- a/src/client/components/script_tuner/editor/view.tsx +++ b/src/client/components/script_tuner/editor/view.tsx @@ -10,6 +10,7 @@ import { LineEditorController } from './line/controller' import { LineEditor } from './line/view' import * as style from './style.css' import { Timeline } from './timeline/view' +import { EditorViewModel } from './view_model' type EditorProps = { className?: string @@ -33,13 +34,29 @@ export class Editor extends React.Component { render() { const { className, controller, model } = this.props const lineEditorController = LineEditorController.of() + const viewModel = new EditorViewModel() return
Editor
- + + +
{ - model.servos.map((servo, index) => ) + model.servos.map((servo, index) => { + return + }) }
diff --git a/src/client/components/script_tuner/editor/view_model.ts b/src/client/components/script_tuner/editor/view_model.ts index 820c7842..11b6539a 100644 --- a/src/client/components/script_tuner/editor/view_model.ts +++ b/src/client/components/script_tuner/editor/view_model.ts @@ -1,2 +1,10 @@ - // TODO map out each of the limbs into script line + +import { observable } from 'mobx' + +export class EditorViewModel { + @observable cellWidth = 32 + @observable scaleX = 2 + @observable height = 200 + @observable timelineLength = 90 +} diff --git a/src/client/components/script_tuner/model.ts b/src/client/components/script_tuner/model.ts index ac4e2794..9fda621f 100644 --- a/src/client/components/script_tuner/model.ts +++ b/src/client/components/script_tuner/model.ts @@ -42,7 +42,7 @@ export class ScriptTunerModel { frames.push({ time: i, - angle: Math.sin(theta), + angle: 2 * Math.sin(theta), pGain: 0, iGain: 0, dGain: 0, From d6f55dfb42c1c938fb9e07cea83e1cf35a32c507 Mon Sep 17 00:00:00 2001 From: Josephus Paye II Date: Thu, 29 Nov 2018 17:02:55 +1100 Subject: [PATCH 10/54] Make timeline and lines have the same length: the longest script --- .../script_tuner/editor/line/view.tsx | 2 +- .../script_tuner/editor/line/view_model.ts | 2 +- .../script_tuner/editor/timeline/view.tsx | 2 +- .../components/script_tuner/editor/view.tsx | 2 +- .../script_tuner/editor/view_model.ts | 26 +++++++++++++++++-- 5 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/client/components/script_tuner/editor/line/view.tsx b/src/client/components/script_tuner/editor/line/view.tsx index 27e5199a..d4a023a3 100644 --- a/src/client/components/script_tuner/editor/line/view.tsx +++ b/src/client/components/script_tuner/editor/line/view.tsx @@ -39,7 +39,7 @@ export class LineEditor extends Component { { // Horizontal grid lines - viewModel.points.map((point, index) => { + new Array(viewModel.width).fill(0).map((_, index) => { const x = index * viewModel.cellWidth return }) diff --git a/src/client/components/script_tuner/editor/line/view_model.ts b/src/client/components/script_tuner/editor/line/view_model.ts index d9a4e754..b1f69a4e 100644 --- a/src/client/components/script_tuner/editor/line/view_model.ts +++ b/src/client/components/script_tuner/editor/line/view_model.ts @@ -35,7 +35,7 @@ export class LineEditorViewModel { @computed get width() { - return this.points.length * this.cellWidth + return this.editorViewModel.timelineLength * this.cellWidth } @computed diff --git a/src/client/components/script_tuner/editor/timeline/view.tsx b/src/client/components/script_tuner/editor/timeline/view.tsx index 93b1c621..ef3fc21d 100644 --- a/src/client/components/script_tuner/editor/timeline/view.tsx +++ b/src/client/components/script_tuner/editor/timeline/view.tsx @@ -13,7 +13,7 @@ type TimelineProps = { @observer export class Timeline extends React.Component { render() { - const length = this.props.length + 1 // How many points on the timeline + const length = this.props.length // How many points on the timeline const scaleX = this.props.scaleX const cellWidth = this.props.cellWidth // Space between each point on the timeline const width = length * cellWidth * scaleX // Full width of the timeline diff --git a/src/client/components/script_tuner/editor/view.tsx b/src/client/components/script_tuner/editor/view.tsx index 1733da7b..e6cdd18e 100644 --- a/src/client/components/script_tuner/editor/view.tsx +++ b/src/client/components/script_tuner/editor/view.tsx @@ -34,7 +34,7 @@ export class Editor extends React.Component { render() { const { className, controller, model } = this.props const lineEditorController = LineEditorController.of() - const viewModel = new EditorViewModel() + const viewModel = EditorViewModel.of(model) return
Editor
diff --git a/src/client/components/script_tuner/editor/view_model.ts b/src/client/components/script_tuner/editor/view_model.ts index 11b6539a..d90106ed 100644 --- a/src/client/components/script_tuner/editor/view_model.ts +++ b/src/client/components/script_tuner/editor/view_model.ts @@ -1,10 +1,32 @@ // TODO map out each of the limbs into script line -import { observable } from 'mobx' +import { computed, observable } from 'mobx' +import { createTransformer } from 'mobx-utils' + +import { ScriptTunerModel } from '../model' export class EditorViewModel { @observable cellWidth = 32 @observable scaleX = 2 @observable height = 200 - @observable timelineLength = 90 + + constructor(private model: ScriptTunerModel) { + } + + static of = createTransformer((model: ScriptTunerModel): EditorViewModel => { + return new EditorViewModel(model) + }) + + @computed + get timelineLength() { + let maxLength = 0 + + this.model.servos.forEach(servo => { + if (servo.frames.length > maxLength) { + maxLength = servo.frames.length + } + }) + + return maxLength + } } From eff78ae97bb5271364cc2ffd8a149a614fc06971 Mon Sep 17 00:00:00 2001 From: Josephus Paye II Date: Thu, 29 Nov 2018 20:26:37 +1100 Subject: [PATCH 11/54] Make points draggable --- .../script_tuner/editor/line/controller.ts | 45 ++++++- .../script_tuner/editor/line/view.tsx | 117 +++++++++++++++++- .../script_tuner/editor/line/view_model.ts | 33 +++-- .../components/script_tuner/editor/view.tsx | 4 +- 4 files changed, 182 insertions(+), 17 deletions(-) diff --git a/src/client/components/script_tuner/editor/line/controller.ts b/src/client/components/script_tuner/editor/line/controller.ts index 4e832c36..54f03458 100644 --- a/src/client/components/script_tuner/editor/line/controller.ts +++ b/src/client/components/script_tuner/editor/line/controller.ts @@ -1,11 +1,48 @@ import { action } from 'mobx' -import { ScriptTunerModel } from '../../model' +import { ScriptTunerModel, Servo } from '../../model' export class LineEditorController { - static of() { - return new LineEditorController() + constructor(private model: Servo) { + this.model = model } - // actions here + static of(model: Servo) { + return new LineEditorController(model) + } + + @action + addFrame = (data: { time: number, angle: number }) => { + this.model.frames.push({ + time: data.time, + angle: data.angle, + pGain: 0, + iGain: 0, + dGain: 0, + torque: 0, + }) + } + + @action + updateFrame = (frameId: number, data: { time: number, angle: number }) => { + const index = this.findFrame(frameId) + + if (index > -1) { + this.model.frames[index].time = data.time + this.model.frames[index].angle = data.angle + } + } + + @action + removeFrame = (frameId: number): void => { + const index = this.findFrame(frameId) + + if (index > -1) { + this.model.frames.splice(index, 1) + } + } + + private findFrame(frameId: number) { + return this.model.frames.findIndex(frame => frame.time === frameId) + } } diff --git a/src/client/components/script_tuner/editor/line/view.tsx b/src/client/components/script_tuner/editor/line/view.tsx index d4a023a3..145ae5b6 100644 --- a/src/client/components/script_tuner/editor/line/view.tsx +++ b/src/client/components/script_tuner/editor/line/view.tsx @@ -19,6 +19,15 @@ type LineEditorProps = { @observer export class LineEditor extends Component { + isDragging: boolean = false + selectedElement: HTMLElement | undefined + svgRef: React.RefObject + + constructor(props: LineEditorProps) { + super(props) + this.svgRef = React.createRef() + } + render() { const viewModel = LineEditorViewModel.of({ servo: this.props.servo, @@ -31,6 +40,11 @@ export class LineEditor extends Component { vectorEffect='non-scaling-stroke' height={viewModel.height + 'px'} width={viewModel.width + 'px'} + ref={this.svgRef} + + onMouseDown={(e) => this.onMouseDown(e, viewModel)} + onMouseMove={(e) => this.onMouseMove(e, viewModel)} + onDoubleClick={(e) => this.onDoubleClick(e.nativeEvent, viewModel)} > // Vertical grid lines @@ -41,7 +55,7 @@ export class LineEditor extends Component { // Horizontal grid lines new Array(viewModel.width).fill(0).map((_, index) => { const x = index * viewModel.cellWidth - return + return }) } @@ -65,16 +79,21 @@ export class LineEditor extends Component { // Points on the main plot line viewModel.svgPoints.map((point, index) => { return this.onRightClick(e, point.id)} > { point.label } @@ -83,4 +102,98 @@ export class LineEditor extends Component {
} + + private onDoubleClick(event: MouseEvent, viewModel: LineEditorViewModel) { + const svg = this.svgRef.current! + const reference = svg.createSVGPoint() + + reference.x = event.clientX + reference.y = event.clientY + + const { x, y } = reference.matrixTransform(svg.getScreenCTM()!.inverse()) + + this.props.controller.addFrame({ + time: viewModel.svgToTime(x), + angle: viewModel.svgToAngle(y), + }) + } + + private onRightClick = ({ nativeEvent: event }: React.MouseEvent, pointId: number) => { + event.preventDefault() + this.props.controller.removeFrame(pointId) + } + + private startDrag() { + this.isDragging = true + + document.addEventListener('mouseup', (event: MouseEvent) => { + this.endDrag() + }, { once: true }) + } + + private endDrag() { + this.isDragging = false + this.selectedElement = undefined + } + + private onMouseDown = ({ nativeEvent: event }: React.MouseEvent, viewModel: LineEditorViewModel) => { + if ((event.target as HTMLElement).dataset.draggable) { + this.selectedElement = (event.target as HTMLElement) + } + } + + private onMouseMove = ({ nativeEvent: event }: React.MouseEvent, viewModel: LineEditorViewModel) => { + if (!this.selectedElement) { + return + } + + // Prevent things that happen on drag, like text selection + event.preventDefault() + + // Start the drag if not already dragging + if (!this.isDragging) { + this.startDrag() + } + + const index = Number(this.selectedElement.dataset.index!) + const mouse = this.getMousePositionInSvgSpace(event) + + const minFrameSeparation = 0.05 + + const previousFrameTime = index === 0 + ? 0 - minFrameSeparation + : viewModel.points[index - 1].time + + const nextFrameTime = index === viewModel.points.length - 1 + ? viewModel.points.length + minFrameSeparation + : viewModel.points[index + 1].time + + // The drag needs to be constrained between the points's neighbours + const time = this.clampToRange( + viewModel.svgToTime(mouse.x), + previousFrameTime + minFrameSeparation, + nextFrameTime - minFrameSeparation, + ) + + const angle = viewModel.svgToAngle(mouse.y) + + this.props.controller.updateFrame( + Number(this.selectedElement.dataset.id), + { time, angle }, + ) + } + + private getMousePositionInSvgSpace(event: MouseEvent) { + const svg = this.svgRef.current! + const CTM = svg.getScreenCTM()! + + return { + x: (event.clientX - CTM.e) / CTM.a, + y: (event.clientY - CTM.f) / CTM.d, + } + } + + private clampToRange(value: number, min: number, max: number) { + return Math.min(Math.max(value, min), max) + } } diff --git a/src/client/components/script_tuner/editor/line/view_model.ts b/src/client/components/script_tuner/editor/line/view_model.ts index b1f69a4e..83d57e4a 100644 --- a/src/client/components/script_tuner/editor/line/view_model.ts +++ b/src/client/components/script_tuner/editor/line/view_model.ts @@ -56,10 +56,10 @@ export class LineEditorViewModel { const point = this.points[i] segments.push({ - x1: point.time * this.cellWidth, - x2: this.points[i + 1].time * this.cellWidth, - y1: this.scaleY(Math.PI - point.angle), - y2: this.scaleY(Math.PI - this.points[i + 1].angle), + x1: this.timeToSvg(point.time), + x2: this.timeToSvg(this.points[i + 1].time), + y1: this.angleToSVG(point.angle), + y2: this.angleToSVG(this.points[i + 1].angle), }) } @@ -70,18 +70,33 @@ export class LineEditorViewModel { get svgPoints() { return this.points.map(point => { return { - x: point.time * this.cellWidth, - y: this.scaleY(Math.PI - point.angle), + id: point.time, + x: this.timeToSvg(point.time), + y: this.angleToSVG(point.angle), label: `(${point.time}, ${point.angle.toFixed(2)})`, } }) } - scaleY(value: number) { - return this.scale(value, -Math.PI, Math.PI, -this.height / 2, this.height / 2) + timeToSvg(time: number) { + return time * this.cellWidth } - scale(num: number, inMin: number, inMax: number, outMin: number, outMax: number) { + svgToTime(coordinate: number) { + return coordinate / this.cellWidth + } + + angleToSVG(angle: number) { + const translated = Math.PI - angle + return this.scale(translated, -Math.PI, Math.PI, -this.height / 2, this.height / 2) + } + + svgToAngle(coordinate: number) { + const unscaled = this.scale(coordinate, -this.height / 2, this.height / 2, -Math.PI, Math.PI) + return -(unscaled - Math.PI) + } + + private scale(num: number, inMin: number, inMax: number, outMin: number, outMax: number) { return (num - inMin) * (outMax - outMin) / (inMax - inMin) + outMin } } diff --git a/src/client/components/script_tuner/editor/view.tsx b/src/client/components/script_tuner/editor/view.tsx index e6cdd18e..a70fb791 100644 --- a/src/client/components/script_tuner/editor/view.tsx +++ b/src/client/components/script_tuner/editor/view.tsx @@ -33,7 +33,6 @@ export class Editor extends React.Component { render() { const { className, controller, model } = this.props - const lineEditorController = LineEditorController.of() const viewModel = EditorViewModel.of(model) return
@@ -50,8 +49,9 @@ export class Editor extends React.Component {
{ model.servos.map((servo, index) => { + const controller = LineEditorController.of(servo) return Date: Thu, 29 Nov 2018 21:16:04 +1100 Subject: [PATCH 12/54] Ensure servo.frames array is sorted for better drag performance --- .../script_tuner/editor/line/controller.ts | 25 ++++++++----------- .../script_tuner/editor/line/view.tsx | 12 +++------ .../script_tuner/editor/line/view_model.ts | 3 +-- 3 files changed, 15 insertions(+), 25 deletions(-) diff --git a/src/client/components/script_tuner/editor/line/controller.ts b/src/client/components/script_tuner/editor/line/controller.ts index 54f03458..8fc4c454 100644 --- a/src/client/components/script_tuner/editor/line/controller.ts +++ b/src/client/components/script_tuner/editor/line/controller.ts @@ -21,28 +21,23 @@ export class LineEditorController { dGain: 0, torque: 0, }) + + // Perserve the sorting by time. Array replaced as MobX's sort() is not in-place. + this.model.frames = this.model.frames.slice().sort((a, b) => a.time - b.time) } @action - updateFrame = (frameId: number, data: { time: number, angle: number }) => { - const index = this.findFrame(frameId) - - if (index > -1) { - this.model.frames[index].time = data.time - this.model.frames[index].angle = data.angle + updateFrame = (frameIndex: number, data: { time: number, angle: number }) => { + if (frameIndex > -1) { + this.model.frames[frameIndex].time = data.time + this.model.frames[frameIndex].angle = data.angle } } @action - removeFrame = (frameId: number): void => { - const index = this.findFrame(frameId) - - if (index > -1) { - this.model.frames.splice(index, 1) + removeFrame = (frameIndex: number) => { + if (frameIndex > -1) { + this.model.frames.splice(frameIndex, 1) } } - - private findFrame(frameId: number) { - return this.model.frames.findIndex(frame => frame.time === frameId) - } } diff --git a/src/client/components/script_tuner/editor/line/view.tsx b/src/client/components/script_tuner/editor/line/view.tsx index 145ae5b6..2edb1eee 100644 --- a/src/client/components/script_tuner/editor/line/view.tsx +++ b/src/client/components/script_tuner/editor/line/view.tsx @@ -84,7 +84,6 @@ export class LineEditor extends Component { cx={point.x} cy={point.y} - data-id={point.id} data-index={index} data-draggable='true' @@ -93,7 +92,7 @@ export class LineEditor extends Component { stroke='black' strokeWidth='1' - onContextMenu={(e) => this.onRightClick(e, point.id)} + onContextMenu={(e) => this.onRightClick(e, index)} > { point.label } @@ -118,9 +117,9 @@ export class LineEditor extends Component { }) } - private onRightClick = ({ nativeEvent: event }: React.MouseEvent, pointId: number) => { + private onRightClick = ({ nativeEvent: event }: React.MouseEvent, pointIndex: number) => { event.preventDefault() - this.props.controller.removeFrame(pointId) + this.props.controller.removeFrame(pointIndex) } private startDrag() { @@ -177,10 +176,7 @@ export class LineEditor extends Component { const angle = viewModel.svgToAngle(mouse.y) - this.props.controller.updateFrame( - Number(this.selectedElement.dataset.id), - { time, angle }, - ) + this.props.controller.updateFrame(index, { time, angle }) } private getMousePositionInSvgSpace(event: MouseEvent) { diff --git a/src/client/components/script_tuner/editor/line/view_model.ts b/src/client/components/script_tuner/editor/line/view_model.ts index 83d57e4a..fdb7f15e 100644 --- a/src/client/components/script_tuner/editor/line/view_model.ts +++ b/src/client/components/script_tuner/editor/line/view_model.ts @@ -45,7 +45,7 @@ export class LineEditorViewModel { @computed get points() { - return this.servo.frames.concat().sort((a, b) => a.time - b.time) + return this.servo.frames } @computed @@ -70,7 +70,6 @@ export class LineEditorViewModel { get svgPoints() { return this.points.map(point => { return { - id: point.time, x: this.timeToSvg(point.time), y: this.angleToSVG(point.angle), label: `(${point.time}, ${point.angle.toFixed(2)})`, From 85b267e8d541d7e44f5c91f41767cd08958c0d84 Mon Sep 17 00:00:00 2001 From: Josephus Paye II Date: Thu, 29 Nov 2018 21:24:03 +1100 Subject: [PATCH 13/54] Use crosshair cursor over the graph --- .../components/script_tuner/editor/line/controller.ts | 10 +++------- .../components/script_tuner/editor/line/style.css | 1 + 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/client/components/script_tuner/editor/line/controller.ts b/src/client/components/script_tuner/editor/line/controller.ts index 8fc4c454..d9b0984b 100644 --- a/src/client/components/script_tuner/editor/line/controller.ts +++ b/src/client/components/script_tuner/editor/line/controller.ts @@ -28,16 +28,12 @@ export class LineEditorController { @action updateFrame = (frameIndex: number, data: { time: number, angle: number }) => { - if (frameIndex > -1) { - this.model.frames[frameIndex].time = data.time - this.model.frames[frameIndex].angle = data.angle - } + this.model.frames[frameIndex].time = data.time + this.model.frames[frameIndex].angle = data.angle } @action removeFrame = (frameIndex: number) => { - if (frameIndex > -1) { - this.model.frames.splice(frameIndex, 1) - } + this.model.frames.splice(frameIndex, 1) } } diff --git a/src/client/components/script_tuner/editor/line/style.css b/src/client/components/script_tuner/editor/line/style.css index b45006a7..8d47d107 100644 --- a/src/client/components/script_tuner/editor/line/style.css +++ b/src/client/components/script_tuner/editor/line/style.css @@ -7,6 +7,7 @@ user-select: none; border: 1px solid #AAA; background-color: white; + cursor: crosshair; } .lineEditorDraggable { From 13167135e4d0c5524f5c7e3458a7f7c06c1df962 Mon Sep 17 00:00:00 2001 From: Josephus Paye II Date: Thu, 6 Dec 2018 19:27:52 +1100 Subject: [PATCH 14/54] Add play head --- .../script_tuner/editor/controller.ts | 18 +++ .../script_tuner/editor/line/style.css | 4 +- .../script_tuner/editor/line/view.tsx | 13 +- .../script_tuner/editor/line/view_model.ts | 5 + .../components/script_tuner/editor/style.css | 2 +- .../script_tuner/editor/timeline/style.css | 5 +- .../script_tuner/editor/timeline/view.tsx | 129 +++++++++++++++--- .../editor/timeline/view_model.ts | 60 ++++++++ .../components/script_tuner/editor/view.tsx | 9 +- .../script_tuner/editor/view_model.ts | 1 + 10 files changed, 216 insertions(+), 30 deletions(-) create mode 100644 src/client/components/script_tuner/editor/controller.ts create mode 100644 src/client/components/script_tuner/editor/timeline/view_model.ts diff --git a/src/client/components/script_tuner/editor/controller.ts b/src/client/components/script_tuner/editor/controller.ts new file mode 100644 index 00000000..0089cf16 --- /dev/null +++ b/src/client/components/script_tuner/editor/controller.ts @@ -0,0 +1,18 @@ +import { action } from 'mobx' + +import { EditorViewModel } from './view_model' + +export class EditorController { + constructor(private viewModel: EditorViewModel) { + this.viewModel = viewModel + } + + static of(viewModel: EditorViewModel) { + return new EditorController(viewModel) + } + + @action + setCurrentTime = (time: number) => { + this.viewModel.currentTime = time + } +} diff --git a/src/client/components/script_tuner/editor/line/style.css b/src/client/components/script_tuner/editor/line/style.css index 8d47d107..b3c555b2 100644 --- a/src/client/components/script_tuner/editor/line/style.css +++ b/src/client/components/script_tuner/editor/line/style.css @@ -1,11 +1,11 @@ .lineEditor { - + line-height: 0; } .lineEditorSvg { font-family: monospace; user-select: none; - border: 1px solid #AAA; + border: 1px solid #888; background-color: white; cursor: crosshair; } diff --git a/src/client/components/script_tuner/editor/line/view.tsx b/src/client/components/script_tuner/editor/line/view.tsx index 2edb1eee..0be56a18 100644 --- a/src/client/components/script_tuner/editor/line/view.tsx +++ b/src/client/components/script_tuner/editor/line/view.tsx @@ -46,13 +46,13 @@ export class LineEditor extends Component { onMouseMove={(e) => this.onMouseMove(e, viewModel)} onDoubleClick={(e) => this.onDoubleClick(e.nativeEvent, viewModel)} > - // Vertical grid lines + // Horizontal grid lines { - // Horizontal grid lines + // Vertical grid lines new Array(viewModel.width).fill(0).map((_, index) => { const x = index * viewModel.cellWidth return @@ -98,6 +98,15 @@ export class LineEditor extends Component { }) } + +
} diff --git a/src/client/components/script_tuner/editor/line/view_model.ts b/src/client/components/script_tuner/editor/line/view_model.ts index fdb7f15e..d514e3d9 100644 --- a/src/client/components/script_tuner/editor/line/view_model.ts +++ b/src/client/components/script_tuner/editor/line/view_model.ts @@ -43,6 +43,11 @@ export class LineEditorViewModel { return this.editorViewModel.height } + @computed + get playPosition() { + return this.editorViewModel.currentTime * this.cellWidth + } + @computed get points() { return this.servo.frames diff --git a/src/client/components/script_tuner/editor/style.css b/src/client/components/script_tuner/editor/style.css index 5ba9989d..e32a5cfb 100644 --- a/src/client/components/script_tuner/editor/style.css +++ b/src/client/components/script_tuner/editor/style.css @@ -14,7 +14,7 @@ } .editorBody { - padding: 4px; + padding: 0 4px; flex-grow: 1; overflow: auto; } diff --git a/src/client/components/script_tuner/editor/timeline/style.css b/src/client/components/script_tuner/editor/timeline/style.css index 6ad110c9..48475262 100644 --- a/src/client/components/script_tuner/editor/timeline/style.css +++ b/src/client/components/script_tuner/editor/timeline/style.css @@ -5,10 +5,11 @@ height: 21px; padding: 0 5px; line-height: 0; - background-color: #AAA; + background-color: #CCC; border-bottom: 1px solid #999; overflow-x: scroll; overflow-y: hidden; + user-select: none; } /* Hide the scrollbar, not using overflow:hidden so we can programmatically scroll the timeline */ @@ -24,5 +25,5 @@ .timelineText { font-size: 10px; - fill: white; + fill: black; } diff --git a/src/client/components/script_tuner/editor/timeline/view.tsx b/src/client/components/script_tuner/editor/timeline/view.tsx index ef3fc21d..1b5bb49c 100644 --- a/src/client/components/script_tuner/editor/timeline/view.tsx +++ b/src/client/components/script_tuner/editor/timeline/view.tsx @@ -1,54 +1,145 @@ import { observer } from 'mobx-react' import * as React from 'react' +import { EditorViewModel } from '../view_model' + import * as style from './style.css' +import { TimelineViewModel } from './view_model' type TimelineProps = { className?: string, - cellWidth: number, - scaleX: number, - length: number + editorViewModel: EditorViewModel, + setCurrentTime(time: number): void } @observer export class Timeline extends React.Component { + readyToDrag: boolean = false + isDragging: boolean = false + svgRef: React.RefObject + + constructor(props: TimelineProps) { + super(props) + this.svgRef = React.createRef() + } + render() { - const length = this.props.length // How many points on the timeline - const scaleX = this.props.scaleX - const cellWidth = this.props.cellWidth // Space between each point on the timeline - const width = length * cellWidth * scaleX // Full width of the timeline - const height = 20 // Height of the timeline - const cells = new Array(Math.ceil(length * scaleX)).fill(0) // The cells on the timeline + const viewModel = TimelineViewModel.of(this.props.editorViewModel) return
this.onMouseDown(e, viewModel)} + onMouseMove={(e) => this.onMouseMove(e, viewModel)} + onClick={(e) => this.onClick(e.nativeEvent, viewModel)} > - + { - cells.map((_, i) => { - const isPrimaryCell = i % scaleX === 0 - return + viewModel.cells.map((_, i) => { + const isPrimaryCell = i % viewModel.scaleX === 0 + return * { isPrimaryCell && - { i / scaleX } + { i / viewModel.scaleX } } }) } + + // Play head. 26 is the natural height of the play head symbol, in pixels. + + +
} + + private onClick(event: MouseEvent, viewModel: TimelineViewModel) { + const svg = this.svgRef.current! + const reference = svg.createSVGPoint() + + reference.x = event.clientX + reference.y = event.clientY + + const { x } = reference.matrixTransform(svg.getScreenCTM()!.inverse()) + + this.props.setCurrentTime(viewModel.svgToTime(x)) + } + + private startDrag() { + this.isDragging = true + + document.addEventListener('mouseup', (event: MouseEvent) => { + this.endDrag() + }, { once: true }) + } + + private endDrag() { + this.isDragging = false + this.readyToDrag = false + } + + private onMouseDown = ({ nativeEvent: event }: React.MouseEvent, viewModel: TimelineViewModel) => { + if ((event.target as HTMLElement).dataset.draggable) { + this.readyToDrag = true + } + } + + private onMouseMove = ({ nativeEvent: event }: React.MouseEvent, viewModel: TimelineViewModel) => { + if (!this.readyToDrag) { + return + } + + // Prevent things that happen on drag, like text selection + event.preventDefault() + + // Start the drag if not already dragging + if (!this.isDragging) { + this.startDrag() + } + + const { x } = this.getMousePositionInSvgSpace(event) + + this.props.setCurrentTime( + this.clampToRange(viewModel.svgToTime(x), 0, viewModel.timelineLength), + ) + } + + private getMousePositionInSvgSpace(event: MouseEvent) { + const svg = this.svgRef.current! + const CTM = svg.getScreenCTM()! + + return { + x: (event.clientX - CTM.e) / CTM.a, + y: (event.clientY - CTM.f) / CTM.d, + } + } + + private clampToRange(value: number, min: number, max: number) { + return Math.min(Math.max(value, min), max) + } } diff --git a/src/client/components/script_tuner/editor/timeline/view_model.ts b/src/client/components/script_tuner/editor/timeline/view_model.ts new file mode 100644 index 00000000..cc3d862f --- /dev/null +++ b/src/client/components/script_tuner/editor/timeline/view_model.ts @@ -0,0 +1,60 @@ +import { computed } from 'mobx' +import { createTransformer } from 'mobx-utils' + +import { EditorViewModel } from '../view_model' + +export class TimelineViewModel { + private editorViewModel: EditorViewModel + + constructor(editorViewModel: EditorViewModel) { + this.editorViewModel = editorViewModel + } + + static of = createTransformer((editorViewModel: EditorViewModel): TimelineViewModel => { + return new TimelineViewModel(editorViewModel) + }) + + @computed + get scaleX() { + return this.editorViewModel.scaleX + } + + @computed + get cellWidth() { + return this.editorViewModel.cellWidth + } + + @computed + get width() { + return this.editorViewModel.timelineLength * this.cellWidth * this.scaleX + } + + @computed + get height() { + return 20 + } + + @computed + get timelineLength() { + return this.editorViewModel.timelineLength + } + + @computed + get cells() { + return new Array(Math.ceil(this.editorViewModel.timelineLength * this.scaleX)).fill(0) + } + + @computed + get playHeadPosition() { + const playHeadWidth = 18 + return this.timeToSvg(this.editorViewModel.currentTime) - (playHeadWidth / 2) + } + + timeToSvg(time: number) { + return time * this.cellWidth * this.scaleX + } + + svgToTime(coordinate: number) { + return coordinate / this.cellWidth / this.scaleX + } +} diff --git a/src/client/components/script_tuner/editor/view.tsx b/src/client/components/script_tuner/editor/view.tsx index a70fb791..3737946f 100644 --- a/src/client/components/script_tuner/editor/view.tsx +++ b/src/client/components/script_tuner/editor/view.tsx @@ -6,6 +6,7 @@ import * as ReactDOM from 'react-dom' import { ScriptTunerController } from '../controller' import { ScriptTunerModel } from '../model' +import { EditorController } from './controller' import { LineEditorController } from './line/controller' import { LineEditor } from './line/view' import * as style from './style.css' @@ -32,17 +33,17 @@ export class Editor extends React.Component { } render() { - const { className, controller, model } = this.props + const { className, model } = this.props const viewModel = EditorViewModel.of(model) + const controller = EditorController.of(viewModel) return
Editor
diff --git a/src/client/components/script_tuner/editor/view_model.ts b/src/client/components/script_tuner/editor/view_model.ts index d90106ed..32a8ba1d 100644 --- a/src/client/components/script_tuner/editor/view_model.ts +++ b/src/client/components/script_tuner/editor/view_model.ts @@ -9,6 +9,7 @@ export class EditorViewModel { @observable cellWidth = 32 @observable scaleX = 2 @observable height = 200 + @observable currentTime = 1 constructor(private model: ScriptTunerModel) { } From fd151a86db19edae27406629e230712f82854563 Mon Sep 17 00:00:00 2001 From: Josephus Paye II Date: Thu, 6 Dec 2018 19:33:14 +1100 Subject: [PATCH 15/54] Fix JSX comments --- src/client/components/script_tuner/editor/line/view.tsx | 3 ++- src/client/components/script_tuner/editor/timeline/view.tsx | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/client/components/script_tuner/editor/line/view.tsx b/src/client/components/script_tuner/editor/line/view.tsx index 0be56a18..6e2ccb37 100644 --- a/src/client/components/script_tuner/editor/line/view.tsx +++ b/src/client/components/script_tuner/editor/line/view.tsx @@ -46,7 +46,7 @@ export class LineEditor extends Component { onMouseMove={(e) => this.onMouseMove(e, viewModel)} onDoubleClick={(e) => this.onDoubleClick(e.nativeEvent, viewModel)} > - // Horizontal grid lines + { /* Horizontal grid lines */ } @@ -99,6 +99,7 @@ export class LineEditor extends Component { }) } + { /* The current play position indicator */ } { } - // Play head. 26 is the natural height of the play head symbol, in pixels. + { /* Play head. 26 is the natural height of the play head symbol, in pixels. */ } Date: Thu, 6 Dec 2018 21:28:56 +1100 Subject: [PATCH 16/54] [WIP] Add playback controls --- .../script_tuner/editor/controller.ts | 76 ++++++++++++++++++- .../components/script_tuner/editor/style.css | 38 +++++++++- .../components/script_tuner/editor/view.tsx | 25 +++++- .../script_tuner/editor/view_model.ts | 3 +- 4 files changed, 137 insertions(+), 5 deletions(-) diff --git a/src/client/components/script_tuner/editor/controller.ts b/src/client/components/script_tuner/editor/controller.ts index 0089cf16..e8d04466 100644 --- a/src/client/components/script_tuner/editor/controller.ts +++ b/src/client/components/script_tuner/editor/controller.ts @@ -1,9 +1,12 @@ -import { action } from 'mobx' +import { action, computed, observable } from 'mobx' import { EditorViewModel } from './view_model' export class EditorController { + raf = 0 + constructor(private viewModel: EditorViewModel) { + console.log('Constructor recreated') this.viewModel = viewModel } @@ -11,8 +14,77 @@ export class EditorController { return new EditorController(viewModel) } + @computed + get startTime() { + return 0 + } + + @computed + get endTime() { + return this.viewModel.timelineLength - 1 + } + @action setCurrentTime = (time: number) => { - this.viewModel.currentTime = time + this.viewModel.currentTime = Math.min(Math.max(time, this.startTime), this.endTime) + } + + @action + play = () => { + if (this.viewModel.isPlaying) { + return + } + + this.raf = requestAnimationFrame(this.playNextFrame) + this.viewModel.isPlaying = true + } + + @action + playNextFrame = () => { + this.viewModel.currentTime = Math.min( + this.viewModel.currentTime + (this.viewModel.cellWidth / this.viewModel.scaleX / 60), + this.endTime, + ) + + if (this.viewModel.currentTime === this.endTime) { + console.log('ended') + this.raf = 0 + this.viewModel.isPlaying = false + } else { + this.raf = requestAnimationFrame(this.playNextFrame) + console.log(this.raf) + } + } + + @action + pause = () => { + if (!this.viewModel.isPlaying) { + return + } + + cancelAnimationFrame(this.raf!) + this.raf = 0 + this.viewModel.isPlaying = false + } + + @action + togglePlayback = () => { + console.log('Toggling playback', this.viewModel.isPlaying) + + if (this.viewModel.isPlaying) { + this.pause() + } else { + this.play() + } + } + + @action + jumpToStart = () => { + this.viewModel.currentTime = 0 + } + + @action + jumpToEnd = () => { + this.viewModel.currentTime = this.viewModel.timelineLength - 1 } } diff --git a/src/client/components/script_tuner/editor/style.css b/src/client/components/script_tuner/editor/style.css index e32a5cfb..0ad02080 100644 --- a/src/client/components/script_tuner/editor/style.css +++ b/src/client/components/script_tuner/editor/style.css @@ -10,7 +10,43 @@ background-color: #777; padding: 0 4px; color: white; - font-size: 13px; + font-size: 14px; + display: flex; + min-height: 24px; + align-items: center; +} + +.editorControls { + margin-left: auto; + height: 18px; +} + +.editorControls button { + width: 18px; + height: 18px; + padding: 0; + display: inline-flex; + align-items: center; + justify-content: center; + background-color: #444; + border: none; + margin-right: 4px; + outline: none; +} + +.editorControls button:hover, +.editorControls button:focus { + background-color: #333; +} + +.editorControls button:active { + background-color: #222; +} + +.editorControls svg { + width: 12px; + height: 12px; + fill: white; } .editorBody { diff --git a/src/client/components/script_tuner/editor/view.tsx b/src/client/components/script_tuner/editor/view.tsx index 3737946f..0b864c27 100644 --- a/src/client/components/script_tuner/editor/view.tsx +++ b/src/client/components/script_tuner/editor/view.tsx @@ -38,7 +38,30 @@ export class Editor extends React.Component { const controller = EditorController.of(viewModel) return
-
Editor
+
+
Editor
+
+ + + +
+
Date: Thu, 6 Dec 2018 21:30:51 +1100 Subject: [PATCH 17/54] Style fix --- src/client/components/script_tuner/editor/controller.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/client/components/script_tuner/editor/controller.ts b/src/client/components/script_tuner/editor/controller.ts index e8d04466..6e739efb 100644 --- a/src/client/components/script_tuner/editor/controller.ts +++ b/src/client/components/script_tuner/editor/controller.ts @@ -6,7 +6,7 @@ export class EditorController { raf = 0 constructor(private viewModel: EditorViewModel) { - console.log('Constructor recreated') + // console.log('Constructor recreated') this.viewModel = viewModel } @@ -47,12 +47,12 @@ export class EditorController { ) if (this.viewModel.currentTime === this.endTime) { - console.log('ended') + // console.log('ended') this.raf = 0 this.viewModel.isPlaying = false } else { this.raf = requestAnimationFrame(this.playNextFrame) - console.log(this.raf) + // console.log(this.raf) } } @@ -69,7 +69,7 @@ export class EditorController { @action togglePlayback = () => { - console.log('Toggling playback', this.viewModel.isPlaying) + // console.log('Toggling playback', this.viewModel.isPlaying) if (this.viewModel.isPlaying) { this.pause() From 79a27e975d79052aa39e7451d3b75fe7d4a46235 Mon Sep 17 00:00:00 2001 From: Josephus Paye II Date: Thu, 20 Dec 2018 20:37:53 +1100 Subject: [PATCH 18/54] Refactor playback and pause/play functionality Now uses `mobxUtils.now()` to keep track of time during playback --- .../components/script_tuner/controller.ts | 43 +++++++++- .../script_tuner/editor/controller.ts | 79 ++++++------------- .../script_tuner/editor/line/view_model.ts | 2 +- .../script_tuner/editor/timeline/view.tsx | 6 +- .../editor/timeline/view_model.ts | 2 +- .../components/script_tuner/editor/view.tsx | 9 ++- .../script_tuner/editor/view_model.ts | 28 ++++--- .../components/script_tuner/install.tsx | 2 +- src/client/components/script_tuner/model.ts | 36 +++++++++ 9 files changed, 129 insertions(+), 78 deletions(-) diff --git a/src/client/components/script_tuner/controller.ts b/src/client/components/script_tuner/controller.ts index 9602eab2..7b33968f 100644 --- a/src/client/components/script_tuner/controller.ts +++ b/src/client/components/script_tuner/controller.ts @@ -1,14 +1,49 @@ -import { action } from 'mobx' +import { action, autorun, IReactionDisposer } from 'mobx' +import { ScriptTunerModel } from './model' import { ScriptTunerNetwork } from './network' +interface ScriptTunerOpts { + network: ScriptTunerNetwork + model: ScriptTunerModel +} + export class ScriptTunerController { + network: ScriptTunerNetwork + model: ScriptTunerModel + stopPlaytimeAutorun?: IReactionDisposer + + constructor(opts: ScriptTunerOpts) { + this.network = opts.network + this.model = opts.model + + this.stopPlaytimeAutorun = autorun(() => { + if (this.model.playTime >= this.model.endTime) { + this.togglePlayback(false) + } + }) - constructor(private network: ScriptTunerNetwork) { // TODO need to add an autorunner that if we are connected to the robot we need to send it update packets } - static of(network: ScriptTunerNetwork) { - return new ScriptTunerController(network) + static of(opts: ScriptTunerOpts) { + return new ScriptTunerController(opts) + } + + @action + setPlayTime(time: number) { + this.model.currentTime = Math.min(Math.max(time, this.model.startTime), this.model.endTime) + this.model.playStart = Date.now() + } + + @action + togglePlayback(isPlaying: boolean = !this.model.isPlaying) { + if (isPlaying) { + this.model.playStart = Date.now() + } else { + this.model.currentTime = this.model.playTime + } + + this.model.isPlaying = isPlaying } } diff --git a/src/client/components/script_tuner/editor/controller.ts b/src/client/components/script_tuner/editor/controller.ts index 6e739efb..9e55f8be 100644 --- a/src/client/components/script_tuner/editor/controller.ts +++ b/src/client/components/script_tuner/editor/controller.ts @@ -1,90 +1,57 @@ import { action, computed, observable } from 'mobx' +import { createTransformer } from 'mobx-utils' -import { EditorViewModel } from './view_model' +import { ScriptTunerController } from '../controller' -export class EditorController { - raf = 0 +import { EditorViewModel } from './view_model' - constructor(private viewModel: EditorViewModel) { - // console.log('Constructor recreated') - this.viewModel = viewModel - } +interface EditorControllerOpts { + viewModel: EditorViewModel, + controller: ScriptTunerController +} - static of(viewModel: EditorViewModel) { - return new EditorController(viewModel) - } +export class EditorController { + viewModel: EditorViewModel + controller: ScriptTunerController - @computed - get startTime() { - return 0 + constructor(opts: EditorControllerOpts) { + this.viewModel = opts.viewModel + this.controller = opts.controller } - @computed - get endTime() { - return this.viewModel.timelineLength - 1 - } + static of = createTransformer((opts: EditorControllerOpts) => { + return new EditorController(opts) + }) - @action - setCurrentTime = (time: number) => { - this.viewModel.currentTime = Math.min(Math.max(time, this.startTime), this.endTime) + setPlayTime = (time: number) => { + this.controller.setPlayTime(time) } - @action play = () => { if (this.viewModel.isPlaying) { return } - this.raf = requestAnimationFrame(this.playNextFrame) - this.viewModel.isPlaying = true + this.controller.togglePlayback(true) } - @action - playNextFrame = () => { - this.viewModel.currentTime = Math.min( - this.viewModel.currentTime + (this.viewModel.cellWidth / this.viewModel.scaleX / 60), - this.endTime, - ) - - if (this.viewModel.currentTime === this.endTime) { - // console.log('ended') - this.raf = 0 - this.viewModel.isPlaying = false - } else { - this.raf = requestAnimationFrame(this.playNextFrame) - // console.log(this.raf) - } - } - - @action pause = () => { if (!this.viewModel.isPlaying) { return } - cancelAnimationFrame(this.raf!) - this.raf = 0 - this.viewModel.isPlaying = false + this.controller.togglePlayback(false) } - @action togglePlayback = () => { - // console.log('Toggling playback', this.viewModel.isPlaying) - - if (this.viewModel.isPlaying) { - this.pause() - } else { - this.play() - } + this.controller.togglePlayback() } - @action jumpToStart = () => { - this.viewModel.currentTime = 0 + this.controller.setPlayTime(this.viewModel.startTime) } - @action jumpToEnd = () => { - this.viewModel.currentTime = this.viewModel.timelineLength - 1 + this.controller.setPlayTime(this.viewModel.endTime) } } diff --git a/src/client/components/script_tuner/editor/line/view_model.ts b/src/client/components/script_tuner/editor/line/view_model.ts index d514e3d9..3a161c2a 100644 --- a/src/client/components/script_tuner/editor/line/view_model.ts +++ b/src/client/components/script_tuner/editor/line/view_model.ts @@ -45,7 +45,7 @@ export class LineEditorViewModel { @computed get playPosition() { - return this.editorViewModel.currentTime * this.cellWidth + return this.editorViewModel.playTime * this.cellWidth } @computed diff --git a/src/client/components/script_tuner/editor/timeline/view.tsx b/src/client/components/script_tuner/editor/timeline/view.tsx index 4e78a19f..03b35548 100644 --- a/src/client/components/script_tuner/editor/timeline/view.tsx +++ b/src/client/components/script_tuner/editor/timeline/view.tsx @@ -9,7 +9,7 @@ import { TimelineViewModel } from './view_model' type TimelineProps = { className?: string, editorViewModel: EditorViewModel, - setCurrentTime(time: number): void + setPlayTime(time: number): void } @observer @@ -87,7 +87,7 @@ export class Timeline extends React.Component { const { x } = reference.matrixTransform(svg.getScreenCTM()!.inverse()) - this.props.setCurrentTime(viewModel.svgToTime(x)) + this.props.setPlayTime(viewModel.svgToTime(x)) } private startDrag() { @@ -124,7 +124,7 @@ export class Timeline extends React.Component { const { x } = this.getMousePositionInSvgSpace(event) - this.props.setCurrentTime( + this.props.setPlayTime( this.clampToRange(viewModel.svgToTime(x), 0, viewModel.timelineLength), ) } diff --git a/src/client/components/script_tuner/editor/timeline/view_model.ts b/src/client/components/script_tuner/editor/timeline/view_model.ts index cc3d862f..f7a9ad20 100644 --- a/src/client/components/script_tuner/editor/timeline/view_model.ts +++ b/src/client/components/script_tuner/editor/timeline/view_model.ts @@ -47,7 +47,7 @@ export class TimelineViewModel { @computed get playHeadPosition() { const playHeadWidth = 18 - return this.timeToSvg(this.editorViewModel.currentTime) - (playHeadWidth / 2) + return this.timeToSvg(this.editorViewModel.playTime) - (playHeadWidth / 2) } timeToSvg(time: number) { diff --git a/src/client/components/script_tuner/editor/view.tsx b/src/client/components/script_tuner/editor/view.tsx index 0b864c27..9a896f2a 100644 --- a/src/client/components/script_tuner/editor/view.tsx +++ b/src/client/components/script_tuner/editor/view.tsx @@ -35,7 +35,10 @@ export class Editor extends React.Component { render() { const { className, model } = this.props const viewModel = EditorViewModel.of(model) - const controller = EditorController.of(viewModel) + const controller = EditorController.of({ + viewModel, + controller: this.props.controller, + }) return
@@ -49,7 +52,7 @@ export class Editor extends React.Component { - + +
From adca3afe1d7c2ef6a284ab68a018a802408684bc Mon Sep 17 00:00:00 2001 From: Josephus Paye II Date: Wed, 23 Jan 2019 17:26:23 +1100 Subject: [PATCH 29/54] Add temporary sample salute script from robot --- src/client/components/script_tuner/model.ts | 16 +- .../script_tuner/sample-script.json | 956 ++++++++++++++++++ 2 files changed, 969 insertions(+), 3 deletions(-) create mode 100644 src/client/components/script_tuner/sample-script.json diff --git a/src/client/components/script_tuner/model.ts b/src/client/components/script_tuner/model.ts index d4e2dcf5..697e9b78 100644 --- a/src/client/components/script_tuner/model.ts +++ b/src/client/components/script_tuner/model.ts @@ -19,6 +19,10 @@ export interface Frame { torque: number, } +import * as sampleScriptJson from './script_converter/converted.json' + +const sampleScript = sampleScriptJson as { [key: string]: Servo } + export class ScriptTunerModel { @observable robot: RobotModel @observable servos: Servo[] @@ -98,10 +102,16 @@ export class ScriptTunerModel { 'LEFT_ANKLE_ROLL', 'HEAD_YAW', 'HEAD_PITCH', - ].map(name => this.makeSampleServo(name, 60)) + ].map(name => { + if (sampleScript[name]) { + return sampleScript[name] + } + + return this.makeSampleServo(name, 5, 0) + }) } - private makeSampleServo(name: string, length: number = 30): Servo { + private makeSampleServo(name: string, length: number = 30, angle?: number): Servo { const frames = [] const period = 10 @@ -110,7 +120,7 @@ export class ScriptTunerModel { frames.push({ time: i, - angle: 2 * Math.sin(theta), + angle: angle !== undefined ? angle : 2 * Math.sin(theta), pGain: 0, iGain: 0, dGain: 0, diff --git a/src/client/components/script_tuner/sample-script.json b/src/client/components/script_tuner/sample-script.json new file mode 100644 index 00000000..323604bb --- /dev/null +++ b/src/client/components/script_tuner/sample-script.json @@ -0,0 +1,956 @@ +{ + "LEFT_HIP_YAW": { + "name": "LEFT_HIP_YAW", + "frames": [ + { + "time": 1, + "angle": 0.02923973, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1.6, + "angle": 0.02923973, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1.8, + "angle": 0.02923973, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2.4, + "angle": 0.02923973, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2.6, + "angle": 0.02923973, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3.4, + "angle": 0.02923973, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_HIP_ROLL": { + "name": "LEFT_HIP_ROLL", + "frames": [ + { + "time": 1, + "angle": 0.06261409, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1.6, + "angle": 0.06261409, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1.8, + "angle": 0.06261409, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2.4, + "angle": 0.06261409, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2.6, + "angle": 0.06261409, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3.4, + "angle": 0.06261409, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_HIP_PITCH": { + "name": "LEFT_HIP_PITCH", + "frames": [ + { + "time": 1, + "angle": -1.215349, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1.6, + "angle": -0.6137422, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1.8, + "angle": -0.6137422, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2.4, + "angle": -0.6137422, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2.6, + "angle": -0.6137422, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3.4, + "angle": -1.215349, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_KNEE": { + "name": "LEFT_KNEE", + "frames": [ + { + "time": 1, + "angle": 1.34201, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1.6, + "angle": 0.5968642, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1.8, + "angle": 0.5968642, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2.4, + "angle": 0.5968642, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2.6, + "angle": 0.5968642, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3.4, + "angle": 1.34201, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_ANKLE_PITCH": { + "name": "LEFT_ANKLE_PITCH", + "frames": [ + { + "time": 1, + "angle": -0.5639089, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1.6, + "angle": -0.276184, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1.8, + "angle": -0.276184, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2.4, + "angle": -0.276184, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2.6, + "angle": -0.276184, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3.4, + "angle": -0.5639089, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_ANKLE_ROLL": { + "name": "LEFT_ANKLE_ROLL", + "frames": [ + { + "time": 1, + "angle": -0.06909663, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1.6, + "angle": -0.06909663, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1.8, + "angle": -0.06909663, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2.4, + "angle": -0.06909663, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2.6, + "angle": -0.06909663, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3.4, + "angle": -0.06909663, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_HIP_YAW": { + "name": "RIGHT_HIP_YAW", + "frames": [ + { + "time": 1, + "angle": -0.02923973, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1.6, + "angle": -0.02923973, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1.8, + "angle": -0.02923973, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2.4, + "angle": -0.02923973, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2.6, + "angle": -0.02923973, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3.4, + "angle": -0.02923973, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_HIP_ROLL": { + "name": "RIGHT_HIP_ROLL", + "frames": [ + { + "time": 1, + "angle": -0.06261409, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1.6, + "angle": -0.06261409, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1.8, + "angle": -0.06261409, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2.4, + "angle": -0.06261409, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2.6, + "angle": -0.06261409, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3.4, + "angle": -0.06261409, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_HIP_PITCH": { + "name": "RIGHT_HIP_PITCH", + "frames": [ + { + "time": 1, + "angle": -1.215349, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1.6, + "angle": -0.6904599, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1.8, + "angle": -0.6904599, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2.4, + "angle": -0.6904599, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2.6, + "angle": -0.6904599, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3.4, + "angle": -1.215349, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_KNEE": { + "name": "RIGHT_KNEE", + "frames": [ + { + "time": 1, + "angle": 1.34201, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1.6, + "angle": 0.6628415, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1.8, + "angle": 0.6628415, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2.4, + "angle": 0.6628415, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2.6, + "angle": 0.6628415, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3.4, + "angle": 1.34201, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_ANKLE_PITCH": { + "name": "RIGHT_ANKLE_PITCH", + "frames": [ + { + "time": 1, + "angle": -0.5639089, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1.6, + "angle": -0.2731152, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1.8, + "angle": -0.2731152, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2.4, + "angle": -0.2731152, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2.6, + "angle": -0.2731152, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3.4, + "angle": -0.5639089, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_ANKLE_ROLL": { + "name": "RIGHT_ANKLE_ROLL", + "frames": [ + { + "time": 1, + "angle": 0.06909663, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1.6, + "angle": 0.06909663, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1.8, + "angle": 0.06909663, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2.4, + "angle": 0.06909663, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2.6, + "angle": 0.06909663, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3.4, + "angle": 0.06909663, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_SHOULDER_PITCH": { + "name": "RIGHT_SHOULDER_PITCH", + "frames": [ + { + "time": 1, + "angle": 1.963495, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1.6, + "angle": 1.543178, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1.8, + "angle": 1.618361, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2.4, + "angle": 1.618361, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2.6, + "angle": 1.618361, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3.4, + "angle": 1.963495, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_SHOULDER_ROLL": { + "name": "RIGHT_SHOULDER_ROLL", + "frames": [ + { + "time": 1, + "angle": -0.1239184, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1.6, + "angle": -0.1239184, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1.8, + "angle": -0.1239184, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2.4, + "angle": -0.1239184, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2.6, + "angle": -0.1239184, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3.4, + "angle": -0.1239184, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_ELBOW": { + "name": "RIGHT_ELBOW", + "frames": [ + { + "time": 1, + "angle": -2.443461, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1.6, + "angle": -0.7269009, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1.8, + "angle": -0.5642592, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2.4, + "angle": -0.5642592, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2.6, + "angle": -0.5642592, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3.4, + "angle": -2.443461, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_SHOULDER_PITCH": { + "name": "LEFT_SHOULDER_PITCH", + "frames": [ + { + "time": 1, + "angle": 1.963495, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1.6, + "angle": -0.06942958, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1.8, + "angle": 0.3417777, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2.4, + "angle": 0.3417777, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2.6, + "angle": 0.200617, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3.4, + "angle": 1.963495, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_SHOULDER_ROLL": { + "name": "LEFT_SHOULDER_ROLL", + "frames": [ + { + "time": 1, + "angle": 0.1239184, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1.6, + "angle": 0.9403681, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1.8, + "angle": 0.9403681, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2.4, + "angle": 0.9403681, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2.6, + "angle": 0.9403681, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3.4, + "angle": 0.1239184, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_ELBOW": { + "name": "LEFT_ELBOW", + "frames": [ + { + "time": 1, + "angle": -2.443461, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1.6, + "angle": -1.527834, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1.8, + "angle": -2.313424, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2.4, + "angle": -2.313424, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2.6, + "angle": -1.603018, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3.4, + "angle": -2.443461, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + } +} From 73c4d0fc05fc5a53e4ba0b1f52a304a3e5111aa5 Mon Sep 17 00:00:00 2001 From: Josephus Paye II Date: Wed, 23 Jan 2019 17:32:19 +1100 Subject: [PATCH 30/54] Rename Servo.name to Servo.id, to match scripts --- .../script_tuner/editor/line/view.tsx | 2 +- .../script_tuner/editor/line/view_model.ts | 4 +-- src/client/components/script_tuner/model.ts | 14 ++++---- .../script_tuner/sample-script.json | 36 +++++++++---------- 4 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/client/components/script_tuner/editor/line/view.tsx b/src/client/components/script_tuner/editor/line/view.tsx index 25597320..975273c4 100644 --- a/src/client/components/script_tuner/editor/line/view.tsx +++ b/src/client/components/script_tuner/editor/line/view.tsx @@ -50,7 +50,7 @@ export class LineEditor extends Component { className={style.lineEditorTitle} x={4} y={16} - >{ viewModel.servoName } + >{ viewModel.servoId } { /* Horizontal grid lines */ } diff --git a/src/client/components/script_tuner/editor/line/view_model.ts b/src/client/components/script_tuner/editor/line/view_model.ts index 8f159dcd..05813837 100644 --- a/src/client/components/script_tuner/editor/line/view_model.ts +++ b/src/client/components/script_tuner/editor/line/view_model.ts @@ -29,8 +29,8 @@ export class LineEditorViewModel { }) @computed - get servoName() { - return this.servo.name + get servoId() { + return this.servo.id } @computed diff --git a/src/client/components/script_tuner/model.ts b/src/client/components/script_tuner/model.ts index 697e9b78..b1aa8cab 100644 --- a/src/client/components/script_tuner/model.ts +++ b/src/client/components/script_tuner/model.ts @@ -6,7 +6,7 @@ import { AppModel } from '../app/model' import { RobotModel } from '../robot/model' export interface Servo { - name: string + id: string frames: Frame[] } @@ -102,16 +102,16 @@ export class ScriptTunerModel { 'LEFT_ANKLE_ROLL', 'HEAD_YAW', 'HEAD_PITCH', - ].map(name => { - if (sampleScript[name]) { - return sampleScript[name] + ].map(id => { + if (sampleScript[id]) { + return sampleScript[id] } - return this.makeSampleServo(name, 5, 0) + return this.makeSampleServo(id, 5, 0) }) } - private makeSampleServo(name: string, length: number = 30, angle?: number): Servo { + private makeSampleServo(id: string, length: number = 30, angle?: number): Servo { const frames = [] const period = 10 @@ -128,6 +128,6 @@ export class ScriptTunerModel { }) } - return { name, frames } + return { id, frames } } } diff --git a/src/client/components/script_tuner/sample-script.json b/src/client/components/script_tuner/sample-script.json index 323604bb..1385d59b 100644 --- a/src/client/components/script_tuner/sample-script.json +++ b/src/client/components/script_tuner/sample-script.json @@ -1,6 +1,6 @@ { "LEFT_HIP_YAW": { - "name": "LEFT_HIP_YAW", + "id": "LEFT_HIP_YAW", "frames": [ { "time": 1, @@ -53,7 +53,7 @@ ] }, "LEFT_HIP_ROLL": { - "name": "LEFT_HIP_ROLL", + "id": "LEFT_HIP_ROLL", "frames": [ { "time": 1, @@ -106,7 +106,7 @@ ] }, "LEFT_HIP_PITCH": { - "name": "LEFT_HIP_PITCH", + "id": "LEFT_HIP_PITCH", "frames": [ { "time": 1, @@ -159,7 +159,7 @@ ] }, "LEFT_KNEE": { - "name": "LEFT_KNEE", + "id": "LEFT_KNEE", "frames": [ { "time": 1, @@ -212,7 +212,7 @@ ] }, "LEFT_ANKLE_PITCH": { - "name": "LEFT_ANKLE_PITCH", + "id": "LEFT_ANKLE_PITCH", "frames": [ { "time": 1, @@ -265,7 +265,7 @@ ] }, "LEFT_ANKLE_ROLL": { - "name": "LEFT_ANKLE_ROLL", + "id": "LEFT_ANKLE_ROLL", "frames": [ { "time": 1, @@ -318,7 +318,7 @@ ] }, "RIGHT_HIP_YAW": { - "name": "RIGHT_HIP_YAW", + "id": "RIGHT_HIP_YAW", "frames": [ { "time": 1, @@ -371,7 +371,7 @@ ] }, "RIGHT_HIP_ROLL": { - "name": "RIGHT_HIP_ROLL", + "id": "RIGHT_HIP_ROLL", "frames": [ { "time": 1, @@ -424,7 +424,7 @@ ] }, "RIGHT_HIP_PITCH": { - "name": "RIGHT_HIP_PITCH", + "id": "RIGHT_HIP_PITCH", "frames": [ { "time": 1, @@ -477,7 +477,7 @@ ] }, "RIGHT_KNEE": { - "name": "RIGHT_KNEE", + "id": "RIGHT_KNEE", "frames": [ { "time": 1, @@ -530,7 +530,7 @@ ] }, "RIGHT_ANKLE_PITCH": { - "name": "RIGHT_ANKLE_PITCH", + "id": "RIGHT_ANKLE_PITCH", "frames": [ { "time": 1, @@ -583,7 +583,7 @@ ] }, "RIGHT_ANKLE_ROLL": { - "name": "RIGHT_ANKLE_ROLL", + "id": "RIGHT_ANKLE_ROLL", "frames": [ { "time": 1, @@ -636,7 +636,7 @@ ] }, "RIGHT_SHOULDER_PITCH": { - "name": "RIGHT_SHOULDER_PITCH", + "id": "RIGHT_SHOULDER_PITCH", "frames": [ { "time": 1, @@ -689,7 +689,7 @@ ] }, "RIGHT_SHOULDER_ROLL": { - "name": "RIGHT_SHOULDER_ROLL", + "id": "RIGHT_SHOULDER_ROLL", "frames": [ { "time": 1, @@ -742,7 +742,7 @@ ] }, "RIGHT_ELBOW": { - "name": "RIGHT_ELBOW", + "id": "RIGHT_ELBOW", "frames": [ { "time": 1, @@ -795,7 +795,7 @@ ] }, "LEFT_SHOULDER_PITCH": { - "name": "LEFT_SHOULDER_PITCH", + "id": "LEFT_SHOULDER_PITCH", "frames": [ { "time": 1, @@ -848,7 +848,7 @@ ] }, "LEFT_SHOULDER_ROLL": { - "name": "LEFT_SHOULDER_ROLL", + "id": "LEFT_SHOULDER_ROLL", "frames": [ { "time": 1, @@ -901,7 +901,7 @@ ] }, "LEFT_ELBOW": { - "name": "LEFT_ELBOW", + "id": "LEFT_ELBOW", "frames": [ { "time": 1, From 3141ceebfa272d0675a916cb5815d51c8dd1e53b Mon Sep 17 00:00:00 2001 From: Josephus Paye II Date: Wed, 23 Jan 2019 17:48:25 +1100 Subject: [PATCH 31/54] Fix build --- src/client/components/script_tuner/model.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/components/script_tuner/model.ts b/src/client/components/script_tuner/model.ts index b1aa8cab..bd7d8c2d 100644 --- a/src/client/components/script_tuner/model.ts +++ b/src/client/components/script_tuner/model.ts @@ -19,7 +19,7 @@ export interface Frame { torque: number, } -import * as sampleScriptJson from './script_converter/converted.json' +import * as sampleScriptJson from './sample-script.json' const sampleScript = sampleScriptJson as { [key: string]: Servo } From 510405d180bf7d5ad2897d74857f1a20be31060a Mon Sep 17 00:00:00 2001 From: Josephus Paye II Date: Thu, 31 Jan 2019 14:20:33 +1100 Subject: [PATCH 32/54] Add script proto files --- .../proto/message/motion/script/Script.proto | 40 +++++++++++++++++++ .../script_tuner/LoadScriptsCommand.proto | 24 +++++++++++ .../script_tuner/SaveScriptCommand.proto | 29 ++++++++++++++ .../message/tools/script_tuner/Scripts.proto | 28 +++++++++++++ 4 files changed, 121 insertions(+) create mode 100644 src/shared/proto/message/motion/script/Script.proto create mode 100644 src/shared/proto/message/tools/script_tuner/LoadScriptsCommand.proto create mode 100644 src/shared/proto/message/tools/script_tuner/SaveScriptCommand.proto create mode 100644 src/shared/proto/message/tools/script_tuner/Scripts.proto diff --git a/src/shared/proto/message/motion/script/Script.proto b/src/shared/proto/message/motion/script/Script.proto new file mode 100644 index 00000000..744b5940 --- /dev/null +++ b/src/shared/proto/message/motion/script/Script.proto @@ -0,0 +1,40 @@ +/* + * This file is part of the NUbots Codebase. + * + * The NUbots Codebase is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The NUbots Codebase is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the NUbots Codebase. If not, see . + * + * Copyright 2013 NUbots + */ +syntax = "proto3"; + +package message.motion.script; + +message Script { + message Frame { + double time = 1; + double angle = 2; + int pGain = 3; + int iGain = 4; + int dGain = 5; + int torque = 6; + } + + message Servo { + string id = 1; + repeated Frame frames = 2; + } + + string path = 1; + Map servos = 2; +} diff --git a/src/shared/proto/message/tools/script_tuner/LoadScriptsCommand.proto b/src/shared/proto/message/tools/script_tuner/LoadScriptsCommand.proto new file mode 100644 index 00000000..0381a5f3 --- /dev/null +++ b/src/shared/proto/message/tools/script_tuner/LoadScriptsCommand.proto @@ -0,0 +1,24 @@ +/* + * This file is part of the NUbots Codebase. + * + * The NUbots Codebase is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The NUbots Codebase is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the NUbots Codebase. If not, see . + * + * Copyright 2013 NUbots + */ + +syntax = "proto3"; + +package message.tools.script_tuner; + +message LoadScriptsCommand {} diff --git a/src/shared/proto/message/tools/script_tuner/SaveScriptCommand.proto b/src/shared/proto/message/tools/script_tuner/SaveScriptCommand.proto new file mode 100644 index 00000000..a30b4289 --- /dev/null +++ b/src/shared/proto/message/tools/script_tuner/SaveScriptCommand.proto @@ -0,0 +1,29 @@ +/* + * This file is part of the NUbots Codebase. + * + * The NUbots Codebase is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The NUbots Codebase is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the NUbots Codebase. If not, see . + * + * Copyright 2013 NUbots + */ + +syntax = "proto3"; + +package message.tools.script_tuner; + +import "message/motion/script/Script.proto"; + +message SaveScriptCommand { + string path = 1; + Script script = 2; +} diff --git a/src/shared/proto/message/tools/script_tuner/Scripts.proto b/src/shared/proto/message/tools/script_tuner/Scripts.proto new file mode 100644 index 00000000..e948c6f1 --- /dev/null +++ b/src/shared/proto/message/tools/script_tuner/Scripts.proto @@ -0,0 +1,28 @@ +/* + * This file is part of the NUbots Codebase. + * + * The NUbots Codebase is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The NUbots Codebase is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the NUbots Codebase. If not, see . + * + * Copyright 2013 NUbots + */ + +syntax = "proto3"; + +package message.tools.script_tuner; + +import "message/motion/script/Script.proto"; + +message Scripts { + repeated Script scripts = 1; +} From c2d5d6bc0c9bdf43e700ede64909cae651a6689b Mon Sep 17 00:00:00 2001 From: Josephus Paye II Date: Thu, 31 Jan 2019 14:24:11 +1100 Subject: [PATCH 33/54] Fix Script.proto --- src/shared/proto/message/motion/script/Script.proto | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/shared/proto/message/motion/script/Script.proto b/src/shared/proto/message/motion/script/Script.proto index 744b5940..f77a6e61 100644 --- a/src/shared/proto/message/motion/script/Script.proto +++ b/src/shared/proto/message/motion/script/Script.proto @@ -24,10 +24,10 @@ message Script { message Frame { double time = 1; double angle = 2; - int pGain = 3; - int iGain = 4; - int dGain = 5; - int torque = 6; + int32 pGain = 3; + int32 iGain = 4; + int32 dGain = 5; + int32 torque = 6; } message Servo { @@ -36,5 +36,5 @@ message Script { } string path = 1; - Map servos = 2; + map servos = 2; } From f144364e83ef48d8ff5ead7e9f380a6d0bfbfaf7 Mon Sep 17 00:00:00 2001 From: Josephus Paye II Date: Thu, 31 Jan 2019 14:32:33 +1100 Subject: [PATCH 34/54] Rename Viewer to Preview --- .../script_tuner/{viewer => preview}/style.css | 14 +++++++------- .../script_tuner/{viewer => preview}/view.tsx | 16 ++++++++-------- .../{viewer => preview}/view_model.ts | 0 src/client/components/script_tuner/view.tsx | 4 ++-- 4 files changed, 17 insertions(+), 17 deletions(-) rename src/client/components/script_tuner/{viewer => preview}/style.css (82%) rename src/client/components/script_tuner/{viewer => preview}/view.tsx (66%) rename src/client/components/script_tuner/{viewer => preview}/view_model.ts (100%) diff --git a/src/client/components/script_tuner/viewer/style.css b/src/client/components/script_tuner/preview/style.css similarity index 82% rename from src/client/components/script_tuner/viewer/style.css rename to src/client/components/script_tuner/preview/style.css index 9f294e69..72c517b8 100644 --- a/src/client/components/script_tuner/viewer/style.css +++ b/src/client/components/script_tuner/preview/style.css @@ -1,4 +1,4 @@ -.viewer { +.preview { display: flex; flex-direction: column; max-height: 100%; @@ -6,7 +6,7 @@ border-right: 1px solid #777; } -.viewerHeader { +.previewHeader { background-color: #777; padding: 0 4px; color: white; @@ -16,14 +16,14 @@ align-items: center; } -.viewerBody { +.previewBody { padding: 0 4px; flex-grow: 1; overflow: hidden; position: relative; } -.viewerHud { +.previewHud { position: absolute; bottom: 16px; width: 100%; @@ -32,7 +32,7 @@ justify-content: center; } -.viewerHudItems span { +.previewHudItems span { background-color: rgba(0,0,0,0.6); color: white; display: inline-block; @@ -40,12 +40,12 @@ padding: 4px 12px; } -.viewerHudItems span:first-child { +.previewHudItems span:first-child { border-top-left-radius: 4px; border-bottom-left-radius: 4px; } -.viewerHudItems span:last-child { +.previewHudItems span:last-child { border-top-right-radius: 4px; border-bottom-right-radius: 4px; margin-right: 0; diff --git a/src/client/components/script_tuner/viewer/view.tsx b/src/client/components/script_tuner/preview/view.tsx similarity index 66% rename from src/client/components/script_tuner/viewer/view.tsx rename to src/client/components/script_tuner/preview/view.tsx index dba161fc..25812523 100644 --- a/src/client/components/script_tuner/viewer/view.tsx +++ b/src/client/components/script_tuner/preview/view.tsx @@ -8,26 +8,26 @@ import { ModelVisualiser } from '../model_visualiser/view' import * as style from './style.css' import { ScriptRobot3dViewModel } from './view_model' -type ViewerProps = { +type PreviewProps = { className?: string model: ScriptTunerModel } @observer -export class Viewer extends React.Component { +export class Preview extends React.Component { render() { const { model, className } = this.props const viewModel = ScriptRobot3dViewModel.of(model) - return
-
-
Viewer
+ return
+
+
Preview
-
+
-
-
+
+
{ model.isPlaying ? 'Playing' : 'Paused' } Time: {(Math.round(model.playTime * 1000) / 1000).toFixed(3)}
diff --git a/src/client/components/script_tuner/viewer/view_model.ts b/src/client/components/script_tuner/preview/view_model.ts similarity index 100% rename from src/client/components/script_tuner/viewer/view_model.ts rename to src/client/components/script_tuner/preview/view_model.ts diff --git a/src/client/components/script_tuner/view.tsx b/src/client/components/script_tuner/view.tsx index bcd35c1e..98408b85 100644 --- a/src/client/components/script_tuner/view.tsx +++ b/src/client/components/script_tuner/view.tsx @@ -9,7 +9,7 @@ import { Editor } from './editor/view' import { ScriptTunerModel } from './model' import { ScriptTunerNetwork } from './network' import * as style from './style.css' -import { Viewer } from './viewer/view' +import { Preview } from './preview/view' export type ScriptTunerProps = { controller: ScriptTunerController @@ -21,7 +21,7 @@ export type ScriptTunerProps = { export const ScriptTuner = observer(({ controller, menu, model, network }: ScriptTunerProps) => { return (
- + From 56ab6056adc56981960dfd997feef9c9bb7a6412 Mon Sep 17 00:00:00 2001 From: Josephus Paye II Date: Thu, 31 Jan 2019 15:08:53 +1100 Subject: [PATCH 35/54] Add scripts explorer to layout --- .../components/script_tuner/balance/style.css | 23 +++++++++++++++++++ .../components/script_tuner/balance/view.tsx | 18 ++++++++++++--- .../script_tuner/controls/style.css | 23 +++++++++++++++++++ .../components/script_tuner/controls/view.tsx | 18 ++++++++++++--- .../script_tuner/explorer/style.css | 23 +++++++++++++++++++ .../components/script_tuner/explorer/view.tsx | 22 ++++++++++++++++++ .../components/script_tuner/preview/style.css | 2 -- src/client/components/script_tuner/style.css | 23 ++++++++++++++----- src/client/components/script_tuner/view.tsx | 10 +++++--- 9 files changed, 145 insertions(+), 17 deletions(-) create mode 100644 src/client/components/script_tuner/balance/style.css create mode 100644 src/client/components/script_tuner/controls/style.css create mode 100644 src/client/components/script_tuner/explorer/style.css create mode 100644 src/client/components/script_tuner/explorer/view.tsx diff --git a/src/client/components/script_tuner/balance/style.css b/src/client/components/script_tuner/balance/style.css new file mode 100644 index 00000000..29327f38 --- /dev/null +++ b/src/client/components/script_tuner/balance/style.css @@ -0,0 +1,23 @@ +.balance { + display: flex; + flex-direction: column; + max-height: 100%; + overflow: hidden; +} + +.balanceHeader { + background-color: #777; + padding: 0 4px; + color: white; + font-size: 14px; + display: flex; + min-height: 24px; + align-items: center; +} + +.balanceBody { + padding: 0 4px; + flex-grow: 1; + overflow: hidden; + position: relative; +} diff --git a/src/client/components/script_tuner/balance/view.tsx b/src/client/components/script_tuner/balance/view.tsx index 5dcd2c26..5c59b828 100644 --- a/src/client/components/script_tuner/balance/view.tsx +++ b/src/client/components/script_tuner/balance/view.tsx @@ -1,10 +1,22 @@ +import * as classNames from 'classnames' import { observer } from 'mobx-react' import * as React from 'react' +import * as style from './style.css' + type BalanceProps = { className?: string } -export const Balance = observer(({ className }: BalanceProps) => { - return
Balance
-}) +@observer +export class Balance extends React.Component { + render() { + return
+
+
Balance
+
+ +
+
+ } +} diff --git a/src/client/components/script_tuner/controls/style.css b/src/client/components/script_tuner/controls/style.css new file mode 100644 index 00000000..63f3b7ae --- /dev/null +++ b/src/client/components/script_tuner/controls/style.css @@ -0,0 +1,23 @@ +.controls { + display: flex; + flex-direction: column; + max-height: 100%; + overflow: hidden; +} + +.controlsHeader { + background-color: #777; + padding: 0 4px; + color: white; + font-size: 14px; + display: flex; + min-height: 24px; + align-items: center; +} + +.controlsBody { + padding: 0 4px; + flex-grow: 1; + overflow: hidden; + position: relative; +} diff --git a/src/client/components/script_tuner/controls/view.tsx b/src/client/components/script_tuner/controls/view.tsx index 396ca360..3d83cc9d 100644 --- a/src/client/components/script_tuner/controls/view.tsx +++ b/src/client/components/script_tuner/controls/view.tsx @@ -1,10 +1,22 @@ +import * as classNames from 'classnames' import { observer } from 'mobx-react' import * as React from 'react' +import * as style from './style.css' + type ControlsProps = { className?: string } -export const Controls = observer(({ className }: ControlsProps) => { - return
Controls
-}) +@observer +export class Controls extends React.Component { + render() { + return
+
+
Controls
+
+ +
+
+ } +} diff --git a/src/client/components/script_tuner/explorer/style.css b/src/client/components/script_tuner/explorer/style.css new file mode 100644 index 00000000..f5754b3d --- /dev/null +++ b/src/client/components/script_tuner/explorer/style.css @@ -0,0 +1,23 @@ +.explorer { + display: flex; + flex-direction: column; + max-height: 100%; + overflow: hidden; +} + +.explorerHeader { + background-color: #777; + padding: 0 4px; + color: white; + font-size: 14px; + display: flex; + min-height: 24px; + align-items: center; +} + +.explorerBody { + padding: 0 4px; + flex-grow: 1; + overflow: hidden; + position: relative; +} diff --git a/src/client/components/script_tuner/explorer/view.tsx b/src/client/components/script_tuner/explorer/view.tsx new file mode 100644 index 00000000..655f4a29 --- /dev/null +++ b/src/client/components/script_tuner/explorer/view.tsx @@ -0,0 +1,22 @@ +import * as classNames from 'classnames' +import { observer } from 'mobx-react' +import * as React from 'react' + +import * as style from './style.css' + +type ExplorerProps = { + className?: string +} + +@observer +export class Explorer extends React.Component { + render() { + return
+
+
Scripts
+
+ +
+
+ } +} diff --git a/src/client/components/script_tuner/preview/style.css b/src/client/components/script_tuner/preview/style.css index 72c517b8..e90ab96c 100644 --- a/src/client/components/script_tuner/preview/style.css +++ b/src/client/components/script_tuner/preview/style.css @@ -3,7 +3,6 @@ flex-direction: column; max-height: 100%; overflow: hidden; - border-right: 1px solid #777; } .previewHeader { @@ -17,7 +16,6 @@ } .previewBody { - padding: 0 4px; flex-grow: 1; overflow: hidden; position: relative; diff --git a/src/client/components/script_tuner/style.css b/src/client/components/script_tuner/style.css index b23ffc71..2f618934 100644 --- a/src/client/components/script_tuner/style.css +++ b/src/client/components/script_tuner/style.css @@ -1,16 +1,30 @@ .container { display: grid; - grid-template-columns: 50% 30% 20%; + grid-template-columns: 25% 50% 25%; grid-template-rows: 50% 50%; width: 100%; height: 100vh; } -.viewer { +.explorer { + border-left: 1px solid #444; + border-right: 1px solid #444; +} + +.preview { + border-right: 1px solid #444; +} +.balanceAndControls { + display: grid; + grid-template-rows: 50% 50%; } .balance { + border-bottom: 1px solid #444; +} + +.controls { } @@ -18,8 +32,5 @@ grid-column-start: 1; grid-column-end: span 3; max-height: 100%; -} - -.controls { - + border-top: 1px solid #444; } diff --git a/src/client/components/script_tuner/view.tsx b/src/client/components/script_tuner/view.tsx index 98408b85..9d01626e 100644 --- a/src/client/components/script_tuner/view.tsx +++ b/src/client/components/script_tuner/view.tsx @@ -6,6 +6,7 @@ import { Balance } from './balance/view' import { ScriptTunerController } from './controller' import { Controls } from './controls/view' import { Editor } from './editor/view' +import { Explorer } from './explorer/view' import { ScriptTunerModel } from './model' import { ScriptTunerNetwork } from './network' import * as style from './style.css' @@ -21,9 +22,12 @@ export type ScriptTunerProps = { export const ScriptTuner = observer(({ controller, menu, model, network }: ScriptTunerProps) => { return (
- - - + + +
+ + +
) From 284d71547146ae2c273637238626c3ebb5440ec8 Mon Sep 17 00:00:00 2001 From: Josephus Paye II Date: Mon, 4 Feb 2019 16:33:51 +1100 Subject: [PATCH 36/54] Fix lint --- src/client/components/script_tuner/view.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/components/script_tuner/view.tsx b/src/client/components/script_tuner/view.tsx index 9d01626e..9e8f7837 100644 --- a/src/client/components/script_tuner/view.tsx +++ b/src/client/components/script_tuner/view.tsx @@ -9,8 +9,8 @@ import { Editor } from './editor/view' import { Explorer } from './explorer/view' import { ScriptTunerModel } from './model' import { ScriptTunerNetwork } from './network' -import * as style from './style.css' import { Preview } from './preview/view' +import * as style from './style.css' export type ScriptTunerProps = { controller: ScriptTunerController From 23d818d7da3dac23f44726323b983c705b4ecf87 Mon Sep 17 00:00:00 2001 From: Josephus Paye II Date: Mon, 4 Feb 2019 16:46:16 +1100 Subject: [PATCH 37/54] Add robot selector --- package.json | 2 + src/client/components/dropdown/view.tsx | 5 +- .../explorer/robot_selector/plug.svg | 3 + .../explorer/robot_selector/robot.svg | 3 + .../stories/robot_selector.stories.tsx | 70 ++++++++++ .../explorer/robot_selector/style.css | 30 +++++ .../explorer/robot_selector/view.tsx | 47 +++++++ .../explorer/robot_selector/view_model.ts | 45 +++++++ src/client/components/select/dropdown.svg | 1 + src/client/components/select/stories/icon.svg | 1 + .../select/stories/select.stories.tsx | 81 ++++++++++++ src/client/components/select/style.css | 73 ++++++++++ src/client/components/select/view.tsx | 125 ++++++++++++++++++ yarn.lock | 71 ++++++++++ 14 files changed, 555 insertions(+), 2 deletions(-) create mode 100644 src/client/components/script_tuner/explorer/robot_selector/plug.svg create mode 100644 src/client/components/script_tuner/explorer/robot_selector/robot.svg create mode 100644 src/client/components/script_tuner/explorer/robot_selector/stories/robot_selector.stories.tsx create mode 100644 src/client/components/script_tuner/explorer/robot_selector/style.css create mode 100644 src/client/components/script_tuner/explorer/robot_selector/view.tsx create mode 100644 src/client/components/script_tuner/explorer/robot_selector/view_model.ts create mode 100644 src/client/components/select/dropdown.svg create mode 100644 src/client/components/select/stories/icon.svg create mode 100644 src/client/components/select/stories/select.stories.tsx create mode 100644 src/client/components/select/style.css create mode 100644 src/client/components/select/view.tsx diff --git a/package.json b/package.json index eac4d356..69c5a2af 100644 --- a/package.json +++ b/package.json @@ -62,6 +62,7 @@ "@types/react-color": "^2.14.0", "@types/react-dom": "^16.0.11", "@types/react-hot-loader": "^4.1.0", + "@types/react-outside-click-handler": "^1.2.0", "@types/react-router": "^4.4.3", "@types/react-router-dom": "^4.3.1", "@types/seedrandom": "^2.4.27", @@ -133,6 +134,7 @@ "react": "^16.7.0", "react-color": "^2.17.0", "react-dom": "^16.7.0", + "react-outside-click-handler": "^1.2.2", "react-resize-detector": "^3.2.1", "react-router": "^4.3.1", "react-router-dom": "^4.3.1", diff --git a/src/client/components/dropdown/view.tsx b/src/client/components/dropdown/view.tsx index 44ccda59..7d983cd1 100644 --- a/src/client/components/dropdown/view.tsx +++ b/src/client/components/dropdown/view.tsx @@ -8,17 +8,18 @@ import * as style from './style.css' export interface DropdownProps { children: ReactNode + className?: string dropdownMenuClassName?: string dropdownToggle: ReactNode isOpen: boolean - onRef(dropdown: HTMLDivElement): void + onRef?(dropdown: HTMLDivElement): void onToggleClick?(event: MouseEvent): void } export const Dropdown: StatelessComponent = (props: DropdownProps) => { const dropdownMenuClassName = classNames(style.dropdownMenu, props.dropdownMenuClassName) return ( -
+
{props.dropdownToggle} diff --git a/src/client/components/script_tuner/explorer/robot_selector/plug.svg b/src/client/components/script_tuner/explorer/robot_selector/plug.svg new file mode 100644 index 00000000..bd776331 --- /dev/null +++ b/src/client/components/script_tuner/explorer/robot_selector/plug.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/client/components/script_tuner/explorer/robot_selector/robot.svg b/src/client/components/script_tuner/explorer/robot_selector/robot.svg new file mode 100644 index 00000000..353fb737 --- /dev/null +++ b/src/client/components/script_tuner/explorer/robot_selector/robot.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/client/components/script_tuner/explorer/robot_selector/stories/robot_selector.stories.tsx b/src/client/components/script_tuner/explorer/robot_selector/stories/robot_selector.stories.tsx new file mode 100644 index 00000000..e0d9ad78 --- /dev/null +++ b/src/client/components/script_tuner/explorer/robot_selector/stories/robot_selector.stories.tsx @@ -0,0 +1,70 @@ +import { action } from '@storybook/addon-actions' +import { storiesOf } from '@storybook/react' +import * as React from 'react' + +import { RobotSelector } from '../view' + +const actions = { + onSelect: action('onSelect'), +} + +const container = { maxWidth: '320px', fontFamily: 'Arial, sans-serif' } + +storiesOf('components.robot_selector', module) + .add('renders empty', () => { + return
+ +
+ }) + .add('renders with robots', () => { + const robots = getRobots() + return
+ +
+ }) + .add('renders with selection', () => { + const robots = getRobots() + const selected = robots[0] + return
+ +
+ }) + +function getRobots() { + return [ + { + id: '1', + name: 'Virtual Robot 1', + connected: true, + enabled: true, + address: '', + port: 0, + }, + { + id: '2', + name: 'Virtual Robot 2', + connected: true, + enabled: true, + address: '', + port: 0, + }, + { + id: '3', + name: 'Virtual Robot 3', + connected: true, + enabled: true, + address: '', + port: 0, + }, + ] +} diff --git a/src/client/components/script_tuner/explorer/robot_selector/style.css b/src/client/components/script_tuner/explorer/robot_selector/style.css new file mode 100644 index 00000000..dad46384 --- /dev/null +++ b/src/client/components/script_tuner/explorer/robot_selector/style.css @@ -0,0 +1,30 @@ +.empty { + color: #888; + padding: 1em; + text-align: center; +} + +.emptyIcon { + background-color: #888; + border-radius: 100%; + box-shadow: + 0 0 8px 0 rgba(0, 0, 0, 0.2), + 1px 1px 4px 0 rgba(0,0,0,0.2); + fill: #fff; + height: 3em; + margin: 0 auto 1em auto; + opacity: 0.8; + padding: 1em; + width: 3em; +} + +.emptyTitle { + font-size: 1.54em; + padding: 0.25em 0; + white-space: nowrap; +} + +.emptyDescription { + font-size: 0.93em; + white-space: nowrap; +} diff --git a/src/client/components/script_tuner/explorer/robot_selector/view.tsx b/src/client/components/script_tuner/explorer/robot_selector/view.tsx new file mode 100644 index 00000000..7a4e4f6c --- /dev/null +++ b/src/client/components/script_tuner/explorer/robot_selector/view.tsx @@ -0,0 +1,47 @@ +import * as classNames from 'classnames' +import { observer } from 'mobx-react' +import * as React from 'react' + +import { RobotModel } from '../../../robot/model' +import { Select, SelectOption } from '../../../select/view' + +import PlugIcon from './plug.svg' +import RobotIcon from './robot.svg' +import * as style from './style.css' +import { RobotSelectorViewModel } from './view_model' + +export type RobotSelectorProps = { + className?: string + robots: RobotModel[] + selected?: RobotModel + onSelect(robot: RobotModel): void +} + +export const RobotSelector = observer((props: RobotSelectorProps) => { + const { className, robots, selected, onSelect } = props + const viewModel = RobotSelectorViewModel.of({ + robots, + selected, + }) + + const empty = ( +
+
+
No connected robots
+ Run yarn start:sim to simulate robots +
+ ) + + return ( +
+ +
+ }) + .add('renders empty', () => { + const empty = ( +
+

No options

+

Add options to see them here

+
+ ) + return
+ +
+ }) + .add('renders with selection', () => { + const options = getOptions() + const selected = options[1] + return
+ } + /> +
+ }) + +function getOptions() { + return [ + { id: 'red', label: 'Red' }, + { id: 'green', label: 'Green' }, + { id: 'blue', label: 'Blue' }, + ] +} diff --git a/src/client/components/select/style.css b/src/client/components/select/style.css new file mode 100644 index 00000000..d48e9d33 --- /dev/null +++ b/src/client/components/select/style.css @@ -0,0 +1,73 @@ +.button { + background-color: transparent; + border: none; + cursor: pointer; + display: flex; + height: 32px; + background-color: #eee; + border: 1px solid #CCC; + padding: 0 8px; + align-items: center; + font-family: inherit; + border-radius: 4px; + line-height: 1; + width: 100%; + outline: none; +} + +.button:hover { + border: 1px solid #1197d3; +} + +.buttonIcon svg { + fill: #1197d3; + height: 18px; + width: 18px; + margin-right: 12px; +} + +.dropdownIcon { + fill: #777; + margin-left: auto; + width: 20px; + height: 20px; +} + +.empty { + color: #888; + padding: 1.5em; + text-align: center; +} + +.dropdown { + background-color: white; + border-bottom-left-radius: 2px; + border-bottom-right-radius: 2px; + box-shadow: + 0px 0px 3px 0px rgba(0, 0, 0, 0.15), + 0px 3px 8px 0px rgba(0, 0, 0, 0.15); + overflow: hidden; + width: 100%; + padding-top: 4px; + padding-bottom: 4px; +} + +.option { + align-items: center; + display: flex; + justify-content: space-between; + font-size: 13px; + padding: 8px; + font-weight: normal; +} + +.option:hover { + background-color: #eee; + cursor: pointer; +} + +.optionSelected, +.optionSelected:hover { + background: #1197d3; + color: white; +} diff --git a/src/client/components/select/view.tsx b/src/client/components/select/view.tsx new file mode 100644 index 00000000..c3f44ceb --- /dev/null +++ b/src/client/components/select/view.tsx @@ -0,0 +1,125 @@ +import * as classNames from 'classnames' +import { action } from 'mobx' +import { observable } from 'mobx' +import { observer } from 'mobx-react' +import * as React from 'react' +import { ReactNode } from 'react' +import OutsideClickHandler from 'react-outside-click-handler' + +import { Dropdown } from '../dropdown/view' + +import DropdownIcon from './dropdown.svg' +import * as style from './style.css' + +export interface SelectOption { + id: string | number + label: string +} + +export type SelectProps = { + className?: string + dropdownMenuClassName?: string + placeholder: string + options: SelectOption[] + selectedOption?: SelectOption + icon?: ReactNode + empty?: ReactNode + onChange(option: SelectOption): void +} + +enum KeyCode { + Escape = 27, +} + +@observer +export class Select extends React.Component { + @observable + private isOpen: boolean = false + private removeListeners?: () => void + + componentDidMount() { + const onKeydown = (event: KeyboardEvent) => this.onDocumentKeydown(event) + document.addEventListener('keydown', onKeydown) + + this.removeListeners = () => { + document.removeEventListener('keydown', onKeydown) + } + } + + componentWillUnmount() { + if (this.removeListeners) { + this.removeListeners() + } + } + + render(): JSX.Element { + const { className, dropdownMenuClassName, icon, placeholder, empty, options, selectedOption } = this.props + + const button = ( + + ) + + return ( + this.close()}> + + { options.length === 0 &&
{ empty || 'No options' }
} + { options.length > 0 &&
{ + options.map(option => { + const optionClassName = selectedOption && selectedOption.id === option.id ? style.optionSelected : '' + return
this.onSelect(option)} + >{ option.label }
+ }) + }
+ } +
+
+ ) + } + + private onToggleClick = () => { + this.toggle() + } + + private onSelect = (option: SelectOption) => { + this.props.onChange && this.props.onChange(option) + this.close() + } + + private onDocumentKeydown(event: KeyboardEvent) { + if (this.isOpen && event.keyCode === KeyCode.Escape) { + this.close() + } + } + + @action + private open() { + if (!this.isOpen) { + this.isOpen = true + } + } + + @action + private close() { + if (this.isOpen) { + this.isOpen = false + } + } + + @action + private toggle() { + this.isOpen = !this.isOpen + } +} diff --git a/yarn.lock b/yarn.lock index 715cdbd9..82509ad2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1706,6 +1706,13 @@ "@types/node" "*" "@types/react" "*" +"@types/react-outside-click-handler@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@types/react-outside-click-handler/-/react-outside-click-handler-1.2.0.tgz#a7c5d7b39affb7a80c45029931efa031f1130820" + integrity sha512-yejuPUAzmlMmFuPGPYY1nxKj9NI7nn8qaCsyK1hte+Qy488+1d49+tVXDOP/N4mHFN+UjNt8HXQpIyVpRDI/YQ== + dependencies: + "@types/react" "*" + "@types/react-router-dom@^4.3.1": version "4.3.1" resolved "https://registry.yarnpkg.com/@types/react-router-dom/-/react-router-dom-4.3.1.tgz#71fe2918f8f60474a891520def40a63997dafe04" @@ -2117,6 +2124,21 @@ after@0.8.2: string.prototype.padstart "^3.0.0" symbol.prototype.description "^1.0.0" +airbnb-prop-types@^2.10.0: + version "2.11.0" + resolved "https://registry.yarnpkg.com/airbnb-prop-types/-/airbnb-prop-types-2.11.0.tgz#2f4169a17ef86e227924d61f2b77defead1aa5be" + integrity sha512-Y46/0gNVDy5gpedxIaoKjigdes+TouqVg7GTYQr73PBfE/lTSvOR/WIgUib0Zonm3Hyvlcax0mHr+v4K8DfGGw== + dependencies: + array.prototype.find "^2.0.4" + function.prototype.name "^1.1.0" + has "^1.0.3" + is-regex "^1.0.4" + object-is "^1.0.1" + object.assign "^4.1.0" + object.entries "^1.0.4" + prop-types "^15.6.2" + prop-types-exact "^1.2.0" + ajv-errors@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.0.tgz#ecf021fa108fd17dfb5e6b383f2dd233e31ffc59" @@ -2361,6 +2383,14 @@ array-unique@^0.3.2: resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= +array.prototype.find@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/array.prototype.find/-/array.prototype.find-2.0.4.tgz#556a5c5362c08648323ddaeb9de9d14bc1864c90" + integrity sha1-VWpcU2LAhkgyPdrrnenRS8GGTJA= + dependencies: + define-properties "^1.1.2" + es-abstract "^1.7.0" + array.prototype.flat@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.1.tgz#812db8f02cad24d3fab65dd67eabe3b8903494a4" @@ -4137,6 +4167,11 @@ console-control-strings@^1.0.0, console-control-strings@~1.1.0: resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= +"consolidated-events@^1.1.1 || ^2.0.0": + version "2.0.2" + resolved "https://registry.yarnpkg.com/consolidated-events/-/consolidated-events-2.0.2.tgz#da8d8f8c2b232831413d9e190dc11669c79f4a91" + integrity sha512-2/uRVMdRypf5z/TW/ncD/66l75P5hH2vM/GR8Jf8HLc2xnfJtmina6F6du8+v4Z2vTrMo7jC+W1tmEEuuELgkQ== + constants-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" @@ -6268,6 +6303,13 @@ has@^1.0.1: dependencies: function-bind "^1.0.2" +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + hash-base@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-2.0.2.tgz#66ea1d856db4e8a5470cadf6fce23ae5244ef2e1" @@ -8854,6 +8896,11 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" +object-is@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.0.1.tgz#0aa60ec9989a0b3ed795cf4d06f62cf1ad6539b6" + integrity sha1-CqYOyZiaCz7Xlc9NBvYs8a1lObY= + object-keys@^1.0.11, object-keys@^1.0.12: version "1.0.12" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.12.tgz#09c53855377575310cca62f55bb334abff7b3ed2" @@ -9980,6 +10027,15 @@ prompts@^0.1.9: kleur "^2.0.1" sisteransi "^0.1.1" +prop-types-exact@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/prop-types-exact/-/prop-types-exact-1.2.0.tgz#825d6be46094663848237e3925a98c6e944e9869" + integrity sha512-K+Tk3Kd9V0odiXFP9fwDHUYRyvK3Nun3GVyPapSIs5OBkITAm15W0CPFD/YKTkMUAbc0b9CUwRQp2ybiBIq+eA== + dependencies: + has "^1.0.3" + object.assign "^4.1.0" + reflect.ownkeys "^0.2.0" + prop-types@^15.5.10: version "15.6.0" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.0.tgz#ceaf083022fc46b4a35f69e13ef75aed0d639856" @@ -10363,6 +10419,16 @@ react-modal@^3.6.1: react-lifecycles-compat "^3.0.0" warning "^3.0.0" +react-outside-click-handler@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/react-outside-click-handler/-/react-outside-click-handler-1.2.2.tgz#2c4609fbaacbfc192e269786d555419b115bf93f" + integrity sha512-MgCxmFARGN1VrZdwoLkER/y3So6mC/fSniXI4XcXcB+Jt05nw/k8a/R1hSoa7p414uZUZ8NfClN3eVmZm9bM5Q== + dependencies: + airbnb-prop-types "^2.10.0" + consolidated-events "^1.1.1 || ^2.0.0" + object.values "^1.0.4" + prop-types "^15.6.1" + react-resize-detector@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/react-resize-detector/-/react-resize-detector-3.2.1.tgz#19bb6e4ed1a6c627bb3b7e845b054215df7ca9d8" @@ -10633,6 +10699,11 @@ redux@^4.0.1: loose-envify "^1.4.0" symbol-observable "^1.2.0" +reflect.ownkeys@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/reflect.ownkeys/-/reflect.ownkeys-0.2.0.tgz#749aceec7f3fdf8b63f927a04809e90c5c0b3460" + integrity sha1-dJrO7H8/34tj+SegSAnpDFwLNGA= + regenerate-unicode-properties@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-7.0.0.tgz#107405afcc4a190ec5ed450ecaa00ed0cafa7a4c" From 888a03360e2a000b2cf21ec717c1c8e692ca7463 Mon Sep 17 00:00:00 2001 From: Josephus Paye II Date: Tue, 5 Feb 2019 17:40:38 +1100 Subject: [PATCH 38/54] Add loading icon component --- .../explorer/loading_icon/style.css | 29 +++++++++++++++++ .../explorer/loading_icon/view.tsx | 32 +++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 src/client/components/script_tuner/explorer/loading_icon/style.css create mode 100644 src/client/components/script_tuner/explorer/loading_icon/view.tsx diff --git a/src/client/components/script_tuner/explorer/loading_icon/style.css b/src/client/components/script_tuner/explorer/loading_icon/style.css new file mode 100644 index 00000000..4c7efdd0 --- /dev/null +++ b/src/client/components/script_tuner/explorer/loading_icon/style.css @@ -0,0 +1,29 @@ +.loading { + position: relative; +} + +.loading svg { + animation: loading-rotate 0.7s linear infinite; + bottom: 0; + height: 100%; + left: 0; + margin: auto; + position: absolute; + right: 0; + top: 0; + transform-origin: center center; + width: 100%; +} + +.loading circle { + stroke-dasharray: 89,200; + stroke-dashoffset: -35px; + stroke-linecap: round; + stroke: #1197d3; +} + +@keyframes loading-rotate { + 100% { + transform: rotate(360deg); + } +} diff --git a/src/client/components/script_tuner/explorer/loading_icon/view.tsx b/src/client/components/script_tuner/explorer/loading_icon/view.tsx new file mode 100644 index 00000000..a1605ece --- /dev/null +++ b/src/client/components/script_tuner/explorer/loading_icon/view.tsx @@ -0,0 +1,32 @@ +import * as classNames from 'classnames' +import { observer } from 'mobx-react' +import * as React from 'react' + +import * as style from './style.css' + +type LoadingIconProps = { + className?: string + size?: number +} + +@observer +export class LoadingIcon extends React.Component { + render() { + const { className, size = 32 } = this.props + return
+ + + +
+ } +} From 56e9683cd833fd8535d9d9f0cce043a72246d526 Mon Sep 17 00:00:00 2001 From: Josephus Paye II Date: Tue, 5 Feb 2019 17:42:06 +1100 Subject: [PATCH 39/54] Add editor blank state when no script is selected --- .../components/script_tuner/editor/style.css | 9 ++ .../components/script_tuner/editor/view.tsx | 107 ++++++++++-------- 2 files changed, 68 insertions(+), 48 deletions(-) diff --git a/src/client/components/script_tuner/editor/style.css b/src/client/components/script_tuner/editor/style.css index a6300b5a..678bb476 100644 --- a/src/client/components/script_tuner/editor/style.css +++ b/src/client/components/script_tuner/editor/style.css @@ -57,3 +57,12 @@ flex-grow: 1; overflow: auto; } + +.editorEmpty { + width: 100%; + height: 1000%; + display: flex; + align-items: center; + justify-content: center; + background-color: white; +} diff --git a/src/client/components/script_tuner/editor/view.tsx b/src/client/components/script_tuner/editor/view.tsx index 79310d3a..9dad814f 100644 --- a/src/client/components/script_tuner/editor/view.tsx +++ b/src/client/components/script_tuner/editor/view.tsx @@ -42,52 +42,59 @@ export class Editor extends React.Component { return
-
Editor
-
- - - - - -
-
- - - -
- { - model.servos.map((servo, index) => { - const controller = LineEditorController.of(servo) - return - }) +
{ model.selectedScript ? `Edit ${model.selectedScript.path}` : 'Editor' }
+ { model.selectedScript &&
+ + + + + +
}
+ + { model.selectedScript === undefined && +
Select a script to edit
+ } + + { model.selectedScript && + } + + { model.selectedScript &&
+ { + model.selectedScript.servos.map((servo, index) => { + const controller = LineEditorController.of(servo) + return + }) + } +
+ }
} @@ -95,16 +102,20 @@ export class Editor extends React.Component { const timelineElement = ReactDOM.findDOMNode(this.timelineRef.current!) as HTMLDivElement const bodyElement = this.bodyRef.current! - timelineElement.addEventListener('scroll', this.onTimelineScroll, { passive: true }) - bodyElement.addEventListener('scroll', this.onBodyScroll, { passive: true }) + if (timelineElement && bodyElement) { + timelineElement.addEventListener('scroll', this.onTimelineScroll, { passive: true }) + bodyElement.addEventListener('scroll', this.onBodyScroll, { passive: true }) + } } componentWillUnmount() { const timelineElement = ReactDOM.findDOMNode(this.timelineRef.current!) as HTMLDivElement const bodyElement = this.bodyRef.current! - timelineElement.removeEventListener('scroll', this.onTimelineScroll) - bodyElement.removeEventListener('scroll', this.onBodyScroll) + if (timelineElement && bodyElement) { + timelineElement.removeEventListener('scroll', this.onTimelineScroll) + bodyElement.removeEventListener('scroll', this.onBodyScroll) + } } onTimelineScroll = (event: UIEvent) => { From 41546d5646e2c91607c9c0243e986f6ab99ede89 Mon Sep 17 00:00:00 2001 From: Josephus Paye II Date: Tue, 5 Feb 2019 17:43:09 +1100 Subject: [PATCH 40/54] Add loading icon to explorer, move sample script data to network --- .../components/script_tuner/controller.ts | 12 +++ .../script_tuner/explorer/controller.ts | 25 +++++ .../script_tuner/explorer/style.css | 29 ++++- .../components/script_tuner/explorer/view.tsx | 43 +++++++- .../components/script_tuner/install.tsx | 2 +- src/client/components/script_tuner/model.ts | 96 ++++------------- src/client/components/script_tuner/network.ts | 98 ++++++++++++++++- .../script_tuner/preview/view_model.ts | 102 +++++++++++------- src/client/components/script_tuner/view.tsx | 2 +- 9 files changed, 286 insertions(+), 123 deletions(-) create mode 100644 src/client/components/script_tuner/explorer/controller.ts diff --git a/src/client/components/script_tuner/controller.ts b/src/client/components/script_tuner/controller.ts index 18a65fb0..fd4fc447 100644 --- a/src/client/components/script_tuner/controller.ts +++ b/src/client/components/script_tuner/controller.ts @@ -1,5 +1,7 @@ import { action, autorun, IReactionDisposer } from 'mobx' +import { RobotModel } from '../robot/model' + import { ScriptTunerModel } from './model' import { ScriptTunerNetwork } from './network' @@ -30,6 +32,16 @@ export class ScriptTunerController { return new ScriptTunerController(opts) } + @action + selectRobot(robot: RobotModel) { + const isInitialSelect = this.model.selectedRobot === undefined + this.model.selectedRobot = robot + + if (isInitialSelect) { + this.network.requestScripts(robot) + } + } + @action setPlayTime(time: number) { this.model.currentTime = Math.min(Math.max(time, this.model.startTime), this.model.endTime) diff --git a/src/client/components/script_tuner/explorer/controller.ts b/src/client/components/script_tuner/explorer/controller.ts new file mode 100644 index 00000000..9a98452d --- /dev/null +++ b/src/client/components/script_tuner/explorer/controller.ts @@ -0,0 +1,25 @@ +import { action, computed, observable } from 'mobx' +import { createTransformer } from 'mobx-utils' + +import { RobotModel } from '../../robot/model' +import { ScriptTunerController } from '../controller' + +interface ExplorerControllerOpts { + controller: ScriptTunerController +} + +export class ExplorerController { + controller: ScriptTunerController + + constructor(opts: ExplorerControllerOpts) { + this.controller = opts.controller + } + + static of = createTransformer((opts: ExplorerControllerOpts) => { + return new ExplorerController(opts) + }) + + selectRobot = (robot: RobotModel) => { + this.controller.selectRobot(robot) + } +} diff --git a/src/client/components/script_tuner/explorer/style.css b/src/client/components/script_tuner/explorer/style.css index f5754b3d..4269c7d7 100644 --- a/src/client/components/script_tuner/explorer/style.css +++ b/src/client/components/script_tuner/explorer/style.css @@ -15,9 +15,36 @@ align-items: center; } -.explorerBody { +.explorerRobotSelector { + padding: 4px; + border-bottom: 1px solid #DDD; +} + +.explorerBody, +.explorerLoading { padding: 0 4px; flex-grow: 1; overflow: hidden; position: relative; + border-bottom: 1px solid #DDD; +} + +.explorerLoading { + justify-content: center; + align-items: center; + display: flex; + flex-direction: column; +} + +.explorerLoadingIcon { + margin-top: -32px; + margin-bottom: 8px; +} + +.explorerEmpty { + width: 100%; + height: 100%; + display: flex; + align-items: center; + justify-content: center; } diff --git a/src/client/components/script_tuner/explorer/view.tsx b/src/client/components/script_tuner/explorer/view.tsx index 655f4a29..fe3d2981 100644 --- a/src/client/components/script_tuner/explorer/view.tsx +++ b/src/client/components/script_tuner/explorer/view.tsx @@ -2,21 +2,58 @@ import * as classNames from 'classnames' import { observer } from 'mobx-react' import * as React from 'react' +import { RobotModel } from '../../robot/model' +import { ScriptTunerController } from '../controller' +import { ScriptTunerModel } from '../model' + +import { LoadingIcon } from './loading_icon/view' +import { RobotSelector } from './robot_selector/view' +import { ExplorerController } from './controller' import * as style from './style.css' type ExplorerProps = { className?: string + controller: ScriptTunerController + model: ScriptTunerModel } @observer export class Explorer extends React.Component { render() { - return
+ const { className, model } = this.props + const controller = ExplorerController.of({ + controller: this.props.controller, + }) + + return
Scripts
- -
+ + { model.isLoading && +
+ + { model.loadingMessage } +
+ } + { !model.isLoading && +
+ { model.selectedRobot === undefined && +
Select a robot to view scripts
+ } + { model.selectedRobot && model.scripts.length === 0 && +
No scripts for selected robot
+ } + { model.selectedRobot && model.scripts.length > 0 && +
List of robot scripts
+ } +
+ }
} } diff --git a/src/client/components/script_tuner/install.tsx b/src/client/components/script_tuner/install.tsx index d95bdac5..28d2feec 100644 --- a/src/client/components/script_tuner/install.tsx +++ b/src/client/components/script_tuner/install.tsx @@ -24,7 +24,7 @@ export function installScriptTuner({ nav, appModel, nusightNetwork, menu }: { Icon, label: 'Scripts', Content: () => { - const network = ScriptTunerNetwork.of(nusightNetwork) + const network = ScriptTunerNetwork.of(nusightNetwork, model) const controller = ScriptTunerController.of({ network, model }) return }, diff --git a/src/client/components/script_tuner/model.ts b/src/client/components/script_tuner/model.ts index bd7d8c2d..24f884f1 100644 --- a/src/client/components/script_tuner/model.ts +++ b/src/client/components/script_tuner/model.ts @@ -5,6 +5,11 @@ import { now } from 'mobx-utils' import { AppModel } from '../app/model' import { RobotModel } from '../robot/model' +export interface Script { + path: string + servos: Servo[] +} + export interface Servo { id: string frames: Frame[] @@ -19,29 +24,21 @@ export interface Frame { torque: number, } -import * as sampleScriptJson from './sample-script.json' - -const sampleScript = sampleScriptJson as { [key: string]: Servo } - export class ScriptTunerModel { - @observable robot: RobotModel - @observable servos: Servo[] + @observable robots: RobotModel[] + @observable selectedRobot?: RobotModel + @observable scripts: Script[] + @observable selectedScript?: Script + @observable isLoading = false + @observable loadingMessage?: string @observable isPlaying = false @observable currentTime = 0 @observable playStartedAt = 0 constructor(robotModels: RobotModel[]) { - this.robot = RobotModel.of({ - id: 'Darwin #1', - connected: true, - enabled: true, - name: 'Darwin #1', - address: '127.0.0.1', - port: 1234, - }) - - // These will come (perhaps over the network) from the selected robot - this.servos = this.makeSampleServos() + this.robots = robotModels + this.selectedRobot = undefined + this.scripts = [] } static of(robots: RobotModel[]): ScriptTunerModel { @@ -69,65 +66,18 @@ export class ScriptTunerModel { @computed get scriptsLength() { - let maxLength = 0 - - this.servos.forEach(servo => { - if (servo.frames.length > maxLength) { - maxLength = servo.frames.length - } - }) - - return maxLength - } + if (this.selectedScript) { + let maxLength = 0 - private makeSampleServos(): Servo[] { - return [ - 'RIGHT_SHOULDER_PITCH', - 'LEFT_SHOULDER_PITCH', - 'RIGHT_SHOULDER_ROLL', - 'LEFT_SHOULDER_ROLL', - 'RIGHT_ELBOW', - 'LEFT_ELBOW', - 'RIGHT_HIP_YAW', - 'LEFT_HIP_YAW', - 'RIGHT_HIP_ROLL', - 'LEFT_HIP_ROLL', - 'RIGHT_HIP_PITCH', - 'LEFT_HIP_PITCH', - 'RIGHT_KNEE', - 'LEFT_KNEE', - 'RIGHT_ANKLE_PITCH', - 'LEFT_ANKLE_PITCH', - 'RIGHT_ANKLE_ROLL', - 'LEFT_ANKLE_ROLL', - 'HEAD_YAW', - 'HEAD_PITCH', - ].map(id => { - if (sampleScript[id]) { - return sampleScript[id] - } - - return this.makeSampleServo(id, 5, 0) - }) - } - - private makeSampleServo(id: string, length: number = 30, angle?: number): Servo { - const frames = [] - const period = 10 - - for (let i = 0; i <= length; i++) { - const theta = (2 * Math.PI * i) / period - - frames.push({ - time: i, - angle: angle !== undefined ? angle : 2 * Math.sin(theta), - pGain: 0, - iGain: 0, - dGain: 0, - torque: 0, + this.selectedScript.servos.forEach(servo => { + if (servo.frames.length > maxLength) { + maxLength = servo.frames.length + } }) + + return maxLength } - return { id, frames } + return 0 } } diff --git a/src/client/components/script_tuner/network.ts b/src/client/components/script_tuner/network.ts index 144d1155..135650fd 100644 --- a/src/client/components/script_tuner/network.ts +++ b/src/client/components/script_tuner/network.ts @@ -1,16 +1,108 @@ +import { action } from 'mobx' + import { Network } from '../../network/network' import { NUsightNetwork } from '../../network/nusight_network' +import { RobotModel } from '../robot/model' + +import { Frame, Servo, Script, ScriptTunerModel } from './model' + +import * as sampleScriptJson from './sample-script.json' +const sampleScript = sampleScriptJson as { [key: string]: Servo } export class ScriptTunerNetwork { - constructor(private network: Network) { + constructor(private network: Network, private model: ScriptTunerModel) { } - static of(nusightNetwork: NUsightNetwork): ScriptTunerNetwork { + static of(nusightNetwork: NUsightNetwork, model: ScriptTunerModel): ScriptTunerNetwork { const network = Network.of(nusightNetwork) - return new ScriptTunerNetwork(network) + return new ScriptTunerNetwork(network, model) + } + + @action + requestScripts(robot: RobotModel) { + this.startLoader(`Loading scripts from ${robot.name}...`) + setTimeout(() => { + this.onScripts() + this.stopLoader() + }, 5000) } destroy() { this.network.off() } + + @action + private onScripts() { + this.model.scripts = [ + { + path: 'Salute.yaml', + servos: makeSampleServos() + } + ] + this.model.isLoading = false + this.model.loadingMessage = '' + } + + @action + private startLoader(message: string = 'Loading...') { + this.model.loadingMessage = message + this.model.isLoading = true + } + + @action + private stopLoader() { + this.model.isLoading = false + this.model.loadingMessage = '' + } +} + +function makeSampleServos(): Servo[] { + return [ + 'RIGHT_SHOULDER_PITCH', + 'LEFT_SHOULDER_PITCH', + 'RIGHT_SHOULDER_ROLL', + 'LEFT_SHOULDER_ROLL', + 'RIGHT_ELBOW', + 'LEFT_ELBOW', + 'RIGHT_HIP_YAW', + 'LEFT_HIP_YAW', + 'RIGHT_HIP_ROLL', + 'LEFT_HIP_ROLL', + 'RIGHT_HIP_PITCH', + 'LEFT_HIP_PITCH', + 'RIGHT_KNEE', + 'LEFT_KNEE', + 'RIGHT_ANKLE_PITCH', + 'LEFT_ANKLE_PITCH', + 'RIGHT_ANKLE_ROLL', + 'LEFT_ANKLE_ROLL', + 'HEAD_YAW', + 'HEAD_PITCH', + ].map(id => { + if (sampleScript[id]) { + return sampleScript[id] + } + + return makeSampleServo(id, 5, 0) + }) +} + +function makeSampleServo(id: string, length: number = 30, angle?: number): Servo { + const frames = [] + const period = 10 + + for (let i = 0; i <= length; i++) { + const theta = (2 * Math.PI * i) / period + + frames.push({ + time: i, + angle: angle !== undefined ? angle : 2 * Math.sin(theta), + pGain: 0, + iGain: 0, + dGain: 0, + torque: 0, + }) + } + + return { id, frames } } diff --git a/src/client/components/script_tuner/preview/view_model.ts b/src/client/components/script_tuner/preview/view_model.ts index cf89c4c4..4d37d282 100644 --- a/src/client/components/script_tuner/preview/view_model.ts +++ b/src/client/components/script_tuner/preview/view_model.ts @@ -36,146 +36,166 @@ export class ScriptRobot3dViewModel implements Robot3dViewModel { @computed get name() { - return this.model.robot.name + return this.model.selectedRobot ? this.model.selectedRobot.name : undefined } @computed get RIGHT_SHOULDER_PITCH() { - return this.model.servos[0].frames.length - ? getAngleAtCurrentTime(this.model.playTime, this.model.servos[0].frames) + const script = this.model.selectedScript + return script && script.servos[0].frames.length + ? getAngleAtCurrentTime(this.model.playTime, script.servos[0].frames) : 0 } @computed get LEFT_SHOULDER_PITCH() { - return this.model.servos[1].frames.length - ? getAngleAtCurrentTime(this.model.playTime, this.model.servos[1].frames) + const script = this.model.selectedScript + return script && script.servos[1].frames.length + ? getAngleAtCurrentTime(this.model.playTime, script.servos[1].frames) : 0 } @computed get RIGHT_SHOULDER_ROLL() { - return this.model.servos[2].frames.length - ? getAngleAtCurrentTime(this.model.playTime, this.model.servos[2].frames) + const script = this.model.selectedScript + return script && script.servos[2].frames.length + ? getAngleAtCurrentTime(this.model.playTime, script.servos[2].frames) : 0 } @computed get LEFT_SHOULDER_ROLL() { - return this.model.servos[3].frames.length - ? getAngleAtCurrentTime(this.model.playTime, this.model.servos[3].frames) + const script = this.model.selectedScript + return script && script.servos[3].frames.length + ? getAngleAtCurrentTime(this.model.playTime, script.servos[3].frames) : 0 } @computed get RIGHT_ELBOW() { - return this.model.servos[4].frames.length - ? getAngleAtCurrentTime(this.model.playTime, this.model.servos[4].frames) + const script = this.model.selectedScript + return script && script.servos[4].frames.length + ? getAngleAtCurrentTime(this.model.playTime, script.servos[4].frames) : 0 } @computed get LEFT_ELBOW() { - return this.model.servos[5].frames.length - ? getAngleAtCurrentTime(this.model.playTime, this.model.servos[5].frames) + const script = this.model.selectedScript + return script && script.servos[5].frames.length + ? getAngleAtCurrentTime(this.model.playTime, script.servos[5].frames) : 0 } @computed get RIGHT_HIP_YAW() { - return this.model.servos[6].frames.length - ? getAngleAtCurrentTime(this.model.playTime, this.model.servos[6].frames) + const script = this.model.selectedScript + return script && script.servos[6].frames.length + ? getAngleAtCurrentTime(this.model.playTime, script.servos[6].frames) : 0 } @computed get LEFT_HIP_YAW() { - return this.model.servos[7].frames.length - ? getAngleAtCurrentTime(this.model.playTime, this.model.servos[7].frames) + const script = this.model.selectedScript + return script && script.servos[7].frames.length + ? getAngleAtCurrentTime(this.model.playTime, script.servos[7].frames) : 0 } @computed get RIGHT_HIP_ROLL() { - return this.model.servos[8].frames.length - ? getAngleAtCurrentTime(this.model.playTime, this.model.servos[8].frames) + const script = this.model.selectedScript + return script && script.servos[8].frames.length + ? getAngleAtCurrentTime(this.model.playTime, script.servos[8].frames) : 0 } @computed get LEFT_HIP_ROLL() { - return this.model.servos[9].frames.length - ? getAngleAtCurrentTime(this.model.playTime, this.model.servos[9].frames) + const script = this.model.selectedScript + return script && script.servos[9].frames.length + ? getAngleAtCurrentTime(this.model.playTime, script.servos[9].frames) : 0 } @computed get RIGHT_HIP_PITCH() { - return this.model.servos[10].frames.length - ? getAngleAtCurrentTime(this.model.playTime, this.model.servos[10].frames) + const script = this.model.selectedScript + return script && script.servos[10].frames.length + ? getAngleAtCurrentTime(this.model.playTime, script.servos[10].frames) : 0 } @computed get LEFT_HIP_PITCH() { - return this.model.servos[11].frames.length - ? getAngleAtCurrentTime(this.model.playTime, this.model.servos[11].frames) + const script = this.model.selectedScript + return script && script.servos[11].frames.length + ? getAngleAtCurrentTime(this.model.playTime, script.servos[11].frames) : 0 } @computed get RIGHT_KNEE() { - return this.model.servos[12].frames.length - ? getAngleAtCurrentTime(this.model.playTime, this.model.servos[12].frames) + const script = this.model.selectedScript + return script && script.servos[12].frames.length + ? getAngleAtCurrentTime(this.model.playTime, script.servos[12].frames) : 0 } @computed get LEFT_KNEE() { - return this.model.servos[13].frames.length - ? getAngleAtCurrentTime(this.model.playTime, this.model.servos[13].frames) + const script = this.model.selectedScript + return script && script.servos[13].frames.length + ? getAngleAtCurrentTime(this.model.playTime, script.servos[13].frames) : 0 } @computed get RIGHT_ANKLE_PITCH() { - return this.model.servos[14].frames.length - ? getAngleAtCurrentTime(this.model.playTime, this.model.servos[14].frames) + const script = this.model.selectedScript + return script && script.servos[14].frames.length + ? getAngleAtCurrentTime(this.model.playTime, script.servos[14].frames) : 0 } @computed get LEFT_ANKLE_PITCH() { - return this.model.servos[15].frames.length - ? getAngleAtCurrentTime(this.model.playTime, this.model.servos[15].frames) + const script = this.model.selectedScript + return script && script.servos[15].frames.length + ? getAngleAtCurrentTime(this.model.playTime, script.servos[15].frames) : 0 } @computed get RIGHT_ANKLE_ROLL() { - return this.model.servos[16].frames.length - ? getAngleAtCurrentTime(this.model.playTime, this.model.servos[16].frames) + const script = this.model.selectedScript + return script && script.servos[16].frames.length + ? getAngleAtCurrentTime(this.model.playTime, script.servos[16].frames) : 0 } @computed get LEFT_ANKLE_ROLL() { - return this.model.servos[17].frames.length - ? getAngleAtCurrentTime(this.model.playTime, this.model.servos[17].frames) + const script = this.model.selectedScript + return script && script.servos[17].frames.length + ? getAngleAtCurrentTime(this.model.playTime, script.servos[17].frames) : 0 } @computed get HEAD_YAW() { - return this.model.servos[18].frames.length - ? getAngleAtCurrentTime(this.model.playTime, this.model.servos[18].frames) + const script = this.model.selectedScript + return script && script.servos[18].frames.length + ? getAngleAtCurrentTime(this.model.playTime, script.servos[18].frames) : 0 } @computed get HEAD_PITCH() { - return this.model.servos[19].frames.length - ? getAngleAtCurrentTime(this.model.playTime, this.model.servos[19].frames) + const script = this.model.selectedScript + return script && script.servos[19].frames.length + ? getAngleAtCurrentTime(this.model.playTime, script.servos[19].frames) : 0 } } diff --git a/src/client/components/script_tuner/view.tsx b/src/client/components/script_tuner/view.tsx index 9e8f7837..41db7aa4 100644 --- a/src/client/components/script_tuner/view.tsx +++ b/src/client/components/script_tuner/view.tsx @@ -22,7 +22,7 @@ export type ScriptTunerProps = { export const ScriptTuner = observer(({ controller, menu, model, network }: ScriptTunerProps) => { return (
- +
From 1cbe481a5a59fccbd2a87a50739ab4b5c16aea60 Mon Sep 17 00:00:00 2001 From: Josephus Paye II Date: Tue, 12 Feb 2019 16:34:07 +1100 Subject: [PATCH 41/54] Remove functions in render, fix lint --- .../script_tuner/editor/line/view.tsx | 32 +++++++--- .../script_tuner/editor/timeline/view.tsx | 27 +++++--- .../components/script_tuner/editor/view.tsx | 49 ++++++++++++--- .../explorer/loading_icon/view.tsx | 14 ++--- .../explorer/robot_selector/view.tsx | 61 +++++++++++-------- .../components/script_tuner/explorer/view.tsx | 2 +- src/client/components/script_tuner/network.ts | 8 +-- 7 files changed, 128 insertions(+), 65 deletions(-) diff --git a/src/client/components/script_tuner/editor/line/view.tsx b/src/client/components/script_tuner/editor/line/view.tsx index 975273c4..3d9f829a 100644 --- a/src/client/components/script_tuner/editor/line/view.tsx +++ b/src/client/components/script_tuner/editor/line/view.tsx @@ -20,8 +20,9 @@ type LineEditorProps = { @observer export class LineEditor extends Component { isDragging: boolean = false - selectedElement: HTMLElement | undefined svgRef: React.RefObject + selectedElement?: HTMLElement + viewModel?: LineEditorViewModel constructor(props: LineEditorProps) { super(props) @@ -34,6 +35,8 @@ export class LineEditor extends Component { editorViewModel: this.props.editorViewModel, }) + this.viewModel = viewModel + return
{ width={viewModel.width + 'px'} ref={this.svgRef} - onMouseDown={(e) => this.onMouseDown(e, viewModel)} - onMouseMove={(e) => this.onMouseMove(e, viewModel)} - onDoubleClick={(e) => this.onDoubleClick(e.nativeEvent, viewModel)} + onMouseDown={this.onMouseDown} + onMouseMove={this.onMouseMove} + onDoubleClick={this.onDoubleClick} > { stroke='black' strokeWidth='1' - onContextMenu={(e) => this.onRightClick(e, index)} + onContextMenu={this.onRightClick} > { point.label } @@ -118,7 +121,13 @@ export class LineEditor extends Component {
} - private onDoubleClick(event: MouseEvent, viewModel: LineEditorViewModel) { + private onDoubleClick({ nativeEvent: event }: React.MouseEvent) { + const viewModel = this.viewModel + + if (!viewModel) { + return + } + const svg = this.svgRef.current! const reference = svg.createSVGPoint() @@ -133,8 +142,9 @@ export class LineEditor extends Component { }) } - private onRightClick = ({ nativeEvent: event }: React.MouseEvent, pointIndex: number) => { + private onRightClick = ({ nativeEvent: event }: React.MouseEvent) => { event.preventDefault() + const pointIndex = Number((event.target as HTMLElement).dataset.index) this.props.controller.removeFrame(pointIndex) } @@ -151,15 +161,17 @@ export class LineEditor extends Component { this.selectedElement = undefined } - private onMouseDown = ({ nativeEvent: event }: React.MouseEvent, viewModel: LineEditorViewModel) => { + private onMouseDown = ({ nativeEvent: event }: React.MouseEvent) => { const leftMouseButton = 0 if (event.button === leftMouseButton && (event.target as HTMLElement).dataset.draggable) { this.selectedElement = (event.target as HTMLElement) } } - private onMouseMove = ({ nativeEvent: event }: React.MouseEvent, viewModel: LineEditorViewModel) => { - if (!this.selectedElement) { + private onMouseMove = ({ nativeEvent: event }: React.MouseEvent) => { + const viewModel = this.viewModel + + if (!this.selectedElement || !viewModel) { return } diff --git a/src/client/components/script_tuner/editor/timeline/view.tsx b/src/client/components/script_tuner/editor/timeline/view.tsx index c9c48425..71c448c4 100644 --- a/src/client/components/script_tuner/editor/timeline/view.tsx +++ b/src/client/components/script_tuner/editor/timeline/view.tsx @@ -17,6 +17,7 @@ export class Timeline extends React.Component { readyToDrag: boolean = false isDragging: boolean = false svgRef: React.RefObject + viewModel?: TimelineViewModel constructor(props: TimelineProps) { super(props) @@ -25,6 +26,7 @@ export class Timeline extends React.Component { render() { const viewModel = TimelineViewModel.of(this.props.editorViewModel) + this.viewModel = viewModel return
{ width={viewModel.width + 'px'} ref={this.svgRef} - onMouseDown={(e) => this.onMouseDown(e, viewModel)} - onMouseMove={(e) => this.onMouseMove(e, viewModel)} - onClick={(e) => this.onClick(e.nativeEvent, viewModel)} + onMouseDown={this.onMouseDown} + onMouseMove={this.onMouseMove} + onClick={this.onClick} > @@ -78,7 +80,13 @@ export class Timeline extends React.Component {
} - private onClick(event: MouseEvent, viewModel: TimelineViewModel) { + private onClick({ nativeEvent: event }: React.MouseEvent) { + const viewModel = this.viewModel + + if (!viewModel) { + return + } + const svg = this.svgRef.current! const reference = svg.createSVGPoint() @@ -103,14 +111,17 @@ export class Timeline extends React.Component { this.readyToDrag = false } - private onMouseDown = ({ nativeEvent: event }: React.MouseEvent, viewModel: TimelineViewModel) => { - if ((event.target as HTMLElement).dataset.draggable) { + private onMouseDown = ({ nativeEvent: event }: React.MouseEvent) => { + const viewModel = this.viewModel + if (viewModel && (event.target as HTMLElement).dataset.draggable) { this.readyToDrag = true } } - private onMouseMove = ({ nativeEvent: event }: React.MouseEvent, viewModel: TimelineViewModel) => { - if (!this.readyToDrag) { + private onMouseMove = ({ nativeEvent: event }: React.MouseEvent) => { + const viewModel = this.viewModel + + if (!viewModel || !this.readyToDrag) { return } diff --git a/src/client/components/script_tuner/editor/view.tsx b/src/client/components/script_tuner/editor/view.tsx index 9dad814f..abb7a3d8 100644 --- a/src/client/components/script_tuner/editor/view.tsx +++ b/src/client/components/script_tuner/editor/view.tsx @@ -24,6 +24,7 @@ export class Editor extends React.Component { props: EditorProps timelineRef: React.RefObject bodyRef: React.RefObject + controller?: EditorController constructor(props: EditorProps) { super(props) @@ -35,21 +36,23 @@ export class Editor extends React.Component { render() { const { className, model } = this.props const viewModel = EditorViewModel.of(model) - const controller = EditorController.of({ + this.controller = EditorController.of({ viewModel, controller: this.props.controller, }) return
-
{ model.selectedScript ? `Edit ${model.selectedScript.path}` : 'Editor' }
+
+ { model.selectedScript ? `Edit ${model.selectedScript.path}` : 'Editor' } +
{ model.selectedScript &&
- - - - - + +
}
@@ -75,7 +78,7 @@ export class Editor extends React.Component { { model.selectedScript && @@ -126,4 +129,34 @@ export class Editor extends React.Component { const timelineElement = ReactDOM.findDOMNode(this.timelineRef.current!) as HTMLDivElement timelineElement.scrollLeft = (event.currentTarget as HTMLDivElement).scrollLeft } + + private jumpToStart = () => { + if (this.controller) { + this.controller.jumpToStart() + } + } + + private togglePlayback = () => { + if (this.controller) { + this.controller.togglePlayback() + } + } + + private jumpToEnd = () => { + if (this.controller) { + this.controller.jumpToEnd() + } + } + + private zoomIn = () => { + if (this.controller) { + this.controller.zoomIn() + } + } + + private zoomOut = () => { + if (this.controller) { + this.controller.zoomOut() + } + } } diff --git a/src/client/components/script_tuner/explorer/loading_icon/view.tsx b/src/client/components/script_tuner/explorer/loading_icon/view.tsx index a1605ece..a4d12259 100644 --- a/src/client/components/script_tuner/explorer/loading_icon/view.tsx +++ b/src/client/components/script_tuner/explorer/loading_icon/view.tsx @@ -17,14 +17,14 @@ export class LoadingIcon extends React.Component { className={classNames([style.loading, className])} style={{ width: size + 'px', height: size + 'px' }} > - +
diff --git a/src/client/components/script_tuner/explorer/robot_selector/view.tsx b/src/client/components/script_tuner/explorer/robot_selector/view.tsx index 7a4e4f6c..1af3d4d6 100644 --- a/src/client/components/script_tuner/explorer/robot_selector/view.tsx +++ b/src/client/components/script_tuner/explorer/robot_selector/view.tsx @@ -3,7 +3,7 @@ import { observer } from 'mobx-react' import * as React from 'react' import { RobotModel } from '../../../robot/model' -import { Select, SelectOption } from '../../../select/view' +import { Option, Select } from '../../../select/view' import PlugIcon from './plug.svg' import RobotIcon from './robot.svg' @@ -17,31 +17,38 @@ export type RobotSelectorProps = { onSelect(robot: RobotModel): void } -export const RobotSelector = observer((props: RobotSelectorProps) => { - const { className, robots, selected, onSelect } = props - const viewModel = RobotSelectorViewModel.of({ - robots, - selected, - }) +@observer +export class RobotSelector extends React.Component { + render() { + const { className, robots, selected } = this.props + const viewModel = RobotSelectorViewModel.of({ + robots, + selected, + }) - const empty = ( -
-
-
No connected robots
- Run yarn start:sim to simulate robots -
- ) + const empty = ( +
+
+
No connected robots
+ Run yarn start:sim to simulate robots +
+ ) - return ( -
- } + /> +
+ ) + } + + private onChange = (option: Option & { robot: RobotModel }) => { + this.props.onSelect(option.robot) + } +} diff --git a/src/client/components/script_tuner/explorer/view.tsx b/src/client/components/script_tuner/explorer/view.tsx index fe3d2981..6ba35806 100644 --- a/src/client/components/script_tuner/explorer/view.tsx +++ b/src/client/components/script_tuner/explorer/view.tsx @@ -6,9 +6,9 @@ import { RobotModel } from '../../robot/model' import { ScriptTunerController } from '../controller' import { ScriptTunerModel } from '../model' +import { ExplorerController } from './controller' import { LoadingIcon } from './loading_icon/view' import { RobotSelector } from './robot_selector/view' -import { ExplorerController } from './controller' import * as style from './style.css' type ExplorerProps = { diff --git a/src/client/components/script_tuner/network.ts b/src/client/components/script_tuner/network.ts index 135650fd..04792499 100644 --- a/src/client/components/script_tuner/network.ts +++ b/src/client/components/script_tuner/network.ts @@ -4,9 +4,9 @@ import { Network } from '../../network/network' import { NUsightNetwork } from '../../network/nusight_network' import { RobotModel } from '../robot/model' -import { Frame, Servo, Script, ScriptTunerModel } from './model' - +import { Frame, Script, ScriptTunerModel, Servo } from './model' import * as sampleScriptJson from './sample-script.json' + const sampleScript = sampleScriptJson as { [key: string]: Servo } export class ScriptTunerNetwork { @@ -36,8 +36,8 @@ export class ScriptTunerNetwork { this.model.scripts = [ { path: 'Salute.yaml', - servos: makeSampleServos() - } + servos: makeSampleServos(), + }, ] this.model.isLoading = false this.model.loadingMessage = '' From 26023d31c852a0b95de50e1ba5819f760d2ae043 Mon Sep 17 00:00:00 2001 From: Josephus Paye II Date: Tue, 12 Feb 2019 18:54:35 +1100 Subject: [PATCH 42/54] Move sample script to simulator, request via network --- .../components/script_tuner/controller.ts | 7 +- .../script_tuner/editor/line/view.tsx | 50 ++++---- .../components/script_tuner/editor/style.css | 2 +- .../script_tuner/editor/timeline/view.tsx | 28 ++--- .../components/script_tuner/editor/view.tsx | 2 +- .../script_tuner/explorer/controller.ts | 5 + .../script_tuner/explorer/style.css | 30 ++++- .../components/script_tuner/explorer/view.tsx | 33 +++++- src/client/components/script_tuner/model.ts | 35 +++--- src/client/components/script_tuner/network.ts | 90 ++++----------- .../script_tuner/preview/view_model.ts | 107 +++++------------- src/virtual_robots/run.ts | 2 +- .../simulators/script_data_simulator.ts | 26 ----- .../script_data_simulator/salute.json} | 0 .../script_data_simulator.ts | 49 ++++++++ src/virtual_robots/virtual_robots.ts | 2 +- 16 files changed, 230 insertions(+), 238 deletions(-) delete mode 100644 src/virtual_robots/simulators/script_data_simulator.ts rename src/{client/components/script_tuner/sample-script.json => virtual_robots/simulators/script_data_simulator/salute.json} (100%) create mode 100644 src/virtual_robots/simulators/script_data_simulator/script_data_simulator.ts diff --git a/src/client/components/script_tuner/controller.ts b/src/client/components/script_tuner/controller.ts index fd4fc447..271b7a89 100644 --- a/src/client/components/script_tuner/controller.ts +++ b/src/client/components/script_tuner/controller.ts @@ -2,7 +2,7 @@ import { action, autorun, IReactionDisposer } from 'mobx' import { RobotModel } from '../robot/model' -import { ScriptTunerModel } from './model' +import { Script, ScriptTunerModel } from './model' import { ScriptTunerNetwork } from './network' interface ScriptTunerOpts { @@ -42,6 +42,11 @@ export class ScriptTunerController { } } + @action + selectScript(script: Script) { + this.model.selectedScript = script + } + @action setPlayTime(time: number) { this.model.currentTime = Math.min(Math.max(time, this.model.startTime), this.model.endTime) diff --git a/src/client/components/script_tuner/editor/line/view.tsx b/src/client/components/script_tuner/editor/line/view.tsx index 3d9f829a..e517c5ef 100644 --- a/src/client/components/script_tuner/editor/line/view.tsx +++ b/src/client/components/script_tuner/editor/line/view.tsx @@ -30,19 +30,17 @@ export class LineEditor extends Component { } render() { - const viewModel = LineEditorViewModel.of({ + this.viewModel = LineEditorViewModel.of({ servo: this.props.servo, editorViewModel: this.props.editorViewModel, }) - this.viewModel = viewModel - return
{ className={style.lineEditorTitle} x={4} y={16} - >{ viewModel.servoId } + >{ this.viewModel.servoId } { /* Horizontal grid lines */ } @@ -62,15 +60,15 @@ export class LineEditor extends Component { { // Vertical grid lines - new Array(viewModel.width).fill(0).map((_, index) => { - const x = index * viewModel.cellWidth + new Array(this.viewModel.width).fill(0).map((_, index) => { + const x = index * this.viewModel!.cellWidth return }) } { // The main plot line - viewModel.svgLineSegments.map((segment, index) => { + this.viewModel.svgLineSegments.map((segment, index) => { return { { // Points on the main plot line - viewModel.svgPoints.map((point, index) => { + this.viewModel.svgPoints.map((point, index) => { return { @@ -121,7 +119,7 @@ export class LineEditor extends Component {
} - private onDoubleClick({ nativeEvent: event }: React.MouseEvent) { + private onDoubleClick = ({ nativeEvent: event }: React.MouseEvent) => { const viewModel = this.viewModel if (!viewModel) { @@ -148,19 +146,6 @@ export class LineEditor extends Component { this.props.controller.removeFrame(pointIndex) } - private startDrag() { - this.isDragging = true - - document.addEventListener('mouseup', (event: MouseEvent) => { - this.endDrag() - }, { once: true }) - } - - private endDrag() { - this.isDragging = false - this.selectedElement = undefined - } - private onMouseDown = ({ nativeEvent: event }: React.MouseEvent) => { const leftMouseButton = 0 if (event.button === leftMouseButton && (event.target as HTMLElement).dataset.draggable) { @@ -208,6 +193,19 @@ export class LineEditor extends Component { this.props.controller.updateFrame(index, { time, angle }) } + private startDrag() { + this.isDragging = true + + document.addEventListener('mouseup', (event: MouseEvent) => { + this.endDrag() + }, { once: true }) + } + + private endDrag() { + this.isDragging = false + this.selectedElement = undefined + } + private getMousePositionInSvgSpace(event: MouseEvent) { const svg = this.svgRef.current! const CTM = svg.getScreenCTM()! diff --git a/src/client/components/script_tuner/editor/style.css b/src/client/components/script_tuner/editor/style.css index 678bb476..83f489a7 100644 --- a/src/client/components/script_tuner/editor/style.css +++ b/src/client/components/script_tuner/editor/style.css @@ -64,5 +64,5 @@ display: flex; align-items: center; justify-content: center; - background-color: white; + color: #000; } diff --git a/src/client/components/script_tuner/editor/timeline/view.tsx b/src/client/components/script_tuner/editor/timeline/view.tsx index 71c448c4..2ae0116f 100644 --- a/src/client/components/script_tuner/editor/timeline/view.tsx +++ b/src/client/components/script_tuner/editor/timeline/view.tsx @@ -80,7 +80,7 @@ export class Timeline extends React.Component {
} - private onClick({ nativeEvent: event }: React.MouseEvent) { + private onClick = ({ nativeEvent: event }: React.MouseEvent) => { const viewModel = this.viewModel if (!viewModel) { @@ -98,19 +98,6 @@ export class Timeline extends React.Component { this.props.setPlayTime(viewModel.svgToTime(x)) } - private startDrag() { - this.isDragging = true - - document.addEventListener('mouseup', (event: MouseEvent) => { - this.endDrag() - }, { once: true }) - } - - private endDrag() { - this.isDragging = false - this.readyToDrag = false - } - private onMouseDown = ({ nativeEvent: event }: React.MouseEvent) => { const viewModel = this.viewModel if (viewModel && (event.target as HTMLElement).dataset.draggable) { @@ -140,6 +127,19 @@ export class Timeline extends React.Component { ) } + private startDrag() { + this.isDragging = true + + document.addEventListener('mouseup', (event: MouseEvent) => { + this.endDrag() + }, { once: true }) + } + + private endDrag() { + this.isDragging = false + this.readyToDrag = false + } + private getMousePositionInSvgSpace(event: MouseEvent) { const svg = this.svgRef.current! const CTM = svg.getScreenCTM()! diff --git a/src/client/components/script_tuner/editor/view.tsx b/src/client/components/script_tuner/editor/view.tsx index abb7a3d8..8435aa03 100644 --- a/src/client/components/script_tuner/editor/view.tsx +++ b/src/client/components/script_tuner/editor/view.tsx @@ -86,7 +86,7 @@ export class Editor extends React.Component { { model.selectedScript &&
{ - model.selectedScript.servos.map((servo, index) => { + model.selectedScriptServos.map((servo, index) => { const controller = LineEditorController.of(servo) return { this.controller.selectRobot(robot) } + + selectScript = (script: Script) => { + this.controller.selectScript(script) + } } diff --git a/src/client/components/script_tuner/explorer/style.css b/src/client/components/script_tuner/explorer/style.css index 4269c7d7..384a45b2 100644 --- a/src/client/components/script_tuner/explorer/style.css +++ b/src/client/components/script_tuner/explorer/style.css @@ -22,7 +22,6 @@ .explorerBody, .explorerLoading { - padding: 0 4px; flex-grow: 1; overflow: hidden; position: relative; @@ -34,6 +33,7 @@ align-items: center; display: flex; flex-direction: column; + padding: 0 4px; } .explorerLoadingIcon { @@ -48,3 +48,31 @@ align-items: center; justify-content: center; } + +.explorerScripts { + width: 100%; + height: 100%; + overflow-x: hidden; + overflow-y: auto; +} + +.explorerScript { + padding: 6px 8px; + line-height: 1; + border-bottom: 1px solid #eee; + cursor: pointer; +} + +.explorerScript:last-child { + border-bottom: 0; +} + +.explorerScript:hover { + background-color: #eee; +} + +.explorerScriptSelected, +.explorerScriptSelected:hover { + color: white; + background-color: #1197d3; +} diff --git a/src/client/components/script_tuner/explorer/view.tsx b/src/client/components/script_tuner/explorer/view.tsx index 6ba35806..91a71cce 100644 --- a/src/client/components/script_tuner/explorer/view.tsx +++ b/src/client/components/script_tuner/explorer/view.tsx @@ -4,7 +4,7 @@ import * as React from 'react' import { RobotModel } from '../../robot/model' import { ScriptTunerController } from '../controller' -import { ScriptTunerModel } from '../model' +import { Script, ScriptTunerModel } from '../model' import { ExplorerController } from './controller' import { LoadingIcon } from './loading_icon/view' @@ -50,10 +50,39 @@ export class Explorer extends React.Component {
No scripts for selected robot
} { model.selectedRobot && model.scripts.length > 0 && -
List of robot scripts
+
{ + model.scripts.map(script => { + const isSelected = Boolean(model.selectedScript && model.selectedScript.path === script.path) + return + }) + }
}
}
} } + +@observer +export class ScriptListItem extends React.Component<{ + script: Script, + isSelected: boolean, + onSelect(script: Script): void +}> { + render() { + const { script, isSelected } = this.props + return
{ script.path }
+ } + + private onClick = () => { + this.props.onSelect(this.props.script) + } +} diff --git a/src/client/components/script_tuner/model.ts b/src/client/components/script_tuner/model.ts index 24f884f1..7a476618 100644 --- a/src/client/components/script_tuner/model.ts +++ b/src/client/components/script_tuner/model.ts @@ -1,20 +1,10 @@ -import { computed } from 'mobx' +import { computed, values } from 'mobx' import { observable } from 'mobx' import { now } from 'mobx-utils' import { AppModel } from '../app/model' import { RobotModel } from '../robot/model' -export interface Script { - path: string - servos: Servo[] -} - -export interface Servo { - id: string - frames: Frame[] -} - export interface Frame { time: number, angle: number, @@ -24,6 +14,16 @@ export interface Frame { torque: number, } +export interface Servo { + id: string + frames: Frame[] +} + +export interface Script { + path: string + servos: {[key: string]: Servo} +} + export class ScriptTunerModel { @observable robots: RobotModel[] @observable selectedRobot?: RobotModel @@ -37,7 +37,6 @@ export class ScriptTunerModel { constructor(robotModels: RobotModel[]) { this.robots = robotModels - this.selectedRobot = undefined this.scripts = [] } @@ -52,7 +51,7 @@ export class ScriptTunerModel { @computed get endTime() { - return this.scriptsLength - 1 + return Math.max(this.scriptsLength - 1, 0) } @computed @@ -64,12 +63,20 @@ export class ScriptTunerModel { return time >= this.endTime ? this.endTime : time } + @computed + get selectedScriptServos() { + if (this.selectedScript) { + return values(this.selectedScript.servos) + } + return [] + } + @computed get scriptsLength() { if (this.selectedScript) { let maxLength = 0 - this.selectedScript.servos.forEach(servo => { + this.selectedScriptServos.forEach(servo => { if (servo.frames.length > maxLength) { maxLength = servo.frames.length } diff --git a/src/client/components/script_tuner/network.ts b/src/client/components/script_tuner/network.ts index 04792499..3da1642d 100644 --- a/src/client/components/script_tuner/network.ts +++ b/src/client/components/script_tuner/network.ts @@ -1,16 +1,18 @@ import { action } from 'mobx' +import { message } from '../../../shared/proto/messages' import { Network } from '../../network/network' import { NUsightNetwork } from '../../network/nusight_network' import { RobotModel } from '../robot/model' import { Frame, Script, ScriptTunerModel, Servo } from './model' -import * as sampleScriptJson from './sample-script.json' -const sampleScript = sampleScriptJson as { [key: string]: Servo } +import LoadScriptsCommand = message.tools.script_tuner.LoadScriptsCommand +import Scripts = message.tools.script_tuner.Scripts export class ScriptTunerNetwork { constructor(private network: Network, private model: ScriptTunerModel) { + this.network.on(Scripts, this.onScripts) } static of(nusightNetwork: NUsightNetwork, model: ScriptTunerModel): ScriptTunerNetwork { @@ -18,29 +20,28 @@ export class ScriptTunerNetwork { return new ScriptTunerNetwork(network, model) } + destroy() { + this.network.off() + } + @action requestScripts(robot: RobotModel) { this.startLoader(`Loading scripts from ${robot.name}...`) - setTimeout(() => { - this.onScripts() - this.stopLoader() - }, 5000) - } - - destroy() { - this.network.off() + const send = { + target: robot.name, + type: 'message.tools.script_tuner.LoadScriptsCommand', + payload: Buffer.from(LoadScriptsCommand.encode({}).finish()), + } + console.log('sending message', send) + this.network.send(send) } @action - private onScripts() { - this.model.scripts = [ - { - path: 'Salute.yaml', - servos: makeSampleServos(), - }, - ] - this.model.isLoading = false - this.model.loadingMessage = '' + private onScripts = (robotModel: RobotModel, scripts: Scripts) => { + console.log('scripts received', robotModel, scripts) + this.model.scripts = Scripts.toObject(scripts).scripts as Script[] + console.log(this.model.scripts) + this.stopLoader() } @action @@ -55,54 +56,3 @@ export class ScriptTunerNetwork { this.model.loadingMessage = '' } } - -function makeSampleServos(): Servo[] { - return [ - 'RIGHT_SHOULDER_PITCH', - 'LEFT_SHOULDER_PITCH', - 'RIGHT_SHOULDER_ROLL', - 'LEFT_SHOULDER_ROLL', - 'RIGHT_ELBOW', - 'LEFT_ELBOW', - 'RIGHT_HIP_YAW', - 'LEFT_HIP_YAW', - 'RIGHT_HIP_ROLL', - 'LEFT_HIP_ROLL', - 'RIGHT_HIP_PITCH', - 'LEFT_HIP_PITCH', - 'RIGHT_KNEE', - 'LEFT_KNEE', - 'RIGHT_ANKLE_PITCH', - 'LEFT_ANKLE_PITCH', - 'RIGHT_ANKLE_ROLL', - 'LEFT_ANKLE_ROLL', - 'HEAD_YAW', - 'HEAD_PITCH', - ].map(id => { - if (sampleScript[id]) { - return sampleScript[id] - } - - return makeSampleServo(id, 5, 0) - }) -} - -function makeSampleServo(id: string, length: number = 30, angle?: number): Servo { - const frames = [] - const period = 10 - - for (let i = 0; i <= length; i++) { - const theta = (2 * Math.PI * i) / period - - frames.push({ - time: i, - angle: angle !== undefined ? angle : 2 * Math.sin(theta), - pGain: 0, - iGain: 0, - dGain: 0, - torque: 0, - }) - } - - return { id, frames } -} diff --git a/src/client/components/script_tuner/preview/view_model.ts b/src/client/components/script_tuner/preview/view_model.ts index 4d37d282..fb24e9bb 100644 --- a/src/client/components/script_tuner/preview/view_model.ts +++ b/src/client/components/script_tuner/preview/view_model.ts @@ -39,164 +39,111 @@ export class ScriptRobot3dViewModel implements Robot3dViewModel { return this.model.selectedRobot ? this.model.selectedRobot.name : undefined } - @computed - get RIGHT_SHOULDER_PITCH() { + private getServoAngle(servoId: string) { const script = this.model.selectedScript - return script && script.servos[0].frames.length - ? getAngleAtCurrentTime(this.model.playTime, script.servos[0].frames) + return script && script.servos[servoId] && script.servos[servoId].frames.length + ? getAngleAtCurrentTime(this.model.playTime, script.servos[servoId].frames) : 0 } + @computed + get RIGHT_SHOULDER_PITCH() { + return this.getServoAngle('RIGHT_SHOULDER_PITCH') + } + @computed get LEFT_SHOULDER_PITCH() { - const script = this.model.selectedScript - return script && script.servos[1].frames.length - ? getAngleAtCurrentTime(this.model.playTime, script.servos[1].frames) - : 0 + return this.getServoAngle('LEFT_SHOULDER_PITCH') } @computed get RIGHT_SHOULDER_ROLL() { - const script = this.model.selectedScript - return script && script.servos[2].frames.length - ? getAngleAtCurrentTime(this.model.playTime, script.servos[2].frames) - : 0 + return this.getServoAngle('RIGHT_SHOULDER_ROLL') } @computed get LEFT_SHOULDER_ROLL() { - const script = this.model.selectedScript - return script && script.servos[3].frames.length - ? getAngleAtCurrentTime(this.model.playTime, script.servos[3].frames) - : 0 + return this.getServoAngle('LEFT_SHOULDER_ROLL') } @computed get RIGHT_ELBOW() { - const script = this.model.selectedScript - return script && script.servos[4].frames.length - ? getAngleAtCurrentTime(this.model.playTime, script.servos[4].frames) - : 0 + return this.getServoAngle('RIGHT_ELBOW') } @computed get LEFT_ELBOW() { - const script = this.model.selectedScript - return script && script.servos[5].frames.length - ? getAngleAtCurrentTime(this.model.playTime, script.servos[5].frames) - : 0 + return this.getServoAngle('LEFT_ELBOW') } @computed get RIGHT_HIP_YAW() { - const script = this.model.selectedScript - return script && script.servos[6].frames.length - ? getAngleAtCurrentTime(this.model.playTime, script.servos[6].frames) - : 0 + return this.getServoAngle('RIGHT_HIP_YAW') } @computed get LEFT_HIP_YAW() { - const script = this.model.selectedScript - return script && script.servos[7].frames.length - ? getAngleAtCurrentTime(this.model.playTime, script.servos[7].frames) - : 0 + return this.getServoAngle('LEFT_HIP_YAW') } @computed get RIGHT_HIP_ROLL() { - const script = this.model.selectedScript - return script && script.servos[8].frames.length - ? getAngleAtCurrentTime(this.model.playTime, script.servos[8].frames) - : 0 + return this.getServoAngle('RIGHT_HIP_ROLL') } @computed get LEFT_HIP_ROLL() { - const script = this.model.selectedScript - return script && script.servos[9].frames.length - ? getAngleAtCurrentTime(this.model.playTime, script.servos[9].frames) - : 0 + return this.getServoAngle('LEFT_HIP_ROLL') } @computed get RIGHT_HIP_PITCH() { - const script = this.model.selectedScript - return script && script.servos[10].frames.length - ? getAngleAtCurrentTime(this.model.playTime, script.servos[10].frames) - : 0 + return this.getServoAngle('RIGHT_HIP_PITCH') } @computed get LEFT_HIP_PITCH() { - const script = this.model.selectedScript - return script && script.servos[11].frames.length - ? getAngleAtCurrentTime(this.model.playTime, script.servos[11].frames) - : 0 + return this.getServoAngle('LEFT_HIP_PITCH') } @computed get RIGHT_KNEE() { - const script = this.model.selectedScript - return script && script.servos[12].frames.length - ? getAngleAtCurrentTime(this.model.playTime, script.servos[12].frames) - : 0 + return this.getServoAngle('RIGHT_KNEE') } @computed get LEFT_KNEE() { - const script = this.model.selectedScript - return script && script.servos[13].frames.length - ? getAngleAtCurrentTime(this.model.playTime, script.servos[13].frames) - : 0 + return this.getServoAngle('LEFT_KNEE') } @computed get RIGHT_ANKLE_PITCH() { - const script = this.model.selectedScript - return script && script.servos[14].frames.length - ? getAngleAtCurrentTime(this.model.playTime, script.servos[14].frames) - : 0 + return this.getServoAngle('RIGHT_ANKLE_PITCH') } @computed get LEFT_ANKLE_PITCH() { - const script = this.model.selectedScript - return script && script.servos[15].frames.length - ? getAngleAtCurrentTime(this.model.playTime, script.servos[15].frames) - : 0 + return this.getServoAngle('LEFT_ANKLE_PITCH') } @computed get RIGHT_ANKLE_ROLL() { - const script = this.model.selectedScript - return script && script.servos[16].frames.length - ? getAngleAtCurrentTime(this.model.playTime, script.servos[16].frames) - : 0 + return this.getServoAngle('RIGHT_ANKLE_ROLL') } @computed get LEFT_ANKLE_ROLL() { - const script = this.model.selectedScript - return script && script.servos[17].frames.length - ? getAngleAtCurrentTime(this.model.playTime, script.servos[17].frames) - : 0 + return this.getServoAngle('LEFT_ANKLE_ROLL') } @computed get HEAD_YAW() { - const script = this.model.selectedScript - return script && script.servos[18].frames.length - ? getAngleAtCurrentTime(this.model.playTime, script.servos[18].frames) - : 0 + return this.getServoAngle('HEAD_YAW') } @computed get HEAD_PITCH() { - const script = this.model.selectedScript - return script && script.servos[19].frames.length - ? getAngleAtCurrentTime(this.model.playTime, script.servos[19].frames) - : 0 + return this.getServoAngle('HEAD_PITCH') } } diff --git a/src/virtual_robots/run.ts b/src/virtual_robots/run.ts index 628bddca..53e69b4b 100644 --- a/src/virtual_robots/run.ts +++ b/src/virtual_robots/run.ts @@ -6,7 +6,7 @@ import { NUClearNetClient } from '../shared/nuclearnet/nuclearnet_client' import { Simulator } from './simulator' import { ChartSimulator } from './simulators/chart_data_simulator' import { OverviewSimulator } from './simulators/overview_simulator' -import { ScriptDataSimulator } from './simulators/script_data_simulator' +import { ScriptDataSimulator } from './simulators/script_data_simulator/script_data_simulator' import { SensorsSimulator } from './simulators/sensors_simulator' import { VirtualRobot } from './virtual_robot' import { VirtualRobots } from './virtual_robots' diff --git a/src/virtual_robots/simulators/script_data_simulator.ts b/src/virtual_robots/simulators/script_data_simulator.ts deleted file mode 100644 index d950e8f3..00000000 --- a/src/virtual_robots/simulators/script_data_simulator.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { action } from 'mobx' -import { NUClearNetPacket } from 'nuclearnet.js' - -import { NUClearNetClient } from '../../shared/nuclearnet/nuclearnet_client' -import { Simulator } from '../simulator' - -export class ScriptDataSimulator extends Simulator { - constructor(nuclearnetClient: NUClearNetClient) { - super(nuclearnetClient) - this.nuclearnetClient.on('message.input.Sensors', this.onSensors) - } - - static of({ nuclearnetClient }: { nuclearnetClient: NUClearNetClient }) { - return new ScriptDataSimulator(nuclearnetClient) - } - - start() { - // TODO - return () => 0 - } - - @action.bound - onSensors(packet: NUClearNetPacket) { - // console.log('ScriptDataSimulator: packet received', packet) - } -} diff --git a/src/client/components/script_tuner/sample-script.json b/src/virtual_robots/simulators/script_data_simulator/salute.json similarity index 100% rename from src/client/components/script_tuner/sample-script.json rename to src/virtual_robots/simulators/script_data_simulator/salute.json diff --git a/src/virtual_robots/simulators/script_data_simulator/script_data_simulator.ts b/src/virtual_robots/simulators/script_data_simulator/script_data_simulator.ts new file mode 100644 index 00000000..d1d0c331 --- /dev/null +++ b/src/virtual_robots/simulators/script_data_simulator/script_data_simulator.ts @@ -0,0 +1,49 @@ +import { action } from 'mobx' +import { NUClearNetPacket } from 'nuclearnet.js' + +import { NUClearNetClient } from '../../../shared/nuclearnet/nuclearnet_client' +import { message } from '../../../shared/proto/messages' +import { Simulator } from '../../simulator' + +import LoadScriptsCommand = message.tools.script_tuner.LoadScriptsCommand +import Scripts = message.tools.script_tuner.Scripts + +import * as SaluteScript from './salute.json' + +export class ScriptDataSimulator extends Simulator { + constructor(nuclearnetClient: NUClearNetClient) { + super(nuclearnetClient) + } + + static of({ nuclearnetClient }: { nuclearnetClient: NUClearNetClient }) { + return new ScriptDataSimulator(nuclearnetClient) + } + + start() { + console.log('ScriptDataSimulator Started') + + const off = this.nuclearnetClient.on('message.tools.script_tuner.LoadScriptsCommand', this.onLoadScripts) + + return () => { + off() + } + } + + @action.bound + onLoadScripts(packet: NUClearNetPacket) { + console.log('Load scripts command received', packet) + const scripts = { + scripts: [ + { + path: 'salute.yaml', + servos: SaluteScript, + }, + ], + } + this.send({ + messageType: 'message.tools.script_tuner.Scripts', + buffer: Scripts.encode(scripts).finish(), + }) + console.log('Responded with', scripts) + } +} diff --git a/src/virtual_robots/virtual_robots.ts b/src/virtual_robots/virtual_robots.ts index aaada609..2bf9221c 100644 --- a/src/virtual_robots/virtual_robots.ts +++ b/src/virtual_robots/virtual_robots.ts @@ -3,7 +3,7 @@ import { FakeNUClearNetClient } from '../server/nuclearnet/fake_nuclearnet_clien import { ChartSimulator } from './simulators/chart_data_simulator' import { OverviewSimulator } from './simulators/overview_simulator' -import { ScriptDataSimulator } from './simulators/script_data_simulator' +import { ScriptDataSimulator } from './simulators/script_data_simulator/script_data_simulator' import { SensorsSimulator } from './simulators/sensors_simulator' import { VisionSimulator } from './simulators/vision_simulator' import { VirtualRobot } from './virtual_robot' From 9b0bb809015859b2fa5121953c449f0381eee63c Mon Sep 17 00:00:00 2001 From: Josephus Paye II Date: Tue, 12 Feb 2019 21:56:27 +1100 Subject: [PATCH 43/54] Add more sample scripts, change all times in script tuner to be milliseconds Only switch to seconds when displaying or working with SVG --- .../script_tuner/editor/line/view.tsx | 4 +- .../script_tuner/editor/line/view_model.ts | 8 +- .../editor/timeline/view_model.ts | 9 +- .../script_tuner/editor/view_model.ts | 2 +- src/client/components/script_tuner/model.ts | 23 +- src/client/components/script_tuner/network.ts | 7 +- .../components/script_tuner/preview/view.tsx | 2 +- .../left_foot_power_kick.json | 1388 ++++++++++++ .../script_data_simulator/nod_no.json | 76 + .../script_data_simulator/nod_yes.json | 92 + .../right_foot_power_kick.json | 1388 ++++++++++++ .../script_data_simulator/salute.json | 1910 ++++++++--------- .../script_data_simulator.ts | 54 +- .../script_data_simulator/stand_up_back.json | 1270 +++++++++++ .../script_data_simulator/stand_up_front.json | 1030 +++++++++ 15 files changed, 6283 insertions(+), 980 deletions(-) create mode 100644 src/virtual_robots/simulators/script_data_simulator/left_foot_power_kick.json create mode 100644 src/virtual_robots/simulators/script_data_simulator/nod_no.json create mode 100644 src/virtual_robots/simulators/script_data_simulator/nod_yes.json create mode 100644 src/virtual_robots/simulators/script_data_simulator/right_foot_power_kick.json create mode 100644 src/virtual_robots/simulators/script_data_simulator/stand_up_back.json create mode 100644 src/virtual_robots/simulators/script_data_simulator/stand_up_front.json diff --git a/src/client/components/script_tuner/editor/line/view.tsx b/src/client/components/script_tuner/editor/line/view.tsx index e517c5ef..603e7b43 100644 --- a/src/client/components/script_tuner/editor/line/view.tsx +++ b/src/client/components/script_tuner/editor/line/view.tsx @@ -171,14 +171,14 @@ export class LineEditor extends Component { const index = Number(this.selectedElement.dataset.index!) const mouse = this.getMousePositionInSvgSpace(event) - const minFrameSeparation = 0.05 + const minFrameSeparation = 50 const previousFrameTime = index === 0 ? 0 - minFrameSeparation : viewModel.points[index - 1].time const nextFrameTime = index === viewModel.points.length - 1 - ? viewModel.points.length + minFrameSeparation + ? viewModel.svgToTime(viewModel.width) // this is the width of the timeline : viewModel.points[index + 1].time // The drag needs to be constrained between the points's neighbours diff --git a/src/client/components/script_tuner/editor/line/view_model.ts b/src/client/components/script_tuner/editor/line/view_model.ts index 05813837..5533e2dd 100644 --- a/src/client/components/script_tuner/editor/line/view_model.ts +++ b/src/client/components/script_tuner/editor/line/view_model.ts @@ -40,7 +40,7 @@ export class LineEditorViewModel { @computed get width() { - return this.editorViewModel.timelineLength * this.cellWidth + return Math.ceil(this.timeToSvg(this.editorViewModel.timelineLength)) } @computed @@ -50,7 +50,7 @@ export class LineEditorViewModel { @computed get playPosition() { - return this.editorViewModel.playTime * this.cellWidth + return this.timeToSvg(this.editorViewModel.playTime) } @computed @@ -88,11 +88,11 @@ export class LineEditorViewModel { } timeToSvg(time: number) { - return time * this.cellWidth + return (time / 1000) * this.cellWidth } svgToTime(coordinate: number) { - return coordinate / this.cellWidth + return (coordinate * 1000) / this.cellWidth } angleToSVG(angle: number) { diff --git a/src/client/components/script_tuner/editor/timeline/view_model.ts b/src/client/components/script_tuner/editor/timeline/view_model.ts index eb71e4d0..ba463d85 100644 --- a/src/client/components/script_tuner/editor/timeline/view_model.ts +++ b/src/client/components/script_tuner/editor/timeline/view_model.ts @@ -26,7 +26,7 @@ export class TimelineViewModel { @computed get width() { - return this.editorViewModel.timelineLength * this.cellWidth * this.scaleX + return this.timeToSvg(this.editorViewModel.timelineLength) } @computed @@ -41,7 +41,8 @@ export class TimelineViewModel { @computed get cells() { - return new Array(Math.ceil(this.editorViewModel.timelineLength * this.scaleX)).fill(0) + const timelineLengthSeconds = this.editorViewModel.timelineLength / 1000 + return new Array(Math.ceil(timelineLengthSeconds * this.scaleX)).fill(0) } @computed @@ -51,10 +52,10 @@ export class TimelineViewModel { } timeToSvg(time: number) { - return time * this.cellWidth * this.scaleX + return (time / 1000) * this.cellWidth * this.scaleX } svgToTime(coordinate: number) { - return coordinate / this.cellWidth / this.scaleX + return (coordinate * 1000) / this.cellWidth / this.scaleX } } diff --git a/src/client/components/script_tuner/editor/view_model.ts b/src/client/components/script_tuner/editor/view_model.ts index f5dbec86..ef654b9e 100644 --- a/src/client/components/script_tuner/editor/view_model.ts +++ b/src/client/components/script_tuner/editor/view_model.ts @@ -19,7 +19,7 @@ export class EditorViewModel { @computed get timelineLength() { - return this.model.scriptsLength + return this.model.timelineLength } @computed diff --git a/src/client/components/script_tuner/model.ts b/src/client/components/script_tuner/model.ts index 7a476618..be426f48 100644 --- a/src/client/components/script_tuner/model.ts +++ b/src/client/components/script_tuner/model.ts @@ -34,6 +34,7 @@ export class ScriptTunerModel { @observable isPlaying = false @observable currentTime = 0 @observable playStartedAt = 0 + previousTimelineLength = 0 constructor(robotModels: RobotModel[]) { this.robots = robotModels @@ -51,13 +52,13 @@ export class ScriptTunerModel { @computed get endTime() { - return Math.max(this.scriptsLength - 1, 0) + return Math.max(this.timelineLength - 1, 0) } @computed get playTime() { const time = this.isPlaying - ? this.currentTime + (now('frame') - this.playStartedAt) / 1000 + ? this.currentTime + (now('frame') - this.playStartedAt) : this.currentTime return time >= this.endTime ? this.endTime : time @@ -72,19 +73,29 @@ export class ScriptTunerModel { } @computed - get scriptsLength() { + get timelineLength() { if (this.selectedScript) { let maxLength = 0 this.selectedScriptServos.forEach(servo => { - if (servo.frames.length > maxLength) { - maxLength = servo.frames.length + const max = Math.max(...servo.frames.map((frame: Frame) => frame.time)) + + if (max > maxLength) { + maxLength = roundUpTo(1000 + max, 1000) } }) - return maxLength + if (maxLength > this.previousTimelineLength) { + this.previousTimelineLength = maxLength + } + + return this.previousTimelineLength } return 0 } } + +function roundUpTo(value: number, nearest: number) { + return Math.ceil(value / nearest) * nearest +} diff --git a/src/client/components/script_tuner/network.ts b/src/client/components/script_tuner/network.ts index 3da1642d..2b87ae7d 100644 --- a/src/client/components/script_tuner/network.ts +++ b/src/client/components/script_tuner/network.ts @@ -27,20 +27,17 @@ export class ScriptTunerNetwork { @action requestScripts(robot: RobotModel) { this.startLoader(`Loading scripts from ${robot.name}...`) - const send = { + this.network.send({ target: robot.name, type: 'message.tools.script_tuner.LoadScriptsCommand', payload: Buffer.from(LoadScriptsCommand.encode({}).finish()), - } - console.log('sending message', send) - this.network.send(send) + }) } @action private onScripts = (robotModel: RobotModel, scripts: Scripts) => { console.log('scripts received', robotModel, scripts) this.model.scripts = Scripts.toObject(scripts).scripts as Script[] - console.log(this.model.scripts) this.stopLoader() } diff --git a/src/client/components/script_tuner/preview/view.tsx b/src/client/components/script_tuner/preview/view.tsx index 25812523..eb9b7e34 100644 --- a/src/client/components/script_tuner/preview/view.tsx +++ b/src/client/components/script_tuner/preview/view.tsx @@ -29,7 +29,7 @@ export class Preview extends React.Component {
{ model.isPlaying ? 'Playing' : 'Paused' } - Time: {(Math.round(model.playTime * 1000) / 1000).toFixed(3)} + Time: {(model.playTime / 1000).toFixed(3)}
diff --git a/src/virtual_robots/simulators/script_data_simulator/left_foot_power_kick.json b/src/virtual_robots/simulators/script_data_simulator/left_foot_power_kick.json new file mode 100644 index 00000000..21d606eb --- /dev/null +++ b/src/virtual_robots/simulators/script_data_simulator/left_foot_power_kick.json @@ -0,0 +1,1388 @@ +{ + "LEFT_KNEE": { + "id": "LEFT_KNEE", + "frames": [ + { + "time": 1000, + "angle": 0.5, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2000, + "angle": 0.5, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3000, + "angle": 1.4, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4500, + "angle": 1.798265, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4698, + "angle": 0.613742, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5098, + "angle": 0.243963, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5798, + "angle": 0.998865, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6098, + "angle": 1.195263, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6598, + "angle": 0.575383, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 7598, + "angle": 0.7196127, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_HIP_PITCH": { + "id": "LEFT_HIP_PITCH", + "frames": [ + { + "time": 1000, + "angle": -0.35, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2000, + "angle": -0.45, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3000, + "angle": -0.8, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4500, + "angle": -1.132354, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4698, + "angle": -1.508271, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5098, + "angle": -0.885323, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5798, + "angle": -0.885323, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6098, + "angle": -0.885323, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6598, + "angle": -0.421948, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 7598, + "angle": -0.3943293, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_HIP_PITCH": { + "id": "RIGHT_HIP_PITCH", + "frames": [ + { + "time": 1000, + "angle": -0.35, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2000, + "angle": -0.45, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3000, + "angle": -0.45, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4500, + "angle": -0.928285, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4698, + "angle": -0.2746496, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5098, + "angle": -0.395864, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5798, + "angle": -0.395864, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6098, + "angle": -0.395864, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6598, + "angle": -0.395864, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 7598, + "angle": -0.3314207, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_KNEE": { + "id": "RIGHT_KNEE", + "frames": [ + { + "time": 1000, + "angle": 0.5, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2000, + "angle": 0.5, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3000, + "angle": 0.5, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4500, + "angle": 0.512475, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4698, + "angle": 1.502134, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5098, + "angle": 0.512475, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5798, + "angle": 0.512475, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6098, + "angle": 0.512475, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6598, + "angle": 0.512475, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 7598, + "angle": 0.6505667, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_ANKLE_PITCH": { + "id": "RIGHT_ANKLE_PITCH", + "frames": [ + { + "time": 1000, + "angle": -0.25, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2000, + "angle": -0.25, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3000, + "angle": -0.25, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4500, + "angle": -0.194863, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4698, + "angle": -0.9865905, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5098, + "angle": -0.194863, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5798, + "angle": -0.194863, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6098, + "angle": -0.194863, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6598, + "angle": -0.194863, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 7598, + "angle": -0.3421612, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_ANKLE_ROLL": { + "id": "RIGHT_ANKLE_ROLL", + "frames": [ + { + "time": 1000, + "angle": 0, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2000, + "angle": -0.27, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3000, + "angle": -0.32, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4500, + "angle": -0.28539, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4698, + "angle": -0.28539, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5098, + "angle": -0.280787, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5798, + "angle": -0.280787, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6098, + "angle": -0.273115, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6598, + "angle": -0.273115, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 7598, + "angle": 0.015344, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_ANKLE_PITCH": { + "id": "LEFT_ANKLE_PITCH", + "frames": [ + { + "time": 1000, + "angle": -0.25, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2000, + "angle": -0.25, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3000, + "angle": -0.8, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4500, + "angle": -0.8423611, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4698, + "angle": 0.328352, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5098, + "angle": 0.382054, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5798, + "angle": -0.105871, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6098, + "angle": -0.098199, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6598, + "angle": -0.173382, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 7598, + "angle": -0.3559704, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_ANKLE_ROLL": { + "id": "LEFT_ANKLE_ROLL", + "frames": [ + { + "time": 1000, + "angle": 0, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2000, + "angle": -0.27, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3000, + "angle": -0.42, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4500, + "angle": -0.018412, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4698, + "angle": -0.3743827, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5098, + "angle": -0.039893, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5798, + "angle": -0.018412, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6098, + "angle": -0.018412, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6598, + "angle": -0.2501, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 7598, + "angle": -0.029153, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_HIP_YAW": { + "id": "RIGHT_HIP_YAW", + "frames": [ + { + "time": 1000, + "angle": 0, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2000, + "angle": 0, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3000, + "angle": 0, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4500, + "angle": -0.030687, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4698, + "angle": -0.030687, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5098, + "angle": -0.030687, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5798, + "angle": -0.030687, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6098, + "angle": -0.030687, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6598, + "angle": -0.030687, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 7598, + "angle": -0.075183, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_HIP_YAW": { + "id": "LEFT_HIP_YAW", + "frames": [ + { + "time": 1000, + "angle": 0, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2000, + "angle": 0, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3000, + "angle": 0, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4500, + "angle": 0.019947, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4698, + "angle": 0.019947, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5098, + "angle": 0.019947, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5798, + "angle": 0.019947, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6098, + "angle": 0.019947, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6598, + "angle": 0.019947, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 7598, + "angle": -0.05984, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_HIP_ROLL": { + "id": "RIGHT_HIP_ROLL", + "frames": [ + { + "time": 1000, + "angle": 0, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2000, + "angle": 0.27, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3000, + "angle": 0.32, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4500, + "angle": 0.141161, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4698, + "angle": 0.141161, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5098, + "angle": 0.141161, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5798, + "angle": 0.141161, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6098, + "angle": 0.141161, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6598, + "angle": 0.141161, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 7598, + "angle": -0.02455, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_HIP_ROLL": { + "id": "LEFT_HIP_ROLL", + "frames": [ + { + "time": 1000, + "angle": 0, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2000, + "angle": 0.27, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3000, + "angle": 0.42, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4500, + "angle": 0.217878, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4698, + "angle": 0.217878, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5098, + "angle": 0.217878, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5798, + "angle": 0.217878, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6098, + "angle": 0.217878, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6598, + "angle": 0.210207, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 7598, + "angle": 0.003069, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_ELBOW": { + "id": "LEFT_ELBOW", + "frames": [ + { + "time": 4500, + "angle": -1.389742, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4698, + "angle": -1.389742, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5098, + "angle": -1.389742, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5798, + "angle": -1.389742, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6098, + "angle": -1.389742, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6598, + "angle": -1.389742, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 7598, + "angle": -1.389742, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_ELBOW": { + "id": "RIGHT_ELBOW", + "frames": [ + { + "time": 4500, + "angle": -1.144246, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4698, + "angle": -1.144246, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5098, + "angle": -1.144246, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5798, + "angle": -1.144246, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6098, + "angle": -1.144246, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6598, + "angle": -1.144246, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 7598, + "angle": -1.144246, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_SHOULDER_ROLL": { + "id": "LEFT_SHOULDER_ROLL", + "frames": [ + { + "time": 4500, + "angle": 0.524558, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4698, + "angle": 0.524558, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5098, + "angle": 0.524558, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5798, + "angle": 0.524558, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6098, + "angle": 0.524558, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6598, + "angle": 0.524558, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 7598, + "angle": 0.524558, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_SHOULDER_ROLL": { + "id": "RIGHT_SHOULDER_ROLL", + "frames": [ + { + "time": 4500, + "angle": -0.619688, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4698, + "angle": -0.619688, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5098, + "angle": -0.619688, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5798, + "angle": -0.619688, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6098, + "angle": -0.619688, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6598, + "angle": -0.619688, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 7598, + "angle": -0.619688, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_SHOULDER_PITCH": { + "id": "LEFT_SHOULDER_PITCH", + "frames": [ + { + "time": 4500, + "angle": 1.633705, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4698, + "angle": 1.633705, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5098, + "angle": 1.633705, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5798, + "angle": 1.633705, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6098, + "angle": 1.633705, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6598, + "angle": 1.633705, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 7598, + "angle": 1.633705, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_SHOULDER_PITCH": { + "id": "RIGHT_SHOULDER_PITCH", + "frames": [ + { + "time": 4500, + "angle": 1.65672, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4698, + "angle": 1.65672, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5098, + "angle": 1.65672, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5798, + "angle": 1.65672, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6098, + "angle": 1.65672, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6598, + "angle": 1.65672, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 7598, + "angle": 1.65672, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + } +} \ No newline at end of file diff --git a/src/virtual_robots/simulators/script_data_simulator/nod_no.json b/src/virtual_robots/simulators/script_data_simulator/nod_no.json new file mode 100644 index 00000000..1dad79bb --- /dev/null +++ b/src/virtual_robots/simulators/script_data_simulator/nod_no.json @@ -0,0 +1,76 @@ +{ + "HEAD_PITCH": { + "id": "HEAD_PITCH", + "frames": [ + { + "time": 190, + "angle": 0, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 380, + "angle": 0, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 570, + "angle": 0, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 660, + "angle": 0, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "HEAD_YAW": { + "id": "HEAD_YAW", + "frames": [ + { + "time": 190, + "angle": -0.5, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 380, + "angle": 0.5, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 570, + "angle": -0.5, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 660, + "angle": 0, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + } +} \ No newline at end of file diff --git a/src/virtual_robots/simulators/script_data_simulator/nod_yes.json b/src/virtual_robots/simulators/script_data_simulator/nod_yes.json new file mode 100644 index 00000000..5dcd6f70 --- /dev/null +++ b/src/virtual_robots/simulators/script_data_simulator/nod_yes.json @@ -0,0 +1,92 @@ +{ + "HEAD_PITCH": { + "id": "HEAD_PITCH", + "frames": [ + { + "time": 200, + "angle": -0.25, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 380, + "angle": 0.35, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 560, + "angle": -0.25, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 740, + "angle": 0.35, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 920, + "angle": -0.25, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "HEAD_YAW": { + "id": "HEAD_YAW", + "frames": [ + { + "time": 200, + "angle": 0, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 380, + "angle": 0, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 560, + "angle": 0, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 740, + "angle": 0, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 920, + "angle": 0, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + } +} \ No newline at end of file diff --git a/src/virtual_robots/simulators/script_data_simulator/right_foot_power_kick.json b/src/virtual_robots/simulators/script_data_simulator/right_foot_power_kick.json new file mode 100644 index 00000000..063e5683 --- /dev/null +++ b/src/virtual_robots/simulators/script_data_simulator/right_foot_power_kick.json @@ -0,0 +1,1388 @@ +{ + "RIGHT_KNEE": { + "id": "RIGHT_KNEE", + "frames": [ + { + "time": 1000, + "angle": 0.5, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2000, + "angle": 0.5, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3000, + "angle": 1.4, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4500, + "angle": 1.798265, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4700, + "angle": 0.613742, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5200, + "angle": 0.613742, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6200, + "angle": 0.613742, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 7200, + "angle": 0.613742, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 8200, + "angle": 2.066777, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 8398, + "angle": 2.066777, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_HIP_PITCH": { + "id": "RIGHT_HIP_PITCH", + "frames": [ + { + "time": 1000, + "angle": -0.35, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2000, + "angle": -0.45, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3000, + "angle": -0.8, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4500, + "angle": -1.132354, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4700, + "angle": -1.508271, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5200, + "angle": -1.508271, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6200, + "angle": -1.508271, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 7200, + "angle": -1.508271, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 8200, + "angle": -0.9160101, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 8398, + "angle": -0.9160101, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_HIP_PITCH": { + "id": "LEFT_HIP_PITCH", + "frames": [ + { + "time": 1000, + "angle": -0.35, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2000, + "angle": -0.45, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3000, + "angle": -0.45, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4500, + "angle": -0.928285, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4700, + "angle": -0.2746496, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5200, + "angle": -0.2746496, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6200, + "angle": -0.2746496, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 7200, + "angle": -0.2746496, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 8200, + "angle": -0.9635752, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 8398, + "angle": -0.9635752, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_KNEE": { + "id": "LEFT_KNEE", + "frames": [ + { + "time": 1000, + "angle": 0.5, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2000, + "angle": 0.5, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3000, + "angle": 0.5, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4500, + "angle": 0.512475, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4700, + "angle": 1.502134, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5200, + "angle": 1.2014, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6200, + "angle": 1.2014, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 7200, + "angle": 1.2014, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 8200, + "angle": 2.128151, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 8398, + "angle": 2.128151, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_ANKLE_PITCH": { + "id": "LEFT_ANKLE_PITCH", + "frames": [ + { + "time": 1000, + "angle": -0.25, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2000, + "angle": -0.25, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3000, + "angle": -0.25, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4500, + "angle": -0.194863, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4700, + "angle": -0.9865905, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5200, + "angle": -1.305736, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6200, + "angle": -1.305736, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 7200, + "angle": -1.305736, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 8200, + "angle": -1.143095, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 8398, + "angle": -1.143095, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_ANKLE_ROLL": { + "id": "LEFT_ANKLE_ROLL", + "frames": [ + { + "time": 1000, + "angle": 0, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2000, + "angle": 0.27, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3000, + "angle": 0.32, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4500, + "angle": 0.28539, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4700, + "angle": 0.28539, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5200, + "angle": -0.02608404, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6200, + "angle": -0.02608404, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 7200, + "angle": -0.02608404, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 8200, + "angle": 0.2777183, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 8398, + "angle": 0.04142759, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_ANKLE_PITCH": { + "id": "RIGHT_ANKLE_PITCH", + "frames": [ + { + "time": 1000, + "angle": -0.25, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2000, + "angle": -0.25, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3000, + "angle": -0.8, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4500, + "angle": -0.8423611, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4700, + "angle": 0.328352, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5200, + "angle": 0.5937955, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6200, + "angle": 0.5937955, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 7200, + "angle": 0.5937955, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 8200, + "angle": -1.063308, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 8398, + "angle": -1.063308, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_ANKLE_ROLL": { + "id": "RIGHT_ANKLE_ROLL", + "frames": [ + { + "time": 1000, + "angle": 0, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2000, + "angle": 0.27, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3000, + "angle": 0.42, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4500, + "angle": 0.018412, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4700, + "angle": 0.3743827, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5200, + "angle": 0.05983986, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6200, + "angle": 0.05983986, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 7200, + "angle": 0.05983986, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 8200, + "angle": 0.2715809, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 8398, + "angle": -0.01687791, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_HIP_YAW": { + "id": "LEFT_HIP_YAW", + "frames": [ + { + "time": 1000, + "angle": 0, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2000, + "angle": 0, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3000, + "angle": 0, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4500, + "angle": 0.030687, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4700, + "angle": 0.030687, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5200, + "angle": 0.030687, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6200, + "angle": 0.030687, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 7200, + "angle": 0.030687, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 8200, + "angle": 0.030687, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 8398, + "angle": 0.030687, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_HIP_YAW": { + "id": "RIGHT_HIP_YAW", + "frames": [ + { + "time": 1000, + "angle": 0, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2000, + "angle": 0, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3000, + "angle": 0, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4500, + "angle": -0.019947, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4700, + "angle": -0.019947, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5200, + "angle": -0.019947, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6200, + "angle": -0.019947, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 7200, + "angle": -0.019947, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 8200, + "angle": -0.019947, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 8398, + "angle": -0.019947, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_HIP_ROLL": { + "id": "LEFT_HIP_ROLL", + "frames": [ + { + "time": 1000, + "angle": 0, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2000, + "angle": -0.27, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3000, + "angle": -0.32, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4500, + "angle": -0.141161, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4700, + "angle": -0.141161, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5200, + "angle": -0.2393594, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6200, + "angle": -0.2393594, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 7200, + "angle": -0.2393594, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 8200, + "angle": -0.141161, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 8398, + "angle": 0.03222146, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_HIP_ROLL": { + "id": "RIGHT_HIP_ROLL", + "frames": [ + { + "time": 1000, + "angle": 0, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2000, + "angle": -0.27, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3000, + "angle": -0.42, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4500, + "angle": -0.217878, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4700, + "angle": -0.217878, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5200, + "angle": -0.2301533, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6200, + "angle": -0.2301533, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 7200, + "angle": -0.2301533, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 8200, + "angle": -0.217878, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 8398, + "angle": 0.05370244, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_ELBOW": { + "id": "RIGHT_ELBOW", + "frames": [ + { + "time": 4500, + "angle": -1.389742, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4700, + "angle": -1.389742, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5200, + "angle": -1.184139, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6200, + "angle": -1.184139, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 7200, + "angle": -1.184139, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 8200, + "angle": -1.389742, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 8398, + "angle": -1.389742, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_ELBOW": { + "id": "LEFT_ELBOW", + "frames": [ + { + "time": 4500, + "angle": -1.144246, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4700, + "angle": -1.144246, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5200, + "angle": -1.196414, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6200, + "angle": -1.196414, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 7200, + "angle": -1.196414, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 8200, + "angle": -1.144246, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 8398, + "angle": -1.144246, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_SHOULDER_ROLL": { + "id": "RIGHT_SHOULDER_ROLL", + "frames": [ + { + "time": 4500, + "angle": -0.524558, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4700, + "angle": -0.524558, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5200, + "angle": -1.49427, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6200, + "angle": -1.49427, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 7200, + "angle": -1.49427, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 8200, + "angle": -0.524558, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 8398, + "angle": -0.524558, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_SHOULDER_ROLL": { + "id": "LEFT_SHOULDER_ROLL", + "frames": [ + { + "time": 4500, + "angle": 0.619688, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4700, + "angle": 0.619688, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5200, + "angle": 1.121422, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6200, + "angle": 1.121422, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 7200, + "angle": 1.121422, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 8200, + "angle": 0.619688, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 8398, + "angle": 0.619688, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_SHOULDER_PITCH": { + "id": "RIGHT_SHOULDER_PITCH", + "frames": [ + { + "time": 4500, + "angle": 1.633705, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4700, + "angle": 1.633705, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5200, + "angle": 1.480269, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6200, + "angle": 1.480269, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 7200, + "angle": 1.480269, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 8200, + "angle": 1.633705, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 8398, + "angle": 1.633705, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_SHOULDER_PITCH": { + "id": "LEFT_SHOULDER_PITCH", + "frames": [ + { + "time": 4500, + "angle": 1.65672, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4700, + "angle": 1.65672, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 5200, + "angle": 1.527834, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 6200, + "angle": 1.527834, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 7200, + "angle": 1.527834, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 8200, + "angle": 1.65672, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 8398, + "angle": 1.65672, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + } +} \ No newline at end of file diff --git a/src/virtual_robots/simulators/script_data_simulator/salute.json b/src/virtual_robots/simulators/script_data_simulator/salute.json index 1385d59b..7fbe9a87 100644 --- a/src/virtual_robots/simulators/script_data_simulator/salute.json +++ b/src/virtual_robots/simulators/script_data_simulator/salute.json @@ -1,956 +1,956 @@ { - "LEFT_HIP_YAW": { - "id": "LEFT_HIP_YAW", - "frames": [ - { - "time": 1, - "angle": 0.02923973, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 1.6, - "angle": 0.02923973, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 1.8, - "angle": 0.02923973, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 2.4, - "angle": 0.02923973, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 2.6, - "angle": 0.02923973, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 3.4, - "angle": 0.02923973, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - } - ] - }, - "LEFT_HIP_ROLL": { - "id": "LEFT_HIP_ROLL", - "frames": [ - { - "time": 1, - "angle": 0.06261409, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 1.6, - "angle": 0.06261409, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 1.8, - "angle": 0.06261409, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 2.4, - "angle": 0.06261409, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 2.6, - "angle": 0.06261409, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 3.4, - "angle": 0.06261409, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - } - ] - }, - "LEFT_HIP_PITCH": { - "id": "LEFT_HIP_PITCH", - "frames": [ - { - "time": 1, - "angle": -1.215349, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 1.6, - "angle": -0.6137422, - "pGain": 80, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 1.8, - "angle": -0.6137422, - "pGain": 80, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 2.4, - "angle": -0.6137422, - "pGain": 80, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 2.6, - "angle": -0.6137422, - "pGain": 80, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 3.4, - "angle": -1.215349, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - } - ] - }, - "LEFT_KNEE": { - "id": "LEFT_KNEE", - "frames": [ - { - "time": 1, - "angle": 1.34201, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 1.6, - "angle": 0.5968642, - "pGain": 80, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 1.8, - "angle": 0.5968642, - "pGain": 80, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 2.4, - "angle": 0.5968642, - "pGain": 80, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 2.6, - "angle": 0.5968642, - "pGain": 80, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 3.4, - "angle": 1.34201, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - } - ] - }, - "LEFT_ANKLE_PITCH": { - "id": "LEFT_ANKLE_PITCH", - "frames": [ - { - "time": 1, - "angle": -0.5639089, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 1.6, - "angle": -0.276184, - "pGain": 80, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 1.8, - "angle": -0.276184, - "pGain": 80, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 2.4, - "angle": -0.276184, - "pGain": 80, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 2.6, - "angle": -0.276184, - "pGain": 80, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 3.4, - "angle": -0.5639089, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - } - ] - }, - "LEFT_ANKLE_ROLL": { - "id": "LEFT_ANKLE_ROLL", - "frames": [ - { - "time": 1, - "angle": -0.06909663, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 1.6, - "angle": -0.06909663, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 1.8, - "angle": -0.06909663, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 2.4, - "angle": -0.06909663, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 2.6, - "angle": -0.06909663, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 3.4, - "angle": -0.06909663, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - } - ] - }, - "RIGHT_HIP_YAW": { - "id": "RIGHT_HIP_YAW", - "frames": [ - { - "time": 1, - "angle": -0.02923973, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 1.6, - "angle": -0.02923973, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 1.8, - "angle": -0.02923973, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 2.4, - "angle": -0.02923973, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 2.6, - "angle": -0.02923973, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 3.4, - "angle": -0.02923973, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - } - ] - }, - "RIGHT_HIP_ROLL": { - "id": "RIGHT_HIP_ROLL", - "frames": [ - { - "time": 1, - "angle": -0.06261409, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 1.6, - "angle": -0.06261409, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 1.8, - "angle": -0.06261409, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 2.4, - "angle": -0.06261409, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 2.6, - "angle": -0.06261409, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 3.4, - "angle": -0.06261409, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - } - ] - }, - "RIGHT_HIP_PITCH": { - "id": "RIGHT_HIP_PITCH", - "frames": [ - { - "time": 1, - "angle": -1.215349, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 1.6, - "angle": -0.6904599, - "pGain": 80, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 1.8, - "angle": -0.6904599, - "pGain": 80, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 2.4, - "angle": -0.6904599, - "pGain": 80, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 2.6, - "angle": -0.6904599, - "pGain": 80, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 3.4, - "angle": -1.215349, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - } - ] - }, - "RIGHT_KNEE": { - "id": "RIGHT_KNEE", - "frames": [ - { - "time": 1, - "angle": 1.34201, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 1.6, - "angle": 0.6628415, - "pGain": 80, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 1.8, - "angle": 0.6628415, - "pGain": 80, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 2.4, - "angle": 0.6628415, - "pGain": 80, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 2.6, - "angle": 0.6628415, - "pGain": 80, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 3.4, - "angle": 1.34201, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - } - ] - }, - "RIGHT_ANKLE_PITCH": { - "id": "RIGHT_ANKLE_PITCH", - "frames": [ - { - "time": 1, - "angle": -0.5639089, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 1.6, - "angle": -0.2731152, - "pGain": 80, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 1.8, - "angle": -0.2731152, - "pGain": 80, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 2.4, - "angle": -0.2731152, - "pGain": 80, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 2.6, - "angle": -0.2731152, - "pGain": 80, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 3.4, - "angle": -0.5639089, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - } - ] - }, - "RIGHT_ANKLE_ROLL": { - "id": "RIGHT_ANKLE_ROLL", - "frames": [ - { - "time": 1, - "angle": 0.06909663, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 1.6, - "angle": 0.06909663, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 1.8, - "angle": 0.06909663, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 2.4, - "angle": 0.06909663, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 2.6, - "angle": 0.06909663, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 3.4, - "angle": 0.06909663, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - } - ] - }, - "RIGHT_SHOULDER_PITCH": { - "id": "RIGHT_SHOULDER_PITCH", - "frames": [ - { - "time": 1, - "angle": 1.963495, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 1.6, - "angle": 1.543178, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 1.8, - "angle": 1.618361, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 2.4, - "angle": 1.618361, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 2.6, - "angle": 1.618361, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 3.4, - "angle": 1.963495, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - } - ] - }, - "RIGHT_SHOULDER_ROLL": { - "id": "RIGHT_SHOULDER_ROLL", - "frames": [ - { - "time": 1, - "angle": -0.1239184, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 1.6, - "angle": -0.1239184, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 1.8, - "angle": -0.1239184, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 2.4, - "angle": -0.1239184, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 2.6, - "angle": -0.1239184, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 3.4, - "angle": -0.1239184, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - } - ] - }, - "RIGHT_ELBOW": { - "id": "RIGHT_ELBOW", - "frames": [ - { - "time": 1, - "angle": -2.443461, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 1.6, - "angle": -0.7269009, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 1.8, - "angle": -0.5642592, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 2.4, - "angle": -0.5642592, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 2.6, - "angle": -0.5642592, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 3.4, - "angle": -2.443461, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - } - ] - }, - "LEFT_SHOULDER_PITCH": { - "id": "LEFT_SHOULDER_PITCH", - "frames": [ - { - "time": 1, - "angle": 1.963495, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 1.6, - "angle": -0.06942958, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 1.8, - "angle": 0.3417777, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 2.4, - "angle": 0.3417777, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 2.6, - "angle": 0.200617, - "pGain": 80, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 3.4, - "angle": 1.963495, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - } - ] - }, - "LEFT_SHOULDER_ROLL": { - "id": "LEFT_SHOULDER_ROLL", - "frames": [ - { - "time": 1, - "angle": 0.1239184, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 1.6, - "angle": 0.9403681, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 1.8, - "angle": 0.9403681, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 2.4, - "angle": 0.9403681, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 2.6, - "angle": 0.9403681, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 3.4, - "angle": 0.1239184, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - } - ] - }, - "LEFT_ELBOW": { - "id": "LEFT_ELBOW", - "frames": [ - { - "time": 1, - "angle": -2.443461, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 1.6, - "angle": -1.527834, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 1.8, - "angle": -2.313424, - "pGain": 50, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 2.4, - "angle": -2.313424, - "pGain": 50, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 2.6, - "angle": -1.603018, - "pGain": 30, - "iGain": 0, - "dGain": 0, - "torque": 100 - }, - { - "time": 3.4, - "angle": -2.443461, - "pGain": 50, - "iGain": 0, - "dGain": 0, - "torque": 100 - } - ] - } -} + "LEFT_HIP_YAW": { + "id": "LEFT_HIP_YAW", + "frames": [ + { + "time": 1000, + "angle": 0.02923973, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1600, + "angle": 0.02923973, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1800, + "angle": 0.02923973, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2400, + "angle": 0.02923973, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2600, + "angle": 0.02923973, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3400, + "angle": 0.02923973, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_HIP_ROLL": { + "id": "LEFT_HIP_ROLL", + "frames": [ + { + "time": 1000, + "angle": 0.06261409, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1600, + "angle": 0.06261409, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1800, + "angle": 0.06261409, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2400, + "angle": 0.06261409, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2600, + "angle": 0.06261409, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3400, + "angle": 0.06261409, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_HIP_PITCH": { + "id": "LEFT_HIP_PITCH", + "frames": [ + { + "time": 1000, + "angle": -1.215349, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1600, + "angle": -0.6137422, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1800, + "angle": -0.6137422, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2400, + "angle": -0.6137422, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2600, + "angle": -0.6137422, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3400, + "angle": -1.215349, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_KNEE": { + "id": "LEFT_KNEE", + "frames": [ + { + "time": 1000, + "angle": 1.34201, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1600, + "angle": 0.5968642, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1800, + "angle": 0.5968642, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2400, + "angle": 0.5968642, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2600, + "angle": 0.5968642, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3400, + "angle": 1.34201, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_ANKLE_PITCH": { + "id": "LEFT_ANKLE_PITCH", + "frames": [ + { + "time": 1000, + "angle": -0.5639089, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1600, + "angle": -0.276184, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1800, + "angle": -0.276184, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2400, + "angle": -0.276184, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2600, + "angle": -0.276184, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3400, + "angle": -0.5639089, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_ANKLE_ROLL": { + "id": "LEFT_ANKLE_ROLL", + "frames": [ + { + "time": 1000, + "angle": -0.06909663, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1600, + "angle": -0.06909663, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1800, + "angle": -0.06909663, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2400, + "angle": -0.06909663, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2600, + "angle": -0.06909663, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3400, + "angle": -0.06909663, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_HIP_YAW": { + "id": "RIGHT_HIP_YAW", + "frames": [ + { + "time": 1000, + "angle": -0.02923973, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1600, + "angle": -0.02923973, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1800, + "angle": -0.02923973, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2400, + "angle": -0.02923973, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2600, + "angle": -0.02923973, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3400, + "angle": -0.02923973, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_HIP_ROLL": { + "id": "RIGHT_HIP_ROLL", + "frames": [ + { + "time": 1000, + "angle": -0.06261409, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1600, + "angle": -0.06261409, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1800, + "angle": -0.06261409, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2400, + "angle": -0.06261409, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2600, + "angle": -0.06261409, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3400, + "angle": -0.06261409, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_HIP_PITCH": { + "id": "RIGHT_HIP_PITCH", + "frames": [ + { + "time": 1000, + "angle": -1.215349, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1600, + "angle": -0.6904599, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1800, + "angle": -0.6904599, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2400, + "angle": -0.6904599, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2600, + "angle": -0.6904599, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3400, + "angle": -1.215349, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_KNEE": { + "id": "RIGHT_KNEE", + "frames": [ + { + "time": 1000, + "angle": 1.34201, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1600, + "angle": 0.6628415, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1800, + "angle": 0.6628415, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2400, + "angle": 0.6628415, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2600, + "angle": 0.6628415, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3400, + "angle": 1.34201, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_ANKLE_PITCH": { + "id": "RIGHT_ANKLE_PITCH", + "frames": [ + { + "time": 1000, + "angle": -0.5639089, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1600, + "angle": -0.2731152, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1800, + "angle": -0.2731152, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2400, + "angle": -0.2731152, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2600, + "angle": -0.2731152, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3400, + "angle": -0.5639089, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_ANKLE_ROLL": { + "id": "RIGHT_ANKLE_ROLL", + "frames": [ + { + "time": 1000, + "angle": 0.06909663, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1600, + "angle": 0.06909663, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1800, + "angle": 0.06909663, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2400, + "angle": 0.06909663, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2600, + "angle": 0.06909663, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3400, + "angle": 0.06909663, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_SHOULDER_PITCH": { + "id": "RIGHT_SHOULDER_PITCH", + "frames": [ + { + "time": 1000, + "angle": 1.963495, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1600, + "angle": 1.543178, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1800, + "angle": 1.618361, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2400, + "angle": 1.618361, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2600, + "angle": 1.618361, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3400, + "angle": 1.963495, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_SHOULDER_ROLL": { + "id": "RIGHT_SHOULDER_ROLL", + "frames": [ + { + "time": 1000, + "angle": -0.1239184, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1600, + "angle": -0.1239184, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1800, + "angle": -0.1239184, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2400, + "angle": -0.1239184, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2600, + "angle": -0.1239184, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3400, + "angle": -0.1239184, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_ELBOW": { + "id": "RIGHT_ELBOW", + "frames": [ + { + "time": 1000, + "angle": -2.443461, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1600, + "angle": -0.7269009, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1800, + "angle": -0.5642592, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2400, + "angle": -0.5642592, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2600, + "angle": -0.5642592, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3400, + "angle": -2.443461, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_SHOULDER_PITCH": { + "id": "LEFT_SHOULDER_PITCH", + "frames": [ + { + "time": 1000, + "angle": 1.963495, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1600, + "angle": -0.06942958, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1800, + "angle": 0.3417777, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2400, + "angle": 0.3417777, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2600, + "angle": 0.200617, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3400, + "angle": 1.963495, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_SHOULDER_ROLL": { + "id": "LEFT_SHOULDER_ROLL", + "frames": [ + { + "time": 1000, + "angle": 0.1239184, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1600, + "angle": 0.9403681, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1800, + "angle": 0.9403681, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2400, + "angle": 0.9403681, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2600, + "angle": 0.9403681, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3400, + "angle": 0.1239184, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_ELBOW": { + "id": "LEFT_ELBOW", + "frames": [ + { + "time": 1000, + "angle": -2.443461, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1600, + "angle": -1.527834, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1800, + "angle": -2.313424, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2400, + "angle": -2.313424, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2600, + "angle": -1.603018, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3400, + "angle": -2.443461, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + } +} \ No newline at end of file diff --git a/src/virtual_robots/simulators/script_data_simulator/script_data_simulator.ts b/src/virtual_robots/simulators/script_data_simulator/script_data_simulator.ts index d1d0c331..6c6d32d6 100644 --- a/src/virtual_robots/simulators/script_data_simulator/script_data_simulator.ts +++ b/src/virtual_robots/simulators/script_data_simulator/script_data_simulator.ts @@ -8,7 +8,17 @@ import { Simulator } from '../../simulator' import LoadScriptsCommand = message.tools.script_tuner.LoadScriptsCommand import Scripts = message.tools.script_tuner.Scripts -import * as SaluteScript from './salute.json' +import * as Bow from './bow.json' +import * as Jump from './jump.json' +import * as LeftFootPowerKick from './left_foot_power_kick.json' +import * as NodNo from './nod_no.json' +import * as NodYes from './nod_yes.json' +import * as RightFootPowerKick from './right_foot_power_kick.json' +import * as Salute from './salute.json' +import * as Stand from './stand.json' +import * as StandUpBack from './stand_up_back.json' +import * as StandUpFront from './stand_up_front.json' +import * as Zombie from './zombie.json' export class ScriptDataSimulator extends Simulator { constructor(nuclearnetClient: NUClearNetClient) { @@ -34,9 +44,49 @@ export class ScriptDataSimulator extends Simulator { console.log('Load scripts command received', packet) const scripts = { scripts: [ + { + path: 'bow.yaml', + servos: Bow, + }, + { + path: 'jump.yaml', + servos: Jump, + }, + { + path: 'left_foot_power_kick.yaml', + servos: LeftFootPowerKick, + }, + { + path: 'nod_no.yaml', + servos: NodNo, + }, + { + path: 'nod_yes.yaml', + servos: NodYes, + }, + { + path: 'right_foot_power_kick.yaml', + servos: RightFootPowerKick, + }, { path: 'salute.yaml', - servos: SaluteScript, + servos: Salute, + }, + { + path: 'stand.yaml', + servos: Stand, + }, + { + path: 'stand_up_back.yaml', + servos: StandUpBack, + }, + { + path: 'stand_up_front.yaml', + servos: StandUpFront, + }, + { + path: 'zombie.yaml', + servos: Zombie, }, ], } diff --git a/src/virtual_robots/simulators/script_data_simulator/stand_up_back.json b/src/virtual_robots/simulators/script_data_simulator/stand_up_back.json new file mode 100644 index 00000000..9c37afbf --- /dev/null +++ b/src/virtual_robots/simulators/script_data_simulator/stand_up_back.json @@ -0,0 +1,1270 @@ +{ + "RIGHT_SHOULDER_PITCH": { + "id": "RIGHT_SHOULDER_PITCH", + "frames": [ + { + "time": 600, + "angle": 2.15269, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1000, + "angle": 3.79916, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1500, + "angle": 4.0855, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2100, + "angle": 3.3901, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2800, + "angle": 3.069862, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3400, + "angle": 2.669395, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3900, + "angle": 1.60557, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4500, + "angle": 2.47, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_SHOULDER_PITCH": { + "id": "LEFT_SHOULDER_PITCH", + "frames": [ + { + "time": 600, + "angle": 2.15269, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1000, + "angle": 3.79916, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1500, + "angle": 4.0855, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2100, + "angle": 3.3901, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2800, + "angle": -3.085972, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3400, + "angle": 2.618761, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3900, + "angle": 1.60557, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4500, + "angle": 2.469929, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_SHOULDER_ROLL": { + "id": "RIGHT_SHOULDER_ROLL", + "frames": [ + { + "time": 600, + "angle": -0.199418, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1000, + "angle": -0.1471063, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1500, + "angle": -0.1394345, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2100, + "angle": -0.14, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2800, + "angle": -0.14, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3400, + "angle": -0.14, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3900, + "angle": -0.138058, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4500, + "angle": -0.42, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_SHOULDER_ROLL": { + "id": "LEFT_SHOULDER_ROLL", + "frames": [ + { + "time": 600, + "angle": 0.199418, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1000, + "angle": 0.2652517, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1500, + "angle": 0.2821296, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2100, + "angle": 0.28, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2800, + "angle": 0.28, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3400, + "angle": 0.28, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3900, + "angle": 0.28, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4500, + "angle": 0.42, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_ELBOW": { + "id": "RIGHT_ELBOW", + "frames": [ + { + "time": 600, + "angle": -0.802783, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1000, + "angle": -2.57197, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1500, + "angle": -1.8101, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2100, + "angle": -0.480647, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2800, + "angle": 0.04488, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3400, + "angle": -0.3448464, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3900, + "angle": -0.639159, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4500, + "angle": -2.5, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_ELBOW": { + "id": "LEFT_ELBOW", + "frames": [ + { + "time": 600, + "angle": -0.802783, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1000, + "angle": -2.57197, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1500, + "angle": -1.8101, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2100, + "angle": -0.480647, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2800, + "angle": 0.029536, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3400, + "angle": -0.2543194, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3900, + "angle": -0.639159, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4500, + "angle": -2.5, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_HIP_YAW": { + "id": "RIGHT_HIP_YAW", + "frames": [ + { + "time": 600, + "angle": 0, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1000, + "angle": 0, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1500, + "angle": 0, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2100, + "angle": 0, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2800, + "angle": -0.018412, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3400, + "angle": 0, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3900, + "angle": 0, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4500, + "angle": 0, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_HIP_YAW": { + "id": "LEFT_HIP_YAW", + "frames": [ + { + "time": 600, + "angle": 0, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1000, + "angle": 0, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1500, + "angle": 0, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2100, + "angle": 0, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2800, + "angle": 0.023015, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3400, + "angle": 0, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3900, + "angle": 0, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4500, + "angle": 0, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_HIP_ROLL": { + "id": "RIGHT_HIP_ROLL", + "frames": [ + { + "time": 600, + "angle": 0, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1000, + "angle": 0, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1500, + "angle": 0, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2100, + "angle": 0, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2800, + "angle": -0.016878, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3400, + "angle": 0, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3900, + "angle": 0, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4500, + "angle": -0.055, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_HIP_ROLL": { + "id": "LEFT_HIP_ROLL", + "frames": [ + { + "time": 600, + "angle": 0, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1000, + "angle": 0, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1500, + "angle": 0, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2100, + "angle": 0, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2800, + "angle": -0.026084, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3400, + "angle": 0, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3900, + "angle": 0, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4500, + "angle": 0.055, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_HIP_PITCH": { + "id": "RIGHT_HIP_PITCH", + "frames": [ + { + "time": 600, + "angle": -1.09424, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1000, + "angle": -0.76699, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1500, + "angle": -1.2323, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2100, + "angle": 0.5078716, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2800, + "angle": 0.509406, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3400, + "angle": 0.5048029, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3900, + "angle": -0.5011, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4500, + "angle": -0.77, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_HIP_PITCH": { + "id": "LEFT_HIP_PITCH", + "frames": [ + { + "time": 600, + "angle": -1.08913, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1000, + "angle": -0.787443, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1500, + "angle": -1.19651, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2100, + "angle": 0.4127416, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2800, + "angle": 0.5124747, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3400, + "angle": 0.5124747, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3900, + "angle": -0.572686, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4500, + "angle": -0.77, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_KNEE": { + "id": "RIGHT_KNEE", + "frames": [ + { + "time": 600, + "angle": 1.66181, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1000, + "angle": 1.59534, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1500, + "angle": 1.76919, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2100, + "angle": 0.7134752, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2800, + "angle": 1.950166, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3400, + "angle": 1.88112, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3900, + "angle": 1.7, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4500, + "angle": 2.08, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_KNEE": { + "id": "LEFT_KNEE", + "frames": [ + { + "time": 600, + "angle": 1.69249, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1000, + "angle": 1.61579, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1500, + "angle": 1.77942, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2100, + "angle": 0.8070709, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2800, + "angle": 1.873448, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3400, + "angle": 1.871914, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3900, + "angle": 1.7, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4500, + "angle": 2.08, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_ANKLE_PITCH": { + "id": "RIGHT_ANKLE_PITCH", + "frames": [ + { + "time": 600, + "angle": -0.792557, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1000, + "angle": 0.455081, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1500, + "angle": 0.453722, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2100, + "angle": 0.24, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2800, + "angle": -1.175316, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3400, + "angle": -1.716944, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3900, + "angle": -1.00013, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4500, + "angle": -1.31, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_ANKLE_PITCH": { + "id": "LEFT_ANKLE_PITCH", + "frames": [ + { + "time": 600, + "angle": -0.736311, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1000, + "angle": 0.465308, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1500, + "angle": 0.457249, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2100, + "angle": 0.24, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2800, + "angle": -1.140026, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3400, + "angle": -1.588058, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3900, + "angle": -1.00013, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4500, + "angle": -1.31, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_ANKLE_ROLL": { + "id": "RIGHT_ANKLE_ROLL", + "frames": [ + { + "time": 600, + "angle": 0.092039, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1000, + "angle": 0.178964, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1500, + "angle": -0.035793, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2100, + "angle": -0.025566, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2800, + "angle": -0.009206, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3400, + "angle": -0.01994662, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3900, + "angle": 0.035793, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4500, + "angle": 0.055, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_ANKLE_ROLL": { + "id": "LEFT_ANKLE_ROLL", + "frames": [ + { + "time": 600, + "angle": 0.097152, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1000, + "angle": 0.046019, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1500, + "angle": -0.010227, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2100, + "angle": -0.102265, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2800, + "angle": 0.023015, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3400, + "angle": -0.071586, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 3900, + "angle": -0.061359, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 4500, + "angle": -0.055, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "HEAD_YAW": { + "id": "HEAD_YAW", + "frames": [ + { + "time": 600, + "angle": 0, + "pGain": 10, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "HEAD_PITCH": { + "id": "HEAD_PITCH", + "frames": [ + { + "time": 600, + "angle": 0.9697126, + "pGain": 10, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + } +} \ No newline at end of file diff --git a/src/virtual_robots/simulators/script_data_simulator/stand_up_front.json b/src/virtual_robots/simulators/script_data_simulator/stand_up_front.json new file mode 100644 index 00000000..c365d292 --- /dev/null +++ b/src/virtual_robots/simulators/script_data_simulator/stand_up_front.json @@ -0,0 +1,1030 @@ +{ + "RIGHT_SHOULDER_PITCH": { + "id": "RIGHT_SHOULDER_PITCH", + "frames": [ + { + "time": 700, + "angle": 3.13955, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1150, + "angle": 0.772104, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1800, + "angle": -0.1860406, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2100, + "angle": 0.7806033, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2350, + "angle": 0.6041524, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2850, + "angle": 2.47, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_SHOULDER_PITCH": { + "id": "LEFT_SHOULDER_PITCH", + "frames": [ + { + "time": 700, + "angle": 3.13955, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1150, + "angle": 0.772104, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1800, + "angle": -0.1077885, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2100, + "angle": 0.8327714, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2350, + "angle": 0.6839389, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2850, + "angle": 2.469929, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_SHOULDER_ROLL": { + "id": "RIGHT_SHOULDER_ROLL", + "frames": [ + { + "time": 700, + "angle": -0.066473, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1150, + "angle": -0.158511, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1800, + "angle": 0.035793, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2100, + "angle": -0.04277015, + "pGain": 10, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2350, + "angle": -0.04277015, + "pGain": 10, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2850, + "angle": -0.42, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_SHOULDER_ROLL": { + "id": "LEFT_SHOULDER_ROLL", + "frames": [ + { + "time": 700, + "angle": 0.066473, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1150, + "angle": 0.158511, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1800, + "angle": -0.035793, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2100, + "angle": 0.09186953, + "pGain": 10, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2350, + "angle": 0.09186953, + "pGain": 10, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2850, + "angle": 0.42, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_ELBOW": { + "id": "RIGHT_ELBOW", + "frames": [ + { + "time": 700, + "angle": -2.6589, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1150, + "angle": -2.71003, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1800, + "angle": -0.25055, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2100, + "angle": -1.079803, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2350, + "angle": -0.07633418, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2850, + "angle": -2.5, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_ELBOW": { + "id": "LEFT_ELBOW", + "frames": [ + { + "time": 700, + "angle": -2.6589, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1150, + "angle": -2.71003, + "pGain": 30, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1800, + "angle": -0.25055, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2100, + "angle": -1.188742, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2350, + "angle": -0.3187623, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2850, + "angle": -2.5, + "pGain": 20, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_HIP_YAW": { + "id": "RIGHT_HIP_YAW", + "frames": [ + { + "time": 700, + "angle": -0.020453, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1150, + "angle": -0.025566, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1800, + "angle": 0.025566, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2100, + "angle": 0.025566, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2350, + "angle": 0.025566, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2850, + "angle": 0, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_HIP_YAW": { + "id": "LEFT_HIP_YAW", + "frames": [ + { + "time": 700, + "angle": 0.020453, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1150, + "angle": 0.025566, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1800, + "angle": -0.025566, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2100, + "angle": -0.025566, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2350, + "angle": -0.025566, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2850, + "angle": 0, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_HIP_ROLL": { + "id": "RIGHT_HIP_ROLL", + "frames": [ + { + "time": 700, + "angle": 0, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1150, + "angle": 0.01534, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1800, + "angle": -0.025566, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2100, + "angle": -0.025566, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2350, + "angle": -0.025566, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2850, + "angle": -0.055, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_HIP_ROLL": { + "id": "LEFT_HIP_ROLL", + "frames": [ + { + "time": 700, + "angle": 0, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1150, + "angle": -0.01534, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1800, + "angle": 0.025566, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2100, + "angle": 0.02915275, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2350, + "angle": 0.02915275, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2850, + "angle": 0.055, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_HIP_PITCH": { + "id": "RIGHT_HIP_PITCH", + "frames": [ + { + "time": 700, + "angle": -0.271003, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1150, + "angle": -1.64647, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1800, + "angle": -1.848898, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2100, + "angle": -1.901066, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2350, + "angle": -1.901066, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2850, + "angle": -1.143095, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_HIP_PITCH": { + "id": "LEFT_HIP_PITCH", + "frames": [ + { + "time": 700, + "angle": -0.271003, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1150, + "angle": -1.64647, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1800, + "angle": -1.925616, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2100, + "angle": -1.899532, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2350, + "angle": -1.899532, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2850, + "angle": -1.287324, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_KNEE": { + "id": "RIGHT_KNEE", + "frames": [ + { + "time": 700, + "angle": 0.424401, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1150, + "angle": 1.03288, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1800, + "angle": 1.067911, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2100, + "angle": 2.290793, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2350, + "angle": 2.290793, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2850, + "angle": 2.21254, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_KNEE": { + "id": "LEFT_KNEE", + "frames": [ + { + "time": 700, + "angle": 0.424401, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1150, + "angle": 1.03288, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1800, + "angle": 1.01114, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2100, + "angle": 2.290793, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2350, + "angle": 2.290793, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2850, + "angle": 2.197197, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_ANKLE_PITCH": { + "id": "RIGHT_ANKLE_PITCH", + "frames": [ + { + "time": 700, + "angle": -1.05333, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1150, + "angle": -1.36524, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1800, + "angle": -0.7763838, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2100, + "angle": -1.144629, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2350, + "angle": -1.144629, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2850, + "angle": -1.224416, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_ANKLE_PITCH": { + "id": "LEFT_ANKLE_PITCH", + "frames": [ + { + "time": 700, + "angle": -1.05333, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1150, + "angle": -1.36524, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1800, + "angle": -0.6812538, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2100, + "angle": -1.135423, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2350, + "angle": -1.135423, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2850, + "angle": -1.117011, + "pGain": 80, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "RIGHT_ANKLE_ROLL": { + "id": "RIGHT_ANKLE_ROLL", + "frames": [ + { + "time": 700, + "angle": 0.01534, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1150, + "angle": 0.046019, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1800, + "angle": 0.03068, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2100, + "angle": 0.03068, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2350, + "angle": 0.03068, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2850, + "angle": 0.055, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "LEFT_ANKLE_ROLL": { + "id": "LEFT_ANKLE_ROLL", + "frames": [ + { + "time": 700, + "angle": -0.01534, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1150, + "angle": -0.046019, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 1800, + "angle": -0.03068, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2100, + "angle": -0.03068, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2350, + "angle": -0.03068, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2850, + "angle": -0.055, + "pGain": 50, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "HEAD_YAW": { + "id": "HEAD_YAW", + "frames": [ + { + "time": 1800, + "angle": 0, + "pGain": 10, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2100, + "angle": 0, + "pGain": 10, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2350, + "angle": 0, + "pGain": 10, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2850, + "angle": 0, + "pGain": 10, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + }, + "HEAD_PITCH": { + "id": "HEAD_PITCH", + "frames": [ + { + "time": 1800, + "angle": -0.5124747, + "pGain": 10, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2100, + "angle": -0.5124747, + "pGain": 10, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2350, + "angle": -0.5124747, + "pGain": 10, + "iGain": 0, + "dGain": 0, + "torque": 100 + }, + { + "time": 2850, + "angle": 0.5, + "pGain": 10, + "iGain": 0, + "dGain": 0, + "torque": 100 + } + ] + } +} \ No newline at end of file From c62978d122dee9d514869dc647642d3036ad70df Mon Sep 17 00:00:00 2001 From: Josephus Paye II Date: Tue, 12 Feb 2019 21:58:05 +1100 Subject: [PATCH 44/54] Remove some sample scripts --- .../script_data_simulator.ts | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/src/virtual_robots/simulators/script_data_simulator/script_data_simulator.ts b/src/virtual_robots/simulators/script_data_simulator/script_data_simulator.ts index 6c6d32d6..c19ae9ef 100644 --- a/src/virtual_robots/simulators/script_data_simulator/script_data_simulator.ts +++ b/src/virtual_robots/simulators/script_data_simulator/script_data_simulator.ts @@ -8,17 +8,13 @@ import { Simulator } from '../../simulator' import LoadScriptsCommand = message.tools.script_tuner.LoadScriptsCommand import Scripts = message.tools.script_tuner.Scripts -import * as Bow from './bow.json' -import * as Jump from './jump.json' import * as LeftFootPowerKick from './left_foot_power_kick.json' import * as NodNo from './nod_no.json' import * as NodYes from './nod_yes.json' import * as RightFootPowerKick from './right_foot_power_kick.json' import * as Salute from './salute.json' -import * as Stand from './stand.json' import * as StandUpBack from './stand_up_back.json' import * as StandUpFront from './stand_up_front.json' -import * as Zombie from './zombie.json' export class ScriptDataSimulator extends Simulator { constructor(nuclearnetClient: NUClearNetClient) { @@ -30,8 +26,6 @@ export class ScriptDataSimulator extends Simulator { } start() { - console.log('ScriptDataSimulator Started') - const off = this.nuclearnetClient.on('message.tools.script_tuner.LoadScriptsCommand', this.onLoadScripts) return () => { @@ -41,17 +35,8 @@ export class ScriptDataSimulator extends Simulator { @action.bound onLoadScripts(packet: NUClearNetPacket) { - console.log('Load scripts command received', packet) const scripts = { scripts: [ - { - path: 'bow.yaml', - servos: Bow, - }, - { - path: 'jump.yaml', - servos: Jump, - }, { path: 'left_foot_power_kick.yaml', servos: LeftFootPowerKick, @@ -72,10 +57,6 @@ export class ScriptDataSimulator extends Simulator { path: 'salute.yaml', servos: Salute, }, - { - path: 'stand.yaml', - servos: Stand, - }, { path: 'stand_up_back.yaml', servos: StandUpBack, @@ -84,16 +65,11 @@ export class ScriptDataSimulator extends Simulator { path: 'stand_up_front.yaml', servos: StandUpFront, }, - { - path: 'zombie.yaml', - servos: Zombie, - }, ], } this.send({ messageType: 'message.tools.script_tuner.Scripts', buffer: Scripts.encode(scripts).finish(), }) - console.log('Responded with', scripts) } } From 4a251512734616d7f259ff10b554386064480236 Mon Sep 17 00:00:00 2001 From: Josephus Paye II Date: Tue, 12 Feb 2019 21:58:27 +1100 Subject: [PATCH 45/54] Minor visual changes --- src/client/components/script_tuner/editor/view.tsx | 2 +- src/client/components/script_tuner/editor/view_model.ts | 2 +- src/client/components/script_tuner/explorer/style.css | 4 ---- src/client/components/script_tuner/style.css | 1 + 4 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/client/components/script_tuner/editor/view.tsx b/src/client/components/script_tuner/editor/view.tsx index 8435aa03..5034eb24 100644 --- a/src/client/components/script_tuner/editor/view.tsx +++ b/src/client/components/script_tuner/editor/view.tsx @@ -44,7 +44,7 @@ export class Editor extends React.Component { return
- { model.selectedScript ? `Edit ${model.selectedScript.path}` : 'Editor' } + { model.selectedScript ? `${model.selectedScript.path} – Editor` : 'Editor' }
{ model.selectedScript &&