11from .gem import *
22from ...utils import settings
33import math
4- import time
4+ import time
55
66# ROS Headers
77import rospy
@@ -53,9 +53,9 @@ def __init__(self):
5353 self .last_reading .wiper_level = 0
5454 self .last_reading .headlights_on = False
5555
56-
5756
58-
57+
58+
5959
6060 # GNSS data subscriber
6161 self .gnss_sub = None
@@ -88,12 +88,9 @@ def time(self):
8888 # Return Gazebo simulation time
8989 return self .sim_time .to_sec ()
9090
91- def gnss_vel_callback (self , msg ):
92- self .last_reading .speed = np .linalg .norm ([msg .vector .x , msg .vector .y ] )
93-
9491 def get_reading (self ) -> GEMVehicleReading :
9592 return self .last_reading
96-
93+
9794
9895 def subscribe_sensor (self , name , callback , type = None ):
9996 if name == 'gnss' :
@@ -111,7 +108,7 @@ def gnss_callback_wrapper(gnss_msg: INSNavGeod):
111108 # Convert IMU's yaw to heading (CW from North), then to navigation yaw (CCW from East)
112109 # This handles the coordinate frame differences between Gazebo and the navigation frame
113110 # Negate yaw to convert from ROS to heading
114- heading = transforms .yaw_to_heading (- yaw - np .pi / 2 , degrees = False )
111+ heading = transforms .yaw_to_heading (- yaw - np .pi / 2 , degrees = False )
115112 navigation_yaw = transforms .heading_to_yaw (
116113 heading , degrees = False )
117114
@@ -127,10 +124,13 @@ def gnss_callback_wrapper(gnss_msg: INSNavGeod):
127124 yaw = navigation_yaw
128125 )
129126
127+ # Calculate speed from GNSS
128+ self .last_reading .speed = np .linalg .norm ([gnss_msg .ve , gnss_msg .vn ])
129+
130130 # Create GNSS reading with fused data
131131 reading = GNSSReading (
132132 pose = pose ,
133- speed = np . linalg . norm ([ gnss_msg . ve , gnss_msg . vn ]) ,
133+ speed = self . last_reading . speed ,
134134 status = 'error' if gnss_msg .error else 'ok'
135135 )
136136 # Added debug
@@ -158,12 +158,6 @@ def callback_with_numpy(msg: PointCloud2):
158158 callback (points )
159159 self .top_lidar_sub = rospy .Subscriber (topic , PointCloud2 , callback_with_numpy )
160160
161- elif name == 'imu' :
162- topic = self .ros_sensor_topics [name ]
163- if type is not None and type is not Imu :
164- raise ValueError ("GEMGazeboInterface only supports Imu for IMU data" )
165- self .imu_sub = rospy .Subscriber (topic , Imu , callback )
166-
167161 elif name == 'front_camera' :
168162 topic = self .ros_sensor_topics [name ]
169163 if type is not None and (type is not Image and type is not cv2 .Mat ):
@@ -200,7 +194,7 @@ def send_command(self, command : GEMVehicleCommand):
200194 # Skip command, similar to hardware interface
201195 return
202196 self .last_command_time = t
203-
197+
204198 # Get current speed
205199 v = self .last_reading .speed
206200
@@ -209,36 +203,36 @@ def send_command(self, command : GEMVehicleCommand):
209203 self .last_reading .accelerator_pedal_position = command .accelerator_pedal_position
210204 self .last_reading .brake_pedal_position = command .brake_pedal_position
211205 self .last_reading .steering_wheel_angle = command .steering_wheel_angle
212-
206+
213207 # Convert pedal to acceleration
214208 accelerator_pedal_position = np .clip (command .accelerator_pedal_position , 0.0 , 1.0 )
215209 brake_pedal_position = np .clip (command .brake_pedal_position , 0.0 , 1.0 )
216-
210+
217211 # Zero out accelerator if brake is active (just like hardware interface)
218212 if brake_pedal_position > 0.0 :
219213 accelerator_pedal_position = 0.0
220-
214+
221215 # Calculate acceleration from pedal positions
222216 acceleration = pedal_positions_to_acceleration (accelerator_pedal_position , brake_pedal_position , v , 0 , 1 )
223-
217+
224218 # Apply reasonable limits to acceleration
225219 max_accel = settings .get ('vehicle.limits.max_acceleration' , 1.0 )
226220 max_decel = settings .get ('vehicle.limits.max_deceleration' , - 2.0 )
227221 acceleration = np .clip (acceleration , max_decel , max_accel )
228-
222+
229223 # Convert wheel angle to steering angle (front wheel angle)
230224 phides = steer2front (command .steering_wheel_angle )
231-
225+
232226 # Apply steering angle limits
233227 min_wheel_angle = settings .get ('vehicle.geometry.min_wheel_angle' , - 0.6 )
234228 max_wheel_angle = settings .get ('vehicle.geometry.max_wheel_angle' , 0.6 )
235229 phides = np .clip (phides , min_wheel_angle , max_wheel_angle )
236-
230+
237231 # Calculate target speed based on acceleration
238232 # Don't use infinite speed, instead calculate a reasonable target speed
239233 current_speed = v
240234 target_speed = current_speed
241-
235+
242236 if acceleration > 0 :
243237 # Accelerating - set target speed to current speed plus some increment
244238 # This is more realistic than infinite speed
@@ -248,16 +242,16 @@ def send_command(self, command : GEMVehicleCommand):
248242 # Braking - set target speed to zero if deceleration is significant
249243 if brake_pedal_position > 0.1 :
250244 target_speed = 0.0
251-
245+
252246 # Create and publish drive message
253247 msg = AckermannDrive ()
254248 msg .acceleration = acceleration
255249 msg .speed = target_speed
256250 msg .steering_angle = phides
257251 msg .steering_angle_velocity = command .steering_wheel_speed # Respect steering velocity limit
258-
252+
259253 # Debug output
260254 print (f"[ACKERMANN] Speed: { msg .speed :.2f} , Accel: { msg .acceleration :.2f} , Steer: { msg .steering_angle :.2f} " )
261-
255+
262256 self .ackermann_pub .publish (msg )
263- self .last_command = command
257+ self .last_command = command
0 commit comments