Fahrerloses Transportsystem bedient Förderbänder einer Fabrik (Robotics Smarttech)

Alles rund um TX(T) und RoboPro, mit ft-Hard- und Software
Computing using original ft hard- and software
Forumsregeln
Bitte beachte die Forumsregeln!
Benutzeravatar
uffi
Beiträge: 404
Registriert: 24 Jan 2014, 16:21
Wohnort: München

Fahrerloses Transportsystem bedient Förderbänder einer Fabrik (Robotics Smarttech)

Beitrag von uffi » 11 Nov 2023, 22:26

Liebe FT Community,

ich möchte Euch mein neues Modell vorstellen: Ein Fahrerloses Transportsystem, welches Förderbänder einer gedachten Fabrik bedient (Fahrzeug gebaut mit dem Set Robotics Smarttech).

Hier ein YouTube-Video: https://youtu.be/LIU9JJ0_3Zo?si=NVJtt3iuAgmvNWnU

Beschreibung:
in mit dem TXT gesteuertes Fahrzeug, welches Boxen 60x60x30 mm laden, transportieren und entladen kann, bedient 4 Förderbänder. Es gibt ein Förderband für den Wareneingang bzw. Anlieferung der Boxen (Station 1), zwei Förderbänder zur Bearbeitung der Boxen (Stationen 2 und 3) und ein Förderband zur Auslieferung (Station 4) bzw. zum Warenausgang. Auf dem Fahrzeug ist ein Rollenförderer installiert, mit dem die Boxen geladen und entladen werden können. Dieser Rollenförderer wird über zwei Federkontakte mit dem Förderband verbunden und über dessen Steuerung mit Spannung versorgt und gesteuert (da der TXT schon die 4 Motoren des Fahrzeugs versorgt und damit über keine weiteren Treiber zur Versorgung des Rollenförderers verfügt).
Die Stationen sind über Barcodes (4 vertikale Linien unterschiedlicher Breite) gekennzeichnet. Die Boxen sind über farbige Kreisflächen in rot und blau gekennzeichnet. Über die auf dem Fahrzeug angebrachte Kamera sollen die Stationen und die Boxen identifiziert werden.
Startposition bzw. initiale Parkposition für das Fahrzeug bei Programmstart ist direkt vor einer der Stationen (ohne Abstand). Im weiteren Verlauf bleibt das Fahrzeug immer direkt vor der zuletzt bedienten Station stehen (ohne Abstand). Sobald eine Box angeliefert wird, soll diese je nach Farbkennung an Station 2 (blau) oder 3 (rot) geliefert werden. Sobald die Bearbeitung dort abgeschlossen ist, soll die Box zur Position 4 gebracht werden.
Das Förderband der Station 1 ist mit einer Lichtschranke hinten ausgestattet. Sobald eine (von einem LKW entladene) Box auf das Förderband gestellt wird, wird diese weiter transportiert, bis die Lichtschranke wieder frei ist. Die Förderbänder der Stationen 2 und 3 sind mit je einem Taster zur Betätigung durch das Personal und je einer Lichtschranke vorne ausgestattet, um die Box für die Abholung durch das Transportfahrzeug nach vorne fahren zu lassen (wird durch den Taster gestartet) und um das Erreichen der Zielposition der Box zu erfassen (durch die unterbrochene Lichtschranke). Sobald die Box vom Förderband nach vorne zur Lichtschranke transportiert wurde, wird dies dem Fahrzeug durch ein per Infrarotlicht übermitteltes Kommando mitgeteilt. Das Kommando beinhaltet die Information, an welcher Station die Box abgeholt werden soll (1, 2 oder 3). Das Ziel ergibt sich für Abholung von Station 1 aus der Farbmarkierung der Box. Im Falle der Stationen 2 oder 3 ist das Ziel immer die Station 4. An Station 4 werden die Boxen imaginär von einem externe Lkw abgeholt. Hier befindet sich eine Lichtschranke am Ende des Förderbandes, die das Förderband abschaltet. Daraus folgt, das die Förderbänder 1 und 4 nur in eine Richtung laufen, während 2 und 3 in beide Richtungen laufen können. Damit bleiben zwei Ausgangstreiber des Controllerboards mit AVR ATMEGA644 und 2x L293D frei für andere Zwecke.
Zur Steuerung der Förderbänder wird ein Board mit ATMEGA644 mit 16 Ein-/Ausgängen (5V, max 20mA) und 8 Ausgängen für 4 Motoren (9V, max 600mA) genutzt. Beim Ankoppeln des Transportfahrzeuges an eine Station wird ein Taster unter dem Förderband betätigt. Daraufhin wird der Ladevorgang gestartet.

