Python :: Aufgabe #173 :: Lösung #2
2 Lösungen

#173
Simulation eines Staubsaug-Roboters
Fortgeschrittener - Python
von hollst
- 22.11.2017 um 22:14 Uhr
Ich bin im Haushalt ein ziemlich fauler Hund. Meine Frau weiß das und so hielt sie mich deshalb kürzlich an, wenigstens hin und wieder das Wohnzimmer zu saugen. Nun gut, mir kam die geniale Idee, dafür einen Staubsaug-Roboter zu kaufen. Gesagt, getan. Meine Frau runzelte zwar, aber letztlich war ihr das egal, wichtig war ja nur, dass sie etwas von der Hausarbeit entlastet wird.
Das Gerät überraschte mich von Anfang an. Es fährt immer geradeaus bis es irgendwo anstößt. Dann dreht es sich auf der Stelle in eine zufällige andere Richtung und fährt wieder weiter geradeaus bis zum nächsten Hindernis. Es teilt mir auch sprachlich z. B. mit, wenn der Akku fast leer ist, es jetzt eine Pause machen wird und zur Ladestation fährt. Andermal sagte es, dass sein Hauptspeicher (sprich Staubsammeltüte) voll ist und ich ihn leeren solle. Das übernimmt natürlich meine Frau, denn bei einem solchen mechanischen Eingriff hat sie kein Vertrauen zu mir.
Der Gipfel war aber, als der Roboter mir bei der gestrigen Arbeit mitteilte, dass er fertig sei und im Zimmer der gesamten Fußboden gereinigt ist.
Das ist doch unmöglich, woher will er das wissen. Und "der gesamte Fußboden" geht schon garnicht, denn in die Ecken kommt er ja sowieso nicht. Ich war immer der Meinung, dass er erst fertig zu sein hat, wenn er abgeschaltet wird. Aber Nein sagte meine Frau, das macht er immer so, ich sollte ihn, wie vereinbart war, nur hin und wieder selbst einsetzen und beobachten (beobachtet wird das Gerät bisweil immer nur von unserer Hauskatze).
Ich wurde neugierig und las entgegen meinen Gewöhnheiten auch die Betriebsanleitung. In der Tat stand darin, dass der Roboter anhält, wenn er mehr als 95 % der Fußbodenfläche gesaugt hat.
Ich dachte, nun gut, 95 % ist okay, aber, wie will er das wissen. Da muss schon eine ziemlich clevere Software im Roboter stecken. Prinzipiell kann man zwar die besaugte Fläche bei Kenntnis der Fahrgeschwindigkeit, der Anstoßpunkte und der neuen Fahrtrichtungen berechnen. Die Flächensegmente, die durch das Zufallsprinzip bereits besaugt worden ware, sind entsprechend zu berücksichtigen (abzuziehen). Alles mathematisch recht kompliziert.
Der Gedanke, es statt einer mathematischen Berechnung durch eine informathematische Simulation abzuschätzen, legt auf der Hand. Dies soll daher die Aufgabenstellung sein.
Ausgehend von einer beliebigen Startposition auf einer leeren, rechteckigen Fläche F = LX x LY, mit LX und LY als Seitenlängen des Rechtecks, einer vorgegebenen Fahrgeschwindigkeit V und einer zufälligen Richtungsänderung bei Zusammenstoß mit einem Hindernis (Wand) ist der Anteil besaugter Fläche bzgl. der Gesamtfußbodenfläche wie folgt anzuschätzen:
Auf einem zu Beginn 100 % mit "Staubpixeln" belegten Rechteck wird ein Staubsaug-Roboter mit dem Radius R gesetzt und fährt per Zufall gewählter Richtung staubsaugend geradeaus (Geschwindigkeit V). Bei Berührung einer Wand ändert er zufällig seine Fahrtrichtung. Während der Fahrt werden alle überfahrenen "Staubpixeln" durch "Reinpixel" ersetzt (siehe Abb. 1). Die Fahrt endet, wenn P_okay = 95 % der Rechtecksfläche mit "Reinpixeln" belegt ist.
Das Gerät überraschte mich von Anfang an. Es fährt immer geradeaus bis es irgendwo anstößt. Dann dreht es sich auf der Stelle in eine zufällige andere Richtung und fährt wieder weiter geradeaus bis zum nächsten Hindernis. Es teilt mir auch sprachlich z. B. mit, wenn der Akku fast leer ist, es jetzt eine Pause machen wird und zur Ladestation fährt. Andermal sagte es, dass sein Hauptspeicher (sprich Staubsammeltüte) voll ist und ich ihn leeren solle. Das übernimmt natürlich meine Frau, denn bei einem solchen mechanischen Eingriff hat sie kein Vertrauen zu mir.
Der Gipfel war aber, als der Roboter mir bei der gestrigen Arbeit mitteilte, dass er fertig sei und im Zimmer der gesamten Fußboden gereinigt ist.
Das ist doch unmöglich, woher will er das wissen. Und "der gesamte Fußboden" geht schon garnicht, denn in die Ecken kommt er ja sowieso nicht. Ich war immer der Meinung, dass er erst fertig zu sein hat, wenn er abgeschaltet wird. Aber Nein sagte meine Frau, das macht er immer so, ich sollte ihn, wie vereinbart war, nur hin und wieder selbst einsetzen und beobachten (beobachtet wird das Gerät bisweil immer nur von unserer Hauskatze).
Ich wurde neugierig und las entgegen meinen Gewöhnheiten auch die Betriebsanleitung. In der Tat stand darin, dass der Roboter anhält, wenn er mehr als 95 % der Fußbodenfläche gesaugt hat.
Ich dachte, nun gut, 95 % ist okay, aber, wie will er das wissen. Da muss schon eine ziemlich clevere Software im Roboter stecken. Prinzipiell kann man zwar die besaugte Fläche bei Kenntnis der Fahrgeschwindigkeit, der Anstoßpunkte und der neuen Fahrtrichtungen berechnen. Die Flächensegmente, die durch das Zufallsprinzip bereits besaugt worden ware, sind entsprechend zu berücksichtigen (abzuziehen). Alles mathematisch recht kompliziert.
Der Gedanke, es statt einer mathematischen Berechnung durch eine informathematische Simulation abzuschätzen, legt auf der Hand. Dies soll daher die Aufgabenstellung sein.
Ausgehend von einer beliebigen Startposition auf einer leeren, rechteckigen Fläche F = LX x LY, mit LX und LY als Seitenlängen des Rechtecks, einer vorgegebenen Fahrgeschwindigkeit V und einer zufälligen Richtungsänderung bei Zusammenstoß mit einem Hindernis (Wand) ist der Anteil besaugter Fläche bzgl. der Gesamtfußbodenfläche wie folgt anzuschätzen:
Auf einem zu Beginn 100 % mit "Staubpixeln" belegten Rechteck wird ein Staubsaug-Roboter mit dem Radius R gesetzt und fährt per Zufall gewählter Richtung staubsaugend geradeaus (Geschwindigkeit V). Bei Berührung einer Wand ändert er zufällig seine Fahrtrichtung. Während der Fahrt werden alle überfahrenen "Staubpixeln" durch "Reinpixel" ersetzt (siehe Abb. 1). Die Fahrt endet, wenn P_okay = 95 % der Rechtecksfläche mit "Reinpixeln" belegt ist.
#2

