ich hatte vor einiger Zeit schonmal gefragt:
https://forum.archlinux.de/d/34084-aktiver-bildschirmhintergrund
Von GerBra kam der Tip "xplanet".
Das habe ich gut studiert, habe auch allerhand sonst probiert und bin schließlich bei "XPaint" gelandet. Orientiert habe ich mich an der original batch.c des installierten XPaint: /usr/share/xpaint/c_scripts/batch/batch.c
Inzwischen geht einiges, zwei getrennte Dateien, dieses kleine Skript:
#!/bin/bash
position () {
curl -s https://api.wheretheiss.at/v1/satellites/25544 | \
jq -r '[.longitude, .latitude, .timestamp] | @tsv' \
> /<home>/worldmap/pos_ISS.txt; \
}
cp /<home>/worldmap/worldmap.png /<home>/worldmap/image.png
xpaint -blind /<home>/worldmap/batch.c &
Pause=5
Repeats=10
i=0
# while [ "$i" -le "$Repeats" ]
while true
do
let "i=$i+1"
echo "i: = $i"
position
sleep $Pause
pcmanfm -w /<home>/worldmap/image.png
done
# rm /<home>/worldmap/pos_ISS.txt
# rm /<home>/worldmap/image.png
# pcmanfm -w /<home>/worldmap/worldmap.png
exit 0
und auf XPaint basierender C-Code:
/* Xpaint-image */
#include <Xpaint.h>
#include <stdio.h>
Image * ImageCreate()
{
Image * img_ptr;
img_ptr = ImageFromFile("/<home>/worldmap/image.png");
if (!img_ptr) {
printf("Fehler: !img_ptr\n");
return NULL;
}
int nbr_col = img_ptr->width;
int nbr_row = img_ptr->height;
FILE *fp;
unsigned char *ip;
const int Repeats=10;
int counter=0;
// while (counter < Repeats) {
while (1) {
counter++;
printf ("counter: %d\n", counter);
double lon, lat;
int time, oldtime;
do {
sleep(1);
// printf ("old: lon, lat, time: %lf %lf %d\n", lon, lat, time);
fp = fopen("/<home>/worldmap/pos_ISS.txt", "r");
fscanf (fp, "%lf %lf %d", &lon, &lat, &time);
fclose(fp);
} while (time == oldtime);
// printf ("new: lon, lat, time: %lf %lf %d\n", lon, lat, time);
oldtime = time;
double co, ro;
int col, row;
co = nbr_col*(180+lon)/360;
col = (int) co;
ro = nbr_row*(90-lat)/180;
row = (int) ro;
if (col < 0 || col >= nbr_col || row < 0 || row >= nbr_row) {
printf("Punkt außerhalb!\n");
sleep(3);
continue;
}
ip = ImagePixel(img_ptr, col, row);
ip[0]=0; ip[1]=255; ip[2]=0;
// ip[0]=255; ip[1]=0; ip[2]=0;
WritePNGn("/<home>/worldmap/image.png", img_ptr);
sleep(3);
}
exit(0);
return img_ptr;
}
// double lon, lat; geogr. Länge, Breite
// co = nbr_col*(180+lon)/360; Mathe: col/nbr_col = (180+lon)/360
// ro = nbr_row*(90-lat)/180; Mathe: row/nbr_row = (90-lat)/180
// ip[0]=0; ip[1]=255; ip[2]=0; grün
// ip[0]=255; ip[1]=0; ip[2]=0; rot
Starten tue ich in der Konsole:
/<home>/worldmap/skript.sh
oder per Eintrag in die Autostart-Datei des LXDE:
/<home>/.config/lxsession/LXDE/autostart
Das Programm anhalten tue ich gar nicht oder je nach Startmodus per "Strg-c" oder "kill PID".
Für Testzwecke sind Zähler in beiden Dateien, die das Programm entsprechend stoppen (dazu neu kompilieren, xPaint erwartet gcc).
Abhängigkeiten des Programms sind XPaint (aus dem AUR), PCManFM (Dateimanager) und jq (JSON-Parser).
Erwartet wird ferner eine Grafikdatei (die Weltkarte): /<home>/worldmap/worldmap.png
Die beiden Programme laufen getrennt voneinander (haben getrennte PID), agieren aber Hand in Hand:
Der Benutzer startet das Skript
das Skript startet xPaint mit angeflanschter batch.c
- besorgt sich Online die ISS-Position
- schreibt die in eine Textdatei
- aus der das C-Programm die Position wieder rausholt
- und damit die Weltkarte aktualisiert (farbiger Punkt an die ISS-Position)
- aus welcher wiederum das Skript den Bildschirmhintergrund neu generiert.
(blassgrüne ISS auf blassblauer Erde - eher unauffällig)
Alle 5 Sekunden passiert das neu.
In der Realität fliegt die ISS in der Zeit 40 Kilometer, auf dem 1.400 px breiten Monitor ist das gerade ein Pixel.
Bedenken hatte ich wegen der Effizienz: Bei jedem 5-Sekunden-Takt wird der Bildschirmhintergrund komplett neu generiert, wo ich doch eigentlich nur einen einzigen Pixel ändern will...
Das Skript holt die ISS-Position und gibt die weiter an xPaint - der Umweg über die Textdatei gefällt mir wenig...
Dem Rechner scheint das alles nichts auszumachen (Standard-Tischrechner, der vor Jahren halbwegs modern war), der Lastmonitor zeigt an CPU-Last 0 beim Skript und maximal 1 Prozent bei xPaint.
Stabilität... so gut ich kann, Problem war, daß Skript und xPaint sich nicht in die Quere kamen: das Skript hat die Regie, es gibt dem xPaint 5 Sekunden für den Rest.
Bedenken hatte ich wegen der geografischen Genauigkeit.
Inspiriert hatte mich der Astroviewer: www.astroviewer.net/iss/de
Der zeigt die ISS im Browser, sodaß ich gut vergleichen kann, und ich sehe: Rein optisch stimmen beide Darstellungen gut überein.
...wobei Abweichungen durchaus zu erwarten wären, denn damit die reale ISS den richtigen Pixel auf dem Monitor bekommt, muß die Transformation:
geogr. Länge/Breite ==> horizontal-/vertikal-Pixel auf dem Monitor
korrekt sein.
Diese Transformation mache ich auf die mathematisch einfachst mögliche Weise, linear.
Kartografisch läuft das auf eine Art Mercator-Projektion hinaus, wie man sie aus alten Schulatlanten vielleicht kennt und bei der die Polarregionen extrem verzerrt sind.
Eine dazu passende Weltkarte fand ich bei der NASA:
https://visibleearth.nasa.gov/images/147190/explorer-base-map
Der Astroviewer nutzt die Weltkarte von OpenStreetMap, die auch aussieht wie eine Mercatorprojektion, Ok.
Dies noch: Zur ISS würde ich die "Tiangong" der Chinesen gern noch dazutun, aber deren Positionsdaten finde ich nicht...
Und schließlich: Die Online-Positionsdaten der ISS sind gelegentlich korrupt oder fehlen ganz.
Im Programm habe ich das nicht abgefangen.
Die Folge ist, daß die ISS dann abstürzt, und zwar im Golf von Guinea... (man muß genau hinsehen, evtl. Farbe wechseln).
Warum im Golf von Guinea? - dort ist der Nabel der Welt...