OrbitLens Devlog #4: Adding multiple satellites
In my last update, I finally got a 3D model of the ISS rendering on
the globe with a basic UI dashboard. It looked cool, but I wanted to
scale it up. I wanted to add multiple famous satellites on top of the
ISS:
The Hubble Space Telescope (HST)NASA’s AquaNASA’s TerraTiangongISS (which already exists)
At least for now. Maybe in later stages, I can add Starlink satellites
or sth. Here is waht I built, how I built it, and the challenges I
faced.
Change/Challenge 1: the orbit that looked like a slinky
I hardcoded a 90-minute orbit line (the ISS orbit time). But other
satellites have different orbital periods, so 90 mins fell short.
Increasing it to a 12-hour calculation made the ISS orbit look like a
massive slinky wrapping around the Earth cus its orbit is only 90mins. I
fixed this by dynamically calculating the exact total orbit time using
the satellite’s math:
const periodMinutes = Math.ceil((2 * Math.PI) / satrec.no);
const halfPeriod = Math.floor(periodMinutes / 2);
Change/Challenge 2: IP ban (again)
The JS fetch() doesn’t consider a ‘429 too many requests’ (i got this
cus vite reloaded the page every time i saved something) response as a
network error, so it tried calculating the HTML error page as orbital
math and crashed. I fixed this by manually checking the response.ok HTTP
status. If the API blocks me, the code redirects to an “Offline
Fallback Mode”—loading a hardcoded string of ISS TLE math so the app
survives.
Change/Challenge 3: improper API request
After like 4 hours, I realized I still wasn’t getting a proper API
response even though the IP ban would have worn off. I looked at the
code and realized I was pulling data for all five satellites in one go
by just comma-separating the values in the URL like this:
…/gp.php?CATNR=25544,20580,48274&FORMAT=tle
(each number references to a satellite)
But after CelesTrak’s documentation, it strictly dictated that the
CATNR parameter only accepts a single catalog number. The server
rejected the request, my code assumed 0 satellites, and the engine
crashed.
The fix:
Writing five separate fetch() blocks is messy, and implementing an
await fetch() in a for-loop creates a slow “waterfall” effect (waiting
for one to finish before starting the next).
I fixed this with JavaScript’s Promise.all. I created an array of the
exact NORAD IDs, mapped over it to generate separate, perfectly
formatted fetch requests, and Promise.all fires them all at the exact
same time.
Change/Challenge 4:
I wanted 3D models for all of these. I found Aqua and HST easily from
NASA. I found Terra, but it was fetching some other incompatible file I
didn’t have, so I just scratched the Terra model. Tiangong was the
biggest pain—everywhere I looked was either paid or on Sketchfab, and I
cant create a Sketchfab account cus of some stupid Epic Games
restriction.
Implementing the files I did have was the next issue. Hardcoding
multiple GLTFLoader blocks would turn the code into spaghetti. Plus, 3D
models from the internet aren’t scaled equally—my Hubble was massive,
and my Aqua model was tiny.
The fix:
I built a central Model Registry object. It maps a satellite’s NORAD
ID to its file path and a specific scale multiplier. Even better, I
implemented a fallback for satellites I done have a model for. If I
track a satellite (like Tiangong) but leave the file path as null, the
code detects this and dynamically generates a glowing cyan sphere using
Three.js math to take its place.
Changes 5 and 6:
I updated the dashboard to include a dropdown to select the satellite
and the telemetry updates accordingly. I also added a camera toggle
feature where the user can lock the camera to follow the satellite or
stay locked on the Earth. Lastly, I implemented a custom loading screen
while the models load.
P.S.Lots of info is compressed cus i crossed the 4000 char limit.
Comments 0
No comments yet. Be the first!
Sign in to join the conversation.