Skip to content

Commit

Permalink
stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
DeDiamondPro committed Mar 4, 2024
1 parent 3985d53 commit 5453ca1
Showing 1 changed file with 303 additions and 21 deletions.
324 changes: 303 additions & 21 deletions code/inverse-kinematics-test/inverse_kinematics.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
from math import *

from adafruit_servokit import ServoKit
from pyPS4Controller.controller import Controller
from time import sleep

pca = ServoKit(channels=16)

servo_offsets = [5, 8, -7, 0, -6, 3, 3, 4, 5, -3, 2, 3]

length = 27
width = 17
leg_length1 = 10.0
leg_length2 = 10.0
pitch_offset = 2
yaw_offset = 0


def set_servo(servo, angle):
pca.servo[servo].angle = angle + servo_offsets[servo]


# https://en.wikipedia.org/wiki/Rotation_matrix
def calculate_rotation(x1, y1, angle):
Expand All @@ -8,31 +27,294 @@ def calculate_rotation(x1, y1, angle):
return x2 - x1, y2 - y1


pitch = 10.0
yaw = 10.0
l = 20.0
b = 10.0
# pitch = 10.0
# yaw = 10.0
#
# height_diff_pitch = length * sin(radians(pitch)) / 2
# height_diff_yaw = width * sin(radians(yaw)) / 2
# leg_movement_x = leg_length1 * (1 - cos(radians(pitch))) / 2
# leg_movement_z = width * (1 - cos(radians(yaw))) / 2
#
# print(calculate_rotation(1.0, 1.0, -30.0))
#
# print("Height difference pitch: {}, height difference yaw: {}".format(height_diff_pitch, height_diff_yaw))
# print("Leg movement x: {}, leg movement y: {}".format(leg_movement_x, leg_movement_z))


def calc_angles(x, y, z):
A = acos(((y * y + x * x) * (y * y + z * z) + y * y * leg_length1 * leg_length1 - y * y * leg_length2 * leg_length2)
/ (2 * y * leg_length1 * sqrt((y * y + x * x) * (y * y + z * z)))) + atan(x / y)
B = acos(
(y * y * leg_length1 * leg_length1 + y * y * leg_length2 * leg_length2 - (y * y + x * x) * (y * y + z * z)) / (
2 * y * y * leg_length1 * leg_length2))
C = atan(z / y)
# print("A: {}, B: {}, C: {}".format(degrees(A), degrees(B), degrees(C)))
return A, B, C


def calc_leg_offsets(x, z, pitch, yaw, rotation):
pitch += pitch_offset
yaw += yaw_offset
height_diff_pitch = x * sin(radians(pitch))
height_diff_yaw = z * sin(radians(yaw))
movement_x_pitch = x * (1 - cos(radians(pitch)))
movement_z_yaw = z * (1 - cos(radians(yaw)))
movement_x_rotation = (x * cos(radians(rotation)) - z * sin(radians(rotation))) - x
movement_z_rotation = (x * sin(radians(rotation)) + z * cos(radians(rotation))) - z
return (
movement_x_pitch + movement_x_rotation,
height_diff_pitch + height_diff_yaw,
movement_z_yaw + movement_z_rotation
)


def set_legs(desired_x, desired_y, desired_z, desired_pitch, desired_yaw, desired_rotation):
for leg in range(3, -1, -1):
try:
x = (length / 2) if leg % 2 else -(length / 2)
z = (width / 2) if leg < 2 else -(width / 2)
offsets = calc_leg_offsets(x, z, desired_pitch, desired_yaw, desired_rotation)
print("Leg {}: X-offset: {}, Y-offset: {}, Z-offset: {}".format(leg, offsets[0], offsets[1], offsets[2]))
angles = calc_angles(desired_x + offsets[0], desired_y + offsets[1], desired_z + offsets[2])
set_leg(leg, angles)
except ValueError:
print("Failed to calculate angles")


