Compare commits
9
Commits
730c2417dd
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1cd15dd6bc | ||
|
|
9321f1973d | ||
|
|
fb88fa67e4 | ||
|
|
052db363d7 | ||
|
|
f0d88ac1b3 | ||
|
|
eba2dfc5a6 | ||
|
|
a467318d24 | ||
|
|
c745bdb5a3 | ||
|
|
a8efe38aaf |
@@ -0,0 +1,113 @@
|
|||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import yaml
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import numpy as np
|
||||||
|
scores_big =[]
|
||||||
|
name = []
|
||||||
|
colors = []
|
||||||
|
def s_a(n):
|
||||||
|
return sum(n)/len(n)
|
||||||
|
|
||||||
|
def mediana(n):
|
||||||
|
while len(n) >2:
|
||||||
|
n.remove(min(n))
|
||||||
|
n.remove(max(n))
|
||||||
|
if len(n) == 2:
|
||||||
|
return s_a(n)
|
||||||
|
else:
|
||||||
|
return n[0]
|
||||||
|
|
||||||
|
def plot(ax, path, color):
|
||||||
|
scores =[]
|
||||||
|
|
||||||
|
for filename in sorted(os.listdir(path)):
|
||||||
|
file_path = os.path.join(path, filename)
|
||||||
|
# Check if it is a file and not a subdirectory
|
||||||
|
if os.path.isfile(file_path) and file_path.endswith('.yaml'):
|
||||||
|
with open(file_path, 'r', encoding='utf-8') as file:
|
||||||
|
data = yaml.load(file, Loader = yaml.Loader)
|
||||||
|
#scores.append(data['score'])
|
||||||
|
scores.append(data['score']/data['total_time'])
|
||||||
|
|
||||||
|
|
||||||
|
ax.plot(range(1, len(scores)+1),scores, '.-', label=f"{path.split('/')[-1]}'s scores", color = color)
|
||||||
|
ax.plot((1, len(scores)),(s_a(scores), s_a(scores)), '--', label=f"{path.split('/')[-1]}'s mean ({round(s_a(scores), 3)})", color = color)
|
||||||
|
ax.plot((1, len(scores)),(mediana(scores), mediana(scores)), ':', label=f"{path.split('/')[-1]}'s mediana ({round(mediana(scores), 3)})", color = color)
|
||||||
|
|
||||||
|
|
||||||
|
def boxplot(ax, path, color):
|
||||||
|
scores =[]
|
||||||
|
|
||||||
|
for filename in sorted(os.listdir(path)):
|
||||||
|
file_path = os.path.join(path, filename)
|
||||||
|
# Check if it is a file and not a subdirectory
|
||||||
|
if os.path.isfile(file_path) and file_path.endswith('.yaml'):
|
||||||
|
with open(file_path, 'r', encoding='utf-8') as file:
|
||||||
|
data = yaml.load(file, Loader = yaml.Loader)
|
||||||
|
#scores.append(data['score'])
|
||||||
|
scores.append(data['score']/data['total_time'])
|
||||||
|
|
||||||
|
scores_big.append(scores)
|
||||||
|
name.append(path.split('/')[-1])
|
||||||
|
colors.append(color)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
global_path = "/home/gestures/Easy_sim/dummy_simulation/stats/"
|
||||||
|
# 1. Name (Dima)
|
||||||
|
# 2. Name-Name (Dima-Elisey)
|
||||||
|
|
||||||
|
DATA = {} # Name of creator - {} - Name of tester
|
||||||
|
|
||||||
|
for dirname in sorted(os.listdir(global_path)):
|
||||||
|
dirpath = os.path.join(global_path, dirname)
|
||||||
|
if os.path.isdir(file_path):
|
||||||
|
data = []
|
||||||
|
if not dirname.contains('-'):
|
||||||
|
name = dirname
|
||||||
|
if not name is DATA:
|
||||||
|
DATA[name] = {}
|
||||||
|
DATA[name][name] = data
|
||||||
|
else:
|
||||||
|
names = dirname.split('-')
|
||||||
|
name1 = names[0]
|
||||||
|
name2 = names[1]
|
||||||
|
if not name1 is DATA:
|
||||||
|
DATA[name1] = {}
|
||||||
|
DATA[name1][name2] = data
|
||||||
|
for filename in sorted(os.listdir(dirpath)):
|
||||||
|
file_path = os.path.join(dirpath, filename)
|
||||||
|
if file_path.endswith('.yaml'):
|
||||||
|
with open(file_path, 'r', encoding='utf-8') as file:
|
||||||
|
datafile = yaml.load(file, Loader = yaml.Loader)
|
||||||
|
# TODO change score to new formula
|
||||||
|
data.append(datafile['score'])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fig, ax = plt.subplots()
|
||||||
|
|
||||||
|
boxplot(ax, "/home/gestures/Easy_sim/dummy_simulation/stats/Dima", "limegreen")
|
||||||
|
boxplot(ax, "/home/gestures/Easy_sim/dummy_simulation/stats/Elisey", "red")
|
||||||
|
boxplot(ax, "/home/gestures/Easy_sim/dummy_simulation/stats/BOBA", "magenta")
|
||||||
|
boxplot(ax, "/home/gestures/Easy_sim/dummy_simulation/stats/Nika", "pink")
|
||||||
|
boxplot(ax, "/home/gestures/Easy_sim/dummy_simulation/stats/Sasha", "orange")
|
||||||
|
plot(ax, "/home/gestures/Easy_sim/dummy_simulation/stats/Christine", "blue")
|
||||||
|
|
||||||
|
scores_BIG = ax.boxplot(scores_big, patch_artist=True, tick_labels=name)
|
||||||
|
# Применяем цвета к каждому ящику
|
||||||
|
for patch, color in zip(scores_BIG['boxes'], colors):
|
||||||
|
patch.set_facecolor(color)
|
||||||
|
ax.set(xlabel='№', ylabel='score')
|
||||||
|
ax.grid()
|
||||||
|
ax.legend()
|
||||||
|
ax.set_title("Scores of students in dummy simulation")
|
||||||
|
plt.show()
|
||||||
|
#path.split('/')[-1]
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
# Данные: (первый человек, второй человек, время1, время2)
|
||||||
|
data = [
|
||||||
|
("Елисей", "Ника", "01:53.68", "00:46.85"),
|
||||||
|
("Ника", "Вова", "00:57.28", "01:05.67"),
|
||||||
|
("Вова", "Елисей","00:38.35", "00:34.74"),
|
||||||
|
("Дима", "Саша", "00:57.45", "00:52.90"),
|
||||||
|
("Саша", "Дима", "00:25.69", "00:55.85"),
|
||||||
|
]
|
||||||
|
|
||||||
|
def time_to_seconds(t):
|
||||||
|
# поддерживает формат mm:ss.xx
|
||||||
|
mm, rest = t.split(":")
|
||||||
|
ss = float(rest)
|
||||||
|
return int(mm) * 60 + ss
|
||||||
|
|
||||||
|
def seconds_to_time(sec):
|
||||||
|
mm = int(sec // 60)
|
||||||
|
ss = sec % 60
|
||||||
|
return f"{mm:02d}:{ss:05.2f}"
|
||||||
|
|
||||||
|
# Подготовка данных
|
||||||
|
labels = [f"{a} → {b}" for a, b, _, _ in data]
|
||||||
|
t1 = np.array([time_to_seconds(x[2]) for x in data])
|
||||||
|
t2 = np.array([time_to_seconds(x[3]) for x in data])
|
||||||
|
|
||||||
|
y = np.arange(len(data))
|
||||||
|
|
||||||
|
# Визуальный стиль
|
||||||
|
plt.style.use("seaborn-v0_8-whitegrid")
|
||||||
|
fig, ax = plt.subplots(figsize=(11, 6))
|
||||||
|
|
||||||
|
color1 = "#4C78A8"
|
||||||
|
color2 = "#F58518"
|
||||||
|
|
||||||
|
bars1 = ax.barh(y, t1, color=color1, edgecolor="none", label="Первое время")
|
||||||
|
bars2 = ax.barh(y, t2, left=t1, color=color2, edgecolor="none", label="Второе время")
|
||||||
|
|
||||||
|
# Подписи на сегментах
|
||||||
|
for i, (b1, b2, a1, a2) in enumerate(zip(bars1, bars2, t1, t2)):
|
||||||
|
ax.text(
|
||||||
|
b1.get_x() + b1.get_width() / 2,
|
||||||
|
b1.get_y() + b1.get_height() / 2,
|
||||||
|
seconds_to_time(a1),
|
||||||
|
ha="center", va="center", color="white", fontsize=10, fontweight="bold"
|
||||||
|
)
|
||||||
|
ax.text(
|
||||||
|
b2.get_x() + b2.get_width() / 2,
|
||||||
|
b2.get_y() + b2.get_height() / 2,
|
||||||
|
seconds_to_time(a2),
|
||||||
|
ha="center", va="center", color="white", fontsize=10, fontweight="bold"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Подписи осей и оформление
|
||||||
|
ax.set_yticks(y)
|
||||||
|
ax.set_yticklabels(labels, fontsize=11)
|
||||||
|
ax.invert_yaxis()
|
||||||
|
ax.set_xlabel("Время, сек.")
|
||||||
|
ax.set_title("Сравнение суммарного времени выполнения задания", fontsize=15, pad=12)
|
||||||
|
ax.legend(loc="lower right")
|
||||||
|
|
||||||
|
# Сетка и рамки
|
||||||
|
ax.spines["top"].set_visible(False)
|
||||||
|
ax.spines["right"].set_visible(False)
|
||||||
|
ax.grid(axis="x", linestyle="--", alpha=0.4)
|
||||||
|
|
||||||
|
plt.tight_layout()
|
||||||
|
|
||||||
|
fig.savefig("first_test.png")
|
||||||
|
|
||||||
|
plt.show()
|
||||||
@@ -0,0 +1,221 @@
|
|||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import yaml
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
|
def total_boxplot(DATA, creator = 'any', tester = 'any', simulation = "dummy_simulation", savepath = "./"):
|
||||||
|
|
||||||
|
fig, ax = plt.subplots()
|
||||||
|
|
||||||
|
data_to_plot = []
|
||||||
|
labels = []
|
||||||
|
title = f'Boxplot of scores in {simulation},'
|
||||||
|
xlabel = ""
|
||||||
|
|
||||||
|
colors_list = plt.colormaps['tab10'].colors
|
||||||
|
|
||||||
|
if creator == tester == 'any':
|
||||||
|
print(f"Warning: setting both creator and tester as 'any' plots only self testing!")
|
||||||
|
title += f" self testing"
|
||||||
|
xlabel = "self tester"
|
||||||
|
for creator_name, data in DATA.items():
|
||||||
|
if creator_name in data:
|
||||||
|
data_to_plot.append(data[creator_name])
|
||||||
|
labels.append(creator_name)
|
||||||
|
|
||||||
|
elif creator == 'any':
|
||||||
|
title += f" tester: {tester}"
|
||||||
|
xlabel = "creator"
|
||||||
|
for creator_name, data in DATA.items():
|
||||||
|
if tester in data:
|
||||||
|
data_to_plot.append(data[tester])
|
||||||
|
#labels.append(f"{creator_name}-{tester}")
|
||||||
|
labels.append(creator_name)
|
||||||
|
|
||||||
|
elif tester == 'any':
|
||||||
|
title += f" creator: {creator}"
|
||||||
|
xlabel = "tester"
|
||||||
|
if creator in DATA:
|
||||||
|
for tester_name, data in DATA[creator].items():
|
||||||
|
data_to_plot.append(data)
|
||||||
|
#labels.append(f"{creator}-{tester}")
|
||||||
|
labels.append(tester_name)
|
||||||
|
|
||||||
|
|
||||||
|
if len(data_to_plot) == 0:
|
||||||
|
print("No appropriate data!")
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
#print(len(data_to_plot), len(labels))
|
||||||
|
median_styling = {'color': 'black', 'linewidth': 2}
|
||||||
|
elements = ax.boxplot(data_to_plot, patch_artist=True, tick_labels=labels, medianprops=median_styling)
|
||||||
|
for i, patch in enumerate(elements['boxes']):
|
||||||
|
patch.set_facecolor(colors_list[(i)%10])
|
||||||
|
|
||||||
|
ax.grid()
|
||||||
|
#ax.legend()
|
||||||
|
ax.set(xlabel=xlabel, ylabel='Score')
|
||||||
|
ax.set_title(title)
|
||||||
|
|
||||||
|
ax.figure.savefig(f'{savepath}/{creator}_{tester}_{simulation}.png', bbox_inches='tight')
|
||||||
|
|
||||||
|
|
||||||
|
def heat_map(DATA, criteria = np.median, savepath = "./"):
|
||||||
|
|
||||||
|
names_to_nums = {name: num for num, name in enumerate(list(DATA.keys()))}
|
||||||
|
values = np.zeros( (len(names_to_nums)+1, len(names_to_nums)+1) )
|
||||||
|
|
||||||
|
testers = {}
|
||||||
|
for creator, Data in DATA.items():
|
||||||
|
total_creator = []
|
||||||
|
for tester, data in Data.items():
|
||||||
|
if not tester in testers:
|
||||||
|
testers[tester] = []
|
||||||
|
if creator in names_to_nums and tester in names_to_nums:
|
||||||
|
creator_idx = names_to_nums[creator]
|
||||||
|
tester_idx = names_to_nums[tester]
|
||||||
|
values[creator_idx, tester_idx] = criteria(data)
|
||||||
|
total_creator += data
|
||||||
|
testers[tester] +=data
|
||||||
|
values[creator_idx, len(names_to_nums)] = criteria(total_creator)
|
||||||
|
|
||||||
|
for tester, data in testers.items():
|
||||||
|
tester_idx = names_to_nums[tester]
|
||||||
|
values[len(names_to_nums), tester_idx] = criteria(data)
|
||||||
|
|
||||||
|
fig, ax = plt.subplots()
|
||||||
|
im = ax.imshow(values, cmap='coolwarm')
|
||||||
|
|
||||||
|
for i in range(values.shape[0]):
|
||||||
|
for j in range(values.shape[1]):
|
||||||
|
text = ax.text(j, i, round(values[i, j],1), ha="center", va="center", color="k")
|
||||||
|
|
||||||
|
ax.set_xticks(range(len(DATA.keys())+1), labels=list(DATA.keys())+['mean'] )
|
||||||
|
ax.set_yticks(range(len(DATA.keys())+1), labels=list(DATA.keys())+['mean'] )
|
||||||
|
|
||||||
|
ax.set(xlabel='tester', ylabel='creator')
|
||||||
|
ax.set_title(f"Cross-validation heatmap ({criteria.__name__})")
|
||||||
|
|
||||||
|
ax.figure.savefig(f"{savepath}/cross_validation_{criteria.__name__}.png")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def convert_score(data):
|
||||||
|
|
||||||
|
score = data['score']
|
||||||
|
Nsof = len(data['exted_sofs'])
|
||||||
|
Ncol = len(data['collisions'])
|
||||||
|
Ksof = data['k_params']['_k_sof']
|
||||||
|
Khp = data['k_params']['_k_hp']
|
||||||
|
Kch = data['k_params']['_k_charge']
|
||||||
|
Khp_max = 100
|
||||||
|
Kch_max = 100
|
||||||
|
|
||||||
|
Kch_r = (score - Ksof*Nsof-Khp*(Khp_max-Ncol)/Khp_max) * Kch_max/Kch
|
||||||
|
|
||||||
|
score_new = Ksof*Nsof*(Kch*Kch_r/Khp_max+Khp*(Khp_max-Ncol)/Khp_max)
|
||||||
|
#print(type(score_new))
|
||||||
|
|
||||||
|
return score_new
|
||||||
|
|
||||||
|
# DATA[name] = {name: [scores]}
|
||||||
|
def no_interface_plot(DATA, savepath = "./"):
|
||||||
|
n = 0
|
||||||
|
names_with = []#DATA.keys()
|
||||||
|
names_without = []
|
||||||
|
for creator, Data in DATA.items():
|
||||||
|
for tester, data in Data.items():
|
||||||
|
if tester == creator:
|
||||||
|
if 'NoInt' in creator:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
|
||||||
|
wInt = creator+'NoInt'
|
||||||
|
if wInt in DATA:
|
||||||
|
names_with.append(creator)
|
||||||
|
names_without.append(wInt)
|
||||||
|
#print(len(names_with), names_with)
|
||||||
|
#print(len(names_without), names_without)
|
||||||
|
'''
|
||||||
|
for tester, data in Data.items():
|
||||||
|
if tester == creator:
|
||||||
|
del DATA[]
|
||||||
|
'''
|
||||||
|
creator_means = {
|
||||||
|
'With interface': [np.median(DATA[name][name]) for name in names_with],
|
||||||
|
'Without interface': [np.median(DATA[name][name]) for name in names_without]}
|
||||||
|
|
||||||
|
x = np.arange(len(names_with)) # the label locations
|
||||||
|
width = 0.25 # the width of the bars
|
||||||
|
multiplier = 0
|
||||||
|
|
||||||
|
fig, ax = plt.subplots(layout='constrained')
|
||||||
|
|
||||||
|
for attribute, measurement in creator_means.items():
|
||||||
|
offset = width * multiplier
|
||||||
|
rects = ax.bar(x + offset, np.round(measurement,2), width, label=attribute)
|
||||||
|
ax.bar_label(rects, padding=3)
|
||||||
|
multiplier += 1
|
||||||
|
ax.set_ylabel('Score')
|
||||||
|
ax.set_title('Change in scores with visual interface disabled')
|
||||||
|
ax.set_xticks(x + width, names_with)
|
||||||
|
ax.legend(loc='upper left', ncols=3)
|
||||||
|
ax.set_ylim(0, 100)
|
||||||
|
ax.grid(axis='y')
|
||||||
|
|
||||||
|
ax.figure.savefig(f"{savepath}/no_interface.png")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
global_path = "/home/gestures6/Easy_sim/dummy_simulation/stats/"
|
||||||
|
# 1. Name (Dima)
|
||||||
|
# 2. Name-Name (Dima-Elisey)
|
||||||
|
|
||||||
|
DATA = {} # Name of creator - {} - Name of tester
|
||||||
|
|
||||||
|
for dirname in sorted(os.listdir(global_path)):
|
||||||
|
dirpath = os.path.join(global_path, dirname)
|
||||||
|
if os.path.isdir(dirpath) and not dirname.startswith('!'):
|
||||||
|
data = []
|
||||||
|
if not '-' in dirname:
|
||||||
|
name = dirname
|
||||||
|
if not name in DATA:
|
||||||
|
DATA[name] = {}
|
||||||
|
DATA[name][name] = data
|
||||||
|
else:
|
||||||
|
names = dirname.split('-')
|
||||||
|
name1 = names[0]
|
||||||
|
name2 = names[1]
|
||||||
|
if not name1 in DATA:
|
||||||
|
DATA[name1] = {}
|
||||||
|
DATA[name1][name2] = data
|
||||||
|
for filename in sorted(os.listdir(dirpath)):
|
||||||
|
file_path = os.path.join(dirpath, filename)
|
||||||
|
if file_path.endswith('.yaml'):
|
||||||
|
with open(file_path, 'r', encoding='utf-8') as file:
|
||||||
|
datafile = yaml.load(file, Loader = yaml.Loader)
|
||||||
|
data.append(convert_score(datafile)) # TODO change score to new formula
|
||||||
|
#data.append(datafile['score'])
|
||||||
|
|
||||||
|
|
||||||
|
#for cr, data in DATA.items():
|
||||||
|
#print(f"{cr}: {data}")
|
||||||
|
savepath = global_path
|
||||||
|
total_boxplot(DATA, creator = 'any', tester = 'any', savepath = savepath)
|
||||||
|
|
||||||
|
no_interface_plot(DATA, savepath = savepath)
|
||||||
|
|
||||||
|
#for name in DATA.keys():
|
||||||
|
#total_boxplot(DATA, creator = name, tester = 'any', savepath = savepath)
|
||||||
|
#total_boxplot(DATA, creator = 'any', tester = name, savepath = savepath)
|
||||||
|
|
||||||
|
#heat_map(DATA, savepath = savepath)
|
||||||
|
|
||||||
|
|
||||||
|
plt.show()
|
||||||
|
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import yaml
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
|
def s_a(n):
|
||||||
|
return sum(n)/len(n)
|
||||||
|
|
||||||
|
def mediana(n):
|
||||||
|
while len(n) >2:
|
||||||
|
n.remove(min(n))
|
||||||
|
n.remove(max(n))
|
||||||
|
if len(n) == 2:
|
||||||
|
return s_a(n)
|
||||||
|
else:
|
||||||
|
return n[0]
|
||||||
|
|
||||||
|
|
||||||
|
def plot(ax, path, color):
|
||||||
|
scores =[]
|
||||||
|
|
||||||
|
for filename in sorted(os.listdir(path)):
|
||||||
|
file_path = os.path.join(path, filename)
|
||||||
|
# Check if it is a file and not a subdirectory
|
||||||
|
if os.path.isfile(file_path) and file_path.endswith('.yaml'):
|
||||||
|
with open(file_path, 'r', encoding='utf-8') as file:
|
||||||
|
data = yaml.load(file, Loader = yaml.Loader)
|
||||||
|
scores.append(data['score'])
|
||||||
|
#scores.append(data['score']/data['total_time'])
|
||||||
|
|
||||||
|
|
||||||
|
ax.plot(range(1, len(scores)+1),scores, '.-', label=f"{path.split('/')[-1]}'s scores", color = color)
|
||||||
|
ax.plot((1, len(scores)),(s_a(scores), s_a(scores)), '--', label=f"{path.split('/')[-1]}'s mean ({round(s_a(scores), 3)})", color = color)
|
||||||
|
ax.plot((1, len(scores)),(mediana(scores), mediana(scores)), ':', label=f"{path.split('/')[-1]}'s mediana ({round(mediana(scores), 3)})", color = color)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
fig, ax = plt.subplots()
|
||||||
|
|
||||||
|
plot(ax, "/home/gestures/Easy_sim/dummy_simulation/stats/Dima", "limegreen")
|
||||||
|
plot(ax, "/home/gestures/Easy_sim/dummy_simulation/stats/Elisey", "red")
|
||||||
|
plot(ax, "/home/gestures/Easy_sim/dummy_simulation/stats/BOBA", "magenta")
|
||||||
|
plot(ax, "/home/gestures/Easy_sim/dummy_simulation/stats/Nika", "pink")
|
||||||
|
plot(ax, "/home/gestures/Easy_sim/dummy_simulation/stats/Sasha", "orange")
|
||||||
|
plot(ax, "/home/gestures/Easy_sim/dummy_simulation/stats/Christine", "blue")
|
||||||
|
|
||||||
|
ax.set(xlabel='№', ylabel='score')
|
||||||
|
ax.grid()
|
||||||
|
ax.legend()
|
||||||
|
ax.set_title("Scores of students in dummy simulation")
|
||||||
|
plt.show()
|
||||||
+62
-16
@@ -1,9 +1,12 @@
|
|||||||
import copy
|
import copy
|
||||||
import time
|
import time
|
||||||
|
import yaml
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
||||||
class RobotController(object):
|
class RobotController(object):
|
||||||
|
|
||||||
def __init__(self, fire_ext_max_capacity = 5, collision_damage = 1, k_sof = 1, k_cas = 1, k_asset = 1, k_hp = 1, fall_damage = 10):
|
def __init__(self, fire_ext_max_capacity = 5, collision_damage = 1, k_sof = 1, k_cas = 1, k_asset = 1, k_hp = 1, fall_damage = 10, k_charge = 1):
|
||||||
|
|
||||||
# STATE VARIABLES
|
# STATE VARIABLES
|
||||||
self._fire_ext_max_capacity = fire_ext_max_capacity
|
self._fire_ext_max_capacity = fire_ext_max_capacity
|
||||||
@@ -12,9 +15,12 @@ class RobotController(object):
|
|||||||
self._start_hp = 100
|
self._start_hp = 100
|
||||||
self._hit_points = self._start_hp
|
self._hit_points = self._start_hp
|
||||||
self._collision_damage = collision_damage
|
self._collision_damage = collision_damage
|
||||||
self._charge_points = 100
|
self._start_charge = 100
|
||||||
|
self._charge_points = self._start_charge
|
||||||
self._fall_damage = fall_damage
|
self._fall_damage = fall_damage
|
||||||
|
|
||||||
|
self._start_time = None
|
||||||
|
|
||||||
self._collisions = []
|
self._collisions = []
|
||||||
self._exted_sofs = []
|
self._exted_sofs = []
|
||||||
self._found_casualty = []
|
self._found_casualty = []
|
||||||
@@ -25,17 +31,29 @@ class RobotController(object):
|
|||||||
self._k_cas = k_cas
|
self._k_cas = k_cas
|
||||||
self._k_asset = k_asset
|
self._k_asset = k_asset
|
||||||
self._k_hp = k_hp
|
self._k_hp = k_hp
|
||||||
|
self._k_charge = k_charge
|
||||||
|
|
||||||
|
def _check_time_init(self):
|
||||||
|
if not self._start_time is None:
|
||||||
|
return
|
||||||
|
self._start_time = time.time()
|
||||||
|
|
||||||
|
def _ts(self):
|
||||||
|
return time.time() - self._start_time
|
||||||
|
|
||||||
''' CONTROL '''
|
''' CONTROL '''
|
||||||
|
|
||||||
# speeds in [-1, 1] extra stuff will be cut
|
# speeds in [-1, 1] extra stuff will be cut
|
||||||
def send_speed_cmd(self, v, w):
|
def send_speed_cmd(self, v, w):
|
||||||
|
self._check_time_init()
|
||||||
|
if self._charge_points == 0:
|
||||||
|
return 0, 0
|
||||||
v = min(max(-1, v), 1)
|
v = min(max(-1, v), 1)
|
||||||
w = min(max(-1, w), 1)
|
w = min(max(-1, w), 1)
|
||||||
return v, w
|
return v, w
|
||||||
|
|
||||||
def send_fire_ext_burst_cmd(self):
|
def send_fire_ext_burst_cmd(self):
|
||||||
|
self._check_time_init()
|
||||||
if self._fire_ext_capacity > 0:
|
if self._fire_ext_capacity > 0:
|
||||||
self._fire_ext_capacity -= 1
|
self._fire_ext_capacity -= 1
|
||||||
return True
|
return True
|
||||||
@@ -43,47 +61,75 @@ class RobotController(object):
|
|||||||
|
|
||||||
# poses in [-1, 1] extra stuff will be cut
|
# poses in [-1, 1] extra stuff will be cut
|
||||||
def send_fire_ext_pose_cmd(self, horisontal_pose, vertical_pose):
|
def send_fire_ext_pose_cmd(self, horisontal_pose, vertical_pose):
|
||||||
|
self._check_time_init()
|
||||||
horisontal_pose = min(max(-1, horisontal_pose), 1)
|
horisontal_pose = min(max(-1, horisontal_pose), 1)
|
||||||
vertical_pose = min(max(-1, vertical_pose), 1)
|
vertical_pose = min(max(-1, vertical_pose), 1)
|
||||||
return horisontal_pose, vertical_pose
|
return horisontal_pose, vertical_pose
|
||||||
|
|
||||||
def send_pick_asset_cmd(self):
|
def send_pick_asset_cmd(self):
|
||||||
|
self._check_time_init()
|
||||||
raise NotImplemented("")
|
raise NotImplemented("")
|
||||||
|
|
||||||
def get_score(self, time_stamp = None):
|
def get_score(self, time_stamp = None):
|
||||||
score = self._k_sof * len(self._exted_sofs) + self._k_cas * len(self._found_casualty) + self._k_asset * len(self._found_assets) + self._k_hp * self._hit_points
|
score = self._k_sof * len(self._exted_sofs) + self._k_cas * len(self._found_casualty) + self._k_asset * len(self._found_assets) + self._k_hp * (self._hit_points/self._start_hp) + self._k_charge * (self._charge_points / self._start_charge)
|
||||||
return score
|
return score
|
||||||
|
|
||||||
def get_str_status(self):
|
def get_str_status(self):
|
||||||
status = f"{type(self).__name__}\n - Total score {self.get_score()}\n - Hit points: {self._hit_points}/{self._start_hp}\n - Extingushed sources of fire {len(self._exted_sofs)}\n - Fire extinguiher capacity {self._fire_ext_capacity}/{self._fire_ext_max_capacity}\n - Collisions {len(self._collisions)}\n - Falls {len(self._falls)}"
|
status = f"{type(self).__name__}\n - Total score {self.get_score()}\n - Hit points: {self._hit_points}/{self._start_hp}\n - Charge points {round(self._charge_points, 2)}\{self._start_charge}\n - Extingushed sources of fire {len(self._exted_sofs)}\n - Fire extinguiher capacity {self._fire_ext_capacity}/{self._fire_ext_max_capacity}\n - Collisions {len(self._collisions)}\n - Falls {len(self._falls)}"
|
||||||
return status
|
return status
|
||||||
|
|
||||||
def send_lights_cmd(self):
|
def send_lights_cmd(self):
|
||||||
pass
|
self._check_time_init()
|
||||||
|
|
||||||
|
|
||||||
def send_fall_reset_cmd(self):
|
def send_fall_reset_cmd(self):
|
||||||
pass
|
self._check_time_init()
|
||||||
|
|
||||||
|
|
||||||
|
def dump_stats(self, save_path = '/tmp'):
|
||||||
|
date = datetime.now().strftime("%d_%H:%M:%S")
|
||||||
|
stats = {"total_time": float(self._ts()),
|
||||||
|
"date": date,
|
||||||
|
"score": float(self.get_score()),
|
||||||
|
"status": self.get_str_status(),
|
||||||
|
"class": type(self).__name__,
|
||||||
|
"k_params": {k: v for k, v in vars(self).items() if k.startswith('_k_') and not callable(v)},
|
||||||
|
"exted_sofs": self._exted_sofs,
|
||||||
|
"collisions": self._collisions,
|
||||||
|
"falls": self._falls
|
||||||
|
}
|
||||||
|
|
||||||
|
path = save_path + f"/sirius_{date}.yaml"
|
||||||
|
with open(path, "w") as file:
|
||||||
|
yaml.dump(stats, file, default_flow_style=False, sort_keys=False)
|
||||||
|
return path
|
||||||
|
return ""
|
||||||
|
|
||||||
''' EVENTS '''
|
''' EVENTS '''
|
||||||
|
|
||||||
def _register_collision(self, time_stamp):
|
def _register_collision(self):
|
||||||
self._collisions.append(time_stamp)
|
self._collisions.append(self._ts())
|
||||||
self._hit_points = max(0, self._hit_points - self._collision_damage)
|
self._hit_points = max(0, self._hit_points - self._collision_damage)
|
||||||
|
|
||||||
def _register_exted_sof(self, time_stamp, sof_params = {}):
|
def _register_exted_sof(self, sof_params = {}):
|
||||||
self._exted_sofs.append((time_stamp,
|
self._exted_sofs.append((self._ts(),
|
||||||
copy.deepcopy(sof_params)))
|
copy.deepcopy(sof_params)))
|
||||||
|
|
||||||
def _register_found_casualty(self, time_stamp, casualty_params = {}):
|
def _register_found_casualty(self, casualty_params = {}):
|
||||||
self._found_casualty.append((time_stamp,
|
self._found_casualty.append((self._ts(),
|
||||||
copy.deepcopy(casualty_params)))
|
copy.deepcopy(casualty_params)))
|
||||||
|
|
||||||
def _register_found_assest(self, time_stamp, asset_params = {}):
|
def _register_found_assest(self, asset_params = {}):
|
||||||
self._found_assets.append((time_stamp,
|
self._found_assets.append((self._ts(),
|
||||||
copy.deepcopy(asset_params)))
|
copy.deepcopy(asset_params)))
|
||||||
|
|
||||||
def _register_fall(self, time_stamp):
|
def _register_fall(self):
|
||||||
self._falls.append(time_stamp)
|
self._falls.append(self._ts())
|
||||||
|
|
||||||
|
def _decrease_charge(self, speed, dt):
|
||||||
|
new_value = self._charge_points - speed * dt
|
||||||
|
self._charge_points = max(0, new_value)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user