Satellite#

Data#

Data is sent via the CDTP protocol, which send data in messages that can contain several data frames (also called message payload frames). Since data is sent as binary data, it is up to the implementation to decide how to organize the data. Additionally, each message can contain metadata in form of tags (key-value pairs) in the message header.

Transmitting Data#

The TransmitterSatellite class can be used to send data during a run over the network. It sends the Begin-of-Run (BOR) message in the starting state and the End-of-Run (EOR) message in the stopping state. This is achieved in the BaseSatellite by dynamically casting it to a TransmitterSatellite.

Warning

Sending data is not thread safe. If multiple threads need to access the sender, it needs to be protected with a mutex.

TransmitterSatellite configuration parameters#

Parameter

Type

Description

Default Value

_bor_timeout

Unsigned integer

Timeout for the BOR message to be successfully sent, in seconds

10

_eor_timeout

Unsigned integer

Timeout for the EOR message to be successfully sent, in seconds

10

_data_timeout

Unsigned integer

Timeout for a data message to be successfully sent, in seconds

10

Receiving Data#

The ReceiverSatellite class can be used to send data during a run over the network. It requires a given list of data transmitters, which is given by the _data_transmitters config parameter. Similar to the TransmitterSatellite mentioned above, executing transmitter transitions in addition to user transitions is achieve in the BaseSatellite by dynamically casting it to a ReceiverSatellite.

ReceiverSatellite configuration parameters#

Parameter

Type

Description

Default Value

_eor_timeout

Unsigned integer

Timeout for the EOR message to be received in seconds

10

_data_transmitters

List of strings

Canonical names of transmitters to connect to

-

constellation::satellite Namespace#

using constellation::satellite::Generator = std::shared_ptr<Satellite>(std::string_view, std::string_view)#
class BaseSatellite#

Subclassed by constellation::satellite::Satellite

Public Functions

virtual ~BaseSatellite()#
inline constexpr std::string_view getSatelliteType() const#

Return the satellite type.

inline constexpr std::string_view getSatelliteName() const#

Return the satellite name.

std::string getCanonicalName() const#

Return the canonical name of the satellite.

The canonical name is satellite_type.satellite_name

inline constexpr bool supportsReconfigure() const#

Returns if online configuration is supported.

inline protocol::CSCP::State getState() const#

Return current state of the satellite.

inline std::string_view getStatus() const#

Return the current status of the satellite.

inline std::string_view getRunIdentifier() const#

Return the current or last used run identifier.

inline constexpr utils::Port getCommandPort() const#

Return the ephemeral port number to which the CSCP socket is bound to.

inline FSM &getFSM()#

Return the FSM of the satellite.

Warning

Use carefully, the FSM gives direct access to low level functionality of the framework.

void join()#

Join CSCP processing thread.

Join the CSCP processing thread, which happens when the satellite is shut down or terminated.

void terminate()#

Terminate the satellite.

Protected Functions

BaseSatellite(std::string_view type, std::string_view name)#

Protected Attributes

log::Logger logger_#
class CommandRegistry#
#include <constellation/satellite/CommandRegistry.hpp>

Registry for user commands.

Class to allow registration and execution of arbitrary commands based on their name. The commands can require any number of arguments that can be converted from std::string. Return values are also possible as long as a conversion to std::string is possible.

Public Functions

template<typename R, typename ...Args>
void add(const std::string &name, std::string description, std::initializer_list<protocol::CSCP::State> states, std::function<R(Args...)> func)#

Register a command with arbitrary arguments from a functional.

Parameters:
  • name – Name of the command

  • description – Description of the command

  • states – States of the finite state machine in which this command can be called

  • func – Functional containing the callable object

Template Parameters:
  • R – Return type

  • Args – Argument types

template<typename T, typename R, typename ...Args>
void add(const std::string &name, std::string description, std::initializer_list<protocol::CSCP::State> states, R (T::* func)(Args...), T *t)#

