Tutorial · Gevorderd · 35 min

Een grijp-en-plaats-toestandsmachine die fouten overleeft

Naderen, grijpen, verifiëren, tillen, plaatsen—een toestandsmachine met de verificatiestap die van een demo iets maakt dat je onbeheerd kunt laten draaien.

Waarom de demo werkt en het systeem niet

Iedereens eerste grijp-en-plaatseffect is een lijst delay()-aanroepen. Ga hierheen, sluit de grijper, ga daarheen, open hem. Het werkt op video en het werkt op de werkbank ongeveer tachtig keer in de honderd, en dat voelt bijna af.

Het is nog lang niet af, want de twintig mislukkingen zijn allemaal stil. De grijper sloot op niets en de arm droeg lucht over de tafel en opende boven de bak. Het onderdeel stond scheef en werd omgegooid in plaats van gegrepen. De servo viel midden in het tillen door onderspanning uit en de regelaar herstartte in een onbekende pose met de kaken dicht.

Wat die rampen in herstelacties verandert, is één ding: een verificatiestap tussen het grijpen en het tillen, en een toestandsmachine die ergens heen kan als het misgaat. Dat is het hele onderwerp van deze pagina.

De toestanden

Een grijp-en-plaatscyclus is negen toestanden, en het is de moeite waard ze alle negen te benoemen in plaats van ze samen te klappen.

Toestand Wat er gebeurt Uitstapvoorwaarde
IDLE Wachten op een opdracht Er komt een grijpverzoek binnen
APPROACH Bewegen naar een pose boven het object, grijper open Arm staat stil
DESCEND Rechte verplaatsing omlaag naar de grijpose Op diepte, of een contactsensor vuurt
GRASP De kaken sluiten, daarna wachttijd Wachttijd verstreken
VERIFY Verifiëren of er echt iets vastzit Vast → LIFT. Leeg → RECOVER
LIFT Rechte verplaatsing terug omhoog naar de naderingspose Arm staat stil
TRANSFER Bewegen naar boven het plaatsdoel Arm staat stil
PLACE Dalen, openen, wachttijd, terugtrekken Terugtrekken voltooid
RECOVER Heropenen, terugtrekken, poging tellen, opnieuw proberen of opgeven Opnieuw → APPROACH. Opgeven → IDLE met foutmelding

Twee ontwerpkeuzes doen hier het meeste werk.

Naderings- en terugtrekposes zijn aparte toestanden, boven het object. Een grijper die vanuit een willekeurige richting rechtstreeks op een onderdeel afgaat, gooit het om, en een grijper die langs een kromme optilt, sleurt het onderdeel zijwaarts voordat het loskomt. Kom altijd recht van boven binnen (of recht langs de insertieas) met een kort recht stuk, en ga zo weer weg.

VERIFY is een toestand, geen coderegel. Het is de enige plek in de cyclus waar de machine erachter komt of de werkelijkheid overeenkwam met het plan, en het heeft ergens heen te falen.

Het grijpen verifiëren

Vier manieren, van goedkoop naar duur. Je hebt er minstens één nodig.

De kaakstandcontrole (gratis)

Heeft je grijper enige meebuigzaamheid, dan stopt het grijpen van een object de kaken vóór de stand waarin ze dichtgaan op lucht. Kun je de kaakstand uitlezen, dan vertelt vergelijken met de stand van het dichtgaan op lucht je dat er iets tussen de vingers zit.

Bij een gewone hobby-servo kun je de stand niet uitlezen—hij werkt in open lus. Maar een servo met de potentiometerwiper doorgevoerd naar een ADC-pin geeft je dat voor de prijs van één draad, en die aanpassing kost tien minuten.

Beperkingen: het vertelt je dat er iets is, niet dat het het juiste is of dat het goed vastzit.

Een microswitch op de vinger (ongeveer 50p)

Een hefboommicroswitch op de binnenkant van één vinger, aangesloten op een ingangspin met een pull-upweerstand. Sluit zodra het drukstuk iets raakt.

