2017-11-21 12 views
0

Kurzbeschreibung:Raspberry Pi - Autostart OpenCV-Script - Fehler mit cv :: imshow()

Ich will Auto-Start eine ausführbare Datei (opencv Binärdatei, erzeugen über C++) über eine systemd service- Skript nach dem Booten, aber ich bin nicht erfolgreich.

Ich habe den Fehler auf die Code-Anweisung "cv :: imshow (....)" eingegrenzt, die ein Fenster öffnet und ein Bild anzeigt. An dieser Stelle gibt der Code den Fehler: "QXcbConnection: Konnte keine Verbindung zur Anzeige herstellen"

Wenn ich jedoch manuell das SH-Skript oder die Binärdatei ausführen, funktionieren beide gut. Ich habe stackoverflow nach den häufigsten Fehlern gesucht und versucht, alles zu beheben, was ich finden konnte. Ich bin ziemlich sicher, dass:

  1. Meine Service-Datei beim Start tatsächlich läuft (bis der Fehler aufgetreten ist)
  2. manuell Ausführung der Binärdatei funktioniert
  3. manuell Ausführung des .sh-Skript funktioniert gut
  4. ich habe keine Laufzeit-Verknüpfung Fehler

ich würde schätzen jede Hilfe (.sh-Skript sehen). Bitte helfen Sie mir, den Fehler zu beheben und erklären Sie mir bitte, warum dieser Fehler überhaupt auftritt. Vielen Dank :)

.

Mein System:

Machine: Raspberry Pi 3 Model B 
Architecture: arm32/ARMv7 
OS: NOOBS 

.

Mein Skript in/etc/systemd/system/(test.service):

sudo chmod u+rwx /etc/systemd/system/test.service 

sudo systemctl enable test 

Und wenn ich den Start:

[Unit] 
Description=lalala 

[Service] 
Type=oneshot 
ExecStart=/bin/bash "/home/pi/Desktop/test.sh" start 
ExecStop=/bin/bash "/home/pi/Desktop/test.sh" stop 
RemainAfterExit=yes 

[Install] 
WantedBy=multi-user.target 

Außerdem habe ich die folgenden Befehle ausführen haben Service wird manuell mit der gleichen Fehlerausgabe wie beim Autostart während des Startvorgangs ausgeführt:

sudo systemctl enable test 

.

Mein Shell-Skript (test.sh):

#!/bin/sh -e 

exec 2> /tmp/test.sh.log  # send stderr to a log file 
exec 1>&2      # send stdout to the same log file 
set -x       # tell sh to display commands before execution 


echo "in script" 


start() 
{ 
    echo "in start" 

    sleep 30 

    LD_LIBRARY_PATH=/usr/local/OpenCV/lib:/usr/local/SFML/lib:/usr/local/curl/lib:$LD_LIBRARY_PATH 
    export LD_LIBRARY_PATH 

    /home/pi/Desktop/test/main -e & 
} 


# THE OTHER CASES, NOT PUT IN HERE (stop, status) 


case "$1" in 
    start) 
     start 
     ;; 
    stop) 
     stop 
     ;; 
    status) 
     status 
     ;; 
    restart) 
     stop 
     start 
     ;; 
    *) 
     echo "Usage: {start|stop|status|restart}" 
     exit 1 
     ;; 
esac 

exit 0 

.

Minimal Beispiel meiner Quellcode: (ausführbare)

#include <opencv2/opencv.hpp> 
#include <opencv2/core.hpp> 
#include <opencv2/highgui.hpp> 
#include <opencv2/imgproc/imgproc.hpp> 

int main() 
{ 
    cv::Mat frame; 
    cv::namedWindow("result", cv::WINDOW_NORMAL); 

    ## CRASH 

    return 0; 
} 

.

P. S:

Ich bin mir bewusst, dass es ein ähnlicher Thread wie dieser ist (Run OpenCV script on start with imshow).Aber da es für diese Frage keine Lösung gibt und ich mehr Informationen zu teilen habe, dachte ich, es wäre angemessener, einen neuen Thread zu starten.

+1

_Stack Überlauf ist eine Frage-Antwort-Website für professionelle und enthusiastische Programmierer. Vielleicht möchten Sie https://raspberrypi.stackexchange.com oder https://serverfault.com/. –

+0

Ich denke, dass Sie eine Antwort oder einen Workaround mit mehr Details in den Seiten bekommen können, die @JamesBrown geben. Die Frage, die Sie sich stellen können, ist: Wie wird der Computer einen GUI-Befehl von einem Terminal interpretieren? Wahrscheinlich ist es möglich, es an ein Setup "Display" oder etwas ähnliches zu übergeben, aber es ist eher eine Konfiguration (des PC/Rasberry Pi) -Problems als ein Programmierproblem. Im Allgemeinen, wenn das Programm ab und zu im Hintergrund läuft, sollte es keine GUI haben, nur ein Log in einer Datei. – api55

+1

Bitte lesen Sie meine Kommentare hier ... https://stackoverflow.com/q/47090354/2836621 –

Antwort

1

Glücklicherweise löste ich das Problem:

Das Problem war in der Konfiguration meiner Service-Skripts. Ich wusste, dass ich eine DISPLAY-Variable an den Ort der X-Anzeige brauche, aber mir war nicht bewusst, dass es auch eine Autorisierung benötigt. Dieser Thread hat mir geholfen, es herauszufinden:

https://unix.stackexchange.com/questions/85244/setting-display-in-systemd-service-file

Kurz:

diese Zeilen hinzufügen test.service in/etc/Service/Service:

Environment=XAUTHORITY=/home/pi/.Xauthority 
Environment=DISPLAY=:0.0