Update project structure and README.md
Change-Id: Ia0d3f878163c9a1d850d750b0def972aae11970e
diff --git a/.gitignore b/.gitignore
index b61d9cf..f1bfc1a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,6 @@
.distdir
*.zip
site/interpreter.*
-site/*.tflite
+site/models/*.tflite
dfu-util
diff --git a/.gitmodules b/.gitmodules
index 452b66b..733e7e7 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,6 +1,6 @@
[submodule "webdfu"]
- path = webdfu
+ path = third_party/webdfu
url = https://github.com/devanlai/webdfu.git
[submodule "libedgetpu"]
- path = libedgetpu
+ path = third_party/libedgetpu
url = https://coral.googlesource.com/libedgetpu
diff --git a/Makefile b/Makefile
index 9729a88..6265c22 100644
--- a/Makefile
+++ b/Makefile
@@ -14,7 +14,7 @@
MAKEFILE_DIR := $(realpath $(dir $(lastword $(MAKEFILE_LIST))))
TEST_DATA_URL := https://github.com/google-coral/edgetpu/raw/master/test_data
-.PHONY: wasm download zip server dfu-util
+.PHONY: wasm download zip server reset clean
COMPILATION_MODE ?= dbg
ifeq ($(filter $(COMPILATION_MODE),opt dbg),)
@@ -50,21 +50,23 @@
"$(MAKEFILE_DIR)/site"
%.tflite:
- cd $(dir $@) && wget "$(TEST_DATA_URL)/$(notdir $@)"
+ mkdir -p $(dir $@) && cd $(dir $@) && wget "$(TEST_DATA_URL)/$(notdir $@)"
-download: site/mobilenet_v1_1.0_224_quant.tflite \
- site/mobilenet_v1_1.0_224_quant_edgetpu.tflite \
- site/ssd_mobilenet_v2_coco_quant_postprocess.tflite \
- site/ssd_mobilenet_v2_coco_quant_postprocess_edgetpu.tflite \
- site/ssd_mobilenet_v2_face_quant_postprocess.tflite \
- site/ssd_mobilenet_v2_face_quant_postprocess_edgetpu.tflite
+download: site/models/mobilenet_v1_1.0_224_quant.tflite \
+ site/models/mobilenet_v1_1.0_224_quant_edgetpu.tflite \
+ site/models/ssd_mobilenet_v2_coco_quant_postprocess.tflite \
+ site/models/ssd_mobilenet_v2_coco_quant_postprocess_edgetpu.tflite \
+ site/models/ssd_mobilenet_v2_face_quant_postprocess.tflite \
+ site/models/ssd_mobilenet_v2_face_quant_postprocess_edgetpu.tflite
-dfu-util:
- git clone git://git.code.sf.net/p/dfu-util/dfu-util || true
- cd $(MAKEFILE_DIR)/dfu-util && ./autogen.sh && ./configure && make
+third_party/dfu-util/src/dfu-util:
+ git -C third_party clone git://git.code.sf.net/p/dfu-util/dfu-util || true
+ cd third_party/dfu-util && ./autogen.sh && ./configure && make
-reset:
- $(MAKEFILE_DIR)/dfu-util/src/dfu-util -D $(MAKEFILE_DIR)/libedgetpu/driver/usb/apex_latest_single_ep.bin -d 1a6e:089a -R || true
+reset: third_party/dfu-util/src/dfu-util
+ third_party/dfu-util/src/dfu-util \
+ -D third_party/libedgetpu/driver/usb/apex_latest_single_ep.bin \
+ -d 1a6e:089a -R || true
zip:
zip -r site.zip site
@@ -74,7 +76,7 @@
clean:
rm -f $(MAKEFILE_DIR)/site/interpreter.* \
- $(MAKEFILE_DIR)/site/*.tflite
+ $(MAKEFILE_DIR)/site/models/*.tflite
################################################################################
# Docker commands
diff --git a/README.md b/README.md
index 558a81a..fd1c20f 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,83 @@
-# WebCoral
+# WebCoral
-Firmware upload is done via webdfu
+This is a project to demonstrate how to access
+[Coral USB Accelerator](https://coral.ai/products/accelerator/) from
+Chrome browser using [WebUSB](https://wicg.github.io/webusb/).
+The demo works on Linux and macOS.
-emscripten_toolchain for Bazel is taken from
-https://github.com/emscripten-core/emsdk/tree/master/bazel/emscripten_toolchain
+## Web Server Setup
-libusb.cc -- universal shim, inspired by
+Clone this repo with submodules:
+```
+git clone --recurse-submodules https://github.com/google-coral/webcoral
+```
+
+Switch directory:
+```
+cd webcoral
+```
+
+Download `.tflite` model files to `site/models`:
+```
+make download
+```
+
+Build WASM files inside Docker container:
+```
+DOCKER_SHELL_COMMAND="make wasm" make docker-shell
+```
+
+Run local web server using python:
+```
+make server
+```
+
+Server is listening on port `8000`.
+
+## System Setup
+
+On **Linux** you need to install device rules to make Coral USB device
+visible in Chrome. You probably already have them installed if you are using
+Coral products. Just in case this repo has a bash script right for that:
+```
+scripts/linux_device_rules.sh install
+```
+and corresponding uninstall command if needed:
+```
+scripts/linux_device_rules.sh uninstall
+```
+
+On **macOS** you don't need to install anything.
+
+## Device Setup
+
+Coral USB accelerator doesn't have preinstalled firmware. If you run `lsusb`
+command right after plugging USB device in, you'll see
+```
+Bus 001 Device 008: ID 1a6e:089a Global Unichip Corp.
+```
+
+This means firmware is not flashed yet. It is possible to flash firmware
+directly from Chrome or from command line. Either way after flashing you'll see:
+```
+Bus 001 Device 009: ID 18d1:9302 Google Inc.
+```
+which means that device is ready to use.
+
+To flash firmware from command line:
+```
+make reset
+```
+
+To flash from Chrome browser, point it to http://localhost:8000/ and press
+`Flash Device Firmware` button. WARNING: this only works on Linux now.
+There is an [issue](https://crbug.com/1189418) on macOS. It is already fixed and
+the fix will be available in Chrome 91.
+
+## Demo
+
+Make sure the USB device was properly flashed. Choose the model you like to run
+and press `Initialize Interpreter` button. TPU model will require to select USB
+device in the dialog. CPU model will be ready immediately. At this moment you
+can run inference on any local image file by pressing `Choose Image File`
+button.
diff --git a/WORKSPACE b/WORKSPACE
index 99d1a0e..a11ccd9 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -16,8 +16,8 @@
# Configure libedgetpu and downstream libraries (TF and Crosstool).
new_local_repository(
name = "libedgetpu",
- path = "libedgetpu",
- build_file = "libedgetpu/BUILD"
+ path = "third_party/libedgetpu",
+ build_file = "third_party/libedgetpu/BUILD"
)
TENSORFLOW_COMMIT = "ee728bcc18abef50b968c4b4cb06523f64abf7ac"
diff --git a/site/dfu.js b/site/dfu.js
index bfebfec..8d02b7f 120000
--- a/site/dfu.js
+++ b/site/dfu.js
@@ -1 +1 @@
-../webdfu/dfu-util/dfu.js
\ No newline at end of file
+../third_party/webdfu/dfu-util/dfu.js
\ No newline at end of file
diff --git a/site/dfuse.js b/site/dfuse.js
index 90f3af9..c710bcc 120000
--- a/site/dfuse.js
+++ b/site/dfuse.js
@@ -1 +1 @@
-../webdfu/dfu-util/dfuse.js
\ No newline at end of file
+../third_party/webdfu/dfu-util/dfuse.js
\ No newline at end of file
diff --git a/site/firmware.bin b/site/firmware.bin
index fe4459a..603c4a1 120000
--- a/site/firmware.bin
+++ b/site/firmware.bin
@@ -1 +1 @@
-../libedgetpu/driver/usb/apex_latest_single_ep.bin
\ No newline at end of file
+../third_party/libedgetpu/driver/usb/apex_latest_single_ep.bin
\ No newline at end of file
diff --git a/site/index.html b/site/index.html
index e8aa5a2..0e381b2 100644
--- a/site/index.html
+++ b/site/index.html
@@ -2,17 +2,17 @@
<html>
<head>
<meta charset="UTF-8">
- <title>Coral USB Accelerator Demo</title>
+ <title>Coral USB Accelerator + WebUSB</title>
<script src="dfu.js"></script>
<script src="dfuse.js"></script>
- <script src="labels.js"></script>
+ <script src="models.js"></script>
<script src="tflite.js"></script>
<script src="interpreter.js"></script>
</head>
<body>
<h1>Coral USB Accelerator Demo</h1>
<button id="button-firmware">1. Flash Device Firmware</button> <span id="firmware-status"></span><br/><br/>
- <button id="button-init">2. Initialize Device</button>
+ <button id="button-init">2. Initialize Interpreter</button>
<select id="model">
<option value="mobilenet_cpu">MobileNet V1 (CPU)</option>
<option value="mobilenet_tpu">MobileNet V1 (TPU)</option>
@@ -28,41 +28,7 @@
<br/><br/>
<!--button id="test">Inference Test</button><br/><br/-->
-
<script>
- const models = {
- 'mobilenet_cpu': {
- 'url': '/mobilenet_v1_1.0_224_quant.tflite',
- 'type': 'classification',
- 'labels': imagenet_labels,
- },
- 'mobilenet_tpu': {
- 'url': '/mobilenet_v1_1.0_224_quant_edgetpu.tflite',
- 'type': 'classification',
- 'labels': imagenet_labels,
- },
- 'ssd_mobilenet_coco_cpu': {
- 'url': '/ssd_mobilenet_v2_coco_quant_postprocess.tflite',
- 'type': 'detection',
- 'labels': coco_labels,
- },
- 'ssd_mobilenet_coco_tpu': {
- 'url': '/ssd_mobilenet_v2_coco_quant_postprocess_edgetpu.tflite',
- 'type': 'detection',
- 'labels': coco_labels,
- },
- 'ssd_mobilenet_face_cpu': {
- 'url': '/ssd_mobilenet_v2_face_quant_postprocess.tflite',
- 'type': 'detection',
- 'labels': ['face'],
- },
- 'ssd_mobilenet_face_tpu': {
- 'url': '/ssd_mobilenet_v2_face_quant_postprocess_edgetpu.tflite',
- 'type': 'detection',
- 'labels': ['face'],
- },
- };
-
async function loadLocalImage(file) {
return new Promise(resolve => {
var reader = new FileReader();
@@ -189,7 +155,7 @@
let model;
document.querySelector("#button-init").addEventListener('click', async () => {
- model = models[document.getElementById('model').value];
+ model = TFLITE_MODELS[document.getElementById('model').value];
console.log(model);
interpreter = new tflite.Interpreter();
if (await interpreter.createFromBuffer(await loadFile(model.url))) {
diff --git a/site/labels.js b/site/models.js
similarity index 96%
rename from site/labels.js
rename to site/models.js
index b47648c..23ffb92 100644
--- a/site/labels.js
+++ b/site/models.js
@@ -14,7 +14,7 @@
* limitations under the License.
* =============================================================================
*/
-const imagenet_labels = [
+const IMAGENET_LABELS = [
"background",
"tench, Tinca tinca",
"goldfish, Carassius auratus",
@@ -1018,7 +1018,7 @@
"toilet tissue, toilet paper, bathroom tissue"
];
-const coco_labels = [
+const COCO_LABELS = [
'person',
'bicycle',
'car',
@@ -1110,3 +1110,42 @@
'hair drier',
'toothbrush',
];
+
+const TFLITE_MODELS = {
+ 'mobilenet_cpu': {
+ 'url': '/models/mobilenet_v1_1.0_224_quant.tflite',
+ 'type': 'classification',
+ 'device': 'cpu',
+ 'labels': IMAGENET_LABELS,
+ },
+ 'mobilenet_tpu': {
+ 'url': '/models/mobilenet_v1_1.0_224_quant_edgetpu.tflite',
+ 'type': 'classification',
+ 'device': 'tpu',
+ 'labels': IMAGENET_LABELS,
+ },
+ 'ssd_mobilenet_coco_cpu': {
+ 'url': '/models/ssd_mobilenet_v2_coco_quant_postprocess.tflite',
+ 'type': 'detection',
+ 'device': 'cpu',
+ 'labels': COCO_LABELS,
+ },
+ 'ssd_mobilenet_coco_tpu': {
+ 'url': '/models/ssd_mobilenet_v2_coco_quant_postprocess_edgetpu.tflite',
+ 'type': 'detection',
+ 'device': 'tpu',
+ 'labels': COCO_LABELS,
+ },
+ 'ssd_mobilenet_face_cpu': {
+ 'url': '/models/ssd_mobilenet_v2_face_quant_postprocess.tflite',
+ 'type': 'detection',
+ 'device': 'cpu',
+ 'labels': ['face'],
+ },
+ 'ssd_mobilenet_face_tpu': {
+ 'url': '/models/ssd_mobilenet_v2_face_quant_postprocess_edgetpu.tflite',
+ 'type': 'detection',
+ 'device': 'tpu',
+ 'labels': ['face'],
+ },
+};
diff --git a/libedgetpu b/third_party/libedgetpu
similarity index 100%
rename from libedgetpu
rename to third_party/libedgetpu
diff --git a/webdfu b/third_party/webdfu
similarity index 100%
rename from webdfu
rename to third_party/webdfu