00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 import time
00019 import csv
00020 import datetime
00021 import rospy
00022
00023 import abc
00024
00025 from sensor_msgs.msg import JointState
00026 from std_msgs.msg import Float64MultiArray
00027 from geometry_msgs.msg import TwistStamped
00028 from geometry_msgs.msg import Twist
00029 from nav_msgs.msg import Odometry
00030 from cob_control_msgs.msg import ObstacleDistances
00031 import tf
00032
00033 DEL = ','
00034 QUOTE = '"'
00035 DATE_TIME_FMT = '%d.%m.%Y %H:%M:%S.%f'
00036
00037
00038 class DataKraken(object):
00039
00040 __metaclass__ = abc.ABCMeta
00041
00042 def __init__(self, file_path, topic_name, data_class):
00043 self.file_path_ = file_path
00044 self.csv_writer_ = None
00045 self.topic_name_ = topic_name
00046 self.data_class_ = data_class
00047 self.data_rows_ = []
00048 self.subscriber_ = None
00049 self.start_ = None
00050
00051 def open(self):
00052 success = False
00053 try:
00054 with open(self.file_path_, 'wt') as csvfile:
00055 self.csv_writer_ = csv.writer(
00056 csvfile, delimiter = DEL, quotechar = QUOTE)
00057 success = self.csv_writer_ is not None
00058 if success:
00059 self.subscriber_ = rospy.Subscriber(
00060 self.topic_name_, self.data_class_, self.callback)
00061 except IOError as ioe:
00062 rospy.logerr(str(ioe))
00063 return success
00064
00065 def writeAllData(self):
00066 success = False
00067 if len(self.data_rows_) > 0:
00068 with open(self.file_path_, 'wt') as csvfile:
00069 self.csv_writer_ = csv.writer(
00070 csvfile, delimiter = DEL, quotechar = QUOTE)
00071 self.csv_writer_.writerows(self.data_rows_)
00072 success = True
00073 rospy.loginfo(
00074 self.__class__.__name__ + ': Successfully wrote data into file: ' + self.file_path_)
00075 else:
00076 rospy.logerr(self.__class__.__name__ +
00077 ': Could not find any data to write into file: ' + self.file_path_)
00078 return success
00079
00080 @abc.abstractmethod
00081 def callback(self, data):
00082 raise NotImplementedError
00083
00084
00085 class JointStateDataKraken(DataKraken):
00086
00087 def __init__(self, file_path):
00088 super(JointStateDataKraken, self).__init__(
00089 file_path, 'joint_states', JointState)
00090 self.init_ = True
00091 self.jointstate_sub_ = None
00092
00093 def callback(self, data):
00094 if self.init_:
00095 self.start_ = datetime.datetime.now()
00096 header = []
00097 header.append('time stamp')
00098 header.append('time delta')
00099 for name in data.name:
00100 header.append(name + '_position')
00101 for name in data.name:
00102 header.append(name + '_velocity')
00103 self.data_rows_.append(header)
00104 self.init_ = False
00105
00106 now = datetime.datetime.now()
00107 delta = now - self.start_
00108
00109 data_row = []
00110 data_row.append(now.strftime(DATE_TIME_FMT))
00111 data_row.append('%.3f' % delta.total_seconds())
00112 data_row.extend(list(data.position))
00113 data_row.extend(list(data.velocity))
00114 self.data_rows_.append(data_row)
00115
00116
00117 class ObstacleDistanceDataKraken(DataKraken):
00118
00119 def __init__(self, file_path):
00120 super(ObstacleDistanceDataKraken, self).__init__(
00121 file_path, 'obstacle_distance', ObstacleDistances)
00122 self.init_ = True
00123
00124 def callback(self, data):
00125 if self.init_:
00126 self.start_ = datetime.datetime.now()
00127 header = []
00128 header.append('time stamp')
00129 header.append('time delta')
00130 header.append('link_of_interest')
00131 header.append('obstacle')
00132 header.append('distance')
00133 header.append('frame_vector_x')
00134 header.append('frame_vector_y')
00135 header.append('frame_vector_z')
00136 header.append('np_frame_vector_x')
00137 header.append('np_frame_vector_y')
00138 header.append('np_frame_vector_z')
00139 header.append('np_obstacle_vector_x')
00140 header.append('np_obstacle_vector_y')
00141 header.append('np_obstacle_vector_z')
00142 self.data_rows_.append(header)
00143 self.init_ = False
00144
00145 now = datetime.datetime.now()
00146 delta = now - self.start_
00147 for elem in data.distances:
00148 data_row = [now.strftime(DATE_TIME_FMT), '%.3f' % delta.total_seconds()]
00149 data_row.append(elem.link_of_interest)
00150 data_row.append(elem.obstacle_id)
00151 data_row.append(elem.distance)
00152 data_row.append(elem.frame_vector.x)
00153 data_row.append(elem.frame_vector.y)
00154 data_row.append(elem.frame_vector.z)
00155 data_row.append(elem.nearest_point_frame_vector.x)
00156 data_row.append(elem.nearest_point_frame_vector.y)
00157 data_row.append(elem.nearest_point_frame_vector.z)
00158 data_row.append(elem.nearest_point_obstacle_vector.x)
00159 data_row.append(elem.nearest_point_obstacle_vector.y)
00160 data_row.append(elem.nearest_point_obstacle_vector.z)
00161 self.data_rows_.append(data_row)
00162
00163
00164 class TwistDataKraken(DataKraken):
00165
00166 def __init__(self, file_path, for_base = False, use_twist_stamped = True):
00167 self.use_twist_stamped_ = use_twist_stamped
00168
00169 if for_base:
00170 super(TwistDataKraken, self).__init__(
00171 file_path, '/base/twist_controller/command', Twist)
00172 else:
00173 if self.use_twist_stamped_:
00174 super(TwistDataKraken, self).__init__(
00175 file_path, 'twist_controller/command_twist_stamped', TwistStamped)
00176 else:
00177 super(TwistDataKraken, self).__init__(
00178 file_path, 'twist_controller/command_twist', Twist)
00179 self.init_ = True
00180
00181 def callback(self, data):
00182 if self.use_twist_stamped_:
00183 frame_id = data.header.frame_id + '_'
00184 twist_data = data.twist
00185 else:
00186 frame_id = ''
00187 twist_data = data
00188
00189 if self.init_:
00190 self.start_ = datetime.datetime.now()
00191 header = []
00192
00193 header.append(frame_id + 'time stamp')
00194 header.append(frame_id + 'time delta')
00195 header.append(frame_id + 'linear_x')
00196 header.append(frame_id + 'linear_y')
00197 header.append(frame_id + 'linear_z')
00198 header.append(frame_id + 'angular_x')
00199 header.append(frame_id + 'angular_y')
00200 header.append(frame_id + 'angular_z')
00201 self.data_rows_.append(header)
00202 self.init_ = False
00203 data_row = []
00204
00205 now = datetime.datetime.now()
00206 delta = now - self.start_
00207 data_row.append(now.strftime(DATE_TIME_FMT))
00208 data_row.append('%.3f' % delta.total_seconds())
00209 data_row.append(twist_data.linear.x)
00210 data_row.append(twist_data.linear.y)
00211 data_row.append(twist_data.linear.z)
00212 data_row.append(twist_data.angular.x)
00213 data_row.append(twist_data.angular.y)
00214 data_row.append(twist_data.angular.z)
00215 self.data_rows_.append(data_row)
00216
00217
00218 class JointVelocityDataKraken(DataKraken):
00219
00220 def __init__(self, file_path):
00221 super(JointVelocityDataKraken, self).__init__(
00222 file_path, 'joint_group_velocity_controller/command', Float64MultiArray)
00223 self.init_ = True
00224
00225 def callback(self, data):
00226 if self.init_:
00227 self.start_ = datetime.datetime.now()
00228 header = []
00229 header.append('time stamp')
00230 header.append('time delta')
00231 for idx, jointvel in enumerate(data.data):
00232 header.append(str(idx + 1))
00233 self.data_rows_.append(header)
00234 self.init_ = False
00235 data_row = []
00236 now = datetime.datetime.now()
00237 delta = now - self.start_
00238 data_row.append(now.strftime(DATE_TIME_FMT))
00239 data_row.append('%.3f' % delta.total_seconds())
00240
00241 for jointvel in data.data:
00242 data_row.append(jointvel)
00243 self.data_rows_.append(data_row)
00244
00245
00246 class FrameTrackingDataKraken(DataKraken):
00247
00248 def __init__(self, file_path, root_frame, chain_tip_link, tracking_frame):
00249 super(FrameTrackingDataKraken, self).__init__(
00250 file_path, None, None)
00251 self.init_ = True
00252 self.timed_transform_ = None
00253 self.tf_ = None
00254 self.root_frame_ = root_frame
00255 self.chain_tip_link_ = chain_tip_link
00256 self.tracking_frame_ = tracking_frame
00257
00258 def open(self):
00259 success = False
00260 try:
00261 with open(self.file_path_, 'wt') as csvfile:
00262 self.csv_writer_ = csv.writer(
00263 csvfile, delimiter = DEL, quotechar = QUOTE)
00264 success = self.csv_writer_ is not None
00265 if success:
00266 self.tf_ = tf.TransformListener()
00267 self.timed_transform_ = rospy.Timer(rospy.Duration.from_sec(0.1), self.callback)
00268 except IOError as ioe:
00269 rospy.logerr(str(ioe))
00270 return success
00271
00272 def writeAllData(self):
00273 self.timed_transform_.shutdown()
00274 self.timed_transform_.join(5.0)
00275 return super(FrameTrackingDataKraken, self).writeAllData()
00276
00277 def callback(self, data):
00278 if self.init_:
00279 self.start_ = datetime.datetime.now()
00280 header = []
00281 header.append('time stamp')
00282 header.append('time delta')
00283 for frame in (self.chain_tip_link_, self.tracking_frame_):
00284 header.append('x Trans ' + self.root_frame_ + ' to ' + frame)
00285 header.append('y Trans ' + self.root_frame_ + ' to ' + frame)
00286 header.append('z Trans ' + self.root_frame_ + ' to ' + frame)
00287 header.append('x Quat ' + self.root_frame_ + ' to ' + frame)
00288 header.append('y Quat ' + self.root_frame_ + ' to ' + frame)
00289 header.append('z Quat ' + self.root_frame_ + ' to ' + frame)
00290 header.append('w Quat ' + self.root_frame_ + ' to ' + frame)
00291 header.append('roll ' + self.root_frame_ + ' to ' + frame)
00292 header.append('pitch ' + self.root_frame_ + ' to ' + frame)
00293 header.append('yaw ' + self.root_frame_ + ' to ' + frame)
00294 self.data_rows_.append(header)
00295 self.init_ = False
00296
00297 trans_root_tip, quat_root_tip, rpy_root_tip = None, None, None
00298 try:
00299
00300 (trans_root_tip, quat_root_tip) = self.tf_.lookupTransform(self.root_frame_, self.chain_tip_link_, rospy.Time(0))
00301 rpy_root_tip = tf.transformations.euler_from_quaternion(quat_root_tip)
00302 except Exception as e:
00303 print('Exception chain_tip_link_: ' + str(e))
00304
00305 trans_root_track, quat_root_track, rpy_root_track = None, None, None
00306 try:
00307
00308
00309 (trans_root_track, quat_root_track) = self.tf_.lookupTransform(self.root_frame_, self.tracking_frame_, rospy.Time(0))
00310 rpy_root_track = tf.transformations.euler_from_quaternion(quat_root_track)
00311
00312 except Exception as e:
00313 print('Exception tracking_frame_: ' + str(e))
00314
00315
00316 if rpy_root_tip is not None and rpy_root_track is not None:
00317 data_row = []
00318
00319 now = datetime.datetime.now()
00320 delta = now - self.start_
00321 data_row.append(now.strftime(DATE_TIME_FMT))
00322 data_row.append('%.3f' % delta.total_seconds())
00323
00324 data_row.extend(trans_root_tip)
00325 data_row.extend(quat_root_tip)
00326 data_row.extend(rpy_root_tip)
00327
00328 data_row.extend(trans_root_track)
00329 data_row.extend(quat_root_track)
00330 data_row.extend(rpy_root_track)
00331
00332 self.data_rows_.append(data_row)
00333
00334
00335 class OdometryDataKraken(DataKraken):
00336
00337 def __init__(self, file_path):
00338 super(OdometryDataKraken, self).__init__(
00339 file_path, '/base/odometry_controller/odometry', Odometry)
00340 self.init_ = True
00341
00342 def callback(self, data):
00343 if self.init_:
00344 self.start_ = datetime.datetime.now()
00345 header = []
00346 header.append(data.header.frame_id + '_time stamp')
00347 header.append(data.header.frame_id + '_time delta')
00348 header.append(data.header.frame_id + '_pos_x')
00349 header.append(data.header.frame_id + '_pos_y')
00350 header.append(data.header.frame_id + '_pos_z')
00351 header.append(data.header.frame_id + '_quat_x')
00352 header.append(data.header.frame_id + '_quat_y')
00353 header.append(data.header.frame_id + '_quat_z')
00354 header.append(data.header.frame_id + '_quat_w')
00355 header.append(data.header.frame_id + '_roll')
00356 header.append(data.header.frame_id + '_pitch')
00357 header.append(data.header.frame_id + '_yaw')
00358 header.append(data.header.frame_id + '_twist_linear_x')
00359 header.append(data.header.frame_id + '_twist_linear_y')
00360 header.append(data.header.frame_id + '_twist_linear_z')
00361 header.append(data.header.frame_id + '_twist_angular_x')
00362 header.append(data.header.frame_id + '_twist_angular_y')
00363 header.append(data.header.frame_id + '_twist_angular_z')
00364 self.data_rows_.append(header)
00365 self.init_ = False
00366 data_row = []
00367
00368 now = datetime.datetime.now()
00369 delta = now - self.start_
00370 data_row.append(now.strftime(DATE_TIME_FMT))
00371 data_row.append('%.3f' % delta.total_seconds())
00372
00373 rpy = tf.transformations.euler_from_quaternion((data.pose.pose.orientation.x, data.pose.pose.orientation.y, data.pose.pose.orientation.z, data.pose.pose.orientation.w,))
00374 data_row.append(data.pose.pose.position.x)
00375 data_row.append(data.pose.pose.position.y)
00376 data_row.append(data.pose.pose.position.z)
00377 data_row.append(data.pose.pose.orientation.x)
00378 data_row.append(data.pose.pose.orientation.y)
00379 data_row.append(data.pose.pose.orientation.z)
00380 data_row.append(data.pose.pose.orientation.w)
00381 data_row.append(rpy[0])
00382 data_row.append(rpy[1])
00383 data_row.append(rpy[2])
00384 data_row.append(data.twist.twist.linear.x)
00385 data_row.append(data.twist.twist.linear.y)
00386 data_row.append(data.twist.twist.linear.z)
00387 data_row.append(data.twist.twist.angular.x)
00388 data_row.append(data.twist.twist.angular.y)
00389 data_row.append(data.twist.twist.angular.z)
00390 self.data_rows_.append(data_row)
00391
00392