changeset 7:6417d860a1ca

Add gait.py with the basic creep
author Radomir Dopieralski <sheep-devel@sheep.art.pl>
date Sat, 26 Mar 2016 22:53:03 +0100
parents bfbc645e9dea
children 7993a8f67e4c
files controller/leg.h fritzing/Makefile fritzing/pcb-had.fzz fritzing/pcb-had.zip python/gait.py python/robot.py
diffstat 6 files changed, 120 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/controller/leg.h	Sun Mar 20 17:31:20 2016 +0100
+++ b/controller/leg.h	Sat Mar 26 22:53:03 2016 +0100
@@ -1,19 +1,10 @@
 #ifndef LEG_H
 #define LEG_H
 
-#ifdef TOTE2
-// For version 2:
 #define COXA    25.0
 #define FEMUR   42.0
 #define TIBIA   38.5
 #define BASE    21.0
-#else
-// For version 1:
-#define COXA    8.0
-#define FEMUR   20.5
-#define TIBIA   28.5
-#define BASE    18.5
-#endif
 
 const signed char LEG_X[4] = {-1, -1, 1, 1};
 const signed char LEG_Y[4] = {1, -1, -1, 1};
--- a/fritzing/Makefile	Sun Mar 20 17:31:20 2016 +0100
+++ b/fritzing/Makefile	Sat Mar 26 22:53:03 2016 +0100
@@ -1,5 +1,5 @@
 FRITZING=fritzing
-PCBS=pcb2.zip pcb3.zip pcb4.zip
+PCBS=pcb-had.zip
 
 all: $(PCBS)
 
Binary file fritzing/pcb-had.fzz has changed
Binary file fritzing/pcb-had.zip has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/gait.py	Sat Mar 26 22:53:03 2016 +0100
@@ -0,0 +1,72 @@
+from machine import delay
+
+
+class Creep:
+    speed = 0.75
+    stride = 14
+    shift = 8
+    shift_steps = 2
+    raise_leg = 10
+    raise_steps = 2
+    next_leg = (
+        (2, 0, 3, 1),   # forward
+        (1, 3, 0, 2),   # backward
+        (1, 2, 3, 0),   # clockwise
+        (3, 0, 1, 2),   # counter-clockwise
+        (2, 3, 1, 0),   # left
+        (3, 2, 0, 1),   # right
+    )
+
+    def __init__(self, robot):
+        self.robot = robot
+        self.shift_x = 0
+        self.shift_y = 0
+        self.on_ground = list(robot.legs)
+        self.dx = 0
+        self.dy = 1
+        self.rotation = 0
+        self.spread = 0
+        leg = robot.legs[0]
+        self.height = leg.tibia
+        self.last_leg = 0
+
+    def move(self):
+        for leg in self.on_ground:
+            dx = self.dx * leg.x_dir * self.speed
+            dy = self.dy * leg.y_dir * self.speed
+            leg.move_to(leg.x - dx, leg.y - dy, -self.height)
+            #leg.rotate_by(-self.rotation * leg.x_dir * leg.y_dir / 2)
+        delay(25)
+
+    def step(self, leg):
+        dx = (leg.x_dir * self.shift - self.shift_x) / self.shift_steps
+        dy = (leg.y_dir * self.shift - self.shift_y) / self.shift_steps
+        for step in range(self.shift_steps):
+            self.robot.move_by(dx, dy, 0)
+            self.shift_x += dx
+            self.shift_y += dy
+            self.move()
+        self.on_ground.remove(leg)
+        for step in range(self.raise_steps):
+            leg.move_by(0, 0, self.raise_leg)
+            self.move()
+        leg.move_to(
+            leg.home + (self.shift_x + self.dx *
+                        self.stride) * leg.x_dir + self.spread,
+            leg.home + (self.shift_y + self.dy *
+                        self.stride) * leg.y_dir + self.spread,
+            self.raise_leg * self.raise_steps - self.height
+        )
+        self.move()
+        self.move()
+        for step in range(self.raise_steps - 1):
+            leg.move_by(0, 0, -self.raise_leg)
+            self.move()
+        self.on_ground.append(leg)
+        self.move()
+
+    def run(self, steps):
+        for step in range(steps):
+            leg = self.robot.legs[self.last_leg]
+            self.step(leg)
+            self.last_leg = self.next_leg[0][self.last_leg]
--- a/python/robot.py	Sun Mar 20 17:31:20 2016 +0100
+++ b/python/robot.py	Sat Mar 26 22:53:03 2016 +0100
@@ -1,19 +1,59 @@
 from machine import I2C, Pin
 import ustruct
+import math
+
+
+I2C_ADDRESS = 0x09
 
 
-class Robot:
-    I2C_ADDRESS = 0x09
+class Leg:
+    base = 70  # cm from the center of the robot to the (0,0) of the leg
 
-    def __init__(self):
-        self.i2c = I2C(sda=Pin(0), scl=Pin(2))
+    def __init__(self, i2c, index, x_dir, y_dir):
+        self.index = index
+        self.i2c = i2c
+        self.x = 0
+        self.y = 0
+        self.z = 0
 
-    def leg_move_to(self, leg, x, y, z):
-        data = ustruct.pack("Bbbbb", 4 * leg, 1, x, y, z)
+    def move_to(self, x, y, z):
+        data = ustruct.pack("Bbbbb", 4 * self.index, 1, x, y, z)
         while True:
             try:
-                self.i2c.writeto(self.I2C_ADDRESS, data)
+                self.i2c.writeto(I2C_ADDRESS, data)
             except OSError:
                 pass
             else:
                 break
+        self.x = x
+        self.y = y
+        self.z = z
+
+    def move_by(self, dx=0, dy=0, dz=0):
+        self.move_to(self.x + dx, self.y + dy, self.z + dz)
+
+    def rotate_by(self, radians):
+        x = self.x + self.base
+        y = self.y + self.base
+        nx = x * math.cos(radians) - y * math.sin(radians) - self.base
+        ny = x * math.sin(radians) + y * math.cos(radians) - self.base
+        self.move_to(nx, ny, self.z)
+
+
+class Robot:
+    def __init__(self):
+        self.i2c = I2C(sda=Pin(0), scl=Pin(2))
+        self.legs = (
+            Leg(self.i2c, 0, -1,  1),
+            Leg(self.i2c, 1, -1, -1),
+            Leg(self.i2c, 2,  1, -1),
+            Leg(self.i2c, 3,  1,  1),
+        )
+
+    def move_by(self, dx=0, dy=0, dz=0):
+        for leg in self.legs:
+            leg.move_by(dx * leg.x_dir, dy * leg.y_dir, dz)
+
+    def rotate_by(self, radians):
+        for leg in self.legs:
+            leg.rotate_by(radians)