Beschreibung eines beispielhaften Ablaufs:
1. Eine Box wird auf das Förderband F1 der Station 1 geladen. Die Lichtschranke L1 wird unterbrochen. Daraufhin wird ein Infrarot-Kommando „1“ abgesetzt und das Fahrzeug steuert die Station 1 an. Gleichzeitig transportiert das Förderband die Box B nach vorne, bis die Lichtschranke wieder frei ist. Erneut wird überprüft, ob sich das Fahrzeug an Station 1 befindet (Abfrage Taster T1). Falls nicht, wird nochmals ein Infrarot-Kommando „1“ abgesetzt. Diese Abfrage und das Senden des Kommandos wird regelmäßig wiederholt, bis das Fahrzeug an Station 1 angedockt hat.
2. Sobald das Fahrzeug an Station 1 angedockt hat (Taster T1 betätigt wurde), wird per Infrarot ein Stop-Kommando vom AVR an den TXT gesendet und das Förderband F1 und der Rollenförderer werden gestartet und die Box wird auf das Transportfahrzeug geladen. Dieser Vorgang wird nach 3s beendet (Timer im AVR und auch im TXT).
3. Daraufhin steuert das Fahrzeug die Ziel-Station an (2 oder 3, je nach erkannter Farbe der Box). Sobald der Taster T2 oder T3 an der Zielstation betätigt wurde, wird ein Stop-Kommando per Infrarot vom AVR an den TXT gesendet und das Förderband F2 oder F3 zum Entladen in Gang gesetzt. Dieser Vorgang wird nach Freigabe der Lichtschranke L2 oder L3 beendet.
4. Sobald die Box an Station 2 oder 3 fertig bearbeitet wurde, betätigt ein imaginärer Arbeiter den jeweiligen Taster. Dann erfolgt der gleiche Ablauf mit Abholen der Box an Station 2 oder 3 und Abliefern der Box an Station 4.

Gruß, uffi
DSC_3674_small.jpg
DSC_3674_small.jpg (169.09 KiB) 2990 mal betrachtet

Benutzeravatar
Widi
Beiträge: 59
Registriert: 04 Mär 2019, 22:00

Re: Fahrerloses Transportsystem bedient Förderbänder einer Fabrik (Robotics Smarttech)

Beitrag von Widi » 12 Nov 2023, 08:44

Hallo uffi
Ein tolles Projekt super umgesetzt,die Idee :idea: die Präzision der Anfahrt einfach nur Klasse :D
macht Lust zum Nachbau ;)

gruss widi

Benutzeravatar
fishfriend
Beiträge: 1822
Registriert: 26 Nov 2010, 11:45

Re: Fahrerloses Transportsystem bedient Förderbänder einer Fabrik (Robotics Smarttech)

Beitrag von fishfriend » 12 Nov 2023, 18:35

Hallo...
Schönes Modell.
Ich bin an etwas ähnlichem. Ich versuche mich an der "Agile Production Simulation" allerdings in 9V.
Dazu hab ich mir auch das Fahrzeug gebaut, allerdings mit einem TXT.

Wie machst du den die Korrektur der Position? Über die Kamera mit dem Barcode?
Hast du ein fertiges Programm als Vorlage genommen oder damit angefangen?

Ich vermute mal der Grundaufbau vom Fahrzeug kommt vom Sarttech. Gehst du da über die Synchronisation der Motoren oder hast du einen eigenen PID Regler genommen? Es sieht sehr geradlinig aus. Richtig gut.
Ich kämpfe gerade mit Fliesen, wo nicht so gerade wird. Ich denke aber, dass es mit dem Linienfolger besser wird, da ja nur an den Stationen ausgerichtet wird.

Mit freundlichen Grüßen
Holger
ft Riesenräder PDF: ftcommunity.de/knowhow/bauanleitungen
TX-Light: Arduino und ftduino mit RoboPro

Benutzeravatar
uffi
Beiträge: 404
Registriert: 24 Jan 2014, 16:21
Wohnort: München

Re: Fahrerloses Transportsystem bedient Förderbänder einer Fabrik (Robotics Smarttech)

Beitrag von uffi » 12 Nov 2023, 20:05

@Widi: vielen Dank für Deine wertschätzenden Worte, eine ganz tolle Rückmeldung! Die Präzision müsste durchaus noch verbessert werden bzw. etwas zuverlässiger gemacht werden, da es ab und zu schon auch mal ein paar Millimeter zu weit daneben positioniert wird, so dass sich die Box beim Laden/Entladen verkantet.

