Prozess ID mittels Pythonscript beenden

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Zappelmann
User
Beiträge: 27
Registriert: Freitag 23. Mai 2014, 11:01

Hallo Zusammen,

Ich öffne mit einem Pythonscript ein TCP Socket Server, um über eine App Befehle von Handy aus an das Script per WLAN zu senden, die dann ausgeführt werden.
Unter anderen starte ich dazu mit einem Befehl (autonom) innerhalb des Scriptes ein weiteres Pythonscript. Leider hab ich bisher keine Möglichkeit gefunden dieses Script dann auch über einen weiteren Befehl innerhalb der Python Datei worüber alles ausgeführt wird, auch wieder zu beenden. Eventuell weis hier jemand Rat dazu.
Ich hatte dazu die Idee, die mit dem Befehl gestartete Python Datei, deren Prozess PID auszulesen und in einer Variable zu schreiben. Die dann von einer Funktion ausgelesen werden kann, um in der Funktion dann die mit Hilfe eines Befehls was vom Handy aus kommt, das Script zu beenden.

Also ich benötige ein Beispiel wie ich innerhalb des unten aufgeführten Scriptes, die entsprechende Prozess ID von dem gestarteten Pythonscript auslesen und in eine Variable schreiben kann, damit diese dann in einer anderen Funktion dann ausgelesen und durch den Aufruf dieser Funktion dann die PID beendet wird.

also eine Funktion um eine Prozess ID zu beenden und eine Funktion um dieser überhaupt auszulesen und in eine Variable einer anderen Funktion zu schreiben.

Ich hoffe das es jetzt nicht allzuwirr von mir beschrieben wurde.
Aber über ein sauberes Beispiel, wie man es lösen kann wäre ich sehr dankbar.



Code: Alles auswählen

import asyncore
import socket
import select
import RPi.GPIO as GPIO
import serial
import time
import os
#Initial GPIO-setup
GPIO.setwarnings(False)
#GPIO.cleanup()
# to use Raspberry Pi board pin numbers
GPIO.setmode(GPIO.BOARD)
GPIO.setup(19,GPIO.OUT)
GPIO.setup(7,GPIO.OUT)
GPIO.setup(22,GPIO.OUT)
GPIO.setup(11,GPIO.OUT)
def ControlAPairOfPins(FirstPin,FirstState,SecondPin,SecondState):
    if FirstState == "1":
        GPIO.output(int(FirstPin),True)
    else:
        GPIO.output(int(FirstPin),False)
    if SecondState == "1":
        GPIO.output(int(SecondPin),True)
    else:
        GPIO.output(int(SecondPin),False)
    return
def Stop():
    ControlAPairOfPins("19","0","7","0")
    ControlAPairOfPins("22","0","11","0")
def Vorwaerts_fahren():
    ControlAPairOfPins("19","1","7","0")
    ControlAPairOfPins("22","1","11","1")
def Rechts_fahren_voll():
    ControlAPairOfPins("19","1","7","1")
    ControlAPairOfPins("22","1","11","1")
def Links_fahren_voll():
    ControlAPairOfPins("19","1","7","0")
    ControlAPairOfPins("22","0","11","1")
def Rueckwaerts_fahren():
    ControlAPairOfPins("19","1","7","1")
    ControlAPairOfPins("22","0","11","1")
def Autonom():
    sudo python autonom.py()    #die Funktion hier ist jetzt leider nicht vollständig, da ich gerade kein zugriff auf das Script habe, was zu hause auf dem Raspi liegt. Ich werde es später korrigieren.

class Client(asyncore.dispatcher_with_send):
    def __init__(self, socket=None, pollster=None):
        asyncore.dispatcher_with_send.__init__(self, socket)
        self.data = ''
        if pollster:
            self.pollster = pollster
            pollster.register(self, select.EPOLLIN)
    def handle_close(self):
        if self.pollster:
            self.pollster.unregister(self)
    def handle_read(self):
        receivedData = self.recv(8192)
        if not receivedData:
            self.close()
            return
        receivedData = self.data + receivedData
        while '\n' in receivedData:
            line, receivedData = receivedData.split('\n',1)
            self.handle_command(line)
        self.data = receivedData
    def handle_command(self, line):
        if line=="forward start":
            Vorwaerts_fahren()
            self.send('ok\n')
        elif line=="forward stop":
           Stop()
            self.send('ok\n')
        if line=="forward left":
            Links_fahren_voll()
            self.send('ok\n')
        elif line=="forward stop":
            Stop()
            self.send('ok\n')
        if line=="forward right":
            Rechts_fahren_voll()
            self.send('ok\n')
        elif line=="forward stop":
            Stop()
            self.send('ok\n')
        if line=="backward start":
            Rueckwaerts_fahren()
            self.send('ok\n')
        elif line=="backward stop":
            Stop()
            self.send('ok\n')
        if line=="autonom":
            Autonom()
            self.send('ok\n')
        else:
            self.send('unknown command\n')
            print 'command:', line
class Server(asyncore.dispatcher):
    def __init__(self, listen_to, pollster):
        asyncore.dispatcher.__init__(self)
        self.pollster = pollster
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        self.bind(listen_to)
        self.listen(5)
    def handle_accept(self):
        newSocket, address = self.accept()
        print "Connected from", address
        Client(newSocket,self.pollster)
def readwrite(obj, flags):
    try:
        if flags & select.EPOLLIN:
            obj.handle_read_event()
        if flags & select.EPOLLOUT:
            obj.handle_write_event()
        if flags & select.EPOLLPRI:
            obj.handle_expt_event()
        if flags & (select.EPOLLHUP | select.EPOLLERR | select.POLLNVAL):
            obj.handle_close()
    except socket.error, e:
        if e.args[0] not in asyncore._DISCONNECTED:
            obj.handle_error()
        else:
            obj.handle_close()
    except asyncore._reraised_exceptions:
        raise
    except:
        obj.handle_error()
