apirrone commited on
Commit
d5562ac
·
1 Parent(s): 087df0d
Files changed (1) hide show
  1. reachy_mini_greetings/main.py +159 -104
reachy_mini_greetings/main.py CHANGED
@@ -12,119 +12,174 @@ import time
12
 
13
 
14
  class GreetingsApp(ReachyMiniApp):
15
- def run(self, reachy_mini: ReachyMini, stop_event: threading.Event):
16
- head_tracker = HeadTracker()
17
- emotions = RecordedMoves("pollen-robotics/reachy-mini-emotions-library")
18
-
19
- moves = [
20
- "proud1",
21
- "proud2",
22
- "success1",
23
- "cheerful1",
24
- "welcoming1",
25
- "loving1",
26
- "surprised1",
27
- ]
28
- is_scared = True
29
- # did_one_turn = False
30
- # tracking = False
31
- # was_tracking = False
32
- # tracking_lost_since = time.time()
33
-
34
- t0 = time.time()
35
- while not stop_event.is_set():
36
- frame = reachy_mini.media.get_frame()
37
- # cv2.imshow("frame", frame)
38
- # cv2.waitKey(1)
39
-
40
- # if did_one_turn:
41
- # eye_center, roll = head_tracker.get_head_position(frame)
42
- # if eye_center is not None:
43
- # tracking = True
44
- # else:
45
- # tracking_lost_since = time.time()
46
-
47
- # if time.time() - tracking_lost_since > 2:
48
- # tracking = False
49
-
50
- # if eye_center is not None and tracking:
51
- # h, w, _ = frame.shape
52
- # eye_center = (eye_center + 1) / 2
53
- # eye_center[0] *= w
54
- # eye_center[1] *= h
55
- # reachy_mini.look_at_image(*eye_center, duration=0.0)
56
-
57
- # if not did_one_turn and not tracking:
58
- pose = create_head_pose(0, 0, 0, 0, 0, 0)
59
- reachy_mini.goto_target(
60
- pose, duration=1, antennas=[0, 0], method="ease_in_out"
61
- )
62
- time.sleep(0.5)
63
-
64
- if is_scared:
65
- reachy_mini.media.play_sound("impatient1.wav")
66
- pose = create_head_pose(-0.01, 0, -0.035, 0, 15, 0)
67
- reachy_mini.goto_target(
68
- pose, duration=0.3, antennas=[-1.5, 1.5], method="ease_in_out"
69
- )
70
- time.sleep(0.2)
71
-
72
- pose = create_head_pose(0, 0, -0.02, 0, 0, 0)
73
- reachy_mini.goto_target(
74
- pose, duration=2, antennas=[-1, 1], method="ease_in_out"
75
- )
76
- time.sleep(0.5)
77
- is_scared = False
78
-
79
- pose = create_head_pose(0.0, 0.02, -0.02, 20, 0, 0)
80
  reachy_mini.goto_target(
81
- pose, duration=0.5, antennas=[-1.5, 0], method="ease_in_out"
82
  )
83
  time.sleep(0.2)
84
 
85
- pose = create_head_pose(0.0, -0.02, -0.02, -20, 0, 0)
86
  reachy_mini.goto_target(
87
- pose, duration=0.5, antennas=[0, 1.6], method="ease_in_out"
88
- )
89
- time.sleep(0.2)
90
-
91
- pose = create_head_pose(0, 0, 0, 0, 0, 0)
92
- reachy_mini.goto_target(
93
- pose, duration=0.5, antennas=[0, 0], method="ease_in_out"
94
- )
95
- reachy_mini.play_move(
96
- emotions.get(np.random.choice(moves)), initial_goto_duration=1.0
97
- )
98
- reachy_mini.media.play_sound("confused1.wav")
99
-
100
- pose = create_head_pose(0, 0, 0.02, 0, -20, -140)
101
- reachy_mini.goto_target(
102
- pose,
103
- body_yaw=np.deg2rad(-100),
104
- duration=1,
105
- antennas=[-1.5, 0],
106
- method="ease_in_out",
107
  )
108
  time.sleep(0.5)
109
 
