You are browsing as a guest. Sign up (or log in) to start making projects!

9h 33m 45s logged

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 Aqua
  • NASA’s Terra
  • Tiangong
  • ISS (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

0
5

Comments 0

No comments yet. Be the first!