Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions api/api-overview.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
Ground stations expose uplink and downlink functionality through API based on ZeroMQ messages (https://zeromq.org/) through TCP transport. The TCP endpoints are not exposed to public network, so in order to work with them, the Client must be connected to the same network.

All data exchanged between ground and PW-Sat2 are AX.25 KISS-encoded frames. Consult AX.25 (http://www.ax25.net/AX25.2.2-Jul\%2098-2.pdf) and APRS (http://www.aprs.org/doc/APRS101.PDF) documentation.

Summary of available endpoints:
\begin{longtable}{l|l}
\toprule
\textbf{Function} & \textbf{Endpoint} \\
\midrule
\endhead
Receive downlink frames & \texttt{tcp://<host>:7001} \\
Transmit uplink frame & \texttt{tcp://<host>:7000} \\
\bottomrule
\end{longtable}

PW-Sat2 maintains an open-source repository, containing among others, a Python code used to decode and encode PW-Sat2 data. The relevant parts are located in GitHub repository: https://github.com/PW-Sat2/PWSat2OBC/tree/master/integration_tests.
38 changes: 38 additions & 0 deletions api/downlink.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
\section{Receiving data}

All frames received and decoded by ground station are pushed as ZeroMQ message. In order to to receive it, client must subscribe to endpoint \texttt{tcp://<host>:7001}.

The incoming frames are AX.25 frames, without synchronization sequence and end flags.

\begin{longtable}{l|l}
\toprule
\textbf{Bytes} & \textbf{Meaning} \\
\midrule
\endhead
7 bytes & Destination call sign \\
7 bytes & Source call sign \\
1 byte & Frame type (constant 0x03) \\
1 byte & Protocol Id (constant 0xF0) \\
6 bits & Frame APID \\
18 bits & Sequence number \\
227 bytes & Frame Payload \\
last 2 bytes & FCS \\
\bottomrule
\end{longtable}

The payload data depends on the frame APID. The PW-Sat2 OBC repository contains code to parse it.
Below is an example (simplified) python code to connect, receive and decode frame.

\begin{verbatim}
import response_frames # from PWSat2OBC/integration_tests
import zmq

sock = context.socket(zmq.SUB)
sock.connect("tcp://%s:%d" % (target, port))
sock.setsockopt(zmq.SUBSCRIBE, "")

frame = sock.recv()
payload = frame[16:-2] # extract ax.25 payload
frame_decoder = response_frames.FrameDecoder(response_frames.frame_factories)
print(frame_decoder.decode(frame))
\end{verbatim}
58 changes: 58 additions & 0 deletions api/uplink.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
\section{Transmitting data}

Similarly to downlink, the uplink uses AX.25 frames (APRS) encoded as ZeroMQ messages, sent to ground station's endpoint (\texttt{tcp://<host>:7000}).

The message follows AX.25 format:


\begin{longtable}{l|l}
\toprule
\textbf{Bytes} & \textbf{Meaning} \\
\midrule
\endhead
7 bytes & Destination call sign \\
7 bytes & Source call sign \\
1 byte & Frame type (constant 0x03) \\
1 byte & Protocol Id (constant 0xF0) \\
4 bytes & Security Code (verified na OBC) \\
1 byte & Frame APID \\
195 bytes & Frame Payload \\
\bottomrule
\end{longtable}

PW-Sat2 OBC repository contains Python code for all available Telecommands to generate payload for AX.25 frames. Below is an example (simplified) python code to connect to ground station, encode telecommand and transmit it.

\begin{verbatim}

import aprs
import zmq

class Wrap:
def __init__(self, byte_str):
self.byte_str = byte_str

def encode(self, *args):
return self.byte_str

def send():
sock = self.context.socket(zmq.PUB)
sock.connect("tcp://%s:%d" % (target, port))

aprs_frame = aprs.Frame()
aprs_frame.source = aprs.Callsign(self.source_callsign)
aprs_frame.destination = aprs.Callsign(self.destination_callsign)

payload = frame.build()
aprs_frame.text = Wrap(convert_bytes_to_string(payload))
buff = array.array('B', self.aprs_frame.encode_kiss())
msg = convert_bytes_to_string(buff)
sock.send(msg)

\end{verbatim}

Example: requesting beacon frame using PW-Sat2 OBC repository code:

\begin{verbatim}
import telecommand
send(telecommand.SendBeacon())
\end{verbatim}
12 changes: 9 additions & 3 deletions main.tex
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,20 @@ \chapter{PW-Sat2 - Overview}
\input{overview/extended-mission.tex}
\input{overview/operations.tex}

\chapter{API}
\input{api/api-overview.tex}
\input{api/downlink.tex}
\input{api/uplink.tex}

\chapter{Software tools reference}
\input{tools/tools-overview.tex}
\input{tools/mission-repo.tex}
\input{tools/gnuradio.tex}
\input{tools/grafana.tex}
\input{tools/session-monitor.tex}
% \input{tools/session-monitor.tex}
\input{tools/uplink-console.tex}
\input{tools/tasklist-generator.tex}
\input{tools/autosession.tex}
% \input{tools/tasklist-generator.tex}
% \input{tools/autosession.tex}

\chapter{\obc Concepts}
\input{obc-procedures/adcs.tex}
Expand Down
4 changes: 2 additions & 2 deletions overview/basic-information.tex
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ \section{PW-Sat2 Basic information}
\end{itemize}
\item Radio (using amateur bands):
\begin{itemize}
\item Uplink: 145.900, BPSK, 1200bps
\item Downlink: 435.275, BPSK, 9600bps
\item Uplink: 145.900, AFSK, 1200bps, AX.25
\item Downlink: 435.275, BPSK, 9600bps, AX.25
\item Full-duplex communication possible.
\end{itemize}
\end{itemize}
10 changes: 5 additions & 5 deletions overview/operations.tex
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,19 @@ \subsection{Session type: Deep-sleep refresh}
Occurs every other day. It's manual: the task list is constant, but operator controls transmission manually using \toolref{Uplink Console}.

\subsection{Session type: Full-mode sessions}
Occurs every 2 weeks. It's manual and requires most work. They're planned at least couple days in advance. Plans for experiments and photos are prepared by OPER members responsible for each experiments. All task lists are prepared (with help of \toolref{Tasklist Generator}) and executed (using \toolref{Uplink Console}) by operators manually.
Occurs every 2 weeks. It's manual and requires most work. They're planned at least couple days in advance. Plans for experiments and photos are prepared by OPER members responsible for each experiments. All task lists are prepared (with help of Tasklist Generator) and executed (using \toolref{Uplink Console}) by operators manually.

\subsection{Steps for each session}

\begin{enumerate}
\item Operator prepares pull request in \toolref{Mission Repository} with data.json, tasklist.py and summary.py. In case of Deep-sleep refresh session, only data.json change is needed.
\item Other team members review and approve the pull request.
\item Operator merges the pull request at least 10 minutes before session.
\item \toolref{Autosession} monitors the repository every minute to check for update. It should automatically pull the changes (and output "New session" in console).
\item \toolref{GnuRadio} is launched by \toolref{Autosession} automatically 2 minutes before session start (taken from data.json).
\item Autosession monitors the repository every minute to check for update. It should automatically pull the changes (and output "New session" in console).
\item \toolref{GnuRadio} is launched by Autosession automatically 2 minutes before session start (taken from data.json).
\item At ths point is possible to launch \toolref{Uplink Console}.
\item After session ends, \toolref{Autosession} closes \toolref{GnuRadio}.
\item Instance of \toolref{Autosession} that's running on primary GS will now summarize the session: download all frames from radio.pw-sat.pl, extract beacons, file lists, and run summary.py if available (which is used to decode experiment data and photos automatically). After that all artifacts are pushed to \toolref{Mission Repository} and telemetry is uploaded to \toolref{Grafana}.
\item After session ends, Autosession closes \toolref{GnuRadio}.
\item Instance of Autosession that's running on primary GS will now summarize the session: download all frames from radio.pw-sat.pl, extract beacons, file lists, and run summary.py if available (which is used to decode experiment data and photos automatically). After that all artifacts are pushed to \toolref{Mission Repository} and telemetry is uploaded to \toolref{Grafana}.
\end{enumerate}


2 changes: 1 addition & 1 deletion tools/grafana.tex
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
\tool{Grafana}

http://grafana.pw-sat.pl:3000/
Grafana contains all telemetry information gathered throughout the mission, accessible through visual dashboards. Access it via http://grafana.pw-sat.pl:3000/.
1 change: 1 addition & 0 deletions tools/tools-overview.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This section discusses tools available on ground stations. To use them, connect to ground station either by SSH (if console is enough) or VNC (if access to UI is needed).