class EPoll(object):
    def __init__(self):
        self.epoll = select.epoll()
        self.fdmap = {}
    def register(self, obj, flags):
        fd = obj.fileno()
        self.epoll.register(fd, flags)
        self.fdmap[fd] = obj
    def unregister(self, obj):
        fd = obj.fileno()
        del self.fdmap[fd]
        self.epoll.unregister(fd)
    def poll(self):
        evt = self.epoll.poll()
        for fd, flags in evt:
            yield self.fdmap[fd], flags
if __name__ == "__main__":
    pollster = EPoll()
    pollster.register(Server(("",12340),pollster), select.EPOLLIN)
    while True:
        evt = pollster.poll()
        for obj, flags in evt:
            readwrite(obj, flags)


MFG

Zappelmann
Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

Für mich klingt das so als ob du os.fork nutzen willst.
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@Zappelmann: Externe Programme werden mit hilfe des subprocess-Moduls gestartet. Auf diesen Popen-Objekte gibt es auch eine kill-Methode.

Auf Modulebene sollte kein ausführbarer Code stehen, erst recht nicht zum Initialisieren von irgendwelcher Hardware. Du solltest alles in Funktionen packen. Warum rufst Du ControlAPairOfPins mit Strings auf, statt direkt mit den passenden Datentypen?, dann wäre die Funktion ein Zweizeiler. Das return ist überflüssig. handle_command macht wohl nicht das, was Du willst, mit einem Wörterbuch cmd->function würde die Funktion auch deutlich einfacher. Ein paar Leerzeilen hier und da wären nett.
Zappelmann
User
Beiträge: 27
Registriert: Freitag 23. Mai 2014, 11:01

darktrym hat geschrieben:Für mich klingt das so als ob du os.fork nutzen willst.

nachdem ich os.fork nachgelesen habe, würde ich dir sogar zustimmen.
Ich weis es ist nicht die elegante lösung aber da meine Programmierkenntnisse sehr rudimentär sind ist es leider auch etwas schwierig mich dort korrekt auszudrücken was ich eigentlich machen möchte.
Zappelmann
User
Beiträge: 27
Registriert: Freitag 23. Mai 2014, 11:01

Sirius3 hat geschrieben:@Zappelmann: Externe Programme werden mit hilfe des subprocess-Moduls gestartet. Auf diesen Popen-Objekte gibt es auch eine kill-Methode.

Auf Modulebene sollte kein ausführbarer Code stehen, erst recht nicht zum Initialisieren von irgendwelcher Hardware. Du solltest alles in Funktionen packen. Warum rufst Du ControlAPairOfPins mit Strings auf, statt direkt mit den passenden Datentypen?, dann wäre die Funktion ein Zweizeiler. Das return ist überflüssig. handle_command macht wohl nicht das, was Du willst, mit einem Wörterbuch cmd->function würde die Funktion auch deutlich einfacher. Ein paar Leerzeilen hier und da wären nett.
das mit dem subprocess hab ich z.B. mit dem Befehl (sudo reboot) so umgesetzt

Code: Alles auswählen

def restart():
    command = "/usr/bin/sudo /sbin/shutdown -r now"
    import subprocess
    process = subprocess.Popen(command.split(), stdout=subprocess.PIPE)
    output = process.communicate()[0]
    print output
im def handle_command hab ich dann die restart funktion so wie die anderen lines wo input übertragen wird mit eingebunden. Das funzt soweit.
Auch das aufrufen eines anderen Pythonscriptes funktioniert dort nur das sich das ganze irgendwann weghängt und nicht mehr reagiert geschweige denn die printausgabe des jeweiligen scriptes überhaupt nciht angezeigt wird.
na gut das soll erstmal egal sein.

Wenn ich das richtig verstehe ist ein Aufruf eines weiteren Python Scriptes was eigenständig als Process laufen soll mit mit subprocess zu realisieren ?
Warum rufst Du ControlAPairOfPins mit Strings auf, statt direkt mit den passenden Datentypen?
was ist daran verkehrt?
Ich muss 2 Motoren über ein Motortreiber die simulatan über unterschiedliche Pins laufen ansteuern.
Ich versteh eventuell deine Frage bezüglich der Datentypen nicht. Welche hätte ich denn deiner Ansicht nach besser nehmen sollen?
Ich mein immerhin funnktioniert es ja.

MFG

Zappelmann
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

darktrym hat geschrieben:Für mich klingt das so als ob du os.fork nutzen willst.
`os.fork()` ist sehr lowlevel. Man würde bevorzugt zu dem bereits angesprochenen `subprocess`-Modul greifen.
Zappelmann hat geschrieben:Unter anderen starte ich dazu mit einem Befehl (autonom) innerhalb des Scriptes ein weiteres Pythonscript.
Falls das andere Python-Programm wirklich als Skript und nicht als Modul ausgeführt werden soll, dann lautet das Schema oft:

Code: Alles auswählen

subprocess.call([sys.executable, 'dein_skript.py'])
Hinter `sys.executable` verbirgt sich die absolute Pfadangabe zum derzeit laufenden Python-Interpreter. Es wird dann also ein weiterer Interpreter als eigener Prozess aufgerufen, der entsprechend das Skript ausführt.
Zappelmann hat geschrieben:Leider hab ich bisher keine Möglichkeit gefunden dieses Script dann auch über einen weiteren Befehl innerhalb der Python Datei worüber alles ausgeführt wird, auch wieder zu beenden.
Dann besser `Popen()` und auf dem damit erzeugten Objekt dann bei Bedarf `.kill()`.
Zuletzt geändert von snafu am Freitag 12. Juni 2015, 15:37, insgesamt 1-mal geändert.
BlackJack

