Update blockly, doesn't work well yet
authorNick Downing <nick.downing@lifx.co>
Wed, 18 Mar 2020 19:31:43 +0000 (06:31 +1100)
committerNick Downing <nick.downing@lifx.co>
Wed, 18 Mar 2020 19:31:43 +0000 (06:31 +1100)
blockly.html.jst
css/bootstrap/custom.less
js/mirobot.js [moved from js/mirobot.js.min with 81% similarity]
navbar.jst

index 7b27007..44e30fc 100644 (file)
@@ -124,7 +124,7 @@ return async env => {
     },
     // body
     async _out => {
-      div#blocklyArea(style="height: 750px;") {}
+      div#blocklyArea(style="height: 720px;") {}
       div#blocklyDiv(style="position: absolute;") {}
     },
     // scripts
@@ -177,37 +177,30 @@ return async env => {
               Blockly.JavaScript.ORDER_COMMA) || '0';
           var c = Blockly.JavaScript.valueToCode(block, 'C',
               Blockly.JavaScript.ORDER_COMMA) || '0';
-          var c = Blockly.JavaScript.valueToCode(block, 'D',
+          var d = Blockly.JavaScript.valueToCode(block, 'D',
               Blockly.JavaScript.ORDER_COMMA) || '0';
-          var c = Blockly.JavaScript.valueToCode(block, 'E',
+          var e = Blockly.JavaScript.valueToCode(block, 'E',
               Blockly.JavaScript.ORDER_COMMA) || '0';
-          return 'await deviceMoveTo(' + a + ', ' + b + ', ' + c + ');\n'
+          return `await deviceMoveTo(${a}, ${b}, ${c}, ${d}, ${e});\n`
         };
 
         Blockly.JavaScript['gripper'] = block => {
-          var d = Blockly.JavaScript.valueToCode(block, 'F',
+          var f = Blockly.JavaScript.valueToCode(block, 'F',
               Blockly.JavaScript.ORDER_COMMA) || '0';
-          return 'await deviceGripper(' + d + ');\n'
+          return `await deviceGripper(${f});\n`
         };
 
         Blockly.JavaScript['delay'] = block => {
           var millisecs = Blockly.JavaScript.valueToCode(block, 'millisecs',
               Blockly.JavaScript.ORDER_COMMA) || '0';
-          return 'await delay(' + millisecs + ');\n'
+          return `await deviceDelay(${millisecs});\n`
         };
 
-        var deviceA = 90;
-        var deviceB = 90;
-        var deviceC = 90;
-        var deviceD = 90;
-        var deviceE = 90;
-        var deviceF = 90;
-        var toolbox = document.getElementById('toolbox');
-        var toolboxA = document.getElementById('toolboxA');
-        var toolboxB = document.getElementById('toolboxB');
-        var toolboxC = document.getElementById('toolboxC');
-        var toolboxD = document.getElementById('toolboxD');
+        var blockly_stop = false;
+        Blockly.JavaScript.INFINITE_LOOP_TRAP =
+          'await deviceDelay(0);\n'
 
+        var toolbox = document.getElementById('toolbox');
         var blocklyArea = document.getElementById('blocklyArea');
         var blocklyDiv = document.getElementById('blocklyDiv');
         var workspace = Blockly.inject(blocklyDiv, {toolbox: toolbox});
@@ -230,321 +223,119 @@ return async env => {
         };
         window.addEventListener('resize', onresize, false);
         onresize();
-        var toolboxTimeout = null;
-        var setToolboxTimeout = () => {
-          if (toolboxTimeout !== null)
-            clearTimeout(toolboxTimeout);
-          toolboxTimeout = setTimeout(
-            () => {
-              toolboxA.textContent = deviceA.toString();
-              toolboxB.textContent = deviceB.toString();
-              toolboxC.textContent = deviceC.toString();
-              toolboxD.textContent = deviceD.toString();
-              workspace.updateToolbox(toolbox)
-            },
-            1000
-          );
-        };
-
-        var device = null;
-        var deviceSend = async (command) => {
-          console.log('deviceSend', command)
-          data = new Uint8Array(command.length);
-          for (var i = 0; i < command.length; ++i)
-            data[i] = command.charCodeAt(i);
-          await device.transferOut(2, data.buffer)
-        }
-        var deviceReceive = async () => {
-          var response = ''
-          while (true) {
-            result = await device.transferIn(2, 64);
-            for (var i = 0; i < result.data.byteLength; ++i)
-              response += String.fromCharCode(result.data.getUint8(i));
-            var n = response.indexOf('\n');
-            if (n >= 0) {
-              response = response.substring(0, n);
-              break;
-            }
-          }
-          return response;
-        }
 
-        var deviceBusy = false;
-        var connectedDevice = document.getElementById("connected-device");
-        var A = document.getElementById('A');
-        var B = document.getElementById('B');
-        var C = document.getElementById('C');
-        var D = document.getElementById('D');
-        var E = document.getElementById('E');
-        var F = document.getElementById('F');
-        var deviceConnect = async () => {
-          deviceBusy = true;
-          try {
-            await device.open();
-            await device.selectConfiguration(1);
-            await device.claimInterface(0);
-
-            // this is for ttyACM devices:
-            //await device.controlTransferOut({
-            //    requestType: 'class',
-            //    recipient: 'interface',
-            //    request: 0x21,
-            //    value: 0,
-            //    index: 2},
-            //    new Uint8Array([0, 8, 7, 0, 0, 0, 8]).buffer); // 460800 bps, 8N1
-            //await device.controlTransferOut({
-            //    requestType: 'class',
-            //    recipient: 'interface',
-            //    request: 0x22,
-            //    value: 2,
-            //    index: 2},
-            //    new Uint8Array([3, 0]).buffer); // turn on DTR (0x01) and RTS (0x02)
-
-            await deviceSend("Z\n");
-            connectedDevice.value = await deviceReceive();
-
-            await deviceSend("U\n");
-            await deviceSend("T1\n");
-
-            deviceA = 90;
-            deviceB = 105;
-            deviceC = 70;
-            deviceD = 80;
-            deviceE = 90;
-            deviceF = 90;
-            setToolboxTimeout();
-
-            A.value = 90
-            B.value = 105
-            C.value = 70
-            D.value = 80
-            E.value = 90
-            F.value = 90
-
-            await deviceSend("A090010\nB105010\nC070010\nD080010\nE090010\nF090010\n");
-            await delay(90 * 50);
-
-            deviceBusy = false;
-          }
-          catch (error) {
-            console.log(error);
+        document.addEventListener(
+          'DOMContentLoaded',
+          () => {
+            axes[0].toolbox = document.getElementById('toolboxA');
+            axes[1].toolbox = document.getElementById('toolboxB');
+            axes[2].toolbox = document.getElementById('toolboxC');
+            axes[3].toolbox = document.getElementById('toolboxD');
+            axes[4].toolbox = document.getElementById('toolboxE');
+            axes[5].toolbox = document.getElementById('toolboxF');
 
-            connectedDevice.value = '';
-            device = null;
+            // following is a hook defined in mirobot.js:
+            var toolboxTimeout = null;
+            setToolboxTimeout = () => {
+              if (toolboxTimeout !== null)
+                clearTimeout(toolboxTimeout);
+              toolboxTimeout = setTimeout(
+                () => {
+                  toolboxTimeout = null;
+                  for (let i = 0; i < 6; ++i)
+                    axes[i].toolbox.textContent = axes[i].slider.value;
+                  workspace.updateToolbox(toolbox);
+                },
+                100
+              );
+            };
           }
-        };
+        );
 
-        var delay = t => {
-          return new Promise(resolve => setTimeout(resolve, t));
+        var deviceMoveTo = async (a, b, c, d, e) => {
+          if (blockly_stop) {
+            console.log('stop in deviceMoveTo()')
+            throw new Error('stopped')
+          }
+          move_axes([500, 500, 500, 500, 500], [a, b, c, d, e])
+          while (tx_queue.length)
+            await sleep(10)
         }
 
-        var deviceMoveTo = async (a, b, c) => {
-          if (device !== null) {
-            await deviceSend(
-              'A' + ('00' + a).slice(-3) + '010\n' +
-              'B' + ('00' + b).slice(-3) + '010\n' +
-              'C' + ('00' + c).slice(-3) + '010\n'
-            );
-            await delay(
-              Math.max(
-                Math.abs(deviceA - a),
-                Math.abs(deviceB - b),
-                Math.abs(deviceC - c)
-              ) * 50
-            );
-            deviceA = a;
-            deviceB = b;
-            deviceC = c;
-            setToolboxTimeout();
-          }
+        var deviceGripper = async f => {
+          if (blockly_stop) {
+            console.log('stop in deviceGripper()')
+            throw new Error('stopped')
+          }
+          move_axis(5, 500, f)
+          while (tx_queue.length)
+            await sleep(10)
         }
 
-        var deviceGripper = async (d) => {
-          if (device !== null) {
-            await deviceSend(
-              'D' + ('00' + d).slice(-3) + '010\n'
-            );
-            await delay(Math.abs(deviceD - d) * 50);
-            deviceD = d;
-            setToolboxTimeout();
+        var deviceDelay = async millisecs => {
+          if (blockly_stop) {
+            console.log('stop in deviceDelay()')
+            throw new Error('stopped')
           }
+          await sleep(millisecs)
         }
 
-        document.addEventListener('DOMContentLoaded', async () => {
-          let devices = await navigator.usb.getDevices();
-          devices.forEach(deviceIn => {
-            console.log('Add |device| to the UI.');
-            if (device === null) {
-              device = deviceIn;
-              deviceConnect();
-            }
-          });
-        });
-
-        navigator.usb.addEventListener('connect', event => {
-          console.log('Add |event.device| to the UI.');
-          if (device === null) {
-            device = deviceIn;
-            deviceConnect();
-          }
-        });
-
-        navigator.usb.addEventListener('disconnect', event => {
-          console.log('Remove |event.device| from the UI.');
-          if (!deviceBusy) {
-            device = null;
-            connectedDevice.value = '';
-          }
-        });
-
-        document.getElementById('connect').addEventListener(
+        document.getElementById('reset').addEventListener(
           'click',
-          async () => {
-            let deviceIn;
-            try {
-              deviceIn = await navigator.usb.requestDevice({ filters: [{
-                  vendorId: 0x1a86,
-                  productId: 0x7523,
-              }]});
-            } catch (err) {
-              console.log('No device was selected.');
-            }
-
-            if (deviceIn !== undefined) {
-              console.log('Add |device| to the UI.');
-              if (device === null) {
-                device = deviceIn;
-                deviceConnect();
+          () => {
+            ;(
+              async () => {
+                if (device !== undefined && !device_busy) {
+                  device_busy = true;
+                  move_axes([500, 500, 500, 500, 500, 500], [0, 0, 0, 0, 0, 0]);
+                  while (tx_queue.length)
+                    await sleep(10)
+                  device_busy = false;
+                }
               }
-            }
+            )()
           }
         );
-
-        A.addEventListener(
-          'input',
-          async () => {
-            var a = A.value;
-            if (device && !deviceBusy && deviceA != a) {
-              await deviceSend(
-                'A' + ('00' + a).slice(-3) + '010\n'
-              );
-              deviceA = a;
-              setToolboxTimeout();
-            }
-          }
-        );
-        B.addEventListener(
-          'input',
-          async () => {
-            var b = B.value;
-            if (device && !deviceBusy && deviceB != b) {
-              await deviceSend(
-                'B' + ('00' + b).slice(-3) + '010\n'
-              );
-              deviceB = b;
-              setToolboxTimeout();
-            }
-          }
-        );
-        C.addEventListener(
-          'input',
-          async () => {
-            var c = C.value;
-            if (device && !deviceBusy && deviceC != c) {
-              await deviceSend(
-                'C' + ('00' + c).slice(-3) + '010\n'
-              );
-              deviceC = c;
-              setToolboxTimeout();
-            }
-          }
-        );
-        D.addEventListener(
-          'input',
-          async () => {
-            var d = D.value;
-            if (device && !deviceBusy && deviceD != d) {
-              await deviceSend(
-                'D' + ('00' + d).slice(-3) + '010\n'
-              );
-              deviceD = d;
-              setToolboxTimeout();
-            }
-          }
-        );
-        E.addEventListener(
-          'input',
-          async () => {
-            var e = E.value;
-            if (device && !deviceBusy && deviceE != e) {
-              await deviceSend(
-                'E' + ('00' + e).slice(-3) + '010\n'
-              );
-              deviceE = e;
-              setToolboxTimeout();
-            }
-          }
-        );
-        F.addEventListener(
-          'input',
-          async () => {
-            var f = F.value;
-            if (device && !deviceBusy && deviceF != f) {
-              await deviceSend(
-                'F' + ('00' + value).slice(-3) + '010\n'
-              );
-              deviceF = f;
-              setToolboxTimeout();
-            }
-          }
-        );
-
-        document.getElementById('home').addEventListener(
+        var blockly_active = false;
+        document.getElementById('run-stop').addEventListener(
           'click',
-          async () => {
-            if (device && !deviceBusy) {
-              deviceBusy = true;
-
-              deviceA = 90;
-              deviceB = 105;
-              deviceC = 70;
-              deviceD = 80;
-              deviceE = 90;
-              deviceF = 90;
-              setToolboxTimeout();
-
-              A.value = 90
-              B.value = 105
-              C.value = 70
-              D.value = 80
-              E.value = 90
-              F.value = 90
-
-              await deviceSend("A090010\nB105010\nC070010\nD080010\nE090010\nF090010\n");
-              await delay(90 * 50);
-
-              deviceBusy = false;
+          () => {
+            if (blockly_active) {
+              console.log('stopping blockly');
+              blockly_stop = true;
             }
-          }
-        );
+            else if (device !== undefined && !device_busy) {
+              console.log('starting blockly');
+              blockly_stop = false;
+              blockly_active = true;
+              device_busy = true;
+              document.getElementById('run-stop').innerHTML = 'Stop'
 
-        document.getElementById('run').addEventListener(
-          'click',
-          async () => {
-            if (device && !deviceBusy) {
-              deviceBusy = true;
               Blockly.JavaScript.addReservedWords('code');
               var code =
-                '(async () => {\n' +
-                Blockly.JavaScript.workspaceToCode(workspace) +
-                '})();\n';
+                `(
+  async () => {
+    try {
+${Blockly.JavaScript.workspaceToCode(workspace)}  }
+    catch (err) {
+      console.log('warning', err.message);
+    }
+    blockly_active = false;
+    device_busy = false;
+    document.getElementById('run-stop').innerHTML = 'Run';
+  }
+)();
+`
               console.log(code);
               try {
                 eval(code);
-              } catch (e) {
-                alert(e);
+              } catch (err) {
+                console.log(err.message);
+                device_busy = false;
+                blockly_active = false;
+                document.getElementById('run').innerHTML = 'Run';
               }
-              deviceBusy = false;
             }
           }
         );
index eca9ea4..3d91ff8 100644 (file)
   }
 }
 
+.header {
+  background: #ddd; //bcf;
+}
+
+.header-blockly {
+  padding-top: 4px;
+  padding-bottom: 0px;
+  background: #ddd; //bcf;
+}
+
 .footer {
   padding-top: 50px;
   padding-bottom: 50px;
similarity index 81%
rename from js/mirobot.js.min
rename to js/mirobot.js
index 2bc78ff..90025a9 100644 (file)
@@ -66,7 +66,7 @@ let tx_task = async device => {
     while (tx_cont) {
       if (tx_queue.length)
         tx_wait(device, tx_queue.shift(), 60000)
-      await sleep(1);
+      await sleep(1)
     }
   }
   catch (err) {
@@ -122,23 +122,52 @@ let axes = [
     max_position: 18103.833333333333
   }
 ]
-let move_to = (axis, speed, value) => {
+let setToolboxTimeout;
+let move_axis = (axis, speed, value) => {
   if (value < axes[axis].min_degrees)
     value = axes[axis].min_degrees
   else if (value > axes[axis].max_degrees)
     value = axes[axis].max_degrees
+  if (axes[axis].slider !== undefined)
+    axes[axis].slider.value = value
   if (axes[axis].value !== undefined)
     axes[axis].value.innerHTML = value
-  if (device !== undefined) {
-    axes[axis].position =
-      Math.round(axes[axis].min_position +
-        (value - axes[axis].min_degrees) *
-        (axes[axis].max_position - axes[axis].min_position) /
-        (axes[axis].max_degrees - axes[axis].min_degrees))
+  axes[axis].position =
+    Math.round(axes[axis].min_position +
+      (value - axes[axis].min_degrees) *
+      (axes[axis].max_position - axes[axis].min_position) /
+      (axes[axis].max_degrees - axes[axis].min_degrees))
+  if (device !== undefined)
     tx_queue.push(
-      `${String.fromCharCode(97 + axis)}${speed} ${String.fromCharCode(65 + axis)}${axes[axis].position}\n`
+      `${String.fromCharCode(97 + axis)}${speed}${String.fromCharCode(65 + axis)}${axes[axis].position}\n`
     )
+  if (setToolboxTimeout !== undefined)
+    setToolboxTimeout()
+}
+let move_axes = (speeds, values) => {
+  text = ''
+  for (let i = 0; i < speeds.length; ++i)
+    text += `${String.fromCharCode(97 + i)}${speeds[i]}`
+  for (let i = 0; i < values.length; ++i) {
+    if (values[i] < axes[i].min_degrees)
+      values[i] = axes[i].min_degrees
+    else if (values[i] > axes[i].max_degrees)
+      values[i] = axes[i].max_degrees
+    if (axes[i].slider !== undefined)
+      axes[i].slider.value = values[i]
+    if (axes[i].values !== undefined)
+      axes[i].values.innerHTML = values[i]
+    axes[i].position =
+      Math.round(axes[i].min_position +
+        (values[i] - axes[i].min_degrees) *
+        (axes[i].max_position - axes[i].min_position) /
+        (axes[i].max_degrees - axes[i].min_degrees))
+    text += `${String.fromCharCode(65 + i)}${axes[i].position}`
   }
+  if (device !== undefined)
+    tx_queue.push(text + '\n')
+  if (setToolboxTimeout !== undefined)
+    setToolboxTimeout()
 }
 
 document.addEventListener(
@@ -168,7 +197,7 @@ document.addEventListener(
 
       let axis = i
       axes[i].slider.oninput = function() {
-        move_to(axis, 32000, this.value)
+        move_axis(axis, 32000, this.value)
       }
     }
 
index d197793..30bcfb2 100644 (file)
@@ -29,7 +29,7 @@ return async (env, head, body, scripts) => {
               span#connection-status {'Disconnected'}
             }
             div.col-sm-5 {
-              button.btn.btn-block.btn-primary.float-right#connect-disconnect(type="button") {'Connect'}
+              button.btn.btn-block.btn-primary#connect-disconnect(type="button") {'Connect'}
             }
           }
           div.row {
@@ -115,15 +115,37 @@ return async (env, head, body, scripts) => {
           //} 
         }
       }
-      if (env.parsed_url.pathname === '/blockly.html')
+
+      if (env.parsed_url.pathname == '/blockly.html') {
+        div.header-blockly {
+          div.container-fluid {
+            div.row {
+              div.col-sm-8 {
+                h5 {'Blockly'}
+              }
+              div.col-sm-2 {
+                button.btn.btn-block.btn-primary#reset(type="button") {'Reset'}
+              }
+              div.col-sm-2 {
+                button.btn.btn-block.btn-primary#run-stop(type="button") {'Run'}
+              }
+            }
+          }
+        }
         await body(_out)
-      else
+      }
+      else {
+        div.header {
+          div.container-fluid {
+            h5 {
+              _out.push(globals.page_to_breadcrumbs[env.parsed_url.pathname] || globals.page_to_title[env.parsed_url.pathname] || env.parsed_url.pathname)
+            }
+          }
+        }
         div.container-fluid {
-          h5 {
-            _out.push(globals.page_to_breadcrumbs[env.parsed_url.pathname] || globals.page_to_title[env.parsed_url.pathname] || env.parsed_url.pathname)
-          } 
           await body(_out)
         }
+      }
       div.footer {
         div.container-fluid {
           `Copyright © ${new XDate().getUTCFullYear()} Technology Education Pty Ltd.`