readme + models
This commit is contained in:
@@ -9,6 +9,27 @@ class ArmController:
|
||||
self.hip_idx = {'left': 23, 'right': 24}
|
||||
self.dead_zone = config.get('dead_zone', 0.2)
|
||||
self.debug = config.get('debug', False)
|
||||
|
||||
def _get_side_indices(self, side):
|
||||
"""
|
||||
Возвращает (shoulder_idx, wrist_idx) для заданной стороны (left/right).
|
||||
При mirror=True интерпретируем сторону как в реальности: левая/правая рука.
|
||||
"""
|
||||
if self.mirror:
|
||||
if side == 'left':
|
||||
s_idx = 12
|
||||
w_idx = 16
|
||||
else:
|
||||
s_idx = 11
|
||||
w_idx = 15
|
||||
else:
|
||||
if side == 'left':
|
||||
s_idx = 11
|
||||
w_idx = 15
|
||||
else:
|
||||
s_idx = 12
|
||||
w_idx = 16
|
||||
return s_idx, w_idx
|
||||
|
||||
def _get_shoulder_width(self, landmarks):
|
||||
"""Ширина плеч для нормировки горизонтальных смещений."""
|
||||
@@ -35,49 +56,55 @@ class ArmController:
|
||||
def _horizontal_displacement_rel(self, landmarks, side):
|
||||
"""
|
||||
Нормированное горизонтальное смещение запястья относительно плеча.
|
||||
При mirror=True инвертируем знак, чтобы скомпенсировать отражение.
|
||||
Сторона `side` — это реальная сторона руки
|
||||
"""
|
||||
if landmarks[self.shoulder_idx[side]][3] < 0.5 or landmarks[self.wrist_idx[side]][3] < 0.5:
|
||||
s_idx, w_idx = self._get_side_indices(side)
|
||||
|
||||
if landmarks[s_idx][3] < 0.5 or landmarks[w_idx][3] < 0.5:
|
||||
return 0.0
|
||||
shoulder = landmarks[self.shoulder_idx[side]][:2]
|
||||
wrist = landmarks[self.wrist_idx[side]][:2]
|
||||
|
||||
shoulder = landmarks[s_idx][:2]
|
||||
wrist = landmarks[w_idx][:2]
|
||||
|
||||
shoulder_width = self._get_shoulder_width(landmarks)
|
||||
if shoulder_width is None:
|
||||
return 0.0
|
||||
|
||||
disp = wrist[0] - shoulder[0]
|
||||
if self.mirror:
|
||||
disp = -disp
|
||||
return disp / shoulder_width
|
||||
|
||||
def _vertical_displacement_rel(self, landmarks, side):
|
||||
"""
|
||||
Нормированное вертикальное смещение запястья относительно плеча.
|
||||
Положительное – запястье выше плеча (рука вверх), отрицательное – ниже.
|
||||
Зеркало не влияет.
|
||||
Вертикальное смещение: верх/низ запястья относительно плеча.
|
||||
Сторона `side` — реальная сторона руки.
|
||||
"""
|
||||
if landmarks[self.shoulder_idx[side]][3] < 0.5 or landmarks[self.wrist_idx[side]][3] < 0.5:
|
||||
s_idx, w_idx = self._get_side_indices(side)
|
||||
|
||||
if landmarks[s_idx][3] < 0.5 or landmarks[w_idx][3] < 0.5:
|
||||
return 0.0
|
||||
shoulder = landmarks[self.shoulder_idx[side]][:2]
|
||||
wrist = landmarks[self.wrist_idx[side]][:2]
|
||||
|
||||
shoulder = landmarks[s_idx][:2]
|
||||
wrist = landmarks[w_idx][:2]
|
||||
|
||||
torso_height = self._get_torso_height(landmarks)
|
||||
if torso_height is None:
|
||||
return 0.0
|
||||
# Так как y растёт вниз, то (shoulder[1] - wrist[1]) > 0, если запястье выше
|
||||
|
||||
disp = shoulder[1] - wrist[1]
|
||||
return disp / torso_height
|
||||
|
||||
def compute_speeds(self, landmarks):
|
||||
# Проверка видимости ключевых точек
|
||||
if (landmarks[11][3] < 0.5 or landmarks[12][3] < 0.5 or
|
||||
landmarks[15][3] < 0.5 or landmarks[16][3] < 0.5):
|
||||
#if self.debug:
|
||||
#print("Руки не видны")
|
||||
if self.debug:
|
||||
print("Руки не видны")
|
||||
return 0.0, 0.0
|
||||
|
||||
# Правая рука (индекс 16) — линейная скорость
|
||||
lin_rel = self._horizontal_displacement_rel(landmarks, 'right')
|
||||
# Левая рука (индекс 15) — угловая скорость
|
||||
ang_rel = self._vertical_displacement_rel(landmarks, 'left')
|
||||
linear_side = self.config['linear_arm']
|
||||
angular_side = self.config['angular_arm']
|
||||
|
||||
lin_rel = self._horizontal_displacement_rel(landmarks, linear_side)
|
||||
ang_rel = self._vertical_displacement_rel(landmarks, angular_side)
|
||||
|
||||
if self.debug:
|
||||
print(f"lin_rel={lin_rel:.3f}, ang_rel={ang_rel:.3f}")
|
||||
@@ -88,7 +115,7 @@ class ArmController:
|
||||
else:
|
||||
linear = min(lin_rel, 1.0) * self.config['max_speed_linear']
|
||||
|
||||
# Угловая скорость (положительная — вправо, отрицательная — влево)
|
||||
# Угловая скорость
|
||||
if abs(ang_rel) < self.dead_zone:
|
||||
angular = 0.0
|
||||
else:
|
||||
@@ -96,3 +123,4 @@ class ArmController:
|
||||
angular = ang_rel_clipped * self.config['max_speed_angular']
|
||||
|
||||
return linear, angular
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
class ControlState:
|
||||
def __init__(self, initial_enabled=True):
|
||||
def __init__(self, initial_enabled=False):
|
||||
self.enabled = initial_enabled
|
||||
|
||||
def update(self, special_gesture):
|
||||
|
||||
Reference in New Issue
Block a user