37 from sensor_msgs.msg
import Imu
38 from tf.transformations
import quaternion_from_euler
39 from dynamic_reconfigure.server
import Server
40 from razor_imu_9dof.cfg
import imuConfig
41 from diagnostic_msgs.msg
import DiagnosticArray, DiagnosticStatus, KeyValue
43 degrees2rad = math.pi/180.0
44 imu_yaw_calibration = 0.0
48 global imu_yaw_calibration
49 rospy.loginfo(
"""Reconfigure request for yaw_calibration: %d""" %(config[
'yaw_calibration']))
51 imu_yaw_calibration = config[
'yaw_calibration']
52 rospy.loginfo(
"Set imu_yaw_calibration to %d" % (imu_yaw_calibration))
55 rospy.init_node(
"razor_node")
69 imuMsg.orientation_covariance = [
79 imuMsg.angular_velocity_covariance = [
89 imuMsg.linear_acceleration_covariance = [
96 port = rospy.get_param(
'~port',
'/dev/ttyUSB0')
97 topic = rospy.get_param(
'~topic',
'imu')
98 frame_id = rospy.get_param(
'~frame_id',
'base_imu_link')
103 accel_x_min = rospy.get_param(
'~accel_x_min', -250.0)
104 accel_x_max = rospy.get_param(
'~accel_x_max', 250.0)
105 accel_y_min = rospy.get_param(
'~accel_y_min', -250.0)
106 accel_y_max = rospy.get_param(
'~accel_y_max', 250.0)
107 accel_z_min = rospy.get_param(
'~accel_z_min', -250.0)
108 accel_z_max = rospy.get_param(
'~accel_z_max', 250.0)
111 magn_x_min = rospy.get_param(
'~magn_x_min', -600.0)
112 magn_x_max = rospy.get_param(
'~magn_x_max', 600.0)
113 magn_y_min = rospy.get_param(
'~magn_y_min', -600.0)
114 magn_y_max = rospy.get_param(
'~magn_y_max', 600.0)
115 magn_z_min = rospy.get_param(
'~magn_z_min', -600.0)
116 magn_z_max = rospy.get_param(
'~magn_z_max', 600.0)
117 calibration_magn_use_extended = rospy.get_param(
'~calibration_magn_use_extended',
False)
118 magn_ellipsoid_center = rospy.get_param(
'~magn_ellipsoid_center', [0, 0, 0])
119 magn_ellipsoid_transform = rospy.get_param(
'~magn_ellipsoid_transform', [[0, 0, 0], [0, 0, 0], [0, 0, 0]])
120 imu_yaw_calibration = rospy.get_param(
'~imu_yaw_calibration', 0.0)
123 gyro_average_offset_x = rospy.get_param(
'~gyro_average_offset_x', 0.0)
124 gyro_average_offset_y = rospy.get_param(
'~gyro_average_offset_y', 0.0)
125 gyro_average_offset_z = rospy.get_param(
'~gyro_average_offset_z', 0.0)
132 pub = rospy.Publisher(topic, Imu, queue_size=1)
133 srv = Server(imuConfig, reconfig_callback)
134 diag_pub = rospy.Publisher(
'diagnostics', DiagnosticArray, queue_size=1)
135 diag_pub_time = rospy.get_time();
138 rospy.loginfo(
"Opening %s...", port)
140 ser = serial.Serial(port=port, baudrate=57600, timeout=1)
142 except serial.serialutil.SerialException:
143 rospy.logerr(
"IMU not found at port "+port +
". Did you specify the correct port in the launch file?")
151 accel_factor = 9.806 / 256.0
152 rospy.loginfo(
"Giving the razor IMU board 5 seconds to boot...")
157 ser.write((
'#o0').encode(
"utf-8"))
163 discard = ser.readlines()
166 ser.write((
'#ox').encode(
"utf-8"))
168 rospy.loginfo(
"Writing calibration values to razor IMU board...")
170 ser.write((
'#caxm' + str(accel_x_min)).encode(
"utf-8"))
171 ser.write((
'#caxM' + str(accel_x_max)).encode(
"utf-8"))
172 ser.write((
'#caym' + str(accel_y_min)).encode(
"utf-8"))
173 ser.write((
'#cayM' + str(accel_y_max)).encode(
"utf-8"))
174 ser.write((
'#cazm' + str(accel_z_min)).encode(
"utf-8"))
175 ser.write((
'#cazM' + str(accel_z_max)).encode(
"utf-8"))
177 if (
not calibration_magn_use_extended):
178 ser.write((
'#cmxm' + str(magn_x_min)).encode(
"utf-8"))
179 ser.write((
'#cmxM' + str(magn_x_max)).encode(
"utf-8"))
180 ser.write((
'#cmym' + str(magn_y_min)).encode(
"utf-8"))
181 ser.write((
'#cmyM' + str(magn_y_max)).encode(
"utf-8"))
182 ser.write((
'#cmzm' + str(magn_z_min)).encode(
"utf-8"))
183 ser.write((
'#cmzM' + str(magn_z_max)).encode(
"utf-8"))
185 ser.write((
'#ccx' + str(magn_ellipsoid_center[0])).encode(
"utf-8"))
186 ser.write((
'#ccy' + str(magn_ellipsoid_center[1])).encode(
"utf-8"))
187 ser.write((
'#ccz' + str(magn_ellipsoid_center[2])).encode(
"utf-8"))
188 ser.write((
'#ctxX' + str(magn_ellipsoid_transform[0][0])).encode(
"utf-8"))
189 ser.write((
'#ctxY' + str(magn_ellipsoid_transform[0][1])).encode(
"utf-8"))
190 ser.write((
'#ctxZ' + str(magn_ellipsoid_transform[0][2])).encode(
"utf-8"))
191 ser.write((
'#ctyX' + str(magn_ellipsoid_transform[1][0])).encode(
"utf-8"))
192 ser.write((
'#ctyY' + str(magn_ellipsoid_transform[1][1])).encode(
"utf-8"))
193 ser.write((
'#ctyZ' + str(magn_ellipsoid_transform[1][2])).encode(
"utf-8"))
194 ser.write((
'#ctzX' + str(magn_ellipsoid_transform[2][0])).encode(
"utf-8"))
195 ser.write((
'#ctzY' + str(magn_ellipsoid_transform[2][1])).encode(
"utf-8"))
196 ser.write((
'#ctzZ' + str(magn_ellipsoid_transform[2][2])).encode(
"utf-8"))
198 ser.write((
'#cgx' + str(gyro_average_offset_x)).encode(
"utf-8"))
199 ser.write((
'#cgy' + str(gyro_average_offset_y)).encode(
"utf-8"))
200 ser.write((
'#cgz' + str(gyro_average_offset_z)).encode(
"utf-8"))
204 ser.write((
'#p').encode(
"utf-8"))
205 calib_data = ser.readlines()
206 calib_data_print =
"Printing set calibration values:\r\n" 207 for row
in calib_data:
208 line = bytearray(row).decode(
"utf-8")
209 calib_data_print += line
210 rospy.loginfo(calib_data_print)
213 ser.write((
'#o1').encode(
"utf-8"))
218 rospy.loginfo(
"Flushing first 200 IMU entries...")
219 for x
in range(0, 200):
220 line = bytearray(ser.readline()).decode(
"utf-8")
221 rospy.loginfo(
"Publishing IMU data...")
225 while not rospy.is_shutdown():
228 line = bytearray(ser.readline()).decode(
"utf-8")
229 if ((line.find(
"#YPRAG=") == -1)
or (line.find(
"\r\n") == -1)):
230 rospy.logwarn(
"Bad IMU data or bad sync")
231 errcount = errcount+1
233 line = line.replace(
"#YPRAG=",
"")
235 line = line.replace(
"\r\n",
"")
236 words = line.split(
",")
238 rospy.logwarn(
"Bad IMU data or bad sync")
239 errcount = errcount+1
244 yaw_deg = -float(words[0])
245 yaw_deg = yaw_deg + imu_yaw_calibration
247 yaw_deg = yaw_deg - 360.0
249 yaw_deg = yaw_deg + 360.0
250 yaw = yaw_deg*degrees2rad
252 pitch = -float(words[1])*degrees2rad
253 roll = float(words[2])*degrees2rad
258 imuMsg.linear_acceleration.x = -float(words[3]) * accel_factor
259 imuMsg.linear_acceleration.y = float(words[4]) * accel_factor
260 imuMsg.linear_acceleration.z = float(words[5]) * accel_factor
262 imuMsg.angular_velocity.x = float(words[6])
264 imuMsg.angular_velocity.y = -float(words[7])
266 imuMsg.angular_velocity.z = -float(words[8])
268 q = quaternion_from_euler(roll,pitch,yaw)
269 imuMsg.orientation.x = q[0]
270 imuMsg.orientation.y = q[1]
271 imuMsg.orientation.z = q[2]
272 imuMsg.orientation.w = q[3]
273 imuMsg.header.stamp= rospy.Time.now()
274 imuMsg.header.frame_id = frame_id
275 imuMsg.header.seq = seq
279 if (diag_pub_time < rospy.get_time()) :
281 diag_arr = DiagnosticArray()
282 diag_arr.header.stamp = rospy.get_rostime()
283 diag_arr.header.frame_id =
'1' 284 diag_msg = DiagnosticStatus()
285 diag_msg.name =
'Razor_Imu' 286 diag_msg.level = DiagnosticStatus.OK
287 diag_msg.message =
'Received AHRS measurement' 288 diag_msg.values.append(KeyValue(
'roll (deg)',
289 str(roll*(180.0/math.pi))))
290 diag_msg.values.append(KeyValue(
'pitch (deg)',
291 str(pitch*(180.0/math.pi))))
292 diag_msg.values.append(KeyValue(
'yaw (deg)',
293 str(yaw*(180.0/math.pi))))
294 diag_msg.values.append(KeyValue(
'sequence number', str(seq)))
295 diag_arr.status.append(diag_msg)
296 diag_pub.publish(diag_arr)
def reconfig_callback(config, level)