@robotical/webapp-types 1.0.1 → 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.
@@ -1,4 +1,4 @@
1
- import { RaftConnectionMethod } from "../../types/raft";
1
+ import { RaftConnectionMethod, RaftTypeE } from "../../types/raft";
2
2
  import WebAppCommunicator from "../../wrapper-app/communicators/WebAppCommunicator";
3
3
  import RAFT from "../RAFTs/RAFT";
4
4
  import Marty from "../RAFTs/Marty/Marty";
@@ -15,8 +15,11 @@ export default class ApplicationManager {
15
15
  connectedRafts: {
16
16
  [key: string]: RAFT;
17
17
  };
18
+ connectedRaftsContext: ConnectedRaftItem[];
18
19
  ricSelectedCb: ((raft: RAFT) => void) | null;
19
20
  toaster: typeof Toaster;
21
+ showBackHomeButton: () => void;
22
+ hideBackHomeButton: () => void;
20
23
  connectedRaftContextMethods: {
21
24
  addConnectedRaft: (connectedRaft: ConnectedRaftItem) => void;
22
25
  removeConnectedRaft: (connectedRaftId: string) => void;
@@ -90,4 +93,5 @@ export default class ApplicationManager {
90
93
  * List the files from the device's local storage
91
94
  */
92
95
  listFilesFromDeviceLocalStorage(dirname: string): Promise<unknown>;
96
+ getTheCurrentlySelectedDeviceOrFirstOfItsKind(deviceType: RaftTypeE): RAFT | undefined;
93
97
  }
@@ -58,6 +58,7 @@ var ApplicationManager = /** @class */ (function () {
58
58
  this._observers = {};
59
59
  // Connected RICs
60
60
  this.connectedRafts = {};
61
+ this.connectedRaftsContext = [];
61
62
  // Callback to call when a RAFT is selected (Phone App only)
62
63
  // We need that to make sure the connection button gets the selected RAFT once the user selects one
63
64
  this.ricSelectedCb = null;
@@ -74,6 +75,8 @@ var ApplicationManager = /** @class */ (function () {
74
75
  // public sessionDbs = new SessionsDBManager();
75
76
  // toaster
76
77
  this.toaster = Toaster;
78
+ this.showBackHomeButton = function () { };
79
+ this.hideBackHomeButton = function () { };
77
80
  // connected raft context methods
78
81
  this.connectedRaftContextMethods = {
79
82
  addConnectedRaft: function (connectedRaft) { },
@@ -458,6 +461,40 @@ var ApplicationManager = /** @class */ (function () {
458
461
  });
459
462
  });
460
463
  };
464
+ /*======== END OF NATIVE COMMANDS ONLY ========*/
465
+ //======================//
466
+ /* UI */
467
+ //======================//
468
+ //======================//
469
+ /* HELPERS */
470
+ //======================//
471
+ ApplicationManager.prototype.getTheCurrentlySelectedDeviceOrFirstOfItsKind = function (deviceType) {
472
+ var _a;
473
+ // checks if the currently selected device is a deviceType and returns it
474
+ // if not, returns the first deviceType in the list (if there is one)
475
+ var currentlySelectedId = (_a = this.connectedRaftsContext.find(function (connectedRaft) { return connectedRaft.isSelected; })) === null || _a === void 0 ? void 0 : _a.id;
476
+ if (currentlySelectedId) {
477
+ var selectedRaft = this.connectedRafts[currentlySelectedId];
478
+ if (!selectedRaft) {
479
+ return;
480
+ }
481
+ if (selectedRaft.type === deviceType) {
482
+ // the currently selected device is a cog, return it
483
+ return selectedRaft;
484
+ }
485
+ else {
486
+ // the currently selected device is not a cog, find the first cog in the list
487
+ var fistCog = void 0;
488
+ for (var raftId in this.connectedRafts) {
489
+ if (this.connectedRafts[raftId].type === deviceType) {
490
+ fistCog = this.connectedRafts[raftId];
491
+ break;
492
+ }
493
+ }
494
+ return fistCog;
495
+ }
496
+ }
497
+ };
461
498
  // Communicator to the wrapper app
462
499
  ApplicationManager.wrapperAppCommunicator = new WebAppCommunicator();
463
500
  return ApplicationManager;
@@ -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", {
@@ -90,7 +92,7 @@ var Cog = /** @class */ (function (_super) {
90
92
  */
91
93
  Cog.prototype.getBatteryStrength = function () {
92
94
  var _a;
93
- return ((_a = this.raftStateInfo) === null || _a === void 0 ? void 0 : _a.Power.battV) || 0;
95
+ return ((_a = this.raftStateInfo) === null || _a === void 0 ? void 0 : _a.Power.battV) ? Math.round(this.raftStateInfo.Power.battV * 100) : 0;
94
96
  };
95
97
  /**
96
98
  * This methods handles RAFT events coming from the RICConnector of the wrapper
@@ -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
  */
@@ -131,7 +153,7 @@ var Cog = /** @class */ (function (_super) {
131
153
  return __awaiter(this, void 0, void 0, function () {
132
154
  return __generator(this, function (_a) {
133
155
  switch (_a.label) {
134
- case 0: return [4 /*yield*/, this.sendRestMessage('led//color/#ff8585')];
156
+ case 0: return [4 /*yield*/, this.sendRestMessage('led/ring/color/#ff8585')];
135
157
  case 1:
136
158
  _a.sent();
137
159
  return [4 /*yield*/, this.sendRestMessage('audio/rtttl/NoteASharp:d=4,o=6,b=600:a#')];
@@ -140,7 +162,7 @@ var Cog = /** @class */ (function (_super) {
140
162
  return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 100); })];
141
163
  case 3:
142
164
  _a.sent();
143
- return [4 /*yield*/, this.sendRestMessage('led//color/#000000')];
165
+ return [4 /*yield*/, this.sendRestMessage('led/ring/color/#000000')];
144
166
  case 4:
145
167
  _a.sent();
146
168
  return [2 /*return*/];
@@ -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
+ };
@@ -49,6 +49,9 @@ export var ConnectedRaftContentProvider = function (_a) {
49
49
  };
50
50
  }
51
51
  }, []);
52
+ useEffect(function () {
53
+ window.applicationManager.connectedRaftsContext = connectedRafts;
54
+ }, [connectedRafts]);
52
55
  var addConnectedRaft = function (connectedRaft) {
53
56
  // if the new raft is already in the list, do not add it again, just select it
54
57
  var existingRaft = connectedRafts.find(function (connectedRaft_) { return connectedRaft_.id === connectedRaft.id; });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@robotical/webapp-types",
3
- "version": "1.0.1",
3
+ "version": "1.0.6",
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",