def set_leg(leg, angles):
index = 0
if leg == 0:
index = 3
elif leg == 1:
index = 0
elif leg == 2:
index = 2
elif leg == 3:
index = 1

set_servo(3 * index, (90 - degrees(angles[0])) if leg < 2 else (90 + degrees(angles[0])))
set_servo(3 * index + 1, (degrees(angles[1])) if leg < 2 else (180 - degrees(angles[1])))
set_servo(3 * index + 2, (90 + degrees(angles[2])) if leg % 2 else (90 - degrees(angles[2])))


for servo in range(12):
pca.servo[servo].set_pulse_width_range(500, 2500)
# set_servo(servo, 90)


set_legs(0, 15, 0, 0, 0, 0)


def ease(x):
return -(cos(pi * x) - 1) / 2


def run(leg, x):
# TL-BR-TR-BL
lifted_leg = 0
if x < 1:
lifted_leg = 2
elif x < 2:
lifted_leg = 1
elif x < 3:
lifted_leg = 0
elif x < 4:
lifted_leg = 3
actual_x = 0
if leg == 0:
actual_x = x + 2
elif leg == 1:
actual_x = x + 3
elif leg == 2:
actual_x = x
elif leg == 3:
actual_x = x + 1

# actual_x = x + leg
# lifted_leg = 4 - floor(x)
if actual_x >= 4:
actual_x -= 4

leg_start = -2.5
leg_end = 3.5

x_offset = leg_start + ((actual_x - 1) / 3) * (leg_end - leg_start)
# if lifted_leg != leg:
# print("{}: {} {}".format(leg, x_offset, (actual_x - 1) / 3))
y_offset = 15
x_leg = (length / 2) if leg % 2 else -(length / 2)
z_leg = (width / 2) if leg < 2 else -(width / 2)
if lifted_leg == 0 or lifted_leg == 2:
desired_pitch = -5
else:
desired_pitch = 5
if lifted_leg == 0 or lifted_leg == 1:
desired_yaw = 7
else:
desired_yaw = -7

raised_leg_x = x - floor(x)

ease_point = 0.2
if raised_leg_x < ease_point:
smoothing = ease(raised_leg_x / ease_point)
elif 1 - ease_point < raised_leg_x <= 1:
smoothing = ease(1 + (raised_leg_x - 1 + ease_point) / ease_point)
else:
smoothing = 1
print(smoothing)

desired_pitch = desired_pitch * smoothing
desired_yaw = desired_yaw * smoothing
desired_pitch = 0
desired_yaw = 0

offsets = calc_leg_offsets(x_leg, z_leg, desired_pitch, desired_yaw, 0)

z_offset = 0
z_offset = (2 if lifted_leg < 2 else -2) * smoothing
x_offset += (2 if lifted_leg % 2 else -2) * smoothing
if lifted_leg == leg:
x_offset = 3 - ease(actual_x) * 6
y_offset = 15 - ease(actual_x * 2) * 5

# if lifted_leg == 1 and leg == 3:
# y_offset += 2
# elif lifted_leg == 3 and leg == 1:
# y_offset += 2

# if leg == 0:
# print(str(leg) + ": (x:" + str(x_offset + offsets[0]) + ", y: " + str(y_offset + offsets[1]),
# ", z: " + str(z_offset + offsets[2]))

angles = calc_angles(x_offset + offsets[0], y_offset + offsets[1], z_offset + offsets[2])
set_leg(leg, angles)


status = 0

# run(0, status)
# run(1, status)
# run(2, status)
# run(3, status)

while True:
status += 0.03
if status >= 4:
status = 0
# print(status)
run(0, status)
run(1, status)
run(2, status)
run(3, status)
sleep(0.01)


class AQLARPController(Controller):
x = 0
y = 15
z = 0
pitch = 0
yaw = 0
rotation = 0

def __init__(self, **kwargs):
Controller.__init__(self, **kwargs)
self.apply()

def apply(self):
set_legs(self.x, self.y, self.z, self.pitch, self.yaw, self.rotation)

