Humanoid Robotics

From IPRE Wiki
Jump to: navigation, search

Welcome, ye Computer Science enthusiasts, to Meena's 2008 Summer Research Wiki.

Abstract (as of 20 June, 2008)

Education in Humanoid Robotics

Meena Seralathan

Mentor: Dr. Doug Blank


Robotics is becoming a rapidly growing facet of computer science research. Specifically, research in artificial intelligence (AI) and developmental robotics (the study of programming robots to learn independently) has become increasingly popular with the development of more sophisticated software and hardware. Now, instead of worrying about the costs of a robot or the limitations of current hardware or software, one of the biggest questions posed in this field of research is how one can program a robot to act autonomously (that is, how a robot can be programmed to think for itself, "feel" for itself, and make decisions based on its own motivations).

In our research we will be exploring these concepts through a humanoid robot. We will try programming behaviors for the robot to see how easily it can interact autonomously with its environment (possibly with the use of a camera, IR sensors, light sensors, or touch sensors), and determining what sort of programs allow the robot to learn more about its environment, and what sorts of programs cause the robot to best remember the locations of obstacles or other important objects in the environment. We will also allow the humanoid robot to be simulated in the robotics software Pyro (Python Robotics), so we may test developmental programs for the robot without having to use a physical robot.

More Detailed Summary of My Work Thus Far

I've been working with a number of things (as you can probably see) that have been related to either humanoid robotics or generic developmental robotics. First I learned a little about Pyro, which is a Python-based application that can be used to simulate robots with neural networks, and can also be used in connection with real robots to test those networks out in real life. But then a new program with a similar aim was discovered: Microsoft Robotics Developer's Studio (MRDS). So then I started learning about that program, paying most attention to the 3D simulation environment and learning how to create autonomous robot simulations. Then came the humanoid robot, the Robonova-1. I then started learning about the robot (battery life, how it can be programmed, what it has and what it can have, etc), and about its movements and such. At first, since the robot cannot act without a RoboBASIC program, I thought about making a program that would allow people to save simple Python commands to a .py file and then translate that file into a .bas file that the robot would understand; later it was decided that instead of translating the Python code it would be used as a layer on top of a .bas file containing pre-defined actions. By the end of the summer I should have the Robonova set up with Myro in the same fashion as other robots pre-included with Myro, and maybe have a network running with it.

Research Done Thus Far

Learning About Pyro/Neural Networks

  • 27 May 2008: Started reading about differences between C# and Java (to prep for translation of pyro code); read through the Pyro tutorials; ended on the "PyroModuleDirectControl" module; edited the code at the end like so:
from pyrobot.brain import Brain

class WallFollow(Brain):
    # follows walls on its left, ignores sonar sensors on its right
    def wallFollow(self, dist):
        sideLeftA = self.robot.sonar[0][0].distance()
        sideLeftB = self.robot.sonar[0][15].distance()
        sideRightA = self.robot.sonar[0][7].distance()
        sideRightB = self.robot.sonar[0][8].distance()
        diagBackLeft = self.robot.sonar[0][14].distance()
        diagBackRight = self.robot.sonar[0][9].distance()
      
        frontLeft = min([s.distance() for s in self.robot.sonar[0][2:4]])
        frontRight = min([s.distance() for s in self.robot.sonar[0][4:6]])
        if frontLeft < dist:
            print "wall in front"
            self.move(0,-0.5)
        elif (sideLeftA < dist or sideLeftB < dist or diagBackLeft < dist):
            print "following left:",
            if frontLeft < sideLeftA:
                print "turn slight away"
                self.move(0.4,-0.1)
            elif frontLeft < diagBackLeft:
            	print "turn a lot toward"
            	self.move(0.3, 0.5)
            elif frontLeft > diagBackLeft:
            	print "turn a bit toward"
            	self.move(0.3, 0.4)
            else:
                print "turn slight toward"
                self.move(0.3,0.1)        
        elif (sideRightA < dist or sideRightB < dist or diagBackRight < dist):
            print "following right:",
            if frontRight < sideRightA:
                print "turn slight away"
                self.move(0.4,-0.1)
            elif frontRight < diagBackRight:
            	print "turn a lot toward"
            	self.move(0.3, 0.5)
            elif frontRight > diagBackRight:
            	print "turn a bit toward"
            	self.move(0.3, 0.4)
            else:
                print "turn slight toward"
                self.move(0.3,0.1)       
        else:
            print "find wall"
            self.move(0.3,0)
    def step(self):
        self.wallFollow(1)

def INIT(engine):
   return WallFollow('WallFollow', engine)
  • 28 May 2008: Read "Bringing up robot: Fundamental mechanisms for creating a self-mativated, self-organizing architecture" article (Blank, D., Kumar, D., Meeden, M., and James Marshall) to get an idea of research already done; read most of "Pyro: A Python-based Versatile Programming Environment for Teaching Robotics" article (Blank, D., Kumar, D., Meeden, M., and Holly Yanco) to learn about background of Pyro project; finished reading up on C# vs Java comparison (will probably try writing test programs tomorrow); read some more of the Pyro tutorial; made the following behaviors after the Vertical Behaviors section:
#class Wander(SubsumptionBehavior):
#    def update(self):
#        self.move( .2, random.random() * 2 - 1)

#class Avoid(SubsumptionBehavior):
#    def update(self):
#        if min([s.value for s in self.robot.range["front-all"]]) < 1:
#            self.move(-.2, 0)
            
##New Behaviors  
class Spin(SubsumptionBehavior):
	def update(self):
			self.move(0,1)

class ForwardFromWall(SubsumptionBehavior):
	def update(self):
		if min([s.value for s in self.robot.range["back-all"]]) < 1:
			self.move(0.3,0)

class ForwardToWall(SubsumptionBehavior):
	def update(self):
		if min([s.value for s in self.robot.range["front-all"]]) > 3:
			self.move(0.3,0)
        
