@robotical/webapp-types 1.0.5 → 1.0.7

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