16-264: Humanoids Assignment #2: Learning

Robotic Piñatas

Gregory Collins, Daniel Cannon, Alexander Williams

Description:

The basic concept behind this assignment was to have a robot try and hit a “piñata” with a bat. A “bat”, constructed out of recycled cardboard, was placed in the grip of the left hand of one robot. We constructed a tower on which a ping pong ball (our piñata) was hung. Initially, we decided on using a second robot to hold the other end of the piñata and have both robots learn from experience how to adjust the system so that a connection between bat and piñata was made. However, we found the human input required to each robot in order to simulate “learning” made the addition of a second robot too tedious. For show, a second robot still holds the other end of the string connected to the piñata.

As with the normal activity of trying to hit a piñata, the individual, or Robosapian RS Media in this case, is blind during the game. A blindfold was provided for the robot during the game. As with a normal case of attempting to hit a piñata, the only way a blindfolded person learns from his or her mistakes is through the cheers and jeers from the surrounding crowd. In our case, we replace the yells from the surrounding crowd with sensor inputs based on missed attempts. Every time the robot swings, we input how the robot missed, and the system adjusts until the robot makes solid contact with the suspended ping pong ball.

Our code is explained further in the following section.

Code:

We found that the robot did not respond correctly to feedback inputs unless all systems being used during the game were previously used. Therefore, we created a warm-up routine for the robot which was performed before we started the “learning” process of the game. The basic code for this is displayed below (not main program, just functions called).

	private void warmUp1() {
    	robot.WAIST_LR_SERVO.moveToPosition(robot.WAIST_LR_SERVO.maxPosition(),4);
        robot.SHOULDER_LEFT_SERVO.moveToPosition(0,8);
        robot.ARM_LEFT_SERVO.moveToPosition(robot.ARM_LEFT_SERVO.maxPosition(),8);
        robot.waitUntilStop();
        robot.ARM_LEFT_SERVO.moveToPosition(1,8);
        robot.waitUntilStop();
        robot.WAIST_LR_SERVO.moveToPosition(20,robot.WAIST_LR_SERVO.maxSpeed());
        robot.waitUntilStop();
   	}
    private void warmUp2() {
     	robot.WAIST_LR_SERVO.moveToPosition(robot.WAIST_LR_SERVO.maxPosition(),4);
        robot.SHOULDER_LEFT_SERVO.moveToPosition(0,8);
        robot.ARM_LEFT_SERVO.moveToPosition(robot.ARM_LEFT_SERVO.maxPosition(),8);
        robot.waitUntilStop();
        robot.ARM_LEFT_SERVO.moveToPosition(1,8);
        robot.waitUntilStop();
        robot.WAIST_LR_SERVO.moveToPosition(10,robot.WAIST_LR_SERVO.maxSpeed());
        robot.waitUntilStop();
   	}    
    private void warmUp3() {
     	robot.WAIST_LR_SERVO.moveToPosition(robot.WAIST_LR_SERVO.maxPosition(),4);
        robot.SHOULDER_LEFT_SERVO.moveToPosition(0,8);
        robot.ARM_LEFT_SERVO.moveToPosition(robot.ARM_LEFT_SERVO.maxPosition(),8);
        robot.waitUntilStop();
        robot.ARM_LEFT_SERVO.moveToPosition(1,8);
        robot.waitUntilStop();
        robot.WAIST_LR_SERVO.moveToPosition(0,robot.WAIST_LR_SERVO.maxSpeed());
        robot.waitUntilStop();
   	}
   	private void warmUp4() {
     	robot.WAIST_LR_SERVO.moveToPosition(robot.WAIST_LR_SERVO.maxPosition(),4);
        robot.SHOULDER_LEFT_SERVO.moveToPosition(0,8);
        robot.ARM_LEFT_SERVO.moveToPosition(robot.ARM_LEFT_SERVO.maxPosition(),8);
        robot.waitUntilStop();
        robot.ARM_LEFT_SERVO.moveToPosition(0,8);
        robot.waitUntilStop();
        robot.ARM_LEFT_SERVO.moveToPosition(robot.ARM_LEFT_SERVO.maxPosition(),8);
        robot.waitUntilStop();
        robot.ARM_LEFT_SERVO.moveToPosition(0,8);
        robot.waitUntilStop();
        try {
        	Thread.sleep(4000);
        } catch (InterruptedException ex) {
        }
   	}
	

