support for is-gesture (#1873)
* support for is-gesture * updated shims * activate shake button * refactor * refactor shake button
This commit is contained in:
parent
8890614325
commit
d640dc5eed
@ -13,6 +13,7 @@ input.onPinPressed(TouchPin.P0, () => {
|
|||||||
|
|
||||||
});
|
});
|
||||||
input.buttonIsPressed(Button.A);
|
input.buttonIsPressed(Button.A);
|
||||||
|
input.isGesture(Gesture.Shake);
|
||||||
input.compassHeading();
|
input.compassHeading();
|
||||||
input.pinIsPressed(TouchPin.P0);
|
input.pinIsPressed(TouchPin.P0);
|
||||||
input.temperature();
|
input.temperature();
|
||||||
@ -27,4 +28,6 @@ input.setAccelerometerRange(AcceleratorRange.OneG);
|
|||||||
|
|
||||||
## See also
|
## See also
|
||||||
|
|
||||||
[onButtonPressed](/reference/input/on-button-pressed), [onGesture](/reference/input/on-gesture), [onPinPressed](/reference/input/on-pin-pressed), [buttonIsPressed](/reference/input/button-is-pressed), [compassHeading](/reference/input/compass-heading), [pinIsPressed](/reference/input/pin-is-pressed), [temperature](/reference/input/temperature), [acceleration](/reference/input/acceleration), [lightLevel](/reference/input/light-level), [rotation](/reference/input/rotation), [magneticForce](/reference/input/magnetic-force), [runningTime](/reference/input/running-time), [setAccelerometerRange](/reference/input/set-accelerometer-range), [calibrate-compass](/reference/input/calibrate-compass)
|
[onButtonPressed](/reference/input/on-button-pressed), [onGesture](/reference/input/on-gesture), [onPinPressed](/reference/input/on-pin-pressed), [buttonIsPressed](/reference/input/button-is-pressed),
|
||||||
|
[is gesture](/reference/input/is-gesture),
|
||||||
|
[compassHeading](/reference/input/compass-heading), [pinIsPressed](/reference/input/pin-is-pressed), [temperature](/reference/input/temperature), [acceleration](/reference/input/acceleration), [lightLevel](/reference/input/light-level), [rotation](/reference/input/rotation), [magneticForce](/reference/input/magnetic-force), [runningTime](/reference/input/running-time), [setAccelerometerRange](/reference/input/set-accelerometer-range), [calibrate-compass](/reference/input/calibrate-compass)
|
||||||
|
28
docs/reference/input/is-gesture.md
Normal file
28
docs/reference/input/is-gesture.md
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
# Is Gesture
|
||||||
|
|
||||||
|
Tests if a gesture is currently detected.
|
||||||
|
|
||||||
|
```sig
|
||||||
|
input.isGesture(Gesture.Shake)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
* ``gesture`` means the way you hold or move the @boardname@. This can be `shake`, `logo up`, `logo down`, `screen up`, `screen down`, `tilt left`, `tilt right`, `free fall`, `3g`, or `6g`.
|
||||||
|
|
||||||
|
## Example: random number
|
||||||
|
|
||||||
|
This program shows a number from `2` to `9` when you shake the @boardname@.
|
||||||
|
|
||||||
|
```blocks
|
||||||
|
forever(function() {
|
||||||
|
if (input.isGesture(Gesture.Shake)) {
|
||||||
|
let x = Math.randomRange(2, 9)
|
||||||
|
basic.showNumber(x)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
## See Also
|
||||||
|
|
||||||
|
[on gesture](/reference/input/on-gesture)
|
@ -24,3 +24,6 @@ input.onGesture(Gesture.Shake,() => {
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## See Also
|
||||||
|
|
||||||
|
[is gesture](/reference/input/is-gesture)
|
@ -340,6 +340,8 @@
|
|||||||
"input.calibrate": "Obsolete, use input.calibrateCompass instead.",
|
"input.calibrate": "Obsolete, use input.calibrateCompass instead.",
|
||||||
"input.calibrateCompass": "Obsolete, compass calibration is automatic.",
|
"input.calibrateCompass": "Obsolete, compass calibration is automatic.",
|
||||||
"input.compassHeading": "Get the current compass heading in degrees.",
|
"input.compassHeading": "Get the current compass heading in degrees.",
|
||||||
|
"input.isGesture": "Tests if a gesture is currently detected.",
|
||||||
|
"input.isGesture|param|gesture": "the type of gesture to detect, eg: Gesture.Shake",
|
||||||
"input.lightLevel": "Reads the light level applied to the LED screen in a range from ``0`` (dark) to ``255`` bright.",
|
"input.lightLevel": "Reads the light level applied to the LED screen in a range from ``0`` (dark) to ``255`` bright.",
|
||||||
"input.magneticForce": "Get the magnetic force value in ``micro-Teslas`` (``µT``). This function is not supported in the simulator.",
|
"input.magneticForce": "Get the magnetic force value in ``micro-Teslas`` (``µT``). This function is not supported in the simulator.",
|
||||||
"input.magneticForce|param|dimension": "TODO",
|
"input.magneticForce|param|dimension": "TODO",
|
||||||
|
@ -291,6 +291,7 @@
|
|||||||
"input.buttonIsPressed|block": "button|%NAME|is pressed",
|
"input.buttonIsPressed|block": "button|%NAME|is pressed",
|
||||||
"input.calibrateCompass|block": "calibrate compass",
|
"input.calibrateCompass|block": "calibrate compass",
|
||||||
"input.compassHeading|block": "compass heading (°)",
|
"input.compassHeading|block": "compass heading (°)",
|
||||||
|
"input.isGesture|block": "is %gesture gesture",
|
||||||
"input.lightLevel|block": "light level",
|
"input.lightLevel|block": "light level",
|
||||||
"input.magneticForce|block": "magnetic force (µT)|%NAME",
|
"input.magneticForce|block": "magnetic force (µT)|%NAME",
|
||||||
"input.onButtonPressed|block": "on button|%NAME|pressed",
|
"input.onButtonPressed|block": "on button|%NAME|pressed",
|
||||||
|
@ -190,6 +190,19 @@ namespace input {
|
|||||||
registerWithDal(MICROBIT_ID_GESTURE, gi, body);
|
registerWithDal(MICROBIT_ID_GESTURE, gi, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests if a gesture is currently detected.
|
||||||
|
* @param gesture the type of gesture to detect, eg: Gesture.Shake
|
||||||
|
*/
|
||||||
|
//% help=input/is-gesture weight=10 blockGap=8
|
||||||
|
//% blockId=deviceisgesture block="is %gesture gesture"
|
||||||
|
//% parts="accelerometer"
|
||||||
|
//% gesture.fieldEditor="gestures" gesture.fieldOptions.columns=4
|
||||||
|
bool isGesture(Gesture gesture) {
|
||||||
|
int gi = (int)gesture;
|
||||||
|
return uBit.accelerometer.getGesture() == gi;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do something when a pin is touched and released again (while also touching the GND pin).
|
* Do something when a pin is touched and released again (while also touching the GND pin).
|
||||||
* @param name the pin that needs to be pressed, eg: TouchPin.P0
|
* @param name the pin that needs to be pressed, eg: TouchPin.P0
|
||||||
|
10
libs/core/shims.d.ts
vendored
10
libs/core/shims.d.ts
vendored
@ -228,6 +228,16 @@ declare namespace input {
|
|||||||
//% NAME.fieldEditor="gestures" NAME.fieldOptions.columns=4 shim=input::onGesture
|
//% NAME.fieldEditor="gestures" NAME.fieldOptions.columns=4 shim=input::onGesture
|
||||||
function onGesture(gesture: Gesture, body: () => void): void;
|
function onGesture(gesture: Gesture, body: () => void): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests if a gesture is currently detected.
|
||||||
|
* @param gesture the type of gesture to detect, eg: Gesture.Shake
|
||||||
|
*/
|
||||||
|
//% help=input/is-gesture weight=10 blockGap=8
|
||||||
|
//% blockId=deviceisgesture block="is %gesture gesture"
|
||||||
|
//% parts="accelerometer"
|
||||||
|
//% gesture.fieldEditor="gestures" gesture.fieldOptions.columns=4 shim=input::isGesture
|
||||||
|
function isGesture(gesture: Gesture): boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do something when a pin is touched and released again (while also touching the GND pin).
|
* Do something when a pin is touched and released again (while also touching the GND pin).
|
||||||
* @param name the pin that needs to be pressed, eg: TouchPin.P0
|
* @param name the pin that needs to be pressed, eg: TouchPin.P0
|
||||||
|
@ -1,30 +1,39 @@
|
|||||||
namespace pxsim.input {
|
namespace pxsim.input {
|
||||||
export function onGesture(gesture: number, handler: RefAction) {
|
function accForGesture(gesture: number) {
|
||||||
let b = board().accelerometerState;
|
let b = board().accelerometerState;
|
||||||
b.accelerometer.activate();
|
b.accelerometer.activate();
|
||||||
|
if (gesture == 11 && !b.useShake) { // SHAKE
|
||||||
if (gesture == 11 && !b.useShake) { // SAKE
|
|
||||||
b.useShake = true;
|
b.useShake = true;
|
||||||
runtime.queueDisplayUpdate();
|
runtime.queueDisplayUpdate();
|
||||||
}
|
}
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function onGesture(gesture: number, handler: RefAction) {
|
||||||
|
const b = accForGesture(gesture);
|
||||||
pxtcore.registerWithDal(DAL.MICROBIT_ID_GESTURE, gesture, handler);
|
pxtcore.registerWithDal(DAL.MICROBIT_ID_GESTURE, gesture, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isGesture(gesture: number): boolean {
|
||||||
|
const b = accForGesture(gesture);
|
||||||
|
return b.accelerometer.getGesture() == gesture;
|
||||||
|
}
|
||||||
|
|
||||||
export function acceleration(dimension: number): number {
|
export function acceleration(dimension: number): number {
|
||||||
let b = board().accelerometerState;
|
let b = board().accelerometerState;
|
||||||
let acc = b.accelerometer;
|
let acc = b.accelerometer;
|
||||||
switch (dimension) {
|
switch (dimension) {
|
||||||
case 0:
|
case 0:
|
||||||
acc.activate(AccelerometerFlag.X);
|
acc.activate(AccelerometerFlag.X);
|
||||||
return acc.getX();
|
return acc.getX();
|
||||||
case 1:
|
case 1:
|
||||||
acc.activate(AccelerometerFlag.Y);
|
acc.activate(AccelerometerFlag.Y);
|
||||||
return acc.getY();
|
return acc.getY();
|
||||||
case 2:
|
case 2:
|
||||||
acc.activate(AccelerometerFlag.Z);
|
acc.activate(AccelerometerFlag.Z);
|
||||||
return acc.getZ();
|
return acc.getZ();
|
||||||
default:
|
default:
|
||||||
acc.activate();
|
acc.activate();
|
||||||
return Math.floor(Math.sqrt(acc.instantaneousAccelerationSquared()));
|
return Math.floor(Math.sqrt(acc.instantaneousAccelerationSquared()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -249,7 +258,10 @@ namespace pxsim {
|
|||||||
updateGesture() {
|
updateGesture() {
|
||||||
// Determine what it looks like we're doing based on the latest sample...
|
// Determine what it looks like we're doing based on the latest sample...
|
||||||
let g = this.instantaneousPosture();
|
let g = this.instantaneousPosture();
|
||||||
|
this.setGesture(g);
|
||||||
|
}
|
||||||
|
|
||||||
|
private setGesture(g: number) {
|
||||||
// Perform some low pass filtering to reduce jitter from any detected effects
|
// Perform some low pass filtering to reduce jitter from any detected effects
|
||||||
if (g == this.currentGesture) {
|
if (g == this.currentGesture) {
|
||||||
if (this.sigma < DAL.MICROBIT_ACCELEROMETER_GESTURE_DAMPING)
|
if (this.sigma < DAL.MICROBIT_ACCELEROMETER_GESTURE_DAMPING)
|
||||||
@ -267,6 +279,11 @@ namespace pxsim {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
forceGesture(g: number) {
|
||||||
|
this.sigma = DAL.MICROBIT_ACCELEROMETER_GESTURE_DAMPING + 1;
|
||||||
|
this.setGesture(g);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads the X axis value of the latest update from the accelerometer.
|
* Reads the X axis value of the latest update from the accelerometer.
|
||||||
* @param system The coordinate system to use. By default, a simple cartesian system is provided.
|
* @param system The coordinate system to use. By default, a simple cartesian system is provided.
|
||||||
@ -378,6 +395,10 @@ namespace pxsim {
|
|||||||
return this.roll;
|
return this.roll;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getGesture(): number {
|
||||||
|
return this.lastGesture;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recalculate roll and pitch values for the current sample.
|
* Recalculate roll and pitch values for the current sample.
|
||||||
* We only do this at most once per sample, as the necessary trigonemteric functions are rather
|
* We only do this at most once per sample, as the necessary trigonemteric functions are rather
|
||||||
@ -401,5 +422,9 @@ namespace pxsim {
|
|||||||
constructor(runtime: Runtime) {
|
constructor(runtime: Runtime) {
|
||||||
this.accelerometer = new Accelerometer(runtime);
|
this.accelerometer = new Accelerometer(runtime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shake() {
|
||||||
|
this.accelerometer.forceGesture(DAL.MICROBIT_ACCELEROMETER_EVT_SHAKE); // SHAKE == 11
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -433,10 +433,10 @@ path.sim-board {
|
|||||||
this.shakeButton.addEventListener(pointerEvents.up, ev => {
|
this.shakeButton.addEventListener(pointerEvents.up, ev => {
|
||||||
let state = this.board;
|
let state = this.board;
|
||||||
svg.fill(this.shakeButton, this.props.theme.virtualButtonUp);
|
svg.fill(this.shakeButton, this.props.theme.virtualButtonUp);
|
||||||
this.board.bus.queue(DAL.MICROBIT_ID_GESTURE, 11); // GESTURE_SHAKE
|
this.board.accelerometerState.shake();
|
||||||
})
|
})
|
||||||
accessibility.enableKeyboardInteraction(this.shakeButton, undefined, () => {
|
accessibility.enableKeyboardInteraction(this.shakeButton, undefined, () => {
|
||||||
this.board.bus.queue(DAL.MICROBIT_ID_GESTURE, 11);
|
this.board.accelerometerState.shake();
|
||||||
});
|
});
|
||||||
accessibility.setAria(this.shakeButton, "button", "Shake the board");
|
accessibility.setAria(this.shakeButton, "button", "Shake the board");
|
||||||
this.shakeText = svg.child(this.g, "text", { x: 400, y: 110, class: "sim-text" }) as SVGTextElement;
|
this.shakeText = svg.child(this.g, "text", { x: 400, y: 110, class: "sim-text" }) as SVGTextElement;
|
||||||
|
Loading…
Reference in New Issue
Block a user