William Hilton пре 5 година
комит
2b3cadd624
55 измењених фајлова са 1973 додато и 0 уклоњено
  1. 1 0
      CNAME
  2. 3 0
      LICENSE
  3. 42 0
      README.html
  4. BIN
      favicon/android-chrome-144x144.png
  5. BIN
      favicon/android-chrome-192x192.png
  6. BIN
      favicon/android-chrome-36x36.png
  7. BIN
      favicon/android-chrome-48x48.png
  8. BIN
      favicon/android-chrome-72x72.png
  9. BIN
      favicon/android-chrome-96x96.png
  10. BIN
      favicon/apple-touch-icon-114x114.png
  11. BIN
      favicon/apple-touch-icon-120x120.png
  12. BIN
      favicon/apple-touch-icon-144x144.png
  13. BIN
      favicon/apple-touch-icon-152x152.png
  14. BIN
      favicon/apple-touch-icon-180x180.png
  15. BIN
      favicon/apple-touch-icon-57x57.png
  16. BIN
      favicon/apple-touch-icon-60x60.png
  17. BIN
      favicon/apple-touch-icon-72x72.png
  18. BIN
      favicon/apple-touch-icon-76x76.png
  19. BIN
      favicon/apple-touch-icon-precomposed.png
  20. BIN
      favicon/apple-touch-icon.png
  21. 12 0
      favicon/browserconfig.xml
  22. BIN
      favicon/favicon-16x16.png
  23. BIN
      favicon/favicon-32x32.png
  24. BIN
      favicon/favicon-96x96.png
  25. BIN
      favicon/favicon.ico
  26. 41 0
      favicon/manifest.json
  27. BIN
      favicon/mstile-144x144.png
  28. BIN
      favicon/mstile-150x150.png
  29. BIN
      favicon/mstile-310x150.png
  30. BIN
      favicon/mstile-310x310.png
  31. BIN
      favicon/mstile-70x70.png
  32. 41 0
      favicon/safari-pinned-tab.svg
  33. 91 0
      index.html
  34. 3 0
      now.json
  35. 48 0
      projects/dyna-myte-2400/index.html
  36. 66 0
      projects/index.html
  37. 101 0
      projects/javascript-cnc-machine/CNC_California.txt
  38. 104 0
      projects/javascript-cnc-machine/CNC_California_Subs.txt
  39. 64 0
      projects/javascript-cnc-machine/CNC_D-SUB_PROGRAM.txt
  40. 802 0
      projects/javascript-cnc-machine/CNC_Simulator.html
  41. 36 0
      projects/javascript-cnc-machine/CNC_Spiral.txt
  42. 117 0
      projects/javascript-cnc-machine/CNC_UC_Logo.txt
  43. 57 0
      projects/javascript-cnc-machine/index.html
  44. BIN
      projects/k-nex-adding-machine/KnexViews.png
  45. 56 0
      projects/k-nex-adding-machine/index.html
  46. BIN
      projects/skype-telepresence-rover/IMG_20110109_184027.jpg
  47. 64 0
      projects/skype-telepresence-rover/index.html
  48. BIN
      projects/ultimate-wotd/UltimateWOTDReview1.png
  49. BIN
      projects/ultimate-wotd/UltimateWOTDReview2.png
  50. BIN
      projects/ultimate-wotd/UltimateWOTDReview3.png
  51. BIN
      projects/ultimate-wotd/UltimateWOTDReview4.png
  52. BIN
      projects/ultimate-wotd/UltimateWOTDWidget.png
  53. 54 0
      projects/ultimate-wotd/index.html
  54. 80 0
      research-interests.html
  55. 90 0
      work-history.html

+ 1 - 0
CNAME

@@ -0,0 +1 @@
+wmhilton.com

+ 3 - 0
LICENSE

@@ -0,0 +1,3 @@
+Copyright (c) 2014 Will Hilton
+
+All rights reserved.

+ 42 - 0
README.html

@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>Readme</title>
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <link rel="stylesheet" href="//yegor256.github.io/tacit/tacit.min.css">
+    <!-- favicon -->
+    <link rel="apple-touch-icon" sizes="57x57" href="/favicon/apple-touch-icon-57x57.png">
+    <link rel="apple-touch-icon" sizes="60x60" href="/favicon/apple-touch-icon-60x60.png">
+    <link rel="apple-touch-icon" sizes="72x72" href="/favicon/apple-touch-icon-72x72.png">
+    <link rel="apple-touch-icon" sizes="76x76" href="/favicon/apple-touch-icon-76x76.png">
+    <link rel="apple-touch-icon" sizes="114x114" href="/favicon/apple-touch-icon-114x114.png">
+    <link rel="apple-touch-icon" sizes="120x120" href="/favicon/apple-touch-icon-120x120.png">
+    <link rel="apple-touch-icon" sizes="144x144" href="/favicon/apple-touch-icon-144x144.png">
+    <link rel="apple-touch-icon" sizes="152x152" href="/favicon/apple-touch-icon-152x152.png">
+    <link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-touch-icon-180x180.png">
+    <link rel="icon" type="image/png" href="/favicon/favicon-32x32.png" sizes="32x32">
+    <link rel="icon" type="image/png" href="/favicon/android-chrome-192x192.png" sizes="192x192">
+    <link rel="icon" type="image/png" href="/favicon/favicon-96x96.png" sizes="96x96">
+    <link rel="icon" type="image/png" href="/favicon/favicon-16x16.png" sizes="16x16">
+    <link rel="manifest" href="/favicon/manifest.json">
+    <link rel="mask-icon" href="/favicon/safari-pinned-tab.svg" color="#ffb300">
+    <link rel="shortcut icon" href="/favicon/favicon.ico">
+    <meta name="msapplication-TileColor" content="#ffb300">
+    <meta name="msapplication-TileImage" content="/favicon/mstile-144x144.png">
+    <meta name="msapplication-config" content="/favicon/browserconfig.xml">
+    <meta name="theme-color" content="#ffb300">
+    <!-- http://realfavicongenerator.net/favicon_result?file_id=p1akurqbdbq0j1lpc14a618p2och6#.V1uVj_krK70 -->
+  </head>
+  <body>
+    <header>&#xA0;</header>
+    <section>
+      <article>
+        <h1 id="wmhiltongithubio" class="deep-link"><a href="#wmhiltongithubio">wmhilton.github.io</a></h1>
+<p>Website of William Hilton, web dev.</p>
+
+      </article>
+    </section>
+    <footer>&#xA0;</footer>
+  </body>
+</html>

BIN
favicon/android-chrome-144x144.png


BIN
favicon/android-chrome-192x192.png


BIN
favicon/android-chrome-36x36.png


BIN
favicon/android-chrome-48x48.png


BIN
favicon/android-chrome-72x72.png


BIN
favicon/android-chrome-96x96.png


BIN
favicon/apple-touch-icon-114x114.png


BIN
favicon/apple-touch-icon-120x120.png


BIN
favicon/apple-touch-icon-144x144.png


BIN
favicon/apple-touch-icon-152x152.png


BIN
favicon/apple-touch-icon-180x180.png


BIN
favicon/apple-touch-icon-57x57.png


BIN
favicon/apple-touch-icon-60x60.png


BIN
favicon/apple-touch-icon-72x72.png


BIN
favicon/apple-touch-icon-76x76.png


BIN
favicon/apple-touch-icon-precomposed.png


BIN
favicon/apple-touch-icon.png


+ 12 - 0
favicon/browserconfig.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<browserconfig>
+  <msapplication>
+    <tile>
+      <square70x70logo src="/favicon/mstile-70x70.png"/>
+      <square150x150logo src="/favicon/mstile-150x150.png"/>
+      <square310x310logo src="/favicon/mstile-310x310.png"/>
+      <wide310x150logo src="/favicon/mstile-310x150.png"/>
+      <TileColor>#ffb300</TileColor>
+    </tile>
+  </msapplication>
+</browserconfig>

BIN
favicon/favicon-16x16.png


BIN
favicon/favicon-32x32.png


BIN
favicon/favicon-96x96.png


BIN
favicon/favicon.ico


+ 41 - 0
favicon/manifest.json

@@ -0,0 +1,41 @@
+{
+	"name": "wmhilton",
+	"icons": [
+		{
+			"src": "\/favicon\/android-chrome-36x36.png",
+			"sizes": "36x36",
+			"type": "image\/png",
+			"density": 0.75
+		},
+		{
+			"src": "\/favicon\/android-chrome-48x48.png",
+			"sizes": "48x48",
+			"type": "image\/png",
+			"density": 1
+		},
+		{
+			"src": "\/favicon\/android-chrome-72x72.png",
+			"sizes": "72x72",
+			"type": "image\/png",
+			"density": 1.5
+		},
+		{
+			"src": "\/favicon\/android-chrome-96x96.png",
+			"sizes": "96x96",
+			"type": "image\/png",
+			"density": 2
+		},
+		{
+			"src": "\/favicon\/android-chrome-144x144.png",
+			"sizes": "144x144",
+			"type": "image\/png",
+			"density": 3
+		},
+		{
+			"src": "\/favicon\/android-chrome-192x192.png",
+			"sizes": "192x192",
+			"type": "image\/png",
+			"density": 4
+		}
+	]
+}

BIN
favicon/mstile-144x144.png


BIN
favicon/mstile-150x150.png


BIN
favicon/mstile-310x150.png


BIN
favicon/mstile-310x310.png


BIN
favicon/mstile-70x70.png


+ 41 - 0
favicon/safari-pinned-tab.svg

@@ -0,0 +1,41 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
+ "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
+<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
+ width="700.000000pt" height="700.000000pt" viewBox="0 0 700.000000 700.000000"
+ preserveAspectRatio="xMidYMid meet">
+<metadata>
+Created by potrace 1.11, written by Peter Selinger 2001-2013
+</metadata>
+<g transform="translate(0.000000,700.000000) scale(0.100000,-0.100000)"
+fill="#000000" stroke="none">
+<path d="M3298 6996 c-1 -2 -41 -6 -88 -10 -47 -3 -86 -6 -87 -6 -2 0 -3
+-1410 -3 -3133 l0 -3133 -72 12 c-40 7 -86 14 -103 17 -56 9 -280 69 -289 78
+-6 5 -17 9 -26 9 -20 0 -251 87 -263 99 -5 5 -9 650 -9 1480 l0 1471 -76 0
+c-466 2 -676 0 -681 -9 -3 -5 -6 -557 -5 -1227 l0 -1218 -115 120 c-280 290
+-478 605 -619 984 -47 127 -123 409 -137 510 -3 25 -8 61 -10 80 -3 19 -8 51
+-11 70 -10 63 -13 503 -3 580 37 305 82 493 170 727 36 96 118 279 139 313 6
+8 22 38 36 65 41 78 214 336 244 365 3 3 25 30 50 60 46 57 259 274 320 325
+192 163 394 297 601 399 l97 47 0 369 1 369 -82 -30 c-1067 -393 -1891 -1313
+-2171 -2424 -23 -94 -28 -115 -41 -190 -3 -16 -8 -41 -10 -55 -12 -58 -15 -75
+-21 -129 -3 -31 -8 -65 -10 -76 -19 -99 -26 -556 -11 -710 8 -82 24 -207 33
+-260 3 -16 7 -39 8 -50 2 -11 8 -45 15 -75 6 -30 13 -64 15 -75 17 -82 94
+-350 115 -400 5 -11 28 -69 51 -130 118 -308 317 -644 552 -933 218 -267 578
+-583 840 -737 9 -5 48 -29 85 -51 71 -43 291 -156 378 -194 83 -35 88 -37 150
+-60 33 -12 76 -28 95 -35 98 -38 306 -95 455 -124 138 -28 152 -30 220 -37 33
+-4 63 -8 66 -10 42 -24 762 -24 786 0 3 2 5 700 5 1550 l0 1546 1204 0 c663 0
+1203 -3 1201 -7 -3 -5 -8 -30 -11 -56 -34 -254 -143 -586 -277 -843 -190 -368
+-435 -662 -786 -945 -102 -82 -366 -244 -498 -305 l-72 -33 -1 -369 0 -369 61
+22 c163 60 386 162 507 232 19 11 51 29 70 39 19 11 37 21 40 24 3 3 43 30 90
+60 240 154 552 423 712 615 18 22 49 58 69 80 52 59 178 229 233 315 27 41 59
+91 71 110 28 43 155 275 155 283 0 3 18 43 39 89 130 275 242 669 276 966 3
+26 8 54 10 62 19 71 27 541 12 714 -18 203 -73 498 -127 671 -12 39 -24 81
+-27 95 -18 79 -166 432 -232 553 -118 213 -183 317 -300 472 -158 210 -349
+413 -541 575 -36 30 -67 57 -70 60 -3 3 -48 37 -100 76 -212 158 -403 270
+-680 397 -53 24 -71 31 -206 82 l-61 24 0 -369 0 -369 76 -36 c116 -56 311
+-171 410 -242 44 -32 160 -122 193 -150 42 -35 273 -266 315 -314 64 -75 185
+-240 248 -340 77 -123 202 -373 239 -479 15 -41 31 -84 36 -95 23 -49 90 -310
+109 -430 6 -33 12 -70 15 -82 l5 -23 -1204 0 -1203 0 0 1546 c0 850 -2 1547
+-4 1549 -12 13 -567 32 -580 21z"/>
+</g>
+</svg>

