Thursday, April 25, 2013

AL5D Arm Manual Control on Pi

The same Tkinter/Python manual robotic arm control program I used on my Mac also worked fine on my Raspberry Pi with the AL5D robotic arm controlled by the Pololu Maestro Micro servo controller.  I just had to change the device filename to "/dev/ttyACM0".

On the Mac side, I logged in with "ssh -X ..." and now any X Windows you open up on the Pi will come through to your Mac.  I should note that to open up a general X session on the Pi,  I use "lxsession", which seems to work better for me than "startx".  Of course I have XQuartz installed on my Mac already.

Mechanical Turk Arm First Movement

The mechanical arm of the AWS Mechanical Turk powered chess playing Mechanical Turk is now built!

Here is the arm under manual control:



I chose the Lynxmotion AL5D robotic arm to provide a reasonable reach at an affordable price.  Moving plastic chess pieces does not require much torque, so I was able to avoid using the very capable but very expensive Dynamixel servos and instead used standard cheap RC servos.  Like many folks, I purchased only the AL5D hardware kit from Lynxmotion, and purchased the RC servos from the cheapest price on Amazon.

Building the AL5D took about four hours altogether.  My only serous complaint is that while the hardware is segregated to some extent in heat-sealed plastic bags, it still is often difficult for a novice to figure out which pieces of hardware is which (for example, 2-56 x .250" steel machine screw vs. #2 x .250" steel tapping screw vs. 3mm x 8mm steel screw).  It would be useful if every heat-sealed bag section had a piece of paper identifying the hardware in that section and perhaps which part of the instructions the hardware is associated with.

Also my HS-805BB servo (that I purchased from somewhere else besides Lynxmotion) came with a horn that was not quite compatible with the servo bracket.  It turns out that Lynxmotion does appear to pack a compatible horn in the kit, but somehow I missed that, so I drilled new holes in the existing horn.  Everything worked out anyway.

All of the controllers from Lynxmotion were overpriced or difficult to interface with a Raspberry Pi, so I chose the Pololu Micro Maestro 6-channel RC controller.  I have had great experiences with Pololu servo controllers in the past.  The Micro Maestro connects to a host via USB, and costs ~$20.  It also can provide some analog or digital input as well as serial output, so it is very function-packed for the price.

Two issues with the Pololu Micro Maestro - first, to use it with a Mac or Linux, you need to run the Maestro Control Center on a PC, and under the "Serial Settings" tab you should set the Serial mode to "USB Dual Port".  Then under "Channel Settings" you should open up the "Min" and "Max" settings for the arm servos to 500µs and 2500µs to assure you can move the Hitec servos a full 180 degrees.

If you are looking for info regarding inverse kinematics of the AL5D, see this blog entry.  Also great source code for full control of the Pololu Micro Maestro can be found here.

Finally, I wrote my first Tkinter program in Python to provide a manual GUI for the arm servo controls on a Mac:



Source code below:

# for more Pololu Micro Maestro interface code # see http://afflator.ontopoeticmachines.org/post/9 def setpos(cha,uS): """maestro uses is 0.25us increments """ pos=int(uS) pos=pos*4 low=pos&0x7f high=pos>>7 #print low,high # cmd, chan, low, high s.write(chr(0x84)+chr(cha)+chr(low)+chr(high)) def setpos0(uS): setpos(0,uS) def setpos1(uS): setpos(1,uS) def setpos2(uS): setpos(2,uS) def setpos3(uS): setpos(3,uS) def setpos4(uS): setpos(4,uS) from Tkinter import * import serial s=serial.Serial() # this /dev/tty.usbmodem device is for my particular system # do ls /dev/tty.usbmodem* to figure out yours # in Dual USB mode, lower number is the command port s.port="/dev/tty.usbmodem00049671" s.baudrate=115200 s.timeout=1 s.open() master = Tk() w0 = Scale(master,command=setpos0,from_=500,to=2500,length=500) w0.grid(row=0,column=0) w0.set(1500) w1 = Scale(master,command=setpos1,from_=500,to=2500,length=500) w1.grid(row=0,column=1) w1.set(1500) w2 = Scale(master,command=setpos2,from_=500,to=2500,length=500) w2.grid(row=0,column=2) w2.set(1500) w3 = Scale(master,command=setpos3,from_=500,to=2500,length=500) w3.grid(row=0,column=3) w3.set(2000) w4 = Scale(master,command=setpos4,from_=500,to=2500,length=500) w4.grid(row=0,column=4) w4.set(1500) #note that the initial servo values may differ slightly between arms setpos(0,1500) setpos(1,1500) setpos(2,1500) setpos(3,2000) setpos(4,1500) master.mainloop()

