tpmkms_4wp 9.5.1 → 9.6.0-beta.1

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.
Files changed (135) hide show
  1. package/common/animals.instance.json +151 -61
  2. package/common/animals.js +3 -5
  3. package/common/asking.js +116 -106
  4. package/common/avatar.test.json +1001 -860
  5. package/common/can.instance.json +2194 -0
  6. package/common/can.js +251 -0
  7. package/common/can.test.json +51307 -0
  8. package/common/characters.js +5 -5
  9. package/common/colors.instance.json +152 -12
  10. package/common/colors.js +3 -6
  11. package/common/comparable.instance.json +33 -3
  12. package/common/comparable.js +3 -6
  13. package/common/concept.js +25 -27
  14. package/common/concept.test.json +180 -144
  15. package/common/conjunction.js +13 -5
  16. package/common/conjunction.test.json +32 -42
  17. package/common/crew.instance.json +433 -173
  18. package/common/crew.js +4 -7
  19. package/common/crew.test.json +4148 -3324
  20. package/common/currency.js +1 -1
  21. package/common/dateTimeSelectors.instance.json +2 -2
  22. package/common/dateTimeSelectors.js +6 -9
  23. package/common/dateTimeSelectors.test.json +76935 -35739
  24. package/common/dates.instance.json +53 -3
  25. package/common/dates.js +3 -6
  26. package/common/dates.test.json +284 -287
  27. package/common/dialogues.js +43 -122
  28. package/common/dialogues.test.json +1248 -1152
  29. package/common/dimension.instance.json +21493 -561
  30. package/common/dimension.js +150 -55
  31. package/common/dimension.test.json +10979 -4625
  32. package/common/drone.instance.json +24709 -0
  33. package/common/drone.js +662 -0
  34. package/common/drone.test.json +30522 -0
  35. package/common/drone_v1.instance.json +24703 -0
  36. package/common/drone_v1.js +596 -0
  37. package/common/drone_v1.test.json +115538 -0
  38. package/common/edible.instance.json +388 -32
  39. package/common/edible.js +3 -5
  40. package/common/emotions.instance.json +85 -76
  41. package/common/emotions.js +4 -7
  42. package/common/emotions.test.json +242 -174
  43. package/common/english_helpers.js +336 -0
  44. package/common/errors.js +6 -6
  45. package/common/evaluate.js +2 -2
  46. package/common/events.js +8 -8
  47. package/common/fastfood.instance.json +1071 -393
  48. package/common/fastfood.js +14 -16
  49. package/common/fastfood.test.json +6970 -6829
  50. package/common/formulas.instance.json +11 -1
  51. package/common/formulas.js +3 -2
  52. package/common/gdefaults.js +111 -17
  53. package/common/help.js +12 -12
  54. package/common/help.test.json +65 -11
  55. package/common/helpers/concept.js +1 -1
  56. package/common/helpers/conjunction.js +54 -44
  57. package/common/helpers/dateTimeSelectors.js +2 -2
  58. package/common/helpers/dialogues.js +10 -2
  59. package/common/helpers/formulas.js +13 -11
  60. package/common/helpers/menus.js +12 -12
  61. package/common/helpers/meta.js +9 -9
  62. package/common/helpers/properties.js +186 -64
  63. package/common/helpers.js +167 -48
  64. package/common/hierarchy.js +12 -10
  65. package/common/kirk.instance.json +11 -1
  66. package/common/kirk.js +4 -6
  67. package/common/kirk.test.json +600 -424
  68. package/common/latin.instance.json +12 -12
  69. package/common/latin.js +12 -14
  70. package/common/length.instance.json +34660 -3158
  71. package/common/length.js +11 -6
  72. package/common/length.test.json +54357 -2557
  73. package/common/math.instance.json +39 -29
  74. package/common/math.js +49 -47
  75. package/common/menus.instance.json +77 -10
  76. package/common/menus.js +4 -13
  77. package/common/meta.js +80 -65
  78. package/common/nameable.js +36 -22
  79. package/common/nameable.test.json +436 -0
  80. package/common/numbers.js +1 -1
  81. package/common/ordering.instance.json +107 -19
  82. package/common/ordering.js +4 -6
  83. package/common/ordering.test.json +835 -417
  84. package/common/people.instance.json +176 -348
  85. package/common/people.js +9 -9
  86. package/common/people.test.json +4135 -3606
  87. package/common/pipboy.instance.json +187 -17
  88. package/common/pipboy.js +4 -4
  89. package/common/pokemon.instance.json +143 -13
  90. package/common/pokemon.js +4 -6
  91. package/common/pressure.instance.json +3610 -1601
  92. package/common/pressure.js +3 -5
  93. package/common/pressure.test.json +433 -477
  94. package/common/properties.instance.json +16 -17
  95. package/common/properties.js +32 -13
  96. package/common/properties.test.json +9565 -6951
  97. package/common/rates.instance.json +59 -0
  98. package/common/rates.js +95 -0
  99. package/common/rates.test.json +27702 -0
  100. package/common/reminders.instance.json +4 -4
  101. package/common/reminders.js +8 -11
  102. package/common/reminders.test.json +64635 -25787
  103. package/common/reports.instance.json +23 -3
  104. package/common/reports.js +21 -21
  105. package/common/scorekeeper.js +9 -12
  106. package/common/sdefaults.js +22 -2
  107. package/common/spock.instance.json +11 -1
  108. package/common/spock.js +4 -7
  109. package/common/spock.test.json +606 -430
  110. package/common/stgame.js +1 -1
  111. package/common/stm.js +41 -24
  112. package/common/tell.js +1 -1
  113. package/common/temperature.instance.json +3163 -1154
  114. package/common/temperature.js +3 -5
  115. package/common/temperature.test.json +433 -477
  116. package/common/tester.js +3 -3
  117. package/common/time.instance.json +24852 -0
  118. package/common/time.js +138 -141
  119. package/common/time.test.json +31876 -3757
  120. package/common/tokenize.js +5 -2
  121. package/common/ui.instance.json +12 -5
  122. package/common/ui.js +4 -13
  123. package/common/weight.instance.json +10501 -4099
  124. package/common/weight.js +3 -5
  125. package/common/weight.test.json +2601 -2263
  126. package/common/words.instance.json +9 -0
  127. package/common/words.js +50 -0
  128. package/common/words.test.json +2 -0
  129. package/common/wp.instance.json +548 -8
  130. package/common/wp.js +10 -8
  131. package/common/wp.test.json +7385 -6906
  132. package/main.js +6 -2
  133. package/package.json +25 -6
  134. package/common/listener.js +0 -50
  135. package/common/listener.test.json +0 -142
