18 Calibration utility for the cyberglove. 21 @contact: ugo@shadowrobot.com, contact@shadowrobot.com 27 from cyberglove_library
import Cyberglove
28 from std_srvs.srv
import Empty
38 A class containing simple information regarding a joint: name, and calibrated value 43 @param name: the name of the joint 44 @param min: the min value to calibrate 45 @param max: the max value to calibrate 55 A class containing all the data for a given calibration step 58 def __init__(self, step_name="", step_description=[""], joints=[]):
60 @param step_name: A short name for this calibration step 61 @param step_description: A table containing 2 descriptions: the first one describes the min pose, the second 63 @param joints: A table containing the joints to be calibrated 74 A class Containing all the calibration data for a given joint. 77 def __init__(self, raw_min=0.0, raw_max=0.0,
78 calibrated_min=0.0, calibrated_max=0.0,
89 The default description function for a step. Just prints a text for each step. 91 @param step_name: the name of the step 92 @param max: if 0=>we're reading the min values, if 1=> max values 95 print "calibrating min values for: " + str(step_name)
97 print "calibrating max values for: " + str(step_name)
102 A function that does nothing. Used to have an empty description function. 110 A utility to calibrate the cyberglove. 113 def __init__(self, description_function=default_description, nb_sensors=22):
115 Initialize some class variables: a table containing the calibration steps, a connection to the cyberglove 116 library and a description function for the calibration steps 118 @param description_function: specify a function you want to use to describe the calibration steps ( text / 119 pictures / animation / ... ). Must take a joint name as parameter. 130 for name
in self.cyberglove.get_joints_names():
135 if description_function
is None:
136 description_function = do_nothing
141 Read the calibration steps from the xml file. 143 @return: 0 when the values were read. 148 joints1 = [
Joint(
"G_IndexMPJ", 0, 90),
Joint(
"G_IndexPIJ", 0, 90),
149 Joint(
"G_MiddleMPJ", 0, 90),
Joint(
"G_MiddlePIJ", 0, 90),
150 Joint(
"G_RingMPJ", 0, 90),
Joint(
"G_RingPIJ", 0, 90),
151 Joint(
"G_PinkieMPJ", 0, 90),
Joint(
"G_PinkiePIJ", 0, 90),
152 Joint(
"G_ThumbAb", 50, 0)]
154 joints1 = [
Joint(
"G_IndexMPJ", 0, 90),
Joint(
"G_IndexPIJ", 0, 90),
155 Joint(
"G_IndexDIJ", 0, 90),
Joint(
"G_MiddleMPJ", 0, 90),
156 Joint(
"G_MiddlePIJ", 0, 90),
Joint(
"G_MiddleDIJ", 0, 90),
157 Joint(
"G_RingMPJ", 0, 90),
Joint(
"G_RingPIJ", 0, 90),
158 Joint(
"G_RingDIJ", 0, 90),
Joint(
"G_PinkieMPJ", 0, 90),
159 Joint(
"G_PinkiePIJ", 0, 90),
Joint(
"G_PinkieDIJ", 0, 90),
160 Joint(
"G_ThumbAb", 50, 0)]
161 self.calibration_steps.append(
163 step_name=
"Joints 0s, 3s and thumb abduction (THJ4)",
165 "Hand flat on a table, fingers joined, thumb opened",
166 "Hand forming a fist, thumb closed"],
170 joints2 = [
Joint(
"G_ThumbIJ", 90, 0),
Joint(
"G_ThumbMPJ", 30, -30),
172 "G_RingMiddleAb", 0, 50),
Joint(
"G_PinkieRingAb", 0, 50),
173 Joint(
"G_WristYaw", 10, -30)]
174 self.calibration_steps.append(
176 step_description=[
"Hand flat fingers joined, thumb completely curled " 177 "under the palm, wrist 2 bent to the left",
178 "Hand flat fingers apart, thumb completely opened," 179 " wrist bent 2 to the right"],
183 joints3 = [
Joint(
"G_ThumbRotate", 60, -60)]
185 step_description=[
"thumb completely under the palm",
186 "thumb completely opened, " 187 "curled over the palm"],
191 joints4 = [
Joint(
"G_PalmArch", 0, 40),
Joint(
"G_WristPitch", -30, 40)]
193 step_description=[
"Hand flat, wrist 1 bent backward",
194 "Palm curled (LFJ5), wrist 1 bent forward"],
201 Run the given step of the calibration, gets the min values. 203 @param index: the index of the step in the calibration file 204 @return: 0 when the values were read. 215 name].raw_min = self.cyberglove.read_raw_average_value(name)
216 self.
joints[name].calibrated_min = joint.min
218 self.
joints[name].is_calibrated += 0.5
223 Run the given step of the calibration, gets the max values. 224 As this method is called after the do_step_min() method, we don't display the description 226 @param index: the index of the step in the calibration file 227 @return: 0 when the values were read. 238 name].raw_max = self.cyberglove.read_raw_average_value(name)
239 self.
joints[name].calibrated_max = joint.max
241 self.
joints[name].is_calibrated += 0.5
246 Check if the joint is calibrated. 248 @param joint_name: the name of the joint 249 @return: 1 if the joint has already been calibrated. 252 return self.
joints[joint_name].is_calibrated
256 Check if all the steps were processed. 258 @return: True if all the steps were processed. 260 for calib
in self.joints.values():
261 if calib.is_calibrated != 1:
268 Reorder the calibration: set the raw_min to the min raw_value 270 for name
in self.joints.keys():
271 if self.
joints[name].raw_min > self.
joints[name].raw_max:
272 tmp_raw = self.
joints[name].raw_min
273 tmp_cal = self.
joints[name].calibrated_min
277 self.
joints[name].raw_max = tmp_raw
278 self.
joints[name].calibrated_max = tmp_cal
282 Check for zero range calibrations, also for min/max values (-> full sensor range not being used) 286 for name
in self.joints.keys():
287 if self.
joints[name].raw_min == self.
joints[name].raw_max:
288 errors.append(
"%s zero range: %f. Min modified (-0.001)." 289 % (name, self.
joints[name].raw_min))
290 self.
joints[name].raw_min -= 0.001
291 if self.
joints[name].raw_max == 1.0:
292 errors.append(
"%s max value is 1.0." % name)
293 if self.
joints[name].raw_min == 0.0:
294 errors.append(
"%s min value is 0.0." % name)
302 Checks if all the steps were processed by calling self.all_steps_done() 303 Reorder the calibration 304 Then writes the whole calibration to a given file. 306 @param filepath: Where to write the calibration 307 @return: 0 if the file has been written, 308 -1 if the calibration is not finished yet, 325 text.append(
"{'cyberglove_calibration': [")
329 text.append(
"['%s', [[%f,%f],[%f,%f]]]," % (
330 name, cal.raw_min, cal.calibrated_min, cal.raw_max, cal.calibrated_max))
337 output = open(filepath,
"w")
340 output.write(line +
"\n")
352 rospy.wait_for_service(
'/rh_cyberglove/reload_calibration', timeout=5)
354 calib = rospy.ServiceProxy(
355 '/rh_cyberglove/reload_calibration', Empty)
356 with open(filename,
"r") as f: 357 calibration_dict = yaml.load(f.read()) 358 calibration_string = calibration_dict["cyberglove_calibration"]
359 rospy.set_param(
"/rh_cyberglove/cyberglove_calibration", calibration_string)
361 except rospy.ServiceException, e:
362 print 'Failed to call service: %s' % str(e)
364 except rospy.ROSException, e:
365 print (
'Service not found, is the driver running?')
375 for i
in range(0, len(cyber_calib.calibration_steps)):
376 raw_input(cyber_calib.calibration_steps[i].step_description[0])
377 cyber_calib.do_step_min(i)
378 raw_input(cyber_calib.calibration_steps[i].step_description[1])
380 cyber_calib.do_step_max(i)
381 error = cyber_calib.write_calibration_file(
"../../param/cyberglove.cal")
387 if __name__ ==
"__main__":
def write_calibration_file(self, filepath)
def __init__(self, raw_min=0.0, raw_max=0.0, calibrated_min=0.0, calibrated_max=0.0, is_calibrated=0)
def __init__(self, step_name="", step_description=[""], joints=[])
def do_step_max(self, index)
def is_step_done(self, joint_name)
def load_calib(self, filename)
def reorder_calibration(self)
def default_description(step_name, max=0)
def __init__(self, name, min=0, max=90)
def __init__(self, description_function=default_description, nb_sensors=22)
def get_calibration_steps(self)
def do_step_min(self, index)
def do_nothing(step_name, max=0)