Go to the documentation of this file.00001 import re
00002 from threading import Thread
00003 import rospy
00004 import rostopic
00005 from BAL.Handlers.keepAliveHandler import KeepAliveHandler
00006 from BAL.Header.Requests.PublishRequest import PublishRequest
00007 from BAL.Header.Requests.imuRequest import IMURequest
00008 from BAL.Header.Response.ParamBuildResponse import IMU
00009
00010 __author__ = 'tom1231'
00011 from rospy import Publisher, Service
00012 from sensor_msgs.msg import Imu, MagneticField
00013 from BAL.Interfaces.Device import Device
00014 from tf.transformations import euler_from_quaternion, quaternion_from_euler
00015 from geometry_msgs.msg import Quaternion
00016 from math import pi
00017 from ric_board.srv._calibIMU import calibIMU, calibIMURequest
00018 from ric_board.msg._imuCalib import imuCalib
00019
00020 CALIB_ID = 1
00021 PUB_ID = 2
00022
00023 class RiCIMU(Device):
00024 def __init__(self, param, output):
00025 Device.__init__(self, param.getIMUName(), output)
00026 self._frameId = param.getIMUFrameId()
00027 self._angle = param.getIMUOrientation()
00028 self._pub = Publisher('%s_AGQ' % self._name, Imu, queue_size=param.getIMUPubHz())
00029 self._pubMag = Publisher('%s_M' % self._name, MagneticField, queue_size=param.getIMUPubHz())
00030 self._pubCalib = Publisher('/imu_calib_publisher', imuCalib, queue_size=param.getIMUPubHz())
00031 Service('/imu_Calibration', calibIMU, self.serviceCallBack)
00032 self._haveRightToPublish = False
00033 self._calib = False
00034 self._xMax = 0.0
00035 self._yMax = 0.0
00036 self._zMax = 0.0
00037 self._xMin = 0.0
00038 self._yMin = 0.0
00039 self._zMin = 0.0
00040
00041
00042 def getType(self):
00043 return IMU
00044
00045 def serviceCallBack(self, request):
00046 validStatus = True
00047
00048 if request.status == calibIMURequest.START_CALIB:
00049 rospy.loginfo("Calibration begin")
00050 self._output.write(IMURequest(calibIMURequest.START_CALIB).dataTosend())
00051 self._calib = True
00052
00053 self._xMax = request.xMax
00054 self._yMax = request.yMax
00055 self._zMax = request.zMax
00056 self._xMin = request.xMin
00057 self._yMin = request.yMin
00058 self._zMin = request.zMin
00059
00060 elif request.status == calibIMURequest.STOP_CALIB:
00061 rospy.loginfo("Calibration end")
00062 self._output.write(IMURequest(calibIMURequest.STOP_CALIB).dataTosend())
00063 rospy.loginfo("Calibration setting saved")
00064 self._calib = False
00065
00066 else:
00067 validStatus = False
00068 return {'ack': validStatus}
00069
00070 def publish(self, data):
00071 if not self._calib and data.getImuMsgId() == PUB_ID:
00072 q = data.getOrientation()
00073 roll, pitch, yaw = euler_from_quaternion((q.y, q.z, q.w, q.x))
00074
00075
00076 array = quaternion_from_euler((yaw + (self._angle * pi / 180)), roll, -1 * pitch)
00077 res = Quaternion()
00078 res.w = array[0]
00079 res.x = array[1]
00080 res.y = array[2]
00081 res.z = array[3]
00082
00083 msg = Imu()
00084 msg.header.frame_id = self._frameId
00085 msg.header.stamp = rospy.get_rostime()
00086 msg.orientation = res
00087 msg.linear_acceleration = data.getAcceleration()
00088 msg.angular_velocity = data.getVelocity()
00089
00090 magMsg = MagneticField()
00091 magMsg.header.frame_id = self._frameId
00092 magMsg.header.stamp = rospy.get_rostime()
00093 magMsg.magnetic_field = data.getMagnetometer()
00094
00095 self._pub.publish(msg)
00096 self._pubMag.publish(magMsg)
00097
00098 elif data.getImuMsgId() == CALIB_ID:
00099 x, y, z = data.getValues()
00100 msg = imuCalib()
00101
00102 if x > self._xMax:
00103 self._xMax = x
00104 if x < self._xMin:
00105 self._xMin = x
00106
00107 if y > self._yMax:
00108 self._yMax = y
00109 if y < self._yMin:
00110 self._yMin = y
00111
00112 if z > self._zMax:
00113 self._zMax = z
00114 if z < self._zMin:
00115 self._zMin = z
00116
00117
00118 msg.x.data = x
00119 msg.x.max = self._xMax
00120 msg.x.min = self._xMin
00121
00122 msg.y.data = y
00123 msg.y.max = self._yMax
00124 msg.y.min = self._yMin
00125
00126 msg.z.data = z
00127 msg.z.max = self._zMax
00128 msg.z.min = self._zMin
00129
00130 self._pubCalib.publish(msg)
00131
00132 def checkForSubscribers(self):
00133 try:
00134 subCheck = re.search('Subscribers:.*', rostopic.get_info_text(self._pub.name)).group(0).split(': ')[1]
00135 subMagCheck = re.search('Subscribers:.*', rostopic.get_info_text(self._pubMag.name)).group(0).split(': ')[1]
00136 subCalibCheck = \
00137 re.search('Subscribers:.*', rostopic.get_info_text(self._pubCalib.name)).group(0).split(': ')[1]
00138
00139 if not self._haveRightToPublish and (subCheck == '' or subMagCheck == '' or subCalibCheck == ''):
00140 self._output.write(PublishRequest(IMU, 0, True).dataTosend())
00141 self._haveRightToPublish = True
00142
00143 elif self._haveRightToPublish and (
00144 subCheck == 'None' and subMagCheck == 'None' and subCalibCheck == 'None'):
00145 self._output.write(PublishRequest(IMU, 0, False).dataTosend())
00146 self._haveRightToPublish = False
00147 except:
00148 pass