threading Probleme

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.
emilio20
User
Beiträge: 22
Registriert: Donnerstag 17. Oktober 2013, 21:08

Hallo
ich bin noch Python Anfänger und bin dabei einen Roboter zu Programmieren. Ich möchte mehrere Funktionen parallel laufen lassen und verwende hier für threading.

Ich habe ein Programm mit threading erstell wo zwei Funktionen control und sensoren parallel laufen. Dies hat auch soweit Funktioniert.

Für den Roboter habe ich dann das Programm Megapi() importiert.
https://github.com/Makeblock-official/P ... /megapi.py

Nachdem ich dies gemacht habe und in den jeweiligen Funktionen Befehle eingefügt habe erhalte ich einige Fehlermeldungen. In der Megapi Class wir ebenfalls threading verwendet.


Programm

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: cp1252 -*-
# Autor:   
# Datum:   20170317
# Version:   1.0

#Megapi import
from megapi import *
import time, os, random

# Threads Bibliothek importieren.
from threading import Thread


# stopp Bedingung für die While Schleifen der Threads.
global stopp_turn
global time_stopp
global leftSpeed
global rigthSpeet
Ultraschall = 0;
Kompass = 0;
z = 0;


#Funktion Fahren in welche Richtung
def move(direction,speed):
    if direction == 1:
        #Vorwärz
        leftSpeed =  -speed
        rigthSpeet =  speed
    elif direction == 2:
        #Rückwärz
        leftSpeed =   speed
        rigthSpeet = -speed
    elif direction == 3:
        #Rückwärz
        leftSpeed =   speed
        rigthSpeet =  speed
    elif direction == 4:
        #Rückwärz
        leftSpeed =  -speed
        rigthSpeet = -speed
    else:
        leftSpeed =  0
        rigthSpeet = 0
    bot.encoderMotorRun(1,rigthSpeet);
    bot.encoderMotorRun(2,leftSpeed);
    print("move",direction)

def printscreen():
   # der Befehl os.system('clear') leert den Bildschirmihalt vor
   # jeder Aktualisierung der Anzeige. So bleibt das Menue stehen
   # und die Bildschirmanzeige im Terminal Fenster steht still.
    os.system('clear')
    print("========== Geschwindigkeitsanzeige ==========")
    #print "Geschwindigkeit linker Motor:  ", leftSpeed
    #print "Geschwindigkeit rechter Motor: ", rigthSpeet
    print("move",direction)
    print "distance:"+str(Ultraschall)+" cm";

def onRead(v):
    global Ultraschall;
    Ultraschall = v;
    #print "distance:"+str(Ultraschall)+" cm";
    

   # So lange stopp = 0 arbeitet dieser Thread in der
   # Endlosschleife.
def control():
    global stopp_control
    global time_stopp
    stopp_control = 0
    turn_degree = 0
    bot = MegaPi()
    bot.start()
    sleep(1);
    while stopp_control == 0: 
            #sleep(1);
            #move(1,100)
            time.sleep( 1 )
            print "vorwärz"
            time.sleep( 1 )
            #sleep(1);
            print "Rückwerz"
            time.sleep( 1 )
            #sleep(2);
            #move(1,0)
            print "links"
            time.sleep( 1 )
            #sleep(2);
            #move(2,100)
            print "rechts"
            #sleep(2);
            #move(1,0)
            if time_stopp < time.time():
                stopp_control = 1
                print "Programm Ende";
            

def sensoren():
    global stopp_control
    global time_stopp
    stopp_control = 0
    bot = MegaPi()
    bot.start()
    sleep(1);
    while stopp_control == 0:
        bot.ultrasonicSensorRead(7,onRead);
        #print "Thread Sensor Run";
        print "distance:"+str(Ultraschall)+" cm";
        #sleep(1);
        time.sleep( 1 )
        if time_stopp < time.time():
                stopp_control = 1
                print "Programm Ende";
        
    
laufzeit=input("Bitte die Zeit in Minuten eingeben die das Roboter-Auto fahren soll: ")    
time_stopp = laufzeit*60 + time.time()

t_control = Thread(target=control)
t_sensoren = Thread(target=sensoren)

t_control.start()
t_sensoren.start()
       
  	  




Fehlerbericht

Code: Alles auswählen

