Implemented most of the RotationMatrix functions.
Added unit tests for combining rotation matrices, using a
rotation matrix to rotate a vector, and pivoting a rotation
matrix around its axes.
Replaced AstroVector operator '*' with infix function 'dot',
because it removes ambiguity between vector dot products
and vector cross products.
Later I will add a 'cross' infix function too.
Corrected minor typo in documentation for Python, C, C#, JavaScript.
"trasnform" -> "transform"
Moved Astronomy object to bottom of source file.
This object is going to end up with a lot of functions,
so it's best to keep outer classes above it.
Removed unnecessary empty {} after classes.
Replace Array<Array<Double>> with Array<DoubleArray>.
This is more efficient because Array<Double> boxes the numbers
inside it, whereas DoubleArray is unboxed.
Restructured the Java code so we pass in command
line arguments to select which demo we want to run.
We will also pass in date/time, latitude/longitude,
or whatever numeric data we need for future demos.
Automated test run of the Java demos from the
unit test suite.
Allow floating point values for seconds when initializing
an AstroTime from (year, month, ..., seconds).
AstroTime can now represent date/time to millisecond resolution.
Represent AstroTime strings in ISO 8601 format:
yyyy-mm-ddThh:mm:ss.sssZ
Minor docstring fixes.
Rename target file to 'astronomy.kt'.
Code changes need to be made to
generate/template/astronomy.kt
and then the target code Main.kt is written by
the code generator. Then both must be committed to git
before pushing to GitHub.
Generate astronomy.py directly in the package directory.
I realized it doesn't make sense to generate it in the
parent directory and then copy it; just generate it where
it will end up anyway.
Updated documentation so people know they can just do
pip install astronomy-engine
to install Astronomy Engine in their Python project.
Removed the GitHub Actions status badge because it is redundant with
the checkmark/X indicator.
Now that private symbols are no longer exported, I had to
fix a couple of places where the unit tests still accessed them.
The pip package was broken!
I violated ancient software development wisdom:
"If you haven't tested it, it doesn't work."
It is now working in:
https://pypi.org/project/astronomy-engine/2.0.15/
Version 2.0.15 of Astronomy Engine for Python (pip)
and Node.js (npm) add support for the new SiderealTime
function. This was previously an internal function,
but now it is exposed for outside callers.
This is just a stub to get started. None of the
necessary macros have been implemented in the Kotlin
code generator. But at least I can start editing the
Kotlin template and generating code from it.
Implemented the Body enum, with documentation strings
in comments. Reworked the Gradle build to generate
GitHub Flavored Markdown (gfm) instead of html.
Because the 'gradlew' command is a batch file in
Windows, I need to use the 'call' command to invoke
it from run.bat, or it does not return to run.bat.
Instead of being executed directly by the GitHub Actions
yml file, the Kotlin build now has been integrated with
the build/test steps for the other 4 languages in the
bash script `generate/run` and the Windows batch file
`generate/run.bat`. This will be necessary to control the
order of execution, because the Kotlin source code will have
to be written by the code generator before it is built
and executed.
I also added hints for myself and other contributors about
how to set up Kotlin/JDK tools on a new developement machine.
These instructions are not needed by most users of Astronomy Engine,
just contributors.
There was already an internal function for calculating
Greenwich Apparent Sidereal Time (GAST). By request,
I have exposed this function for outside users.
Added a minimal unit test to verify the function is
callable and returns the correct result for one case.
This function is already exhaustively tested by unit
tests that verify other functions that already called
this function when it was internal, so minimal testing
is sufficient in this case.
Added the following new functions to all 4 languages:
MassProduct: find the GM product for all Solar System bodies.
LagrangePoint: calculate L1..L5 state vectors for a pair of bodies.
LagrangePointFast: calculate L1..L5 state vectors given
state vectors and GM products of a pair of bodies.
Reworked the tests that use JPL Horizons output files containing
state vectors so that they generalize to different parameters.
Specifically, soon I will need to pass in (major_body, minor_body,
point) to support Lagrange point tests.
I want to be able to re-use the code for loading state
vectors from a JPL Horizons text file, instead of copy-n-paste
like I did in C. So I reworked it as an iterator.
There were a few places inside the unit test function LoadStateVectors
where I had error messages that printed the wrong function name
(VerifyStateBody instead of LoadStateVectors) if an error was detected.
This is because of a copy-n-paste oversight. They are fixed.
In languages that support it, using hypot(x,y) is a little
easier to read than sqrt(x*x + y*y). Some documentation
(e.g. the man page for the C function) leads me to believe
hypot might also be better behaved than sqrt in some cases.
The JavaScript Math.hypot() is especially nice because it works
for any number of dimensions, so I can use it in 2D and 3D cases.
C only allows 2D usage, as does Python 3.7. Python 3.8 added
support for any number of dimensions, but I don't want to break
compatibility with Python 3.7 just yet. Therefore, in C and Python,
I am only using hypot for 2D cases.
C# does not appear to have any kind of hypot function,
so no changes were made to the C# code.
Thanks to https://github.com/ebraminio for this suggestion.
There is no function double.IsFinite() in .NET Framework.
Reworked the sanity check in Astronomy.Pivot so the C# code
builds in these older .NET platforms.
My custom Markdown documentation generator for C had
a bug when emitting the listing of a #define.
It is not valid to try to hyperlink to other symbols,
because the Markdown syntax gets listed literally inside
the context of a C code block.
In most cases, people calculating Lagrange points will just
want to pass in the bodies and not have to worry about calculating
their state vectors and masses.
Renamed Astronomy_LagrangePoint to Astronomy_LagrangePointFast.
Added new function Astronomy_LagrangePoint that accepts body enum
values instead of state vectors and masses. It knows to optimize
the precision of the calculation by calling GeoMoonState for the
Earth/Moon case.
I confirmed that the Mac version of GitHub Actions does not
flush stderr on exit, so that is why I couldn't see my
diagnostic error messages. Now I can tell VerifyEquilateral
is failing due to a slightly out of bounds length ratio
in the Earth/Moon/M4 equilateral triangle. Made the tolerance
window a little larger, and trying again.
I think I have finally tracked down where the 5.4 arcminute
discrepancy comparing my L4 with JPL Horizons L4 is coming from.
When I feed JPL's geocentric Moon state vector through my
L4/L5 calculator, the result is in a slightly different plane
than it should be. It looks like a mistake in JPL Horizons!
I also fixed a bug where ctest's LoadStateVectors() was not
initializing the state.status before appending to the array.
The result was uninitialized random garbage in the status.
It is conceptually simpler to take cross products to
generate 3 coordinate axes (essentially a rotation matrix)
that represent radial, tangential, and normal directions
with respect to the major and minor bodies.
Before comparing my Lagrange point calculations to JPL Horizons,
I check to see if my Lagrange point calculations form an
equilateral triangle from (major body, minor body, L4/L5).
When ctest.c detects that a state vector error is
unacceptably large, it now prints extra diagnostics
about the two vector values, their magnitudes, and
how much of the error is angular and how much is
a magnitude discrepancy.
Calculated the angles between JPL Horizons velocity vectors
for the geocentric Moon and the geocentric L4/L5.
They are always very close to 60 degrees apart, within 0.15 arcsec.
This is not large enough to explain the velocity vector
errors my code calculates.
The Lagrange test was using Solar System barycentric
state vectors for the pair of bodies. This involved
a lot of unnecessary calculation.
For the Sun/EMB test, use heliocentric coordinates.
For the Earth/Moon test, use geocentric coordinates.
Fail the lagrange_jpl test if we see the major/minor/L4,L5
triangle deviate more than a tiny fraction from equilateral,
after adding the velocity components.
This convinces me that the JPL Horizons velocity vectors
make sense for L4/L5.
I'm having problems confirming formulas for L4/L5 velocity vectors.
So I wanted to test the assumption that these Lagrange points would
have velocity vectors that would leave the major body, minor body,
and Lagrange point in an equilateral triangle after all 3 bodies
continued in a straight line at their current relative velocities.
This does turn out to be the case, which means there is just
a bug in how I'm calculating the velocity vectors.
I just need to find the bug.