Using TLE.JS Library for Satellite Position and Dish Pointing
Tags: satellite, javascript, node, tutorial
Published: 2020-08-10 14:52:41

Earlier last year I, blew the dust off my satellite communication textbook and attempted to write a dish pointing app for my company that's in the satellite communications realm.

I quickly discovered that the math was involved, and after several days of exhausting math and Python code writing, I came up a (barely) usable app:

{% github Awmages/dish-pointer %}

Recently, I came back to this project wanting to port it over to a React app and **dreaded** refactoring the math, that is, until I discovered Two-Line Elements(TLE) set and the [tle.js](https://github.com/davidcalhoun/tle.js/) library.

##What is TLE

According to [wikipedia.org](https://en.wikipedia.org/wiki/Two-line_element_set) the two-line element is
> ... a data format encoding a list of orbital elements of an Earth-orbiting object for a given point in time, the epoch. Using suitable prediction formula, the state (position and velocity) at any point in the past or future can be estimated to some accuracy.


below is an example TLE of the International Space Station

```ISS (ZARYA)             
1 25544U 98067A   20220.25765183  .00031791  00000-0  57938-3 0  9999
2 25544  51.6453  95.7043 0001117  20.0719 119.8247 15.49172948239931```

TLEs give a series of mathematical numbers to plot the orbit of the space object, which can be utilized to find the predicted Latitude and Longitude (among other things).

TLE's can be obtained from multiple sites such as [celestrak.com](https://celestrak.com/NORAD/elements) [space-track.org](http://www.space-track.org/), and other websites.

##What is TLE.js

During research for my web application, I discovered the [TLE.js](https://github.com/davidcalhoun/tle.js/) library. TLE.js is a JavaScript library that processes the tle data with easy to use functions.

{% github davidcalhoun/tle.js %}


##TLE.js Example 1: Satellite Position

###Installation
`npm install tle.js` or `yarn add tle.js`

###Import
in our index.js file import getLatLngObj
```javascript
const { getLatLngObj } = require("tle.js/dist/tlejs.cjs");
```
###Usage
create a constant of a string
```javascript
const { getLatLngObj } = require("tle.js/dist/tlejs.cjs");

const tle = `ISS (ZARYA)
1 25544U 98067A   17206.18396726  .00001961  00000-0  36771-4 0  9993
2 25544  51.6400 208.9163 0006317  69.9862  25.2906 15.54225995 67660`;
```
then console log the results
```javascript
const { getLatLngObj } = require("tle.js/dist/tlejs.cjs");

const tle = `ISS (ZARYA)
1 25544U 98067A   17206.18396726  .00001961  00000-0  36771-4 0  9993
2 25544  51.6400 208.9163 0006317  69.9862  25.2906 15.54225995 67660`;

console.log(getLatLngObj(tle));
```
Console Log:```text
{ lat: 32.69293160995973, lng: -164.48496742284183 }
```
Note in our example Lng is a negative value; this means the satellite is currently in the Western Hemisphere, a positive value means would mean it is in the Eastern Hemisphere. If the Lat value is negative, then the satellite is in the Southern Hemisphere, if positive then the Northern Hemisphere.

```javascript
const { getLatLngObj } = require("tle.js/dist/tlejs.cjs");

const tle = `ISS (ZARYA)
1 25544U 98067A   17206.18396726  .00001961  00000-0  36771-4 0  9993
2 25544  51.6400 208.9163 0006317  69.9862  25.2906 15.54225995 67660`;

let satPos = getLatLngObj(tle);
let lat = "N";
let lng = "E";

if (satPos.lat < 0) {
  lat = "S";
}
if (satPos.lng < 0) {
  lng = "W";
}
console.log(
  "Latitude: " + Math.abs(satPos.lat) + " " + lat + ", " + "Longitude: ",
  Math.abs(satPos.lng) + " " + lng
);
```
Console Log
```
Latitude: 50.59794614813468 N, Longitude:  91.89917475916603 W
```

##TLE.js Example 2: Dish Pointing

To get azimuth and elevation directions from tle.js, use `getSatelliteInfo()`. `getSatelliteInfo()` variables are `getSatelliteInfo(tle, optionalTimestamp, observerLat, observerLng, oberserverElevation)` note that the timestamp is optional.

Grab the desired lat/long coordinates of the observer site, and paste into the correct constants.
```javascript
const { getSatelliteInfo } = require("tle.js/dist/tlejs.cjs");

const tle = `ISS (ZARYA)
1 25544U 98067A   17206.18396726  .00001961  00000-0  36771-4 0  9993
2 25544  51.6400 208.9163 0006317  69.9862  25.2906 15.54225995 67660`;

const observerLat = 37.709203;
const observerLng = -97.427754;
```

run `getSatelliteInfo()`. If not using optionalTimestamp enter null, if on the ground enter 0 for elevation.

```javascript
const { getSatelliteInfo } = require("tle.js/dist/tlejs.cjs");

const tle = `ISS (ZARYA)
1 25544U 98067A   17206.18396726  .00001961  00000-0  36771-4 0  9993
2 25544  51.6400 208.9163 0006317  69.9862  25.2906 15.54225995 67660`;

const observerLat = 37.709203;
const observerLng = -97.427754;

console.log(getSatelliteInfo(tle, null, observerLat, observerLng, 0))
```
Console Log
```
{
  lng: -103.77041233731748,
  lat: 48.083145374941935,
  elevation: 11.084527491294315,
  azimuth: 337.91719541768254,
  range: 1357.0378375655516,
  height: 393.729417250428,
  velocity: 7.679154118414166
}
```
* lng is the longitudinal position of the satellite
* lat is the latitudinal position of the satellite
* elevation is the dish's pointing elevation
* azimuth is the dish's needed direction to point the satellite

`getSattelliteInfo()` doesn't take in consideration the line of sight of the dish, and whether the satellite is observable for that use `getVisibleSattelites()`.

##Conclusion
By utilizing the tle.js library, modern engineers can quickly deploy web or mobile applications that can track satellites, provide satellite dish look angles, and provide a list of visible satellites. With just a bit of searching 
you can find great libraries, like tle.js, that significantly reduce the headache and time spent on small components of much larger projects.

###Example Code
{% github Awmages/tle-example %}