-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlog.w
2026 lines (1704 loc) · 96.6 KB
/
log.w
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
\date{2021 January 5}
Took another deep dive down a rabbit hole thanks to LSL's shoddy
implementation of its (inadequate) single precision floating point.
If single precision itself weren't an insult to anybody trying to
do physical modeling, the conversion of floating point numbers to
strings is a dagger in the back. Suppose you have a floating point
number like, say, 1.67e-7, which is well within the dynamic range
and precision of a single precision IEEE float. Now you cast the
value to a string and print it, for example:
\begin{verbatim}
float a = 1.67e-7;
llOwnerSay((string) a);
\end{verbatim}
What do you get? Well, hold on to your hat, it's:
\begin{verbatim}
0.000000
\end{verbatim}
That's right, it knows nothing of scientific notation, and shifts
every significant digit off the end of the six decimal places it
edits. Now, foolishliy, try to pass that number from one script to
another by encoding it as JSON with, say:
\begin{verbatim}
llOwnerSay(llList2Json(JSON_ARRAY, [ a ]));
\end{verbatim}
And the answer is...
\begin{verbatim}
[0.000000]
\end{verbatim}
Yes, it uses the same idiot float to string conversion and loses the
entire mantissa. I didn't just pull this number out of the air, by
the way. It happens to be the mass of the planet Mercury expressed in
units of solar mass. So what this means is that if you ever allow
LSL to express a float as a string, it makes Mercury as massless as a
photon.
The only way to work around this is to integrate something like the
LSL library {\tt float2Sci()} function, which is huge, complicated, and
excruciatingly slow, and explicitly call it wherever you need to pass
a float as a string. This is just hideous, but shoddy happens, and
who're you gonna call?
\date{2021 January 6}
Well, the LSL Wiki recommends {\tt Float2Hex}, which encodes floats as
a C99 hexadecimal float with no loss of precision and is much faster
than {\tt float2Sci()}. Well, that may be, and it does indeed work,
but it is still many times (around a factor 5 to 7) slower than the
native (float) conversion. So, if performance matters, as when passing
values between scripts with JSON or CSV messages, the only practical
approach is to scale your values so they don't lose precision, then
scale them back on the receiving end.
\date{2021 January 8}
After a number of tests, it became evident that a model in which each
particle autonomously evaluated the forces on it and moved accordingly
simply wasn't going to work.
\date{2021 January 9}
Successive optimisation of performance of simulation. Each test run is
64 steps.
\begin{verbatim}
Computation Model update
Initial state 2.1787 14.8694
Float2Hex to (float) 0.7557 14.9567 In UPDATE message
Mindist 0.1 0.7315 8.2216 32 moves taken
llSetLinkPrimParamsFast 0.7994 1.4001 Eliminates 0.2 sec delay
Separate table of velocities from mParams
Send single message to update all masses
Send message as CSV, not JSON
\end{verbatim}
Added a ``Set kaboom n'' facility which causes masses to self-destruct if
an update places them greater than $n$ AU from the deployer. This cleans
up runaway masses without counting on their dying due to going off
world or onto a parcel where they aren't permitted.
Added a Run on/off command, which calls timeStep off the timer, with a
time step tickTime which is currently fixed at 0.01 second. Since this
is run off the timer, it is interruptable.
Modified the Step command to use the Run timer mechanism, limited by
a variable stepLimit which it sets to the specified count. This can be
stopped by Run off. If you set stepLimit to zero, the previous compute
bound code is used (temporarily) to allow running benchmarks which can
be compared to those above, when we get back to tuning again.
\date{2021 January 10}
Made a galaxy disc texture for the deployer. The image is of NGC3982,
from:
\begin{verse}
\url{https://esahubble.org/images/opo1036a/}\\
\url{https://esahubble.org/copyright/}
\end{verse}
This as been processed into two texture images in textures/
\begin{verbatim}
NGC3982.png 512x512 single sided
NGC3982x2.png 1024x512 double sided
\end{verbatim}
In the latter image, the right side is flipped so when it's applied to
a sphere as follows, it covers both sides and aligns properly.
\begin{verbatim}
Size <1, 1, 0.05>
Rotation <0, 0, 0>
Texture
Scale <1, 1, x>
Repeats 1
Rotation 90 deg.
Offset <0, 0, x>
\end{verbatim}
Added a ``Hide run'' command and support to hide the deployer while the
simulation is running. You can, as before, hide or show the deployer
permanently with ``Hide on/off''. A new {\tt setRun()} function handles all
state changes of ``runmode''.
\date{2021 January 11}
Modified {\tt fixArgs()} to remove the \{\ldots \} rotation syntax
which only applies to Euler angle rotations in the Calculator.
Modified the Mass command and REZ message handler to store and
pass the Mass colour specification as a string, allowing our
extended colour specifications to be passed to the mass in the INIT
message. An extended colour specification is:
\begin{verbatim}
<r, g, b [, alpha [ , glow ] ]>
\end{verbatim}
Note that {\tt fixArgs} handles eliding any spaces within the
specification, even though it may not look like a vector
or rotation.
Added code to the INIT message handler in Mass to handle the extended
colour specification. The colour specification from the Mass statement
is parsed by the {\tt exColour()} function, which returns a list
containing the colour, alpha, and glow specifications, automatically
specifying omitted optional parameters. If an invalid colour
specification is given, a list representing solid white with no glow is
returned.
Had another go at drawing (semi-)reasonable paths behind objects with
a particle system. This time, I have the masses rotate themselves in
the direction of travel so their Z axis (the \verb+RIBBON_MASK+ particle
emission direction) is oriented along the vector from their old to new
position). This works pretty well, but note that it uses the dreaded
{\tt llRotBetween()} and may flake out, requiring replacement by the more
reliable library function we've used elsewhere. Also, it's not
optimised: there's no need to fiddle with rotating the masses unless
we're drawing paths, but we presently do it all the time.
Added the ability to trace paths by laying down temporary prims to form
lines along the orbits. This is done in the masses with a new {\tt
flPlotLine()} function, which is a (reasonably) general line drawing
mechanism that works in region co-ordinates and plots with skinny
cylinders. This is controlled by ``Set paths lines'' and can be turned
off with ``Set paths off''. Particle paths continue to be available
via ``Set paths on''. The prim path mechanism basically works, but
needs instrumentation and tuning to determine how much it costs us and
what we can do to reduce the simulation overhead.
Added computation of simulated time and display in a floating text
legend, along with the step number, above the deployer. The legend
is controlled with ``Set legend on/off'' and is, by default, off.
\date{2021 January 12}
Proposal for simulated time: set the simulation rate with:
\begin{verbatim}
Set simrate n
\end{verbatim}
where $n$ is the number of simulated years per second. The simulator
will strive to approximate that rate.
\begin{verbatim}
Set step n
\end{verbatim}
Set the number of simulated years per integration step. This is the
default as long as accelerations do not force us to use smaller steps.
In the normal case (low accelerations), the simulation process is to
perform R/S steps per second, to which each is allotted S/R seconds
to complete, with a timed wait at the end of each step so the rate
simulation rate is achieved.
If high accelerations force us to a smaller step size, then we adjust
the number of steps accordingly, and reduce the wait between steps.
If the required number of steps take longer than we can compute at the
requested rate, we are in a time deficit situation and should report
this to the user.
This is complicated by the fact that it's possible we may be able to
compute steps faster than the masses can update themselves. We need to
be able to detect this and have the masses discard updates to avoid
overflowing their inbound event queues. Perhaps we should time stamp
the updates so the masses can detect getting behind. Unfortunately,
we'll have to use Unix time with a resolution of only one second, since
{\tt llGetTime()} is local to each script. An alternative is {\tt
llGetTIimeOfDay()}, but that requires handling wrapping around
midnight. {\tt llGetTimestamp()} is right out, as it requires string
bashing which is way too costly.
\date{2021 January 12}
Added code to allow a suffix to be specified after the interval in
the Set simrate and Set steprate commands. If no suffix is given,
the specification is interpreted as years. Valid suffixes are:
\begin{verbatim}
h Hour
d Day
w Week (1/52 year)
m Month (1/12 year)
y Year (default)
D Decade
C Century
\end{verbatim}
\date{2021 January 13}
Created a new platform, ``Uraniborg'' (named after Tycho's
observatory), with a texture called ``Starfield'' which was generated
by ``Terranova Planet Maker''.
Created a utility to compile the Jet Propulsion Laboratory (JPL)
DE118 (digital ephemeris) initial state vector for the solar system
as of JD 2440400.5 (1969-06-28 00:00 UTC) into Mass commands to
define the bodies. This program is:
\begin{verbatim}
tools/solar_state_vector.pl
\end{verbatim}
and reads an unmodified file, {\tt tools/aconst.h} containing the
positions and velocities of the Sun, planets (including Pluto), and the
Earth's Moon. The other properties of the bodies (name, mass, colour,
and radius) are taken from a table included in the program. The output
is a list of Mass declarations in the format which can be read directly
by the Gravitation deployer.
The DE118 state vector is expressed with position units of astronomical
units (AU) and velocity of AU per day. We transform velocity into our
units of AU per year. Further, DE118 uses a co-ordinate system in
which the Z axis points to the Earth's north celestial pole, the X axis
points toward the vernal equinox, and the Y axis at Right Ascension 6
hours. The \verb+solar_state_vector.pl+ rotates the position and velocity
vector around the X axis to align the Z axis with the normal to the
ecliptic plane, transforming the co-ordinates to our heliocentric
co-ordinates.
Added an Epoch command which allows specifying the start epoch of a
model loaded into the simulator. This doesn't presently do anything,
but it accepts the Epoch declaration generated from DE118 database.
\date{2021 January 14}
Ran the full Solar System simulation overnight, for 137,000 steps
and 377 simulated years, with no disasters or apparent errors in
the resulting configuration.
Built a complete box for the Uraniborg space model environment. The
floor is unchanged, while the sides and root are double-sided versions
of the Uraniborg platform, with the star field on both sides, and
marked phantom, which allows objects and avatars to move through them
unimpeded. They, however, serve as a background when viewing or
photographing models within the box.
\date{2021 January 23}
Moved generation of the floating text legend to Minor Planets to save
memory in the main script, and because the JD editing functions and
information about the tracked object are already there.
Built Asteroid and Comet models, with the comet generating particle
systems to showo the coma and tail, scaled to its distance from the
Sun, and the tail oriented away from the Sun.
Developed the first cut at a mass model generator for the numerical
integrator, with the first focus on central configurations such as
Trojan systems and rosettes. This took a deep dive into the Perl {\tt
Math::Quaternion} and {\tt Math::Vector::Real} modules, which are well
worth mastering for this kind of work.
\date{2021 January 24}
Added the ability specify the number of orbit segments in the:
\begin{verbatim}
Orbits body [ nsegments ]
\end{verbatim}
command.
Using the Asteroid body script as the pathfinder, added the ability to
display a floating text legend above the body showing the most recently
updated rectangular co-ordinates and radius vector (in AU) and the
heliocentric latitude and longitude in degrees. This is generated by
{\tt updateLegend()}, which is passed only the rectangular co-ordinates
of the update: it figured out the heliocentric spherical co-ordinated
from that and deployerPos saved from when it was rezzed. A handy {\tt
rectSph()} function is provided for this transformation, which may
prove useful elsewhere.
Display of the legend is controlled by \verb+s_legend+ in the settings,
which may be toggled by touching the body. We'll look into command and
script control of this further down the road.
Fixed parsing of Epoch statements with HH:MM[:SS] time specifications,
Julian day specifications without fractional parts. Added a call so
the model is immediately updated when the Epoch is set.
Added ``Set real on/off/step n'' to control real time, in which the
planets display their current configuration. The real time display is
update every 30 second by default, but may be changed with the ``step
n'' specification where $n$ is the interval in seconds.
In the process of putting together a sample of representative asteroid
and comet orbits as a test suite, somehow or other I accidentally ended
up with a UTF-8 character trailing one of the orbital element
parameters. This, when imported into Minor Planets and eventually
passed to the ephemeris evaluator set off a Chinese fire drill of
disasters due to typos, inadequate error checking, and LSL's propensity
for propagating NaNs through a long series of computations until it
decides to tell you ``Math error'' with no more precision than the name
of the script in which it occurred. After several hours of debugging
and tracing back to the source, the one-character fix became obvious,
but in the process error checking and fault tolerance in orbital
element specifications has been much improved, which is something I
intended to do anyway before shipping and would have been well advised
to do before it could have saved me a great deal of time and trouble.
In any case, everything works now with the examples that provoked the
original problem and further slips of the keyboard should be caught
before they cause calamity.
In order to suppport the forthcoming ``true ellipse orbit'' feature and
possible future optimisations I added the ability to request ephemeris
data for multiple dates in the \verb+LM_EP_CALC+ message simply by including
multiple Julian date/fraction pairs between the body bitmask and the
handle at the end. The request concatenates all of the requested
ephemerides into a message, appends the handle, and returns it to
the requester. This is 100\% compatible with existing requests that
only require the ephemeris for a single date. As always, the Minor
Planets script serves as the pathfinder for this---it will be propagated
to the rest of the ephemeris scripts once it's fully tested here.
\date{2021 January 26}
Updated all of our display items which rez prims [{\tt flPlotLine()},
the creation of ellipses for orbits, and {\tt markerBall()}] to test
whether the item they're creating is 10 metres or more from the
deployer and do the little trick of moving the deployer there before
rezzing the object. A new function, {\tt flRezRegion()}, which takes
the same arguments as {\tt llRezObject()}, handles this automatically.
\date{2021 January 27}
After several days of developing the mechanism to display elliptical
orbits with ellipses created from scaled and properly oriented cylinder
prims, I returned to figuring out why some minor planets ended up with
potato-shaped orbits. Suspecting our usual nemesis of single precision
round-off, I developed tools to allow comparing an orbit computation by
Solar System Live with one done by our ``Orbit 10'' command. These
tools are maintained in the \verb+.../Gravitation/orbit_debug+
directory (which is outside the Git repository).
Testing with orbit of 5496 (1973 NA), whose orbit displays hideously
and has orbital elements:
\begin{verbatim}
Asteroid "5496 (1973 NA)" t 2455540.5 a 2.434695101869629
e 0.6368122950745937 i 68.00432693434864 w 118.1062637269031
node 101.0823617074469 M 322.5808921760293 H 16.0 G 0.150
\end{verbatim}
I found that the discrepancy between the two evaluators was almost
entirely in the B (heliocentric latitude) value, with errors as
high as 14.7\%.
Well, upon further investigation, LSL's single precision is (in this
case, and bearing in mind the hoops we jump through to cope with it)
completely exonerated. The problem turned out to be a fat finger in
the expression in posMP() in Minor Planets which computes the
heliocentric latitude from the co-ordinates returned from
computeOrbit(). Once fixed, the discrepancy between the double
precision Solar System Live values and those computed in LSL were no
more than 0.01]% for the test orbit.
Performed an audit of all orbit tracing to validate its accuracy
against the double precision VSOP87 in Solar System Live and to check
whether the truncation of some of the periodic terms for the giant
planets due to the 64 Kb script memory limit compromised accuracy in
single precision evaluation. Everything appears to be OK, and is more
than adequate for proper appearance at the scales in which we render
the model.
\date{2021 January 28}
Added preliminary support for plotting orbits of parabolic and
hyperbolic orbits. If the orbit has no semi-major axis, we plot
outward from the periapse along both arms of the curve (positive time
and negative time) until we reach a limit in AU set by \verb+o_aulimit+
which is currently fixed at 10 AU.
Rewrote the Orbit command to integrate line and ellipse orbits and
allow the user to control whether the prims that represent them are
permanent or temporary. The command is now:
\begin{verbatim}
Orbit body [ segments/ellipse [ permanent ] ]
\end{verbatim}
At the moment, temporary ellipses are not implemented, but line orbits
may be either permanent or temporary.
Added the abililty of external commands (those not implemented within
the main script) to suspend scripts. The code in the main script must
set scriptSuspend as usual, but when the external command is done, it
can send a \verb+LM_CP_RESUME+link message which will call {\tt
scriptResume()} and get the script running again. Initially
implemented this for the Orbit command, allowing development of a minor
planet element parsing and orbit display test script, ``{\tt Script:
Orbits}''.
Meeus algorithms (including constants) are available for Go at:
\begin{verse}
\url{https://godoc.org/github.com/soniakeys/meeus/v3}
\end{verse}
Integrated the multiple ephemeris request logic for \verb+LM_EP_CALC+
into {\tt Ephemeris: Mars}, which will serve as the pathfinder for
ellipse fitting to planets. The code is essentially identical to that
developed and tested in Minor Planets, and will be integrated into the
other planet ephemeris calculators once it's checked out on Mars.
\date{2021 January 29}
Propagated the multiple request ephemeris code into the ephemeris
evaluators for all planets and tested them all with the "``orbit
\ldots\ ellipse'' command. Everything worked except Pluto, which
awaits an overhaul to use the JPL orbital element definition instead of
the Meeus periodic term solution.
Decided to break with my tradition of not starting Git management of
the project until declaring a release candidate. This project has
become sufficiently sprawling and complicated that maintaining an audit
trail of changes and being able to examine code prior to major
re-structurings justifies the additional overhead at this point. So I
created the repository:
\begin{verbatim}
git init
\end{verbatim}
and populated it with the current state of the source code.
\begin{verbatim}
git add --all
git commit -m "Initial commit"
\end{verbatim}
Note that at this point I am not creating a GitHub repository, but
simply starting Git configuration control on a local basis.
Eliminated the unused items from the \verb+LM_OR_ELEMENTS+ messages
sent in orbital ellipse generation from the Orbits and Minor Planets
scripts.
Completed the first pass of moving the numerical integrator from the
main Gravitation script (where it has been disabled to avoid memory
crashes) to its own ``Numerical Integration'' script. This script
handles the Mass command to declare the masses as well as running the
integration itself. Most of this is done by processing commands
forwarded from the main script when a numerical integration model is
loaded. The main script now forwards its settings to the other scripts
in the deployer with an \verb+LM_AS_SETTINGS+ link message as well as
to the masses with llRegionSay\ldots . It is basically working, but
there are a lot of state-setting issues such as handling settings
turning the legend on and off while a numerical integration is running.
Fixed propagation of the legend settings to Numerical Integration.
Completed the initial implementation of a replacement for the Pluto
ephemeris calculator with a stripped-down version of the Minor Planets
evaluator using the JPL Small-Body Database orbital elements for Pluto,
which are hard coded into the \verb+s_elem+ list in the source. From a
cursory test, plotting position and drawing the orbit appear to be
working OK, but fitting an orbit ellipse is wrong (while fitting an
ellipse to the same elements loaded as an asteroid works fine). I'll
dig into this after night's restorative sleep.
\date{2021 January 30}
The problem with fitting an ellipse to Pluto's orbit was simple: we
didn't have the required table entries for the {\tt apsides()} function
in Orbits to find the perihelion time of Pluto. I added them (from the
JPL Small-Body Database) and everything works fine now.
Script suspend and resume for the Orbit and Orbit \ldots\ ellipse
commands now work correctly. The ``Orbits'' script may be used to
verify this as well as testing edge cases for orbit generation.
Fixed Script suspend/resume to work with Step command for planetary
theory. Fixed script suspend/resume to work with the Step command
for numerical integration.
\date{2021 January 31}
Added script suspend/resume support for the Planet, Asteroid, Comet,
and Mass commands. This is still tacky for the Planet command with no
arguments, which presently resumes after the first planet completes
initialisation. It should wait until all of them have initialised.
Completed a very preliminary implementation of the cluster synthesiser
in \verb+tools/cluster_models/cluster.pl+. It is parameterised by
arguments to the function {\tt addCluster()} (which will eventually be
set by the command line or a parameter file), and creates Mass
declarations for the specified number of masses, with or without a
central mass. This is intended to model star clusters, and test models
typically run with parameters like:
\begin{verbatim}
set auscale 0.00003
set kaboom 250000
\end{verbatim}
as they are set in the {\tt Galcent} test script in the development
deployer. At the moment, all masses are placed in circular orbits, are
white, and have the same size. Refinements to set these parameters
will be added over time---the immediate goal is to test the numerical
integrator in a complex environment, not make pretty pictures.
\date{2021 February 1}
W. B. Klemperer's paper on symmetrical meta-stable n-body central
configurations, ``Some Properties of Rosette Configurations of
Gravitating Bodies in Homographic Equilibrium'' ({\em Astronomical Journal}.
67 (3), April 1962: 162–167).
\begin{verse}
\url{http://articles.adsabs.harvard.edu/pdf/1962AJ.....67..162K}
\end{verse}
contains equations for a parameter he calls ``$k$'' which provides a
correction factor to the sum of masses in the configuration that
computes the net central force on a body in a symmetrical polygonal
``rosette'' configuration that is used to calculate the constant angular
velocity at which the bodies will orbit (at least initially)
circularly. These equations (two versions are supplied, one for an
even number of bodies, one for odd) are incorrect and do not reproduce
the values given in Table I which purport to have been computed from
them. (The error(s) are in addition to the typographical error in the
equation for an even number of bodies, where ``$u$'' appears instead of the
intended ``$n$''.) I cannot even figure out what Klemperer was trying to
do in the equations, so after wasting a great deal of time, I simply
re-derived the whole thing from first principles, implementing the
vector calculations in \verb+tools/cluster_models/cluster.pl+ in the function
netForce(), which computes the vector net force on a body in the
current model, taking the gravitational constant $G$ as 1. It also
returns the total mass of bodies in the model, and Klemperer's $k$ value
may be computed as the magnitude of the force vector divided by the
total mass. Testing this for the examples in Klemperer's paper shows
that the values in his Table I are correct, notwithstanding the
erroneous equations claimed to have produced them. In any case, we can
now correctly compute the central force for any symmetrical
configuration, with much greater precision than the three significant
digits given in Klemperer's paper.
Added support for central masses in ring configurations. With the
general computation of k, this doesn't require any special handling in
computation or orbital velocity, as the central mass is automatically
accounted for. Adding even a large central mass doesn't noticeably
stabilise a three mass rosette configuration, which becomes undone due
to single precision round-off just about as quickly as in the absence
of one.
Added support for elliptical orbits in clusters generated by
{\tt addCluster()} in {\tt cluster.pl}. After assigning a random eccentricity to
the orbit within the range specified in the {\tt addCluster()} call,
{\tt genCluster} computes the velocity of a body at periapse in an orbit with
the chosen semi-major axis and eccentricity around the centre of mass
using the vis-viva equation:
\begin{verse}
\url{https://en.wikipedia.org/wiki/Vis-viva_equation}
\end{verse}
which simply expresses the invariant total energy of a geodesic orbit
as the sum of its gravitational potential and kinetic energy and
solving for periapse velocity, which is:
\[
v = \sqrt{((1 - e) G M )/ ((1 + e) a)}
\]
where $a$ is the semi-major axis, $e$ the eccentricity, and $G M$ the
standard gravitational parameter ($\mu$). For simplicity, we start all
bodies at apoapse and let evolution of the model shuffle them up
based upon the different orbital periods.
\date{2021 February 4}
In the Galactic Centre module, calculation of positions of sources S175
and S4714, both of which have eccentricities in excess of 0.98, were
failing when trying to use the Landgraf/Stumpff algorithm for
near-parabolic motion presented in chapter 35 of Meeus's {\em
Astronomical Algorithms}. This is the algorithm we've been using in
Solar System Live for ages, but it simply does not work in single
precision floating point: it runs away and bails out on a failure to
converge. I removed it and made {\tt gKepler} use the Roger Sinnott
binary search algorithm, which works for any eccentricity up to 1.
This corrected the calculation for these sources.
Making a synthetic comet with an eccentricity of 0.985, I verified that
the near-parabolic algorithm also fails in Minor Planets. I removed it
from there as well, which gives a little more breathing room in script
memory there.
In an attempt to speed up updates when there are many objects in a
simulation (a case exacerbated by the Galactic Centre model, where the
full cluster now has 43 objects, I changed the distribution of position
updates to objects from individual {\tt llRegionSayTo()} calls for each
object to a collective update sent with {\tt llRegionSay()} which
contains as many object updates as will fit in 1024 characters. This
is based upon research with Gridmark, which revealed that the
bottleneck with region messages is the rate at which they can be sent
and not the byte rate. This way we can update all 43 objects with just
two messages.
To further improve performance, I replaced sending co-ordinates as
decimal numbers with the {\tt fuis()} and {\tt siuf()} functions from
the library:
\begin{verse}
\url{http://wiki.secondlife.com/wiki/User:Strife_Onizuka/Float_Functions}
\end{verse}
which preserve all bits of a float's precision and encode each number
as just 6 base64 characters. This allows packing more updates into a
message and is much faster when encoding and decoding.
With these changes in place, the computation and distribution of updates
appears to be substantially faster than all of the individual objects
can update themselves. We'll need some form of feedback and throttling
to avoid lost messages and the consequent jerky updates.
\date{2021 February 5}
To avoid message loss and non-responsiveness to Run/stop commands, I
implemented a feedback mechanism which prevents sending an update
to Galactic Centre sources before they're all done moving from the
previous update. This is done by having the last source created
(and how it detects it's last a dog-dirty trick, but lightning fast)
send an UPDATED message to the deployer when it's done moving. In
Gravitation, we ignore timer ticks to update between the time we send
an \verb+LM_GC_UPDATE+ message and when the UPDATED confirmation arrives.
This keeps everything in sync and avoids flooding the message queue.
Modified {\tt sendSettings()} in Gravitation to include simEpoch in the
settings, and the Epoch command to push settings when changing the
Epoch. Galactic Centre now uses this to place sources at their correct
position for the epoch rather than in placeholder positions which were
updated on the first simulation step. This is a small refinement, but
it looks a lot less silly when you're starting up a simulation.
Implemented orbit tracing and elliptical orbit fitting for the Galactic
Centre model. As with Minor Planets, this is done entirely within
Galactic Centre with only a little help from Orbits to draw the orbit
outline.
Completed a major code clean-up in the Mass and Source objects (those
used in Numerical Integration and Galactic Centre simulations,
respectively). I removed lots of dead code dating to when the masses
had more autonomy, added support for the Set Labels command to show or
hide object labels, and generally made things more comprehensible.
This leaves only the Solar System planets to be done, but since the
script is replicated in each one, that's a lot more busy-work which I'll
defer until I'm confident there aren't more changes I need to propagate
to all of them.
Upgraded the Mass command handler in Numerical Integration to
correctly handle quoted body names in upper and lower case. This
provides compatibility with the Asteroid and Comment commands in
Minor Planets and the Centre and Source declarations in Galactic
Centre. This was simplified since all of the arguments to the Mass
command after the name are inherently case-insensitive.
\date{2021 February 6}
It appears that in the course of avatar events, occasionally a {\tt
llRegionSay[To]()} message will be lost, even when it is right nearby
in a nearly idle region and the recipient listener does not have a
problem with message queue overflow. This happens every ten minutes or
so to one of the confirmation messages from Galactic Centre sources
which we use to throttle the rate at which updates are sent,resulting
in the simulation freezing up. I added logic to the {\tt timer()}
event in Gravitation which sets a watchdog timer whenever it starts
deferring updates due to \verb+ev_updating+ being set.
After a much more involved struggle than was expected (or justified,
based upon the eventual solution), I got the sources created by
Galactic Centre to clean up their ``Set paths lines'' trails after
being deleted by the deployer. This is a bit more complicated than you
might think, because the {\tt flPlotLine()} objects created for trails
do not have the main deployer as their creator, but rather the
individual sources which plotted them along the orbit. This means the
trails will not respond to a {\tt ypres} message from the main
deployer, but instead must receive a message forwarded by the
individual source that rezzed them. (Since we always check the key of
the sender of a message to an object to avoid confusion if more than
one instance of one of our models is present in a given region.) I
added code to forward the ypres message to the line segments and a
handler in the script within them to clean themselves up upon receiving
it.
I also confirmed that you don't need to mark a prim Temporary when
creating it with the builder, but that setting \verb+PRIM_TEMP_ON_REZ+
in its \verb+on_rez()+ event suffices. This makes it much easier
working with temporary prims, as they don't ``peek-a-boo'' and
disappear while you're editing them before taking them into inventory.
The trails for Galactic Centre objects created by ``Set paths lines''
appeared to get out ahead of the objects as they moved along their
orbits because we updated the path with {\tt flPlotLine()} before
moving the object itself. I changed the order of updates which fixed
such ``anticipatory orbiting''.
Propagated the changes from the Galactic Centre source object to the
Numerical Integration mass object which is very similar but not
identical (for one thing, it does not presently use the bulk update
message protocol or handshake completion of updates back to the
deployer). Everything appears to be behaving. These changes also,
of course, need to be installed in the Solar System planets, but as
noted above, I'll defer that larger and fussy job until I'm sure things
have settled down and I only need to visit them once.
``Ignore previous wire\ldots .'' The ``lost messages'' problem with
Galactic Centre that caused so much commotion above turned out to have
an entirely different and more subtle cause. The ``GC Fast'' model I
was using for most of my testing included a ``S999'' source that I
ginned up in a hyperbolic path in order to test tracing non-closed
paths in the Orbits command. Well, as it happened, that was the last
source declared in the model and, being on a hyperbolic trajectory,
eventually flew away out of Kaboom range and self-destructed. Once the
source was gone, there was nobody to return the UPDATED confirmation to
the deployer, and the simulation would freeze. The un-sticking code
wouldn't help, since the source responsible for acknowledging the
update had permanently shuffled off this grid of existence.
To cope with this, I moved handling of Kaboom detection from the Source
object's script into Galactic Centre itself, whose main update loop now
checks every new position computed for a source for being in excess of
\verb+s_kaboom+ AU from the deployer and also for falling outside the
region box of $<[0,255), [0,255), [0,4096)>$. If a source has strayed
beyond where it belongs, it is sent a KABOOM message and its key
removed from \verb+source_keys+, which causes it to be ignored on
subsequent update cycles. Note that this does not handle sources
straying off the parcel but remaining within the region. That will
take additional hackery in the new {\tt elKaboom()} function to deal
with.
This is not presently required for Numerical Integration masses as they
do not use a confirmation messages and may disappear without stalling
the simulation. If and when we add confirmation to them, logic like
this will be required there as well.
To avert an imminent memory crisis in Galactic Centre (where we may
want to load more than forty known sources orbiting Sgr A*), I split
the user interface and parsing of object parameters into the original
Galactic Centre script and the evolution of orbital motion into a new
Galactic Patrol script, which is invoked by the main simulator and also
handles related functions such as plotting orbits and fitting ellipses
to closed orbits. This gets all of the gnarly orbital mechanics and
storage of orbital elements out of Galactic Centre and allows Galactic
Patrol to handle that without all the clutter of parsing object
definitions and assorted text bashing. There are many refinements to
be made (in particular, Galactic Patrol stores far more orbital element
information about each source than it actually needs, but it's
basically working and can load the complete galactic centre model
without blowing a gasket.
Went through all of the Ephemeris calculators for Solar System,
changing all of the calculation of periodic terms to perform additions
in the order of absolute magnitude, smallest to largest. This serves
to make the most of the (severely) limited dynamic range available in
LSL's single precision floats. I further cleaned up code, disabling
computation of some higher order powers of time which were not used in
some of the simpler sets of periodic terms. Comparing results from the
original and optimised code showed only very minor differences in a few
items which wouldn't make a difference in the display, but given that
we're forced to deal with single precision, it makes me feel better
knowing that proper floating point hygeine allows is to make the most
of what we're given.
Modified the Pluto ephemeris calculator to range reduce the
heliocentric latitude to 0 to \verb+TWO_PI+. This is consistent with
all of the other ephemeris calculators. It actually doesn't make any
difference in any of our uses of the ephemeris results, but it's easier
to compare results among ephemeris calculations if they're all
consistent in the range of results they return.
\date{2021 February 7}
Further adjusted the division of responsibility between Galactic Centre
and Galactic Patrol to equalise memory usage between the two. Galactic
Centre contained an entire copy of the orbital position calculation
code which was used simply for setting the initial position of newly
created sources. To get rid of all that duplicated code, I modified
the creation of sources as follows. When a new source is created,
Galactic Centre now places it coincident with the central mass, which
doesn't require the deployer to jump to the location of the mass. Once
the mass is created and sends its SOURCED message, Galactic Centre
notifies Galactic Patrol with an \verb+LM_GP_SOURCE+ message which now
includes the current simEpoch as well as the source key and orbital
elements. When Galactic Patrol receives this message, it computes the
initial position of the mass at simEpoch and sends it to the mass with
llRegionSayTo() in an update (``{\tt U:}'') message addressed just to
that mass. The Source menu in the object then moves to the specified
position using {\tt llSetLinkPrimitiveParamsFast()} if it is within ten
metres of the initial position and {\tt llSetRegionPos()} if it's
further away.
With these changes in place and all of the now-unused code in Galactic
Centre removed, after loading the entire ``Sgr A*'' model, with 45
sources, memory usage is only 67\% in Galactic Centre and 79\% in
Galactic Patrol. These could further be reduced by modifying Galactic
Centre to discard the orbital elements of sources after sending them to
Galactic Patrol and Galactic Patrol to only store the orbital elements
it needs to compute the orbital position instead of the whole thing as
it presently does. Since neither are presently near the cliff, and
we're unlikely to add many more sources to the model in the near
future, there's no reason to proceed further at this time.
\date{2021 February 8}
Began experimentation with automatically setting step and tick times
for Numerical Integration simulations. To untangle the parameters, as
a temporary expedient I made ``Set steprate'' directly set the
integration step time in years, while ``Set simrate'' sets the timer tick
rate running steps in seconds. This is horrid from a consistency
standpoint and incompatible with Solar System and Galactic Centre, but
it makes it a lot easier to observe the effect of settings. I ran the
{\tt Galcent} model overnight with:
\begin{verbatim}
Set step 20y
Set sim 0.1
\end{verbatim}
and everything went smoothly, including stopping immediately when I
paused it after running all night.
Removed {\tt fixargs()} from Gravitation. None of the commands parsed
there require its tender ministrations, so it was just wasting space
and time.
Moved processing of the ``Orbit'' command from Gravitation to the
Orbits script itself as an auxiliary command. This saved a bit of
memory in the Gravitation script, but the main motivation was
permitting extension of the Orbit command to properly handle body names
of Solar System objects (including tracked minor planets), quoted body
names including spaces and upper and lower case, and improved error
detection and reporting. The Orbit command now accepts names of Solar
System bodies as well as their index, permits quoted name fields, and
respects letter case for body names, including those it forwards to
Minor Planets and Galactic Centre for handling.
Completed a major revision to Numerical Integration's communication
with its Mass objects. These previously used hex-encoded floating
point numbers to pass initial creation parameters and settings to
masses, and decimal numbers to send new positions. Now they all use
Base64-encoded {\tt fuis()} and {\tt siuf()} to send floating-point
values with full precision in base64 encoded binary strings (actually,
integers). This allowed the complete elimination of the LSL Library
{\tt Float2Hex} function, which was huge in terms to static memory and
slow. All onward communications from Numerical Integration now use
base64 encoding, although other components still speak in primitive
pidgin dialects.
\date{2021 February 9}
Ran a Numerical Integration {\tt Galcent} simulation with ``Set paths
lines'' overnight with no problems.
Updated Galactic Centre and Source to communicate settings to the
sources using {\tt fuis()} and {\tt siuf()} instead of decimal numbers.
This is faster and prevents loss of precision on values such as AUscale
which might otherwise be truncated.
Removed decoding of settings in Galactic Centre and Galactic Patrol
which were never actually used by those modules.
\date{2021 February 10}
Made the long-deferred and much-dreaded sweep through all of the Solar
System planets, updating them to receive their settings and update from
the deployer via {\tt fuis()}/{\tt siuf()}. Most of the planets were
broken with respect to ``Set paths lines'', not containing the required
{\tt flPlotLine} object, which is now fixed. I cleaned up some
obsolete code in the planets, some dating back to their Flocking Birds
ancestor. The Asteroid and Comet models were updated like the planets,
and their generation of a floating text legend made to respect ``Set
labels'' from the deployer.
Set the colour of the trails drawn by Solar System planets based upon
the resistor colour code of their planet number. Asteroids and comets
draw a silver trail, based on the 10\% tolerance band colour.
Moved the {\tt asteroid.lsl}, {\tt comet.lsl}, and
\verb+comet_head.lsl+ scripts from the {\tt scripts/ephemeris}
directory, where they were incorrectly placed, to the {\tt
scripts/planets} directory where they belong.
Installed the new, much faster, version of {\tt fuis()} in Galactic Centre,
Galactic Patrol, Gravitation, and Numerical Integration. This version
removes capabilities we don't require (preservation of sign on negative
zero and encoding of infinities) and, in return, runs almost three
times faster than the version from the LSL Library.
\date{2021 February 11}
Rewrote the orbit computation code in the Orbits script's handling of
the \verb+LM_OR_PLOT+ and \verb+LM_EP_RESULT+ messages to store all its
Julian dates in the [ \verb+whole_day+, fraction ] list format, use
{\tt sumJD()} to increment dates while plotting the orbit, and a new
{\tt compJD()} function to compare dates in list format. This removes
a great deal of code gnarl and makes it much easier to understand what
is going on.
Removed the special-purpose code for closing elliptical orbits and
replaced it with simple computation of the closing segment. This
allows the adaptive segment length mechanism to work on the first
and last segments of the orbit without any special cases or duplication
of code.
Replaced the complex and ugly code for plotting parabolic and
hyperbolic trajectories with a much simpler strategy which computes the
start and end dates of the plot by subtracting and adding the extent to
be plotted from the perihelion date. These are then used precisely as
the start and end dates of an elliptical orbit, and allows the adaptive
segment length mechanism to be used without modification.
Created a new model script, ``{\tt Nearby Stars}'', based upon the
table in A. K. Dewdney's {\em The Armchair Universe}, p. 235. This
represents the positions and velocities of stars near the Sun, as known
in 1988. I'll have see what's available from the Gaia data releases or
more recent catalogues to create a more comprehensive model. This
isn't a particularly interesting model, since the nearby stars are so
far apart with respect to their masses, they just keep on going with
their own proper motions until they pass the Kaboom radius and go away.
I'll have to experiment with stirring things up with, say, a passing
through intermediate mass black hole, to see if that makes things more
thrilling.
\date{2021 February 13}
Completed a major revision of how orbits and plotted and ellipses fit
for orbits of sources orbiting the Galactic Centre. Due to the
historical path by which the code was developed, there was a large
degree of duplication between the orbit displays generated for Solar
System bodies in Orbits and the equivalent code in Galactic Patrol.
This not only wasted space, but it made maintenance more difficult
because very similar functions were done in two different places. When,
for example, we added the adaptive step size for plotting orbits in
Orbits, it only applied to Solar System bodies and not Galactic Centre
sources.
The revision ripped out essentially all of the orbit-related code from
Galactic Centre and Galactic Patrol and replaced it with transmission
of the essential orbital elements when sources are added, then the
Orbits module sending a \verb+LM_EP_CALC+ message to Galactic Patrol to
calculate the positions of the source. This is not entirely
straightforward because the ephemeris calculators for Solar System
return heliocentric spherical co-ordinates (L, B, R), while Galactic
Centre's evaluator computes rectangular (Cartesian) co-ordinates (X, Y,
Z), so when using these co-ordinates code must be aware of the source.
Nonetheless, the duplication of code is minor and most of the orbit
display code is now in common. This dramatically reduced memory usage
in Galactic Centre and Galactic Patrol, making them entirely safe from
out of memory conditions even when loading large models such as our
``Sgr A*'' script.
Note that Minor Planets still has its own handler for the
\verb+LM_OR_ELLIPSE+ message, which largely duplicates that in Orbits.
Another refinement would be getting rid of it as well, but I will leave
this for another day, as the level of duplication is modest and we
aren't tight on memory in Minor Planets.
\date{2021 February 14}
Promoted the script containing examples of representative minor planets
to \verb+notecards/minor_planets.nc+ and added to the Git repository.
Completed the rationalisation of orbit display by removing the
\verb+LM_OR_ELLIPSE+ handler in Minor Planets and integrating
generation of orbit ellipses for minor planets with the main code in
Orbits. This required ironing out a few wrinkles, such as transmitting
eccentricity and semi-major axis back to Orbits when a new minor planet
is tracked and modifying the {\tt apsides()} function in Orbits to
correctly compute the perihelion and aphelion dates for minor planets
from their orbital elements, but in the end little code was added there
and a great deal removed from Minor Planets.
Cleaned up all of the dead code commented out and made obsolete by the
re-organisation of the orbit and ellipse display mechanisms.
Began the upgrade of the Earth model to be responsive to the date.
Added code to process the Julian day included in the UPDATE message
from the deployer, extract the Gregorian month, and set the texture
for the Earth globe to the correct month from the inventory. We
also calculate the Greenwich Mean Sidereal Time (GMST) which, in
conjunction with the position of the Earth (from the update) and
deployer (provided by the PINIT message), we should be able to
rotate the Earth so the proper hemisphere faces the Sun, but I shall
defer such a tilt with rotation until I've gotten some shut-eye.
Linked the Luna model to the Earth model as a sub-link, with the
intention of setting its position based upon our {\tt lowmoon()}
calculation from the date in the UPDATE message. This is not presently
done.
\date{2021 February 15}
To make it simpler to initially position the Earth and Moon model, I