@Zappelmann: Du übergibst Zahlen als Zeichenketten wo man eben besser Zahlen verwendet hätte. Wieso verwendest Du dort Zeichenketten?
Zappelmann
User
Beiträge: 27
Registriert: Freitag 23. Mai 2014, 11:01

BlackJack hat geschrieben:@Zappelmann: Du übergibst Zahlen als Zeichenketten wo man eben besser Zahlen verwendet hätte. Wieso verwendest Du dort Zeichenketten?
wo genau im script meinst du ?
BlackJack

@Zappelmann: Ist Dein Name Programm? Also so ein rumzappler mit einer Aufmerksamkeitsspanne von einem Goldfisch? :twisted: Ich meine genau die selben Stellen die Sirius3 auch schon damit gemeint hat. Also da wo Du Zeichenketten übergibst nur um die dann umständlich in Zahlen und Wahrheitswerte umzuwandeln.
Zappelmann
User
Beiträge: 27
Registriert: Freitag 23. Mai 2014, 11:01

BlackJack hat geschrieben:@Zappelmann: Ist Dein Name Programm? Also so ein rumzappler mit einer Aufmerksamkeitsspanne von einem Goldfisch? :twisted: Ich meine genau die selben Stellen die Sirius3 auch schon damit gemeint hat. Also da wo Du Zeichenketten übergibst nur um die dann umständlich in Zahlen und Wahrheitswerte umzuwandeln.
meinst du hier ?

Code: Alles auswählen

def ControlAPairOfPins(FirstPin,FirstState,SecondPin,SecondState):
    if FirstState == "1":
        GPIO.output(int(FirstPin),True)
    else:
        GPIO.output(int(FirstPin),False)
    if SecondState == "1":
        GPIO.output(int(SecondPin),True)
    else:
        GPIO.output(int(SecondPin),False)
    return

def Stop():
    ControlAPairOfPins("19","0","7","0")
    ControlAPairOfPins("22","0","11","0")
??
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Ja genau, folgendes ist (wie es momentan benutzt wird) aequivalent:

Code: Alles auswählen

def control_pin_pair(pin1, state1, pin2, state2):
    GPIO.output(pin1, state1)
    GPIO.output(pin2, state2)

def stop():
    control_pin_pair(19, False, 7, False)
    control_pin_pair(22, False, 11, False)

# oder gleich ohne die Funktion
def stop2():
    pins = [19, 7, 22, 11]
    for pin in pins:
        GPIO.output(pin, False)
Zappelmann
User
Beiträge: 27
Registriert: Freitag 23. Mai 2014, 11:01

sorry musste eben weg....

ja ok, hab jetzt den letzten Post mal eben drüber geschaut und gesehen das ihr ihn geändert habt. Fragt mich nicht warum ich das so geschrieben habe. Da ich selber kein Porgrammierer bin, habe ich einfach aus dem was ich in Python an Wissen in vier Monaten mir erlernt habe, es so programmiert sodas es mir logisch vorkam, sodas es funktioniert. Im Grunde ist dies sogar ein Teil des Scriptes was ich für mein Roboter entwickelt habe. Das eigentliche Hauptprogramm was viel größer ist, ist eventuell ähnlich confus von mir geschrieben. Da ihr aber so mir scheint viel mehr Erfahrung damit habt, was einen sauberen Code angeht, sind mir hier einige durchaus weit vorraus. Also bitte nicht wundern wenn ich dass eine oder andere nicht immer sofort verstehe.

Jedoch habe ich hier jetzt schon einige konstruktive Hilfestellungen, eben gelesen sodass ich mich gleich weiter damit beschäftigen werde.

Jedoch hab ich zu dem letzten Script eine Frage, was war denn an meinem Code verkehrt, anders ausgedrückt
war es inefficient oder ist es performencelastiger dadurch geworden ?
Ich mein, hier wurde geschrieben dass ich es umständlich umgebogen habe.
Wenn ich weis was dabei von Nachteil war, kann ich zumindest versuchen es in Zukunft zu vermeiden.

Denn tatsächlich ist es so, dass ich das eigentliche Hauptprogramm als eigenen Prozess aus der App heraus starten möchte. Dabei soll die autonome Funktion den Roboter Steuern.
Damit ich die Verbindung aber überhaupt aufbauen kann, benötige ich das oben eingestellte Script was natürlich nicht von mir stammt. Bis auf den Teil den ich für die Steuerung eingesetzt habe. Diese Serversocket Python Datei war ein Zusatz von der App um mit dem Raspi die Verbindung aufzubauen. Meine Absicht dahinter ist, dass ich über dieses Scipt das Python Hauptprogramm starten kann , dass die komplette Statusrückgabe in irgendeiner Konsolle dargestellt wird. Und dass ich das Script auch sauber aus der App wieder beenden kann, ohne das ich ein Reset des Roboters durchführen muss.

hier ist der aktuell Status des Serverscriptes, wenn ich die angeführten Beispiele von weiter oben richtig Verstanden habe, muss ich dann doch noch einiges ändern.

Code: Alles auswählen


import asyncore
import socket
import select
import RPi.GPIO as GPIO
import serial
import time
import os
#Initial GPIO-setup
GPIO.setwarnings(False)
#GPIO.cleanup()

GPIO.setmode(GPIO.BOARD)
GPIO.setup(19,GPIO.OUT)
GPIO.setup(7,GPIO.OUT)
GPIO.setup(22,GPIO.OUT)
GPIO.setup(11,GPIO.OUT)


