AstroZ: Astronomical and Spacecraft Toolkit

Hey just wanted to show off my project AstroZ! It’s still a work in progress, but it is far enough that I wanted to show it off. It currently supports parsing of the 2 most common data formats you’ll encounter in the spacecraft world (CCSDS for telemetry, and Vita49 for RF communications).

Recently, I added in TLE support which will allow me to begin the next phase I’m excited to build out; orbit propagation and determination which will lead into mission planning. I know this is a bit niche, but excited to be using zig in this way, and at some point i want to utilize this toolkit to build out a simulation suite

28 Likes

I was able to get the RK4 orbit propagation working today and I’m happy with the accuracy with fairly minimal inputs! I’m hoping to add more complex models in the future to further get orbit prop as accurate as I can.

I tested a 2 day orbit prediction using an existing real spacecrafts TLE and was very happy with the results. I am still on the lookout for a decent plotting lib for zig (LMK what is out there please!), so for now the visualization is done in python, but all the raw prop data is fed directly from zig

8 Likes

made a quick update that also adds in impulse maneuvers. Here is what a handful of small pulses from the “engine” does to orbit prop using the same TLE

3 Likes

bit better of a look with the impulse towards the end of the prop and not towards the beginning

2 Likes

now with phase maneuvers. This makes raising / lower orbits a breeze! No longer need 2x impulse inputs. You can just ask for a phase maneuver which will handle the rest! Useful when you are trying to meet up with another spacecraft, by raising/lowering orbit

1 Like

one of the trickier maneuver types: plane changes. Ran into a challenging bug implementing this where energy of the sc was growing exponentially while it was attempting this maneuver. In plane changes, the energy of the spacecraft should remain unchanged and the orbit should only shift velocity vector direction but not magnitude (due to orbits being a closed system). After some tweaks was able to find out what was causing the crazy energy growth and get something that looks as I would expect

2024-07-09T23:48:30,338815486-04:00

3 Likes

now i want to start focusing on the spacecraft modeling. So the first step in that is being able to determine orientation. The code is def still a bit of a mess, and can probably be cleaned up, but my goal was to get it working and I am happy seeing the orientation showing up as I would expect

3 Likes

FITS File image generation was my next thing to tackle here. S/O to @tensorush for porting cfitsio to zig for me and making this a much simpler process overall.

Here is an example Hubble telescope fits image of a narrowband filter for the Pillars of Creation being parsed via AstroZ

7 Likes

It’s been a minute since i got around to working on this but happy to say that orbital mechanics are finally part of this repo! You can use it calculate transfers and such between celestial objs. I ran through a quick test between Mars and Earth and im very happy with the nice path the “spacecraft” would take


6 Likes

Just finished up adding in monte carlo simulations to the orbital mechanics. In a perfect world we would know with 100% all the variables exactly but we need to introduce some randomness to make sure everything still works when we introduce an imperfect system

9 Likes

Update: astroz now has the fastest open source SGP4 propagation implementation

SGP4 is the prediction algorithm for accurate orbit prediction. Every satellite tracker and Starlink pass app is using SGP4 most likely under the hood, and now zig can claim the fastest open source implementation

Here are some benchmarks against the main alternatives:

Implementation Speed
astroz (zig) 5.6M props/sec
sgp4 (rust) 5.3M props/sec
astroz (python+zig) 4.8M props/sec
satkit (python+rust) 3.4M props/sec
python-sgp4 (python+cpp) 2.8M props/sec

Also now astroz can be used via python:
pip install astroz

Python hits ~4.8M/sec with numpy, which is quite a bit faster than python-sgp4 (the most widely used SGP4 library despite going through FFI.

Went the C API route and curious if there is a better way than how its implemented here? Open to any feedback on it. Thanks!

Repo: GitHub - ATTron/astroz: Astrodynamics and Spacecraft Toolkit Written in Zig! Features orbit prop, celestial precession, CCSDS parsing, RF parsing, fits image parsing, and more!

17 Likes

Hi! Really impressive work.

Regarding the python bindings, you really only have two options:

  • C API: what you just did, but you need to write and ship Python files
  • CPython: what I did in Zignal, so the whole library compiles to zignal.so and I just do import zignal, and everything is there.

Within the CPython option you also have two options:

Also, have a look at pdoc to generate documentation for your Python bindings:

Example for zignal: zignal API documentation

7 Likes

Thanks for the advice @adria ! Yeah the easiest way i thought to “brute force” was just to write the python, but i like the idea of a *.so since it may keep things cleaner.

Something I don’t have a ton of info on, but if i moved from ctypes with C API and instead go the CPython route does that remove the FFI overhead / slowdown ? I noticed that the FFI overhead does eat a decent amount of performance ?

Yes, using Cpython instead of FFI should noticeably increase the performance.
Your functions will have the same performance as built-in Python functions. No code will be interpreted by Python: just pointer casting, and “parsing”.
With the FFI approach you need to do a lot of extra work at runtime.

Sickk i will take a pass at doing it that wat then! Right now i know there is a potential footgun where if you don’t batch your propagations the FFI overhead really starts to bog things down so i would rather remove that

1 Like

I’d recommend doing some benchmarking first, like porting a small functionality you’ve noticed it’s slow.
The CPython API is quite verbose…

yeah i actually did some work today unrelated to the bindings, but adding SIMD operations to the propagation methods and basically got a 2x speedup for “free” (minus the hours of my life).

I have to test the single passing with it now to see, but before i was basically down to matching the other libs in terms of speed in the worst case, which was mainly due to the FFI overhead eating more and more cpu time the longer it ran.

I noticed in your implementation that you directly call the the C API from zig which i really like, but i see how verbose it gets and you end up having to create all the generators yourself

3 Likes

Right, I’m learning as I go, so from time to time a give another look the the bindings and the docs and refactor stuff.

Did a write up the optimization deep dive: I Made Zig Compute 33 Million Satellite Positions in 3 Seconds. No GPU Required. | Anthony T's Blog

Covers the SIMD stuff, the vectorized atan2, comptime constants, and the cache tiling for
constellation mode. Also have a demo of using the python bindings to prop 19 milion positions for the entire LEO public catalog: 13,344 Satellites - astroz

ziggit_small

17 Likes

Wow, this is super cool!