Anti Backlash in Dataframe Programmieren

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.
Antworten
peachli
User
Beiträge: 18
Registriert: Dienstag 13. März 2018, 20:21

Hallo!
Ich habe für ein Bewegendes Bauteil Positionswerte und die Richtung aufgeschrieben. Nun ist es so, dass die Bewegung mit einem Backlash bzw. Hysterese behaftet ist. Das heißt, wenn ich in die selbe Richtung fahre bewegt sich die tatsächliche Position, wenn ich jedoch die Richtung wechsel, wird erst der Backlash durchfahren bevor sich das Bautail tatsächlich bewegt. Ich habe das mal versucht an einer Grafik zu visualisieren. Im Prinzipt ist es so, als wenn ich eine Kugel in einem Kasten Positionieren möchte. Sagen wir der kasten ist 110 mm breit und die Kugel liegt mit einem Durchmesser von 10 mm genau in der Mitte. Bewege ich jetzt den Kasten immer 50 mm hin und her, ändert sich die Position der Kugel nicht, weil man sich noch im Backlash befindet. Bewege ich, jedoch die Kiste z.B. um 60 mm nach Links, erfährt die Kugel eine Verschiebung von 10 mm nach Links, obwohl ich 60 mm gefahren bin. Fahre ich dann in der selben Richtung weitere 10 mm erfährt die Kugel die selbe Positionsänderung, da diese jetzt an der Flanke der Kiste anliegt.

Ich habe nun die Startposition der Kugel vorgegeben (z.B. Linke Flanke) und einen Dataframe mit Positionsänderungen und möchte daraus jetzt einen neuen Dataframe erzeugen, der mir den Backlash berechnet und nur die tatsächliche Position der Kugel ausgibt.
Leider habe ich keinen Vollständigen Code, weil ich es irgendwie nicht hinbekomme, aber vielleicht hat Jemand eine Idee wie ich das programmiertechnisch umsetzen könnte. Im Prinzip muss ich ja nur den Dataframe von oben bis unten durchgehen und dann die Virtuelle Kiste verschieben und bei überschreiten der Grenzen die Kugel mitschleifen. Aber mir ist das gerade ein wenig zu abstrakt.
Bild

Code: Alles auswählen

 
backlash=50
 richtung='az'		
 n=df.shape[0]           #Länge (Zeilen) des Dataframes auslesen
 i=4
    if backlash>0:                  #Wenn ein Backlash vorhanden ist
                if richtung=='az':         #Richtung aus der man gekommen ist (az= von auf nach zu)
                       B_L=df[namen[0]].loc[i]			#Absolute Position der linken Flanke
                       B_R=df[namen[0]].loc[i]+backlash 	#Absolute Position der rechten Flanke
                       K_ist=df[namen[0]].loc[i]			#Absolute Ist-Position der Kugel
                    while i<=n:						#DataFrame komplett durchlaufen
                        if df[namen[0]].loc[i+1]<df[namen[0]].loc[i+1]:		#Bleibt die Richtung gleich
                                  B_L=B_L
                                  i=i+1								#Eine Zeile weiter springen
                                  
Benutzeravatar
pixewakb
User
Beiträge: 1409
Registriert: Sonntag 24. April 2011, 19:43

Ich antworte, weil hier sonst keiner geantwortet hat. Ich stehe mit pandas noch auf Kriegsfuß.

Hast du mal erwogen, eine Funktion zu schreiben, das Dataframe dort mit der Bewegung zu übergeben und die Struktur Dataframe dann in ein einfacheres Konstrukt, Liste, dict o. ä. zu überführen, das Problem zu lösen und dann das ganze wieder in ein Dataframe zu geben und zurückzugeben?

Nur mal so eine Idee...
Kniffte
User
Beiträge: 64
Registriert: Dienstag 27. September 2016, 11:05

@peachli:

du solltest dir die .shift() funktion für dataframes anschauen.
vielleicht hilft dir folgender Code als Einstieg weiter:
(es fehlt noch zu prüfen ob der "Kasten" also b_left oder b_right die minimale bzw. maximal Position erreicht haben,
ggf. noch ob die startposition der kugel innerhalb b_left und b_right liegt, ...)

Code: Alles auswählen

import pandas as pd

OPEN_TO_CLOSE = 100
BACKLASH = 5
B_LEFT = 4
B_RIGHT = B_LEFT + BACKLASH
START_BALL_POS = 7

def init_dataframe(open_to_close, b_left, b_right, start_ball_pos):
    df = pd.DataFrame({'open_to_close':range(open_to_close)})
    df['open_to_close'] = ''
    df['abs_ball_pos'] = ''
    df.set_value(b_left, 'open_to_close', 'b_left')
    df.set_value(b_right, 'open_to_close', 'b_right')
    df.set_value(start_ball_pos, 'abs_ball_pos', 'ball')

    return df

def close(df, steps):
    for _ in range(steps):
        if df.loc[df['abs_ball_pos'] == 'ball']['open_to_close'].item() == 'b_left': # to implement: check if b_left exceeds open position
            df['abs_ball_pos'] = df['abs_ball_pos'].shift(1)
            df['open_to_close'] = df['open_to_close'].shift(1)
        else:
            df['open_to_close'] = df['open_to_close'].shift(1)

def open(df, steps):
    for _ in range(steps):
        if df.loc[df['abs_ball_pos'] == 'ball']['open_to_close'].item() == 'b_right': # to implement: check if b_right exceeds close position
            df['abs_ball_pos'] = df['abs_ball_pos'].shift(-1)
            df['open_to_close'] = df['open_to_close'].shift(-1)
        else:
            df['open_to_close'] = df['open_to_close'].shift(-1)

def get_ball_pos(df):
    ball_pos = pd.Index(df['abs_ball_pos']).get_loc('ball')
    print(ball_pos)


if __name__ == '__main__':
    df = init_dataframe(OPEN_TO_CLOSE, B_LEFT, B_RIGHT, START_BALL_POS)
    close(df, 10)
    get_ball_pos(df)
    
Antworten