Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 import roslib
00032 roslib.load_manifest('elektron_sensors')
00033
00034 import rospy
00035
00036 from sensor_msgs.msg import Imu
00037 from std_msgs.msg import Bool
00038 from std_srvs.srv import Empty, EmptyResponse
00039
00040 from PyKDL import Rotation
00041
00042 import serial
00043 import math
00044
00045
00046 class Gyro:
00047 """
00048 Class for interfacing with gyroscope on Elektron mobile robot.
00049 Responsible for retrieving data from device, calibration and
00050 calculating current orientation.
00051 """
00052
00053 def __init__(self):
00054
00055 self.device = rospy.get_param('~device', '/dev/ttyUSB0')
00056 self.baud = rospy.get_param('~baud', 38400)
00057 self.ser = serial.Serial(self.device, self.baud, timeout=1)
00058
00059
00060 self.orientation = 0
00061 self.bias = 0
00062
00063 self.calibrating = False
00064
00065 self.frame_id = 'base_footprint'
00066 self.prev_time = rospy.Time.now()
00067
00068
00069 self.pub = rospy.Publisher("/imu/data", Imu)
00070
00071
00072 self.scale = rospy.get_param('~rot_scale', 1.0)
00073
00074
00075 rospy.Service("/imu/calibrate", Empty, self.calibrateCallback)
00076
00077
00078 self.is_calibratedPublisher = rospy.Publisher('/imu/is_calibrated', Bool, latch=True)
00079
00080
00081 self.is_CalibratedResponseMsg = Bool();
00082
00083
00084
00085
00086 self.is_CalibratedResponseMsg.data = True;
00087 self.is_calibratedPublisher.publish(self.is_CalibratedResponseMsg)
00088
00089 def calibrate(self):
00090
00091 rospy.loginfo("Calibrating Gyro. Don't move the robot now")
00092 start_time = rospy.Time.now()
00093 cal_duration = rospy.Duration(5.0)
00094 offset = 0
00095 cnt = 0
00096
00097 self.ser.flushInput()
00098 while rospy.Time.now() < start_time + cal_duration:
00099
00100
00101 str = self.ser.readline()
00102 nums = str.split()
00103
00104
00105 if (len(nums) != 5):
00106 continue
00107
00108 cnt += 1
00109 gyro = int(nums[2])
00110 ref = int(nums[3])
00111 temp = int(nums[4])
00112
00113 val = ref-gyro;
00114
00115 offset += val;
00116
00117 self.bias = 1.0 * offset / cnt
00118 rospy.loginfo("Gyro calibrated with offset %f"%self.bias)
00119
00120
00121 self.is_CalibratedResponseMsg.data = True
00122 self.is_calibratedPublisher.publish(self.is_CalibratedResponseMsg)
00123
00124 return True
00125
00126
00127
00128 def calibrateCallback(self, req):
00129 """The imu/calibrate service handler."""
00130
00131 rospy.loginfo("Calibration request")
00132
00133 self.calibrating = True
00134
00135 return EmptyResponse()
00136
00137
00138 def spin(self):
00139 self.prev_time = rospy.Time.now()
00140
00141 while not rospy.is_shutdown():
00142 if self.calibrating:
00143 self.calibrate()
00144 self.calibrating = False
00145 self.prev_time = rospy.Time.now()
00146
00147
00148 imu = Imu()
00149 imu.header.frame_id = self.frame_id
00150
00151
00152 str = self.ser.readline()
00153
00154
00155 imu.header.stamp = rospy.Time.now()
00156
00157 nums = str.split()
00158
00159
00160 if (len(nums) != 5):
00161 continue
00162
00163 gyro = int(nums[2])
00164 ref = int(nums[3])
00165 temp = int(nums[4])
00166
00167 val = (ref-gyro - self.bias) * 1000 / 3 / 1024 * self.scale
00168
00169 imu.angular_velocity.x = 0
00170 imu.angular_velocity.y = 0
00171 imu.angular_velocity.z = val * math.pi / 180
00172 imu.angular_velocity_covariance = [0, 0, 0, 0, 0, 0, 0, 0, 1]
00173 imu.orientation_covariance = [0.001, 0, 0, 0, 0.001, 0, 0, 0, 0.1]
00174
00175 self.orientation += imu.angular_velocity.z * (imu.header.stamp - self.prev_time).to_sec()
00176 self.prev_time = imu.header.stamp
00177 (imu.orientation.x, imu.orientation.y, imu.orientation.z, imu.orientation.w) = Rotation.RotZ(self.orientation).GetQuaternion()
00178 self.pub.publish(imu)
00179
00180
00181
00182 if __name__ == '__main__':
00183 rospy.init_node('gyroscope')
00184 gyro = Gyro()
00185 gyro.calibrate()
00186
00187 try:
00188 gyro.spin()
00189 except rospy.ROSInterruptException: pass
00190 except IOError: pass
00191 except KeyError: pass