Register a command with arbitrary arguments from a member function pointer and object pointer.

Parameters:
  • name – Name of the command

  • description – Description of the command

  • states – States of the finite state machine in which this command can be called

  • func – Pointer to the member function of t to be called

  • t – Pointer to the called object

Template Parameters:
  • T – Type of the called object

  • R – Return type

  • Args – Argument types

config::Value call(protocol::CSCP::State state, const std::string &name, const config::List &args)#

Calls a registered function with its arguments This method calls a registered function and returns the output of the function, or an empty string.

Parameters:
  • state – Current state of the finite state machine when this call was made

  • name – Name of the command to be called

  • args – List of arguments

Throws:
  • UnknownUserCommand – if no command is not registered under this name

  • InvalidUserCommand – if the command is registered but cannot be called in the current state

  • MissingUserCommandArguments – if the number of arguments does not match

  • std::invalid_argument – if an argument or the return value could not be decoded or encoded to std::string

Returns:

Return value of the called function

std::map<std::string, std::string> describeCommands() const#

Generate map of commands with comprehensive description.

The description consists of the user-provided command description from registering the command. In addition, this description is appended with a statement on how many arguments the command requires and a list of states in which the command can be called.

Returns:

Map with command names and descriptions

class CommunicationError : public constellation::satellite::SatelliteError#
#include <constellation/satellite/exceptions.hpp>

Satellite Error for device communication.

An error occurred in the user code implementation of a satellite when attempting to communicate with hardware

Public Functions

inline explicit CommunicationError(const std::string &reason)#
class FSM#

Public Types

using State = protocol::CSCP::State#
using Transition = protocol::CSCP::Transition#
using TransitionCommand = protocol::CSCP::TransitionCommand#
using TransitionPayload = std::variant<std::monostate, config::Configuration, std::string>#

Payload of a transition function: variant with config, partial_config or run identifier

using TransitionFunction = State (FSM::*)(TransitionPayload)#

Function pointer for a transition function: takes the variant mentioned above, returns new State

using TransitionMap = std::map<Transition, TransitionFunction>#

Maps the allowed transitions of a state to a transition function

using StateTransitionMap = std::map<State, TransitionMap>#

Maps state to transition maps for that state

Public Functions

inline FSM(BaseSatellite *satellite)#

Construct the final state machine of a satellite.

Parameters:

satelliteSatellite class with functions of transitional states

~FSM()#
inline State getState() const#

Returns the current state of the FSM.

inline std::chrono::system_clock::time_point getLastChanged() const#

Return the timestamp of the last state change.

bool isAllowed(Transition transition) const#

Check if a FSM transition is allowed in current state.

Parameters:

transition – Transition to check if allowed

Returns:

True if transition is possible

void react(Transition transition, TransitionPayload payload = {})#

Perform a FSM transition.

Parameters:
  • transition – Transition to perform

  • payload – Payload for the transition function

Throws:

FSMError – if the transition is not a valid transition in the current state

bool reactIfAllowed(Transition transition, TransitionPayload payload = {})#

Perform a FSM transition if allowed, otherwise do nothing.

Parameters:
  • transition – Transition to perform if allowed

  • payload – Payload for the transition function

Returns:

True if the transition was initiated

std::pair<message::CSCP1Message::Type, std::string> reactCommand(TransitionCommand transition_command, const message::PayloadBuffer &payload)#

Perform a FSM transition via a CSCP message.

Parameters:
  • transition_command – Transition command from CSCP

  • payload – Payload frame from CSCP

Returns:

Tuple containing the CSCP message type and a description

void requestInterrupt(std::string_view reason)#

Try to perform an interrupt as soon as possible.

This function waits for the next steady state and performs an interrupt if in ORBIT or RUN state, otherwise nothing is done. It guarantees that the FSM is in a state where the satellite can be safely shut down.

Warning