class Client(asyncore.dispatcher_with_send):
    def __init__(self, socket=None, pollster=None):
        asyncore.dispatcher_with_send.__init__(self, socket)
        self.data = ''
        if pollster:
            self.pollster = pollster
            pollster.register(self, select.EPOLLIN)

    def handle_close(self):
        if self.pollster:
            self.pollster.unregister(self)

    def handle_read(self):
        receivedData = self.recv(8192)
        if not receivedData:
            self.close()
            return
        receivedData = self.data + receivedData
        while '\n' in receivedData:
            line, receivedData = receivedData.split('\n',1)
            self.handle_command(line)
        self.data = receivedData

    def handle_command(self, line):
        if line=="forward start":
            Vorwaerts_fahren()
            self.send('ok\n')
        elif line=="forward stop":
            Stop()
            self.send('ok\n')
        if line=="forward left":
            Links_fahren_voll()
            self.send('ok\n')
        elif line=="forward stop":
            Stop()
            self.send('ok\n')
        if line=="forward right":
            Rechts_fahren_voll()
            self.send('ok\n')
        elif line=="forward stop":
            Stop()
            self.send('ok\n')
        if line=="backward start":
            Rueckwaerts_fahren()
            self.send('ok\n')
        elif line=="backward stop":
            self.send('ok\n')
        elif line=="backward stop":
            Stop()
            self.send('ok\n')
        if line=="poweroff":
            shutdown()
            self.send('ok\n')
        elif line=="forward stop":
            Stop()
            self.send('ok\n')
        if line=="/usr/bin/sudo /sbin/shutdown -r now":
            restart()
            self.send('ok\n')
        elif line=="forward stop":
            Stop()
            self.send('ok\n')
        if line=="sudo python robot-umbau-3.py":
            autonom()
            self.send('ok\n')
        if line=="cd Downloads/raspirobotboard-master/examples":
            cd()
            self.send('ok\n')
        else:
            self.send('unknown command\n')
            print 'Unknown command:', line

def ControlAPairOfPins(FirstPin,FirstState,SecondPin,SecondState):
    if FirstState == "1":
        GPIO.output(int(FirstPin),True)
    else:
        GPIO.output(int(FirstPin),False)
    if SecondState == "1":
        GPIO.output(int(SecondPin),True)
    else:
        GPIO.output(int(SecondPin),False)
    return

def Stop():
    ControlAPairOfPins("19","0","7","0")
    ControlAPairOfPins("22","0","11","0")

def Vorwaerts_fahren():
    ControlAPairOfPins("19","1","7","0")
    ControlAPairOfPins("22","1","11","1")

def Rechts_fahren_voll():
    ControlAPairOfPins("19","1","7","1")
    ControlAPairOfPins("22","1","11","1")

def Links_fahren_voll():
    ControlAPairOfPins("19","1","7","0")
    ControlAPairOfPins("22","0","11","1")

def Rueckwaerts_fahren():
    ControlAPairOfPins("19","1","7","1")
    ControlAPairOfPins("22","0","11","1")

def shutdown():
    os.system("poweroff")

def restart():
    command = "/usr/bin/sudo /sbin/shutdown -r now"
    import subprocess
    process = subprocess.Popen(command.split(), stdout=subprocess.PIPE)
    output = process.communicate()[0]
    print output

def autonom():
    command = "sudo python robot-umbau-3.py"
    import subprocess
    process = subprocess.Popen(command.split(), stdout=subprocess.PIPE)
    output = process.communicate()[0]
    print output

def cd():
    command = "cd Downloads/raspirobotboard-master/examples"
    import subprocess
    process = subprocess.Popen(command.split(), stdout=subprocess.PIPE)
    output = process.communicate()[0]
    print output

def chaser():
    command = "sudo python led-chaser-small.py"
    import subprocess
    process = subprocess.Popen(command.split(), stdout=subprocess.PIPE)
    output = process.communicate()[0]
    print output


class Server(asyncore.dispatcher):
    def __init__(self, listen_to, pollster):
        asyncore.dispatcher.__init__(self)
        self.pollster = pollster
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        self.bind(listen_to)
        self.listen(5)

    def handle_accept(self):
        newSocket, address = self.accept()
        print "Connected from", address
        Client(newSocket,self.pollster)

def readwrite(obj, flags):
    try:
        if flags & select.EPOLLIN:
            obj.handle_read_event()
        if flags & select.EPOLLOUT:
            obj.handle_write_event()
        if flags & select.EPOLLPRI:
            obj.handle_expt_event()
        if flags & (select.EPOLLHUP | select.EPOLLERR | select.POLLNVAL):
            obj.handle_close()
    except socket.error, e:
        if e.args[0] not in asyncore._DISCONNECTED:
            obj.handle_error()
        else:
            obj.handle_close()
    except asyncore._reraised_exceptions:
        raise
    except:
        obj.handle_error()


class EPoll(object):
    def __init__(self):
        self.epoll = select.epoll()
        self.fdmap = {}
    def register(self, obj, flags):
        fd = obj.fileno()
        self.epoll.register(fd, flags)
        self.fdmap[fd] = obj
    def unregister(self, obj):
        fd = obj.fileno()
        del self.fdmap[fd]
        self.epoll.unregister(fd)
    def poll(self):
        evt = self.epoll.poll()
        for fd, flags in evt:
            yield self.fdmap[fd], flags
        for fd, flags in evt:
            yield self.fdmap[fd], flags


if __name__ == "__main__":
    pollster = EPoll()
    pollster.register(Server(("",12340),pollster), select.EPOLLIN)
    while True:
        evt = pollster.poll()
        for obj, flags in evt:
            readwrite(obj, flags)