+ 91 - 0
index.html

@@ -0,0 +1,91 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>wmhilton</title>
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <link rel="stylesheet" href="//yegor256.github.io/tacit/tacit.min.css">
+    <!-- favicon -->
+    <link rel="apple-touch-icon" sizes="57x57" href="/favicon/apple-touch-icon-57x57.png">
+    <link rel="apple-touch-icon" sizes="60x60" href="/favicon/apple-touch-icon-60x60.png">
+    <link rel="apple-touch-icon" sizes="72x72" href="/favicon/apple-touch-icon-72x72.png">
+    <link rel="apple-touch-icon" sizes="76x76" href="/favicon/apple-touch-icon-76x76.png">
+    <link rel="apple-touch-icon" sizes="114x114" href="/favicon/apple-touch-icon-114x114.png">
+    <link rel="apple-touch-icon" sizes="120x120" href="/favicon/apple-touch-icon-120x120.png">
+    <link rel="apple-touch-icon" sizes="144x144" href="/favicon/apple-touch-icon-144x144.png">
+    <link rel="apple-touch-icon" sizes="152x152" href="/favicon/apple-touch-icon-152x152.png">
+    <link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-touch-icon-180x180.png">
+    <link rel="icon" type="image/png" href="/favicon/favicon-32x32.png" sizes="32x32">
+    <link rel="icon" type="image/png" href="/favicon/android-chrome-192x192.png" sizes="192x192">
+    <link rel="icon" type="image/png" href="/favicon/favicon-96x96.png" sizes="96x96">
+    <link rel="icon" type="image/png" href="/favicon/favicon-16x16.png" sizes="16x16">
+    <link rel="manifest" href="/favicon/manifest.json">
+    <link rel="mask-icon" href="/favicon/safari-pinned-tab.svg" color="#ffb300">
+    <link rel="shortcut icon" href="/favicon/favicon.ico">
+    <meta name="msapplication-TileColor" content="#ffb300">
+    <meta name="msapplication-TileImage" content="/favicon/mstile-144x144.png">
+    <meta name="msapplication-config" content="/favicon/browserconfig.xml">
+    <meta name="theme-color" content="#ffb300">
+    <!-- http://realfavicongenerator.net/favicon_result?file_id=p1akurqbdbq0j1lpc14a618p2och6#.V1uVj_krK70 -->
+  </head>
+  <body>
+    <header>&#xA0;</header>
+    <section>
+      <article>
+        <!--
+title: wmhilton
+-->
+<h1>wmhilton
+<small> I do all sorts of things...</small>
+</h1>
+<p><strong>I&apos;m a much better web developer than this site would suggest.</strong> &#x1F603;
+<br>I&apos;ve just been working on cooler stuff than this site.</p>
+<hr>
+<h2 id="what-am-i-working-on" class="deep-link"><a href="#what-am-i-working-on">What am I working on?</a></h2>
+<p>My two latest projects are extraordinary. They&apos;re not really ready for release (or even beta testing) but once they are, I&apos;m going to write not just one, but a whole series of blog posts about them.</p>
+<ul>
+<li><a href="https://github.com/wmhilton/esgit">esgit</a> A fully working implementation of <code>git</code> in ECMAScript that also happens to work <em>in the browser</em>. (See next item!)</li>
+<li><a href="https://nde.now.sh">nde</a> Imagine Atom editor, but completely in client-side browser JavaScript, that you can use to develop your progressive web app. With hot-module reloading. And dynamic module loading (all of npm without the &quot;npm install&quot;). And full file system emulation, git, and Github integration! Oh, and did I mention it&apos;s self-hosted (you can edit the editor) and it caches everything offline with service workers?</li>
+</ul>
+<p>Prior to that: Bare metal programming!</p>
+<ul>
+<li>Hardware! I got myself a <a href="https://www.nandland.com/goboard">Nandland Go</a> FPGA board. Currently fiddling with I2C and SPI.</li>
+<li>Assembly! Check out the gif of <a href="https://github.com/wmhilton/boots">It-boots-but-that&apos;s-about-it OS</a> booting and reading a file from disk(ette).</li>
+<li>C! Not technically bare metal, but my <a href="https://gitlab.com/dukboot/dukboot">dukboot</a> project aims to build a tiny library OS around the <a href="http://duktape.org">duktape</a> JS engine.</li>
+</ul>
+<p>Prior to that, I was on a tooling binge. Check out:</p>
+<ul>
+<li><a href="https://github.com/update-readme/update-readme">update-readme</a> Auto-generate (and maintain!) your next README file</li>
+<li><a href="https://github.com/wmhilton/create-node-module#js">create-node-module</a> Refactor your code into lots of small modules, without the friction of set up that would slow you down</li>
+<li><a href="https://github.com/wmhilton/beautify">beautify</a> All code looks beautiful, once you&apos;ve parsed its AST.</li>
+</ul>
+<p>These tools are all hovering around the 90% complete stage. I&apos;m saving that last 10% for a rainy weekend.</p>
+<h2 id="what-else" class="deep-link"><a href="#what-else">What else?</a></h2>
+<ul>
+<li><a href="https://github.com/wmhilton/download-with-webtorrent-button">webtorrent-button</a> Supercharge ordinary download links with WebTorrent P2P!</li>
+<li><a href="https://github.com/jus/jus">jus</a> I&apos;m a contributor/maintainer</li>
+<li><a href="https://github.com/npm/marky-markdown">marky-markdown</a> I contributed the browserified bundle!</li>
+<li><a href="https://node-modules.io">node-modules.io</a> I maintain a site dedicated to npm alternatives and host my own registry mirror</li>
+</ul>
+<h2 id="what-about-projects-from-college-and-earlier" class="deep-link"><a href="#what-about-projects-from-college-and-earlier">What about projects from college and earlier?</a></h2>
+<p>Check out <a href="./projects/">Projects</a>!</p>
+<h2 id="do-you-ever-get-paid-to-build-websites" class="deep-link"><a href="#do-you-ever-get-paid-to-build-websites">Do you ever get paid to build websites?</a></h2>
+<p>I do! Not all of them are still in existance. However, here are some recent commercial projects I&apos;ve worked on that I&apos;m proud of:</p>
+<ul>
+<li><a href="https://app.classicalwalkoffame.net/">American Classical Music Walk of Fame Player</a> is my first Progressive Web App.
+Offline support, A2HS install banners, media session API for album art.</li>
+<li><a href="http://patent.online.cars/">Online.Cars search</a> Not originally my design, but I was lead developer for several months including a full rewrite in Vue.</li>
+</ul>
+<h2 id="whats-your-secret-master-plan" class="deep-link"><a href="#whats-your-secret-master-plan">What&apos;s your secret master plan?</a></h2>
+<p>Elon Musk <a href="https://www.tesla.com/blog/secret-tesla-motors-master-plan-just-between-you-and-me">had one</a>.
+My parents often wonder, <a href="https://github.com/project-leibniz/master-plan">but I do have a plan</a>.
+(I also have a <a href="https://github.com/wmhilton/modload#5-year-plan">5-year plan</a>!)</p>
+<hr>
+<p>My plan is to migrate content from <a href="https://sites.google.com/site/wmhilton/home">https://sites.google.com/site/wmhilton/home</a> over here, since Github is the place to be these days. That&apos;s been my plan since 2014 though so don&apos;t hold your breath. I should make that part of my 5-year plan.</p>
+<p>Meanwhile, perhaps you&apos;d like to peruse some of my code projects over at <a href="https://github.com/wmhilton">@wmhilton</a>?</p>
+
+      </article>
+    </section>
+    <footer>&#xA0;</footer>
+  </body>
+</html>

+ 3 - 0
now.json

@@ -0,0 +1,3 @@
+{
+  "alias": "wmhilton.com"
+}

+ 48 - 0
projects/dyna-myte-2400/index.html

@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>Dyna Myte 2400</title>
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <link rel="stylesheet" href="//yegor256.github.io/tacit/tacit.min.css">
+    <!-- favicon -->
+    <link rel="apple-touch-icon" sizes="57x57" href="/favicon/apple-touch-icon-57x57.png">
+    <link rel="apple-touch-icon" sizes="60x60" href="/favicon/apple-touch-icon-60x60.png">
+    <link rel="apple-touch-icon" sizes="72x72" href="/favicon/apple-touch-icon-72x72.png">
+    <link rel="apple-touch-icon" sizes="76x76" href="/favicon/apple-touch-icon-76x76.png">
+    <link rel="apple-touch-icon" sizes="114x114" href="/favicon/apple-touch-icon-114x114.png">
+    <link rel="apple-touch-icon" sizes="120x120" href="/favicon/apple-touch-icon-120x120.png">
+    <link rel="apple-touch-icon" sizes="144x144" href="/favicon/apple-touch-icon-144x144.png">
+    <link rel="apple-touch-icon" sizes="152x152" href="/favicon/apple-touch-icon-152x152.png">
+    <link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-touch-icon-180x180.png">
+    <link rel="icon" type="image/png" href="/favicon/favicon-32x32.png" sizes="32x32">
+    <link rel="icon" type="image/png" href="/favicon/android-chrome-192x192.png" sizes="192x192">
+    <link rel="icon" type="image/png" href="/favicon/favicon-96x96.png" sizes="96x96">
+    <link rel="icon" type="image/png" href="/favicon/favicon-16x16.png" sizes="16x16">
+    <link rel="manifest" href="/favicon/manifest.json">
+    <link rel="mask-icon" href="/favicon/safari-pinned-tab.svg" color="#ffb300">
+    <link rel="shortcut icon" href="/favicon/favicon.ico">
+    <meta name="msapplication-TileColor" content="#ffb300">
+    <meta name="msapplication-TileImage" content="/favicon/mstile-144x144.png">
+    <meta name="msapplication-config" content="/favicon/browserconfig.xml">
+    <meta name="theme-color" content="#ffb300">
+    <!-- http://realfavicongenerator.net/favicon_result?file_id=p1akurqbdbq0j1lpc14a618p2och6#.V1uVj_krK70 -->
+  </head>
+  <body>
+    <header>&#xA0;</header>
+    <section>
+      <article>
+        <!--
+title: Dyna Myte 2400
+-->
+<h1 id="dyna-myte-2400" class="deep-link"><a href="#dyna-myte-2400">Dyna Myte 2400</a></h1>
+<p>This CNC machine sat unused in the UC Robotic&apos;s Lab for years until we re-discovered the manual one day. I read the manual and taught myself how to use it with great results.</p>
+<div class="youtube-video"><iframe width="560" height="315" src="https://www.youtube.com/embed/pemZhpormRg" frameborder="0" allowfullscreen></iframe></div>
+<p><em>A video of the CNC machine running a routine I wrote</em></p>
+<p>I followed up by writing an <a href="../javascript-cnc-machine">emulator</a> in Javascript to test CNC code.</p>
+
+      </article>
+    </section>
+    <footer>&#xA0;</footer>
+  </body>
+</html>

+ 66 - 0
projects/index.html