Dit is qua waarde verreweg de beste optie. Het is een direct digitaal antwoord op “zit er iets tussen de kaken”, het overleeft alles, en het ontdendert in drie regels software. Zet hem op het meebuigzame deel van de vinger, zodat hij betrouwbaar aanslaat bij een herhaalbare kracht.

Stroommeten (ongeveer £2)

Een shunt of een hallsensor in de servovoeding. Een servo die op lucht dichtgaat loopt terug naar stationair verbruik; een servo die op een object dichtgaat houdt een verhoogde stroom vast.

Beperkingen: ruisachtig, vraagt om een drempel die je kalibreert, en gaat het mis wanneer de batterij inzakt. De moeite waard wanneer je ook een verplettering wilt detecteren in plaats van alleen een vasthouden—een stroom ver boven de verwachte waarde betekent dat het onderdeel harder was dan verwacht, of dat je misgreep en de opspanning pakte.

Stralbreking over de kaken (ongeveer £1)

Een IR-zender en fototransistor over de kaakopening. Een verbroken bundel betekent dat er iets in de opening zit.

Beperkingen: hij ziet het object voordat je het hebt gegrepen, dus controleert hij aanwezigheid in plaats van grip. Combineer hem met iets anders. Echt goed op machines die transparante of donkere objecten pakken waar zicht lastig mee heeft.

Het opstellen

Het patroon is een gewone toestandsmachine met een niet-blokkerende timer, zodat niets in de lus blijft hangen en de noodstop responsief blijft:

enum State { IDLE, APPROACH, DESCEND, GRASP, VERIFY, LIFT, TRANSFER, PLACE, RECOVER };

State state = IDLE;
uint32_t stateEnteredAt = 0;
uint8_t  attempts = 0;

const uint8_t  MAX_ATTEMPTS = 3;
const uint16_t GRASP_DWELL_MS = 350;   // let the compliance settle before you trust it
const uint16_t SETTLE_MS      = 250;

void enter(State next) { state = next; stateEnteredAt = millis(); }
bool elapsed(uint16_t ms) { return millis() - stateEnteredAt >= ms; }

// Debounced: one reading is a glitch, three in a row is a fact.
bool objectHeld() {
  static uint8_t streak = 0;
  streak = digitalRead(GRIP_SWITCH) == LOW ? min(streak + 1, 3) : 0;
  return streak >= 3;
}

void loop() {
  arm.update();          // non-blocking motion, every pass
  gripper.update();

  switch (state) {
    case IDLE:
      if (jobPending()) { attempts = 0; arm.moveTo(approachPose); enter(APPROACH); }
      break;

    case APPROACH:
      gripper.open();
      if (arm.arrived() && elapsed(SETTLE_MS)) { arm.moveTo(graspPose); enter(DESCEND); }
      break;

    case DESCEND:
      if (arm.arrived()) { gripper.close(); enter(GRASP); }
      break;

    case GRASP:
      // The dwell is not politeness. A compliant finger rings after closing,
      // and reading the switch during the ring gives you a coin flip.
      if (elapsed(GRASP_DWELL_MS)) enter(VERIFY);
      break;

    case VERIFY:
      if (objectHeld()) { arm.moveTo(approachPose); enter(LIFT); }
      else              { enter(RECOVER); }
      break;

    case LIFT:
      if (arm.arrived()) { arm.moveTo(placeApproach); enter(TRANSFER); }
      break;

    case TRANSFER:
      if (arm.arrived()) { arm.moveTo(placePose); enter(PLACE); }
      break;

    case PLACE:
      if (arm.arrived() && elapsed(SETTLE_MS)) {
        gripper.open();
        // Open BEFORE retreating, and retreat straight up, or you drag the part.
        if (elapsed(SETTLE_MS + 200)) { arm.moveTo(placeApproach); enter(IDLE); }
      }
      break;

    case RECOVER:
      gripper.open();
      if (elapsed(SETTLE_MS)) {
        if (++attempts < MAX_ATTEMPTS) { arm.moveTo(approachPose); enter(APPROACH); }
        else { raiseFault("grasp failed after 3 attempts"); enter(IDLE); }
      }
      break;
  }
}

Drie details daarin verdienen hun plek:

