bagtocsv_robot.py 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. # coding: utf-8
  2. #!/usr/bin/env python2
  3. import os
  4. import rosbag
  5. import csv
  6. import math
  7. import rospy
  8. import sys
  9. import time
  10. import numpy as np
  11. from datetime import datetime
  12. import argparse
  13. import pandas as pd
  14. import json
  15. def quaternion_to_euler(x, y, z, w):
  16. # 将四元数归一化
  17. try:
  18. length = np.sqrt(x**2 + y**2 + z**2 + w**2)
  19. x /= length
  20. y /= length
  21. z /= length
  22. w /= length
  23. # 计算欧拉角
  24. #roll = np.arctan2(2*(w*x + y*z), 1 - 2*(x**2 + y**2))
  25. #pitch = np.arcsin(2*(w*y - z*x))
  26. yaw = np.arctan2(2*(w*z + x*y), 1 - 2*(y**2 + z**2))
  27. return yaw
  28. except :
  29. return 0
  30. def parsehancheng(input_dir, output_dir):
  31. json_path=os.path.join(output_dir,'output.json')
  32. try:
  33. dic_trajectory = ['Time','simTime','simFrame','PointNumber','posX','posY','posZ','posH',
  34. 'TargetX','TargetY','TargetZ','TargetH']
  35. trajectory_file = open(output_dir + "/"+"trajectory_pji.csv", 'w')
  36. writer_trajectory = csv.writer(trajectory_file)
  37. writer_trajectory.writerow(dic_trajectory)
  38. dic_EgoState = ['Time','simTime','simFrame','posX','posY','posZ','posH','speedX','speedH','cmd_speedX','cmd_speedH','obstacle','task_error_code','latitude','longitude']
  39. EgoState_file = open(output_dir + "/"+"ego_pji.csv", 'w')
  40. writer_EgoState = csv.writer(EgoState_file)
  41. writer_EgoState.writerow(dic_EgoState)
  42. dic_drive=['Time', 'Real_Speed', 'latitude', 'longitude', 'angular_velocity_z']
  43. drive_file = open(output_dir + "/"+"drive.csv", 'w')
  44. writer_drive = csv.writer(drive_file)
  45. writer_drive.writerow(dic_drive)
  46. #dic_robot_pos = ['Time','simtime','FrameID','HeadingAngle','X', 'Y' ,'Z','latitude','longitude']
  47. #robot_pos_file = open(output_dir + "/"+"pos_pji.csv", 'w')
  48. #writer_robot_pos = csv.writer(robot_pos_file)
  49. #writer_robot_pos.writerow(dic_robot_pos)
  50. dic_objects = ['Time','simTime','simFrame','playerId','posH','posX', 'posY' ,'posZ','label','dimX','dimY','dimZ',
  51. 'speedX','speedY','speedZ','speedH_X','speedH_Y','speedH_Z','accelX','accelY','accelZ','accelH_X','accelH_Y','accelH_Z']
  52. objects_file = open(output_dir + "/"+"objects_pji.csv", 'w')
  53. writer_objects = csv.writer(objects_file)
  54. writer_objects.writerow(dic_objects)
  55. frame_max=sys.maxsize
  56. with rosbag.Bag(input_dir ,'r') as bag:
  57. #wheel_odom_flag=False
  58. #cmd_vel_flag=False
  59. first_message_time = None
  60. Frame_robot_pose=1
  61. obstacle_state=0
  62. speed_linear=0
  63. speed_angular=0
  64. speed_linear2=0
  65. speed_angular2=0
  66. cmd_speed_angular=0
  67. cmd_speed_linear=0
  68. first_message_time = None
  69. framenum_ego = 1
  70. task_error_code=0
  71. #framenum_obj = 1
  72. locationsimtime=' '
  73. date_time=' '
  74. simFrame=1
  75. latitude=0
  76. longitude=0
  77. ego_posx,ego_posy,ego_posz,ego_posH=0,0,0,0
  78. #用来判断机器人点云/图像/规划/定位是否丢帧↓↓↓
  79. #num_image_raw=0
  80. #rate_image_raw=10
  81. num_velodyne_points=0
  82. rate_velodyne_points=10
  83. bag_start_time = bag.get_start_time()
  84. bag_end_time = bag.get_end_time()
  85. duration=bag_end_time-bag_start_time
  86. Theoretical_velodyne_points_num=int(duration*rate_velodyne_points)
  87. #Theoretical_image_raw_num=int(duration*rate_image_raw)
  88. #print(duration)
  89. robot_pose_lost_flag=True
  90. final_trajectorye_lost_flag=True
  91. gnss_lost_flag=True
  92. pcd_exist_flag=False
  93. #用来判断机器人点云/图像/规划/定位是否丢帧↑↑↑
  94. for topic,msg,t in bag.read_messages(topics=['/wheel','/obstacle_detection','/wheel_odom','/cmd_vel','/robot_pose','/tracking/objects','/nav/task_feedback_info',
  95. '/robot/final_trajectory','/gnss','/image_raw','/velodyne_points']):
  96. if first_message_time is None:
  97. first_message_time = t
  98. first_message_time = rospy.Time.to_sec(first_message_time)
  99. first_message_time = datetime.fromtimestamp(first_message_time)
  100. if topic == "/velodyne_points":
  101. pcd_exist_flag=True
  102. num_velodyne_points+=1
  103. '''
  104. if topic == "/image_raw":
  105. num_image_raw+=1
  106. '''
  107. if topic == "/gnss":
  108. latitude=msg.latitude/10000000
  109. longitude=msg.longitude/10000000
  110. gnss_lost_flag=False
  111. if topic == "/obstacle_detection":
  112. obstacle_state=msg.data
  113. #print(msg.data)
  114. #之前的解析用的是这个话题,现在改成/wheel了
  115. '''
  116. if topic == "/wheel_odom":
  117. #wheel_odom_flag=True
  118. speed_linear=msg.twist.twist.linear.x*3.6
  119. speed_angular=msg.twist.twist.angular.z
  120. '''
  121. if topic == "/wheel":
  122. #wheel_odom_flag=True
  123. speed_linear2=(msg.twist.twist.linear.x+msg.twist.twist.linear.y)*0.5*3.6
  124. speed_angular2=(msg.twist.twist.linear.y-msg.twist.twist.linear.x)/0.5
  125. #print('speed_linear2=',speed_linear2,'speed_angular2=',speed_angular2)
  126. if topic == "/cmd_vel":
  127. #cmd_vel_flag=True
  128. cmd_speed_linear=msg.linear.x*3.6
  129. cmd_speed_angular=msg.angular.z
  130. if topic == "/nav/task_feedback_info":
  131. task_error_code=msg.task_error_code
  132. if topic == "/robot_pose":
  133. timestamp = rospy.Time.to_sec(t)
  134. date_time = datetime.fromtimestamp(timestamp)
  135. locationsimtime=(date_time-first_message_time).total_seconds()
  136. ego_posx=msg.pose.position.x
  137. poseX=ego_posx
  138. #poseX=ego_posx-88.96626338170609
  139. ego_posy=msg.pose.position.y
  140. poseY=ego_posy
  141. #poseY=ego_posy-40.553671177476645
  142. poseZ=msg.pose.position.z
  143. orientationX=msg.pose.orientation.x
  144. orientationY=msg.pose.orientation.y
  145. orientationZ=msg.pose.orientation.z
  146. orientationW=msg.pose.orientation.w
  147. egoyaw=quaternion_to_euler(orientationX,orientationY,orientationZ,orientationW)
  148. if poseX!=0.0 and poseY!=0.0:
  149. robot_pose_lost_flag=False
  150. #message_location =[date_time,locationsimtime,framenum_ego,egoyaw,poseX,poseY,poseZ,latitude,longitude]
  151. #print(f'date_time={date_time}, locationtime={locationsimtime}')
  152. #writer_robot_pos.writerow(message_location)
  153. #if wheel_odom_flag and cmd_vel_flag:
  154. message_EgoState =[str(t)[:-6],locationsimtime,Frame_robot_pose,poseX,poseY,poseZ,egoyaw,
  155. speed_linear2,speed_angular2,cmd_speed_linear,cmd_speed_angular,obstacle_state,task_error_code,latitude,longitude]
  156. message_drive=[str(t)[:-6],speed_linear2,latitude,longitude,speed_angular2]
  157. writer_EgoState.writerow(message_EgoState)
  158. writer_drive.writerow(message_drive)
  159. framenum_ego+=1
  160. Frame_robot_pose+=1
  161. if topic == "/tracking/objects":
  162. msg_l = len(msg.objects)
  163. if msg_l and (locationsimtime != ' ') and (date_time != ' '):
  164. #timestamp = rospy.Time.to_sec(t)
  165. #date_time = datetime.fromtimestamp(timestamp)
  166. #simtime=(date_time-first_message_time).total_seconds()
  167. for i in range(msg_l):
  168. obj_ID = msg.objects[i].id
  169. obj_x = msg.objects[i].pose.position.x
  170. #obj_x = msg.objects[i].pose.position.x-88.96626338170609
  171. obj_y = msg.objects[i].pose.position.y
  172. #obj_y = msg.objects[i].pose.position.y-40.553671177476645
  173. obj_z = msg.objects[i].pose.position.z
  174. obj_orientationX=msg.objects[i].pose.orientation.x
  175. obj_orientationY=msg.objects[i].pose.orientation.y
  176. obj_orientationZ=msg.objects[i].pose.orientation.z
  177. obj_orientationW=msg.objects[i].pose.orientation.w
  178. objyaw=quaternion_to_euler(obj_orientationX,obj_orientationY,obj_orientationZ,obj_orientationW)
  179. obj_lable=msg.objects[i].label
  180. obj_dimX=msg.objects[i].dimensions.x
  181. obj_dimY=msg.objects[i].dimensions.y
  182. obj_dimZ=msg.objects[i].dimensions.z
  183. velocity_linear_x=msg.objects[i].velocity.linear.x
  184. velocity_linear_y=msg.objects[i].velocity.linear.y
  185. velocity_linear_z=msg.objects[i].velocity.linear.z
  186. velocity_angular_x=msg.objects[i].velocity.angular.x
  187. velocity_angular_y=msg.objects[i].velocity.angular.y
  188. velocity_angular_z=msg.objects[i].velocity.angular.z
  189. acceleration_linear_x=msg.objects[i].acceleration.linear.x
  190. acceleration_linear_y=msg.objects[i].acceleration.linear.y
  191. acceleration_linear_z=msg.objects[i].acceleration.linear.z
  192. acceleration_angular_x=msg.objects[i].acceleration.angular.x
  193. acceleration_angular_y=msg.objects[i].acceleration.angular.y
  194. acceleration_angular_z=msg.objects[i].acceleration.angular.z
  195. message_obj =[str(t)[:-6],locationsimtime,Frame_robot_pose,obj_ID,objyaw,obj_x,obj_y,obj_z,obj_lable,obj_dimX,obj_dimY,obj_dimZ,
  196. velocity_linear_x,velocity_linear_y,velocity_linear_z,velocity_angular_x,velocity_angular_y,
  197. velocity_angular_z,acceleration_linear_x,acceleration_linear_y,acceleration_linear_z,
  198. acceleration_angular_x,acceleration_angular_y,acceleration_angular_z]
  199. #print(f'{date_time}, {locationsimtime}')
  200. writer_objects.writerow(message_obj)
  201. #framenum_obj+=1
  202. if topic == "/robot/final_trajectory":
  203. PointNumber=1
  204. timestamp1 = rospy.Time.to_sec(t)
  205. date_time1 = datetime.fromtimestamp(timestamp1)
  206. locationsimtime1=(date_time1-first_message_time).total_seconds()
  207. if ego_posx!=0 or ego_posy!=0:
  208. if msg.waypoints!=[]:#判断规划是否丢帧
  209. final_trajectorye_lost_flag=False
  210. for i in range(len(msg.waypoints)):
  211. Targetx=msg.waypoints[i].pose.pose.position.x
  212. Targety=msg.waypoints[i].pose.pose.position.y
  213. Targetz=msg.waypoints[i].pose.pose.position.z
  214. orientationX=msg.waypoints[i].pose.pose.orientation.x
  215. orientationY=msg.waypoints[i].pose.pose.orientation.y
  216. orientationZ=msg.waypoints[i].pose.pose.orientation.z
  217. orientationW=msg.waypoints[i].pose.pose.orientation.w
  218. TargetH=quaternion_to_euler(orientationX,orientationY,orientationZ,orientationW)
  219. message_trajectory =[date_time1,locationsimtime1,simFrame,PointNumber,ego_posx,ego_posy,poseZ,egoyaw,Targetx,Targety,Targetz,TargetH]
  220. writer_trajectory.writerow(message_trajectory)
  221. PointNumber+=1
  222. simFrame+=1
  223. #robot_pos_file.close()
  224. objects_file.close()
  225. EgoState_file.close()
  226. trajectory_file.close()
  227. with open(json_path, "w") as file:
  228. data = []
  229. if pcd_exist_flag:
  230. if (Theoretical_velodyne_points_num - num_velodyne_points) / Theoretical_velodyne_points_num > 0.6:
  231. data.append('点云丢帧')
  232. '''
  233. if (Theoretical_image_raw_num - num_image_raw) / Theoretical_image_raw_num > 0.6:
  234. data.append('图像丢帧')
  235. '''
  236. else:
  237. data.append('点云缺失')
  238. if robot_pose_lost_flag or gnss_lost_flag:
  239. data.append('自车数据缺失')
  240. if final_trajectorye_lost_flag:
  241. data.append('无规划路径')
  242. if data == []:
  243. data = ['正常']
  244. # 将数据转换为 JSON 格式并写入文件
  245. json.dump(data, file, ensure_ascii=False)
  246. except:
  247. with open(json_path, "w") as file:
  248. data = ['解析程序错误']
  249. json.dump(data, file, ensure_ascii=False)
  250. # if __name__ == "__main__":
  251. # #input_dir='/home/dell/下载/VD100M6-BJ-Perception2024-10-24-15-48-07.bag'
  252. # #output_dir='/home/dell/下载'
  253. # input_dir=sys.argv[1]
  254. # output_dir = sys.argv[2]
  255. # bagname=input_dir.split('/')[-1].split('.bag')[0]
  256. # output_dir=os.path.join(output_dir, bagname)
  257. # if not os.path.exists(output_dir):
  258. # os.makedirs(output_dir)
  259. # parsehancheng(input_dir, output_dir)
  260. # if __name__ == '__main__':
  261. def parse(input_dir, output_dir):
  262. # input_dir='/media/dell/HIKSEMI/pji_DGNC/pjioutrobot_2024-08-21-15-12-04.bag'
  263. # output_dir='/media/dell/HIKSEMI/pji_DGNC'
  264. # input_dir=sys.argv[1]
  265. # output_dir = sys.argv[2]
  266. bagname=input_dir.split('/')[-1].split('.bag')[0]
  267. output_dir=os.path.join(output_dir, bagname)
  268. if not os.path.exists(output_dir):
  269. os.makedirs(output_dir)
  270. parsehancheng(input_dir, output_dir)