class WanderAvoidFollowWall(SubsumptionBehavior):
	def update(self):
		sideLeftA = self.robot.sonar[0][0].distance()
		sideLeftB = self.robot.sonar[0][15].distance()
		sideRightA = self.robot.sonar[0][7].distance()
		sideRightB = self.robot.sonar[0][8].distance()
		diagBackLeft = self.robot.sonar[0][14].distance()
		diagBackRight = self.robot.sonar[0][9].distance()
		frontLeft = min([s.distance() for s in self.robot.sonar[0][2:4]])
		frontRight = min([s.distance() for s in self.robot.sonar[0][4:6]])
		
		if min([s.value for s in self.robot.range["front-all"]]) > 3:
			self.move( .2, random.random() * 2 - 1)
		elif min([s.value for s in self.robot.range["front-all"]]) < 0.5:
			self.move( -.2, 0)
		elif min([s.value for s in self.robot.range["front-all"]]) < 1:
			if frontLeft < 1:
				print "wall in front (left)"
				self.move(0,-0.5)
			elif (sideLeftA < 1 or sideLeftB < 1 or diagBackLeft < 1):
				print "following left:",
				
				if frontLeft < sideLeftA:
					print "turn slight away"
					self.move(0.4,-0.1)
				elif frontLeft < diagBackLeft:
					print "turn a lot toward"
					self.move(0.3, 0.5)
				elif frontLeft > diagBackLeft:
					print "turn a bit toward"
					self.move(0.3, 0.4)
				else:
					print "turn slight toward"
					self.move(0.3,0.1)
			elif frontRight < 1:
				print "wall in front (right)"
				self.move(0, 0.5)		        
			elif (sideRightA < 1 or sideRightB < 1 or diagBackRight < 1):
				print "following right:",
				
				if frontRight < sideRightA:
					print "turn slight away"
					self.move(0.4,-0.1)
				elif frontRight < diagBackRight:
					print "turn a lot toward"
					self.move(0.3, 0.5)
				elif frontRight > diagBackRight:
					print "turn a bit toward"
					self.move(0.3, 0.4)
				else:
					print "turn slight toward"
					self.move(0.3,0.1)       
			else:
				print "find wall"
				self.move(0.3,0)
  
def INIT(engine):
    subsumption = SubsumptionBrain( engine )
    # add behaviors, lowest priorities first:
#    subsumption.add( Wander() ) 	   
    subsumption.add( Spin() )  
    subsumption.add( ForwardToWall() )  
    subsumption.add( ForwardFromWall() )
#    subsumption.add( Avoid() )
    subsumption.add( WanderAvoidFollowWall() )
    return subsumption

