16
16
import message_filters
17
17
import cv2
18
18
from transformations import *
19
+ from swarm_msgs .msg import DroneTraj
20
+ import struct
21
+ from swarm_msgs .msg import VIOFrame
19
22
20
23
cur_trans = None
21
24
pub = None
@@ -30,7 +33,7 @@ def __init__(self):
30
33
self .enable_mesher = rospy .get_param ('~enable_mesher' , True )
31
34
self .enable_rendering = rospy .get_param ('~enable_rendering' , True )
32
35
self .output_map = rospy .get_param ('~output_map' , False )
33
-
36
+ self . enable_submap = rospy . get_param ( '~enable_submap' , False )
34
37
35
38
if cuda :
36
39
ti .init (arch = ti .cuda , device_memory_fraction = 0.5 , dynamic_index = True , offline_cache = True )
@@ -40,6 +43,7 @@ def __init__(self):
40
43
self .disp_level = 0
41
44
self .count = 0
42
45
self .cur_pose = None ## Naive approach, need sync!!!
46
+ self .cur_frame = None ## Naive approach, need sync!!!
43
47
self .initial_mapping ()
44
48
45
49
if self .enable_rendering :
@@ -52,21 +56,7 @@ def __init__(self):
52
56
self .pub_occ = rospy .Publisher ('/occ' , PointCloud2 , queue_size = 10 )
53
57
self .pub_tsdf_surface = rospy .Publisher ('/pub_tsdf_surface' , PointCloud2 , queue_size = 10 )
54
58
55
- self .pose_sub = message_filters .Subscriber ('~pose' , PoseStamped )
56
- self .depth_sub = message_filters .Subscriber ('~depth' , Image , queue_size = 10 )
57
-
58
- if self .texture_enabled :
59
- if self .texture_compressed :
60
- self .image_sub = message_filters .Subscriber ('~image' , CompressedImage , queue_size = 10 )
61
- else :
62
- self .image_sub = message_filters .Subscriber ('~image' , Image )
63
- self .ts = message_filters .ApproximateTimeSynchronizer ([self .depth_sub , self .image_sub , self .pose_sub ], 10 , slop = 0.03 )
64
- self .ts .registerCallback (self .process_depth_image_pose )
65
-
66
- else :
67
- self .ts = message_filters .ApproximateTimeSynchronizer ([self .depth_sub , self .pose_sub ], 10 , slop = 0.03 )
68
- self .ts .registerCallback (self .process_depth_pose )
69
-
59
+ self .init_subscribers ()
70
60
fx_dep = rospy .get_param ('Kdepth/fx' , 384.2377014160156 )
71
61
fy_dep = rospy .get_param ('Kdepth/fy' , 384.2377014160156 )
72
62
cx_dep = rospy .get_param ('Kdepth/cx' , 323.4873046875 )
@@ -81,6 +71,36 @@ def __init__(self):
81
71
self .K = np .array ([fx_dep , 0.0 , cx_dep , 0.0 , fy_dep , cy_dep , 0.0 , 0.0 , 1.0 ])
82
72
self .Kcolor = np .array ([fx_color , 0.0 , cx_color , 0.0 , fy_color , cy_color , 0.0 , 0.0 , 1.0 ])
83
73
74
+ def init_subscribers (self ):
75
+ self .depth_sub = message_filters .Subscriber ('~depth' , Image , queue_size = 10 )
76
+
77
+ if self .enable_submap :
78
+
79
+ self .frame_sub = message_filters .Subscriber ('~frame_local' , VIOFrame )
80
+ self .traj_sub = rospy .Subscriber ("~traj" , DroneTraj , self .traj_callback , queue_size = 10 , tcp_nodelay = True )
81
+ if self .texture_enabled :
82
+ if self .texture_compressed :
83
+ self .image_sub = message_filters .Subscriber ('~image' , CompressedImage , queue_size = 10 )
84
+ else :
85
+ self .image_sub = message_filters .Subscriber ('~image' , Image )
86
+ self .ts = message_filters .ApproximateTimeSynchronizer ([self .depth_sub , self .image_sub , self .frame_sub ], 10 , slop = 0.03 )
87
+ self .ts .registerCallback (self .process_depth_image_frame )
88
+ else :
89
+ self .ts = message_filters .ApproximateTimeSynchronizer ([self .depth_sub , self .frame_sub ], 10 , slop = 0.03 )
90
+ self .ts .registerCallback (self .process_depth_frame )
91
+ else :
92
+ self .pose_sub = message_filters .Subscriber ('~pose' , PoseStamped )
93
+ if self .texture_enabled :
94
+ if self .texture_compressed :
95
+ self .image_sub = message_filters .Subscriber ('~image' , CompressedImage , queue_size = 10 )
96
+ else :
97
+ self .image_sub = message_filters .Subscriber ('~image' , Image )
98
+ self .ts = message_filters .ApproximateTimeSynchronizer ([self .depth_sub , self .image_sub , self .pose_sub ], 10 , slop = 0.03 )
99
+ self .ts .registerCallback (self .process_depth_image_pose )
100
+ else :
101
+ self .ts = message_filters .ApproximateTimeSynchronizer ([self .depth_sub , self .pose_sub ], 10 , slop = 0.03 )
102
+ self .ts .registerCallback (self .process_depth_pose )
103
+
84
104
def get_general_mapping_opts (self ):
85
105
max_disp_particles = rospy .get_param ('~disp/max_disp_particles' , 8000000 )
86
106
occupy_thres = rospy .get_param ('~occupy_thres' , 0 )
@@ -124,7 +144,6 @@ def get_submap_opts(self):
124
144
return opts
125
145
126
146
def initial_mapping (self ):
127
- self .enable_submap = rospy .get_param ('~enable_submap' , False )
128
147
self .mapping_type = rospy .get_param ('~mapping_type' , 'tsdf' )
129
148
self .texture_enabled = rospy .get_param ('~texture_enabled' , True )
130
149
max_mesh = rospy .get_param ('~disp/max_mesh' , 1000000 )
@@ -151,6 +170,7 @@ def initial_mapping(self):
151
170
if self .enable_mesher :
152
171
self .mesher = MarchingCubeMesher (self .mapping , max_mesh , tsdf_surface_thres = self .voxel_size * 5 )
153
172
173
+ #TODO: Move test to test.py
154
174
def test_mesher (self ):
155
175
self .mapping .init_sphere ()
156
176
self .mesher .generate_mesh (1 )
@@ -162,14 +182,33 @@ def update_test_mesher(self):
162
182
self .mapping .cvt_TSDF_to_voxels_slice (self .render .slice_z , 100 )
163
183
self .render .set_particles (self .mapping .export_TSDF_xyz , self .mapping .export_color )
164
184
185
+ def process_depth_frame (self , depth_msg , frame ):
186
+ self .cur_frame = frame
187
+ self .depth_msg = depth_msg
188
+ self .rgb_array = np .array ([], dtype = int )
189
+ self .texture_image = np .array ([], dtype = int )
190
+
191
+ def process_depth_image_frame (self , depth_msg , image , frame ):
192
+ if type (image ) == CompressedImage :
193
+ np_arr = np .frombuffer (image .data , np .uint8 )
194
+ self .texture_image = cv2 .imdecode (np_arr , cv2 .IMREAD_COLOR )
195
+ else :
196
+ np_arr = np .frombuffer (image .data , np .uint8 )
197
+ np_arr = np_arr .reshape ((image .height , image .width , - 1 ))
198
+ self .texture_image = np_arr
199
+ self .depth_msg = depth_msg
200
+ self .rgb_array = np .array ([], dtype = int )
201
+ self .cur_frame = frame
165
202
166
203
def process_depth_pose (self , depth_msg , pose ):
204
+ #TODO: frame from pose
167
205
self .cur_pose = pose
168
206
self .depth_msg = depth_msg
169
207
self .rgb_array = np .array ([], dtype = int )
170
208
self .texture_image = np .array ([], dtype = int )
171
209
172
210
def process_depth_image_pose (self , depth_msg , image , pose ):
211
+ #TODO: frame from pose
173
212
if type (image ) == CompressedImage :
174
213
np_arr = np .frombuffer (image .data , np .uint8 )
175
214
self .texture_image = cv2 .imdecode (np_arr , cv2 .IMREAD_COLOR )
@@ -190,23 +229,18 @@ def process_pcl_pose(self, msg, pose):
190
229
# self.taichimapping_pcl_callback(pose, xyz_array, rgb_array)
191
230
192
231
def update (self ):
193
- if self .cur_pose is not None :
194
- self .taichimapping_depth_callback (self .cur_pose , self .depth_msg , self .rgb_array )
232
+ if self .cur_frame is not None :
233
+ self .taichimapping_depth_callback (self .cur_frame , self .depth_msg , self .rgb_array )
195
234
self .cur_pose = None
196
235
else :
197
236
if self .mapping_type == "tsdf" and self .enable_rendering :
198
237
if self .render .enable_slice_z :
199
238
self .mapping .cvt_TSDF_to_voxels_slice (self .render .slice_z )
200
239
self .render .set_particles (self .mapping .export_TSDF_xyz , self .mapping .export_color )
201
240
202
-
203
-
204
- def taichimapping_depth_callback (self , pose , depth_msg , rgb_array = None ):
241
+ def taichimapping_depth_callback (self , frame , depth_msg , rgb_array = None ):
205
242
mapping = self .mapping
206
-
207
243
start_time = time .time ()
208
-
209
- _R , _T = pose_msg_to_numpy (pose .pose )
210
244
211
245
t_pcl2npy = (time .time () - start_time )* 1000
212
246
start_time = time .time ()
@@ -216,7 +250,15 @@ def taichimapping_depth_callback(self, pose, depth_msg, rgb_array=None):
216
250
depthmap = np .frombuffer (depth_msg .data , dtype = np .uint16 )
217
251
depthmap = np .reshape (depthmap , (h , w ))
218
252
219
- mapping .recast_depth_to_map (_R , _T , depthmap , self .texture_image , w , h , self .K , self .Kcolor )
253
+ if self .enable_submap :
254
+ pose = pose_msg_to_numpy (frame .odom .pose .pose )
255
+ frame_id = frame .frame_id
256
+ print ("process frame" , frame_id )
257
+ ext = pose_msg_to_numpy (frame .extrinsics [0 ])
258
+ mapping .recast_depth_to_map_by_frame (frame_id , frame .is_keyframe , pose , ext , depthmap , self .texture_image , w , h , self .K , self .Kcolor )
259
+ else :
260
+ R , T = pose_msg_to_numpy (frame .odom .pose .pose )
261
+ mapping .recast_depth_to_map_by (frame_id , R , T , depthmap , self .texture_image , w , h , self .K , self .Kcolor )
220
262
221
263
t_recast = (time .time () - start_time )* 1000
222
264
@@ -297,6 +339,12 @@ def taichimapping_pcl_callback(self, pose, xyz_array, rgb_array=None):
297
339
298
340
self .count += 1
299
341
print (f"Time: pcl2npy { t_pcl2npy :.1f} ms t_recast { t_recast :.1f} ms ms t_v2p { t_v2p :.1f} ms t_pubros { t_pubros :.1f} ms t_render { t_render :.1f} ms" )
342
+
343
+ def traj_callback (self , traj ):
344
+ frame_poses = {}
345
+ for i in range (len (traj .frame_ids )):
346
+ frame_poses [traj .frame_ids [i ]] = pose_msg_to_numpy (traj .poses [i ])
347
+ self .mapping .set_frame_poses (frame_poses )
300
348
301
349
def pub_to_ros_surface (self , pos_ , colors_ , TEXTURE_ENABLED ):
302
350
if TEXTURE_ENABLED :
0 commit comments