-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathexperiment_run.py
executable file
·455 lines (374 loc) · 17.5 KB
/
experiment_run.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
import os
import sys
import time
import random
import threading
import multiprocessing
import subprocess
from pydub import AudioSegment
from pydub.playback import play
import vlc
import pygame
from mode_config import ModeManager
from head_control import HeadMotors
from torso_control import TorsoMotors
mode_manager = ModeManager()
head_motors = HeadMotors()
torso_motors = TorsoMotors()
start_exp = False #should be false
audio_playing = False
nextsection = False
jazz1 = None
start_cond = "c3"
def keyboard_listener(paused, eyebrow_process, yaw_process, rsh_process):
global start_exp
global start_cond
paused_state = True # Track the paused state
while True:
user_input = input("Enter command (s to start, p to pause/resume, q to quit): ").lower()
if user_input == 'c3':
start_exp = True
start_cond = 'c3'
print("Experiment (Condition 3) started.")
if user_input == 'c4':
start_exp = True
start_cond = 'c4'
print("Experiment (Condition 4) started.")
elif user_input == 'p':
if paused_state:
paused.clear() # Resume the eyebrow process
print("Program resumed.")
else:
paused.set() # Pause the eyebrow process
print("Program paused.")
paused_state = not paused_state # Toggle paused state
elif user_input == 'q':
eyebrow_process.terminate()
eyebrow_process.join() # Ensure the process has terminated
yaw_process.terminate()
yaw_process.join()
rsh_process.terminate()
rsh_process.join()
terminate_program()
break
def eye_brow_idle(paused):
while True:
paused.wait() # Block the loop when the event is set (paused)
probability = 0.07 # Probability of eyebrow idle movement
blink_speed = random.choice([800, 1000])
if random.random() < probability:
try:
head_motors.move("eye_brow_l", 210, blink_speed - 100)
time.sleep(0.01)
head_motors.move("eye_brow_r", 510, blink_speed)
time.sleep(0.4 if blink_speed == 1000 else 0.8 if blink_speed == 800 else 0.9)
head_motors.move("eye_brow_l", 350, blink_speed - 100)
time.sleep(0.01)
head_motors.move("eye_brow_r", 343, blink_speed)
except Exception as e:
print(f"Error in eyebrow movement: {e}")
time.sleep(0.01)
continue
time.sleep(0.5)
def playaudio(audio, speed=1.0):
global audio_playing
if speed != 1.0:
audio = audio.speedup(playback_speed=speed)
t = threading.Thread(target=play, args=(audio,))
t.start()
def sound_waiter(s):
global audio_playing
audio_playing = True
time.sleep(s/1000)
time.sleep(1)
audio_playing = False
def terminate_program():
print("Terminating program.")
if jazz1:
jazz1.terminate()
torso_motors.release_motors()
torso_motors.release_hands('all')
head_motors.close()
pygame.quit()
sys.exit(0)
def yaw_roll(paused):
while True:
paused.wait() # Block the loop when the event is set (paused)
probability = 0.07 # Probability of eye movement
if random.random() < probability:
random_value = random.randint(0, 300)
random_speed = random.randint(300, 500)
head_motors.move("head_yaw", random_value, random_speed)
random_rt = random.randint(1, 3)
time.sleep(random_rt)
head_motors.move("head_yaw", 180, random_speed)
time.sleep(0.5)
def display_image_on_screen(image_path):
#screen = pygame.display.set_mode((0, 0))
screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
image = pygame.image.load(image_path)
image = pygame.transform.scale(image, screen.get_size())
screen.blit(image, (0, 0))
pygame.display.flip()
return screen
def handle_pygame_events(jazz_process):
global nextsection
for event in pygame.event.get():
if event.type == pygame.QUIT or event.type == pygame.KEYDOWN or event.type == pygame.MOUSEBUTTONDOWN:
try:
jazz_process.terminate()
pygame.quit()
nextsection = True
except Exception as e:
print(e)
def pygame_thread(image_path):
screen = display_image_on_screen(image_path)
# Keep checking for events until nextsection is True
while not nextsection:
handle_pygame_events(jazz1)
time.sleep(0.1)
"""
def play_video_on_loop(vlc_instance, video_path):
player = vlc_instance.media_player_new()
media = vlc_instance.media_new(video_path)
media.add_option('no-audio') # Mute the video
player.set_media(media)
#player.set_fullscreen(True)
player.play()
return player
"""
def control_video_player(vlc_instance, video_path, control_event):
player = vlc_instance.media_player_new()
media = vlc_instance.media_new(video_path)
media.add_option('no-audio')
player.set_fullscreen(True)
player.set_media(media)
player.play()
while not control_event.is_set():
state = player.get_state()
if state in [vlc.State.Ended, vlc.State.Stopped, vlc.State.Error]:
player.play() # Loop the video
time.sleep(0.1)
player.stop() # Stop the video when the event is set
def play_video_in_thread(vlc_instance, video_path, no_loop=False, full=False, mute=True, delay=True):
player = vlc_instance.media_player_new()
media = vlc_instance.media_new(video_path)
if mute == True:
media.add_option('no-audio') # Mute the video if needed
if full:
player.set_fullscreen(True)
player.set_media(media)
player.play()
if delay:
print("delay")
time.sleep(1)
player.play()
while True:
state = player.get_state()
if state in [vlc.State.Ended, vlc.State.Stopped, vlc.State.Error]:
break
time.sleep(0.1)
if no_loop == True:
player.stop() # Stop and close the player after playback ends
return player # Return the player to control it later
def hand_shoulder_idle(paused):
while True:
paused.wait() # Block the loop when the event is set (paused)
probability = 0.07 # Probability of eyebrow idle movement
blink_speed = 0.001
movement_number = random.randint(1, 2)
if random.random() < probability:
try:
if movement_number == 1:
torso_motors.arm_move("arm_r", 170, 0.01) # 170 Down - 90 Up When screw is front
torso_motors.arm_move("arm_l", 80, 0.01) # 160 Up - 80 Down When screw is front
time.sleep(0.5)
for i in range(4):
torso_motors.arm_move("r_shoulder", 90, 0.01) # 70 cap front - 160 cap top
torso_motors.arm_move("l_shoulder", 140, 0.01) # 160 cap front - 60 cap top
time.sleep(0.5)
torso_motors.arm_move("r_shoulder", 70, 0.01) # 70 cap front - 160 cap top
torso_motors.arm_move("l_shoulder", 160, 0.01) # 160 cap front - 60 cap top
time.sleep(0.5)
elif movement_number == 2:
torso_motors.arm_move("arm_r", 170, 0.01) # 170 Down - 90 Up When screw is front
torso_motors.arm_move("arm_l", 80, 0.01) # 160 Up - 80 Down When screw is front
time.sleep(0.5)
for i in range(4):
torso_motors.arm_move("arm_r", 150, 0.01) # 170 Down - 90 Up When screw is front
torso_motors.arm_move("arm_l", 100, 0.01) # 160 Up - 80 Down When screw is front
time.sleep(0.5)
torso_motors.arm_move("arm_r", 170, 0.01) # 170 Down - 90 Up When screw is front
torso_motors.arm_move("arm_l", 80, 0.01) # 160 Up - 80 Down When screw is front
time.sleep(0.5)
elif movement_number == 3:
pass
elif movement_number == 4:
pass
else:
pass
except Exception as e:
print(f"Error in hand_shoulder movement: {e}")
time.sleep(0.01)
continue
time.sleep(0.5)
if __name__ == "__main__":
pygame.init()
paused = multiprocessing.Event() # Use multiprocessing.Event directly
paused.set() # Start in a paused state
random_brow_process = multiprocessing.Process(target=eye_brow_idle, args=(paused,))
random_yaw_roll_process = multiprocessing.Process(target=yaw_roll, args=(paused,))
random_rsh_process = multiprocessing.Process(target=hand_shoulder_idle, args=(paused,))
audio_m1 = AudioSegment.from_file('experiment/voice/1.m4a')
audio_m2 = AudioSegment.from_file('experiment/voice/2.m4a')
audio_m3 = AudioSegment.from_file('experiment/voice/3.m4a')
audio_m4 = AudioSegment.from_file('experiment/voice/4.m4a')
audio_m5 = AudioSegment.from_file('experiment/voice/5.m4a')
audio_m5_j = AudioSegment.from_file('experiment/voice/5-jazz.m4a')
audio_m6 = AudioSegment.from_file('experiment/voice/6.m4a')
video_m7 = '/home/mirrly/mirrly_backend/experiment/videos/7.mp4'
audio_m8_c1 = AudioSegment.from_file('experiment/voice/8-c1.m4a')
video_m8_c2 = '/home/mirrly/mirrly_backend/experiment/videos/8-c2.mp4'
audio_m9 = AudioSegment.from_file('experiment/voice/9.m4a')
audio_m10 = AudioSegment.from_file('experiment/voice/10.m4a')
audio_m12 = AudioSegment.from_file('experiment/voice/12.m4a')
audio_m13 = AudioSegment.from_file('experiment/voice/13.m4a')
audio_m14 = AudioSegment.from_file('experiment/voice/14.m4a')
# Initialize VLC instance
vlc_instance = vlc.Instance('--input-repeat=999999', '--mouse-hide-timeout=0')
# Event to control the video playback
#logo_video_event = threading.Event()
#logo_video_thread = threading.Thread(target=control_video_player, args=(vlc_instance, "logo_intro.mp4", logo_video_event))
#logo_video_thread.start()
try:
# Start a separate thread to listen for the keyboard inputs
keyboard_thread = threading.Thread(target=keyboard_listener, args=(paused, random_brow_process,
random_yaw_roll_process, random_rsh_process))
keyboard_thread.daemon = True
keyboard_thread.start()
# Wake up motion
head_motors.move("eye_brow_l", 210, 500)
head_motors.move("eye_brow_r", 510, 500)
head_motors.move("head_pitch", 125, 800)
head_motors.move("head_yaw", 180, 400)
torso_motors.arm_move("arm_r", 170, 0.001) # 170 Down - 90 Up When screw is front
torso_motors.arm_move("arm_l", 80, 0.001) # 160 Up - 80 Down When screw is front
torso_motors.arm_move("r_shoulder", 70, 0.001) # 70 cap front - 160 cap top -
torso_motors.arm_move("l_shoulder", 160, 0.001) # 160 cap front - 60 cap top
# Wait until the experiment starts
print("Enter c3 or c4 to start...")
while not start_exp:
time.sleep(1)
print(f"Actual: {start_cond}")
time.sleep(1)
head_motors.move("eye_brow_l", 350, 400)
head_motors.move("eye_brow_r", 343, 400)
head_motors.move("head_pitch", 220, 300)
head_motors.move("eye_self", 139, 300) # 139-277
time.sleep(5)
head_motors.move("head_pitch", 195, 1000)
head_motors.move("eye_self", 277, 600) # 139-277
random_brow_process.start()
time.sleep(2)
head_motors.move("eye_self", 190, 600) # 139-277
head_motors.move("head_yaw", 400, 400)
time.sleep(2)
head_motors.move("head_yaw", 180, 700)
time.sleep(3)
playaudio(audio_m1)
random_yaw_roll_process.start()
torso_motors.arm_move("arm_l", 160, 0.01) # 160 Up - 80 Down When screw is front
#torso_motors.arm_move("arm_r", 90, 0.01) # 170 Down - 90 Up When screw is front
time.sleep(1)
playaudio(audio_m2)
torso_motors.arm_move("l_shoulder", 140, 0.005) # 160 cap front - 60 cap top
torso_motors.arm_move("arm_l", 140, 0.01) # 160 Up - 80 Down When screw is front
time.sleep(0.5)
torso_motors.arm_move("l_shoulder", 160, 0.005) # 160 cap front - 60 cap top
torso_motors.arm_move("arm_l", 160, 0.01) # 160 Up - 80 Down When screw is front
time.sleep(0.5)
torso_motors.arm_move("l_shoulder", 140, 0.005) # 160 cap front - 60 cap top
torso_motors.arm_move("arm_l", 140, 0.01) # 160 Up - 80 Down When screw is front
time.sleep(0.5)
torso_motors.arm_move("l_shoulder", 160, 0.005) # 160 cap front - 60 cap top
torso_motors.arm_move("arm_l", 160, 0.01) # 160 Up - 80 Down When screw is front
time.sleep(0.5)
torso_motors.arm_move("arm_l", 80, 0.005) # 160 Up - 80 Down When screw is front
#torso_motors.arm_move("arm_r", 170, 0.005) # 170 Down - 90 Up When screw is front
sound_waiter(len(audio_m1) + len(audio_m2) - 2500)
playaudio(audio_m3)
random_rsh_process.start()
sound_waiter(len(audio_m3))
playaudio(audio_m4)
sound_waiter(len(audio_m4))
#pygame.init()
playaudio(audio_m5)
# Start pygame thread to display image
pygame_thread_obj = threading.Thread(target=pygame_thread, args=("/home/mirrly/mirrly_backend/experiment/images/qrpic.jpg", ))
pygame_thread_obj.start()
# Wait until audio_m5 is done
sound_waiter(len(audio_m5))
# Start jazz music after audio_m5 is done
jazz1 = subprocess.Popen(['vlc', '--intf', 'dummy', '--loop', '/home/mirrly/mirrly_backend/experiment/voice/5-jazz.m4a'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# pygame event handling continues in the pygame thread
pygame_thread_obj.join()
playaudio(audio_m6)
sound_waiter(len(audio_m6))
vlc_instance2 = vlc.Instance('--mouse-hide-timeout=0')
video_thread_2 = threading.Thread(target=play_video_in_thread, args=(vlc_instance2, video_m7, True, True, False))
video_thread_2.start()
video_thread_2.join() # Ensure the video plays to completion
if start_cond == 'c3':
playaudio(audio_m8_c1)
sound_waiter(len(audio_m8_c1))
paused.clear()
time.sleep(1)
head_motors.move("eye_brow_l", 210, 500)
head_motors.move("eye_brow_r", 510, 500)
head_motors.move("head_pitch", 125, 800)
head_motors.move("head_yaw", 180, 400)
torso_motors.arm_move("arm_r", 170, 0.001) # 170 Down - 90 Up When screw is front
torso_motors.arm_move("arm_l", 80, 0.001) # 160 Up - 80 Down When screw is front
torso_motors.arm_move("r_shoulder", 70, 0.001) # 70 cap front - 160 cap top -
torso_motors.arm_move("l_shoulder", 160, 0.001) # 160 cap front - 60 cap top
#logo_video_event.set()
time.sleep(2)
vlc_instance3 = vlc.Instance('--mouse-hide-timeout=0')
video_thread_3 = threading.Thread(target=play_video_in_thread, args=(vlc_instance3, video_m8_c2, True, True, False))
video_thread_3.start()
video_thread_3.join() # Ensure the video plays to completion
head_motors.move("eye_brow_l", 370, 400)
head_motors.move("eye_brow_r", 343, 400)
head_motors.move("head_pitch", 195, 1000)
head_motors.move("eye_self", 190, 300) # 139-277
time.sleep(1)
#pygame.init()
paused.set()
time.sleep(1)
nextsection = False
playaudio(audio_m9)
sound_waiter(len(audio_m9))
playaudio(audio_m10)
# Wait until audio_m5 is done
sound_waiter(len(audio_m10))
# Start pygame thread to display image
pygame_thread_obj_2 = threading.Thread(target=pygame_thread, args=("/home/mirrly/mirrly_backend/experiment/images/9_qr.jpg",))
pygame_thread_obj_2.start()
# Start jazz music after audio_m10 is done
jazz1 = subprocess.Popen(['vlc', '--intf', 'dummy', '--loop', '/home/mirrly/mirrly_backend/experiment/voice/11-jazz.m4a'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# pygame event handling continues in the pygame thread
pygame_thread_obj_2.join()
playaudio(audio_m12)
sound_waiter(len(audio_m12))
playaudio(audio_m13)
sound_waiter(len(audio_m13))
playaudio(audio_m14)
sound_waiter(len(audio_m14))
subprocess.Popen(['vlc', '--intf', 'dummy', '--loop', '/home/mirrly/mirrly_backend/experiment/voice/15-jazz.m4a'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
while True:
time.sleep(1)
except Exception as e:
print(f"Exception occurred: {e}")
#logo_video_event.set() # Ensure the video is stopped
#logo_video_thread.join() # Wait for the video thread to finish
terminate_program()