Exemplo n.º 1
0
class PidClient:
    MOMENTUM_CONSTANT = 0.10

    def __init__(self):
      stream = open("pid_values.yml", "r")
      pid_values = yaml.load(stream)
    
      self.thetaPid = Pid(pid_values['theta_p'], pid_values['theta_i'], pid_values['theta_d'], True)
      self.xPosPid = Pid(pid_values['xpos_p'], pid_values['xpos_i'], pid_values['xpos_d'], False)
      self.arduino = Arduino()

    def parseState(self, state):
      self.state = state
      self.theta = state[0]
      self.thetaDot = state[1]
      self.xPos = state[2]
      self.phiDot = state[3]

    def updateRadPerSec(self, newRadPerSec):
      self.arduino.updateMotorPower(newRadPerSec)

    def determineControl(self, state):
      self.parseState(state)

      # emergency breaks
      if(abs(self.theta) > 0.30):
        return 0

      self.thetaTerm = self.thetaPid.getControl(self.theta)
      self.xPosTerm = self.xPosPid.getControl(self.xPos)

      # // If the xPosTerm did its job and got us leaning back towards X=0, 
      # // then stop trying to accelerate away from X=0.
      momentum = self.MOMENTUM_CONSTANT *  abs(self.phiDot)

      if abs(self.xPos) < 0.1:
        self.xPosTerm = 0

      if self.xPos > 0 and self.theta < -momentum:
        self.xPosTerm = 0

      if self.xPos < 0 and self.theta > momentum:
        self.xPosTerm = 0

      # note that thetaDotTerm and phiDotTerm are zeroed out.
      newRadPerSec = self.thetaTerm + self.xPosTerm
      newRadPerSec = -newRadPerSec
      newRadPerSec = self._constrain(newRadPerSec, -10, 10)
      return newRadPerSec


    def _constrain(self, val, min_val, max_val):
      return min(max_val, max(min_val, val))
Exemplo n.º 2
0
def main():

    if (len(sys.argv) != 2):
        print("give me a model file as argument please!")
        exit()

    modelfile = sys.argv[1]

    arduino = Arduino()
    model = load_model(modelfile)
    print("waiting for first state...")
    obs = arduino.waitForState()
    print("neat found first state!")

    while (True):
        obs = arduino.waitForState()
        foo = np.array(obs)
        bar = foo.reshape((1, -1))
        action = model.predict(bar, batch_size=1)
        action = action[0][0]
        print(action)
        arduino.updateMotorPower(action)
Exemplo n.º 3
0
class World(BaseWorld):
    MAX_EPISODE_DURATION = 10  # seconds
    MAX_ANGLE = 0.25  # in radians. ~> 14.3 degrees
    MAX_DISTANCE = 30  # in radians

    def __init__(self):
        self.state = State()
        self.arduino = Arduino()
        self.observation_space = SomeSpace(4)
        self.action_space = SomeSpace(1, 1.0, -1.0)
        self.episodeStartTime = datetime.datetime.now()
        self.arduino.resetRobot()

        # Pin Setup:
        self.buttonPin = 4
        GPIO.setmode(GPIO.BCM)
        GPIO.setup(self.buttonPin, GPIO.IN, pull_up_down=GPIO.PUD_UP)

    # returns four states
    def getObservation(self):
        self.state = self.arduino.getState()
        self.observation = self.state[:4]
        self.outerDt = self.state[4]
        self.targetRPS = self.state[5]
        return self.observation

    # returns observation, reward, done
    def step(self, action):
        self.accelerateMotors(action)
        observation = self.getObservation()
        if observation == False:
            return False, False, False

        return observation, self.__reward(), self.isDone()

    def reset(self):
        print("initiating reset...")
        self.arduino.stopMotors()
        self.arduino.resetRobot()  # primarily setting xPos = 0
        print('\a')
        print("waiting on reset button...")
        while 1:
            if GPIO.input(self.buttonPin):  # button is released
                a = 1
                # do Nothing
            else:  # button is pressed:
                print("button pressed! Here we go!")
                break

        self.episodeStartTime = datetime.datetime.now()
        return self.getObservation()

    def updateMotors(self, newPower):
        self.arduino.updateMotorPower(newPower)

    def accelerateMotors(self, acc):
        self.arduino.accelerateMotorPower(acc)

    # determines if episode is done
    # conditions:
    # 0) Robot has fallen over
    # 1) Robot is too far from center-balanced
    # 2) Episode is over MAX_EPISODE_DURATION
    def isDone(self):
        return self.__isFallen() or self.__isFarAway() or self.__isRetired()

    def __reward(self):
        return 1

    def __stopMotors(self):
        self.arduino.stopMotors()

    # Is the robot angle or x position too ugly?
    def __isFallen(self):
        if (math.fabs(self.observation[0]) > self.MAX_ANGLE):
            print("!!!!!!!!!!!!!!!isFallen. Angle: {} > {}".format(
                self.observation[0], self.MAX_ANGLE))
            return True
        else:
            return False

    def __isFarAway(self):
        if (math.fabs(self.observation[2]) > self.MAX_DISTANCE):
            print("!!!!!!!!!!!!!!!isFarAway. Distance: {} > {}".format(
                self.observation[2], self.MAX_DISTANCE))
            return True
        else:
            return False

    # Is the episode over MAX_EPISODE_DURATION
    def __isRetired(self):
        delta = datetime.datetime.now() - self.episodeStartTime
        if (delta.seconds > self.MAX_EPISODE_DURATION):
            print("!!!!!!!!!!!!!!!isRetired {} > {}".format(
                delta.seconds, self.MAX_EPISODE_DURATION))
            return True
        else:
            return False