110
- pose = create_head_pose(0, 0, 0, 0, 0, 0)
111
- reachy_mini.goto_target(
112
- pose, duration=1, antennas=[0, 0], method="ease_in_out"
113
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
 
115
- if np.random.rand() < 0.2:
116
- reachy_mini.media.play_sound("dance1.wav")
117
- pose = create_head_pose(0, 0, 0.02, 0, -30, 100)
118
- reachy_mini.goto_target(
119
- pose,
120
- body_yaw=np.deg2rad(80),
121
- duration=1,
122
- antennas=[0, 1.5],
123
- method="ease_in_out",
124
- )
125
- time.sleep(0.5)
126
-
127
- print("reset")
 
 
 
128
 
129
  time.sleep(0.02)
130
 
 
12
 
13
 
14
  class GreetingsApp(ReachyMiniApp):
15
+ head_tracker = HeadTracker()
16
+ emotions = RecordedMoves("pollen-robotics/reachy-mini-emotions-library")
17
+
18
+ moves = [
19
+ "proud1",
20
+ "proud2",
21
+ "success1",
22
+ "cheerful1",
23
+ "welcoming1",
24
+ "loving1",
25
+ "surprised1",
26
+ ]
27
+ first_start = True
28
+ is_tracking = False
29
+ last_track_time = time.time()
30
+ lost_track_timeout = 2.0 # s
31
+ stop_tracking_timeout = 15.0 # s
32
+
33
+ def wake_up_sequence(self, reachy_mini: ReachyMini):
34
+ print("Start wake up sequence")
35
+ pose = create_head_pose(0, 0, 0, 0, 0, 0)
36
+ reachy_mini.goto_target(pose, duration=1, antennas=[0, 0], method="ease_in_out")
37
+ time.sleep(0.05)
38
+
39
+ if self.first_start:
40
+ reachy_mini.media.play_sound("impatient1.wav")
41
+ pose = create_head_pose(-0.01, 0, -0.035, 0, 15, 0)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  reachy_mini.goto_target(
43
+ pose, duration=0.3, antennas=[-1.5, 1.5], method="ease_in_out"
44
  )
45
  time.sleep(0.2)
46
 
47
+ pose = create_head_pose(0, 0, -0.02, 0, 0, 0)
48
  reachy_mini.goto_target(
49
+ pose, duration=2, antennas=[-1, 1], method="ease_in_out"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  )
51
  time.sleep(0.5)
52
 
53
+ pose = create_head_pose(0.0, 0.02, -0.02, 20, 0, 0)
54
+ reachy_mini.goto_target(
55
+ pose, duration=0.5, antennas=[-1.5, 0], method="ease_in_out"
56
+ )
57
+ if not self.first_start:
58
+ for _ in range(10):
59
+ frame = reachy_mini.media.get_frame()
60
+ ret = self.track_head(reachy_mini, frame)
61
+ if ret and np.random.rand() < 0.5:
62
+ reachy_mini.goto_target(body_yaw=0, duration=0.3)
63
+ return
64
+ time.sleep(0.2)
65
+
66
+ pose = create_head_pose(0.0, -0.02, -0.02, -20, 0, 0)
67
+ reachy_mini.goto_target(
68
+ pose, duration=0.5, antennas=[0, 1.6], method="ease_in_out"
69
+ )
70
+ if not self.first_start:
71
+ for _ in range(10):
72
+ frame = reachy_mini.media.get_frame()
73
+ ret = self.track_head(reachy_mini, frame)
74
+ if ret and np.random.rand() < 0.5:
75
+ reachy_mini.goto_target(body_yaw=0, duration=0.3)
76
+ return
77
+ time.sleep(0.2)
78
+
79
+ pose = create_head_pose(0, 0, 0, 0, 0, 0)
80
+ reachy_mini.goto_target(
81
+ pose, duration=0.5, antennas=[0, 0], method="ease_in_out"
82
+ )
83
+ reachy_mini.play_move(
84
+ self.emotions.get(np.random.choice(self.moves)), initial_goto_duration=1.0
85
+ )
86
+ reachy_mini.media.play_sound("confused1.wav")
87
+
88
+ if not self.first_start:
89
+ for _ in range(10):
90
+ frame = reachy_mini.media.get_frame()
91
+ ret = self.track_head(reachy_mini, frame)
92
+ if ret and np.random.rand() < 0.5:
93
+ reachy_mini.goto_target(body_yaw=0, duration=0.3)
94
+ return
95
+
96
+ pose = create_head_pose(0, 0, 0.02, 0, -20, -140)
97
+ reachy_mini.goto_target(
98
+ pose,
99
+ body_yaw=np.deg2rad(-100),
100
+ duration=1,
101
+ antennas=[-1.5, 0],
102
+ method="ease_in_out",
103
+ )
104
+ if not self.first_start:
105
+ for _ in range(10):
106
+ frame = reachy_mini.media.get_frame()
107
+ ret = self.track_head(reachy_mini, frame)
108
+ if ret and np.random.rand() < 0.5:
109
+ reachy_mini.goto_target(body_yaw=0, duration=0.3)
110
+ return
111
+ time.sleep(0.5)
112
+
113
+ pose = create_head_pose(0, 0, 0, 0, 0, 0)
114
+ reachy_mini.goto_target(pose, duration=1, antennas=[0, 0], method="ease_in_out")
115
+
116
+ if np.random.rand() < 0.2:
117
+ reachy_mini.media.play_sound("dance1.wav")
118
+ pose = create_head_pose(0, 0, 0.02, 0, -30, 100)
119
+ reachy_mini.goto_target(
120
+ pose,
121
+ body_yaw=np.deg2rad(80),
122
+ duration=1,
123
+ antennas=[0, 1.5],
124
+ method="ease_in_out",
125
+ )
126
+ if not self.first_start:
127
+ for _ in range(10):
128
+ frame = reachy_mini.media.get_frame()
129
+ ret = self.track_head(reachy_mini, frame)
130
+ if ret and np.random.rand() < 0.5:
131
+ reachy_mini.goto_target(body_yaw=0, duration=0.3)
132
+ return
133
+ time.sleep(0.5)
134
+ pose = create_head_pose(0, 0, 0, 0, 0, 0)
135
+ reachy_mini.goto_target(pose, duration=1, antennas=[0, 0], method="ease_in_out")
136
+
137
+ self.first_start = False
138
+
139
+ def track_head(self, reachy_mini: ReachyMini, frame: np.ndarray):
140
+ eye_center, roll = self.head_tracker.get_head_position(frame)
141
+ if eye_center is None:
142
+ if (
143
+ self.is_tracking
144
+ and time.time() - self.last_tracking_time > self.lost_track_timeout
145
+ ):
146
+ self.is_tracking = False
147
+ print("Lost track of the face")
148
+ return False
149
+
150
+ if not self.is_tracking:
151
+ self.start_tracking_time = time.time()
152
+ self.is_tracking = True
153
+ self.last_tracking_time = time.time()
154
+ h, w, _ = frame.shape
155
+ eye_center = (eye_center + 1) / 2
156
+ eye_center[0] *= w
157
+ eye_center[1] *= h
158
+ reachy_mini.look_at_image(*eye_center, duration=0.0)
159
+
160
+ if time.time() - self.start_tracking_time > self.stop_tracking_timeout:
161
+ self.is_tracking = False
162
+ print("Stop tracking the face")
163
+ reachy_mini.goto_target(body_yaw=0, duration=0.5)
164
+ return False
165
+ return True
166
 
167
+ def run(self, reachy_mini: ReachyMini, stop_event: threading.Event):
168
+ t0 = time.time()
169
+ while not stop_event.is_set():
170
+ frame = reachy_mini.media.get_frame()
171
+ if self.first_start:
172
+ self.wake_up_sequence(reachy_mini)
173
+ else:
174
+ if not self.is_tracking:
175
+ for _ in range(10):
176
+ self.track_head(reachy_mini, frame)
177
+ frame = reachy_mini.media.get_frame()
178
+ else:
179
+ ret = self.track_head(reachy_mini, frame)
180
+ # print("found face" if ret else "lost face")
181
+ if not self.is_tracking:
182
+ self.wake_up_sequence(reachy_mini)
183
 
184
  time.sleep(0.02)
185