Stap 12: P.3, Code: Inverse kinematica en andere Code Bits
Aanvankelijk vonden wij met inbegrip van inverse kinematic berekeningen in onze Objective C-code, maar dit bleek te zijn van een slecht idee omdat er tal van berekeningen zijn te doen bij initialisatie, en nadat ze eenmaal klaar, er geen noodzaak is om hen te herhalen. Immers, is het feit dat de objecten niet bewegen de basis van onze controleregeling. In plaats daarvan we hard-code hoeken.
Een zeer belangrijk stuk van code is een methode die de arm als het zal vertragen de bestemming, in plaats van duwen het helemaal benadert en hoop het niet start oscillerende (misschien in een ideale wereld met ideale servo's).
Ten eerste, wij onderbreken uitvoering voor een kleine hoeveelheid tijd dat de servo naar de hoek geven wij hen (de eerste keer deze methode wordt aangeroepen, de servo wil niet nog zijn in beweging):
[NSThread sleepForTimeInterval:0.03];
Vervolgens vergelijken wij de servo de huidige hoekige positie naar de gewenste eindpositie - als het is dicht genoeg (die we gedefinieerd als 2 graden), stelt u de variabele vervolgens dat de huidige hoek gelijk is aan de gewenste eindpositie slaat (u zult zien waarom dit zinvol in een moment):
Als (abs(targetAngle-angle) < = 2) {hoek = targetAngle;}
Nu, berekenen één tiende het verschil tussen de huidige hoek en de hoek van de doel - als de huidige hoek gelijk aan de target-hoek is, dit nul zal retourneren:
dubbele diff = (targetAngle - hoek) * 0.1;
Nu, de servo naar de huidige positie van de hoekige plus één tiende het verschil - verplaatsen als de huidige hoek gelijk aan de hoek van de doelgroep is, hierdoor wordt de servo om helemaal naar de doel-hoek:
[zelf moveActualTo:(angle + diff)];
Zie de video beschrijving hieronder om een beter begrip van hoe een waarom dit gebeurt. U vindt deze code in de methode van de calculateChange in Motor.m, die als onderdeel van een zipbestand in de volgende stap is gekoppeld.
De eerste versie van onze code alleen gebruikt de elektromagneet (dit is wat we hebben naar de regionals - de video was genomen rond 6 uur de dag van, na een nighter krijgen om te werken!) en keek zoiets als dit:
YouTube video beschrijving:
"Dit is de eerste volledige test van onze robotarm voor de Massachusetts wetenschap Olympiade. We hadden een van de coördinaten verkeerd in ons programma (Ja, later bleek een software probleem - veel beter dan een willekeurige "MOSFET niet aanzetten" glitch!), zodat het niet te halen een van de nagels, maar we hebben het vast op tijd voor de regionale evenement later die dag en won de eerste plaats door een aardverschuiving!
Een van de problemen die we al eerder (en dat veel van de teams had op de regionals) was oscillerende servo's en servo's die te snel bewegen en zwaaien van de arm in onvoorspelbare paden. Om dit te verhelpen, schreven we een algoritme dat de servo's vertraagt naarmate ze dichter bij hun uiteindelijke bestemming door hen een continue stroom van de coördinaten die exponentieel dichter en dichter bij de doelgroep hoek tot de servo zijn is in sommige delta, meestal één of twee graden, of deze hoek dicht genoeg om gewoon direct daarheen. Elke iteratie wordt berekend door het vinden van een tiende van de hoek die de servo nog reizen moet om de stap hebt voltooid. In plaats van met behulp van recursie om de hoek-berekening methode zich noemen totdat de stap voltooid is, oftewel de hand liggende keuze, wij een NSTimer in zijn eigen besturingsthread gebruikt om te vermijden moetend vertragingen toevoegen aan ons programma te houden de berekeningen met de servo's (de servo's gaan veel langzamer dan de computer hoeken spugen kan).
De reden waarom we exponentiële afname gebruiken in plaats van alleen vertraagd lineaire beweging is dat de arm in wezen fungeert als een gedempte harmonische oscillator (als we aannemen de proportionele term in de servo's interne PID-regelaar domineert rond het punt van de reeks, die lijkt dat te passen wat ik heb waargenomen wanneer de arm was oscillerende), dus als we het lineair rijden, het zal beginnen met enkele oorspronkelijke kinetische energie als het eenmaal op de plaats van bestemming en oscilleren eromheen plaats komen tot stilstand. De enige oplossing (als we aandringen op het rijden het lineair) is de arm vertragen tot de amplitude van de trilling verminderen totdat wij het aanvaardbaar vinden, dat is niet wenselijk, als men bedenkt dat het hier een getimede competitie. In plaats daarvan, als we het omzetten in de volgende hoek met in een exponentieel rottend patroon, het moet daar aankomen met relatief weinig kinetische energie, met fout veroorzaakt alleen door het feit dat wij het discrete gegevens geven.
Elke positie die de servo's moeten bereiken wordt berekend inverse kinematics gebruiken en vervolgens individueel aangepast met behulp van handmatige modus van onze programma's zo correct mogelijk te zijn. Een van de dingen die we zijn bezig voor Staten volgende maand is real-time inverse kinematic besturingselement dat ons toelaten zal om het verplaatsen van de arm einde effector in elke precieze pad dat we kiezen, in plaats van alleen maar verhuizen de servo's aan elke hoek een tegelijk, zoals wij nu doen.
Hoewel we hoeft niet een elektromagneet, en niet een universele grijper of klauw, waarmee objecten (dus dwingt ons om de helft van het bord ongewijzigd te laten) halen, automatische controle dat deze arm betekent is kunnen halen objecten snel en met geen menselijke fout, zodat we met succes 100% van de objecten die wij streven ernaar om iedere keer we de arm lopen plaatsen."