Ich kann bei bedarf auch mal das Hauptprogramm hier einstellen.
Da ich Eure Hilfe hier schätze, freue ich mich natürlich auf weitere Vorschläge wie ich meine Anforderungen umsetzen kann.

MFG

Zappelmann

@BackJack mein Name stammt daher, weil ich in meinem Leben immer wieder lustige Begegnungen mit STROM hatte. :mrgreen:
Zappelmann
User
Beiträge: 27
Registriert: Freitag 23. Mai 2014, 11:01

So hier mal der Raspirobot Code
es laufen noch 2 weitere Script die aber im Moment für das Thema eine untergeordnete Rollen Spielen.
zum Einem ist es ein shutdown Script was auf ein Interrupt reagiert und zum anderen ist ein ein kleines LED lauflicht was über I²C lauft. Teile hier in den Script sind auch für I²C geschrieben. Das betrifft u.a. die Fahrzeugbeleuchtung.
Der Code läuft mit der Hardware einwandfrei und macht genau das was er soll.

Optimierungsvorschläge sind sehr willkommen.

Code: Alles auswählen


##!/usr/bin/python
##Raspobot Autonome Erkundung
from time import sleep
import time
import RPi.GPIO as GPIO
import smbus
from Adafruit_PWM_Servo_Driver import PWM

GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(19,GPIO.OUT)
GPIO.setup(7,GPIO.OUT)
GPIO.setup(22,GPIO.OUT)
GPIO.setup(11,GPIO.OUT)
GPIO.setup(18,GPIO.OUT)
GPIO.setup(12,GPIO.OUT)
GPIO.setup(16,GPIO.IN)
GPIO.setup(10,GPIO.IN)
GPIO.setup(26,GPIO.IN)
GPIO.setup(13,GPIO.IN)
GPIO.setup(24,GPIO.IN)
GPIO.setup(8,GPIO.IN)
Schalter = 21
LED = 23
pwm = PWM(0x40, debug=True)
servoMin = 150  # Min pulse length out of 4096
servoMax = 600  # Max pulse length out of 4096
servoMid = 375  # Mid pulse length out of 4096


BUSNR  = 1
ADDR   = 0x20
ADDR1  = 0x21
IODIRA = 0x00
IODIRB = 0x01
GPIOA  = 0x12
GPIOB  = 0x13

PINAA = [0x00]
PINA10 = [0x88] #Blinker_rechts
PINA11 = [0x60] #Brems_licht
PINA12 = [0x14] #Blinker_links
PINA13 = [0x06] #Rueck_licht
PINA14 = [0x03] #Front_licht
PINA15 = [0x03] #Rueck_licht

PINBA = [0x00]
PINB10 = [0x88] #Blinker_rechts
PINB11 = [0x60] #Brems_licht
PINB10 = [0x88] #Blinker_rechts
PINB11 = [0x60] #Brems_licht
PINB12 = [0x14] #Blinker_links
PINB13 = [0x06] #Rueck_licht
PINB14 = [0x03] #Front_licht

i2cBus = smbus.SMBus(BUSNR)
i2cBus.write_byte_data(ADDR, IODIRA, 0x00)
i2cBus.write_byte_data(ADDR, IODIRB, 0x01)
i2cBus.write_byte_data(ADDR1, IODIRA, 0x00)
i2cBus.write_byte_data(ADDR1, IODIRB, 0x01)

GPIO.setup(Schalter,GPIO.IN)
GPIO.setup(LED,GPIO.OUT)

DELAY = 1

print "Ultraschallmessung mit HC-SR04"

#A routine to control a pair of pins

def ControlAPairOfPins(FirstPin,FirstState,SecondPin,SecondState):
    if FirstState == "1":
        GPIO.output(int(FirstPin),True)
    else:
        GPIO.output(int(FirstPin),False)
    if SecondState == "1":
        GPIO.output(int(SecondPin),True)
    else:
        GPIO.output(int(SecondPin),False)
    return

def Stop():
    ControlAPairOfPins("19","0","7","0")
    ControlAPairOfPins("22","0","11","0")
    for leds in PINA11:
        i2cBus.write_byte_data(ADDR, GPIOA, leds)
        sleep(DELAY)
    for leds in PINAA:
        i2cBus.write_byte_data(ADDR, GPIOA, leds)

def Stop_anhalten_permanent():
    ControlAPairOfPins("19","0","7","0")
    ControlAPairOfPins("22","0","11","0")
    for leds in PINA11:
        i2cBus.write_byte_data(ADDR, GPIOA, leds)
        sleep(DELAY)
    for leds in PINAA:
        i2cBus.write_byte_data(ADDR, GPIOA, leds)

def Vorwaerts_fahren():
    for leds in PINA14:
        i2cBus.write_byte_data(ADDR, GPIOA, leds)
    ControlAPairOfPins("19","1","7","0")
    ControlAPairOfPins("22","1","11","1")

def Geradeaus_vorwaerts_start():
    for leds in PINA14:
        i2cBus.write_byte_data(ADDR, GPIOA, leds)
    ControlAPairOfPins("19","1","7","0")
    ControlAPairOfPins("22","1","11","1")

def Links_fahren():
    for leds in PINA12:
        i2cBus.write_byte_data(ADDR, GPIOA, leds)
    ControlAPairOfPins("19","0","7","0")
    ControlAPairOfPins("22","0","11","1")
    time.sleep(0.65)
    for leds in PINAA:
        i2cBus.write_byte_data(ADDR, GPIOA, leds)

def Links_fahren_voll():
    for leds in PINA12:
        i2cBus.write_byte_data(ADDR, GPIOA, leds)
    ControlAPairOfPins("19","1","7","0")
    ControlAPairOfPins("22","0","11","1")
    time.sleep(0.45)
    for leds in PINAA:
        i2cBus.write_byte_data(ADDR, GPIOA, leds)
        i2cBus.write_byte_data(ADDR, GPIOA, leds)