This function is not thread safe, meaning that no other react command should be called during execution.

Parameters:

reason – Reason for the requested interrupt

void registerStateCallback(const std::string &identifier, std::function<void(State)> callback)#

Registering a callback to be executed when a new state was entered.

This function adds a new state update callback. Registered callbacks are used to distribute the state of the FSM whenever it was changed.

Warning

State callbacks block the execution of further transitions, callbacks that take a long time should offload the work to a new thread.

Parameters:
  • identifier – Identifier string for this callback

  • callback – Callback taking the new state as argument

void unregisterStateCallback(const std::string &identifier)#

Unregistering a state callback.

This function removed the state update callback with the given identifier

Parameters:

identifier – Identifier string for this callback

class FSMError : public constellation::utils::RuntimeError#
#include <constellation/satellite/exceptions.hpp>

Finite State Machine Error.

An error occurred in a request to the finite state machine

Subclassed by constellation::satellite::InvalidFSMTransition

Protected Functions

FSMError() = default#
class InvalidCDTPMessageType : public constellation::satellite::SatelliteError#
#include <constellation/satellite/exceptions.hpp>

Error when a received CDTP message does not have the correct type.

Public Functions

inline explicit InvalidCDTPMessageType(message::CDTP1Message::Type type, std::string_view reason)#
class InvalidFSMTransition : public constellation::satellite::FSMError#
#include <constellation/satellite/exceptions.hpp>

Invalid transition requested.

A transition of the finite state machine was requested which is not allowed from the current state

Public Functions

inline explicit InvalidFSMTransition(protocol::CSCP::Transition transition, protocol::CSCP::State state)#
class InvalidUserCommand : public constellation::satellite::UserCommandError#
#include <constellation/satellite/exceptions.hpp>

Invalid user command.

The user command is not valid in the current state of the finite state machine

Public Functions

inline explicit InvalidUserCommand(const std::string &command, protocol::CSCP::State state)#
class InvalidUserCommandArguments : public constellation::satellite::UserCommandError#
#include <constellation/satellite/exceptions.hpp>

Invalid arguments for user command.

Public Functions

inline explicit InvalidUserCommandArguments(std::string_view argtype, std::string_view valuetype)#
class InvalidUserCommandResult : public constellation::satellite::UserCommandError#
#include <constellation/satellite/exceptions.hpp>

Invalid return type from user command.

Public Functions

inline explicit InvalidUserCommandResult(std::string_view argtype)#
class MissingUserCommandArguments : public constellation::satellite::UserCommandError#
#include <constellation/satellite/exceptions.hpp>

Missing arguments for user command.

Public Functions

inline explicit MissingUserCommandArguments(const std::string &command, std::size_t args_expected, std::size_t args_given)#
class ReceiverSatellite : public constellation::satellite::Satellite, private constellation::pools::BasePool<message::CDTP1Message, chirp::DATA, zmq::socket_type::pull>#
#include <constellation/satellite/ReceiverSatellite.hpp>

Satellite class with additional functions to receive data.

Subclassed by DevNullReceiverSatellite

Public Functions

void running(const std::stop_token &stop_token) final#

Run function.

Note

For data receiving satellites, this function must not be implemented. Instead receive_bor(), receive_data() and receive_eor() have to be implemented.

Parameters:

stop_token – Token which tracks if running should be stopped or aborted

Protected Functions

ReceiverSatellite(std::string_view type, std::string_view name)#

Construct a data receiving satellite.

Parameters:
  • typeSatellite type

  • name – Name of this satellite instance

virtual void receive_bor(const message::CDTP1Message::Header &header, config::Configuration config) = 0#

Receive and handle Begin-of-Run (BOR) message.

Parameters:
  • header – Header of the BOR message containing e.g. the sender name

  • config – Configuration of the sending satellite to be stored

virtual void receive_data(message::CDTP1Message &&data_message) = 0#

