App Entwicklungsanleitung und Beispielapp hinzugefügt

This commit is contained in:
Andreas Völker 2018-12-30 14:34:18 +01:00
parent 591ab2be0c
commit 1c78390fb2
5 changed files with 213 additions and 0 deletions

58
apps/example.py Executable file
View File

@ -0,0 +1,58 @@
#!/usr/bin/env python3
import os
import sys
import random
import time
# Groesse des Bildschirms bestimmen
Nx = int(sys.argv[1])
Ny = int(sys.argv[2])
# Bestimme den Parameter
time_ms = 100
try:
time_ms = int(sys.argv[3])
except:
pass
# Puffer fuer Pixel erstellen und mit 0 initialisieren
buffer = bytearray(b"\x00" * (3 * Nx * Ny))
curPixel = 0
while True:
# Zufaellige Pixel waeheln
# rot
x_r = random.randint(0, Nx-1)
y_r = random.randint(0, Ny-1)
i_r = 3*(x_r+Nx*y_r)
# gruen
x_g = random.randint(0, Nx-1)
y_g = random.randint(0, Ny-1)
i_g = 3*(x_g+Nx*y_g)
# blau
x_b = random.randint(0, Nx-1)
y_b = random.randint(0, Ny-1)
i_b = 3*(x_b+Nx*y_b)
# Pixel in Puffer schreiben
# rot
buffer[i_r+0] = 0xff # Rotanteil
buffer[i_r+1] = 0x00 # Gruenanteil
buffer[i_r+2] = 0x00 # Blauanteil
# gruen
buffer[i_g+0] = 0x00 # Rotanteil
buffer[i_g+1] = 0xff # Gruenanteil
buffer[i_g+2] = 0x00 # Blauanteil
# blau
buffer[i_b+0] = 0x00 # Rotanteil
buffer[i_b+1] = 0x00 # Gruenanteil
buffer[i_b+2] = 0xff # Blauanteil
# Zeige den Puffer an
os.write(1, buffer)
# warte time_ms ms
time.sleep(time_ms*0.001)

View File

