ekms 9.6.0-beta.5 → 9.6.0-beta.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/common/drone.instance.json +5 -48
- package/common/drone.js +100 -175
- package/common/drone.test.json +5268 -9910
- package/common/helpers.js +18 -1
- package/common/length.instance.json +4116 -826
- package/common/length.js +1 -0
- package/common/length.test.json +10868 -0
- package/package.json +2 -2
|
@@ -6,11 +6,10 @@
|
|
|
6
6
|
"point is a concept",
|
|
7
7
|
"points are nameable orderable and memorable",
|
|
8
8
|
{
|
|
9
|
-
"apply": "(args) => {\n expectDirection(args)\n expectDistanceForMove(args)\n\n args.config.addSemantic({\n match: ({context, isA}) => isA(context.marker, 'quantity') && isA(context.unit.marker, 'unitPerUnit'),\n apply: async ({context, objects, api, gr, fragments, e, say}) => {\n // send a command to the drone\n const instantiation = await fragments(\"quantity in meters per second\", { quantity: context })\n const result = await e(instantiation)\n const desired_speed = result.evalue.amount.evalue.evalue\n
|
|
9
|
+
"apply": "(args) => {\n expectDirection(args)\n expectDistanceForMove(args)\n\n args.config.addSemantic({\n match: ({context, isA}) => isA(context.marker, 'quantity') && isA(context.unit.marker, 'unitPerUnit'),\n apply: async ({context, objects, api, gr, fragments, e, say}) => {\n // send a command to the drone\n const instantiation = await fragments(\"quantity in meters per second\", { quantity: context })\n const result = await e(instantiation)\n const desired_speed = result.evalue.amount.evalue.evalue\n objects.runCommand = true\n objects.current.speed = desired_speed\n objects.current.speedUnitsOfUser = context.unit\n }\n })\n\n args.config.addSemantic({\n match: ({context, objects, isA}) => objects.current.direction && context.marker == 'controlStart',\n apply: ({context, objects, api}) => {\n objects.runCommand = false \n }\n })\n\n args.config.addSemantic({\n match: ({context, objects, isA}) => objects.current.direction && context.marker == 'controlEnd',\n apply: async ({context, objects, api}) => {\n // send a command to the drone\n if (objects.runCommand) {\n await api.sendCommand()\n }\n }\n })\n }"
|
|
10
10
|
},
|
|
11
11
|
{
|
|
12
12
|
"operators": [
|
|
13
|
-
"([calibrate])",
|
|
14
13
|
"([back])",
|
|
15
14
|
"([turn] (direction))",
|
|
16
15
|
"([pause] ([number]))",
|
|
@@ -24,7 +23,7 @@
|
|
|
24
23
|
"isA": [
|
|
25
24
|
"noun"
|
|
26
25
|
],
|
|
27
|
-
"semantic": "async ({objects, mentions, api, e, context}) => {\n
|
|
26
|
+
"semantic": "async ({objects, mentions, api, e, context}) => {\n objects.runCommand = true\n const ordinal = api.currentOrdinal() - 1\n const lastPoint = mentions({ context: { marker: 'point' }, condition: (context) => context.ordinal == ordinal })\n objects.current.destination = lastPoint\n }"
|
|
28
27
|
},
|
|
29
28
|
{
|
|
30
29
|
"id": "toPoint",
|
|
@@ -32,7 +31,7 @@
|
|
|
32
31
|
"preposition"
|
|
33
32
|
],
|
|
34
33
|
"bridge": "{ ...next(operator), operator: operator, point: after[0], interpolate: [{ property: 'operator' }, { property: 'point' }] }",
|
|
35
|
-
"semantic": "async ({objects, api, e, context}) => {\n
|
|
34
|
+
"semantic": "async ({objects, api, e, context}) => {\n objects.runCommand = true\n const point = await e(context.point)\n objects.current.destination = point.evalue\n }"
|
|
36
35
|
},
|
|
37
36
|
{
|
|
38
37
|
"id": "go"
|
|
@@ -45,17 +44,6 @@
|
|
|
45
44
|
"bridge": "{ ...next(operator), direction: after[0], interpolate: [{ context: operator }, { property: 'direction' }] }",
|
|
46
45
|
"semantic": "({context, objects, api}) => {\n objects.runCommand = true\n objects.current.direction = context.direction.marker\n }"
|
|
47
46
|
},
|
|
48
|
-
{
|
|
49
|
-
"id": "calibrate",
|
|
50
|
-
"words": [
|
|
51
|
-
"configure"
|
|
52
|
-
],
|
|
53
|
-
"isA": [
|
|
54
|
-
"verb"
|
|
55
|
-
],
|
|
56
|
-
"bridge": "{ ...next(operator), interpolate: [{ context: operator }] }",
|
|
57
|
-
"semantic": "async ({context, objects, api, mentioned}) => {\n let power = 20\n const moveTimeInSeconds = 0.5\n let distanceInCM = 0\n let startBackward\n for (; power < 30; ++power) {\n const start = await api.sonic();\n await api.forward(power, { batched: true })\n await api.pause(moveTimeInSeconds, { batched: true })\n await api.stop()\n const end = await api.sonic();\n if (end !== start) {\n distanceInCM = start - end\n startBackward = end\n break;\n }\n }\n\n const metersPerSecondForward = (distanceInCM/100)/moveTimeInSeconds\n\n // reset\n\n await api.backward(power, { batched: true })\n await api.pause(moveTimeInSeconds, { batched: true })\n await api.stop()\n const endBackward = await api.sonic();\n\n const metersPerSecondBackward = ((endBackward-startBackward)/100)/moveTimeInSeconds\n \n // console.log(`Distance ${distance} cm`)\n // console.log(`Time ${moveTime} ms`)\n // console.log(`M/S ${metersPerSecond}`)\n\n objects.calibration.minPower = power\n objects.calibration.power = power\n objects.current.power = power\n objects.calibration.speedForward = metersPerSecondForward\n objects.calibration.speedBackward = metersPerSecondBackward\n objects.calibration.isCalibrated = true\n\n const ordinal = api.nextOrdinal()\n mentioned({ marker: 'point', ordinal, point: { x: 0, y: 0 }, description: \"start\" })\n objects.current.ordinal = ordinal\n\n api.saveCalibration(objects.calibration)\n }"
|
|
58
|
-
},
|
|
59
47
|
{
|
|
60
48
|
"id": "pause",
|
|
61
49
|
"isA": [
|
|
@@ -73,7 +61,7 @@
|
|
|
73
61
|
"1": "{ marker: 'drone' }"
|
|
74
62
|
},
|
|
75
63
|
"bridge": "{ ...next(operator), object: after[0], interpolate: [{ context: operator }, { property: 'object' }] }",
|
|
76
|
-
"semantic": "async ({mentioned, context, objects, api, say}) => {\n
|
|
64
|
+
"semantic": "async ({mentioned, context, objects, api, say}) => {\n await api.stop()\n api.markCurrentPoint()\n }"
|
|
77
65
|
}
|
|
78
66
|
],
|
|
79
67
|
"generators": [
|
|
@@ -15683,12 +15671,11 @@
|
|
|
15683
15671
|
}
|
|
15684
15672
|
},
|
|
15685
15673
|
{
|
|
15686
|
-
"apply": "(args) => {\n expectDirection(args)\n expectDistanceForMove(args)\n\n args.config.addSemantic({\n match: ({context, isA}) => isA(context.marker, 'quantity') && isA(context.unit.marker, 'unitPerUnit'),\n apply: async ({context, objects, api, gr, fragments, e, say}) => {\n // send a command to the drone\n const instantiation = await fragments(\"quantity in meters per second\", { quantity: context })\n const result = await e(instantiation)\n const desired_speed = result.evalue.amount.evalue.evalue\n
|
|
15674
|
+
"apply": "(args) => {\n expectDirection(args)\n expectDistanceForMove(args)\n\n args.config.addSemantic({\n match: ({context, isA}) => isA(context.marker, 'quantity') && isA(context.unit.marker, 'unitPerUnit'),\n apply: async ({context, objects, api, gr, fragments, e, say}) => {\n // send a command to the drone\n const instantiation = await fragments(\"quantity in meters per second\", { quantity: context })\n const result = await e(instantiation)\n const desired_speed = result.evalue.amount.evalue.evalue\n objects.runCommand = true\n objects.current.speed = desired_speed\n objects.current.speedUnitsOfUser = context.unit\n }\n })\n\n args.config.addSemantic({\n match: ({context, objects, isA}) => objects.current.direction && context.marker == 'controlStart',\n apply: ({context, objects, api}) => {\n objects.runCommand = false \n }\n })\n\n args.config.addSemantic({\n match: ({context, objects, isA}) => objects.current.direction && context.marker == 'controlEnd',\n apply: async ({context, objects, api}) => {\n // send a command to the drone\n if (objects.runCommand) {\n await api.sendCommand()\n }\n }\n })\n }"
|
|
15687
15675
|
},
|
|
15688
15676
|
{
|
|
15689
15677
|
"extraConfig": true,
|
|
15690
15678
|
"operators": [
|
|
15691
|
-
"([calibrate])",
|
|
15692
15679
|
"([back])",
|
|
15693
15680
|
"([turn] (direction))",
|
|
15694
15681
|
"([pause] ([number]))",
|
|
@@ -15720,16 +15707,6 @@
|
|
|
15720
15707
|
],
|
|
15721
15708
|
"bridge": "{ ...next(operator), direction: after[0], interpolate: [{ context: operator }, { property: 'direction' }] }"
|
|
15722
15709
|
},
|
|
15723
|
-
{
|
|
15724
|
-
"id": "calibrate",
|
|
15725
|
-
"words": [
|
|
15726
|
-
"configure"
|
|
15727
|
-
],
|
|
15728
|
-
"isA": [
|
|
15729
|
-
"verb"
|
|
15730
|
-
],
|
|
15731
|
-
"bridge": "{ ...next(operator), interpolate: [{ context: operator }] }"
|
|
15732
|
-
},
|
|
15733
15710
|
{
|
|
15734
15711
|
"id": "pause",
|
|
15735
15712
|
"isA": [
|
|
@@ -15927,11 +15904,6 @@
|
|
|
15927
15904
|
"verb",
|
|
15928
15905
|
false
|
|
15929
15906
|
],
|
|
15930
|
-
[
|
|
15931
|
-
"calibrate",
|
|
15932
|
-
"verb",
|
|
15933
|
-
false
|
|
15934
|
-
],
|
|
15935
15907
|
[
|
|
15936
15908
|
"call",
|
|
15937
15909
|
"verb",
|
|
@@ -18718,11 +18690,6 @@
|
|
|
18718
18690
|
"verb",
|
|
18719
18691
|
false
|
|
18720
18692
|
],
|
|
18721
|
-
[
|
|
18722
|
-
"calibrate",
|
|
18723
|
-
"verb",
|
|
18724
|
-
false
|
|
18725
|
-
],
|
|
18726
18693
|
[
|
|
18727
18694
|
"call",
|
|
18728
18695
|
"verb",
|
|
@@ -21780,11 +21747,6 @@
|
|
|
21780
21747
|
"verb",
|
|
21781
21748
|
false
|
|
21782
21749
|
],
|
|
21783
|
-
[
|
|
21784
|
-
"calibrate",
|
|
21785
|
-
"verb",
|
|
21786
|
-
false
|
|
21787
|
-
],
|
|
21788
21750
|
[
|
|
21789
21751
|
"call",
|
|
21790
21752
|
"verb",
|
|
@@ -24762,11 +24724,6 @@
|
|
|
24762
24724
|
"verb",
|
|
24763
24725
|
false
|
|
24764
24726
|
],
|
|
24765
|
-
[
|
|
24766
|
-
"calibrate",
|
|
24767
|
-
"verb",
|
|
24768
|
-
false
|
|
24769
|
-
],
|
|
24770
24727
|
[
|
|
24771
24728
|
"call",
|
|
24772
24729
|
"verb",
|
package/common/drone.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const { knowledgeModule, where } = require('./runtime').theprogrammablemind
|
|
2
|
-
const { defaultContextCheck, getValue, setValue } = require('./helpers')
|
|
2
|
+
const { OverrideCheck, defaultContextCheck, getValue, setValue } = require('./helpers')
|
|
3
3
|
const drone_tests = require('./drone.test.json')
|
|
4
4
|
const instance = require('./drone.instance.json')
|
|
5
5
|
const hierarchy = require('./hierarchy')
|
|
@@ -107,6 +107,8 @@ https://www.amazon.ca/Freenove-Raspberry-Tracking-Avoidance-Ultrasonic/dp/B0BNDQ
|
|
|
107
107
|
you are facing north. patrol between here and 100 feet to the west
|
|
108
108
|
this way is south
|
|
109
109
|
|
|
110
|
+
go forward for 1 second\nbackward 2 meters (implicit stop)
|
|
111
|
+
|
|
110
112
|
go back
|
|
111
113
|
*/
|
|
112
114
|
|
|
@@ -121,14 +123,17 @@ function expectDirection(args) {
|
|
|
121
123
|
}
|
|
122
124
|
|
|
123
125
|
function expectDistanceForMove(args) {
|
|
124
|
-
// TODO save id for recalibration
|
|
125
126
|
args.config.addSemantic({
|
|
126
127
|
match: ({context, isA}) => isA(context.marker, 'quantity') && !isA(context.unit.marker, 'unitPerUnit'),
|
|
127
|
-
apply: async ({context, objects, fragments, e}) => {
|
|
128
|
+
apply: async ({context, objects, fragments, e, say, gp}) => {
|
|
128
129
|
const instantiation = await fragments("quantity in meters", { quantity: context })
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
130
|
+
try {
|
|
131
|
+
const result = await e(instantiation)
|
|
132
|
+
objects.runCommand = true
|
|
133
|
+
objects.current.distance = result.evalue.amount.evalue.evalue
|
|
134
|
+
} catch (e) {
|
|
135
|
+
say(`Don't know how to interpret ${await gp(context)} in meters`)
|
|
136
|
+
}
|
|
132
137
|
}
|
|
133
138
|
})
|
|
134
139
|
}
|
|
@@ -144,21 +149,6 @@ function expectDistanceForMove(args) {
|
|
|
144
149
|
-90
|
|
145
150
|
*/
|
|
146
151
|
|
|
147
|
-
class OverrideCheck {
|
|
148
|
-
constructor(base, checks) {
|
|
149
|
-
this.base = base
|
|
150
|
-
this.checks = checks
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
check(obj) {
|
|
154
|
-
for (const check of this.checks) {
|
|
155
|
-
if (obj[check] == this.base.prototype[check]) {
|
|
156
|
-
throw new Error(`For ${obj.constructor.name} you need to override ${check}`)
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
152
|
/*
|
|
163
153
|
L = track separation width (distance between the centers of the two tracks, measured side-to-side, in meters or whatever unit you like)
|
|
164
154
|
|
|
@@ -177,7 +167,7 @@ The time t needed to turn by angle θ is:
|
|
|
177
167
|
*/
|
|
178
168
|
class API {
|
|
179
169
|
constructor() {
|
|
180
|
-
this.overrideCheck = new OverrideCheck(API, ['forwardDrone', 'backwardDrone', 'rotateDrone', 'sonicDrone', 'tiltAngleDrone', 'panAngleDrone', 'stopDrone'
|
|
170
|
+
this.overrideCheck = new OverrideCheck(API, ['forwardDrone', 'backwardDrone', 'rotateDrone', 'sonicDrone', 'tiltAngleDrone', 'panAngleDrone', 'stopDrone'])
|
|
181
171
|
this.overriden = this.constructor !== API
|
|
182
172
|
}
|
|
183
173
|
|
|
@@ -187,42 +177,39 @@ class API {
|
|
|
187
177
|
}
|
|
188
178
|
this._objects = objects
|
|
189
179
|
this._objects.defaultTime = { hour: 9, minute: 0, second: 0, millisecond: 0 }
|
|
190
|
-
this._objects.ordinal = 0
|
|
191
180
|
delete this.testDate
|
|
192
181
|
|
|
193
|
-
objects.calibration = {
|
|
194
|
-
speed: undefined, // meters per second
|
|
195
|
-
widthOfTankInMM: 188,
|
|
196
|
-
widthOfTreadInMM: 44,
|
|
197
|
-
}
|
|
198
182
|
objects.current = {
|
|
199
|
-
angleInRadians: 0
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
// ordinal // ordinal of the current point or the current point that the recent movement started at
|
|
183
|
+
angleInRadians: 0,
|
|
184
|
+
speed: this.minimumSpeedDrone(),
|
|
185
|
+
ordinal: 0, // ordinal of the current point or the current point that the recent movement started at
|
|
203
186
|
}
|
|
204
187
|
objects.history = []
|
|
205
|
-
objects.calibration.isCalibrated = false
|
|
206
188
|
objects.sonicTest = 5
|
|
189
|
+
|
|
190
|
+
this.args.mentioned({ marker: 'point', ordinal: this.nextOrdinal(), point: { x: 0, y: 0 }, description: "start" })
|
|
207
191
|
}
|
|
208
192
|
|
|
209
|
-
|
|
210
|
-
return this._objects.
|
|
193
|
+
currentOrdinal() {
|
|
194
|
+
return this._objects.current.ordinal
|
|
211
195
|
}
|
|
212
196
|
|
|
213
197
|
nextOrdinal() {
|
|
214
|
-
return this._objects.ordinal += 1
|
|
198
|
+
return this._objects.current.ordinal += 1
|
|
215
199
|
}
|
|
216
200
|
|
|
217
201
|
currentPoint() {
|
|
218
|
-
if (!this._objects.current.endTime) {
|
|
202
|
+
if (!this._objects.current.startTime || !this._objects.current.endTime) {
|
|
219
203
|
return null // in motion
|
|
220
204
|
}
|
|
221
|
-
const ordinal = this.
|
|
205
|
+
const ordinal = this.currentOrdinal()
|
|
222
206
|
const lastPoint = this.args.mentions({ context: { marker: 'point' }, condition: (context) => context.ordinal == ordinal })
|
|
207
|
+
if (!this._objects.current.startTime && !this._objects.current.endTime) {
|
|
208
|
+
return lastPoint // did not move
|
|
209
|
+
}
|
|
223
210
|
|
|
224
211
|
const durationInSeconds = (this._objects.current.endTime - this._objects.current.startTime) / 1000
|
|
225
|
-
const speedInMetersPerSecond =
|
|
212
|
+
const speedInMetersPerSecond = this._objects.current.speed
|
|
226
213
|
const direction = this._objects.current.direction
|
|
227
214
|
const distanceInMeters = speedInMetersPerSecond * durationInSeconds * (direction == 'forward' ? 1 : -1)
|
|
228
215
|
const angleInRadians = this._objects.current.angleInRadians
|
|
@@ -232,10 +219,12 @@ class API {
|
|
|
232
219
|
}
|
|
233
220
|
|
|
234
221
|
markCurrentPoint() {
|
|
235
|
-
const ordinal = this.nextOrdinal()
|
|
236
222
|
const point = this.currentPoint()
|
|
223
|
+
if (!point) {
|
|
224
|
+
return
|
|
225
|
+
}
|
|
226
|
+
const ordinal = this.nextOrdinal()
|
|
237
227
|
this.args.mentioned({ marker: 'point', ordinal, point })
|
|
238
|
-
this._objects.current.ordinal = ordinal
|
|
239
228
|
this._objects.current.endTime = null
|
|
240
229
|
this._objects.current.startTime = null
|
|
241
230
|
}
|
|
@@ -245,32 +234,33 @@ class API {
|
|
|
245
234
|
const { fragments, e, say, gr } = this.args
|
|
246
235
|
|
|
247
236
|
// TODO account for forward vs backward speed
|
|
248
|
-
|
|
237
|
+
const minimumSpeed = this.minimumSpeedDrone()
|
|
238
|
+
if (objects.current.speed < minimumSpeed) {
|
|
249
239
|
const unitsOfUser = objects.current.speedUnitsOfUser
|
|
250
|
-
const minimumValueInDroneUnits = await fragments("number meters per second", { number: { marker: 'integer', value:
|
|
240
|
+
const minimumValueInDroneUnits = await fragments("number meters per second", { number: { marker: 'integer', value: minimumSpeed } })
|
|
251
241
|
const valueInUsersUnits = await fragments("quantity in units", { quantity: minimumValueInDroneUnits, unit_length: unitsOfUser })
|
|
252
242
|
const evaluated = await e(valueInUsersUnits)
|
|
253
243
|
say(`The drone cannot go that slow. The minimum speed is ${await gr(evaluated.evalue)}`)
|
|
254
244
|
objects.runCommand = false
|
|
255
|
-
objects.current.
|
|
245
|
+
objects.current.speed = minimumSpeed
|
|
256
246
|
return
|
|
257
247
|
}
|
|
258
248
|
|
|
259
249
|
// TODO account for forward vs backward speed
|
|
260
|
-
|
|
261
|
-
|
|
250
|
+
const maximumSpeed = this.maximumSpeedDrone()
|
|
251
|
+
if (objects.current.speed > maximumSpeed) {
|
|
262
252
|
const unitsOfUser = objects.current.speedUnitsOfUser
|
|
263
253
|
const maximumValueInDroneUnits = await fragments("number meters per second", { number: { marker: 'integer', value: maximumSpeed } })
|
|
264
254
|
const valueInUsersUnits = await fragments("quantity in units", { quantity: maximumValueInDroneUnits, unit_length: unitsOfUser })
|
|
265
255
|
const evaluated = await e(valueInUsersUnits)
|
|
266
256
|
say(`The drone cannot go that fast. The maximum speed is ${await gr(evaluated.evalue)}`)
|
|
267
257
|
objects.runCommand = false
|
|
268
|
-
objects.current.
|
|
258
|
+
objects.current.speed = minimumSpeed
|
|
269
259
|
return
|
|
270
260
|
}
|
|
271
261
|
|
|
272
262
|
const stopAtDistance = async (direction, distanceMeters) => {
|
|
273
|
-
const speed_meters_per_second =
|
|
263
|
+
const speed_meters_per_second = this._objects.current.speed
|
|
274
264
|
const duration_seconds = distanceMeters / speed_meters_per_second
|
|
275
265
|
await this.pause(duration_seconds, { batched: true })
|
|
276
266
|
await this.stop()
|
|
@@ -278,26 +268,29 @@ class API {
|
|
|
278
268
|
}
|
|
279
269
|
|
|
280
270
|
if (this._objects.current.destination) {
|
|
281
|
-
|
|
282
|
-
const
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
271
|
+
const currentPoint = this.args.mentions({ context: { marker: 'point' } }).point
|
|
272
|
+
const destinationPoint = this._objects.current.destination.point
|
|
273
|
+
if (currentPoint.x == destinationPoint.x && currentPoint.y == destinationPoint.y) {
|
|
274
|
+
// already there
|
|
275
|
+
} else {
|
|
276
|
+
const polar = cartesianToPolar(currentPoint, destinationPoint)
|
|
277
|
+
const destinationAngleInRadians = polar.angle
|
|
278
|
+
const angleDelta = (destinationAngleInRadians - this._objects.current.angleInRadians)
|
|
279
|
+
await this.rotate(angleDelta)
|
|
280
|
+
await this.forward(this._objects.current.speed)
|
|
281
|
+
await stopAtDistance("forward", polar.radius)
|
|
282
|
+
this._objects.current.destination = undefined
|
|
283
|
+
}
|
|
291
284
|
return
|
|
292
285
|
}
|
|
293
286
|
|
|
294
|
-
const command = {
|
|
287
|
+
const command = { speed: this._objects.current.speed, ...this._objects.current }
|
|
295
288
|
switch (command.direction) {
|
|
296
289
|
case 'forward':
|
|
297
|
-
await this.forward(command.
|
|
290
|
+
await this.forward(command.speed, { batched: command.distance })
|
|
298
291
|
break
|
|
299
292
|
case 'backward':
|
|
300
|
-
await this.backward(command.
|
|
293
|
+
await this.backward(command.speed, { batched: command.distance })
|
|
301
294
|
break
|
|
302
295
|
case 'right':
|
|
303
296
|
await this.rotate(-Math.PI/4)
|
|
@@ -316,25 +309,17 @@ class API {
|
|
|
316
309
|
}
|
|
317
310
|
}
|
|
318
311
|
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
// override this to save the calibration to not have to run it over and over again and be annoing.
|
|
325
|
-
async saveCalibration(calibration) {
|
|
326
|
-
this._objects.history.push({ marker: 'history', saveCalibration: true })
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
async forward(power, options) {
|
|
330
|
-
const time = await this.forwardDrone(power, options)
|
|
312
|
+
async forward(speed, options) {
|
|
313
|
+
await this.forwardDrone(speed, options)
|
|
314
|
+
const time = this.now()
|
|
331
315
|
this._objects.current.startTime = time
|
|
332
316
|
this._objects.current.endTime = null
|
|
333
317
|
return time
|
|
334
318
|
}
|
|
335
319
|
|
|
336
|
-
async backward(
|
|
337
|
-
|
|
320
|
+
async backward(speed, options) {
|
|
321
|
+
await this.backwardDrone(speed, options)
|
|
322
|
+
const time = this.now()
|
|
338
323
|
this._objects.current.startTime = time
|
|
339
324
|
this._objects.current.endTime = null
|
|
340
325
|
return time
|
|
@@ -359,8 +344,11 @@ class API {
|
|
|
359
344
|
}
|
|
360
345
|
|
|
361
346
|
async stop(options) {
|
|
362
|
-
|
|
363
|
-
|
|
347
|
+
await this.stopDrone(options)
|
|
348
|
+
const time = this.now()
|
|
349
|
+
if (this._objects.current.startTime) {
|
|
350
|
+
this._objects.current.endTime = time
|
|
351
|
+
}
|
|
364
352
|
return time
|
|
365
353
|
}
|
|
366
354
|
|
|
@@ -370,37 +358,46 @@ class API {
|
|
|
370
358
|
|
|
371
359
|
// subclass and override the remaining to call the drone
|
|
372
360
|
|
|
373
|
-
// this is for testing
|
|
374
361
|
async pauseDrone(durationInSeconds, options) {
|
|
375
362
|
this._objects.history.push({ marker: 'history', pause: durationInSeconds, ...options })
|
|
376
363
|
this.testDate = new Date(this.testDate.getTime() + (durationInSeconds-1)*1000)
|
|
377
364
|
}
|
|
378
365
|
|
|
379
|
-
|
|
366
|
+
// meters per second
|
|
367
|
+
minimumSpeedDrone() {
|
|
368
|
+
return 0.25
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
// meters per second
|
|
372
|
+
maximumSpeedDrone() {
|
|
373
|
+
return 1.2
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
now(lookahead = false) {
|
|
380
377
|
if (this.args.isProcess || this.args.isTest) {
|
|
381
378
|
if (!this.testDate) {
|
|
382
379
|
this.testDate = new Date(2025, 5, 29, 14, 52, 0)
|
|
383
380
|
}
|
|
384
|
-
|
|
385
|
-
|
|
381
|
+
if (lookahead) {
|
|
382
|
+
return new Date(this.testDate.getTime() + 1000)
|
|
383
|
+
} else {
|
|
384
|
+
this.testDate = new Date(this.testDate.getTime() + 1000)
|
|
385
|
+
return this.testDate
|
|
386
|
+
}
|
|
386
387
|
} else {
|
|
387
388
|
return new Date()
|
|
388
389
|
}
|
|
389
390
|
}
|
|
390
391
|
|
|
391
392
|
// CMD_MOTOR#1000#1000#
|
|
392
|
-
async forwardDrone(
|
|
393
|
-
const time = this.now()
|
|
393
|
+
async forwardDrone(speed, options) {
|
|
394
394
|
this._objects.sonicTest -= 10 // make the speed about the same as the actual drone
|
|
395
|
-
this._objects.history.push({ marker: 'history', direction: 'forward',
|
|
396
|
-
return time
|
|
395
|
+
this._objects.history.push({ marker: 'history', direction: 'forward', speed, time: this.now(true), ...options })
|
|
397
396
|
}
|
|
398
397
|
|
|
399
|
-
async backwardDrone(
|
|
400
|
-
const time = this.now()
|
|
398
|
+
async backwardDrone(speed, options) {
|
|
401
399
|
this._objects.sonicTest += 10 // make the speed about the same as the actual drone
|
|
402
|
-
this._objects.history.push({ marker: 'history', direction: 'backward',
|
|
403
|
-
return time
|
|
400
|
+
this._objects.history.push({ marker: 'history', direction: 'backward', speed, time: this.now(true), ...options })
|
|
404
401
|
}
|
|
405
402
|
|
|
406
403
|
// -angle is counterclockwise
|
|
@@ -423,9 +420,7 @@ class API {
|
|
|
423
420
|
}
|
|
424
421
|
|
|
425
422
|
async stopDrone(options) {
|
|
426
|
-
|
|
427
|
-
this._objects.history.push({ marker: 'history', power: 0, time, ...options })
|
|
428
|
-
return time
|
|
423
|
+
this._objects.history.push({ marker: 'history', speed: 0, time: this.now(true), ...options })
|
|
429
424
|
}
|
|
430
425
|
}
|
|
431
426
|
|
|
@@ -507,23 +502,21 @@ const template = {
|
|
|
507
502
|
const instantiation = await fragments("quantity in meters per second", { quantity: context })
|
|
508
503
|
const result = await e(instantiation)
|
|
509
504
|
const desired_speed = result.evalue.amount.evalue.evalue
|
|
510
|
-
const desired_power = objects.current.power * (desired_speed / objects.calibration.speedForward)
|
|
511
505
|
objects.runCommand = true
|
|
512
|
-
objects.current.
|
|
506
|
+
objects.current.speed = desired_speed
|
|
513
507
|
objects.current.speedUnitsOfUser = context.unit
|
|
514
508
|
}
|
|
515
509
|
})
|
|
516
510
|
|
|
517
511
|
args.config.addSemantic({
|
|
518
|
-
match: ({context, objects, isA}) => objects.current.direction &&
|
|
512
|
+
match: ({context, objects, isA}) => objects.current.direction && context.marker == 'controlStart',
|
|
519
513
|
apply: ({context, objects, api}) => {
|
|
520
514
|
objects.runCommand = false
|
|
521
515
|
}
|
|
522
516
|
})
|
|
523
517
|
|
|
524
518
|
args.config.addSemantic({
|
|
525
|
-
|
|
526
|
-
match: ({context, objects, isA}) => objects.current.direction && objects.calibration.isCalibrated && context.marker == 'controlEnd',
|
|
519
|
+
match: ({context, objects, isA}) => objects.current.direction && context.marker == 'controlEnd',
|
|
527
520
|
apply: async ({context, objects, api}) => {
|
|
528
521
|
// send a command to the drone
|
|
529
522
|
if (objects.runCommand) {
|
|
@@ -534,7 +527,6 @@ const template = {
|
|
|
534
527
|
},
|
|
535
528
|
{
|
|
536
529
|
operators: [
|
|
537
|
-
"([calibrate])",
|
|
538
530
|
"([back])",
|
|
539
531
|
"([turn] (direction))",
|
|
540
532
|
"([pause] ([number]))",
|
|
@@ -547,12 +539,10 @@ const template = {
|
|
|
547
539
|
id: "back",
|
|
548
540
|
isA: ['noun'],
|
|
549
541
|
semantic: async ({objects, mentions, api, e, context}) => {
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
objects.current.destination = lastPoint
|
|
555
|
-
}
|
|
542
|
+
objects.runCommand = true
|
|
543
|
+
const ordinal = api.currentOrdinal() - 1
|
|
544
|
+
const lastPoint = mentions({ context: { marker: 'point' }, condition: (context) => context.ordinal == ordinal })
|
|
545
|
+
objects.current.destination = lastPoint
|
|
556
546
|
}
|
|
557
547
|
},
|
|
558
548
|
{
|
|
@@ -560,11 +550,9 @@ const template = {
|
|
|
560
550
|
isA: ['preposition'],
|
|
561
551
|
bridge: "{ ...next(operator), operator: operator, point: after[0], interpolate: [{ property: 'operator' }, { property: 'point' }] }",
|
|
562
552
|
semantic: async ({objects, api, e, context}) => {
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
objects.current.destination = point.evalue
|
|
567
|
-
}
|
|
553
|
+
objects.runCommand = true
|
|
554
|
+
const point = await e(context.point)
|
|
555
|
+
objects.current.destination = point.evalue
|
|
568
556
|
}
|
|
569
557
|
},
|
|
570
558
|
{ id: "go" },
|
|
@@ -578,58 +566,6 @@ const template = {
|
|
|
578
566
|
},
|
|
579
567
|
// check: { marker: 'turn', exported: true, extra: ['direction'] }
|
|
580
568
|
},
|
|
581
|
-
{
|
|
582
|
-
id: 'calibrate',
|
|
583
|
-
words: ['configure'],
|
|
584
|
-
isA: ['verb'],
|
|
585
|
-
bridge: "{ ...next(operator), interpolate: [{ context: operator }] }",
|
|
586
|
-
semantic: async ({context, objects, api, mentioned}) => {
|
|
587
|
-
let power = 20
|
|
588
|
-
const moveTimeInSeconds = 0.5
|
|
589
|
-
let distanceInCM = 0
|
|
590
|
-
let startBackward
|
|
591
|
-
for (; power < 30; ++power) {
|
|
592
|
-
const start = await api.sonic();
|
|
593
|
-
await api.forward(power, { batched: true })
|
|
594
|
-
await api.pause(moveTimeInSeconds, { batched: true })
|
|
595
|
-
await api.stop()
|
|
596
|
-
const end = await api.sonic();
|
|
597
|
-
if (end !== start) {
|
|
598
|
-
distanceInCM = start - end
|
|
599
|
-
startBackward = end
|
|
600
|
-
break;
|
|
601
|
-
}
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
const metersPerSecondForward = (distanceInCM/100)/moveTimeInSeconds
|
|
605
|
-
|
|
606
|
-
// reset
|
|
607
|
-
|
|
608
|
-
await api.backward(power, { batched: true })
|
|
609
|
-
await api.pause(moveTimeInSeconds, { batched: true })
|
|
610
|
-
await api.stop()
|
|
611
|
-
const endBackward = await api.sonic();
|
|
612
|
-
|
|
613
|
-
const metersPerSecondBackward = ((endBackward-startBackward)/100)/moveTimeInSeconds
|
|
614
|
-
|
|
615
|
-
// console.log(`Distance ${distance} cm`)
|
|
616
|
-
// console.log(`Time ${moveTime} ms`)
|
|
617
|
-
// console.log(`M/S ${metersPerSecond}`)
|
|
618
|
-
|
|
619
|
-
objects.calibration.minPower = power
|
|
620
|
-
objects.calibration.power = power
|
|
621
|
-
objects.current.power = power
|
|
622
|
-
objects.calibration.speedForward = metersPerSecondForward
|
|
623
|
-
objects.calibration.speedBackward = metersPerSecondBackward
|
|
624
|
-
objects.calibration.isCalibrated = true
|
|
625
|
-
|
|
626
|
-
const ordinal = api.nextOrdinal()
|
|
627
|
-
mentioned({ marker: 'point', ordinal, point: { x: 0, y: 0 }, description: "start" })
|
|
628
|
-
objects.current.ordinal = ordinal
|
|
629
|
-
|
|
630
|
-
api.saveCalibration(objects.calibration)
|
|
631
|
-
}
|
|
632
|
-
},
|
|
633
569
|
{
|
|
634
570
|
id: 'pause',
|
|
635
571
|
isA: ['verb'],
|
|
@@ -648,17 +584,8 @@ const template = {
|
|
|
648
584
|
},
|
|
649
585
|
bridge: "{ ...next(operator), object: after[0], interpolate: [{ context: operator }, { property: 'object' }] }",
|
|
650
586
|
semantic: async ({mentioned, context, objects, api, say}) => {
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
}
|
|
654
|
-
if (objects.calibration.speedForward) {
|
|
655
|
-
await api.stop()
|
|
656
|
-
api.markCurrentPoint()
|
|
657
|
-
} else {
|
|
658
|
-
const stopTime = await api.stop()
|
|
659
|
-
objects.calibration.endTime = stopTime
|
|
660
|
-
objects.calibration.duration = (objects.calibration.endTime - objects.calibration.startTime)/1000
|
|
661
|
-
}
|
|
587
|
+
await api.stop()
|
|
588
|
+
api.markCurrentPoint()
|
|
662
589
|
}
|
|
663
590
|
},
|
|
664
591
|
],
|
|
@@ -689,13 +616,11 @@ knowledgeModule( {
|
|
|
689
616
|
context: [
|
|
690
617
|
defaultContextCheck({ marker: 'point', exported: true, extra: ['ordinal', { property: 'point', check: ['x', 'y'] }, 'description', { property: 'stm', check: ['id', 'names'] }] }),
|
|
691
618
|
defaultContextCheck({ marker: 'turn', exported: true, extra: ['direction'] }),
|
|
692
|
-
defaultContextCheck({ marker: 'history', exported: true, extra: ['pause', 'direction', '
|
|
619
|
+
defaultContextCheck({ marker: 'history', exported: true, extra: ['pause', 'direction', 'speed', 'turn', 'time', 'sonic', 'batched'] }),
|
|
693
620
|
defaultContextCheck(),
|
|
694
621
|
],
|
|
695
622
|
objects: [
|
|
696
623
|
{ km: 'stm' },
|
|
697
|
-
{ path: ['isCalibrated'] },
|
|
698
|
-
{ path: ['calibration'] },
|
|
699
624
|
{ path: ['history'] },
|
|
700
625
|
{ path: ['current'] },
|
|
701
626
|
{ path: ['runCommand'] },
|