-
Notifications
You must be signed in to change notification settings - Fork 1
/
party_nao_project.py
205 lines (159 loc) · 7.03 KB
/
party_nao_project.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
# -*- coding: UTF-8 -*-
from naoqi import ALProxy
# Import moves
from moves import *
# Import algorithm and classes (Node, Problem)
import search_algorithms_partyNAO
from search_algorithms_partyNAO import Problem
# Import utilities
import time
import argparse
import operator
import math
import random
import glob, os
import pydub
import music_detection as md
from threading import Thread
import sys
from argparse import ArgumentParser
# Import problem fot partyNAO
import party_nao_problem_def as pnp
# Argument parsing
parser = ArgumentParser()
parser.add_argument("-p", "--robot-port",
dest="port",
required=True,
help="Port of NAO robot",
metavar="PORT")
args = vars(parser.parse_args())
port = args
# Robot connection settings
ip = "127.0.0.1"
port = int(args["port"]) #virtual robot port
#--------------------------------------------------------------#
# The following function and threads allow us to synchronize the execution of the choreography and the song
def execution_best_sequence(flat_list):
d1 = {v: k for k, v in pnp.position_list_dictionary.items()}
for el in flat_list:
position = d1[el]
position.main(ip, port)
class ThreadSong(Thread):
def __init__(self):
Thread.__init__(self)
def run(self):
md.play_song(song)
class ThreadDance(Thread):
def __init__(self):
Thread.__init__(self)
def run(self):
#time.sleep(3.0)
execution_best_sequence(flat_list)
#----------------------------MAIN------------------------------#
# Read from the file the pairs and fill a dictionary used during the execution
f = open("permutationsFile.txt", 'r')
dict_moves_time = {}
for line in f:
name_move = line[2:].split('),')
ns = name_move[0].split(',')
move1 = ns[0][1:-1]
move2 = ns[1][2:-1]
move = (move1, move2)
timer = float(name_move[1][1:-3])
dict_moves_time[move] = timer
#--------------------------------------------------------------#
# Select a random song and analyze the amplitude
song = md.random_song()
analyzed_song = md.analyze_music(song)
#--------------------------------------------------------------#
print("Using simulated annealing algorithm to find the best sequence for the selected song...")
#--------------------------------------------------------------#
# For each move we extract the minimum and maximum time between the move and every possible goal
# Then we construct the dictionary {key=goal_move, value=(min_time, max_time)}
list_goals_with_crouch = ["OB_sit relax", "OB_sit", "OB_stand zero", "OB_stand", "OB_hello", "OB_wipe forehead",
"OB_crouch"]
d_min_max = {}
for el in list_goals_with_crouch:
l = []
for key in dict_moves_time:
if key[1] == el:
l.append(dict_moves_time[key])
min_time_for_goal = min(l)
max_time_for_goal = max(l)
d_min_max[el] = (min_time_for_goal, max_time_for_goal)
times_indexes = []
while times_indexes == []: # This while terminates when a sequence which respects all the constraints of the problem
# is found.
used_intermediate_moves = []
dict_totale = {}
for i in range(50): # This for allow us to generate 100 possible solutions in order to choose the best one
used_intermediate_moves = []
while len(used_intermediate_moves) <= 4: # This while condition allows us to respect the constraint of
# the problem(" The algorithm A
# must use at least 5 different intermediate positions")
used_intermediate_moves = []
list_goals = ["OB_sit relax", "OB_sit", "OB_stand zero", "OB_stand", "OB_hello", "OB_wipe forehead"]
total_solution = []
next_initial_state = "OB_stand init"
total_time = 0
already_crouched = False
while list_goals != []: # This while allow us to find a solution for each sub-problem
dict_path_1 = {}
dict_path_2 = {}
for el in list_goals: # For each goal we find a solution
problem = pnp.partyNAO(next_initial_state, el, dict_moves_time, d_min_max[el],
analyzed_song, pnp.list_fast_moves, pnp.list_normal_moves, pnp.list_slow_moves,
total_time)
sol = search_algorithms_partyNAO.simulated_annealing_full(problem)
for el in sol[1:-1]:
if el not in used_intermediate_moves:
used_intermediate_moves.append(el)
dict_path_1[el] = sol
dict_path_2[el] = problem.tot_time
dict_path_2_reversed = {v: k for k, v in dict_path_2.items()}
# Add the computed sub_solution to the total_sequence
total_solution.append(dict_path_1[dict_path_2_reversed[min(dict_path_2.values())]][:-1])
next_initial_state = dict_path_1[dict_path_2_reversed[min(dict_path_2.values())]][-1]
list_goals.remove(next_initial_state)
total_time += min(dict_path_2.values())
if list_goals == [] and already_crouched == False:
list_goals.append("OB_crouch")
already_crouched = True
# We add the state "Crouch" to be sure that it's the las move (in order to respect the constraint of the problem)
total_solution[-1].append("OB_crouch")
tot_seq_len = 0
for el in total_solution: # Computing the length of the sequence
tot_seq_len += len(el)
dict_totale[(total_time, tot_seq_len)] = total_solution
l_tempi = []
l_seq = []
times_indexes = []
# We use the following cycle in order to scan the whole solutions dictionary and we select the best ones
# (considering the constraint on time and number of moves, in order to create an artistic/complex choreography)
for i in dict_totale.keys():
print('Debug', i[0], i[1])
l_tempi.append(i[0])
if i[0] > 80 and i[0] < 100 and i[1] > 12 and i[1] < 16:
times_indexes.append(i) # salviamo la tupla con il tempo che ci piace
l_seq.append(i[1])
#--------------------------------------------------------------#
# Extracting the best solution
print("Extracting the best solution...")
max_index = 0
for i in range(len(times_indexes)):
if times_indexes[i][1] > max_index:
max_index = i
print("TOTAL TIME: ", times_indexes[max_index])
best_sequence = dict_totale[times_indexes[max_index]]
flat_list = []
for sublist in best_sequence:
for item in sublist:
flat_list.append(item)
print("BEST SEQUENCE: ", flat_list, "NUMBER OF MOVES: ", len(flat_list))
#--------------------------------------------------------------#
# Execution of the best move and start the song.
t1 = ThreadSong()
t2= ThreadDance()
t2.start()
t1.start()
#--------------------------------------------------------------#