openc3-cosmos-geosim 1.0.0

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.
@@ -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 %>