pi@raspberrypi:~/robot $ python Auto.py
Bitte die Zeit in Minuten eingeben die das Roboter-Auto fahren soll: 1
init MegaPi
init MegaPi
Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
    self.run()
  File "/usr/lib/python2.7/threading.py", line 763, in run
    self.__target(*self.__args, **self.__kwargs)
  File "Auto.py", line 74, in control
    bot = MegaPi()
  File "/usr/local/lib/python2.7/dist-packages/megapi.py", line 69, in __init__
    signal.signal(signal.SIGINT, self.exit)
ValueError: signal only works in main thread


Exception in thread Thread-2:
Traceback (most recent call last):
  File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
    self.run()
  File "/usr/lib/python2.7/threading.py", line 763, in run
    self.__target(*self.__args, **self.__kwargs)
  File "Auto.py", line 104, in sensoren
    bot = MegaPi()
  File "/usr/local/lib/python2.7/dist-packages/megapi.py", line 69, in __init__
    signal.signal(signal.SIGINT, self.exit)
ValueError: signal only works in main thread

pi@raspberrypi:~/robot $



Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

@emilio20: Das sieht jetzt erst einmal so aus, als ob megapi nicht dazu geeignet ist, außerhalb des Haupthreads verwendet zu werden. Der Code von megapi schaut auch etwas seltsam aus und weist zudem einige imports auf, die gar nicht verwendet werden; ich würde diesem Modul jedenfalls nicht vertrauen.

Die Kommunikation zwischen Threads solltest Du nicht über globals vornehmen. Besser ist die Verwendung von Queues oder das Nutzen von threading.Events. Eine saubere Anwendung von Threads ist übrigens alles andere als einfach, und die Implementierung von megapi macht da keine Ausnahme.
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

@emilio20:
Die Klasse `MegaPi` nutzt das Signal SIGINT, um `sys.exit()` aufzurufen - Autsch. Das ist ein ziemlich mieser Kontrollfluss. Es macht die Klasse praktisch unbrauchbar für direkte Benutzung in Threads und stört auch bei normaler Entwicklung und Testung an der Konsole. Wenn man SIGINT abfängt, sollte man ganz genau wissen, was man da tut. Und der Code mit dem `__del__` sieht nicht danach aus. Ich rate von der Benutzung der Bibliothek ab.
emilio20
User
Beiträge: 22
Registriert: Donnerstag 17. Oktober 2013, 21:08

Hallo vielen Dank,
aber ohne MegaPi kann ich meinen Roboter nicht betreiben oder müsste mir das ganze selbe schreiben. Hierzu fehlt mir jedoch die Erfahrung in Python.

Dann werde ich wohl nicht Fahren und eine Servo Motor für meinen Ultraschall Sensor Parallel betrieben können.

Die Bibliothek ist vom Hersteller soweit ich weiß Makeblock
emilio20
User
Beiträge: 22
Registriert: Donnerstag 17. Oktober 2013, 21:08

Kann mir jemand die Funktion erklären ? Ich verstehe nicht wie der Wert in (v) kommt ?
Wie erhalte ich von bot.ultrasonicSensorRead(6,onRead); direkt den Wert ?
bot.ultrasonicSensorRead(6,Ultraschall) ???????? geht nicht

Code: Alles auswählen

from megapi import *

def onRead(v):
	print "distance:"+str(v)+" cm";

if __name__ == '__main__':
	bot = MegaPi()
	bot.start()
	while 1:
		sleep(0.1);
bot.ultrasonicSensorRead(6,onRead);
Zuletzt geändert von Anonymous am Samstag 18. März 2017, 14:18, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

Der Wert v kommt daher, dass du im Fall eines sensor-Reads *benachrichtigt* wirst. Du stoesst also eine Messung an, deren Ergebnis prinzipbedingt nicht sofort verfuegbar ist. Deshalb gibst du eine Rueckruffunktion an, die dann den Wert als "v" in deinem Fall uebergeben bekommt.

Allerdings nicht so wie du das hingeschrieben hast. Denn du fuehrst die Messung nicht aus, da sie *NACH* der Endlosschleife kommt. Bitte Grundlagen Python per Tutorial erarbeiten. Programmieren ist nicht rate mal mit Rosenthal.
emilio20
User
Beiträge: 22
Registriert: Donnerstag 17. Oktober 2013, 21:08

