From 4c19950e00529d2d8e49306a0d27d245318f3fc7 Mon Sep 17 00:00:00 2001 From: Robert Szczepanski Date: Tue, 28 Sep 2021 16:24:08 +0200 Subject: [PATCH 1/3] Save example binaries Signed-off-by: Robert Szczepanski --- scripts/test_arduino_library.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/test_arduino_library.sh b/scripts/test_arduino_library.sh index c6cccd62..33faab98 100755 --- a/scripts/test_arduino_library.sh +++ b/scripts/test_arduino_library.sh @@ -60,8 +60,12 @@ InstallLibraryDependencies () { InstallLibraryDependencies for f in ${ARDUINO_LIBRARIES_DIR}/${LIBRARY_NAME}/examples/*/*.ino; do - echo "compiling $(basename ${f} .ino)" + EXAMPLE_NAME=$(basename ${f} .ino) + EXAMPLE_BINARIES=examples/${EXAMPLE_NAME}/output + mkdir -p ${EXAMPLE_BINARIES} + echo "compiling ${EXAMPLE_NAME}" ${ARDUINO_CLI_TOOL} compile --build-cache-path ${TEMP_BUILD_DIR} --build-path ${TEMP_BUILD_DIR} --fqbn arduino:mbed:nano33ble $f + cp ${TEMP_BUILD_DIR}/${EXAMPLE_NAME}.ino.* ${EXAMPLE_BINARIES} done rm -rf ${ARDUINO_LIBRARIES_DIR} From d9dfa7e9f64a2afbdda9fcbbd49edc62a538815b Mon Sep 17 00:00:00 2001 From: Robert Szczepanski Date: Tue, 28 Sep 2021 16:24:53 +0200 Subject: [PATCH 2/3] Build patched examples in CI workflow Signed-off-by: Robert Szczepanski --- .github/workflows/ci.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1af8d436..d274c572 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,7 +34,16 @@ jobs: name: Arduino CLI Build steps: - uses: actions/checkout@v2 + - name: Test run: | ./scripts/install_arduino_cli.sh ./scripts/test_arduino_library.sh "${PWD}" + + - name: Apply serial patch on tflite-micro + run: | + sed --in-place '/#define DEBUG_SERIAL_OBJECT/s/(Serial)/(Serial1)/' src/tensorflow/lite/micro/system_setup.cpp + + - name: Build patched binaries + run: | + ./scripts/test_arduino_library.sh "${PWD}" From 87d650cfeb5bc8ad1fcd5f0e144a11fb5a8cbac4 Mon Sep 17 00:00:00 2001 From: Wojciech Meller Date: Tue, 28 Sep 2021 16:26:18 +0200 Subject: [PATCH 3/3] Add Renode tests to CI workflow Signed-off-by: Wojciech Meller --- .github/workflows/ci.yml | 6 + examples/hello_world/hello_world.robot | 32 + examples/magic_wand/magic_wand.robot | 39 ++ .../magic_wand/test_files/angle_rotated.data | 650 ++++++++++++++++++ .../magic_wand/test_files/circle_rotated.data | 650 ++++++++++++++++++ examples/micro_speech/micro_speech.robot | 27 + examples/micro_speech/test_files/README | 1 + .../test_files/audio_yes_1s.s16le.pcm | Bin 0 -> 32000 bytes .../person_detection/person_detection.robot | 60 ++ examples/person_detection/test_files/README | 9 + .../test_files/no_person_image_0.jpg | Bin 0 -> 3787 bytes .../test_files/no_person_image_1.jpg | Bin 0 -> 3910 bytes .../test_files/person_image_0.jpg | Bin 0 -> 3853 bytes .../test_files/person_image_1.jpg | Bin 0 -> 3836 bytes 14 files changed, 1474 insertions(+) create mode 100644 examples/hello_world/hello_world.robot create mode 100644 examples/magic_wand/magic_wand.robot create mode 100644 examples/magic_wand/test_files/angle_rotated.data create mode 100644 examples/magic_wand/test_files/circle_rotated.data create mode 100644 examples/micro_speech/micro_speech.robot create mode 100644 examples/micro_speech/test_files/README create mode 100644 examples/micro_speech/test_files/audio_yes_1s.s16le.pcm create mode 100644 examples/person_detection/person_detection.robot create mode 100644 examples/person_detection/test_files/README create mode 100644 examples/person_detection/test_files/no_person_image_0.jpg create mode 100644 examples/person_detection/test_files/no_person_image_1.jpg create mode 100644 examples/person_detection/test_files/person_image_0.jpg create mode 100644 examples/person_detection/test_files/person_image_1.jpg diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d274c572..79517350 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,3 +47,9 @@ jobs: - name: Build patched binaries run: | ./scripts/test_arduino_library.sh "${PWD}" + + - name: Test patched builds in Renode + uses: antmicro/renode-test-action@v1.0.0 + with: + renode-version: '1.12.0+20210914gitc77eea21' + tests-to-run: 'examples/**/*.robot' diff --git a/examples/hello_world/hello_world.robot b/examples/hello_world/hello_world.robot new file mode 100644 index 00000000..d6295ed9 --- /dev/null +++ b/examples/hello_world/hello_world.robot @@ -0,0 +1,32 @@ +*** Settings *** +Suite Setup Setup +Suite Teardown Teardown +Test Setup Reset Emulation +Test Teardown Test Teardown +Resource ${RENODEKEYWORDS} + +*** Variables *** +${UART} sysbus.uart0 + +*** Keywords *** +Create Machine + Execute Command mach create + Execute Command machine LoadPlatformDescription @platforms/boards/arduino_nano_33_ble.repl + + Execute Command sysbus LoadELF @${CURDIR}/output/hello_world.ino.elf + +*** Test Cases *** +Should Print Brightness Sequence + Create Machine + Create Terminal Tester ${UART} + + Execute Command machine EnableProfiler @${CURDIR}/hello_world.dump + Start Emulation + + Wait For Line On Uart 127 + Wait For Line On Uart 260 + Wait For Line On Uart 205 + Wait For Line On Uart 195 + Wait For Line On Uart 10 + Wait For Line On Uart 1 + Wait For Line On Uart 100 diff --git a/examples/magic_wand/magic_wand.robot b/examples/magic_wand/magic_wand.robot new file mode 100644 index 00000000..9abc02a9 --- /dev/null +++ b/examples/magic_wand/magic_wand.robot @@ -0,0 +1,39 @@ +*** Settings *** +Suite Setup Setup +Suite Teardown Teardown +Test Setup Reset Emulation +Test Teardown Test Teardown +Resource ${RENODEKEYWORDS} + +*** Variables *** +${UART} sysbus.uart0 + +*** Keywords *** +Create Machine + Execute Command mach create + Execute Command machine LoadPlatformDescription @platforms/boards/arduino_nano_33_ble.repl + + Execute Command sysbus LoadELF @${CURDIR}/output/magic_wand.ino.elf + +*** Test Cases *** +Should Detect RING Motion + Create Machine + Create Terminal Tester ${UART} + + Execute Command sysbus.twi0.lsm9ds1_imu FeedAccelerationSample @${CURDIR}/test_files/circle_rotated.data + + Execute Command machine EnableProfiler "${CURDIR}/magic_wand_ring.dump" + Start Emulation + Wait For Line On Uart Magic starts + Wait For Line On Uart RING: + +Should Detect SLOPE Motion + Create Machine + Create Terminal Tester ${UART} + + Execute Command sysbus.twi0.lsm9ds1_imu FeedAccelerationSample @${CURDIR}/test_files/angle_rotated.data + + Execute Command machine EnableProfiler "${CURDIR}/magic_wand_slope.dump" + Start Emulation + Wait For Line On Uart Magic starts + Wait For Line On Uart SLOPE: diff --git a/examples/magic_wand/test_files/angle_rotated.data b/examples/magic_wand/test_files/angle_rotated.data new file mode 100644 index 00000000..33012f26 --- /dev/null +++ b/examples/magic_wand/test_files/angle_rotated.data @@ -0,0 +1,650 @@ +# This file contains accelerometer test samples +# for TensorFlow magic wand demo encoding the SLOPE motion. +# +# Original data from: +# https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/micro/examples/magic_wand/slope_micro_features_data.cc +# +# Samples modified to be compatible with +# Arduino Nano 33 BLE board (rotated and inverted channels, each sample repeated 5 times) +# and Renode (samples expressed in floating point numbers in G units). +# + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.709 0.132 0.766 + 0.709 0.132 0.766 + 0.709 0.132 0.766 + 0.709 0.132 0.766 + 0.709 0.132 0.766 + 0.659 0.249 0.751 + 0.659 0.249 0.751 + 0.659 0.249 0.751 + 0.659 0.249 0.751 + 0.659 0.249 0.751 + 0.630 0.314 0.714 + 0.630 0.314 0.714 + 0.630 0.314 0.714 + 0.630 0.314 0.714 + 0.630 0.314 0.714 + 0.623 0.244 0.709 + 0.623 0.244 0.709 + 0.623 0.244 0.709 + 0.623 0.244 0.709 + 0.623 0.244 0.709 + 0.659 0.230 0.707 + 0.659 0.230 0.707 + 0.659 0.230 0.707 + 0.659 0.230 0.707 + 0.659 0.230 0.707 + 0.748 0.202 0.704 + 0.748 0.202 0.704 + 0.748 0.202 0.704 + 0.748 0.202 0.704 + 0.748 0.202 0.704 + 0.728 0.219 0.714 + 0.728 0.219 0.714 + 0.728 0.219 0.714 + 0.728 0.219 0.714 + 0.728 0.219 0.714 + 0.710 0.239 0.722 + 0.710 0.239 0.722 + 0.710 0.239 0.722 + 0.710 0.239 0.722 + 0.710 0.239 0.722 + 0.612 0.116 0.744 + 0.612 0.116 0.744 + 0.612 0.116 0.744 + 0.612 0.116 0.744 + 0.612 0.116 0.744 + 0.570 -0.049 0.753 + 0.570 -0.049 0.753 + 0.570 -0.049 0.753 + 0.570 -0.049 0.753 + 0.570 -0.049 0.753 + 0.527 -0.279 0.748 + 0.527 -0.279 0.748 + 0.527 -0.279 0.748 + 0.527 -0.279 0.748 + 0.527 -0.279 0.748 + 0.592 -0.664 0.668 + 0.592 -0.664 0.668 + 0.592 -0.664 0.668 + 0.592 -0.664 0.668 + 0.592 -0.664 0.668 + 0.609 -0.635 0.601 + 0.609 -0.635 0.601 + 0.609 -0.635 0.601 + 0.609 -0.635 0.601 + 0.609 -0.635 0.601 + 0.606 -0.559 0.509 + 0.606 -0.559 0.509 + 0.606 -0.559 0.509 + 0.606 -0.559 0.509 + 0.606 -0.559 0.509 + 0.536 -0.162 0.286 + 0.536 -0.162 0.286 + 0.536 -0.162 0.286 + 0.536 -0.162 0.286 + 0.536 -0.162 0.286 + 0.495 -0.144 0.255 + 0.495 -0.144 0.255 + 0.495 -0.144 0.255 + 0.495 -0.144 0.255 + 0.495 -0.144 0.255 + 0.495 -0.085 0.209 + 0.495 -0.085 0.209 + 0.495 -0.085 0.209 + 0.495 -0.085 0.209 + 0.495 -0.085 0.209 + 0.698 0.416 -0.006 + 0.698 0.416 -0.006 + 0.698 0.416 -0.006 + 0.698 0.416 -0.006 + 0.698 0.416 -0.006 + 1.117 0.304 0.033 + 1.117 0.304 0.033 + 1.117 0.304 0.033 + 1.117 0.304 0.033 + 1.117 0.304 0.033 + 1.480 0.405 0.082 + 1.480 0.405 0.082 + 1.480 0.405 0.082 + 1.480 0.405 0.082 + 1.480 0.405 0.082 + 1.908 1.008 0.198 + 1.908 1.008 0.198 + 1.908 1.008 0.198 + 1.908 1.008 0.198 + 1.908 1.008 0.198 + 1.743 0.990 0.229 + 1.743 0.990 0.229 + 1.743 0.990 0.229 + 1.743 0.990 0.229 + 1.743 0.990 0.229 + 1.453 0.934 0.234 + 1.453 0.934 0.234 + 1.453 0.934 0.234 + 1.453 0.934 0.234 + 1.453 0.934 0.234 + 0.896 0.838 0.126 + 0.896 0.838 0.126 + 0.896 0.838 0.126 + 0.896 0.838 0.126 + 0.896 0.838 0.126 + 0.911 0.792 0.078 + 0.911 0.792 0.078 + 0.911 0.792 0.078 + 0.911 0.792 0.078 + 0.911 0.792 0.078 + 0.918 0.741 0.027 + 0.918 0.741 0.027 + 0.918 0.741 0.027 + 0.918 0.741 0.027 + 0.918 0.741 0.027 + 0.960 0.734 -0.114 + 0.960 0.734 -0.114 + 0.960 0.734 -0.114 + 0.960 0.734 -0.114 + 0.960 0.734 -0.114 + 0.959 0.613 -0.135 + 0.959 0.613 -0.135 + 0.959 0.613 -0.135 + 0.959 0.613 -0.135 + 0.959 0.613 -0.135 + 1.015 0.426 -0.152 + 1.015 0.426 -0.152 + 1.015 0.426 -0.152 + 1.015 0.426 -0.152 + 1.015 0.426 -0.152 + 1.110 -0.116 -0.106 + 1.110 -0.116 -0.106 + 1.110 -0.116 -0.106 + 1.110 -0.116 -0.106 + 1.110 -0.116 -0.106 + 1.129 -0.314 -0.063 + 1.129 -0.314 -0.063 + 1.129 -0.314 -0.063 + 1.129 -0.314 -0.063 + 1.129 -0.314 -0.063 + 1.179 -0.486 0.012 + 1.179 -0.486 0.012 + 1.179 -0.486 0.012 + 1.179 -0.486 0.012 + 1.179 -0.486 0.012 + 1.510 -0.656 0.118 + 1.510 -0.656 0.118 + 1.510 -0.656 0.118 + 1.510 -0.656 0.118 + 1.510 -0.656 0.118 + 1.553 -0.558 0.116 + 1.553 -0.558 0.116 + 1.553 -0.558 0.116 + 1.553 -0.558 0.116 + 1.553 -0.558 0.116 + 1.367 -0.361 0.126 + 1.367 -0.361 0.126 + 1.367 -0.361 0.126 + 1.367 -0.361 0.126 + 1.367 -0.361 0.126 + 0.922 -0.076 0.222 + 0.922 -0.076 0.222 + 0.922 -0.076 0.222 + 0.922 -0.076 0.222 + 0.922 -0.076 0.222 + 0.971 -0.026 0.210 + 0.971 -0.026 0.210 + 0.971 -0.026 0.210 + 0.971 -0.026 0.210 + 0.971 -0.026 0.210 + 1.053 0.050 0.194 + 1.053 0.050 0.194 + 1.053 0.050 0.194 + 1.053 0.050 0.194 + 1.053 0.050 0.194 + 1.082 0.072 0.178 + 1.082 0.072 0.178 + 1.082 0.072 0.178 + 1.082 0.072 0.178 + 1.082 0.072 0.178 + 1.073 0.100 0.169 + 1.073 0.100 0.169 + 1.073 0.100 0.169 + 1.073 0.100 0.169 + 1.073 0.100 0.169 + 1.050 0.133 0.162 + 1.050 0.133 0.162 + 1.050 0.133 0.162 + 1.050 0.133 0.162 + 1.050 0.133 0.162 + 0.976 0.226 0.156 + 0.976 0.226 0.156 + 0.976 0.226 0.156 + 0.976 0.226 0.156 + 0.976 0.226 0.156 + 0.886 0.323 0.154 + 0.886 0.323 0.154 + 0.886 0.323 0.154 + 0.886 0.323 0.154 + 0.886 0.323 0.154 + 1.154 0.240 0.130 + 1.154 0.240 0.130 + 1.154 0.240 0.130 + 1.154 0.240 0.130 + 1.154 0.240 0.130 + 0.916 0.124 0.116 + 0.916 0.124 0.116 + 0.916 0.124 0.116 + 0.916 0.124 0.116 + 0.916 0.124 0.116 + 0.937 0.124 0.132 + 0.937 0.124 0.132 + 0.937 0.124 0.132 + 0.937 0.124 0.132 + 0.937 0.124 0.132 + 0.981 0.115 0.153 + 0.981 0.115 0.153 + 0.981 0.115 0.153 + 0.981 0.115 0.153 + 0.981 0.115 0.153 + 0.962 0.094 0.184 + 0.962 0.094 0.184 + 0.962 0.094 0.184 + 0.962 0.094 0.184 + 0.962 0.094 0.184 + 1.017 0.085 0.177 + 1.017 0.085 0.177 + 1.017 0.085 0.177 + 1.017 0.085 0.177 + 1.017 0.085 0.177 + 1.027 0.092 0.173 + 1.027 0.092 0.173 + 1.027 0.092 0.173 + 1.027 0.092 0.173 + 1.027 0.092 0.173 + 1.110 0.158 0.168 + 1.110 0.158 0.168 + 1.110 0.158 0.168 + 1.110 0.158 0.168 + 1.110 0.158 0.168 + 1.030 0.101 0.181 + 1.030 0.101 0.181 + 1.030 0.101 0.181 + 1.030 0.101 0.181 + 1.030 0.101 0.181 + 1.054 0.139 0.180 + 1.054 0.139 0.180 + 1.054 0.139 0.180 + 1.054 0.139 0.180 + 1.054 0.139 0.180 + 1.044 0.010 0.152 + 1.044 0.010 0.152 + 1.044 0.010 0.152 + 1.044 0.010 0.152 + 1.044 0.010 0.152 + 1.007 0.074 0.169 + 1.007 0.074 0.169 + 1.007 0.074 0.169 + 1.007 0.074 0.169 + 1.007 0.074 0.169 diff --git a/examples/magic_wand/test_files/circle_rotated.data b/examples/magic_wand/test_files/circle_rotated.data new file mode 100644 index 00000000..ba03bbc9 --- /dev/null +++ b/examples/magic_wand/test_files/circle_rotated.data @@ -0,0 +1,650 @@ +# This file contains accelerometer test samples +# for TensorFlow magic wand demo encoding the RING motion. +# +# Original data from: +# https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/micro/examples/magic_wand/ring_micro_features_data.cc +# +# Samples modified to be compatible with +# Arduino Nano 33 BLE board (rotated and inverted channels, each sample repeated 5 times) +# and Renode (samples expressed in floating point numbers in G units). +# + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.000 0.000 0.000 + 0.827 0.228 0.665 + 0.827 0.228 0.665 + 0.827 0.228 0.665 + 0.827 0.228 0.665 + 0.827 0.228 0.665 + 0.716 0.339 0.680 + 0.716 0.339 0.680 + 0.716 0.339 0.680 + 0.716 0.339 0.680 + 0.716 0.339 0.680 + 0.812 0.564 0.680 + 0.812 0.564 0.680 + 0.812 0.564 0.680 + 0.812 0.564 0.680 + 0.812 0.564 0.680 + 0.818 0.552 0.679 + 0.818 0.552 0.679 + 0.818 0.552 0.679 + 0.818 0.552 0.679 + 0.818 0.552 0.679 + 0.751 0.528 0.665 + 0.751 0.528 0.665 + 0.751 0.528 0.665 + 0.751 0.528 0.665 + 0.751 0.528 0.665 + 0.618 0.432 0.658 + 0.618 0.432 0.658 + 0.618 0.432 0.658 + 0.618 0.432 0.658 + 0.618 0.432 0.658 + 0.592 0.445 0.655 + 0.592 0.445 0.655 + 0.592 0.445 0.655 + 0.592 0.445 0.655 + 0.592 0.445 0.655 + 0.556 0.484 0.667 + 0.556 0.484 0.667 + 0.556 0.484 0.667 + 0.556 0.484 0.667 + 0.556 0.484 0.667 + 0.510 0.590 0.684 + 0.510 0.590 0.684 + 0.510 0.590 0.684 + 0.510 0.590 0.684 + 0.510 0.590 0.684 + 0.475 0.672 0.674 + 0.475 0.672 0.674 + 0.475 0.672 0.674 + 0.475 0.672 0.674 + 0.475 0.672 0.674 + 0.390 0.786 0.660 + 0.390 0.786 0.660 + 0.390 0.786 0.660 + 0.390 0.786 0.660 + 0.390 0.786 0.660 + 0.128 1.124 0.562 + 0.128 1.124 0.562 + 0.128 1.124 0.562 + 0.128 1.124 0.562 + 0.128 1.124 0.562 + 0.111 1.140 0.526 + 0.111 1.140 0.526 + 0.111 1.140 0.526 + 0.111 1.140 0.526 + 0.111 1.140 0.526 + 0.033 1.044 0.486 + 0.033 1.044 0.486 + 0.033 1.044 0.486 + 0.033 1.044 0.486 + 0.033 1.044 0.486 +-0.134 0.652 0.416 +-0.134 0.652 0.416 +-0.134 0.652 0.416 +-0.134 0.652 0.416 +-0.134 0.652 0.416 +-0.143 0.534 0.390 +-0.143 0.534 0.390 +-0.143 0.534 0.390 +-0.143 0.534 0.390 +-0.143 0.534 0.390 +-0.117 0.381 0.365 +-0.117 0.381 0.365 +-0.117 0.381 0.365 +-0.117 0.381 0.365 +-0.117 0.381 0.365 + 0.094 0.060 0.314 + 0.094 0.060 0.314 + 0.094 0.060 0.314 + 0.094 0.060 0.314 + 0.094 0.060 0.314 + 0.190 0.007 0.322 + 0.190 0.007 0.322 + 0.190 0.007 0.322 + 0.190 0.007 0.322 + 0.190 0.007 0.322 + 0.342 -0.095 0.338 + 0.342 -0.095 0.338 + 0.342 -0.095 0.338 + 0.342 -0.095 0.338 + 0.342 -0.095 0.338 + 0.842 -0.106 0.360 + 0.842 -0.106 0.360 + 0.842 -0.106 0.360 + 0.842 -0.106 0.360 + 0.842 -0.106 0.360 + 0.965 -0.041 0.351 + 0.965 -0.041 0.351 + 0.965 -0.041 0.351 + 0.965 -0.041 0.351 + 0.965 -0.041 0.351 + 0.960 0.012 0.352 + 0.960 0.012 0.352 + 0.960 0.012 0.352 + 0.960 0.012 0.352 + 0.960 0.012 0.352 + 1.124 0.042 0.366 + 1.124 0.042 0.366 + 1.124 0.042 0.366 + 1.124 0.042 0.366 + 1.124 0.042 0.366 + 1.178 0.056 0.322 + 1.178 0.056 0.322 + 1.178 0.056 0.322 + 1.178 0.056 0.322 + 1.178 0.056 0.322 + 1.338 0.015 0.312 + 1.338 0.015 0.312 + 1.338 0.015 0.312 + 1.338 0.015 0.312 + 1.338 0.015 0.312 + 1.532 0.010 0.254 + 1.532 0.010 0.254 + 1.532 0.010 0.254 + 1.532 0.010 0.254 + 1.532 0.010 0.254 + 1.590 0.005 0.241 + 1.590 0.005 0.241 + 1.590 0.005 0.241 + 1.590 0.005 0.241 + 1.590 0.005 0.241 + 1.565 0.060 0.227 + 1.565 0.060 0.227 + 1.565 0.060 0.227 + 1.565 0.060 0.227 + 1.565 0.060 0.227 + 1.560 0.282 0.204 + 1.560 0.282 0.204 + 1.560 0.282 0.204 + 1.560 0.282 0.204 + 1.560 0.282 0.204 + 1.524 0.262 0.180 + 1.524 0.262 0.180 + 1.524 0.262 0.180 + 1.524 0.262 0.180 + 1.524 0.262 0.180 + 1.522 0.385 0.138 + 1.522 0.385 0.138 + 1.522 0.385 0.138 + 1.522 0.385 0.138 + 1.522 0.385 0.138 + 1.626 0.596 0.084 + 1.626 0.596 0.084 + 1.626 0.596 0.084 + 1.626 0.596 0.084 + 1.626 0.596 0.084 + 1.604 0.639 0.055 + 1.604 0.639 0.055 + 1.604 0.639 0.055 + 1.604 0.639 0.055 + 1.604 0.639 0.055 + 1.511 0.771 0.019 + 1.511 0.771 0.019 + 1.511 0.771 0.019 + 1.511 0.771 0.019 + 1.511 0.771 0.019 + 1.132 0.932 -0.016 + 1.132 0.932 -0.016 + 1.132 0.932 -0.016 + 1.132 0.932 -0.016 + 1.132 0.932 -0.016 + 1.013 0.924 -0.015 + 1.013 0.924 -0.015 + 1.013 0.924 -0.015 + 1.013 0.924 -0.015 + 1.013 0.924 -0.015 + 0.812 0.849 -0.001 + 0.812 0.849 -0.001 + 0.812 0.849 -0.001 + 0.812 0.849 -0.001 + 0.812 0.849 -0.001 + 0.500 0.628 0.088 + 0.500 0.628 0.088 + 0.500 0.628 0.088 + 0.500 0.628 0.088 + 0.500 0.628 0.088 + 0.463 0.609 0.114 + 0.463 0.609 0.114 + 0.463 0.609 0.114 + 0.463 0.609 0.114 + 0.463 0.609 0.114 + 0.382 0.559 0.155 + 0.382 0.559 0.155 + 0.382 0.559 0.155 + 0.382 0.559 0.155 + 0.382 0.559 0.155 + 0.278 0.420 0.234 + 0.278 0.420 0.234 + 0.278 0.420 0.234 + 0.278 0.420 0.234 + 0.278 0.420 0.234 + 0.272 0.390 0.254 + 0.272 0.390 0.254 + 0.272 0.390 0.254 + 0.272 0.390 0.254 + 0.272 0.390 0.254 + 0.336 0.200 0.327 + 0.336 0.200 0.327 + 0.336 0.200 0.327 + 0.336 0.200 0.327 + 0.336 0.200 0.327 + 0.630 -0.556 0.558 + 0.630 -0.556 0.558 + 0.630 -0.556 0.558 + 0.630 -0.556 0.558 + 0.630 -0.556 0.558 + 0.740 -0.607 0.640 + 0.740 -0.607 0.640 + 0.740 -0.607 0.640 + 0.740 -0.607 0.640 + 0.740 -0.607 0.640 + 0.868 -0.430 0.706 + 0.868 -0.430 0.706 + 0.868 -0.430 0.706 + 0.868 -0.430 0.706 + 0.868 -0.430 0.706 + 1.042 0.042 0.778 + 1.042 0.042 0.778 + 1.042 0.042 0.778 + 1.042 0.042 0.778 + 1.042 0.042 0.778 + 0.973 0.084 0.763 + 0.973 0.084 0.763 + 0.973 0.084 0.763 + 0.973 0.084 0.763 + 0.973 0.084 0.763 + 0.931 0.185 0.735 + 0.931 0.185 0.735 + 0.931 0.185 0.735 + 0.931 0.185 0.735 + 0.931 0.185 0.735 + 0.766 0.252 0.682 + 0.766 0.252 0.682 + 0.766 0.252 0.682 + 0.766 0.252 0.682 + 0.766 0.252 0.682 + 0.757 0.230 0.673 + 0.757 0.230 0.673 + 0.757 0.230 0.673 + 0.757 0.230 0.673 + 0.757 0.230 0.673 + 0.757 0.218 0.671 + 0.757 0.218 0.671 + 0.757 0.218 0.671 + 0.757 0.218 0.671 + 0.757 0.218 0.671 + 0.714 0.222 0.656 + 0.714 0.222 0.656 + 0.714 0.222 0.656 + 0.714 0.222 0.656 + 0.714 0.222 0.656 + 0.746 0.238 0.659 + 0.746 0.238 0.659 + 0.746 0.238 0.659 + 0.746 0.238 0.659 + 0.746 0.238 0.659 + 0.731 0.276 0.640 + 0.731 0.276 0.640 + 0.731 0.276 0.640 + 0.731 0.276 0.640 + 0.731 0.276 0.640 + 0.754 0.214 0.634 + 0.754 0.214 0.634 + 0.754 0.214 0.634 + 0.754 0.214 0.634 + 0.754 0.214 0.634 + 0.735 0.207 0.637 + 0.735 0.207 0.637 + 0.735 0.207 0.637 + 0.735 0.207 0.637 + 0.735 0.207 0.637 + 0.742 0.194 0.637 + 0.742 0.194 0.637 + 0.742 0.194 0.637 + 0.742 0.194 0.637 + 0.742 0.194 0.637 + 0.716 0.248 0.634 + 0.716 0.248 0.634 + 0.716 0.248 0.634 + 0.716 0.248 0.634 + 0.716 0.248 0.634 + 0.697 0.265 0.631 + 0.697 0.265 0.631 + 0.697 0.265 0.631 + 0.697 0.265 0.631 + 0.697 0.265 0.631 + 0.797 0.252 0.628 + 0.797 0.252 0.628 + 0.797 0.252 0.628 + 0.797 0.252 0.628 + 0.797 0.252 0.628 + 0.816 0.204 0.592 + 0.816 0.204 0.592 + 0.816 0.204 0.592 + 0.816 0.204 0.592 + 0.816 0.204 0.592 + 0.812 0.218 0.618 + 0.812 0.218 0.618 + 0.812 0.218 0.618 + 0.812 0.218 0.618 + 0.812 0.218 0.618 + 0.828 0.231 0.633 + 0.828 0.231 0.633 + 0.828 0.231 0.633 + 0.828 0.231 0.633 + 0.828 0.231 0.633 + 0.736 0.222 0.640 + 0.736 0.222 0.640 + 0.736 0.222 0.640 + 0.736 0.222 0.640 + 0.736 0.222 0.640 + 0.787 0.221 0.634 + 0.787 0.221 0.634 + 0.787 0.221 0.634 + 0.787 0.221 0.634 + 0.787 0.221 0.634 diff --git a/examples/micro_speech/micro_speech.robot b/examples/micro_speech/micro_speech.robot new file mode 100644 index 00000000..1e4cf425 --- /dev/null +++ b/examples/micro_speech/micro_speech.robot @@ -0,0 +1,27 @@ +*** Settings *** +Suite Setup Setup +Suite Teardown Teardown +Test Setup Reset Emulation +Test Teardown Test Teardown +Resource ${RENODEKEYWORDS} + +*** Variables *** +${UART} sysbus.uart0 + +*** Keywords *** +Create Machine + Execute Command mach create + Execute Command machine LoadPlatformDescription @platforms/boards/arduino_nano_33_ble.repl + + Execute Command sysbus LoadELF @${CURDIR}/output/micro_speech.ino.elf + +*** Test Cases *** +Should Detect Yes Pattern + Create Machine + Execute Command sysbus.pdm SetInputFile @${CURDIR}/test_files/audio_yes_1s.s16le.pcm + + Create Terminal Tester ${UART} + Execute Command machine EnableProfiler @${CURDIR}/micro_speech.dump + Start Emulation + + Wait For Line On Uart Heard yes diff --git a/examples/micro_speech/test_files/README b/examples/micro_speech/test_files/README new file mode 100644 index 00000000..314ffdb2 --- /dev/null +++ b/examples/micro_speech/test_files/README @@ -0,0 +1 @@ +The `audio_yes_1s.s16le.pcm` file was originally downloaded (and adapted) from https://github.com/tensorflow/tflite-micro/tree/main/tensorflow/lite/micro/examples/micro_speech diff --git a/examples/micro_speech/test_files/audio_yes_1s.s16le.pcm b/examples/micro_speech/test_files/audio_yes_1s.s16le.pcm new file mode 100644 index 0000000000000000000000000000000000000000..3fa74a6fb996b86c8a9b8371f125a8c506dfdbd0 GIT binary patch literal 32000 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

xrn6NVm>kk$I8&*fmp$fhQw9| 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 literal 0 HcmV?d00001 diff --git a/examples/person_detection/person_detection.robot b/examples/person_detection/person_detection.robot new file mode 100644 index 00000000..a3b8c2c1 --- /dev/null +++ b/examples/person_detection/person_detection.robot @@ -0,0 +1,60 @@ +*** Settings *** +Suite Setup Setup +Suite Teardown Teardown +Test Setup Reset Emulation +Test Teardown Test Teardown +Resource ${RENODEKEYWORDS} + +*** Keywords *** +Should Run Detection + Wait For Line On Uart Attempting to start Arducam + Wait For Line On Uart Starting capture + Wait For Line On Uart Image captured + Wait For Line On Uart Reading \\d+ bytes from Arducam treatAsRegex=true + Wait For Line On Uart Finished reading + Wait For Line On Uart Decoding JPEG and converting to greyscale + Wait For Line On Uart Image decoded and processed + ${l}= Wait For Line On Uart Person score: (-?\\d+) No person score: (-?\\d+) treatAsRegex=true + ${s}= Evaluate int(${l.groups[0]}) - int(${l.groups[1]}) + + [return] ${s} + +Run Test + [Arguments] ${image} + + Execute Command Clear + Execute Command mach create + Execute Command machine LoadPlatformDescription @platforms/boards/arduino_nano_33_ble.repl + Execute Command sysbus LoadELF @${CURDIR}/output/person_detection.ino.elf + + Create Terminal Tester sysbus.uart0 + Execute Command sysbus.spi2.camera ImageSource @${image} + Execute Command machine EnableProfiler "${CURDIR}/person_detection.dump" + Start Emulation + +Detect Template + [Arguments] ${image} + + Run Test ${image} + ${r}= Should Run Detection + Should Be True ${r} > 30 + +No Detect Template + [Arguments] ${image} + + Run Test ${image} + ${r}= Should Run Detection + Should Be True ${r} < -30 + +*** Test Cases *** +Should Detect Person + [Template] Detect Template + + ${CURDIR}/test_files/person_image_0.jpg + ${CURDIR}/test_files/person_image_1.jpg + +Should Not Detect Person + [Template] No Detect Template + + ${CURDIR}/test_files/no_person_image_0.jpg + ${CURDIR}/test_files/no_person_image_1.jpg diff --git a/examples/person_detection/test_files/README b/examples/person_detection/test_files/README new file mode 100644 index 00000000..a734145b --- /dev/null +++ b/examples/person_detection/test_files/README @@ -0,0 +1,9 @@ +The following files were originally downloaded (and later resized and converted) from https://unsplash.com/: +* no_person_image_0.jpg +* no_person_image_1.jpg +* person_image_0.jpg +* person_image_1.jpg + +This is the Unsplash license (https://unsplash.com/license): + +Unsplash grants you an irrevocable, nonexclusive, worldwide copyright license to download, copy, modify, distribute, perform, and use photos from Unsplash for free, including for commercial purposes, without permission from or attributing the photographer or Unsplash. This license does not include the right to compile photos from Unsplash to replicate a similar or competing service. diff --git a/examples/person_detection/test_files/no_person_image_0.jpg b/examples/person_detection/test_files/no_person_image_0.jpg new file mode 100644 index 0000000000000000000000000000000000000000..08cb8a7ae7d055c287c820ac33689dad3a24acb4 GIT binary patch literal 3787 zcmV;+4m9!q*#F=F5K2Z#MgRc;0RTtgv=4-_35A08bV92_7dE+-%&EF&BoC^soAFflYVG#@89JvcHvE;BST|G)qX2mo3D zpaB690RO}Q8~^|V00RL50RR9100000000C91_A>I0SEy9!~i)E00IF60|EpC1_TBJ z0RR910RjU61Q7)iAqFuMB0*7Mae)UEGLfON6(d5?BvNw0;qVqEGh+YR00;pA002J# zP=4l14?nx2vOT>k(y zKbdY@(Ek8Z=i~c|(WY4>TD`;EIfO$d=J+Y(e)UbJ-N7yRh$(w=e5`%F>1SHo8%yPh zQG_Ktqz*HZPCq)9{uey9PU_9iv8jtYONG@L9Z5U5Ca5kf^CyPN2N@KO^43df%HxB` zt(tYXp6Ld2I|v?&2`=&5XA`fcg)GMt!Js-j`>pHm0bt z9Yhf;f%s)lFgf`1ocG0Z2z3)>GqtRR;SJ0(55Rr~m|kCF0iWJ&H&@;DVI&U z8>rxx9$A8o=RRTkRS!_x%RG`tD8jaemN-fT3NyPK>)HOPQ7%7+7Ume3v8rBe&L@MfN4DT23WhO3m;%$}pvx{{T*2bkj%o z?XMK97j$HiMYFv6Ybz;O_VMpgPSfc30(_GhInS?uTBvTmu$Ific*gvC``0(H8&*6c za@>zYHL^#x?p?tCzR5sZOU+MSi; z3lgog;11+Qab1J#qFLqXkR+2LHz)_M6u0d@{UvDhz*U_COyQ3N1w2<3ds!|(Xa>OE zV1VMYu$b7(iDXGzb^;9X@-y?ZE`Su zGN%;hLbO}UmW|HU+N^V)`-md1t#q468B8iwf2(f<{c9<$?jetTtd4yS!ImE?BGT_s zbWm)k1b5>Z`R1wgtw!d}3HyPK+wpB9^QawW;A-+~+Pwb&jSMuM>ClH7|K~ zEhm!F=#R)?T*LeR$T~*CbukYBLw@qG3Pir71M0&1323xgdX7I6x7>WTSiQcpHt2$ zbehGw5+gy6b46O}_V0yu8ToNsr%$>UOL=F#OG+dNtk~V=Kd<(w?+$G?=_9&~qcF$~ z>*@Z~Z{3zyO~trZJ;)u`H6` zQ(VcW+ysheRGBfACj=TU*6`!PGNF&K=7G7lmMgCw(pTO&+MLy;FNLbL8d)3*Rg1F_=y9OM%GX< znzv83J0t<7vADti03zhoZ%uWUpVXGkGy+&iZM!Byr}eLsZB{cIw0L4Rk_UVP%~f=H z&bu;3Jkml!a$&cGDl@hd1D8Xek9VnyUCzX z&Ps#$RG$9;I?{EKZ)GjWA#jIo?nrEURBTrcn)+W{pp?5@ayr%mRN64 zUt}Yktzi_{vPdi1`{PTKht_($zler_Fj;`Me?kADu1J zzSAD+;H3IQ@JHyxgZooEjL{%C4F&$PBi%M7{-H4j@)-<2cMOE+iHs-ka(&<11d%d=hB^M z`hnAKq__?|kQ^p)yyv!QoY&L90&FTs1&ANiMre3-dxC%#W|4{WFb4y$$GvI0x_Kla z+#EIrI}_XVrP|ftlH}XO*n%b4zaMk;uSbV8ND~dfTw{at_*Z~5JGPL@Sr43g0DF6J zkIt%kcJ|g?Ml*R9!t4xfoT{F~E>q_*_ zsOimOW57)R0Qm-vx3@*Zv;|m>=Ds|% zR+0%Ys=zMo-H5^Ut@g1jnytJ{*ag=lj>9>o+Mcrn_pY&$BT_))*R=r+-LO+Lu`(lh z7qIwHkl(4e@gD~RBR=>i_oZ(kZvFF3YzSyP6*!Qbk8FFSY+<9}jQuipE~I)MI8r()yCPIP*ksexr&TRO;<_OO$`; zroY~sirK3;jQcUhE9Kj5k}z*Ba7IUQScfr5xlR~o9}36C40G$8)~O#O8RNL2S=b&8 zelrqz9QxCJ0zp0JhS|!lX|3#ek+69DBac!D=kupsKW!z>riig_OrR=GagP50pS4zX z9=Qd)k;WtlBN*WS09R_8JyjORSVKRe_ z)kvC91cG?b6WEIJwGC7pKx|xh-6VxZKYD2m>l97t=3$e!u=<+Y_s9q0bs6-{dTt}x zg#jl=6swdI#Y)&y2U+`%C6AXku#1Kek}LH#jHF8ZG85{)$Xa5{jyEeUmF>U`C` zI==Q;hl_sEMmQ1>ynG2gjcB{-t-Dh0;#-am(-Ry9?UFN!_S;n#ct6cj&*fdkiBalt z#WIUg)nABpXyOrq$Hif{Z>TGr(UI$y1{8B6%fKPO0b%cgeg=qxs+9_>-j!fTDrL%_ zi6f9bE9dycWCiepW7Ba1^rG#O25%hhSIEZa_V|iw+Jy3gw-R{c9Ek~RgY)`Q%Zmu* z!^IzlF@u76pr+IIXKMq-M>U|?$`m%-gWCtaQ`p-Ww2O6x&gRRoI5}c?{i{2BNgCsG zg2z8ReQLW+mc}bbw3J6C{v8U2$oP+6_N@(}^z4a~XvJ5Mi!-PnOwf#aX5C4LOKBUi z%<^MDofe%zr`rgbEu%>hOBkbaNY4W~^`mXNmK%#{7XHo~sMW9*;d8T|f7-T7sdU3z zxoslXdw-GGbMps^lfV8Fl96ii#ksc_nYV-&8NQykZTpb zc*=OQ#-sej`;Ytm>nW1UQ<DZP zM|^Qc$JDnm1-X?iuJsFr^FsEeHXngLU#S?bdu`18^X47tqzIlf4Xcc|rEI<8>fCx9 zWKj?0ctY?w?enD9uEOD1G09>xn)cL}yI{v~0AoDRlT9pFGKl1K8@nqJRXSX<8vq~~aLWH;hVcehw&vD*}y5px~al?KRc&Y0|^K7*`dUlN9< zsIepyi8OYhY#Dw!zjJ>7|6cc;d!BRO&-;1qz31F>?#a~29Kdd*Z>SH@(a`}0rvo^l z06GAO{x5%L&?#UB@Lw1i7$6Kxj4&7zBNG!0&IX4uvobR=v2d`kvaz#su*2Y-T%7D& zr!o8AB6NS9ATZ;pk)4@|`E>RF~<{&yzfS!X6#6fq`4+sGO9T;@F+y4Op zGe8*udJxlJ8O09J|Lsf(7wE?$C3_W_5`>_~;Vi#_gz0@2ic%H|#XvYF9 zzw$st6K&NHss0Xy$%L7TIAr1Vc}-qq)~!vAo*@+jG_+jnl0k6RF<6nnm@!E}A|dms$$ zF45fjN&Wd`OWnlEo{U-WZ1L9z6RrH7fOvOkhtZmPw7UXp(^IZTrhDqrAKVk?U6qeN z!N!*6LvK9a5Q;pP%YOHB?}NIQN>IoT3DvBQg=>cu3;f&a^r}cpzDUd%_b`Dw~(17>hdsLiFE%@ zK=^w;Ll+MrxX1N~_ZI{6ra7Km5VbLFAznXlCa0qFRUo;)J3{Oykr)=BHC3t!$2Hg= zzHY3I$Uac7TmmCkNjT|=+`8N-FC9PUh#C}SUIS0Y3j$!+(i z4ftY{IhZa_ZKNJP)X1N7rLWoz%5}6TJorlL(F;%LyQ`(;A~}AvPW^D_*nyT)e0QyUzGZKAND-0LDbd2Z`KK5Je*?#98cDK zL;jO9S4>go9MBeW*iyIbTo)1@9u$N=O*;Wvp=t*Nbxj_9fzKC_b9_e*4=;eKLVbh_ zLaH;Lq$tnry_fSM@BJz)z7+y>2?5>4G_~7>2?@`?+DJxK6cHMt;JA0zjhqn?J;oU! z+*TGLeFqx#*Kc+AUm0dHSRILkvuYi7odAo`gf2<*Ob@PQ{*xr)bWcQH6=DZ1ClB%m8uo^<@h`peK?#jAITSW3GOO~YO%~5)V_m=226Uaklb)QY8@tO+5j+Gzr%R z9tPi}+1~#mq|{oLTp8JlcNZY>303osxxsFAsk-JH{8{P!94&ch*s+IYNx$6`AV;@qEzMd$F`zkfR)ZfkXA;Uf2TnmFBr0pF0@ ztRhw?lfbIvaeuFFGw<|KFU|gnxGBXgJ2n}6O?MuaY!}O7$$01yG~Go@RQ20EP^)p> zMi5(}&NseIad_4(nU`ca8|9MwXI~bwHS{fH+RLl$zw@`r(}>v&{-PtHffxNb6v(uN zPiz?3U9p_9_4zm^!Sz`rnZUf1dF<6*Fs4AWz#Hoji4p%G%wvcn_yXgaF#eIk_5IMb z(3O;`T5RQf>%htwij)ItmC_>agdYZ*zb<>loQYmyreFB&(87*N{(j1NN)Bb(lpzmP~7jCAl0 z$=pLJm@K@7R70@jAA>H=t@lDZuIzg4)xR-BR0Lcz6N0JB=cuHZ?X$W3wuS$z0x{Ui z&Sz2sK3#9xt7=JY0q3-dBfN^sz~8>RF&#RvzYB~!pcbg+s7ZC-4{zNFv%iIw-Yv^7 z|9Wxgi_N2hDp&+!QbO~&SPm$?g}=7HT+~QA*yfEqFpk=BAos4;m^Fl=Yf{+dN8X0< z(0E=PZ?+)wCmwu$QMSQjped~XvV5vC}qTSpdSYwhY7ne^g6fz_q| zz+!H5A|GjL-5~8!vxjJpsMGhBp7u{}wB5OG60*(DZ&KEF9*31tG!^xgdjzcz_3Q_MY+GB#n1Eu*C0;Eiu{Dd6wnR@gMd7Vi|i!SsW94rKz^6 z)G*fIe`)sR?5d1%y@`EjtmLs9e_@&jmqKV9oj&8x{slRK^KXjBep1J04m!LKOWc>& z1oUBVE0KjYMx~WG7pCyICg0h&Tp$?tT$FeWeaem2u;s3sOB;XeG4`9Pxk%({bvX(ae^)rFYq zwBK1s&#Z?+0Z#wYV_M6&w~Q4~w{_(B9xHs$jq@Fw?8!uPzHeQmw5Zwtu5Lo-9N64r zq{1tH(-iSATZ}({iXKLGnezK_fW4y^_Kkkik6V7c-k-*^TY6T6y3JHYvf-AP7rHxV zJd;hoL`$fSyp(L-rKt^W4Q}O=nZ*#7hp05{ZR*|qY&Jgw|F?SGMdpSh%FNfDkSs@I z1<@bYXLBaT)?K|?Z1vr&&{p8VBB|rzD7%>nqbf__P#;$CRcCp1AvkN{sD6p+fyLUWT+p_1;s>0ct=5s%VB0Y z#jWqEL?tu9C5`Ft^fjmk$KUVqH3o%T>ggd#DW;;f7fY@*girco-Z%#|&tN+0G&Yjb zzCnE|4-F+p*uDw}Rb@?d*L38+R-Q?Z^iQezXss)G8!fqP9ZN~P_}eA=WtyClgXq-u zWT<>q75I{7I%R#3arfhkTSngM?|Rg4mQgy6suK@J)$sY>&Z#o$$O^XGMdt>akOBk^ z!?Jqs)J)V+p4L{ZVPYmXiXAVk5SlOHEsvXB(n^)(QqF+d4Glp+t=18X9Cd%NiBg5D zCSXz@*M4ZfW?}AeGpWSf?0|loC>A3>v|xO330hr(^{GW{^WUS1%b>+VD;HApSW?P^ ze{HNwV00J+Pk`{mmQCs?A^R4?@%XfxnY?7h6{wHR2>_9P@u*q2VsJN0;rKV|J{j|#gl`S=S9&MX{&^>n~)MeW93HC1=hvFgV z>mpc#(FPHf9Z~@ydqz2`9460+%dr#~_Zps~jbvF&g7~gCT#<9w$o46^wis$&n@PxNZGusL4#OrF4l>la4qjh?J5OrVG zEd(1Q_dKY3d zoc8|nbj8g8?OgYIr#3{pLT7o18I<;o$Zz~$InOR@q;*6?2wqH|u6Ui!*-~HorRNzz zT2pk~_h;7OMN+YuVyVTO&~`sb{r z9O&)t{#fX$qp7RVV~>Slne3z6R@|9EaO~@0TGKysZfrAxrQa9$U(j=3dkT|iv_YqR zN@bng9n2orGt=-Ro%cx0YJcyQ_QcTB>k(HIJOUeh!zGk?N+EJpDL1x3MAxmbG&St> zx0k&`SNm(+VrX7<{K@G2VB?Kic3y2GucEZv!cL_6H8C+mUoD?k;=A#KDwDoS?~3uw hh7iF%dc@lTK_TX>I75NDFwUOZ#v4^A2o!Ph`9HcRD?R`K literal 0 HcmV?d00001 diff --git a/examples/person_detection/test_files/person_image_0.jpg b/examples/person_detection/test_files/person_image_0.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0935bd31659a948761860ecdfd978a5726274d54 GIT binary patch literal 3853 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 literal 0 HcmV?d00001 diff --git a/examples/person_detection/test_files/person_image_1.jpg b/examples/person_detection/test_files/person_image_1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..89b24e552c6f63ef5e1eab13ddcd93475bbaedff GIT binary patch literal 3836 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