Wie schreibe ich Komponententests für Roboter (und andere mechanische Geräte)?

22

Ich bin Mitglied des Robotikclubs meiner High School und für die Programmierung des Roboters verantwortlich. Ein Vorschlag, den ich immer wieder von Erwachsenen höre, ist, dass ich Unit-Tests schreiben sollte, um meinen Code zu validieren. Die Codebasis wird immer größer, und ich stimme zu, dass Unit-Tests sehr hilfreich wären, um Fehler schneller zu erkennen.

Ich bin mir jedoch nicht ganz sicher, wie ich das erreichen könnte. Meines Wissens wird ein Unit-Test durchgeführt, indem eine Funktion (oder ein Teilsystem des Codes) einer Reihe von Eingaben zugeführt wird, um sicherzustellen, dass jedes Mal dieselbe Ausgabe ausgegeben wird. Der Code, den ich derzeit habe, verarbeitet keine großen Datenmengen, sondern bearbeitet die Hardwarekomponenten des Roboters direkt. Die meiste Komplexität entsteht dadurch, dass sichergestellt wird, dass die Elektronik einwandfrei ist, der Code im Moment mit der tatsächlichen Hardware des Roboters übereinstimmt usw. Oft kann ich nur feststellen, ob es ein Problem gibt, indem ich den Code in den Roboter selbst lade. und versuchen, es auszuführen.

Wie können Komponententests für Code geschrieben werden, mit dem ein mechanisches Gerät bedient werden kann? Es scheint mir, dass Sie Fehler nur feststellen können, wenn Sie den Betrieb der Maschine beobachten.

Oder missverstehe ich nur, wie Unit-Tests funktionieren sollten?

( Wenn es darauf ankommt, hier ist der Code , er ist in C ++ geschrieben und ich nehme an FRC teil. )

Michael0x2a
quelle

Antworten:

21

Sie müssen die Hardwareschicht verspotten , um diesen Test durchzuführen. Anstatt dass Ihr Code mit der eigentlichen Hardware kommuniziert, sprechen Sie mit einer gefälschten Version der Hardware, die Sie steuern und anschließend verwenden können, um zu überprüfen, ob Ihr Code ordnungsgemäß funktioniert.

Leider gibt es einige Probleme, die Sie überwinden müssen:

  • Es ist schwieriger, Dinge in relativ einfachen Sprachen zu verspotten (und damit viel mehr Arbeit)
  • Es ist schwieriger, Dinge auf Hardware-Ebene zu verspotten (und damit viel mehr Arbeit)

Der größte Vorteil automatisierter Komponententests besteht darin, dass Sie Ihre Tests jederzeit ausführen können, um nach dem Schreiben des Originalcodes für längere Zeit Regressionsfehler zu erkennen. Bei diesen Arten von Wettbewerben wird Ihr Code nach dem Ende des Wettbewerbs überhaupt nicht mehr verwendet, sodass Sie den größten Teil des Werts der Tests nicht wirklich erhalten. In Anbetracht der Schwierigkeit, Tests zu Ihrem speziellen Fall hinzuzufügen, ist es möglicherweise besser, Ihre Zeit nur für manuelle Tests zu nutzen und sich auf die Funktionen für den Wettbewerb zu konzentrieren.

Oleksi
quelle
1
Gute Antwort. Besonders die Tatsache, dass der Code nach dem Wettbewerb nicht mehr verwendet wird und der große Vorteil automatisierter Komponententests erst nach dem Schreiben der Tests zum Tragen kommt. Sie könnten in Betracht ziehen, einige Ihrer Tests zu automatisieren, wenn Sie feststellen, dass Sie denselben Test immer wieder ausführen. Aber bis dies passiert, hat es nicht viel Sinn.
Dawood sagt, dass Monica am
Keine Notwendigkeit, die Hardware überhaupt zu verspotten. Wenn der Roboter protokolliert, führen Sie das Testprogramm aus und beobachten Sie die Protokolle. Der letzte Test erfordert die Beobachtung, dass "links abbiegen" im Protokoll dem Roboter entsprechen sollte, der links abbiegt. Sie müssen ein
Testkabel
4
@DavidWallace Bei der Verwendung von TDD / BDD werden die Vorteile von Unit-Tests sofort deutlich. Erstens, indem es ermöglicht wird, dass der Code sofort sicher überarbeitet wird, und zweitens, dass die Implementierung auf die minimale Implementierung beschränkt wird, die zur Erfüllung der Tests erforderlich ist.
S.Robins
4
@mattnz schlechte Idee, und ich weiß aus Erfahrung. Was ist, wenn der zu testende Code sehr, sehr schwer ausfällt und der Roboterarm gegen die Wand stürzt und ein Stück xxxx $ Hardware zerstört?
Mittwoch,
2
@ Mattnz: Unsere Roboter sind ungefähr 2 Fuß mal 3 Fuß mal 4 Fuß groß und wiegen ungefähr 150 Pfund. Das Kit / die Registrierung kostet 5.000 US-Dollar pro Jahr und wir beschaffen in der Regel weitere 5 bis 10.000 US-Dollar für den Kauf zusätzlicher Teile. Das schlimmste Szenario würde wahrscheinlich über 10 Dollar kosten;)
Michael0x2a
10

