11from .gem import *
22from ...utils import settings
33import math
4+ import time
45
56# ROS Headers
67import rospy
78from std_msgs .msg import String , Bool , Float32 , Float64
89from sensor_msgs .msg import Image ,PointCloud2
10+ import message_filters
911try :
1012 from novatel_gps_msgs .msg import NovatelPosition , NovatelXYZ , Inspva
1113except ImportError :
@@ -55,6 +57,7 @@ def __init__(self):
5557 self .front_depth_sub = None
5658 self .top_lidar_sub = None
5759 self .stereo_sub = None
60+ self .sync = None
5861 self .faults = []
5962
6063 # -------------------- PACMod setup --------------------
@@ -151,6 +154,7 @@ def subscribe_sensor(self, name, callback, type = None):
151154 if name == 'gnss' :
152155 topic = self .ros_sensor_topics [name ]
153156 if topic .endswith ('inspva' ):
157+ #GEM e2 uses Novatel GNSS
154158 if type is not None and (type is not Inspva and type is not GNSSReading ):
155159 raise ValueError ("GEMHardwareInterface GEM e2 only supports Inspva/GNSSReading for GNSS" )
156160 if type is Inspva :
@@ -169,24 +173,25 @@ def callback_with_gnss_reading(inspva_msg: Inspva):
169173 callback (GNSSReading (pose ,speed ,inspva_msg .status ))
170174 self .gnss_sub = rospy .Subscriber (topic , Inspva , callback_with_gnss_reading )
171175 else :
172- #assume it's septentrio
176+ #assume it's septentrio on GEM e4
173177 if type is not None and (type is not INSNavGeod and type is not GNSSReading ):
174178 raise ValueError ("GEMHardwareInterface GEM e4 only supports INSNavGeod/GNSSReading for GNSS" )
175179 if type is INSNavGeod :
176180 self .gnss_sub = rospy .Subscriber (topic , INSNavGeod , callback )
177181 else :
178182 def callback_with_gnss_reading (msg : INSNavGeod ):
179183 pose = ObjectPose (ObjectFrameEnum .GLOBAL ,
180- x = msg .longitude ,
181- y = msg .latitude ,
184+ t = self .time (),
185+ x = math .degrees (msg .longitude ), #Septentrio GNSS uses radians rather than degrees
186+ y = math .degrees (msg .latitude ),
182187 z = msg .height ,
183188 yaw = math .radians (msg .heading ), #heading from north in degrees (TODO: maybe?? check this)
184189 roll = math .radians (msg .roll ),
185190 pitch = math .radians (msg .pitch ),
186191 )
187192 speed = np .sqrt (msg .ve ** 2 + msg .vn ** 2 )
188193 callback (GNSSReading (pose ,speed ,('error' if msg .error else 'ok' )))
189- self .gnss_sub = rospy .Subscriber (topic , Inspva , callback_with_gnss_reading )
194+ self .gnss_sub = rospy .Subscriber (topic , INSNavGeod , callback_with_gnss_reading )
190195 elif name == 'top_lidar' :
191196 topic = self .ros_sensor_topics [name ]
192197 if type is not None and (type is not PointCloud2 and type is not np .ndarray ):
@@ -227,6 +232,40 @@ def callback_with_cv2(msg : Image):
227232 cv_image = conversions .ros_Image_to_cv2 (msg , desired_encoding = "passthrough" )
228233 callback (cv_image )
229234 self .front_depth_sub = rospy .Subscriber (topic , Image , callback_with_cv2 )
235+ elif name == 'sensor_fusion_Lidar_Camera_GNSS' :
236+ def callback_with_cv2_numpy_gnss (rgb_image_msg : Image , lidar_pc2_msg : PointCloud2 , gnss_msg : INSNavGeod ):
237+ points = conversions .ros_PointCloud2_to_numpy (lidar_pc2_msg , want_rgb = False )
238+ cv_image = conversions .ros_Image_to_cv2 (rgb_image_msg , desired_encoding = "bgr8" )
239+ pose = ObjectPose (ObjectFrameEnum .GLOBAL ,
240+ t = 0 ,
241+ x = gnss_msg .longitude ,
242+ y = gnss_msg .latitude ,
243+ z = gnss_msg .height ,
244+ yaw = math .radians (gnss_msg .heading ), #heading from north in degrees (TODO: maybe?? check this)
245+ roll = math .radians (gnss_msg .roll ),
246+ pitch = math .radians (gnss_msg .pitch ),
247+ )
248+ speed = np .sqrt (gnss_msg .ve ** 2 + gnss_msg .vn ** 2 )
249+ callback (cv_image ,points ,GNSSReading (pose ,speed ,('error' if gnss_msg .error else 'ok' )))
250+ topic_camera = self .ros_sensor_topics ['front_camera' ]
251+ topic_lidar = self .ros_sensor_topics ['top_lidar' ]
252+ topic_gnss = self .ros_sensor_topics ['gnss' ]
253+ self .front_camera_sub = message_filters .Subscriber (topic_camera , Image )
254+ self .top_lidar_sub = message_filters .Subscriber (topic_lidar , PointCloud2 )
255+ self .gnss_sub = message_filters .Subscriber (topic_gnss , INSNavGeod )
256+ self .sync = message_filters .ApproximateTimeSynchronizer ([self .front_camera_sub , self .top_lidar_sub ,self .gnss_sub ], queue_size = 10 , slop = 0.1 )
257+ self .sync .registerCallback (callback_with_cv2_numpy_gnss )
258+ elif name == 'sensor_fusion_Lidar_Camera' :
259+ def callback_with_cv2_numpy (rgb_image_msg : Image , lidar_pc2_msg : PointCloud2 ):
260+ points = conversions .ros_PointCloud2_to_numpy (lidar_pc2_msg , want_rgb = False )
261+ cv_image = conversions .ros_Image_to_cv2 (rgb_image_msg , desired_encoding = "bgr8" )
262+ callback (cv_image ,points )
263+ topic_camera = self .ros_sensor_topics ['front_camera' ]
264+ topic_lidar = self .ros_sensor_topics ['top_lidar' ]
265+ self .front_camera_sub = message_filters .Subscriber (topic_camera , Image )
266+ self .top_lidar_sub = message_filters .Subscriber (topic_lidar , PointCloud2 )
267+ self .sync = message_filters .ApproximateTimeSynchronizer ([self .front_camera_sub , self .top_lidar_sub ], queue_size = 10 , slop = 0.1 )
268+ self .sync .registerCallback (callback_with_cv2_numpy )
230269
231270
232271 # PACMod enable callback function
0 commit comments