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.