Skip to content

Commit

Permalink
Merge branch 'main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
dragonejt authored Jul 26, 2024
2 parents c8f0bab + 3f42da8 commit 74c983d
Show file tree
Hide file tree
Showing 6 changed files with 858 additions and 21 deletions.
42 changes: 23 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,10 @@ python driver.py -t
#### A few optional settings for the driver.py file
Options that may be added to the driver.py test run. Use these at your own discretion.

`--conftest-seed=###` - set the random values seed for this run
`--randomly-seed=###` - set the random order seed for this run
`--verbose` or `-v` - set verbosity level, also -vv, -vvv, etc.
`-k KEYWORD` - only run tests that match the KEYWORD (see `pytest --help`)
`--conftest-seed=###` - set the random values seed for this run
`--randomly-seed=###` - set the random order seed for this run
`--verbose` or `-v` - set verbosity level, also -vv, -vvv, etc.
`-k KEYWORD` - only run tests that match the KEYWORD (see `pytest --help`)

NOTE: Running tests will output results using provided seeds, but each seed is random when not set directly.
Example start of test output:
Expand All @@ -164,35 +164,38 @@ python -m coverage run --branch --source=onair,plugins -m pytest ./test/

#### Command breakdown:

`python -m` - invokes the python runtime on the library following the -m
`coverage run` - runs coverage data collection during testing, wrapping itself on the test runner used
`--branch` - includes code branching information in the coverage report
`--source=onair,plugins` - tells coverage where the code under test exists for reporting line hits
`-m pytest` - tells coverage what test runner (framework) to wrap
`./test` - run all tests found in this directory and subdirectories
`python -m` - invokes the python runtime on the library following the -m
`coverage run` - runs coverage data collection during testing, wrapping itself on the test runner used
`--branch` - includes code branching information in the coverage report
`--source=onair,plugins` - tells coverage where the code under test exists for reporting line hits
`-m pytest` - tells coverage what test runner (framework) to wrap
`./test` - run all tests found in this directory and subdirectories

#### A few optional settings for the command line
Options that may be added to the command line test run. Use these at your own discretion.

`--disable-warnings` - removes the warning reports, but displays count (i.e., 124 passed, 1 warning in 0.65s)
`-p no:randomly` - ONLY required to stop random order testing IFF pytest-randomly installed
`--conftest-seed=###` - set the random values seed for this run
`--randomly-seed=###` - set the random order seed for this run
`--verbose` or `-v` - set verbosity level, also -vv, -vvv, etc.
`-k KEYWORD` - only run tests that match the KEYWORD (see `pytest --help`)
`--disable-warnings` - removes the warning reports, but displays count (i.e., 124 passed, 1 warning in 0.65s)
`-p no:randomly` - ONLY required to stop random order testing IFF pytest-randomly installed
`--conftest-seed=###` - set the random values seed for this run
`--randomly-seed=###` - set the random order seed for this run
`--verbose` or `-v` - set verbosity level, also -vv, -vvv, etc.
`-k KEYWORD` - only run tests that match the KEYWORD (see `pytest --help`)

NOTE: see note about seeds in driver.py section above

### To view testing line coverage after run:
NOTE: you may or may not need the `python -m` to run coverage report or html

`coverage report` - prints basic results in terminal
or
`coverage html` - creates htmlcov/index.html, automatic when using driver.py for testing
`coverage report` - prints basic results in terminal
or
`coverage html` - creates htmlcov/index.html, automatic when using driver.py for testing

then
`<browser_here> htmlcov/index.html` - browsable coverage (i.e., `firefox htmlcov/index.html`)

## Running with Core Flight System (cFS)
OnAIR can be setup to subscribe to and recieve messages from cFS. For more information see [doc/cfs-onair-guide.md](doc/cfs-onair-guide.md)

## License and Copyright

Please refer to [NOSA GSC-19165-1 OnAIR.pdf](NOSA%20GSC-19165-1%20OnAIR.pdf) and [COPYRIGHT](COPYRIGHT).
Expand All @@ -205,6 +208,7 @@ We are a small team, but will try to respond in a timely fashion.
If you would like to contribute to the repository, GREAT!
First you will need to complete the [Individual Contributor License Agreement (pdf)](doc/Indv_CLA_OnAIR.pdf).
Then, email it to [email protected] with [email protected] CCed.
Please include your github username in the email.

Next, please create an issue for the fix or feature and note that you intend to work on it.
Fork the repository and create a branch with a name that starts with the issue number.
Expand Down
104 changes: 104 additions & 0 deletions doc/cfs-onair-guide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# Using OnAIR with Core Flight System (cFS)

## Overview

In order for OnAIR to receive cFS messages, cFS must include the Software Bus Network (SBN) app and the SBN Client library in its tree.

SBN is a cFS application that enables pub/sub across the software busses (SB) of multiple cFS instances: https://github.com/nasa/SBN

SBN Client is an external library that implements the SBN protocol. This allows other environments, including Python, to communicate with a Software Bus via the SBN: https://github.com/nasa/SBN-Client

In OnAIR, the sbn_adapter DataSource uses SBN Client to subscribe to messages on the Software Bus. When cFS messages are received, it extracts the data from the message structs and passes it up to the rest of the OnAIR system.