@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>Projects</title>
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <link rel="stylesheet" href="//yegor256.github.io/tacit/tacit.min.css">
+    <!-- favicon -->
+    <link rel="apple-touch-icon" sizes="57x57" href="/favicon/apple-touch-icon-57x57.png">
+    <link rel="apple-touch-icon" sizes="60x60" href="/favicon/apple-touch-icon-60x60.png">
+    <link rel="apple-touch-icon" sizes="72x72" href="/favicon/apple-touch-icon-72x72.png">
+    <link rel="apple-touch-icon" sizes="76x76" href="/favicon/apple-touch-icon-76x76.png">
+    <link rel="apple-touch-icon" sizes="114x114" href="/favicon/apple-touch-icon-114x114.png">
+    <link rel="apple-touch-icon" sizes="120x120" href="/favicon/apple-touch-icon-120x120.png">
+    <link rel="apple-touch-icon" sizes="144x144" href="/favicon/apple-touch-icon-144x144.png">
+    <link rel="apple-touch-icon" sizes="152x152" href="/favicon/apple-touch-icon-152x152.png">
+    <link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-touch-icon-180x180.png">
+    <link rel="icon" type="image/png" href="/favicon/favicon-32x32.png" sizes="32x32">
+    <link rel="icon" type="image/png" href="/favicon/android-chrome-192x192.png" sizes="192x192">
+    <link rel="icon" type="image/png" href="/favicon/favicon-96x96.png" sizes="96x96">
+    <link rel="icon" type="image/png" href="/favicon/favicon-16x16.png" sizes="16x16">
+    <link rel="manifest" href="/favicon/manifest.json">
+    <link rel="mask-icon" href="/favicon/safari-pinned-tab.svg" color="#ffb300">
+    <link rel="shortcut icon" href="/favicon/favicon.ico">
+    <meta name="msapplication-TileColor" content="#ffb300">
+    <meta name="msapplication-TileImage" content="/favicon/mstile-144x144.png">
+    <meta name="msapplication-config" content="/favicon/browserconfig.xml">
+    <meta name="theme-color" content="#ffb300">
+    <!-- http://realfavicongenerator.net/favicon_result?file_id=p1akurqbdbq0j1lpc14a618p2och6#.V1uVj_krK70 -->
+  </head>
+  <body>
+    <header>&#xA0;</header>
+    <section>
+      <article>
+        <!--
+title: Projects
+-->
+<h1 id="personal-projects" class="deep-link"><a href="#personal-projects">Personal Projects</a></h1>
+<h2 id="post-academia" class="deep-link"><a href="#post-academia">Post-academia</a></h2>
+<ul>
+<li><a href="https://github.com/wmhilton/decshell">Declarative Shell Scripting</a></li>
+<li><a href="https://github.com/wmhilton/lock-screen">Transparent Lock Screen for Windows</a></li>
+<li><a href="https://github.com/wmhilton/treeui">TreeUI</a></li>
+</ul>
+<h2 id="graduate-school" class="deep-link"><a href="#graduate-school">Graduate School</a></h2>
+<ul>
+<li><a href="https://wmhilton.github.io/hubo-js">Hubo-in-the-Browser</a></li>
+<li><a href="https://github.com/wmhilton/img2asm6502">Image &#x2192; 6502 Assembly</a></li>
+</ul>
+<h2 id="college" class="deep-link"><a href="#college">College</a></h2>
+<ul>
+<li><a href="./skype-telepresence-rover/">Skype Telepresence Rover</a></li>
+<li><a href="./dyna-myte-2400/">Dyna Myte 2400</a></li>
+<li><a href="./javascript-cnc-machine/">Javascript CNC Machine Emulator</a></li>
+</ul>
+<h2 id="high-school" class="deep-link"><a href="#high-school">High School</a></h2>
+<ul>
+<li><a href="./ultimate-wotd/">Ultimate Word-of-the-Day</a></li>
+<li><a href="./k-nex-adding-machine/">K&apos;nex Adding Machine</a></li>
+</ul>
+
+      </article>
+    </section>
+    <footer>&#xA0;</footer>
+  </body>
+</html>

+ 101 - 0
projects/javascript-cnc-machine/CNC_California.txt

@@ -0,0 +1,101 @@
+This program should cut out an outline, a few letters, and then a rectangular
+border, resulting in a metal postcard about 6" wide (X dir) by 5" high (Y dir).
+
+Set the zero point of the drill tip at the bottom-left corner of the rectangle
+that will be printed, leaving room for the machine to draw 6" in the positive X
+and Y directions. I *think* it had room for 6 inches, it says in the manual what
+the box size is. I *think* it was 6"x8" but I could be way off.
+
+I'm reusing as many settings as possible from the D-SUB cutting program.
+
+START MM  02 // Use millimeters. Program ID 01 is taken by the D-SUB program I think.
+ TD=   3.175 // Tool diameter: 1/8 in = 3.175 mm
+FR XY  =03.7 // Divided the suggested feedrate by two, because tool was flexing.
+FR Z   =01.2 // Feedrate based on 1 cutting edge, instead of 4, then slightly reduced.
+SETUP >zcxyu // Allow user to position tool above bottom-left corner.
+Z>C          // Raise tool
+GOfX   8.500 // Point 1 of Figure 1
+GOfY 121.000 //
+GO Z-  9.000 // Insert tool
+GO X   8.000 // Point 2 
+   Y 119.000 //
+GO X   9.000 // Point 3
+   Y 110.500 //
+GO X   6.500 // Point 4
+   Y 100.500 //
+GO X  12.500 // Point 5
+   Y  92.500 //
+GO X  13.500 // Point 6
+   Y  83.500 //
+GO X  25.000 // Point 7
+   Y  70.500 //
+GO X  25.500 // Point 8
+   Y  64.300 //
+GO X  28.000 // Point 9
+   Y  60.500 //
+GO X  30.000 // Point 10
+   Y  60.500 //
+GO X  32.000 // Point 11
+   Y  57.500 //
+GO X  30.000 // Point 12
+   Y  55.000 //
+GO X  31.000 // Point 13
+   Y  51.500 //
+GO X  43.500 // Point 14
+   Y  31.000 //
+GO X  53.000 // Point 15
+   Y  30.000 //
+GO X  63.000 // Point 16
+   Y  25.500 //
+GO X  74.000 // Point 17
+   Y  16.000 //   
+GO X  76.500 // Point 18
+   Y   9.000 //   
+GO X 100.000 // Point 19
+   Y  11.000 //   
+GO X  99.500 // Point 20
+   Y  21.000 //   
+GO X 103.500 // Point 21
+   Y  28.000 //   
+GO X  99.000 // Point 22
+   Y  36.000 //   
+GO X  47.500 // Point 23
+   Y  83.500 //   
+GO X  47.500 // Point 24
+   Y 121.000 //   
+GO X   8.500 // Return to Point 1
+   Y 121.000 //
+Z>C          // Raise tool
+GOfX  78.000 // Point 1 of Figure 2
+GOfY 103.500 //
+GO Z-  9.000 // Insert tool
+GO Y  73.000 // Point 2
+GO Y  89.000 // Point 3 
+GO X  98.000 // Point 4 
+GO Y 103.500 // Point 5
+GO Y  73.000 // Point 6
+Z>C          // Raise tool
+GOfX 110.000 // Point 1 of Figure 3
+GO Z-  9.000 // Insert tool
+GO Y  85.000 // Point 2 of Figure 3
+Z>C          // Raise tool
+GOfY  92.000 // Point 3 
+GO Z-  9.000 // Insert tool
+Z>C          // Raise tool
+GOfX 124.500 // Point 1 of Figure 4
+GOfY  73.000 //
+GO Z-  9.000 // Insert tool
+Z>C          // Raise tool
+GOfY  79.000 // Point 2 of Figure 4
+GO Z-  9.000 // Insert tool
+GO Y 100.000 // Point 3 of Figure 4
+Z>C          // Raise tool
+GOfX   0.000 // Return home
+GOfY   0.000 //
+GO Z-  9.000 // Insert tool
+GO X 144.000 // Point 2 of border
+GO Y 126.000 // Point 3 of border
+GO X   0.000 // Point 4 of border
+GO Y   0.000 // Return home.
+Z>C          // Raise tool
+END NEW PART //

+ 104 - 0
projects/javascript-cnc-machine/CNC_California_Subs.txt

@@ -0,0 +1,104 @@
+START MM  02 // Use millimeters. Program ID 01 is taken by the D-SUB program I think.
+ TD=   3.175 // Tool diameter: 1/8 in = 3.175 mm
+FR XY  =03.7 // Divided the suggested feedrate by two, because tool was flexing.
+FR Z   =01.2 // Feedrate based on 1 cutting edge, instead of 4, then slightly reduced.
+SETUP >zcxyu // Allow user to position tool above bottom-left corner.
+Z>C          // Raise tool
+GOfX   8.500 // Point 1 of Figure 1
+GOfY 121.000 //
+GO Z-  9.000 // Insert tool
+GO X   8.000 // Point 2 
+   Y 119.000 //
+GO X   9.000 // Point 3
+   Y 110.500 //
+GO X   6.500 // Point 4
+   Y 100.500 //
+GO X  12.500 // Point 5
+   Y  92.500 //
+GO X  13.500 // Point 6
+   Y  83.500 //
+GO X  25.000 // Point 7
+   Y  70.500 //
+GO X  25.500 // Point 8
+   Y  64.300 //
+GO X  28.000 // Point 9
+   Y  60.500 //
+GO X  30.000 // Point 10
+   Y  60.500 //
+GO X  32.000 // Point 11
+   Y  57.500 //
+GO X  30.000 // Point 12
+   Y  55.000 //
+GO X  31.000 // Point 13
+   Y  51.500 //
+GO X  43.500 // Point 14
+   Y  31.000 //
+GO X  53.000 // Point 15
+   Y  30.000 //
+GO X  63.000 // Point 16
+   Y  25.500 //
+GO X  74.000 // Point 17
+   Y  16.000 //   
+GO X  76.500 // Point 18
+   Y   9.000 //   
+GO X 100.000 // Point 19
+   Y  11.000 //   
+GO X  99.500 // Point 20
+   Y  21.000 //   
+GO X 103.500 // Point 21
+   Y  28.000 //   
+GO X  99.000 // Point 22
+   Y  36.000 //   
+GO X  47.500 // Point 23
+   Y  83.500 //   
+GO X  47.500 // Point 24
+   Y 121.000 //   
+GO X   8.500 // Return to Point 1
+   Y 121.000 //
+Z>C          // Raise tool
+CALL SUB 111 //
+Z>C          // Raise tool
+CALL SUB 222
+Z>C          // Raise tool
+CALL SUB  33
+Z>C          // Raise tool
+GOfX   0.000 // Return home
+GOfY   0.000 //
+GO Z-  9.000 // Insert tool
+GO X 144.000 // Point 2 of border
+GO Y 126.000 // Point 3 of border
+GO X   0.000 // Point 4 of border
+GO Y   0.000 // Return home.
+Z>C          // Raise tool
+END NEW PART //
+
+
+SUB 111     
+GOfX  78.000 // Point 1 of Figure 2
+GOfY 103.500 //
+GO Z-  9.000 // Insert tool
+GO Y  73.000 // Point 2
+GO Y  89.000 // Point 3 
+GO X  98.000 // Point 4 
+GO Y 103.500 // Point 5
+GO Y  73.000 // Point 6
+SUB RETURN     
+
+SUB 222
+GOfX 110.000 // Point 1 of Figure 3
+GO Z-  9.000 // Insert tool
+GO Y  85.000 // Point 2 of Figure 3
+Z>C          // Raise tool
+GOfY  92.000 // Point 3 
+GO Z-  9.000 // Insert tool
+SUB RETURN
+
+SUB 33
+GOfX 124.500 // Point 1 of Figure 4
+GOfY  73.000 //
+GO Z-  9.000 // Insert tool
+Z>C          // Raise tool
+GOfY  79.000 // Point 2 of Figure 4
+GO Z-  9.000 // Insert tool
+GO Y 100.000 // Point 3 of Figure 4
+SUB RETURN

+ 64 - 0
projects/javascript-cnc-machine/CNC_D-SUB_PROGRAM.txt

@@ -0,0 +1,64 @@
+This is a D-sub socket cutting program.  Author: William Hilton
+Use a 1/8 inch diameter HSS (high speed steel) mill that can drill holes. The tool's cutting depth should be slightly > 9mm. The metal to be cut is high carbon steel. Feed Rate = RPM * CHIPSIZE * NUM OF BLADES (Gracias Doug!) Use lowest belt, with dial at slightly below 4.
+
+Edit the program to cut different connector types:
+25-pin: 47      15-pin: 33.75       9-pin: 25
+
+START MM  01 // Use millimeters, program ID 01
+ TD=   3.175 // Tool diameter: 1/8 in = 3.175 mm
+FR XY  =03.7 // Divided the suggested feedrate by two, because tool was flexing.
+FR Z   =01.2 // Feedrate based on 1 cutting edge, instead of 4, then slightly reduced.
+SETUP >zcxyu // Allow user to position tool above 1st hole.
+REPEAT    02 // Second traverse gets the edges better
+GOfX   0.000 // Go to 1st hole
+GOfY   0.000 //
+GO Z-  6.000 // Drill 1st hole
+Z>C          // Raise tool
+CALL SUB  10 // Cut left side...
+ZERO AT      // (Set origin to right hole)
+   X  47.000 // * Change depending on connector *
+   Y   0.000 //
+CALL SUB  11 // ...Cut right side...
+ZERO AT      // (Reset origin to left hole)
+   X- 47.000 // * Change depending on connector *              
+   Y   0.000 //
+GO X   6.920 // ...And return to Point 1.
+   Y   3.410 //
+Z>C          // Raise tool
+GOfX  47.000 // Go to 2nd hole * Change depending on connector *
+   Y   0.000 //
+GO Z  -6.000 // Drill 2nd hole
+Z>C          // Raise tool
+REPEAT END   //
+END NEW PART //
+
+SUB 10       // Left Side (located on line 050)
+GO X   6.920 // Point 1
+   Y   3.410 //
+GO Z-  9.000 // Insert tool
+ARC          // Point 2
+ XC=   6.920 //
+ YC=   1.500 //
+  a= 101.470 //
+GO X   5.740 // Point 3
+   Y-  2.280 //
+ARC          // Point 4
+ XC=   7.120 //
+ YC=-  2.000 //
+  a=  79.530 //
+SUB RETURN   //
+
+SUB 11       // Right Side (located on line 100)
+GO X-  7.120 // Point 5
+   Y-  3.410 //
+ARC          // Point 6
+ XC=-  7.120 //
+ YC=-  2.000 //
+  a=  79.530 //
+GO X-  5.050 // Point 7
+   Y   1.120 //
+ARC          // Point 8
+ XC=-  6.920 //
+ YC=   1.500 //
+  a= 101.470 //
+SUB RETURN   //

