mirror of
https://github.com/VioletTides/KnockThru.git
synced 2026-10-17 18:03:17 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8a90745e25 | ||
|
|
ff3f150e00 | ||
|
|
c6a7f8c2cc | ||
|
|
ab331f0a85 | ||
|
|
9a0d044d3c | ||
|
|
e01afc9833 |
No files matched your search
+1
-1
@@ -1,5 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(KnockThru VERSION 1.0.1 LANGUAGES CXX)
|
||||
project(KnockThru VERSION 1.0.2 LANGUAGES CXX)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
@@ -52,6 +52,8 @@ Any of these three knocks works. Use the same kind for every knock in a set.
|
||||
|
||||

|
||||
|
||||
A surface knock also works on your leg. Keep the controller where the headset cameras can see it, because knocks out of view get missed more often.
|
||||
|
||||
Pause for a moment, then knock at a steady pace. After your last knock, KnockThru waits a moment in case another one follows.
|
||||
|
||||

|
||||
@@ -191,7 +193,7 @@ The log is `~/.config/knockthru/application.log`.
|
||||
Copy the Linux ARM64 ZIP from the releases page to the Frame, then run:
|
||||
|
||||
```sh
|
||||
unzip -oq knockthru-1.0.1-linux-arm64.zip -d ~/KnockThru
|
||||
unzip -oq knockthru-1.0.2-linux-arm64.zip -d ~/KnockThru
|
||||
~/KnockThru/knockthru --install
|
||||
```
|
||||
|
||||
@@ -212,7 +214,7 @@ Steam Frame build (needs Zig 0.16.0) and release ZIP (needs Node.js):
|
||||
|
||||
```sh
|
||||
scripts/build-arm64.sh
|
||||
node scripts/package.mjs --build-dir build-arm64 --version 1.0.1
|
||||
node scripts/package.mjs --build-dir build-arm64 --version 1.0.2
|
||||
```
|
||||
|
||||
README images (needs Pillow, numpy, ffmpeg, and Chromium, after the host build):
|
||||
|
||||
@@ -5,7 +5,7 @@ set -euo pipefail
|
||||
|
||||
root="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
build="${1:-$root/build-arm64}"
|
||||
version="${KNOCKTHRU_VERSION:-1.0.1}"
|
||||
version="${KNOCKTHRU_VERSION:-1.0.2}"
|
||||
# KNOCKTHRU_TEST_HOOK=1 builds in the test hook from src/app.cpp. Releases never set it.
|
||||
test_hook="${KNOCKTHRU_TEST_HOOK:-}"
|
||||
mkdir -p "$build/bin"
|
||||
|
||||
+2
-1
@@ -73,7 +73,8 @@ void merge(AppConfig& config, const json& file, const fs::path& path) {
|
||||
{"controller_peak", &d.controller_peak}, {"confirmed_peak", &d.confirmed_peak},
|
||||
{"partner_peak", &d.partner_peak}, {"headset_peak", &d.headset_peak}, {"headset_knock_peak", &d.headset_knock_peak},
|
||||
{"max_speed_after", &d.max_speed_after}, {"surface_speed_after", &d.surface_speed_after},
|
||||
{"max_speed_before", &d.max_speed_before}, {"together_distance", &d.together_distance},
|
||||
{"max_speed_before", &d.max_speed_before}, {"surface_speed_before", &d.surface_speed_before},
|
||||
{"together_distance", &d.together_distance},
|
||||
{"same_spot", &d.same_spot}, {"merge_s", &d.merge_s}, {"min_gap_s", &d.min_gap_s}, {"fast_gap_s", &d.fast_gap_s},
|
||||
{"max_gap_s", &d.max_gap_s}, {"quiet_before_s", &d.quiet_before_s}};
|
||||
if (!value.is_object()) fail("detector must be an object");
|
||||
|
||||
@@ -116,7 +116,7 @@ std::optional<Knock> KnockDetector::judge(Device device, std::size_t i) const {
|
||||
if (sample.accel < threshold) return std::nullopt;
|
||||
const auto* before = nearest(history, sample.t - 0.03);
|
||||
const auto* after = nearest(history, sample.t + 0.03);
|
||||
if (!before || !after || norm(before->velocity) >= config_.max_speed_before ||
|
||||
if (!before || !after || norm(before->velocity) >= (surface ? config_.surface_speed_before : config_.max_speed_before) ||
|
||||
norm(after->velocity) >= (surface ? config_.surface_speed_after : config_.max_speed_after))
|
||||
return std::nullopt;
|
||||
return knock;
|
||||
|
||||
@@ -25,8 +25,9 @@ struct DetectorConfig {
|
||||
double max_speed_after = 0.4; // m/s, 30 ms after the spike
|
||||
double surface_speed_after = 0.55; // m/s, table knocks rebound
|
||||
double max_speed_before = 1.8; // m/s, 30 ms before the spike
|
||||
double surface_speed_before = 2.2; // m/s, knocks on a leg come in faster
|
||||
double together_distance = 0.15; // m, controller separation for a together knock
|
||||
double same_spot = 0.03; // m, surface knocks in one sequence must land this close
|
||||
double same_spot = 0.06; // m, surface knocks in one sequence must land this close. Leg knocks spread more than desk knocks.
|
||||
double merge_s = 0.08; // spikes closer than this are one knock (bounces)
|
||||
double min_gap_s = 0.15; // closer surface knocks are table bounces
|
||||
double fast_gap_s = 0.105; // closer together or headset knocks are rebounds
|
||||
|
||||
Binary file not shown.
Binary file not shown.
+12
-1
@@ -110,7 +110,8 @@ DetectorConfig test_config() {
|
||||
{"min_approach_together", &config.min_approach[0]}, {"min_approach_surface", &config.min_approach[1]},
|
||||
{"min_approach_headset", &config.min_approach[2]},
|
||||
{"max_speed_after", &config.max_speed_after}, {"surface_speed_after", &config.surface_speed_after},
|
||||
{"max_speed_before", &config.max_speed_before}, {"same_spot", &config.same_spot},
|
||||
{"max_speed_before", &config.max_speed_before}, {"surface_speed_before", &config.surface_speed_before},
|
||||
{"same_spot", &config.same_spot},
|
||||
{"min_gap_s", &config.min_gap_s}, {"fast_gap_s", &config.fast_gap_s}, {"max_gap_s", &config.max_gap_s},
|
||||
{"quiet_before_s", &config.quiet_before_s}};
|
||||
std::stringstream list(set);
|
||||
@@ -225,6 +226,16 @@ void replay_tests() {
|
||||
check(surface["surfacex2"] >= 16, "surface: at least 16 surface doubles");
|
||||
auto headset = replay("headset");
|
||||
check(headset["headsetx2"] >= 15, "headset: at least 15 headset doubles");
|
||||
// Doubles and triples knocked on a leg with each hand, headset worn. At
|
||||
// surface_speed_before 1.8 most right-hand knocks were lost, giving 9 actions.
|
||||
auto leg = replay("leg");
|
||||
check(leg["surfacex2"] + leg["surfacex3"] >= 14 && total(leg) == leg["surfacex2"] + leg["surfacex3"],
|
||||
"leg: at least 14 surface actions, nothing else");
|
||||
// About 40 doubles knocked on a leg, a few seconds apart, mostly with the
|
||||
// right hand. At same_spot 0.03, 20 counted.
|
||||
auto leg_doubles = replay("leg-doubles");
|
||||
check(leg_doubles["surfacex2"] >= 23 && total(leg_doubles) == leg_doubles["surfacex2"],
|
||||
"leg-doubles: at least 23 surface doubles, nothing else");
|
||||
check(total(replay("play")) == 0, "play: no actions");
|
||||
check(total(replay("noise")) == 0, "noise: no actions");
|
||||
// The controllers bumping while the wearer fit the strap on each one, in Into the Radius 2.
|
||||
|
||||
Reference in new issue
Block a user