Zuviel Werbung? - > Hier kostenlos beim SPS-Forum registrieren

Ergebnis 1 bis 8 von 8

Thema: Strecken finden aus Coordinaten eines LaserScanners

  1. #1
    Registriert seit
    19.01.2016
    Ort
    Irschenberg
    Beiträge
    4
    Danke
    3
    Erhielt 0 Danke für 0 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Guten Tag,
    Ich habe die ehrvolle Aufgabe bekommen einen Lichtschnittsensor in eine Produktionslinie einzubinden. Hierbei handelt es sich um das Fabrikat: "Leuze LPS 36/EN".
    Von dem Sensor bekomme ich 760 Punkte mit X und Y Coordinaten. Meine Aufgabe ist es Objekte(Bretter mit Waldkante) zu vermessen. Es wäre ansich kein Problem wenn das Objekt immer eben daliegen würde(Siehe Bild 1)
    Unbenannt.pngBild 1
    Ich habe mir gedacht ich könnte das Problem Lösen indem ich nach geraden Strecken suche und die ungerade Waldkante über einfache Division ausrechnen könnte.

    Jetzt kommt mein Problem:
    Ich brauche einen Algorithmus mit welchen ich Strecken rein aus Coordinaten bestimmen kann.

    Ich hatte bereits eine Idee, jedoch ist sie soo rechenintensiv, dass mir meine 319-3pn/dp mit einer Zykluszeit von über 70ms das leben schwer macht.

    Hat irgendjemand eine idee?
    Danke schonmal im Vorraus


    Info:
    Ich habe alle Messpunkt in einem DB(DB_Messdaten) abgelegt



    STRUCT
    Messpunkt : ARRAY [1 .. 750 ] OF //vorläufige Platzhaltervariable
    "Messpunkt";
    END_STRUCT ;
    BEGIN
    Messpunkt[1].YWert := 0;
    Messpunkt[1].XWert := 0;
    Messpunkt[2].YWert := 0;
    Messpunkt[2].XWert := 0;
    Messpunkt[3].YWert := 0;
    Messpunkt[3].XWert := 0;
    Messpunkt[4].YWert := 0;
    Messpunkt[4].XWert := 0;

    etc.


    Hier mein Testprogramm:

    Code:
    FUNCTION "StraightFinder" : VOID
    TITLE =Straight Finder
    //
    //
    //Dieses Programm dient zum erkennen von Geraden, aus der Datenwolke des LPS
    //
    //
    //
    AUTHOR : Oberm
    VERSION : 0.1
    
    
    VAR_INPUT
      Extern_mode : BOOL ;    
      IN_Aufloes : INT ;    
      IN_min_laenge : INT ;    
    END_VAR
    VAR_TEMP
      Aufloesung : INT ;    
      Pointer_01 : DWORD ;    //Wird mehrmals für verschiedenes verwendet!!!!!
      step01 : INT ;    
      Pointer_02 : DWORD ;    //Wird mehrmals für verschiedenes verwendet!!!!!
      Punkt_A1_Pointer : DWORD ;    
      step2 : INT ;    
      Punkt_B1_Pointer : DWORD ;    
      Hoehendiff : INT ;    
      Laengendiff : INT ;    
      Steigung : REAL ;    
      min_laenge : INT ;    
      step3 : DINT ;    
      Pointer_03 : DINT ;    
      Temp_distance : INT ;    
      Vergl_wert : INT ;    
      Pointer_04 : DINT ;    
      Anz_Punkt : INT ;    
      theo_anz_Punkt : DINT ;    
      step4 : INT ;    
    END_VAR
    BEGIN
    NETWORK
    TITLE =Grundparameter
    
    //Auflösung festlegen (zwischen 0 - 20 empfohlen)   0 = max
          UN    #Extern_mode; 
          SPBN  m01; 
          L     450; 
          T     #min_laenge; 
    
          L     10; 
          T     #Aufloesung; 
    
          SPA   m02; 
    m01:  NOP   0; 
          L     #IN_min_laenge; 
          T     #min_laenge; 
    
    
          L     #IN_Aufloes; 
          T     #Aufloesung; 
    m02:  NOP   0; 
    
    
    NETWORK
    TITLE =Anfang Suchen
    //
    //Den ersten relevanten Messpunkt suchen
          AUF   "Messdaten"; 
          L     P#36.0; 
          T     #Pointer_01; 
    
          L     365; 
    next: T     #step01; 
          L     DBW [#Pointer_01]; 
          L     0; 
          <>I   ; 
          SPB   m03; //Escape
    
          L     #Pointer_01; 
          L     P#4.0; 
          +D    ; 
          T     #Pointer_01; 
    
          L     #step01; 
          LOOP  next; 
    m03:  NOP   0; 
    
    
    
    NETWORK
    TITLE =Straight Finder Main Programm
    //Von einem festen Punkt(A1) wird versucht eine Strecke zu finden, welche 
    //möglichst lang ist. Hierzu wird am Anfang die kleinstmöglich Strecke gesucht und 
    //dann Stück für Stück verlängert. Strecke A1->B1
    //
    //Das Programm soll nun überprüfen, anhand der Punkte die auf dieser Strecke 
    //liegen, ob diese Gerade ist! Hierzu wird vorher definiert, wie viele Punkt auf 
    //dieser Strecke liegen müssten (minus Fehlertoleranz). Sind nun deutlich weniger 
    //Punkte auf dieser Strecke als zuvor, ist die geradheit der Strecke nichtmehr 
    //gewährleistet!!! Die letzte gültige Strecke soll in einem DB Abgespeichert 
    //werden und der Punkt A1 wird auf die Position des Punktes B1 gesetzt! Nun 
    //beginnt das Prozedere von vorn mit einem neuen Punkt A1!!!
    //
    //Vorbereiten
          AUF   DI     2; 
    
          L     P#0.0; 
          T     #Pointer_02; 
    
    
          L     #Pointer_01; 
          T     #Punkt_A1_Pointer; 
    
    
          L     #Pointer_01; 
          L     P#4.0; 
          +D    ; 
          T     #Punkt_B1_Pointer; 
    
    
    
    // Hier Beginnt es !!!
          L     1000; //Dient als obergrenze falls fehler im Programm sind
    nex3: T     #step4; 
    
          L     DBW [#Punkt_B1_Pointer]; 
          L     DBW [#Punkt_A1_Pointer]; 
          -I    ; 
          T     #Hoehendiff; 
    
    
          L     #Punkt_A1_Pointer; 
          L     P#2.0; 
          +D    ; 
          T     #Pointer_01; 
    
          L     #Punkt_B1_Pointer; 
          L     P#2.0; 
          +D    ; 
          T     #Pointer_02; 
    
    
          L     DBW [#Pointer_02]; 
          L     DBW [#Pointer_01]; 
          -I    ; 
          T     #Laengendiff; 
    
          L     #Hoehendiff; 
          ITD   ; 
          DTR   ; 
          L     #Laengendiff; 
          ITD   ; 
          DTR   ; 
          /R    ; 
          T     #Steigung; 
    
    //Vorbereitung  für 2. Loop
    
          L     #Punkt_A1_Pointer; 
          L     P#6.0; 
          +D    ; 
          T     #Pointer_03; 
          L     0; 
          T     #Temp_distance; 
          L     0; 
          T     #Anz_Punkt; 
    
    
    
    
    
    
          L     #Punkt_B1_Pointer; 
          L     #Punkt_A1_Pointer; 
          -D    ; 
          SRD   3; 
          L     4; 
          /D    ; 
          T     #theo_anz_Punkt; 
    
    nex2: T     #step3; 
          L     DBW [#Pointer_03]; 
          L     DBW [#Pointer_01]; 
    
          -I    ; 
          T     #Temp_distance; 
    
    
          L     #Temp_distance; 
          DTR   ; 
          L     #Steigung; 
    
          *R    ; 
          L     DBW [#Punkt_A1_Pointer]; 
          DTR   ; 
          +R    ; 
          RND   ; 
          T     #Vergl_wert; 
    
    
          L     #Pointer_03; 
          L     P#2.0; 
          -D    ; 
          T     #Pointer_04; 
    
    //Überprüfen ob Punkt auf der Strecke liegt
          U(    ; 
          L     #Vergl_wert; 
          L     #Aufloesung; 
          -I    ; 
          L     DBW [#Pointer_04]; 
    
          <=I   ; 
          )     ; 
          U(    ; 
          L     #Vergl_wert; 
          L     #Aufloesung; 
          +I    ; 
          L     DBW [#Pointer_04]; 
    
          >=I   ; 
          )     ; 
    //falls der Punkt auf der Strecke liegt wird dieser Gewertet
          SPBN  m001; 
          L     #Anz_Punkt; 
          L     1; 
          +I    ; 
          T     #Anz_Punkt; 
    m001: NOP   0; 
    
    //nächsten Punkt auf der Strecke vorbreiten
    
          L     #Pointer_03; 
          L     P#4.0; 
          +D    ; 
          T     #Pointer_03; 
    
    
          L     #step3; 
          LOOP  nex2; 
    
    //Überprüfen ob es sich um eine Strecke Handelt
    
          L     #Anz_Punkt; 
          L     3; //Fehlertolleranz
          +I    ; 
          L     #theo_anz_Punkt; 
          <I    ; 
          SPB   m002; //Loop beenden falls die Strecke nichtmehr gewährleistet ist
    
    //Strecke verlängern
          L     #Punkt_B1_Pointer; 
          L     P#4.0; 
          +D    ; 
          T     #Punkt_B1_Pointer; 
    
          L     #step4; 
    
          LOOP  nex3; 
    
    m002: NOP   0; 
    
    //--Die Arbeit am Programm habe ich ab hier Pausiert um zu Testen ob er überhaupt die Erste Strecke findet--//
    
          L     #Anz_Punkt; 
    
    
          L     #Temp_distance;
    Geändert von Mare232 (26.08.2016 um 08:59 Uhr)
    Zitieren Zitieren Strecken finden aus Coordinaten eines LaserScanners  

  2. #2
    Registriert seit
    22.03.2007
    Ort
    Detmold (im Lipperland)
    Beiträge
    11.197
    Danke
    389
    Erhielt 2.296 Danke für 1.910 Beiträge

    Standard

    Hallo,
    also erstmal würde ich so etwas NICHT in AWL sondern besser in SCL lösen.
    Dann würde ich mir in einer Schleife die Gradientensprünge (ggf. als seperates Array) abbilden. Das geschieht in dem du den y-Unterschied zwischen benachbarenden Werten errechnest. Eventuell kann es hier allerdings sinnvoll sein, dass du nicht direkt nebeneinander liegende Werte betrachtest sondern in einem gröberen Raster.
    Dabei würde dann (je nach deiner Rechnung) in etwa so etwas dabei heraus kommen :

    __________
    _____ * * _____

    _____/\ _________/\ ___
    \/ \/


    Anhand der Gradientensprünge und deren Richtung kannst du nun die einzelnen Übergänge finden.
    Das sollte dann für eine 319 auch kein allzu großes Problem darstellen ...

    Gruß
    Larry

  3. Folgender Benutzer sagt Danke zu Larry Laffer für den nützlichen Beitrag:

    Mare232 (25.08.2016)

  4. #3
    Mare232 ist offline Neuer Benutzer
    Themenstarter
    Registriert seit
    19.01.2016
    Ort
    Irschenberg
    Beiträge
    4
    Danke
    3
    Erhielt 0 Danke für 0 Beiträge

    Standard

    Hi Larry,
    Erstmal danke für deine Antwort
    Hört sich recht vielversprechend an. Es giebt dabei leider nur ein kleines Problem.
    Ich habe leider null ahnung von Gradienten. Und deine Zeichung sagt mir leider auch nichts

    Vielleicht könntest du mir ja ein bsp geben. Ich hätte zwar schon Dr.Google gefragt aber anscheinend gibt bei Gradienten je nach anwendung ziemliche unterschieden

  5. #4
    Registriert seit
    29.03.2004
    Beiträge
    5.172
    Danke
    129
    Erhielt 1.506 Danke für 1.107 Beiträge

    Standard

    Was Larry mit Gradient wahrscheinlich meint ist, du sollst die Y Werte differenzieren, d.h. die 1. Ableitung von Y.
    Mit "Gradiendensprung" ist dann wohl die 2. Ableitung gemeint.
    Mit der 1. Ableitung bekommst du heraus wie schief dein Brett liegt (Steigung) mit der zweiten bekommst du die Enden des Bretts, d.h. wenn sich die Steigung ändert.
    Das ist dann aber sehr anfällig auf Rauschen. Ich habe sowas mal zur Erkennung eines bestimmten Signalverlaufs in der Prozesstechnik angewendet.

    Aber ich finde deinen eigenen Ansatz gar nicht verkehrt. Um das etwas zu beschleunigen könntest du das Prinzip der binären Suche anwenden. An deinem Startpunkt (z.B. die Mitte) wo du dir sicher bist, dass dort immer ein Brett liegt, stellst du dort die Steigung fest. Dann gehst du an die Außengrenzen und prüfst ob dort ebenfalls die Steigung ist, dann halbierst du die Strecke und setzt das Fenster weiter nach innen. Wenn du dort auf die gesuchte Steigung triffst, dann gehst du wieder um die halbe Strecke nach außen usw. Bei 750 Punkten bist du bei ca. 10 Schritten am Ziel.
    Die Genialität einer Konstruktion liegt in ihrer Einfachheit – Kompliziert bauen kann jeder.

    (Sergei Pawlowitsch Koroljow, sowjetischer Konstrukteur von Raketen und Weltraumpionier)

  6. Folgender Benutzer sagt Danke zu Thomas_v2.1 für den nützlichen Beitrag:

    Mare232 (26.08.2016)

  7. #5
    Registriert seit
    22.03.2007
    Ort
    Detmold (im Lipperland)
    Beiträge
    11.197
    Danke
    389
    Erhielt 2.296 Danke für 1.910 Beiträge

    Standard

    Zitat Zitat von Thomas_v2.1 Beitrag anzeigen
    Mit der 1. Ableitung bekommst du heraus wie schief dein Brett liegt (Steigung) mit der zweiten bekommst du die Enden des Bretts, d.h. wenn sich die Steigung ändert.
    Das ist dann aber sehr anfällig auf Rauschen
    Genau so hatte ich es gemeint.
    Das Rauschen lässt sich "unterdrücken" (also kontrollierbar halten) wenn man sich nicht auf direkt nebeneinander liegende Werte konzentriert sondern das Raster vergrößert. Das habe ich selbst schon für verschiedene Kurven so eingesetzt (und es hat die CPU, bei mir i.d.R. eine 317, nicht sonderlich belastet).

    Von der programmtechnischen Umsetzung sieht das so aus :
    Du durchläufst dein Array in einer Schleife und bildest immer eine Differenz der y-Werte von [i] und z.B. [i+5] und speicherst diese zunächst in einem seperaten Array ab (das hilft für das beurteilen).
    Das Ergebnis ist dann, dass du jeweils dort, wo sich die Steigung deiner Kurve ändert einen positiven bzw. negativen Ausschlag erhältst und dort, wo sich die Steigung nicht ändert, keine Werte (oder eben ein Rauschen) drin stehen hast.
    Mit meiner ASCII-Zeichen-Strichgrafik wollte ich das eigentlich darstellen - da hat mir die Forums-Software aber einen Strich durch die Rechnung gemacht.

    Gruß
    Larry

  8. Folgender Benutzer sagt Danke zu Larry Laffer für den nützlichen Beitrag:

    Mare232 (26.08.2016)

  9. #6
    Mare232 ist offline Neuer Benutzer
    Themenstarter
    Registriert seit
    19.01.2016
    Ort
    Irschenberg
    Beiträge
    4
    Danke
    3
    Erhielt 0 Danke für 0 Beiträge

    Standard

    Danke Larry und Thomas,
    Ihr habt mir beide sehr geholfen
    Ich probier mal heute das Programm zu machen und lass euch dann wissen wie es hingehauen hat.
    Euch beiden derweil noch einen schönen Tag
    Mfg
    Marinus

    Hier nochmal die Funktionsbeschreibung um zu überprüfen ob ichs richtig verstanden habe
    Code:
    Das Programm startet am Punkt A1(erster relevanter Punkt) und Berechent die 
    Steigung zum Punkt B1. Der Abstand von A1->B1 wird über die Aufösung, in 
    Netzwerk 2, bestimmt. Die Steigung wird in ein Array abgespeichert und der 
    Punkt A1 wird um eine Pos. weiter geschoben. Das Prozedere beginnt von vorne!
    Sind alle Punkt durch, so wird das Array ausgewertet und alle Steigungsgruppen zu einzelnen Strecken zusammengefasst.
    Geändert von Mare232 (26.08.2016 um 08:44 Uhr)

  10. #7
    Registriert seit
    22.03.2007
    Ort
    Detmold (im Lipperland)
    Beiträge
    11.197
    Danke
    389
    Erhielt 2.296 Danke für 1.910 Beiträge

    Standard

    So in etwa ...
    Möglicherweise musst du allerdings nicht die Steigung von Punkt A1 nach B1 und dann B1 nach C1 usw. berechnen sondern (und das musst du halt ausprobieren an Hand deiner Werte) vielleicht eher von A1 nach E1 und dann von B1 nach F1 usw.
    Du solltest aber auch in diesem Zusammenhang über SCL nachdenken ...

    Viel Erfolg ...

    Gruß
    Larry

  11. #8
    Mare232 ist offline Neuer Benutzer
    Themenstarter
    Registriert seit
    19.01.2016
    Ort
    Irschenberg
    Beiträge
    4
    Danke
    3
    Erhielt 0 Danke für 0 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Ja genau
    So hab ich das auch gemeint mit:
    Der Abstand von A1->B1 wird über die Aufösung, in
    Netzwerk 2, bestimmt.
    Ich gebe vor wie viele Punkte der Punkt B1 vom Punkt A1 entfernt ist.
    Code:
    //Auflösung festlegen (zwischen 0 - 20 empfohlen)   0 = max
          UN    #Extern_mode; 
          SPBN  m01; 
          L     450; 
          T     #min_laenge; 
    
          L     10; 
          T     #Aufloesung; 
    
          SPA   m02; 
    m01:  NOP   0; 
          L     #IN_min_laenge; 
          T     #min_laenge; 
    
    
          L     #IN_Aufloes; 
          T     #Aufloesung; 
    m02:  NOP   0;
    Zum Thema SCL: Kann ich nich
    Aber ich hab das Programm in AWL soweit schon fertig
    Ich werds Heute Nachmittag mal an der Anlage Testen.

    Nochmal Danke für die Hilfe

    Gruß
    Marinus

Ähnliche Themen

  1. 24VDC über große Strecken verteilen?!
    Von Krumnix im Forum Elektronik
    Antworten: 9
    Letzter Beitrag: 05.07.2016, 10:31
  2. Strecken Messung in einer Kartonagenmaschine
    Von sonic_229 im Forum Antriebstechnik
    Antworten: 8
    Letzter Beitrag: 09.07.2014, 14:25
  3. Ein Bit aus Doppelwort finden
    Von Flo im Forum Simatic
    Antworten: 8
    Letzter Beitrag: 15.04.2010, 23:37
  4. Aufruf eines DB`s finden
    Von Spud im Forum Simatic
    Antworten: 10
    Letzter Beitrag: 18.08.2008, 12:03
  5. Antworten: 16
    Letzter Beitrag: 02.02.2007, 19:13

Stichworte

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •