spi

module
v0.0.0-...-e61c81d Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 7, 2021 License: MIT

README

Streaming Proximity Index (SPI)

Introduction

This repo contains a Go implementation of a streaming index for object proximity in space above Earth. Currently this implementation consumes streams of TLEs, and it and produces a stream of proximity reports.

The emitted reports are not Conjunction Summary Messages or related data products. Output is not intended for any operational, planning, or decision-making purpose. Please see the license (MIT) for this software.

This code is designed to support large catalogs and to participate in multi-stage event processing systems. For example, an SPI processor could consume orbital data produced by multiple upstream processes, and it could then feed proximity reports to downstream process such as high-fidelity conjunction analysis, user interfaces, and message routers.

SPI is the core index for the ASTRIA's Conjunction Streaming Service (CSS), which includes a message bus, graphical user interfaces, and other components. SPI is itself an ASTRIA project.

Usage

Prerequisites

You need to install Go to use this code. Once Go is installed, you should be able to download and compile the tools with

go get github.com/ut-astria/spi/...
Batch

For a simple, non-streaming demo, you can pipe TLEs to the demo program spibatch.

Here's an example that uses Celestrak data. jq is used to extract some data from generated reports.

mkdir -p data

for F in starlink planet cosmos-2251-debris.txt 1999-025; do
  curl https://www.celestrak.com/NORAD/elements/$F.txt > data/$F.tle
done

cat data/*.tle |
  spibatch -horizon 3600 |
  tee reports.json |
  jq -r 'select(.Speed > 10 and .Dist < 5)|[.At,.Dist,.Objs[0].LLA.Alt,.Speed,.Objs[0].Name,.Objs[1].Name]|@csv'

Here's an example report:

{
    "Id": "b569e8cac4e46d81ef0b0abc14fc077dabd3423a",
    "Sig": "506c368347d0e191d983b22c2b6e2b6e7f8b99a1",
    "Generated": "2020-09-20T17:36:33.801853276Z",
    "At": "2020-09-20T18:33:55.5Z",
    "Dist": 17.087626,
    "Speed": 8.213095,
    "Objs": [
        {
            "Name": "30826",
            "Obj": {
                "CatNum": "30826",
                "TLE": [
                    "FENGYUN 1C DEB          \r\n",
                    "1 30826U 99025AVL 20264.50297615  .00000147  00000-0  32242-4 0  9992\r\n",
                    "2 30826  98.8949 276.7687 0195456 167.9040 347.1859 14.62649227722649\r\n"
                ]
            },
            "Age": 23378,
            "Type": "debris",
            "ECI": {
                "X": -1346.4899,
                "Y": 5031.214,
                "Z": 4583.924
            },
            "Vel": {
                "X": 0.25534344,
                "Y": 5.1364465,
                "Z": -5.6568265
            },
            "LLA": {
                "Lat": 41.527008,
                "Lon": -173.61009,
                "Alt": 569.4128
            }
        },
        {
            "Name": "45226",
            "Obj": {
                "CatNum": "45226",
                "TLE": [
                    "STARLINK-1217           \r\n",
                    "1 45226U 20012BA  20264.25001157 -.00012830  00000-0 -86243-3 0  9991\r\n",
                    "2 45226  52.9993 328.9800 0001287 117.8194  46.9549 15.05604400 33522\r\n"
                ]
            },
            "Age": 45235,
            "Type": "payload",
            "ECI": {
                "X": -1344.0011,
                "Y": 5016.6367,
                "Z": 4575.3623
            },
            "Vel": {
                "X": -6.65854,
                "Y": 1.3224211,
                "Z": -3.3971028
            },
            "LLA": {
                "Lat": 41.554783,
                "Lon": -173.59503,
                "Alt": 552.7139
            }
        }
    ]
}

We can use the utility program spiplot make a basic plot of the reported distances:

cat reports.json | spitool plot

The graph is written to reports.png.

Example output:

Example

Streaming (demo)

Streaming input and output is an important capability. As new data streams in, new reports and cancellations of obsolete reports stream out. SPI is designed for systems that run continuously, processing data as it becomes available and feeding downstream systems asynchronously.

The packages in this repo are intended to be used as components in large-scale event processing systems based on message buses or similar infrastructure. This code does not itself integrate with any specific message bus or streaming infrastructure. Since the SPI API is fairly simple, integration with these systems is usually straightforward. The example program spipipe demonstrates very basic streaming capabilities using UNIX pipes.

Here's a very basic example using FIFOs and the demo program spipipe. This example uses some Planet Labs historical TLEs.

mkfifo in
cat <>in | spipipe -v | tee pipe.json &
cat data/planetlabs/planet_mc_20200725.tle > in
cat data/planetlabs/planet_mc_20200726.tle > in
cat data/planetlabs/planet_mc_20200727.tle > in
sleep 5
kill $!
rm in
Application development

The primary end-user package is node, which represents a dynamic collection of core indexes from the index package. See cmd/spibatch and cmd/spipipe for some demo code that uses these packages.

Design

An SPI instance is configured for a time horizon (seconds to many hours), and SPI can maintain a rolling window for that horizon. When new TLEs arrive, those TLEs are continuously propagated (currently using SGP4) through that rolling window as time passes. SPI emits proximity reports asynchronously. As updated TLEs are ingested by SPI, SPI generates both new proximity reports and cancellations of obsolete previous reports.

The underlying index is composed of subindexes for time slices. These core indexes are based on S2 Geometry. SPI also supports optional inter-slice proximity scanning for efficient, higher-resolution output.

SPI is designed to be able to be scaled horizontally if necessary. In horizontal deployments, each SPI node manages its own set of time slices sampled (usually just modulo some value) from the horizon for the entire node cluster.

The SPI implementation is fully in-memory. There is no I/O other than consuming input and publishing output. SPI-based applications can of course use databases and other persistence mechanisms, but SPI itself doesn't do filesystem I/O. For efficient RAM use, SPI interns all data and uses 32-bit integers and floating point numbers for its index-intensive processing. Those implementation decisions are hidden from SPI users. As a capacity planning example, running SPI (spipipe) with a 10-minute horizon and 10,000 tracked objects has a resident set size (RSS) of about 2.2GB. With some configurations, tracking 25,000 objects with a 24-hour horizon has total RSS of about 1TB (perhaps across multiple nodes). Note that these capacity planning examples depend on configuration parameters, in-bound traffic, and evolving implemention details.

Directories

Path Synopsis
cmd
spitool
Package main is a command-line tool for working with TLEs.
Package main is a command-line tool for working with TLEs.
Package index implements a stream-able geospatial index on positions in Cartesian 3-space.
Package index implements a stream-able geospatial index on positions in Cartesian 3-space.
Package node implements a potentially live collection of indexes.
Package node implements a potentially live collection of indexes.
Package prop defines basic types for propagating data to a position.
Package prop defines basic types for propagating data to a position.
Package sgp4 provides a method for analytical propagation of a satellite.
Package sgp4 provides a method for analytical propagation of a satellite.
Package tle integrates SGP4 and package prop in a SGP4TLE.
Package tle integrates SGP4 and package prop in a SGP4TLE.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL