ICA_0702(1).py 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011
  1. import pandas as pd
  2. import numpy as np
  3. class ICA:
  4. def __init__(self, df):
  5. self.df = df #object_df
  6. self.segmented_data = []
  7. """
  8. 注释:zhangyu 0626 新增
  9. """
  10. self.roadPos_df = None
  11. self.roadMark_df = None
  12. """
  13. 纵向指标
  14. """
  15. self.stable_start_time_cruise = None
  16. self.stable_average_speed = None
  17. self.percentage_accel = None
  18. self.percentage_lon_acc_roc = None
  19. self.delay_time_cruise = None
  20. self.delay_time_THW = None
  21. self.rise_time_cruise = None
  22. self.rise_time_THW = None
  23. self.peak_time_cruise = None
  24. self.peak_time_THW = None
  25. self.overshoot_cruise = None
  26. self.overshoot_THW = None
  27. self.settling_time = None
  28. self.steady_error_cruise = None
  29. self.steady_error_THW = None
  30. self.stable_start_time_THW = None
  31. self.stable_average_THW = None
  32. """
  33. 横向指标
  34. """
  35. self.lateral_control01_minimum_distance_nearby_lane = None
  36. self.lateral_control02_maximum_lateral_offset = None
  37. self.lateral_control03_relative_lateral_offset_distribution_expectation = None
  38. self.lateral_control04_relative_lateral_offset_distribution_standard_deviation = None
  39. self.lateral_control05_absolute_lateral_offset_distribution_expectation = None
  40. self.lateral_control06_absolute_lateral_offset_distribution_standard_deviation = None
  41. self.lateral_control07_maximum_lateral_deviation = None
  42. self.lateral_control08_minimum_lateral_deviation = None
  43. self.lateral_control09_absolute_position_oscillation_frequency = None
  44. self.lateral_control10_absolute_position_oscillation_difference = None
  45. self.lateral_control11_maximum_heading_deviation = None
  46. self.lateral_control12_relative_position_oscillation_frequency = None
  47. self.lateral_control13_relative_position_oscillation_difference = None
  48. def _segment_data_by_status(self, status_name, status_value):
  49. """
  50. 根据状态名称和状态值对DataFrame中的数据进行分段处理。
  51. Args:
  52. status_name (str): DataFrame中用于标识状态的列名。
  53. status_value (Any): 需要进行分段处理的状态值。
  54. Returns:
  55. None
  56. Raises:
  57. KeyError: 如果DataFrame中不存在'ACC_status'或'simTime'列时,抛出KeyError异常。
  58. """
  59. if 'ACC_status' not in self.df.columns:
  60. raise KeyError("'ACC_status' column not found in the dataframe.")
  61. if 'simTime' not in self.df.columns:
  62. raise KeyError("'simTime' column not found in the dataframe.")
  63. filtered_data = self.df[self.df[status_name] == status_value]
  64. current_segment = []
  65. for index, row in filtered_data.iterrows():
  66. if not current_segment or abs(float(row['simTime']) - float(current_segment[-1]['simTime'])) <= 0.01:
  67. current_segment.append(row)
  68. else:
  69. self.segmented_data.append(pd.DataFrame(current_segment))
  70. current_segment = [row]
  71. if current_segment:
  72. self.segmented_data.append(pd.DataFrame(current_segment))
  73. def _get_headway_time(self, df):
  74. pass
  75. def _find_stable_speed_cruise(self, window_size, percent_deviation, set_value):
  76. """
  77. 在给定的速度数据中查找稳定的巡航速度段,并计算该段的平均速度。
  78. Args:
  79. window_size (int): 滑动窗口的大小,表示用于计算平均速度的速度数据点数量。
  80. percent_deviation (float): 设定值的允许偏差百分比。
  81. set_value (float): 期望的稳定速度设定值。
  82. Returns:
  83. None
  84. """
  85. speed_data = self.df['speedX'].values
  86. deviation = set_value * (percent_deviation / 100)
  87. stable_start = None
  88. stable_average_speed = None
  89. for i in range(len(speed_data) - window_size + 1):
  90. window_data = speed_data[i:i + window_size]
  91. if all(set_value - deviation <= s <= set_value + deviation for s in window_data):
  92. if stable_start is None:
  93. stable_start = i
  94. stable_end = i + window_size - 1
  95. stable_average_speed = np.mean(window_data)
  96. j = i + window_size
  97. while j < len(speed_data) - window_size + 1:
  98. next_window_data = speed_data[j:j + window_size]
  99. if all(set_value - deviation <= s <= set_value + deviation for s in next_window_data):
  100. stable_end = j + window_size - 1
  101. stable_average_speed = (stable_average_speed * (j - stable_start) + sum(next_window_data)) / (
  102. j - stable_start + window_size)
  103. j += window_size
  104. else:
  105. stable_start = j + window_size - 1
  106. stable_end = i + window_size - 1
  107. stable_average_speed = np.mean(window_data)
  108. break
  109. self.stable_start_time_cruise = self.df['simTime'].iloc[stable_start]
  110. self.stable_average_speed = stable_average_speed
  111. def _find_stable_THW(self, window_size, percent_deviation, set_value):
  112. """
  113. 在给定的数据窗口中查找稳定跟车时距离THW,并计算该段内THW的平均值。
  114. Args:
  115. window_size (int): 窗口大小,表示在数据中寻找稳定段时考虑的连续数据点数量。
  116. percent_deviation (float): THW值相对于设定值的允许偏差百分比。
  117. set_value (float): THW的设定值。
  118. Returns:
  119. None
  120. """
  121. THW = self.df['THW'].values
  122. deviation = set_value * (percent_deviation / 100)
  123. stable_start = None
  124. stable_average_THW = None
  125. for i in range(len(THW) - window_size + 1):
  126. window_data = THW[i:i + window_size]
  127. if all(set_value - deviation <= s <= set_value + deviation for s in window_data):
  128. if stable_start is None:
  129. stable_start = i
  130. stable_end = i + window_size - 1
  131. stable_average_THW = np.mean(window_data)
  132. j = i + window_size
  133. while j < len(THW) - window_size + 1:
  134. next_window_data = THW[j:j + window_size]
  135. if all(set_value - deviation <= s <= set_value + deviation for s in next_window_data):
  136. stable_end = j + window_size - 1
  137. stable_average_THW = (stable_average_THW * (j - stable_start) + sum(next_window_data)) / (
  138. j - stable_start + window_size)
  139. j += window_size
  140. else:
  141. stable_start = j + window_size - 1
  142. stable_end = i + window_size - 1
  143. stable_average_THW = np.mean(window_data)
  144. break
  145. self.stable_start_time_THW = self.df['simTime'].iloc[stable_start]
  146. self.stable_average_THW = stable_average_THW
  147. def _find_closest_time_stamp_cruise(self, df, target_speed, start_index):
  148. """
  149. 在给定的数据帧df中,从start_index索引位置开始,查找与目标速度target_speed最接近的时间戳。
  150. Args:
  151. df (pd.DataFrame): 包含速度和时间戳等信息的数据帧,需要至少包含'speedX'和'simTime'两列。
  152. target_speed (float): 目标速度值,用于在数据帧中查找最接近此值的时间戳。
  153. start_index (int): 开始查找的索引位置,即在数据帧df中从该索引位置开始向后查找。
  154. Returns:
  155. pd.Timestamp: 与目标速度最接近的时间戳。
  156. """
  157. subset = df.loc[start_index + 1:]
  158. speed_diff = np.abs(subset['speedX'] - target_speed)
  159. closest_index = speed_diff.idxmin()
  160. closest_timestamp = subset.loc[closest_index, 'simTime']
  161. return closest_timestamp
  162. def _find_closest_time_stamp_THW(self, df, target_THW, start_index):
  163. """
  164. 在DataFrame中找到与目标THW值最接近的时间戳。
  165. Args:
  166. df (pandas.DataFrame): 包含'THW'和'simTime'列的DataFrame,其中'THW'表示目标变量,'simTime'表示时间戳。
  167. target_THW (float): 目标THW值。
  168. start_index (int): 开始搜索的索引位置(不包含)。
  169. Returns:
  170. pandas.Timestamp: 与目标THW值最接近的时间戳。
  171. """
  172. subset = df.loc[start_index + 1:]
  173. THW_diff = np.abs(subset['THW'] - target_THW)
  174. closest_index = THW_diff.idxmin()
  175. closest_timestamp = subset.loc[closest_index, 'simTime']
  176. return closest_timestamp
  177. def _get_first_change_index_cruise(self):
  178. """
  179. 获取数据集中第一次巡航速度发生变化的索引。
  180. Args:
  181. 无参数。
  182. Returns:
  183. Union[int, None]: 如果存在巡航速度发生变化的索引,则返回第一个发生变化的索引(int类型);
  184. 如果不存在,则返回None。
  185. """
  186. change_indices = self.df[self.df['set_cruise_speed'] != self.df['set_cruise_speed'].shift()].index
  187. if not change_indices.empty:
  188. first_change_index = change_indices.min()
  189. else:
  190. first_change_index = None
  191. return first_change_index
  192. def _get_first_change_index_THW(self):
  193. """
  194. 获取DataFrame中'set_headway_time'列首次发生变化的索引值。
  195. Args:
  196. 无参数。
  197. Returns:
  198. Union[int, None]: 如果存在变化,则返回首次发生变化的索引值(int类型),否则返回None。
  199. """
  200. change_indices = self.df[self.df['set_headway_time'] != self.df['set_headway_time'].shift()].index
  201. if not change_indices.empty:
  202. first_change_index = change_indices.min()
  203. else:
  204. first_change_index = None
  205. return first_change_index
  206. def calculate_reasonable_acceleration_percentage(self):
  207. """
  208. 计算合理的加速度百分比。
  209. Args:
  210. 无。
  211. Returns:
  212. 无返回值,但会更新对象的 percentage_accel 属性,表示合理的加速度百分比(单位:%)。
  213. """
  214. df = self.df_follow.copy()
  215. col_list = ['simTime', 'simFrame', 'playerId', 'v', 'accel', 'accel', 'lon_acc_roc'] # target_id
  216. df = df[col_list].copy()
  217. count_accel_in_range = 0
  218. total_accel_frames = 0
  219. ego_df = df[df['playerId'] == 1][['simTime', 'simFrame', 'v', 'accel', 'lon_acc_roc']]
  220. for row in self.segmented_data:
  221. df = row[col_list].copy()
  222. filtered_data = df[(df['accel'] >= -5) & (df['accel'] <= 4)]
  223. count_accel_in_range = count_accel_in_range + len(filtered_data)
  224. total_accel_frames = total_accel_frames + len(df)
  225. self.percentage_accel = (count_accel_in_range / total_accel_frames) * 100
  226. print(f"percentage_accel: {self.percentage_accel}")
  227. def calculate_reasonable_acceleration_change_rate_percentage(self):
  228. """
  229. 计算纵向加速度变化率(lon_acc_roc)的合理变化率百分比。
  230. Args:
  231. 无参数。
  232. Returns:
  233. 无返回值,但会更新对象的 percentage_lon_acc_roc 属性。
  234. """
  235. df = self.df_follow.copy()
  236. col_list = ['simTime', 'simFrame', 'playerId', 'v', 'accel', 'accel', 'lon_acc_roc'] # target_id
  237. df = df[col_list].copy()
  238. count_lon_acc_roc_in_range = 0
  239. total_lon_acc_roc_frames = 0
  240. for row in self.segmented_data:
  241. df = row[col_list].copy()
  242. filtered_data = df[(df['lon_acc_roc'] >= -5) & (df['lon_acc_roc'] <= 6)]
  243. count_lon_acc_roc_in_range = count_lon_acc_roc_in_range + len(filtered_data)
  244. total_lon_acc_roc_frames = total_lon_acc_roc_frames + len(df)
  245. self.percentage_lon_acc_roc = (count_lon_acc_roc_in_range / total_lon_acc_roc_frames) * 100
  246. def get_delay_time_cruise(self):
  247. """
  248. 计算巡航速度改变后的延迟时间。
  249. Args:
  250. 无。
  251. Returns:
  252. 无返回值,但会设置self.delay_time为计算得到的延迟时间(秒)。
  253. Raises:
  254. 无特定异常,但会捕获并打印任何发生的异常信息。
  255. """
  256. try:
  257. change_indices = self.df[self.df['set_cruise_speed'] != self.df['set_cruise_speed'].shift()].index
  258. print(f"Change indices of set speed: {change_indices}")
  259. if not change_indices.empty:
  260. first_change_index = change_indices[change_indices != 0].min()
  261. set_cruise_speed_at_change = self.df.loc[first_change_index, 'set_cruise_speed']
  262. timestamp_at_change = self.df.loc[first_change_index, 'simTime']
  263. print(f"Set speed at first change: {set_cruise_speed_at_change}, Timestamp: {timestamp_at_change}")
  264. target_speed = (self.stable_average_speed + self.df.loc[first_change_index, 'speedX']) / 2
  265. closest_index = (self.df['speedX'] - target_speed).abs().idxmin()
  266. closest_current_speed = self.df.loc[closest_index, 'speedX']
  267. closest_timestamp = self.df.loc[closest_index, 'simTime']
  268. print(f"Closest speed: {closest_current_speed} at time: {closest_timestamp}")
  269. self.delay_time_cruise = closest_timestamp - timestamp_at_change
  270. print(f"Delay time: {self.delay_time_cruise}")
  271. else:
  272. print("No valid change point for further calculation.")
  273. except Exception as e:
  274. print(f"An error occurred: {e}")
  275. def get_delay_time_THW(self):
  276. """
  277. 计算THW改变后的延迟时间。
  278. Args:
  279. 无。
  280. Returns:
  281. 无返回值,但会设置self.delay_time为计算得到的延迟时间(秒)。
  282. Raises:
  283. 无特定异常,但会捕获并打印任何发生的异常信息。
  284. """
  285. try:
  286. change_indices = self.df[self.df['set_headway_time'] != self.df['set_headway_time'].shift()].index
  287. print(f"Change indices of set speed: {change_indices}")
  288. if not change_indices.empty:
  289. first_change_index = change_indices[change_indices != 0].min()
  290. set_THW_at_change = self.df.loc[first_change_index, 'set_headway_time']
  291. timestamp_at_change = self.df.loc[first_change_index, 'simTime']
  292. print(f"Set THW at first change: {set_THW_at_change}, Timestamp: {timestamp_at_change}")
  293. target_THW = (self.stable_average_THW + self.df.loc[first_change_index, 'set_headway_time']) / 2
  294. closest_index = (self.df['set_headway_time'] - target_THW).abs().idxmin()
  295. closest_current_THW = self.df.loc[closest_index, 'set_headway_time']
  296. closest_timestamp = self.df.loc[closest_index, 'simTime']
  297. print(f"Closest speed: {closest_current_THW} at time: {closest_timestamp}")
  298. self.delay_time_THW = closest_timestamp - timestamp_at_change
  299. print(f"Delay time: {self.delay_time_THW}")
  300. else:
  301. print("No valid change point for further calculation.")
  302. except Exception as e:
  303. print(f"An error occurred: {e}")
  304. def get_rise_time_cruise(self):
  305. """
  306. 计算巡航时从初速度到达稳定平均速度的90%的所需时间(rise time)。
  307. Args:
  308. 无。
  309. Returns:
  310. 无返回值,但会设置实例属性self.rise_time为计算得到的rise time。
  311. """
  312. first_change_index = self._get_first_change_index_cruise()
  313. initial_speed = self.df.loc[first_change_index, 'speedX']
  314. target_speed_90 = initial_speed + (self.stable_average_speed - initial_speed) * 0.9
  315. target_speed_10 = initial_speed + (self.stable_average_speed - initial_speed) * 0.1
  316. timestamp_at_10 = self._find_closest_time_stamp_cruise(self.df, target_speed_10, first_change_index)
  317. timestamp_at_90 = self._find_closest_time_stamp_cruise(self.df, target_speed_90, first_change_index)
  318. print(f"Closest speed at 10% range from set speed: {timestamp_at_10}")
  319. print(f"Closest speed at 90% range from set speed: {timestamp_at_90}")
  320. self.rise_time_cruise = timestamp_at_90 - timestamp_at_10
  321. print(f"Rise time: {self.rise_time_cruise}")
  322. def get_rise_time_THW(self):
  323. """
  324. 计算巡航时从初THW到达稳定THW的90%的所需时间(rise time)。
  325. Args:
  326. 无。
  327. Returns:
  328. 无返回值,但会设置实例属性self.rise_time_THW为计算得到的rise time。
  329. """
  330. first_change_index = self._get_first_change_index_THW()
  331. initial_THW = self.df.loc[first_change_index, 'THW']
  332. target_THW_90 = initial_THW + (self.stable_average_THW - initial_THW) * 0.9
  333. target_THW_10 = initial_THW + (self.stable_average_THW - initial_THW) * 0.1
  334. timestamp_at_10 = self._find_closest_time_stamp_THW(self.df, target_THW_10, first_change_index)
  335. timestamp_at_90 = self._find_closest_time_stamp_THW(self.df, target_THW_90, first_change_index)
  336. print(f"Closest speed at 10% range from set speed: {timestamp_at_10}")
  337. print(f"Closest speed at 90% range from set speed: {timestamp_at_90}")
  338. self.rise_time_THW = timestamp_at_90 - timestamp_at_10
  339. print(f"Rise time: {self.rise_time_THW}")
  340. def get_peak_time_cruise(self):
  341. """
  342. 计算巡航阶段速度峰值时间。
  343. Args:
  344. 无。
  345. Returns:
  346. 无返回值,但将计算得到的巡航阶段速度峰值时间(从首次变化时间开始计时)存储在实例变量 self.peak_time 中。
  347. """
  348. first_change_index = self._get_first_change_index_cruise()
  349. start_time = self.df.loc[first_change_index, 'simTime']
  350. peak_time = self.df.loc[self.df['speedX'].idxmax(), 'simTime']
  351. self.peak_time_cruise = peak_time - start_time
  352. def get_peak_time_THW(self):
  353. """
  354. 计算THW阶段速度峰值时间。
  355. Args:
  356. 无。
  357. Returns:
  358. 无返回值,但将计算得到的巡航阶段速度峰值时间(从首次变化时间开始计时)存储在实例变量 self.peak_time 中。
  359. """
  360. first_change_index = self._get_first_change_index_THW()
  361. start_time = self.df.loc[first_change_index, 'simTime']
  362. peak_time = self.df.loc[self.df['THW'].idxmax(), 'simTime']
  363. self.peak_time_THW = peak_time - start_time
  364. def get_overshoot_cruise(self):
  365. """
  366. 计算超速巡航超调量。
  367. Args:
  368. 无。
  369. Returns:
  370. 无返回值,但会更新类的成员变量 `overshoot`。
  371. """
  372. first_change_index = self._get_first_change_index_cruise()
  373. initial_speed = self.df.loc[first_change_index, 'speedX']
  374. if initial_speed > self.stable_average_speed:
  375. self.overshoot_cruise = (self.stable_average_speed - self.df[
  376. 'speedX'].min()) * 100 / self.stable_average_speed
  377. elif initial_speed < self.stable_average_speed:
  378. self.overshoot_cruise = (self.df[
  379. 'speedX'].max() - self.stable_average_speed) * 100 / self.stable_average_speed
  380. else:
  381. self.overshoot_cruise = 0
  382. def get_overshoot_THW(self):
  383. """
  384. 计算超速THW超调量。
  385. Args:
  386. 无。
  387. Returns:
  388. 无返回值,但会更新类的成员变量 `overshoot`。
  389. """
  390. first_change_index = self._get_first_change_index_THW()
  391. initial_THW = self.df.loc[first_change_index, 'THW']
  392. if initial_THW > self.stable_average_THW:
  393. self.overshoot_THW = (self.stable_average_THW - self.df['THW'].min()) * 100 / self.stable_average_THW
  394. elif initial_THW < self.stable_average_THW:
  395. self.overshoot_THW = (self.df['THW'].max() - self.stable_average_THW) * 100 / self.stable_average_THW
  396. else:
  397. self.overshoot_THW = 0
  398. def get_steady_error_cruise(self):
  399. """
  400. 计算巡航稳态误差。
  401. Args:
  402. 无参数。
  403. Returns:
  404. 无返回值,但会更新对象的steady_error属性。
  405. Raises:
  406. ValueError: 如果stable_average_speed为None时,会抛出此异常。
  407. """
  408. first_change_index = self._get_first_change_index_cruise()
  409. set_cruise_speed = self.df.loc[first_change_index, 'set_cruise_speed']
  410. if self.stable_average_speed:
  411. self.steady_error_cruise = (self.stable_average_speed - set_cruise_speed) * 100 / self.stable_average_speed
  412. else:
  413. raise ValueError("Stable average speed is None.")
  414. def get_steady_error_THW(self):
  415. """
  416. 计算THW稳态误差。
  417. Args:
  418. 无参数。
  419. Returns:
  420. 无返回值,但会更新对象的steady_error属性。
  421. Raises:
  422. ValueError: 如果stable_average_THW为None时 ,会抛出此异常。
  423. """
  424. first_change_index = self._get_first_change_index_THW()
  425. set_THW = self.df.loc[first_change_index, 'set_headway_time']
  426. if self.stable_average_THW:
  427. self.steady_error_THW = (self.stable_average_THW - set_THW) * 100 / self.stable_average_THW
  428. else:
  429. raise ValueError("Stable average THW is None.")
  430. def get_target_recongnition_cut_in_time_mid(self):
  431. """
  432. 获取目标识别切入时间中间值。
  433. Args:
  434. 无参数。
  435. Returns:
  436. float: 目标识别切入时间中点(单位:秒),如果未获取到则返回None。
  437. """
  438. pass
  439. def get_target_recongnition_cut_in_time_SD(self):
  440. """
  441. 获取目标识别切入时间(SD)标准差
  442. Args:
  443. Returns:
  444. 目标识别切入时间(SD)的值,若函数无具体返回值则无返回(在此情况下,该函数被标记为 pass)
  445. """
  446. pass
  447. def get_target_recongnition_cut_off_time_mid(self):
  448. """
  449. 获取目标识别切出时间中间值。
  450. Args:
  451. 无参数。
  452. Returns:
  453. float: 目标识别切出时间中点(单位:秒),如果未获取到则返回None。
  454. """
  455. pass
  456. def get_target_recongnition_cut_off_time_SD(self):
  457. """
  458. 获取目标识别切出时间(SD)标准差
  459. Args:
  460. Returns:
  461. 目标识别切出时间(SD)的值,若函数无具体返回值则无返回(在此情况下,该函数被标记为 pass)
  462. """
  463. pass
  464. def get_stop_time(self):
  465. pass
  466. def Compute_nearby_distance_to_lane_boundary(self, x, width_ego):
  467. """
  468. 计算自车到车道边界线的距离,需要减去自车宽度
  469. Args:
  470. x.lateralDist :到边界线距离
  471. width_ego:车宽
  472. Returns:
  473. 自车到车道边界线的距离
  474. """
  475. if x.lateralDist < abs(x.right_lateral_distance):
  476. return x.lateralDist - width_ego / 2
  477. else:
  478. return abs(x.right_lateral_distance) - width_ego / 2
  479. def func_laneOffset_abs(self, x):
  480. """
  481. 计算自车横向偏移量的绝对值
  482. Args:
  483. x.laneOffset :横向偏移量
  484. Returns:
  485. 横向偏移量的绝对值
  486. """
  487. return abs(x.laneOffset)
  488. def func_center_line_cycle_optical(self, l):
  489. """
  490. 计算偏离车道中心线的振荡周期和极差,极大值要大于0,极小值要小于0
  491. Args:
  492. l :波的数值列表,如 l = [1, 2, 1, 2, 1, 0, -1, 0, 1, 2, 1, 2, 0, -1, 2]
  493. Returns:
  494. cycle:振荡周期数
  495. maximum_range:最大极差
  496. """
  497. # print("\n穿过y=0的周期数: ")
  498. length = len(l)
  499. number_peak = 0
  500. number_trough = 0
  501. # 生成新的、只含有波峰波谷的列表
  502. new_list = []
  503. plus = []
  504. minus = []
  505. for number, value in enumerate(l):
  506. if number == 0:
  507. if value > l[number + 1] and value > 0:
  508. number_peak += 1
  509. plus.append(value)
  510. if value < l[number + 1] and value < 0:
  511. number_trough += 1
  512. minus.append(value)
  513. continue
  514. if number == length - 1:
  515. if value > l[number - 1] and value > 0:
  516. number_peak += 1
  517. plus.append(value)
  518. if len(minus) != 0:
  519. new_list.append(min(minus))
  520. minus = []
  521. if value < l[number - 1] and value < 0:
  522. number_trough += 1
  523. minus.append(value)
  524. if len(plus) != 0:
  525. new_list.append(max(plus))
  526. plus = []
  527. if len(minus) != 0:
  528. new_list.append(min(minus))
  529. minus = []
  530. if len(plus) != 0:
  531. new_list.append(max(plus))
  532. plus = []
  533. continue
  534. if value >= l[number - 1] and value > l[number + 1] and value > 0:
  535. number_peak += 1
  536. plus.append(value)
  537. if len(minus) != 0:
  538. new_list.append(min(minus))
  539. minus = []
  540. if value < l[number - 1] and value <= l[number + 1] and value < 0:
  541. number_trough += 1
  542. minus.append(value)
  543. if len(plus) != 0:
  544. new_list.append(max(plus))
  545. plus = []
  546. cycle = min(number_peak, number_trough) - 1
  547. difference_list = []
  548. for i in range(len(new_list) - 1):
  549. difference = abs(new_list[i] - new_list[i + 1])
  550. difference_list.append(difference)
  551. if len(difference_list) == 0:
  552. maximum_range = -1
  553. # print(f"极差: {maximum_range}")
  554. else:
  555. maximum_range = max(difference_list)
  556. # print(f"极差: {maximum_range}")
  557. return cycle, maximum_range
  558. def func_normal_cycle_optical(self, l):
  559. """
  560. 计算振荡周期和极差,两个相邻的极大值(或极小值)算一次振荡
  561. Args:
  562. l :波的数值列表,如 l = [1, 2, 1, 2, 1, 0, -1, 0, 1, 2, 1, 2, 0, -1, 2]
  563. Returns:
  564. cycle:振荡周期数
  565. maximum_range:最大极差
  566. """
  567. # print("正常的周期数: ")
  568. length = len(l)
  569. number_peak = 0
  570. number_trough = 0
  571. # 生成新的、只含有波峰波谷的列表
  572. new_list = []
  573. for number, value in enumerate(l):
  574. if number == 0:
  575. if value > l[number + 1]:
  576. number_peak += 1
  577. new_list.append(value)
  578. if value < l[number + 1]:
  579. number_trough += 1
  580. new_list.append(value)
  581. continue
  582. if number == length - 1:
  583. if value > l[number - 1]:
  584. number_peak += 1
  585. new_list.append(value)
  586. if value < l[number - 1]:
  587. number_trough += 1
  588. new_list.append(value)
  589. continue
  590. if value >= l[number - 1] and value > l[number + 1]:
  591. number_peak += 1
  592. new_list.append(value)
  593. if value < l[number - 1] and value <= l[number + 1]:
  594. number_trough += 1
  595. new_list.append(value)
  596. if abs(number_peak - number_trough) > 1:
  597. pass
  598. else:
  599. cycle = max(number_peak, number_trough) - 1
  600. difference_list = []
  601. for i in range(len(new_list) - 1):
  602. difference = abs(new_list[i] - new_list[i + 1])
  603. difference_list.append(difference)
  604. if len(difference_list) == 0:
  605. maximum_range = -1
  606. # print(f"极差: {maximum_range}")
  607. else:
  608. maximum_range = max(difference_list)
  609. # print(f"极差: {maximum_range}")
  610. return cycle, maximum_range
  611. def _lateral_control01_minimum_distance_nearby_lane(self):
  612. """
  613. 横向控制01指标:计算离近侧车道线最小距离(m)
  614. Args:
  615. Returns:
  616. None
  617. """
  618. roadMark_df = self.roadMark_df
  619. player_df = self.df
  620. ego_df = player_df[player_df.playerId == 1]
  621. width_ego = ego_df['dimY'].values.tolist()[0]
  622. # 提取距离左车道线和右车道线距离
  623. roadMark_left_df = roadMark_df[roadMark_df.id == 0].reset_index(drop=True)
  624. roadMark_right_df = roadMark_df[roadMark_df.id == 2].reset_index(drop=True)
  625. roadMark_left_df['right_lateral_distance'] = roadMark_right_df['lateralDist']
  626. # 计算到车道边界线距离
  627. roadMark_left_df['nearby_distance_to_lane_boundary'] = roadMark_left_df.apply(
  628. lambda x: self.Compute_nearby_distance_to_lane_boundary(x, width_ego), axis=1)
  629. nearby_distance_to_lane_boundary = min(roadMark_left_df['nearby_distance_to_lane_boundary'])
  630. self.lateral_control01_minimum_distance_nearby_lane = round(nearby_distance_to_lane_boundary, 3)
  631. def _lateral_control02_maximum_lateral_offset(self):
  632. """
  633. 横向控制02指标:计算最大横向偏移量(m)
  634. Args:
  635. Returns:
  636. None
  637. """
  638. roadPos_df = self.roadPos_df
  639. # 提取自车的roadPos数据
  640. roadPos_ego_df = roadPos_df[roadPos_df.playerId == 1].reset_index(drop=True)
  641. # 计算横向偏移量的绝对值
  642. roadPos_ego_df['laneOffset_abs'] = roadPos_ego_df.apply(lambda x: self.func_laneOffset_abs(x), axis=1)
  643. max_laneOffset_abs_index = roadPos_ego_df['laneOffset_abs'].idxmax()
  644. row_with_max_value = roadPos_ego_df.iloc[max_laneOffset_abs_index].laneOffset
  645. self.lateral_control02_maximum_lateral_offset = round(row_with_max_value, 3)
  646. def _lateral_control03_relative_lateral_offset_distribution_expectation(self):
  647. """
  648. 横向控制03指标:计算相对横向偏移量分布期望(m)
  649. Args:
  650. Returns:
  651. None
  652. """
  653. # 提取自车宽度
  654. roadPos_df = self.roadPos_df
  655. roadPos_ego_df = roadPos_df[roadPos_df.playerId == 1].reset_index(drop=True)
  656. mean_laneOffset_index = roadPos_ego_df['laneOffset'].mean()
  657. self.lateral_control03_relative_lateral_offset_distribution_expectation = round(mean_laneOffset_index, 3)
  658. def _lateral_control04_relative_lateral_offset_distribution_standard_deviation(self):
  659. """
  660. 横向控制04指标:计算相对横向偏移量分布标准差(m)
  661. Args:
  662. Returns:
  663. None
  664. """
  665. # 提取自车宽度
  666. roadPos_df = self.roadPos_df
  667. roadPos_ego_df = roadPos_df[roadPos_df.playerId == 1].reset_index(drop=True)
  668. mean_laneOffset_index = roadPos_ego_df['laneOffset'].std()
  669. self.lateral_control04_relative_lateral_offset_distribution_standard_deviation = round(mean_laneOffset_index, 3)
  670. def _lateral_control05_absolute_lateral_offset_distribution_expectation(self):
  671. """
  672. 横向控制05指标:计算绝对横向偏移量分布期望(m)
  673. Args:
  674. Returns:
  675. None
  676. """
  677. roadPos_df = self.roadPos_df
  678. roadPos_ego_df = roadPos_df[roadPos_df.playerId == 1].reset_index(drop=True)
  679. roadPos_ego_df['laneOffset_abs'] = roadPos_ego_df.apply( \
  680. lambda x: self.func_laneOffset_abs(x), axis=1)
  681. mean_laneOffset_index = roadPos_ego_df['laneOffset_abs'].mean()
  682. self.lateral_control05_absolute_lateral_offset_distribution_expectation = round(mean_laneOffset_index, 3)
  683. def _lateral_control06_absolute_lateral_offset_distribution_standard_deviation(self):
  684. """
  685. 横向控制06指标:计算绝对横向偏移量分布标准差(m)
  686. Args:
  687. Returns:
  688. None
  689. """
  690. roadPos_df = self.roadPos_df
  691. roadPos_ego_df = roadPos_df[roadPos_df.playerId == 1].reset_index(drop=True)
  692. roadPos_ego_df['laneOffset_abs'] = roadPos_ego_df.apply( \
  693. lambda x: self.func_laneOffset_abs(x), axis=1)
  694. mean_laneOffset_index = roadPos_ego_df['laneOffset_abs'].std()
  695. self.lateral_control06_absolute_lateral_offset_distribution_standard_deviation = round(mean_laneOffset_index, 3)
  696. def _lateral_control07_maximum_lateral_deviation(self):
  697. """
  698. 横向控制07指标:横向距离极大值(m)
  699. Args:
  700. Returns:
  701. None
  702. """
  703. roadPos_df = self.roadPos_df
  704. roadPos_ego_df = roadPos_df[roadPos_df.playerId == 1].reset_index(drop=True)
  705. roadPos_ego_df['laneOffset_abs'] = roadPos_ego_df.apply(lambda x: self.func_laneOffset_abs(x), axis=1)
  706. max_laneOffset_abs_index = roadPos_ego_df['laneOffset_abs'].idxmax()
  707. row_with_max_value = roadPos_ego_df.iloc[max_laneOffset_abs_index].laneOffset
  708. self.lateral_control07_maximum_lateral_deviation = row_with_max_value
  709. def _lateral_control08_minimum_lateral_deviation(self):
  710. """
  711. 横向控制08指标:横向距离极小值(m)
  712. Args:
  713. Returns:
  714. None
  715. """
  716. roadPos_df = self.roadPos_df
  717. roadPos_ego_df = roadPos_df[roadPos_df.playerId == 1].reset_index(drop=True)
  718. roadPos_ego_df['laneOffset_abs'] = roadPos_ego_df.apply(lambda x: self.func_laneOffset_abs(x), axis=1)
  719. max_laneOffset_abs_index = roadPos_ego_df['laneOffset_abs'].idxmin()
  720. row_with_min_value = roadPos_ego_df.iloc[max_laneOffset_abs_index].laneOffset
  721. self.lateral_control08_minimum_lateral_deviation = row_with_min_value
  722. def _lateral_control09_absolute_position_oscillation_frequency(self):
  723. """
  724. 横向控制09指标:横向绝对位置振荡频率(Hz)
  725. Args:
  726. Returns:
  727. None
  728. """
  729. roadPos_df = self.roadPos_df
  730. roadPos_ego_df = roadPos_df[roadPos_df.playerId == 1].reset_index(drop=True)
  731. roadPos_ego_list = roadPos_ego_df['laneOffset'].values.tolist()
  732. cycle_number, _ = self.func_center_line_cycle_optical(roadPos_ego_list)
  733. self.lateral_control09_absolute_position_oscillation_frequency = round(cycle_number, 3)
  734. def _lateral_control10_absolute_position_oscillation_difference(self):
  735. """
  736. 横向控制10指标:横向绝对位置振荡极差(m)
  737. Args:
  738. Returns:
  739. None
  740. """
  741. roadPos_df = self.roadPos_df
  742. roadPos_ego_df = roadPos_df[roadPos_df.playerId == 1].reset_index(drop=True)
  743. roadPos_ego_list = roadPos_ego_df['laneOffset'].values.tolist()
  744. _, maximum_range = self.func_center_line_cycle_optical(roadPos_ego_list)
  745. self.lateral_control10_absolute_position_oscillation_difference = round(maximum_range, 3)
  746. def _lateral_control11_maximum_heading_deviation(self):
  747. """
  748. 横向控制11指标:最大偏航角
  749. Args:
  750. Returns:
  751. None
  752. """
  753. player_df = self.df
  754. road_mark_df = self.roadMark_df
  755. ego_df = player_df[player_df.playerId == 1].reset_index(drop=True)
  756. # 左车道线曲率,右车道线曲率,求二者平均值,计算车道线曲率,再与自车朝向相减
  757. road_mark_left_df = road_mark_df[road_mark_df.id == 0].reset_index(drop=True)
  758. road_mark_right_df = road_mark_df[road_mark_df.id == 2].reset_index(drop=True)
  759. road_mark_left_df['curvHor_left'] = road_mark_left_df['curvHor']
  760. road_mark_left_df['curvHor_right'] = road_mark_right_df['curvHor']
  761. road_mark_left_df['curvHor_middle'] = road_mark_left_df[['curvHor_left', 'curvHor_right']].apply( \
  762. lambda x: (x['curvHor_left'] + x['curvHor_right']) / 2, axis=1)
  763. ego_df['curvHor_middle'] = road_mark_left_df['curvHor_middle']
  764. ego_df['heading_deviation_abs'] = ego_df[['curvHor_middle', 'posH']].apply( \
  765. lambda x: abs(x['posH'] - x['curvHor_middle']), axis=1)
  766. row_with_max_value = max(ego_df['heading_deviation_abs'])
  767. self.lateral_control11_maximum_heading_deviation = row_with_max_value
  768. def _lateral_control12_relative_position_oscillation_frequency(self):
  769. """
  770. 横向控制12指标:横向相对位置振荡频率(Hz)
  771. Args:
  772. Returns:
  773. None
  774. """
  775. roadPos_df = self.roadPos_df
  776. roadPos_ego_df = roadPos_df[roadPos_df.playerId == 1].reset_index(drop=True)
  777. roadPos_ego_list = roadPos_ego_df['laneOffset'].values.tolist()
  778. cycle_number, _ = self.func_normal_cycle_optical(roadPos_ego_list)
  779. self.lateral_control12_relative_position_oscillation_frequency = round(cycle_number, 3)
  780. def _lateral_control13_relative_position_oscillation_difference(self):
  781. """
  782. 横向控制13指标:横向相对位置振荡极差(m)
  783. Args:
  784. Returns:
  785. None
  786. """
  787. roadPos_df = self.roadPos_df
  788. roadPos_ego_df = roadPos_df[roadPos_df.playerId == 1].reset_index(drop=True)
  789. roadPos_ego_list = roadPos_ego_df['laneOffset'].values.tolist()
  790. _, maximum_range = self.func_normal_cycle_optical(roadPos_ego_list)
  791. self.lateral_control13_relative_position_oscillation_difference = round(maximum_range, 3)