@ -26,6 +26,7 @@ Apps = [
{"guiname": "YoutubeDL", "name": "youtubedl", "cmd": "apps/youtubedl.sh", "persistent": False},
{"guiname": "Show Framebuffer", "name": "fbcp", "cmd": ["apps/fbcp", "/dev/fb0"]},
{"guiname": "Strobo", "name": "strobo", "cmd": "apps/strobo.py"},
{"guiname": "Beispiel", "name": "example", "cmd": "apps/example.py"},
#{"guiname": "Colored noise", "name": "cnoise", "cmd": "apps/cnoise", "persistent": False},

BIN
doku/app-development.pdf Normal file

Binary file not shown.

153
doku/app-development.tex Normal file
View File

@ -0,0 +1,153 @@
\documentclass[a5paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{ngerman}
\usepackage{graphicx}
\usepackage{hyperref}
\usepackage{listings}
\usepackage{parskip}
\setlength{\parindent}{0pt}
\title{App Entwicklungsanleitung}
\author{Andreas}
\begin{document}
\maketitle
\tableofcontents
\newpage
\section{Allgemeines}
Apps für den Pixelserver sind normale Konsolenanwendungen. Sie werden vom Pixelserver gestartet und generieren dann Bilder. Diese geben sie über die Standardausgabe aus und der Pixelserver zeigt sie dann an. Dies erlaubt es Apps in quasi allen Programmiersprachen zu entwickeln. Wenn der Nutzer eine App startet wird das entsprechende Programm ausgeführt und es wird vom Pixelserver beendet, wenn der Nutzer eine andere App auswählt. Hierbei kann Apps vom Nutzer ein zusätzlicher freier Parameter übergeben werden.
\subsection{Persistente Apps}
Einzelne Apps können auch als persistent markiert werden. Das heißt sie laufen dann auch im Hintergrund weiter, wenn der User eine andere App auswählt. Sie können auch keine Parameter übernehmen. Diese persistenten Apps sollten nur verwendet werden, wenn es für die Funktionalität \textbf{zwingend} notwendig ist.
\subsection{Konfiguration}
Damit der Pixelserver Apps kennt müssen sich in der \textit{config.py} eingetragen werden. In der Variable \textit{Apps} befindet sich eine Liste der Apps. Jede hat das folgende Format:
\begin{lstlisting}[frame=single, basicstyle=\small]
{"guiname": "<Name fuer Nutzer>",
"name": "<Kennung fuer API>",
"cmd": "<Pfad zur ausfuehrbaren Datei>"},
\end{lstlisting}
Üblicherweise sollten die Apps im Verzeichnis \textit{apps/} liegen.
\textbf{Beispiel:}
\begin{lstlisting}[frame=single, basicstyle=\small]
{"guiname": "Pong",
"name": "pong",
"cmd": "apps/pong.py"},
\end{lstlisting}
\section{Parameter}
An die ausgeführte Anwendung werden immer drei Parameter übergeben:
\begin{itemize}
\item \textbf{1} (Breite): Die Breite des Bildschirms in Pixeln. Im folgenden $N_x$
\item \textbf{2} (Höhe): Die Höhe des Bildschirms in Pixeln. Im folgenden $N_y$
\item \textbf{3} (Parameter): Ein von der App frei nutzbarer Parameter. Persistente Apps müssen für korrekte Funktionalität ignorieren.
\end{itemize}
\section{Bildausgabe}
Ein Bild besteht aus $N_x\cdot N_y$ Pixeln. Jeder Pixel besteht aus den Farben \textit{Rot}, \textit{Grün} und \textit{Blau}. Jede Farbe wird als ein Byte dargestellt, wobei $0$ minimaler Intensität und $255$ maximaler Intensität entspricht.
Für ein Bild müssen die Pixel Zeilenweise mit der Pixelreinfolge Rot, Grün, Blau auf die Standardausgabe geschrieben werden. Dieses muss in einem einzigen Schreibbefehl ausgegeben werden.
Der Index $i_{Farbe}$ des Pixels $x$ in der Breite und $y$ in der Höhe ergibt sich wie folgt:
\begin{align*}
i_{rot} &= 3\cdot(x+N_x\cdot y)+0\\
i_{gruen} &= 3\cdot(x+N_x\cdot y)+1\\
i_{blau} &= 3\cdot(x+N_x\cdot y)+2
\end{align*}
Hierbei werden $x \in \{0, 1, \dots, N_x-1\}$, $y \in \{0, 1, \dots, N_y-1\}$ und $i_{Farbe} \in \{0, 1, \dots, N_x\cdot N_y-1\}$ von $0$ an gezählt.
Wenn eine App einige Sekunden (Standardeinstellung: 40 Sekunden) kein Bild ausgibt, wird sie vom Pixelserver als abgestürzt betrachtet und beendet.
\section{setup-apps.sh}
Um die Apps zu installieren/kompilieren sollte der User vor dem ersten Start des Pixelservers das Skript \textit{setup-apps.sh} aufrufen. Somit sollte der Entwickler einer App hier seine App eintragen, damit sie korrekt gebaut wird. Für einige Sprachen sind schon Schema in der \textit{setup-apps.sh} hierfür vorgesehen.
\subsection{Skriptsprachen}
Für Skriptsprachen sollten die Skripte im Allgemeinen ausführbare gemacht werden und es sollte eine Zeile der Form:
\begin{lstlisting}[frame=single, basicstyle=\small]
chmod +x apps/newapp.py
\end{lstlisting}
hinzugefügt werden.
\subsection{C/C++}
Apps in C und C++ liegen in \textit{apps/c-src} und werden mit CMake kompiliert. Sie sollten zu der entsprechenden \textit{apps/c-src/CMakeLists.txt} hinzugefügt werden.
Es werden dann im Verzeichnis \textit{build/c} gebaut und sollten mit einer Zeile der Form
\begin{lstlisting}[frame=single, basicstyle=\small]
mv build/c/nywapp apps/
\end{lstlisting}
in der \textit{setup-apps.sh} an den richtigen Ort kopiert werden.
\section{Python App Beispiel}
Hier betrachten wir eine Beispielapp in Python die zufällige Pixel nacheinander Rot, Grün oder Blau macht. Die Geschwindigkeit des Setzens der Pixel soll hier über den Parameter (in Millisekunden) eingestellt werden.
Dazu wird in \textit{apps/example.py} folgende Datei angelegt
\begin{lstlisting}[frame=single, basicstyle=\small]
#!/usr/bin/env python3
import os
import sys
import random
import time
# Groesse des Bildschirms bestimmen
Nx = int(sys.argv[1])
Ny = int(sys.argv[2])
# Bestimme den Parameter
time_ms = 100
try:
time_ms = int(sys.argv[3])
except:
pass
# Puffer fuer Pixel erstellen und mit 0 initialisieren
buffer = bytearray(b"\x00" * (3 * Nx * Ny))
curPixel = 0
while True:
# Zufaellige Pixel waeheln
# rot
x_r = random.randint(0, Nx-1)
y_r = random.randint(0, Ny-1)
i_r = 3*(x_r+Nx*y_r)
# gruen
x_g = random.randint(0, Nx-1)
y_g = random.randint(0, Ny-1)
i_g = 3*(x_g+Nx*y_g)
# blau
x_b = random.randint(0, Nx-1)
y_b = random.randint(0, Ny-1)
i_b = 3*(x_b+Nx*y_b)
# Pixel in Puffer schreiben
# rot
buffer[i_r+0] = 0xff # Rotanteil
buffer[i_r+1] = 0x00 # Gruenanteil
buffer[i_r+2] = 0x00 # Blauanteil
# gruen
buffer[i_g+0] = 0x00 # Rotanteil
buffer[i_g+1] = 0xff # Gruenanteil
buffer[i_g+2] = 0x00 # Blauanteil
# blau
buffer[i_b+0] = 0x00 # Rotanteil
buffer[i_b+1] = 0x00 # Gruenanteil
buffer[i_b+2] = 0xff # Blauanteil
# Zeige den Puffer an
os.write(1, buffer)
# warte time_ms ms
time.sleep(time_ms*0.001)
\end{lstlisting}
In \textit{config.py} wird folgendes zu den \textit{Apps} hinzugefügt:
\begin{lstlisting}[frame=single, basicstyle=\small]
{"guiname": "Beispiel",
"name": "example",
"cmd": "apps/example.py"},
\end{lstlisting}
Zuletzt wird zur \textit{setup-apps.sh}
\begin{lstlisting}[frame=single, basicstyle=\small]
chmod +x apps/example.py
\end{lstlisting}
hinzugefügt und die App ist einsatzbereit.
\end{document}

View File

@ -5,6 +5,7 @@
chmod +x apps/pong.py
chmod +x apps/swifthohenberg.py
chmod +x apps/strobo.py
chmod +x apps/example.py
chmod +x apps/youtubedl.sh