+ 802 - 0
projects/javascript-cnc-machine/CNC_Simulator.html

@@ -0,0 +1,802 @@
+<!--
+layout: false
+-->
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
+
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<!--
+Useful websites:
+Comparison of Canvas and SVG
+http://people.mozilla.com/~vladimir/xtech2006/
+
+Canvas Tutorial
+https://developer.mozilla.org/en/Canvas_tutorial/
+
+Animating with Javascript + Canvas
+http://dev.opera.com/articles/view/blob-sallad-canvas-tag-and-javascrip/
+-->
+<title>CNC Simulator</title>
+
+<script type="text/javascript">
+// Global variables
+var temp = "";
+var start_second = 0;
+var intervalID = 0;
+var running = true;
+var seconds = 0; // 6 degrees
+var time_inc = 1; // in seconds
+var sec_hand_length = 70;
+var min_hand_length = 65;
+var hour_hand_length = 35;
+var clock_radius = 75;
+
+
+// Function to run as soon as page loads
+function init()
+{
+    var d = new Date();
+    var curr_hour = d.getHours();
+    var curr_min = d.getMinutes();
+    start_second = d.getSeconds();
+    seconds = start_second + 60*curr_min + 60*60*((curr_hour) % 12);
+    intervalID = window.setInterval(animate,1000);
+    
+    // Initialize the canvas.
+    
+}
+
+
+
+// Animate one frame of the animation
+function animate()
+{
+    var canvas = document.getElementById("cnc_canvas");
+    var ctx = canvas.getContext("2d");
+    var sec_angle = 0;
+    var min_angle = 0;
+    var hour_angle = 0;
+    //alert("Breakpoint animate");
+    // Always put the terminating code near the top in case there is an error later on and the function exits before it can stop the interval timer.
+    seconds = seconds + time_inc;
+    //if (seconds % 60 > (3+start_second) % 60) {
+    //    stop();
+    //}
+    
+    with (ctx) {
+        // What? No "clear canvas" command?
+        clearRect(0,0,400,600);
+        
+        // Draw clock face
+        strokeStyle = "black";
+        lineWidth = 1;
+        beginPath();
+        arc(100, 100, clock_radius, 0.001, 2*Math.PI, false);
+        //alert("Breakpoint arc");
+        stroke();
+        //alert("Breakpoint stroke");
+        
+        // Draw second hand.
+        lineWidth = 1;
+        strokeStyle = "green";
+        beginPath();
+        moveTo(100,100);
+        sec_angle = 180-360/60*seconds;
+        //alert("Breakpoint sec_angle = " + String(sec_angle));
+        temp = "x = " + String(100+sec_hand_length*Sin(sec_angle)) + " y = " + String(100+sec_hand_length*Cos(sec_angle));
+        //alert("Breakpoint " + temp);        
+        lineTo(100+sec_hand_length*Sin(sec_angle), 100+sec_hand_length*Cos(sec_angle));
+        //alert("Breakpoint lineTo");
+        stroke();
+        
+        // Draw minute hand.
+        beginPath();
+        strokeStyle = "red";
+        lineWidth = 2;
+        moveTo(100,100);
+        min_angle = 180-360/60*seconds/60;
+        lineTo(100+min_hand_length*Sin(min_angle), 100+min_hand_length*Cos(min_angle));
+        stroke();
+        
+        // Draw hour hand.
+        lineWidth = 3;
+        strokeStyle = "blue";
+        beginPath();
+        moveTo(100,100);
+        hour_angle = 180-360/12*seconds/60/60;
+        lineTo(100+hour_hand_length*Sin(hour_angle), 100+hour_hand_length*Cos(hour_angle));
+        stroke();
+    }
+}
+
+function stop() {
+    window.clearInterval(intervalID);
+    running = false;
+}
+function start() {
+    time_inc = 1;
+    // Only start if we're not already running an animation.
+    if (!running) {
+        running = true;
+        intervalID = window.setInterval(animate,1000);
+    }
+}
+function start_high_speed() {
+    // If we're not already running an animation.
+    if (running) {
+        // Kill previous interval
+        stop();
+    }
+    time_inc = 15;
+    running = true;
+    intervalID = window.setInterval(animate,10);        
+}
+
+function d2r(degrees) {
+    return degrees*Math.PI/180;
+}
+function Sin(degrees) {
+    return Math.sin(d2r(degrees));
+}
+function Cos(degrees) {
+    return Math.cos(d2r(degrees));
+}
+</script>
+
+
+<style type="text/css">
+td {
+    padding-top: 10px;
+}
+</style>
+</head>
+
+<body onload="init()">
+<h2 style="margin-bottom: 0">CNC Simulator</h2>
+<table>
+ <tr>
+  <td style="vertical-align: top">
+   <div style="border-width: 5px; border-style: ridge;">
+    <p style="font-weight: bold; margin: 10px">
+     <span id="x_disp">X:</span>
+     <br>
+     <span id="y_disp">Y:</span>
+     <br>
+     <span id="z_disp">Z:</span>
+     <br>
+     <span id="time_disp">Time:</span>
+    </p>
+   </div>
+   <form action>
+    <table>
+     <tr>
+      <td>
+        <label for="ppi_input">Pixels per inch:</label>
+        <br>
+        <input id="ppi_input" type="text" value="127" style="width: 5em">
+      </td>
+      <td>
+       <label for="time_step_input">Time step:</label>
+       <br>
+       <input id="time_step_input" type="text" value="1" style="width: 5em">
+      </td>
+     </tr>
+     <tr>
+      <td>
+        <label for="speed_input">Speed factor:</label>
+        <br>
+        <input id="speed_input" type="text" value="5" style="width: 5em; margin-right: 5em;">
+      </td>
+      <td>
+        <label for="blitz_input">Blitz mode:</label>
+        <input type="checkbox" id="blitz_input" checked="checked">
+      </td>
+     </tr>
+     <tr>
+      <td>
+        <label for="offset_x">Offset X:</label>
+        <br>
+        <input id="offset_x" type="text" value="50" style="width: 5em; margin-right: 5em;">
+      </td>
+      <td>
+        <label for="offset_y">Offset Y:</label>        
+        <br>
+        <input id="offset_y" type="text" value="50" style="width: 5em; margin-right: 5em;">
+      </td>
+     </tr>
+     <tr>
+      <td colspan="2">
+    <label for="code_input">Enter CNC code here:<br></label>
+    <textarea rows="20" cols="50" id="code_input">START MM  01 // Use millimeters, program ID 01
+ TD=   3.175 // Tool diameter: 1/8 in = 3.175 mm
+FR XY  =03.7 // Divided the suggested feedrate by two, because tool was flexing.
+FR Z   =01.2 // Feedrate based on 1 cutting edge, instead of 4, then slightly reduced.
+SETUP &gt;zcxyu // Allow user to position tool above 1st hole.
+REPEAT    02 // Second traverse gets the edges better
+GOfX   0.000 // Go to 1st hole
+GOfY   0.000 //
+GO Z-  6.000 // Drill 1st hole
+Z&gt;C          // Raise tool
+CALL SUB  10 // Cut left side...
+ZERO AT      // (Set origin to right hole)
+   X  47.000 // * Change depending on connector *
+   Y   0.000 //
+CALL SUB  11 // ...Cut right side...
+ZERO AT      // (Reset origin to left hole)
+   X- 47.000 // * Change depending on connector *              
+   Y   0.000 //
+GO X   6.920 // ...And return to Point 1.
+   Y   3.410 //
+Z&gt;C          // Raise tool
+GOfX  47.000 // Go to 2nd hole * Change depending on connector *
+   Y   0.000 //
+GO Z  -6.000 // Drill 2nd hole
+Z&gt;C          // Raise tool
+REPEAT END   //
+END NEW PART //
+
+SUB 10       // Left Side (located on line 050)
+GO X   6.920 // Point 1
+   Y   3.410 //
+GO Z-  9.000 // Insert tool
+ARC          // Point 2
+ XC=   6.920 //
+ YC=   1.500 //
+  a= 101.470 //
+GO X   5.740 // Point 3
+   Y-  2.280 //
+ARC          // Point 4
+ XC=   7.120 //
+ YC=-  2.000 //
+  a=  79.530 //
+SUB RETURN   //
+
+SUB 11       // Right Side (located on line 100)
+GO X-  7.120 // Point 5
+   Y-  3.410 //
+ARC          // Point 6
+ XC=-  7.120 //
+ YC=-  2.000 //
+  a=  79.530 //
+GO X-  5.050 // Point 7
+   Y   1.120 //
+ARC          // Point 8
+ XC=-  6.920 //
+ YC=   1.500 //
+  a= 101.470 //
+SUB RETURN   //
+    </textarea>
+    <br>
+     <input name="submit" type="button" value="Click To Run Simulator" onclick="startSimulation();">
+     <input id="pause_input" type="button" value="Pause" onclick="pause();">
+    </td>
+    </tr>
+    </table>
+    </form>
+   </td>
+   <td style="vertical-align:top">
+    <canvas id="cnc_canvas" width="780" height="650" style="border:1px solid black"></canvas>
+   </td>
+ </tr>
+</table>
+<hr>
+<div class="output_wrapper">
+ <b>Output:</b>
+ <pre id="output"></pre>
+</div>
+<script type="text/javascript">
+// The so-called Prototype Dollar function, a shortcut for document.getElementById()
+function $() {
+    var elements = new Array();
+    for (var i = 0; i < arguments.length; i++) {
+        var element = arguments[i];
+        if (typeof element == "string")
+            element = document.getElementById(element);
+        if (arguments.length == 1)
+            return element;
+        elements.push(element);
+    }
+    return elements;
+}
+ctx = null;
+canvas = null;
+function clear_vars() {// Global variables
+    unit = "MM"; // or "IN"
+    time_step = 1; // update every half second.
+    ppi = 96; // Pixels per inch
+    cf = 1; // Pixel to unit ratio
+    td = 1; // Tool diameter
+    max_frx = 1; // Maximum feed rate X
+    max_fry = 1; // Maximum feed rate Y
+    max_frz = 1; // Maximum feed rate Z
+    x_inc = 1; // Distance to move per tick
+    y_inc = 1; // Distance to move per tick
+    z_inc = 1; // Distance to move per tick
+    a_inc = 1; // Distance to move per tick
+    mar_x = 10; // Horizontal margin of origin
+    mar_y = 10; // Vertical margin of origin
+    tool_c = 2; // Clearance height.
+    tool_x = 0; // Tool position X
+    tool_y = 0; // Tool position Y
+    tool_z = 0; // Tool position Z
+    tool_a = 0; // Tool angle (used for arcs)
+    arc_r = 0;  // Radius of currently drawn arc.
+    arc_dir = false; // Counter-clockwise
+    old_x = 0;  // Previous tool position X
+    old_y = 0;  // Previous tool position Y
+    old_z = 0;  // Previous tool position Z
+    old_a = 0;  // Previous tool angle (used for arcs)
+    goal_x = 0; // Destination coordinate
+    goal_y = 0; // Destination coordinate
+    goal_z = 0; // Destination coordinate
+    xc = 0; // Used for drawing arcs
+    yc = 0; // Used for drawing arcs
+    ac = 0; // Used for drawing arcs
+    time = 0;   // Time needed to execute cut.
+    time_x = 0;
+    time_y = 0;
+    time_z = 0;
+    time_a = 0; // Used for arcs
+    time_elapsed = 0;
+    n = 0;      // Line index
+    lines = []; // Array of each line of code
+    line = "";  // Current line
+    moving = false; // Set to true when the tool is moving from one point to another.
+    arcing = false; // Set to true when the tool is arcing.
+    interval_id = 0; // Variable needed to stop the timer during real-time mode
+    blitz_done = false; // Variable used to stop the timer in blitz mode.   
+    paused = false; // Pause/unpaused state
+    speed = 1;
+    stack = []; // Line numbers to return to
+    canvas_stack = 0; // How many times restore() the canvas
+    canvas = $("cnc_canvas");
+    ctx = canvas.getContext("2d");   
+}
+function startSimulation() {
+    // Clean up variables from the last run.
+    clear_vars();
+    // Clear debug output
+    $("output").innerHTML = "";
+    // Because the previous run might not have finished
+    for (var i = 0; i < 50; i++) {
+        ctx.restore();
+    }
+    // Stop the clock
+    stop();
+    // Since there is no "clear canvas" command.
+    ctx.fillStyle = "white"
+    ctx.fillRect(0, 0, canvas.width, canvas.height);
+    ctx.strokeStyle = "black";
+    /*
+    The canvas has it's origin in the top-left corner, but the CNC
+    Machine has it's origin in the bottom-left corner. Therefore,
+    we translate the origin and apply a transformation matrix to
+    flip the Y direction.
+    */   
+    ctx.save();
+    canvas_stack = canvas_stack + 1;
+    ctx.transform(1, 0, 0, -1, 0, 0);  
+    mar_x = parseFloat($("offset_x").value);
+    mar_y = parseFloat($("offset_y").value);
+    ctx.translate(mar_x, mar_y-canvas.height); 
+    ctx.save();
+    canvas_stack = canvas_stack + 1;
+    
+    lines = $("code_input").value.split("\n"); //str.split("\n");
+    ppi = parseFloat($("ppi_input").value);    
+    // Start the animation sequence
+    n = -1;    
+    debugn("There are " + lines.length + " lines");
+    // Stop all animations
+    window.clearInterval(interval_id);
+    paused = true;
+    pause();
+}
+function pause() {
+    if (paused) {
+        paused = false;
+        // Set the speed
+        speed = parseFloat($("speed_input").value);
+        time_step = parseFloat($("time_step_input").value);
+        // Start the CNC simulation.
+        if ($("blitz_input").checked) {
+            while (blitz_done == false) {
+                tick();
+            }
+        } else {
+            interval_id = window.setInterval(tick,1000*time_step/speed);
+        }
+        $("pause_input").value = "Pause";
+    } else {
+        paused = true;
+        window.clearInterval(interval_id);
+        $("pause_input").value = "Resume";
+    }
+}
+function nextLine() {
+    n = n + 1;
+    if (n >= lines.length) {
+        return false;
+    } else {
+        line = lines[n];
+        return true;
+    }
+}
+function startsWith(s1, s2) {
+    if (s1.substr(0,s2.length) == s2) {
+        return true;
+    } else {
+        return false;
+    }
+}
+function deg2rad(d) {
+    return (Math.PI/180)*d;
+}
+function rad2deg(r) {
+    return (180/Math.PI)*r;
+}
+function tick() {    
+    if (moving) {
+        // Store previous position
+        old_x = tool_x;
+        old_y = tool_y;
+        old_z = tool_z;
+        old_a = tool_a;
+        // Figure out new position
+        if (time < time_step) {
+            if (arcing) {
+                tool_a = goal_a;
+                tool_x = xc + Math.cos(tool_a)*arc_r;
+                tool_y = yc + Math.sin(tool_a)*arc_r;
+            } else {
+                tool_x = goal_x;
+                tool_y = goal_y;
+                tool_z = goal_z;
+            }
+            time_elapsed = time_elapsed + time;
+        } else {
+            if (arcing) {
+                tool_a = tool_a + a_inc;
+                tool_x = xc + Math.cos(tool_a)*arc_r;
+                tool_y = yc + Math.sin(tool_a)*arc_r;
+            } else {
+                tool_x = tool_x + x_inc;
+                tool_y = tool_y + y_inc;
+                tool_z = tool_z + z_inc;
+            }
+            time_elapsed = time_elapsed + time_step;
+        }              
+        // Update display
+        $("x_disp").innerHTML = "X: " + tool_x;
+        $("y_disp").innerHTML = "Y: " + tool_y;
+        $("z_disp").innerHTML = "Z: " + tool_z;
+        $("time_disp").innerHTML = "Time: " + time_elapsed;
+        
+        // Draw line if tool is below surface.
+        if (tool_z < 0) {
+            with (ctx) {            
+                // Draw hole
+                beginPath();
+                fillStyle = "black";
+                arc(tool_x, tool_y, td/2.0, 0, Math.PI*2.0, true);
+                fill();
+                // Draw line
+                lineCap = "round";
+                lineWidth = td;
+                beginPath();
+                strokeStyle = "black";
+                if (arcing) {                    
+                    arc(xc, yc, arc_r, old_a, tool_a, arc_dir);
+                } else {                    
+                    moveTo(old_x, old_y);                
+                    lineTo((tool_x), (tool_y));
+                }
+                stroke();                  
+            }
+        } else {
+            // Draw hollow dot (so we can see the path of the tool)
+            with (ctx) {  
+                lineWidth = 1/cf;
+                strokeStyle = "blue";
+                strokeRect((tool_x)-1/cf, (tool_y) -1/cf, 3/cf, 3/cf);
+            }
+        }
+        // Decrease time
+        time = time - time_step;
+        // Finish line
+        if (time < 0) {
+            time = 0;
+            moving = false;
+            arcing = false;
+        }
+        debug(".");
+    } else {
+        // Always safest to put this first, in case of unhandled syntax
+        // errors later on in the code.
+        if (nextLine()) {
+            ndebug("Line " + n + ": ");
+        } else {
+            ndebug("Ended because there are no more lines.");
+            n = -1;
+            ndebug("canvas_stack = " + canvas_stack);
+            for (var i = 0; i < canvas_stack; i++) {
+                ndebug("ctx.restore()");
+                ctx.restore();
+            }
+            blitz_done = true;
+            window.clearInterval(interval_id);
+            return;
+        }
+        //debug(line);
+        if (startsWith(line, "START")) {
+            // Set unit
+            unit = line.substr(6,2);
+            debugd("Unit: " + unit);
+            if (unit == "MM") {
+                debugd("Millimeters");
+                cf = ppi / 25.4;
+            } else if (unit == "IN") {
+                debugd("Inches");
+                cf = ppi;
+            } else {
+                ndebug("Invalid unit");
+                n = lines.length;
+                return;
+            }
+            debug("Scale: " + cf);
+            ctx.scale(cf, cf);
+        } else if (startsWith(line, " TD=")) {
+            // Set tool diameter
+            debugd("Tool Diameter: " + line.substring(4,12));
+            td = parseFloat(line.substring(4,12));
+            ctx.lineWidth = td;            
+            debug("ctx.lineWidth = " + ctx.lineWidth);
+        } else if (startsWith(line, "FR")) {
+            // TODO: set feed rate
+            debugd("Setting feed rate for " + line.substr(3,3) + " to " + line.substring(8,12));
+            if (line.indexOf("X") != -1) {
+                max_frx = parseFloat(line.substring(8,12));
+                debug(" set FR X = " + max_frx);
+            }
+            if (line.indexOf("Y") != -1) {
+                max_fry = parseFloat(line.substring(8,12));
+                debug(" set FR Y = " + max_fry);
+            }
+            if (line.indexOf("Z") != -1) {
+                max_frz = parseFloat(line.substring(8,12));
+                debug(" set FR Z = " + max_frz);
+            }
+        } else if (startsWith(line, "SETUP")) {
+            // This step doesn't translate well, and would get annoying
+            debug("Setup: " + line.substring(7,12));
+            debug(" Note: in real life, this command would let you position the tool at a new 'zero' position.");
+        } else if (startsWith(line, "Z>C")) {
+            tool_z = tool_c;
+            debug("Z>C: Z = " + String(tool_c));
+        } else if (startsWith(line, "GO")) {
+            goal_x = tool_x; time_x = 0;
+            goal_y = tool_y; time_y = 0;
+            goal_z = tool_z; time_z = 0;
+            debugd("Go");
+            do {
+                if (line.substr(3,1) == "f") {
+                    // TODO: how fast is "fast" anyway?
+                }
+                if (line.substr(3,1) == "X") {
+                    goal_x = parseFloat(line.substring(5,12));
+                    if (line.substr(4,1) == "-") {
+                        goal_x = -goal_x;
+                    }                    
+                    time_x = Math.abs((goal_x - tool_x) / max_frx);
+                    debugd("X coor: " + goal_x);
+                } else if (line.substr(3,1) == "Y") {
+                    goal_y = parseFloat(line.substring(5,12));
+                    if (line.substr(4,1) == "-") {
+                        goal_y = -goal_y;
+                    }
+                    time_y = Math.abs((goal_y - tool_y) / max_fry);
+                    debugd("Y coor: " + goal_y);
+                } else if (line.substr(3,1) == "Z") {                    
+                    goal_z = parseFloat(line.substring(5,12));                    
+                    if (line.substr(4,1) == "-") {
+                        goal_z = -goal_z;
+                    }
+                    time_z = Math.abs((goal_z - tool_z) / max_frz);
+                    debugd("Z coor: " + goal_z);
+                }
+                n = n+1;
+                if (n >= lines.length) {
+                    break;
+                }
+                line = lines[n];
+            } while (line.substr(0,2) == "  ")
+            n = n - 1;
+            // Compute how many seconds it will take to execute this cut
+            time = Math.max(Math.max(time_x, time_y), time_z);
+            debugd("Time Required: "+time);
+            x_inc = (goal_x - tool_x) / time * time_step;
+            y_inc = (goal_y - tool_y) / time * time_step;
+            z_inc = (goal_z - tool_z) / time * time_step;
+            debug("X inc: " + x_inc + " Y inc: " + y_inc +" Z inc: " + z_inc);
+            moving = true;
+        } else if (startsWith(line, "ZERO AT")) {
+            // Translate the canvas origin
+            debugd("ZERO AT");
+            goal_x = 0; time_x = 0;
+            goal_y = 0; time_y = 0;
+            goal_z = 0; time_z = 0;
+            if (!nextLine()) { return; }
+            while (line.substr(0,2) == "  ") {
+                if (line.substr(3,1) == "X") {
+                    goal_x = parseFloat(line.substring(5,12));
+                    if (line.substr(4,1) == "-") {
+                        goal_x = -goal_x;
+                    }
+                    debug(" X coor: " + goal_x);
+                } else if (line.substr(3,1) == "Y") {
+                    goal_y = parseFloat(line.substring(5,12));                   
+                    if (line.substr(4,1) == "-") {
+                        goal_y = -goal_y;
+                    }
+                    debug(" Y coor: " + goal_y);
+                } else if (line.substr(3,1) == "Z") {                    
+                    goal_z = parseFloat(line.substring(5,12));                    
+                    if (line.substr(4,1) == "-") {
+                        goal_z = -goal_z;
+                    }
+                    debug(" Z coor: " + goal_z);
+                }
+                if (!nextLine()) { break; }
+            } 
+            n = n - 1;
+            // Translate the canvas origin
+            ctx.save();            
+            ctx.translate(goal_x, goal_y);
+            canvas_stack = canvas_stack + 1;
+            // Untranslate tool
+            tool_x = tool_x - goal_x;
+            tool_y = tool_y - goal_y;
+        } else if (startsWith(line, "ARC")) {
+            debugd("ARC");
+            if (!nextLine()) { return; }
+            if (line.substr(0,4) == " XC=") {
+                xc = parseFloat(line.substring(5,12));
+                if (line.substr(4,1) == "-") {
+                    xc = -xc;
+                }
+                debug(" XC: " + xc);
+            } else {
+                debug("I really expected a line starting with ' XC='");
+            }
+            if (!nextLine()) { return; }
+            if (line.substr(0,4) == " YC=") {
+                yc = parseFloat(line.substring(5,12));
+                if (line.substr(4,1) == "-") {
+                    yc = -yc;
+                }
+                debug(" YC: " + yc);
+            } else {
+                debug("I really expected a line starting with ' YC='");
+            }
+            if (!nextLine()) { return; }
+            if (line.substr(0,4) == "  a=") {
+                // I call the variable 'ac' for resemblance
+                ac = parseFloat(line.substring(5,12));
+                if (line.substr(4,1) == "-") {
+                    ac = -ac;
+                    arc_dir = true;
+                } else {
+                    arc_dir = false;
+                }
+                debugd(" AC: " + ac);                
+                ac = deg2rad(ac);
+                debugd("in radians: " + ac); 
+            } else {
+                debug("I really expected a line starting with '  a='");
+            }
+            arc_r = Math.sqrt( Math.pow(xc-tool_x, 2) +
+                               Math.pow(yc-tool_y, 2) );
+            debugd("R = " + arc_r);
+            var dist = Math.abs(arc_r*ac);
+            var xyfr = (max_frx + max_fry)/2;
+            time = dist/xyfr;
+            debugd("Time Required: " + time);            
+            a_inc = ac/time*time_step;
+            debugd("a_inc = " + a_inc);
+            // Math.atan2 seems to be measuring Clockwise from the Y
+            // axis. Ridiculous.
+            tool_a = Math.atan2(tool_y-yc, tool_x-xc);
+            debugd("tool_a = " + rad2deg(tool_a) + " degrees");
+            goal_a = Math.atan2(tool_y-yc, tool_x-xc) + ac;
+            debug("goal_a = " + rad2deg(goal_a) + " degrees");
+            moving = true;
+            arcing = true;
+            //arcing = true;
+        } else if (startsWith(line, "CALL SUB")) {
+            // Push line # onto stack
+            debugd("Calling Sub");
+            stack.push(n);
+            ctx.save();
+            canvas_stack = canvas_stack + 1;
+            // Get the SUB id
+            var sub_id = line.substring(9,12).replace(" ","");
+            var sub_id = "SUB " + sub_id;
+            debugd("Scanning for '" + sub_id +"'");
+            // Move the cursor location to the start of the subroutine.
+            n = -1;
+            while (n < lines.length) {
+                n = n + 1;
+                line = lines[n];
+                if (line.substr(0,sub_id.length) == sub_id) {
+                    debugd("Found '" + sub_id + "' on line " + String(n));
+                    debug("Stack: " + String(stack));
+                    break;
+                }
+            }                
+        } else if (startsWith(line, "SUB RETURN")) {
+            // Return to our line # in the stack.
+            n = stack.pop();
+            ctx.restore();
+            canvas_stack = canvas_stack - 1;
+            debugd("SUB RETURN return to line " + String(n));
+            debug("Stack: " + String(stack));
+        } else if (startsWith(line, "REPEAT END")) {
+            if (stack.length > 0) {
+                n = stack.pop();
+                debug("REPEAT END return to line " + String(n));
+            } else {
+                debug("Passing REPEAT END");
+            }
+        } else if (startsWith(line, "REPEAT")) {
+            var rep_num = parseInt(line.substring(10,12))
+            debugd("REPEAT " + String(rep_num) + " times");
+            for (var i = 1; i < rep_num; i++) {
+                stack.push(n);
+            }
+            debug("Stack: " + String(stack));
+        } else if (startsWith(line, "END")) {
+            n = lines.length;
+            debug("Encountered an END");
+        } else {
+            debug("Skipping line: " + line);
+        }
+    }  
+}
+
+/*
+These are placed at the end, so if prior code has syntax errors,
+the page will clearly be broken.
+*/
+function debug(str) {
+    var obj;
+    obj = $("output");
+    obj.innerHTML = obj.innerHTML + str;
+}
+function ndebug(str) {
+    var obj;
+    obj = $("output");
+    obj.innerHTML = obj.innerHTML + "\n" + str;
+}
+function debugn(str) {
+    var obj;
+    obj = $("output");
+    obj.innerHTML = obj.innerHTML + str + "\n";
+}
+function ndebugn(str) {
+    var obj;
+    obj = $("output");
+    obj.innerHTML = obj.innerHTML + "\n" + str + "\n";
+}
+function debugd(str) {
+    var obj;
+    obj = $("output");
+    obj.innerHTML = obj.innerHTML + str + "... ";
+}
+</script>
+<footer>
+<hr>
+<p style="text-align: center; font-style:italic"><a href="http://validator.w3.org/#validate-by-upload">Freaking valid HTML5 baby!!!</a></p>
+</footer>
+</body>
+</html>