Tried to make the sim robot dance, but couldn't figure out how to create three separate movements for it (might look at code again tomorrow to modify for multiple movements during updates, if that is the problem); read partway through Horizontal Behavior section.

  • 29 May 2008: Finished reading articles; continued reading Pyro tutorials online (reached second part of Neural Networks section); edited multiple bits of code for exercises (won't paste all of them here to conserve page space); planning on downloading a compiler for C# on laptop and trying some programs tomorrow, since compiler on Park computer's apparently out of date.

A section about chat bots in the "Python AI" article reminded me of a Japanese robotics project I read about awhile ago, where researchers were trying to use humanoid robots to interact vocally with people by interpreting what they said and outputting appropriate responses (I think the robot in that article was doing a physics lecture or a scientific Q&A session). Might be worth simplifying into a project for this summer. The article also mentioned a GuessLang program that can analyze a webpage and figure out what language it's in; this could probably be modified to work with an interactive robot that could work in different languages, or could simulate a fluent speaker for language students needing to be immersed in the language. Maybe.

The dissertation ("A Framework for Reactive Intelligence through Agile Component-Based Behaviors") pointed out some interesting things about different languages and efficiency/speed. C++ (and I would guess other "system programming languages") take less time to process information in (on average C++ is 20x faster than Python and can get up to 100x faster in common applications), so it would make sense to try programming in one of these system programming languages. We'll already be using C# to translate Pyro, so we might as well use it for further experimentation as well, or try using Java or C++ for the fun of it.

  • 3 June 2008: Read some articles pertaining to android AI, recent research in humanoid robotics, and other related topics. Looked over the code for an ELIZA-based program called Therapist (program that simulates a discussion with a therapist by responding to human input/responses). Could probably make such a program better by transferring it to a neural network-like format, where program/robot could learn how to respond to different questions or statements (or at least tell the user to stop asking/saying whatever's causing the program/robot trouble). Could have certain keywords also act as reinforcement values, maybe. Will mess with some chat bots on my laptop to gauge their limitations, and will see if I can find out how they are implemented and what makes them better than ELIZA (maybe they're already using networks).
  • 18 June 2008: Back to Pyro (MRDS too complicated for current purposes). Have spent enough time with MRDS to have forgotten parts of Pyro tutorials, so will start with a review.

Learning About Microsoft Robotics Developer's Studio (MRDS) and Simulations

  • 3 June 2008: Downloaded, installed, and started messing with Microsoft Robotics Developer Studio 2008. Messed with the VPL (visual programming language) approach to programming. Trying to figure out how to use more complicated loops than if statements (for loops and while loops aren't included as draggable programming parts). Looks like lists/2D arrays are also the only data structures readily available for the visual programmer to use; trying to figure out if other structures are useable, and if so how exactly they can be implemented. Coding by dragging icons feels restrictive, annoying; feel like it would take less time just to type out the commands (it would definitely take less time to include things like while loops or dictionaries, if I wanted to include them for some reason). Wondering whether it's possible to textually code somewhere and import the code into the rest of the program; seems MRDS2008 can work with Visual Studio C# for some applications, so I might install that and see if I can use it instead of VPL.
  • 4 June 2008: Went through tutorials on how to use the MRDS simulation program, looked up videos and articles about the Robonova-1 (the robot that's coming in soon). Downloaded a zip file that had files for simulating the Robonova-1, will look at it tomorrow.
  • 5-6 June 2008: Tried running zip files; didn't work. Considered making own mesh files and project for creating robot in simulation, realized learning how to use the art program alone (Blender) could take weeks, decided to see what I could so about the zip file. Got the references to work, but for some reason it can't connect to the Microsoft servers. Posted about it on the Development Forums, will check later to see if I got a reply. If necessary will try connecting to different server.

In the meantime, read through shiny new book, Programming Microsoft Robotics Studio (Sara Morgan); learning how to set up a service that will allow for "autonomous roaming" on a LEGO NXT; hoping to get this into a simulator and see if it works, then learn how to get other robots working in the same manner (right now it seems services are meant for REAL robots, not simulated robots, so I'll have to look up info about that; might have to eventually modify sim environment itself).

  • 9-10 June 2008: Found out the zip for the robot was just for the model of the robot, not for moving or anything. Couldn't connect to a server because it didn't have any services in its code. Still looking for something to explain how to use behaviors on sim robots instead of real robots. Looking for code online that will help override whatever code Microsoft uses for movement in simulations (since Microsoft doesn't do a good job of explaining the code that isn't directly discussed in the tutorials). Also looked through random classes to try and find out what might need altering. Will have to look at robot to figure out what sensors it has/joint movement/etc so I can make a behavior that is specific to that robot.
  • 16 June 2008): Found out that partial cause of my problems with MRDS. Stuff works fine now. Looking at code from this site to get idea of how to make robots move on their own in the simulator.

Using the Robonova-1

  • 16 June 2008: Worked a little with the Robonova-1. Think it has a short battery life; not sure how long it needs to be charged because LED light on the charger always changes to green after maybe twenty minutes, but the robot loses power shortly after (10-20 mins). Will charge for a few hours tomorrow to see if the battery can last for an hour, at least. Can't try fancy robot moves at the moment anyway because of lack of space.
  • 18 June 2008: Robonova-1's battery lasted about an hour when charged for 5 hours and left standing with the power on. Will see how long battery lasts when robot is moving a bit.

Realized sensors I thought were already in the robot are optional additions; only sensor robot has now is the IR for the remote control. Wondering whether the sensor might be usable for other things; unfortunately it's broken, so this can't be tested.

  • 19 June 2008: Tried out the "catch-and-play" features of the Robonova (is indeed as easy to do as the package claimed). Tried out walking program; pretty good but sort of wobbly/non-fluid. Will examine it again after battery has charged (lasted about 40 mins after charging for a long long time) and see if better movements can be created (maybe more human-like walking motions). Also tried out the fighting and dancing moves, because I couldn't help myself. Robot is surprisingly stable when the battery's mostly charged.

Also wrote abstract, read a little about available sensors for the Robonova (can purchase sound sensors, touch sensors, light sensors, and IR sensors), Bluetooth compatibility, trying to use other languages other than Robobasic for programming the robot (a bit trickier; will probably require an interpreter to be created to translate Python/whatever code into Robobasic or some intermediate code). Will read a little more about the latter, then will see about installing Pyro on me laptop cause the liveCD uses a different sort of Linux. May also try seeing just how stable the Robonova can be. Hah hah.

  • 20 June 2008: Read some info about hardware on Robonova and think RoboBasic does something to its code to make it recognizable to the software on the robot, and that this thing can't be emulated with other languages or compilers. There is a possible way to program in C, but the steps to getting to this point went over my head since I'm not familiar enough with hardware/software engineering, and procedure was potentially harmful to the robot if not carried out correctly. Also would not necessarily make the Python problem less of a problem. Problem might be able to be resolved with new chip that can accept languages like Python, but read that they might not work as quickly as the one included due to the amount of servos they have to control simultaneously. Also would require doing a lot of things I would rather not have to do (changing boards and stuff).
  • 23 June 2008: No sensors to test out; will read through Myro code to figure out how robots are connected to the computer with Myro; test out more features of Robonova and maybe see if I can make the motions more fluid and/or "human-like."
  • 26 June 2008: Myro code leaves me to believe that software on Scribbler flukes is specifically designed to be able to receive whatever's sent in Python, so it won't help with getting Robonova to work with Python. RoboBasic apparently doesn't support any sort of inheritance, so I can't even make an abstract set of commands to use within RoboBasic. I borderline understand how to send byte commands in C while using a bluetooth device, but of course that doesn't help much here. :]

Will just write a program that allows the person to write the commands in Python and then save a Robobasic-compatible file.

  • 2 July 2008: Looked at sensors again and picked out a few that seemed cool; lurked the RoboSavvy forums to see what bluetooth devices seemed most popular. Should get some sensors in soon.
  • 16 July 2008: GUI got erased in freak Ubuntu accident, but apparently won't be needing it anyway.

Instead, have list of actions that will (as of now) be included in Myro (Along with their code letter. If you were interested.):

STANDARD_POSE    'A
BEND             'B
SIT              'C
STEP_FORWARD     'D
STEP_BACKWARD    'E
STEP_LEFT        'F
STEP_RIGHT       'G
TURN_LEFT        'H
TURN_RIGHT       'I
LEFT_KICK        'J
RIGHT_KICK       'K
LEFT_CHOP        'L
RIGHT_CHOP       'M
FORWARD_STANDUP  'N
BACKWARD_STANDUP 'O
PUNCH_FRONT      'P
PUNCH_LEFT       'Q
PUNCH_RIGHT      'R
TUMBLE_FORWARD   'S
TUBLE_BACKWARD   'T
CARTWHEEL_LEFT   'U
CARTWHEEL_RIGHT  'V

Writing the Myro stuff now.

Creating New Interface for Students to Work With RoboNova-1 Using Python

20 June 2008: Came up with initial list of functions that can be used for doing stuff with Robonova in Myro/Pyro:

#Commands

#stepForward()
#stepBackward()
#moveOneLeg("leg","direction")
##leg = left, right
##direction = forward, back, left, right, forOut, backOut, lOut, rOut, bend
#bend()
#moveArm("arm", "direction")
##arm = left, right
##direction = front, back, up, horiz, toChest
#standardPose()

#kick("direction")
##directon = left, right
#chop("direction")
##directon = left, right
#dance()
#fly()
#punch("direction")
##directon = left, right

#read<sensor>() //no sensors to read yet :/

#playSound(pitch, length)
#playMusic([listOfNotes])
##notes = A-G
##T = tempo;
##L = low octave;
##M = mid octave;
##H = high octave;
##+,# = sharp;
##$,- = flat
##. = dotted note
##P,<sp>,(rest) = rest
##<,L = drop an octave
##>,H = raise an octave
##1 = whole note; 2 = half note, 4 = quarter note, 8 = eighth note
##6 = sixteenth note; 0 = thirty-second note

Haven't actually written them yet; read some BASIC tutorials to get a better feel for the language so I could try and figure out how to make easy Python code that will also easily translate into a BASIC format.

  • 1 July 2008: Writing program to translate the simple Python commands into roboBasic. More annoying than previously expected, but almost done with recognizing if/else statements correctly (problem comes with the "end" statement that's got to come at the end of the whole block, instead of just after if blocks or just after else blocks).
  • 2 July 2008: Finished program. Started on a GUI, and ended up with something resembling a grey chatroom window. Looking around to see if there's a(n easy) way of putting text boxes in a graphics window so I can make something that looks a tad nicer (I could do it with JAVA >__>;;; ). Made a short help dictionary for the GUI when it gets finished.
  • 7 July 2008: Will be working on GUI and the robot movements; see if I can make some original ones that could be useful for general programs, as well as make the existing movements better, nicer-looking.
  • 14 July 2008 (Vive la France!): Found a program (Glade3) for making GUI in Python; made a prototype but it got erased in a freak Ubuntu accident. Will have to remake it; will also see about having the GUI also do the compiling of the RoboBasic code, and allow it to do simple movements by pressing an indicated letter/number key.

List of commands currently supported by the GUI (right now case-sensitive):

standardPose()
bend()
sit()
stepForward()
stepBackward()
stepLeft()
stepRight()
turnLeft()
turnRight()
leftKick()
rightKick()
leftChop()
rightChop()
getUp("front"); getUp("back")
punch("right"); punch("left"); punch("front")
beep(<frequency>, <length>)
playMusic([<listOfNotes>])
 * notes = A-G
 * T = tempo;
 * L = low octave;
 * M = mid octave;
 * H = high octave;
 * +,# = sharp;
 * $,- = flat
 * . = dotted note
 * P,<sp>,(rest) = rest
 * <,L = drop an octave
 * >,H = raise an octave
 * 1 = whole note; 2 = half note, 4 = quarter note, 8 = eighth note
 * 6 = sixteenth note; 0 = thirty-second note
delay(<seconds>)

Conclusions Drawn Thus Far

coming soon!

Media

Pictures

Coming soon!

Manuals

Robonova-1 Instruction Manual v1.0 : Powerpoint of tips for using Robonova-1. In case someone has to do some roboBASIC coding in the future, since the provided documentation's not so great.

Robonova-1 Instruction Manual v1.5 : V1.5 of Powerpoint.

Robonova-1 Instruction Manual v1.75 : The Exciting V1.75 of the Powerpoint Manual.

Robonova-1 Instruction Manual v2.0 : The Highly-Anticipated V2.0 of the Powerpoint Manual.

Myro Code v0.5

import math, serial

#ser = serial.Serial("/dev/ttyS0", 57600)
serial = serial.Serial("COM1", 57600)

def openPort():
    serial.open()

def standardPose():
    serial.write("A")
    
def bend():
    serial.write("B")
    
def sit():
    serial.write("C")

def step(distance, direction = "forward"):
    go = direction
    if go.lower() == "forward":
        steps = int(round(distance/10.0))
        for i in range(steps):
            serial.write("D")
    elif go.lower() == "backward":
        steps = int(round(distance/19.5))
        for i in range(steps):
            serial.write("E")
    elif go.lower() == "left":
        steps = int(round(distance/4.5))
        for i in range(steps):
            serial.write("F")
    elif go.lower() == "right":
        steps = int(round(distance/6.0))
        for i in range(steps):
            serial.write("G")
    else:
        print "Can't take a step that way!"

def turn(direction, angle = 90):
    go = direction
    if go.lower() == "left":
        turns = int(round(angle/12))
        serial.write("H")
    elif go.lower() == "right":
        turns = int(round(angle/14))
        serial.write("I")
    else:
        print "Can't turn that way!"

def kick(direction):
    go = direction
    if go.lower() == "left":
        serial.write("J")
    elif go.lower() == "right":
        serial.write("K")
    else:
        print "Can't kick like that!"
        
def chop(direction):
    go = direction
    if go.lower() == "left":
        serial.write("L")
    elif go.lower() == "right":
        serial.write("M")
    else:
        print "Can't do a chop that way!"

def getUp(direction = "onStomach"):
    go = direction
    if go.lower() == "onstomach":
        serial.write("N")
    elif go.lower() == "onback":
        serial.write("O")
    else:
        print "Can't get up that way!"

def punch(direction = "front"):
    go = direction
    if go.lower() == "left":
        serial.write("P")
    elif go.lower() == "right":
        serial.write("Q")
    elif go.lower() == "front":
        serial.write("R")
    else:
        print "Can't punch that way!"

def closePort():
    serial.close()

Master Robonova-1 Program (For Use With Myro)

'=============================================================================
'Robonova-1 Master Program : Contains all commands that Myro
'                            will include in its code
'X : temporary variable     /Reads ASCII values of commands 
'			     from Myro
'
'============================== auto_main ====================================
DIM X AS BYTE

PTP SETON
PTP ALLON

'======================== Motor Direction Setting ============================
DIR G6A,1,0,0,1,0,0		
DIR G6B,1,1,1,1,1,1		
DIR G6C,0,0,0,0,0,0		
DIR G6D,0,1,1,0,1,0		

'======================= Motor Start Position Read ===========================
TEMPO 230
MUSIC "CDE"
GETMOTORSET G24,1,1,1,1,1,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,1,0

'============================ Motor Power On  ================================
SPEED 5
MOTOR G24	
GOSUB STANDARD_POSE

MAIN:
	GOSUB READ_FLUKE
	'GOSUB WRITE_FLUKE
	
	IF X = 65 THEN 
		GOSUB STANDARD_POSE    'A
	ELSEIF X = 66 THEN
		GOSUB BEND             'B
	ELSEIF X = 67 THEN 
		GOSUB SIT              'C
	ELSEIF X = 68 THEN 
		GOSUB STEP_FORWARD     'D
		DELAY 1000
		GOSUB STANDARD_POSE
	ELSEIF X = 69 THEN 
		GOSUB STEP_BACKWARD    'E
		DELAY 1000
		GOSUB STANDARD_POSE
	ELSEIF X = 70 THEN 
		GOSUB STEP_LEFT        'F
		DELAY 1000
		GOSUB STANDARD_POSE
	ELSEIF X = 71 THEN 
		GOSUB STEP_RIGHT       'G
		DELAY 1000
		GOSUB STANDARD_POSE
	ELSEIF X = 72 THEN 
		GOSUB TURN_LEFT        'H
		DELAY 1000
		GOSUB STANDARD_POSE
	ELSEIF X = 73 THEN
		GOSUB TURN_RIGHT       'I
		DELAY 1000
		GOSUB STANDARD_POSE
	ELSEIF X = 74 THEN 
		GOSUB LEFT_KICK        'J
		DELAY 1000
		GOSUB STANDARD_POSE
	ELSEIF X = 75 THEN 
		GOSUB RIGHT_KICK       'K
		DELAY 1000
		GOSUB STANDARD_POSE
	ELSEIF X = 76 THEN 
		GOSUB LEFT_CHOP        'L
		DELAY 1000
		GOSUB STANDARD_POSE
	ELSEIF X = 77 THEN 
		GOSUB RIGHT_CHOP       'M
		DELAY 1000
		GOSUB STANDARD_POSE
	ELSEIF X = 78 THEN 
		GOSUB FORWARD_STANDUP  'N
		DELAY 1000
		GOSUB STANDARD_POSE
	ELSEIF X = 79 THEN 
		GOSUB BACKWARD_STANDUP 'O
		DELAY 1000
		GOSUB STANDARD_POSE
	ELSEIF X = 80 THEN 
		GOSUB PUNCH_LEFT       'P
		DELAY 1000
		GOSUB STANDARD_POSE
	ELSEIF X = 81 THEN
		GOSUB PUNCH_RIGHT 'Q
		DELAY 1000
		GOSUB STANDARD_POSE
	ELSEIF X = 82 THEN 
		GOSUB PUNCH_FRONT 'R
		DELAY 1000
		GOSUB STANDARD_POSE
'	ELSEIF X = 83 THEN GOSUB READ_ACCELEROMETER 'S
'	ELSEIF X = 84 THEN GOSUB READ_GYRO 'T
'	ELSEIF X = 85 THEN GOSUB READ_IR 'U
'	ELSEIF X = 86 THEN GOSUB READ_SONAR 'V
'	ELSEIF X = 87 THEN GOSUB READ_LIGHT 'W
'	ELSEIF X = 88 THEN GOSUB READ_SOUND 'X
'	ELSEIF X = 89 THEN GOSUB READ_TOUCH 'Y

	ELSE
		MUSIC "<C"

	ENDIF
	GOTO MAIN

READ_FLUKE:
	ERX 57600, X, READ_FLUKE
	RETURN
	
'WRITE_FLUKE:
'	ETX 115200, X
'	RETURN
	
'=============================================================================
STANDARD_POSE:

	MOVE G6A,100,  76, 145,  93, 100, 100
	MOVE G6D,100,  76, 145,  93, 100, 100
	MOVE G6B,100,  30,  80, 100, 100, 100
	MOVE G6C,100,  30,  80, 100, 100, 100
	WAIT

	RETURN

'=============================================================================
BEND:
	SPEED 8
	MOVE G6A, 100, 58, 135, 160, 100, 100
	MOVE G6D, 100, 58, 135, 160, 100, 100
	MOVE G6B, 100, 30, 80, , , ,
	MOVE G6C, 100, 30, 80, , , ,
	WAIT

	SPEED 6

	RETURN

'=============================================================================
SIT:
	SPEED 10
	MOVE G6A,100, 151,  23, 140, 101, 100
	MOVE G6D,100, 151,  23, 140, 101, 100
	MOVE G6B,100,  30,  80, 100, 100, 100
	MOVE G6C,100,  30,  80, 100, 100, 100	
	WAIT

	RETURN

'=============================================================================
STEP_FORWARD:

	SPEED 5
	MOVE24  85,  71, 152,  91, 112,  60, 100,  40,  80,    ,    ,    , 100,  40,  80,    ,    ,    , 112,  76, 145,  93,  92,  60,
	
	SPEED 14
	MOVE24  90, 107, 105, 105, 114,  60,  90,  40,  80,    ,    ,    , 100,  40,  80,    ,    ,    , 114,  76, 145,  93,  90,  60,
	MOVE24  90,  56, 143, 122, 114,  60,  80,  40,  80,    ,    ,    , 105,  40,  80,    ,    ,    , 113,  80, 145,  90,  90,  60,
	MOVE24  90,  46, 163, 112, 114,  60,  80,  40,  80,    ,    ,    , 105,  40,  80,    ,    ,    , 112,  80, 145,  90,  90,  60,

	SPEED 10
	MOVE24 100,  66, 141, 113, 100, 100,  90,  40,  80,    ,    ,    , 100,  40,  80,    ,    ,    , 100,  83, 156,  80, 100, 100,
	MOVE24 113,  78, 142, 105,  90,  60, 100,  40,  80,    ,    ,    , 100,  40,  80,    ,    ,    ,  90, 102, 136,  85, 114,  60,

	SPEED 14
	MOVE24 113,  76, 145,  93,  90,  60, 100,  40,  80,    ,    ,    ,  90,  40,  80,    ,    ,    ,  90, 107, 105, 105, 114,  60,
	MOVE24 113,  80, 145,  90,  90,  60, 105,  40,  80,    ,    ,    ,  80,  40,  80,    ,    ,    ,  90,  56, 143, 122, 114,  60,
	MOVE24 112,  80, 145,  90,  90,  60, 105,  40,  80,    ,    ,    ,  80,  40,  80,    ,    ,    ,  90,  46, 163, 112, 114,  60,

	SPEED 10
	MOVE24 100,  83, 156,  80, 100, 100, 100,  40,  80,    ,    ,    ,  90,  40,  80,    ,    ,    , 100,  66, 141, 113, 100, 100,
	MOVE24  90, 102, 136,  85, 114,  60, 100,  40,  80,    ,    ,    , 100,  40,  80,    ,    ,    , 113,  78, 142, 105,  90,  60,
	
	SPEED 14
	MOVE24  90, 107, 105, 105, 114,  60,  90,  40,  80,    ,    ,    , 100,  40,  80,    ,    ,    , 113,  76, 145,  93,  90,  60,
	
	SPEED 5
	MOVE24  85,  71, 152,  91, 112,  60, 100,  40,  80,    ,    ,    , 100,  40,  80,    ,    ,    , 112,  76, 145,  93,  92,  60,
	WAIT

	RETURN

'=============================================================================
STEP_BACKWARD:

	SPEED 5
	MOVE G6A, 85,  71, 152,  91, 112, 60
	MOVE G6D,112,  76, 145,  93,  92, 60
	MOVE G6B,100,  40,  80, , , ,
	MOVE G6C,100,  40,  80, , , ,
	WAIT

	SPEED 13
	MOVE G6A, 90, 107, 105, 105, 114, 60
	MOVE G6D,113,  78, 145,  93,  90, 60
	MOVE G6B, 90,  40,  80, , , ,
	MOVE G6C,100,  40,  80, , , ,
	WAIT

	SPEED 7
	MOVE G6D,113,  76, 142, 105,  90, 60
	MOVE G6A, 90,  96, 136,  85, 114, 60
	MOVE G6C,100,  40,  80, , , ,	
	MOVE G6B,100,  40,  80, , , ,
	WAIT

	MOVE G6D,100,  62, 146, 108, 100, 100
	MOVE G6A,100,  88, 140,  86, 100, 100
	MOVE G6C,90,  40,  80, , , ,
	MOVE G6B,100,  40,  80, , , ,
	WAIT
	
	MOVE G6D,90,  56, 143, 122, 114,  60
	MOVE G6A,113,  80, 145,  90,  90,  60
	MOVE G6C,80,  40,  80, , , ,
	MOVE G6B,105,  40,  80, , , ,
	WAIT
	
	SPEED 13
	MOVE G6D,90, 107, 105, 105, 114, 60
	MOVE G6A,113,  78, 145,  93, 90, 60
	MOVE G6C,90,  40,  80, , , ,
	MOVE G6B,100,  40,  80, , , ,
	WAIT

	SPEED 7
	MOVE G6A,113,  76, 142, 105,  90, 60
	MOVE G6D,90,  96, 136,  85, 114, 60
	MOVE G6B,100,  40,  80, , , ,
	MOVE G6C,100,  40,  80, , , ,
	WAIT

	MOVE G6A,100,  62, 146, 108, 100, 100
	MOVE G6D,100,  88, 140,  86, 100, 100
	MOVE G6B, 90,  40,  80, , , ,
	MOVE G6C,100,  40,  80, , , ,
	WAIT
	
	MOVE G6A, 90,  56, 143, 122, 114,  60
	MOVE G6D,113,  80, 145,  90,  90,  60
	MOVE G6B, 80,  40,  80, , , ,
	MOVE G6C,105,  40,  80, , , ,
	WAIT

	SPEED 13
	MOVE G6A, 90, 107, 105, 105, 114, 60
	MOVE G6D,113,  78, 145,  93,  90, 60
	MOVE G6B, 90,  40,  80, , , ,
	MOVE G6C,100,  40,  80, , , ,
	WAIT

	SPEED 5
	MOVE G6A, 85,  71, 152,  91, 112, 60
	MOVE G6D,112,  76, 145,  93,  92, 60
	MOVE G6B,100,  40,  80, , , ,
	MOVE G6C,100,  40,  80, , , ,
	WAIT

	RETURN

'=============================================================================
STEP_LEFT:
	
	SPEED 5
	MOVE G6A,  85,  71, 152,  91, 112,  60,
	MOVE G6D, 112,  76, 145,  93,  92,  60,
	MOVE G6B, 100,  40,  80,    ,    ,    ,
	MOVE G6C, 100,  40,  80,    ,    ,    ,
	WAIT

	SPEED 9
	MOVE G6D, 110,  92, 124,  97,  93,  70,
	MOVE G6A,  76,  72, 160,  82, 128,  70,
	MOVE G6B, 100,  35,  90,    ,    ,    ,
	MOVE G6C, 100,  35,  90,    ,    ,    ,
	WAIT

	MOVE G6A,  93,  76, 145,  94, 109, 100,
	MOVE G6D,  93,  76, 145,  94, 109, 100, 
	MOVE G6B, 100,  35,  90,    ,    ,    ,
	MOVE G6C, 100,  35,  90,    ,    ,    ,
	WAIT
	
	MOVE G6A, 110,  92, 124,  97,  93,  70,
	MOVE G6D,  76,  72, 160,  82, 128,  70,
	MOVE G6B, 100,  35,  90,    ,    ,    ,
	MOVE G6C, 100,  35,  90,    ,    ,    ,
	WAIT

	SPEED 9
	MOVE G6D,  86,  83, 135,  97, 114,  60,
	MOVE G6A, 113,  78, 145,  93,  93,  60,
	MOVE G6C,  90,  40,  80,    ,    ,    , 
	MOVE G6B, 100,  40,  80,    ,    ,    , 
	WAIT
	
	MOVE G6D,  85,  71, 152,  91, 112,  60,
	MOVE G6A, 112,  76, 145,  93,  92,  60,
	MOVE G6C, 100,  40,  80,    ,    ,    ,
	MOVE G6B, 100,  40,  80,    ,    ,    ,
	WAIT

	SPEED 6

	RETURN

'=============================================================================
STEP_RIGHT:

	SPEED 5
	MOVE G6D,  85,  71, 152,  91, 112, 60 
	MOVE G6A, 112,  76, 145,  93,  92, 60
	MOVE G6C, 100,  40,  80,  ,  ,  ,
	MOVE G6B, 100,  40,  80,  ,  ,  ,
	WAIT

	SPEED 9
	MOVE G6A,110,  92, 124,  97,  93,  70
	MOVE G6D, 76,  72, 160,  82, 128,  70
	MOVE G6B,100,  35,  90, , , ,
	MOVE G6C,100,  35,  90, , , ,
	WAIT
	
	MOVE G6A, 93,  76, 145,  94, 109, 100
	MOVE G6D, 93,  76, 145,  94, 109, 100	
	MOVE G6B,100,  35,  90, , , ,
	MOVE G6C,100,  35,  90, , , ,	
	WAIT

	MOVE G6D,110,  92, 124,  97,  93,  70
	MOVE G6A, 76,  72, 160,  82, 128,  70
	MOVE G6B,100,  35,  90, , , ,
	MOVE G6C,100,  35,  90, , , ,
	WAIT

	MOVE G6A, 86,  83, 135,  97, 114,  60
	MOVE G6D,113,  78, 145,  93,  93,  60
	MOVE G6B, 90,  40,  80, , , ,
	MOVE G6C,100,  40,  80, , , ,
	WAIT

	MOVE G6A, 85,  71, 152,  91, 112, 60
	MOVE G6D,112,  76, 145,  93,  92, 60
	MOVE G6B,100,  40,  80, , , ,	
	MOVE G6C,100,  40,  80, , , ,
	WAIT
	
	SPEED 6

	RETURN

'=============================================================================
TURN_LEFT:

	SPEED 6
	MOVE G6D,  85,  71, 152,  91, 112,  60
	MOVE G6A, 112,  76, 145,  93,  92,  60
	MOVE G6C, 100,  40,  80,    ,    ,    ,
	MOVE G6B, 100,  40,  80,    ,    ,    ,
	WAIT
	
	SPEED 9
	MOVE G6A, 113,  75, 145,  97,  93,  60
	MOVE G6D,  90,  50, 157, 115, 112,  60
	MOVE G6B, 105,  40,  70,    ,    ,    ,
	MOVE G6C,  90,  40,  70,    ,    ,    ,
	WAIT

	MOVE G6A, 108,  78, 145,  98,  93,  60
	MOVE G6D,  95,  43, 169, 110, 110,  60
	MOVE G6B, 105,  40,  70,    ,    ,    ,
	MOVE G6C,  80,  40,  70,    ,    ,    ,
	WAIT

	RETURN

'=============================================================================
TURN_RIGHT:

	SPEED 6
	MOVE G6A,  85,  71, 152,  91, 112,  60
	MOVE G6D, 112,  76, 145,  93,  92,  60
	MOVE G6B, 100,  40,  80,    ,    ,    ,
	MOVE G6C, 100,  40,  80,    ,    ,    ,
	WAIT

	SPEED 9
	MOVE G6D, 113,  75, 145,  97,  93,  60
	MOVE G6A,  90,  50, 157, 115, 112,  60
	MOVE G6C, 105,  40,  70,    ,    ,    ,
	MOVE G6B,  90,  40,  70,    ,    ,    ,
	WAIT

	MOVE G6D, 108,  78, 145,  98,  93,  60
	MOVE G6A,  95,  43, 169, 110, 110,  60
	MOVE G6C, 105,  40,  70,    ,    ,    ,
	MOVE G6B,  80,  40,  70,    ,    ,    ,
	WAIT

	RETURN

'=============================================================================
LEFT_KICK:

	SPEED 4
	MOVE G6A, 70,  56, 180,  79, 102, 100
	MOVE G6D,112,  56, 180,  79, 104, 100
	MOVE G6B, 90,  45,  70, 100, 100, 100
	MOVE G6C,110,  45,  70, 100, 100, 100
	WAIT

	SPEED 6
	MOVE G6A, 90,  90, 127,  65, 116,  100
	MOVE G6D,115,  60, 180,  79,  95,  100
	MOVE G6B,140,  45,  70, 100, 100, 100
	MOVE G6C, 60,  45,  70, 100, 100, 100
	WAIT

	SPEED 15
	HIGHSPEED SETON
	MOVE G6A, 90,  90, 127, 147, 116,  100
	MOVE G6D,115,  52, 180,  79,  95,  100
	MOVE G6B, 60,  45,  70, 100, 100, 100
	MOVE G6C,140,  45,  70, 100, 100, 100
	WAIT

	DELAY 500
	HIGHSPEED SETOFF
	SPEED 5
	MOVE G6A, 70,  76, 145,  93, 104, 100
	MOVE G6D,115,  76, 145,  93, 102, 100
	MOVE G6B, 90,  45,  70, 100, 100, 100	
	MOVE G6C,110,  45,  70, 100, 100, 100
	WAIT

	RETURN

'=============================================================================
RIGHT_KICK:

	SPEED 4
	MOVE G6A,112,  56, 180,  79, 104, 100
	MOVE G6D, 70,  56, 180,  79, 102, 100
	MOVE G6B,110,  45,  70, 100, 100, 100
	MOVE G6C, 90,  45,  70, 100, 100, 100
	WAIT

	SPEED 6
	MOVE G6A,115,  60, 180,  79,  95,  100
	MOVE G6D, 90,  90, 127,  65, 116,  100
	MOVE G6B, 80,  45,  70, 100, 100, 100
	MOVE G6C,120,  45,  70, 100, 100, 100
	WAIT

	SPEED 15
	HIGHSPEED SETON
	MOVE G6A,115,  52, 180,  79,  95,  100
	MOVE G6D, 90,  90, 127, 147, 116,  100
	MOVE G6B,140,  45,  70, 100, 100, 100
	MOVE G6C, 60,  45,  70, 100, 100, 100
	WAIT

	DELAY 500
	HIGHSPEED SETOFF
	SPEED 5
	MOVE G6A,115,  76, 145,  93, 102, 100
	MOVE G6D, 70,  76, 145,  93, 104, 100
	MOVE G6B,110,  45,  70, 100, 100, 100
	MOVE G6C, 90,  45,  70, 100, 100, 100
	WAIT

	RETURN

'=============================================================================
LEFT_CHOP:

	SPEED 7
	MOVE G6A,  85,  71, 152,  91, 107, 60
	MOVE G6D, 108,  76, 145,  93, 100, 60
	MOVE G6B, 100,  40,  80,  ,  ,  ,
	MOVE G6C, 100,  40,  80,  ,  ,  ,
	WAIT

	SPEED 12
	HIGHSPEED SETON
	MOVE G6A, 98, 157,  20, 134, 110, 100
	MOVE G6D, 57, 115,  77, 125, 134, 100
	MOVE G6B,107, 135, 108, 100, 100, 100
	MOVE G6C,112,  92,  99, 100, 100, 100
	WAIT

	DELAY 1000
	HIGHSPEED SETOFF
	SPEED 15

	GOSUB SIT

	RETURN

'=============================================================================
RIGHT_CHOP:

	SPEED 7
	MOVE G6D,  85,  71, 152,  91, 107, 60
	MOVE G6A, 108,  76, 145,  93, 100, 60
	MOVE G6C, 100,  40,  80,  ,  ,  ,
	MOVE G6B, 100,  40,  80,  ,  ,  ,
	WAIT
	
	SPEED 12
	HIGHSPEED SETON
	MOVE G6D, 98, 157,  20, 134, 110, 100
	MOVE G6A, 57, 115,  77, 125, 134, 100
	MOVE G6B,112,  92,  99, 100, 100, 100
	MOVE G6C,107, 135, 108, 100, 100, 100
	WAIT

	DELAY 1000
	HIGHSPEED SETOFF
	SPEED 15

	GOSUB SIT

	RETURN

'=============================================================================
FORWARD_STANDUP:

	SPEED 10
	MOVE G6A,100, 130, 120,  80, 110, 100
	MOVE G6D,100, 130, 120,  80, 110, 100
	MOVE G6B,150, 160,  10, 100, 100, 100
	MOVE G6C,150, 160,  10, 100, 100, 100
	WAIT

	MOVE G6A, 80, 155,  85, 150, 150, 100
	MOVE G6D, 80, 155,  85, 150, 150, 100
	MOVE G6B,185,  40, 60,  100, 100, 100
	MOVE G6C,185,  40, 60,  100, 100, 100
	WAIT

	MOVE G6A, 75, 165,  55, 165, 155, 100
	MOVE G6D, 75, 165,  55, 165, 155, 100
	MOVE G6B,185,  10, 100, 100, 100, 100
	MOVE G6C,185,  10, 100, 100, 100, 100
	WAIT

	MOVE G6A, 60, 165,  30, 165, 155, 100
	MOVE G6D, 60, 165,  30, 165, 155, 100
	MOVE G6B,170,  10, 100, 100, 100, 100
	MOVE G6C,170,  10, 100, 100, 100, 100
	WAIT

	MOVE G6A, 60, 165,  25, 160, 145, 100
	MOVE G6D, 60, 165,  25, 160, 145, 100
	MOVE G6B,150,  60,  90, 100, 100, 100
	MOVE G6C,150,  60,  90, 100, 100, 100
	WAIT

	MOVE G6A,100, 155,  25, 140, 100, 100
	MOVE G6D,100, 155,  25, 140, 100, 100
	MOVE G6B,130,  50,  85, 100, 100, 100
	MOVE G6C,130,  50,  85, 100, 100, 100
	WAIT

	RETURN

'=============================================================================
BACKWARD_STANDUP:

	SPEED 10
	MOVE G6A,100,  10, 100, 115, 100, 100
	MOVE G6D,100,  10, 100, 115, 100, 100
	MOVE G6B,100, 130,  10, 100, 100, 100
	MOVE G6C,100, 130,  10, 100, 100, 100
	WAIT

	MOVE G6A,100, 10,  83, 140, 100, 100
	MOVE G6D,100, 10,  83, 140, 100, 100
	MOVE G6B,20, 130,  10, 100, 100, 100
	MOVE G6C,20, 130,  10, 100, 100, 100
	WAIT

	MOVE G6A,100, 126,  60, 50, 100, 100
	MOVE G6D,100, 126,  60, 50, 100, 100
	MOVE G6B,20,  30,  90, 100, 100, 100
	MOVE G6C,20,  30,  90, 100, 100, 100
	WAIT

	MOVE G6A,100, 165,  70, 15, 100, 100
	MOVE G6D,100, 165,  70, 15, 100, 100
	MOVE G6B, 30,  20,  95,100, 100, 100
	MOVE G6C, 30,  20,  95,100, 100, 100
	WAIT

	MOVE G6A,100, 165,  40, 100, 100, 100
	MOVE G6D,100, 165,  40, 100, 100, 100
	MOVE G6B,110,  70,  50, 100, 100, 100
	MOVE G6C,110,  70,  50, 100, 100, 100
	WAIT

	RETURN

'=============================================================================
PUNCH_RIGHT:

	SPEED 7
	MOVE G6A, 108,  76, 145,  93, 100, 60
	MOVE G6D,  85,  71, 152,  91, 107, 60
	MOVE G6B,  70,  40,  80,  ,  ,  ,
	MOVE G6C, 130,  40,  80,  ,  ,  ,
	WAIT

	SPEED 10
	HIGHSPEED SETON
	MOVE G6A,  66, 163,  85,  65, 130
	MOVE G6D, 107, 164,  21, 125,  93
	MOVE G6B,  50,  72,  86
	MOVE G6C, 189,  40,  77
	WAIT

	DELAY 1000
	HIGHSPEED SETOFF

	GOSUB SIT

	RETURN

'=============================================================================
PUNCH_LEFT:

	SPEED 7
	MOVE G6A,  85,  71, 152,  91, 107, 60
	MOVE G6D, 108,  76, 145,  93, 100, 60
	MOVE G6B, 130,  40,  80,  ,  ,  ,
	MOVE G6C,  70,  40,  80,  ,  ,  ,
	WAIT

	SPEED 12
	HIGHSPEED SETON
	MOVE G6A, 107, 164,  21, 125,  93
	MOVE G6D,  66, 163,  85,  65, 130
	MOVE G6B, 189,  40,  77
	MOVE G6C,  50,  72,  86
	WAIT
	
	DELAY 1000
	HIGHSPEED SETOFF

	GOSUB SIT

	RETURN

'=============================================================================
PUNCH_FRONT:

	SPEED 15
	MOVE G6A, 92, 100, 110, 100, 107, 100
	MOVE G6D, 92, 100, 110, 100, 107, 100
	MOVE G6B,190, 150,  10, 100, 100, 100
	MOVE G6C,190, 150,  10, 100, 100, 100
	WAIT
	
	SPEED 15
	HIGHSPEED SETON
	MOVE G6B,190,  10, 75, 100, 100, 100
	MOVE G6C,190, 140,  10, 100, 100, 100
	WAIT
	DELAY 500
	
	MOVE G6B,190, 140,  10, 100, 100, 100
	MOVE G6C,190,  10, 75, 100, 100, 100
	WAIT
	DELAY 500

	MOVE G6A, 92, 100, 113, 100, 107, 100
	MOVE G6D, 92, 100, 113, 100, 107, 100
	MOVE G6B,190, 150,  10, 100, 100, 100
	MOVE G6C,190, 150,  10, 100, 100, 100
	WAIT
	
	HIGHSPEED SETOFF
	MOVE G6A,100, 115,  90, 110, 100, 100
	MOVE G6D,100, 115,  90, 110, 100, 100
	MOVE G6B,100,  80,  60, 100, 100, 100
	MOVE G6C,100,  80,  60, 100, 100, 100
	WAIT

	RETURN

'=============================================================================
'READ_ACCELEROMETER:
'READ_GYRO:
'READ_IR:
'READ_SONAR:
'READ_TOUCH:
'READ_LIGHT:
'READ_SOUND:

References/Useful Links

Blank, D., Kumar, D., Meeden, M., and James Marshall. "Bringing up robot: Fundamental mechanisms for creating a self-mativated, self-organizing architecture." (more info later)

Blank, D., Kumar, D., Meeden, M., and Holly Yanco. "Pyro: A Python-based Versatile Programming Environment for Teaching Robotics." (more info later)

PyroRobotics.com: Best resource for learning how to use Pyro, and a good resource for learning about neural networks and robot behavior through simulations as well as real-life robot programming.

Python AI Research: Article that discusses using Python in AI programming. Includes description of ELIZA and various other intelligence programs that have been written in Python.

A Framework for Reactive Intelligence through Agile Component-Based Behaviors: Dissertation about using Python for programming robot behaviors. Gives some interesting reasons for using Python over languages like C++ and Java, and goes into detail about a proposed behavior model.

AI Expert Newsletter: This article mainly looked at Pyro, but also talks about some of the advancements in computer intelligence, such as their ability (or inability) to produce jokes that humans find funny.

Morgan, Sara. Programming Microsoft Robotics Studio. Redmond, Washington: Microsoft Press, 2008.

Microsoft Robotics: Home page of MRDS. The tutorials are pretty good, and the forums are your best bet for finding out how to do everything else.

RoboSavvy Forums: Provides extensive information about the Robonova-1, its software, and its hardware. A must-read for anyone working with the robot.

Hacking the Fluke - details on the Fluke and how to communicate with robots through it.