~xdavidwu/motion-control

139e1679be026f99ccfae8e459f0432723eed397 — Pinghao Wu 3 months ago 2309713
count squats with joycon
3 files changed, 69 insertions(+), 2 deletions(-)

M .gitignore
M Makefile
A cmd/squats/main+joycon.ha
M .gitignore => .gitignore +1 -0
@@ 7,3 7,4 @@
/buttonc
/evdev/codes.ha
/event-codes
/squats

M Makefile => Makefile +2 -2
@@ 1,7 1,7 @@
SENSORS ?= joycon
SENSORS_LIBS =
HEADERS_PREFIX ?= /usr/include
BINARIES = event-codes evdev-dump-events uinput-pointer sensors-dump pointerd pointerc motion-control buttonc
BINARIES = event-codes evdev-dump-events uinput-pointer sensors-dump pointerd pointerc motion-control buttonc squats

ifeq ($(SENSORS), joycon)
	SENSORS_LIBS = -levdev


@@ 23,7 23,7 @@ buttonc pointerc:
	hare build -o $@ tools/$@/
pointerd: evdev/codes.ha
	hare build -levdev -o $@ cmd/$@/
motion-control:
motion-control squats:
	hare build $(SENSORS_LIBS) -T +$(SENSORS) -o $@ cmd/$@/

clean:

A cmd/squats/main+joycon.ha => cmd/squats/main+joycon.ha +66 -0
@@ 0,0 1,66 @@
use errors;
use fmt;
use sensors::joycon;
use time;
use unix::signal;
use unix::tty;
use os;

let exit: bool	= false;

fn sigint(sig: signal::sig, info: *signal::siginfo, ucontext: *opaque) void = {
	exit = true;
};

type status = enum u8 {
	UP,
	DOWN,
	IDLE,
};

def THRESHOLD: f64 = 10.0;

export fn main() void = {
	const joycon = joycon::new(void)!;
	defer joycon::destroy(joycon);

	signal::handle(signal::sig::INT, &sigint, signal::flag::RESTART);

	const screen = tty::isatty(os::stdout_file);

	let count = 0u64;
	let last = status::UP;
	let lastts = time::now(time::clock::MONOTONIC);

	for (let i = 0; !exit; i += 1) {
		const sample = joycon::next_sample(joycon)!;
		const gyro = sample.gyroscope;

		if (i % 50 == 0) {
			if (screen) {
				fmt::print("\x1b[1;1H\x1b[0J")!;
			};

			fmt::printfln("Gyroscope:\t{}\t{}\t{}\tdps\n",
				gyro.0, gyro.1, gyro.2)!;
			const s = if (gyro.1 > THRESHOLD) status::UP
				else if (gyro.1 < -THRESHOLD) status::DOWN
				else status::IDLE;
			const want = if (last == status::UP) status::DOWN
				else status::UP;
			const ts = time::now(time::clock::MONOTONIC);
			if (s == want && time::diff(lastts, ts) > time::SECOND) {
				last = s;
				lastts = ts;
				count += 1;
			};

			fmt::println(switch (s) {
			case status::UP => yield 'U';
			case status::DOWN => yield 'D';
			case status::IDLE => yield 'X';
			}, count / 2)!;

		};
	};
};