+ 36 - 0
projects/javascript-cnc-machine/CNC_Spiral.txt

@@ -0,0 +1,36 @@
+// Draw a spiral
+START IN  
+ TD=   0.075
+FR XY  =0.20
+GO Z- .1
+REPEAT     4
+ZERO AT
+   X- 0.1
+   Y  0.0
+ARC
+ XC= 0
+ YC= 0
+  a= 90
+ZERO AT
+   X 0
+   Y -.1
+ARC
+ XC= 0
+ YC= 0
+  a= 90
+ZERO AT
+   X .1
+   Y 0
+ARC
+ XC= 0
+ YC = 0
+  a = 90
+ZERO AT
+   X 0
+   Y .1
+ARC
+ XC= 0
+ YC= 0
+  a= 90
+REPEAT END
+END

+ 117 - 0
projects/javascript-cnc-machine/CNC_UC_Logo.txt

@@ -0,0 +1,117 @@
+START MM  01 // Use millimeters, program ID 01
+ TD=   3.175 // Tool diameter: 1/8 in = 3.175 mm
+FR XY  =03.7 // Divided the suggested feedrate by two, because tool was flexing.
+FR Z   =01.2 // Feedrate based on 1 cutting edge, instead of 4, then slightly reduced.
+SETUP >zcxyu // Allow user to position tool above 1st hole.
+GOfX  13.000
+GOfY  174
+GO Z-  3.000
+GO Y  167
+GO X 30
+GO Y 85
+ARC
+ XC= 73
+ YC= 88
+  a= 94
+GO X 80
+   Y 45
+ARC
+ XC= 130
+ YC= 83
+  a= 45
+GO X 123
+   Y 20
+GO Y 27
+   X 125
+ARC 
+ XC= 138
+ YC= 89
+  a=-140
+GO X 110
+   Y 145
+GO Y 154
+ARC
+ XC= 131
+ YC= 89
+  a= 105
+GO X 75
+GO Y 51
+ARC
+ XC= 76
+ YC= 83
+  a=-90
+GO X 44
+   Y 84
+GO Y 174
+GO X 13
+Z>C
+
+GOfX 100
+GOfY 175
+GO Z- 9
+GO Y 167
+GO X 128
+GO Y 175
+GO X 100
+Z>C
+
+GOfX 130
+GOfY 158
+GO Z-9
+GO Y 80
+ARC
+ XC= 96
+ YC= 83
+  a=-40
+GO X 120
+   Y 59
+ARC
+ XC= 144
+ YC= 83
+  a=-40
+GO X 110
+   Y 80
+GO Y 124
+ARC
+ XC= 150
+ YC= 88
+  a= 164
+GO X 178
+GO Y 43
+GO X 176
+   Y 45
+ARC
+ XC= 157
+ YC= 91
+  a=-60
+GO X 126
+   Y 53
+ARC
+ XC= 105
+ YC= 87
+  a= 55
+GO X 145
+   Y 83
+GO Y 152
+ARC
+ XC= 149
+ YC= 121
+  a=-85
+GO X 180
+GO Y 127
+GO X 186
+   Y 126
+GO X 190
+   Y 154
+GO X 184
+   Y 155
+GO X 183
+   Y 148
+ARC
+ XC= 140
+ YC= 65
+  a= 21
+GO X 148
+GO Y 158
+GO X 130
+END

