# Table of Contents - [Index | RACCOON OS](#index-raccoon-os) - [Frequently Asked Questions | RACCOON OS](#frequently-asked-questions-raccoon-os) - [Download and Run an Emulator | RACCOON OS](#download-and-run-an-emulator-raccoon-os) - [Tutorials | RACCOON OS](#tutorials-raccoon-os) - [Installing Packages | RACCOON OS](#installing-packages-raccoon-os) - [Download an Install on a Supported Machine | RACCOON OS](#download-an-install-on-a-supported-machine-raccoon-os) - [Compile a ROS2 Workspace for the Target Platform | RACCOON OS](#compile-a-ros2-workspace-for-the-target-platform-raccoon-os) - [Create a ROS2 Workspace | RACCOON OS](#create-a-ros2-workspace-raccoon-os) - [Create a Custom Image | RACCOON OS](#create-a-custom-image-raccoon-os) - [Install ROS2 and a Rust Demo Node | RACCOON OS](#install-ros2-and-a-rust-demo-node-raccoon-os) - [Why Yocto Linux? | RACCOON OS](#why-yocto-linux-raccoon-os) - [Development Tasks | RACCOON OS](#development-tasks-raccoon-os) - [OS Platform | RACCOON OS](#os-platform-raccoon-os) - [Delta Updates | RACCOON OS](#delta-updates-raccoon-os) - [Boot Process | RACCOON OS](#boot-process-raccoon-os) - [Ground Segment | RACCOON OS](#ground-segment-raccoon-os) - [YAMCS Setup | RACCOON OS](#yamcs-setup-raccoon-os) - [Usage of the CCSDS in RACCOON OS | RACCOON OS](#usage-of-the-ccsds-in-raccoon-os-raccoon-os) - [Userspace | RACCOON OS](#userspace-raccoon-os) - [Application Framework | RACCOON OS](#application-framework-raccoon-os) - [COP-1 | RACCOON OS](#cop-1-raccoon-os) - [Defining a Custom PUS Service | RACCOON OS](#defining-a-custom-pus-service-raccoon-os) - [404 Page not found | RACCOON OS](#404-page-not-found-raccoon-os) - [404 Page not found | RACCOON OS](#404-page-not-found-raccoon-os) - [404 Page not found | RACCOON OS](#404-page-not-found-raccoon-os) - [404 Page not found | RACCOON OS](#404-page-not-found-raccoon-os) - [404 Page not found | RACCOON OS](#404-page-not-found-raccoon-os) - [404 Page not found | RACCOON OS](#404-page-not-found-raccoon-os) - [404 Page not found | RACCOON OS](#404-page-not-found-raccoon-os) --- # Index | RACCOON OS RACCOON OS documentation [#](https://docs.raccoon.jdiez.me/#raccoon-os-documentation) ====================================================================================== Welcome! You have found the OS and Userspace documentation. This is still under construction. Please expand the sidebar to see the available documentation topics. --- # Frequently Asked Questions | RACCOON OS Frequently Asked Questions [#](https://docs.raccoon.jdiez.me/docs/faq/#frequently-asked-questions) =================================================================================================== What is RACCOON OS? [#](https://docs.raccoon.jdiez.me/docs/faq/#what-is-raccoon-os) ------------------------------------------------------------------------------------ RACCOON OS is a free, open source distribution of Linux for space applications. It consists of a OS platform that provides a bandwidth-efficient update mechanism, bootloader, device-specific drivers etc. and a set of applications known as the RACCOON Userspace. The Userspace applications implement standard space protocols including [Space Packet (CCSDS 130.3-G-1)](https://public.ccsds.org/Pubs/130x3g1.pdf) , [USLP (CCSDS 700.1-G-1)](https://public.ccsds.org/Pubs/700x1g1.pdf) , [COP-1 (CCSDS 232.1-B-2)](https://public.ccsds.org/Pubs/232x1b2e2c1.pdf) , [CFDP (CCSDS 720.1-G-4)](https://public.ccsds.org/Pubs/720x1g4.pdf) and a reduced set of the services in the [Packet Utilisation Standard (ECSS-E-ST-70-41C)](https://ecss.nl/standard/ecss-e-st-70-41c-space-engineering-telemetry-and-telecommand-packet-utilization-15-april-2016/) . The implementation of some of these protocols and services is built on top of existing open source libraries. The Userspace uses ROS2 for its middleware and ecosystem of useful nodes. In addition to the Userspace applications, we provide a set of tools to describe commands and telemetry using [XTCE](https://public.ccsds.org/Pubs/660x2g2.pdf) (a CCSDS recommended standard for ground segments), which also generate on-board software code from templates. The mission database generated by the Userpace tools can be used by mission control systems that support the XTCE standard. [Yamcs](https://yamcs.org/) is the reference mission control software that we use for development and operation. What can RACCOON OS do today? [#](https://docs.raccoon.jdiez.me/docs/faq/#what-can-raccoon-os-do-today) -------------------------------------------------------------------------------------------------------- * Build bootable images for the currently supported platforms: qemux86\_64, imx8mp, raspberrypi0. * Support for other platforms with a [Yocto Linux](https://yoctoproject.org/) BSPs should be easy to add. * Manage a filesystem versioning repository based on [OSTree](https://github.com/ostreedev/ostree) , generate and apply bandwidth-minimizing delta upgrades. Roll back to previous versions. * Prototype implementations of the standard protocols and services mentioned above. * Run [ROS2 Humble](https://docs.ros.org/en/humble/index.html) and cross-compile ROS2 workspaces to run on the target. * Packages like python3, numpy, gnuradio (with support for UHD radios) and many other common open source utilities. * Run the functional test / acquire telemetry for the thermal, vacuum and radiation tests of the [RACCOON Mission](https://www.tu.berlin/raumfahrttechnik/forschung/aktuelle-projekte/raccoon) . * [Test Controller source code](https://gitlab.com/raccoon-os/thermal-test-ws/-/tree/master/src?ref_type=heads) * [Test Mission Database (TC/TM) definition](https://gitlab.com/raccoon-os/thermal-test-ws/-/blob/master/mdb/thermal_test.py?ref_type=heads) * [Yamcs Configuration](https://docs.raccoon.jdiez.me/docs/faq/TODO_open_source) What is missing in RACCOON OS? [#](https://docs.raccoon.jdiez.me/docs/faq/#what-is-missing-in-raccoon-os) ---------------------------------------------------------------------------------------------------------- * Housekeeper service * Packet Storage and Retrieval service * Realtime Forwarding Control service * A custom PUS service for Software Update * Currently software updates are applied manually in the command line. * Support for SDLS and SDLS-EP * Application sandboxing * A way for the user to create custom images of RACCOON OS without needing to use the Yocto Linux build system. This will probably be done as some cli/gui wrappers around the `ostree` utilities. How do software updates work on RACCOON OS? [#](https://docs.raccoon.jdiez.me/docs/faq/#how-do-software-updates-work-on-raccoon-os) ------------------------------------------------------------------------------------------------------------------------------------ How does RACCOON OS compare with … [#](https://docs.raccoon.jdiez.me/docs/faq/#how-does-raccoon-os-compare-with-) ------------------------------------------------------------------------------------------------------------------ ### RODOS [#](https://docs.raccoon.jdiez.me/docs/faq/#rodos) [RODOS (Real time Onboard Dependable Operating System)](https://gitlab.com/rodos/rodos) is a FOSS, actively developed operating system for space applications that is widely used in academic missions in Germany and other countries. RODOS primarily targets bare-metal systems (microcontrollers, etc.), but applications written for RODOS can also run on POSIX systems. It provides a cross-platform implementation of a topic-based publish/subscribe middleware, which has been shown to be easy to understand for many aerospace engineers. In contrast to RACCOON OS, RODOS does not provide implementations of space protocols, applications, interfaces to a ground segment, device drivers (beyond a Hardware Abstraction Library for the chip’s peripherals). RACCOON OS does not target bare-metal platforms. ### NASA Core Flight System [#](https://docs.raccoon.jdiez.me/docs/faq/#nasa-core-flight-system) The [NASA Core Flight System (cFS)](https://github.com/nasa/cFS) is a FOSS software package that consists of multiple libraries written in C/C++ and a set of applications that implement many standard space protocols and services. cFS has been used in numerous missions (academic, institutional, private) and is at the forefront of open source space technology. cFS implementations of standards like CFDP, Space Data Link Security and SDLS-EP are widely used as reference implementations of these standards. In contrast to RACCOON OS, cFS does not provide any kind of hardware support beyond the Operating System Abstraction Layer (OSAL). cFS also does not provide a reference ground segment implementation that is capable of sending commands. [NASA OpenMCT](https://github.com/nasa/openmct) has some compatibility with cFS, but the interface between the on-board side and the ground segment must be implemented by the user. [1](https://docs.raccoon.jdiez.me/docs/faq/#fn:1) ### NanoSat MO Framework [#](https://docs.raccoon.jdiez.me/docs/faq/#nanosat-mo-framework) The [NanoSat MO Framework](https://github.com/esa/nanosat-mo-framework) is an open source framework for implementing space applications following the [CCSDS Mission Operations](https://public.ccsds.org/publications/moims.aspx) standard. It was developed as a PhD thesis at Graz University of Technology in partnership with the European Space Agency, who currently maintains the software. The NMF has been used on [OPS-SAT](https://www.esa.int/Enabling_Support/Operations/OPS-SAT) (TODO: and potentially other missions?) The CCSDS MO Standard defines a set of services typically used for spacecraft operations (similar to the ECCS’s Packet Utilisation Standard [2](https://docs.raccoon.jdiez.me/docs/faq/#fn:2) ) and a custom middleware called the Message Abstraction Layer (MAL)[3](https://docs.raccoon.jdiez.me/docs/faq/#fn:3) . NMF provides a Java implementation of these services and MAL. In contrast to RACCOON OS, the custom middleware (MAL) is only supported on Java and C++. Due to the lack of interoperability with other middleware solutions, there is a very reduced ecosystem of software that can be used. Furthermore, it requires developers to learn a new API which is less than ideally documented and for which there are few examples. It is important to note that the NanoSat MO Framework **is not** free software. It is licensed with a custom, non- [OSI-approved](https://opensource.org/licenses) license (“European Space Agency Public License (ESA-PL) Weak Copyleft – v2.4”) ### F' [#](https://docs.raccoon.jdiez.me/docs/faq/#f) [F’ (F Prime)](https://github.com/nasa/fprime) is a FOSS, cutting-edge flight software framework developed by NASA which has first class support for bare-metal applications and running on Linux. It has been successfully deployed on several space missions. Similar to cFS, F’ comes with a wide variety of first- and third-party applications to support common space protocols and services. F’ also provides with a fully featured ground segment (the [F’ Ground Data System](https://nasa.github.io/fprime/UsersGuide/gds/gds-introduction.html) ) which supports commanding, telemetry and others. Furthermore, F’ is extensively documented and many examples and tutorials can be found. In contrast with RACCOON OS, F’ uses a custom middleware based on components, ports and topologies. F’ does not provide any device drivers beyond a hardware abstraction layer. The F’ GDS works very well in conjunction with the F’ Flight Software - the mission database is directly generated from the same configuration files used to create onboard software structures. However, connecting the F’ Flight Software with a standards-based ground segment (like Yamcs) is up to the user. F’ is the most similar FOSS operating system for space applications to RACCOON OS. The main difference between F’ and RACCOON OS is that in the latter, we try to leverage existing, widely adopted solutions for the middleware and libraries. The former provides a unified API that is cross platform on bare-metal and Linux systems alike. RACCOON OS does not target bare-metal systems. The authors of RACCOON OS would recommend writing software for bare-metal computers on spacecraft using F'. ### SpaceOS [#](https://docs.raccoon.jdiez.me/docs/faq/#spaceos) [SpaceOS](https://tarides.com/blog/2023-07-31-ocaml-in-space-welcome-spaceos/) is a proprietary unikernel written in OCaml and commercialized by [Tarides](https://tarides.com/) , a French company which specializes in securing critical systems. Unfortunately, very little information about SpaceOS is publically available. The only source is the blog post linked here. We can infer that the SpaceOS compiler takes a set of user-provided Linux applications and creates a single-binary operating system that only contains the drivers necessary to run the user applications. What redundancy/reliability features does RACCOON OS have? [#](https://docs.raccoon.jdiez.me/docs/faq/#what-redundancyreliability-features-does-raccoon-os-have) ----------------------------------------------------------------------------------------------------------------------------------------------------------------- * Automatic rollback to previous software versions if a configurable number of boot attempts is exceeded. * Filesystem metadata and data checksums and redundancy (by using the `DUP` profile, similar to raid1). * This is accomplished by using [Btrfs](https://en.wikipedia.org/wiki/Btrfs) by default. Other freely available and widely used filesystems only offer metadata checksums. Has RACCOON OS been used in space? [#](https://docs.raccoon.jdiez.me/docs/faq/#has-raccoon-os-been-used-in-space) ------------------------------------------------------------------------------------------------------------------ It has not been used in space yet but there are two missions planned to launch in the next year. How is RACCOON OS licensed? [#](https://docs.raccoon.jdiez.me/docs/faq/#how-is-raccoon-os-licensed) ---------------------------------------------------------------------------------------------------- It is licensed with GPLv3. The copyright is owned by the Technische Universität Berlin. We are in the process of founding a non-profit organization to manage the IP rights of RACCOON OS. ### How can I use the GPLv3 licensed code of RACCOON OS? [#](https://docs.raccoon.jdiez.me/docs/faq/#how-can-i-use-the-gplv3-licensed-code-of-raccoon-os) Please see [this](https://www.tldrlegal.com/license/gnu-general-public-license-v3-gpl-3) summary of the GPLv3 license. Note: this is not legal advice. If you make any changes to the software, you must publish your modified changes with the same license (GPLv3). You can use RACCOON OS for commercial applications, as long as you publish your source code. If you wish to use RACCOON OS but not publish your source code, you must purchase a license from the RACCOON Foundation. Note: the RACCOON Foundation is not yet able to accept license purchases. What warranty does RACCOON OS come with? [#](https://docs.raccoon.jdiez.me/docs/faq/#what-warranty-does-raccoon-os-come-with) ------------------------------------------------------------------------------------------------------------------------------ As stated in the GPLv3 license, > **THERE IS NO WARRANTY FOR THE PROGRAM**, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. In the future, you will be able to purchase a custom warranty for RACCOON OS from approved vendors. Why is RACCOON OS based on Linux? [#](https://docs.raccoon.jdiez.me/docs/faq/#why-is-raccoon-os-based-on-linux) ---------------------------------------------------------------------------------------------------------------- We believe that Linux-based systems bring significant benefits over embedded systems for space applications. In terms of security, the Linux kernel has been battle-tested by being a foundational technology of modern IT infrastructure. Many exploit mitigations are on by default, and Linux provides robust access controls to prevent applications from accessing data from other applciations. Using Linux in space also comes with some challenges that RACCOON OS aims to address. * * * 1. OpenMCT can be connected to a Yamcs instance with existing open-source plugins. [↩︎](https://docs.raccoon.jdiez.me/docs/faq/#fnref:1) 2. In fact, CCSDS MO is intended to be a successor of the Packet Utilisation Standard but (… whatever …). TODO source the presentation where this timeline is shown. [↩︎](https://docs.raccoon.jdiez.me/docs/faq/#fnref:2) 3. The author notes that “MAL” means “bad” in Spanish. [↩︎](https://docs.raccoon.jdiez.me/docs/faq/#fnref:3) --- # Download and Run an Emulator | RACCOON OS Download and Run an Emulator [#](https://docs.raccoon.jdiez.me/docs/tutorials/download_and_run/#download-and-run-an-emulator) ============================================================================================================================== The easiest way to get started with RACCOON OS is to use the [`emu.py`](https://gitlab.com/raccoon-os/raccoon-os/-/blob/master/scripts/emu.py?ref_type=heads) script. Alternatively, you can [download and install](https://docs.raccoon.jdiez.me/docs/tutorials/download_and_install/) the OS on a supported machine. The `emu.py` script downloads the bootloader and filesystem for the image that you choose, creates a backing virtual disk drive, and runs the emulator. You must have `qemu-system-x86_64` and `python3` installed on your computer. Create a directory to follow along, download the `emu.py` script and make it executable: $ mkdir -p dev/raccoon_hello_world $ wget https://raccoon.jdiez.me/emu.py $ chmod +x emu.py Feel free to read the `emu.py` script before executing it. It’s a very simple Python script that doesn’t need elevated privileges. The CI/CD system deploys `emu.py` directly from the git repository. Let’s run it: $ ./emu.py -i raccoon-image-dev -p dev-emulator The following things happened: * the `dev-emulator` folder was created * the following files were downloaded: `u-boot-qemux86-64.rom` and `raccoon-image-dev-qemux86-64.rootfs.ota-btrfs` * an `overlay.qcow2` virtual drive was created * `u-boot` loaded the boot configuration and started the kernel * the system connected to the virtual network and started a SSH server The VM’s SSH port 22 is forwarded to port 2221 on the host. So let’s connect to it: $ ssh -o StrictHostKeyChecking=no root@localhost -p 2221 Why do we need `StrictHostKeyChecking=no`? This is because when you decide to recreate the VM (for example, to test a new OS build), a new SSH host key will be generated - and your SSH client will show a warning about a potential man-in-the-middle attack. When we connect, we are greeted by a banner reminiscent of installing Slackware from a CD-ROM in the 2000s: $ ssh -o StrictHostKeyChecking=no root@localhost -p 2221 Welcome to... ______ ___ _____ _____ _____ _____ _____ _ _ _____ _____ | ___ \/ _ \/ __ \/ __ \/ __ \ _ || _ | \ | | | _ / ___| | |_/ / /_\ \ / \/| / \/| / \/ | | || | | | \| | | | | \ `--. | /| _ | | | | | | | | | || | | | . ` | | | | |`--. \ | |\ \| | | | \__/\| \__/\| \__/\ \_/ /\ \_/ / |\ | \ \_/ /\__/ / \_| \_\_| |_/\____/ \____/ \____/\___/ \___/\_| \_/ \___/\____/ version 0.4 - yocto scarthgap - now with 100% more OTA! root@qemux86-64:/var/rootdirs/home/root# Let’s take a look at the filesystem setup we have out of the box: root@qemux86-64:/var/rootdirs/home/root# df -kh Filesystem Size Used Available Use% Mounted on /dev/sda 250.3M 130.2M 54.4M 71% /sysroot /dev/sda 250.3M 130.2M 54.4M 71% / /dev/sda 250.3M 130.2M 54.4M 71% /boot /dev/sda 250.3M 130.2M 54.4M 71% /usr /dev/sda 250.3M 130.2M 54.4M 71% /var devtmpfs 470.0M 0 470.0M 0% /dev tmpfs 478.0M 128.0K 477.9M 0% /run We can expand it to fill the whole disk: # btrfs filesystem resize max / Resize device id 1 (/dev/sda) from 250.25MiB to max # df -kh Filesystem Size Used Available Use% Mounted on /dev/sda 10.0G 130.2M 9.8G 1% /sysroot /dev/sda 10.0G 130.2M 9.8G 1% / [...] You can also [setup data redundancy](https://docs.raccoon.jdiez.me/docs/tutorials/download_and_run/TODO) (also known as RAID1) to make the filesystem robust against single bit flips. What can we do from here? At the moment, not much. RACCOON OS ships a versioned, immutable-by-default filesystem. This is necessary for [low bandwidth Delta Updates](https://docs.raccoon.jdiez.me/docs/os_platform/delta_updates/) . Learn about [installing packages](https://docs.raccoon.jdiez.me/docs/tutorials/installing_packages/) in the next tutorial. --- # Tutorials | RACCOON OS TODO hello world[1](https://docs.raccoon.jdiez.me/docs/tutorials/#fn:1) > this is an info hint * * * 1. this is a footnote [↩︎](https://docs.raccoon.jdiez.me/docs/tutorials/#fnref:1) --- # Installing Packages | RACCOON OS Installing Packages [#](https://docs.raccoon.jdiez.me/docs/tutorials/installing_packages/#installing-packages) =============================================================================================================== In this tutorial we will learn how to install packages on RACCOON OS. You should have completed the [emulator](https://docs.raccoon.jdiez.me/docs/tutorials/download_and_run/) or [hardware machine](https://docs.raccoon.jdiez.me/docs/tutorials/download_and_install/) in this tutorial before going through this one. > This tutorial is \*\*only applicable for development use-cases\*\*. To add packages to a custom image, see \[this\](TODO) tutorial. Unlock the Filesystem [#](https://docs.raccoon.jdiez.me/docs/tutorials/installing_packages/#unlock-the-filesystem) ------------------------------------------------------------------------------------------------------------------- The RACCOON OS filesystem is managed by [OSTree](https://docs.raccoon.jdiez.me/docs/tutorials/installing_packages/TODO) and it is immutable by default (except for `/home` and `/var`, which are writeable). This is needed for [low bandwidth Delta Updates](https://docs.raccoon.jdiez.me/docs/os_platform/delta_updates/) . # touch /bin/hello touch: /bin/hello: Read-only file system During development, you may want to [build an application package](https://docs.raccoon.jdiez.me/docs/tutorials/installing_packages/TODO) and directly install it on your running system without needing to [build a system update](https://docs.raccoon.jdiez.me/docs/tutorials/installing_packages/TODO) (which takes longer). We can _unlock_ the filesystem, which will create an overlay into which you can install packages (similar to how containers work). OSTree provides two filesystem unlock modes: `transient` (default, doesn’t persist across reboots) and `hotfix` (persists across reboots). We want our changes to persist, so use `hotfix`: # ostree admin unlock --hotfix Copying /etc changes: 0 modified, 0 removed, 8 added Transaction complete; bootconfig swap: yes; bootversion: boot.0.1, deployment count change: 1 Hotfix mode enabled. A writable overlayfs is now mounted on /usr for this booted deployment. A non-hotfixed clone has been created as the non-default rollback target. Let’s inspect the currently active OSTree deployments: # ostree admin status * raccoon-os 473726f8ab60d9bab99d9ab266a4baef55f4f70ffc5cef685c6180652ed36fc9.0 Version: 0.4 Unlocked: hotfix origin refspec: raccoon-os:qemux86-64 raccoon-os 473726f8ab60d9bab99d9ab266a4baef55f4f70ffc5cef685c6180652ed36fc9.1 (rollback) Version: 0.4 origin refspec: raccoon-os:qemux86-64 The current deployment is unlocked, and OSTree has created a rollback deployment. Reboot and you are now able to add files: # touch /bin/foo # > \*\*Important\*\*: any changes made to an \*unlocked filesystem\* will be \*\*DISCARDED\*\* the next time that you \[download and deploy an update\](TODO). This is intended: we want the filesystem to have the exact state that the build system generates. Files in \`/home\` and \`/var\` are preserved across upgrades. Refresh the Package Index [#](https://docs.raccoon.jdiez.me/docs/tutorials/installing_packages/#refresh-the-package-index) --------------------------------------------------------------------------------------------------------------------------- Now that the filesystem is unlocked, we can use `opkg` (the package manager on RACCOON OS) to install some of the programs that are available on the package repository. First, we need to update the package index: # opkg update Downloading https://raccoon.jdiez.me/deploy/ipk/all/Packages.gz. Updated source 'uri-all-0'. Downloading https://raccoon.jdiez.me/deploy/ipk/core2-64/Packages.gz. Updated source 'uri-core2-64-0'. Downloading https://raccoon.jdiez.me/deploy/ipk/qemux86_64/Packages.gz. Updated source 'uri-qemux86_64-0'. > If you run \`opkg update\` or \`opkg install\` on a \*\*locked\*\* filesystem, you may encounter unexpected behaviour. This is a known \[issue\](TODO). Make sure to unlock the filesystem as described above before proceeding. Install a Package [#](https://docs.raccoon.jdiez.me/docs/tutorials/installing_packages/#install-a-package) ----------------------------------------------------------------------------------------------------------- You can see the list of packages that are compiled by default in the [repo.yml](https://gitlab.com/raccoon-os/raccoon-os/-/blob/master/kas/repo.yml?ref_type=heads) configuration file. Let’s go ahead and install a sane text editor: # opkg install vim [...] Installing vim (9.1.0114) on root Downloading https://raccoon.jdiez.me/deploy/ipk/core2-64/vim_9.1.0114-r0_core2-64.ipk. [...] Configuring vim. update-alternatives: Linking /usr/bin/vi to /usr/bin/vim.vim update-alternatives: Linking /usr/bin/vim to /usr/bin/vim.vim # Now you may want to [install ROS2 and a demo workspace](https://docs.raccoon.jdiez.me/docs/tutorials/installing_packages/TODO) . --- # Download an Install on a Supported Machine | RACCOON OS Download and Install on a Supported Machine [#](https://docs.raccoon.jdiez.me/docs/tutorials/download_and_install/#download-and-install-on-a-supported-machine) ================================================================================================================================================================ TODO --- # Compile a ROS2 Workspace for the Target Platform | RACCOON OS TODO --- # Create a ROS2 Workspace | RACCOON OS Create a ROS2 Workspace [#](https://docs.raccoon.jdiez.me/docs/tutorials/create_ros_workspace/#create-a-ros2-workspace) ======================================================================================================================== ROS2 plays a crucial role in the RACCOON OS [Userspace](https://docs.raccoon.jdiez.me/docs/userspace/) . It’s used as the topic-based publish/subscribe/service middleware and also as the build system for your mission-specific deployment. In this tutorial we will create and run an example ROS2 workspace on our development machine, and in the next step we will [compile it for a target platform](https://docs.raccoon.jdiez.me/docs/tutorials/compile_ros_workspace_for_target/) . Create the Workspace Structure [#](https://docs.raccoon.jdiez.me/docs/tutorials/create_ros_workspace/#create-the-workspace-structure) -------------------------------------------------------------------------------------------------------------------------------------- This is basically the same process as described in the [ROS2 `colcon` tutorial](https://docs.ros.org/en/humble/Tutorials/Beginner-Client-Libraries/Colcon-Tutorial.html) . We optionally use an official [`ros` container image](https://hub.docker.com/_/ros/) to simplify the ROS2 installation process, but if your OS is [supported](https://docs.ros.org/en/humble/Installation.html) by ROS2 (i.e. Ubuntu 22.04, RHEL 8 or Windows 10) it’s recommended to use those binary packages instead of a container. ### Create a New Folder and Initialize Git [#](https://docs.raccoon.jdiez.me/docs/tutorials/create_ros_workspace/#create-a-new-folder-and-initialize-git) $ mkdir -p ros2-example-workspace/src $ cd ros2-example-workspace $ git init ### `container.sh` [#](https://docs.raccoon.jdiez.me/docs/tutorials/create_ros_workspace/#containersh) For convenience, we can create a simple script that will run whatever commands it is given inside of the ROS2 container. #!/bin/sh # Check if the 'ros' pod exists, if not create it if ! podman pod exists ros; then podman pod create --name ros --userns keep-id fi podman run \ -it \ --pod ros \ --workdir /work \ -v $(pwd):/work \ docker.io/ros:humble-ros-base \ "$@" Instead of `docker` we use `podman` because of its simplicity and lack of need to run a privileged daemon. It also makes it easy to run as the same user inside the container, instead of as `root`, using the `--userns=keep-id` flag. This alleviates the typical permissions problem that you may encounter when using build containers. Make the script executable and commit it: $ chmod +x container.sh $ git add container.sh $ git commit -m "Add container.sh" [master (root-commit) c3f47cf] Add container.sh 1 file changed, 7 insertions(+) create mode 100755 container.sh Add a Simple C++ Publisher Node [#](https://docs.raccoon.jdiez.me/docs/tutorials/create_ros_workspace/#add-a-simple-c-publisher-node) -------------------------------------------------------------------------------------------------------------------------------------- We follow similar steps to those described in the [ROS2 C++ tutorial](https://docs.ros.org/en/foxy/Tutorials/Beginner-Client-Libraries/Writing-A-Simple-Cpp-Publisher-And-Subscriber.html) . While we mostly want to write the applications for RACCOON OS in Rust, we’ll add a simple publisher node in C++ to show the process of cross-compiling to the target in a simple way first. Preparing a Rust package for cross-compilation is a slightly more advanced workflow that is described in [this tutorial](https://docs.raccoon.jdiez.me/docs/tutorials/create_ros_workspace/TODO) . Run the following command from the `src` directory of your ROS2 workspace (optionally prefixed by `../container.sh`): src/ $ ../container.sh ros2 pkg create --build-type ament_cmake cpp_simple_publisher going to create a new package package name: cpp_simple_publisher destination directory: /work package format: 3 version: 0.0.0 description: TODO: Package description maintainer: ['jdiez '] licenses: ['TODO: License declaration'] build type: ament_cmake dependencies: [] creating folder ./cpp_simple_publisher creating ./cpp_simple_publisher/package.xml creating source and include folder creating folder ./cpp_simple_publisher/src creating folder ./cpp_simple_publisher/include/src/cpp_simple_publisher creating ./cpp_simple_publisher/CMakeLists.txt Now let’s add the code for the publisher: src/cpp\_simple\_publisher/src/main.cc #include #include #include #include #include "rclcpp/rclcpp.hpp" #include "std_msgs/msg/string.hpp" using namespace std::chrono_literals; /* This example creates a subclass of Node and uses std::bind() to register a * member function as a callback from the timer. */ class MinimalPublisher : public rclcpp::Node { public: MinimalPublisher() : Node("minimal_publisher"), count_(0) { publisher_ = this->create_publisher("topic", 10); timer_ = this->create_wall_timer( 500ms, std::bind(&MinimalPublisher::timer_callback, this)); } private: void timer_callback() { auto message = std_msgs::msg::String(); message.data = "Hello, world! " + std::to_string(count_++); RCLCPP_INFO(this->get_logger(), "Publishing: '%s'", message.data.c_str()); publisher_->publish(message); } rclcpp::TimerBase::SharedPtr timer_; rclcpp::Publisher::SharedPtr publisher_; size_t count_; }; int main(int argc, char * argv[]) { rclcpp::init(argc, argv); rclcpp::spin(std::make_shared()); rclcpp::shutdown(); return 0; } Finally, we need to tell CMake how to build the publisher. Add this to `src/simple_cpp_publisher/CMakeLists.txt`: src/simple\_cpp\_publisher/CMakeLists.txt cmake_minimum_required(VERSION 3.5) project(cpp_simple_publisher) # Default to C++14 if(NOT CMAKE_CXX_STANDARD) set(CMAKE_CXX_STANDARD 14) endif() if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") add_compile_options(-Wall -Wextra -Wpedantic) endif() find_package(ament_cmake REQUIRED) find_package(rclcpp REQUIRED) find_package(std_msgs REQUIRED) add_executable(talker src/main.cc) ament_target_dependencies(talker rclcpp std_msgs) install(TARGETS talker DESTINATION lib/${PROJECT_NAME}) ament_package() Let’s build it and run it (from the top level directory of your workspace): $ ./container.sh colcon build Starting >>> cpp_simple_publisher Finished <<< cpp_simple_publisher [4.97s] Summary: 1 package finished [5.10s] $ ./container.sh bash jdiez@ros:~$ source install/setup.sh jdiez@ros:~$ ros2 run cpp_simple_publisher talker [INFO] [1723064903.495775843] [minimal_publisher]: Publishing: 'Hello, world! 0' [INFO] [1723064903.995789024] [minimal_publisher]: Publishing: 'Hello, world! 1' [INFO] [1723064904.495774612] [minimal_publisher]: Publishing: 'Hello, world! 2' [INFO] [1723064904.995864134] [minimal_publisher]: Publishing: 'Hello, world! 3' Note how we are first running `source install.sh` **inside** the container shell, and then we are using `ros2 run` to start the `talker` node. **In a new terminal** we can run `ros2 topic echo /topic` to confirm that ROS2 messages are being published: $ ./container.sh ros2 topic echo /topic data: Hello, world! 18 --- data: Hello, world! 19 --- data: Hello, world! 20 --- data: Hello, world! 21 Note how there is no `docker-compose` required here. Such is the power of `podman` pods! --- # Create a Custom Image | RACCOON OS Create a Custom Image [#](https://docs.raccoon.jdiez.me/docs/tutorials/create_a_custom_image/#create-a-custom-image) ===================================================================================================================== After you have downloaded a pre-built RACCOON OS image and [run it in an emulator](https://docs.raccoon.jdiez.me/docs/tutorials/download_and_run/) or [installed it on a supported machine](https://docs.raccoon.jdiez.me/docs/tutorials/download_and_install/) , you may want to create a custom image based on the packages you want to have installed for your deployment/mission. Creating a custom image is also a prerequisite for using the [Delta Update](https://docs.raccoon.jdiez.me/docs/tutorials/create_a_custom_image/TODO) system. To do this, you create a new repository which will contain the Yocto build metadata for your deployment. $ mkdir meta-raccoon-example $ cd meta-raccoon-example Create a [kas](https://docs.raccoon.jdiez.me/) `config.yml` file with the following contents: header: version: 13 includes: - file: kas/preset/qemux86.yml repo: raccoon repos: src/raccoon: url: https://gitlab.com/raccoon-os/raccoon-os branch: master layers: meta-raccoon: meta-raccoon-bsp: This tells `kas` to clone the RACCOON OS repository, add the `meta-raccooon` and `meta-raccoon-bsp` layers to your build, and also includes the [`kas/preset/qemux86.yml`](https://gitlab.com/raccoon-os/raccoon-os/-/blob/master/kas/preset/qemux86.yml?ref_type=heads) configuration. You can see which other presets are available in the [Supported Configurations](https://docs.raccoon.jdiez.me/docs/tutorials/create_a_custom_image/TODO) page. (`imx8mp`, `qemux86`, `raspberrypi0-wifi`) These preset configurations are used to build the base development images that are used in the previous tutorials, and are thus a good starting point for your custom build configuration. Build Prerequisites [#](https://docs.raccoon.jdiez.me/docs/tutorials/create_a_custom_image/#build-prerequisites) ----------------------------------------------------------------------------------------------------------------- First, install a recent version of `kas`: $ pip install kas>=4.4 You also need to install the build prerequistes listed in the Yocto Project [System Requirements](https://docs.yoctoproject.org/ref-manual/system-requirements.html) page. It’s recommended to install these on your host operating system instead of using a container for the build. The external dependencies are minimal, and this lets you take the most advantage of the Yocto build system. However it’s also very easy to run any build commands inside a container provided by `kas`. Simply replace `kas` with `kas-container` in any of the following instructions. Run the Build [#](https://docs.raccoon.jdiez.me/docs/tutorials/create_a_custom_image/#run-the-build) ----------------------------------------------------------------------------------------------------- $ kas build config.yml This single command does a lot of work. * it clones the git repositories of all of the layers and dependencies mentioned in the configuration file * it creates the bitbake configuration files `$build/conf/local.conf` and `$build/conf/bblayers.conf` * it sources the OpenEmbedded build environment and * runs `bitbake $target` (where `$target` is a variable specified in the config.yml - see the [`kas` project configuration documentation](https://kas.readthedocs.io/en/latest/userguide/project-configuration.html) ). This process downloads about 3GB of shared `sstate-cache` files from the RACCOON OS infrastructure. This is intended to massively speed up builds based on predefined and supported configurations. On a build machine with 4 threads and a fast internet connection, the build process for this configuration takes approximately 15 minutes. Some effort has been put to avoid downstream users from having to re-compile the Linux kernel for a supported target, as this is a very CPU-intensive process that can take a long time on non-specialized hardware. If you use the preset configurations and don’t make any changes that would trigger a kernel recompilation, clean builds should not cause `bitbake` to recompile the kernel. If this still happens, please [file an issue](https://gitlab.com/raccoon-os/raccoon-os/-/issues) . --- # Install ROS2 and a Rust Demo Node | RACCOON OS Install ROS2 and a Rust Demo Node [#](https://docs.raccoon.jdiez.me/docs/tutorials/install_ros2/#install-ros2-and-a-rust-demo-node) ==================================================================================================================================== In this tutorial we will learn how to install the pre-compiled ROS2 distribution and run a demo node written in Rust. You must have first completed the setup tutorial for [an emulator](https://docs.raccoon.jdiez.me/docs/tutorials/download_and_run/) or for a [hardware machine](https://docs.raccoon.jdiez.me/docs/tutorials/download_and_install/) and unlocked the filesystem in the [Installing Packages](https://docs.raccoon.jdiez.me/docs/tutorials/installing_packages/) tutorial. > If you would like to add the packages discussed in this tutorial to a custom image build, see the \[custom image creation\](TODO) tutorial. Since ROS2 plays a crucial role in the [Userspace](https://docs.raccoon.jdiez.me/docs/userspace/) , we want to make it as easy as possible to install and run your ROS2 workspaces on RACCOON OS. You can simply install the ros-core package (remember, your filesystem must be [unlocked](https://docs.raccoon.jdiez.me/docs/tutorials/installing_packages/#unlock-the-filesystem) ): # opkg install ros-core Installing rosidl-default-runtime (1.2.0-2) on root Downloading https://raccoon.jdiez.me/deploy/ipk/core2-64/rosidl-default-runtime_1.2.0-2-r0_core2-64.ipk. Installing ros-environment (3.2.2-1) on root Downloading https://raccoon.jdiez.me/deploy/ipk/core2-64/ros-environment_3.2.2-1-r0_core2-64.ipk. Installing ros-workspace (1.0.2-2) on root Downloading https://raccoon.jdiez.me/deploy/ipk/core2-64/ros-workspace_1.0.2-2-r0_core2-64.ipk. Installing sros2-cmake (0.10.5-1) on root Downloading https://raccoon.jdiez.me/deploy/ipk/core2-64/sros2-cmake_0.10.5-1-r0_core2-64.ipk. Installing ament-index-python (1.4.0-2) on root [... many dependencies omitted ...] Configuring ros-core. # We can source the ROS2 environment setup script and use the `ros2` cli as usual: # source /usr/opt/ros/humble/setup.sh [... warnings omitted, see below ...] # ros2 topic list /parameter_events /rosout A few things to note here: * **Instead of the usual base path for ROS2 being `/opt/ros/$ROS_DISTRO`, on RACCOON OS it is `/usr/opt/ros/$DISTRO`**. * BusyBox writes some warnings about calling `head` with an invalid option `c`. ROS2 expects to be running on a `sh`\-compatible shell, which BusyBox mostly is, but some commandline options to builtin shell functions are not available on BusyBox. This is a [known issue](https://docs.raccoon.jdiez.me/docs/tutorials/install_ros2/TODO) . * The `ros2` command takes quite a while to execute. This is a [known issue](https://docs.raccoon.jdiez.me/docs/tutorials/install_ros2/TODO) in upstream `ros2-cli`. --- # Why Yocto Linux? | RACCOON OS Why Yocto Linux? [#](https://docs.raccoon.jdiez.me/docs/os_platform/why_yocto/#why-yocto-linux) ================================================================================================ [Yocto Linux (poky)](https://www.yoctoproject.org/) is the base Linux distribution that is used together with the [OpenEmbedded](https://www.openembedded.orgwiki/Main_Page) to build RACCOON OS. Yocto-based OSes are somewhat different to the typical desktop Linux distributions like Ubuntu, Fedora, Alpine Linux, etc. that you may be familiar with. These so-called _binary_ distributions are very convenient to use. You can simply download a precompiled disk image that acts as a “live installer”, which can be booted in the target system in a standard way. Once installed, you can use the distribution’s package manager to download and install most software that you may typically want to use. RACCOON OS targets primarily embedded computing systems based on ARM application processors with **very limited resources** like RAM, storage, and processor clock. This requires some special considerations: Boot Process / Linux Kernel [#](https://docs.raccoon.jdiez.me/docs/os_platform/why_yocto/#boot-process--linux-kernel) ---------------------------------------------------------------------------------------------------------------------- Unlike x86-based systems, whose built-in [BIOS](https://en.wikipedia.org/wiki/BIOS) takes care of initializing the hardware and loading a first-stage bootloader, all of the boot code for ARM computers is stored in user flash. That means that the operating system has to supply the first stage bootloader and any firmware that may be needed for subsystems like RAM. These highly hardware-specific components and their build process are not extensively standarized, so the OS needs to handle them directly. Thus, most mainstream/binary Linux distributions **don’t support booting most ARM-based systems**. There are some notable exceptions like [Raspberry Pi OS](https://www.raspberrypi.com/software/) , which is a first-party remix of Debian for Raspberry Pi boards and [Asahi Linux](https://asahilinux.org/) , a third-party distribution of Fedora targetting Apple M-series chips. Popular systems like Raspberry Pi tend to get first party support from mainstream distrbutions, but the embedded systems that RACCOON targets would require individiual attention to port these distributions to them. Furthermore, it is often necessary to apply hardware-specific patches to the Linux kernel for a given target system. However, we aim to use very similar kernel configurations on supported systems, and run as close to mainline Linux as possible. And this is where Yocto Linux starts helping us: embedded Linux hardware vendors will almost certainly provide a Board Support Package (BSP) for that particular platform. **In theory**, that means that it should be possible to “just add” the vendor’s Yocto layer to our build, and we should be able to build the OS from that platform out of the box. **In reality**, the quality of vendor BSPs varies greatly and may be partially incompatible with our desired approach of deviating as little as possible from mainline Linux and u-boot. However, in most cases it should be possible to build a working image, and then extract the relevant information from the vendor BSP and reconfigure our build to use more standarized components. We have already done this process for the [Supported Platforms](https://docs.raccoon.jdiez.me/docs/os_platform/why_yocto/TODO_link) . Cross-Compiling Applications [#](https://docs.raccoon.jdiez.me/docs/os_platform/why_yocto/#cross-compiling-applications) ------------------------------------------------------------------------------------------------------------------------- The next thing one typically wants to do with an embedded system beside installing pre-existing software is to install your own software on it. Assuming that development computers are x86 based and the target system is ARM based, it is not directly possible to compile software for the target system using the same tools you use to compile on the development computers. There are a few possibilities here: * **Copy the source code to the target platform and compile it there**: this is the simplest solution, but your target platform will most likely be significantly less powerful than your development computer, making this option impractical in many cases. * **Use an ARM build server**: it’s possible to rent ARM servers from cloud providers or buy dedicated hardware for this purpose. However, we would like to avoid making that a requirement for building RACCOON OS. * **Cross-compile for the target architecture**: takes advantage of your existing development hardware, but introduces significant complexity to the build system. We choose the third option, cross compiling, considering that most users of RACCOON OS will want to use their existing build computing infrastructure (i.e. even just a laptop running x86 Linux). Mainstream Linux distribution have **very limited support** for cross-compiling. --- # Development Tasks | RACCOON OS Development Tasks [#](https://docs.raccoon.jdiez.me/docs/os_platform/development_tasks/#development-tasks) =========================================================================================================== This is the main page for development tasks. --- # OS Platform | RACCOON OS OS Platform [#](https://docs.raccoon.jdiez.me/docs/os_platform/#os-platform) ============================================================================= RACCOON OS consists of the base OS platform and the [Userspace](https://docs.raccoon.jdiez.me/docs/userspace/) . The base platform is responsible for: * Booting the system * Providing commonly used packages like ROS2, Python, GNURadio, etc * Making it possible to cross-compile and deploy user applications * Creating a versioned filesystem that can be updated over the air The base platform is a Linux distrbution created using [Yocto](https://www.yoctoproject.org/) . Eventually, this page will contain information about how to: * Build a bootable RACCOON OS for a hardware or emulated target * Add a ROS/RACCOON workspace to the image * Create an update package * Enable Secure Boot --- # Delta Updates | RACCOON OS Delta Updates [#](https://docs.raccoon.jdiez.me/docs/os_platform/delta_updates/#delta-updates) =============================================================================================== --- # Boot Process | RACCOON OS Boot Process [#](https://docs.raccoon.jdiez.me/docs/os_platform/boot/#boot-process) ==================================================================================== --- # Ground Segment | RACCOON OS Ground Segment [#](https://docs.raccoon.jdiez.me/docs/ground_segment/#ground-segment) ====================================================================================== --- # YAMCS Setup | RACCOON OS YAMCS Setup [#](https://docs.raccoon.jdiez.me/docs/ground_segment/yamcs_setup/#yamcs-setup) ============================================================================================ TODO: describe how to setup YAMCS here --- # Usage of the CCSDS in RACCOON OS | RACCOON OS Why CCSDS? [#](https://docs.raccoon.jdiez.me/docs/ccsds_usage/#why-ccsds) ========================================================================== RACCOON OS is based on the Standards of the CCSDS. The CCSDS standards are internationally accepted as major communication standard for satellites. Using this allows users of RACCOON OS to use according groundstation solutions. This includes rental ground stations, such as AWS Ground Stations, or GUI solutions, such as YAMCS. Which Parts of the CCSDS Standards are implemented? [#](https://docs.raccoon.jdiez.me/docs/ccsds_usage/#which-parts-of-the-ccsds-standards-are-implemented) ============================================================================================================================================================ * CCSDS 131.0-B-5 TM SYNCHRONIZATION AND CHANNEL CODING * REED-SOLOMON CODING * PSEUDO-RANDOMIZER: 255-bit pseudo-random sequence * CCSDS 231.0-B-4 TC SYNCHRONIZATION AND CHANNEL CODING * BCH CODING * COMMUNICATIONS LINK TRANSMISSION UNIT * RANDOMIZER * CCSDS 232.0-B-4 TC SPACE DATA LINK PROTOCOL * PROTOCOL SPECIFICATION WITHOUT SDLS OPTION * CCSDS 232.1-B-2 COMMUNICATIONS OPERATION PROCEDURE-1 * FOP-1 * FARM-1 * CCSDS 301.0-B-4 TIME CODE FORMATS * CCSDS UNSEGMENTED TIME CODE (CUC) * CCSDS DAY SEGMENTED TIME CODE (CDS) * CCSDS 732.1-B-2 UNIFIED SPACE DATA LINK PROTOCOL * PROTOCOL SPECIFICATION WITHOUT SDLS OPTION Additionally we use the [sat-rs](https://github.com/us-irs/sat-rs?tab=readme-ov-file) library as implementation of CCSDS 133.0-B-2 SPACE PACKET PROTOCOL. Which Parts of the CCSDS Standards are planned to be implemented? [#](https://docs.raccoon.jdiez.me/docs/ccsds_usage/#which-parts-of-the-ccsds-standards-are-planned-to-be-implemented) ======================================================================================================================================================================================== * CCSDS 132.0-B-3 TM SPACE DATA LINK PROTOCOL * CCSDS 732.0-B-4 AOS SPACE DATA LINK PROTOCOL * CCSDS 355.0-B-2 SPACE DATA LINK SECURITY PROTOCOL --- # Userspace | RACCOON OS Userspace [#](https://docs.raccoon.jdiez.me/docs/userspace/#userspace) ======================================================================= RACCOON OS uses the CCSDS [Space Packet Protocol](https://public.ccsds.org/Pubs/133x0b2e1.pdf) and the ESA [Packet Utilisation Standard](https://ecss.nl/standard/ecss-e-st-70-41c-space-engineering-telemetry-and-telecommand-packet-utilization-15-april-2016/) . A number of standard PUS services are available, but it is expected that users will define their own services. **TODO add some diagrams of the different parts of the userspace** **TODO describe how we use ROS** --- # Application Framework | RACCOON OS Application Framework [#](https://docs.raccoon.jdiez.me/docs/userspace/application_structure/#application-framework) ===================================================================================================================== The RACCOON application framework is intended to provide a standardized way to develop space applications in RACCOON OS. Each application processes **only** commands for a single APID. An application has at least one PUS service. Multiple applications may process commands for a given APID; for example, if the service implementation is split up in different applications. Structure [#](https://docs.raccoon.jdiez.me/docs/userspace/application_structure/#structure) ============================================================================================= This section describes what the structure of the source code directory for an application that uses the RACCOON OS app framework should look like. Currently, only applications written in Rust are supported. Rust [#](https://docs.raccoon.jdiez.me/docs/userspace/application_structure/#rust) ----------------------------------------------------------------------------------- . ├── Cargo.toml ├── mdb │ ├── example.xml │   └── example.py └── src ├── gen │   ├── mod.rs │   └── example_service.rs ├── handler │   ├── mod.rs │   └── example_service.rs └── main.rs * `src/main.rs`: the entry point of the application. Responsible for launching the services and I/O handlers. * `mdb/example.py` file is a description of a PUS service named `example`. Running this script causes the following files to be created: * `mdb/example.xml`: a XTCE description of the commands and telemetry in the `example` service. * `src/gen/example_service.rs`: a Rust module that contains the descriptions of commands and telemetry, and functions to encode and decode them. * `src/handler/example_service.rs`: a skeleton handler for the `example` service. --- # COP-1 | RACCOON OS The Rust implementation of COP-1 can be found [here](https://gitlab.com/rccn/ccsds-protocols-rs/-/tree/main/src/cop1) . COP-1 is split into FOP-1, which is running on ground and FARM-1, which is running on the satellite. In other open source implementations usually only the “needed” part is implemented. So for groundstations FOP-1 and for satellites FARM-1. In an effort to use COP-1 biderectional and during inter-satellite links both parts are implemented here. FOP-1 and FARM-1 are implemented “as defined” in the CCSDS. It was a focus during implementation to keep the structure of the implementation as closely connected to the standard as possible to make the implementaion better understandable. This led to some design choices, which I currently regard as unfortunate. Usage [#](https://docs.raccoon.jdiez.me/docs/ccsds_usage/cop1/#usage) ====================================================================== FOP-1 [#](https://docs.raccoon.jdiez.me/docs/ccsds_usage/cop1/#fop-1) ---------------------------------------------------------------------- As stated above, FOP-1 is the groundstation or transmitting part of COP-1. Additionally, it is the “complex” part of the algorithm. FOP-1 owns multiple buffers, handles retransmission and manages the link. Each virtual channel shall have its own FOP-1 object running. Mission specific definitions must be set during object specification. Depending on the Frame to be used, the according predefined types can be used: UslpFop1 and TcFop1, instead of the Fop1 object, since the frame generic is predefined here already. pub type UslpFop1 = Fop1, MAX_FRAME_SIZE, TFDZ_SIZE, INSERT_ZONE_SIZE>; pub type TcFop1 = Fop1; pub struct Fop1 * **Uslp Frames**: If the USLP Frame shall be used for a mission the UslpFop1 may be used. The UslpFop1 requires a couple of generic constants: MAX\_FRAME\_SIZE, TFDZ\_SIZE and INSERT\_ZONE\_SIZE (even if the frame size is variable the maximimum buffer space must be provided). Due to the flexibility of the USLP frame the MAX\_FRAME\_SIZE can not be calculated from the TFDZ and INSERT\_ZONE sizes or vice versa. * **TC Frames**: Accordingly to the UslpFop1 type, for the TcFop1 Object only needs the MAX\_FRAME\_SIZE to be provided. * **Custom Frames**: If another frame shall be used with this FOP-1 implementation, the following traits have to be implemented for said frame it: _CCSDSFrame_ and _CCSDSFrameTC_. Additionally, a constructor object without a lifetime (see Open Tasks below) must be implemented which implements the _CCSDSFrameTCConstructor_ trait. the Fop1 implementation requires an user implemented Fop1Connector. This object is called at the lower levels of the FOP-1 implementation when the frame shall be send or an error occured. The object shall implement the Fop1Connector trait. ### FOP1connector trait [#](https://docs.raccoon.jdiez.me/docs/ccsds_usage/cop1/#fop1connector-trait) The FOP1Connector trait looks like this: /// Trait to be used to implement FOP-1 actions, which are used by the FOP-1 algorithm to interact with the system. pub trait Fop1Connector { fn transmit_request_for_frame<'raw, PackageType: CCSDSFrame<'raw>>(&mut self, frame: &PackageType, req_id: u64) -> Result; fn notify(&self, notification: FOP1Notifications, req_id: u64) -> Result<(), FOP1Error>; fn alert(&self, alert: FOP1Alerts)-> Result<(), FOP1Error>; fn abort(&self, gvcid: u8) -> Result<(), FOP1Error>; } The four functions come from the CCSDS. An example for the implementation of the transmit\_request\_for\_frame function could be the usage of a serial interface and the transmission of the raw data to that interface. In [RACCOON OS implementation](https://gitlab.com/rccn/rccn-userspace-ws/-/tree/master/src/rccn_usr_comm?ref_type=heads) this function uses the zenoh middleware to forward the data to an according key. The data is picked up by the fec app and further handled there. The notify, alert and abort functions shall provide feedback to higher layers of the code. This could be simply print statements (or using the log crate) or also messages to zenoh keys, depending on the FDIR mechanism. In RACCOON OS the FDIR mechanism is not yet fully defined. If a transmission perforemd one state of the following enum shall be returned. If the transmission was performed in the FOP1Connector, e.g. via a serial interface, Failure or Success shall be returned, depending on the result. This will lead to the call of the _receive\_response\_from\_lower\_layer_ function, described below. If for example a middleware is used between the sending algorithm and the FOP1 thread the _receive\_response\_from\_lower\_layer_ function must be called manually depending on the result. #[derive(PartialEq, Clone)] pub enum TransmitResult{ Failure, Unknown, Success } ### Functions [#](https://docs.raccoon.jdiez.me/docs/ccsds_usage/cop1/#functions) After initialization the FOP-1 algorithms has ?? functions to interact: #### directive handling [#](https://docs.raccoon.jdiez.me/docs/ccsds_usage/cop1/#directive-handling) pub fn handle_fop1_directive(&mut self, control_input: FOP1Directives) -> Result<(), Error> With this function the FOP-1 Algorithm can be directly controlled using the following directives: pub enum FOP1Directives{ InitAdWithoutCLCWCheck(u64), InitAdWithCLCLCheck(u64), InitAdWithUnlock(u64), InitAdWithSetVr((u64, u8)), TerminateAdService(u64), ResumeAdService(u64), SetVs((u64, u8)), SetFopSlidingWindow((u64, u8)), //k SetT1Initial((u64, u64)), SetTransmissionLimit((u64, u8)), SetTimeoutType((u64, u8)), //tt } The four Init functions as well as the Terminate function will send a control frame via the transmit path provided in the FOP1connector to the FARM-1 part. The other functions only adapt setting on the FOP-1 end. The functions called depending on the given directive are also public and can be called directly. ### Processing a CLCW field [#](https://docs.raccoon.jdiez.me/docs/ccsds_usage/cop1/#processing-a-clcw-field) pub fn process_clcw_from_valid_cop1(&mut self, clcw: CLCW) -> Result This function must be called when a clcw field is received. The informations inside the CLCW field will provide feedback to the FOP-1 algorithm about the state of the FARM-1 algorithm, which frames have been received and which frames must be transmitted next. ### check timer [#](https://docs.raccoon.jdiez.me/docs/ccsds_usage/cop1/#check-timer) pub fn check_timer(&mut self)-> Result This crate does not do threading. Threading or tasking must be done externally and so the timer must be repeatedly checked. To do this, the check\_timer function must be called. Depending on the timeout provided in FOP-1 initialization the algorithm will perform resending of a frame or will abbort the transmition process. ### transfer fdu [#](https://docs.raccoon.jdiez.me/docs/ccsds_usage/cop1/#transfer-fdu) pub fn receive_request_to_transfer_fdu<'raw, PackageType: CCSDSFrameTC<'raw>>(&mut self, req_id: u64, frame: &PackageType)-> Result<(), Error> To send a frame the _receive\_request\_to\_transfer\_fdu_ function shall be called. There is not much else to say here. ### lower layer interaction [#](https://docs.raccoon.jdiez.me/docs/ccsds_usage/cop1/#lower-layer-interaction) pub fn receive_response_from_lower_layer(&mut self, req_id: u64, response: u8) -> Result<(), Error> Depending on the implementation this function can is called directly. If, for example, a middleware is used between the transmission algorithm and the the FOP1 Connector this functrion must be called manually. ### Open Tasks [#](https://docs.raccoon.jdiez.me/docs/ccsds_usage/cop1/#open-tasks) * This code was developed after the implementation of the TC and USLP frame, which are both using rust lifetimes to allow efficiant usage of micro controllers. FOP-1 and FARM-1 both are implemented as frame agnostic as possible. Currently, in rust lifetimes, traits and generics do not behave well together ( [further infos](https://users.rust-lang.org/t/traits-generics-and-lifetimes/128993) ), which led to the implementation as it is. If rust improves upon the behaviour I would like to improve this here as well. * The code currently uses a vector as buffer for frames. I would like to switch this in the future to a basic array, as this leed to better embedded support. FARM-1 [#](https://docs.raccoon.jdiez.me/docs/ccsds_usage/cop1/#farm-1) ------------------------------------------------------------------------ Farm-1 runs on the receiving end of the link and --- # Defining a Custom PUS Service | RACCOON OS Defining a Custom PUS Service [#](https://docs.raccoon.jdiez.me/docs/userspace/defining_a_service/#defining-a-custom-pus-service) ================================================================================================================================== In addition to the functionality provided by standard PUS services, it is expected that you will want to define your own services to accomplish mission-specific tasks. This consists of: * Choosing a service ID * Defining commands * Defining telemetry * Implementing a service handler For both commands and telemetry, the task is to specify the data types exchanged between the ground segment and space segment. In order to support many ground station software packages, we use the [XML Telemetric and Command Exchange™](https://www.omg.org/xtce/index.htm) (XTCE) standard. We use [`pymdb`](https://github.com/yamcs/pymdb) to generate XTCE descriptions easily. In the future, we want to provide a less verbose version using YAML. The `mdb/service.py` file [#](https://docs.raccoon.jdiez.me/docs/userspace/defining_a_service/#the-mdbservicepy-file) ---------------------------------------------------------------------------------------------------------------------- To start a new service, create a file `mdb/service.py` in your application directory. The name should reflect the name of your service. Add the following contents: from yamcs.pymdb import * from rustgen import * service = System("Raccoon") service_type_id = 130 base_cmd = Command( system=service, name="base", abstract=True, base="/PUS/pus-tc", assignments={"type": service_type_id}, ) ### Choosing a service ID [#](https://docs.raccoon.jdiez.me/docs/userspace/defining_a_service/#choosing-a-service-id) IDs below 127 are reserved for standard PUS services. You can use service IDs above 127. The service ID must be unique within an APID. Defining commands [#](https://docs.raccoon.jdiez.me/docs/userspace/defining_a_service/#defining-commands) ---------------------------------------------------------------------------------------------------------- For each command that you want to define, add the following to `mdb/service.py`: my_new_command = Command( system=service, base=base_cmd, assignments={"subtype": 1}, name="MyNewCommand", arguments=[\ # ...\ ], ) Pay attention to the `assignments={"subtype": 1}` line. This specifies the PUS subservice type, which is used to identify the command. You should increment it for each command that you define. ### Command arguments [#](https://docs.raccoon.jdiez.me/docs/userspace/defining_a_service/#command-arguments) The `arguments` array specifies the available arguments for the command. They can be of the following types: * **Supported**: * [IntegerArgument](https://github.com/yamcs/pymdb/blob/master/src/yamcs/pymdb/commands.py#L324) * [EnumeratedArgument](https://github.com/yamcs/pymdb/blob/master/src/yamcs/pymdb/commands.py#L256) * **Not yet supported**: * [AbsoluteTimeArgument](https://github.com/yamcs/pymdb/blob/master/src/yamcs/pymdb/commands.py#L109) * [AggregateArgument](https://github.com/yamcs/pymdb/blob/master/src/yamcs/pymdb/commands.py#L138) * [ArrayArgument](https://github.com/yamcs/pymdb/blob/master/src/yamcs/pymdb/commands.py#L165) * [BinaryArgument](https://github.com/yamcs/pymdb/blob/master/src/yamcs/pymdb/commands.py#L194) * [BooleanArgument](https://github.com/yamcs/pymdb/blob/master/src/yamcs/pymdb/commands.py#L225) * [FloatArgument](https://github.com/yamcs/pymdb/blob/master/src/yamcs/pymdb/commands.py#L285) Take a look at the argument list for each of the linked class in the `pymdb` source code to see the available options. #### Example [#](https://docs.raccoon.jdiez.me/docs/userspace/defining_a_service/#example) arguments=[\ IntegerArgument(\ name="BatteryNum",\ minimum=1,\ maximum=3,\ encoding=uint8_t,\ signed=False,\ ),\ IntegerArgument(\ name="CustomLength",\ minimum=0,\ maximum=244,\ encoding=IntegerEncoding(bits=5),\ signed=False,\ ),\ EnumeratedArgument(\ name="EnumArg",\ choices=[[0, "OFF"], [1, "ON"], [2, "EXPLODE"]],\ encoding=uint8_t,\ ),\ EnumeratedArgument(\ name="EnumeratedArgCustomType",\ choices=[[0, "AUS"], [1, "EIN"], [2, "JA"]],\ encoding=IntegerEncoding(bits=4),\ ),\ ], Defining telemetry [#](https://docs.raccoon.jdiez.me/docs/userspace/defining_a_service/#defining-telemetry) ------------------------------------------------------------------------------------------------------------ The process of defining telemetry is very similar to commands, with some differences. A new telemetry container is defined by adding the following to `mdb/service.py`: my_telemetry = Container( system=service, base="/PUS/pus-tm", name="MyTelemetry", condition=AndExpression( EqExpression("/PUS/pus-tm/type", service_type_id), EqExpression("/PUS/pus-tm/subtype", 1) ), entries=[\ ...\ ] ) The two key differences are: * The subservice type (i.e. telemetry packet identifier) is specified in the `condition` field, and it has to be ANDed together with the service type. Remember to increment the subtype for each telemetry container you define. * Instead of an `arguments` field, we use `entries`. ### Container entries [#](https://docs.raccoon.jdiez.me/docs/userspace/defining_a_service/#container-entries) … #### Example [#](https://docs.raccoon.jdiez.me/docs/userspace/defining_a_service/#example-1) … Autogenerating Rust [#](https://docs.raccoon.jdiez.me/docs/userspace/defining_a_service/#autogenerating-rust) -------------------------------------------------------------------------------------------------------------- Implementing a Service Handler [#](https://docs.raccoon.jdiez.me/docs/userspace/defining_a_service/#implementing-a-service-handler) ------------------------------------------------------------------------------------------------------------------------------------ --- # 404 Page not found | RACCOON OS 404 === Page Not Found -------------- ### [RACCOON OS](https://docs.raccoon.jdiez.me/) --- # 404 Page not found | RACCOON OS 404 === Page Not Found -------------- ### [RACCOON OS](https://docs.raccoon.jdiez.me/) --- # 404 Page not found | RACCOON OS 404 === Page Not Found -------------- ### [RACCOON OS](https://docs.raccoon.jdiez.me/) --- # 404 Page not found | RACCOON OS 404 === Page Not Found -------------- ### [RACCOON OS](https://docs.raccoon.jdiez.me/) --- # 404 Page not found | RACCOON OS 404 === Page Not Found -------------- ### [RACCOON OS](https://docs.raccoon.jdiez.me/) --- # 404 Page not found | RACCOON OS 404 === Page Not Found -------------- ### [RACCOON OS](https://docs.raccoon.jdiez.me/) --- # 404 Page not found | RACCOON OS 404 === Page Not Found -------------- ### [RACCOON OS](https://docs.raccoon.jdiez.me/) ---