Hand spåra mekanisk Arm - Pyduino + språng Motion (11 / 11 steg)
Steg 11: Provning + felsökning koden
Okej förhoppningsvis du framgångsrikt har samlat en arm eller åtminstone har fyra servon ansluten till enheten Arduino som är redo att testa. Vi kommer att ställa in koden mycket som hur vi ställa upp med bara en servo. Att få klo arbetet kommer att innebära lite mer än vad vi gjorde tidigt men det fortfarande inte alltför svårt. För jordluckraren allt vi ska göra är beräkna normaliserade avstånd mellan våra pekaren tummen och pekfingret. För att hitta avståndet mellan våra två punkter kommer vi behöva veta lite vektor aritmetik. Vi kommer att hitta skillnaden mellan vektorn pekar på våra tummen och pekaren finger. Därefter kan vi beräkna avstånd/omfattningen genom att hitta den 2norm som du kan slags se som en 3D Pythagoras sats. För att se hur detta görs kolla in raderna 91 till 107 i koden nedan. Om du har Välkommen några kommentarer om koden gratis för att be men det bör vara ganska rakt fram om du har kunnat följa med hittills.
Om du inte kan få koden att arbeta kontrollera att du har din leapd tjänst kör och din arduino enhet ansluten till datorn. Du kan också prova att lägga till i kontrollen för fyra servon ett servo i taget om du fick koden i föregående steg att arbeta.
Optimera koden
Det finns några tweaks för att göra som normalisering gränsen för fingret pekaren och tummen som spänner på servon. Jag ställa spänner på servo utifrån hur jag bifogade motorerna i arm eftersom jag inte ville motorerna flyttar den armen i marken eller i själva Arduino enheten. Du kan hitta gränsen för normalisering mellan tummen och pekaren finger på rad 104. Intervallen för motorerna kan också hittas på linjer 118,119,120.
Koden kan också hittas här: https://github.com/theown1/pyduino_leapmotion/blob...
# Enkel språng motion program för att spåra positionen för din hand
# importera bibliotek där LeapMotionSDK är
importera sys
sys.Path.INSERT (0, "LeapLib /")
importera Leap, tråd, tid
från steg importera CircleGesture, KeyTapGesture, ScreenTapGesture, SwipeGesture
från pyduino import *
importera numpy som np
klass SampleListener(Leap.Listener):
finger_names = ["Tumme", "Index", "Mellersta", "Ring", "Pinky"]
bone_names = ["Metakarpal", "Proximala", "Mellanliggande", "Distala"]
state_names = ['STATE_INVALID', 'STATE_START', 'STATE_UPDATE', 'STATE_END']
oldtime = time.time()
NEWTIME = time.time()
def on_init(self, controller):
# om din arduino kördes på en seriell port annat än ' / dev/ttyACM0 / "
# förklara: en = Arduino(serial_port='/dev/ttyXXXX')
Self.a = Arduino()
# sömn så gott om tid för datorn att göra seriell anslutning
Time.Sleep(3)
# Definiera Pins för Arduino servon
själv. PIN2 = 2 # Azimuthal
själv. PIN3 = 3 # höjd
själv. PIN4 = 4 # handleden
själv. PIN5 = 5 # klo
Self.previous_angles = [0,0,0,0]
# ge tid för att göra anslutningen
Time.Sleep(1)
skriva ut "Initialized"
def on_connect(self, controller):
skriva ut "Ansluten"
# Aktivera gester
Controller.enable_gesture(LEAP.Gesture.TYPE_CIRCLE);
Controller.enable_gesture(LEAP.Gesture.TYPE_KEY_TAP);
Controller.enable_gesture(LEAP.Gesture.TYPE_SCREEN_TAP);
Controller.enable_gesture(LEAP.Gesture.TYPE_SWIPE);
def on_disconnect(self, controller):
# Observera: skickas inte när du kör i ett felsökningsprogram.
skriva ut "Frånkopplad"
def on_exit(self, controller):
Time.Sleep(1)
# Återställ arduino när du slutar programmet
Self.a.servo_write (själv. PIN2, 90) # Az
Self.a.servo_write (själv. PIN3, 0) # Alt
Self.a.servo_write (själv. PIN4, 100) # handleden
Self.a.servo_write (själv. PIN5, 70) # klo
Self.a.Close()
skriva ut "Exited"
def on_frame(self, controller):
# Vi vill bara få ställning som handen varje så ofta
Self.NEWTIME = time.time()
om self.newtime-self.oldtime > 0,1: # varje 10 ms få en ram
# Få senaste ramen och rapportera lite grundläggande information
ram = controller.frame()
interaction_box = frame.interaction_box
skriva ut "ram-id: %d, tidsstämpel: %d, händer: %d, fingrar: %d, verktyg: %d, gester: %d" () %
Frame.ID, frame.timestamp, len(frame.hands), len(frame.fingers), len(frame.tools), len(frame.gestures()))
# Få händer
för hand i frame.hands:
handType = "Vänster hand" om hand.is_left annat "högra hand"
normalized_point = interaction_box.normalize_point(hand.palm_position,True)
själv. XPOS = normalized_point.x
själv. YPOS = normalized_point.y
själv. ZPOS = normalized_point.z
skriva ut "%s, id %d, x-position: %s" % (handType, hand.id, int (själv. XPOS * 180))
skriva ut "%s, id %d, y-position: %s" % (handType, hand.id, int (själv. YPOS * 85))
skriva ut "%s, id %d, z-position: %s" % (handType, hand.id, int (själv. ZPOS * 180))
skriva ut "mina fingrar =',len(hand.fingers)
om len(hand.fingers) > = 2:
x1 = hand.fingers[0].tip_position[0]
Y1 = hand.fingers[0].tip_position[1]
Z1 = hand.fingers[0].tip_position[2]
# calc avståndet mellan två fingrar
x2 = hand.fingers[1].tip_position[0]
Y2 = hand.fingers[1].tip_position[1]
Z2 = hand.fingers[1].tip_position[2]
# calc 2norm för skillnaden mellan vektor till tummen och pekaren finger
r = ((x1-x2) ** 2 + (y1-y2) ** 2 + (z1-z2) ** 2) ** 0,5
# utföra en rå normalisering
dist_norm = r/100.
# kan behöva ändra 100 till något annat
skriva ut "Finger spets avstånd = ', dist_norm
# inte riktigt en normaliserad position, ibland kan vara mer än 1
om dist_norm > = 1:
dist_norm = 1
#for finger i hand.fingers:
#print finger, "-", finger.tip_position
# avgöra motorer – justera vinkel spänner här också
XPOS_servo = abs (145-self. XPOS * 145) # 0 - Azimut
YPOS_servo = abs (85-self. YPOS * 85) # 1 - höjd
ZPOS_servo = 35 + 135 * själv. ZPOS # handleden vinkel
# Skriv värdet till servo på arduino
Self.a.servo_write (själv. PIN2,int(XPOS_servo)) # Azimuth
Self.a.servo_write (själv. PIN3,int(YPOS_servo)) # höjd
Self.a.servo_write (själv. PIN4,int(ZPOS_servo)) # handleden
# klo utbud
CLAW_SERVO = abs(90-dist_norm*70)
skriva ut "klo vinkel =', CLAW_SERVO
Self.a.servo_write (själv. PIN5,int(CLAW_SERVO))
# uppdatering den gamla tiden
Self.oldtime = self.newtime
# uppdatering tidigare värden
Self.previous_angles[0] = XPOS_servo
Self.previous_angles[1] = YPOS_servo
Self.previous_angles[2] = ZPOS_servo
Self.previous_angles[3] = CLAW_SERVO
annat:
passera # hålla framåt i tiden tills 1 sekund uppnås
def main ():
# Skapa en prov lyssnaren och controller
lyssnaren = SampleListener()
Controller = Leap.Controller()
# Har prov lyssnaren ta emot händelser från registeransvarige
Controller.add_listener(Listener)
# Hålla processen igång tills retur trycks
skriva ut "Tryck på Enter för att avsluta..."
försök:
sys.stdin.readline()
Förutom KeyboardInterrupt:
passera
Slutligen:
# Ta bort provet lyssnaren när du är klar
Controller.remove_listener(Listener)
om __name__ == "__main__":
Main ()