feat: addded 🦖
This commit is contained in:
parent
8479dec345
commit
90d08671d9
254
control.py
254
control.py
@ -40,6 +40,16 @@ controllerLogger = setup_logger("Controller", CONTROLLER_LOG_LEVEL)
|
|||||||
# Initialize controller
|
# Initialize controller
|
||||||
xbox = Xbox(controllerLogger)
|
xbox = Xbox(controllerLogger)
|
||||||
CONTROLLER_MODE = xbox.initialized
|
CONTROLLER_MODE = xbox.initialized
|
||||||
|
xbox.mode_count = 4
|
||||||
|
|
||||||
|
neutral_position = np.array([
|
||||||
|
[0.1, 0.15, -0.15],
|
||||||
|
[-0.1, 0.15, -0.15],
|
||||||
|
[-0.2, -0.00, -0.15],
|
||||||
|
[-0.1, -0.15, -0.15],
|
||||||
|
[0.1, -0.15, -0.15],
|
||||||
|
[0.2, 0, -0.15]
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
def interpol2(point2, point1, t):
|
def interpol2(point2, point1, t):
|
||||||
@ -48,6 +58,22 @@ def interpol2(point2, point1, t):
|
|||||||
return t * x1 + (1 - t) * x2, t * y1 + (1 - t) * y2, t * z1 + (1 - t) * z2
|
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):
|
||||||
|
time_passed = 0
|
||||||
|
for i in range(len(step_duration)):
|
||||||
|
time_passed += step_duration[i]
|
||||||
|
if t % movement_duration < time_passed:
|
||||||
|
return i
|
||||||
|
|
||||||
|
|
||||||
|
def get_current_step_advancement(t, movement_duration, step_duration, current_step):
|
||||||
|
current_step = get_current_step(t, step_duration, movement_duration)
|
||||||
|
t = t % movement_duration
|
||||||
|
for i in range(0, current_step):
|
||||||
|
t -= step_duration[i]
|
||||||
|
return t / step_duration[current_step]
|
||||||
|
|
||||||
|
|
||||||
def inverse(x, y, z):
|
def inverse(x, y, z):
|
||||||
"""
|
"""
|
||||||
"""
|
"""
|
||||||
@ -111,24 +137,9 @@ def legs(targets_robot):
|
|||||||
return targets
|
return targets
|
||||||
|
|
||||||
|
|
||||||
def walkV1(t, speed_x, speed_y, speed_rotation):
|
def naive_walk(t, speed_x, speed_y):
|
||||||
max_slider = 0.200
|
|
||||||
xboxdata = xbox.get_data()
|
|
||||||
print(xboxdata)
|
|
||||||
speed_x = max_slider * xboxdata["x1"]
|
|
||||||
speed_y = max_slider * xboxdata["y1"]
|
|
||||||
|
|
||||||
slider_max = 0.200
|
slider_max = 0.200
|
||||||
|
|
||||||
neutral_position = np.array([
|
|
||||||
[0.1, 0.15, -0.15],
|
|
||||||
[-0.1, 0.15, -0.15],
|
|
||||||
[-0.2, -0.00, -0.15],
|
|
||||||
[-0.1, -0.15, -0.15],
|
|
||||||
[0.1, -0.15, -0.15],
|
|
||||||
[0.2, 0, -0.15]
|
|
||||||
])
|
|
||||||
|
|
||||||
real_position = np.copy(neutral_position)
|
real_position = np.copy(neutral_position)
|
||||||
|
|
||||||
movement_x = np.array([
|
movement_x = np.array([
|
||||||
@ -158,36 +169,15 @@ def walkV1(t, speed_x, speed_y, speed_rotation):
|
|||||||
assert len(
|
assert len(
|
||||||
step_duration) == step_count, f"all movements steps must have a length, currently, {len(step_duration)}/{step_count} have them"
|
step_duration) == step_count, f"all movements steps must have a length, currently, {len(step_duration)}/{step_count} have them"
|
||||||
|
|
||||||
def get_current_step(t):
|
|
||||||
time_passed = 0
|
|
||||||
for i in range(len(step_duration)):
|
|
||||||
time_passed += step_duration[i]
|
|
||||||
if t % movement_duration < time_passed:
|
|
||||||
return i
|
|
||||||
|
|
||||||
def get_current_step_advancement(t):
|
|
||||||
current_step = get_current_step(t)
|
|
||||||
t = t % movement_duration
|
|
||||||
for i in range(0, current_step):
|
|
||||||
t -= step_duration[i]
|
|
||||||
return t / step_duration[current_step]
|
|
||||||
|
|
||||||
def get_next_step(t):
|
def get_next_step(t):
|
||||||
return floor((get_current_step(t) + 1) % step_count)
|
return floor((get_current_step(t, step_duration, movement_duration) + 1) % step_count)
|
||||||
|
|
||||||
def rotate(patte):
|
|
||||||
return [1, -1, 0, -1, 1, 0][
|
|
||||||
patte] * movement_x # + [-1, 1, -1, 1][patte] * movement_y # mettre des 0 partout sur le Y fait une très belle rotation
|
|
||||||
|
|
||||||
def normalize(matrix, slider_max, speed):
|
|
||||||
return (matrix / slider_max) * speed
|
|
||||||
|
|
||||||
offsets = np.array([0, 1 / 3, 2 / 3, 0, 1 / 3, 2 / 3]) * movement_duration # offset between each leg
|
offsets = np.array([0, 1 / 3, 2 / 3, 0, 1 / 3, 2 / 3]) * movement_duration # offset between each leg
|
||||||
assert len(offsets) == num_patte, f"all offsets must be set, currently, {len(offsets)}/{num_patte} have them"
|
assert len(offsets) == num_patte, f"all offsets must be set, currently, {len(offsets)}/{num_patte} have them"
|
||||||
|
|
||||||
for patte in range(num_patte):
|
for patte in range(num_patte):
|
||||||
time = t + offsets[patte]
|
time = t + offsets[patte]
|
||||||
mov_index_start = get_current_step(time)
|
mov_index_start = get_current_step(time, step_duration, movement_duration)
|
||||||
mov_index_end = get_next_step(time)
|
mov_index_end = get_next_step(time)
|
||||||
|
|
||||||
mov_start_x = normalize(movement_x[mov_index_start], slider_max, speed_x)
|
mov_start_x = normalize(movement_x[mov_index_start], slider_max, speed_x)
|
||||||
@ -199,17 +189,16 @@ def walkV1(t, speed_x, speed_y, speed_rotation):
|
|||||||
mov_start_z = movement_z[mov_index_start]
|
mov_start_z = movement_z[mov_index_start]
|
||||||
mov_end_z = movement_z[mov_index_end]
|
mov_end_z = movement_z[mov_index_end]
|
||||||
|
|
||||||
mov_start_rotate = normalize(rotate(patte)[mov_index_start], 0.5, speed_rotation)
|
mov_start = neutral_position[patte] + mov_start_z + mov_start_x + mov_start_y
|
||||||
mov_end_rotate = normalize(rotate(patte)[mov_index_end], 0.5, speed_rotation)
|
mov_end = neutral_position[patte] + mov_end_z + mov_end_x + mov_end_y
|
||||||
|
|
||||||
mov_start = neutral_position[patte] + mov_start_z + mov_start_x + mov_start_y + mov_start_rotate
|
|
||||||
mov_end = neutral_position[patte] + mov_end_z + mov_end_x + mov_end_y + mov_end_rotate
|
|
||||||
|
|
||||||
(real_position[patte][0],
|
(real_position[patte][0],
|
||||||
real_position[patte][1],
|
real_position[patte][1],
|
||||||
real_position[patte][2]) = interpol2(mov_start, mov_end, get_current_step_advancement(time))
|
real_position[patte][2]) = interpol2(mov_start, mov_end,
|
||||||
print(
|
get_current_step_advancement(time, movement_duration, step_duration,
|
||||||
f"[{patte}] [{get_current_step(time)}->{get_next_step(time)}], start: {mov_start}, end: {mov_end}, current ({real_position[patte][0]}, {real_position[patte][1]}, {real_position[patte][2]})")
|
mov_index_start))
|
||||||
|
legsLogger.debug(
|
||||||
|
f"[{patte}] [{mov_index_start}->{mov_index_end}], start: {mov_start}, end: {mov_end}, current ({real_position[patte][0]}, {real_position[patte][1]}, {real_position[patte][2]})")
|
||||||
|
|
||||||
return legs(real_position)
|
return legs(real_position)
|
||||||
|
|
||||||
@ -223,6 +212,10 @@ def translate(tx, ty, tz):
|
|||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
|
def normalize(matrix, slider_max, speed):
|
||||||
|
return (matrix / slider_max) * speed
|
||||||
|
|
||||||
|
|
||||||
def Rx(alpha):
|
def Rx(alpha):
|
||||||
return np.array([
|
return np.array([
|
||||||
[1.0, 0.0, 0.0, 0.0],
|
[1.0, 0.0, 0.0, 0.0],
|
||||||
@ -250,38 +243,39 @@ def Rz(alpha):
|
|||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
# multiplication de matrices: @
|
def walk(t, sx, sy, sr):
|
||||||
# gauche: monde, droite: repere
|
xboxdata = xbox.get_data()
|
||||||
|
max_slider = 0.200
|
||||||
|
controllerLogger.debug(xboxdata)
|
||||||
|
if xbox.mode == 0:
|
||||||
|
return static()
|
||||||
|
elif xbox.mode == 1:
|
||||||
|
return jump(xboxdata["y2"])
|
||||||
|
elif xbox.mode == 2:
|
||||||
|
return 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:
|
||||||
|
return dev(t, max_slider * xboxdata["y1"], max_slider * xboxdata["x1"], max_slider * xboxdata["y2"],
|
||||||
|
max_slider * xboxdata["x2"])
|
||||||
|
else:
|
||||||
|
return naive_walk(t, max_slider * xboxdata["x1"], max_slider * xboxdata["y1"])
|
||||||
|
|
||||||
def walkV2(t, speed_x, speed_y, speed_rotation):
|
|
||||||
|
def static():
|
||||||
|
return legs(neutral_position)
|
||||||
|
|
||||||
|
|
||||||
|
# Walk V2
|
||||||
|
def dev(t, x1, y1, x2, y2):
|
||||||
def get_rotation_center(speed_x, speed_y, theta_point):
|
def get_rotation_center(speed_x, speed_y, theta_point):
|
||||||
direction = np.array([-speed_y, speed_x])
|
direction = np.array([-speed_y, speed_x])
|
||||||
return direction / max(0.001, theta_point)
|
return direction / max(0.001, theta_point)
|
||||||
|
|
||||||
x0, y0 = get_rotation_center(speed_x, speed_y, speed_rotation)
|
x0, y0 = get_rotation_center(x1, y1, x2)
|
||||||
|
|
||||||
print(x0, y0)
|
print(x0, y0)
|
||||||
|
|
||||||
"""
|
num_patte = 6
|
||||||
python simulator.py -m walk
|
|
||||||
|
|
||||||
Le but est d'intégrer tout ce que nous avons vu ici pour faire marcher le robot
|
|
||||||
|
|
||||||
- Sliders: speed_x, speed_y, speed_rotation, la vitesse cible du robot
|
|
||||||
- Entrée: t, le temps (secondes écoulées depuis le début)
|
|
||||||
speed_x, speed_y, et speed_rotation, vitesses cibles contrôlées par les sliders
|
|
||||||
- Sortie: un tableau contenant les 12 positions angulaires cibles (radian) pour les moteurs
|
|
||||||
"""
|
|
||||||
# t = t*speed_x * 20
|
|
||||||
num_patte = 4
|
|
||||||
slider_max = 0.200
|
|
||||||
|
|
||||||
neutral_position = np.array([
|
|
||||||
[-0.06, 0.06, -0.13],
|
|
||||||
[-0.06, -0.06, -0.13],
|
|
||||||
[0.06, -0.06, -0.13], # [0.15, 0.15, -0.01],
|
|
||||||
[0.06, 0.06, -0.13]
|
|
||||||
])
|
|
||||||
|
|
||||||
real_position = np.copy(neutral_position)
|
real_position = np.copy(neutral_position)
|
||||||
|
|
||||||
@ -299,31 +293,19 @@ def walkV2(t, speed_x, speed_y, speed_rotation):
|
|||||||
assert len(
|
assert len(
|
||||||
step_duration) == step_count, f"all movements steps must have a length, currently, {len(step_duration)}/{step_count} have them"
|
step_duration) == step_count, f"all movements steps must have a length, currently, {len(step_duration)}/{step_count} have them"
|
||||||
|
|
||||||
def get_current_step(t):
|
|
||||||
time_passed = 0
|
|
||||||
for i in range(len(step_duration)):
|
|
||||||
time_passed += step_duration[i]
|
|
||||||
if t % movement_duration < time_passed:
|
|
||||||
return i
|
|
||||||
|
|
||||||
def get_current_step_advancement(t):
|
|
||||||
current_step = get_current_step(t)
|
|
||||||
t = t % movement_duration
|
|
||||||
for i in range(0, current_step):
|
|
||||||
t -= step_duration[i]
|
|
||||||
return t / step_duration[current_step]
|
|
||||||
|
|
||||||
def get_next_step(t):
|
def get_next_step(t):
|
||||||
return floor((get_current_step(t) + 1) % step_count)
|
return floor((get_current_step(t, step_duration, movement_duration) + 1) % step_count)
|
||||||
|
|
||||||
offsets = np.array([0, 0.5, 0, 0.5]) * movement_duration # offset between each leg
|
offsets = np.array([0, 1 / 2, 2 / 3, 0, 1 / 2, 2 / 3]) * movement_duration # offset between each leg
|
||||||
assert len(offsets) == num_patte, f"all offsets must be set, currently, {len(offsets)}/{num_patte} have them"
|
assert len(offsets) == num_patte, f"all offsets must be set, currently, {len(offsets)}/{num_patte} have them"
|
||||||
|
|
||||||
for patte in range(num_patte):
|
for patte in range(num_patte):
|
||||||
time = t + offsets[patte]
|
time = t + offsets[patte]
|
||||||
mov_index_start = get_current_step(time)
|
mov_index_start = get_current_step(time, step_duration, movement_duration)
|
||||||
mov_index_end = get_next_step(time)
|
mov_index_end = get_next_step(time)
|
||||||
|
|
||||||
|
step_adv = get_current_step_advancement(t, movement_duration, step_duration, mov_index_start)
|
||||||
|
|
||||||
mov_start_z = movement_z[mov_index_start]
|
mov_start_z = movement_z[mov_index_start]
|
||||||
mov_end_z = movement_z[mov_index_end]
|
mov_end_z = movement_z[mov_index_end]
|
||||||
|
|
||||||
@ -332,11 +314,11 @@ def walkV2(t, speed_x, speed_y, speed_rotation):
|
|||||||
|
|
||||||
(real_position[patte][0],
|
(real_position[patte][0],
|
||||||
real_position[patte][1],
|
real_position[patte][1],
|
||||||
real_position[patte][2]) = interpol2(mov_start, mov_end, get_current_step_advancement(time))
|
real_position[patte][2]) = interpol2(mov_start, mov_end, step_adv)
|
||||||
|
|
||||||
dthteta = speed_rotation * 2
|
dthteta = x2 * 2
|
||||||
|
|
||||||
theta = dthteta * (get_current_step_advancement(time) - 0.5)
|
theta = dthteta * (step_adv - 0.5)
|
||||||
# theta = 0
|
# theta = 0
|
||||||
print(theta)
|
print(theta)
|
||||||
# rotating the vector
|
# rotating the vector
|
||||||
@ -352,13 +334,95 @@ def walkV2(t, speed_x, speed_y, speed_rotation):
|
|||||||
real_position[patte][0] = x2
|
real_position[patte][0] = x2
|
||||||
real_position[patte][1] = y2
|
real_position[patte][1] = y2
|
||||||
|
|
||||||
# print(
|
|
||||||
# f"[{patte}] [{get_current_step(time)}->{get_next_step(time)}], start: {mov_start}, end: {mov_end}, current ({real_position[patte][0]}, {real_position[patte][1]}, {real_position[patte][2]})")
|
|
||||||
|
|
||||||
return legs(real_position)
|
return legs(real_position)
|
||||||
|
|
||||||
|
|
||||||
walk = walkV1
|
def jump(sy):
|
||||||
|
offset = np.array([
|
||||||
|
[0, 0, -0.15],
|
||||||
|
[0, 0, -0.15],
|
||||||
|
[0, 0, -0.15],
|
||||||
|
[0, 0, -0.15],
|
||||||
|
[0, 0, -0.15],
|
||||||
|
[0, 0, -0.15]
|
||||||
|
])
|
||||||
|
offset *= sy
|
||||||
|
return legs(neutral_position + offset)
|
||||||
|
|
||||||
|
|
||||||
|
# based on walk V1
|
||||||
|
def dino_naive(t, speed_x, speed_y, hz, hy, hx):
|
||||||
|
slider_max = 0.200
|
||||||
|
|
||||||
|
real_position = np.copy(neutral_position)
|
||||||
|
|
||||||
|
movement_x = np.array([
|
||||||
|
[0.00, 0, 0],
|
||||||
|
[0.04, 0, 0],
|
||||||
|
[-0.04, 0, 0],
|
||||||
|
])
|
||||||
|
|
||||||
|
movement_y = np.array([
|
||||||
|
[0.0, 0, 0],
|
||||||
|
[0, 0.04, 0],
|
||||||
|
[0, -0.04, 0],
|
||||||
|
])
|
||||||
|
|
||||||
|
movement_z = np.array([
|
||||||
|
[0, 0, 0.08],
|
||||||
|
[0, 0, -0.02],
|
||||||
|
[0, 0, -0.02]
|
||||||
|
])
|
||||||
|
|
||||||
|
# duration of each step of the movement
|
||||||
|
step_duration = np.array([0.05, 0.3, 0.05])
|
||||||
|
|
||||||
|
step_count = len(movement_z)
|
||||||
|
movement_duration = np.sum(step_duration)
|
||||||
|
|
||||||
|
assert len(
|
||||||
|
step_duration) == step_count, f"all movements steps must have a length, currently, {len(step_duration)}/{step_count} have them"
|
||||||
|
|
||||||
|
def get_next_step(t):
|
||||||
|
return floor((get_current_step(t, step_duration, movement_duration) + 1) % step_count)
|
||||||
|
|
||||||
|
offsets = np.array([0, 1 / 3, 2 / 3, 0, 1 / 3, 2 / 3]) * movement_duration # offset between each leg
|
||||||
|
assert len(offsets) == num_patte, f"all offsets must be set, currently, {len(offsets)}/{num_patte} have them"
|
||||||
|
|
||||||
|
for patte in range(num_patte):
|
||||||
|
if patte in [2, 5]:
|
||||||
|
continue
|
||||||
|
time = t + offsets[patte]
|
||||||
|
mov_index_start = get_current_step(time, step_duration, movement_duration)
|
||||||
|
mov_index_end = get_next_step(time)
|
||||||
|
|
||||||
|
mov_start_x = normalize(movement_x[mov_index_start], slider_max, speed_x)
|
||||||
|
mov_end_x = normalize(movement_x[mov_index_end], slider_max, speed_x)
|
||||||
|
|
||||||
|
mov_start_y = normalize(movement_y[mov_index_start], slider_max, speed_y)
|
||||||
|
mov_end_y = normalize(movement_y[mov_index_end], slider_max, speed_y)
|
||||||
|
|
||||||
|
mov_start_z = movement_z[mov_index_start]
|
||||||
|
mov_end_z = movement_z[mov_index_end]
|
||||||
|
|
||||||
|
mov_start = neutral_position[patte] + mov_start_z + mov_start_x + mov_start_y
|
||||||
|
mov_end = neutral_position[patte] + mov_end_z + mov_end_x + mov_end_y
|
||||||
|
|
||||||
|
(real_position[patte][0],
|
||||||
|
real_position[patte][1],
|
||||||
|
real_position[patte][2]) = interpol2(mov_start, mov_end,
|
||||||
|
get_current_step_advancement(time, movement_duration, step_duration,
|
||||||
|
mov_index_start))
|
||||||
|
|
||||||
|
real_position[2][2] = -0.1
|
||||||
|
real_position[2][0] = -0.28
|
||||||
|
|
||||||
|
real_position[5][2] = 0.05 + hz
|
||||||
|
real_position[5][0] = 0.25 + hx
|
||||||
|
real_position[5][1] = hy
|
||||||
|
print(hx)
|
||||||
|
return legs(real_position)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
print("N'exécutez pas ce fichier, mais simulator.py")
|
print("N'exécutez pas ce fichier, mais simulator.py")
|
||||||
|
15
xbox.py
15
xbox.py
@ -3,16 +3,18 @@ import pygame
|
|||||||
|
|
||||||
class Xbox:
|
class Xbox:
|
||||||
def __init__(self, controllerLogger):
|
def __init__(self, controllerLogger):
|
||||||
|
self.logger = controllerLogger
|
||||||
|
self.mode_count = 2
|
||||||
|
self.mode = 0
|
||||||
pygame.init()
|
pygame.init()
|
||||||
self.controllers = []
|
self.controllers = []
|
||||||
for i in range(0, pygame.joystick.get_count()):
|
for i in range(0, pygame.joystick.get_count()):
|
||||||
self.controllers.append(pygame.joystick.Joystick(i))
|
self.controllers.append(pygame.joystick.Joystick(i))
|
||||||
self.controllers[-1].init()
|
self.controllers[-1].init()
|
||||||
controllerLogger.info(f"Detected controller {self.controllers[-1].get_name()}")
|
self.logger.info(f"Detected controller {self.controllers[-1].get_name()}")
|
||||||
|
|
||||||
if len(self.controllers) == 0:
|
if len(self.controllers) == 0:
|
||||||
controllerLogger.critical("No controllers detected. Can't initialize remote control.")
|
self.logger.critical("No controllers detected. Can't initialize remote control.")
|
||||||
self.initialized = True
|
self.initialized = True
|
||||||
else:
|
else:
|
||||||
self.initialized = False
|
self.initialized = False
|
||||||
@ -38,8 +40,13 @@ class Xbox:
|
|||||||
value = 0
|
value = 0
|
||||||
self.data[{0: "x1", 1: "y1", 4: "y2", 3: "x2", 5: "r2", 2: "l2"}[event["axis"]]] = value
|
self.data[{0: "x1", 1: "y1", 4: "y2", 3: "x2", 5: "r2", 2: "l2"}[event["axis"]]] = value
|
||||||
elif "button" in keys:
|
elif "button" in keys:
|
||||||
# TODO
|
|
||||||
pass
|
pass
|
||||||
|
elif "joy" in keys: # To manage arrows
|
||||||
|
data = event["value"][0]
|
||||||
|
if data != 0:
|
||||||
|
self.mode += data
|
||||||
|
self.mode %= self.mode_count
|
||||||
|
self.logger.info(f"Switched mode ({data}). New mode: {self.mode}")
|
||||||
else:
|
else:
|
||||||
print(event)
|
print(event)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user