Go to the documentation of this file.00001
00002 import os
00003 import signal
00004 import sys
00005 import math
00006 import time
00007
00008 import rospy
00009 import tf
00010 from tf.transformations import euler_from_quaternion, quaternion_from_euler
00011
00012 from std_msgs.msg import *
00013 from nav_msgs.msg import *
00014
00015
00016 MARKER_TIME_INTERVAL = 1.0
00017 MARKER_TIME_INTERVAL_BIG = 50
00018 MARKER_TIME_INTERVAL_MID = 10
00019
00020
00021
00022 class DataOdometry(object):
00023
00024
00025 def __init__(self):
00026 rospy.loginfo("[DataOdometry] init()")
00027 self.prevOdom = None
00028 self.currOdom = None
00029 self.iniPosX = None
00030 self.iniPosY = None
00031 self.initTime = None
00032 self.lastTime = None
00033 self.totalTime = 0.0
00034 self.travDist = 0.0
00035 self.numSamples = 0
00036
00037 self.dataTime = []
00038 self.dataTravDist = []
00039
00040 self.dataX = []
00041 self.dataY = []
00042 self.dataZ = []
00043 self.dataVx = []
00044 self.dataVy = []
00045 self.dataVz = []
00046 self.dataAx = []
00047 self.dataAy = []
00048 self.dataAz = []
00049
00050 self.dataBVx = []
00051 self.dataBVy = []
00052 self.dataBVz = []
00053
00054 self.dataR = []
00055 self.dataP = []
00056 self.dataH = []
00057 self.dataVr = []
00058 self.dataVp = []
00059 self.dataVh = []
00060
00061 self.markerPointX = []
00062 self.markerPointY = []
00063 self.markerPointZ = []
00064 self.markerPointHeading = []
00065 self.markerPointTime = []
00066 self.markerLabelStr = []
00067 self.markerLabelTime = 0
00068
00069
00070
00071 def getCurrentPose(self):
00072 return self.currOdom
00073
00074
00075
00076
00077
00078 def odometryHandler(self, msg):
00079
00080 if (self.currOdom == None):
00081 self.iniPosX = msg.pose.pose.position.x
00082 self.iniPosY = msg.pose.pose.position.y
00083
00084 self.currOdom = msg
00085
00086 self.currOdom.pose.pose.position.x = self.currOdom.pose.pose.position.x - self.iniPosX
00087 self.currOdom.pose.pose.position.y = self.currOdom.pose.pose.position.y - self.iniPosY
00088
00089 self.lastTime = msg.header.stamp.to_sec()
00090 if (self.initTime == None):
00091 self.initTime = msg.header.stamp.to_sec()
00092
00093 if (self.prevOdom == None):
00094 self.prevOdom = self.currOdom
00095
00096
00097 dt = self.currOdom.header.stamp.to_sec() - self.prevOdom.header.stamp.to_sec()
00098 if (dt > 0.19):
00099 self.totalTime = self.totalTime + dt
00100 rospy.logdebug(self.totalTime)
00101
00102
00103 self.dataTime.append(self.totalTime)
00104
00105
00106 self.dataX.append(self.currOdom.pose.pose.position.y)
00107 self.dataY.append(self.currOdom.pose.pose.position.x)
00108 self.dataZ.append(-self.currOdom.pose.pose.position.z)
00109
00110
00111 dx = (self.currOdom.pose.pose.position.y - self.prevOdom.pose.pose.position.y)
00112 dy = (self.currOdom.pose.pose.position.x - self.prevOdom.pose.pose.position.x)
00113 dz = (self.currOdom.pose.pose.position.z - self.prevOdom.pose.pose.position.z)
00114
00115 self.travDist = self.travDist + math.sqrt(dx*dx + dy*dy)
00116 self.dataTravDist.append(self.travDist)
00117
00118
00119 vx = (self.currOdom.pose.pose.position.y - self.prevOdom.pose.pose.position.y) / dt
00120 vy = (self.currOdom.pose.pose.position.x - self.prevOdom.pose.pose.position.x) / dt
00121 vz = (self.currOdom.pose.pose.position.z - self.prevOdom.pose.pose.position.z) / dt
00122
00123
00124 prev_vx = 0.0
00125 prev_vy = 0.0
00126 prev_vz = 0.0
00127 if (self.numSamples > 0):
00128 prev_vx = self.dataVx[self.numSamples - 1]
00129 prev_vy = self.dataVy[self.numSamples - 1]
00130 prev_vz = self.dataVz[self.numSamples - 1]
00131
00132 vx = 0.6*prev_vx + 0.4*vx
00133 vy = 0.6*prev_vy + 0.4*vy
00134 vz = 0.6*prev_vz + 0.4*vz
00135
00136 self.dataVx.append(vx)
00137 self.dataVy.append(vy)
00138 self.dataVz.append(vz)
00139
00140 self.dataBVx.append(self.currOdom.twist.twist.linear.x)
00141 self.dataBVy.append(self.currOdom.twist.twist.linear.y)
00142 self.dataBVz.append(-self.currOdom.twist.twist.linear.z)
00143
00144 velXY = math.sqrt(vx*vx + vy*vy)
00145 velZ = math.fabs(vz)
00146 velTotal = math.sqrt(vx*vx + vy*vy + vz*vz)
00147
00148
00149 ax = (self.currOdom.twist.twist.linear.y - self.prevOdom.twist.twist.linear.y) / dt
00150 ay = (self.currOdom.twist.twist.linear.x - self.prevOdom.twist.twist.linear.x) / dt
00151 az = (self.currOdom.twist.twist.linear.z - self.prevOdom.twist.twist.linear.z) / dt
00152
00153
00154 prev_ax = 0.0
00155 prev_ay = 0.0
00156 prev_az = 0.0
00157 if (self.numSamples > 0):
00158 prev_ax = self.dataAx[self.numSamples - 1]
00159 prev_ay = self.dataAy[self.numSamples - 1]
00160 prev_az = self.dataAz[self.numSamples - 1]
00161
00162 ax = 0.6*prev_ax + 0.4*ax
00163 ay = 0.6*prev_ay + 0.4*ay
00164 az = 0.6*prev_az + 0.4*az
00165
00166 self.dataAx.append(ax)
00167 self.dataAy.append(ay)
00168 self.dataAz.append(az)
00169
00170
00171 auxOrient = self.currOdom.pose.pose.orientation
00172 quat = (auxOrient.x, auxOrient.y, auxOrient.z, auxOrient.w)
00173 [roll, pitch, yaw] = list(euler_from_quaternion(quat))
00174
00175 roll = math.degrees(roll)
00176 pitch = math.degrees(pitch)
00177 yaw = math.degrees(yaw)
00178
00179
00180 yaw_compass = yaw
00181 if (yaw < 0.0):
00182 yaw_compass = yaw + 360.0
00183
00184 self.dataR.append(roll)
00185 self.dataP.append(pitch)
00186 self.dataH.append(yaw_compass)
00187
00188
00189 self.dataVr.append(math.degrees(self.currOdom.twist.twist.angular.x))
00190 self.dataVp.append(math.degrees(self.currOdom.twist.twist.angular.y))
00191 self.dataVh.append(math.degrees(self.currOdom.twist.twist.angular.z))
00192
00193
00194 if (self.totalTime > self.markerLabelTime):
00195 self.markerPointX.append( self.currOdom.pose.pose.position.y)
00196 self.markerPointY.append( self.currOdom.pose.pose.position.x)
00197 self.markerPointZ.append(-self.currOdom.pose.pose.position.z)
00198 self.markerPointHeading.append(math.radians(yaw) + math.pi/2.0)
00199 self.markerPointTime.append(self.markerLabelTime)
00200 self.markerLabelStr.append("{0} s".format(self.markerLabelTime))
00201 self.markerLabelTime = self.markerLabelTime + MARKER_TIME_INTERVAL
00202
00203
00204 self.prevOdom = self.currOdom
00205 self.numSamples = self.numSamples + 1
00206
00207
00208
00209
00210 def getTime(self):
00211
00212 self.totalTime
00213
00214
00215 def getRangeDataX(self):
00216 if (len(self.dataX) <= 0):
00217 return [0, 0]
00218 minVal = self.dataX[0]
00219 maxVal = self.dataX[0]
00220 for val in self.dataX:
00221 if (minVal > val):
00222 minVal = val
00223 if (maxVal < val):
00224 maxVal = val
00225 return [minVal, maxVal]
00226
00227
00228 def getRangeDataY(self):
00229 if (len(self.dataY) <= 0):
00230 return [0, 0]
00231 minVal = self.dataY[0]
00232 maxVal = self.dataY[0]
00233 for val in self.dataY:
00234 if (minVal > val):
00235 minVal = val
00236 if (maxVal < val):
00237 maxVal = val
00238 return [minVal, maxVal]
00239
00240
00241 def getRangeDataZ(self):
00242 if (len(self.dataZ) <= 0):
00243 return [0, 0]
00244 minVal = self.dataZ[0]
00245 maxVal = self.dataZ[0]
00246 for val in self.dataZ:
00247 if (minVal > val):
00248 minVal = val
00249 if (maxVal < val):
00250 maxVal = val
00251 return [minVal, maxVal]
00252
00253
00254