def Rechts_fahren():
    for leds in PINA10:
        i2cBus.write_byte_data(ADDR, GPIOA, leds)
    ControlAPairOfPins("19","1","7","1")
    ControlAPairOfPins("22","1","11","0")
    time.sleep(0.65)
    for leds in PINAA:
        i2cBus.write_byte_data(ADDR, GPIOA, leds)

def Rechts_fahren_voll():
    for leds in PINA10:
        i2cBus.write_byte_data(ADDR, GPIOA, leds)
    ControlAPairOfPins("19","1","7","1")
    ControlAPairOfPins("22","1","11","1")
    time.sleep(0.45)
    for leds in PINAA:
        i2cBus.write_byte_data(ADDR, GPIOA, leds)

def Rueckwaerts_fahren():
    for leds in PINA15:
        i2cBus.write_byte_data(ADDR1, GPIOA, leds)
    ControlAPairOfPins("19","1","7","1")
    ControlAPairOfPins("22","0","11","1")
    time.sleep(1.5)
    for leds in PINAA:
        i2cBus.write_byte_data(ADDR1, GPIOA, leds)

def Rueckwaerts_fahren_l():
    for leds in PINA15:
        i2cBus.write_byte_data(ADDR1, GPIOA, leds)
    ControlAPairOfPins("19","1","7","1")
    ControlAPairOfPins("22","0","11","1")
    time.sleep(0.5)
    for leds in PINAA:
        i2cBus.write_byte_data(ADDR1, GPIOA, leds)

def Rueckwaerts_fahren_r():
    for leds in PINA15:
        i2cBus.write_byte_data(ADDR1, GPIOA, leds)
    ControlAPairOfPins("19","1","7","1")
    ControlAPairOfPins("22","0","11","1")
    time.sleep(0.5)
    for leds in PINAA:
        i2cBus.write_byte_data(ADDR1, GPIOA, leds)

def setServoPulse(channel, pulse):
  pulseLength = 1000000                   # 1,000,000 us per second
  pulseLength /= 60                       # 60 Hz
  print "%d us per period" % pulseLength
  pulseLength /= 4096                     # 12 bits of resolution
  print "%d us per bit" % pulseLength
  pulse *= 1000
  pulse /= pulseLength
  pwm.setPWM(channel, 0, pulse)

pwm.setPWMFreq(60)

def Messung_permanent_vorn():
    GPIO.output(18, False)
    time.sleep(0.1)
    GPIO.output(18, True)
    time.sleep(0.00001)
    start = time.time()
    GPIO.output(18, False)
    while GPIO.input(13)==0:
        pass
    start = time.time()
    while GPIO.input(13)==1:
        pass
    stop = time.time()
    elapsed = stop-start
    global dist_vorn_perma
    dist_vorn_perma = elapsed * 17500
    print "Abstand_vorn: %.1f cm" % dist_vorn_perma

def Messung_permanent_links():
    GPIO.output(18, False)
    time.sleep(0.1)
    GPIO.output(18, False)
    time.sleep(0.1)
    GPIO.output(18, True)
    time.sleep(0.00001)
    start = time.time()
    GPIO.output(18, False)
    while GPIO.input(26)==0:
        pass
    start = time.time()
    while GPIO.input(26)==1:
        pass
    stop = time.time()
    elapsed = stop-start
    global dist_links_perma
    dist_links_perma = elapsed * 17000
    print "Abstand_links: %.1f cm" % dist_links_perma

def Messung_permanent_voll_links():
    GPIO.output(18, False)
    time.sleep(0.1)
    GPIO.output(18, True)
    time.sleep(0.00001)
    start = time.time()
    GPIO.output(18, False)
    while GPIO.input(10)==0:
        pass
    start = time.time()
    while GPIO.input(10)==1:
        pass
    stop = time.time()
    elapsed = stop-start
    global dist_links_voll_perma
    dist_links_voll_perma = elapsed * 17000
    print "Abstand_links_voll: %.1f cm" % dist_links_voll_perma

def Messung_permanent_rechts():
    GPIO.output(18, False)
    time.sleep(0.1)
    GPIO.output(18, True)
    time.sleep(0.00001)
    start = time.time()
    GPIO.output(18, False)
    while GPIO.input(24)==0:
        pass
    start = time.time()
    while GPIO.input(24)==1:
        pass
    stop = time.time()
    elapsed = stop-start
    global dist_rechts_perma
    dist_rechts_perma = elapsed * 17000
    print "Abstand_rechts: %.1f cm" % dist_rechts_perma

def Messung_permanent_voll_rechts():
    GPIO.output(18, False)
    time.sleep(0.1)
    GPIO.output(18, True)
    time.sleep(0.00001)
    start = time.time()
    GPIO.output(18, False)
    while GPIO.input(8)==0:
        pass
    start = time.time()
    while GPIO.input(8)==1:
        pass
    stop = time.time()
    elapsed = stop-start
    global dist_rechts_voll_perma
    dist_rechts_voll_perma = elapsed * 17000
    print "Abstand_rechts_voll: %.1f cm" % dist_rechts_voll_perma

def Messung_distance_vorn():
    GPIO.output(18, False)
    time.sleep(0.5)
    GPIO.output(18, True)
    time.sleep(0.00001)
    start = time.time()
    GPIO.output(18, False)
    while GPIO.input(16)==0:
        pass
    while GPIO.input(16)==0:
        pass
    start = time.time()
    while GPIO.input(16)==1:
        pass
    stop = time.time()
    elapsed = stop-start
    global distance
    distance = elapsed * 17500
    print "Abstand_vorn_servo: %.1f cm" % distance

