update satrs book
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<p align="center"> <img src="misc/satrs-logo-v2.png" width="40%"> </p>
|
||||
|
||||
[](https://absatsw.irs.uni-stuttgart.de/projects/sat-rs/)
|
||||
<!-- [](https://absatsw.irs.uni-stuttgart.de/projects/sat-rs/) -->
|
||||
[](https://robamu.github.io/sat-rs/book/)
|
||||
[](https://crates.io/crates/satrs)
|
||||
[](https://docs.rs/satrs)
|
||||
|
||||
@@ -35,3 +35,7 @@ docs-satrs:
|
||||
RUSTDOCFLAGS="--cfg docsrs --generate-link-to-definition -Z unstable-options" cargo +nightly doc -p satrs --all-features
|
||||
|
||||
docs: docs-satrs
|
||||
|
||||
[working-directory:"satrs-book"]
|
||||
book *args:
|
||||
mdbook build {{args}}
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
[book]
|
||||
authors = ["Robin Mueller"]
|
||||
language = "en"
|
||||
multilingual = false
|
||||
src = "src"
|
||||
title = "The sat-rs book"
|
||||
|
||||
[output.html]
|
||||
additional-js = ["mermaid.min.js", "mermaid-init.js"]
|
||||
|
||||
[output.linkcheck]
|
||||
command = "mdbook-linkcheck2"
|
||||
|
||||
[preprocessor]
|
||||
|
||||
[preprocessor.mermaid]
|
||||
command = "mdbook-mermaid"
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
(() => {
|
||||
const darkThemes = ['ayu', 'navy', 'coal'];
|
||||
const lightThemes = ['light', 'rust'];
|
||||
|
||||
const classList = document.getElementsByTagName('html')[0].classList;
|
||||
|
||||
let lastThemeWasLight = true;
|
||||
for (const cssClass of classList) {
|
||||
if (darkThemes.includes(cssClass)) {
|
||||
lastThemeWasLight = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const theme = lastThemeWasLight ? 'default' : 'dark';
|
||||
mermaid.initialize({ startOnLoad: true, theme });
|
||||
|
||||
// Simplest way to make mermaid re-render the diagrams in the new theme is via refreshing the page
|
||||
|
||||
for (const darkTheme of darkThemes) {
|
||||
document.getElementById('mdbook-theme-' + darkTheme).addEventListener('click', () => {
|
||||
if (lastThemeWasLight) {
|
||||
window.location.reload();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
for (const lightTheme of lightThemes) {
|
||||
document.getElementById('mdbook-theme-' + lightTheme).addEventListener('click', () => {
|
||||
if (!lastThemeWasLight) {
|
||||
window.location.reload();
|
||||
}
|
||||
});
|
||||
}
|
||||
})();
|
||||
Vendored
+2609
File diff suppressed because one or more lines are too long
@@ -1,11 +1,11 @@
|
||||
# Summary
|
||||
|
||||
- [Introduction](./introduction.md)
|
||||
- [Design](./design.md)
|
||||
|
||||
# Basic concepts and components
|
||||
|
||||
- [Communication with Space Systems](./communication.md)
|
||||
- [TMTC modelling](./tmtc-modelling.md)
|
||||
- [Working with Constrained Systems](./constrained-systems.md)
|
||||
- [Actions](./actions.md)
|
||||
- [Modes and Health](./modes-and-health.md)
|
||||
@@ -15,3 +15,8 @@
|
||||
# Example project
|
||||
|
||||
- [The satrs-example application](./example.md)
|
||||
|
||||
# Additional information
|
||||
|
||||
- [Design](./design.md)
|
||||
|
||||
|
||||
@@ -3,40 +3,9 @@
|
||||
Space systems generally need to be commanded regularly. This can include commands periodically
|
||||
required to ensure a healthy system, or commands to reach the mission goals.
|
||||
|
||||
These commands can be modelled using the concept of Actions. the ECSS PUS standard also provides
|
||||
the PUS service 8 for actions, but provides few concrete subservices and specification on how
|
||||
action commanding could look like.
|
||||
|
||||
`sat-rs` proposes two recommended ways to perform action commanding:
|
||||
|
||||
1. Target ID and Action ID based. The target ID is a 32-bit unsigned ID for an OBSW object entity
|
||||
which can also accept Actions. The action ID is a 32-bit unsigned ID for each action that a
|
||||
target is able to perform.
|
||||
2. Target ID and Action String based. The target ID is the same as in the first proposal, but
|
||||
the unique action is identified by a string.
|
||||
|
||||
The library provides an `ActionRequest` abstraction to model both of these cases.
|
||||
|
||||
## Commanding with ECSS PUS 8
|
||||
|
||||
`sat-rs` provides a generic ECSS PUS 8 action command handler. This handler can convert PUS 8
|
||||
telecommands which use the commanding scheme 1 explained above to an `ActionRequest` which is
|
||||
then forwarded to the target specified by the Target ID.
|
||||
|
||||
There are 3 requirements for the PUS 8 telecommand:
|
||||
|
||||
1. The subservice 128 must be used
|
||||
2. Bytes 0 to 4 of application data must contain the target ID in `u32` big endian format.
|
||||
3. Bytes 4 to 8 of application data must contain the action ID in `u32` big endian format.
|
||||
4. The rest of the application data are assumed to be command specific additional parameters. They
|
||||
will be added to an IPC store and the corresponding store address will be sent as part of the
|
||||
`ActionRequest`.
|
||||
|
||||
## Sending back telemetry
|
||||
|
||||
There are some cases where the regular verification provided by PUS in response to PUS action
|
||||
commands is not sufficient and some additional telemetry needs to be sent to ground. In that
|
||||
case, it is recommended to chose some custom subservice for action TM data and then send the
|
||||
telemetry using the same scheme as shown above, where the first 8 bytes of the application
|
||||
data is reserved for the target ID and action ID.
|
||||
These commands can be modelled using the concept of Actions. If you have not read the
|
||||
[TMTC modelling](./tmtc-modelling.md) chapter yet, it is recommended to read it first.
|
||||
|
||||
For a low number of actions, it is recommended to add the actions as `enum` variants of your
|
||||
`Request` type. For a higher number of actions, you can create a dedicated `ActionRequest`
|
||||
structure.
|
||||
|
||||
@@ -8,14 +8,9 @@ most of these systems have internet access during development cycle. There are v
|
||||
provided by CCSDS and ECSS which can be useful to determine how to communicate with the satellite
|
||||
and the primary On-Board Software.
|
||||
|
||||
# Application layer
|
||||
|
||||
Most communication with space systems is usually packet based. For example, the CCSDS space
|
||||
packet standard only specifies a 6 byte header with at least 1 byte payload. The PUS packet
|
||||
standard is a subset of the space packet standard, which adds some fields and a 16 bit CRC, but
|
||||
it is still centered around small packets. `sat-rs` provides support for these ECSS and CCSDS
|
||||
standards and also attempts to fill the gap to the internet protocol by providing the following
|
||||
components.
|
||||
packet standard only specifies a 6 byte header with at least 1 byte payload. The `sat-rs` library
|
||||
provides some support for the [CCSDS space packet protocol](https://ccsds.org/Pubs/133x0b2e2.pdf).
|
||||
|
||||
1. [UDP TMTC Server](https://docs.rs/satrs/latest/satrs/hal/std/udp_server/index.html).
|
||||
UDP is already packet based which makes it an excellent fit for exchanging space packets.
|
||||
@@ -31,21 +26,65 @@ components.
|
||||
# Working with telemetry and telecommands (TMTC)
|
||||
|
||||
The commands sent to a space system are commonly called telecommands (TC) while the data received
|
||||
from it are called telemetry (TM). Keeping in mind the previous section, the concept of a TC source
|
||||
and a TM sink can be applied to most satellites. The TM sink is the one entity where all generated
|
||||
telemetry arrives in real-time. The most important task of the TM sink usually is to send all
|
||||
arriving telemetry to the ground segment of a satellite mission immediately. Another important
|
||||
task might be to store all arriving telemetry persistently. This is especially important for
|
||||
space systems which do not have permanent contact like low-earth-orbit (LEO) satellites.
|
||||
from it are called telemetry (TM). One way to model the packet handling is to introduce the concept
|
||||
of a TC source and a TM sink can be applied to most satellites. The TM sink is the one entity where
|
||||
all generated telemetry arrives in real-time. The most important task of the TM sink usually is to
|
||||
send all arriving telemetry to the ground segment of a satellite mission immediately.
|
||||
|
||||
Another important task might be to store all arriving telemetry persistently. This is especially
|
||||
important for space systems which do not have permanent contact like low-earth-orbit (LEO)
|
||||
satellites.
|
||||
|
||||
The diagram below shows one concrete example of how this could look like.
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
Dev[Device Handlers] --> Sink[TM Sink]
|
||||
Sub[Subsystem Handlers] --> Sink
|
||||
Sink --> Ground[Ground Link]
|
||||
Sink --> Store[Persistent Storage]
|
||||
Sink --> Udp[UDP Server]
|
||||
Sink --> Tcp[TCP Server]
|
||||
```
|
||||
|
||||
The most important task of a TC source is to deliver the telecommands to the correct recipients.
|
||||
For component oriented software using message passing, this usually includes staged demultiplexing
|
||||
components to determine where a command needs to be sent.
|
||||
For component oriented software using message passing, this usually includes demultiplexing
|
||||
to determine where a command needs to be sent.
|
||||
|
||||
The diagram below shows one concrete example of how this could look like.
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
Udp[UDP Server] --> Source[TC Source]
|
||||
Tcp[TCP Server] --> Source
|
||||
Radio[Radio Handler] --> Source
|
||||
Source --> Dev[Device Handlers]
|
||||
Source --> Sub[Subsystem Handlers]
|
||||
Source --> File[File Service Handler]
|
||||
```
|
||||
|
||||
Using a generic concept of a TC source and a TM sink as part of the software design simplifies
|
||||
the flexibility of the TMTC infrastructure: Newly added TM generators and TC receiver only have to
|
||||
forward their generated or received packets to those handler objects.
|
||||
|
||||
# Packet format
|
||||
|
||||
We talked about some basic support for the CCSDS space packet protocol. This is a really simple
|
||||
protocol which just specifies a header that every exchanged TMTC packet has:
|
||||
|
||||

|
||||
|
||||
This is a protocol which already provides us with some useful fields:
|
||||
|
||||
- ID field provided by the Application Process Identifier (APID). This can also be useful for packet
|
||||
multiplexing
|
||||
- Basic sequence counter which can be used to determine missed packets
|
||||
|
||||
However, how does the actual payload that we want to send to or from the satellite actually look
|
||||
like? While there are standards like the Packet Utilisation Standard (PUS), we recommend a payload
|
||||
format which is created with the excellent [`serde`](https://serde.rs/) library. The
|
||||
[TMTC modelling](./tmtc-modelling.md) chapter provides more information.
|
||||
|
||||
# Low-level protocols and the bridge to the communcation subsystem
|
||||
|
||||
Many satellite systems usually use the lower levels of the OSI layer in addition to the application
|
||||
@@ -55,4 +94,3 @@ might provide components to handle standard like the Unified Space Data Link Sta
|
||||
software but most of the time the handling of communication is performed through custom
|
||||
software and hardware. Still, connecting this custom software and hardware to `sat-rs` can mostly
|
||||
be done by using the concept of TC sources and TM sinks mentioned previously.
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
Software for space systems oftentimes has different requirements than the software for host
|
||||
systems or servers. Currently, most space systems are considered embedded systems.
|
||||
|
||||
For these systems, the computation power and the available heap are important resources
|
||||
For these systems, the computation power and the available memory are important resources
|
||||
which are also constrained. This might make completeley heap based memory management schemes which
|
||||
are oftentimes used on host and server based systems unfeasable. Still, completely forbidding
|
||||
heap allocations might make software development unnecessarilly difficult, especially in a
|
||||
@@ -14,6 +14,12 @@ initialization time and avoid frequent run-time allocations. This prevents issue
|
||||
running out of memory (something even Rust can not protect from) or heap fragmentation on systems
|
||||
without a MMU.
|
||||
|
||||
# Using an embedded allocator
|
||||
|
||||
The [`embedded-alloc`](https://github.com/rust-embedded/embedded-alloc) library provides
|
||||
a global allocator based on statically sized memory blocks. It also exposes an API
|
||||
which allows run-time tracking of the memory usage.
|
||||
|
||||
# Using pre-allocated pool structures
|
||||
|
||||
A candidate for heap allocations is the TMTC and handling. TC, TMs and IPC data are all
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
Satellites and space systems in general are complex systems with a wide range of requirements for
|
||||
both the hardware and the software. Consequently, the general design of the library is centered
|
||||
around many light-weight components which try to impose as few restrictions as possible on how to
|
||||
solve certain problems. This is also the reason why sat-rs is explicitely called a library
|
||||
instead of a framework.
|
||||
solve certain problems.
|
||||
|
||||
There are still a lot of common patterns and architectures across these systems where guidance
|
||||
of how to solve a problem and a common structure would still be extremely useful to avoid pitfalls
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 56 KiB |
@@ -14,23 +14,22 @@ The primary goal of the sat-rs library is to provide re-usable components
|
||||
to write on-board software for remote systems like rovers or satellites. It is specifically written
|
||||
for the special requirements for these systems.
|
||||
|
||||
It should be noted that sat-rs is early-stage software. Important features are missing. New releases
|
||||
with breaking changes are released regularly, with all changes documented inside respective
|
||||
changelog files. You should only use this library if your are willing to work in this
|
||||
environment.
|
||||
|
||||
A lot of the architecture and general design considerations are based on the
|
||||
Some architecture and general design considerations are based on the
|
||||
[FSFW](https://egit.irs.uni-stuttgart.de/fsfw/fsfw) C++ framework which has flight heritage
|
||||
through the 2 missions [FLP](https://www.irs.uni-stuttgart.de/en/research/satellitetechnology-and-instruments/smallsatelliteprogram/flying-laptop/)
|
||||
and [EIVE](https://www.irs.uni-stuttgart.de/en/research/satellitetechnology-and-instruments/smallsatelliteprogram/EIVE/).
|
||||
|
||||
However, `sat-rs` has a significantly reduced scope compared to those frameworks. Rust provides
|
||||
a great ecosystem and a powerful standard library which reduced the need of large and complex
|
||||
frameworks.
|
||||
|
||||
# Getting started with the example
|
||||
|
||||
The [`satrs-example`](https://egit.irs.uni-stuttgart.de/rust/sat-rs/src/branch/main/satrs-example)
|
||||
provides various practical usage examples of the `sat-rs` framework. If you are more interested in
|
||||
the practical application of `sat-rs` inside an application, it is recommended to have a look at
|
||||
the example application. The [`satrs-minisim`](https://egit.irs.uni-stuttgart.de/rust/sat-rs/src/branch/main/satrs-minisim)
|
||||
applicatin complements the example application and can be used to simulate some physical devices
|
||||
application complements the example application and can be used to simulate some physical devices
|
||||
for the `satrs-example` device handlers.
|
||||
|
||||
# Flight Heritage
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
# Serialization
|
||||
@@ -0,0 +1,86 @@
|
||||
# TMTC modelling using Rust
|
||||
|
||||
Before we talk about how to model telecommand and telemetry data using Rust, we are going
|
||||
to present some basic concepts and useful libraries first.
|
||||
|
||||
## Serialization
|
||||
|
||||
Serialization and deserialization is the process of converting (Rust) data structures into
|
||||
some format which can be stored or transmitted. We can use this system for generating the payload
|
||||
of our telecommand and telemetry packets. This allows us to model our payloads with Rust data
|
||||
structures, fits perfectly into the data-driven approach that Rust programs tend to favor and
|
||||
allows us to use the excellent type system.
|
||||
|
||||
The Rust ecosystem provides the [`serde`](https://serde.rs/) library for this task. The library
|
||||
makes it trivial to add serialization support to custom datastructures by providing a
|
||||
[`derive`](https://serde.rs/derive.html) macro. In almost all cases, you can just add this derive
|
||||
macro to a data structure to make it serializable with any `serde` compatible serializer.
|
||||
|
||||
There are various serializers available which are well suited to the requirements of space systems.
|
||||
|
||||
- Generally, we try to minimize the payload size to save data bandwidth.
|
||||
- The data does not necessarily have to be human-readable
|
||||
|
||||
We recommend the [`postcard`](https://github.com/jamesmunns/postcard) serializer, which fulfills
|
||||
these requirements and also works well for embedded systems.
|
||||
|
||||
## Modelling telecommands and telemetry
|
||||
|
||||
Using a serializer library like `serde` allows us to do some interesting things. For example,
|
||||
let's assume you have a `Camera` object in software that you want to send some commands to.
|
||||
This object should have the following capability:
|
||||
|
||||
- Process a ping command
|
||||
- Capture an image
|
||||
- Send back configuration data
|
||||
|
||||
You can now model a request to your `Camera` object using the following data structure
|
||||
|
||||
```rust
|
||||
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub enum CameraRequest {
|
||||
Ping,
|
||||
CaptureImage,
|
||||
RequestConfig,
|
||||
}
|
||||
```
|
||||
|
||||
This data structure models all the requests that the `Camera` provides.
|
||||
On the telemetry side, you would have a similar object
|
||||
|
||||
```rust
|
||||
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub enum CameraResponse {
|
||||
Ok,
|
||||
Config(ConfigStructure)
|
||||
}
|
||||
```
|
||||
|
||||
where `ConfigStructure` would be some other wrapped configuration structure, and the `Ok` response
|
||||
would be the reply for successful execution for all other commands which do not have additional
|
||||
telemetry information.
|
||||
|
||||
Rust makes it trivial to move components into a new shared library. You can now put these data
|
||||
structures in a shared `types` or `data` library which can be re-used by both a ground system
|
||||
library and by the on-board software.
|
||||
|
||||
On the ground system, you could use a function like [`postcard::to_allocvec`](https://docs.rs/postcard/latest/postcard/fn.to_allocvec.html)
|
||||
to generate the byte representation of a `CameraRequest`, which is then sent as the payload
|
||||
inside a CCSDS space packet. On the on-board software side, you can use
|
||||
[`postcard::from_bytes`](https://docs.rs/postcard/latest/postcard/fn.from_bytes.html) to deserialize
|
||||
the `CameraRequest` from the raw payload bytes. In both cases, you do not need to hand-write
|
||||
the serialization and de-serialization code anymore. The only trade-off is that you need a Rust
|
||||
conversion layer if you want to create your telecommands in another language like Python.
|
||||
|
||||
Using Rust structures like this also has other advantages. Once you have the `CameraRequest`
|
||||
structure, you can `match` on it to cover **all** commands that the device handler needs to cover.
|
||||
If you add a new field, you have to handle the new field variant as well and you can not forget
|
||||
to handle a variant.
|
||||
|
||||
One trade-off to keep in mind is that a Rust `enum` will always have the size of its largest variant
|
||||
in memory. If you need to send large payload to and from the on-board software, you can also
|
||||
add this data as a secondary data blob behind the primary `serde` payload, and still send something
|
||||
like small metadata as part of the payload. `postcard` can tell you the size of the deserialized
|
||||
payload which helps with determining the size of any additional payload data.
|
||||
|
||||
We recommend this approach for all TMTC definitions where you control all sides of the communication.
|
||||
Reference in New Issue
Block a user