@robotical/webapp-types 1.0.5 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-types/src/application/RAFTs/Cog/Cog.d.ts +6 -0
- package/dist-types/src/application/RAFTs/Cog/Cog.js +23 -1
- package/dist-types/src/application/RAFTs/Cog/PublishedDataAnalyser.d.ts +28 -0
- package/dist-types/src/application/RAFTs/Cog/PublishedDataAnalyser.js +423 -0
- package/dist-types/src/application/RAFTs/RAFT.js +0 -1
- package/dist-types/src/application/RAFTs/raft-subscription-helpers.d.ts +4 -0
- package/dist-types/src/application/RAFTs/raft-subscription-helpers.js +31 -0
- package/package.json +1 -1
|
@@ -4,11 +4,13 @@ import { RaftTypeE } from "../../../types/raft";
|
|
|
4
4
|
import { CogStateInfo, RICLedLcdColours } from "@robotical/roboticaljs";
|
|
5
5
|
import { RaftConnEvent, RaftPublishEvent, RaftUpdateEvent } from "@robdobsn/raftjs";
|
|
6
6
|
import { RaftInfoEvents } from "../../../types/events/raft-info";
|
|
7
|
+
import PublishedDataAnalyser from "./PublishedDataAnalyser";
|
|
7
8
|
export declare class Cog extends RAFT implements RICInterface {
|
|
8
9
|
id: string;
|
|
9
10
|
type: RaftTypeE;
|
|
10
11
|
_ledLcdColours: RICLedLcdColours;
|
|
11
12
|
raftStateInfo: CogStateInfo | null;
|
|
13
|
+
publishedDataAnalyser: PublishedDataAnalyser;
|
|
12
14
|
constructor(id: string);
|
|
13
15
|
get ledLcdColours(): RICLedLcdColours;
|
|
14
16
|
/**
|
|
@@ -23,6 +25,10 @@ export declare class Cog extends RAFT implements RICInterface {
|
|
|
23
25
|
* This methods handles RAFT events coming from the RICConnector of the wrapper
|
|
24
26
|
*/
|
|
25
27
|
handleRaftEvent(eventType: string, eventEnum: RaftConnEvent | RaftUpdateEvent | RaftPublishEvent | RaftInfoEvents, eventName: string, eventData: any): void;
|
|
28
|
+
/**
|
|
29
|
+
* Conn Event Handler
|
|
30
|
+
*/
|
|
31
|
+
connEventHandler(eventEnum: RaftConnEvent, eventName: string, data: any): Promise<void>;
|
|
26
32
|
/**
|
|
27
33
|
* Pub Event Handler
|
|
28
34
|
*/
|
|
@@ -51,8 +51,9 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
51
51
|
};
|
|
52
52
|
import RAFT from "../RAFT";
|
|
53
53
|
import { RaftTypeE } from "../../../types/raft";
|
|
54
|
-
import { RaftPublishEvent } from "@robdobsn/raftjs";
|
|
54
|
+
import { RaftConnEvent, RaftPublishEvent } from "@robdobsn/raftjs";
|
|
55
55
|
import { RaftInfoEvents } from "../../../types/events/raft-info";
|
|
56
|
+
import PublishedDataAnalyser from "./PublishedDataAnalyser";
|
|
56
57
|
var Cog = /** @class */ (function (_super) {
|
|
57
58
|
__extends(Cog, _super);
|
|
58
59
|
function Cog(id) {
|
|
@@ -68,6 +69,7 @@ var Cog = /** @class */ (function (_super) {
|
|
|
68
69
|
];
|
|
69
70
|
// RAFT State Info
|
|
70
71
|
_this.raftStateInfo = null;
|
|
72
|
+
_this.publishedDataAnalyser = new PublishedDataAnalyser(_this);
|
|
71
73
|
return _this;
|
|
72
74
|
}
|
|
73
75
|
Object.defineProperty(Cog.prototype, "ledLcdColours", {
|
|
@@ -98,6 +100,9 @@ var Cog = /** @class */ (function (_super) {
|
|
|
98
100
|
Cog.prototype.handleRaftEvent = function (eventType, eventEnum, eventName, eventData) {
|
|
99
101
|
_super.prototype.handleRaftEvent.call(this, eventType, eventEnum, eventName, eventData);
|
|
100
102
|
switch (eventType) {
|
|
103
|
+
case "conn":
|
|
104
|
+
this.connEventHandler(eventEnum, eventName, eventData);
|
|
105
|
+
break;
|
|
101
106
|
case "pub":
|
|
102
107
|
this.pubEventHandler(eventEnum, eventName, eventData);
|
|
103
108
|
break;
|
|
@@ -108,6 +113,23 @@ var Cog = /** @class */ (function (_super) {
|
|
|
108
113
|
break;
|
|
109
114
|
}
|
|
110
115
|
};
|
|
116
|
+
/**
|
|
117
|
+
* Conn Event Handler
|
|
118
|
+
*/
|
|
119
|
+
Cog.prototype.connEventHandler = function (eventEnum, eventName, data) {
|
|
120
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
121
|
+
return __generator(this, function (_a) {
|
|
122
|
+
switch (eventEnum) {
|
|
123
|
+
case RaftConnEvent.CONN_DISCONNECTED:
|
|
124
|
+
this.publishedDataAnalyser.unsubscribeFromPublishedData();
|
|
125
|
+
break;
|
|
126
|
+
default:
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
return [2 /*return*/];
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
};
|
|
111
133
|
/**
|
|
112
134
|
* Pub Event Handler
|
|
113
135
|
*/
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { CogStateInfo } from "@robotical/roboticaljs";
|
|
2
|
+
import RAFT from "../RAFT";
|
|
3
|
+
interface CogState {
|
|
4
|
+
tilt: boolean | "forward" | "backward" | "left" | "right";
|
|
5
|
+
movementType: boolean | "shake" | "move";
|
|
6
|
+
rotation: boolean | "clockwise" | "counter-clockwise";
|
|
7
|
+
buttonClick: boolean;
|
|
8
|
+
objectSense: boolean | "left" | "right";
|
|
9
|
+
lightSense: boolean | "left" | "right";
|
|
10
|
+
irMessage: boolean | "left" | "right";
|
|
11
|
+
}
|
|
12
|
+
declare class PublishedDataAnalyser {
|
|
13
|
+
private cog;
|
|
14
|
+
cogState: CogState;
|
|
15
|
+
private pubSub;
|
|
16
|
+
constructor(cog: RAFT);
|
|
17
|
+
subscribeToPublishedData(): void;
|
|
18
|
+
unsubscribeFromPublishedData(): void;
|
|
19
|
+
analyse(data: CogStateInfo): void;
|
|
20
|
+
detectTilt(data: CogStateInfo, isMoving: boolean): void;
|
|
21
|
+
detectMovement(data: CogStateInfo): boolean;
|
|
22
|
+
detectRotation(data: CogStateInfo, isMoving: boolean): void;
|
|
23
|
+
detectButtonClick(data: CogStateInfo): void;
|
|
24
|
+
detectObjectSense(data: CogStateInfo): void;
|
|
25
|
+
detectLightSense(data: CogStateInfo): void;
|
|
26
|
+
detectIRMessage(data: CogStateInfo): void;
|
|
27
|
+
}
|
|
28
|
+
export default PublishedDataAnalyser;
|
|
@@ -0,0 +1,423 @@
|
|
|
1
|
+
import { raftPubSubscriptionHelper } from "../raft-subscription-helpers";
|
|
2
|
+
import { isVersionGreater_errorCatching } from "../../../utils/helpers/compare-version";
|
|
3
|
+
var PublishedDataAnalyser = /** @class */ (function () {
|
|
4
|
+
function PublishedDataAnalyser(cog) {
|
|
5
|
+
this.cog = cog;
|
|
6
|
+
this.cog = cog;
|
|
7
|
+
this.cogState = {
|
|
8
|
+
tilt: false,
|
|
9
|
+
movementType: false,
|
|
10
|
+
rotation: false,
|
|
11
|
+
buttonClick: false,
|
|
12
|
+
objectSense: false,
|
|
13
|
+
lightSense: false,
|
|
14
|
+
irMessage: false
|
|
15
|
+
};
|
|
16
|
+
this.pubSub = null;
|
|
17
|
+
this.subscribeToPublishedData();
|
|
18
|
+
}
|
|
19
|
+
PublishedDataAnalyser.prototype.subscribeToPublishedData = function () {
|
|
20
|
+
var _this = this;
|
|
21
|
+
this.pubSub = raftPubSubscriptionHelper(this.cog);
|
|
22
|
+
this.pubSub.subscribe(function (data) {
|
|
23
|
+
_this.analyse(data.stateInfo);
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
PublishedDataAnalyser.prototype.unsubscribeFromPublishedData = function () {
|
|
27
|
+
var _a;
|
|
28
|
+
(_a = this.pubSub) === null || _a === void 0 ? void 0 : _a.unsubscribe();
|
|
29
|
+
};
|
|
30
|
+
PublishedDataAnalyser.prototype.analyse = function (data) {
|
|
31
|
+
var isMoving = this.detectMovement(data);
|
|
32
|
+
this.detectTilt(data, isMoving);
|
|
33
|
+
this.detectRotation(data, isMoving);
|
|
34
|
+
this.detectButtonClick(data);
|
|
35
|
+
this.detectObjectSense(data);
|
|
36
|
+
this.detectLightSense(data);
|
|
37
|
+
this.detectIRMessage(data);
|
|
38
|
+
};
|
|
39
|
+
PublishedDataAnalyser.prototype.detectTilt = function (data, isMoving) {
|
|
40
|
+
tiltDetection.detectTilt(data, isMoving, this.cogState, this.cog.getRaftVersion());
|
|
41
|
+
};
|
|
42
|
+
PublishedDataAnalyser.prototype.detectMovement = function (data) {
|
|
43
|
+
return shakeDetector.detectShake(data.LSM6DS.ax, data.LSM6DS.ay, data.LSM6DS.az, Date.now(), this.cogState);
|
|
44
|
+
};
|
|
45
|
+
PublishedDataAnalyser.prototype.detectRotation = function (data, isMoving) {
|
|
46
|
+
rotationDetection.detectRotation(data, isMoving, this.cogState);
|
|
47
|
+
};
|
|
48
|
+
PublishedDataAnalyser.prototype.detectButtonClick = function (data) {
|
|
49
|
+
buttonClickDetection.detectButtonClick(data.Light.irVals[2], this.cogState, this.cog.getRaftVersion());
|
|
50
|
+
};
|
|
51
|
+
PublishedDataAnalyser.prototype.detectObjectSense = function (data) {
|
|
52
|
+
var objectSenseValueArray = data.Light.irVals;
|
|
53
|
+
objectSenseDetection.detectObjectSense(objectSenseValueArray, this.cogState);
|
|
54
|
+
};
|
|
55
|
+
PublishedDataAnalyser.prototype.detectLightSense = function (data) {
|
|
56
|
+
var lightSenseValue = data.Light.ambientVals[0];
|
|
57
|
+
lightSenseDetection.detectLightSense(lightSenseValue, this.cogState);
|
|
58
|
+
};
|
|
59
|
+
PublishedDataAnalyser.prototype.detectIRMessage = function (data) {
|
|
60
|
+
var irMessageData = data;
|
|
61
|
+
// irMessageDetection.detectIRMessage(data, this.cogState);
|
|
62
|
+
};
|
|
63
|
+
return PublishedDataAnalyser;
|
|
64
|
+
}());
|
|
65
|
+
var TiltDetection = /** @class */ (function () {
|
|
66
|
+
function TiltDetection() {
|
|
67
|
+
}
|
|
68
|
+
TiltDetection.prototype.distance = function (a, b) { return Math.sqrt((Math.pow(a, 2) + Math.pow(b, 2))); };
|
|
69
|
+
TiltDetection.rotateAccelData = function (x, y, z, degrees) {
|
|
70
|
+
// Convert degrees to radians
|
|
71
|
+
var radians = degrees * (Math.PI / 180);
|
|
72
|
+
// First rotate by 180 degrees about y axis
|
|
73
|
+
var rotatedX = 0 - x;
|
|
74
|
+
var rotatedY = y;
|
|
75
|
+
var rotatedZ = 0 - z;
|
|
76
|
+
var initialRotatedX = rotatedX;
|
|
77
|
+
// Calculate cosine and sine of the rotation angle
|
|
78
|
+
var cosTheta = Math.cos(radians);
|
|
79
|
+
var sinTheta = Math.sin(radians);
|
|
80
|
+
// Rotate around the z-axis
|
|
81
|
+
rotatedX = initialRotatedX * cosTheta - rotatedY * sinTheta;
|
|
82
|
+
rotatedY = initialRotatedX * sinTheta + rotatedY * cosTheta;
|
|
83
|
+
rotatedZ = rotatedZ; // z remains unchanged as the rotation is around the z-axis
|
|
84
|
+
return { x: rotatedX, y: rotatedY, z: rotatedZ };
|
|
85
|
+
};
|
|
86
|
+
TiltDetection.prototype.detectTilt = function (data, isMoving, cogState, cogVersion) {
|
|
87
|
+
if (isMoving === void 0) { isMoving = false; }
|
|
88
|
+
if (isMoving)
|
|
89
|
+
return;
|
|
90
|
+
var tiltCorrectionForOlderCog = 30;
|
|
91
|
+
var tiltCorrectionForNewerCog = -90;
|
|
92
|
+
var correctionCutOffVersion = "1.2.0";
|
|
93
|
+
var tiltCorrection = tiltCorrectionForOlderCog;
|
|
94
|
+
if (isVersionGreater_errorCatching(cogVersion, correctionCutOffVersion)) {
|
|
95
|
+
tiltCorrection = tiltCorrectionForNewerCog;
|
|
96
|
+
}
|
|
97
|
+
var _a = TiltDetection.rotateAccelData(data.LSM6DS.ax, data.LSM6DS.ay, data.LSM6DS.az, tiltCorrection), x = _a.x, y = _a.y, z = _a.z;
|
|
98
|
+
var pitch = Math.atan2(x, this.distance(y, z));
|
|
99
|
+
var roll = Math.atan2(y, this.distance(x, z));
|
|
100
|
+
var yaw = Math.atan2(z, this.distance(x, y));
|
|
101
|
+
// no tilt example values: pitch: 0.00, roll: 0.00, yaw: 1.50
|
|
102
|
+
// tilt left example values: pitch: 0.00, roll: -1.00, yaw: 0.50
|
|
103
|
+
// tilt right example values: pitch: 0.00, roll: 1.00, yaw: 0.50
|
|
104
|
+
// tilt forward example values: pitch: -1.00, roll: 0.00, yaw: 0.50
|
|
105
|
+
// tilt backward example values: pitch: 1.00, roll: 0.00, yaw: 0.50
|
|
106
|
+
var forwardBackwardThreshold = 20 * (Math.PI / 180); // threshold for forward and backward tilt
|
|
107
|
+
var leftRightThreshold = 20 * (Math.PI / 180); // threshold for left and right tilt
|
|
108
|
+
var upDownThreshold = 0.5; // threshold for up and down tilt
|
|
109
|
+
var tiltDirection = false;
|
|
110
|
+
if (pitch < -forwardBackwardThreshold) { // && Math.abs(yaw) < upDownThreshold) {
|
|
111
|
+
tiltDirection = "forward";
|
|
112
|
+
}
|
|
113
|
+
if (pitch > forwardBackwardThreshold) { // && Math.abs(yaw) < upDownThreshold) {
|
|
114
|
+
tiltDirection = "backward";
|
|
115
|
+
}
|
|
116
|
+
if (roll < -leftRightThreshold) { // && Math.abs(yaw) < upDownThreshold) {
|
|
117
|
+
tiltDirection = "left";
|
|
118
|
+
}
|
|
119
|
+
if (roll > leftRightThreshold) { // && Math.abs(yaw) < upDownThreshold) {
|
|
120
|
+
tiltDirection = "right";
|
|
121
|
+
}
|
|
122
|
+
cogState.tilt = tiltDirection;
|
|
123
|
+
};
|
|
124
|
+
return TiltDetection;
|
|
125
|
+
}());
|
|
126
|
+
var RotationDetection = /** @class */ (function () {
|
|
127
|
+
function RotationDetection() {
|
|
128
|
+
this.dataBuffer = [];
|
|
129
|
+
this.bufferSize = 20; // buffer size for rotation detection
|
|
130
|
+
this.DELAY_FOR_ROTATION = 500; // delay between rotation detection
|
|
131
|
+
this.ROTATION_THRESHOLD = 8; // threshold for rotation detection
|
|
132
|
+
this.rotationDetected = false;
|
|
133
|
+
this.lastRotationDetectionTime = 0;
|
|
134
|
+
this.rotationTimer = null;
|
|
135
|
+
}
|
|
136
|
+
RotationDetection.prototype.addToBuffer = function (data) {
|
|
137
|
+
this.dataBuffer.push(data);
|
|
138
|
+
if (this.dataBuffer.length > this.bufferSize) {
|
|
139
|
+
this.dataBuffer.shift();
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
RotationDetection.prototype.detectRotation = function (data, isMoving, cogState) {
|
|
143
|
+
if (isMoving === void 0) { isMoving = false; }
|
|
144
|
+
this.bufferSize = this.bufferSize;
|
|
145
|
+
this.DELAY_FOR_ROTATION = this.DELAY_FOR_ROTATION;
|
|
146
|
+
this.ROTATION_THRESHOLD = this.ROTATION_THRESHOLD;
|
|
147
|
+
var currentTime = Date.now();
|
|
148
|
+
this.addToBuffer(data.LSM6DS.gz);
|
|
149
|
+
if (this.dataBuffer.length < this.bufferSize) {
|
|
150
|
+
return; // Wait until buffer is full
|
|
151
|
+
}
|
|
152
|
+
if (currentTime - this.lastRotationDetectionTime < this.DELAY_FOR_ROTATION || isMoving) {
|
|
153
|
+
// Ensure there is a minimum time between detections
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
var metric = this.calculateMetric();
|
|
157
|
+
// Check if the magnitude of the rate of change is above the threshold
|
|
158
|
+
if (metric > this.ROTATION_THRESHOLD || metric < -this.ROTATION_THRESHOLD) {
|
|
159
|
+
this.lastRotationDetectionTime = currentTime;
|
|
160
|
+
this.dataBuffer = [];
|
|
161
|
+
if (metric > this.ROTATION_THRESHOLD) {
|
|
162
|
+
// console.log("Clockwise rotation detected:", metric);
|
|
163
|
+
cogState.rotation = "clockwise";
|
|
164
|
+
}
|
|
165
|
+
else if (metric < -this.ROTATION_THRESHOLD) {
|
|
166
|
+
// console.log("Counter-clockwise rotation detected:", metric);
|
|
167
|
+
cogState.rotation = "counter-clockwise";
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
cogState.rotation = false;
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
RotationDetection.prototype.calculateMetric = function () {
|
|
175
|
+
//let gzArray = [];
|
|
176
|
+
var sum = 0;
|
|
177
|
+
for (var i = 0; i < this.dataBuffer.length; i++) {
|
|
178
|
+
//sum += this.dataBuffer[i].LSM6DS.gz;
|
|
179
|
+
sum += this.dataBuffer[i];
|
|
180
|
+
//gzArray.push(this.dataBuffer[i]);
|
|
181
|
+
}
|
|
182
|
+
//console.log("gz buffer (" + gzArray.length + " elements avg. " + (sum / this.dataBuffer.length) + "): " + gzArray);
|
|
183
|
+
//console.log(this.dataBuffer);
|
|
184
|
+
return sum / this.dataBuffer.length;
|
|
185
|
+
};
|
|
186
|
+
return RotationDetection;
|
|
187
|
+
}());
|
|
188
|
+
var ShakeDetector = /** @class */ (function () {
|
|
189
|
+
function ShakeDetector() {
|
|
190
|
+
this.thresholdAccelerationMove = 0.3;
|
|
191
|
+
this.thresholdAcceleration = 1; // how much acceleration is needed to consider shaking
|
|
192
|
+
this.thresholdShakeNumber = 1; // how many shakes are needed
|
|
193
|
+
this.interval = 400; // how much time between shakes
|
|
194
|
+
this.maxShakeDuration = 1500; // Maximum duration between first and last shakes in a sequence
|
|
195
|
+
this.coolOffPeriod = 1500; // how much time to wait before detecting another shake
|
|
196
|
+
this.lastTime = 0;
|
|
197
|
+
this.lastTimeShakeDetected = 0;
|
|
198
|
+
this.sensorBundles = [];
|
|
199
|
+
this.gravityVector = [0, 0, 0];
|
|
200
|
+
this.lastVector = [0, 0, 0];
|
|
201
|
+
this.shakeInProgress = false;
|
|
202
|
+
this.moveInProgress = false;
|
|
203
|
+
}
|
|
204
|
+
ShakeDetector.prototype.detectShake = function (xAcc, yAcc, zAcc, timestamp, cogState) {
|
|
205
|
+
this.thresholdAcceleration = this.thresholdAcceleration;
|
|
206
|
+
this.thresholdAccelerationMove = this.thresholdAccelerationMove;
|
|
207
|
+
this.thresholdShakeNumber = this.thresholdShakeNumber;
|
|
208
|
+
this.interval = this.interval;
|
|
209
|
+
this.maxShakeDuration = this.maxShakeDuration;
|
|
210
|
+
this.coolOffPeriod = this.coolOffPeriod;
|
|
211
|
+
var magAcc = Math.sqrt(xAcc * xAcc + yAcc * yAcc + zAcc * zAcc);
|
|
212
|
+
if (magAcc > 0.9 && magAcc < 1.1) {
|
|
213
|
+
// device is stationary-ish, log direction of acc values to get a rough reading on where down is
|
|
214
|
+
this.gravityVector = [xAcc, yAcc, zAcc];
|
|
215
|
+
if (this.moveInProgress) {
|
|
216
|
+
// console.log("move detected");
|
|
217
|
+
cogState.movementType = "move";
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
// console.log("no move detected");
|
|
221
|
+
cogState.movementType = false;
|
|
222
|
+
}
|
|
223
|
+
this.moveInProgress = false;
|
|
224
|
+
this.shakeInProgress = false;
|
|
225
|
+
this.sensorBundles = [];
|
|
226
|
+
return this.moveInProgress;
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
//console.log("move in progrss. prev state: ", this.moveInProgress);
|
|
230
|
+
// potentially threshold this with thresholeAccelerationMove if we want it to be less trigger happy
|
|
231
|
+
this.moveInProgress = true;
|
|
232
|
+
// this assumes that the orientation of the device doesn't change during the movement, so it's not ideal
|
|
233
|
+
var x = xAcc - this.gravityVector[0];
|
|
234
|
+
var y = yAcc - this.gravityVector[1];
|
|
235
|
+
var z = zAcc - this.gravityVector[2];
|
|
236
|
+
var mag = Math.sqrt(x * x + y * y + z * z);
|
|
237
|
+
if (mag > this.thresholdAcceleration || this.shakeInProgress) {
|
|
238
|
+
this.shakeInProgress = true;
|
|
239
|
+
var diffThresh = this.thresholdAcceleration;
|
|
240
|
+
if (mag > this.thresholdAcceleration) {
|
|
241
|
+
// console.log('large magnitude movement ', x, y, z, this.gravityVector);
|
|
242
|
+
// check if the acc vector is significantly changed from the previous large value
|
|
243
|
+
if (!this.sensorBundles.length || Math.sqrt(Math.pow(this.lastVector[0] - x, 2) + Math.pow(this.lastVector[1] - y, 2) + Math.pow(this.lastVector[2] - z, 2)) > this.thresholdAcceleration) {
|
|
244
|
+
this.sensorBundles.push({ x: x, y: y, z: z, timestamp: timestamp });
|
|
245
|
+
//console.log(this.sensorBundles);
|
|
246
|
+
this.lastVector = [x, y, z];
|
|
247
|
+
// todo - call performCheck() to do a more detailed analysis of the readings? Might need some tweaks
|
|
248
|
+
if (this.sensorBundles.length > this.thresholdShakeNumber) {
|
|
249
|
+
// console.log("Shake detected!");
|
|
250
|
+
this.sensorBundles = [];
|
|
251
|
+
this.shakeInProgress = false;
|
|
252
|
+
cogState.movementType = "shake";
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
// this.noMoveCallback();
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
if (!this.sensorBundles.length || (timestamp - this.sensorBundles[this.sensorBundles.length - 1].timestamp) > this.interval) {
|
|
259
|
+
this.shakeInProgress = false;
|
|
260
|
+
this.sensorBundles = [];
|
|
261
|
+
// console.log("resetting shake detector. Move detected");
|
|
262
|
+
// fire move detector
|
|
263
|
+
cogState.movementType = "move";
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
return this.moveInProgress;
|
|
268
|
+
/*
|
|
269
|
+
if (this.sensorBundles.length === 0 || timestamp - this.lastTime > this.interval) {
|
|
270
|
+
// Check if we should reset based on time since last recorded shake
|
|
271
|
+
if (this.sensorBundles.length > 0 && (timestamp - this.sensorBundles[0].timestamp) > this.maxShakeDuration) {
|
|
272
|
+
this.sensorBundles = []; // Reset the sensor data if the shakes are too far apart
|
|
273
|
+
}
|
|
274
|
+
this.sensorBundles.push({ xAcc, yAcc, zAcc, timestamp });
|
|
275
|
+
this.lastTime = timestamp;
|
|
276
|
+
this.performCheck();
|
|
277
|
+
}
|
|
278
|
+
*/
|
|
279
|
+
}
|
|
280
|
+
};
|
|
281
|
+
ShakeDetector.prototype.performCheck = function (cogState) {
|
|
282
|
+
var _this = this;
|
|
283
|
+
var matrix = [
|
|
284
|
+
[0, 0],
|
|
285
|
+
[0, 0],
|
|
286
|
+
[0, 0] // Z axis positive and negative
|
|
287
|
+
];
|
|
288
|
+
for (var _i = 0, _a = this.sensorBundles; _i < _a.length; _i++) {
|
|
289
|
+
var bundle = _a[_i];
|
|
290
|
+
this.updateAxis(0, bundle.x, matrix);
|
|
291
|
+
this.updateAxis(1, bundle.y, matrix);
|
|
292
|
+
this.updateAxis(2, bundle.z, matrix, -1);
|
|
293
|
+
}
|
|
294
|
+
// check if any of the negatives and the positives are greater than the threshold
|
|
295
|
+
var negativesTotal = matrix.reduce(function (acc, axis) { return acc + axis[1]; }, 0);
|
|
296
|
+
var positivesTotal = matrix.reduce(function (acc, axis) { return acc + axis[0]; }, 0);
|
|
297
|
+
if (matrix.some(function (axis) { return axis[0] >= _this.thresholdShakeNumber && axis[1] >= _this.thresholdShakeNumber; })) {
|
|
298
|
+
// if (positivesTotal >= this.thresholdShakeNumber && negativesTotal >= this.thresholdShakeNumber) {
|
|
299
|
+
if (Date.now() - this.lastTimeShakeDetected < this.coolOffPeriod) {
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
this.lastTimeShakeDetected = Date.now();
|
|
303
|
+
// console.log("Shake detected!", JSON.stringify(matrix));
|
|
304
|
+
cogState.movementType = "shake";
|
|
305
|
+
this.sensorBundles = [];
|
|
306
|
+
}
|
|
307
|
+
};
|
|
308
|
+
ShakeDetector.prototype.updateAxis = function (index, acceleration, matrix, adjustment) {
|
|
309
|
+
if (adjustment === void 0) { adjustment = 0; }
|
|
310
|
+
var accelerationAdjusted = acceleration + adjustment;
|
|
311
|
+
if (accelerationAdjusted > this.thresholdAcceleration) {
|
|
312
|
+
matrix[index][0]++;
|
|
313
|
+
// console.log(JSON.stringify(matrix));
|
|
314
|
+
}
|
|
315
|
+
else if (accelerationAdjusted < -this.thresholdAcceleration) {
|
|
316
|
+
matrix[index][1]++;
|
|
317
|
+
// console.log(JSON.stringify(matrix));
|
|
318
|
+
}
|
|
319
|
+
};
|
|
320
|
+
return ShakeDetector;
|
|
321
|
+
}());
|
|
322
|
+
var ButtonClickDetection = /** @class */ (function () {
|
|
323
|
+
function ButtonClickDetection() {
|
|
324
|
+
/*
|
|
325
|
+
When the threshold is exceeded, the button is clicked, but we want to send the event when the button is released
|
|
326
|
+
so that the event is triggered only once.
|
|
327
|
+
*/
|
|
328
|
+
this.clickThreshold = 1600;
|
|
329
|
+
this.releaseThreshold = 1590;
|
|
330
|
+
this.lastTime = 0;
|
|
331
|
+
this.buttonClicked = false;
|
|
332
|
+
}
|
|
333
|
+
ButtonClickDetection.prototype.detectButtonClick = function (buttonValue, cogState, cogVersion) {
|
|
334
|
+
var correctionCutOffVersion = "1.2.0";
|
|
335
|
+
var clickThreshold = 1600;
|
|
336
|
+
if (isVersionGreater_errorCatching(cogVersion, correctionCutOffVersion)) {
|
|
337
|
+
clickThreshold = 1500;
|
|
338
|
+
}
|
|
339
|
+
var releaseThreshold = 1590;
|
|
340
|
+
if (isVersionGreater_errorCatching(cogVersion, correctionCutOffVersion)) {
|
|
341
|
+
releaseThreshold = 1490;
|
|
342
|
+
}
|
|
343
|
+
this.clickThreshold = clickThreshold;
|
|
344
|
+
this.releaseThreshold = releaseThreshold;
|
|
345
|
+
var currentTime = Date.now();
|
|
346
|
+
if (buttonValue > this.clickThreshold && !this.buttonClicked) {
|
|
347
|
+
// console.log("Button clicked", buttonValue);
|
|
348
|
+
this.buttonClicked = true;
|
|
349
|
+
this.lastTime = currentTime;
|
|
350
|
+
cogState.buttonClick = true;
|
|
351
|
+
}
|
|
352
|
+
else if (buttonValue < this.releaseThreshold && this.buttonClicked) {
|
|
353
|
+
// console.log("Button released", buttonValue);
|
|
354
|
+
this.buttonClicked = false;
|
|
355
|
+
cogState.buttonClick = false;
|
|
356
|
+
}
|
|
357
|
+
// } else {
|
|
358
|
+
// this.buttonClicked = false;
|
|
359
|
+
// this.buttonReleaseCallback();
|
|
360
|
+
// }
|
|
361
|
+
};
|
|
362
|
+
return ButtonClickDetection;
|
|
363
|
+
}());
|
|
364
|
+
var ObjectSenseDetection = /** @class */ (function () {
|
|
365
|
+
function ObjectSenseDetection() {
|
|
366
|
+
this.objectSensed0Threshold = 2500; // left of the arrow
|
|
367
|
+
this.objectSensed1Threshold = 2500; // right of the arrow
|
|
368
|
+
this.objectSensed2Threshold = 1500; // button
|
|
369
|
+
}
|
|
370
|
+
ObjectSenseDetection.prototype.detectObjectSense = function (objectSenseValue, cogState) {
|
|
371
|
+
if (objectSenseValue[0] > this.objectSensed0Threshold) {
|
|
372
|
+
cogState.objectSense = "left";
|
|
373
|
+
}
|
|
374
|
+
else if (objectSenseValue[1] > this.objectSensed1Threshold) {
|
|
375
|
+
cogState.objectSense = "right";
|
|
376
|
+
}
|
|
377
|
+
else {
|
|
378
|
+
cogState.objectSense = false;
|
|
379
|
+
}
|
|
380
|
+
};
|
|
381
|
+
return ObjectSenseDetection;
|
|
382
|
+
}());
|
|
383
|
+
var LightSenseDetection = /** @class */ (function () {
|
|
384
|
+
function LightSenseDetection() {
|
|
385
|
+
this.lightSenseThreshold = 450;
|
|
386
|
+
}
|
|
387
|
+
LightSenseDetection.prototype.detectLightSense = function (lightSenseValue, cogState) {
|
|
388
|
+
if (lightSenseValue > this.lightSenseThreshold) {
|
|
389
|
+
cogState.lightSense = true;
|
|
390
|
+
}
|
|
391
|
+
else {
|
|
392
|
+
cogState.lightSense = false;
|
|
393
|
+
}
|
|
394
|
+
};
|
|
395
|
+
return LightSenseDetection;
|
|
396
|
+
}());
|
|
397
|
+
var IRMessageDetection = /** @class */ (function () {
|
|
398
|
+
function IRMessageDetection() {
|
|
399
|
+
this.irMessage0Threshold = 0;
|
|
400
|
+
this.irMessage1Threshold = 0;
|
|
401
|
+
}
|
|
402
|
+
IRMessageDetection.prototype.detectIRMessage = function (irMessageValue, cogState) {
|
|
403
|
+
// placeholder for now
|
|
404
|
+
if (irMessageValue[0] > this.irMessage0Threshold) {
|
|
405
|
+
cogState.irMessage = "left";
|
|
406
|
+
}
|
|
407
|
+
else if (irMessageValue[1] > this.irMessage1Threshold) {
|
|
408
|
+
cogState.irMessage = "right";
|
|
409
|
+
}
|
|
410
|
+
else {
|
|
411
|
+
cogState.irMessage = false;
|
|
412
|
+
}
|
|
413
|
+
};
|
|
414
|
+
return IRMessageDetection;
|
|
415
|
+
}());
|
|
416
|
+
var rotationDetection = new RotationDetection();
|
|
417
|
+
var shakeDetector = new ShakeDetector();
|
|
418
|
+
var buttonClickDetection = new ButtonClickDetection();
|
|
419
|
+
var tiltDetection = new TiltDetection();
|
|
420
|
+
var objectSenseDetection = new ObjectSenseDetection();
|
|
421
|
+
var lightSenseDetection = new LightSenseDetection();
|
|
422
|
+
var irMessageDetection = new IRMessageDetection();
|
|
423
|
+
export default PublishedDataAnalyser;
|
|
@@ -38,7 +38,6 @@ import { AppSentMessage } from "../../types/communication-between-apps/wrapper-c
|
|
|
38
38
|
import { RaftTypeE } from "../../types/raft";
|
|
39
39
|
import { RaftInfoEvents } from "../../types/events/raft-info";
|
|
40
40
|
import { RaftPublishEvent, } from "@robdobsn/raftjs";
|
|
41
|
-
;
|
|
42
41
|
var RAFT = /** @class */ (function () {
|
|
43
42
|
function RAFT(id) {
|
|
44
43
|
this.id = id;
|
|
@@ -57,3 +57,7 @@ export declare const raftRejectedSubscriptionHelper: (raft: RAFT) => {
|
|
|
57
57
|
subscribe: (callback: any) => void;
|
|
58
58
|
unsubscribe: () => void;
|
|
59
59
|
};
|
|
60
|
+
export declare const raftPubSubscriptionHelper: (raft: RAFT) => {
|
|
61
|
+
subscribe: (callback: (eventData: any) => void) => void;
|
|
62
|
+
unsubscribe: () => void;
|
|
63
|
+
};
|
|
@@ -322,3 +322,34 @@ var raftRejectedSubscriptionObserver_ = function (callback) {
|
|
|
322
322
|
},
|
|
323
323
|
};
|
|
324
324
|
};
|
|
325
|
+
export var raftPubSubscriptionHelper = function (raft) {
|
|
326
|
+
var observer = null;
|
|
327
|
+
return {
|
|
328
|
+
subscribe: function (callback) {
|
|
329
|
+
observer = raftPubSubscriptionObserver_(callback);
|
|
330
|
+
raft.subscribe(observer, ["raftinfo"]);
|
|
331
|
+
},
|
|
332
|
+
unsubscribe: function () {
|
|
333
|
+
if (observer) {
|
|
334
|
+
raft.unsubscribe(observer);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
};
|
|
338
|
+
};
|
|
339
|
+
var raftPubSubscriptionObserver_ = function (callback) {
|
|
340
|
+
return {
|
|
341
|
+
notify: function (eventType, eventEnum, eventName, eventData) {
|
|
342
|
+
switch (eventType) {
|
|
343
|
+
case "raftinfo":
|
|
344
|
+
switch (eventEnum) {
|
|
345
|
+
case "STATE_INFO":
|
|
346
|
+
callback(eventData);
|
|
347
|
+
break;
|
|
348
|
+
default:
|
|
349
|
+
break;
|
|
350
|
+
}
|
|
351
|
+
break;
|
|
352
|
+
}
|
|
353
|
+
},
|
|
354
|
+
};
|
|
355
|
+
};
|