## Example
An example distribution of cFS integrated with OnAIR can be found [here.](https://github.com/the-other-james/cFS/tree/OnAIR-integration)

In this example, OnAIR is configured to the subscribe to the sample_app house keeping telemetry packet, `SAMPLE_APP_HkTlm_t`.

### Quick Start
Requirements: Docker

After cloning the repository, use `docker compose` to build and run a container called `cfs-onair` which should have both cFS and OnAIR dependencies set up.

``` bash
docker compose up -d
```

After building, Docker will start the `cfs-onair` container in the background. Attach to the container using `docker exec`.

```bash
docker exec -it cfs-onair bash
```

Inside the `cfs-onair` container, use the build script to build cFS. SBN, SBN Client and OnAIR are added as cFS apps that will be built/installed by the cFS CMake system.

``` bash
./_build.sh
```

Then navigate to the install directory and run cFS.

``` bash
cd build/exe/cpu1
./core-cpu1
```

Open a new terminal. Then attach to the same `cfs-onair` container and navigate to the same intall directory.

``` bash
docker exec -it cfs-onair bash
cd build/exe/cpu1
```

In this example, the build system copies OnAIR, the OnAIR telemetry metadata and config files, the ctypes structs of the cFS messages and the `sbn_python_client` python module from `sbn_client` files to `cf/`. The `sbn-client.so` binary is also installed to the `cf/` directory.

Now OnAIR can be run from the install directory `build/exe/cpu1`.

```bash
python3 cf/onair/driver.py cf/onair/cfs_sample_app.ini
```

If OnAIR successfully connects to cFS via SBN Client and SBN, you should see the following start up log

```
SBN Adapter ignoring data file (telemetry should be live)
SBN Client library loaded: '<CDLL 'sbn_client.so', handle 11d7eef0 at 0xffff93b1f910>'
SBN_Client Connecting to 127.0.0.1, 2234
SBN Client init: 0
SBN Client command pipe: 0
SBN_Adapter Running
SBN Client subscribe msg (id 0x883): 0
***************************************************
************ SIMULATION STARTED ************
***************************************************
App message received: MsgId 0x00000883
Payload: <message_headers.SAMPLE_APP_HkTlm_Payload_t object at 0xffff93ae7140>
```

### Explanation

This repo is essentially the base distribution of cFS with three additional `apps` added, `sbn`, `sbn_client` and `onair_app`. While SBN_Client and OnAIR can exist outside of cFS as standalone projects, they were added as cFS apps to take advantage of the cFS build system.

### SBN and SBN Client
SBN and SBN Client are added as submodules in the `apps/` folder. They are added to the build system by appending them to the global app list found in the `targets.cmake` file. Since SBN is an actual cFS app it also needs to be added to the cfe start up script, `cpu1-cfe_es_startup.scr`. When SBN Client is built, it results in `sbn-client.so` binary that other processes, such as OnAIR, will use to communicate with the SBN.

By default, SBN's configuration table (`sbn_conf_tbl.c`) will assign the address and port `127.0.0.1:2234` to this instance of the SBN app. In order for SBN_Client to talk to SBN it must use the same address, which is set in `sbn_client_defs.h`.

### OnAIR
An additional folder, called `onair_app/` is also added to the `apps/` folder. This folder contains the OnAIR source directory as a submodule, as well as a telemetry metadata file, config file, and a message_headers.py file. The `onair_app` also has a `CMakeLists.txt` file directing how it should be built by the cFS build system. In this case it just copies the files to the target directory.

`s_o.ini` - this is the config file. It specifies the name/location of the telemetry metadata file and selects `sbn_adapter` as the OnAIR Datasource.

`s_o_TLM_CONFIG.json` - this is the telemetry metadata file. It lists each data field that OnAIR is interested in as well as their order. Most importantly, in the `channels` field it matches the cFS message ID with name of the message and the name of the actual message struct. `sbn_adapter` will subscribe to the message IDs listed here. When a message is received `sbn_adapter` will use the received message IDs to determine the structure of the message so it can correctly unpack it.

```
"channels":{
"0x0883": ["SAMPLE_APP", "SAMPLE_APP_HkTlm_t"]
}
```

`message_headers.py` - this python file is unqiue to `sbn_adapter.py` (i.e its not needed anywhere else in OnAIR). It defines the message structs that will be received using python ctypes. In this example `message_headers.py` contains the sample app house keeping message structs found in `sample_app/fsw/src/sample_app_msg.h`.


14 changes: 14 additions & 0 deletions onair/config/sbn_cfs_config.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[DEFAULT]
TelemetryDataFilePath =
TelemetryFile =
TelemetryMetadataFilePath = cf/onair/onair/data/telemetry_configs/
MetaFile = adapter_TLM_CONFIG.json
ParserFileName = cf/onair/onair/data_handling/sbn_adapter.py

KnowledgeRepPluginDict = {'generic':'cf/onair/plugins/generic/__init__.py'}
LearnersPluginDict = {'generic':'cf/onair/plugins/generic/__init__.py'}
PlannersPluginDict = {'generic':'cf/onair/plugins/generic/__init__.py'}
ComplexPluginDict = {'generic':'cf/onair/plugins/generic/__init__.py'}

[RUN_FLAGS]
IO_Flag = true
10 changes: 8 additions & 2 deletions onair/data/telemetry_configs/adapter_TLM_CONFIG.json
Original file line number Diff line number Diff line change
Expand Up @@ -115,5 +115,11 @@
"SAMPLE.sample_data_gps_t.sample_data_lat",
"SAMPLE.sample_data_gps_t.sample_data_lng",
"SAMPLE.sample_data_gps_t.sample_data_alt"
]
}
],
"channels":
{
"0x0887": ["SAMPLE", "sample_data_power_t"],
"0x0889": ["SAMPLE", "sample_data_thermal_t"],
"0x088A": ["SAMPLE", "sample_data_gps_t"]
}
}
Loading

0 comments on commit 74c983d

Please sign in to comment.