Mercurial > Kubik
changeset 155:ff5817807016
joy
| author | Radomir Dopieralski <sheep-devel@sheep.art.pl> |
|---|---|
| date | Thu, 07 Aug 2014 17:59:42 +0200 |
| parents | 869a77d30574 |
| children | 61e00a8f9255 e33e8a3c322a |
| files | creep.py joy.py |
| diffstat | 2 files changed, 177 insertions(+), 49 deletions(-) [+] |
line wrap: on
line diff
--- a/creep.py Thu Aug 07 17:56:57 2014 +0200 +++ b/creep.py Thu Aug 07 17:59:42 2014 +0200 @@ -1,62 +1,111 @@ -import kubik +#!/usr/bin/env python +# -*- coding: utf-8 -*- -STRIDE = 36 -SPEED = 2 -SWING = 24 -SWING_SPEED = 4 -HEIGHT = -35 -STEP = -5 -OVERLAP = 0 -FPS = 24 +class Creep(object): + step_height = 5.0 # How high to raise the legs. + stride = 16.0 # How long steps to take. + swing = 12, 9 # How much to shift the body x and y. + swing_speed = 3 # How fast to shift the body. + posture = 10, 16 # How much to change posture depending on direction. + leg_order = { + 'forward': {None: 1, 1: 0, 0: 2, 2: 3, 3: 1}, + 'rotate_left': {None: 0, 0: 1, 1: 2, 2: 3, 3: 0}, + 'rotate_right': {None: 0, 0: 3, 3: 2, 2: 1, 1: 0}, + } + def __init__(self, robot): + self.robot = robot + self.on_ground = set(self.robot.legs) + self.speed = [0.0, 1.0] + self.rotation = 0.0 + self.gait = 'forward' -def _swing(robot, delay, steps): - for i in range(delay): - yield - pause = STRIDE / SPEED + 3 - SWING * 2 / SWING_SPEED - for step in range(steps): - for i in range(pause): + def _raise_leg(self, leg): + """Raises the leg off the ground.""" + self.on_ground.remove(leg) + leg.move_to((None, None, self.step_height)) + for frame in range(2): + yield + + def _lower_leg(self, leg): + """Puts the leg on the ground.""" + leg.move_to((None, None, leg.home[2] + 1)) + for frame in range(2): yield - for i in range(-SWING, SWING, SWING_SPEED): - robot.shift = [-i, 0, 0] - yield - for i in range(pause): - yield - for i in range(SWING, -SWING, -SWING_SPEED): - robot.shift = [-i, 0, 0] + leg.move_to((None, None, leg.home[2])) + self.on_ground.add(leg) + + def _advance_leg(self, leg): + """Moves the leg forward.""" + leg.move_to(( + ( + leg.home[0] - self.stride * self.speed[0] * leg.x_dir - + self.posture[0] * abs(self.speed[0]) + ), + ( + leg.home[1] + self.stride * self.speed[1] + + leg.y_dir * self.posture[1] * abs(self.speed[1]) + ), + None, + )) + leg.rotate_by(self.rotation * leg.x_dir * leg.y_dir * 10) + for frame in range(4): yield - -def _creep(leg, side, delay, steps): - for i in range(delay): - yield - for step in range(steps): - leg.move_to((None, None, STEP)) - for i in range(4): - yield - leg.move_to((None, STRIDE, None)) - for i in range(2): - yield - leg.move_to((None, None, HEIGHT)) - for y in range(STRIDE, -STRIDE, -SPEED): - leg.move_to((None, y, None)) + def _shift_body(self, shift): + """Shifts the body to the specified position.""" + shift = list(shift) + while self.robot.shift[:2] != shift: + for i in range(2): + if self.robot.shift[i] > shift[i]: + self.robot.shift[i] -= self.swing_speed + elif self.robot.shift[i] < shift[i]: + self.robot.shift[i] += self.swing_speed yield + def stomp_anim(self): + """This animation is for making steps and shifting the body.""" + leg_index = None + while True: + while not self.gait: + # Don't raise the legs if not moving. + try: + yield self._shift_body((0, 0)).next() + except StopIteration: + yield + leg_index = self.leg_order[self.gait][leg_index] + leg = self.robot.legs[leg_index] + for frame in self._shift_body((leg.x_dir * self.swing[0], + -leg.y_dir * self.swing[1])): + yield + for frame in self._raise_leg(leg): + yield + for frame in self._advance_leg(leg): + yield + for frame in self._lower_leg(leg): + yield -def creep(robot, steps): - delay = (2 * STRIDE / SPEED + 6) / 4 - animations = [ - _swing(robot, 0, steps), - _creep(robot.legs[0], 1, delay * 0 + OVERLAP, steps), - _creep(robot.legs[1], 1, delay * 1 - OVERLAP, steps), - _creep(robot.legs[3], -1, delay * 2 + OVERLAP, steps), - _creep(robot.legs[2], -1, delay * 3 - OVERLAP, steps), - ] - return animations + def retract_anim(self): + """This animation is for moving the legs on the ground. + They should all move in the opposite direction than the speed. + """ + while True: + for leg in self.on_ground: + leg.move_by((self.speed[0] * 0.5 * leg.x_dir, + -self.speed[1], 0)) + if self.rotation: + leg.rotate_by(-self.rotation * leg.x_dir * leg.y_dir) + yield if __name__ == '__main__': + import kubik + + FPS = 24 + robot = kubik.Robot() - robot.home() - animations = creep(robot, 10) - robot.run_animations(animations, FPS) + creep = Creep(robot) + robot.run_animations([ + creep.stomp_anim(), + creep.retract_anim(), + ], FPS)
--- a/joy.py Thu Aug 07 17:56:57 2014 +0200 +++ b/joy.py Thu Aug 07 17:59:42 2014 +0200 @@ -0,0 +1,79 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import os + +import pygame + +import kubik +import creep + + +FPS = 24 + + +class Walk(creep.Creep): + def __init__(self, robot): + super(Walk, self).__init__(robot) + self.speed = [0.0, 0.0] + self.rotation = 0.0 + self.gait = '' + + def joy_anim(self): + """This animation is for reading user input.""" + while True: + for event in pygame.event.get(): + if event.type == pygame.QUIT: + raise SystemExit() + elif event.type == pygame.JOYBUTTONDOWN: + if event.button == 10: + self.gait = 'forward' + elif event.button == 11: + if self.rotation > 0: + self.gait = 'rotate_left' + else: + self.gait = 'rotate_right' + elif event.button == 0: + serial = self.robot.legs[0].hip.serial + serial.write('0xfd') + sensor = ord(serial.read(1)) + print "Sensor value: %d" % sensor + else: + print "Button %d" % event.button + elif event.type == pygame.JOYBUTTONUP: + if event.button in (10, 11): + self.gait = '' + elif event.type == pygame.JOYAXISMOTION: + if event.axis == 0: + self.speed[0] = event.value + self.rotation = 0.0 + elif event.axis == 1: + self.speed[1] = -event.value + self.rotation = 0.0 + elif event.axis == 2: + self.robot.shift[2] = event.value * 12 + elif event.axis == 3: + self.rotation = event.value + self.speed = [0.0, 0.0] + yield + + + +if __name__ == '__main__': + # Initialize PyGame. + os.environ['SLD_VIDEODRIVER'] = 'dummy' + pygame.display.init() + pygame.joystick.init() + for joy in range(pygame.joystick.get_count()): + pygame.joystick.Joystick(joy).init() + + # Initialize the robot. + robot = kubik.Robot() + robot.home() + walk = Walk(robot) + clock = pygame.time.Clock() + robot.run_animations([ + walk.stomp_anim(), + walk.retract_anim(), + walk.joy_anim(), + ], FPS)
