55import ctypes
66import struct
77
8- # from ...state import VehicleState, ObjectPose
9- # from ...onboard import Component
10-
118# OpenCV and cv2 bridge
129import cv2
1310from cv_bridge import CvBridge
1411import numpy as np
1512import os
1613import time
14+ from functools import partial
1715
18- # TODO: change these arrays to use dictionaries, format eg. {filename: data}
19- lidar_points = None
20- camera_image = None
21- fl_image = None
22- fr_image = None
23- rl_image = None
24- rr_image = None
25- depth_images = None
26- gnss_locations = None
27- frame_position = None
16+ camera_images = {"oak" : None , "fr" : None , "fl" : None , "rr" : None , "rl" : None , "fr_rect" : None , "fl_rect" : None , "rr_rect" : None , "rl_rect" : None }
17+ lidar_clouds = {"ouster" : None , "livox" : None }
18+ depth_images = {"depth" : None }
19+ gnss_locations = {"nav_fix" : None }
2820lidar_filetype = ".npz"
2921camera_filetype = ".png"
3022depth_filetype = ".tif"
3123gnss_filetype = ".npy"
3224bridge = CvBridge ()
3325
34- def lidar_callback (lidar : PointCloud2 ):
35- global lidar_points
36- lidar_points = (lidar )
37-
38- def camera_callback (img : Image ):
39- global camera_image
40- camera_image = (img )
41-
42- def fl_camera_callback (img : Image ):
43- global fl_image
44- fl_image = (img )
45-
46- def fr_camera_callback (img : Image ):
47- global fr_image
48- fr_image = (img )
26+ def lidar_callback (scanner , lidar : PointCloud2 ):
27+ global lidar_clouds
28+ lidar_clouds [scanner ] = lidar
4929
50- def rl_camera_callback ( img : Image ):
51- global rl_image
52- rl_image = ( img )
30+ def camera_callback ( camera , img : Image ):
31+ global camera_images
32+ camera_images [ camera ] = img
5333
54- def rr_camera_callback (img : Image ):
55- global rr_image
56- rr_image = (img )
57-
58- def depth_callback (img : Image ):
34+ def depth_callback (camera , img : Image ):
5935 global depth_images
60- depth_images = ( img )
36+ depth_images [ camera ] = img
6137
62- def gnss_callback (sat_fix : NavSatFix ):
38+ def gnss_callback (gnss , sat_fix : NavSatFix ):
6339 global gnss_locations
64- gnss_locations = ( sat_fix )
40+ gnss_locations [ gnss ] = sat_fix
6541
6642def pc2_to_numpy (pc2_msg , want_rgb = False ):
6743 gen = pc2 .read_points (pc2_msg , skip_nans = True )
@@ -87,74 +63,70 @@ def pc2_to_numpy(pc2_msg, want_rgb = False):
8763 else :
8864 return np .array (list (gen ),dtype = np .float32 )[:,:3 ]
8965
90- # def clear_scan():
91- # global lidar_points
92- # lidar_points = []
93- # global camera_image
94- # camera_image = []
95- # global depth_images
96- # depth_images = []
97- # global gnss_locations
98- # gnss_locations = []
66+ def clear_scan ():
67+ global camera_images
68+ for camera in camera_images :
69+ camera_images [camera ] = None
70+ global lidar_clouds
71+ for lidar in lidar_clouds :
72+ lidar_clouds [lidar ] = None
73+ global depth_images
74+ for camera in depth_images :
75+ depth_images [camera ] = None
76+ global gnss_locations
77+ for gnss in gnss_locations :
78+ gnss_locations [gnss ] = None
9979
100- # TODO: when data is stored in dictionaries, change to only save files which exist and change error checking
101- def save_scan (lidar_fn , camera_fn , fl_fn , fr_fn , rl_fn , rr_fn , depth_fn , gnss_fn , index ):
102- # if len(lidar_filenames) != len(lidar_points) or len(camera_filenames) != len(camera_image) or len(depth_filenames) != len(depth_images):
103- # print("Missing data, scan", index, "cannot be saved")
104- # print(len(lidar_filenames), len(lidar_points), len(camera_filenames), len(camera_image), len(depth_filenames), len(depth_images))
105- # return
80+ def save_scan (folder , index ):
10681 print ("Saving scan" , index )
10782
108- if frame_position != None :
109- np .save ("state" + str (index ), frame_position )
110- else :
111- print ("No state found" )
112-
113- # for i in range(len(lidar_points)):
114- # current_lidar = lidar_points[i]
115- # lidar_fn = lidar_filename + str(index) + lidar_filetype
116- pc = pc2_to_numpy (lidar_points ,want_rgb = False ) # convert lidar feed to numpy
117- np .savez (lidar_fn + str (index ) + lidar_filetype ,pc )
118-
119- # for i in range(len(camera_image)):
120- # current_camera = camera_image[i]
121- # camera_fn = camera_filenames[i] + str(index) + camera_filetype
122- cv2 .imwrite (camera_fn + str (index ) + camera_filetype ,bridge .imgmsg_to_cv2 (camera_image ))
123- cv2 .imwrite (fl_fn + str (index ) + camera_filetype ,bridge .imgmsg_to_cv2 (fl_image ))
124- cv2 .imwrite (fr_fn + str (index ) + camera_filetype ,bridge .imgmsg_to_cv2 (fr_image ))
125- cv2 .imwrite (rl_fn + str (index ) + camera_filetype ,bridge .imgmsg_to_cv2 (rl_image ))
126- cv2 .imwrite (rr_fn + str (index ) + camera_filetype ,bridge .imgmsg_to_cv2 (rr_image ))
127-
128- # for i in range(len(depth_images)):
129- dimage = bridge .imgmsg_to_cv2 (depth_images )
130- # depth_fn = depth_filenames[i] + str(index) + depth_filetype
131- dimage_non_nan = dimage [np .isfinite (dimage )]
132- # print("Depth range",np.min(dimage_non_nan),np.max(dimage_non_nan))
133- dimage = np .nan_to_num (dimage ,nan = 0 ,posinf = 0 ,neginf = 0 )
134- dimage = (dimage / 4000 * 0xffff )
135- # print("Depth pixel range",np.min(dimage),np.max(dimage))
136- dimage = dimage .astype (np .uint16 )
137- cv2 .imwrite (depth_fn + str (index ) + depth_filetype ,dimage )
83+ for lidar in lidar_clouds :
84+ lidar_points = lidar_clouds [lidar ]
85+ if lidar_points != None :
86+ lidar_fn = os .path .join (folder , lidar + str (index ) + lidar_filetype )
87+ pc = pc2_to_numpy (lidar_points , want_rgb = False ) # convert lidar feed to numpy
88+ np .savez (lidar_fn , pc )
89+
90+ for camera in camera_images :
91+ camera_image = camera_images [camera ]
92+ if camera_image != None :
93+ camera_fn = os .path .join (folder , camera + str (index ) + camera_filetype )
94+ cv2 .imwrite (camera_fn , bridge .imgmsg_to_cv2 (camera_image ))
95+
96+ for camera in depth_images :
97+ depth_image = depth_images [camera ]
98+ if depth_image != None :
99+ depth_fn = os .path .join (folder , camera + str (index ) + depth_filetype )
100+ dimage = bridge .imgmsg_to_cv2 (depth_image )
101+ dimage_non_nan = dimage [np .isfinite (dimage )]
102+ dimage = np .nan_to_num (dimage ,nan = 0 ,posinf = 0 ,neginf = 0 )
103+ dimage = (dimage / 4000 * 0xffff )
104+ dimage = dimage .astype (np .uint16 )
105+ cv2 .imwrite (depth_fn , dimage )
138106
139- # for i in range(len( gnss_locations)) :
140- # sat_fix = gnss_locations[i ]
141- # gnss_fn = gnss_filenames + str(index) + gnss_filetype
142- if gnss_locations :
143- coordinates = np .array ([gnss_locations .latitude , gnss_locations .longitude ])
144- np .save (gnss_fn + str (index ) + gnss_filetype , coordinates )
107+ for gnss in gnss_locations :
108+ location = gnss_locations [gnss ]
109+ if location != None :
110+ gnss_fn = os . path . join ( folder , gnss + str ( index ) + gnss_filetype )
111+ coordinates = np .array ([location .latitude , location .longitude ])
112+ np .save (gnss_fn + str (index ) + gnss_filetype , coordinates )
145113
146114def main (folder = 'data' ,start_index = 0 ):
147115 # Initialize node and establish subscribers
148116 rospy .init_node ("capture_ouster_oak" ,disable_signals = True )
149- ouster_sub = rospy .Subscriber ("/ouster/points" , PointCloud2 , lidar_callback )
150- # livox_sub = rospy.Subscriber("/livox/lidar", PointCloud2, lidar_callback)
151- oak_sub = rospy .Subscriber ("/oak/rgb/image_raw" , Image , camera_callback )
152- cam_fl_sub = rospy .Subscriber ("/camera_fl/arena_camera_node/image_raw" , Image , fl_camera_callback )
153- cam_fr_sub = rospy .Subscriber ("/camera_fr/arena_camera_node/image_raw" , Image , fr_camera_callback )
154- cam_rl_sub = rospy .Subscriber ("/camera_rl/arena_camera_node/image_raw" , Image , rl_camera_callback )
155- cam_rr_sub = rospy .Subscriber ("/camera_rr/arena_camera_node/image_raw" , Image , rr_camera_callback )
156- depth_sub = rospy .Subscriber ("/oak/stereo/image_raw" , Image , depth_callback )
157- gnss_sub = rospy .Subscriber ("/septentrio_gnss/navsatfix" , NavSatFix , gnss_callback )
117+ ouster_sub = rospy .Subscriber ("/ouster/points" , PointCloud2 , partial (lidar_callback , "ouster" ))
118+ livox_sub = rospy .Subscriber ("/livox/lidar" , PointCloud2 , partial (lidar_callback , "livox" ))
119+ oak_sub = rospy .Subscriber ("/oak/rgb/image_raw" , Image , partial (camera_callback , "oak" ))
120+ cam_fl_sub = rospy .Subscriber ("/camera_fl/arena_camera_node/image_raw" , Image , partial (camera_callback , "fl" ))
121+ cam_fr_sub = rospy .Subscriber ("/camera_fr/arena_camera_node/image_raw" , Image , partial (camera_callback , "fr" ))
122+ cam_rl_sub = rospy .Subscriber ("/camera_rl/arena_camera_node/image_raw" , Image , partial (camera_callback , "rl" ))
123+ cam_rr_sub = rospy .Subscriber ("/camera_rr/arena_camera_node/image_raw" , Image , partial (camera_callback , "rr" ))
124+ cam_fl_rect_sub = rospy .Subscriber ("/camera_fl/arena_camera_node/image_rect_color" , Image , partial (camera_callback , "fl_rect" ))
125+ cam_fr_rect_sub = rospy .Subscriber ("/camera_fr/arena_camera_node/image_rect_color" , Image , partial (camera_callback , "fr_rect" ))
126+ cam_rl_rect_sub = rospy .Subscriber ("/camera_rl/arena_camera_node/image_rect_color" , Image , partial (camera_callback , "rl_rect" ))
127+ cam_rr_rect_sub = rospy .Subscriber ("/camera_rr/arena_camera_node/image_rect_color" , Image , partial (camera_callback , "rr_rect" ))
128+ depth_sub = rospy .Subscriber ("/oak/stereo/image_raw" , Image , partial (depth_callback , "depth" ))
129+ gnss_sub = rospy .Subscriber ("/septentrio_gnss/navsatfix" , NavSatFix , partial (gnss_callback , "nav_fix" ))
158130
159131 # Store scans
160132 index = start_index
@@ -163,32 +135,13 @@ def main(folder='data',start_index=0):
163135 print (" Storing depth images as" , depth_filetype )
164136 print (" Ctrl+C to quit" )
165137 while True :
166- if camera_image :
167- cv2 .imshow ("result" ,bridge .imgmsg_to_cv2 (camera_image ))
138+ if camera_images [ "oak" ] :
139+ cv2 .imshow ("result" ,bridge .imgmsg_to_cv2 (camera_images [ "oak" ] ))
168140 time .sleep (.5 )
169- files = [os .path .join (folder , 'ouster' ),os .path .join (folder , 'oak' ),
170- os .path .join (folder , 'fl' ), os .path .join (folder , 'fr' ),
171- os .path .join (folder , 'rl' ), os .path .join (folder , 'rr' ),
172- os .path .join (folder , 'depth' ), os .path .join (folder , 'septentrio' )]
173- # lidar_files = [os.path.join(folder, 'ouster')]
174- # camera_files = [os.path.join(folder, 'oak'),
175- # os.path.join(folder, 'fl'), os.path.join(folder, 'fr'),
176- # os.path.join(folder, 'rl'), os.path.join(folder, 'rr')]
177- # depth_files = [os.path.join(folder, 'depth')]
178- # gnss_files = [os.path.join(folder, 'septentrio')]
179- save_scan (* files , index )
180- # clear_scan()
141+ save_scan (folder , index )
142+ clear_scan ()
181143 index += 1
182144
183- # class StateTracker(Component):
184- # def rate(self):
185- # return 4.0 # Hz
186- # def state_inputs(self):
187- # return ['vehicle']
188- # def update(self, vehicle : VehicleState):
189- # global frame_position
190- # frame_position = np.array(vehicle.pose.frame, vehicle.pose.t, vehicle.pose.x, vehicle.pose.y)
191-
192145if __name__ == '__main__' :
193146 import sys
194147 folder = 'data'
0 commit comments