Receive and handle data message.

Note

Any tags in the header should be stored next to the payload frames.

Parameters:

data_message – Data message containing the header and the payload

virtual void receive_eor(const message::CDTP1Message::Header &header, config::Dictionary run_metadata) = 0#

Receive and handle End-of-Run (EOR) message.

Parameters:
  • header – Header of the EOR message containing e.g. the sender name

  • run_metadata – Dictionary with run metata of the sending satellite to be stored

virtual bool should_connect(const chirp::DiscoveredService &service) final#

Checks whether or not to connect to a discovered service.

Returns:

True if service should be connected to, false otherwise

class RecvTimeoutError : public constellation::satellite::SatelliteError#
#include <constellation/satellite/exceptions.hpp>

Error when receiving a message timed out.

Public Functions

inline explicit RecvTimeoutError(const std::string &what, std::chrono::seconds timeout)#
class Satellite : public constellation::satellite::BaseSatellite#
#include <constellation/satellite/Satellite.hpp>

Satellite class with transitional user functions.

Subclassed by DummySatelliteNR< constellation::satellite::Satellite >, DummySatelliteNR< SatelliteT >, SputnikSatellite, constellation::satellite::ReceiverSatellite, constellation::satellite::TransmitterSatellite

Public Functions

virtual ~Satellite() = default#
void initializing(config::Configuration &config) override#

Initialize satellite.

In this function a satellite can for example check the configuration or establish connection to a device.

Note

A satellite can be re-initializied from INIT, i.e. this function can be called twice in a row. Any actions required to be undone before another initialization should be done in launching() instead.

Parameters:

config – Configuration of the satellite

void launching() override#

Launch satellite.

In this function the configuration should be applied and the satellite prepared for data taking, for example by ramping up the high voltage of a device.

void landing() override#

Land satellite.

In this function should actions performed in the launching() function should be undone, for example by ramping down the high voltage of a device.

void reconfiguring(const config::Configuration &partial_config) override#

Reconfigure satellite.

In this function a partial configuration should be applied to the already launched satellite. This function should throw if a configuration parameter is changed that is not supported in online reconfiguration.

Note

By default, the satellite does not support online reconfiguration. Support for online reconfiguration can be enabled with support_reconfigure().

Parameters:

partial_config – Changes to the configuration of the satellite

void starting(std::string_view run_identifier) override#

Start satellite.

In this function the data acquisition of the satellite should be started, for example by opening the output file.

Note

This function should not take a long time to execute. Slow actions such as applying a configuration should be performed in the launching() function.

Parameters:

run_identifier – Run identifier for the upcoming run

void stopping() override#

Stop satellite.

In this function the data acquisition of the satellite should be stopped, for example by closing the output file.

void running(const std::stop_token &stop_token) override#

Run function.

In this function the data acquisition of the satellite should be continuously executed.

Parameters:

stop_token – Token which tracks if running should be stopped or aborted

void interrupting(protocol::CSCP::State previous_state) override#

Interrupt function.

In this function a response for the transition from ORBIT or RUN to the SAFE state can be implemented. This includes for example closing open files or turning off the high voltage. By default, this function calls stopping() (if in RUN state) and then landing().

Parameters:

previous_state – State in which the satellite was being interrupted

void failure(protocol::CSCP::State previous_state) override#

Failure function.

In this function a response to uncatched errors can be implemented. It is executed after entering the ERROR state.

Parameters:

previous_state – State in which the satellite was before experiencing a failure

Protected Functions

Satellite(std::string_view type, std::string_view name)#

Construct a satellite.

Parameters:
  • typeSatellite type

  • name – Name of this satellite instance

inline constexpr void support_reconfigure(bool enable = true)#

Enable or disable support for reconfigure transition.

Required to enable the reconfiguring() function (disabled by default).

Parameters:

enable – If online reconfiguration support should be enabled

