openx.py 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. Created on Mon Mar 14 15:44:01 2022
  5. @author: lxj
  6. """
  7. import xml.etree.ElementTree as ET
  8. from scenariogeneration import xodr
  9. from scenariogeneration import xosc
  10. from scenariogeneration import ScenarioGenerator
  11. from scenariogeneration.xodr import RoadSide, Object, ObjectType, Dynamic, Orientation
  12. import math, os
  13. from xodr_generator2 import road_detector_new
  14. from datetime import datetime
  15. import traceback
  16. import json
  17. import pandas as pd
  18. from enum import Enum
  19. import elevation_0323 as el
  20. import warnings
  21. warnings.filterwarnings("ignore")
  22. # xodr_list = ['/home/hancheng/taiheqiao_map/thq_1116.xodr', '/home/hancheng/gongyuanbeihuan_map/OD/OpenDRIVE.xodr','/home/hancheng/glyt_map/OpenDRIVE2.xodr']
  23. # osgb_list = ['/home/hancheng/taiheqiao_map/thq_1116.opt.osgb', '/home/hancheng/gongyuanbeihuan_map/osgb/GJBM_20km_0822.opt.osgb', '/home/hancheng/glyt_map/OSGB/jinlong_20231129_2_guazai.opt.osgb']
  24. xodr_list = ['/root/rosmerge/resource/thq.xodr', '/root/rosmerge/resource/OpenDRIVE.xodr',
  25. '/root/rosmerge/resource/gelan.xodr']
  26. osgb_list = ['/root/rosmerge/resource/thq.opt.osgb', '/root/rosmerge/resource/GJBM_20km_0822.opt.osgb',
  27. '/root/rosmerge/resource/gelan.opt.osgb']
  28. class Scenario(ScenarioGenerator):
  29. def __init__(self, gps, obs, gps_time, ego_speed, work_mode, period, abspath, timeofday, map_id):
  30. ScenarioGenerator.__init__(self)
  31. self.gps = gps
  32. self.obs = obs
  33. self.gps_time = gps_time
  34. self.ego_speed = ego_speed
  35. self.work_mode = work_mode
  36. self.period = period # 场景持续的时间
  37. self.abspath = abspath
  38. self.weather = xosc.PrecipitationType.dry # 默认是晴天
  39. self.visual_fog_range = 20000 # 正常的能见度,没有雾
  40. self.time = timeofday # 用于判断白天还是黑夜
  41. self.map_id = map_id
  42. # self.ObjectID = ObjectID
  43. # self.Speed = Speed
  44. def road(self, **kwargs):
  45. positionEgo = self.gps
  46. planview = xodr.PlanView()
  47. for i in range(len(positionEgo) - 1):
  48. x = 0.000001 if abs(positionEgo[i].x) < 0.000001 else positionEgo[i].x
  49. y = 0.000001 if abs(positionEgo[i].y) < 0.000001 else positionEgo[i].y
  50. nextx = 0.000001 if abs(positionEgo[i + 1].x) < 0.000001 else positionEgo[i + 1].x
  51. nexty = 0.000001 if abs(positionEgo[i + 1].y) < 0.000001 else positionEgo[i + 1].y
  52. h = float(positionEgo[i].h)
  53. planview.add_fixed_geometry(xodr.Line(math.sqrt(math.pow(nextx - x, 2) + math.pow(nexty - y, 2))), x, y, h)
  54. planview.add_fixed_geometry(xodr.Line(100), nextx, nexty, h)
  55. # create two different roadmarkings
  56. rm_solid = xodr.RoadMark(xodr.RoadMarkType.solid, 0.2)
  57. rm_dashed = xodr.RoadMark(xodr.RoadMarkType.broken, 0.2)
  58. # create simple lanes
  59. lanes = xodr.Lanes()
  60. lanesection1 = xodr.LaneSection(0, xodr.standard_lane(offset=1.75, rm=rm_dashed))
  61. lanesection1.add_left_lane(xodr.standard_lane(offset=3.5, rm=rm_dashed))
  62. lanesection1.add_left_lane(xodr.standard_lane(offset=3.5, rm=rm_dashed))
  63. lanesection1.add_left_lane(xodr.standard_lane(offset=3.5, rm=rm_solid))
  64. lanesection1.add_right_lane(xodr.standard_lane(offset=3.5, rm=rm_dashed))
  65. lanesection1.add_right_lane(xodr.standard_lane(offset=3.5, rm=rm_dashed))
  66. lanesection1.add_right_lane(xodr.standard_lane(offset=3.5, rm=rm_solid))
  67. lanes.add_lanesection(lanesection1)
  68. lanes.add_laneoffset(xodr.LaneOffset(a=1.75))
  69. road = xodr.Road(0, planview, lanes)
  70. odr = xodr.OpenDrive('myroad')
  71. # 静态元素
  72. tree = ET.parse(os.getcwd() + '/models/static_object_models.xodr')
  73. root = tree.getroot()
  74. objects_dict = root.iter(tag='object')
  75. road = create_static_object(road, objects_dict)
  76. # road = create_static_object(road, object_id=0, object_type=ObjectType.railing, repeat_flag=1)
  77. odr.add_road(road)
  78. odr.adjust_roads_and_lanes()
  79. return odr
  80. def get_section(self, left_lanemark):
  81. return None
  82. def split_road_section(self, enu_file, lane_file):
  83. lane_content = pd.read_csv(lane_file)
  84. # 把车道分割开来,一个车道段,多种geometry
  85. # 首先判断车道线数值是否有断裂,断裂处根据自车轨迹生成道路参数
  86. left_lanemark = lane_content[lane_content['LaneID'] == 1][['Time', 'FrameID', 'LanePosition', 'LaneQuality']]
  87. right_lanemark = lane_content[lane_content['LaneID'] == 2][['Time', 'FrameID', 'LanePosition', 'LaneQuality']]
  88. left_break_section = self.get_section(left_lanemark, 1)
  89. right_break_section = self.get_section(right_lanemark, 1)
  90. break_section = []
  91. normal_section = []
  92. # 判断是否变道,然后判断是否弯道
  93. # 最终目标是得到多个geometry参数,确定每个连接线处的s/t偏移量?,以及左右道路的个数和宽度
  94. return None
  95. def check_outliers_and_modify(self, datalist):
  96. for index in datalist.index:
  97. if index < 3:
  98. datalist.loc[index] = datalist[index] if abs(
  99. datalist[index] - datalist[index + 1:index + 3].mean()) < 0.5 else 2 * datalist[
  100. index + 1] - datalist[index + 1:index + 3].mean()
  101. elif 3 <= index < len(datalist) - 3:
  102. datalist.loc[index] = datalist[index] if abs(
  103. datalist[index] - datalist[index + 1:index + 3].mean()) < 0.5 or abs(
  104. datalist[index] - datalist[index - 3:index].mean()) < 0.5 else (datalist[index - 1] + datalist[
  105. index + 1]) / 2
  106. else:
  107. datalist.loc[index] = datalist[index] if abs(
  108. datalist[index] - datalist[index - 3:index].mean()) < 0.5 else 2 * datalist[index - 1] - datalist[
  109. index - 3:index].mean()
  110. return datalist
  111. def get_new_LaneID(self, change_flag, laneID, frameid, item):
  112. '''
  113. 修改laneID,change_list包含了每个变道片段
  114. '''
  115. if item[0] <= frameid < item[1]:
  116. return laneID + change_flag
  117. else:
  118. return laneID
  119. def get_lane_width(self, data1, data2):
  120. lane_union = pd.merge(data1, data2, on=['FrameID'])
  121. lane_union['width'] = lane_union['LanePosition_y'] - lane_union['LanePosition_x']
  122. a = lane_union["width"].quantile(0.75)
  123. b = lane_union["width"].quantile(0.25)
  124. lane_width = abs((a + b) / 2)
  125. return lane_width
  126. def road_pre_study(self, label_file, lane_file):
  127. laneDF = pd.read_csv(lane_file)
  128. road_label = ''
  129. flag = 0 # flag = 0 can use road_ego to generate .xodr, flag = 1 better use road to generate .xodr
  130. with open(label_file) as f:
  131. label = json.load(f)
  132. ego_actions = label['自车行为']
  133. for item in ego_actions:
  134. if ('变道' in item['type_']) or ('转成功' in item['type_']) or ('掉头' in item['type_']):
  135. road_label = item['type_']
  136. flag = 1
  137. break
  138. else:
  139. road_label = item['type_']
  140. if road_label == '向左变道成功':
  141. # 查找变道标记点
  142. change_flag = 1
  143. lane_1 = laneDF[(laneDF['LaneID'] == 1) & (laneDF['LaneQuality'] > 1)]
  144. lane_1 = lane_1.reset_index(drop=True)
  145. leftlanepositon = lane_1['LanePosition']
  146. lane_1['LanePosition'] = self.check_outliers_and_modify(leftlanepositon)
  147. lane_1['last_Position'] = lane_1[['LanePosition']].shift(axis=0, periods=1) # axis指定移动的轴:0为行,1为列
  148. lane_1['last_FrameID'] = lane_1[['FrameID']].shift(axis=0, periods=1) # axis指定移动的轴:0为行,1为列
  149. lane_1['change_flag'] = lane_1.apply(
  150. lambda x: change_flag if (x['LanePosition'] - x['last_Position'] <= -3) and (
  151. x['FrameID'] - x['last_FrameID'] == 1) else 0, axis=1) # 默认情况下 axis=0 表示按列,axis=1 表示按行。
  152. lane_1['split_flag'] = lane_1.apply(lambda x: 99 if x['FrameID'] - x['last_FrameID'] > 1 else 0, axis=1)
  153. lane_2 = laneDF[(laneDF['LaneID'] == 2) & (laneDF['LaneQuality'] > 1)]
  154. lane_2 = lane_2.reset_index(drop=True)
  155. rightlanepositon = lane_2['LanePosition']
  156. lane_2['LanePosition'] = self.check_outliers_and_modify(rightlanepositon)
  157. lane_2['last_Position'] = lane_2[['LanePosition']].shift(axis=0, periods=1) # axis指定移动的轴:0为行,1为列
  158. lane_2['last_FrameID'] = lane_2[['FrameID']].shift(axis=0, periods=1) # axis指定移动的轴:0为行,1为列
  159. lane_2['change_flag'] = lane_2.apply(
  160. lambda x: change_flag if (x['LanePosition'] - x['last_Position'] <= -3) and (
  161. x['FrameID'] - x['last_FrameID'] == 1) else 0, axis=1) # 默认情况下 axis=0 表示按列,axis=1 表示按行。
  162. lane_2['split_flag'] = lane_2.apply(lambda x: 99 if x['FrameID'] - x['last_FrameID'] > 1 else 0, axis=1)
  163. lane_width = self.get_lane_width(lane_1[['FrameID', 'LanePosition']], lane_2[['FrameID', 'LanePosition']])
  164. # 左变道用左车道线数据靠谱,不会有他车遮挡,找到变道数据段
  165. change_lane_point = list(lane_1[lane_1['change_flag'] == change_flag]['change_flag'].index) + [
  166. list(lane_1.index)[-1]]
  167. change_lane_section = [
  168. (lane_1.loc[change_lane_point[i], 'FrameID'], lane_1.loc[change_lane_point[i + 1], 'FrameID']) for i in
  169. range(len(change_lane_point) - 1)]
  170. for item in change_lane_section:
  171. # 变道后修改原始laneID
  172. # laneDF['LaneID'] = laneDF.apply(lambda x: x['LaneID'] - change_flag if item[0] <= x['FrameID'] < item[1] else x['LaneID'], axis=1)
  173. # laneDF['LanePosition'] = laneDF.apply(lambda x: x['LanePosition'] - change_flag * lane_width if item[0] <= x['FrameID'] < item[1] else x['LanePosition'], axis=1)
  174. # laneDF['LaneID'] = laneDF.apply(lambda x: x['LaneID'] - change_flag if x['FrameID'] == max(laneDF['FrameID']) else x['LaneID'], axis=1)
  175. # laneDF['LanePosition'] = laneDF.apply(lambda x: x['LanePosition'] - change_flag * lane_width if x['FrameID'] == max(laneDF['FrameID']) else x['LanePosition'], axis=1)
  176. # 修正左左车道线和右右车道线数值
  177. if change_flag == 1:
  178. lane_0 = laneDF[
  179. (laneDF['LaneID'] == 0) & (laneDF['LaneQuality'] > 1) & (laneDF['FrameID'] < item[0])]
  180. if not lane_0.empty:
  181. left_lane_width = self.get_lane_width(lane_0[['FrameID', 'LanePosition']],
  182. lane_1[['FrameID', 'LanePosition']])
  183. else:
  184. left_lane_width = lane_width
  185. print(left_lane_width)
  186. # new_lane_1 = laneDF[laneDF['LaneID'] == 1][['FrameID','LanePosition']]
  187. # new_lane_1.rename(columns={'LanePosition':'LanePosition2'},inplace=True)
  188. # laneDF = pd.merge(laneDF, new_lane_1, on=['FrameID'])
  189. # laneDF['LanePosition'] = laneDF.apply(lambda x: x['LanePosition2'] - left_lane_width if (item[0] <= x['FrameID'] < item[1]) and (x['LaneID'] == 0) else x['LanePosition'], axis=1)
  190. # laneDF['LanePosition'] = laneDF.apply(lambda x: x['LanePosition2'] - left_lane_width if x['FrameID'] == max(laneDF['FrameID']) and (x['LaneID'] == 0) else x['LanePosition'], axis=1)
  191. # laneDF['LanePosition'] = laneDF.apply(lambda x: x['LanePosition2'] - left_lane_width if (item[0] <= x['FrameID'] < item[1]) and (x['LaneID'] == -1) else x['LanePosition'], axis=1)
  192. # laneDF['LanePosition'] = laneDF.apply(lambda x: x['LanePosition2'] - left_lane_width if x['FrameID'] == max(laneDF['FrameID']) and (x['LaneID'] == 0) else x['LanePosition'], axis=1)
  193. # laneDF['LaneID'] = laneDF.apply(lambda x: 3 if x['LaneID'] == -1 else x['LaneID'], axis=1)
  194. # 缺右车道线right_lane_width处理
  195. print(laneDF[laneDF['FrameID'] > 1860][['FrameID', 'LaneID', 'LanePosition']].head(50))
  196. print('road_label: ', road_label)
  197. return laneDF
  198. def road_new(self, **kwargs):
  199. polyfit_fig_path = os.path.join(self.abspath, 'simulation', 'polyfit.jpg')
  200. # run road detector
  201. enu_file = os.path.join(self.abspath, 'pos.csv')
  202. lane_file = os.path.join(self.abspath, 'lane.csv')
  203. label_file = os.path.join(self.abspath, 'label.json')
  204. # study road style: straight\curve\split-line; ego action: change-lane\no-change\cross-turn
  205. lane_content = self.road_pre_study(label_file, lane_file)
  206. # road split sections
  207. # self.split_road_section(enu_file, lane_file)
  208. try:
  209. laneid_tuple = [0, 1, 2, 3]
  210. uv_coord_info, road_info, left_lane_info, right_lane_info = road_detector_new(enu_file, lane_content,
  211. laneid_tuple,
  212. polyfit_fig_path)
  213. except:
  214. print('road detection failed!!!! Use ego trail road.')
  215. error = {'time': datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3], 'traceback': traceback.format_exc()}
  216. with open('error.log', 'a+') as f:
  217. json.dump(error, f, indent=4)
  218. f.write('\n')
  219. return self.road_ego()
  220. origin_x = uv_coord_info[0]
  221. origin_y = uv_coord_info[1]
  222. uv_coord_hdg = uv_coord_info[2]
  223. reference_line_offset = road_info[0]
  224. model_u = road_info[1] # in fomrat [c3, c2, c1, c0]
  225. model_v = road_info[2] # in fomrat [c3, c2, c1, c0]
  226. road_length = road_info[3]
  227. print(uv_coord_info)
  228. print(road_info)
  229. # generate xodr file
  230. planview = xodr.PlanView(origin_x, origin_y, uv_coord_hdg)
  231. # Create geometry and add it to the planview
  232. # parampoly3 = xodr.ParamPoly3(au=model_u[3], bu=model_u[2], cu=model_u[1], du=model_u[0], av=model_v[3], bv=model_v[2], cv=model_v[1], dv=model_v[0], prange='arcLength',length=road_length)
  233. parampoly3 = xodr.ParamPoly3(au=0, bu=model_u[2], cu=model_u[1], du=model_u[0], av=0, bv=model_v[2],
  234. cv=model_v[1], dv=model_v[0], prange='arcLength', length=road_length)
  235. planview.add_geometry(parampoly3)
  236. # create two different roadmarkings
  237. rm_solid = xodr.RoadMark(xodr.RoadMarkType.solid, 0.2)
  238. rm_dashed = xodr.RoadMark(xodr.RoadMarkType.broken, 0.2, laneChange=xodr.LaneChange.both)
  239. ##4. Create centerlane
  240. centerlane = xodr.Lane(a=reference_line_offset)
  241. centerlane.add_roadmark(rm_dashed)
  242. ##5. Create lane section form the centerlane
  243. lanesec = xodr.LaneSection(0, centerlane)
  244. ##6. Create left and right lanes
  245. lane_id = 0
  246. for lane in left_lane_info:
  247. lane_id += 1
  248. lane_width = lane[0]
  249. spd_limit = lane[1]
  250. lane_left = xodr.Lane(a=lane_width)
  251. lane_left.add_roadmark(rm_dashed)
  252. # Add lanes to lane section
  253. lanesec.add_left_lane(lane_left)
  254. lane_id = 0
  255. for lane in right_lane_info:
  256. lane_id -= 1
  257. lane_width = lane[0]
  258. spd_limit = lane[1]
  259. lane_right = xodr.Lane(a=lane_width)
  260. lane_right.add_roadmark(rm_dashed)
  261. # Add lanes to lane section
  262. lanesec.add_right_lane(lane_right)
  263. ##8. Add lane section to Lanes
  264. lanes = xodr.Lanes()
  265. lanes.add_laneoffset(xodr.LaneOffset(s=0, a=reference_line_offset))
  266. lanes.add_lanesection(lanesec)
  267. ##9. Create Road from Planview and Lanes
  268. road = xodr.Road(1, planview, lanes)
  269. ##10. Create the OpenDrive class (Master class)
  270. odr = xodr.OpenDrive('myroad')
  271. ##11. Finally add roads to Opendrive
  272. odr.add_road(road)
  273. ##12. Adjust initial positions of the roads looking at succ-pred logic
  274. odr.adjust_roads_and_lanes()
  275. # ##13. Print the .xodr file
  276. # xodr.prettyprint(odr.get_element())
  277. # ##14. Run the .xodr with esmini
  278. # xodr.run_road(odr,os.path.join('..','pyoscx','esmini'))
  279. return odr
  280. def getXoscPosition(egodata, t, e, n, h, z, obj_type, offset_x, offset_y, offset_h, start_time):
  281. '将dataframe的轨迹转换为场景文件的轨迹数据, Time, ego_e, ego_n, headinga'
  282. position = []
  283. time = []
  284. # cur_time = 0.0
  285. egodata = egodata[[t, e, n, h, z, obj_type]]
  286. egodata = egodata.reset_index(drop=True)
  287. # egodata[t] = egodata.index / 10
  288. egodata[t] = (egodata[t] - start_time) / 1000
  289. egodata[e] = egodata[e] + offset_x
  290. egodata[n] = egodata[n] + offset_y
  291. egodata[h] = egodata[h] + offset_h
  292. egodata[h] = egodata.apply(lambda x: x[h] if x[h] < 360 else x[h] - 360, axis=1)
  293. type_list = list(egodata[obj_type])
  294. ego_type = int(max(type_list, key=type_list.count))
  295. lasth = float(egodata.at[0, h])
  296. init_flag = True
  297. # two method to set z value
  298. zflag = 0 # 1
  299. if zflag:
  300. # 根据地图的xy值计算z值
  301. zfile = '/home/hancheng/weihao/gongyuanbei_elevation.csv'
  302. # zfile = '/home/hancheng/simulation_dynamic/elevation_df_taiheqiao.csv'
  303. zdata = pd.read_csv(zfile)
  304. for row in egodata.iterrows():
  305. hhh = math.radians(row[1][h])
  306. xodr_z = el.cal_elevation(zdata, float(row[1][e]), float(row[1][n]))
  307. if init_flag:
  308. position.append(
  309. xosc.WorldPosition(x=float(row[1][e]), y=float(row[1][n]), z=xodr_z, h=hhh, p=0, r=0))
  310. init_flag = False
  311. else:
  312. if float(row[1][h]) - lasth > 300:
  313. hhh = math.radians(float(row[1][h]) - 360)
  314. elif float(row[1][h]) - lasth < -300:
  315. hhh = math.radians(float(row[1][h]) + 360)
  316. position.append(
  317. xosc.WorldPosition(x=float(row[1][e]), y=float(row[1][n]), z=xodr_z, h=hhh, p=0, r=0))
  318. lasth = hhh
  319. time.append(float(row[1][t]))
  320. # time.append(cur_time)
  321. # cur_time += 0.1
  322. return position, time, ego_type
  323. else:
  324. # z = 0
  325. for row in egodata.iterrows():
  326. hhh = math.radians(row[1][h])
  327. if init_flag:
  328. position.append(
  329. xosc.WorldPosition(x=float(row[1][e]), y=float(row[1][n]), z=float(row[1][z]), h=hhh, p=0, r=0))
  330. init_flag = False
  331. else:
  332. if float(row[1][h]) - lasth > 300:
  333. hhh = math.radians(float(row[1][h]) - 360)
  334. elif float(row[1][h]) - lasth < -300:
  335. hhh = math.radians(float(row[1][h]) + 360)
  336. position.append(
  337. xosc.WorldPosition(x=float(row[1][e]), y=float(row[1][n]), z=float(row[1][z]), h=hhh, p=0, r=0))
  338. lasth = hhh
  339. time.append(float(row[1][t]))
  340. # time.append(cur_time)
  341. # cur_time += 0.1
  342. return position, time, ego_type
  343. def scenario(self, **kwargs):
  344. road = xosc.RoadNetwork(roadfile=xodr_list[self.map_id], scenegraph=osgb_list[self.map_id])
  345. catalog = xosc.Catalog()
  346. catalog.add_catalog('VehicleCatalog', 'Distros/Current/Config/Players/Vehicles')
  347. catalog.add_catalog('PedestrianCatalog', 'Distros/Current/Config/Players/Pedestrians')
  348. catalog.add_catalog('ControllerCatalog', 'Distros/Current/Config/Players/driverCfg.xml')
  349. pbb = xosc.BoundingBox(0.5, 0.5, 1.8, 2.0, 0, 0.9)
  350. mbb = xosc.BoundingBox(1, 2, 1.7, 1.5, 0, 0.9)
  351. bb = xosc.BoundingBox(2.1, 4.5, 1.8, 1.5, 0, 0.9)
  352. bus_bb = xosc.BoundingBox(2.55, 10.5, 3.1, 5.1, 0, 1.45)
  353. bus_fa = xosc.Axle(0.48, 0.91, 2.5, 4.5, 1.5)
  354. bus_ba = xosc.Axle(0, 0.91, 2.5, 4.5, 1.5)
  355. truck_bb = xosc.BoundingBox(2.8, 8.744, 3.78, 4.372, 0, 1.89)
  356. truck_fa = xosc.Axle(0.48, 1, 2.8, 4.372, 1.5)
  357. truck_ba = xosc.Axle(0, 1, 2.8, 4.372, 1.5)
  358. fa = xosc.Axle(0.5, 0.6, 1.8, 3.1, 0.3)
  359. ba = xosc.Axle(0, 0.6, 1.8, 0, 0.3)
  360. red_veh = xosc.Vehicle('Audi_A3_2009_black', xosc.VehicleCategory.car, bb, fa, ba, 69.444, 200, 10)
  361. red_veh.add_property(name='control', value='external')
  362. white_veh = xosc.Vehicle('Audi_A3_2009_red', xosc.VehicleCategory.car, bb, fa, ba, 69.444, 200, 10)
  363. male_ped = xosc.Pedestrian('Christian', 'male adult', 70, xosc.PedestrianCategory.pedestrian, pbb)
  364. motorcycle = xosc.Vehicle('Kawasaki_ZX-9R_black', xosc.VehicleCategory.motorbike, mbb, fa, ba, 69.444, 200, 10)
  365. truck = xosc.Vehicle('MANTGS_11_Black', xosc.VehicleCategory.truck, truck_bb, truck_fa,
  366. truck_ba, 26.4, 10, 10)
  367. bus = xosc.Vehicle('MercedesTravego_10_ArcticWhite', xosc.VehicleCategory.bus, bus_bb, bus_fa, bus_ba, 29, 10,
  368. 10)
  369. prop = xosc.Properties()
  370. cnt = xosc.Controller('DefaultDriver', prop)
  371. cnt2 = xosc.Controller('No Driver', prop)
  372. # 添加自车实体
  373. egoname = 'Ego'
  374. entities = xosc.Entities()
  375. entities.add_scenario_object(egoname, red_veh, cnt)
  376. # 添加目标车实体
  377. objname = 'Player'
  378. ped_type, car_type, bicycle_motor_type, bus_type, truct_type = get_obj_type(self.work_mode)
  379. positionEgo = self.gps
  380. positionObj = self.obs
  381. for i, row in enumerate(positionObj):
  382. if len(row[1]) < 10:
  383. continue
  384. obj_type = row[2] # 根据目标物类型添加对应的实体
  385. if obj_type in ped_type:
  386. entities.add_scenario_object(objname + str(i), male_ped)
  387. elif obj_type in car_type:
  388. entities.add_scenario_object(objname + str(i), white_veh, cnt2)
  389. elif obj_type in bicycle_motor_type:
  390. entities.add_scenario_object(objname + str(i), motorcycle, cnt2)
  391. elif obj_type in bus_type:
  392. entities.add_scenario_object(objname + str(i), bus, cnt2)
  393. elif obj_type in truct_type:
  394. entities.add_scenario_object(objname + str(i), truck, cnt2)
  395. # 初始化
  396. init = xosc.Init()
  397. step_time = xosc.TransitionDynamics(xosc.DynamicsShapes.step, xosc.DynamicsDimension.time, 0)
  398. egospeed = xosc.AbsoluteSpeedAction(self.ego_speed, step_time)
  399. # 设置初始环境要素,例如天气时间等
  400. default_precipitation = xosc.PrecipitationType.dry
  401. default_cloudstate = xosc.CloudState.free
  402. # json_path = os.path.join(self.abspath, 'label.json')
  403. # with open(json_path, 'r', encoding='utf-8') as f:
  404. # sc_json = json.load(f)
  405. # weather = sc_json['天气情况'][0]['type_'] #['自然环境']
  406. # if weather == '晴':
  407. # f.close()
  408. # elif weather == '多云':
  409. # default_cloudstate = xosc.CloudState.cloudy
  410. # elif weather == '阴':
  411. # default_cloudstate = xosc.CloudState.overcast
  412. # elif weather == '雨':
  413. # default_cloudstate = xosc.CloudState.overcast
  414. # default_precipitation = xosc.PrecipitationType.rain
  415. # elif weather == '雪':
  416. # default_cloudstate = xosc.CloudState.overcast
  417. # default_precipitation = xosc.PrecipitationType.snow
  418. # elif weather == '雾霾' or weather == '沙尘':
  419. # self.visual_fog_range = 700
  420. # default_cloudstate = xosc.CloudState.cloudy
  421. init.add_global_action(
  422. xosc.EnvironmentAction(name="InitEnvironment", environment=xosc.Environment(
  423. xosc.TimeOfDay(True, 2019, 12, 19, 12, 0, 0),
  424. xosc.Weather(
  425. sun_intensity=2000, sun_azimuth=40, sun_elevation=20,
  426. cloudstate=default_cloudstate,
  427. precipitation=default_precipitation,
  428. precipitation_intensity=1,
  429. visual_fog_range=self.visual_fog_range),
  430. xosc.RoadCondition(friction_scale_factor=0.7))))
  431. # ego car init
  432. ego_init_h = positionEgo[0].h
  433. init.add_init_action(egoname, xosc.TeleportAction(
  434. xosc.WorldPosition(x=positionEgo[0].x, y=positionEgo[0].y, z=positionEgo[0].z, h=ego_init_h, p=0, r=0)))
  435. init.add_init_action(egoname, egospeed)
  436. # ego car trail
  437. trajectory = xosc.Trajectory('egoTrajectory', False)
  438. polyline = xosc.Polyline(self.gps_time, positionEgo)
  439. trajectory.add_shape(polyline)
  440. speedaction = xosc.FollowTrajectoryAction(trajectory, xosc.FollowMode.position, xosc.ReferenceContext.absolute,
  441. 1, 0)
  442. trigger = xosc.ValueTrigger('drive_start_trigger', 0, xosc.ConditionEdge.rising,
  443. xosc.SimulationTimeCondition(0, xosc.Rule.greaterThan))
  444. trigger_init = xosc.ValueTrigger(name='init_trigger', delay=0, conditionedge=xosc.ConditionEdge.rising,
  445. valuecondition=xosc.SimulationTimeCondition(value=0,
  446. rule=xosc.Rule.greaterThan))
  447. event_init = xosc.Event('Event_init', xosc.Priority.overwrite)
  448. action_light = xosc.CustomCommandAction(0, 0, 0, 0, 1, 0, 0)
  449. light_flag = 'auto'
  450. if self.time == 64800:
  451. light_flag = 'true'
  452. text = f'<Environment><TimeOfDay headlights="{light_flag}" timezone="8" value="{self.time}" /></Environment>'
  453. node = ET.Element("CustomCommandAction")
  454. node.attrib = {'type': 'scp'}
  455. node.text = f"<![CDATA[\n{text}]\n]>"
  456. action_light.add_element(node)
  457. event_init.add_action('headlight', action_light)
  458. event_init.add_trigger(trigger_init)
  459. event = xosc.Event('Event1', xosc.Priority.overwrite)
  460. event.add_trigger(trigger)
  461. event.add_action('newspeed', speedaction)
  462. man = xosc.Maneuver('my maneuver')
  463. man.add_event(event_init)
  464. man.add_event(event)
  465. mangr = xosc.ManeuverGroup('mangroup', selecttriggeringentities=True)
  466. mangr.add_actor('Ego')
  467. mangr.add_maneuver(man)
  468. trigger0 = xosc.Trigger('start')
  469. act = xosc.Act('Act1', trigger0)
  470. act.add_maneuver_group(mangr)
  471. ego_story = xosc.Story('mystory_ego')
  472. ego_story.add_act(act)
  473. stop_trigger = xosc.ValueTrigger('stop_trigger', 0, xosc.ConditionEdge.none,
  474. xosc.SimulationTimeCondition(self.period, xosc.Rule.greaterThan), 'stop')
  475. sb = xosc.StoryBoard(init, stoptrigger=stop_trigger)
  476. sb.add_story(ego_story)
  477. # object car trail
  478. if positionObj:
  479. for i, row in enumerate(positionObj):
  480. name = objname + str(i)
  481. if len(row[1]) < 10:
  482. continue
  483. obj_type = row[2]
  484. # 根据目标车需要动态创建实体
  485. x = row[0][0].x
  486. y = row[0][0].y
  487. z = row[0][0].z
  488. h = row[0][0].h
  489. start_time = row[1][0]
  490. init_position = xosc.WorldPosition(x=x, y=y, z=z, h=h, p=0, r=0)
  491. newentity = xosc.AddEntityAction(name, init_position)
  492. newentity_trigger = xosc.ValueTrigger(name='newentity_trigger', delay=0,
  493. conditionedge=xosc.ConditionEdge.rising,
  494. valuecondition=xosc.SimulationTimeCondition(value=start_time,
  495. rule=xosc.Rule.equalTo))
  496. newentity_event = xosc.Event('Event_newentity', xosc.Priority.overwrite)
  497. newentity_event.add_trigger(newentity_trigger)
  498. newentity_event.add_action('newentity_action', newentity)
  499. man_obj = xosc.Maneuver('my maneuver')
  500. man_obj.add_event(newentity_event)
  501. # 添加目标车轨迹
  502. trajectoryM = xosc.Trajectory('objectTrajectory', False)
  503. polylineM = xosc.Polyline(row[1], row[0])
  504. trajectoryM.add_shape(polylineM)
  505. obj_trail_action = xosc.FollowTrajectoryAction(trajectory=trajectoryM,
  506. following_mode=xosc.FollowMode.position,
  507. reference_domain=xosc.ReferenceContext.absolute,
  508. scale=1, offset=0, initialDistanceOffset=0)
  509. obj_trail_event = xosc.Event('Event1', xosc.Priority.overwrite)
  510. # obj_start_trigger = xosc.EntityTrigger("obj-start-trigger", 0, xosc.ConditionEdge.rising, xosc.SpeedCondition(0, xosc.Rule.greaterThan),'Ego')
  511. obj_start_trigger = xosc.ValueTrigger('obj_start_trigger', 0, xosc.ConditionEdge.rising,
  512. xosc.SimulationTimeCondition(start_time, xosc.Rule.greaterThan))
  513. obj_trail_event.add_trigger(obj_start_trigger)
  514. obj_trail_event.add_action('trail_action', obj_trail_action)
  515. # if obj_type in ped_type:
  516. # walp_trigger = xosc.EntityTrigger('ped_walp_trigger', 0, xosc.ConditionEdge.rising,\
  517. # xosc.TimeToCollisionCondition(self.intersectime, xosc.Rule.lessThan, entity=name), 'Ego')
  518. # obj_trail_event.add_trigger(walp_trigger)
  519. man_obj.add_event(obj_trail_event)
  520. # 行人特有的事件
  521. if obj_type in ped_type:
  522. ped_event = xosc.Event('Event_ped', xosc.Priority.overwrite)
  523. ped_event.add_trigger(obj_start_trigger)
  524. ped_action = xosc.CustomCommandAction(0, 0, 0, 0, 1, 0, 0)
  525. ped_action.add_element(self.createUDAction(name))
  526. ped_event.add_action('ped_trail_action', ped_action)
  527. man_obj.add_event(ped_event)
  528. # finish_trigger = xosc.EntityTrigger('finish_trigger', 0, xosc.ConditionEdge.rising, xosc.ReachPositionCondition(position=row[1][0],tolerance=1),name)
  529. # event4 = xosc.Event('Event_ped',xosc.Priority.overwrite)
  530. # event4.add_trigger(finish_trigger)
  531. # be_still_action = xosc.AbsoluteSpeedAction(0, xosc.TransitionDynamics(xosc.DynamicsShapes.step, xosc.DynamicsDimension.time, 1))
  532. # event4.add_action('ped_be_still_action',be_still_action)
  533. # man_obj.add_event(event4)
  534. # 轨迹最后删除实体
  535. last_time = row[1][-1]
  536. del_action = xosc.DeleteEntityAction(name)
  537. del_trigger = xosc.ValueTrigger(name='entity_del_trigger', delay=0,
  538. conditionedge=xosc.ConditionEdge.rising,
  539. valuecondition=xosc.SimulationTimeCondition(value=last_time,
  540. rule=xosc.Rule.greaterThan))
  541. del_event = xosc.Event('Event_del', xosc.Priority.overwrite)
  542. del_event.add_trigger(del_trigger)
  543. del_event.add_action('del_action', del_action)
  544. man_obj.add_event(del_event)
  545. obj_mangroup = xosc.ManeuverGroup('mangroup', selecttriggeringentities=True)
  546. obj_mangroup.add_actor(name)
  547. obj_mangroup.add_maneuver(man_obj)
  548. obj_act = xosc.Act('Act2', trigger0)
  549. obj_act.add_maneuver_group(obj_mangroup)
  550. obj_story = xosc.Story('mystory_' + name)
  551. obj_story.add_act(obj_act)
  552. sb.add_story(obj_story)
  553. # prettyprint(sb.get_element())
  554. paramet = xosc.ParameterDeclarations()
  555. sce = xosc.Scenario('my scenario', 'Maggie', paramet, entities, sb, road, catalog)
  556. return sce
  557. def createUDAction(self, name):
  558. # tree = ET.parse('./models/ped_CDATA.xosc')
  559. # root = tree.getroot()
  560. # ele = root[5][2][1][0][1][1][0][0][0]
  561. # newnode = ET.Element("CustomCommandAction")
  562. # newnode.attrib = {'type': 'scp'}
  563. # newnode.text = '<![CDATA[\n' + ele.text + ']\n]>'
  564. speed = 3
  565. motion = 'walk'
  566. text = f'<Traffic>\n <ActionMotion actor="{name}" move="{motion}" speed="{speed}" force="false" ' \
  567. f'rate="0" delayTime="0.0" activateOnExit="false"/>\n</Traffic>'
  568. newnode = ET.Element("CustomCommandAction")
  569. newnode.attrib = {'type': 'scp'}
  570. newnode.text = f"<![CDATA[\n{text}]\n]>"
  571. return newnode
  572. class WorkMode(Enum):
  573. cicv = 0 # CICV车端
  574. roadside = 1 # 车网路端
  575. car = 2 # 车网车端
  576. merge = 3 # 车网车端路端融合
  577. def get_obj_type(mode):
  578. if mode == WorkMode.cicv.value:
  579. # CICV车端
  580. ped_type = [7]
  581. car_type = [2]
  582. bicycle_motor_type = [8]
  583. bus_type = [3]
  584. truct_type = [4]
  585. elif mode == WorkMode.roadside.value:
  586. # 车网路端
  587. ped_type = [0]
  588. car_type = [2]
  589. bicycle_motor_type = [1, 3]
  590. bus_type = [5]
  591. truct_type = [7]
  592. elif mode == WorkMode.car.value:
  593. # 车网车端
  594. ped_type = [1]
  595. car_type = [6]
  596. bicycle_motor_type = [2, 3, 4, 5]
  597. bus_type = [7, 8]
  598. truct_type = [9]
  599. else:
  600. # 车网车端路端融合
  601. ped_type = [1]
  602. car_type = [6]
  603. bicycle_motor_type = [2, 3, 4, 5]
  604. bus_type = [7, 8]
  605. truct_type = [9]
  606. return ped_type, car_type, bicycle_motor_type, bus_type, truct_type
  607. # 创建道路旁静止的场景
  608. def create_static_object(road, object_dict):
  609. for single_object in object_dict:
  610. for k, v in ObjectType.__members__.items():
  611. if k == single_object.attrib['type']:
  612. single_object.attrib['type'] = v
  613. break
  614. road_object = Object(
  615. s=single_object.attrib['s'],
  616. t=single_object.attrib['t'],
  617. Type=single_object.attrib['type'],
  618. dynamic=Dynamic.no,
  619. id=single_object.attrib['id'],
  620. name=single_object.attrib['name'],
  621. zOffset=single_object.attrib['zOffset'],
  622. validLength=single_object.attrib['validLength'],
  623. orientation=Orientation.none,
  624. length=single_object.attrib['length'],
  625. width=single_object.attrib['width'],
  626. height=single_object.attrib['height'],
  627. pitch=single_object.attrib['pitch'],
  628. roll=single_object.attrib['roll']
  629. )
  630. # 判断此object是否是重复的元素
  631. repeat = single_object.find('repeat')
  632. if repeat is not None:
  633. road.add_object_roadside(road_object_prototype=road_object, repeatDistance=0, side=RoadSide.left,
  634. tOffset=1.75)
  635. road.add_object_roadside(road_object_prototype=road_object, repeatDistance=0, side=RoadSide.right,
  636. tOffset=-1.755)
  637. else:
  638. road.add_object(road_object)
  639. return road
  640. def change_CDATA(filepath):
  641. '行人场景特例,对xosc文件内的特殊字符做转换'
  642. f = open(filepath, "r", encoding="UTF-8")
  643. txt = f.readline()
  644. all_line = []
  645. # txt是否为空可以作为判断文件是否到了末尾
  646. while txt:
  647. txt = txt.replace("&lt;", "<").replace("&gt;", ">").replace("&amp;", "&").replace("&quot;", '"').replace(
  648. "&apos;", "'")
  649. all_line.append(txt)
  650. # 读取文件的下一行
  651. txt = f.readline()
  652. f.close()
  653. f1 = open(filepath, 'w', encoding="UTF-8")
  654. for line in all_line:
  655. f1.write(line)
  656. f1.close()
  657. def path_changer(xosc_path, xodr_path, osgb_path):
  658. """
  659. provided by Dongpeng Ding
  660. :param xosc_path:
  661. :param xodr_path:
  662. :param osgb_path:
  663. :return:
  664. """
  665. tree = ET.parse(xosc_path)
  666. treeRoot = tree.getroot()
  667. # for OpenScenario v0.9, v1.0
  668. for RoadNetwork in treeRoot.findall('RoadNetwork'):
  669. for Logics in RoadNetwork.findall('LogicFile'):
  670. Logics.attrib['filepath'] = xodr_path
  671. for SceneGraph in RoadNetwork.findall('SceneGraphFile'):
  672. SceneGraph.attrib['filepath'] = osgb_path
  673. for Logics in RoadNetwork.findall('Logics'):
  674. Logics.attrib['filepath'] = xodr_path
  675. for SceneGraph in RoadNetwork.findall('SceneGraph'):
  676. SceneGraph.attrib['filepath'] = osgb_path
  677. # for VTD xml
  678. for Layout in treeRoot.findall('Layout'):
  679. Layout.attrib['File'] = xodr_path
  680. Layout.attrib['Database'] = osgb_path
  681. tree.write(xosc_path, xml_declaration=True)
  682. def readXML(xoscPath):
  683. xodrFileName = ""
  684. osgbFileName = ""
  685. tree = ET.parse(xoscPath)
  686. treeRoot = tree.getroot()
  687. for RoadNetwork in treeRoot.findall('RoadNetwork'):
  688. for Logics in RoadNetwork.findall('LogicFile'):
  689. xodrFileName = Logics.attrib['filepath']
  690. for SceneGraph in RoadNetwork.findall('SceneGraphFile'):
  691. osgbFileName = SceneGraph.attrib['filepath']
  692. for Logics in RoadNetwork.findall('Logics'):
  693. xodrFileName = Logics.attrib['filepath']
  694. for SceneGraph in RoadNetwork.findall('SceneGraph'):
  695. osgbFileName = SceneGraph.attrib['filepath']
  696. return xodrFileName[xodrFileName.rindex("/") + 1:], osgbFileName[osgbFileName.rindex("/") + 1:]
  697. def formatThree(rootDirectory):
  698. """
  699. xodr and osgb file path are fixed
  700. :return:
  701. """
  702. for root, dirs, files in os.walk(rootDirectory):
  703. for file in files:
  704. if ".xosc" == file[-5:]:
  705. # xodrFilePath = "/volume4T/goodscenarios/generalization/toyiqi/model/Rd_001.xodr" # 泛化效果好的场景用的
  706. # osgbFilePath = "/volume4T/goodscenarios/generalization/toyiqi/model/Rd_001.osgb" # 泛化效果好的场景用的
  707. # xodrFilePath = "/volume4T/goodscenarios/generalization/toyiqi/model/Cross.xodr" # 泛化效果好的场景用的
  708. # osgbFilePath = "/volume4T/goodscenarios/generalization/toyiqi/model/Cross.osgb" # 泛化效果好的场景用的
  709. xodrFilePath = "/home/hancheng/hc_project/2023-08-08-10-50-16_jsons1/2023-08-08-10-50-16_jsons_0/2023-08-08-10-50-16_jsons_0.xodr" # 直路,泛化好用
  710. osgbFilePath = "/home/hancheng/VIRES/VTD.2022.1/Runtime/Tools/RodDistro_7001_Rod4.6.3/DefaultProject/Database/json0.opt.osgb" # 直路,泛化好用
  711. # xodrFilePath = "/home/lxj/wendang_lxj/L4/L4_scenarios/piliang_model/China_Crossing_002.xodr" # 十字路口,泛化好用
  712. # osgbFilePath = "/home/lxj/wendang_lxj/L4/L4_scenarios/piliang_model/China_Crossing_002.opt.osgb" # 十字路口,泛化好用
  713. # xodrFilePath = "/home/lxj/wendang_lxj/Sharing_VAN/homework/test/DF_yuexiang_1224.xodr" # Sharing-van还原用的
  714. # osgbFilePath = "/home/lxj/wendang_lxj/Sharing_VAN/homework/test/DF_yuexiang_1224.opt.osgb" # Sharing-van还原用的
  715. path_changer(root + "/" + file, xodrFilePath, osgbFilePath)
  716. print("Change success: " + root + "/" + file)
  717. def formatTwo(rootDirectory):
  718. """
  719. data format:
  720. simulation
  721. file.xosc
  722. file.xodr
  723. file.osgb
  724. :return:
  725. """
  726. for root, dirs, files in os.walk(rootDirectory):
  727. for file in files:
  728. if ".xosc" == file[-5:]:
  729. xodrFilePath = ""
  730. osgbFilePath = ""
  731. for odrFile in os.listdir(root):
  732. if ".xodr" == odrFile[-5:]:
  733. xodrFilePath = root + "/" + odrFile
  734. break
  735. for osgbFile in os.listdir(root):
  736. if ".osgb" == osgbFile[-5:]:
  737. osgbFilePath = root + "/" + osgbFile
  738. break
  739. path_changer(root + "/" + file, xodrFilePath, osgbFilePath)
  740. print("Change success: " + root + "/" + file)
  741. def formatOne(rootDirectory):
  742. """
  743. data format:
  744. openx
  745. xosc
  746. file.xosc
  747. xodr
  748. file.xodr
  749. osgb
  750. file.osgb
  751. :return:
  752. """
  753. for root, dirs, files in os.walk(rootDirectory):
  754. for file in files:
  755. if "xosc" == file[-4:]:
  756. xodrFilePath = ""
  757. osgbFilePath = ""
  758. for odrFile in os.listdir(root[:-4] + "xodr"):
  759. if "xodr" == odrFile[-4:]:
  760. xodrFilePath = root[:-4] + "xodr/" + odrFile
  761. break
  762. for osgbFile in os.listdir(root[:-4] + "osgb"):
  763. if "osgb" == osgbFile[-4:]:
  764. osgbFilePath = root[:-4] + "osgb/" + osgbFile
  765. break
  766. path_changer(root + "/" + file, xodrFilePath, osgbFilePath)
  767. print("Change success: " + root + "/" + file)
  768. def chongQingFormat(rootDirectory):
  769. """
  770. supporting file format: chong qing folder format
  771. :return:
  772. """
  773. counter = 1
  774. for root, dirs, files in os.walk(rootDirectory):
  775. for file in files:
  776. if "xosc" == file[-4:]:
  777. if "ver1.0.xosc" == file[-11:]:
  778. xodrFileName, osgbFileName = readXML(root + "/" + file)
  779. xodrFilePath = "/Xodrs/" + xodrFileName
  780. osgbFilePath = "/Databases/" + osgbFileName
  781. path_changer(root + "/" + file, xodrFilePath, osgbFilePath)
  782. print(counter, "Change success: " + root + "/" + file)
  783. else:
  784. xodrFileName, osgbFileName = readXML(root + "/" + file)
  785. xodrFilePath = "/Xodrs/" + xodrFileName
  786. osgbFilePath = "/Databases/" + osgbFileName
  787. path_changer(root + "/" + file, xodrFilePath, osgbFilePath)
  788. print(counter, "Change success: " + root + "/" + file)
  789. counter += 1