def Messung_dist_links():
    GPIO.output(18, False)
    time.sleep(1)
    GPIO.output(18, True)
    time.sleep(0.00001)
    start = time.time()
    GPIO.output(18, False)
    while GPIO.input(16)==0:
        pass
    start = time.time()
    while GPIO.input(16)==1:
        pass
    stop = time.time()
    elapsed = stop-start
    global dist_links
    dist_links = elapsed * 17000
    print "Abstand_links_servo: %.1f cm" % dist_links

def Messung_dist_rechts():
    GPIO.output(18, False)
    time.sleep(1)
    GPIO.output(18, True)
    time.sleep(0.00001)
    start = time.time()
    GPIO.output(18, False)
    while GPIO.input(16)==0:
        pass
    start = time.time()
    while GPIO.input(16)==1:
        pass
    stop = time.time()
    elapsed = stop-start
    global dist_rechts
    dist_rechts = elapsed * 17000
    print "Abstand_rechts_servo: %.1f cm" % dist_rechts

def Error():
    Stop()
    GPIO.output(LED, 1)
    time.sleep(0.3)
    GPIO.output(LED, 0)
    time.sleep(0.3)

try:
    while True:
        GPIO.output(LED,1)
        if (GPIO.input(Schalter) == 0):
            GPIO.output(LED, 0)
            Vorwaerts_fahren()
            print "fahre_vorwaerts"
            Messung_permanent_vorn()
            if dist_vorn_perma < 25:
                Stop_anhalten_permanent()
                print "STOP_VORN"
                Rueckwaerts_fahren()
                print "fahre_ruckwaerts"
                Stop()
                print "STOP"
                pwm.setPWM(0, 0, servoMin)
                time.sleep(1)
                Messung_dist_links()
                pwm.setPWM(0, 0, servoMax)
                time.sleep(1)
                Messung_dist_rechts()
                pwm.setPWM(0, 0, servoMid)
                time.sleep(1)
                if dist_links > dist_rechts:
                    Rueckwaerts_fahren_l()
                    print "fahre_rueckwaerts_links"
                    Rueckwaerts_fahren_l()
                    print "fahre_rueckwaerts_links"
                    Links_fahren_voll()
                    print "fahre_links_voll"
                else:
                    Rueckwaerts_fahren_r()
                    print "fahre_rueckwaerts_rechts"
                    Rechts_fahren_voll()
                    print "fahre_rechts_voll"
            else:
                Geradeaus_vorwaerts_start()
                print "geradeaus_vorwaerts_start"
            Messung_permanent_links()
            if dist_links_perma < 16:
                Rechts_fahren()
                print "fahre_rechts"
                Geradeaus_vorwaerts_start()
                print "fahre_geradeaus"
            Messung_permanent_voll_links()
            if dist_links_voll_perma < 16:
                Rechts_fahren()
                print "fahre_voll_rechts"
                Geradeaus_vorwaerts_start()
                print "fahre_geradeaus"
            Messung_permanent_links()
            if dist_links_perma < 16:
                Rechts_fahren()
                print "fahre_rechts"
                Geradeaus_vorwaerts_start()
                print "fahre_geradeaus"
            Messung_permanent_vorn()
            if dist_vorn_perma < 25:
                Stop_anhalten_permanent()
                print "STOP_VORN"
                Rueckwaerts_fahren()
                print "fahre_ruckwaerts"
                Stop()
                print "STOP"
                pwm.setPWM(0, 0, servoMin)
                time.sleep(1)
                Messung_dist_links()
                pwm.setPWM(0, 0, servoMax)
                time.sleep(1)
                Messung_dist_rechts()
                pwm.setPWM(0, 0, servoMid)
                time.sleep(1)
                if dist_links > dist_rechts:
                    Rueckwaerts_fahren_l()
                    print "fahre_rueckwaerts_links"
                    Links_fahren_voll()
                    print "fahre_links_voll"
                else:
                    Rueckwaerts_fahren_r()
                    print "fahre_rueckwaerts_rechts"
                    Rechts_fahren_voll()
                    print "fahre_rechts_voll"
            else:
                Geradeaus_vorwaerts_start()
                print "geradeaus_vorwaerts_start"
            Messung_permanent_rechts()
            if dist_rechts_perma < 16:
                Links_fahren()
                print "fahre_links"
                Geradeaus_vorwaerts_start()
                print "fahre_geradeaus"
            Messung_permanent_voll_rechts()
            if dist_rechts_voll_perma < 16:
                Links_fahren()
                print "fahre_voll_links"
                Geradeaus_vorwaerts_start()
                print "fahre_geradeaus"
            Messung_permanent_rechts()
            if dist_rechts_perma < 16:
                Links_fahren()
                print "fahre_links"
                Geradeaus_vorwaerts_start()
                print "fahre_geradeaus"
        else:
            print("Ich bin stehen geblieben, lege den Schalter S1 zum fortfahren um!")
            Error()

except KeyboardInterrupt:
    Stop()
    print("Ich bin stehen geblieben, du musst das Programm neustarten!")
    GPIO.output(LED, 1)


So hier mal das Hauptprogramm....
Kann man dass eigentlich als ganzes modul in der anderen Datei so einbinden das es mit einem input read oder line innerhalb des oberen scripts aufgerufen werden kann ? Oder ist es doch besser das als eigenen Process so starten zu wollen wie ich das vorhabe?