template<typename T, typename R, typename ...Args>
inline void register_command(const std::string &name, std::string description, std::initializer_list<protocol::CSCP::State> states, R (T::* func)(Args...), T *t)#

Register a new user command.

Parameters:
  • name – Name of the command

  • description – Comprehensive description of the command

  • states – States of the finite state machine in which this command can be called

  • func – Pointer to the member function to be called

  • t – Pointer to the satellite object

template<typename R, typename ...Args>
inline void register_command(const std::string &name, std::string description, std::initializer_list<protocol::CSCP::State> states, std::function<R(Args...)> func)#

Register a new user command from a function or lambda.

Parameters:
  • name – Name of the command

  • description – Comprehensive description of the command

  • states – States of the finite state machine in which this command can be called

  • func – Function to be called

class SatelliteError : public constellation::utils::RuntimeError#
#include <constellation/satellite/exceptions.hpp>

Generic Satellite Error.

An unspecified error occurred in the user code implementation of a satellite

Subclassed by constellation::satellite::CommunicationError, constellation::satellite::InvalidCDTPMessageType, constellation::satellite::RecvTimeoutError, constellation::satellite::SendTimeoutError

Public Functions

inline explicit SatelliteError(const std::string &reason)#

Protected Functions

SatelliteError() = default#
class SendTimeoutError : public constellation::satellite::SatelliteError#
#include <constellation/satellite/exceptions.hpp>

Error when sending a message timed out.

Public Functions

inline explicit SendTimeoutError(const std::string &what, std::chrono::seconds timeout)#
class TransmitterSatellite : public constellation::satellite::Satellite#
#include <constellation/satellite/TransmitterSatellite.hpp>

Satellite class with additional functions to transmit data.

Subclassed by RandomTransmitterSatellite

Public Functions

DataMessage newDataMessage(std::size_t frames = 1)#

Create new message for attaching data frames.

Note

This function increases the CDTP sequence number.

Note

To send the data message, use sendDataMessage().

Parameters:

frames – Number of data frames to reserve

bool trySendDataMessage(DataMessage &message)#

Attempt to send data message created with newDataMessage()

Note

The return value of this function has to be checked. If it is false, one should take action such as discarding the message, trying to send it again or throwing an exception.

Parameters:

message – Reference to data message

Returns:

True if the message was successfully sent/queued, false otherwise

void sendDataMessage(DataMessage &message)#

Send data message created with `newDataMessage()

Note

This method will block until the message has been sent or the timeout for sending data messages has been reached. In the latter case, a SendTimeoutError exception is thrown.

Parameters:

message – Reference to data message

Throws:

SendTimeoutError – If data send timeout is reached

template<typename T>
inline void setBORTag(std::string_view key, const T &value)#

Set tag for the BOR message metadata send at the begin of the run.

template<typename T>
inline void setEORTag(std::string_view key, const T &value)#

Set tag for the EOR message metadata send at the end of the run.

inline constexpr utils::Port getDataPort() const#

Return the ephemeral port number to which the CDTP socket is bound to.

Protected Functions

TransmitterSatellite(std::string_view type, std::string_view name)#

Construct a data transmitting satellite.

Parameters:
  • typeSatellite type

  • name – Name of this satellite instance

class UnknownUserCommand : public constellation::satellite::UserCommandError#
#include <constellation/satellite/exceptions.hpp>

Invalid user command.

The user command is not registered

Public Functions

inline explicit UnknownUserCommand(const std::string &command)#
class UserCommandError : public constellation::utils::RuntimeError#
#include <constellation/satellite/exceptions.hpp>

Error thrown for all user command errors

Subclassed by constellation::satellite::InvalidUserCommand, constellation::satellite::InvalidUserCommandArguments, constellation::satellite::InvalidUserCommandResult, constellation::satellite::MissingUserCommandArguments, constellation::satellite::UnknownUserCommand

Protected Functions

UserCommandError() = default#