Wednesday, April 17, 2013

Where the Chess Playing Turk Workers were from

I was able to directly track where the players of my first AWS Mechanical Turk chess game were from since I was using an external web site to serve up the HITs.  I used FreeGeoIP to convert the IP addresses to Lat/Long pairs, and then used BatchGeo to map them.

Here is where all 21 players were from:


Many were from the US:


And many were from India:



Monday, April 15, 2013

First Mechanical Turk Chess Game over

After some problems with my Raspberry Pi SD card blowing up, I was able to rebuild (and back up) the system, and had the first full AWS Mechanical Turk mediated chess game played out.  As you can see, it was a pretty long game, complete with pawn promotion.  The actual game time was about three days.

I paid $0.05 per move.  I suspect that in the future I should 1) pay a bonus for checkmate to get the game moving a bit quicker and 2) see if I can block workers who play for one color to also play for the other.  But glad to see that everything worked, and there was actually checkmate!

Here are the results:

  +-----------------+
8 | Q . . Q . . . . |
7 | . . . . . . . P |
6 | K . . . . . . . |
5 | P . . . . . . . |
4 | P . . . . . . P |
3 | . . . . . K . . |
2 | . . . . . . . . |
1 | . . . . . . . . |
  +-----------------+
    A B C D E F G H


1. 'e4', 'Nf6'
2. 'd3', 'd6'
3. 'a3', 'Bg4'
4. 'f3', 'Bh5'
5. 'a4', 'a5'
6. 'g4', 'd5'
7. 'Qd2', 'dxe4'
8. 'dxe4', 'Bg6'
9. 'Nc3', 'c6'
10. 'Qxd8+', 'Kxd8'
11. 'Be3', 'c5'
12. 'Bxc5', 'Na6'
13. 'Rd1+', 'Kc7'
14. 'Bxa6', 'bxa6'
15. 'Nd5+', 'Kc6'
16. 'Be3', 'Rd8'
17. 'c4', 'h6'
18. 'Nb4+', 'Kb7'
19. 'Rxd8', 'Nd5'
20. 'Nxd5', 'e6'
21. 'Nb6', 'Bb4+'
22. 'Kf2', 'Rxd8'
23. 'Ne2', 'f5'
24. 'exf5', 'exf5'
25. 'Nc3', 'fxg4'
26. 'fxg4', 'Bxc3'
27. 'bxc3', 'Rd3'
28. 'Bd4', 'Rxd4'
29. 'cxd4', 'Kxb6'
30. 'c5+', 'Kc7'
31. 'd5', 'Be4'
32. 'Rd1', 'Bh7'
33. 'Rd4', 'g5'
34. 'h4', 'h5'
35. 'd6+', 'Kd7'
36. 'Rd5', 'Bg8'
37. 'Rxg5', 'Kc8'
38. 'Rxg8+', 'Kd7'
39. 'gxh5', 'Ke6'
40. 'Ra8', 'Kd5'
41. 'Rxa6', 'Kc4'
42. 'c6', 'Kb4'
43. 'Rb6+', 'Kc5'
44. 'c7', 'Kd5'
45. 'Kf3', 'Kd4'
46. 'c8=Q', 'Kd5'
47. 'Qf5+', 'Kd4'
48. 'Qe4+', 'Kc5'
49. 'h6', 'Kxb6'
50. 'h7', 'Kc5'
51. 'd7', 'Kb6'
52. 'd8=Q+', 'Ka6'
53. 'Qea8#'