@fishfriend: Danke für Dein Interesse und Deine Rückmeldung zur Geradeausfahrt. Sehr interessant, auch von Deinen Plänen zu erfahren.
Zu Deinen Fragen:
1) Die Ausrichtung des Fahrzeugs vor den Stationen mache ich über die Summe der Positionen der beiden äußeren Streifen 1 und 4 (Referenzposition 0 ist in der Mitte).
2) Ich habe das RoboPro-Programm komplett neu erstellt. Bei Interesse kann ich das hier gerne posten.
3) Du hast richtig vermutet, das Fahrzeug basiert auf dem vierrädrigen Modell aus dem Set Robotics Smarttech.
4) Ich nutze die Synchronisierung aller 4 Motoren in RoboPro mit den 4 Zählereingängen am TXT. Im Detail habe ich das in diesem Video hier gezeigt:

https://youtu.be/xs11Yvi_T0o?si=8FU6xOH1Mn_jfVCc

Gruß, uffi

DirkW
Moderator
Beiträge: 550
Registriert: 10 Nov 2014, 16:16

Re: Fahrerloses Transportsystem bedient Förderbänder einer Fabrik (Robotics Smarttech)

Beitrag von DirkW » 14 Nov 2023, 10:12

Hallo Uffi,

klasse Projekt. :D

Am besten gefällt mir, das du die Kamera mit Barcode eingebunden hast.
Somit könntest du z.B. auch die Industrieanlage zur Versorgung des Hochregallager mit einbinden etc.

Grüße
Dirk

Benutzeravatar
uffi
Beiträge: 404
Registriert: 24 Jan 2014, 16:21
Wohnort: München

Re: Fahrerloses Transportsystem bedient Förderbänder einer Fabrik (Robotics Smarttech)

Beitrag von uffi » 22 Nov 2023, 11:14

@DirkW

Danke für die Blumen, Dirk! :D
Es freut mich sehr, dass Dir das Modell gefällt und dass Du diese Nutzung der Kamera zur Identifikation der Stationen besonders magst.
Danke nochmal für den Verkauf Deiner USB-Kamera an mich, die hier zum Einsatz kam.

Gruß, uffi

Benutzeravatar
fishfriend
Beiträge: 1822
Registriert: 26 Nov 2010, 11:45

Re: Fahrerloses Transportsystem bedient Förderbänder einer Fabrik (Robotics Smarttech)

Beitrag von fishfriend » 25 Nov 2023, 14:35

Hallo...
Ich dachte, ich hätte es verstanden - aber...
Im Video (ab 1.05 min) ist das Unterprogramm Fahren.
Sehe ich das richtig, dass der Motor 1 nicht mit den anderen Motoren sychronisiert ist?
Oder hab ich jetzt einen Denkfehler, weil alle anderen auch die gleiche Distanz bekommen.

Bei meinem Projekt mache ich große Vortschritte. Hab aber auch Probleme u.a. mit genau dem Querverfahren.
Es kommt u.a. darauf an, wie weit die Z10 auf den Encodermotoren sind. Dadurch hab ich am Modell schon eine große Abweichung.
Auch die Akkuspannung spielt eine Rolle. Deswegen ich als erstes nun die Ladestation baue.
Du hast an deinem Modell den Vorteil mit den Kran und der Kabelführung.

Mit freundlichen Grüßen
Holger
ft Riesenräder PDF: ftcommunity.de/knowhow/bauanleitungen
TX-Light: Arduino und ftduino mit RoboPro

Benutzeravatar
uffi
Beiträge: 404
Registriert: 24 Jan 2014, 16:21
Wohnort: München

Re: Fahrerloses Transportsystem bedient Förderbänder einer Fabrik (Robotics Smarttech)

Beitrag von uffi » 25 Nov 2023, 15:52

Hallo Holger,

ich habe das so verstanden, dass es ausreicht, die Motoren 2-4 auf den Motor 1 zu synchronisieren. Damit laufen dann alle vier Motoren synchron. Zumindest ist es in der Hilfe von RoboPro so beschrieben.

Gruß, Dirk

Benutzeravatar
fishfriend
Beiträge: 1822
Registriert: 26 Nov 2010, 11:45

Re: Fahrerloses Transportsystem bedient Förderbänder einer Fabrik (Robotics Smarttech)

Beitrag von fishfriend » 25 Nov 2023, 19:28

Hallo...
Von der Richtung her, kommt der Syncronisationsbefehl nicht am Motor 1 an.

Ich hab das gerade noch mal ausprobiert. Es ist scheinbar so, das der Motor 1 bei deinem Modell halt so gut läuft, das er im Takt bleibt.
Bei meinem Modell nicht :-(
Aber OK ich nehm den einfach mit rein und probier weiter.
Ich hab ja noch andere Probleme -ähm- Herausforderungen zu lösen :-)
Mit freundlichen Grüßen
Holger
ft Riesenräder PDF: ftcommunity.de/knowhow/bauanleitungen
TX-Light: Arduino und ftduino mit RoboPro