Hallo
das bot.ultrasonicSensorRead(6,onRead); muss eingerückt werden das ist ja bei mir der Fall. Das Grundprogramm Funktioniert ja auch.
Ich wollte eigentlich nur wissen ob ich immer mit der Funktion onRead Arbeiten muss oder ob dich den Wert direkt in eine Variable schreiben kann ?

Wenn ich mein Programm erstelle möchte ich den Sensorwert einlesen und je nach Wert eine Funktion ausführen. Dieser Programmcode Funktioniert.
Die frage ich ob ich dies vereinfachen kann ?

Code: Alles auswählen


from megapi import *
import time, os, random
global stopp_turn
global time_stopp


def onRead(v):
    global Ultraschall;
    Ultraschall = v;
    


def sensoren():
    global stopp_control
    global time_stopp
    stopp_control = 0
    bot = MegaPi()
    bot.start()
    sleep(1);
    while stopp_control == 0:
        bot.ultrasonicSensorRead(7,onRead);
        time.sleep( 2 )
        print "distance:"+str(Ultraschall)+" cm";
        if time_stopp < time.time():
                stopp_control = 1
                print "Programm Ende";

                
laufzeit=input("Bitte die Zeit in Minuten eingeben die das Roboter-Auto fahren soll: ")    
time_stopp = laufzeit*60 + time.time()        
sensoren()




__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du kannst nur ueber den Callback benachrichtigt werden.
BlackJack

@emilio20: Auch wenn das funktioniert ist es äusserst unschön. ``global`` hat in einem sauberen Programm nichts zu suchen. Solange Du das noch einsetzt und überall die überflüssigen Semikolons ans Zeilenende pappst, bist Du nicht wirklich bei Python angekommen. :-)
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

@emilio20: Sich als erklärter Anfänger direkt in Threads und Callbacks zu stürzen ist schon mutig. Ich habe Dir mal (in Ermangelung der passenden Hardware) ein ungetestetes Stück Code abgefasst, von dem Du Dich Deinem Projekt vielleicht besser annähern kannst.

Versuche den Code zu verstehen und nicht der Versuchung "Programmieren durch raten" zu erliegen. Und bedenke bitte, dass der Code von MegaPi eher fragwürdig ist.

Code: Alles auswählen

from queue import Queue
from megapi import MegaPi


PORT = 7
data_queue = Queue()


def process_sensor_data(data):
    data_queue.put(data)


def run_sensor():
    bot = MegaPi()
    bot.ultrasonicSensorRead(PORT, process_sensor_data)
    bot.start()
    while True:
        data = data_queue.get()
        message = 'distance: {} cm'.format(data)
        print(message)


if __name__ == '__main__':
    run_sensor() 
emilio20
User
Beiträge: 22
Registriert: Donnerstag 17. Oktober 2013, 21:08

Hallo
vielen Dank für die Auskunft. Ich weiß ich muss noch sehr viel lernen in Python
, normaler weiße Programmiere ich PLC Steuerungen in SCL, ST oder C++ mit Python habe ich so meine Probleme.
Ich wäre euch sehr dankbar wenn ich mir ein kleines Beispiel Posten könnte was ich alles falsch mache.
Hier mal an Code an dem ich verzweifele.

Code: Alles auswählen

Megapi import
from megapi import *
import time, os, random

# Threads Bibliothek importieren.
#from threading import Thread


# stopp Bedingung für die While Schleifen der Threads.
global stopp_turn
global time_stopp
global leftSpeed
global rigthSpeet


    #Funktion Fahren in welche Richtung
    def move(direction,speed):
        if direction == 1:
            #Vorwärz
            leftSpeed =  -speed
            rigthSpeet =  speed
        elif direction == 2:
            #Rückwärz
            leftSpeed =   speed
            rigthSpeet = -speed
        elif direction == 3:
            #Rückwärz
            leftSpeed =   speed
            rigthSpeet =  speed
        elif direction == 4:
            #Rückwärz
            leftSpeed =  -speed
            rigthSpeet = -speed
        else:
            leftSpeed =  0
            rigthSpeet = 0
        bot.encoderMotorRun(1,rigthSpeet);
        bot.encoderMotorRun(2,leftSpeed);
        print("move",direction)



    def onRead(v):
        global ultrasonic;
        ultrasonic = v;
        print "distance:"+str(v)+" cm";
                

       # So lange stopp = 0 arbeitet dieser Thread in der
       # Endlosschleife.
    def control():
        global stopp_control
        global time_stopp
        stopp_control = 0
        turn_degree = 0
        bot = MegaPi()
        bot.start()
        sleep(1);
        while stopp_control == 0:
            bot.ultrasonicSensorRead(7,onRead);
            if ultrasonic > 100:
                move(1,100)
                print "move(FWD)"
            else:
                move(1,0)
                print "move(STOP)"
            print "Programm Run";
            time.sleep( 1 )    
            if time_stopp < time.time():
                stopp_control = 1
                print "Programm Ende";
                

               
        
    laufzeit=input("Bitte die Zeit in Minuten eingeben die das Roboter-Auto fahren soll: ")    
    time_stopp = laufzeit*60 + time.time()

    
    control()



