38 PKG =
'pr2_counterbalance_check' 49 import matplotlib.pyplot
as plt
50 from StringIO
import StringIO
52 from pr2_self_test_msgs.msg
import Plot, TestValue, TestParam
54 ok_dict = {
False:
'FAIL',
True:
'OK' }
57 return map(
lambda x: x
if x < 128
else x-256, map(ord, s))
61 self.
time = numpy.array(msg.time)
64 self.
effort = numpy.array(msg.effort)
81 for fd
in msg.flex_data:
88 for ld
in msg.lift_data:
120 if len(msg.arg_value) > 24:
134 self.
min_flex = msg.lift_data[0].flex_data[0].flex_position
135 self.
max_flex = msg.lift_data[0].flex_data[-1].flex_position
138 for i
in range(0, 9):
143 params.append(TestParam(key=
'Lift Dither', value=str(self.
lift_dither)))
144 params.append(TestParam(key=
'Flex Dither', value=str(self.
flex_dither)))
145 params.append(TestParam(key=
'Lift Joint', value=self.
lift_joint))
146 params.append(TestParam(key=
'Flex Joint', value=self.
flex_joint))
147 params.append(TestParam(key=
'Timeout Hit', value=ok_dict[
not self.
timeout_hit]))
148 params.append(TestParam(key=
'Flex Tested', value=str(self.
flex_test)))
150 params.append(TestParam(key=
'Lift MSE', value=str(self.
lift_mse)))
151 params.append(TestParam(key=
'Lift Avg Abs', value=str(self.
lift_avg_abs)))
152 params.append(TestParam(key=
'Lift Avg Effort', value=str(self.
lift_avg_eff)))
155 params.append(TestParam(key=
'Lift P Gain', value=str(self.
lift_p)))
156 params.append(TestParam(key=
'Lift I Gain', value=str(self.
lift_i)))
157 params.append(TestParam(key=
'Lift D Gain', value=str(self.
lift_d)))
158 params.append(TestParam(key=
'Lift I Clamp', value=str(self.
lift_i_clamp)))
160 params.append(TestParam(key=
'Num Lifts', value=str(self.
num_lifts)))
161 params.append(TestParam(key=
'Min Lift', value=
"%.2f" % self.
min_lift))
162 params.append(TestParam(key=
'Max Lift', value=
"%.2f" % self.
max_lift))
165 params.append(TestParam(key=
'Flex MSE', value=str(self.
flex_mse)))
166 params.append(TestParam(key=
'Flex Avg Abs', value=str(self.
flex_avg_abs)))
167 params.append(TestParam(key=
'Flex Avg Effort', value=str(self.
flex_avg_eff)))
168 params.append(TestParam(key=
'Flex P Gain', value=str(self.
flex_p)))
169 params.append(TestParam(key=
'Flex I Gain', value=str(self.
flex_i)))
170 params.append(TestParam(key=
'Flex D Gain', value=str(self.
flex_d)))
171 params.append(TestParam(key=
'Flex I Clamp', value=str(self.
flex_i_clamp)))
172 params.append(TestParam(key=
'Num Flexes', value=str(self.
num_flexes)))
173 params.append(TestParam(key=
'Min Flex', value=
"%.2f" % self.
min_flex))
174 params.append(TestParam(key=
'Max Flex', value=
"%.2f" % self.
max_flex))
176 for key, val
in self.named_params.iteritems():
177 params.append(TestParam(key=key, value=str(val)))
183 __slots__ = [
'html',
'summary',
'result',
'values']
195 for ld
in data.lift_data:
196 for fd
in ld.flex_data:
198 avg_effort_list.append(fd.lift_hold.effort_avg)
200 avg_effort_list.append(fd.flex_hold.effort_avg)
202 return avg_effort_list
205 sq_array = avg_effort_array * avg_effort_array
206 return numpy.average(sq_array)
209 abs_array = abs(avg_effort_array)
210 return numpy.average(abs_array)
213 return numpy.average(avg_effort_array)
219 for ld
in data.lift_data:
220 fd = ld.flex_data[flex_index]
221 lift_list.append(ld.lift_position)
223 effort_list.append(fd.lift_hold.effort_avg)
225 effort_list.append(fd.flex_hold.effort_avg)
227 return lift_list, effort_list
230 ld = data.lift_data[lift_index]
235 for fd
in ld.flex_data:
236 flex_list.append(fd.flex_position)
238 effort_list.append(fd.lift_hold.effort_avg)
240 effort_list.append(fd.flex_hold.effort_avg)
242 return flex_list, effort_list
248 for fd
in data.lift_data[0].flex_data:
249 flex_list.append(fd.flex_position)
255 for ld
in data.lift_data:
256 lifts.append(ld.lift_position)
267 for i
in range(0, params.num_lifts):
269 effort_list.append(efforts)
273 flex_grid, lift_grid = numpy.meshgrid(numpy.array(flexes), numpy.array(lifts))
274 effort_grid = numpy.array(effort_list)
276 CS = plt.contour(flex_grid, lift_grid, effort_grid)
277 plt.clabel(CS, inline=0, fontsize=10)
283 plt.savefig(stream, format =
'png')
284 image = stream.getvalue()
287 p.title =
'lift_effort_contour' 289 p.title =
'flex_effort_contour' 291 p.image_format =
'png' 304 flex_position = data.lift_data[0].flex_data[flex_index].flex_position
306 plt.plot(numpy.array(lift_position), numpy.array(effort))
308 plt.title(
'Shoulder Lift Effort at Flex Position %.2f' % (flex_position))
310 plt.title(
'Shoulder Flex Effort at Flex Position %.2f' % (flex_position))
312 plt.xlabel(
'Lift Position')
314 plt.axhline(y = 0, color =
'r', label='_nolegend_')
317 plt.savefig(stream, format =
'png')
318 image = stream.getvalue()
321 p.title =
'lift_effort_const_flex_%d' % flex_index
323 p.title =
'flex_effort_const_flex_%d' % flex_index
325 p.image_format =
'png' 342 mse_ok = mse < params.lift_mse
343 avg_abs_ok = avg_abs < params.lift_avg_abs
344 avg_eff_ok = abs(avg_eff) < abs(params.lift_avg_eff)
346 if mse_ok
and avg_abs_ok:
347 result.summary =
'Lift efforts OK' 349 result.summary =
'Counterbalance is too weak. Requires adjustment' 351 result.summary =
'Counterbalance is too strong. Requires adjustment' 353 html = [
'<p>%s</p>' % result.summary]
355 html.append(
'<table border="1" cellpadding="2" cellspacing="0">')
356 html.append(
'<tr><td><b>Parameter</b></td><td><b>Value</b></td><td><b>Maximum</b></td><td><b>Status</b></td></tr>')
357 html.append(
'<tr><td><b>Mean Sq. Effort</b></td><td>%.2f</td><td>%.2f</td><td>%s</td></tr>' % (mse, params.lift_mse, ok_dict[mse_ok]))
358 html.append(
'<tr><td><b>Average Abs. Effort</b></td><td>%.2f</td><td>%.2f</td><td>%s</td></tr>' % (avg_abs, params.lift_avg_abs, ok_dict[avg_abs_ok]))
359 html.append(
'<tr><td><b>Average Effort</b></td><td>%.2f</td><td>%.2f</td><td>%s</td></tr>' % (avg_eff, params.lift_avg_eff, ok_dict[avg_eff_ok]))
360 html.append(
'</table>')
362 result.html =
'\n'.join(html)
364 result.result = mse_ok
and avg_abs_ok
367 result.values.append(TestValue(
'Lift MSE', str(mse),
'', str(params.lift_mse)))
368 result.values.append(TestValue(
'Lift Avg. Abs. Effort', str(avg_abs),
'', str(params.lift_avg_abs)))
369 result.values.append(TestValue(
'Lift Avg. Effort', str(avg_eff),
'', str(params.lift_avg_eff)))
379 avg_efforts = numpy.array(
get_efforts(data,
False))
384 mse_ok = mse < params.flex_mse
385 avg_abs_ok = avg_abs < params.flex_avg_abs
386 avg_eff_ok = abs(avg_eff) < abs(params.flex_avg_eff)
388 if mse_ok
and avg_abs_ok:
389 result.summary =
'Flex efforts OK' 391 result.summary =
'Flex MSE/Avg. Absolute effort too high' 393 html = [
'<p>%s</p>' % result.summary]
395 html.append(
'<table border="1" cellpadding="2" cellspacing="0">')
396 html.append(
'<tr><td><b>Parameter</b></td><td><b>Value</b></td><td><b>Maximum</b></td><td><b>Status</b></td></tr>')
397 html.append(
'<tr><td><b>Mean Sq. Effort</b></td><td>%.2f</td><td>%.2f</td><td>%s</td></tr>' % (mse, params.flex_mse, ok_dict[mse_ok]))
398 html.append(
'<tr><td><b>Average Abs. Effort</b></td><td>%.2f</td><td>%.2f</td><td>%s</td></tr>' % (avg_abs, params.flex_avg_abs, ok_dict[avg_abs_ok]))
399 html.append(
'<tr><td><b>Average Effort</b></td><td>%.2f</td><td>%.2f</td><td>%s</td></tr>' % (avg_eff, params.flex_avg_eff, ok_dict[avg_eff_ok]))
400 html.append(
'</table>')
402 result.html =
'\n'.join(html)
404 result.result = mse_ok
and avg_abs_ok
407 result.values.append(TestValue(
'Flex MSE', str(mse),
'', str(params.flex_mse)))
408 result.values.append(TestValue(
'Flex Avg. Abs. Effort', str(avg_abs),
'', str(params.flex_avg_abs)))
409 result.values.append(TestValue(
'Flex Avg. Effort', str(avg_eff),
'', str(params.flex_avg_eff)))
422 A = numpy.load(model_file)[:-1].transpose()
424 X = numpy.linalg.lstsq(A,B)
426 print >> sys.stderr,
"Unable to calculate CB adjustment. May have incorrect model data" 428 traceback.print_exc()
435 return (secondary, cb_bar)
449 if (abs(secondary) > 25
or abs(cb_bar) > 25):
450 result.result =
False 451 result.summary =
'Unable to calculate CB adjustment. Data may be corrupt or CB may be too far off' 452 result.html =
'<p>Unable to calculate CB adjustment.</p>' 455 secondary_dir =
'CW' if secondary > 0
else 'CCW' 456 cb_bar_dir =
'CW' if cb_bar > 0
else 'CCW' 458 adjust_msg =
'<table border="1" cellpadding="2" cellspacing="0">' 459 adjust_msg +=
'<tr><td><b>Adjustment</b></td><td><b>Turns</b></td><td><b>Direction</b></td><td><b>Allowable Tolerance</b></td></tr>\n' 460 adjust_msg +=
'<tr><td>Secondary Spring</td><td>%.1f</td><td>%s</td><td>%.1f</td></tr>\n' % (abs(secondary), secondary_dir, params.screw_tol)
461 adjust_msg +=
'<tr><td>Arm Gimbal Shaft</td><td>%.1f</td><td>%s</td><td>%.1f</td></tr>\n' % (abs(cb_bar), cb_bar_dir, params.bar_tol)
462 adjust_msg +=
'</table>\n' 465 if abs(secondary) > params.screw_tol
or abs(cb_bar) > params.bar_tol:
466 result.result =
False 467 result.summary =
'CB adjustment recommended. Follow instructions below to tune CB. ' 468 result.html =
'<p>CB adjustment recommended. Adjusting the counterbalance will increase performance of the arm. (Note: CW = "Clockwise")</p>\n<p>%s</p>\n' % adjust_msg
472 result.html =
'<p>No CB adjustment recommended. You may choose to adjust the CB using the following instructions, but this is within tolerance.</p>\n<p>%s</p>' % adjust_msg
475 result.values = [TestValue(
'Secondary Spring Adjustment', str(secondary),
'', str(params.screw_tol)),
476 TestValue(
'CB Bar Adjustment', str(cb_bar),
'', str(params.bar_tol))]
def analyze_lift_efforts(params, data)
Checks shoulder lift efforts against params.
def _get_mean_abs_effort(avg_effort_array)
Stores parameters from CB analysis test.
def _get_lift_positions(data)
def _get_const_lift_effort(data, lift_index=0, lift_calc=True)
def get_efforts(data, lift_calc)
Get average efforts for CB test as a list.
def _get_mean_effort(avg_effort_array)
def get_test_params(self)
def _get_mean_sq_effort(avg_effort_array)
def plot_efforts_by_lift_position(params, data, flex_index=-1, lift_calc=True)
Plots CB efforts against shoulder lift position.
def _get_const_flex_effort(data, flex_index=0, lift_calc=True)
Returns a list of lift positions, efforts for a given flex position (vary by lift) ...
def check_cb_adjustment(params, data, model_file)
Return CB adjustments to minimize total torque.
def calc_cb_adjust(data, model_file)
Calculates CB adjustment.
def _get_flex_positions(data)
def plot_effort_contour(params, data, lift_calc=True)
Gives effort contour plot of efforts by lift, flex position.
def analyze_flex_efforts(params, data)
Checks shoulder flex efforts against params.