openc3-cosmos-geosim 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,624 @@
1
+ # encoding: ascii-8bit
2
+
3
+ # Copyright 2022 OpenC3, Inc.
4
+ # All Rights Reserved.
5
+ #
6
+ # This program is free software; you can modify and/or redistribute it
7
+ # under the terms of the GNU Affero General Public License
8
+ # as published by the Free Software Foundation; version 3 with
9
+ # attribution addendums as found in the LICENSE.txt
10
+ #
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU Affero General Public License for more details.
15
+
16
+ # Simulates the fake satellite used in COSMOS User Training
17
+
18
+ require 'openc3'
19
+
20
+ module OpenC3
21
+ MAX_PWR_WATT_SECONDS = 100000
22
+ INIT_PWR_WATT_SECONDS = 25000
23
+ HYSTERESIS = 2.0
24
+
25
+ # Simulated satellite for the training. Populates several packets and cycles
26
+ # the telemetry to simulate a real satellite.
27
+ class SimSat < SimulatedTarget
28
+ def initialize(target_name)
29
+ super(target_name)
30
+
31
+ @target = System.targets[target_name]
32
+ position_filename = File.join(@target.dir, 'data', 'position.bin')
33
+ attitude_filename = File.join(@target.dir, 'data', 'attitude.bin')
34
+ @position_file = File.open(position_filename, 'rb')
35
+ @attitude_file = File.open(attitude_filename, 'rb')
36
+ @position_file_size = File.size(position_filename)
37
+ @attitude_file_size = File.size(attitude_filename)
38
+ @position_file_bytes_read = 0
39
+ @attitude_file_bytes_read = 0
40
+
41
+ @pos_packet = Structure.new(:BIG_ENDIAN)
42
+ @pos_packet.append_item('DAY', 16, :UINT)
43
+ @pos_packet.append_item('MSOD', 32, :UINT)
44
+ @pos_packet.append_item('USOMS', 16, :UINT)
45
+ @pos_packet.append_item('POSX', 32, :FLOAT)
46
+ @pos_packet.append_item('POSY', 32, :FLOAT)
47
+ @pos_packet.append_item('POSZ', 32, :FLOAT)
48
+ @pos_packet.append_item('SPARE1', 16, :UINT)
49
+ @pos_packet.append_item('SPARE2', 32, :UINT)
50
+ @pos_packet.append_item('SPARE3', 16, :UINT)
51
+ @pos_packet.append_item('VELX', 32, :FLOAT)
52
+ @pos_packet.append_item('VELY', 32, :FLOAT)
53
+ @pos_packet.append_item('VELZ', 32, :FLOAT)
54
+ @pos_packet.append_item('SPARE4', 32, :UINT)
55
+ @pos_packet.enable_method_missing
56
+
57
+ @att_packet = Structure.new(:BIG_ENDIAN)
58
+ @att_packet.append_item('DAY', 16, :UINT)
59
+ @att_packet.append_item('MSOD', 32, :UINT)
60
+ @att_packet.append_item('USOMS', 16, :UINT)
61
+ @att_packet.append_item('Q1', 32, :FLOAT)
62
+ @att_packet.append_item('Q2', 32, :FLOAT)
63
+ @att_packet.append_item('Q3', 32, :FLOAT)
64
+ @att_packet.append_item('Q4', 32, :FLOAT)
65
+ @att_packet.append_item('BIASX', 32, :FLOAT)
66
+ @att_packet.append_item('BIASY', 32, :FLOAT)
67
+ @att_packet.append_item('BIASZ', 32, :FLOAT)
68
+ @att_packet.append_item('SPARE', 32, :FLOAT)
69
+ @att_packet.enable_method_missing
70
+
71
+ # Initialize fixed parts of packets
72
+ packet = @tlm_packets['HEALTH_STATUS']
73
+ packet.enable_method_missing
74
+ packet.CcsdsSeqFlags = 'NOGROUP'
75
+ packet.CcsdsLength = packet.buffer.length - 7
76
+
77
+ packet = @tlm_packets['THERMAL']
78
+ packet.enable_method_missing
79
+ packet.CcsdsSeqFlags = 'NOGROUP'
80
+ packet.CcsdsLength = packet.buffer.length - 7
81
+
82
+ packet = @tlm_packets['EVENT']
83
+ packet.enable_method_missing
84
+ packet.CcsdsSeqFlags = 'NOGROUP'
85
+ packet.CcsdsLength = packet.buffer.length - 7
86
+
87
+ packet = @tlm_packets['ADCS']
88
+ packet.enable_method_missing
89
+ packet.CcsdsSeqFlags = 'NOGROUP'
90
+ packet.CcsdsLength = packet.buffer.length - 7
91
+
92
+ packet = @tlm_packets['IMAGE']
93
+ packet.enable_method_missing
94
+ packet.CcsdsSeqFlags = 'NOGROUP'
95
+ packet.image = ("\x05" * 10000) + "The Secret is Astral Body"
96
+ packet.CcsdsLength = packet.buffer.length - 7
97
+
98
+ packet = @tlm_packets['MECH']
99
+ packet.enable_method_missing
100
+ packet.CcsdsSeqFlags = 'NOGROUP'
101
+ packet.CcsdsLength = packet.buffer.length - 7
102
+
103
+ packet = @tlm_packets['IMAGER']
104
+ packet.enable_method_missing
105
+ packet.CcsdsSeqFlags = 'NOGROUP'
106
+ packet.CcsdsLength = packet.buffer.length - 7
107
+
108
+ @get_count = 0
109
+ @queue = Queue.new
110
+
111
+ # ADCS
112
+ @trackStars = Array.new
113
+ @trackStars[0] = 1237
114
+ @trackStars[1] = 1329
115
+ @trackStars[2] = 1333
116
+ @trackStars[3] = 1139
117
+ @trackStars[4] = 1161
118
+ @trackStars[5] = 682
119
+ @trackStars[6] = 717
120
+ @trackStars[7] = 814
121
+ @trackStars[8] = 583
122
+ @trackStars[9] = 622
123
+ @adcs_ctrl = 'OFF'
124
+ @sr_ang_to_sun = 0
125
+
126
+ # HEALTH_STATUS
127
+ @cmd_acpt_cnt = 0
128
+ @cmd_rjct_cnt = 0
129
+ @mode = 'SAFE'
130
+ @cpu_pwr = 100
131
+ @table_data = "\x00" * 10
132
+
133
+ # THERMAL
134
+ @temp1 = 0
135
+ @temp2 = 0
136
+ @heater1_ctrl = 'OFF'
137
+ @heater1_state = 'OFF'
138
+ @heater1_setpt = 0.0
139
+ @heater1_pwr = 0.0
140
+ @heater2_ctrl = 'OFF'
141
+ @heater2_state = 'OFF'
142
+ @heater2_setpt = 0.0
143
+ @heater2_pwr = 0.0
144
+
145
+ # MECH
146
+ @slrpnl1_ang = 180.0
147
+ @slrpnl2_ang = 180.0
148
+ @slrpnl1_state = 'STOWED'
149
+ @slrpnl2_state = 'STOWED'
150
+ @slrpnl1_pwr = 0.0
151
+ @slrpnl2_pwr = 0.0
152
+ @pwr_watt_seconds = INIT_PWR_WATT_SECONDS
153
+ @battery = (@pwr_watt_seconds.to_f / MAX_PWR_WATT_SECONDS.to_f) * 100.0
154
+
155
+ # IMAGER
156
+ @collects = 0
157
+ @duration = 10
158
+ @collect_type = 'NORMAL'
159
+ @imager_state = 'OFF'
160
+ @imager_pwr = 0.0
161
+ @collect_end_time = nil
162
+ end
163
+
164
+ def set_rates
165
+ set_rate('ADCS', 10)
166
+ set_rate('HEALTH_STATUS', 100)
167
+ set_rate('THERMAL', 100)
168
+ set_rate('MECH', 100)
169
+ set_rate('IMAGER', 100)
170
+ end
171
+
172
+ def accept_cmd(message = nil)
173
+ if message
174
+ event_packet = @tlm_packets['EVENT']
175
+ event_packet.message = message
176
+ time = Time.now
177
+ event_packet.timesec = time.tv_sec
178
+ event_packet.timeus = time.tv_usec
179
+ event_packet.ccsdsseqcnt += 1
180
+ @queue << event_packet.dup
181
+ end
182
+ @cmd_acpt_cnt += 1
183
+ end
184
+
185
+ def reject_cmd(message)
186
+ event_packet = @tlm_packets['EVENT']
187
+ event_packet.message = message
188
+ time = Time.now
189
+ event_packet.timesec = time.tv_sec
190
+ event_packet.timeus = time.tv_usec
191
+ event_packet.ccsdsseqcnt += 1
192
+ @queue << event_packet.dup
193
+ @cmd_rjct_cnt += 1
194
+ end
195
+
196
+ def write(packet)
197
+ name = packet.packet_name.upcase
198
+
199
+ case name
200
+ when 'COLLECT'
201
+ if @mode == 'OPERATE'
202
+ @collects += 1
203
+ @duration = packet.read('duration')
204
+ @collect_type = packet.read("type")
205
+ @collect_end_time = Time.now + @duration
206
+ accept_cmd()
207
+ else
208
+ reject_cmd("Mode must be OPERATE to collect images")
209
+ end
210
+
211
+ when 'ABORT'
212
+ @collect_end_time = nil
213
+ accept_cmd()
214
+
215
+ when 'CLEAR'
216
+ accept_cmd()
217
+ @collects = 0
218
+ @cmd_acpt_cnt = 0
219
+ @cmd_rjct_cnt = 0
220
+
221
+ when 'SET_MODE'
222
+ mode = packet.read('mode')
223
+ case mode
224
+ when 'SAFE'
225
+ @mode = mode
226
+ accept_cmd()
227
+ when 'CHECKOUT'
228
+ if @battery >= 50.0
229
+ @mode = mode
230
+ accept_cmd()
231
+ else
232
+ reject_cmd("Cannot enter checkout if battery < 50.0%")
233
+ end
234
+ when 'OPERATE'
235
+ if @temp1 < 35.0 and @temp1 > 25.0 and @temp2 < 35.0 and @temp2 > 25.0
236
+ @mode = mode
237
+ accept_cmd()
238
+ else
239
+ reject_cmd("Cannot enter OPERATE unless temperatures are stable near 30.0")
240
+ end
241
+ else
242
+ reject_cmd("Invalid Mode: #{mode}")
243
+ end
244
+
245
+ when 'SLRPNLDEPLOY'
246
+ num = packet.read('NUM')
247
+ case num
248
+ when 1
249
+ @slrpnl1_state = 'DEPLOYED'
250
+ accept_cmd()
251
+ when 2
252
+ @slrpnl2_state = 'DEPLOYED'
253
+ accept_cmd()
254
+ else
255
+ reject_cmd("Invalid Solar Array Number: #{num}")
256
+ end
257
+
258
+ when 'SLRPNLSTOW'
259
+ num = packet.read('NUM')
260
+ case num
261
+ when 1
262
+ @slrpnl1_state = 'STOWED'
263
+ accept_cmd()
264
+ when 2
265
+ @slrpnl2_state = 'STOWED'
266
+ accept_cmd()
267
+ else
268
+ reject_cmd("Invalid Solar Array Number: #{num}")
269
+ end
270
+
271
+ when 'SLRPNLANG'
272
+ num = packet.read('NUM')
273
+ ang = packet.read('ANG')
274
+ case num
275
+ when 1
276
+ case ang
277
+ when 0..360
278
+ @slrpnl1_ang = ang
279
+ accept_cmd()
280
+ else
281
+ reject_cmd("Invalid Solar Array Angle: #{setpt}")
282
+ end
283
+ when 2
284
+ case ang
285
+ when 0..360
286
+ @slrpnl2_ang = ang
287
+ accept_cmd()
288
+ else
289
+ reject_cmd("Invalid Solar Array Angle: #{setpt}")
290
+ end
291
+ else
292
+ reject_cmd("Invalid Solar Array Number: #{num}")
293
+ end
294
+
295
+ when 'TABLE_LOAD'
296
+ @table_data = packet.read('DATA')
297
+
298
+ when 'HTR_CTRL'
299
+ num = packet.read('NUM')
300
+ state = packet.read('STATE')
301
+ case num
302
+ when 1
303
+ case state
304
+ when 'ON', 'OFF'
305
+ @heater1_ctrl = state
306
+ accept_cmd()
307
+ else
308
+ reject_cmd("Invalid Heater Control: #{state}")
309
+ end
310
+ when 2
311
+ case state
312
+ when 'ON', 'OFF'
313
+ @heater2_ctrl = state
314
+ accept_cmd()
315
+ else
316
+ reject_cmd("Invalid Heater Control: #{state}")
317
+ end
318
+ else
319
+ reject_cmd("Invalid Heater Number: #{num}")
320
+ end
321
+
322
+ when 'HTR_STATE'
323
+ num = packet.read('NUM')
324
+ state = packet.read('STATE')
325
+ case num
326
+ when 1
327
+ case state
328
+ when 'ON', 'OFF'
329
+ @heater1_state = state
330
+ accept_cmd()
331
+ else
332
+ reject_cmd("Invalid Heater State: #{state}")
333
+ end
334
+ when 2
335
+ case state
336
+ when 'ON', 'OFF'
337
+ @heater2_state = state
338
+ accept_cmd()
339
+ else
340
+ reject_cmd("Invalid Heater State: #{state}")
341
+ end
342
+ else
343
+ reject_cmd("Invalid Heater Number: #{num}")
344
+ end
345
+
346
+ when 'HTR_SETPT'
347
+ num = packet.read('NUM')
348
+ setpt = packet.read('SETPT')
349
+ case num
350
+ when 1
351
+ case setpt
352
+ when -100..100
353
+ @heater1_setpt = setpt
354
+ accept_cmd()
355
+ else
356
+ reject_cmd("Invalid Heater Setpoint: #{setpt}")
357
+ end
358
+ when 2
359
+ case setpt
360
+ when -100..100
361
+ @heater2_setpt = setpt
362
+ accept_cmd()
363
+ else
364
+ reject_cmd("Invalid Heater Setpoint: #{setpt}")
365
+ end
366
+ else
367
+ reject_cmd("Invalid Heater Number: #{num}")
368
+ end
369
+
370
+ when 'ADCS_CTRL'
371
+ state = packet.read('STATE')
372
+ case state
373
+ when 'ON', 'OFF'
374
+ @adcs_ctrl = state
375
+ accept_cmd()
376
+ else
377
+ reject_cmd("Invalid ADCS Control: #{state}")
378
+ end
379
+ end
380
+ end
381
+
382
+ def graceful_kill
383
+ end
384
+
385
+ def get_pending_packets(count_100hz)
386
+ pending_packets = super(count_100hz)
387
+ while @queue.length > 0
388
+ pending_packets << @queue.pop
389
+ end
390
+ pending_packets
391
+ end
392
+
393
+ def read(count_100hz, time)
394
+ pending_packets = get_pending_packets(count_100hz)
395
+
396
+ pending_packets.each do |packet|
397
+ case packet.packet_name
398
+ when 'ADCS'
399
+ # Read 44 Bytes for Position Data
400
+ pos_data = nil
401
+ begin
402
+ pos_data = @position_file.read(44)
403
+ @position_file_bytes_read += 44
404
+ rescue
405
+ # Do Nothing
406
+ end
407
+
408
+ if pos_data.nil? or pos_data.length == 0
409
+ # Assume end of file - close and reopen
410
+ @position_file.close
411
+ @position_file = File.open(File.join(@target.dir, 'data', 'position.bin'), 'rb')
412
+ pos_data = @position_file.read(44)
413
+ @position_file_bytes_read = 44
414
+ end
415
+
416
+ @pos_packet.buffer = pos_data
417
+ packet.posx = @pos_packet.posx
418
+ packet.posy = @pos_packet.posy
419
+ packet.posz = @pos_packet.posz
420
+ packet.velx = @pos_packet.velx
421
+ packet.vely = @pos_packet.vely
422
+ packet.velz = @pos_packet.velz
423
+
424
+ # Read 40 Bytes for Attitude Data
425
+ att_data = nil
426
+ begin
427
+ att_data = @attitude_file.read(40)
428
+ @attitude_file_bytes_read += 40
429
+ rescue
430
+ # Do Nothing
431
+ end
432
+
433
+ if att_data.nil? or att_data.length == 0
434
+ @attitude_file.close
435
+ @attitude_file = File.open(File.join(@target.dir, 'data', 'attitude.bin'), 'rb')
436
+ att_data = @attitude_file.read(40)
437
+ @attitude_file_bytes_read = 40
438
+ end
439
+
440
+ @att_packet.buffer = att_data
441
+ packet.q1 = @att_packet.q1
442
+ packet.q2 = @att_packet.q2
443
+ packet.q3 = @att_packet.q3
444
+ packet.q4 = @att_packet.q4
445
+ packet.biasx = @att_packet.biasx
446
+ packet.biasy = @att_packet.biasy
447
+ packet.biasy = @att_packet.biasz
448
+
449
+ packet.star1id = @trackStars[((@get_count / 100) + 0) % 10]
450
+ packet.star2id = @trackStars[((@get_count / 100) + 1) % 10]
451
+ packet.star3id = @trackStars[((@get_count / 100) + 2) % 10]
452
+ packet.star4id = @trackStars[((@get_count / 100) + 3) % 10]
453
+ packet.star5id = @trackStars[((@get_count / 100) + 4) % 10]
454
+
455
+ packet.posprogress = (@position_file_bytes_read.to_f / @position_file_size.to_f) * 100.0
456
+ packet.attprogress = (@attitude_file_bytes_read.to_f / @attitude_file_size.to_f) * 100.0
457
+ @sr_ang_to_sun = packet.posprogress * 3.6
458
+ packet.sr_ang_to_sun = @sr_ang_to_sun
459
+ packet.adcs_ctrl = @adcs_ctrl
460
+
461
+ packet.timesec = time.tv_sec
462
+ packet.timeus = time.tv_usec
463
+ packet.ccsdsseqcnt += 1
464
+
465
+ when 'HEALTH_STATUS'
466
+ packet.timesec = time.tv_sec
467
+ packet.timeus = time.tv_usec
468
+ packet.ccsdsseqcnt += 1
469
+
470
+ packet.cmd_acpt_cnt = @cmd_acpt_cnt
471
+ packet.cmd_rjct_cnt = @cmd_rjct_cnt
472
+ packet.mode = @mode
473
+ packet.cpu_pwr = @cpu_pwr
474
+ packet.table_data = @table_data
475
+
476
+ when 'THERMAL'
477
+ packet.timesec = time.tv_sec
478
+ packet.timeus = time.tv_usec
479
+ packet.ccsdsseqcnt += 1
480
+
481
+ if @heater1_ctrl == 'ON'
482
+ if @temp1 < (@heater1_setpt - HYSTERESIS)
483
+ @heater1_state = 'ON'
484
+ elsif @temp1 > (@heater1_setpt + HYSTERESIS)
485
+ @heater1_state = 'OFF'
486
+ end
487
+ end
488
+
489
+ if @heater2_ctrl == 'ON'
490
+ if @temp2 < (@heater2_setpt - HYSTERESIS)
491
+ @heater2_state = 'ON'
492
+ elsif @temp2 > (@heater2_setpt + HYSTERESIS)
493
+ @heater2_state = 'OFF'
494
+ end
495
+ end
496
+
497
+ if @heater1_state == 'ON'
498
+ @heater1_pwr = 300
499
+ @temp1 += 0.5
500
+ if @temp1 > 50.0
501
+ @temp1 = 50.0
502
+ end
503
+ else
504
+ @heater1_pwr = 0
505
+ @temp1 -= 0.1
506
+ if @temp1 < -20.0
507
+ @temp1 = -20.0
508
+ end
509
+ end
510
+
511
+ if @heater2_state == 'ON'
512
+ @heater2_pwr = 300
513
+ @temp2 += 0.5
514
+ if @temp2 > 100.0
515
+ @temp2 = 100.0
516
+ end
517
+ else
518
+ @heater2_pwr = 0
519
+ @temp2 -= 0.1
520
+ if @temp2 < -20.0
521
+ @temp2 = -20.0
522
+ end
523
+ end
524
+
525
+ packet.heater1_ctrl = @heater1_ctrl
526
+ packet.heater1_state = @heater1_state
527
+ packet.heater1_setpt = @heater1_setpt
528
+ packet.heater1_pwr = @heater1_pwr
529
+ packet.heater2_ctrl = @heater2_ctrl
530
+ packet.heater2_state = @heater2_state
531
+ packet.heater2_setpt = @heater2_setpt
532
+ packet.heater2_pwr = @heater2_pwr
533
+ packet.temp1 = @temp1
534
+ packet.temp2 = @temp2
535
+
536
+ when 'MECH'
537
+ if @adcs_ctrl == 'ON'
538
+ @slrpnl1_ang = @sr_ang_to_sun
539
+ @slrpnl2_ang = @sr_ang_to_sun
540
+ end
541
+
542
+ delta_ang = (@sr_ang_to_sun - @slrpnl1_ang).abs
543
+ if delta_ang > 180.0
544
+ delta_ang = 360 - delta_ang
545
+ end
546
+ if @slrpnl1_state == 'DEPLOYED'
547
+ @slrpnl1_pwr = 500 * (1 - (delta_ang / 180.0))
548
+ else
549
+ @slrpnl1_pwr = 0
550
+ end
551
+
552
+ delta_ang = (@sr_ang_to_sun - @slrpnl2_ang).abs
553
+ if delta_ang > 180.0
554
+ delta_ang = 360 - delta_ang
555
+ end
556
+ if @slrpnl2_state == 'DEPLOYED'
557
+ @slrpnl2_pwr = 500 * (1 - (delta_ang / 180.0))
558
+ else
559
+ @slrpnl2_pwr = 0
560
+ end
561
+
562
+ incoming_pwr = @slrpnl1_pwr + @slrpnl2_pwr # Upto 1000 per second
563
+
564
+ used_pwr = @cpu_pwr + @imager_pwr + @heater1_pwr + @heater2_pwr # Up to 900 per second
565
+ delta_pwr = incoming_pwr - used_pwr
566
+ @pwr_watt_seconds += delta_pwr
567
+ if @pwr_watt_seconds < 0
568
+ @pwr_watt_seconds = 100
569
+ elsif @pwr_watt_seconds > MAX_PWR_WATT_SECONDS
570
+ @pwr_watt_seconds = MAX_PWR_WATT_SECONDS
571
+ end
572
+ @battery = (@pwr_watt_seconds.to_f / MAX_PWR_WATT_SECONDS.to_f) * 100.0
573
+ if @battery < 50.0
574
+ @mode = 'SAFE'
575
+ end
576
+
577
+ packet.timesec = time.tv_sec
578
+ packet.timeus = time.tv_usec
579
+ packet.ccsdsseqcnt += 1
580
+ packet.slrpnl1_ang = @slrpnl1_ang
581
+ packet.slrpnl2_ang = @slrpnl2_ang
582
+ packet.slrpnl1_state = @slrpnl1_state
583
+ packet.slrpnl2_state = @slrpnl2_state
584
+ packet.slrpnl1_pwr = @slrpnl1_pwr
585
+ packet.slrpnl2_pwr = @slrpnl2_pwr
586
+ packet.battery = @battery
587
+
588
+ when 'IMAGER'
589
+ if @collect_end_time
590
+ if @collect_end_time < Time.now
591
+ @imager_state = 'OFF'
592
+ @collect_end_time = nil
593
+ @imager_pwr = 0
594
+ image_packet = @tlm_packets['IMAGE']
595
+ time = Time.now
596
+ image_packet.timesec = time.tv_sec
597
+ image_packet.timeus = time.tv_usec
598
+ image_packet.ccsdsseqcnt += 1
599
+ @queue << image_packet.dup
600
+ else
601
+ @imager_state = 'ON'
602
+ @imager_pwr = 200
603
+ end
604
+ else
605
+ @imager_pwr = 0
606
+ end
607
+
608
+ packet.timesec = time.tv_sec
609
+ packet.timeus = time.tv_usec
610
+ packet.ccsdsseqcnt += 1
611
+ packet.collects = @collects
612
+ packet.duration = @duration
613
+ packet.collect_type = @collect_type
614
+ packet.imager_state = @imager_state
615
+ packet.imager_pwr = @imager_pwr
616
+
617
+ end
618
+ end
619
+
620
+ @get_count += 1
621
+ pending_packets
622
+ end
623
+ end
624
+ end
@@ -0,0 +1,30 @@
1
+ # Ignored Parameters
2
+ IGNORE_PARAMETER CCSDSVER
3
+ IGNORE_PARAMETER CCSDSTYPE
4
+ IGNORE_PARAMETER CCSDSSHF
5
+ IGNORE_PARAMETER CCSDSAPID
6
+ IGNORE_PARAMETER CCSDSSEQFLAGS
7
+ IGNORE_PARAMETER CCSDSSEQCNT
8
+ IGNORE_PARAMETER CCSDSLENGTH
9
+ IGNORE_PARAMETER PKTID
10
+
11
+ # Ignored Items
12
+ IGNORE_ITEM CCSDSVER
13
+ IGNORE_ITEM CCSDSTYPE
14
+ IGNORE_ITEM CCSDSSHF
15
+ IGNORE_ITEM CCSDSAPID
16
+ IGNORE_ITEM CCSDSSEQFLAGS
17
+ IGNORE_ITEM CCSDSSEQCNT
18
+ IGNORE_ITEM CCSDSLENGTH
19
+ IGNORE_ITEM PACKET_TIME
20
+ IGNORE_ITEM PACKET_TIMESECONDS
21
+ IGNORE_ITEM RECEIVED_TIMESECONDS
22
+ IGNORE_ITEM TIMESEC
23
+ IGNORE_ITEM TIMEUS
24
+ IGNORE_ITEM PKTID
25
+
26
+ # Explicitly define command and telemetry files
27
+ # If not given then all the files in cmd/tlm will be processed in
28
+ # alphabetical order
29
+ COMMANDS cmds.txt
30
+ TELEMETRY tlm.txt
data/plugin.txt ADDED
@@ -0,0 +1,9 @@
1
+ # Set VARIABLEs here to allow variation in your plugin
2
+ # See https://openc3.com/docs/v5/plugins for more information
3
+ VARIABLE geosim_port 7272
4
+ VARIABLE geosim_microservice_name GEOSIM
5
+
6
+ MICROSERVICE GEOSIM <%= geosim_microservice_name %>
7
+ WORK_DIR .
8
+ PORT <%= geosim_port %>
9
+ CMD ruby geosat_target.rb <%= geosim_port %>