emilio20
User
Beiträge: 22
Registriert: Donnerstag 17. Oktober 2013, 21:08

Hallo kbr
Wenn ich deinen Code auf dem Raspberry pi verwende erhalte ich

Code: Alles auswählen

Traceback (most recent call last):
  File "testUS.py", line 2, in <module>
    from queue import Queue
ImportError: No module named queue
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

@emilio20: Nun, dann verwendest Du wohl noch Python 2. Dann musst Du 'queue' großschreiben. Ein Blick in die Dokumentation zeigt Dir dann auch, wie diese zu verwenden ist. Überhaupt ist die Dokumentation immer einen Blick wert ... :)
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

@kbr ich bezweifele, dass das so wie gewuenscht funktioniert. Auch wenn es danach aussieht (und besser waere...), dass man eine kontinuierliche Werteabfrage mittels callback bekommt, ist das eine one-shot-Funktion. Der callback ist nur deshalb da, weil die ganze Chose via serieller Schnittstelle auf einen Arduino zugreift.
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

@__deets__: Hmm, so genau habe mir MegaPi gar nicht angeschaut, bzw. anschauen wollen. Dann müsste ultrasonicSensorRead tatsächlich in die Schleife gezogen werden. Jetzt gefällt mit MegaPi sogar noch weniger ...
emilio20
User
Beiträge: 22
Registriert: Donnerstag 17. Oktober 2013, 21:08