@@ -0,0 +1,596 @@
1
+ const { knowledgeModule, where } = require('./runtime').theprogrammablemind
2
+ const { defaultContextCheck, getValue, setValue } = require('./helpers')
3
+ const droneV1_tests = require('./drone_v1.test.json')
4
+ const instance = require('./drone_v1.instance.json')
5
+ const hierarchy = require('./hierarchy')
6
+ const ordinals = require('./ordinals')
7
+ const nameable = require('./nameable')
8
+ const rates = require('./rates')
9
+ const help = require('./help')
10
+ const { degreesToRadians, radiansToDegrees, cartesianToPolar } = require('./helpers/drone')
11
+
12
+ /*
13
+ todo
14
+
15
+ VOSK
16
+
17
+ https://alphacephei.com/vosk/
18
+
19
+ FreeNode Tank
20
+
21
+ https://docs.freenove.com/projects/fnk0077/en/latest/fnk0077/codes/tutorial/3_Module_test_%28necessary%29.html
22
+ https://www.amazon.ca/Freenove-Raspberry-Tracking-Avoidance-Ultrasonic/dp/B0BNDQFRP1/ref=sr_1_1_sspa?crid=1JT788RT84O8C&dib=eyJ2IjoiMSJ9.1W6XTWnHwPcqZTD8iRfmF7hHwiVycHjB02NHKEcqGfQSUKyJfN0OLyaaoCcypQug_C9CGah-7wLgfAtJRs_JKiwDsqYXqFfvvoU5ETBk_Le-S9Qt4kwh92r0w19bzA5my7aQpT52ssw8-f8Xpzjbqm1uFsLh82jF4V7P8xMKobjVHHILXalReEPuJz2OlF6y_ihwtUuVLDjMkuvNPoK-M7YLntLqKQy229XKjtDSUV4J0YT1L8uLVWHZ-ySs_MmG_w-oyZ9QFIe0a9hJEMuiu_BcaDmxFkwMeGBro2uczAU.NlqF_FH_6PvflZKozPylFlIyKuwx7mAB-jAggC1aPFk&dib_tag=se&keywords=Freenove+Tank+Robot+Kit&qid=1766258114&sprefix=freenove+drone+robot+kit%2Caps%2C130&sr=8-1-spons&sp_csd=d2lkZ2V0TmFtZT1zcF9hdGY&psc=1
23
+
24
+
25
+ send commands to arduino from another computer:
26
+
27
+ https://www.npmjs.com/package/johnny-five
28
+
29
+ KEYESTUDIO Mini Tank Robot V2 Smart Car Kit for Arduino
30
+
31
+ https://www.amazon.ca/KEYESTUDIO-Infrared-Ultrasonic-Obstacle-Avoidance/dp/B07X4W7SZ5/ref=sr_1_10?crid=2A71NHZNTAION&dib=eyJ2IjoiMSJ9.W-I4I_tfyGdGt2UrNlNrlFeKnfIwppniNSX5FJndx77Ht944f9RylJD9me0PiqV5V_b185b17BsrPdKxmYYHnJ-Odb7hbdVzKs019mag1nCL-Wqe4aR0IYrEOzJkKTnR4YbXGYwriLd26OBYjhNvgaCFyE5uwsYkAK-qJXI2Xiui19oLiLYrmJvBz0bCHe4s7U6OdmaumYhhfxpVErk1E1zAwxE8kdq_YD7ZCMRjKS9Tr6cbayIh9GKDwMLuW-LCdzOW2eQx-dTB7yXV53rpV34IBAcCE1IgmwwNIIW7E6Y.fdaAuj4qvXq-67f5ktOq7Coo8lggrMiB_TFFtluqDtI&dib_tag=se&keywords=Adafruit+Mini+Round+Robot+Chassis+Kit&qid=1766256581&sprefix=adafruit+mini+round+robot+chassis+kit+%2Caps%2C123&sr=8-10
32
+ https://github.com/ericmend/mini-drone/blob/master/README.md
33
+
34
+
35
+
36
+
37
+ vosk
38
+
39
+ https://github.com/sunfounder/picar-x/tree/v2.0/gpt_examples
40
+ https://github.com/sunfounder/picar-x/tree/v2.0/example
41
+ VOSK: https://docs.sunfounder.com/projects/picar-x-v20/en/latest/ai_interaction/python_voice_control.html
42
+
43
+ DONE why is 3 meters not marker: length its marker dimension
44
+ DONE how to handle time in the testing
45
+ repeat that/what/say again/say that again
46
+ make it say the howToCalibrate right from the start. maybe have some prime it call?!?!?!
47
+ convert from length to a some kind of standard number
48
+ shut up/dont talk/be quiet -> stop saying responses
49
+
50
+ use it to measure distances -> go forward. stop. how far was that
51
+
52
+ call this point a
53
+ move 5 feet
54
+ call this point b
55
+ moving between a and b is called patrol 1
56
+ do patrol 1 every 3 minutes
57
+
58
+ what is patrol 1
59
+
60
+ calibrate distance
61
+ stop
62
+
63
+ go forward slowly
64
+ stop
65
+ that was 2 feet
66
+
67
+ do a circle 2 feet in diameter every 2 minutes
68
+
69
+ this is jeff
70
+ say hi
71
+
72
+
73
+ say your names
74
+ car 1 do patrol one
75
+ car 1 and 2 go to point a
76
+
77
+ who car 1
78
+
79
+ just say the speed
80
+
81
+ go forward 2 meters
82
+
83
+ pan camera left slowly
84
+ do the cylon every 30 seconds
85
+
86
+ patrol one is forward 10 feet left 2 feet right 3 feet and back to the start
87
+ go forward 10 feet then go back to the start
88
+
89
+ go to the last point
90
+ go back 2 positions
91
+
92
+ call the first point start
93
+ call the second point fred
94
+ call the last point june
95
+ call the next point albert
96
+
97
+ pause for 4 seconds
98
+ */
99
+
100
+ /*
101
+ ^
102
+ y
103
+ |
104
+ 90
105
+ |
106
+ -180/180 <--^--> 0 -- x ->
107
+ |
108
+ -90
109
+ */
110
+ class API {
111
+ initialize({ objects }) {
112
+ this._objects = objects
113
+ this._objects.defaultTime = { hour: 9, minute: 0, second: 0, millisecond: 0 }
114
+ this._objects.ordinal = 0
115
+ delete this.testDate
116
+
117
+ objects.calibration = {
118
+ startTime: undefined, // start time for calibration
119
+ endTime: undefined, // end time for calibration
120
+ duration: undefined, // end time - start time
121
+ distance: undefined, // distance travelled during calibration in mm
122
+ power: 0.1,
123
+ speed: undefined, // meters per second
124
+ }
125
+ objects.current = {
126
+ power: 0.1,
127
+ angleInDegrees: 0 //easier to debug
128
+ // direction: undefined, // direction to go if going
129
+ // power: undefined, // power
130
+ // ordinal // ordinal of the current point or the current point that the recent movement started at
131
+ }
132
+ objects.history = []
133
+ objects.isCalibrated = false
134
+ }
135
+
136
+ isCalibrated() {
137
+ return this._objects.isCalibrated
138
+ }
139
+
140
+ nextOrdinal() {
141
+ return this._objects.ordinal += 1
142
+ }
143
+
144
+ currentPoint() {
145
+ if (!this._objects.current.endTime) {
146
+ return null // in motion
147
+ }
148
+ const ordinal = this._objects.current.ordinal
149
+ const lastPoint = this.args.mentions({ context: { marker: 'point' }, condition: (context) => context.ordinal == ordinal })
150
+
151
+ const durationInSeconds = (this._objects.current.endTime - this._objects.current.startTime) / 1000
152
+ const speedInMetersPerSecond = (this._objects.current.power / this._objects.calibration.power) * this._objects.calibration.speed
153
+ const direction = this._objects.current.direction
154
+ const distanceInMeters = speedInMetersPerSecond * durationInSeconds * (direction == 'forward' ? 1 : -1)
155
+ const angleInRadians = degreesToRadians(this._objects.current.angleInDegrees)
156
+
157
+ const yPrime = lastPoint.point.y + distanceInMeters * Math.sin(angleInRadians)
158
+ const xPrime = lastPoint.point.x + distanceInMeters * Math.cos(angleInRadians)
159
+ return { x: xPrime, y: yPrime }
160
+ }
161
+
162
+ markCurrentPoint() {
163
+ const ordinal = this.nextOrdinal()
164
+ const point = this.currentPoint()
165
+ this.args.mentioned({ marker: 'point', ordinal, point })
166
+ this._objects.current.ordinal = ordinal
167
+ this._objects.current.endTime = null
168
+ this._objects.current.startTime = null
169
+ }
170
+
171
+ now() {
172
+ if (this.args.isProcess || this.args.isTest) {
173
+ if (!this.testDate) {
174
+ this.testDate = new Date(2025, 5, 29, 14, 52, 0)
175
+ }
176
+ this.testDate = new Date(this.testDate.getTime() + 1000)
177
+ return this.testDate
178
+ } else {
179
+ return new Date()
180
+ }
181
+ }
182
+
183
+ // this is for testing
184
+ pause(duration_in_seconds) {
185
+ this._objects.history.push({ marker: 'history', pause: duration_in_seconds })
186
+ this.testDate = new Date(this.testDate.getTime() + (duration_in_seconds-1)*1000)
187
+ }
188
+
189
+ sendCommand() {
190
+ const stopAtDistance = (distanceMeters) => {
191
+ const speed_meters_per_second = this._objects.calibration.speed
192
+ const duration_seconds = distanceMeters / speed_meters_per_second
193
+ this.pause(duration_seconds)
194
+ this.stop()
195
+ this.markCurrentPoint()
196
+ }
197
+
198
+ if (this._objects.current.destination) {
199
+ const currentPoint = this.args.mentions({ context: { marker: 'point' } })
200
+ const polar = cartesianToPolar(currentPoint.point, this._objects.current.destination.point)
201
+ const destinationAngleInDegrees = radiansToDegrees(polar.angle)
202
+ let angleDelta = destinationAngleInDegrees - this._objects.current.angleInDegrees
203
+ if (angleDelta > 180) {
204
+ angleDelta -= 360
205
+ } else if (angleDelta < -180) {
206
+ angleDelta += 360
207
+ }
208
+ this.rotate(angleDelta)
209
+ this.forward(this._objects.current.power)
210
+ stopAtDistance(polar.radius)
211
+ return
212
+ }
213
+
214
+ const command = { power: this._objects.current.power, ...this._objects.current }
215
+ switch (command.direction) {
216
+ case 'forward':
217
+ this.forward(command.power)
218
+ break
219
+ case 'backward':
220
+ this.backward(command.power)
221
+ break
222
+ case 'right':
223
+ this.rotate(-90)
224
+ break
225
+ case 'left':
226
+ this.rotate(90)
227
+ break
228
+ case 'around':
229
+ this.rotate(180)
230
+ break
231
+ }
232
+
233
+ if (command.distance) {
234
+ const distanceMeters = command.distance
235
+ stopAtDistance(distanceMeters)
236
+ }
237
+ }
238
+
239
+ forward(power) {
240
+ const time = this.forwardDrone(power)
241
+ this._objects.current.startTime = time
242
+ this._objects.current.endTime = null
243
+ return time
244
+ }
245
+
246
+ backward(power) {
247
+ const time = this.backwardDrone(power)
248
+ this._objects.current.startTime = time
249
+ this._objects.current.endTime = null
250
+ return time
251
+ }
252
+
253
+ // TODO allow saying turn while its moving and make that one moves so you can go back wiggly?
254
+ rotate(angleInDegrees) {
255
+ this.rotateDrone(angleInDegrees)
256
+ this._objects.current.angleInDegrees = (this._objects.current.angleInDegrees + angleInDegrees) % 360
257
+ }
258
+
259
+ tiltAngle(angle) {
260
+ tiltAngleDrone(angle)
261
+ }
262
+
263
+ panAngle(angle) {
264
+ panAngleDrone(angle)
265
+ }
266
+
267
+ stop() {
268
+ const time = this.stopDrone()
269
+ this._objects.current.endTime = time
270
+ return time
271
+ }
272
+
273
+ // subclass and override the remaining to call the drone
274
+
275
+ forwardDrone(power) {
276
+ const time = this.now()
277
+ this._objects.history.push({ marker: 'history', direction: 'forward', power, time })
278
+ return time
279
+ }
280
+
281
+ backwardDrone(power) {
282
+ const time = this.now()
283
+ this._objects.history.push({ marker: 'history', direction: 'backward', power, time })
284
+ return time
285
+ }
286
+
287
+ // -angle is counterclockwise
288
+ // +angle is clockwise
289
+
290
+ rotateDrone(angle) {
291
+ this._objects.history.push({ marker: 'history', turn: angle })
292
+ }
293
+
294
+ tiltAngleDrone(angle) {
295
+ }
296
+
297
+ panAngleDrone(angle) {
298
+ }
299
+
300
+ stopDrone() {
301
+ const time = this.now()
302
+ this._objects.history.push({ marker: 'history', power: 0, time })
303
+ return time
304
+ }
305
+ }
306
+
307
+ const howToCalibrate = "When you are ready say calibrate. The drone will drive forward at 10 percent power then say stop. Measure the distance and tell me that. Or you can say the speed of the drone at percentage of power."
308
+
309
+ function askForProperty({
310
+ ask,
311
+ propertyPath,
312
+ contextPath=[],
313
+ query,
314
+ matchr,
315
+ oneShot=false,
316
+ }) {
317
+ ask({
318
+ where: where(),
319
+ oneShot,
320
+
321
+ matchq: ({ api, context, objects }) => !getValue(propertyPath, objects) && context.marker == 'controlEnd',
322
+ applyq: async ({ say, objects }) => {
323
+ return query
324
+ },
325
+
326
+ matchr,
327
+ applyr: async ({objects, context}) => {
328
+ setValue(propertyPath, objects, getValue(contextPath, context))
329
+ },
330
+ })
331
+ }
332
+
333
+ function askForCalibrationDistance(args) {
334
+ askForProperty({
335
+ ...args,
336
+ propertyPath: ['calibration', 'distance'],
337
+ query: "How far did the drone go?",
338
+ matchr: ({context, objects}) => objects.calibration.endTime && context.marker == 'quantity' && context.unit.dimension == 'length',
339
+ })
340
+ }
341
+
342
+ function askForEndTime(args) {
343
+ askForProperty({
344
+ ...args,
345
+ propertyPath: ['calibration', 'endTime'],
346
+ query: "Say stop when the drone has driven enough.",
347
+ matchr: () => false,
348
+ })
349
+ }
350
+
351
+ function askForStartTime(args) {
352
+ askForProperty({
353
+ ...args,
354
+ propertyPath: ['calibration', 'startTime'],
355
+ query: howToCalibrate,
356
+ matchr: () => false,
357
+ })
358
+ }
359
+
360
+ // expectProperty
361
+ function expectDirection(args) {
362
+ args.config.addSemantic({
363
+ match: ({context, isA}) => isA(context.marker, 'direction'),
364
+ apply: ({objects, context}) => {
365
+ objects.runCommand = true
366
+ objects.current.direction = context.marker
367
+ }
368
+ })
369
+ }
370
+
371
+ // expectProperty
372
+ function expectDistanceForCalibration(args) {
373
+ args.config.addSemantic({
374
+ oneShot: true,
375
+ match: ({context, isA, objects}) => isA(context.marker, 'quantity') && !isA(context.unit.marker, 'unitPerUnit') && objects.calibration.startTime,
376
+ apply: async ({context, objects, fragments, e}) => {
377
+ const instantiation = await fragments("quantity in meters", { quantity: context })
378
+ const result = await e(instantiation)
379
+ objects.calibration.distance = result.evalue.amount.evalue.evalue
380
+ }
381
+ })
382
+ }
383
+
384
+ function expectDistanceForMove(args) {
385
+ // TODO save id for recalibration
386
+ args.config.addSemantic({
387
+ match: ({context, isA}) => isA(context.marker, 'quantity') && !isA(context.unit.marker, 'unitPerUnit'),
388
+ apply: async ({context, objects, fragments, e}) => {
389
+ const instantiation = await fragments("quantity in meters", { quantity: context })
390
+ const result = await e(instantiation)
391
+ objects.runCommand = true
392
+ objects.current.distance = result.evalue.amount.evalue.evalue
393
+ }
394
+ })
395
+ }
396
+
397
+ function expectCalibrationCompletion(args) {
398
+ args.config.addSemantic({
399
+ oneShot: true,
400
+ match: ({context, objects, isA}) => context.marker == 'controlEnd' && objects.calibration.distance && objects.calibration.duration && !objects.calibration.speed,
401
+ apply: ({api, context, objects, _continue, say, mentioned}) => {
402
+ objects.calibration.speed = objects.calibration.distance / objects.calibration.duration
403
+ objects.isCalibrated = true
404
+ say(`The drone is calibrated. The speed is ${objects.calibration.speed.toFixed(4)} meters per second at 10 percent power`)
405
+ const ordinal = api.nextOrdinal()
406
+ mentioned({ marker: 'point', ordinal, point: { x: objects.calibration.distance, y: 0 }, distance: objects.calibration.distance, description: "calibration stop" })
407
+ objects.current.ordinal = ordinal
408
+ _continue()
409
+ expectDistanceForMove(args)
410
+ }
411
+ })
412
+ }
413
+
414
+ const template = {
415
+ fragments: [
416
+ "quantity in meters",
417
+ "quantity in meters per second",
418
+ ],
419
+ configs: [
420
+ "drone is a concept",
421
+ //TODO "forward left, right, backward are directions",
422
+ "around, forward, left, right, and backward are directions",
423
+ "speed and power are properties",
424
+ "point is a concept",
425
+ // TODO fix/add this "position means point",
426
+ "points are nameable orderable and memorable",
427
+ (args) => {
428
+ askForCalibrationDistance(args)
429
+ askForEndTime(args)
430
+ askForStartTime(args)
431
+
432
+ expectDirection(args)
433
+ expectDistanceForCalibration(args)
434
+ expectCalibrationCompletion(args)
435
+
436
+ args.config.addSemantic({
437
+ match: ({context, isA}) => isA(context.marker, 'quantity') && isA(context.unit.marker, 'unitPerUnit'),
438
+ apply: async ({context, objects, api, fragments, e}) => {
439
+ // send a command to the drone
440
+ const instantiation = await fragments("quantity in meters per second", { quantity: context })
441
+ const result = await e(instantiation)
442
+ const desired_speed = result.evalue.amount.evalue.evalue
443
+ const desired_power = objects.current.power * (desired_speed / objects.calibration.speed)
444
+ objects.runCommand = true
445
+ objects.current.power = desired_power
446
+ }
447
+ })
448
+
449
+ args.config.addSemantic({
450
+ match: ({context, objects, isA}) => objects.current.direction && objects.isCalibrated && context.marker == 'controlStart',
451
+ apply: ({context, objects, api}) => {
452
+ objects.runCommand = false
453
+ }
454
+ })
455
+
456
+ args.config.addSemantic({
457
+ // match: ({context, objects, isA}) => objects.current.direction && objects.isCalibrated && (context.marker == 'controlEnd' || context.marker == 'controlBetween'),
458
+ match: ({context, objects, isA}) => objects.current.direction && objects.isCalibrated && context.marker == 'controlEnd',
459
+ apply: ({context, objects, api}) => {
460
+ // send a command to the drone
461
+ if (objects.runCommand) {
462
+ // debugger
463
+ api.sendCommand()
464
+ }
465
+ }
466
+ })
467
+ },
468
+ {
469
+ operators: [
470
+ "([calibrate])",
471
+ "([turn] (direction))",
472
+ "([pause] ([number]))",
473
+ "([stop] ([drone|])?)",
474
+ "([go])",
475
+ "([toPoint|to] (point))",
476
+ ],
477
+ bridges: [
478
+ {
479
+ id: "toPoint",
480
+ isA: ['preposition'],
481
+ bridge: "{ ...next(operator), operator: operator, point: after[0], interpolate: [{ property: 'operator' }, { property: 'point' }] }",
482
+ semantic: async ({objects, api, e, context}) => {
483
+ if (api.isCalibrated()) {
484
+ objects.runCommand = true
485
+ const point = await e(context.point)
486
+ objects.current.destination = point.evalue
487
+ }
488
+ }
489
+ },
490
+ { id: "go" },
491
+ {
492
+ id: 'turn',
493
+ isA: ['verb'],
494
+ bridge: "{ ...next(operator), direction: after[0], interpolate: [{ context: operator }, { property: 'direction' }] }",
495
+ semantic: ({context, objects, api}) => {
496
+ objects.runCommand = true
497
+ objects.current.direction = context.direction.marker
498
+ },
499
+ // check: { marker: 'turn', exported: true, extra: ['direction'] }
500
+ },
501
+ {
502
+ id: 'calibrate',
503
+ isA: ['verb'],
504
+ bridge: "{ ...next(operator), interpolate: [{ context: operator }] }",
505
+ semantic: ({context, objects, api, mentioned}) => {
506
+ objects.current.direction = 'forward'
507
+ const startTime = api.forward(objects.current.power)
508
+ objects.calibration.startTime = startTime
509
+
510
+ const ordinal = api.nextOrdinal()
511
+ mentioned({ marker: 'point', ordinal, point: { x: 0, y: 0 }, description: "calibration start" })
512
+ objects.current.ordinal = ordinal
513
+ }
514
+ },
515
+ {
516
+ id: 'pause',
517
+ isA: ['verb'],
518
+ bridge: "{ ...operator, time: after[0], interpolate: [{ context: operator }, { property: 'time' }] }",
519
+ semantic: async ({context}) => {
520
+ // why doesn't nodejs add a sleep function. I always have to look up how to do this because its not fucking memorable.
521
+ // function sleep(ms) { return new Promise(r => setTimeout(r, ms)); }
522
+ // await sleep(context.time.value*1000)
523
+ }
524
+ },
525
+ {
526
+ id: 'stop',
527
+ isA: ['verb'],
528
+ optional: {
529
+ 1: "{ marker: 'drone' }",
530
+ },
531
+ bridge: "{ ...next(operator), object: after[0], interpolate: [{ context: operator }, { property: 'object' }] }",
532
+ semantic: ({mentioned, context, objects, api, say}) => {
533
+ if (!objects.calibration.startTime) {
534
+ return // ignore
535
+ }
536
+ if (objects.calibration.speed) {
537
+ /*
538
+ const stopTime = api.stop()
539
+ const ordinal = api.nextOrdinal()
540
+ const point = api.currentPoint()
541
+ mentioned({ marker: 'point', ordinal, point })
542
+ objects.current.ordinal = ordinal
543
+ */
544
+ api.stop()
545
+ api.markCurrentPoint()
546
+ } else {
547
+ const stopTime = api.stop()
548
+ objects.calibration.endTime = stopTime
549
+ objects.calibration.duration = (objects.calibration.endTime - objects.calibration.startTime)/1000
550
+ }
551
+ }
552
+ },
553
+ ],
554
+ generators: [
555
+ {
556
+ match: ({context}) => context.marker == 'help' && !context.paraphrase && context.isResponse,
557
+ apply: () => ''
558
+ },
559
+ ],
560
+ semantics: [
561
+
562
+ ],
563
+ },
564
+ ],
565
+ }
566
+
567
+ knowledgeModule( {
568
+ config: { name: 'drone_v1' },
569
+ includes: [nameable, ordinals, hierarchy, rates, help],
570
+ api: () => new API(),
571
+
572
+ module,
573
+ description: 'controlling a drone. this is version one with a more complicated calibration. the drone has a distance sensor to I am going to write against that. I keeps this because I implemented new features for it and its acting like an integration test.',
574
+ test: {
575
+ name: './drone_v1.test.json',
576
+ contents: droneV1_tests,
577
+ checks: {
578
+ context: [
579
+ defaultContextCheck({ marker: 'point', exported: true, extra: ['ordinal', { property: 'point', check: ['x', 'y'] }, 'description', { property: 'stm', check: ['id', 'names'] }] }),
580
+ defaultContextCheck({ marker: 'turn', exported: true, extra: ['direction'] }),
581
+ defaultContextCheck({ marker: 'history', exported: true, extra: ['pause', 'direction', 'power', 'turn', 'time'] }),
582
+ defaultContextCheck(),
583
+ ],
584
+ objects: [
585
+ { km: 'stm' },
586
+ { path: ['isCalibrated'] },
587
+ { path: ['calibration'] },
588
+ { path: ['history'] },
589
+ { path: ['current'] },
590
+ { path: ['runCommand'] },
591
+ ],
592
+ }
593
+ },
594
+ instance,
595
+ template,
596
+ })