Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/nasa/ogma
Last synced: 3 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/nasa/ogma
- Owner: nasa
- License: other
- Created: 2021-08-05T15:28:13.000Z (about 3 years ago)
- Default Branch: develop
- Last Pushed: 2024-03-22T11:05:36.000Z (8 months ago)
- Last Synced: 2024-05-01T22:48:10.763Z (6 months ago)
- Language: Haskell
- Size: 28.5 MB
- Stars: 319
- Watchers: 12
- Forks: 22
- Open Issues: 9
-
Metadata Files:
- Readme: README.md
- License: LICENSE.pdf
Awesome Lists containing this project
- my-awesome - nasa/ogma - systems,flight-software,fprime,robot-operating-system,robotics,ros,ros2,runtime-monitoring,runtime-monitoring-system,runtime-verification,rv,space-ros,spacecraft pushed_at:2024-09 star:0.3k fork:0.0k Generator of runtime monitors for flight and robotics applications. (Haskell)
README
# OGMA
Ogma is a tool to facilitate the integration of safe runtime monitors into
other systems. Ogma extends
[Copilot](https://github.com/Copilot-Language/copilot), a high-level runtime
verification framework that generates hard real-time C99 code.# Features
- Generating [NASA Core Flight System](https://cfs.gsfc.nasa.gov/) runtime
monitoring applications that monitor data received from the message bus.- Generating [Robot Operating System](https://ros.org) runtime monitoring
applications.- Generating [F' (FPrime)](https://github.com/nasa/fprime/) runtime monitoring
components.- Generating message handlers for NASA Core Flight System applications to make
external data in structs available to a Copilot monitor.- Generating the glue code necessary to work with C structs in Copilot.
Integration of monitors into larger applications (e.g., simulators).## Table of Contents
- [Installation](#installation)
- [Pre-requisites](#pre-requisites)
- [Compilation](#compilation)
- [Usage](#usage)
- [cFS Application Generation](#cfs-application-generation)
- [ROS Application Generation](#ros-application-generation)
- [F' Component Generation](#f-component-generation)
- [Struct Interface Generation](#struct-interface-generation)
- [Contributions](#contributions)
- [Acknowledgements](#acknowledgements)
- [License](#license)# Installation
[(Back to top)](#table-of-contents)## Pre-requisites
[(Back to top)](#table-of-contents)To install Ogma from source, users must have the tools GHC and cabal-install.
At this time, we recommend GHC 8.6 and a version of cabal-install between 2.4
and 3.2. (Ogma has been tested with GHC versions up to 9.2 and cabal-install
versions up to 3.6, although the installation steps may vary slightly depending
on the version of cabal-install being used.)On Debian or Ubuntu Linux, both can be installed with:
```sh
$ apt-get install ghc cabal-install
```On Mac, they can be installed with:
```sh
$ brew install ghc cabal-install
```## Compilation
[(Back to top)](#table-of-contents)Once GHC and cabal are installed, the simplest way to install Ogma is with:
```sh
$ git clone https://github.com/nasa/ogma.git
$ cd ogma
$ export PATH="$HOME/.cabal/bin/:$PATH"
$ cabal v1-update
$ cabal v1-install alex happy
$ cabal v1-install BNFC copilot
$ cabal v1-install ogma-*/
```After that, the `ogma` executable will be placed in the directory
`$HOME/.cabal/bin/`, where `$HOME` represents your user's home directory.# Usage
[(Back to top)](#table-of-contents)The main invocation of `ogma` with `--help` lists sub-commands available. More
details are provided in the following sections.## cFS Application Generation
[NASA Core Flight System](https://cfs.gsfc.nasa.gov/) (cFS) is a flight
software architecture to implement complex systems by combining multiple
reusable applications that communicate to one another via a software bus. cFS
has been used, among others, on spacecraft, cubesats, and drones.Ogma includes multiple facilities to generate cFS applications. The cFS
applications generated by Ogma perform three steps to connect Copilot monitors
to the application:
- Subscribe to a message in the cFS communication bus.
- When a message of the desired kind arrives, copy the data to make it
available to Copilot and call the monitor's main entry point.
- Declare handlers that are executed when the property being monitored is
violated.When using this facility, Ogma produces a Copilot file that the user is
expected to modify to implement the property to monitor. To avoid having to
modify the generated C files that implement the cFS app itself, Ogma gives the
ability to state what information one is interested in monitoring. If the kind
of information is known to Ogma, it will automatically subscribe to the
necessary messages and make it available to Copilot. Ogma provides additional
flags to customize the list of known variables, so that projects can maintain
their own variable databases beyond what Ogma includes by default.cFS applications are generated using the Ogma command `cfs`, which receives
three main arguments:
- `--app-target-dir DIR`: location where the cFS application files must be
stored.
- `--variable-file FILENAME`: a file containing a list of variables that must
be made available to the monitor.
- `--variable-db FILENAME`: a file containing a database of known variables,
and the message they are included with.The following execution generates an initial cFS application for runtime
monitoring using Copilot:
```
$ ogma cfs --variable-db examples/cfs-variable-db --variable-file examples/cfs-variables
```The application generated by Ogma contains the following files:
```
copilot-cfs-demo/CMakeLists.txt
copilot-cfs-demo/fsw/for_build/Makefile
copilot-cfs-demo/fsw/mission_inc/copilot_cfs_perfids.h
copilot-cfs-demo/fsw/platform_inc/copilot_cfs_msgids.h
copilot-cfs-demo/fsw/src/copilot_cfs.c
copilot-cfs-demo/fsw/src/Properties.hs
copilot-cfs-demo/fsw/src/copilot_cfs_msg.h
copilot-cfs-demo/fsw/src/copilot_cfs_events.h
copilot-cfs-demo/fsw/src/copilot_cfs_version.h
copilot-cfs-demo/fsw/src/copilot_cfs.h
```Users are expected to modify `Properties.hs` to adjust the property being
monitored. Although it is possible to adjust the file `copilot_cfs.c` to
include property violation handlers, we recommend adding them in a separate C
file and modifying the compilation scripts to include that additional file.
That way, invoking Ogma again will not overwrite the changes made to the cFS
application.In this particular example, the C code generated contains the following
instruction to subscribe to an `ICAROUS_POSITION_MID` message to obtain
the vehicle position:
```c
CFE_SB_Subscribe(ICAROUS_POSITION_MID, COPILOT_CommandPipe);
```The message dispatcher included in the application detects a message
of this kind and calls a dedicated subroutine:
```c
void COPILOT_ProcessCommandPacket(void)
{
CFE_SB_MsgId_t MsgId;MsgId = CFE_SB_GetMsgId(COPILOTMsgPtr);
switch (MsgId)
{
case ICAROUS_POSITION_MID:
COPILOT_ProcessIcarousPosition();
break;
...
```Finally, the dedicated subroutine makes data available to the monitor
and calls the main Copilot entry point `step`:```c
void COPILOT_ProcessIcarousPosition(void)
{
position_t* msg;
msg = (position_t*) COPILOTMsgPtr;
position = *msg;
step();
}
```## ROS Application Generation
The Robot Operating System (ROS) is a framework to build robot applications.
Ogma is able to generate ROS monitoring applications that subscribe to obtain
the data needed by the monitors and report any violations. At present, support
for ROS app generation is considered preliminary.ROS applications are generated using the Ogma command `ros`, which receives
four main arguments:
- `--app-target-dir DIR`: location where the ROS application files must be
stored.
- `--variable-file FILENAME`: a file containing a list of variables that must
be made available to the monitor.
- `--variable-db FILENAME`: a file containing a database of known variables,
and the topic they are included with.
- `--handlers FILENAME`: a file containing a list of handlers used in the
specification.The following execution generates an initial ROS application for runtime
monitoring using Copilot:
```sh
$ ogma ros --handlers filename --variable-file variables --variable-db ros-variable-db --app-target-dir ros_demo
```The application generated by Ogma contains the following files:
```
ros_demo/copilot/CMakeLists.txt
ros_demo/copilot/src/copilot_monitor.cpp
ros_demo/copilot/src/copilot_logger.cpp
ros_demo/copilot/src/.keep
ros_demo/copilot/package.xml
ros_demo/Dockerfile
```The Dockerfile can be used to compile the application inside the base image for
the Space ROS distribution. To build the image, first place the core
implementation of the monitors in C inside the directory
`ros_demo/copilot/src/` (see 'Current limitations' for details). After, you can
compile the image with:
```
docker build .
```### Format of the Variables DB File
The argument variable DB passed to the ROS backend should contain a list of
variables, together with their types and the corresponding ROS topic in which
those variables are passed. Each line in that file has the format:```
("","","","")
```For example, an input variable called "temperature" of type 64-bit signed
integer coming in a ROS topic called "/battery/temperature" should have a
matching entry in the variable DB file like the following:```
("temperature","int64_t","/battery/temperature","ignore")
```There should never be two lines in the same file with the same variable name.
Variables in the DB that are not not used in any of the properties being
monitored and/or are not listed in the variable file passed as argument to the
ROS command will be ignored.For a more concrete example, see the files in `ogma-cli/examples/ros-copilot/`
and the last step of the script
`.github/workflows/repo-ghc-8.6-cabal-2.4-ros.yml`, which generates a ROS
monitor with multiple variables and compiles the resulting code.### Current limitations
The user must place the code generated by Copilot monitors in two files,
`ros_demo/src/monitor.h` and `ros_demo/src/monitor.c`. No Copilot or C code for
the monitors is generated by default.The code generated by default assumes that handlers receive no arguments. The
user must modify the handlers accordingly if that is not the case.Although the variable DB file is not mandatory, it is in practice required to
monitor any requirement that uses any input data: no topic subscriptions will
be generated for any variables for which a DB entry cannot be found. At present,
Ogma will proceed without warnings if a variable is mentioned in a requirement
or variables file but a matching entry is not found in the variable DB.## F' Component Generation
F' (FPrime) is a component-based framework for spaceflight applications.
Ogma is able to generate F' monitoring components that subscribe to obtain
the data needed by the monitors and report any violations. At present, support
for F' component generation is considered preliminary.F' components are generated using the Ogma command `fprime`, which receives
five main arguments:
- `--app-target-dir DIR`: location where the F' application files must be
stored.
- `--variable-file FILENAME`: a file containing a list of variables that must
be made available to the monitor.
- `--variable-db FILENAME`: a file containing a database of known variables,
and their types.
- `--handlers FILENAME`: a file containing a list of handlers used in the
specification.The following execution generates an initial F' component for runtime
monitoring using Copilot:
```sh
$ ogma fprime --handlers filename --variable-file filename --variable-db fprime-variable-db --app-target-dir fprime_demo
```The component generated by Ogma contains the following files:
```
fprime_demo/CMakeLists.txt
fprime_demo/Copilot.fpp
fprime_demo/Copilot.cpp
fprime_demo/Copilot.hpp
fprime_demo/Dockerfile
fprime_demo/inline-copilot
```### File formats
The format of the variables, variable DB, and handlers file are as follows.
The variables file can contain a list of variables used in a specification, one
per line. For example, if we are working with a specification that uses three
boolean variables called `autopilot`, `sensorLimitsExceeded`, and `pullup`, we
can provide them to Ogma's `fprime` command in a file like the following:
```sh
$ cat variables
autopilot
sensorLimitsExceeded
pullup
```The variables database file contains a list of known variables and their types.
It does not matter if there are variables that are not used for one particular
specification, or property/requirement/monitor. The only thing that matters is
that the variables used, and their types, be listed in the file. Continuing
with the same example, we could have:```sh
$ cat fprime-variable-db
("temperature", "uint8_t")
("autopilot", "bool")
("sensorLimitsExceeded", "bool")
("pullup", "bool")
("current_consumption", "float")
```In our example, we only care about the boolean variables; it is sufficient that
they be listed in the variable DB file.Finally, the handlers file is a list of monitor handlers that the generated
FPrime component should restrict to monitoring. They are listed one per line:
```sh
$ cat handlers
handlerpropREQ_001
```### Current limitations
The user must place the code generated by Copilot monitors in three files,
`fprime_demo/src/copilot.h`, `fprime_demo/src/copilot_types.h` and
`fprime_demo/src/copilot.c`. No Copilot or C code for the monitors is generated
by default by the `fprime` command.The code generated by default assumes that handlers receive no arguments. The
user must modify the handlers accordingly if that is not the case.## Struct Interface Generation
A lot of the information that must be monitored in real-world C applications is
packed in structs. Copilot allows accessing specific fields of C structs, but
requires additional definitions in the Copilot language to make the shape of
those structs known to the compiler.Ogma is able to generate the boilerplate code needed to work with C structs in
Copilot. For example, to use the following struct as the type of an extern
stream in Copilot, the user is expected to define several Copilot (Haskell)
types and type class instances:```c
typedef struct {
double x;
double y;
} point;
```Ogma can generate that code automatically with the `structs` subcommand:
```haskell
$ ogma structs --header-file-name examples/point.h
data Point = Point
{ pX :: Field "x" Double
, pY :: Field "y" Double
}instance Struct Point where
typename _ = "point"
toValues v = [ Value Double (pX v), Value Double (pY v) ]instance Typed Point where
typeOf = Struct (Point (Field 0) (Field 0))```
By including these definitions in a Copilot file, users can now access the
individual `x` and `y` fields of a `Point` in a stream.# Contributions
[(Back to top)](#table-of-contents)The best way to contribute to Ogma is to report any issues you find via the
issue tracker, and to use Ogma to build applications or in your own research
and let us know about your results.We kindly ask users not to send PRs to this project. Instead, please document
the bugs you find or other suggestions as issues and we will make the necessary
changes.# Acknowledgements
[(Back to top)](#table-of-contents)Ogma has been created by Ivan Perez and Alwyn Goodloe.
The Ogma team would like to thank Swee Balachandran, Dimitra Giannakopoulou,
Anastasia Mavridou, Cesar Munoz and Thomas Pressburger, for the input during
the development of Ogma.X-Plane images obtained via the X-Plane 10 (Pro) flight simulator. Re-shared
with permission.# License
[(Back to top)](#table-of-contents)Copyright 2020-2021 United States Government as represented by the
Administrator of the National Aeronautics and Space Administration. All Rights
Reserved.See the file LICENSE.pdf for details.