De wachttijd na het grijpen. Een meebuigzame vinger blijft enkele honderden milliseconden natrillen na het sluiten. Verifieer je tijdens het natrillen, dan krijg je een muntworp. 300–400 ms is meestal ruim genoeg; meet wat jouw vinger doet door de schakelaar een seconde na het sluiten te loggen.

Ontdenderde verificatie. Eén schakelmeting is ruis. Drie opeenvolgende metingen is een feit, en het kost drie doorlopen van een lus die op honderden hertz draait.

Een begrensd aantal pogingen. Onbeperkt opnieuw proberen is hoe een robot de hele nacht door een onderdeel schuurt dat er al een uur op de vloer ligt. Drie pogingen en dan een foutmelding die een mens moet wissen.

Wat je doet als opnieuw proberen niet helpt

RECOVER probeert zoals geschreven gewoon opnieuw vanaf dezelfde pose, en dat repareert het veelvoorkomende geval—het onderdeel stond scheef, de kaken duwden het, en de tweede poging zit goed. Het repareert geen onderdeel dat ergens anders ligt. Bruikbare escalaties, op volgorde:

  1. Duw de nadering bij. Verschuif de grijpose bij elke nieuwe poging een paar millimeter in een kleine spiraal. Kost drie regels en redt een verbazingwekkend deel van de gevallen.
  2. Meet opnieuw. Heb je een camera of een afstandssensor, neem dan een verse meting in plaats van te vertrouwen op de pose die je kreeg.
  3. Maak de opening groter. Een kaakopening die strak op het nominale onderdeel is afgesteld, faalt op een gedraaid onderdeel. Open verder bij een nieuwe poging.
  4. Geef luid op. Een fout die de machine stopt en zegt in welke toestand ze stond, is beter dan een machine die doorgaat en stilletjes de afvalbak vult.

Storingen die niet de schuld van de grijper zijn

Als een grijp-en-plaatscyclus onbetrouwbaar is, is het vaak niet het grijpen:

Symptoom Gangbare oorzaak
Faalt alleen bij snelle cycli Te weinig stabilisatietijd. De arm is volgens zijn eigen berekening aangekomen en trilt nog na
Faalt na twintig minuten Servo wordt warm. Zie vastloopstroom—de kaken worden waarschijnlijk de hele terugweg dichtgehouden
Gooit het onderdeel om bij het naderen Daalt in een hoek in plaats van recht langs de insertieas
Laat het los tijdens het transport, niet bij het pakken Versnelling. De grip was gedimensioneerd voor statisch vasthouden en de beweging vraagt meer
Sleurt het onderdeel bij het loslaten Trekt terug voordat de kaken helemaal open zijn, of trekt langs een kromme terug
Regelaar herstart halverwege de cyclus De servovoeding zakt in. Scheid het servo-voedingstraject
Werkt, en werkt dan steeds minder Vuile grijpvlakken. μ daalt naarmate stof zich ophoopt, en daar is geen alarm voor

De vierde rij is het waard om even bij stil te staan, want het is de die er het meest op een mysterie lijkt. Een grip die op de werkbank perfect houdt, kan 40 ms na het begin van het tillen loslaten—voordat de arm zichtbaar is bewogen—omdat de versnellingsterm overheerst. De gripper-simulator laat je met je eigen getallen het precieze moment zien, en de oplossing is meestal het profiel vertragen in plaats van harder knijpen.

Waar je hiernaartoe gaat

Zodra de cyclus betrouwbaar is, zijn dit de volgende toevoegingen, op volgorde van waarde:

  1. Cyclustellen en een foutenlog. Je kunt een betrouwbaarheidsgetal niet verbeteren dat je niet meet.
  2. Een echt bewegingsprofiel op het transport, zodat de versnelling begrensd is en je stopt met de grip overmatig te dimensioneren om schokkende bewegingen te overleven.
  3. Pose uit metingen in plaats van uit constanten, en dat is de stap van een demo naar een machine.

Volgende stap

Verken de graaf

Onderdeel van deze bouwprojecten

Projecten en leerroutes waarin deze tutorial voorkomt.

Verder lezen

Bronnen