Muster

Erfahren Sie, wie Muster durch die Generierung trapezförmiger Bewegungsparameter für Abwechslung in der StrokeEngine-Bewegung sorgen.

Muster unterscheiden StrokeEngine von anderen Bewegungssystemen. Bei jedem Muster handelt es sich um ein kleines Programm, das den nächsten Satz trapezförmiger Bewegungsparameter generiert: Zielposition, Geschwindigkeit und Beschleunigung.

Verfügbare Muster

Die OSSM-Firmware stellt 7 Muster (Indizes 0-6) zur Verfügung: Simple Stroke, Teasing or Pounding, Robo Stroke, Half'n'Half, Deeper, Stop'n'Go und Insist. Jack Hammer und Stroke Nibbler sind in der StrokeEngine-Bibliothek verfügbar, aber derzeit nicht in der OSSM-Firmware implementiert.

OSSM-Muster (0-6)

Nur in der Bibliothek verfügbare Muster

Diese Muster sind in der StrokeEngine-Bibliothek verfügbar, aber in der OSSM-Firmware derzeit nicht implementiert. Sie sind hier für Entwickler dokumentiert, die benutzerdefinierte Firmware oder andere StrokeEngine-basierte Projekte erstellen.

Erstellen benutzerdefinierter Muster

Sie können Ihre eigenen Muster erstellen, indem Sie in der Header-only-Datei pattern.h eine Unterklasse von Pattern erstellen.

Unterklasse der Pattern-Klasse

Erstellen Sie eine neue Klasse, die Pattern erweitert. Eine minimale Implementierung finden Sie unter SimpleStroke:

class SimpleStroke : public Pattern {
    public:
        SimpleStroke(const char *str) : Pattern(str) {}

Der Konstruktor speichert die Anzeigenamenzeichenfolge des Musters.

Überschreiben Sie set-Funktionen bei Bedarf

Implementieren Sie set-Funktionen erneut, wenn Sie benutzerdefinierte Berechnungen benötigen:

void setTimeOfStroke(float speed = 0) {
    // In & Out have same time, so divide by 2
    _timeOfStroke = 0.5 * speed;
}

Implementieren Sie die nextTarget-Funktion

Dies ist die Kernfunktion, die StrokeEngine nach jedem Hub aufruft, um die nächsten Bewegungsparameter abzurufen.

motionParameter nextTarget(unsigned int index) {
    // Maximum speed of the trapezoidal motion
    _nextMove.speed = int(1.5 * _stroke/_timeOfStroke);

    // Acceleration to meet the profile
    _nextMove.acceleration = int(3.0 * _nextMove.speed/_timeOfStroke);

    // Odd stroke moves out
    if (index % 2) {
        _nextMove.stroke = _depth - _stroke;

    // Even stroke moves in
    } else {
        _nextMove.stroke = _depth;
    }

    _index = index;
    return _nextMove;
}

Der Parameter index beginnt bei 0, wenn das Muster zum ersten Mal aufgerufen wird, und erhöht sich nach jedem Hub um 1. Verwenden Sie dies, um Muster zu erstellen, die sich im Laufe der Zeit ändern.

Debugging-Ausgabe hinzufügen

Kapseln Sie Serial.print()-Anweisungen mit Präprozessoranweisungen, damit sie umgeschaltet werden können:

#ifdef DEBUG_PATTERN
    Serial.println("TimeOfInStroke: " + String(_timeOfInStroke));
    Serial.println("TimeOfOutStroke: " + String(_timeOfOutStroke));
#endif

Registrieren Sie das Muster

Fügen Sie eine Instanz Ihrer Musterklasse zum Array patternTable[] am Ende der Datei hinzu:

static Pattern *patternTable[] = {
    new SimpleStroke("Simple Stroke"),
    new TeasingPounding("Teasing or Pounding"),
    new YourNewPattern("Your Pattern Name")  // Add your pattern here
};

Musteranforderungen

Tiefen- und Hubgrenzen

Muster müssen Hubpositionen innerhalb des Intervalls [0, stroke] zurückgeben. StrokeEngine überwacht alle zurückgegebenen motionParameter-Werte und schneidet Positionen außerhalb von [depth - stroke, depth] ab, um Verletzungen vorzubeugen.

Die in StrokeEngine festgelegten Tiefen- und Hubwerte sind axiomatische Grenzen. Ihr Muster definiert den Bewegungsbereich, den es innerhalb dieser Grenzen verwendet. Für die Geschwindigkeit über timeOfStroke gelten die gleichen Sicherheitsbeschränkungen.

Reibungslose Parameteränderungen

Ihr Muster muss Parameteränderungen ordnungsgemäß verarbeiten. Wenn sich die Tiefen- oder Hubwerte während des Vorgangs ändern, muss das Muster:

  • jederzeit innerhalb des Intervalls [depth, depth - stroke] bleiben
  • Transferbewegungen mit der gleichen Geschwindigkeit wie normale Bewegungen ausführen
  • unberechenbares Verhalten vermeiden

Testen Sie Ihr Muster gründlich anhand von Parameteränderungen, insbesondere Tiefen- und Hubänderungen, die möglicherweise zusätzliche Hubstrecken erfordern.

Verwendung des Indexparameters

Der Parameter index liefert wichtige Statusinformationen:

  • Wird auf 0 zurückgesetzt, wenn StrokeEngine.setPattern(int) oder StrokeEngine.startMotion() aufgerufen wird
  • Wird nach jedem erfolgreich ausgeführten Zug inkrementiert
  • Durch den Vergleich von index == _index wird ermittelt, ob es sich um eine Aktualisierung des aktuellen Hubs und nicht um einen neuen Hub handelt

Speichern Sie den letzten Index in _index, bevor die Funktion zurückkehrt, um den Hubstatus zu verfolgen.

Pausen implementieren

Muster können Pausen zwischen Hüben einfügen. Wenn die Zielposition erreicht ist, fragt StrokeEngine alle paar Millisekunden nach neuen Bewegungsbefehlen.

Um eine Pause zu implementieren, geben Sie _nextMove.skip = true von Ihrer nextTarget()-Funktion zurück. StrokeEngine wird später erneut abfragen, anstatt eine neue Bewegung zu starten.

Die Basisklasse Pattern stellt drei Hilfsfunktionen für die Pausenverwaltung bereit:

FunktionBeschreibung
_startDelay()Startet den Verzögerungstimer
_updateDelay(int delayInMillis)Legt die Pausendauer in Millisekunden fest (kann jederzeit aktualisiert werden)
_isStillDelayed()Gibt true zurück, wenn die geplante Zeit nicht erreicht wurde

Wenn ein Hub überfällig wird, wird er sofort ausgeführt. Eine Beispielimplementierung finden Sie im Stop'n'Go-Muster.

Mitwirkende Muster

Nachdem Sie Ihr Muster gründlich getestet haben, senden Sie einen Pull Request mit Ihrer aktualisierten pattern.h-Datei.

Auf dieser Seite