Ich hab ein weiteres Problem festgestellt, vielleicht habt Ihr dazu eine Lösung.
Wenn ich das eigentliche Roboterprogram über ne putty starte bekomme ich sämtliche printausgaben angezeigt. Wie Ihr feststellen könnt sind das nicht wenige. Wenn ich jedoch die Datei aus der python datei starten lasse die ja das script aufrufen soll, dann sehe ich leider keine Printausgabe in der entsprechenden Consolle. Ich sehe nur eine Ausgabe die der letzten Befehlseingabe von der Tablet App, die dass alles steuern soll. Gibt es da einen Weg die Printausgabe irgendwie anzeigen zu lassen ? Oder klappt das nicht weil der Process aus der Serverdatei gestartet wurde und dieser unsichtbar läuft bis man ihn killt ?

Ok reicht für heute

noch eins das mit dem kill() Befehl wie muss das aussehen ich hab kein schimmer wie ich den schreiben muss damit der den process terminiert.


MFG

Zappelmann
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@Zappelmann: Du startest Deine externen Programme gar nicht im Hintergrund, sondern wartest bis sie zu Ende sind. Somit kann Dein Server auch nicht mehr reagieren und gar keine Kill-Befehle mehr annehmen. Statt command zu splitten wäre es doch sinnvoller, gleich eine Liste anzugeben. Wenn Du etwas sehen willst, solltest Du stdout nicht umleiten. Importe gehören an den Anfang des Skripts:

Code: Alles auswählen

def autonom():
    command = ["sudo", "python", "robot-umbau-3.py"]
    return subprocess.Popen(command)
Den Rückgabewert kannst Du Dir in Deiner Server-Klasse merken und falls ein kill-Command kommt, damit den Prozess wieder beenden.
Zappelmann
User
Beiträge: 27
Registriert: Freitag 23. Mai 2014, 11:01

@Sirius3

erstmal vielen Dank für deine Erklärung. Das mit dem stdout werde ich mir merken. Nach dieser Änderung hatte er die Printausgabe jetzt sauber übertragen wie ich es haben wollte. Super danke.

Aber das mit dem Kill hab ich nicht ganz verstanden.
Du startest Deine externen Programme gar nicht im Hintergrund, sondern wartest bis sie zu Ende sind. Somit kann Dein Server auch nicht mehr reagieren und gar keine Kill-Befehle mehr annehmen.
dann erklär mir doch mal bitte wie ich den Process beenden kann, ohne die Server Datei dabei zu beenden?

Öhm also das Roboter Script ist eigentlich so konzepiert das es permanent immer die Schleife durchläuft. Bis ich ein Hardwarbreak mit nem Schalter setze. Siehe das Ende vom Script. Dort hab ich den break eingebaut. Soll heisen dass der Roboter so lange fährt bis ich Ihn entweder durch den Hardwareschalter pausiere oder das der durch ein Taster zum Shutdown gesetzt wird. In jedem Fall läuft das Roboterscript bis zum Ende aktiv durch auch wenn es pausiert ist. Ich kann die Pause jederzeit rausnhemen dann fährt der einfach weiter und zieht die schleife immer wieder durch. Was ich damit meine ich würde ja lange warten können bis es zu Ende ist.

Oder, läuft der Process jetzt direkt aktiv im Vordergrund ? Und muss zuerst beendet werden, damit ich wieder auf die Server Datei zugriff habe um weitere Befehle von der Tablet App anzunehmen ?

Würde der Kill Befehl denn überhaupt das Script beenden ? Oder kann der Befehl von der Serverapp, nicht verarbeitet werden weil der durch den aktiven Process blockiert wird? Dann würde ja ein Kill Befehl wenig bringen da der befehl erst garnicht verarbeitet wird ?

Oder gibt es da noch eine andere Möglichkeit wie ich das Roboterscript beenden kann wenn es auf der Serverapp heraus gestartet wurde ?

Wenn ja dann gib mal bitte ein Beispiel.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@Zappelmann: process.communicate() wartet, bis der Prozess zu Ende ist, so lange reagiert Dein Server nicht mehr auf neue Kommandos. In meinem Beispiel habe ich deshalb das communicate rausgelöscht.
Zappelmann
User
Beiträge: 27
Registriert: Freitag 23. Mai 2014, 11:01

Code: Alles auswählen


def autonom1():
    command = ["sudo", "python", "robot-umbau-3.py"]
    return subprocess.Popen(command)

def stopautonom():
    subprocess.Popen.kill(command)
    GPIO.cleanup()

wäre das so richtig ?? das GPIO.cleanup() soll zusätzlich die GPIO´s auf 0 zurücksetzen wenn das Script beendet wird.
BlackJack

@Zappelmann: Welchen Wert hat denn `command` in `stopautonom()` und wo kommt der her?
Zappelmann
User
Beiträge: 27
Registriert: Freitag 23. Mai 2014, 11:01

Moin Zusammen,

also wenn ich den letzten Post mir durchlese, schein ich das wohl doch noch nicht gerafft zu haben.
ich bin davon ausgegangen das ich den command von Autonom1 übernehmen muss um damit dann den subprocess zu beenden. Aber ich glaube ich liege hier voll daneben.
Ich hab jetzt das ganze We versucht das hinzubekommen jedoch ohne Erfolg.

Das einzige was funzt ist den Subprocess zu starten. Auch die Printausgabe wird mir sauber angezeigt. Aber das mit dem beenden funzt garnicht.
Eventuell hab ich einfach nur nen Denkfehler bei der Problematik oder ich raff das einfach nicht. Eigentlich will ich ja nur den Subprocess über eine weitere Buttoneingabe von der handyapp aus beenden.

MFG

Zappelmann
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@Zappelmann: "autonom1" liefert Dir als Rückgabewert ein Prozess-Objekt, dessen kill-Methode Du in "stopautonom" verwenden kannst. Also irgendwo in handle_command:

Code: Alles auswählen

if line == "start autonom":
    self.autonom_process = autonom1()
elif line == "stop autonom":
    self.autonom_process.kill()
Antworten