def on_up_arrow_press(self):
self.y += 0.5
self.apply()

def on_down_arrow_press(self):
self.y -= 0.5
self.apply()

def on_L3_x(self, value):
adjusted = value / 32767
self.z = -adjusted * 5
self.apply()

def on_L3_y(self, value):
adjusted = value / 32767
self.x = -adjusted * 5
self.apply()

def on_R3_x(self, value):
adjusted = value / 32767
self.yaw = -adjusted * 15
self.apply()

def on_R3_y(self, value):
adjusted = value / 32767
self.pitch = -adjusted * 15
self.apply()

def on_L3_left(self, value):
self.on_L3_x(value)

def on_L3_right(self, value):
self.on_L3_x(value)

def on_L3_x_at_rest(self):
self.on_L3_x(0)

def on_L3_down(self, value):
self.on_L3_y(value)

def on_L3_up(self, value):
self.on_L3_y(value)

def on_L3_y_at_rest(self):
self.on_L3_y(0)

def on_R3_left(self, value):
self.on_R3_x(value)

height_diff_pitch = l * sin(radians(pitch)) / 2
height_diff_yaw = b * sin(radians(yaw)) / 2
leg_movement_x = l * (1 - cos(radians(pitch))) / 2
leg_movement_y = b * (1 - cos(radians(yaw))) / 2
def on_R3_right(self, value):
self.on_R3_x(value)

print(calculate_rotation(1.0, 1.0, -30.0))
def on_R3_x_at_rest(self):
self.on_R3_x(0)

print("Height difference pitch: {}, height difference yaw: {}".format(height_diff_pitch, height_diff_yaw))
print("Leg movement x: {}, leg movement y: {}".format(leg_movement_x, leg_movement_y))
def on_R3_down(self, value):
self.on_R3_y(value)

l1 = 10.0
l2 = 10.0
def on_R3_up(self, value):
self.on_R3_y(value)

x = 0.0
y = 15.0
z = 0.0
def on_R3_y_at_rest(self):
self.on_R3_y(0)

A = acos(((y * y + x * x) * (y * y + z * z) + y * y * l1 * l1 - y * y * l2 * l2)
/ (2 * y * l1 * sqrt((y * y + x * x) * (y * y + z * z)))) + atan(x / y)
B = acos((y * y * l1 * l1 + y * y * l2 * l2 - (y * y + x * x) * (y * y + z * z)) / (2 * y * y * l1 * l2))
C = atan(z / y)
# controller = AQLARPController(interface="/dev/input/js0", connecting_using_ds4drv=False)
# controller.listen()

print("A: {}, B: {}, C: {}".format(degrees(A), degrees(B), degrees(C)))
# pca.servo[2].angle = 95
# pca.servo[5].angle = 98
# pca.servo[8].angle = 95
# pca.servo[11].angle = 92
#
# while True:
# for h in range(0, 100, 1):
# angles = calc_angles(-2 + (100 - h) / 25, 12 + h / 20.0, 0)
# for i in range(4):
# if i <= 1:
# pca.servo[3 * i].angle = 90 - degrees(angles[0])
# pca.servo[3 * i + 1].angle = degrees(angles[1])
# else:
# pca.servo[3 * i].angle = 90 + degrees(angles[0])
# pca.servo[3 * i + 1].angle = 180 - degrees(angles[1])
# time.sleep(0.01)
# for h in range(100, 0, -1):
# angles = calc_angles(-2 + (100 - h) / 25, 12 + h / 20.0, 0)
# for i in range(4):
# if i <= 1:
# pca.servo[3 * i].angle = 90 - degrees(angles[0])
# pca.servo[3 * i + 1].angle = degrees(angles[1])
# else:
# pca.servo[3 * i].angle = 90 + degrees(angles[0])
# pca.servo[3 * i + 1].angle = 180 - degrees(angles[1])
# time.sleep(0.01)

0 comments on commit 5453ca1

Please sign in to comment.