div(style="padding-left: calc(100vw - 100%);") {
div.container {
div.row {
- div.'col-sm-3' {
+ div.col-sm-5 {
_out.push(techedu_horizontal)
}
- div.'col-sm-9' {
+ div.'col-sm-7'.pad-20 {
'Breadcrumbs'
}
}
div.row {
- div.'col-sm-3' {
+ div.col-sm-5 {
+ div.mirobot-control {
+ div.container-fluid {
+ div.row {
+ div.'col-sm-7'.pad-10 {
+ 'MiRobot: '
+ span#connection-status {'Disconnected'}
+ }
+ div.col-sm-5 {
+ button.btn.btn-block.btn-primary.float-right#connect-disconnect(type="button") {'Connect'}
+ }
+ }
+ }
+ }
+ div.mirobot-control {
+ div.container-fluid {
+ div.row {
+ div.col-sm-7 {
+ input.mirobot-slider#slider-a(type="range" min="-90" max="90" value="0") {}
+ }
+ div.col-sm-5 {
+ 'Axis A: '
+ span#value-a {'0'}
+ }
+ }
+ }
+ }
+ div.mirobot-control {
+ div.container-fluid {
+ div.row {
+ div.col-sm-7 {
+ input.mirobot-slider#slider-b(type="range" min="-90" max="90" value="0") {}
+ }
+ div.col-sm-5 {
+ 'Axis B: '
+ span#value-b {'0'}
+ }
+ }
+ }
+ }
+ div.mirobot-control {
+ div.container-fluid {
+ div.row {
+ div.col-sm-7 {
+ input.mirobot-slider#slider-c(type="range" min="-90" max="90" value="0") {}
+ }
+ div.col-sm-5 {
+ 'Axis C: '
+ span#value-c {'0'}
+ }
+ }
+ }
+ }
+ div.mirobot-control {
+ div.container-fluid {
+ div.row {
+ div.col-sm-7 {
+ input.mirobot-slider#slider-d(type="range" min="-90" max="90" value="0") {}
+ }
+ div.col-sm-5 {
+ 'Axis D: '
+ span#value-d {'0'}
+ }
+ }
+ }
+ }
+ div.mirobot-control {
+ div.container-fluid {
+ div.row {
+ div.col-sm-7 {
+ input.mirobot-slider#slider-e(type="range" min="-90" max="90" value="0") {}
+ }
+ div.col-sm-5 {
+ 'Axis E: '
+ span#value-e {'0'}
+ }
+ }
+ }
+ }
+ div.mirobot-control {
+ div.container-fluid {
+ div.row {
+ div.col-sm-7 {
+ input.mirobot-slider#slider-f(type="range" min="-90" max="90" value="0") {}
+ }
+ div.col-sm-5 {
+ 'Axis F: '
+ span#value-f {'0'}
+ }
+ }
+ }
+ }
'Navigation'
}
- div.'col-sm-9' {
+ div.col-sm-7 {
await body(_out)
}
}
}
},
// scripts
- scripts
+ async _out => {
+ script {
+ let sleep = ms => {
+ return new Promise(resolve => setTimeout(resolve, ms));
+ }
+
+ let rx_active = false
+ let rx_cont = false
+ let rx_buf = ''
+ let rx_task = async device => {
+ console.log('rx_task')
+ rx_active = true
+ try {
+ while (rx_cont) {
+ transfer_result = await device.transferIn(2, 1)
+ //console.log('transfer_result', transfer_result)
+ if (transfer_result.status === 'ok')
+ for (let i = 0; i < transfer_result.data.byteLength; ++i) {
+ if (rx_buf.length >= 1024) {
+ console.log('rx_task overrun')
+ break
+ }
+ rx_buf += String.fromCharCode(
+ transfer_result.data.getUint8(0)
+ )
+ }
+ }
+ }
+ catch (err) {
+ console.log('rx_task err', err.message)
+ }
+ console.log('rx_task done')
+ rx_active = false
+ }
+ let rx_stop = async () => {
+ console.log('rx_stop')
+ rx_cont = false
+ while (rx_active)
+ await sleep(100)
+ console.log('rx_stop done')
+ }
+
+ let tx_immediate = async (device, text) => {
+ console.log('tx_immediate', text)
+ data = new Uint8Array(text.length);
+ for (var i = 0; i < text.length; ++i)
+ data[i] = text.charCodeAt(i);
+ await device.transferOut(2, data.buffer)
+ }
+
+ document.addEventListener(
+ 'DOMContentLoaded',
+ () => {
+ let device, device_busy = false
+ let axes = [
+ {
+ slider: document.getElementById("slider-a"),
+ value: document.getElementById("value-a"),
+ min_degrees: -90,
+ min_position: 8000,
+ max_degrees: 90,
+ max_position: 40000
+ },
+ {
+ slider: document.getElementById("slider-b"),
+ value: document.getElementById("value-b"),
+ min_degrees: -90,
+ min_position: 8000,
+ max_degrees: 90,
+ max_position: 40000
+ },
+ {
+ slider: document.getElementById("slider-c"),
+ value: document.getElementById("value-c"),
+ min_degrees: -90,
+ min_position: 8000,
+ max_degrees: 90,
+ max_position: 40000
+ },
+ {
+ slider: document.getElementById("slider-d"),
+ value: document.getElementById("value-d"),
+ min_degrees: -90,
+ min_position: 8000,
+ max_degrees: 90,
+ max_position: 40000
+ },
+ {
+ slider: document.getElementById("slider-e"),
+ value: document.getElementById("value-e"),
+ min_degrees: -90,
+ min_position: 8000,
+ max_degrees: 90,
+ max_position: 40000
+ },
+ {
+ slider: document.getElementById("slider-f"),
+ value: document.getElementById("value-f"),
+ min_degrees: -90,
+ min_position: 8000,
+ max_degrees: 90,
+ max_position: 40000
+ }
+ ]
+ for (let i = 0; i < axes.length; ++i) {
+ axes[i].value.innerHTML = axes[i].slider.value
+
+ let axis = i
+ axes[i].slider.oninput = function() {
+ axes[axis].value.innerHTML = this.value
+ if (device && !device_busy) {
+ axes[axis].position =
+ Math.round(axes[axis].min_position +
+ (this.value - axes[axis].min_degrees) *
+ (axes[axis].max_position - axes[axis].min_position) /
+ (axes[axis].max_degrees - axes[axis].min_degrees))
+ tx_immediate(
+ device,
+ `${String.fromCharCode(97 + axis)}32000 ${String.fromCharCode(65 + axis)}${axes[axis].position}\n`
+ )
+ }
+ }
+ }
+
+ document.getElementById('connect-disconnect').addEventListener(
+ 'click',
+ () => {
+ ;(
+ async () => {
+ if (!device_busy) {
+ device_busy = true
+ if (device === undefined) {
+ // connect request
+ try {
+ device = await navigator.usb.requestDevice(
+ {filters: [{vendorId: 0x1a86, productId: 0x7523}]}
+ )
+ await device.open()
+ try {
+ await device.selectConfiguration(1)
+ await device.claimInterface(0)
+
+ console.assert(!rx_active, '!rx_active')
+ rx_cont = true
+ rx_task(device)
+
+ await sleep(100)
+ rx_buf = ''
+
+ tx_immediate(device, '\n')
+ await sleep(100)
+ if (rx_buf.slice(0, 1) === '>') {
+ console.log('prompt detected')
+ rx_buf = rx_buf.slice(1)
+ document.getElementById('connection-status').innerHTML = 'Connected'
+ document.getElementById('connect-disconnect').innerHTML = 'Disconnect'
+ }
+ else {
+ console.log('no prompt detected')
+ device.close()
+ await rx_stop()
+ device = undefined
+ }
+ }
+ catch (err) {
+ console.log('exception', err.message)
+ device.close()
+ await rx_stop()
+ device = undefined
+ }
+ }
+ catch (err) {
+ console.log('exception', err.message)
+ device = undefined
+ }
+ }
+ else {
+ // disconnect request
+ device.close()
+ await rx_stop()
+ device = undefined
+ document.getElementById('connection-status').innerHTML = 'Disconnected'
+ document.getElementById('connect-disconnect').innerHTML = 'Connect'
+ }
+ device_busy = false
+ }
+ }
+ )()
+ }
+ )
+ }
+ )
+ }
+
+ scripts(_out)
+ }
)
}
// head
async _out => {},
// body
- async _out => {
- div {
- div.container-fluid {
- div.row {
- div.col-sm-8 {
- 'MiRobot status: '
- span#connection-status {'Disconnected'}
- }
- div.col-sm-4 {
- button.btn.btn-block.btn-primary.float-right#connect-disconnect(type="button") {'Connect'}
- }
- }
- }
- }
- div {
- div.container-fluid {
- div.row {
- div.col-sm-8 {
- input.slider#slider-a(type="range" min="-90" max="90" value="0") {}
- }
- div.col-sm-4 {
- 'Axis A: '
- span#value-a {'0'}
- }
- }
- }
- }
- div {
- div.container-fluid {
- div.row {
- div.col-sm-8 {
- input.slider#slider-b(type="range" min="-90" max="90" value="0") {}
- }
- div.col-sm-4 {
- 'Axis B: '
- span#value-b {'0'}
- }
- }
- }
- }
- div {
- div.container-fluid {
- div.row {
- div.col-sm-8 {
- input.slider#slider-c(type="range" min="-90" max="90" value="0") {}
- }
- div.col-sm-4 {
- 'Axis C: '
- span#value-c {'0'}
- }
- }
- }
- }
- div {
- div.container-fluid {
- div.row {
- div.col-sm-8 {
- input.slider#slider-d(type="range" min="-90" max="90" value="0") {}
- }
- div.col-sm-4 {
- 'Axis D: '
- span#value-d {'0'}
- }
- }
- }
- }
- }
+ async _out => {},
// scripts
- async _out => {
- script {
- let sleep = ms => {
- return new Promise(resolve => setTimeout(resolve, ms));
- }
-
- let rx_active = false
- let rx_cont = false
- let rx_buf = ''
- let rx_task = async device => {
- console.log('rx_task')
- rx_active = true
- try {
- while (rx_cont) {
- transfer_result = await device.transferIn(2, 1)
- //console.log('transfer_result', transfer_result)
- if (transfer_result.status === 'ok')
- for (let i = 0; i < transfer_result.data.byteLength; ++i) {
- if (rx_buf.length >= 1024) {
- console.log('rx_task overrun')
- break
- }
- rx_buf += String.fromCharCode(
- transfer_result.data.getUint8(0)
- )
- }
- }
- }
- catch (err) {
- console.log('rx_task err', err.message)
- }
- console.log('rx_task done')
- rx_active = false
- }
- let rx_stop = async () => {
- console.log('rx_stop')
- rx_cont = false
- while (rx_active)
- await sleep(100)
- console.log('rx_stop done')
- }
-
- let tx_immediate = async (device, text) => {
- console.log('tx_immediate', text)
- data = new Uint8Array(text.length);
- for (var i = 0; i < text.length; ++i)
- data[i] = text.charCodeAt(i);
- await device.transferOut(2, data.buffer)
- }
-
- document.addEventListener(
- 'DOMContentLoaded',
- () => {
- let device, device_busy = false
- let axes = [
- {
- slider: document.getElementById("slider-a"),
- value: document.getElementById("value-a"),
- min_degrees: -90,
- min_position: 8000,
- max_degrees: 90,
- max_position: 40000
- },
- {
- slider: document.getElementById("slider-b"),
- value: document.getElementById("value-b"),
- min_degrees: -90,
- min_position: 8000,
- max_degrees: 90,
- max_position: 40000
- },
- {
- slider: document.getElementById("slider-c"),
- value: document.getElementById("value-c"),
- min_degrees: -90,
- min_position: 8000,
- max_degrees: 90,
- max_position: 40000
- },
- {
- slider: document.getElementById("slider-d"),
- value: document.getElementById("value-d"),
- min_degrees: -90,
- min_position: 8000,
- max_degrees: 90,
- max_position: 40000
- }
- ]
- for (let i = 0; i < axes.length; ++i) {
- axes[i].value.innerHTML = axes[i].slider.value
-
- let axis = i
- axes[i].slider.oninput = function() {
- axes[axis].value.innerHTML = this.value
- if (device && !device_busy) {
- axes[axis].position =
- Math.round(axes[axis].min_position +
- (this.value - axes[axis].min_degrees) *
- (axes[axis].max_position - axes[axis].min_position) /
- (axes[axis].max_degrees - axes[axis].min_degrees))
- tx_immediate(
- device,
- `${String.fromCharCode(97 + axis)}32000 ${String.fromCharCode(65 + axis)}${axes[axis].position}\n`
- )
- }
- }
- }
-
- document.getElementById('connect-disconnect').addEventListener(
- 'click',
- () => {
- ;(
- async () => {
- if (!device_busy) {
- device_busy = true
- if (device === undefined) {
- // connect request
- try {
- device = await navigator.usb.requestDevice(
- {filters: [{vendorId: 0x1a86, productId: 0x7523}]}
- )
- await device.open()
- try {
- await device.selectConfiguration(1)
- await device.claimInterface(0)
-
- console.assert(!rx_active, '!rx_active')
- rx_cont = true
- rx_task(device)
-
- await sleep(100)
- rx_buf = ''
-
- tx_immediate(device, '\n')
- await sleep(100)
- if (rx_buf.slice(0, 1) === '>') {
- console.log('prompt detected')
- rx_buf = rx_buf.slice(1)
- document.getElementById('connection-status').innerHTML = 'Connected'
- document.getElementById('connect-disconnect').innerHTML = 'Disconnect'
- }
- else {
- console.log('no prompt detected')
- device.close()
- await rx_stop()
- device = undefined
- }
- }
- catch (err) {
- console.log('exception', err.message)
- device.close()
- await rx_stop()
- device = undefined
- }
- }
- catch (err) {
- console.log('exception', err.message)
- device = undefined
- }
- }
- else {
- // disconnect request
- device.close()
- await rx_stop()
- device = undefined
- document.getElementById('connection-status').innerHTML = 'Disconnected'
- document.getElementById('connect-disconnect').innerHTML = 'Connect'
- }
- device_busy = false
- }
- }
- )()
- }
- )
- }
- )
- }
- }
+ async _out => {}
)
}