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
00032
00033
00034
00035
00036
00037 """
00038 Generate YAML calibration file from Velodyne db.xml.
00039
00040 The input data provided by the manufacturer are in degrees and
00041 centimeters. The YAML file uses radians and meters, following ROS
00042 standards [REP-0103].
00043
00044 """
00045
00046 from __future__ import print_function
00047
00048 import math
00049 import optparse
00050 import os
00051 import sys
00052 from xml.etree import ElementTree
00053 import yaml
00054
00055
00056 usage = """usage: %prog infile.xml [outfile.yaml]
00057
00058 Default output file is input file with .yaml suffix."""
00059 parser = optparse.OptionParser(usage=usage)
00060 options, args = parser.parse_args()
00061
00062 if len(args) < 1:
00063 parser.error('XML file name missing')
00064 sys.exit(9)
00065
00066 xmlFile = args[0]
00067 if len(args) >= 2:
00068 yamlFile = args[1]
00069 else:
00070 yamlFile, ext = os.path.splitext(xmlFile)
00071 yamlFile += '.yaml'
00072
00073 print('converting "' + xmlFile + '" to "' + yamlFile + '"')
00074
00075 calibrationGood = True
00076 def xmlError(msg):
00077 'handle XML calibration error'
00078 global calibrationGood
00079 calibrationGood = False
00080 print('gen_calibration.py: ' + msg)
00081
00082 db = None
00083 try:
00084 db = ElementTree.parse(xmlFile)
00085 except IOError:
00086 xmlError('unable to read ' + xmlFile)
00087 except ElementTree.ParseError:
00088 xmlError('XML parse failed for ' + xmlFile)
00089
00090 if not calibrationGood:
00091 sys.exit(2)
00092
00093
00094 calibration = {'num_lasers': 0, 'lasers': []}
00095 cm2meters = 0.01
00096
00097 def addLaserCalibration(laser_num, key, val):
00098 'Define key and corresponding value for laser_num'
00099 global calibration
00100 if laser_num < len(calibration['lasers']):
00101 calibration['lasers'][laser_num][key] = val
00102 else:
00103 calibration['lasers'].append({key: val})
00104
00105
00106 num_enabled = 0
00107 enabled_lasers = []
00108 enabled = db.find('DB/enabled_')
00109 if enabled == None:
00110 print('no enabled tags found: assuming all 64 enabled')
00111 num_enabled = 64
00112 enabled_lasers = [True for i in xrange(num_enabled)]
00113 else:
00114 index = 0
00115 for el in enabled:
00116 if el.tag == 'item':
00117 this_enabled = int(el.text) != 0
00118 enabled_lasers.append(this_enabled)
00119 index += 1
00120 if this_enabled:
00121 num_enabled += 1
00122
00123 calibration['num_lasers'] = num_enabled
00124 print(str(num_enabled) + ' lasers')
00125
00126
00127 minIntensities = db.find('DB/minIntensity_')
00128 if minIntensities != None:
00129 index = 0
00130 for el in minIntensities:
00131 if el.tag == 'item':
00132 if enabled_lasers[index]:
00133 value = float(el.text)
00134 if value != 0.0:
00135 addLaserCalibration(index, 'min_intensity', value)
00136 index += 1
00137
00138
00139 maxIntensities = db.find('DB/maxIntensity_')
00140 if maxIntensities != None:
00141 index = 0
00142 for el in maxIntensities:
00143 if el.tag == 'item':
00144 if enabled_lasers[index]:
00145 value = float(el.text)
00146 if value != 255.0:
00147 addLaserCalibration(index, 'max_intensity', float(el.text))
00148 index += 1
00149
00150
00151 for el in db.find('DB/points_'):
00152 if el.tag == 'item':
00153 for px in el:
00154 for field in px:
00155 if field.tag == 'id_':
00156 index = int(field.text)
00157 if not enabled_lasers[index]:
00158 break
00159 addLaserCalibration(index, 'laser_id', index)
00160
00161 if field.tag == 'rotCorrection_':
00162 addLaserCalibration(index, 'rot_correction',
00163 math.radians(float(field.text)))
00164 elif field.tag == 'vertCorrection_':
00165 addLaserCalibration(index, 'vert_correction',
00166 math.radians(float(field.text)))
00167 elif field.tag == 'distCorrection_':
00168 addLaserCalibration(index, 'dist_correction',
00169 float(field.text) * cm2meters)
00170 elif field.tag == 'distCorrectionX_':
00171 addLaserCalibration(index, 'dist_correction_x',
00172 float(field.text) * cm2meters)
00173 elif field.tag == 'distCorrectionY_':
00174 addLaserCalibration(index, 'dist_correction_y',
00175 float(field.text) * cm2meters)
00176 elif field.tag == 'vertOffsetCorrection_':
00177 addLaserCalibration(index, 'vert_offset_correction',
00178 float(field.text) * cm2meters)
00179 elif field.tag == 'horizOffsetCorrection_':
00180 addLaserCalibration(index, 'horiz_offset_correction',
00181 float(field.text) * cm2meters)
00182 elif field.tag == 'focalDistance_':
00183 addLaserCalibration(index, 'focal_distance',
00184 float(field.text) * cm2meters)
00185 elif field.tag == 'focalSlope_':
00186 addLaserCalibration(index, 'focal_slope', float(field.text))
00187
00188
00189 if calibration['num_lasers'] <= 0:
00190 xmlError('no lasers defined')
00191 elif calibration['num_lasers'] != num_enabled:
00192 xmlError('inconsistent number of lasers defined')
00193
00194
00195
00196
00197 if calibrationGood:
00198
00199
00200 f = open(yamlFile, 'w')
00201 try:
00202 yaml.dump(calibration, f)
00203 finally:
00204 f.close()