1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489 | # Copyright (c) 2024 MBARI
# MBARI Proprietary Information. Confidential. All Rights Reserved
# Unauthorized copying or distribution of this file via any medium is strictly
# prohibited.
#
# WARNING - This file contains information whose export is restricted by the
# Export Administration Act of 1979 (Title 50, U.S.C., App. 2401 et seq.), as
# amended. Violations of these export laws are subject to severe civil and/or
# criminal penalties.
mission trackPatch {
"""
Vehicle runs yo-yos, with patch detect enabled for cholorphyll
concentration.
"""
arguments {
# Vehicle safety parameters
MinAltitude = 5 meter
"""
Minimum altitude for the entire mission.
"""
MaxDepth = 65 meter
"""
Maximum depth for the entire mission.
"""
MinWaterDepth = 10 meter
"""
Minimum water depth for the entire mission.
"""
MinOffshore = 2000 meter
"""
Minimum offshore distance for the entire mission.
"""
NeedCommsTime = 180 minute
"""
Maximum time between surfacings for communications
"""
MissionTimeout = 56 hour
"""
Timeout for the entire mission
"""
MassDefault = Control:VerticalControl.massDefault
"""
Static setting for mass during the mission. Defaults to massDefault
setting in the Config/Control.cfg file.
"""
BuoyancyNeutral = Control:VerticalControl.buoyancyNeutral
"""
Buoyancy bladder position while performing the YoYo behavior. Defaults
to buoyancyNeutral setting in the Config/Control.cfg file.
"""
# Basic guidance settings
YoYoMinDepth = 5.0 meter
"""
Minimum depth during yo-yo's.
"""
YoYoMaxDepth = 25.0 meter
"""
Maximum depth during yo-yo's.
"""
YoYoUpPitch = 20.0 degree
"""
Pitch when yo-yo's are ascending.
"""
YoYoDownPitch = -20.0 degree
"""
Pitch when yo-yo's are descending.
"""
Speed = 1 meter_per_second
"""
Vehicle speed.
"""
WpMaxDistance = 1000 meter
"""
Maximum length of each tracking leg
"""
WpTimeout = 8000 second
"""
Maximum duration of each tracking leg
"""
WaterFrame = true
"""
Set WaterFrame true to drive towards waypoints in the water frame of
reference
"""
Repeat = 20 count
"""
Maximum number of tracking legs
"""
# Constant settings for each tracking leg
Turn = 90 degree
"""
Amount to turn at each leg
"""
Reverse = 180 degree
"""
Change in bearing which reverses vehicle direction
"""
TwoPi = 360 degree
"""
Applied to stop run-up of angles
"""
TimeWindowPeakRpt = NaN minute
"""
If greater than zero, report a peak every window. If NaN or zero, this
variable is ignored.
"""
# debug
# </Description><Units:minute/><Value>1</Value></DefineArg>
LowPassWindowLen = 20 count
"""
Low-pass window length (based on depth sensor sampling interval 0.4
second) for low-pass filtering.
"""
PeakChlShallowBnd = 10 meter
"""
Shallow depth bound for detecting chl peak on each descent or ascent
profile.
"""
# debug
# </Description><Units:meter/><Value>3</Value></DefineArg>
PeakChlDeepBnd = 20 meter
"""
Deep depth bound for detecting chl peak on each descent or ascent
profile.
"""
# debug
# </Description><Units:meter/><Value>8</Value></DefineArg>
NumOfProfilesSlidingwindow = 10 count
"""
Length of horizontal sliding window. The highest yoyo-wise chl peak
(after low-pass filtering by a filter of length FilterWidthHorizontal)
within this window.
"""
FilterWidth = 4 count
"""
Width of boxcar filter used in horizontal patch detection
"""
BeginThreshold = NaN microgram_per_liter
"""
If non-NaN, sets threshold for starting horizontal patch detection
"""
OffPeakFraction = 80 percent
"""
When filtered horizontal value is this fraction of the peak, consider it
outside the patch.
"""
PatchMode = false
"""
If true, use center of "in peak" range as the turn-around point. If
false use maximum horizontal peak location as the turn-around point.
"""
PatchTrackingHorizontal = true
"""
Set true to turn on horizontal patch tracking
"""
# Variable Settings for each tracking leg
WpBearing = -90 degree
"""
Bearing being followed in the current leg. Set this to initialize start
direction of patch tracking.
"""
}
output {
PatchDetectOn = false
"""
Mission sets this to true when the patch has been crossed.
"""
WpDone = false
"""
Mission sets this to true when the cross-patch waypoint has been
reached.
"""
PatchChl = NaN microgram_per_liter
PatchChlDepth = NaN meter
PatchChlLatitude = NaN degree
PatchChlLongitude = NaN degree
PatchChlDistance = 0 meter
}
# The timeout
timeout duration=MissionTimeout
# And now the mission
behavior Guidance:AltitudeEnvelope {
run in parallel
set minAltitude = MinAltitude
}
behavior Guidance:DepthEnvelope {
run in parallel
set maxDepth = MaxDepth
}
insert id="SurfaceCommsSplit" Insert/Surface.tl {
redefineArg SurfacePitch = 20 degree
redefineArg SurfaceSpeed = 1 meter_per_second
redefineArg UnpackSplitAtSurface = true
}
aggregate SurfaceComms {
run when ( called )
insert Insert/Surface.tl {
redefineArg SurfacePitch = 20 degree
redefineArg SurfaceSpeed = 1 meter_per_second
}
}
# GPS Update. Don't go too long w/o a GPS fix.
aggregate NeedComms {
run when (
Universal:platform_pitch_angle > 0 degree
and ( elapsed ( Universal:time_fix ) > NeedCommsTime )
or ( elapsed ( Universal:time_fix ) > ( NeedCommsTime + 10 minute ) )
)
syslog important "NeedComms Timeout Surfacing"
call refId="SurfaceComms"
}
behavior Guidance:OffshoreEnvelope {
run in parallel
set minOffshore = MinOffshore
}
behavior Guidance:WaterDepthEnvelope {
run in parallel
set minWaterDepth = MinWaterDepth
}
behavior Guidance:Pitch {
run in parallel
set massPosition = MassDefault
}
behavior Guidance:Buoyancy {
run in parallel
set position = BuoyancyNeutral
}
# If we're executing here or below, lets' get science data!
insert Insert/Science.tl {
redefineArg PeakDetectChlActive = true
redefineArg PatchTracking = true
redefineArg TimeWindowPeakReport = TimeWindowPeakRpt
redefineArg LowPassWindowLength = LowPassWindowLen
redefineArg PeakShallowBound = PeakChlShallowBnd
redefineArg PeakDeepBound = PeakChlDeepBnd
redefineArg OffPeakFractionHorizontal = OffPeakFraction
}
behavior Guidance:SetSpeed {
run in parallel
set speed = Speed
}
behavior Guidance:DepthEnvelope {
run in parallel
set minDepth = YoYoMinDepth
set maxDepth = YoYoMaxDepth
set downPitch = YoYoDownPitch
set upPitch = YoYoUpPitch
}
behavior Guidance:YoYo {
run in parallel
set downPitch = YoYoDownPitch
set upPitch = YoYoUpPitch
}
aggregate PatchDetectHorizontal {
run in sequence repeat=Repeat
aggregate PatchDetection {
run when ( PatchDetectOn )
behavior Trigger:PeakDetectHorizontal id="PeakDetectHorizontalTrigger" {
run in sequence
break if ( WpDone )
set patchTracking = PatchTrackingHorizontal
set detectFrom = Science:PeakChl
set depthFrom = Science:PeakChlDepth
set latitudeFrom = Science:PeakChlLatitude
set longitudeFrom = Science:PeakChlLongitude
set beginThreshold = BeginThreshold
set offPeakFraction = OffPeakFraction
set filterWidth = FilterWidth
set numProfilesSlidingwindow = NumOfProfilesSlidingwindow
set centerPeak = PatchMode
outputArg PatchChl = peakDetect
outputArg PatchChlDepth = peakDepth
outputArg PatchChlLatitude = peakLatitude
outputArg PatchChlLongitude = peakLongitude
outputArg PatchChlDistance = peakDistance
}
syslog important "Fell below OffPeakFraction. Patch value is " + PatchChl~microgram_per_liter
+ " at lat = " + PatchChlLatitude~degree + ", lon = " + PatchChlLongitude~degree + ", dep = "
+ PatchChlDepth~meter + ", distance = " + PatchChlDistance~meter
sendData service=express (
PatchChl,
PatchChlDepth,
PatchChlLatitude,
PatchChlLongitude
)
assign id="AssignPatchDetectOff" in sequence PatchDetectOn = false
}
assign id="AssignPatchDetectOn" in sequence PatchDetectOn = true
syslog important "Next: bearing for CrossLeg: " + WpBearing~degree + ". WpMaxDistance = "
+ WpMaxDistance~meter + ". Current lat, lon = " + Universal:latitude~degree + ", "
+ Universal:longitude~degree + "."
aggregate CrossLeg {
"""
This is a long leg across the width of the patch. Also the first
leg in a mission run. Two waypoints run in parallel: a short run
to the surfacing point, and a longer run to the edge of the
patch.
"""
run in sequence
break if (
WpDone
or ( PatchDetectOn == false )
)
behavior Guidance:Waypoint id="CrossSurfaceWp" {
run in sequence
timeout duration=WpTimeout
set distanceDelta = PatchChlDistance
set distanceDeltaBearing = WpBearing
set waterFrame = WaterFrame
}
call refId="SurfaceComms"
behavior Guidance:Waypoint id="CrossPeakWp" {
run in sequence
timeout duration=WpTimeout
set distanceDelta = WpMaxDistance
set distanceDeltaBearing = WpBearing
set waterFrame = WaterFrame
}
syslog important "CrossPeakWp done. Lat, lon = " + Universal:latitude~degree + ", "
+ Universal:longitude~degree + ". Patch value is " + PatchChl~microgram_per_liter + " at lat = "
+ PatchChlLatitude~degree + ", lon = " + PatchChlLongitude~degree + ", dep = "
+ PatchChlDepth~meter + ", distance = " + PatchChlDistance~meter
assign id="AssignPatchDetectOffInCrossLeg" in sequence PatchDetectOn = false
assign id="AssignWpDoneInCrossLeg" in sequence WpDone = true
}
assign id="AssignWpBearingForInLeg" in sequence WpBearing = ( WpBearing + Reverse ) % TwoPi
syslog important "Next: bearing for InLeg: " + WpBearing~degree + ". Current lat, lon = "
+ Universal:latitude~degree + ", " + Universal:longitude~degree + ". Patch value is "
+ PatchChl~microgram_per_liter + " at lat = " + PatchChlLatitude~degree + ", lon = "
+ PatchChlLongitude~degree + ", dep = " + PatchChlDepth~meter + ", distance = "
+ PatchChlDistance~meter
behavior Guidance:Waypoint id="InLegWp" {
"""
Simply drive back towards the patch center
"""
run in sequence
timeout duration=WpTimeout
set distanceDelta = PatchChlDistance
set distanceDeltaBearing = WpBearing
set waterFrame = WaterFrame
}
assign id="AssignWpBearingForOutLeg" in sequence WpBearing = ( WpBearing - Turn ) % TwoPi
syslog important "Next: bearing for OutLeg: " + WpBearing~degree + ". WpMaxDistance = "
+ WpMaxDistance~meter + ". Current lat, lon = " + Universal:latitude~degree + ", "
+ Universal:longitude~degree + ". Patch value is " + PatchChl~microgram_per_liter + " at lat = "
+ PatchChlLatitude~degree + ", lon = " + PatchChlLongitude~degree + ", dep = "
+ PatchChlDepth~meter + ", distance = " + PatchChlDistance~meter
call refId="SurfaceCommsSplit"
assign id="AssignPatchDetectOnForOutLeg" in sequence PatchDetectOn = true
aggregate OutLeg {
"""
Drive outward until edge of patch is detected.
"""
run in sequence
break if (
WpDone
or ( PatchDetectOn == false )
)
behavior Guidance:Waypoint id="OutLegWp" {
run in sequence
timeout duration=WpTimeout
set distanceDelta = WpMaxDistance
set distanceDeltaBearing = WpBearing
set waterFrame = WaterFrame
}
assign id="AssignPatchDetectOffInOutLeg" in sequence PatchDetectOn = false
assign id="AssignWpDoneInOutLeg" in sequence WpDone = true
}
assign id="AssignWpBearingForCrossLeg" in sequence WpBearing = ( WpBearing + Reverse ) % TwoPi
}
}
|