simulation_hmi.py 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. # -*-ing:utf-8-*-
  2. import os
  3. import sys
  4. from datetime import datetime
  5. import traceback
  6. import json
  7. import math
  8. import pandas as pd
  9. import subprocess
  10. import time
  11. import multiprocessing # 导入进程模块
  12. from functools import partial # 导入偏函数
  13. import warnings
  14. warnings.filterwarnings("ignore")
  15. from openx import Scenario, formatThree, formatTwo, change_CDATA
  16. import osgbGenerator
  17. from utils import smooth_1, get_coordinate_cow, get_map_name, reverse_gyb_gps
  18. class Batchrun:
  19. def __init__(self, path, keyFileName):
  20. """"初始化方法"""
  21. self.path = path
  22. self.keyFileName = keyFileName
  23. def getFile(self, path, keyFileName):
  24. '''
  25. 获得可以进行轨迹提取的所有片段文件夹路径
  26. Parameters
  27. ----------
  28. path : TYPE
  29. DESCRIPTION.
  30. Returns
  31. -------
  32. FileList : TYPE
  33. 可以进行轨迹提取的所有片段文件夹路径.
  34. '''
  35. files = os.listdir(path) # 得到文件夹下的所有文件,包含文件夹名称
  36. FileList = []
  37. if keyFileName not in files:
  38. for name in files:
  39. if os.path.isdir(path + '/' + name):
  40. FileList.extend(self.getFile(path + '/' + name, keyFileName)) # 回调函数,对所有子文件夹进行搜索
  41. else:
  42. FileList.append(path)
  43. FileList = list(set(FileList))
  44. return FileList
  45. def generateScenarios_raw(self, absPath, param):
  46. '''
  47. 原始自然驾驶场景还原
  48. '''
  49. # 读取自车数据
  50. posPath = os.path.join(absPath, param) # 用来生成场景中自车和他车的路径
  51. posdata = pd.read_csv(posPath)
  52. # 读取仿真地图数据
  53. offset_x = -457000.0
  54. offset_y = -4400000.0
  55. # offset_h = 90 # 初始headinga 和 VTD 有 90偏角
  56. offset_h = 0
  57. # 对感知数据进行后处理
  58. # 对公园北环路进行坐标转换
  59. # 根据pos文件规范时间戳
  60. posdata['Time'] = posdata['Time'].apply(lambda x: (x // 100) * 100)
  61. # 绝对高程与相对高程的差值
  62. posdata['altitude'] = 19.27
  63. # posdata['Type'].replace({8:2, 10:2}, inplace=True)
  64. pos_ego = posdata.loc[posdata['ID'] == -1, ['Time', 'East', 'North', 'HeadingAngle', 'altitude', 'Type']]
  65. # pos_ego[['East', 'North']] = pos_ego.apply(get_coordinate_cow, axis=1)
  66. # pos_ego = posdata.loc[posdata['ID'] == -1, ['Time', 'position_x', 'position_y', 'HeadingAngle', 'Type']]
  67. pos_ego = pos_ego.reset_index(drop=True)
  68. # offset_x = -float(pos_ego.at[0, 'East']) # 初始East 设为0
  69. # offset_y = -float(pos_ego.at[0, 'North']) # 初始North 设为0
  70. start_time = pos_ego.at[0, 'Time']
  71. ego_points, gps_time, ego_type = Scenario.getXoscPosition(pos_ego, 'Time', 'East', 'North', 'HeadingAngle',
  72. 'altitude', 'Type', offset_x, offset_y, offset_h,
  73. start_time)
  74. # ego_points, gps_time, ego_type = Scenario.getXoscPosition(pos_ego, 'Time', 'position_x', 'position_y', 'HeadingAngle', 'Type', offset_x, offset_y, offset_h, start_time)
  75. # 读取目标数据
  76. pos_obs = posdata # 排除非目标物的物体
  77. # pos_obs = posdata[posdata['Type'] != 10] # 排除非目标物的物体
  78. pos_obs = pos_obs.loc[
  79. pos_obs['ID'] != -1, ['Time', 'ID', 'East', 'North', 'HeadingAngle', 'AbsVel', 'altitude', 'Type']]
  80. # pos_obs = pos_obs.loc[pos_obs['ID'] != -1, ['Time', 'ID', 'position_x', 'position_y', 'HeadingAngle', 'Type']]
  81. # !!!!自定义修改
  82. # pos_obs.loc[pos_obs['ID'] == 1200, 'type'] = 7
  83. # pos_obs.loc[pos_obs['ID'] == 1197, 'type'] = 7
  84. # pos_obs.loc[pos_obs['ID'] == 1200, 'position_x'] += 1
  85. # pos_obs.loc[pos_obs['ID'] == 1200, 'position_y'] -= 2
  86. # pos_obs.loc[pos_obs['ID'] == 1197, 'position_x'] += 1
  87. # pos_obs.loc[pos_obs['ID'] == 1197, 'position_y'] -= 1
  88. # pos_obs.loc[pos_obs['ID'] == 1203, 'type'] = 4
  89. # pos_obs.loc[pos_obs['ID'] == 1203, 'position_x'] = 456319
  90. # pos_obs.loc[pos_obs['ID'] == 1203, 'position_y'] = 4397979
  91. # pos_obs.loc[pos_obs['ID'] == 1203, 'HeadingAngle'] = 1
  92. # offset_h = 30
  93. # pos_obs.loc[pos_obs['ID'] == 1194, 'type'] = 7
  94. # pos_obs.loc[pos_obs['ID'] == 1188, 'type'] = 2
  95. # pos_obs.loc[pos_obs['ID'] == 1189, 'type'] = 2
  96. # pos_obs.loc[pos_obs['ID'] == 1195, 'type'] = 2
  97. # obsPath = os.path.join(absPath, 'obs.csv') # 用来筛选场景中不需要的他车
  98. # obsdata = pd.read_csv(obsPath)
  99. # obsdata = obsdata[(obsdata['ObjectPosY'] < 5) & (obsdata['ObjectPosY'] > -5) & (obsdata['ObjectPosX'] > -10) & (obsdata['ObjectPosX'] < 100)] # 排除车道线范围外且前向距离较远的目标物
  100. # idlist = obsdata['ObjectID'].tolist() # 筛选出符合条件的的目标物ID
  101. # pos_obs = pos_obs[(pos_obs['ID'].isin(idlist))]
  102. pos_obs = pos_obs.reset_index(drop=True)
  103. groups = pos_obs.groupby('ID')
  104. object_points = []
  105. for key, value in groups:
  106. if len(value) < 5:
  107. continue
  108. # value = smooth_1(value)
  109. object_points.append(
  110. Scenario.getXoscPosition(value, 'Time', 'East', 'North', 'HeadingAngle', 'altitude', 'Type', offset_x,
  111. offset_y, offset_h, start_time))
  112. # object_points.append(Scenario.getXoscPosition(value, 'Time', 'position_x', 'position_y', 'HeadingAngle', 'type', offset_x, offset_y, offset_h,start_time))
  113. ego_speed = 5
  114. period = math.ceil(gps_time[-1] - gps_time[0])
  115. work_mode = 0 # 0为CICV车端数据
  116. hour = int(absPath.split('/')[-1].split('-')[3])
  117. if hour + 8 >= 24:
  118. hour = hour - 16
  119. else:
  120. hour = hour + 8
  121. time_of_day = hour * 3600
  122. # 没有路灯防止天过暗
  123. if time_of_day >= 64800:
  124. time_of_day = 64800
  125. s = Scenario(ego_points, object_points, gps_time, ego_speed, work_mode, period, absPath, time_of_day)
  126. filename = absPath + '/simulation' + '_' + param.split("_")[1].split(".")[0]
  127. files = s.generate(filename)
  128. change_CDATA(files[0][0])
  129. print(files)
  130. # 生成osgb
  131. # osgbGenerator.formatTwo(filename)
  132. # 修改xosc路径
  133. # formatThree(filename)
  134. # # # 生成每个场景的描述文件 json
  135. # # getLabel(output_path, scenario_series['场景编号'], scenario_series['场景名称'])
  136. # 拷贝到vtd路径下
  137. # vtd_path = os.path.join('/home/lxj/VIRES/VTD.2021.3/Data/Projects/Current/Scenarios/myScenario', datetime.now().strftime("%Y%m%d%H%M%S"))
  138. # if not os.path.exists(vtd_path):
  139. # os.makedirs(vtd_path)
  140. # os.system('cp '+ files[0][0] + ' ' + vtd_path + '/')
  141. def multiRun(self, path, param):
  142. files = self.getFile(path, self.keyFileName)
  143. print('程序开始,%s 个数据包' % len(files))
  144. t1 = time.time()
  145. # 无参数时,使用所有cpu核; 有参数时,使用CPU核数量为参数值
  146. pool = multiprocessing.Pool(processes=10)
  147. pfunc = partial(self.generateScenarios_raw, param)
  148. pool.map(pfunc, files)
  149. # 调用join之前,先调用close函数,否则会出错。执行完close后不会有新的进程加入到pool,join函数等待所有子进程结束
  150. pool.close()
  151. pool.join()
  152. t2 = time.time()
  153. print("程序结束,并行执行时间:%s s" % int(t2 - t1))
  154. def batchRun(self, path, param):
  155. files = self.getFile(path, self.keyFileName)
  156. print('程序开始,%s 个数据包' % len(files))
  157. for di, absPath in enumerate(sorted(files)):
  158. print(absPath)
  159. # try:
  160. self.generateScenarios_raw(absPath, param)
  161. # except:
  162. # print('Augmentation failed!!!!')
  163. # error = {'time':datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3],'traceback':traceback.format_exc()}
  164. # with open('error.log','a+') as f:
  165. # json.dump(error, f, indent=4)
  166. # f.write('\n')
  167. # print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
  168. return None
  169. def GenerateVideo(self, root_path):
  170. # 批量生成视频
  171. imagelist = self.getFile(root_path, 'image')
  172. for item in imagelist:
  173. strs = item.split('/')
  174. respath = os.path.join(item, "video.mp4")
  175. # respath = os.path.join(res_path,strs[-3],strs[-2],"video.mp4")
  176. print('---------------------')
  177. # os.makedirs(os.path.join(res_path,strs[-3],strs[-2]))
  178. command = "ffmpeg -f image2 -r 10 -pattern_type glob -i '" + item + "/image/*.jpg" + "' -y '" + respath + "'"
  179. print(command)
  180. process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
  181. process.wait()
  182. if __name__ == "__main__":
  183. # rootPath = "/media/hancheng/Simulation5/pjisuv_pjisuv95_data_merge_2024-01-31-07-53-50_TTC_11" # 跟车
  184. rootPath = sys.argv[1] # 跟车
  185. # 生成场景
  186. a = Batchrun(rootPath, "pos_orig.csv")
  187. a.batchRun(rootPath, 'pos_orig.csv')
  188. # a.batchRun(rootPath, 'pos_hmi.csv')
  189. # a.multiRun(rootPath, 0)
  190. # 生成视频
  191. # a.GenerateVideo(rootPath)