Ich kann mir ein paar Dinge vorstellen, die Sie berücksichtigen müssen. Die erste besteht darin, die Hardwarezugriffsebene so dünn wie möglich zu gestalten, selbst wenn dies das Erstellen einer grundlegenden Wrapper-Ebene für diese Ebene bedeutet. Dies bietet Ihnen einige Vorteile. Das erste ist, dass Sie das hardwarespezifische Verhalten Ihres Codes vom Hardwarezugriff selbst isolieren können, was bedeutet, dass Sie alles bis zum Ende Ihrer Hardwarekommunikation testen können, ohne auf die Hardware selbst zugreifen zu müssen.

Wenn Sie beispielsweise ein I2C-basiertes Signalisierungsprotokoll entwerfen müssen, können Sie testen, ob Ihr Code die richtigen I2C-Signale generiert, ohne die Hardware in Ihre Tests einbinden zu müssen.

Bei Aufrufen der eigentlichen Hardware können Sie testen, ob sie sich richtig verhalten, indem Sie Ihre Hardwareebene verspotten. Hier zahlt es sich wirklich aus, eine sehr dünne Hardwareebene beizubehalten, da Sie Ihre Verspottung so reduzieren können, dass sie nur die erforderlichen Mindestfunktionen ausführt Adressieren Sie die Hardware tatsächlich, aber Sie müssen die einzelnen Signale nicht unbedingt selbst testen, da alle Ihre Signale auf einer höheren Ebene testbar sein sollten. Dies bedeutet, dass Sie mit Ihrem Mock überprüfen, ob Aufrufe an bestimmte Hardwaremethoden erfolgen, die dazu führen, dass Ihre Signale an die Hardware gesendet werden. Wenn Sie Ihre Hardware abfragen müssen, muss Ihr Mock in der Lage sein, nur Ereignisse oder Methoden in Ihrem Code auszulösen, da Ihre Rückmeldung wiederum auf einer höheren Ebene behandelt werden sollte.

Dies passt im Wesentlichen zu dem, was Oleksi in seiner Antwort gesagt hat , da es in der Regel mehr Arbeit ist, Dinge auf Hardware-Ebene zu verspotten. Es ist jedoch nicht so schwierig, wenn Sie sich an eine möglichst schlanke Minimal-Code- / Aufruf-Ebene halten, die Sie für die erstellen können Hardware.

Wenn Sie Code haben, der alle Tests besteht, müssen Sie noch eine Reihe manueller Tests durchführen, um sicherzugehen, dass Sie in Ihrer Hardware-Schicht alles richtig gemacht haben.

Die andere Sache, die neben dem Verspotten und dem Überlagern in den Sinn kommt, ist die Verwendung einer Test-First-Entwicklungspraxis. Im Wesentlichen codieren Sie Ihre Anforderungen als Testkriterien und stützen Ihre Implementierung auf Ihre Tests. Auf diese Weise können Sie sicherstellen, dass Sie Ihren Implementierungscode auf ein Minimum beschränken, und gleichzeitig sicherstellen, dass alle Ihre Testfälle Ihre Entwicklungsbemühungen vorantreiben. Indem Sie nicht zu viel Zeit für anderen potenziell nicht kritischen Code verschwenden, zu dem Sie möglicherweise "nur weil" verleitet werden, hilft test Ihnen, konzentriert zu bleiben, und erleichtert es Ihnen, Ihren Code beim Debuggen und bei der Verwendung zu ändern Ihrer Unit-Tests und Mocks. Das Debuggen von Softwarefehlern durch die Hardware ist bekanntermaßen kompliziert und beansprucht einen großen Teil Ihrer Zeit, den Sie besser für andere Aufgaben ausgeben würden.

