@@ -5,6 +5,8 @@ import * as rlt from "rltools"
55import * as math from "mathjs"
66import { Gamepad } from "./gamepad.js"
77import { GamepadController } from "./gamepad_controller.js"
8+ import { Position } from "./trajectories/position.js"
9+ import { Lissajous } from "./trajectories/lissajous.js"
810// import Controller from "./controller.js"
911
1012// check url for "file" parameter
@@ -14,22 +16,6 @@ const file_url = file ? file : "./blob/checkpoint.h5"
1416
1517let proxy_controller = null
1618
17- function lissajous ( t ) {
18- const scale = 0.5
19- const duration = 10
20- const A = 1
21- const B = 0.5
22- const progress = t * 2 * Math . PI / duration
23- const d_progress = 2 * Math . PI / duration
24- const x = scale * Math . sin ( A * progress )
25- const y = scale * Math . sin ( B * progress )
26- const vx = scale * Math . cos ( A * progress ) * A * d_progress
27- const vy = scale * Math . cos ( B * progress ) * B * d_progress
28- return [ x , y , 0 , vx , vy , 0 ]
29- }
30- function default_trajectory ( t ) {
31- return [ 0 , 0 , 0 , 0 , 0 , 0 ]
32- }
3319
3420class ProxyController {
3521 constructor ( current_policy ) {
@@ -62,6 +48,7 @@ class MultiController{
6248}
6349
6450let model = null
51+ let trajectory = null
6552class Policy {
6653 constructor ( ) {
6754 this . step = 0
@@ -113,17 +100,17 @@ class Policy{
113100 if ( ! this . policy_states || this . policy_states . length !== states . length ) {
114101 this . policy_states = states . map ( ( ) => null )
115102 }
103+ this . step += 1
116104 return states . map ( ( state , i ) => {
117105 state . observe ( )
118106 const observation_description = document . getElementById ( "observations" ) . observation
119107 let input = math . matrix ( [ observation_description . split ( "." ) . map ( x => this . get_observation ( state , x ) ) . flat ( ) ] )
120- const input_offset = default_trajectory ( this . step / 100 )
108+ const input_offset = trajectory . evaluate ( this . step / 100 )
121109 input_offset . forEach ( ( x , i ) => {
122110 input . _data [ 0 ] [ i ] = input . _data [ 0 ] [ i ] - x
123111 } )
124112 const [ output , new_state ] = model . evaluate_step ( input , this . policy_states [ i ] )
125113 this . policy_states [ i ] = new_state
126- this . step += 1
127114 return output . valueOf ( ) [ 0 ]
128115 } )
129116 }
@@ -176,6 +163,43 @@ async function load_model(checkpoint){
176163}
177164
178165async function main ( ) {
166+ const trajectory_select = document . getElementById ( "reference-trajectory" )
167+ const trajectories = { "Position" : Position , "Lissajous" : Lissajous }
168+ trajectory_select . innerHTML = ""
169+ for ( const name in trajectories ) {
170+ trajectory_select . innerHTML += `<option value="${ name } ">${ name } </option>`
171+ }
172+ trajectory_select . addEventListener ( "change" , ( event ) => {
173+ const trajectory_class = trajectories [ event . target . value ]
174+ trajectory = new trajectory_class ( )
175+
176+ const trajectory_options_container = document . getElementById ( "reference-trajectory-options" )
177+ trajectory_options_container . innerHTML = ""
178+ const trajectory_option_template = document . getElementById ( "reference-trajectory-option-template" )
179+
180+ for ( const [ key , config ] of Object . entries ( trajectory . parameters ) ) {
181+ const template = trajectory_option_template . content . cloneNode ( true )
182+
183+ const labels = template . querySelectorAll ( ".control-container-label" )
184+ labels [ 0 ] . textContent = key
185+ labels [ 1 ] . textContent = config . default
186+
187+ const slider = template . querySelector ( "input[type=range]" )
188+ slider . min = config . range [ 0 ]
189+ slider . max = config . range [ 1 ]
190+ slider . step = 0.01
191+ slider . value = config . default
192+
193+ slider . addEventListener ( "input" , ( ) => {
194+ labels [ 1 ] . textContent = slider . value
195+ trajectory . set_parameter ( key , parseFloat ( slider . value ) )
196+ } )
197+
198+ trajectory_options_container . appendChild ( template )
199+ }
200+ } )
201+ trajectory_select . dispatchEvent ( new Event ( "change" ) )
202+
179203 document . getElementById ( "default-checkpoint-btn" ) . addEventListener ( "click" , async ( ) => {
180204 load_model ( file_url )
181205 } )
0 commit comments