import logging
import time

# Attempt to load gopigo, which is not available when simulating the robot.
try:
    import gopigo
    gopigo_available = True
except ImportError:
    gopigo_available = False


class Actuator(object):
    @property
    def actions(self):
        raise NotImplementedError()

    def act(self, action):
        if action not in self.actions:
            return False
        if action is None:
            # Do nothing, which is valid.
            return True
        return self._act(action)

    def _act(self, action):
        raise NotImplementedError()


class MotorAction(object):
    IDLE, FORWARD, BACKWARD, TURN_LEFT, TURN_RIGHT = range(5)


class Motors(Actuator):
    def __init__(self):
        self.duration = 0.05

    @property
    def actions(self):
        return [MotorAction.FORWARD, MotorAction.BACKWARD, MotorAction.IDLE, MotorAction.TURN_LEFT,
                MotorAction.TURN_RIGHT]

    def _act(self, action):
        if not gopigo_available:
            return False

        # Translate to action.
        if action == MotorAction.TURN_LEFT:
            action_call = gopigo.left
        elif action == MotorAction.TURN_RIGHT:
            action_call = gopigo.right
        elif action == MotorAction.FORWARD:
            action_call = gopigo.fwd
        elif action == MotorAction.BACKWARD:
            action_call = gopigo.bwd
        elif action == MotorAction.IDLE:
            action_call = gopigo.stop
        else:
            action_call = None
        assert action_call is not None

        # Perform action for `duration` seconds and stop afterwards.
        logging.info('performing motor action %d' % action)
        action_call()
        time.sleep(self.duration)
        gopigo.stop()
        return True


class SimulatedMotors(Motors):
    def _act(self, action):
        logging.info('simulating motor action %d' % action)
        time.sleep(self.duration)
        return True

@@ -21,16 +21,32 @@
 t time%0A%0A
+import freenect%0A
 # Attemp
@@ -1939,28 +1939,744 @@
 ration)%0A        return True%0A
+%0A%0Aclass KinectTiltMotor(Actuator):%0A    @property%0A    def actions(self):%0A        return range(-20, 20)%0A%0A    def _act(self, action):%0A        return freenect.sync_set_tilt_degs(action) == 0%0A%0A%0Aclass LEDAction(object):%0A    OFF = freenect.LED_OFF%0A    GREEN = freenect.LED_GREEN%0A    RED = freenect.LED_RED%0A    YELLOW = freenect.LED_YELLOW%0A    BLINK_GREEN = freenect.LED_BLINK_GREEN%0A    BLINK_RED_YELLOW = freenect.LED_BLINK_RED_YELLOW%0A%0A%0Aclass KinectLED(Actuator):%0A    @property%0A    def actions(self):%0A        return %5BLEDAction.OFF, LEDAction.GREEN, LEDAction.RED, LEDAction.YELLOW, LEDAction.BLINK_GREEN,%0A                LEDAction.BLINK_RED_YELLOW%5D%0A%0A    def _act(self, action):%0A        return freenect.sync_set_led(action)%0A

Add Kinect actuators