satrs-book init #64
1
satrs-book/.gitignore
vendored
Normal file
1
satrs-book/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
book
|
6
satrs-book/book.toml
Normal file
6
satrs-book/book.toml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
[book]
|
||||||
|
authors = ["Robin Mueller"]
|
||||||
|
language = "en"
|
||||||
|
multilingual = false
|
||||||
|
src = "src"
|
||||||
|
title = "The sat-rs book"
|
19
satrs-book/src/SUMMARY.md
Normal file
19
satrs-book/src/SUMMARY.md
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# Summary
|
||||||
|
|
||||||
|
- [Introduction](./introduction.md)
|
||||||
|
- [Design](./design.md)
|
||||||
|
- [Communication with Space Systems](./communication.md)
|
||||||
|
- [Working with Constrained Systems](./constrained-systems.md)
|
||||||
|
- [Actions](./actions.md)
|
||||||
|
- [Modes and Health](./modes-and-health.md)
|
||||||
|
- [Housekeeping Data](./housekeeping.md)
|
||||||
|
- [Events](./events.md)
|
||||||
|
- [Power Components](./power.md)
|
||||||
|
- [Thermal Components](./thermal.md)
|
||||||
|
- [Persistent TM storage](./persistent-tm-storage.md)
|
||||||
|
- [FDIR](./fdir.md)
|
||||||
|
- [Serialization of Data](./serialization.md)
|
||||||
|
- [Logging](./logging.md)
|
||||||
|
- [Modelling space systems](./modelling-space-systems.md)
|
||||||
|
- [Ground Segments](./ground-segments.md)
|
||||||
|
|
42
satrs-book/src/actions.md
Normal file
42
satrs-book/src/actions.md
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
# Working with Actions
|
||||||
|
|
||||||
|
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 framework 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.
|
||||||
|
|
46
satrs-book/src/communication.md
Normal file
46
satrs-book/src/communication.md
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
# Communication with sat-rs based software
|
||||||
|
|
||||||
|
Communication is a huge topic for space systems. Remote systems are usually not (directly)
|
||||||
|
connected to the internet and only have 1-2 communication links during nominal operation. However,
|
||||||
|
most of these systems have internet access during development cycle. There are various standards
|
||||||
|
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.
|
||||||
|
|
||||||
|
1. [UDP TMTC Server](https://docs.rs/satrs-core/0.1.0-alpha.0/satrs_core/hal/host/udp_server/index.html#).
|
||||||
|
UDP is already packet based which makes it an excellent fit for exchanging space packets.
|
||||||
|
2. TCP TMTC Server. This is a stream based protocol, so the server uses the COBS framing protocol
|
||||||
|
to always deliver complete packets.
|
||||||
|
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
The most important task of a TC source is to deliver the telecommands to the correct recipients.
|
||||||
|
For modern component oriented software using message passing, this usually includes staged
|
||||||
|
demultiplexing components to determine where a command needs to be sent.
|
||||||
|
|
||||||
|
# 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
|
||||||
|
layer covered by the PUS standard or the CCSDS space packets standard. This oftentimes requires
|
||||||
|
special hardware like dedicated FPGAs to handle forward error correction fast enough. `sat-rs`
|
||||||
|
might provide components to handle standard like the Unified Space Data Link Standard (USLP) in
|
||||||
|
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.
|
||||||
|
|
57
satrs-book/src/constrained-systems.md
Normal file
57
satrs-book/src/constrained-systems.md
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
# Working with Constrained Systems
|
||||||
|
|
||||||
|
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 the most important resources
|
||||||
|
which are 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
|
||||||
|
time where the OBSW might be running on Linux based systems with hundreds of MBs of RAM.
|
||||||
|
|
||||||
|
A useful pattern used commonly in space systems is to limit heap allocations to program
|
||||||
|
initialization time and avoid frequent run-time allocations. This prevents issues like
|
||||||
|
running out of memory (something even Rust can not protect from) or heap fragmentation.
|
||||||
|
|
||||||
|
# Using pre-allocated pool structures
|
||||||
|
|
||||||
|
A huge candidate for heap allocations is the TMTC and handling. TC, TMs and IPC data are all
|
||||||
|
candidates where the data size might vary greatly. The regular solution for host systems
|
||||||
|
might be to send around this data as a `Vec<u8>` until it is dropped. `sat-rs` provides
|
||||||
|
another solution to avoid run-time allocations by offering and recommendng pre-allocated static
|
||||||
|
pools.
|
||||||
|
|
||||||
|
These pools are split into subpools where each subpool can have different page sizes.
|
||||||
|
For example, a very small TC pool might look like this:
|
||||||
|
|
||||||
|
TODO: Add image
|
||||||
|
|
||||||
|
A TC entry inside this pool has a store address which can then be sent around without having
|
||||||
|
to dynamically allocate memory. The same principle can also be applied to the TM and IPC data.
|
||||||
|
|
||||||
|
# Using special crates to prevent smaller allocations
|
||||||
|
|
||||||
|
Another common way to use the heap on host systems is using containers like `String` and `Vec<u8>`
|
||||||
|
to work with data where the size is not known beforehand. The most common solution for embedded
|
||||||
|
systems is to determine the maximum expected size and then use a pre-allocated `u8` buffer and a
|
||||||
|
size variable. Alternatively, you can use the following crates for more convenience or a smart
|
||||||
|
behaviour which at the very least reduce heap allocations:
|
||||||
|
|
||||||
|
1. [`smallvec`](https://docs.rs/smallvec/latest/smallvec/).
|
||||||
|
2. [`arrayvec`](https://docs.rs/arrayvec/latest/arrayvec/index.html) which also contains an
|
||||||
|
[`ArrayString`](https://docs.rs/arrayvec/latest/arrayvec/struct.ArrayString.html) helper type.
|
||||||
|
3. [`tinyvec`](https://docs.rs/tinyvec/latest/tinyvec/).
|
||||||
|
|
||||||
|
# Using a fixed amount of threads
|
||||||
|
|
||||||
|
On host systems, it is a common practice to dynamically spawn new threads to handle workloads.
|
||||||
|
On space systems this is generally considered an anti-pattern as this is considered undeterministic
|
||||||
|
and might lead to similar issues like when dynamically using the heap. For example, spawning a new
|
||||||
|
thread might use up the remaining heap of a system, leading to undeterministic errors.
|
||||||
|
|
||||||
|
The most common way to avoid this is to simply spawn all required threads at program initialization
|
||||||
|
time. If a thread is done with its task, it can go back to sleeping regularly, only occasionally
|
||||||
|
checking for new jobs. If a system still needs to handle bursty concurrent loads, another possible
|
||||||
|
way commonly used for host systems as well would be to use a threadpool, for example by using the
|
||||||
|
[`threadpool`](https://crates.io/crates/threadpool) crate.
|
||||||
|
|
57
satrs-book/src/design.md
Normal file
57
satrs-book/src/design.md
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
# Framework Design
|
||||||
|
|
||||||
|
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 framework is centered
|
||||||
|
around many light-weight components which try to impose as few restrictions as possible on how to
|
||||||
|
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
|
||||||
|
which were already solved and to avoid boilerplate code. This framework tries to provide this
|
||||||
|
structure and guidance the following way:
|
||||||
|
|
||||||
|
1. Providing this book which explains the architecture and design patterns in respect to common
|
||||||
|
issues and requirements of space systems.
|
||||||
|
2. Providing an example application. Space systems still commonly have large monolithic
|
||||||
|
primary On-Board Softwares, so the choice was made to provide one example software which
|
||||||
|
contains the various features provided by sat-rs.
|
||||||
|
3. Providing a good test suite. This includes both unittests and integration tests. The integration
|
||||||
|
tests can also serve as smaller usage examples than the large `satrs-example` application.
|
||||||
|
|
||||||
|
This framework has special support for standards used in the space industry. This especially
|
||||||
|
includes standards provided by Consultative Committee for Space Data Systems (CCSDS) and European
|
||||||
|
Cooperation for Space Standardization (ECSS). It does not enforce using any of those standards,
|
||||||
|
but it is always recommended to use some sort of standard for interoperability.
|
||||||
|
|
||||||
|
A lot of the modules and design considerations are based on the Flight Software Framework (FSFW).
|
||||||
|
The FSFW has its own [documentation](https://documentation.irs.uni-stuttgart.de/fsfw/), which
|
||||||
|
will be referred to when applicable. The FSFW was developed over a period of 10 years for the
|
||||||
|
Flying Laptop Project by the University of Stuttgart with Airbus Defence and Space GmbH.
|
||||||
|
It has flight heritage through the 2 mssions [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/).
|
||||||
|
Therefore, a lot of the design concepts were ported more or less unchanged to the `sat-rs`
|
||||||
|
framework.
|
||||||
|
FLP is a medium-size small satellite with a higher budget and longer development time than EIVE,
|
||||||
|
which allowed to build a highly reliable system while EIVE is a smaller 6U+ cubesat which had a
|
||||||
|
shorter development cycle and was built using cheaper COTS components. This framework also tries
|
||||||
|
to accumulate the knowledge of developing the OBSW and operating the satellite for both these
|
||||||
|
different systems and provide a solution for a wider range of small satellite systems.
|
||||||
|
|
||||||
|
`sat-rs` can be seen as a modern port of the FSFW which uses common principles of software
|
||||||
|
engineering to provide a reliable and robust basis for space On-Board Software. The choice
|
||||||
|
of using the Rust programming language was made for the following reasons:
|
||||||
|
|
||||||
|
1. Rust has safety guarantees which are a perfect fit for space systems which generally have high
|
||||||
|
robustness and reliablity guarantees.
|
||||||
|
2. Rust is suitable for embedded systems. It can also be run on smaller embedded systems like the
|
||||||
|
STM32 which have also become common in the space sector. All space systems are embedded systems,
|
||||||
|
which makes using large languages like Python challenging even for OBCs with more performance.
|
||||||
|
3. Rust has support for linking C APIs through its excellent FFI support. This is especially
|
||||||
|
important because many vendor provided libaries are still C based.
|
||||||
|
4. Modern tooling like a package managers and various development helper, which can further reduce
|
||||||
|
development cycles for space systems. `cargo` provides tools like auto-formatters and linters
|
||||||
|
which can immediately ensure a high software quality throughout each development cycle.
|
||||||
|
5. A large ecosystem with excellent libraries which also leverages the excellent tooling provided
|
||||||
|
previously. Integrating these libraries is a lot easier compared to languages like C/C++ where
|
||||||
|
there is still no standardized way to use packages.
|
||||||
|
|
16
satrs-book/src/events.md
Normal file
16
satrs-book/src/events.md
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# Events
|
||||||
|
|
||||||
|
Events can be an extremely important mechanism used for remote systems to monitor unexpected
|
||||||
|
or expected anomalies and events occuring on these systems. They are oftentimes tied to
|
||||||
|
Fault Detection, Isolation and Recovery (FDIR) operations, which need to happen autonomously.
|
||||||
|
|
||||||
|
Events can also be used as a convenient Inter-Process Communication (IPC) mechansism, which is
|
||||||
|
also observable for the Ground segment. The PUS Service 5 standardizes how the ground interface
|
||||||
|
for events might look like, but does not specify how other software components might react
|
||||||
|
to those events. There is the PUS Service 19, which might be used for that purpose, but the
|
||||||
|
event components recommended by this framework do not really need this service.
|
||||||
|
|
||||||
|
The following images shows how the flow of events could look like in a system where components
|
||||||
|
can generate events, and where other system components might be interested in those events:
|
||||||
|
|
||||||
|
![Event flow](images/event_man_arch.png)
|
1
satrs-book/src/fdir.md
Normal file
1
satrs-book/src/fdir.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
# Fault Detecion, Isolation And Recovery (FDIR)
|
1
satrs-book/src/ground-segments.md
Normal file
1
satrs-book/src/ground-segments.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
# Ground Segments
|
24
satrs-book/src/housekeeping.md
Normal file
24
satrs-book/src/housekeeping.md
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# Housekeeping Data
|
||||||
|
|
||||||
|
Remote systems like satellites and rovers oftentimes generate data autonomously and periodically.
|
||||||
|
The most common example for this is temperature or attitude data. Data like this is commonly
|
||||||
|
referred to as housekeeping data, and is usually one of the most important and most resource heavy
|
||||||
|
data sources received from a satellite. Standards like the PUS Service 3 make recommendation how to
|
||||||
|
expose housekeeping data, but the applicability of the interface offered by PUS 3 has proven to be
|
||||||
|
partially difficult and clunky for modular systems.
|
||||||
|
|
||||||
|
First, we are going to list some assumption and requirements about Housekeeping (HK) data:
|
||||||
|
|
||||||
|
1. HK data is generated periodically by various system components throughout the
|
||||||
|
systems.
|
||||||
|
2. An autonomous and periodic sampling of that HK data to be stored and sent to Ground is generally
|
||||||
|
required. A minimum interface consists of requesting a one-shot sample of HK, enabling and
|
||||||
|
disabling the periodic autonomous generation of samples and modifying the collection interval
|
||||||
|
of the periodic autonomous generation.
|
||||||
|
3. HK data often needs to be shared to other software components. For example, a thermal controller
|
||||||
|
wants to read the data samples of all sensor components.
|
||||||
|
|
||||||
|
A commonly required way to model HK data in a clean way is also to group related HK data into sets,
|
||||||
|
which can then dumped via a similar interface.
|
||||||
|
|
||||||
|
TODO: Write down `sat-rs` recommendations how to expose and work with HK data.
|
259
satrs-book/src/images/event_man_arch.graphml
Normal file
259
satrs-book/src/images/event_man_arch.graphml
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:java="http://www.yworks.com/xml/yfiles-common/1.0/java" xmlns:sys="http://www.yworks.com/xml/yfiles-common/markup/primitives/2.0" xmlns:x="http://www.yworks.com/xml/yfiles-common/markup/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd">
|
||||||
|
<!--Created by yEd 3.22-->
|
||||||
|
<key attr.name="Description" attr.type="string" for="graph" id="d0"/>
|
||||||
|
<key for="port" id="d1" yfiles.type="portgraphics"/>
|
||||||
|
<key for="port" id="d2" yfiles.type="portgeometry"/>
|
||||||
|
<key for="port" id="d3" yfiles.type="portuserdata"/>
|
||||||
|
<key attr.name="url" attr.type="string" for="node" id="d4"/>
|
||||||
|
<key attr.name="description" attr.type="string" for="node" id="d5"/>
|
||||||
|
<key for="node" id="d6" yfiles.type="nodegraphics"/>
|
||||||
|
<key for="graphml" id="d7" yfiles.type="resources"/>
|
||||||
|
<key attr.name="url" attr.type="string" for="edge" id="d8"/>
|
||||||
|
<key attr.name="description" attr.type="string" for="edge" id="d9"/>
|
||||||
|
<key for="edge" id="d10" yfiles.type="edgegraphics"/>
|
||||||
|
<graph edgedefault="directed" id="G">
|
||||||
|
<data key="d0" xml:space="preserve"/>
|
||||||
|
<node id="n0">
|
||||||
|
<data key="d6">
|
||||||
|
<y:ShapeNode>
|
||||||
|
<y:Geometry height="509.9999999999999" width="768.7000000000003" x="579.3105418719211" y="304.7"/>
|
||||||
|
<y:Fill hasColor="false" transparent="false"/>
|
||||||
|
<y:BorderStyle color="#000000" raised="false" type="line" width="1.0"/>
|
||||||
|
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Ubuntu" fontSize="16" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="21.936037063598633" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="150.1282958984375" x="26.197490701913352" xml:space="preserve" y="24.234711021505348">Example Event Flow<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="-0.5" labelRatioY="-0.5" nodeRatioX="-0.46591974671274444" nodeRatioY="-0.452480958781362" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
|
||||||
|
<y:Shape type="rectangle"/>
|
||||||
|
</y:ShapeNode>
|
||||||
|
</data>
|
||||||
|
</node>
|
||||||
|
<node id="n1">
|
||||||
|
<data key="d6">
|
||||||
|
<y:ShapeNode>
|
||||||
|
<y:Geometry height="60.0" width="203.0" x="814.0" y="506.6799999999999"/>
|
||||||
|
<y:Fill color="#FFFF00" transparent="false"/>
|
||||||
|
<y:BorderStyle color="#000000" raised="false" type="line" width="1.0"/>
|
||||||
|
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Ubuntu" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.452094078063965" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="86.21258544921875" x="58.393707275390625" xml:space="preserve" y="21.27395296096796">Event Manager<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
|
||||||
|
<y:Shape type="rectangle"/>
|
||||||
|
</y:ShapeNode>
|
||||||
|
</data>
|
||||||
|
</node>
|
||||||
|
<node id="n2">
|
||||||
|
<data key="d6">
|
||||||
|
<y:ShapeNode>
|
||||||
|
<y:Geometry height="60.0" width="82.0" x="617.6" y="413.23"/>
|
||||||
|
<y:Fill color="#FF9900" transparent="false"/>
|
||||||
|
<y:BorderStyle color="#000000" raised="false" type="line" width="1.0"/>
|
||||||
|
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Ubuntu" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="30.90418815612793" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="55.120361328125" x="13.4398193359375" xml:space="preserve" y="14.547905921936035">Event
|
||||||
|
Creator 0<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
|
||||||
|
<y:Shape type="rectangle"/>
|
||||||
|
</y:ShapeNode>
|
||||||
|
</data>
|
||||||
|
</node>
|
||||||
|
<node id="n3">
|
||||||
|
<data key="d6">
|
||||||
|
<y:ShapeNode>
|
||||||
|
<y:Geometry height="60.0" width="76.55999999999995" x="988.5" y="335.62999999999994"/>
|
||||||
|
<y:Fill color="#FF9900" transparent="false"/>
|
||||||
|
<y:BorderStyle color="#000000" raised="false" type="line" width="1.0"/>
|
||||||
|
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Ubuntu" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="30.90418815612793" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="55.120361328125" x="10.719819335937473" xml:space="preserve" y="14.547905921936035">Event
|
||||||
|
Creator 2<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
|
||||||
|
<y:Shape type="rectangle"/>
|
||||||
|
</y:ShapeNode>
|
||||||
|
</data>
|
||||||
|
</node>
|
||||||
|
<node id="n4">
|
||||||
|
<data key="d6">
|
||||||
|
<y:ShapeNode>
|
||||||
|
<y:Geometry height="60.0" width="72.55999999999983" x="860.6610837438426" y="335.62999999999994"/>
|
||||||
|
<y:Fill color="#FF9900" transparent="false"/>
|
||||||
|
<y:BorderStyle color="#000000" raised="false" type="line" width="1.0"/>
|
||||||
|
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Ubuntu" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="30.90418815612793" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="55.120361328125" x="8.719819335937359" xml:space="preserve" y="14.547905921936035">Event
|
||||||
|
Creator 1<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
|
||||||
|
<y:Shape type="rectangle"/>
|
||||||
|
</y:ShapeNode>
|
||||||
|
</data>
|
||||||
|
</node>
|
||||||
|
<node id="n5">
|
||||||
|
<data key="d6">
|
||||||
|
<y:ShapeNode>
|
||||||
|
<y:Geometry height="60.0" width="87.27999999999997" x="1112.52" y="335.62999999999994"/>
|
||||||
|
<y:Fill color="#FF9900" transparent="false"/>
|
||||||
|
<y:BorderStyle color="#000000" raised="false" type="line" width="1.0"/>
|
||||||
|
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Ubuntu" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="30.90418815612793" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="55.120361328125" x="16.079819335937373" xml:space="preserve" y="14.547905921936035">Event
|
||||||
|
Creator 3<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
|
||||||
|
<y:Shape type="rectangle"/>
|
||||||
|
</y:ShapeNode>
|
||||||
|
</data>
|
||||||
|
</node>
|
||||||
|
<node id="n6">
|
||||||
|
<data key="d6">
|
||||||
|
<y:ShapeNode>
|
||||||
|
<y:Geometry height="60.0" width="126.0" x="781.0" y="620.26"/>
|
||||||
|
<y:Fill color="#FFCC00" transparent="false"/>
|
||||||
|
<y:BorderStyle color="#000000" raised="false" type="line" width="1.0"/>
|
||||||
|
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Ubuntu" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="30.90418815612793" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="92.78865051269531" x="16.605674743652344" xml:space="preserve" y="14.547905921936035">PUS Service 5
|
||||||
|
Event Reporting
|
||||||
|
<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
|
||||||
|
<y:Shape type="rectangle"/>
|
||||||
|
</y:ShapeNode>
|
||||||
|
</data>
|
||||||
|
</node>
|
||||||
|
<node id="n7">
|
||||||
|
<data key="d6">
|
||||||
|
<y:ShapeNode>
|
||||||
|
<y:Geometry height="60.0" width="118.63999999999987" x="928.2" y="620.26"/>
|
||||||
|
<y:Fill color="#FFCC00" transparent="false"/>
|
||||||
|
<y:BorderStyle color="#000000" raised="false" type="line" width="1.0"/>
|
||||||
|
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Ubuntu" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="30.90418815612793" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="84.08859252929688" x="17.2757037353515" xml:space="preserve" y="14.547905921936035">PUS Service 19
|
||||||
|
Event Action<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
|
||||||
|
<y:Shape type="rectangle"/>
|
||||||
|
</y:ShapeNode>
|
||||||
|
</data>
|
||||||
|
</node>
|
||||||
|
<node id="n8">
|
||||||
|
<data key="d6">
|
||||||
|
<y:ShapeNode>
|
||||||
|
<y:Geometry height="60.0" width="87.27999999999997" x="792.1260377358491" y="733.8400000000001"/>
|
||||||
|
<y:Fill color="#FFCC99" transparent="false"/>
|
||||||
|
<y:BorderStyle color="#000000" raised="false" type="line" width="1.0"/>
|
||||||
|
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Ubuntu" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="30.90418815612793" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="59.932403564453125" x="13.673798217773424" xml:space="preserve" y="14.547905921936035">Telemetry
|
||||||
|
Sink<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
|
||||||
|
<y:Shape type="rectangle"/>
|
||||||
|
</y:ShapeNode>
|
||||||
|
</data>
|
||||||
|
</node>
|
||||||
|
<node id="n9">
|
||||||
|
<data key="d6">
|
||||||
|
<y:ShapeNode>
|
||||||
|
<y:Geometry height="170.79999999999995" width="210.80000000000018" x="1076.84" y="601.88"/>
|
||||||
|
<y:Fill hasColor="false" transparent="false"/>
|
||||||
|
<y:BorderStyle color="#000000" raised="false" type="line" width="1.0"/>
|
||||||
|
<y:NodeLabel alignment="left" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="143.6875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="181.591796875" x="8.373079774614325" xml:space="preserve" y="7.444138124199753">Subscriptions
|
||||||
|
|
||||||
|
1. Event Creator 0 subscribes
|
||||||
|
for event 0
|
||||||
|
2. Event Creator 1 subscribes
|
||||||
|
for event group 2
|
||||||
|
3. PUS Service 5 handler
|
||||||
|
subscribes for all events
|
||||||
|
4. PUS Service 19 handler
|
||||||
|
subscribes for all events<y:LabelModel><y:SmartNodeLabelModel distance="4.0"/></y:LabelModel><y:ModelParameter><y:SmartNodeLabelModelParameter labelRatioX="-0.5" labelRatioY="-0.5" nodeRatioX="-0.4602795077105583" nodeRatioY="-0.45641605313700395" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/></y:ModelParameter></y:NodeLabel>
|
||||||
|
<y:Shape type="rectangle"/>
|
||||||
|
</y:ShapeNode>
|
||||||
|
</data>
|
||||||
|
</node>
|
||||||
|
<edge id="e0" source="n4" target="n1">
|
||||||
|
<data key="d10">
|
||||||
|
<y:PolyLineEdge>
|
||||||
|
<y:Path sx="8.058916256157545" sy="0.0" tx="-10.5" ty="0.0"/>
|
||||||
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
|
<y:Arrows source="none" target="standard"/>
|
||||||
|
<y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Ubuntu" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="30.90418815612793" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="53.92036437988281" x="8.639817810058275" xml:space="preserve" y="29.00100609374465">event 1
|
||||||
|
(group 1)<y:LabelModel><y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/></y:LabelModel><y:ModelParameter><y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="35.59999999999969" distanceToCenter="true" position="left" ratio="0.34252387409930674" segment="-1"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
||||||
|
<y:BendStyle smoothed="false"/>
|
||||||
|
</y:PolyLineEdge>
|
||||||
|
</data>
|
||||||
|
</edge>
|
||||||
|
<edge id="e1" source="n2" target="n1">
|
||||||
|
<data key="d10">
|
||||||
|
<y:PolyLineEdge>
|
||||||
|
<y:Path sx="0.0" sy="11.93999999999994" tx="-83.5" ty="0.0">
|
||||||
|
<y:Point x="832.0" y="455.16999999999996"/>
|
||||||
|
</y:Path>
|
||||||
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
|
<y:Arrows source="none" target="standard"/>
|
||||||
|
<y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Ubuntu" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="30.90418815612793" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="53.92036437988281" x="25.334655000000453" xml:space="preserve" y="-40.972107505798476">event 0
|
||||||
|
(group 0)<y:LabelModel><y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/></y:LabelModel><y:ModelParameter><y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="25.520000000000095" distanceToCenter="true" position="left" ratio="0.20267159489379444" segment="0"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
||||||
|
<y:BendStyle smoothed="false"/>
|
||||||
|
</y:PolyLineEdge>
|
||||||
|
</data>
|
||||||
|
</edge>
|
||||||
|
<edge id="e2" source="n3" target="n1">
|
||||||
|
<data key="d10">
|
||||||
|
<y:PolyLineEdge>
|
||||||
|
<y:Path sx="-23.719999999999914" sy="5.5" tx="87.56000000000006" ty="0.0"/>
|
||||||
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
|
<y:Arrows source="none" target="standard"/>
|
||||||
|
<y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Ubuntu" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="30.90418815612793" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="53.92036437988281" x="5.6761352539062955" xml:space="preserve" y="27.551854405966765">event 2
|
||||||
|
(group 3)<y:LabelModel><y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/></y:LabelModel><y:ModelParameter><y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="5.676132812499983" distanceToCenter="false" position="left" ratio="0.3219761157957032" segment="-1"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
||||||
|
<y:BendStyle smoothed="false"/>
|
||||||
|
</y:PolyLineEdge>
|
||||||
|
</data>
|
||||||
|
</edge>
|
||||||
|
<edge id="e3" source="n5" target="n1">
|
||||||
|
<data key="d10">
|
||||||
|
<y:PolyLineEdge>
|
||||||
|
<y:Path sx="-6.275467980295616" sy="0.0" tx="57.5" ty="8.5">
|
||||||
|
<y:Point x="1149.8845320197042" y="545.1799999999998"/>
|
||||||
|
</y:Path>
|
||||||
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
|
<y:Arrows source="none" target="standard"/>
|
||||||
|
<y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Ubuntu" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="30.90418815612793" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="97.38468933105469" x="26.667665869801795" xml:space="preserve" y="43.287014528669715">event 3 (group 2)
|
||||||
|
event 4 (group 2)<y:LabelModel><y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/></y:LabelModel><y:ModelParameter><y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="75.3599999999999" distanceToCenter="true" position="left" ratio="0.2967848459873102" segment="0"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
||||||
|
<y:BendStyle smoothed="false"/>
|
||||||
|
</y:PolyLineEdge>
|
||||||
|
</data>
|
||||||
|
</edge>
|
||||||
|
<edge id="e4" source="n1" target="n6">
|
||||||
|
<data key="d10">
|
||||||
|
<y:PolyLineEdge>
|
||||||
|
<y:Path sx="-65.0" sy="0.0" tx="6.5" ty="0.0"/>
|
||||||
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
|
<y:Arrows source="none" target="standard"/>
|
||||||
|
<y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Ubuntu" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.452094078063965" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="83.16456604003906" x="-98.78228302001958" xml:space="preserve" y="16.63042580701972"><<all events>><y:LabelModel><y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/></y:LabelModel><y:ModelParameter><y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="57.20000000000004" distanceToCenter="true" position="right" ratio="0.4441995640590947" segment="-1"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
||||||
|
<y:BendStyle smoothed="false"/>
|
||||||
|
</y:PolyLineEdge>
|
||||||
|
</data>
|
||||||
|
</edge>
|
||||||
|
<edge id="e5" source="n1" target="n7">
|
||||||
|
<data key="d10">
|
||||||
|
<y:PolyLineEdge>
|
||||||
|
<y:Path sx="42.660000000000196" sy="0.0" tx="-29.359999999999786" ty="0.0"/>
|
||||||
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
|
<y:Arrows source="none" target="standard"/>
|
||||||
|
<y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Ubuntu" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.452094078063965" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="83.16456604003906" x="20.4177438354493" xml:space="preserve" y="17.885881494816203"><<all events>><y:LabelModel><y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/></y:LabelModel><y:ModelParameter><y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="62.0" distanceToCenter="true" position="left" ratio="0.492249939452652" segment="-1"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
||||||
|
<y:BendStyle smoothed="false"/>
|
||||||
|
</y:PolyLineEdge>
|
||||||
|
</data>
|
||||||
|
</edge>
|
||||||
|
<edge id="e6" source="n1" target="n2">
|
||||||
|
<data key="d10">
|
||||||
|
<y:PolyLineEdge>
|
||||||
|
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
|
||||||
|
<y:Point x="658.6" y="536.6799999999998"/>
|
||||||
|
</y:Path>
|
||||||
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
|
<y:Arrows source="none" target="standard"/>
|
||||||
|
<y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Ubuntu" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="30.90418815612793" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="44.69230651855469" x="-131.99129340961497" xml:space="preserve" y="-45.45208675384538">event 1
|
||||||
|
event 2<y:LabelModel><y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/></y:LabelModel><y:ModelParameter><y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="right" ratio="0.6426904695623505" segment="0"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
||||||
|
<y:BendStyle smoothed="false"/>
|
||||||
|
</y:PolyLineEdge>
|
||||||
|
</data>
|
||||||
|
</edge>
|
||||||
|
<edge id="e7" source="n1" target="n4">
|
||||||
|
<data key="d10">
|
||||||
|
<y:PolyLineEdge>
|
||||||
|
<y:Path sx="-35.69940886699487" sy="0.0" tx="-17.140492610837327" ty="1.5"/>
|
||||||
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
|
<y:Arrows source="none" target="standard"/>
|
||||||
|
<y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Ubuntu" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.452094078063965" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="46.14430236816406" x="-54.352158195608126" xml:space="preserve" y="-79.29459128622307">group 2<y:LabelModel><y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/></y:LabelModel><y:ModelParameter><y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="31.279999999999973" distanceToCenter="true" position="left" ratio="0.6800790648728832" segment="-1"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
||||||
|
<y:BendStyle smoothed="false"/>
|
||||||
|
</y:PolyLineEdge>
|
||||||
|
</data>
|
||||||
|
</edge>
|
||||||
|
<edge id="e8" source="n6" target="n8">
|
||||||
|
<data key="d10">
|
||||||
|
<y:PolyLineEdge>
|
||||||
|
<y:Path sx="0.0" sy="0.0" tx="8.233962264150945" ty="-21.42352238805968"/>
|
||||||
|
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||||
|
<y:Arrows source="none" target="standard"/>
|
||||||
|
<y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Ubuntu" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="30.90418815612793" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="87.40060424804688" x="-100.50030212402339" xml:space="preserve" y="11.337896156311103">enabled Events
|
||||||
|
as PUS 5 TM<y:LabelModel><y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/></y:LabelModel><y:ModelParameter><y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="56.79999999999995" distanceToCenter="true" position="right" ratio="0.5" segment="0"/></y:ModelParameter><y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/></y:EdgeLabel>
|
||||||
|
<y:BendStyle smoothed="false"/>
|
||||||
|
</y:PolyLineEdge>
|
||||||
|
</data>
|
||||||
|
</edge>
|
||||||
|
</graph>
|
||||||
|
<data key="d7">
|
||||||
|
<y:Resources/>
|
||||||
|
</data>
|
||||||
|
</graphml>
|
BIN
satrs-book/src/images/event_man_arch.png
Normal file
BIN
satrs-book/src/images/event_man_arch.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 70 KiB |
23
satrs-book/src/introduction.md
Normal file
23
satrs-book/src/introduction.md
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
The sat-rs book
|
||||||
|
======
|
||||||
|
|
||||||
|
This book is the primary information resource for the [sat-rs framework](https://egit.irs.uni-stuttgart.de/rust/sat-rs)
|
||||||
|
in addition to the regular API documentation. It contains the following resources:
|
||||||
|
|
||||||
|
1. Architecture informations and consideration which would exceeds the scope of the regular API.
|
||||||
|
2. General information on how to build On-Board Software and how `sat-rs` can help to fulfill
|
||||||
|
the unique requirements of writing software for remote systems.
|
||||||
|
2. A Getting-Started workshop where a small On-Board Software is built from scratch using
|
||||||
|
sat-rs components.
|
||||||
|
|
||||||
|
# Introduction
|
||||||
|
|
||||||
|
The primary goal of the sat-rs framework 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.
|
||||||
|
|
||||||
|
A lot of the 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/).
|
||||||
|
|
1
satrs-book/src/logging.md
Normal file
1
satrs-book/src/logging.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
# Logging
|
1
satrs-book/src/modelling-space-systems.md
Normal file
1
satrs-book/src/modelling-space-systems.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
# Modelling Space Systems
|
102
satrs-book/src/modes-and-health.md
Normal file
102
satrs-book/src/modes-and-health.md
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
# Modes
|
||||||
|
|
||||||
|
Modes are an extremely useful concept for complex system in general. They also allow simplified
|
||||||
|
system reasoning for both system operators and OBSW developers. They model the behaviour of a
|
||||||
|
component and also provide observability of a system. A few examples of how to model
|
||||||
|
different components of a space system with modes will be given.
|
||||||
|
|
||||||
|
## Modelling a pyhsical devices with modes
|
||||||
|
|
||||||
|
The following simple mode scheme with the following three mode
|
||||||
|
|
||||||
|
- `OFF`
|
||||||
|
- `ON`
|
||||||
|
- `NORMAL`
|
||||||
|
|
||||||
|
can be applied to a large number of simpler devices of a remote system, for example sensors.
|
||||||
|
|
||||||
|
1. `OFF` means that a device is physically switched off, and the corresponding software component
|
||||||
|
does not poll the device regularly.
|
||||||
|
2. `ON` means that a device is pyhsically switched on, but the device is not polled perically.
|
||||||
|
3. `NORMAL` means that a device is powered on and polled periodically.
|
||||||
|
|
||||||
|
If a devices is `OFF`, the device handler will deny commands which include physical communication
|
||||||
|
with the connected devices. In `NORMAL` mode, it will autonomously perform periodic polling
|
||||||
|
of a connected physical device in addition to handling remote commands by the operator.
|
||||||
|
Using these three basic modes, there are two important transitions which need to be taken care of
|
||||||
|
for the majority of devices:
|
||||||
|
|
||||||
|
1. `OFF` to `ON` or `NORMAL`: The device first needs to be powered on. After that, the
|
||||||
|
device initial startup configuration must be performed.
|
||||||
|
2. `NORMAL` or `ON` to `OFF`: Any important shutdown configuration or handling must be performed
|
||||||
|
before powering off the device.
|
||||||
|
|
||||||
|
## Modelling a controller with modes
|
||||||
|
|
||||||
|
Controller components are not modelling physical devices, but a mode scheme is still the best
|
||||||
|
way to model most of these components.
|
||||||
|
|
||||||
|
For example, a hypothetical attitude controller might have the following modes:
|
||||||
|
|
||||||
|
- `SAFE`
|
||||||
|
- `TARGET IDLE`
|
||||||
|
- `TARGET POINTING GROUND`
|
||||||
|
- `TARGET POINTING NADIR`
|
||||||
|
|
||||||
|
We can also introduce the concept of submodes: The `SAFE` mode can for example have a
|
||||||
|
`DEFAULT` submode and a `DETUMBLE` submode.
|
||||||
|
|
||||||
|
## Achieving system observability with modes
|
||||||
|
|
||||||
|
If a system component has a mode in some shape or form, this mode should be observable. This means
|
||||||
|
that the operator can also retrieve the mode for a particular component. This is especially
|
||||||
|
important if these components can change their mode autonomously.
|
||||||
|
|
||||||
|
If a component is able to change its mode autonomously, this is also something which is relevant
|
||||||
|
information for the operator or for other software components. This means that a component
|
||||||
|
should also be able to announce its mode.
|
||||||
|
|
||||||
|
This concept becomes especially important when applying the mode concept on the whole
|
||||||
|
system level. This will also be explained in detail in a dedicated chapter, but the basic idea
|
||||||
|
is to model the whole system as a tree where each node has a mode. A new capability is added now:
|
||||||
|
A component can announce its mode recursively. This means that the component will announce its
|
||||||
|
own mode first before announcing the mode of all its children. Using a scheme like this, the mode
|
||||||
|
of the whole system can be retrieved using only one command. The same concept can also be used
|
||||||
|
for commanding the whole system, which will be explained in more detail in the dedicated systems
|
||||||
|
modelling chapter.
|
||||||
|
|
||||||
|
In summary, a component which has modes has to expose the following 4 capabilities:
|
||||||
|
|
||||||
|
1. Set a mode
|
||||||
|
2. Read the mode
|
||||||
|
3. Announce the mode
|
||||||
|
4. Announce the mode recursively
|
||||||
|
|
||||||
|
## Using ECSS PUS to perform mode commanding
|
||||||
|
|
||||||
|
# Health
|
||||||
|
|
||||||
|
Health is an important concept for systems and components which might fail.
|
||||||
|
Oftentimes, the health is tied to the mode of a system component in some shape or form, and
|
||||||
|
determines whether a system component is usable. Health is also an extremely useful concept
|
||||||
|
to simplify the Fault Detection, Isolation and Recovery (FDIR) concept of a system.
|
||||||
|
|
||||||
|
The following health states are based on the ones used inside the FSFW and are enough to model most
|
||||||
|
use-cases:
|
||||||
|
|
||||||
|
- `HEALTHY`
|
||||||
|
- `FAULTY`
|
||||||
|
- `NEEDS RECOVERY`
|
||||||
|
- `EXTERNAL CONTROL`
|
||||||
|
|
||||||
|
1. `HEALTHY` means that a component is working nominally, and can perform its task without any issues.
|
||||||
|
2. `FAULTY` means that a component does not work properly. This might also impact other system
|
||||||
|
components, so the passivation and isolation of that component is desirable for FDIR purposes.
|
||||||
|
3. `NEEDS RECOVERY` is used to attempt a recovery of a component. For example, a simple sensor
|
||||||
|
could be power-cycled if there were multiple communication issues in the last time.
|
||||||
|
4. `EXTERNAL CONTROL` is used to isolate an individual component from the rest of the system. For
|
||||||
|
example, on operator might be interested in testing a component in isolation, and the interference
|
||||||
|
of the system is not desired. In that case, the `EXTERNAL CONTROL` health state might be used
|
||||||
|
to prevent mode commands from the system while allowing external mode commands.
|
||||||
|
|
||||||
|
|
1
satrs-book/src/persistent-tm-storage.md
Normal file
1
satrs-book/src/persistent-tm-storage.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
# Persistent Telemetry (TM) Storage
|
1
satrs-book/src/power.md
Normal file
1
satrs-book/src/power.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
# Power Components
|
1
satrs-book/src/serialization.md
Normal file
1
satrs-book/src/serialization.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
# Serialization
|
1
satrs-book/src/thermal.md
Normal file
1
satrs-book/src/thermal.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
# Thermal Components
|
@ -51,9 +51,9 @@ use std::vec::Vec;
|
|||||||
/// .expect("Error sending PUS TC via UDP");
|
/// .expect("Error sending PUS TC via UDP");
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// The [fsrc-example crate](https://egit.irs.uni-stuttgart.de/rust/fsrc-launchpad/src/branch/main/fsrc-example)
|
/// The [satrs-example crate](https://egit.irs.uni-stuttgart.de/rust/fsrc-launchpad/src/branch/main/-example)
|
||||||
/// server code also includes
|
/// server code also includes
|
||||||
/// [example code](https://egit.irs.uni-stuttgart.de/rust/fsrc-launchpad/src/branch/main/fsrc-example/src/bin/obsw/tmtc.rs)
|
/// [example code](https://egit.irs.uni-stuttgart.de/rust/sat-rs/src/branch/main/satrs-example/src/tmtc.rs#L67)
|
||||||
/// on how to use this TC server. It uses the server to receive PUS telecommands on a specific port
|
/// on how to use this TC server. It uses the server to receive PUS telecommands on a specific port
|
||||||
/// and then forwards them to a generic CCSDS packet receiver.
|
/// and then forwards them to a generic CCSDS packet receiver.
|
||||||
pub struct UdpTcServer<E> {
|
pub struct UdpTcServer<E> {
|
||||||
|
Loading…
Reference in New Issue
Block a user