Benutzeravatar
fishfriend
Beiträge: 1822
Registriert: 26 Nov 2010, 11:45

Re: Fahrerloses Transportsystem bedient Förderbänder einer Fabrik (Robotics Smarttech)

Beitrag von fishfriend » 25 Nov 2023, 19:59

Hallo...
Also Syncron 1 an M2, M3 und M4, soll alle Motoren Sycron laufen lassen.
Irgendwas mache ich falsch...
Mit freundlichen Grüßen
Holger
ft Riesenräder PDF: ftcommunity.de/knowhow/bauanleitungen
TX-Light: Arduino und ftduino mit RoboPro

Benutzeravatar
fishfriend
Beiträge: 1822
Registriert: 26 Nov 2010, 11:45

Re: Fahrerloses Transportsystem bedient Förderbänder einer Fabrik (Robotics Smarttech)

Beitrag von fishfriend » 25 Nov 2023, 23:49

Hallo...
Ich hab schon mal ein paar Fehler bei mir gefunden, die so nicht sofort auffallen.
1. Die Naben waren nur 97% bombenfest.
2. Schwerer Fehler bei meiner Regelung.
Um an der Wand, zwei Taster gedrückt zu halten, hab ich bei der Korrektur die falsche Richtung programmiert.
Das führte dazu, dass der Roboter erst auch den zweiten Taster von der Wand löste um dann wieder mit beiden Tastern kontakt zu bekommen. Das fiel sonst nicht auf.
3. Mit dem Gleichlauf und einer Regelung hab ich aufgegeben. Ich lasse nun auf einer Seite, einen Motor um eine Stufe schneller drehen. Dadurch ist der Andruck größer.
Das klappt nun besser als beim Original im ft-Video.
Wahrscheinlich könnte man das durch eine Regelung noch besser hin bekommen, aber z.B. der Hub der Taster alleine, führt zu einer Ungenauigkeit. Wenn nun der Greifer das Bauteil nimmt oder absetzt, ist das so gerade in der Toleranz der unteren Fase am Bauteil.
Das Lustige ist, genau das gleiche Problem hat ft in ihrem Modell. In einem neuen Video von einer SPS Messe, gibt es ein Interview wo im Vordergrund die Anlage läuft und der Greifer - ich sag mal mit leichter Gewallt, den Baustein auf den Roboter absetzt. Es ist tatsächlich zu hören.
Mit freundlichen Grüßen
Holger
ft Riesenräder PDF: ftcommunity.de/knowhow/bauanleitungen
TX-Light: Arduino und ftduino mit RoboPro

Benutzeravatar
uffi
Beiträge: 404
Registriert: 24 Jan 2014, 16:21
Wohnort: München

Re: Fahrerloses Transportsystem bedient Förderbänder einer Fabrik (Robotics Smarttech)

Beitrag von uffi » 07 Jan 2024, 18:27

Hallo Community,

ich habe mein Modell umgebaut:

Im Vergleich zur vorherigen Version wird hier das Fahrerlose Transport System FTS mit Python + OpenCV vom PC aus über WLAN mit dem TXT im Online Modus gesteuert (Netzwerkverbindung über die Community Firmware CFW für den Fischertechnik TXT Controller). Statt der Barcodes in der vorherigen Version wird nun eine Ziffernerkennung an den Stationen genutzt. Die Anfahrt zur Station erfolgt mit einer PD Regelung der Motorleistung auf die Position der Ziffer im Kamerabild.

Hier gibt es ein Video der neuen Version:
https://youtu.be/tBlB3YD43_A

Der erste Teil zeigt Video-Aufnahmen mit einer Vollformat-35mm-Kamera montiert auf einem Gimbal, der mittlere Teil mit derselben Kamera montiert auf einem Stativ und der letzte Teil zeigt Mitschnitte der USB-Kamera auf dem FTS inklusive Ergebnisanzeige der Bildverarbeitung.

Und hier der Python Code, der auf dem PC läuft:

Code: Alles auswählen

from __future__ import print_function
import cv2 as cv
import numpy as np
import ftrobopy
import time

###########################################################################