Code:

Our learning code is based on a simple feedback system. In order for the robot to swing its bat and hit the suspended ping pong ball, it must be given some input as to how to adjust itself. We decided to focus on the two servos associated with the swinging, or left, arm.

Once finished with its warm-up routine, it enters into a loop. This loop only breaks when it makes contact with the ping pong ball (or when we tell it that it has made contact). We found that we needed to control both the wrist and shoulder servos of the left arm in order to get the robot to make adjustments to where its bat would contact the ping pong ball. Therefore, the “learning” feedback inputs are intended on modifying those servos.

The inputs to the system are based on the sensors on the front and back of the RS Media’s feet. The left foot sensors correspond to adjustments needed to the shoulder and the right foot sensors correspond to adjustments needed to the wrist. After each swing, depending on how the robot missed the target, we press down on the pressure sensors on front or back (front corresponding to an increase in servo position and back corresponding to a decrease in servo position). On the following swing, the robot makes an adjustment to the servo corresponding to the sensor pressed. This process is repeated until the ball is contacted. This “learning process” is meant to represent the robot attempting to correct the height of its arm based on whether it missed high or low.

The code for the main function is provided below.

	private void learnToHit() {
    	int loop=0;
        int shoulderAdd=0;
        int wristAdd=0;
            
        robot.WAIST_LR_SERVO.moveToPosition(robot.WAIST_LR_SERVO.maxPosition(),4);
        robot.SHOULDER_LEFT_SERVO.moveToPosition(shoulder,8);
        robot.ARM_LEFT_SERVO.moveToPosition(wrist,8);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException ex) {
        }
        robot.WAIST_LR_SERVO.moveToPosition(0,robot.WAIST_LR_SERVO.maxSpeed());
        robot.waitUntilStop();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException ex) {
        }
            
        //Left Foot Sensors = Shoulder Adjustments
        //Right Foot Sensors = Wrist Adjustments
            
        while(loop==0) {
        	shoulderAdd=0;
            wristAdd=0;
            if (robot.TOUCH_LEFT_FOOT_FRONT.isTriggered()) {
            	shoulderAdd=5;
            }
            if (robot.TOUCH_LEFT_FOOT_BACK.isTriggered()) {
            	shoulderAdd=-5;
          	}
         	if (robot.TOUCH_RIGHT_FOOT_FRONT.isTriggered()) {
            	wristAdd=1;
            }
            if (robot.TOUCH_RIGHT_FOOT_BACK.isTriggered()) {
            	wristAdd=-1;
            }
                
            shoulder=shoulder+shoulderAdd;
            wrist=wrist+wristAdd;
            if (shoulder>=25)
            	shoulder=0;
            if (shoulder<0)
            	shoulder=24;
            if (wrist>3)
            	wrist=0;
            if (wrist<0)
            	wrist=3;
                
            robot.WAIST_LR_SERVO.moveToPosition(robot.WAIST_LR_SERVO.maxPosition(),4);
            robot.SHOULDER_LEFT_SERVO.moveToPosition(shoulder,8);
            robot.ARM_LEFT_SERVO.moveToPosition(wrist,8);
            try {
            	Thread.sleep(1000);
            } catch (InterruptedException ex) {
            }
            robot.WAIST_LR_SERVO.moveToPosition(0,robot.WAIST_LR_SERVO.maxSpeed());
            robot.waitUntilStop();
            try {
            	Thread.sleep(2000);
            } catch (InterruptedException ex) {
            }
        }
    }
	

General Issues:

We found that the input to the system caused us the most amount of trouble on this assignment. We initially attempted to create some means of inputting directions to the robot through use of the controller and monitor; however we failed in our attempts. When we switched to using the feet, we accomplished our goal, but found that the sensors did not work every time they were pressed. It often took 2-3 times for the robot to respond to inputs. This can be seen in the YouTube video linked below.

YouTube Link for Video of Learning Process: Click Here