Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate wiki files to docs #162

Merged
merged 3 commits into from
Nov 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions doc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
![alt text](../OnAIR_logo.svg "The OnAIR logo, italicized NASA worm style font in blue and orange")

# Documents and Guides

## Start Here

[Tutorial](tutorial.md) : Steps through installation, running, updating configuration files, and loading plugins. IN PROGRESS

[Purpose and Use](purpose-and-use.md) : When to use OnAIR (and when _not_ to). NOT COMPLETE

## Guides

[Running with Redis](redis-example.md) : How to run OnAIR with live data provided via Redis.

[Running with cFS](cfs-onair-guide.md) : How to run OnAIR with NASA's core Flight System as a live data source.

[Unit-Testing](unit-testing.md) : How to run the unit-tests and generate a coverage report.

[Writing your own Plugin](writing-your-own-plugin.md) : NOT COMPLETE

[Writing your own DataSource](writing-your-own-data-source.md) : NOT COMPLETE

## Further Reading/Learning

[OnAIR's Architecture](architecture.md) : Describe's OnAIR's architecture. IN PROGRESS

[Publications](publications.md) : Notable publications
167 changes: 167 additions & 0 deletions doc/architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@

# **WIP: Under Construction and not yet complete.**

The cognitive architecture is the heart of OnAIR and consists of several components.

- [Configuration Files](#the-configuration-files)
- [Initialization File](#initialization-ini-file)
- [Telemetry Definitions File](#telemetry-definitions-json-file)
- [OnAirDataSource](#the-onairdatasource)
- [Pipeline](#the-pipeline)
- [Data Types](#data-types)
- [Plugins](#the-plugins)

## The Configuration Files
These files define the components and data structure that will be used by a running instance of OnAIR.

### Initialization (.ini) File
Provides the details about the components and other files used by OnAIR to perform its data reasoning.

It consists of the following sections:

- **[FILES]** - Pathing and file name information, it is a required section and all following keys are required
- TelemetryFilePath (string) - location of the telemetry file on the local system
- TelemetryFile (string) - name of the telemtry file, used by file access [OnAir data sources](#the-onairdatasource)
- MetaFilePath (string)- location of the telemtry definitions file
- MetaFile (string) - name of the [telemetry definitions file](#telemetry-definitions-json-file), a JSON file

- **[DATA_HANDLING]** - The telemetry data parser, it is a required section and the following key is required
- DataSourceFile (string) - full path and python file name of the [OnAir data source](#the-onairdatasource) to use

- **[PLUGINS]** - The various [plugins](#the-plugins) that OnAIR will use to construct the [pipeline](#the-pipeline), it is a required section and all following keys are required
- KnowledgeRepPluginDict (dict)
- LearnersPluginDict (dict)
- PlannersPluginDict (dict)
- ComplexPluginDict (dict)

Each plugin dictionary consists of key, name for the plugin at runtime, to value, path to the plugin's base directory. The key name is not required to be the same as the name of the plugin, but the directory used for the plugin must contain the concrete plugin class named **\<directory name\>_plugin.py**. Multiple of the same plugin directory may be used by defining unique key names, e.g. {"Reporter1":"plugins/reporter", "Reporter2":"plugins/reporter"} will provide two reporter plugins. A plugin type may be left empty by giving it an empty dict, **{}**.

- **[OPTIONS]** - Provides for any optional settings, section and its key are optional
- IO_Enabled (bool) - this determines whether or not to provide text output during runtime, omission of this equates to **_false_**

### Telemetry Definitions (.json) File
Also known as the 'Metafile', this provides the information necessary for OnAIR to understand the received data.

## The OnAirDataSource
This is the adapter that attaches OnAIR to a telemetry source. It provides the basic data that is used by the cognitive components to render reasoning about the system.

There are a few provided by default (located in the [onair/data_handling](https://github.com/nasa/OnAIR/tree/686df367bf4b9679ee9be11524230e99a499e5f0/onair/data_handling) directory):
- CSV - data from a .csv formatted file
- Redis - data from Redis server channels
- SBN - data via the Software Bus Network attached to an instance of [NASA's core Flight Software](https://github.com/nasa/cFS "cFS on GitHub")

However, all of these just implement the abstract class `OnAirDataSource` and users are able (nay, encouraged!) to write their own.

## The Pipeline
This is the path in which the received data from the source will flow.

The order of plugin operations is determined by placement in the plugin list within the [initilization](#initialization-ini-file) file used when running OnAIR. Plugins run from first to last in the order they are placed within their dictionary definitions.

### Data Types
There are two types of data used by the constructs in OnAIR, low and high level data

- `low_level_data`
- also referred to as the "frame"
- current snapshot of data received through whatever [OnAirDataSource](#the-onairdatasource) is in use

- `high_level_data`
- reasoned data from plugins
- built and grows as the [pipeline](#the-pipeline) is traversed


### The Plugins

There are two methods required to be implemented by OnAIR for the plugins, `update` and `render_reasoning`.
- `update` pulls data into the plugin for use, this includes either low_level_data, high_level_data, or both dependent upon the plugin type
- `render_reasoning` pushes out high_level_data in the form of a python dict with key/value pairs, i.e., this is the data you want made available to plugins further down the pipeline

What a plugin does with the data and how it renders its reasoning is up to the plugin developer to decide. However, the order of operations is established by the initialize file used and OnAIR.

### Plugin Flow

- Knowledge Representations (KR) - run first
- all KRs run `update`, receiving ONLY `low_level_data`
- all KRs run `render_reasoning`, returning their respective dictionaries of reasonings
- all KR reasonings are put into the `high_level_data` as "\<KR plugin name\>:{\<returned reasoning dict\>}"
- Learners (LN) - run second
- all KRs run `update`, receiving `low_level_data` and all KR's resonings in the `high_level_data`
- LNs do not receive other LNs reasonings
- all LNs run `render_resoning`, returning their respective dictionaries of reasonings
- all LN resonings are put into the `high_level_data` as "\<LN plugin name\>:{\<returned reasoning dict\>}"
- Planners (PL) - run third
- all PLs run `update`, receiving ONLY KR's and LN's reasonings in the `high_level_data`
- PLs do not receive other PLs resonings
- all PLs run `render_resoning`, returning their respective dictionaries of reasonings
- all PL resonings are put into the `high_level_data` as "\<PL plugin name\>:{\<returned reasoning dict\>}"
- Complex Reasoners (CR) - run last
- each CR runs `update` and `render_resoning` receiving all KR, LN, PL, and any previous CR's reasonings in the `high_level_data`
- each CR completes resoning, returning their respective dictionaries of reasonings
- each CR resonings are put into the `high_level_data` as "\<CR plugin name\>:{\<returned reasoning dict\>}"
- CRs in turn get progressively more data than the one before it

Here is a illustration of this relationship:
[insert image here]


The best way to "see" this relationship is to run the reporter example:
```
python driver.py onair/config/reporter_config.ini
```
sample output:
```
...
INTERPRETED SYSTEM STATUS: ---
Knowledge Reporter 1: UPDATE
Knowledge Reporter 2: UPDATE
Knowledge Reporter 1: RENDER_REASONING
Knowledge Reporter 2: RENDER_REASONING
Learners Reporter 1: UPDATE
Learners Reporter 2: UPDATE
Learners Reporter 1: RENDER_REASONING
Learners Reporter 2: RENDER_REASONING
Planner Reporter 1: UPDATE
Planner Reporter 2: UPDATE
Planner Reporter 1: RENDER_REASONING
Planner Reporter 2: RENDER_REASONING
Complex Reporter 1: UPDATE
Complex Reporter 1: RENDER_REASONING
Complex Reporter 2: UPDATE
Complex Reporter 2: RENDER_REASONING
...
```

This gives some minimal output; however, you can edit the reporter plugin ([plugin/reporter/reporter_plugin.py](https://github.com/nasa/OnAIR/blob/686df367bf4b9679ee9be11524230e99a499e5f0/plugins/reporter/reporter_plugin.py) line 14) and change verbose_mode to True:

```
...
INTERPRETED SYSTEM STATUS: ---

Knowledge Reporter 1: UPDATE

: headers ['Time', 'VOLTAGE', 'CURRENT', 'THRUST', 'ALTITUDE', 'ACCELERATION', 'TEMPERATURE', 'SCIENCE_COLLECTION', 'LABEL_ERROR_STATE']

: low_level_data <class 'list'> = '[946707839.0, 30.0, 12.0, 200.0, 0.0, 0.0, 182.28, 0.0, 1.0]'

: high_level_data <class 'dict'> = '{}'

Knowledge Reporter 2: UPDATE

: headers ['Time', 'VOLTAGE', 'CURRENT', 'THRUST', 'ALTITUDE', 'ACCELERATION', 'TEMPERATURE', 'SCIENCE_COLLECTION', 'LABEL_ERROR_STATE']

: low_level_data <class 'list'> = '[946707839.0, 30.0, 12.0, 200.0, 0.0, 0.0, 182.28, 0.0, 1.0]'

: high_level_data <class 'dict'> = '{}'

Knowledge Reporter 1: RENDER_REASONING

: My low_level_data is [946707839.0, 30.0, 12.0, 200.0, 0.0, 0.0, 182.28, 0.0, 1.0]

: My high_level_data is {}

Knowledge Reporter 2: RENDER_REASONING

: My low_level_data is [946707839.0, 30.0, 12.0, 200.0, 0.0, 0.0, 182.28, 0.0, 1.0]

: My high_level_data is {}
...
```
2 changes: 1 addition & 1 deletion doc/cfs-onair-guide.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Using OnAIR with Core Flight System (cFS)
# Using OnAIR with core Flight System (cFS)

## Overview

Expand Down
10 changes: 10 additions & 0 deletions doc/publications.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# The Onboard Artificial Intelligence Research (OnAIR) Platform

Presented at AI in and for SPACE (SPAICE) 2024.
Paper available here: https://zenodo.org/records/13885517

## Abstract

In this paper, we present the NASA On-Board Artificial Intelligence Research (OnAIR) Platform, a dual-use tool for rapid prototyping autonomous capabilities for earth and space missions, serving as both a cognitive architecture and a software pipeline.
OnAIR has been used for autonomous reasoning in applications spanning various domains and implementation environments, supporting the use of raw data files, simulators, embodied agents, and recently in an onboard experimental flight payload.
We review the OnAIR architecture and recent applications of OnAIR for autonomous reasoning in various projects at NASA, concluding with a discussion on the intended use for the public domain, and directions for future work.
1 change: 1 addition & 0 deletions doc/purpose-and-use.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
TODO!
101 changes: 101 additions & 0 deletions doc/redis-example.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
Using the redis_adapter.py as the DataSource, telemetry can be received through multiple Redis channels and inserted into the full data frame.

## OnAIR config file (.ini)

The redis_example.ini uses a very basic setup:
- meta : redis_example_CONFIG.json
- parser : onair/data_handling/redis_adapter.py
- plugins : one of each type, all of them 'generic' that do nothing

## Telemetry config file (.json)

The telemetry file defines the subscribed channels, data frame and subsystems.
- subscriptions : defines channel names where telemetry will be received
- order : designation of where each 'channel.telemetry_item' is to be put in full data frame (the data header)
- subsystems : data for each specific telemetry item (descriptions only for redis example)


## Receipt of telemetry

The Redis adapter expects any published telemetry on a channel to include:
- time
- every telemetry_item as described under "order" as 'channel.telemetry_item'

All messages sent must be json format (key to value) and will warn when it is not then discard the message (outputting what was received first). Keys should match the required telemetry_item names with the addition of "time." Values should be floats.

## Running the example

If not already running, start a Redis server on 'localhost', port:6379 (typical defaults)
```
redis-server
```

Start up OnAIR with the redis_example.ini file:
```
python driver.py onair/config/redis_example.ini
```
You should see:
```
Redis Adapter ignoring file

---- Redis adapter connecting to server...

---- ... connected!

---- Subscribing to channel: state_0

---- Subscribing to channel: state_1

---- Subscribing to channel: state_2

---- Redis adapter: channel 'state_0' received message type: subscribe.

---- Redis adapter: channel 'state_1' received message type: subscribe.

---- Redis adapter: channel 'state_2' received message type: subscribe.

***************************************************
************ SIMULATION STARTED ************
***************************************************
```

In another process run the experimental publisher:
```
python redis-experiment-publisher.py
```
This will send telemetry every 2 seconds, one channel at random until all 3 channels have recieved data then repeat for a total of 9 times (all of which can be changed in the file). Its output should be similar to this:
```
Published data to state_0, [0, 0.1, 0.2]
Published data to state_1, [1, 1.1, 1.2]
Published data to state_2, [2, 2.1, 2.2]
Completed 1 loops
Published data to state_2, [3, 3.1, 3.2]
Published data to state_1, [4, 4.1, 4.2]
```
And OnAir should begin receiving data similarly to this:
```
--------------------- STEP 1 ---------------------

CURRENT DATA: [0, 0.1, 0.2, '-', '-', '-', '-']
INTERPRETED SYSTEM STATUS: ---

--------------------- STEP 2 ---------------------

CURRENT DATA: [1, 0.1, 0.2, 1.1, 1.2, '-', '-']
INTERPRETED SYSTEM STATUS: ---

--------------------- STEP 3 ---------------------

CURRENT DATA: [2, 0.1, 0.2, 1.1, 1.2, 2.1, 2.2]
INTERPRETED SYSTEM STATUS: ---

--------------------- STEP 4 ---------------------

CURRENT DATA: [3, 0.1, 0.2, 1.1, 1.2, 3.1, 3.2]
INTERPRETED SYSTEM STATUS: ---

--------------------- STEP 5 ---------------------

CURRENT DATA: [4, 0.1, 0.2, 4.1, 4.2, 3.1, 3.2]
INTERPRETED SYSTEM STATUS: ---
```
Loading
Loading