vref1 = np.array ([[  0,   0,   0,   0,   0, 255, 255,   0,   0,   0,   0,   0,   0,   0,   0,   0],
                   [  0,   0, 255, 255, 255, 255, 255,   0,   0,   0,   0,   0,   0,   0,   0,   0],
                   [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
                   [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]])

vref2 = np.array ([[  0, 255, 255, 255, 255,   0,   0,   0,   0,   0,   0,   0, 255, 255, 255, 255],
                   [255, 255, 255, 255, 255,   0,   0,   0, 255, 255, 255, 255, 255, 255, 255, 255],
                   [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,   0,   0, 255, 255, 255],
                   [  0, 255, 255, 255, 255, 255, 255, 255,   0,   0,   0,   0,   0, 255, 255, 255]])

vref3 = np.array ([[  0, 255, 255, 255,   0,   0,   0,   0,   0,   0,   0,   0, 255, 255, 255,   0],
                   [255, 255, 255, 255,   0,   0, 255, 255, 255,   0,   0,   0, 255, 255, 255, 255],
                   [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
                   [  0,   0, 255, 255, 255,   0,   0,   0, 255, 255, 255, 255, 255, 255,   0,   0]])

vref4 = np.array ([[  0,   0,   0,   0,   0,   0,   0, 255, 255, 255, 255, 255, 255,   0,   0,   0],
                   [  0,   0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,   0,   0,   0],
                   [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
                   [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]])

###########################################################################

def detectFigures():
    station = 0
    position = 0
    while True:
        jpg = txt.getCameraFrame()
        if jpg == None:
            continue
        else:
            break

    frame = cv.imdecode(np.frombuffer(bytearray(jpg)), cv.IMREAD_COLOR)
    roi = frame[20:160, 80:240]
    mask = cv.cvtColor(roi, cv.COLOR_BGR2GRAY)
    ret, thresh = cv.threshold(mask, 70, 255,cv.THRESH_BINARY_INV)
    contours,hierarchy = cv.findContours(thresh,2,cv.CHAIN_APPROX_SIMPLE)

    if len(contours):
        cont = max (contours, key = cv.contourArea)
        cont = cont + (80, 20)
        cv.drawContours(frame, [cont], 0, (0,255,0), 1)
        x,y,w,h = cv.boundingRect(cont)
        position = x + int(w/2)
        if 100 < position < 220:
#            x = x-int((h-w)/2)
            x_roi = x-80
            y_roi = y-20
            roi = thresh[y_roi:y_roi+h, x_roi:x_roi+w]
            resized = cv.resize(roi,(16,16),interpolation=cv.INTER_AREA)
            ret, thresh_resized = cv.threshold(resized, 127, 255,cv.THRESH_BINARY)
            resized = thresh_resized
#            cv.imshow('resized',resized)
            slice1 = resized[:,0:4]
            slice2 = resized[:,4:8]
            slice3 = resized[:,8:12]
            slice4 = resized[:,12:16]
            proj1 = np.amax(slice1, axis=1)
            proj2 = np.amax(slice2, axis=1)
            proj3 = np.amax(slice3, axis=1)
            proj4 = np.amax(slice4, axis=1)
            projection = np.array([proj1, proj2, proj3, proj4])
#            print(projection)   
            error = np.array([255, 255, 255, 255])
            error[0] = (projection != vref1).sum()
            error[1] = (projection != vref2).sum()
            error[2] = (projection != vref3).sum()
            error[3] = (projection != vref4).sum()
#            print ("error", error.min())

            if error.min() < 10:
                station = np.argmin(error)
                station = station + 1
                frame = cv.putText(frame, str(station), (x+w+5, y+5), cv.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 1, cv.LINE_AA) 
                frame = cv.putText(frame, str(position), (x+w+5, y+h), cv.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 255), 1, cv.LINE_AA) 

#    print(station)
    cv.imshow('frame', frame)
    cv.waitKey(1)
    out.write(frame)
    return position, station

#########################################
# function to detect red or blue boxes
# return values are
# 0: no Box color detected
# 2: red Box detected
# 3: blue Box detected
##########################################

def detectBoxColor():
    x1, x2, y1, y2 = 170, 186, 186, 190
    tnoce = int (8*(x2-x1)*(y2-y1)/10)
    # noce is target number of correct elements
    # > 80% of elements should be in range

    while True:
        jpg = txt.getCameraFrame()
        if jpg == None:
            continue
        else:
            break

    frame = cv.imdecode(np.frombuffer(bytearray(jpg)), cv.IMREAD_COLOR)
    roi = frame[y1:y2, x1:x2]
    hsv = cv.cvtColor(roi, cv.COLOR_BGR2HSV)
    hue = hsv[:, :, 0]
#    print ('hue')
#    print(hue)
    result2 = np.count_nonzero((hue >= 160) | (hue <= 20))
#    print ('result for red', result2)
    result3 = np.count_nonzero((hue >= 80) & (hue <= 140))
#    print ('result for blue', result3)

    if result2 > tnoce:
        color = 'red'
        result = 2
    elif result3 > tnoce:
        color = 'blue'
        result = 3
    else:
        color = 'no box'
        result = 0

    frame = cv.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 1)
    frame = cv.putText(frame, color, (x2+5, y2), cv.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 1, cv.LINE_AA) 
    cv.imshow('frame', frame)
    cv.waitKey(1)
    out.write(frame)
#    print (color)
    return result

###########################################################################

def displayCam():
    while True:
        jpg = txt.getCameraFrame()
        if jpg == None:
            continue
        else:
            break

    frame = cv.imdecode(np.frombuffer(bytearray(jpg)), cv.IMREAD_COLOR)
    cv.imshow('frame', frame)
    cv.waitKey(1)
    out.write(frame)

#########################################################
# function to drive in sync to a distance
# m1 and m2 are on the front axis
# m3 and m4 are on the rear axis
# for drive to the left m2 and m3 must go forward
# for drive to the right m1 and m4 must go forward
#########################################################

def drive(distance, power_m1m4, power_m2m3):
    txt.SyncDataBegin()
    m1.setDistance(distance, syncto=m2)
    m2.setDistance(distance, syncto=None)
    m3.setDistance(distance, syncto=m4)
    m4.setDistance(distance, syncto=m2)
    txt.incrMotorCmdId(1)
    txt.incrMotorCmdId(2)
    txt.incrMotorCmdId(3)
    txt.incrMotorCmdId(4)
    m1.setSpeed(power_m1m4)
    m2.setSpeed(power_m2m3)
    m3.setSpeed(power_m2m3)
    m4.setSpeed(power_m1m4)
    txt.SyncDataEnd()
    while not (m1.finished() and m2.finished() and m3.finished() and m4.finished()):
        displayCam()
        txt.updateWait()
    txt.stopAll()
    txt.updateWait()
    d = txt.getCurrentCounterValue()
    print(d)
    
#########################################################
# function to drive aligned to position of figure
# m1 and m2 are on the front axis
# m3 and m4 are on the rear axis
# for drive to the left m2 and m3 must go forward
# for drive to the right m1 and m4 must go forward
#########################################################

def driveFigure(distance, power_m1m4, power_m2m3):
    position_old, station = detectFigures()
    while station == 0:
        position_old, station = detectFigures()

    txt.SyncDataBegin()
    m1.setDistance(distance, syncto=m4)
    m2.setDistance(distance, syncto=None)
    m3.setDistance(distance, syncto=m2)
    m4.setDistance(distance, syncto=None)
    txt.incrMotorCmdId(1)
    txt.incrMotorCmdId(2)
    txt.incrMotorCmdId(3)
    txt.incrMotorCmdId(4)
    m1.setSpeed(power_m1m4)
    m2.setSpeed(power_m2m3)
    m3.setSpeed(power_m2m3)
    m4.setSpeed(power_m1m4)
    txt.SyncDataEnd()
    irStatusTaster = txt.joystick(1,0,0)

    while not (m1.finished() and m2.finished() and m3.finished() and m4.finished()):
        if irStatusTaster.updown():
            break
        position, station = detectFigures()
        while station == 0:
            position, station = detectFigures()
        print (position, station)

# PD control for driving aligned to position of figure

        p = position - 180
        d = position - position_old
        position_old = position
        print ('p=', p, 'd=', d)
        pwm = power_m1m4 + 4*p + 4*d
        
        if pwm > -384:
                pwm = -384
        elif pwm < -512:
                pwm = -512

        print ('pwm', pwm)
        m1.setSpeed(pwm)
        m4.setSpeed(pwm)
        txt.updateWait()

    starttime = time.time()
    while (time.time() < starttime + 0.5):
        displayCam()

    txt.stopAll()
    txt.updateWait()
    d = txt.getCurrentCounterValue()
    print(d)

###########################################################################
# function to connect to station and load or unload boxes
# input: none
# output: color of box (only for station 1)
###########################################################################

def connect():
    position, station = detectFigures()
    while station == 0:
        position, station = detectFigures()
    print ("Station", station, "Position", position)
    while ((station) and (position > 188)):
        steps = int((position - 180)/8)
        drive (steps, 340, 340)
        position, station = detectFigures()
        print ("Station", station, "Position", position)
    while ((station) and (position < 172)):
        steps = int((180 - position)/8)
        drive (steps, -340, -340)
        position, station = detectFigures()
        print ("Station", station, "Position", position)
    color = 0
    if station == 1:
        while color == 0:
            color = detectBoxColor()
    else:
        color = 4

    driveFigure(64, -448, 448)
    starttime = time.time()
    while (time.time() < starttime + 3):
        displayCam()
    drive (42, 448, -448)    
    return color

###########################################################################
# function to drive to target station
# input: command = target station
# output: none
###########################################################################

def driveStation(command):
    position, actualStation = detectFigures()
    while actualStation == 0:
        position, actualStation = detectFigures()

    print('actualStation=', actualStation, 'command=', command)
    
    if command > actualStation:
        distance = 60*(command - actualStation)
        drive(distance, 340, 340)
    elif command < actualStation:
        distance = 62*(actualStation - command)
        drive(distance, -340, -340)

###########################################################################
# Main Program
###########################################################################

txt=ftrobopy.ftrobopy('192.168.2.105')
txt.startCameraOnline()
time.sleep(3)
m1=txt.motor(1)
m2=txt.motor(2)
m3=txt.motor(3)
m4=txt.motor(4)

fourcc = cv.VideoWriter_fourcc(*'X264')
out = cv.VideoWriter('FT_Cam.mp4',fourcc, 10.0, (320,240))

irCommand = txt.joystick(0,0,0)
# left joystick is used

while True:
    detectFigures()
    command = int (-15 * irCommand.leftright())
    if command:
        driveStation (command)
        command = connect()
        print('delivery=', command)
        driveStation (command)
        connect()

    if cv.waitKey(1) & 0xFF == ord('q'):
        break

    txt.updateWait()

txt.stopCameraOnline()
txt.stopOnline()
out.release()
cv.destroyAllWindows()
DSC_4179.jpg
DSC_4179.jpg (164.92 KiB) 1477 mal betrachtet
Gruß, uffi

Benutzeravatar
uffi
Beiträge: 404
Registriert: 24 Jan 2014, 16:21
Wohnort: München

Re: Fahrerloses Transportsystem bedient Förderbänder einer Fabrik (Robotics Smarttech)

Beitrag von uffi » 09 Jan 2024, 18:15

Falls sich jemand für die Methode zur Erkennung der Ziffern interessiert, die habe ich aus diesem Artikel, der online frei verfügbar ist (keine Anmeldung, keine Gebühr):

"Rapid Feature Extraction for Optical Character Recognition"

Link:

https://arxiv.org/abs/1206.0238

Zunächst wird das Rechteck um die extrahierte Contour auf die Größe 16x16 Pixel skaliert. Dann wird dieses 16x16 Feld in 4 gleichbreite Säulen zerteilt und die Pixel in jeder Säule auf die jeweilige Seite der Säule projiziert. Diese Projektion wird dann mit den zuvor ermittelten Referenzen verglichen. Ich finde das ist eine interessante Methode für OCR.

Hier ein Beispiel mit 3 Säulen:
projection.PNG
projection.PNG (4.82 KiB) 1338 mal betrachtet
Dadurch brauche ich keine Python OCR Library.

juh
Beiträge: 907
Registriert: 23 Jan 2012, 13:48

Re: Fahrerloses Transportsystem bedient Förderbänder einer Fabrik (Robotics Smarttech)

Beitrag von juh » 10 Jan 2024, 18:36

Hallo Uffi,
sehr interessant, danke für den Hinweis. Wie bist du auf diese Arbeit aufmerksam geworden?
vg
Jan

Benutzeravatar
uffi
Beiträge: 404
Registriert: 24 Jan 2014, 16:21
Wohnort: München

Re: Fahrerloses Transportsystem bedient Förderbänder einer Fabrik (Robotics Smarttech)

Beitrag von uffi » 11 Jan 2024, 16:31

Hallo juh,

ich hatte zunächst vor, eine OCR library (ich glaube es war easyOCR) zu nutzen. Dies war jedoch nicht erfolgreich, da nach der vollständigen Installation der Lib beim ersten Start des Python Programms beim Import der Lib immer ein endloser Download von irgendwelchen Dateien aus dem Internet gestartet wurde, der dann mit einem Fehler abgebrochen wurde.

Daher habe ich mich bei meinen Recherchen auf möglichst simple Feature Extraction nur auf Basis von OpenCV fokussiert und bin mit dem Artikel fündig geworden.

Gruß, uffi

Benutzeravatar
uffi
Beiträge: 404
Registriert: 24 Jan 2014, 16:21
Wohnort: München

Re: Fahrerloses Transportsystem bedient Förderbänder einer Fabrik (Robotics Smarttech)

Beitrag von uffi » 14 Jan 2024, 14:46

Frage an die Community:

Hat schon jemand hier eine OCR library für Python auf dem PC zum laufen gebracht?

Falls ja, welche?

Danke und Gruß,uffi

atzensepp
Beiträge: 660
Registriert: 10 Jul 2012, 21:40
Wohnort: Uttenreuth

Re: Fahrerloses Transportsystem bedient Förderbänder einer Fabrik (Robotics Smarttech)

Beitrag von atzensepp » 14 Jan 2024, 16:09

Hallo Uffi,

unter Linux verwende ich bisweilen pytesseract, was ganz gut funktioniert. Nur Vorzeichen klappen nicht bei mir.

https://pypi.org/project/pytesseract/

Hier ein Beispiel:

Code: Alles auswählen


crop_img = gray[50:380, 600:1000]
cv2.imshow("temperatures", crop_img)
cv2.waitKey(0)
gray=crop_img
gray = cv2.GaussianBlur(gray, (5,5),0)

# Apply thresholding to preprocess the image
ret,thresh = cv2.threshold(gray, 120 , 255, 0) #cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
cv2.imshow("Bild",thresh)
cv2.waitKey(0)
# Apply OCR to extract the numbers from the image
numbers = pytesseract.image_to_string(thresh, config='--psm 6 outputbase digits')

# Print the extracted numbers
print(numbers)
               
Edit: Beispiel
Raw-Bildausschnitt von der Camera
Raw-Bildausschnitt von der Camera
Bildschirmfoto vom 2024-01-15 18-25-56.png (97.09 KiB) 927 mal betrachtet
&quot;gethreasholdeter&quot; Bildausschnitt
"gethreasholdeter" Bildausschnitt
Bildschirmfoto vom 2024-01-15 18-26-17.png (15.35 KiB) 927 mal betrachtet
Ausgabe Pytesseract
Ausgabe Pytesseract
Bildschirmfoto vom 2024-01-15 18-26-39.png (8.09 KiB) 927 mal betrachtet

Benutzeravatar
uffi
Beiträge: 404
Registriert: 24 Jan 2014, 16:21
Wohnort: München

Re: Fahrerloses Transportsystem bedient Förderbänder einer Fabrik (Robotics Smarttech)

Beitrag von uffi » 16 Jan 2024, 17:38

Hallo atzensepp,

danke für Deine ausführliche und beeindruckende Antwort! Ein tolles funktionierendes Beispiel.

Dann werde ich pytesseract mal ausprobieren. Fragen dazu:

1. Geht mit der Installation auch eine Modifikation von openCV einher (so war es bei easyOCR)?
2. Wird auch pytorch benötigt wie bei easyOCR?

Danke und Gruß, uffi

atzensepp
Beiträge: 660
Registriert: 10 Jul 2012, 21:40
Wohnort: Uttenreuth

Re: Fahrerloses Transportsystem bedient Förderbänder einer Fabrik (Robotics Smarttech)

Beitrag von atzensepp » 16 Jan 2024, 19:54

Hallo Uffi,

pytesseract ist ein Wrapper, der Tesseract als externes Programm aufruft.
Ich habe es gerade mal unter Windows mit Python 3.10.9 probiert:
  • Installation von Tesseract-OCR
  • pip install opencv-python
  • pip install pytesseract
Links: Unter Linux ist die Installation auch sehr unproblematisch.

Benutzeravatar
uffi
Beiträge: 404
Registriert: 24 Jan 2014, 16:21
Wohnort: München

Re: Fahrerloses Transportsystem bedient Förderbänder einer Fabrik (Robotics Smarttech)

Beitrag von uffi » 21 Jan 2024, 16:11

Hallo atzensepp,

danke für Deine detaillierten Tipps. Die Installation von pytesseract hat damit geklappt. Für meinen Anwendungsfall bin ich allerdings ein wenig enttäuscht. Ich habe es mit folgendem Code versucht, roi ist bereits der genau um die Ziffer ausgeschnittene, rechteckige Bereich, der auf Schwarz-Weiß geschwellt wurde:

Code: Alles auswählen

            custom_config = r'--oem 3 --psm 10 -c tessedit_char_whitelist=1234'
            # Apply OCR to extract the numbers from the image
            number = pytesseract.image_to_string(roi, config=custom_config)
            # Print the extracted number
            print('pt OCR', number)
--psm 10 ist der page segmentation mode 10, bei dem eine einzelne Ziffer angenommen wird.

Damit werden die einzelnen Zahlen nur ca. jedes 2. bis 3. mal überhaupt erkannt (bei stehendem FTS) und es gibt auch Fehlerkennungen der '1' als '4'. Das ist mir so zu unzuverlässig und deutlich schlechter, als meine Methode.

Mache ich da noch was falsch? Klappt es mit Grauwerten besser? oder mit Blur?

Danke und Gruß, uffi

Antworten