efficient.py 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. ##################################################################
  4. #
  5. # Copyright (c) 2023 CICV, Inc. All Rights Reserved
  6. #
  7. ##################################################################
  8. """
  9. @Authors: xieguijin(xieguijin@china-icv.cn), yangzihao(yangzihao@china-icv.cn)
  10. @Data: 2023/08/03
  11. @Last Modified: 2023/08/03
  12. @Summary: Functionality metrics
  13. """
  14. import os
  15. import sys
  16. sys.path.append('../common')
  17. sys.path.append('../modules')
  18. sys.path.append('../results')
  19. import numpy as np
  20. import pandas as pd
  21. from data_info import DataInfoList
  22. from score_weight import cal_score_with_priority, cal_weight_from_80
  23. from common import score_grade, string_concatenate, replace_key_with_value
  24. import matplotlib.pyplot as plt
  25. class Efficient(object):
  26. """
  27. Class for achieving efficient metrics for autonomous driving.
  28. Attributes:
  29. df: Vehicle driving data, stored in dataframe format.
  30. """
  31. def __init__(self, data_processed, custom_data, scoreModel, resultPath):
  32. self.eval_data = pd.DataFrame()
  33. self.data_processed = data_processed
  34. self.scoreModel = scoreModel
  35. self.resultPath = resultPath
  36. self.data = data_processed.obj_data[1]
  37. self.mileage = data_processed.report_info['mileage']
  38. self.df = pd.DataFrame()
  39. self.speed_dict = dict()
  40. self.config = data_processed.config
  41. efficient_config = data_processed.efficient_config
  42. self.efficient_config = efficient_config
  43. # common data
  44. self.bulitin_metric_list = self.config.builtinMetricList
  45. # dimension data
  46. self.weight_custom = efficient_config['weightCustom']
  47. self.metric_list = efficient_config['metric']
  48. self.type_list = efficient_config['type']
  49. self.type_name_dict = efficient_config['typeName']
  50. self.name_dict = efficient_config['name']
  51. self.unit_dict = efficient_config['unit']
  52. # custom metric data
  53. self.customMetricParam = efficient_config['customMetricParam']
  54. self.custom_metric_list = list(self.customMetricParam.keys())
  55. self.custom_data = custom_data
  56. self.custom_param_dict = {}
  57. # score data
  58. self.weight = efficient_config['weightDimension']
  59. self.weight_type_dict = efficient_config['typeWeight']
  60. self.weight_type_list = efficient_config['typeWeightList']
  61. self.weight_dict = efficient_config['weight']
  62. self.weight_list = efficient_config['weightList']
  63. self.priority_dict = efficient_config['priority']
  64. self.priority_list = efficient_config['priorityList']
  65. self.kind_dict = efficient_config['kind']
  66. self.optimal_dict = efficient_config['optimal']
  67. self.multiple_dict = efficient_config['multiple']
  68. self.kind_list = efficient_config['kindList']
  69. self.optimal_list = efficient_config['optimalList']
  70. self.multiple_list = efficient_config['multipleList']
  71. # metric data
  72. self.metric_dict = efficient_config['typeMetricDict']
  73. self.drive_metric_list = self.metric_dict['efficientDrive']
  74. self.stop_metric_list = self.metric_dict['efficientStop']
  75. # self.drive_metric_list = ["averageSpeed"]
  76. # self.stop_metric_list = ["stopDuration", "stopCount"]
  77. self._get_data()
  78. self._effi_param_cal()
  79. self.time_list = self.data['simTime'].values.tolist()
  80. self.speed_list = list()
  81. self.value_dict = {}
  82. self.average_v = 0
  83. self.stop_count = 0
  84. self.stop_duration = 0
  85. self.sum_stop_time = 0
  86. self.pass_junction_time = 0
  87. self.score = 0
  88. def _get_data(self):
  89. """
  90. Get the data required for efficient evaluation according to efficient_INFO in DataInfoList.
  91. Parameters:
  92. df: Dataframe containing the vehicle running data.
  93. Returns:
  94. peak_valley: List of indices representing peaks and valleys.
  95. """
  96. efficient_info_list = DataInfoList.EFFICIENT_INFO
  97. self.df = self.data[efficient_info_list].copy()
  98. def _effi_param_cal(self):
  99. """
  100. """
  101. self.df = self.df[self.df['playerId'] == 1]
  102. # self.df = self.df[self.df['id'] == 1]
  103. # self.df['v'] = self.df.apply(lambda row: self.velocity(row['speed_x'], row['speed_y']), axis=1)
  104. # self.df['v'] = self.df.apply(lambda row: self.velocity(row['speedX'], row['speedY']), axis=1)
  105. def _cal_max_min_avg(self, num_list):
  106. maxx = max(num_list) if num_list else "-"
  107. minn = min(num_list) if num_list else "-"
  108. avg = sum(num_list) / len(num_list) if num_list else "-"
  109. result = {
  110. "max": maxx,
  111. "min": minn,
  112. "avg": avg
  113. }
  114. return result
  115. def average_velocity(self):
  116. """
  117. 1.速度的平均值
  118. 2.平均速度 = 里程/时间
  119. 速度不为0为开始时间,速度为0为结束时间
  120. """
  121. self.average_v = self.df['v'].mean()
  122. self.speed_list = self.df['v'].values.tolist()
  123. self.speed_dict = self._cal_max_min_avg(self.df['v'].dropna().values.tolist())
  124. def stop_duration_and_count(self):
  125. """
  126. 百公里停车次数
  127. 平均每次停车时长
  128. 驾照科目二考试判定为停车的标准:在考试项目区域内,汽车停顿2秒以上都算中途停车。
  129. """
  130. stop_v_threshold = 0.01
  131. stop_time_threshold = 0.5 # 12.5帧
  132. without_obstacle = self.df[self.df['obstacle'] == 0].copy()
  133. stop_time_list = without_obstacle[without_obstacle['v'] <= stop_v_threshold]['simTime'].values.tolist()
  134. # stop_time_list = self.df[self.df['v'] == 0]['simTime'].values.tolist()
  135. stop_frame_list = without_obstacle[without_obstacle['v'] <= stop_v_threshold]['simFrame'].values.tolist()
  136. # stop_frame_list = self.df[self.df['v'] == 0]['simFrame'].values.tolist()
  137. stop_frame_group = []
  138. stop_time_group = []
  139. f1 = stop_frame_list[0] if stop_frame_list else 0
  140. t1 = stop_time_list[0] if stop_time_list else 0
  141. sum_stop_time = 0
  142. for i in range(1, len(stop_frame_list)):
  143. if stop_frame_list[i] - stop_frame_list[i - 1] != 1:
  144. f2 = stop_frame_list[i - 1]
  145. # 当帧数大于13时才确定为停车
  146. # 当时长大于0.5s才确定为停车
  147. if f2 - f1 >= 13:
  148. t2 = stop_time_list[i - 1]
  149. stop_frame_group.append((f1, f2))
  150. stop_time_group.append((t1, t2))
  151. sum_stop_time += (t2 - t1)
  152. self.stop_count += 1
  153. # update f1, t1
  154. f1 = stop_frame_list[i]
  155. t1 = stop_time_list[i]
  156. f2 = stop_frame_list[-1] if stop_frame_list else 0
  157. # 如果最后一段的帧数差大于13,且停车统计列表中的最后一帧不为用例的最后一帧
  158. if f2 - f1 >= 13 and f2 != self.df['simFrame'].values.tolist()[-1]:
  159. t2 = stop_time_list[-1]
  160. stop_frame_group.append((f1, f2))
  161. stop_time_group.append((t1, t2))
  162. sum_stop_time += (t2 - t1)
  163. self.stop_count += 1
  164. self.sum_stop_time = sum_stop_time
  165. self.stop_duration = sum_stop_time / self.stop_count if self.stop_count != 0 else 0
  166. # self.stop_count = self.stop_count / self.mileage * 1000000
  167. def efficient_statistic(self):
  168. arr_effi = []
  169. self.average_velocity()
  170. self.stop_duration_and_count()
  171. if "averageSpeed" in self.metric_list:
  172. average_v = self.average_v
  173. arr_effi.append(average_v)
  174. self.value_dict["averageSpeed"] = average_v
  175. if "stopDuration" in self.metric_list:
  176. stop_duration = self.stop_duration
  177. arr_effi.append(stop_duration)
  178. self.value_dict["stopDuration"] = stop_duration
  179. if "stopCount" in self.metric_list:
  180. stop_count = self.stop_count
  181. arr_effi.append(stop_count)
  182. self.value_dict["stopCount"] = stop_count
  183. # arr_effi = [average_v, stop_count, stop_time]
  184. return arr_effi
  185. def custom_metric_param_parser(self, param_list):
  186. """
  187. param_dict = {
  188. "paramA" [
  189. {
  190. "kind": "-1",
  191. "optimal": "1",
  192. "multiple": ["0.5","5"],
  193. "spare1": null,
  194. "spare2": null
  195. }
  196. ]
  197. }
  198. """
  199. kind_list = []
  200. optimal_list = []
  201. multiple_list = []
  202. spare_list = []
  203. # spare1_list = []
  204. # spare2_list = []
  205. for i in range(len(param_list)):
  206. kind_list.append(int(param_list[i]['kind']))
  207. optimal_list.append(float(param_list[i]['optimal']))
  208. multiple_list.append([float(x) for x in param_list[i]['multiple']])
  209. spare_list.append([item["param"] for item in param_list[i]["spare"]])
  210. # spare1_list.append(param_list[i]['spare1'])
  211. # spare2_list.append(param_list[i]['spare2'])
  212. result = {
  213. "kind": kind_list,
  214. "optimal": optimal_list,
  215. "multiple": multiple_list,
  216. "spare": spare_list,
  217. # "spare1": spare1_list,
  218. # "spare2": spare2_list
  219. }
  220. return result
  221. def custom_metric_score(self, metric, value, param_list):
  222. """
  223. """
  224. param = self.custom_metric_param_parser(param_list)
  225. self.custom_param_dict[metric] = param
  226. score_model = self.scoreModel(param['kind'], param['optimal'], param['multiple'], np.array([value]))
  227. score_sub = score_model.cal_score()
  228. score = sum(score_sub) / len(score_sub)
  229. return score
  230. def effi_score(self):
  231. arr_effi = self.efficient_statistic()
  232. print("\n[高效性表现及得分情况]")
  233. print("高效性各指标值:", [round(num, 2) for num in arr_effi])
  234. arr_effi = np.array([arr_effi])
  235. score_model = self.scoreModel(self.kind_list, self.optimal_list, self.multiple_list, arr_effi)
  236. score_sub = score_model.cal_score()
  237. score_sub = list(map(lambda x: 80 if np.isnan(x) else x, score_sub))
  238. score_metric = [round(num, 2) for num in score_sub]
  239. metric_list = [x for x in self.metric_list if x in self.config.builtinMetricList]
  240. score_metric_dict = {key: value for key, value in zip(metric_list, score_metric)}
  241. custom_metric_list = list(self.customMetricParam.keys())
  242. for metric in custom_metric_list:
  243. value = self.custom_data[metric]['value']
  244. param_list = self.customMetricParam[metric]
  245. score = self.custom_metric_score(metric, value, param_list)
  246. score_metric_dict[metric] = round(score, 2)
  247. score_metric_dict = {key: score_metric_dict[key] for key in self.metric_list}
  248. score_metric = list(score_metric_dict.values())
  249. score_type_dict = {}
  250. if self.weight_custom: # 自定义权重
  251. score_metric_with_weight_dict = {key: score_metric_dict[key] * self.weight_dict[key] for key in
  252. self.weight_dict}
  253. for type in self.type_list:
  254. type_score = sum(
  255. value for key, value in score_metric_with_weight_dict.items() if key in self.metric_dict[type])
  256. score_type_dict[type] = round(type_score, 2)
  257. score_type_with_weight_dict = {key: score_type_dict[key] * self.weight_type_dict[key] for key in
  258. score_type_dict}
  259. score_efficient = sum(score_type_with_weight_dict.values())
  260. else: # 客观赋权
  261. self.weight_list = cal_weight_from_80(score_metric)
  262. self.weight_dict = {key: value for key, value in zip(self.metric_list, self.weight_list)}
  263. score_efficient = cal_score_with_priority(score_metric, self.weight_list, self.priority_list)
  264. for type in self.type_list:
  265. type_weight = sum(value for key, value in self.weight_dict.items() if key in self.metric_dict[type])
  266. self.weight_dict = {key: round(value / type_weight, 4) for key, value in self.weight_dict.items() if
  267. key in self.metric_dict[type]}
  268. type_score_metric = [value for key, value in score_metric_dict.items() if key in self.metric_dict[type]]
  269. type_weight_list = [value for key, value in self.weight_dict.items() if key in self.metric_dict[type]]
  270. type_priority_list = [value for key, value in self.priority_dict.items() if
  271. key in self.metric_dict[type]]
  272. type_score = cal_score_with_priority(type_score_metric, type_weight_list, type_priority_list)
  273. score_type_dict[type] = round(type_score, 2)
  274. score_efficient = round(score_efficient, 2)
  275. print("高效性各指标基准值:", self.optimal_list)
  276. print(f"高效性得分为:{score_efficient:.2f}分。")
  277. print(f"高效性各类型得分为:{score_type_dict}。")
  278. print(f"高效性各指标得分为:{score_metric_dict}。")
  279. return score_efficient, score_type_dict, score_metric_dict
  280. def effi_weight_distribution(self):
  281. # get weight distribution
  282. weight_distribution = {}
  283. weight_distribution["name"] = "高效性"
  284. if "efficientDrive" in self.type_list:
  285. drive_weight_indexes_dict = {key: f"{key}({value * 100:.2f}%)" for key, value in self.weight_dict.items() if
  286. key in self.drive_metric_list}
  287. weight_distribution_drive = {
  288. "driveWeight": f"行驶({self.weight_type_dict['efficientDrive'] * 100:.2f}%)",
  289. "indexes": drive_weight_indexes_dict
  290. }
  291. weight_distribution['efficientDrive'] = weight_distribution_drive
  292. if "efficientStop" in self.type_list:
  293. stop_weight_indexes_dict = {key: f"{key}({value * 100:.2f}%)" for key, value in self.weight_dict.items() if
  294. key in self.stop_metric_list}
  295. weight_distribution_stop = {
  296. "stopWeight": f"停车({self.weight_type_dict['efficientStop'] * 100:.2f}%)",
  297. "indexes": stop_weight_indexes_dict
  298. }
  299. weight_distribution['efficientStop'] = weight_distribution_stop
  300. return weight_distribution
  301. def _get_weight_distribution(self, dimension):
  302. # get weight distribution
  303. weight_distribution = {}
  304. weight_distribution["name"] = self.config.dimension_name[dimension]
  305. for type in self.type_list:
  306. type_weight_indexes_dict = {key: f"{self.name_dict[key]}({value * 100:.2f}%)" for key, value in
  307. self.weight_dict.items() if
  308. key in self.metric_dict[type]}
  309. weight_distribution_type = {
  310. "weight": f"{self.type_name_dict[type]}({self.weight_type_dict[type] * 100:.2f}%)",
  311. "indexes": type_weight_indexes_dict
  312. }
  313. weight_distribution[type] = weight_distribution_type
  314. return weight_distribution
  315. def report_statistic(self):
  316. """
  317. Returns:
  318. """
  319. # report_dict = {
  320. # "name": "高效性",
  321. # "weight": f"{self.weight * 100:.2f}%",
  322. # "weightDistribution": weight_distribution,
  323. # "score": score_efficient,
  324. # "level": grade_efficient,
  325. # 'score_type': score_type,
  326. # 'score_metric': score_metric,
  327. #
  328. # "description1": effi_description1,
  329. # "description2": effi_description2,
  330. # "description3": effi_description3,
  331. #
  332. # "efficientDrive": drive_dict,
  333. # "efficientStop": stop_dict,
  334. # }
  335. # brakePedal_list = self.data_processed.driver_ctrl_data['brakePedal_list']
  336. # throttlePedal_list = self.data_processed.driver_ctrl_data['throttlePedal_list']
  337. # steeringWheel_list = self.data_processed.driver_ctrl_data['steeringWheel_list']
  338. #
  339. # # common parameter calculate
  340. # brake_vs_time = self.zip_time_pairs(brakePedal_list, 100)
  341. # throttle_vs_time = self.zip_time_pairs(throttlePedal_list, 100)
  342. # steering_vs_time = self.zip_time_pairs(steeringWheel_list)
  343. report_dict = {
  344. "name": "高效性",
  345. # "weight": f"{self.weight * 100:.2f}%",
  346. }
  347. # len_time = len(self.time_list)
  348. # duration = self.time_list[-1]
  349. # duration_minute = round(duration / 60, 2)
  350. score_efficient, score_type_dict, score_metric_dict = self.effi_score()
  351. # get weight distribution
  352. # report_dict["weightDistribution"] = self._get_weight_distribution("efficient")
  353. # score_efficient, score_metric = self.effi_score()
  354. score_efficient = int(score_efficient) if int(score_efficient) == score_efficient else round(score_efficient, 2)
  355. grade_efficient = score_grade(score_efficient)
  356. report_dict["score"] = score_efficient
  357. report_dict["level"] = grade_efficient
  358. # for description
  359. # good_type_list = []
  360. # bad_type_list = []
  361. # good_metric_list = []
  362. # bad_metric_list = []
  363. # str for description
  364. # str_over_optimal = ""
  365. # type_details_dict = {}
  366. # for type in self.type_list:
  367. # bad_type_list.append(type) if score_type_dict[type] < 80 else good_type_list.append(type)
  368. #
  369. # type_dict = {
  370. # "name": type,
  371. # }
  372. #
  373. # builtin_graph_dict = {}
  374. # custom_graph_dict = {}
  375. #
  376. # score_type = score_type_dict[type]
  377. # grade_type = score_grade(score_type)
  378. # type_dict["score"] = score_type
  379. # type_dict["level"] = grade_type
  380. #
  381. # type_dict_indexes = {}
  382. # for metric in self.metric_dict[type]:
  383. # bad_metric_list.append(metric) if score_metric_dict[metric] < 80 else good_metric_list.append(metric)
  384. #
  385. # if metric in self.bulitin_metric_list:
  386. # # for indexes
  387. # type_dict_indexes[metric] = {
  388. # "name": f"{self.name_dict[metric]}({self.unit_dict[metric]})",
  389. # "score": score_metric_dict[metric],
  390. # "value": f'{self.value_dict[metric]:.2f}',
  391. # # "range": f"[0, {self.optimal_dict['averageSpeed']})",
  392. # # "deviation": f"+{avv_deviation:.2f}%" if avv_deviation > 0 else f"{avv_deviation:.2f}%"
  393. # }
  394. #
  395. # if self.kind_dict[metric] == -1:
  396. # type_dict_indexes[metric]["range"] = f"[0, {self.optimal_dict[metric]}]"
  397. # metric_over_optimal = ((self.value_dict[metric] - self.optimal_dict[metric]) /
  398. # self.optimal_dict[
  399. # metric]) * 100
  400. # type_dict_indexes[metric][
  401. # "deviation"] = f"+{metric_over_optimal:.2f}%" if metric_over_optimal > 0 else f"0%"
  402. #
  403. # elif self.kind_dict[metric] == 1:
  404. # type_dict_indexes[metric]["range"] = f"[{self.optimal_dict[metric]}, inf)"
  405. # metric_over_optimal = ((self.value_dict[metric] - self.optimal_dict[metric]) /
  406. # self.optimal_dict[
  407. # metric]) * 100
  408. # type_dict_indexes[metric][
  409. # "deviation"] = f"0%" if metric_over_optimal > 0 else f"{metric_over_optimal:.2f}%"
  410. #
  411. # elif self.kind_dict[metric] == 0:
  412. # value = self.value_dict[metric]
  413. # minn = self.optimal_dict[metric] * self.multiple_dict[metric][0]
  414. # maxx = self.optimal_dict[metric] * self.multiple_dict[metric][1]
  415. #
  416. # type_dict_indexes[metric]["range"] = f"[{minn}, {maxx}]"
  417. #
  418. # if value < minn:
  419. # metric_over_optimal = (value - minn) / minn * 100
  420. # elif value > maxx:
  421. # metric_over_optimal = (value - maxx) / maxx * 100
  422. # else:
  423. # metric_over_optimal = 0
  424. #
  425. # type_dict_indexes[metric][
  426. # "deviation"] = f"+{metric_over_optimal:.2f}%" if metric_over_optimal > 0 else f"{metric_over_optimal:.2f}%"
  427. #
  428. # # metric_over_optimal = ((self.value_dict[metric] - self.optimal_dict[metric]) / self.optimal_dict[
  429. # # metric]) * 100
  430. # # type_dict_indexes[metric][
  431. # # "deviation"] = f"+{metric_over_optimal:.2f}%" if metric_over_optimal > 0 else f"{metric_over_optimal:.2f}%"
  432. #
  433. # if score_metric_dict[metric] < 80:
  434. # str_over_optimal += f'{self.name_dict[metric]}为{round(self.value_dict[metric], 2)}{self.unit_dict[metric]},超过合理范围{metric_over_optimal}%;'
  435. #
  436. # else:
  437. # # for indexes
  438. # type_dict_indexes[metric] = {
  439. # "name": f"{self.name_dict[metric]}({self.unit_dict[metric]})",
  440. # "score": score_metric_dict[metric],
  441. # "value": f'{self.custom_data[metric]["value"][0]:.2f}',
  442. # # "range": f"[0, {self.optimal_dict['averageSpeed']})",
  443. # # "deviation": f"+{avv_deviation}%" if avv_deviation > 0 else f"{avv_deviation}%"
  444. # }
  445. #
  446. # value = self.custom_data[metric]["value"][0]
  447. # optimal = self.custom_param_dict[metric]['optimal'][0]
  448. #
  449. # if self.custom_param_dict[metric]['kind'][0] == -1:
  450. # type_dict_indexes[metric][
  451. # "range"] = f"[0, {self.custom_param_dict[metric]['optimal'][0]}]"
  452. #
  453. # metric_over_optimal = (value - optimal) / optimal * 100
  454. # type_dict_indexes[metric][
  455. # "deviation"] = f"+{metric_over_optimal:.2f}%" if metric_over_optimal > 0 else f"0%"
  456. #
  457. # elif self.custom_param_dict[metric]['kind'][0] == 1:
  458. # type_dict_indexes[metric][
  459. # "range"] = f"[{self.custom_param_dict[metric]['optimal'][0]}, inf)"
  460. #
  461. # metric_over_optimal = (value - optimal) / optimal * 100
  462. # type_dict_indexes[metric][
  463. # "deviation"] = f"0%" if metric_over_optimal > 0 else f"{metric_over_optimal:.2f}%"
  464. #
  465. # elif self.custom_param_dict[metric]['kind'][0] == 0:
  466. # minn = value * self.custom_param_dict[metric]['multiple'][0][0]
  467. # maxx = value * self.custom_param_dict[metric]['multiple'][0][1]
  468. #
  469. # type_dict_indexes[metric]["range"] = f"[{minn}, {maxx}]"
  470. #
  471. # if value < minn:
  472. # metric_over_optimal = (value - minn) / minn * 100
  473. # elif value > maxx:
  474. # metric_over_optimal = (value - maxx) / maxx * 100
  475. # else:
  476. # metric_over_optimal = 0
  477. #
  478. # type_dict_indexes[metric][
  479. # "deviation"] = f"+{metric_over_optimal:.2f}%" if metric_over_optimal > 0 else f"{metric_over_optimal:.2f}%"
  480. #
  481. # # metric_over_optimal = ((self.custom_param_dict[metric]['optimal'][0] -
  482. # # self.custom_data[metric]["value"][0]) /
  483. # # self.custom_param_dict[metric]['optimal'][0]) * 100
  484. # # type_dict_indexes[metric][
  485. # # "deviation"] = f"+{metric_over_optimal:.2f}%" if metric_over_optimal > 0 else f"{metric_over_optimal:.2f}%"
  486. #
  487. # if score_metric_dict[metric] < 80:
  488. # str_over_optimal += f'{self.name_dict[metric]}为{self.custom_data[metric]["value"][0]:.2f}{self.unit_dict[metric]},超过合理范围{metric_over_optimal}%;'
  489. #
  490. # custom_graph_dict[metric] = self.custom_data[metric]['reportData']
  491. #
  492. # # str_uncomf_over_optimal = str_uncomf_over_optimal[:-1] + ";"
  493. # type_dict["indexes"] = type_dict_indexes
  494. # type_dict["builtin"] = builtin_graph_dict
  495. # type_dict["custom"] = custom_graph_dict
  496. #
  497. # type_details_dict[type] = type_dict
  498. # report_dict["details"] = type_details_dict
  499. # efficient description
  500. # str_over_optimal = str_over_optimal[:-1]
  501. # if grade_efficient == '优秀':
  502. # effi_description1 = '机器人行驶效率高;'
  503. # elif grade_efficient == '良好':
  504. # effi_description1 = '机器人在本轮测试中的表现满足设计指标要求;'
  505. # elif grade_efficient == '一般':
  506. # str_ineffi_type = string_concatenate(bad_metric_list)
  507. # effi_description1 = f'机器人需要在{str_ineffi_type}指标上进一步优化。其中,{str_over_optimal};'
  508. # elif grade_efficient == '较差':
  509. # str_ineffi_type = string_concatenate(bad_metric_list)
  510. # effi_description1 = f'需要提高机器人在{str_ineffi_type}指标上的表现。其中,{str_over_optimal};'
  511. #
  512. # if not bad_metric_list:
  513. # effi_description2 = '高效性在各个指标上的表现俱佳'
  514. # effi_description3 = "机器人的规划控制能力良好,通行效率高"
  515. # else:
  516. # str_effi_type = string_concatenate(good_metric_list)
  517. # str_ineffi_type = string_concatenate(bad_metric_list)
  518. #
  519. # effi_description2 = f"{str_effi_type}指标表现良好,{str_ineffi_type}指标表现不佳。其中,{str_over_optimal}"
  520. # effi_description3 = "应该优化机器人的规划控制逻辑,提高机器人的通行效率"
  521. # report_dict["description1"] = replace_key_with_value(effi_description1, self.name_dict)
  522. # report_dict["description2"] = replace_key_with_value(effi_description2, self.name_dict)
  523. # report_dict["description3"] = effi_description3
  524. description = "· 在高效性方面,"
  525. if self.stop_count > 0:
  526. description += f"出现{self.stop_count}次无障碍物停止,需重点优化。"
  527. else:
  528. description += f"平均速度{self.speed_dict['avg']:.4f}m/s,未出现无障碍物停止,表现{grade_efficient}。"
  529. report_dict["description"] = description
  530. description1 = f"次数:{self.stop_count}次;" \
  531. f"总时长:{self.sum_stop_time:.4f}s;" \
  532. f"平均时长:{self.stop_duration:.4f}s"
  533. description2 = f"最大值:{self.speed_dict['max']:.4f}m/s;" \
  534. f"最小值:{self.speed_dict['min']:.4f}m/s;" \
  535. f"平均值:{self.speed_dict['avg']:.4f}m/s"
  536. report_dict["description1"] = description1
  537. report_dict["description2"] = description2
  538. plt.figure(figsize=(12, 3))
  539. plt.plot(self.time_list, self.speed_list, label='Speed')
  540. plt.xlabel('Time(s)')
  541. plt.ylabel('Speed(m/s)')
  542. plt.legend()
  543. # 调整布局,消除空白边界
  544. plt.tight_layout()
  545. plt.savefig(os.path.join(self.resultPath, "Speed.png"))
  546. plt.close()
  547. print(report_dict)
  548. return report_dict
  549. def get_eval_data(self):
  550. df = self.eval_data
  551. return df