+ 57 - 0
projects/javascript-cnc-machine/index.html

@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>Javascript CNC Machine Emulator</title>
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <link rel="stylesheet" href="//yegor256.github.io/tacit/tacit.min.css">
+    <!-- favicon -->
+    <link rel="apple-touch-icon" sizes="57x57" href="/favicon/apple-touch-icon-57x57.png">
+    <link rel="apple-touch-icon" sizes="60x60" href="/favicon/apple-touch-icon-60x60.png">
+    <link rel="apple-touch-icon" sizes="72x72" href="/favicon/apple-touch-icon-72x72.png">
+    <link rel="apple-touch-icon" sizes="76x76" href="/favicon/apple-touch-icon-76x76.png">
+    <link rel="apple-touch-icon" sizes="114x114" href="/favicon/apple-touch-icon-114x114.png">
+    <link rel="apple-touch-icon" sizes="120x120" href="/favicon/apple-touch-icon-120x120.png">
+    <link rel="apple-touch-icon" sizes="144x144" href="/favicon/apple-touch-icon-144x144.png">
+    <link rel="apple-touch-icon" sizes="152x152" href="/favicon/apple-touch-icon-152x152.png">
+    <link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-touch-icon-180x180.png">
+    <link rel="icon" type="image/png" href="/favicon/favicon-32x32.png" sizes="32x32">
+    <link rel="icon" type="image/png" href="/favicon/android-chrome-192x192.png" sizes="192x192">
+    <link rel="icon" type="image/png" href="/favicon/favicon-96x96.png" sizes="96x96">
+    <link rel="icon" type="image/png" href="/favicon/favicon-16x16.png" sizes="16x16">
+    <link rel="manifest" href="/favicon/manifest.json">
+    <link rel="mask-icon" href="/favicon/safari-pinned-tab.svg" color="#ffb300">
+    <link rel="shortcut icon" href="/favicon/favicon.ico">
+    <meta name="msapplication-TileColor" content="#ffb300">
+    <meta name="msapplication-TileImage" content="/favicon/mstile-144x144.png">
+    <meta name="msapplication-config" content="/favicon/browserconfig.xml">
+    <meta name="theme-color" content="#ffb300">
+    <!-- http://realfavicongenerator.net/favicon_result?file_id=p1akurqbdbq0j1lpc14a618p2och6#.V1uVj_krK70 -->
+  </head>
+  <body>
+    <header>&#xA0;</header>
+    <section>
+      <article>
+        <!--
+title: Javascript CNC Machine Emulator
+-->
+<h1 id="javascript-cnc-machine-emulator" class="deep-link"><a href="#javascript-cnc-machine-emulator">Javascript CNC Machine Emulator</a></h1>
+<p>The University of Cincinnati&apos;s Robotics Team had a DYNA MYTE 2400 CNC machine sitting in its lab for several years. After sitting unused for many years, someone found the manual and I quickly made it my project to learn how to use it. During my time in California, I developed an urge to send a unique kind of postcard to my friends at the Robotics Team at UC - a CNC-it-yourself postcard. Having written a report on CNC machines comparing G-code with the native language of the DYNA MYTE 2400 the previous quarter, I knew the basic commands by heart (and could reference the manual for the rest). After coming up with my design for the postcard and writing out the code I thought would produce it, I decided I needed some way to test it before I sent it to the team. So I spent a couple of nights learning how to use the HTML5 <code>&lt;canvas&gt;</code> element and made a quick 2D emulator to parse my DYNA MYTE code and render it.</p>
+<div class="youtube-video"><iframe width="560" height="315" src="https://www.youtube.com/embed/ZL0pXrBJSBo" frameborder="0" allowfullscreen></iframe></div>
+<p><em>Video demonstrating my Javascript emulator of the lab&apos;s CNC machine</em></p>
+<p>I sent them the code, and a link to this YouTube video to encourage them to machine the postcard. However, no one understood the machine as well as I did, and they weren&apos;t able to get the code entered while I was in California. It wasn&apos;t until I returned and entered the code myself that the postcard became a physical reality.</p>
+<p>You can try the emulator yourself here: <a href="CNC_Simulator.html">CNC_Simulator.html</a> It is just an HTML page with the Javascript source code embedded and no external references. Here are some sample CNC programs you can try:</p>
+<ul>
+<li><a href="CNC_Spiral.txt">CNC_Spiral.txt</a> - A simple example</li>
+<li><a href="CNC_D-SUB_PROGRAM.txt">CNC_D-SUB_PROGRAM.txt</a> - A program for cutting D-SUB sockets in sheet metal, which was the first use of the machine for the robotics team.</li>
+<li><a href="CNC_California.txt">CNC_California.txt</a> - The program seen in the video above.</li>
+<li><a href="CNC_California_Subs.txt">CNC_California_Subs.txt</a> - The same program, but using subroutines.</li>
+<li><a href="CNC_UC_Logo.txt">CNC_UC_Logo.txt</a> - A program for cutting the UC logo into sheet metal. (Note that UC&apos;s Logo is subject to regulations and shouldn&apos;t be used without permission.)</li>
+</ul>
+<p><em>Note</em>: You will have to change the Pixels per Inch setting based on your monitor to scale the image if it doesn&apos;t fit.</p>
+
+      </article>
+    </section>
+    <footer>&#xA0;</footer>
+  </body>
+</html>

BIN
projects/k-nex-adding-machine/KnexViews.png


+ 56 - 0
projects/k-nex-adding-machine/index.html

