diff --git a/api/api-overview.tex b/api/api-overview.tex new file mode 100644 index 0000000..c2f41ce --- /dev/null +++ b/api/api-overview.tex @@ -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://:7001} \\ + Transmit uplink frame & \texttt{tcp://: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. \ No newline at end of file diff --git a/api/downlink.tex b/api/downlink.tex new file mode 100644 index 0000000..54ae31c --- /dev/null +++ b/api/downlink.tex @@ -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://: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} \ No newline at end of file diff --git a/api/uplink.tex b/api/uplink.tex new file mode 100644 index 0000000..77e4581 --- /dev/null +++ b/api/uplink.tex @@ -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://: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} \ No newline at end of file diff --git a/main.tex b/main.tex index 9338584..3bf63dd 100644 --- a/main.tex +++ b/main.tex @@ -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} diff --git a/overview/basic-information.tex b/overview/basic-information.tex index e707ed4..29afa20 100644 --- a/overview/basic-information.tex +++ b/overview/basic-information.tex @@ -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} \ No newline at end of file diff --git a/overview/operations.tex b/overview/operations.tex index 2a33ee0..cd99d6d 100644 --- a/overview/operations.tex +++ b/overview/operations.tex @@ -32,7 +32,7 @@ \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} @@ -40,11 +40,11 @@ \subsection{Steps for each session} \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} diff --git a/tools/grafana.tex b/tools/grafana.tex index fb69f31..e3b4e90 100644 --- a/tools/grafana.tex +++ b/tools/grafana.tex @@ -1,3 +1,3 @@ \tool{Grafana} -http://grafana.pw-sat.pl:3000/ \ No newline at end of file +Grafana contains all telemetry information gathered throughout the mission, accessible through visual dashboards. Access it via http://grafana.pw-sat.pl:3000/. \ No newline at end of file diff --git a/tools/tools-overview.tex b/tools/tools-overview.tex new file mode 100644 index 0000000..9085e96 --- /dev/null +++ b/tools/tools-overview.tex @@ -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). \ No newline at end of file