Compare commits

..

3 Commits

Author SHA1 Message Date
0b23964d25 feat: added comments 2025-05-04 22:57:38 +02:00
aebc157507 feat: removed useless function 2025-05-04 22:33:59 +02:00
248e8dd073 feat: added sliders back 2025-05-04 22:30:57 +02:00
2 changed files with 111 additions and 125 deletions

View File

@ -44,24 +44,27 @@ CONTROLLER_MODE = xbox.initialized
xbox.mode_count = 5
neutral_position = np.array([
[0.1, 0.16, -0.15],
[-0.1, 0.16, -0.15],
[-0.2, -0.00, -0.15],
[-0.1, -0.16, -0.15],
[0.1, -0.16, -0.15],
[0.2, 0, -0.15]
[0.08, 0.16, -0.12],
[-0.08, 0.16, -0.12],
[-0.2, -0.00, -0.12],
[-0.08, -0.16, -0.12],
[0.08, -0.16, -0.12],
[0.2, 0, -0.12]
])
REAL = 0
# Robot setup
if REAL == 1:
try:
portHandler = PortHandler("/dev/ttyUSB0")
except:
portHandler = PortHandler("/dev/ttyUSB1")
packetHandler = PacketHandler(1.0)
portHandler.openPort()
x = portHandler.setBaudRate(1000000)
print(x)
portHandler.setBaudRate(1000000)
ADDR_GOAL_POSITION = 30
ids = []
@ -71,17 +74,24 @@ if REAL == 1:
print(f"Found AX-12 with id: {id}")
ids.append(id)
time.sleep(0.01)
if len(ids) != 18:
legsLogger.error("Not all motor found. Press enter to continue")
input()
# Done
def interpol2(point2, point1, t):
"""
Linear interpolation between two points in space
"""
x1, y1, z1 = point1
x2, y2, z2 = point2
return t * x1 + (1 - t) * x2, t * y1 + (1 - t) * y2, t * z1 + (1 - t) * z2
def get_current_step(t, step_duration, movement_duration):
"""
helper function used to calculate the current step of the movement i.e. what part of the movement.
"""
time_passed = 0
for i in range(len(step_duration)):
time_passed += step_duration[i]
@ -90,6 +100,9 @@ def get_current_step(t, step_duration, movement_duration):
def get_current_step_advancement(t, movement_duration, step_duration, current_step):
"""
helper function used to calculate the current advancement of the movement step i.e. the percentage of progression of said movement.
"""
current_step = get_current_step(t, step_duration, movement_duration)
t = t % movement_duration
for i in range(0, current_step):
@ -99,6 +112,7 @@ def get_current_step_advancement(t, movement_duration, step_duration, current_st
def inverse(x, y, z):
"""
Calculate the angle of each motor to have the end of the feet at a specified position
"""
# Dimensions (m)
z += l1v
@ -106,7 +120,6 @@ def inverse(x, y, z):
theta0 = atan2(y, x)
l = sqrt((sqrt(x ** 2 + y ** 2) - l1) ** 2 + z ** 2)
# l = sqrt((x - l1h*cos(theta0)) ** 2 + (y - l1h*sin(theta0)) ** 2 + (z + l1v) ** 2)
param2 = -1 * (-(l ** 2) + l2 ** 2 + l3 ** 2) / (2 * l2 * l3)
@ -123,15 +136,13 @@ def inverse(x, y, z):
theta1 = acos(param1) + asin(z / l)
# return [-theta0, theta1, theta2]
angle1 = atan(l2v / l2h)
return [-theta0, theta1 + angle1, theta2 + angle1 - pi / 2 + atan(l3h / l3v)]
# return [0, angle1 , angle1 -pi/2 + atan(l3h/l3v)]
def legs(targets_robot):
"""
takes a list of target and offsets it to be in the legs referential
takes a list of target and offsets them to be in the legs referential
"""
targets = [0] * 18
@ -160,7 +171,72 @@ def legs(targets_robot):
return targets
def normalize(matrix, slider_max, speed):
return (matrix / slider_max) * speed
counter = 0
def convert_to_robot(positions):
"""
Send a robot position to the real robot.
"""
global counter
counter += 1
if counter % 2 != 0:
return
index = [
11, 12, 13,
41, 42, 43,
21, 22, 23,
51, 52, 53,
61, 62, 63,
31, 32, 33]
dir = [-1] * 18
for i in range(len(positions)):
value = int(512 + positions[i] * 150 * dir[i])
packetHandler.write2ByteTxOnly(portHandler, index[i], ADDR_GOAL_POSITION, value)
def walk(t, sx, sy, sr):
"""
Choose the algorithm depending on input of xbox controller
"""
xboxdata = xbox.get_data()
if xbox.initialized:
max_slider = 0.200
controllerLogger.debug(xboxdata)
if xbox.mode == 0:
positions = static()
elif xbox.mode == 1:
positions = jump(xboxdata["y2"])
elif xbox.mode == 2:
positions = dino_naive(t, max_slider * xboxdata["y1"], max_slider * xboxdata["x1"],
max_slider * xboxdata["y2"],
max_slider * xboxdata["x2"], max_slider * (xboxdata["r2"] + 1))
elif xbox.mode == 3:
positions = naive_walk(t, max_slider * xboxdata["x1"], max_slider * xboxdata["y1"])
elif xbox.mode == 4:
positions = walk_v2(t, max_slider * xboxdata["y1"], -1 * max_slider * xboxdata["x1"],
xboxdata["x2"] * max_slider,
max_slider * xboxdata["y2"])
# print(positions)
if REAL == 1:
convert_to_robot(positions)
return positions
else:
return walk_v2(t, sx, sy, sr, None)
# different move algorithm
def naive_walk(t, speed_x, speed_y):
"""
First version of walk, using triangle for each step
"""
slider_max = 0.200
real_position = np.copy(neutral_position)
@ -226,89 +302,25 @@ def naive_walk(t, speed_x, speed_y):
return legs(real_position)
def normalize(matrix, slider_max, speed):
return (matrix / slider_max) * speed
counter = 0
def convert_to_robot(positions):
global counter
counter += 1
if counter % 2 != 0:
return
print(positions)
index = [
11, 12, 13,
41, 42, 43,
21, 22, 23,
51, 52, 53,
61, 62, 63,
31, 32, 33]
dir = [-1] * 18
for i in range(len(positions)):
value = int(512 + positions[i] * 150 * dir[i])
packetHandler.write2ByteTxOnly(portHandler, index[i], ADDR_GOAL_POSITION, value)
# packetHandler.writeTxOnly(portHandler, index[i], ADDR_GOAL_POSITION, 2,
# bytes(value))
def stand(x1, y1, x2, y2):
return [
0, 0, 0,
0, 0, 0,
x1, 0, 0,
0, -0.5, 0,
0, -0.5, 0,
y1, 0, 0
]
def walk(t, sx, sy, sr):
xboxdata = xbox.get_data()
val = xboxdata["x1"]
max_slider = 0.200
controllerLogger.debug(xboxdata)
if xbox.mode == 0:
positions = static()
elif xbox.mode == 1:
positions = jump(xboxdata["y2"])
elif xbox.mode == 2:
positions = dino_naive(t, max_slider * xboxdata["y1"], max_slider * xboxdata["x1"], max_slider * xboxdata["y2"],
max_slider * xboxdata["x2"], max_slider * (xboxdata["r2"] + 1))
elif xbox.mode == 3:
positions = naive_walk(t, max_slider * xboxdata["x1"], max_slider * xboxdata["y1"])
elif xbox.mode == 4:
positions = dev(t, max_slider * xboxdata["y1"], -1 * max_slider * xboxdata["x1"], xboxdata["x2"] * max_slider,
max_slider * xboxdata["y2"])
elif xbox.mode == 5:
positions = stand(xboxdata["x1"], xboxdata["y1"], xboxdata["x2"], xboxdata["y2"])
print(positions)
if REAL == 1:
convert_to_robot(positions)
return positions
def static():
"""
Function to have the robot stand at the neutral position
"""
return legs(neutral_position)
# Walk V2
def dev(t, speed_x, speed_y, speed_r, y2):
def walk_v2(t, speed_x, speed_y, speed_r, y2):
"""
x1: speed along the x-axis
y1: speed along the y-axis
x2: rotational speed along the z-axis
Second version of the walking algorithm, using circle for each leg
This is the main algorithm.
"""
max_dist = 0.3
print(speed_r)
def get_rotation_center(speed_x, speed_y, theta_point):
"""
Helper function that calculate the center of rotation of the robot based on the current parameters
"""
norm = sqrt(speed_x ** 2 + speed_y ** 2)
r = 1000 if theta_point == 0 else norm / theta_point
@ -318,15 +330,13 @@ def dev(t, speed_x, speed_y, speed_r, y2):
return 0, 0
center_x, center_y = get_rotation_center(speed_x, speed_y, speed_r)
legsLogger.debug(f"rotation center: center_x: {center_x}, center_y: {center_y}")
real_position = np.copy(neutral_position)
movement_z = np.array([
[0, 0, 0.02],
[0, 0, -0.01],
[0, 0, -0.01]
[0, 0, 0.03],
[0, 0, -0.02],
[0, 0, -0.02]
])
step_duration = np.array([0.15, 0.3, 0.15])
@ -406,6 +416,9 @@ def dev(t, speed_x, speed_y, speed_r, y2):
def jump(sy):
"""
Make the robot jump (at least we wished)
"""
offset = np.array([
[0, 0, -0.15],
[0, 0, -0.15],
@ -418,8 +431,10 @@ def jump(sy):
return legs(neutral_position + offset)
# based on walk V1
def dino_naive(t, speed_x, speed_y, hz, hy, hx):
"""
based on walk naive, but with a head and a tail
"""
slider_max = 0.200
real_position = np.copy(neutral_position)
@ -492,34 +507,5 @@ def dino_naive(t, speed_x, speed_y, hz, hy, hx):
return legs(real_position)
def robot_input():
print("Send motors wave (press enter)")
input()
for id in ids:
packetHandler.write2ByteTxRx(portHandler, id, ADDR_GOAL_POSITION, 512)
input()
angle = [512, 624, 400, 512, 624, 400]
for id in range(1, 7):
packetHandler.write2ByteTxRx(portHandler, id * 10 + 1, ADDR_GOAL_POSITION, angle[id - 1])
input()
# Dino mode
packetHandler.write2ByteTxRx(portHandler, 12, ADDR_GOAL_POSITION, 650)
packetHandler.write2ByteTxRx(portHandler, 42, ADDR_GOAL_POSITION, 650)
packetHandler.write2ByteTxRx(portHandler, 43, ADDR_GOAL_POSITION, 400)
input()
for id in ids:
packetHandler.write2ByteTxRx(portHandler, id, ADDR_GOAL_POSITION, 512)
# t = 0.0
# while True:
# print("Send motors wave (press enter)")
# angle = 512 + int(50 * np.sin(t))
# print(angle)
# packetHandler.write2ByteTxRx(portHandler, 53, ADDR_GOAL_POSITION, angle)
# time.sleep(0.001)
# t += 0.01
if __name__ == "__main__":
print("N'exécutez pas ce fichier, mais simulator.py")

View File

@ -15,9 +15,9 @@ class Xbox:
if len(self.controllers) == 0:
self.logger.critical("No controllers detected. Can't initialize remote control.")
self.initialized = True
else:
self.initialized = False
else:
self.initialized = True
self.data = {"x1": 0, "x2": 0, "y1": 0, "y2": 0, "up": 0, "down": 0, "left": 0, "right": 0, "r1": 0, "r2": 0,
"r3": 0,
"l1": 0, "l2": 0, "l3": 0}