@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>K&apos;nex Adding Machine</title>
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <link rel="stylesheet" href="//yegor256.github.io/tacit/tacit.min.css">
+    <!-- favicon -->
+    <link rel="apple-touch-icon" sizes="57x57" href="/favicon/apple-touch-icon-57x57.png">
+    <link rel="apple-touch-icon" sizes="60x60" href="/favicon/apple-touch-icon-60x60.png">
+    <link rel="apple-touch-icon" sizes="72x72" href="/favicon/apple-touch-icon-72x72.png">
+    <link rel="apple-touch-icon" sizes="76x76" href="/favicon/apple-touch-icon-76x76.png">
+    <link rel="apple-touch-icon" sizes="114x114" href="/favicon/apple-touch-icon-114x114.png">
+    <link rel="apple-touch-icon" sizes="120x120" href="/favicon/apple-touch-icon-120x120.png">
+    <link rel="apple-touch-icon" sizes="144x144" href="/favicon/apple-touch-icon-144x144.png">
+    <link rel="apple-touch-icon" sizes="152x152" href="/favicon/apple-touch-icon-152x152.png">
+    <link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-touch-icon-180x180.png">
+    <link rel="icon" type="image/png" href="/favicon/favicon-32x32.png" sizes="32x32">
+    <link rel="icon" type="image/png" href="/favicon/android-chrome-192x192.png" sizes="192x192">
+    <link rel="icon" type="image/png" href="/favicon/favicon-96x96.png" sizes="96x96">
+    <link rel="icon" type="image/png" href="/favicon/favicon-16x16.png" sizes="16x16">
+    <link rel="manifest" href="/favicon/manifest.json">
+    <link rel="mask-icon" href="/favicon/safari-pinned-tab.svg" color="#ffb300">
+    <link rel="shortcut icon" href="/favicon/favicon.ico">
+    <meta name="msapplication-TileColor" content="#ffb300">
+    <meta name="msapplication-TileImage" content="/favicon/mstile-144x144.png">
+    <meta name="msapplication-config" content="/favicon/browserconfig.xml">
+    <meta name="theme-color" content="#ffb300">
+    <!-- http://realfavicongenerator.net/favicon_result?file_id=p1akurqbdbq0j1lpc14a618p2och6#.V1uVj_krK70 -->
+  </head>
+  <body>
+    <header>&#xA0;</header>
+    <section>
+      <article>
+        <!--
+title: K'nex Adding Machine
+-->
+<h1 id="knex-adding-machine" class="deep-link"><a href="#knex-adding-machine">K&apos;nex Adding Machine</a></h1>
+<p>This is a project I did my freshmen year of high school. 100% for fun, I built a binary half-adder using mechanical logic gates constructed out of K&apos;nex. If you know what that means, good for you! If not, you can watch this lovely video. (Keep in mind this is from 2004.) The logic gate designs for the NOT and AND gates are my own. (The design for the OR gate is, as they say in patent lingo, &quot;obvious to a person having ordinary skill in that field&quot;.)</p>
+<p>Some statistics about the video:</p>
+<ul>
+<li>It has generated over <em>70,000 views</em> and had a steady viewership!
+<img src="./KnexViews.png" alt="graph of YouTube views since 2007"></li>
+<li>It was on the <em>front page</em> of Google search results for &quot;mechanical logic gates&quot; for some years.</li>
+<li>For many years, it was the top YouTube search result for &quot;mechanical logic gates&quot;. <em>Update 2013/07: It&apos;s dropped to #3. There are a whole bunch of new videos related to the field too!</em></li>
+</ul>
+<div class="youtube-video"><iframe width="560" height="315" src="https://www.youtube.com/embed/3vXlQZvS-nM" frameborder="0" allowfullscreen></iframe></div>
+<p><em>Video of my mechanical adding machine constructed in 2004</em></p>
+<p>At the time this was uploaded, there was very little material on the Internet on mechanical logic gates. There were a few Lego designs using rotating shafts, but that was it. <strong>This work is completely unique;</strong> <s>as far as I know, no one has built anything using these logic gate designs before or since.</s> <em>Update: My work was cited in a <a href="https://mechalogic.wordpress.com/about/">project proposal</a> by some Carnegie Mellon University students.</em> I think I made a significant dent in the field of mechanical logic gates.</p>
+<p>The top hit for &quot;mechanical logic gates&quot; (http://goldfish.ikaruga.co.uk/logic.html) includes a link to my video. I suggested the owner add that link, because there was so little information on mechanical logic gates at the time. Since then, more people have constructed binary adders using mechanical logic. However, my machine is still special because it is reversible - most designs I have seen since require marbles falling or some other process that must be manually reset.</p>
+
+      </article>
+    </section>
+    <footer>&#xA0;</footer>
+  </body>
+</html>

BIN
projects/skype-telepresence-rover/IMG_20110109_184027.jpg


+ 64 - 0
projects/skype-telepresence-rover/index.html

@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>Skype Telepresence Rover</title>
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <link rel="stylesheet" href="//yegor256.github.io/tacit/tacit.min.css">
+    <!-- favicon -->
+    <link rel="apple-touch-icon" sizes="57x57" href="/favicon/apple-touch-icon-57x57.png">
+    <link rel="apple-touch-icon" sizes="60x60" href="/favicon/apple-touch-icon-60x60.png">
+    <link rel="apple-touch-icon" sizes="72x72" href="/favicon/apple-touch-icon-72x72.png">
+    <link rel="apple-touch-icon" sizes="76x76" href="/favicon/apple-touch-icon-76x76.png">
+    <link rel="apple-touch-icon" sizes="114x114" href="/favicon/apple-touch-icon-114x114.png">
+    <link rel="apple-touch-icon" sizes="120x120" href="/favicon/apple-touch-icon-120x120.png">
+    <link rel="apple-touch-icon" sizes="144x144" href="/favicon/apple-touch-icon-144x144.png">
+    <link rel="apple-touch-icon" sizes="152x152" href="/favicon/apple-touch-icon-152x152.png">
+    <link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-touch-icon-180x180.png">
+    <link rel="icon" type="image/png" href="/favicon/favicon-32x32.png" sizes="32x32">
+    <link rel="icon" type="image/png" href="/favicon/android-chrome-192x192.png" sizes="192x192">
+    <link rel="icon" type="image/png" href="/favicon/favicon-96x96.png" sizes="96x96">
+    <link rel="icon" type="image/png" href="/favicon/favicon-16x16.png" sizes="16x16">
+    <link rel="manifest" href="/favicon/manifest.json">
+    <link rel="mask-icon" href="/favicon/safari-pinned-tab.svg" color="#ffb300">
+    <link rel="shortcut icon" href="/favicon/favicon.ico">
+    <meta name="msapplication-TileColor" content="#ffb300">
+    <meta name="msapplication-TileImage" content="/favicon/mstile-144x144.png">
+    <meta name="msapplication-config" content="/favicon/browserconfig.xml">
+    <meta name="theme-color" content="#ffb300">
+    <!-- http://realfavicongenerator.net/favicon_result?file_id=p1akurqbdbq0j1lpc14a618p2och6#.V1uVj_krK70 -->
+  </head>
+  <body>
+    <header>&#xA0;</header>
+    <section>
+      <article>
+        <!--
+title: Skype Telepresence Rover
+-->
+<h1 id="skype-telepresence-rover" class="deep-link"><a href="#skype-telepresence-rover">Skype Telepresence Rover</a></h1>
+<p><img src="IMG_20110109_184027.jpg" alt="The current prototype">
+<br><em>The current prototype.</em></p>
+<p>While on co-op in California, I often used Skype to video call my family. I even attended my brother&apos;s high school graduation virtually via Skype; from a laptop, I chatted with all my old friends from high school and joined in group conversations. People carried me around so I could say hi to everyone at the party. It was a great experience, but I depended on others for mobility. At one point, I was set down facing a wall for 10 minutes until someone noticed and turned me around.</p>
+<p>This got me thinking, what would it take to have a real telepresence? A full-blown telepresence robot like an <a href="http://anybots.com/">Anybot</a> or a <a href="http://www.willowgarage.com/pages/texai/overview">Texai</a> was out of the question; I&apos;m a college student on a shoe-string budget. But with the shrinking cost of electronics, I was convinced I could make a telepresence robot on a shoestring budget. All I had to do was integrate some existing technology: Skype, a netbook, and an RC car. I estimated I could make a telepresence robot for less than $300!</p>
+<p>Part List:</p>
+<ul>
+<li>A netbook with 2GB RAM, acquired from Craigslist for $150</li>
+<li>A $60 RC car from Meijer</li>
+<li>An $30 Arduino microcontroller to connect the laptop to the RC car</li>
+<li>Some wood and screws to mount the laptop and Arduino to the RC car</li>
+<li>Python code (using the Skype API) to send and receive steering and speed commands</li>
+</ul>
+<div class="youtube-video"><iframe width="560" height="315" src="https://www.youtube.com/embed/QsiM0Cjdzhk" frameborder="0" allowfullscreen></iframe></div>
+<p><em>This is from an earlier prototype that was built on a chassis that did not have a built-in motor controller.</em></p>
+<div class="youtube-video"><iframe width="560" height="315" src="https://www.youtube.com/embed/UroWCdb6SUo" frameborder="0" allowfullscreen></iframe></div>
+<p><em>For my second prototype, I used a complete electric car chassis, and reverse engineered the built-in motor controller. This video demonstrates applying a 3-5V input causing the wheels to spin, drawing power from the built-in battery, not the voltage source.</em></p>
+<p>I had hoped to make a video of the robot in action, but have been too distracted to add the joystick control needed to steer the robot properly. In the meanwhile, above are a couple of videos I took during the development of the Skype Rover.</p>
+<p>The idea is really simple. The rover has it&apos;s own Skype Account. When you call it, it automatically accepts the call and puts your video in full-screen mode so others can see you well. On the controlling end, a Python code lets you send steering and speed commands using the mouse or a joystick, and on the rover end is Python code that receives the commands and sends them through a USB cable to the Arduino, which controls voltages wired into the RC car&apos;s motor controller. It is a masterpiece of integration, really. The technologies for telepresence were just there, waiting to be connected with a little bit of solder and Python by some clever individual. If it works, thousands of DIY hobbiests could build one of these things in a weekend.</p>
+<p>The project is about 90% complete. Upon my return to UC, I decided I wanted to be able to give tours of the UC Engineering building via the Skype Rover. However, initial tests revealed the engineering building has too many Wi-Fi deadzones to be able to drive the robot down a hallway without disconnecting. I also discovered that the open-loop control combined with latency issues made the rover extremely difficult to drive. Disheartened, I have temporarily shelved the Skype Telepresence Rover in favor of pursuing other projects such as learning ROS, the Robot Operating System from Willow Garage.</p>
+<p>After finishing most of the code, I searched for similar projects on the Internet and found <a href="http://sparkyjr.ning.com/">Sparky Jr</a>. Sparky Jr. has a similar goal; however, my rover was less expensive because of the decision to use an RC car chassis and a netbook rather than a Roomba chassis and a Mac mini.</p>
+
+      </article>
+    </section>
+    <footer>&#xA0;</footer>
+  </body>
+</html>

BIN
projects/ultimate-wotd/UltimateWOTDReview1.png


BIN
projects/ultimate-wotd/UltimateWOTDReview2.png


BIN
projects/ultimate-wotd/UltimateWOTDReview3.png


BIN
projects/ultimate-wotd/UltimateWOTDReview4.png


BIN
projects/ultimate-wotd/UltimateWOTDWidget.png


+ 54 - 0
projects/ultimate-wotd/index.html

@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>Ultimate Word-of-the-Day</title>
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <link rel="stylesheet" href="//yegor256.github.io/tacit/tacit.min.css">
+    <!-- favicon -->
+    <link rel="apple-touch-icon" sizes="57x57" href="/favicon/apple-touch-icon-57x57.png">
+    <link rel="apple-touch-icon" sizes="60x60" href="/favicon/apple-touch-icon-60x60.png">
+    <link rel="apple-touch-icon" sizes="72x72" href="/favicon/apple-touch-icon-72x72.png">
+    <link rel="apple-touch-icon" sizes="76x76" href="/favicon/apple-touch-icon-76x76.png">
+    <link rel="apple-touch-icon" sizes="114x114" href="/favicon/apple-touch-icon-114x114.png">
+    <link rel="apple-touch-icon" sizes="120x120" href="/favicon/apple-touch-icon-120x120.png">
+    <link rel="apple-touch-icon" sizes="144x144" href="/favicon/apple-touch-icon-144x144.png">
+    <link rel="apple-touch-icon" sizes="152x152" href="/favicon/apple-touch-icon-152x152.png">
+    <link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-touch-icon-180x180.png">
+    <link rel="icon" type="image/png" href="/favicon/favicon-32x32.png" sizes="32x32">
+    <link rel="icon" type="image/png" href="/favicon/android-chrome-192x192.png" sizes="192x192">
+    <link rel="icon" type="image/png" href="/favicon/favicon-96x96.png" sizes="96x96">
+    <link rel="icon" type="image/png" href="/favicon/favicon-16x16.png" sizes="16x16">
+    <link rel="manifest" href="/favicon/manifest.json">
+    <link rel="mask-icon" href="/favicon/safari-pinned-tab.svg" color="#ffb300">
+    <link rel="shortcut icon" href="/favicon/favicon.ico">
+    <meta name="msapplication-TileColor" content="#ffb300">
+    <meta name="msapplication-TileImage" content="/favicon/mstile-144x144.png">
+    <meta name="msapplication-config" content="/favicon/browserconfig.xml">
+    <meta name="theme-color" content="#ffb300">
+    <!-- http://realfavicongenerator.net/favicon_result?file_id=p1akurqbdbq0j1lpc14a618p2och6#.V1uVj_krK70 -->
+  </head>
+  <body>
+    <header>&#xA0;</header>
+    <section>
+      <article>
+        <!--
+title: Ultimate Word-of-the-Day
+-->
+<h1 id="ultimate-word-of-the-day" class="deep-link"><a href="#ultimate-word-of-the-day">Ultimate Word-of-the-Day</a></h1>
+<p>To help me prepare for the SAT, I wrote a &quot;Word of the Day&quot; desktop widget that consolidated the word-of-the-days from several different websites. (This was before I switched to Linux during my senior year of high school, and when I used Konfabulator (later Yahoo!) Widgets on Windows XP.)</p>
+<p>It was a phenomenal success! <strong>My widget received over 20,000 downloads.</strong> No piece of code I have written before or after has spawned so much love and devotion. I do not actively develop it anymore, but I have updated it on occasion when people tell me the dictionary sources are broken. In fact, some of the highest reviews I have gotten have been from people pleading with me to fix the sources because they love this software so much. <s>Last time I checked (2011-11-01), it was still available for download at <a href="http://widgets.yahoo.com/widgets/ultimate-wotd/">http://widgets.yahoo.com/widgets/ultimate-wotd/</a></s> Yahoo! discontinued the Yahoo! Widget platform in March 2012.</p>
+<p><img src="./UltimateWOTDWidget.png" alt="Ultimate WOTD by William Hilton. This Widget grabs the Word of the Day from multiple sources, and provides the pronunciations(s), definition(s), usage examples, etymology, and even audio pronunciations when available! It also provides a link back to the source&apos;s webpage. This is a great way to increase your vocabulary, especially if you are preparing for the SAT or PSAT!">
+<br><em>A screenshot of my widget in the Yahoo! Widget Gallery</em></p>
+<p>Here are some of the raving reviews people wrote, in reverse chronological order:</p>
+<p><img src="./UltimateWOTDReview1.png" alt="Simply phenomenal. Don&apos;t even bother with the other dictionary widgets; this is the only one you&apos;ll ever need. It is perfect in every way. Thank you William for fixing it!"></p>
+<p><img src="./UltimateWOTDReview3.png" alt="This is a really great widget. It&apos;s really unfortunate that it has been abandoned. Dictionary.com and Mirriam Webster are not working for me. I decided to use the whole yahoo widget software instead of the windows vista sidebar just for this particular widget. I am hoping that these will somehow get fixed especially the dictionary.com"></p>
+<p><img src="./UltimateWOTDReview4.png" alt="This sir, is an awesome widget. It&apos;s a logophile&apos;s wet dream and my favorite widget by far! I am so disappointed you won&apos;t be continuing it. Is there any chance you would reconsider? Please? PLEASE?!? ..."></p>
+<p><img src="./UltimateWOTDReview2.png" alt="Great widget! The variety of selection, and ease of use make it the ultimate utility for any widget collection. Thank you for providing this widget!"></p>
+<p>The success of this widget has led me to contemplate making a phone app version. However, I am not pursuing that at this time.</p>
+
+      </article>
+    </section>
+    <footer>&#xA0;</footer>
+  </body>
+</html>

+ 80 - 0
research-interests.html

@@ -0,0 +1,80 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>Research Interests</title>
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <link rel="stylesheet" href="//yegor256.github.io/tacit/tacit.min.css">
+    <!-- favicon -->
+    <link rel="apple-touch-icon" sizes="57x57" href="/favicon/apple-touch-icon-57x57.png">
+    <link rel="apple-touch-icon" sizes="60x60" href="/favicon/apple-touch-icon-60x60.png">
+    <link rel="apple-touch-icon" sizes="72x72" href="/favicon/apple-touch-icon-72x72.png">
+    <link rel="apple-touch-icon" sizes="76x76" href="/favicon/apple-touch-icon-76x76.png">
+    <link rel="apple-touch-icon" sizes="114x114" href="/favicon/apple-touch-icon-114x114.png">
+    <link rel="apple-touch-icon" sizes="120x120" href="/favicon/apple-touch-icon-120x120.png">
+    <link rel="apple-touch-icon" sizes="144x144" href="/favicon/apple-touch-icon-144x144.png">
+    <link rel="apple-touch-icon" sizes="152x152" href="/favicon/apple-touch-icon-152x152.png">
+    <link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-touch-icon-180x180.png">
+    <link rel="icon" type="image/png" href="/favicon/favicon-32x32.png" sizes="32x32">
+    <link rel="icon" type="image/png" href="/favicon/android-chrome-192x192.png" sizes="192x192">
+    <link rel="icon" type="image/png" href="/favicon/favicon-96x96.png" sizes="96x96">
+    <link rel="icon" type="image/png" href="/favicon/favicon-16x16.png" sizes="16x16">
+    <link rel="manifest" href="/favicon/manifest.json">
+    <link rel="mask-icon" href="/favicon/safari-pinned-tab.svg" color="#ffb300">
+    <link rel="shortcut icon" href="/favicon/favicon.ico">
+    <meta name="msapplication-TileColor" content="#ffb300">
+    <meta name="msapplication-TileImage" content="/favicon/mstile-144x144.png">
+    <meta name="msapplication-config" content="/favicon/browserconfig.xml">
+    <meta name="theme-color" content="#ffb300">
+    <!-- http://realfavicongenerator.net/favicon_result?file_id=p1akurqbdbq0j1lpc14a618p2och6#.V1uVj_krK70 -->
+  </head>
+  <body>
+    <header>&#xA0;</header>
+    <section>
+      <article>
+        <!--
+title: Research Interests
+-->
+<h1 id="research-interests" class="deep-link"><a href="#research-interests">Research Interests</a></h1>
+<h2 id="past-research" class="deep-link"><a href="#past-research">Past Research:</a></h2>
+<p>I was selected for an NSF-funded undergraduate research experience at the University of Cincinnati. I and two other students researched novel stereovision filtering, computer vision, and obstacle avoidance algorithms on UC&apos;s intelligent ground vehicles.</p>
+<p>As a graduate student at Drexel University, I participated in the DARPA Robotics Challenge and developed experience with the Hubo humanoid robot.</p>
+<h2 id="past-areas-of-interest" class="deep-link"><a href="#past-areas-of-interest">Past Areas of interest</a></h2>
+<h3 id="human-robot-interaction" class="deep-link"><a href="#human-robot-interaction">Human-robot interaction</a></h3>
+<p>How can we ensure our robot-filled future is full of perceptive, helpful, friendly robots, rather than dumb, pesky, frustrating ones?</p>
+<h4 id="why-im-no-longer-interested" class="deep-link"><a href="#why-im-no-longer-interested">Why I&apos;m no longer interested</a></h4>
+<p>As of 2012-2014, the technology is just not mature/reliable enough to do meaningful experiments with humanoid robots.
+The robots I had to work with were too dumb, pesky, frustrating for even <em>me</em> to put up with. And that&apos;s saying something.</p>
+<h3 id="perception" class="deep-link"><a href="#perception">Perception</a></h3>
+<p>How to make sense of the wealth of sensor data available to robots</p>
+<h4 id="why-im-no-longer-interested-1" class="deep-link"><a href="#why-im-no-longer-interested-1">Why I&apos;m no longer interested</a></h4>
+<p>Actually, it would still probably be a pretty interesting field. But frankly, it looks like
+machine vision, 3D reconstruction from video, augmented reality physics, etc all seem
+to be coming along just fine.</p>
+<h3 id="machine-learning" class="deep-link"><a href="#machine-learning">Machine learning</a></h3>
+<p>How to organize and apply knowledge</p>
+<h4 id="why-im-no-longer-interested-2" class="deep-link"><a href="#why-im-no-longer-interested-2">Why I&apos;m no longer interested</a></h4>
+<p>I&apos;m a machine learning hipster. I was into it before it was a buzzword.
+After studying it for three years at university, I was kind of disappointed in a &quot;this is it?&quot; way.
+Then deep neural nets took off, and the tools became so plug-and-play that everyone
+and their dog can build an &quot;app&quot; that uses machine learning. While neural nets do indeed organize
+knowledge, to date the ML field has been obsessed with results/performance,
+without concerning itself with <em>understanding</em> how these nets are organizing that knowledge.
+It is a very shallow victory.</p>
+<h3 id="machine-ethics" class="deep-link"><a href="#machine-ethics">Machine ethics</a></h3>
+<p>What do we tell cognitive agents about how to behave? Can we define or enforce ethical robot / AI behavior?</p>
+<h4 id="why-im-no-longer-interested-3" class="deep-link"><a href="#why-im-no-longer-interested-3">Why I&apos;m no longer interested</a></h4>
+<p>I don&apos;t believe it matters, because they can&apos;t be any worse than humans.</p>
+<h2 id="continued-areas-of-interest" class="deep-link"><a href="#continued-areas-of-interest">Continued areas of interest</a></h2>
+<h3 id="cheap-hardware-revolution" class="deep-link"><a href="#cheap-hardware-revolution">Cheap hardware revolution</a></h3>
+<p>How can we best take advantage of game-changing cheap hardware, like the Kinect and Android phones?</p>
+<h3 id="ubiquitous-computing" class="deep-link"><a href="#ubiquitous-computing">Ubiquitous Computing</a></h3>
+<p>As the number of embedded computers increases, how can we keep the interface complexity from also increasing?</p>
+<h3 id="disposable-computing" class="deep-link"><a href="#disposable-computing">Disposable Computing</a></h3>
+<p>How cheap can computing get? Raspberry Pi Zero, unlimited free cloud deployments... could we start replacing our smartphones every week? Every day?</p>
+
+      </article>
+    </section>
+    <footer>&#xA0;</footer>
+  </body>
+</html>

+ 90 - 0
work-history.html

@@ -0,0 +1,90 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>Work History</title>
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <link rel="stylesheet" href="//yegor256.github.io/tacit/tacit.min.css">
+    <!-- favicon -->
+    <link rel="apple-touch-icon" sizes="57x57" href="/favicon/apple-touch-icon-57x57.png">
+    <link rel="apple-touch-icon" sizes="60x60" href="/favicon/apple-touch-icon-60x60.png">
+    <link rel="apple-touch-icon" sizes="72x72" href="/favicon/apple-touch-icon-72x72.png">
+    <link rel="apple-touch-icon" sizes="76x76" href="/favicon/apple-touch-icon-76x76.png">
+    <link rel="apple-touch-icon" sizes="114x114" href="/favicon/apple-touch-icon-114x114.png">
+    <link rel="apple-touch-icon" sizes="120x120" href="/favicon/apple-touch-icon-120x120.png">
+    <link rel="apple-touch-icon" sizes="144x144" href="/favicon/apple-touch-icon-144x144.png">
+    <link rel="apple-touch-icon" sizes="152x152" href="/favicon/apple-touch-icon-152x152.png">
+    <link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-touch-icon-180x180.png">
+    <link rel="icon" type="image/png" href="/favicon/favicon-32x32.png" sizes="32x32">
+    <link rel="icon" type="image/png" href="/favicon/android-chrome-192x192.png" sizes="192x192">
+    <link rel="icon" type="image/png" href="/favicon/favicon-96x96.png" sizes="96x96">
+    <link rel="icon" type="image/png" href="/favicon/favicon-16x16.png" sizes="16x16">
+    <link rel="manifest" href="/favicon/manifest.json">
+    <link rel="mask-icon" href="/favicon/safari-pinned-tab.svg" color="#ffb300">
+    <link rel="shortcut icon" href="/favicon/favicon.ico">
+    <meta name="msapplication-TileColor" content="#ffb300">
+    <meta name="msapplication-TileImage" content="/favicon/mstile-144x144.png">
+    <meta name="msapplication-config" content="/favicon/browserconfig.xml">
+    <meta name="theme-color" content="#ffb300">
+    <!-- http://realfavicongenerator.net/favicon_result?file_id=p1akurqbdbq0j1lpc14a618p2och6#.V1uVj_krK70 -->
+  </head>
+  <body>
+    <header>&#xA0;</header>
+    <section>
+      <article>
+        <!--
+title: Work History
+-->
+<p>TODO: Use a <a href="http://quasar-framework.org/components/timeline.html">Quasar Timeline</a> widget?</p>
+<h1 id="ata-engineering-inc" class="deep-link"><a href="#ata-engineering-inc">ATA Engineering, Inc.</a></h1>
+<p>San Diego, CA.<br>
+Mar 29 - Sept 17, 2010 and Mar 30 - Sept 18, 2009</p>
+<p>How I benefited ATA:</p>
+<ul>
+<li>Built finite element models, ran analyses, and post-processed results.
+<ul>
+<li><strong>Created clear presentations</strong> for customers explaining the results.</li>
+</ul>
+</li>
+<li>Communicated closely with the sales team to determine and meet their needs.
+<ul>
+<li>Created an application to track software sales</li>
+</ul>
+</li>
+<li>During down time, wrote new web-based tools to run on ATA&#x2019;s intranet:
+<ul>
+<li>An analysis server webpage that <strong>saved engineers time</strong>.</li>
+<li>A WYSIWYG floor plan editor that made maintaining online floor plans <strong>easy for HR</strong>.</li>
+</ul>
+</li>
+<li>Upgraded, customized and <strong>enhanced</strong> ATA&apos;s software issue-reporting website and timesheet application.</li>
+</ul>
+<h1 id="uc-simulation-center-with-procter--gamble" class="deep-link"><a href="#uc-simulation-center-with-procter--gamble">UC Simulation Center with Procter &amp; Gamble.</a></h1>
+<p>Cincinnati, OH.<br>
+Mar 29 - Sept 17, 2011</p>
+<p>How I benefited P&amp;G:</p>
+<ul>
+<li>Ported 15,000 lines of undocumented C++ code from 32-bit Windows to 64-bit Linux.
+<ul>
+<li>This <strong>reduced simulation time</strong> and <strong>simplified the simulation process</strong> by allowing the entire process run on their Linux cluster.</li>
+<li><strong>Documented the code</strong>, uncovering the equations and assumptions used by the model that was previously a black box.</li>
+</ul>
+</li>
+<li>Wrote a proof-of-concept tool to import geometry from a proprietary design program into the simulation.
+<ul>
+<li>Laid the foundation for tighter collaboration between P&amp;G designers and simulators.</li>
+</ul>
+</li>
+</ul>
+<h1 id="drexel-university" class="deep-link"><a href="#drexel-university">Drexel University</a></h1>
+<p>TODO</p>
+<h1 id="mobile-ad-monitor" class="deep-link"><a href="#mobile-ad-monitor">Mobile Ad Monitor</a></h1>
+<p>TODO</p>
+<h1 id="swordfish-web-solutions" class="deep-link"><a href="#swordfish-web-solutions">Swordfish Web Solutions</a></h1>
+<p>TODO</p>
+
+      </article>
+    </section>
+    <footer>&#xA0;</footer>
+  </body>
+</html>