-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtcs-sim.tcl
executable file
·2914 lines (2276 loc) · 81.8 KB
/
tcs-sim.tcl
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
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#!/usr/bin/tclsh
################################################################################
proc ShowUsage {} {
puts "\n Usage: tcs-sim.tcl <LOCATION> \[-ver\]\n \[-fast\]"
}
################################################################################
proc deg2rad { deg } {
global pi
set rad [ expr {($deg * $pi) / 180.0} ]
return $rad
}
################################################################################
proc sex2dec { sexvalue } {
set place1 ""
set place2 ""
set place3 ""
scan $sexvalue {%3d:%2d:%4f} place1 place2 place3
# if the string is malformatted, return some diagnostics consistent w/ real TCS-NG
if {$place1 == ""} {
return -1
}
if {$place2 == ""} {
return -2
}
if {$place3 == ""} {
return -3
}
set decval [expr {abs($place1) + $place2 / 60.0 + $place3 / 3600.0}]
if {[string index $sexvalue 0] == "-"} {
set decval [ expr {$decval * -1.0} ]
}
return $decval
}
################################################################################
# proc to calculate julian date given the calendar date
# input is year (integer), month (integer) and UT day (decimal)
# returns decimal julian date
# From "Astronomical Algorithms" by J. Meeus
# Copyright 1991, First Edition
# Page 61
proc cd2jd { y m d } {
if {$m <= 2} {
set y [expr {$y - 1}]
set m [expr {$m + 12}]
}
set a [expr {int($y / 100)}]
set b [expr {2 - $a + int($a / 4)}]
set jd [ format "%14.6f" [expr {int(365.25 * ($y + 4716)) + int(30.600001 * ($m + 1)) + $d + $b - 1524.5}] ]
return $jd
}
################################################################################
# proc to calculate MEAN siderial time at greenwich UT julian date
# returns decimal hours
# From "Astronomical Algorithms" by J. Meeus
# Copyright 1991, First Edition
# Page 83
proc SiderealTime { jdut } {
set T [expr {($jdut - 2451545.0) / 36525}]
set T2 [expr {$T * $T}]
set T3 [expr {$T2 * $T}]
set mst [expr {280.46061837 + 360.98564736629 * ($jdut - 2451545.0) + 0.000387933 * $T2 - $T3 / 38710000}]
if {$mst < 0} {
set mst [expr {$mst - ((int($mst/360.0) - 1.0) * 360.0)}]
} else {
set mst [expr {$mst - (int($mst/360.0) * 360.0)}]
}
set mst [expr {$mst / 15.0}]
return $mst
}
################################################################################
# proc to calculate RA given altitude and azimuth
# in decimal degrees, siderial time at greenwich in decimal hours,
# observatory latitude and longitude in decimal degrees
# RA and Dec is returned as a 2-element list:
# { RA (decimal hrs) Dec (decimal degrees) }
# From Patrick Wallace's H2E.f routine - SLALIB Library
# note Azimuth is reckoned as 0 degrees is North and moving
# through East, South, and then West
proc e2h { alt az st lat long } {
global radian
set cosphi [expr {cos($lat/$radian)}]
set sinphi [expr {sin($lat/$radian)}]
set cosA [expr {cos($az/$radian)}]
set sinA [expr {sin($az/$radian)}]
set cosh [expr {cos($alt/$radian)}]
set sinh [expr {sin($alt/$radian)}]
set x [expr {-$cosA * $cosh * $sinphi + $sinh * $cosphi}]
set y [expr {-$sinA * $cosh}]
set z [expr {$cosA * $cosh * $cosphi + $sinh * $sinphi}]
set r [expr {sqrt($x * $x + $y * $y)}]
if {$r == 0.0} {
set H 0.0
} else {
set H [expr {atan2($y,$x) * $radian}]
}
set ra [expr {$st - $long/15.0 - $H/15.0}]
if {$ra < 0} {
set ra [expr {$ra + 24.0}]
}
set dec [expr {atan2($z,$r) * $radian}]
return [list $ra $dec]
}
################################################################################
proc TCSradec2azel { ra dec } {
# distilled from A.R.Gibbs' skycoor class
# ra and dec given in decimal hours (ra) and decimal degrees (dec).
# az, el returned in decimal degrees
# renamed from radec2azel to not collide with definition in astrolib.tcl
global gobslat gobslong pi simTime
set lha [ SimLHA $simTime(currentLST) $ra ]
set fMST [ deg2rad [ expr {15 * $simTime(currentGMST)} ] ]
set fLat [ deg2rad $gobslat ]
set fLon [ deg2rad $gobslong ]
set fRA [ deg2rad [ expr {15 * $ra} ] ]
set fDec [ deg2rad $dec ]
set fHA [ expr {[ deg2rad [ expr {15 * $lha} ]]} ]
set fX [expr {cos ($fLat) * sin ($fDec) - sin ($fLat) * cos ($fDec) * cos ($fHA)}]
set fY [expr {-cos ($fDec) * sin ($fHA)}]
set fAz [expr {atan2 ($fY, $fX)}]
if {$fAz < 0.0} { set fAz [expr {2.0 * $pi + $fAz}] }
set fCosAlt [expr {sqrt ($fX * $fX + $fY * $fY)}]
set fSinAlt [expr {sin ($fDec) * sin ($fLat) + cos ($fDec) * cos ($fLat) * cos ($fHA)}]
set fAlt [expr {atan2 ($fSinAlt, $fCosAlt)}]
set fAlt [expr {$fAlt * 180.0 / $pi}]
set fAz [expr {$fAz * 180.0 / $pi}]
# set fHA [expr {$fHA * 180.0 / $pi}]
return [list $fAz $fAlt]
}
################################################################################
proc GetJD { { date "now" } } {
# get the UT date right now:
if {$date == "now"} {
set datestring [ SimReturnDate ]
scan $datestring "%2u/%2u/%4u" month day year
set timestring [ SimReturnTime ]
scan $timestring "%2u:%2u:%2u" hr min sec
} else {
set year [ string range $date 0 3 ]
set month [ string range $date 4 5 ]
set day [ string range $date 6 7 ]
set hr 0
set min 0
set sec 0
}
set julianday [ cd2jd $year $month $day ]
set frac [ expr {($hr / 24.0) + ($min / 1440.0) + ($sec / 86400.0)} ]
set jdnow [ expr {$julianday + $frac} ]
return $jdnow
}
################################################################################
proc SimSysKill {} {
# Kills TCS process after disabling stopping all telescope motion.
set result [ SimDisable 1 ]
set vwait 100
after $vwait { exit }
# bye bye! we just killed ourselves
return "OK"
}
################################################################################
proc SimSysReset { args } {
# can be called with zero or multiple arguments:
# SYSRESET
# SYSRESET TIME MM/DD/YYYY HH:MM:SS
# note: in real TCS, SYSRESET TIME only allowed if time is before Feb. 2013
global simTime simTrack gobslong
set return "OK"
# strip off curly braces:
set args [ string map { "{" "" "}" "" } $args ]
set argc [ llength $args ]
if {$args == ""} {
set simTime(offset) 0
SimInitializeTCS
return $return
}
if {$argc >= 1} {
set firstarg [ lindex $args 0 ]
}
if {$firstarg == "TIME"} {
# we'll simulate a time change by keeping track of an offset between the true current
# time and the desired time, and applying the offset when queried
# first zero out the offset to have the present as a reference:
set simTime(offset) 0
SimInitializeTCS
set timearg ""
set datearg ""
set datearg [ lindex $args 1 ]
set timearg [ lindex $args 2 ]
# calculate the requested date in seconds since 1970:
set result [ clock scan "$datearg $timearg" -gmt 1 ]
# get the current time in seconds since 1970:
set timenow [ GetTimeSeconds ]
if {![ string is integer $result ]} {
return "FAILED"
}
# update the time:
set timediff [ expr {int($result - $timenow)} ]
set simTime(offset) $timediff
# time is changed, go ahead with the initialization
SimInitializeTCS
return "OK"
} else {
return "UNKNOWN_CMD"
}
}
################################################################################
proc SimSysSave {} {
SimWriteFocusFile [ SimReturnFocus ]
return "OK"
}
################################################################################
proc SimReturnSim {} {
# returns "SIM", when queried with "SIM" - TCS-NG will not know how to respond to
# this query, so it's a way to tell if you're talking to a real NG system or a simulator
return "SIM"
}
################################################################################
proc SimReturnTime {} {
# returns the UT time:
global simTime
set timenow [ clock seconds ]
# apply the offset, if nonzero:
if {[ info exists simTime(offset) ]} {
set seconds [ expr {$timenow + $simTime(offset)} ]
set newtime [ clock format "$seconds" -format "%T" -gmt 1 ]
set simTime(currentUT) $newtime
} else {
set simTime(currentUT) [ clock format $timenow -format "%T" -gmt 1 ]
}
# NG returns time to hundredths of a second. Add that here (note that hundredths place
# is truncated, not rounded, but nobody should care):
set frac ".[ string range [ clock clicks -milliseconds ] end-2 end-1 ]"
append simTime(currentUT) $frac
return $simTime(currentUT)
}
################################################################################
proc SimReturnDate {} {
global simTime
set timenow [ clock seconds ]
if {[ info exists simTime(offset) ]} {
set seconds [ expr {$timenow + $simTime(offset)} ]
set date [ clock format "$seconds" -format "%D" -gmt 1 ]
} else {
set date [ clock format [ clock seconds ] -format "%D" -gmt 1 ]
}
return $date
}
################################################################################
proc SimReturnJD {} {
global simJD
set simJD [ format "%7.1f" [ GetJD ] ]
return $simJD
}
################################################################################
proc SimReturnEpoch {} {
global simEpoch
return $simEpoch
}
################################################################################
proc SimReturnStow { req } {
global stowFile focusFile
if {$req == "focus"} {
set inchannel [ open $focusFile r ]
set line [ gets $inchannel ]
return [ lindex $line 0 ]
}
set inchannel [ open $stowFile r ]
while {![ eof $inchannel ]} {
set line [ gets $inchannel ]
set firstword [ lindex $line 0 ]
set value [ lindex $line 1 ]
if {$firstword == $req} {
close $inchannel
return $value
}
}
return "UNKNOWN_CMD"
close $inchannel
}
################################################################################
proc SimWriteStowFile { dome az el } {
global stowFile
set outchannel [ open $stowFile w+ ]
puts $outchannel "dome $dome"
puts $outchannel "az $az"
puts $outchannel "el $el"
close $outchannel
}
################################################################################
proc SimWriteFocusFile { value } {
global focusFile
set outchannel [ open $focusFile w+ ]
puts $outchannel $value
close $outchannel
}
################################################################################
proc SimReturnHA {} {
global simTime
return $simTime(sexLHA)
}
################################################################################
proc SimReturnFocusSpeed {} {
global simFocSpeed
return $simFocSpeed
}
################################################################################
proc SimReturnRate { rate } {
global simRate
switch $rate {
"guide" { set return $simRate(guide) }
"drift" { set return $simRate(drift) }
default { set return "FAILED" }
}
return $return
}
################################################################################
proc SimReturnPad {} {
}
################################################################################
proc SimSetFocusSpeed { speed } {
global simFocSpeed simFocus
if {$speed == "FAST"} {
set simFocSpeed "FAST"
set simFocus(rate) 100
} else {
# should really test to see if arg is "SLOW", but TCS doesn't so anything that
# is not fast is therefore slow
set simFocSpeed "SLOW"
set simFocus(rate) 2
}
# if a move was in progress, re-start the move with the new focus speed:
SimFocusMove $simFocus(target) 0
return "OK"
}
################################################################################
proc SimSetCorrections { correction state } {
# there appears to be no way to toggle the OBJECT corrections...what are these anyway?
# if state is ON, turn the correction on; any other arg will disable
global simCorr
if {$state == "ON"} {
set value 1
} else {
set value 0
}
switch $correction {
"PROPMO" { set simCorr(propmo) $value }
"PRECES" { set simCorr(preces) $value }
"NUTAT" { set simCorr(nutat) $value }
"ABERRATE" { set simCorr(aberrate) $value }
"REFRAC" { set simCorr(refrac) $value }
"FLEX" { set simCorr(flex) $value }
"PARALLAX" { set simCorr(parallax) $value }
"BIAS" { set simCorr(bias) $value }
default { return "FAILED" }
}
return "OK"
}
################################################################################
proc SimReturnCorrections {} {
# returns a string indicating the status of various corrections. if all corrections
# are active, the string will look like this: MPNARFp+tob if no corrections active,
# will look like this: _______+___
global simTrack simCorr
set corr ""
# proper motion:
if {$simCorr(propmo)} { append corr M } else { append corr _ }
# precession:
if {$simCorr(preces)} { append corr P } else { append corr _ }
# nutation:
if {$simCorr(nutat)} { append corr N } else { append corr _ }
# aberration:
if {$simCorr(aberrate)} { append corr A } else { append corr _ }
# refraction:
if {$simCorr(refrac)} { append corr R } else { append corr _ }
# flexure:
if {$simCorr(flex)} { append corr F } else { append corr _ }
# parallax:
if {$simCorr(parallax)} { append corr p } else { append corr _ }
# add a +
append corr +
# sidereal tracking:
if {$simTrack(tracking)} { append corr t } else { append corr _ }
# object rate:
if {$simCorr(object)} { append corr o } else { append corr _ }
# bias rates active:
if {$simCorr(bias)} { append corr b } else { append corr _ }
return $corr
}
################################################################################
proc SimReturnBeam {} {
# dummy proc: always return "A"
return "A"
}
################################################################################
proc SimReturnMotion {} {
# TCS-NG encodes the motor motion status in an 8-bit integer:
# 64 = ??
# 32 = ??
# 16 = Derotator?
# 8 = Dome
# 4 = Focus
# 2 = Dec
# 1 = RA
global simRA simDEC simDome simFocus
set int 0
if {$simRA(moving)} {
incr int 1
}
if {$simDEC(moving)} {
incr int 2
}
if {$simFocus(moving)} {
incr int 4
}
if {$simDome(moving)} {
incr int 8
}
# convert to hexadecimal (?)
set int [ format "%x" $int ]
return $int
}
################################################################################
proc SimReturnLimits {} {
# TCS-NG encodes the limit status in an 8-bit integer:
# 64 = focus high limit
# 32 = focus low limit
# 16 = horizon soft limit (ignoring this)
# 8 = horizon hard limit (use this)
# 4 = derotator limit (ignore)
# 2 = declination limit (high and low?)
# 1 = RA/HA limit (high and low?)
global simLimit
set int 0
if {$simLimit(FOC+)} {
incr int 64
}
if {$simLimit(FOC-)} {
incr int 32
}
if {$simLimit(HOR)} {
incr int 8
}
if {$simLimit(DEC)} {
incr int 2
}
if {$simLimit(RA)} {
incr int 1
}
set hex [ format "%x" $int ]
# not sure what the second argument refers to:
# "%d %d",limstatus(),inp(DIO_PortC1));
return "$hex 0"
}
################################################################################
proc SimReturnLimitProf {} {
global HorizonList
set numentries [ llength $HorizonList ]
set returnstring ""
for {set i 0} {$i < $numentries} {incr i} {
set index [ expr {$i * 2} ]
append returnstring " [ lindex [ lindex $HorizonList $i ] 1 ]"
}
return $returnstring
}
################################################################################
proc SimReturnFlexFile {} {
set returnstring "dummy pointing model text"
return $returnstring
}
################################################################################
proc SimReturnPEC {} {
global simPEC
# TCS returns 4 PEC-related quantities: pec_condition, pec_count, pec_index, and pec_mode
# pec_condition is the status: 0=OFF/1=ON/2=TRAINING/3=WAITING
# pec_count - how many times the index pulse is passed - unimportant for simulator
# pec_index is whether or not it's synced: 0=WAITING/1=INDEXED
# pec_train is what it was commanded to do: 0=OFF/1=ON/2=TRAINING
# Check and see if the count is high enough to be considered indexed...simulated shortcut, rather
# than simulating an actual index point. Once high enough, change condition from "waiting" to "on"
# condition 3 = WAITING
if {$simPEC(condition) == 3} {
if {$simPEC(count) >= 10} {
set simPEC(index) 1
# condition 1 = ON
set simPEC(condition) 1
}
}
return "$simPEC(condition) $simPEC(count) $simPEC(index) $simPEC(train)"
}
################################################################################
proc SimReturnFocus {} {
global simFocus
SimUpdateFocus
return [ expr {int($simFocus(current))} ]
}
################################################################################
proc SimReturnDome { arg } {
# request for DOME to TCS returns 6 arguments: dome_del_pos, dome_mode, dome_initialized,
# tel_az, dome_az, and dome_home. Dome mode is autodome on/off
# Control Info: [DEL] [MOD] [INIT] [TELAZ] [AZ] [HOME]
# DEL(Delta Position) = +XXX.XXXXXXX
# MOD(Mode) = XX
# INIT(Initialized) = XX
# TELAZ(Telescope Azimuth) = +XXX.XXXXXXX
# AZ(Dome Azimuth) = +XXX.XXXXXXX
# HOME(Home Position) = +XXX.XXXXXXX
# optional argument "PARAM" means to dump out the dome setup parameters:
# Parameters: [CPD] [SD] [W] [SDW] [NU] [RHO] [PHI] [LOOK] [HOLD]
# CPD(Counts Per Degree) = XXX.xxxxxxx
# SD(Stow Degrees)= XXX.xxxxxxx
# W(Dome Width) = XXX.xxxxxxx
# SDW(Stow Dome Width)= XXX.xxxxxxx
# NU = XXX.xxxxxxx
# RHO = XXX.xxxxxxx
# PHI = XXX.xxxxxxx
# LOOK(Lookahead) = XX
# HOLD(Hold Dome) = XX
global simDome
if {$arg == "PARAM"} {
set return [ format "%10.6f %10.6f %10.6f %10.6f %10.6f %10.6f %10.6f %s %s" $simDome(cpd) $simDome(sd) $simDome(w) $simDome(sdw) $simDome(nu) $simDome(rho) $simDome(phi) $simDome(look) $simDome(hold) ]
} else {
SimUpdateDome
set domeaz $simDome(current)
set telaz [ SimReturnAZ ]
set delta [ SimMinDist $domeaz $telaz ]
set return [ format "%11.7f %s %s %11.7f %11.7f %11.7f" $delta $simDome(auto) 0 $telaz $domeaz 0 ]
}
return $return
}
################################################################################
proc SimReturnRA {} {
# returns sexagesimal RA
global simRA
SimUpdateRA
set return [ dec2sex $simRA(current) 2 ]
return $return
}
################################################################################
proc SimReturnDEC {} {
# returns sexagesimal DEC
global simDEC
SimUpdateDEC
set return [ dec2sex $simDEC(current) 1 ]
if {$simDEC(current) >= 0} {
set return "+$return"
}
return $return
}
################################################################################
proc SimReturnAZ {} {
set azel [ SimUpdateAZEL ]
set az [ format "%0.1f" [ lindex $azel 0 ] ]
return $az
}
################################################################################
proc SimReturnEL {} {
set azel [ SimUpdateAZEL ]
set el [ format "%0.1f" [ lindex $azel 1 ] ]
return $el
}
################################################################################
proc SimReturnEQ {} {
return "XXXXX.x"
}
################################################################################
proc SimReturnAirmass {} {
set el [ SimReturnEL ]
set airmass [ SimAirmass $el ]
return $airmass
}
################################################################################
proc SimReturnDisable {} {
global simDisabled
return $simDisabled
}
################################################################################
proc SimReturnAll {} {
global simLimit simTime simRA simDEC simDome simFocus simEpoch
# set line1 "0 1 2 2 4 5 6 7 "
# set line2 "01234567890123456789012345678901234567890123456789012345678901234567890123456789"
# most values are updated only when requested...do this now:
set ra [ SimReturnRA ]
set dec [ SimReturnDEC ]
# could call SimUpdateAZEL directly, to save us an radec2azel calculation...
set az [ SimReturnAZ ]
set el [ SimReturnEL ]
set motion [ SimReturnMotion ]
set airmass [ SimReturnAirmass ]
set sexLST [ SimReturnLST ]
set decimalLHA [ SimLHA $simTime(currentLST) $simRA(current) ]
set sexLHA [ dec2sex $decimalLHA -1 ]
if {$decimalLHA >= 0} {
set sexLHA "+$sexLHA"
}
set simTime(sexLHA) $sexLHA
set simTime(currentLHA) $decimalLHA
# update to see if we're in a limit:
set result [ SimCheckLimits $az $el $decimalLHA $simDEC(current) $simFocus(current) ]
# if so, disable, unless limit override is actives
if {$simLimit(RA) || $simLimit(DEC) || $simLimit(HOR)} {
if {!$simLimit(inhibit)} {
SimDisable 1
}
}
set epoch $simEpoch
# set ngtext [ format " %2s %-9s %-9s %-9s %-8s %5.2f %6.2f %5.2f %7.2f" $motion $ra $dec $sexLHA $sexLST $el $az $airmass $epoch ]
set ngtext [ format " %02s %-9s %-9s %-9s %-8s %5.2f %6.2f %5.2f %7.2f" $motion $ra $dec $sexLHA $sexLST $el $az $airmass $epoch ]
return $ngtext
}
################################################################################
proc SimReturnXra {} {
# Returns: [COM] [NEXT] [REF] [OFF] [WOB] [DIFF] [BIAS] [GUIDE] [DRIFT]
#COM(Commanded Position) = HH:MM:SS.ss
#NEXT(Next Position) = HH:MM:SS.ss
#REF(Reference Position) = HH:MM:SS.ss
#OFF(Offset Position) = +HH:MM:SS.ss
#WOB(Wobble) = +HH:MM:SS.ss
#DIFF(Difference) = +XXXXXXXXX.xxx
#BIAS(Bias Rate) = +XXXXXXXXX.xxx
#GUIDE(Guide Rate) = +XXXXXXXXX.xxx
#DRIFT(Drift Rate) = +XXXXXXXXX.xxx
global simRA simRate
# simulator doesn't keep track of everything; return placeholders for some values:
set com [ dec2sex $simRA(current) ]
set next [ dec2sex $simRA(next) ]
set ref "ref"
set off "off"
set wob "wob"
set diff "diff"
set bias $simRate(biasra)
set guide $simRate(guide)
set drift $simRate(drift)
set return [ format "%s %s %s %s %s %s %s %s %s" $com $next $ref $off $wob $diff $bias $guide $drift ]
}
################################################################################
proc SimReturnXdec {} {
# Returns: [COM] [NEXT] [REF] [OFF] [WOB] [DIFF] [BIAS] [GUIDE] [DRIFT]
#COM(Commanded Position) = HH:MM:SS.ss
#NEXT(Next Position) = HH:MM:SS.ss
#REF(Reference Position) = HH:MM:SS.ss
#OFF(Offset Position) = +HH:MM:SS.ss
#WOB(Wobble) = +HH:MM:SS.ss
#DIFF(Difference) = +XXXXXXXXX.xxx
#BIAS(Bias Rate) = +XXXXXXXXX.xxx
#GUIDE(Guide Rate) = +XXXXXXXXX.xxx
#DRIFT(Drift Rate) = +XXXXXXXXX.xxx
global simDEC simRate
# simulator doesn't keep track of everything; return placeholders for some values:
set com [ dec2sex $simDEC(current) ]
set next [ dec2sex $simDEC(next) ]
set ref "ref"
set off "off"
set wob "wob"
set diff "diff"
set bias $simRate(biasdec)
set guide $simRate(guide)
set drift $simRate(drift)
set return [ format "%s %s %s %s %s %s %s %s %s" $com $next $ref $off $wob $diff $bias $guide $drift ]
}
################################################################################
proc SimReturnXall {} {
global simDome simFocus
SimUpdateFocus
SimUpdateDome
set focus $simFocus(current)
set dome $simDome(current)
# current version of TCS-NG actually has these values hard-coded in...TBD:
set iis -224.4
set pa -145.6
set jd [ SimReturnJD ]
set date [ SimReturnDate ]
set return [ format "%7s %6.1f %6.1f %6.1f %10s %7.1f" $focus $dome $iis $pa $date $jd ]
return $return
}
################################################################################
proc GetFinishTime { start distance rate } {
# rate must be in units per second
return [ expr {$start + abs($distance / ($rate * 1.0))} ]
}
################################################################################
proc GetTimeSeconds {} {
# returns number of seconds from 1970, with precision to milliseconds
global simTime
# need to report the TCS time, not necessarily the true time (if restarted
# with SYSRESET TIME for example)
set ms [ clock clicks -milliseconds ]
if {[ info exists simTime(offset) ]} {
set offset $simTime(offset)
} else {
set offset 0
}
set seconds [ expr {$offset + ($ms / 1000.0)} ]
return $seconds
}
################################################################################
proc UpdateTime { initialtime seconds } {
# initialtime comes to us in decimal hours; seconds in integer seconds
return [ expr {$initialtime + ($seconds/3600.0)} ]
}
################################################################################
proc SimDeclare { value } {
# valid values are either INITNEXT or INITCOM.
global simRA simDEC simTrack simEL simAZ simDome
if {$value != "INITCOM" && $value != "INITNEXT" && $value != "STOW"} {
return "FAILED"
}
# INITCOM (set current to commanded) not very useful since (target) is always
# kept the same as (current) - even when tracking, stopping, etc.
# don't do any syntax vetting - this should have been done by now
if {$value == "INITCOM"} {
if {$simRA(target) != ""} {
set simRA(current) $simRA(target)
}
if {$simDEC(target) != ""} {
set simDEC(current) $simDEC(target)
}
} elseif {$value == "INITNEXT"} {
set simRA(current) $simRA(next)
set simRA(target) $simRA(next)
set simDEC(current) $simDEC(next)
set simDEC(target) $simDEC(next)
# workaround for declare as next position while not tracking:
if {!$simTrack(tracking)} {
SimTracking "ON"
SimUpdateRA
SimTracking "OFF"
}
} elseif {$value == "STOW"} {
# set the current position of the telescope (and dome?) to the stow position:
set simDome(sd) $simDome(current)
set simEL(stow) $simEL(current)
set simAZ(stow) $simAZ(current)
SimWriteStowFile $simDome(sd) $simAZ(stow) $simEL(stow)
}
return "OK"
}
################################################################################
proc SimStepRA { value } {
return "OK"
}
################################################################################
proc SimStepDEC { value } {
return "OK"
}
################################################################################
proc SimPEC { value } {
# argument ON turns on the PEC, any other argument shuts it off
# pec_condition -> 0=off, 1=on, 2=training, 3=waiting
# pec_count -> decimal number of indexes
# pec_index -> 0=waiting, 1=indexed
# pec_train -> 0=off, 1=on, 2=training
global simPEC
if {$value == "ON"} {
set simPEC(condition) 3
} else {
# turn PEC off and lose the index:
set simPEC(condition) 0
set simPEC(index) 0
set simPEC(count) 0