S.Robins
quelle
2

Ich kann Ihnen sagen, wie sie es auf Flugsimulatoren machen

Erstens erhalten Sie nur die Hälfte der Antwort, wenn Sie diese Frage nur Programmierern stellen. Sie sollten sie daher wahrscheinlich auf http://electronics.stackexchange.com kreuzen, während Sie gerade dabei sind.

Ich habe noch keine Arbeit mit Robotern gemacht, aber ich habe 5 Jahre damit verbracht, Hardware für Flugsimulatoren zu entwickeln, damit ich Ihnen sagen kann, wie ihre Architektur funktioniert.

Die Hardware-Schicht ist dumm

Es enthält eine grundlegende Schnittstelle, über die Sie einfache Ein- / Ausgabewerte anpassen und Interpolations-Haltepunkte für analoge Signale festlegen können. Wenn Sie mit "frischer" Hardware arbeiten, funktioniert alles wie erwartet mit wenig oder keiner Kalibrierung, aber im Laufe der Zeit unterliegen die Teile einem mechanischen Verschleiß und müssen angepasst werden.

Die Kalibrierung ist eine einfache Tabelle, die aufgeteilte Werte zwischen den min / max-Werten enthält. Um die Eingabe an diesen zu messen, wird normalerweise ein Servo verwendet (z. B. ein lineares Potentiometer, ein Wandler, Beschleunigungsmesser usw.). Oder bei Instrumenten beurteilen Sie die Genauigkeit einfach visuell und stellen sie ein, bis sie kalibriert sind.

Die Softwareschicht ist das Gegenteil

Alles ist komplex und miteinander verbunden, daher ist es wichtig, einige Variablen zu isolieren, um die Funktionalität zu testen. Sie müssen sich keine Gedanken über Szenarien machen, da es viel einfacher ist, einige realistische Szenarien auszuführen, in denen Sie Daten sammeln können. Wenn Sie die Tests ausführen, messen Sie im Grunde genommen die gespeicherten Daten anhand der aktuellen Ausgabe.

In einem Flugsimulator wird dies als QTG (Qualification Test Guide) bezeichnet. Im Kern werden die Daten in einem 2D-Raster aufgezeichnet, wobei eine Dimension die Zeit und die andere die Ausgabe ist.

Ob Sie es glauben oder nicht, das ist das Wesentliche bei der Entwicklung der Modelle. Ein echtes Flugzeug ist mit einer Tonne Sensoren ausgestattet und wird in kontrollierten Szenarien herumgeflogen. Da alle Steuerungen ohne menschliche Interaktion gesteuert werden können, werden die Tests vom Computer ausgeführt (dh die Sim fliegt selbst) und die Daten werden verglichen.

Auch wenn die Robotik in einem ganz anderen Maßstab erstellt wird, sind die Prinzipien dieselben. Der traditionelle Ansatz besteht darin, die Hardware- und Softwareschichten vollständig zu trennen, damit beide einzeln getestet werden können. Hardware-Input wird über Servos gesammelt und über eine unabhängige Schnittstelle eingestellt. Der Software-Eingang kann eingestellt / gelesen werden, indem die Signalisierung, die sonst an die Hardware gesendet würde, unabhängig gemessen und verglichen und mit den bekannten "guten" Daten verglichen wird.

Die Tests selbst müssen nicht unbedingt komplex sein, solange die Ergebnisse vorhersehbar, messbar und reproduzierbar sind.

Evan Scholle
quelle
1

Wie bereits gesagt, verspotten Sie die Hardware-Teile und stumpfen Sie sie heraus. Wenn Sie beispielsweise eine Schnittstelle zum Roboter haben, können Sie diese Schnittstelle erben und dann einfache Stub-Implementierungen vornehmen. Dann können Sie testen, ob die Stub-Implementierung wie erwartet aufgerufen wurde. Wenn das erwartete Funktionen oder erwartete Parameter sind.

martiert
quelle