von jule0625 (120 Punkte)
- 01.08.2018 um 17:57 Uhr
Hallo, habe mich etwas mit deiner Aufgabenstellung befasst und dazu folgenden Lösungsansatz gefunden. Da ich neu in dieser Branche bin habe ich die Visualisierung noch nicht gemacht. Das angefügte Programm beinhaltet die zufällige Fahrtrichtung bei einem Zusammenstoß mit der Wand, die Interpolation eines Fahrtwinkels und den gemessenen Fahrweg. Im Zuge dessen, wurde eine Funktion eingebaut, welche 95% der Saugfläche reproduzieren soll.
Python-Code

import random import time import matplotlib.pyplot as plt import math Bufferx=[0,0]; Buffery=[0,0]; zeiger=0; N=2; #Feldgröße 50x50 #Saugfläche 1x1; Koordinaten=[0,0];#definition der Start x,y koordinaten Xlimit=20; Ylimit=20; saugfläche=1*1; x=0; verfahrweg=0; #Berechnung 95% der Fläche fertig=0.95*((Xlimit*Ylimit)/(saugfläche)) def zufallswinkel(): winkel=0; winkelart=random.randint(0,1) #bestimmun ob positiv oder negativer winkel if winkelart==0: winkel=random.randint(0,90) else: winkel=-(random.randint(0,90)) return winkel; def interpolator(winkel):#Interpolator errechnet in Abhängigkeit vom Winkel den #Änderungsfaktor der Koordinaten prozent=[0,0]; #....x.y.Koordination if winkel>0: prozent[0]=round(-0.111*winkel+10); prozent[1]=round(0.111*winkel); elif winkel<0: prozent[0]=round(-(-0.111*-(winkel)+10)); prozent[1]=round(-(0.111*-(winkel))); return prozent; while(1): if Koordinaten[0]<=0:#Rechtsfahrt Koordinaten[0]=0; winkel=zufallswinkel(); print(winkel,"°"); x=0; elif Koordinaten[0]>=Xlimit:#Linksfahrt Koordinaten[0]=Xlimit; winkel=zufallswinkel(); print(winkel,"°"); x=0; if Koordinaten[1]<=0:#Obenfahrt Koordinaten[1]=0; winkel=zufallswinkel(); print(winkel,"°"); x=0; elif Koordinaten[1]>=Ylimit:#Untenfahrt Koordinaten[1]=Ylimit; winkel=zufallswinkel(); print(winkel,"°"); x=0; if x==0:#Koordinaten in Ringpuffer speichern um Verfahrweg zu messen #dies erfolgt immer beim Anstoßen bzw. 1mal beim wegfahren xWert=int(Koordinaten[0]); yWert=int(Koordinaten[1]); Bufferx[zeiger]=xWert; Buffery[zeiger]=yWert; zeiger = (zeiger + 1) % N; #print(Bufferx,Buffery); deltax=(Bufferx[0]-Bufferx[1]); deltay=(Buffery[0]-Buffery[1]); Betrag=abs(math.sqrt(deltax**(2)+deltay**(2))); verfahrwega=verfahrweg; verfahrweg=Betrag+verfahrwega;#aufsummierung print("letzter Weg",Betrag); print("Verfahrweg",verfahrweg); else: pass print(Koordinaten);#Ausgabe der Wegkoordinaten prozent=interpolator(winkel);#Ermittlung des Faktors Koordinaten[0]=Koordinaten[0]+prozent[0]#interpolationsfaktor Koordinaten[1]=Koordinaten[1]+prozent[1]#interpolationsfaktor if verfahrweg>=fertig: print("95% der Fläche gesaugt"); break; time.sleep(1); x=x+1; #if 95%==True:
Kommentare:
Für diese Lösung gibt es noch keinen Kommentar
Seite 1 von 0
1