Zur Info,
das Programm funktioniert leider nicht :(
emilio20
User
Beiträge: 22
Registriert: Donnerstag 17. Oktober 2013, 21:08

Hallo
ich habe nach einiger Sucherei ein Scrip eines anderen Roboter gefunden das ich auf meine Bedürfnisse abgeändert habe.
Mit diesem Programm fahr der Roboter erst mal geradeaus und wenn der Ultraschall Sensor < 50 ist hält er an.

Ist aber nicht ganz nach meiner vorstellung da ich die ganze Fahrlogik in "onDistance" schreiben müsste.
Der Roboter soll später bei einem Hindernis anhalten dann mit dem Ultraschallsensor schauen ob links oder rechts mehr Platz ist und demenspricht Handeln. Wenn kein Platz ist umdrehen. Das ganze habe ich schon in C++. Jetzt versuche ich es in Python umzusetzen.

Hier mal der Code

Code: Alles auswählen

from megapi import *
if __name__ == '__main__':
	def onDistance(dist):
		print "distance:",dist
		if dist<50 :
                        bot.encoderMotorRun(1,0);
                        bot.encoderMotorRun(2,0);
		else:	
                        bot.encoderMotorRun(1,-100);
                        bot.encoderMotorRun(2,100);
		
	bot = MegaPi()
	bot.start()
	while(1):
		try:
                        sleep(0.2)
			bot.ultrasonicSensorRead(7,onDistance);
		except Exception,ex:
			print str(ex)
sleep(0.2)
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

Wenn du das in C++ hast, wuerde mich mal interessieren, wie das ausschaut. Denn das es dann in Python so viel Probleme bereitet macht mich stutzig. Das geht nahezu genauso.

Wenn du ein komplexeres Verhalten haben moechtest, kommst du IMHO nicht um eine vernuenftige Ereignisschleife & einen Zustandsautomaten fuer die Roboterlogik aus. Ausser du benutzt so etwas einfaches wie Braitenberg.
emilio20
User
Beiträge: 22
Registriert: Donnerstag 17. Oktober 2013, 21:08

Hallo,
es geht mir eigentlich nicht um das Schaltwerk, dies kenne ich aus der SPS Programmierung hier muss man mit einer Schrittkette arbeiten da die Steuerung immer laufen muss und nicht in einer while hängen soll.
Mein Problem ist eigentlich die Megapi Python Bibliothek. Wenn ich z.b den Ultraschallsensoren auslesen möchte muss ich die Funktion onRead verwenden und kann nicht direkt wie in C++ den Wert im Hauptprogramm abfragen.
Ich Poste mal mein Arduino Programm ist aber auch noch nicht ganz ausgereift. Hier ist noch kein Schaltwerk vorhanden.
Ich kann einfach den Ultraschallsensor einlesen.

Code: Alles auswählen

if((ultrasonic_7.distanceCm()) > (150)){
[codebox=c file=Unbenannt.c]
#include <Arduino.h>
#include <Wire.h>
#include <SoftwareSerial.h>

#include <MeMegaPi.h>

//Encoder Motor
MeEncoderOnBoard Encoder_1(SLOT1);
MeEncoderOnBoard Encoder_2(SLOT2);
MeEncoderOnBoard Encoder_3(SLOT3);
MeEncoderOnBoard Encoder_4(SLOT4);

void isr_process_encoder1(void)
{
if(digitalRead(Encoder_1.getPortB()) == 0){
Encoder_1.pulsePosMinus();
}else{
Encoder_1.pulsePosPlus();
}
}

void isr_process_encoder2(void)
{
if(digitalRead(Encoder_2.getPortB()) == 0){
Encoder_2.pulsePosMinus();
}else{
Encoder_2.pulsePosPlus();
}
}

void isr_process_encoder3(void)
{
if(digitalRead(Encoder_3.getPortB()) == 0){
Encoder_3.pulsePosMinus();
}else{
Encoder_3.pulsePosPlus();
}
}

void isr_process_encoder4(void)
{
if(digitalRead(Encoder_4.getPortB()) == 0){
Encoder_4.pulsePosMinus();
}else{
Encoder_4.pulsePosPlus();
}
}

void move(int direction, int speed)
{
int leftSpeed = 0;
int rightSpeed = 0;
if(direction == 1){
leftSpeed = -speed;
rightSpeed = speed;
}else if(direction == 2){
leftSpeed = speed;
rightSpeed = -speed;
}else if(direction == 3){
leftSpeed = speed;
rightSpeed = speed;
}else if(direction == 4){
leftSpeed = -speed;
rightSpeed = -speed;
}
Encoder_1.setTarPWM(rightSpeed);
Encoder_2.setTarPWM(leftSpeed);
}
void moveDegrees(int direction,long degrees, int speed_temp)
{
speed_temp = abs(speed_temp);
if(direction == 1)
{
Encoder_1.move(degrees,(float)speed_temp);
Encoder_2.move(-degrees,(float)speed_temp);
}
else if(direction == 2)
{
Encoder_1.move(-degrees,(float)speed_temp);
Encoder_2.move(degrees,(float)speed_temp);
}
else if(direction == 3)
{
Encoder_1.move(degrees,(float)speed_temp);
Encoder_2.move(degrees,(float)speed_temp);
}
else if(direction == 4)
{
Encoder_1.move(-degrees,(float)speed_temp);
Encoder_2.move(-degrees,(float)speed_temp);
}
}

double angle_rad = PI/180.0;
double angle_deg = 180.0/PI;
void Drehe(double Winkel);
double Drehwinkel_Soll;
double Stopp;
double Drehen_Links;
double Drehen_Rechts;
double Vmax_Dreh_L;
double Vmax_Dreh_R;
MeCompass compass_8(8);
void Servo_Run();
double Count;
double US_30_rechts;
double US_90_grade;
double US_150_links;
MeUltrasonicSensor ultrasonic_7(7);
Servo servo_6_1;
MePort port_6(6);
double Zufallszahl;

void Drehe(double Winkel)
{
Drehwinkel_Soll = (compass_8.getAngle()) + (Winkel);
Stopp = 0;
if((Drehwinkel_Soll) > (360)){
Drehwinkel_Soll = (Drehwinkel_Soll) - (360);
}
if((Drehwinkel_Soll) < (0)){
Drehwinkel_Soll = (Drehwinkel_Soll) + (360);
}
while(!(((Stopp)==(1))))
{
_loop();
if((Drehwinkel_Soll) > (compass_8.getAngle())){
Drehen_Links = (compass_8.getAngle()) + ((360) - (Drehwinkel_Soll));
}else{
Drehen_Links = (compass_8.getAngle()) - (Drehwinkel_Soll);
}
if((compass_8.getAngle()) > (Drehwinkel_Soll)){
Drehen_Rechts = (Drehwinkel_Soll) + ((360) - (compass_8.getAngle()));
}else{
Drehen_Rechts = (Drehwinkel_Soll) - (compass_8.getAngle());
}
if((Drehen_Links) < (Drehen_Rechts)){
Vmax_Dreh_L = (Drehen_Links) * (2);
if((Vmax_Dreh_L) < (100)){
Vmax_Dreh_L = 100;
}
move(3,Vmax_Dreh_L);
}else{
Vmax_Dreh_R = (Drehen_Rechts) * (2);
if((Vmax_Dreh_R) < (100)){
Vmax_Dreh_R = 100;
}
move(4,Vmax_Dreh_R);
}
if(((Drehen_Links) < (10)) || ((Drehen_Rechts) < (10))){
Stopp = 1;
}
}
move(4,0);
move(3,0);
}

void Servo_Run()
{
if(((Count)==( 0 ))){
US_30_rechts = ultrasonic_7.distanceCm();
servo_6_1.write(90);
}
if(((Count)==(10))){
US_90_grade = ultrasonic_7.distanceCm();
servo_6_1.write(150);
}
if(((Count)==(20))){
US_150_links = ultrasonic_7.distanceCm();
servo_6_1.write(90);
}
if((Count) > (30)){
US_90_grade = ultrasonic_7.distanceCm();
servo_6_1.write(30);
Count = 0;
}
Count += 1;
}

void setup(){
compass_8.begin();
attachInterrupt(Encoder_1.getIntNum(), isr_process_encoder1, RISING);
attachInterrupt(Encoder_2.getIntNum(), isr_process_encoder2, RISING);
servo_6_1.attach(port_6.pin1());
//Set Pwm 8KHz
TCCR1A = _BV(WGM10);
TCCR1B = _BV(CS11) | _BV(WGM12);
TCCR2A = _BV(WGM21) | _BV(WGM20);
TCCR2B = _BV(CS21);
}

void loop(){
Servo_Run();
if((ultrasonic_7.distanceCm()) > (50)){
if((ultrasonic_7.distanceCm()) > (150)){
move(1,255);
}else{
move(1,100);
}
}else{
move(1,0);
if(((US_150_links) > (80)) || ((US_30_rechts) > (80))){
if((US_150_links) > (US_30_rechts)){
Zufallszahl = random(-15,(-40)+1);
Drehe(Zufallszahl);
}else{
Zufallszahl = random(15,(40)+1);
Drehe(Zufallszahl);
}
}else{
move(2,100);
_delay(1);
Servo_Run();
if((US_150_links) > (US_30_rechts)){
Zufallszahl = random(-90,(-170)+1);
Drehe(Zufallszahl);
}else{
Zufallszahl = random(90,(170)+1);
Drehe(Zufallszahl);
}
}
}
_delay(0.01);
_loop();
}

void _delay(float seconds){
long endTime = millis() + seconds * 1000;
while(millis() < endTime)_loop();
}

void _loop(){
Encoder_1.loop();
Encoder_2.loop();
}
[/code]
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ah, C++ auf dem Arduino... das erklaert einiges.

Wie ich schon schrieb - du brauchst eine Ereignisschleife. Der Arduino bringt das schon von Haus aus mit, und du nutzt das auch.

Und dein Programm schreibt sich dann auch einfach um:

Code: Alles auswählen


import time
from megapi import *


sensorValue = 0 # initial value, better stop than sorry

def sensorCallback(dist):
    global sensorValue
    sensorValue = dist


def work():
    if sensorValue < 50:
        stop()
    else:
        forward()


def main():
    bot = MegaPi()
    bot.start()
    while True:
        bot.ultrasonicSensorRead(7, sensorCallback)
        work()
        sleep(0.1)

if __name__ == '__main__':
    main()
Den globalen Zustand kann man natuerlich auch noch beseitigen, dazu habe ich gerade keine Lust. Ich denke mal es wird eh gefrickelt wie es nur geht... wie immer beim Pi.. *seufz*
Antworten