From: <wa...@us...> - 2009-07-31 23:43:10
|
Revision: 20337 http://personalrobots.svn.sourceforge.net/personalrobots/?rev=20337&view=rev Author: wattsk Date: 2009-07-31 23:43:02 +0000 (Fri, 31 Jul 2009) Log Message: ----------- Backing up qual dev branch Modified Paths: -------------- pkg/branches/qual_test_2009_07_22/onboard/robots.xml pkg/branches/qual_test_2009_07_22/src/qualification/result.py pkg/branches/qual_test_2009_07_22/src/qualification/test.py pkg/branches/qual_test_2009_07_22/src/qualification/ui.py pkg/branches/qual_test_2009_07_22/srv/ScriptDone.srv pkg/branches/qual_test_2009_07_22/tests/simple_example/test.xml pkg/branches/qual_test_2009_07_22/xrc/gui.fbp pkg/branches/qual_test_2009_07_22/xrc/gui.xrc Added Paths: ----------- pkg/branches/qual_test_2009_07_22/onboard/head_cart_qual.xml pkg/branches/qual_test_2009_07_22/onboard/pr2_qual.xml pkg/branches/qual_test_2009_07_22/src/qualification/qual_frame.py Removed Paths: ------------- pkg/branches/qual_test_2009_07_22/onboard/onboards.xml Added: pkg/branches/qual_test_2009_07_22/onboard/head_cart_qual.xml =================================================================== --- pkg/branches/qual_test_2009_07_22/onboard/head_cart_qual.xml (rev 0) +++ pkg/branches/qual_test_2009_07_22/onboard/head_cart_qual.xml 2009-07-31 23:43:02 UTC (rev 20337) @@ -0,0 +1,47 @@ +<robot_tests> + <!-- Builds tree of onboard qualification tests for qualification GUI --> + + <!-- Each element is organized as follows: + <parent_name label="Name as Displayed in GUI" child_name="name_of_any_subnodes"> + <child_name label="Child name as Displayed in GUI" + pre="pre_subtest_script.launch" + test="test_launch_file.launch" /> + <child_name label="Other Child name as Displayed in GUI" + pre="pre_subtest_script.launch" + test="other_test_launch_file.launch" /> + </parent_name> + Labels must be unique for each element. Base folder is qualification/onboard + + Change child_name -> node_name ... + Relabel to reduce confusion + + --> + + <robot label="Robot Checkout and Visualization" + test="checkout/robot_checkout.launch" /> + + <robot label="Sensors" child_name="sensors" > + <sensors label="Tilt Hokuyo" + test="hokuyo_test/tilt_selftest.launch" /> + </robot> + + <robot label="Head / Laser Tilt" child_name="head_laser_tests" > + <head_laser_tests label="Head" child_name="head" > + <head label="Head Tilt Hysteresis" + test="head_test/hysteresis_head_tilt.launch" /> + <head label="Head Tilt Sinesweep" + test="head_test/sinesweep_head_tilt.launch" /> + <head label="Head Pan Hysteresis" + test="head_test/hysteresis_head_pan.launch" /> + <head label="Head Pan Sinesweep" + test="head_test/sinesweep_head_pan.launch" /> + </head_laser_tests> + <head_laser_tests label="Laser Tilt" child_name="laser_tilt" > + <laser_tilt label="Laser Tilt Hysteresis" + test="laser_tilt_test/hysteresis_laser_tilt.launch" /> + <laser_tilt label="Laser Tilt Sinesweep" + test="laser_tilt_test/sinesweep_laser_tilt.launch" /> + </head_laser_tests> + </robot> + +</robot_tests> Deleted: pkg/branches/qual_test_2009_07_22/onboard/onboards.xml =================================================================== --- pkg/branches/qual_test_2009_07_22/onboard/onboards.xml 2009-07-31 23:30:47 UTC (rev 20336) +++ pkg/branches/qual_test_2009_07_22/onboard/onboards.xml 2009-07-31 23:43:02 UTC (rev 20337) @@ -1,238 +0,0 @@ -<robot_tests> - <!-- Builds tree of onboard qualification tests for qualification GUI --> - - <!-- Each element is organized as follows: - <parent_name label="Name as Displayed in GUI" child_name="name_of_any_subnodes"> - <child_name label="Child name as Displayed in GUI" - pre="pre_subtest_script.launch" - test="test_launch_file.launch" /> - <child_name label="Other Child name as Displayed in GUI" - pre="pre_subtest_script.launch" - test="other_test_launch_file.launch" /> - </parent_name> - Labels must be unique for each element. Base folder is qualification/onboard - - Change child_name -> node_name ... - Relabel to reduce confusion - - --> - - <robot label="Robot Checkout" test="checkout/robot_checkout.launch" /> - - <robot label="Sensors" child_name="sensors" > - <sensors label="Base Hokuyo" - test="hokuyo_test/base_selftest.launch" /> - <sensors label="Tilt Hokuyo" - test="hokuyo_test/tilt_selftest.launch" /> - <sensors label="IMU" - test="imu_test/selftest.launch" /> - </robot> - - <robot label="Right Arm" child_name="right_arm" > - <!-- No sinesweeps for shoulder --> - <right_arm label="Counterbalance - Right" - pre="full_arm_test/right_arm_test.launch" - test="full_arm_test/counterbalance_test.launch" /> - - <right_arm label="Shoulder - Right" child_name="r_shoulder" > - <r_shoulder label="R Shoulder Pan Hysteresis" - pre="full_arm_test/right_arm_test.launch" - test="full_arm_test/hysteresis_shoulder_pan.launch" /> - <r_shoulder label="R Shoulder Lift Hysteresis" - pre="full_arm_test/right_arm_test.launch" - test="full_arm_test/hysteresis_shoulder_lift.launch" /> - <r_shoulder label="R Upperarm Roll Hysteresis" - pre="full_arm_test/right_arm_test.launch" - test="full_arm_test/hysteresis_upper_arm_roll.launch" /> - </right_arm> - <right_arm label="Upperarm - Right" child_name="r_upperarm" > - <r_upperarm label="R Elbow Flex Hysteresis" - pre="full_arm_test/right_arm_test.launch" - test="full_arm_test/hysteresis_elbow_flex.launch" /> - <r_upperarm label="R Elbow Flex Sinesweep" - pre="full_arm_test/right_arm_test.launch" - test="full_arm_test/sinesweep_elbow_flex.launch" /> - <r_upperarm label="R Forearm Roll Hysteresis" - pre="full_arm_test/right_arm_test.launch" - test="full_arm_test/hysteresis_forearm_roll.launch" /> - <r_upperarm label="R Forearm Roll Sinesweep" - pre="full_arm_test/right_arm_test.launch" - test="full_arm_test/sinesweep_forearm_roll.launch" /> - </right_arm> - <right_arm label="Wrist - Right" child_name="r_wrist" > - <r_wrist label="R Wrist Flex Hysteresis" - pre="full_arm_test/right_arm_test.launch" - test="full_arm_test/hysteresis_wrist_flex.launch" /> - <r_wrist label="R Wrist Flex Sinesweep" - pre="full_arm_test/right_arm_test.launch" - test="full_arm_test/sinesweep_wrist_flex.launch" /> - <r_wrist label="R Wrist Roll Hysteresis" - pre="full_arm_test/right_arm_test.launch" - test="full_arm_test/hysteresis_wrist_roll.launch" /> - <r_wrist label="R Wrist Roll Sinesweep" - pre="full_arm_test/right_arm_test.launch" - test="full_arm_test/sinesweep_wrist_roll.launch" /> - </right_arm> - <right_arm label="Gripper - Right" child_name="r_gripper" > - <r_gripper label="R Gripper Hysteresis" - pre="full_arm_test/right_arm_test.launch" - test="full_arm_test/hysteresis_gripper.launch" /> - </right_arm> - </robot> - - <robot label="Left Arm" child_name="left_arm" > - <left_arm label="Shoulder - Left" child_name="l_shoulder" > - <l_shoulder label="L Shoulder Pan Hysteresis" - pre="full_arm_test/left_arm_test.launch" - test="full_arm_test/hysteresis_shoulder_pan.launch" /> - <l_shoulder label="L Shoulder Lift Hysteresis" - pre="full_arm_test/left_arm_test.launch" - test="full_arm_test/hysteresis_shoulder_lift.launch" /> - <l_shoulder label="L Upperarm Roll Hysteresis" - pre="full_arm_test/left_arm_test.launch" - test="full_arm_test/hysteresis_upper_arm_roll.launch" /> - </left_arm> - <left_arm label="Upperarm - Left" child_name="l_upperarm" > - <l_upperarm label="L Elbow Flex Hysteresis" - pre="left_arm_test.launch" - test="full_arm_test/hysteresis_elbow_flex.launch" /> - <l_upperarm label="L Elbow Flex Sinesweep" - pre="left_arm_test.launch" - test="full_arm_test/sinesweep_elbow_flex.launch" /> - <l_upperarm label="L Forearm Roll Hysteresis" - pre="left_arm_test.launch" - test="full_arm_test/hysteresis_forearm_roll.launch" /> - <l_upperarm label="L Forearm Roll Sinesweep" - pre="left_arm_test.launch" - test="full_arm_test/sinesweep_forearm_roll.launch" /> - </left_arm> - <left_arm label="Wrist - Left" child_name="l_wrist" > - <l_wrist label="L Wrist Flex Hysteresis" - pre="full_arm_test/left_arm_test.launch" - test="full_arm_test/hysteresis_wrist_flex.launch" /> - <l_wrist label="L Wrist Flex Sinesweep" - pre="full_arm_test/left_arm_test.launch" - test="full_arm_test/sinesweep_wrist_flex.launch" /> - <l_wrist label="L Wrist Roll Hysteresis" - pre="full_arm_test/left_arm_test.launch" - test="full_arm_test/hysteresis_wrist_roll.launch" /> - <l_wrist label="L Wrist Roll Sinesweep" - pre="full_arm_test/left_arm_test.launch" - test="full_arm_test/sinesweep_wrist_roll.launch" /> - </left_arm> - <left_arm label="Gripper - Left" child_name="l_gripper" > - <l_gripper label="L Gripper Hysteresis" - pre="full_arm_test/left_arm_test.launch" - test="full_arm_test/hysteresis_gripper.launch" /> - </left_arm> - </robot> - - <robot label="Head / Laser Tilt" child_name="head_laser_tests" > - <head_laser_tests label="Head" child_name="head" > - <head label="Head Tilt Hysteresis" - test="head_test/hysteresis_head_tilt.launch" /> - <head label="Head Tilt Sinesweep" - test="head_test/sinesweep_head_tilt.launch" /> - <head label="Head Pan Hysteresis" - test="head_test/hysteresis_head_pan.launch" /> - <head label="Head Pan Sinesweep" - test="head_test/sinesweep_head_pan.launch" /> - </head_laser_tests> - <head_laser_tests label="Laser Tilt" child_name="laser_tilt" > - <laser_tilt label="Laser Tilt Hysteresis" - test="laser_tilt_test/hysteresis_laser_tilt.launch" /> - <laser_tilt label="Laser Tilt Sinesweep" - test="laser_tilt_test/sinesweep_laser_tilt.launch" /> - </head_laser_tests> - </robot> - - <robot label="Spine Test" - test="torso_lift_test/hysteresis_torso_lift.launch" /> - - <robot label="Base Tests" child_name="base_tests" > - <base_tests label="FL Caster" child_name="fl_caster" > - <fl_caster label="FL Caster Turret Hysteresis" - pre="caster_test/fl_caster.launch" - test="caster_test/hysteresis_caster_turret.launch" /> - <fl_caster label="FL Caster Turret Sinesweep" - pre="caster_test/fl_caster.launch" - test="caster_test/sinesweep_caster_turret.launch" /> - <fl_caster label="FL Caster R Wheel Hysteresis" - pre="caster_test/fl_caster.launch" - test="caster_test/hysteresis_caster_right.launch" /> - <fl_caster label="FL Caster R Wheel Sinesweep" - pre="caster_test/fl_caster.launch" - test="caster_test/sinesweep_caster_right.launch" /> - <fl_caster label="FL Caster L Wheel Hysteresis" - pre="caster_test/fl_caster.launch" - test="caster_test/hysteresis_caster_left.launch" /> - <fl_caster label="FL Caster L Wheel Sinesweep" - pre="caster_test/fl_caster.launch" - test="caster_test/sinesweep_caster_left.launch" /> - </base_tests> - - <base_tests label="FR Caster" child_name="fr_caster" > - <fr_caster label="FR Caster Turret Hysteresis" - pre="caster_test/fr_caster.launch" - test="caster_test/hysteresis_caster_turret.launch" /> - <fr_caster label="FR Caster Turret Sinesweep" - pre="caster_test/fr_caster.launch" - test="caster_test/sinesweep_caster_turret.launch" /> - <fr_caster label="FR Caster R Wheel Hysteresis" - pre="caster_test/fr_caster.launch" - test="caster_test/hysteresis_caster_right.launch" /> - <fr_caster label="FR Caster R Wheel Sinesweep" - pre="caster_test/fr_caster.launch" - test="caster_test/sinesweep_caster_right.launch" /> - <fr_caster label="FR Caster L Wheel Hysteresis" - pre="caster_test/fr_caster.launch" - test="caster_test/hysteresis_caster_left.launch" /> - <fr_caster label="FR Caster L Wheel Sinesweep" - pre="caster_test/fr_caster.launch" - test="caster_test/sinesweep_caster_left.launch" /> - </base_tests> - - <base_tests label="BL Caster" child_name="bl_caster" > - <bl_caster label="BL Caster Turret Hysteresis" - pre="caster_test/bl_caster.launch" - test="caster_test/hysteresis_caster_turret.launch" /> - <bl_caster label="BL Caster Turret Sinesweep" - pre="caster_test/bl_caster.launch" - test="caster_test/sinesweep_caster_turret.launch" /> - <bl_caster label="BL Caster R Wheel Hysteresis" - pre="caster_test/bl_caster.launch" - test="caster_test/hysteresis_caster_right.launch" /> - <bl_caster label="BL Caster R Wheel Sinesweep" - pre="caster_test/bl_caster.launch" - test="caster_test/sinesweep_caster_right.launch" /> - <bl_caster label="BL Caster L Wheel Hysteresis" - pre="caster_test/bl_caster.launch" - test="caster_test/hysteresis_caster_left.launch" /> - <bl_caster label="BL Caster L Wheel Sinesweep" - pre="caster_test/bl_caster.launch" - test="caster_test/sinesweep_caster_left.launch" /> - </base_tests> - - <base_tests label="BR Caster" child_name="br_caster" > - <br_caster label="BR Caster Turret Hysteresis" - pre="caster_test/br_caster.launch" - test="caster_test/hysteresis_caster_turret.launch" /> - <br_caster label="BR Caster Turret Sinesweep" - pre="caster_test/br_caster.launch" - test="caster_test/sinesweep_caster_turret.launch" /> - <br_caster label="BR Caster R Wheel Hysteresis" - pre="caster_test/br_caster.launch" - test="caster_test/hysteresis_caster_right.launch" /> - <br_caster label="BR Caster R Wheel Sinesweep" - pre="caster_test/br_caster.launch" - test="caster_test/sinesweep_caster_right.launch" /> - <br_caster label="BR Caster L Wheel Hysteresis" - pre="caster_test/br_caster.launch" - test="caster_test/hysteresis_caster_left.launch" /> - <br_caster label="BR Caster L Wheel Sinesweep" - pre="caster_test/br_caster.launch" - test="caster_test/sinesweep_caster_left.launch" /> - </base_tests> -</robot> - -</robot_tests> Copied: pkg/branches/qual_test_2009_07_22/onboard/pr2_qual.xml (from rev 19448, pkg/branches/qual_test_2009_07_22/onboard/onboards.xml) =================================================================== --- pkg/branches/qual_test_2009_07_22/onboard/pr2_qual.xml (rev 0) +++ pkg/branches/qual_test_2009_07_22/onboard/pr2_qual.xml 2009-07-31 23:43:02 UTC (rev 20337) @@ -0,0 +1,239 @@ +<robot_tests> + <!-- Builds tree of onboard qualification tests for qualification GUI --> + + <!-- Each element is organized as follows: + <parent_name label="Name as Displayed in GUI" child_name="name_of_any_subnodes"> + <child_name label="Child name as Displayed in GUI" + pre="pre_subtest_script.launch" + test="test_launch_file.launch" /> + <child_name label="Other Child name as Displayed in GUI" + pre="pre_subtest_script.launch" + test="other_test_launch_file.launch" /> + </parent_name> + Labels must be unique for each element. Base folder is qualification/onboard + + Change child_name -> node_name ... + Relabel to reduce confusion + + --> + + <robot label="Robot Checkout" test="checkout/robot_checkout.launch" + key="0.0" /> + + <robot label="Sensors" child_name="sensors" > + <sensors label="Base Hokuyo" + test="hokuyo_test/base_selftest.launch" /> + <sensors label="Tilt Hokuyo" + test="hokuyo_test/tilt_selftest.launch" /> + <sensors label="IMU" + test="imu_test/selftest.launch" /> + </robot> + + <robot label="Right Arm" child_name="right_arm" > + <!-- No sinesweeps for shoulder --> + <right_arm label="Counterbalance - Right" + pre="full_arm_test/right_arm_test.launch" + test="full_arm_test/counterbalance_test.launch" /> + + <right_arm label="Shoulder - Right" child_name="r_shoulder" > + <r_shoulder label="R Shoulder Pan Hysteresis" + pre="full_arm_test/right_arm_test.launch" + test="full_arm_test/hysteresis_shoulder_pan.launch" /> + <r_shoulder label="R Shoulder Lift Hysteresis" + pre="full_arm_test/right_arm_test.launch" + test="full_arm_test/hysteresis_shoulder_lift.launch" /> + <r_shoulder label="R Upperarm Roll Hysteresis" + pre="full_arm_test/right_arm_test.launch" + test="full_arm_test/hysteresis_upper_arm_roll.launch" /> + </right_arm> + <right_arm label="Upperarm - Right" child_name="r_upperarm" > + <r_upperarm label="R Elbow Flex Hysteresis" + pre="full_arm_test/right_arm_test.launch" + test="full_arm_test/hysteresis_elbow_flex.launch" /> + <r_upperarm label="R Elbow Flex Sinesweep" + pre="full_arm_test/right_arm_test.launch" + test="full_arm_test/sinesweep_elbow_flex.launch" /> + <r_upperarm label="R Forearm Roll Hysteresis" + pre="full_arm_test/right_arm_test.launch" + test="full_arm_test/hysteresis_forearm_roll.launch" /> + <r_upperarm label="R Forearm Roll Sinesweep" + pre="full_arm_test/right_arm_test.launch" + test="full_arm_test/sinesweep_forearm_roll.launch" /> + </right_arm> + <right_arm label="Wrist - Right" child_name="r_wrist" > + <r_wrist label="R Wrist Flex Hysteresis" + pre="full_arm_test/right_arm_test.launch" + test="full_arm_test/hysteresis_wrist_flex.launch" /> + <r_wrist label="R Wrist Flex Sinesweep" + pre="full_arm_test/right_arm_test.launch" + test="full_arm_test/sinesweep_wrist_flex.launch" /> + <r_wrist label="R Wrist Roll Hysteresis" + pre="full_arm_test/right_arm_test.launch" + test="full_arm_test/hysteresis_wrist_roll.launch" /> + <r_wrist label="R Wrist Roll Sinesweep" + pre="full_arm_test/right_arm_test.launch" + test="full_arm_test/sinesweep_wrist_roll.launch" /> + </right_arm> + <right_arm label="Gripper - Right" child_name="r_gripper" > + <r_gripper label="R Gripper Hysteresis" + pre="full_arm_test/right_arm_test.launch" + test="full_arm_test/hysteresis_gripper.launch" /> + </right_arm> + </robot> + + <robot label="Left Arm" child_name="left_arm" > + <left_arm label="Shoulder - Left" child_name="l_shoulder" > + <l_shoulder label="L Shoulder Pan Hysteresis" + pre="full_arm_test/left_arm_test.launch" + test="full_arm_test/hysteresis_shoulder_pan.launch" /> + <l_shoulder label="L Shoulder Lift Hysteresis" + pre="full_arm_test/left_arm_test.launch" + test="full_arm_test/hysteresis_shoulder_lift.launch" /> + <l_shoulder label="L Upperarm Roll Hysteresis" + pre="full_arm_test/left_arm_test.launch" + test="full_arm_test/hysteresis_upper_arm_roll.launch" /> + </left_arm> + <left_arm label="Upperarm - Left" child_name="l_upperarm" > + <l_upperarm label="L Elbow Flex Hysteresis" + pre="left_arm_test.launch" + test="full_arm_test/hysteresis_elbow_flex.launch" /> + <l_upperarm label="L Elbow Flex Sinesweep" + pre="left_arm_test.launch" + test="full_arm_test/sinesweep_elbow_flex.launch" /> + <l_upperarm label="L Forearm Roll Hysteresis" + pre="left_arm_test.launch" + test="full_arm_test/hysteresis_forearm_roll.launch" /> + <l_upperarm label="L Forearm Roll Sinesweep" + pre="left_arm_test.launch" + test="full_arm_test/sinesweep_forearm_roll.launch" /> + </left_arm> + <left_arm label="Wrist - Left" child_name="l_wrist" > + <l_wrist label="L Wrist Flex Hysteresis" + pre="full_arm_test/left_arm_test.launch" + test="full_arm_test/hysteresis_wrist_flex.launch" /> + <l_wrist label="L Wrist Flex Sinesweep" + pre="full_arm_test/left_arm_test.launch" + test="full_arm_test/sinesweep_wrist_flex.launch" /> + <l_wrist label="L Wrist Roll Hysteresis" + pre="full_arm_test/left_arm_test.launch" + test="full_arm_test/hysteresis_wrist_roll.launch" /> + <l_wrist label="L Wrist Roll Sinesweep" + pre="full_arm_test/left_arm_test.launch" + test="full_arm_test/sinesweep_wrist_roll.launch" /> + </left_arm> + <left_arm label="Gripper - Left" child_name="l_gripper" > + <l_gripper label="L Gripper Hysteresis" + pre="full_arm_test/left_arm_test.launch" + test="full_arm_test/hysteresis_gripper.launch" /> + </left_arm> + </robot> + + <robot label="Head / Laser Tilt" child_name="head_laser_tests" > + <head_laser_tests label="Head" child_name="head" > + <head label="Head Tilt Hysteresis" + test="head_test/hysteresis_head_tilt.launch" /> + <head label="Head Tilt Sinesweep" + test="head_test/sinesweep_head_tilt.launch" /> + <head label="Head Pan Hysteresis" + test="head_test/hysteresis_head_pan.launch" /> + <head label="Head Pan Sinesweep" + test="head_test/sinesweep_head_pan.launch" /> + </head_laser_tests> + <head_laser_tests label="Laser Tilt" child_name="laser_tilt" > + <laser_tilt label="Laser Tilt Hysteresis" + test="laser_tilt_test/hysteresis_laser_tilt.launch" /> + <laser_tilt label="Laser Tilt Sinesweep" + test="laser_tilt_test/sinesweep_laser_tilt.launch" /> + </head_laser_tests> + </robot> + + <robot label="Spine Test" + test="torso_lift_test/hysteresis_torso_lift.launch" /> + + <robot label="Base Tests" child_name="base_tests" > + <base_tests label="FL Caster" child_name="fl_caster" > + <fl_caster label="FL Caster Turret Hysteresis" + pre="caster_test/fl_caster.launch" + test="caster_test/hysteresis_caster_turret.launch" /> + <fl_caster label="FL Caster Turret Sinesweep" + pre="caster_test/fl_caster.launch" + test="caster_test/sinesweep_caster_turret.launch" /> + <fl_caster label="FL Caster R Wheel Hysteresis" + pre="caster_test/fl_caster.launch" + test="caster_test/hysteresis_caster_right.launch" /> + <fl_caster label="FL Caster R Wheel Sinesweep" + pre="caster_test/fl_caster.launch" + test="caster_test/sinesweep_caster_right.launch" /> + <fl_caster label="FL Caster L Wheel Hysteresis" + pre="caster_test/fl_caster.launch" + test="caster_test/hysteresis_caster_left.launch" /> + <fl_caster label="FL Caster L Wheel Sinesweep" + pre="caster_test/fl_caster.launch" + test="caster_test/sinesweep_caster_left.launch" /> + </base_tests> + + <base_tests label="FR Caster" child_name="fr_caster" > + <fr_caster label="FR Caster Turret Hysteresis" + pre="caster_test/fr_caster.launch" + test="caster_test/hysteresis_caster_turret.launch" /> + <fr_caster label="FR Caster Turret Sinesweep" + pre="caster_test/fr_caster.launch" + test="caster_test/sinesweep_caster_turret.launch" /> + <fr_caster label="FR Caster R Wheel Hysteresis" + pre="caster_test/fr_caster.launch" + test="caster_test/hysteresis_caster_right.launch" /> + <fr_caster label="FR Caster R Wheel Sinesweep" + pre="caster_test/fr_caster.launch" + test="caster_test/sinesweep_caster_right.launch" /> + <fr_caster label="FR Caster L Wheel Hysteresis" + pre="caster_test/fr_caster.launch" + test="caster_test/hysteresis_caster_left.launch" /> + <fr_caster label="FR Caster L Wheel Sinesweep" + pre="caster_test/fr_caster.launch" + test="caster_test/sinesweep_caster_left.launch" /> + </base_tests> + + <base_tests label="BL Caster" child_name="bl_caster" > + <bl_caster label="BL Caster Turret Hysteresis" + pre="caster_test/bl_caster.launch" + test="caster_test/hysteresis_caster_turret.launch" /> + <bl_caster label="BL Caster Turret Sinesweep" + pre="caster_test/bl_caster.launch" + test="caster_test/sinesweep_caster_turret.launch" /> + <bl_caster label="BL Caster R Wheel Hysteresis" + pre="caster_test/bl_caster.launch" + test="caster_test/hysteresis_caster_right.launch" /> + <bl_caster label="BL Caster R Wheel Sinesweep" + pre="caster_test/bl_caster.launch" + test="caster_test/sinesweep_caster_right.launch" /> + <bl_caster label="BL Caster L Wheel Hysteresis" + pre="caster_test/bl_caster.launch" + test="caster_test/hysteresis_caster_left.launch" /> + <bl_caster label="BL Caster L Wheel Sinesweep" + pre="caster_test/bl_caster.launch" + test="caster_test/sinesweep_caster_left.launch" /> + </base_tests> + + <base_tests label="BR Caster" child_name="br_caster" > + <br_caster label="BR Caster Turret Hysteresis" + pre="caster_test/br_caster.launch" + test="caster_test/hysteresis_caster_turret.launch" /> + <br_caster label="BR Caster Turret Sinesweep" + pre="caster_test/br_caster.launch" + test="caster_test/sinesweep_caster_turret.launch" /> + <br_caster label="BR Caster R Wheel Hysteresis" + pre="caster_test/br_caster.launch" + test="caster_test/hysteresis_caster_right.launch" /> + <br_caster label="BR Caster R Wheel Sinesweep" + pre="caster_test/br_caster.launch" + test="caster_test/sinesweep_caster_right.launch" /> + <br_caster label="BR Caster L Wheel Hysteresis" + pre="caster_test/br_caster.launch" + test="caster_test/hysteresis_caster_left.launch" /> + <br_caster label="BR Caster L Wheel Sinesweep" + pre="caster_test/br_caster.launch" + test="caster_test/sinesweep_caster_left.launch" /> + </base_tests> +</robot> + +</robot_tests> Property changes on: pkg/branches/qual_test_2009_07_22/onboard/pr2_qual.xml ___________________________________________________________________ Added: svn:mergeinfo + Modified: pkg/branches/qual_test_2009_07_22/onboard/robots.xml =================================================================== --- pkg/branches/qual_test_2009_07_22/onboard/robots.xml 2009-07-31 23:30:47 UTC (rev 20336) +++ pkg/branches/qual_test_2009_07_22/onboard/robots.xml 2009-07-31 23:43:02 UTC (rev 20337) @@ -1,11 +1,20 @@ <robots> - <robot name="PRE" pkg="pr2_alpha" file="pre.launch" - -/> + <robot name="PRE" start_pkg="pr2_alpha" startup="pre.launch" + test_file="pr2_qual.xml" serial="my_serial" /> + + + <robot name="HCA" start_pkg="pr2_head_cart" startup="hca.launch" + test_file="head_cart_qual.xml" serial="hca" /> + + <robot name="HCC" start_pkg="pr2_head_cart" startup="hcc.launch" + test_file="head_cart_qual.xml" serial="hcc" /> + + +<!-- <robot name="PRF" pkg="pr2_alpha" file="prf.launch" /> <robot name="PRG" pkg="pr2_alpha" file="prg.launch" /> - <robot name="HCA" pkg="pr2_head_cart" file="hca.launch" /> <robot name="HCB" pkg="pr2_head_cart" file="hcb.launch" /> <robot name="HCC" pkg="pr2_head_cart" file="hcc.launch" /> +--> </robots> Added: pkg/branches/qual_test_2009_07_22/src/qualification/qual_frame.py =================================================================== --- pkg/branches/qual_test_2009_07_22/src/qualification/qual_frame.py (rev 0) +++ pkg/branches/qual_test_2009_07_22/src/qualification/qual_frame.py 2009-07-31 23:43:02 UTC (rev 20337) @@ -0,0 +1,714 @@ +#!/usr/bin/env python +# +# Software License Agreement (BSD License) +# +# Copyright (c) 2008, Willow Garage, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided +# with the distribution. +# * Neither the name of the Willow Garage nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +### Author: Kevin Watt + +import roslib +import roslib.packages +roslib.load_manifest('qualification') + +import rospy + +import os +import sys +from datetime import datetime +import wx +import time +from wx import xrc +from wx import html + +from xml.dom import minidom + +from qualification.msg import * +from qualification.srv import * +from qualification.test import * +from qualification.result import * + +import traceback + +import invent_client.invent_client +from invent_client.invent_client import Invent + +import runtime_monitor +from runtime_monitor.monitor_panel import MonitorPanel + +import wg_hardware_roslaunch.roslaunch_caller as roslaunch_caller + + +RESULTS_DIR = os.path.join(roslib.packages.get_pkg_dir('qualification'), 'results') + +## Main frame of qualification +## Loads tests, launches them and records results +class QualificationFrame(wx.Frame): + def __init__(self, parent): + wx.Frame.__init__(self, parent, wx.ID_ANY, "Qualification") + + self._result_service = None + self._prestartup_done_srv = None + self._shutdown_done_srv = None + + self.load_wg_test_map() + + self.create_menu_bar() + + # Load the XRC resource + xrc_path = os.path.join(roslib.packages.get_pkg_dir('qualification'), 'xrc/gui.xrc') + self._res = xrc.XmlResource(xrc_path) + + # Load the main panel + self._root_panel = self._res.LoadPanel(self, 'main_panel') + + self._top_panel = xrc.XRCCTRL(self._root_panel, "top_panel") + self._top_sizer = wx.BoxSizer(wx.HORIZONTAL) + self._top_panel.SetSizer(self._top_sizer) + self._current_panel = None + self._log_panel = xrc.XRCCTRL(self._root_panel, "log_panel") + self._log = xrc.XRCCTRL(self._log_panel, 'log') + + self._test_log = {} # Move to results class? + self.log("Startup") + self.reset() + + self.Bind(wx.EVT_CLOSE, self.on_close) + + self._startup_launch = None + self._shutdown_launch = None + self._subtest_launch = None + self._prestartup_launch = None + self._current_test = None + + self._spin_timer = wx.Timer(self, wx.ID_ANY) + self.Bind(wx.EVT_TIMER, self.on_spin, self._spin_timer) + self._spin_timer.Start(100) + + self._show_results_always = False + #self._config_service = None + + rospy.set_param('/invent/username', '') + rospy.set_param('/invent/password', '') + + def create_menu_bar(self): + menubar = wx.MenuBar() + self._file_menu = wx.Menu() + self._file_menu.Append(1001, "Invent Login\tCTRL+l") + self._file_menu.Append(wx.ID_EXIT, "E&xit") + menubar.Append(self._file_menu, "&File") + + self._options_menu = wx.Menu() + self._options_menu.AppendCheckItem(2001, "Always Show Results") + menubar.Append(self._options_menu, "&Options") + + self._powerboard_menu = wx.Menu() + self._powerboard_menu.Append(3101, "Power Board\tCTRL+b") + self._powerboard_menu.AppendCheckItem(3150, "Breaker 0\tCTRL+0") + self._powerboard_menu.AppendCheckItem(3151, "Breaker 1\tCTRL+1") + self._powerboard_menu.AppendCheckItem(3152, "Breaker 2\tCTRL+2") + self._powerboard_menu.Check(3150, rospy.get_param('powerboard/0')) + self._powerboard_menu.Check(3151, rospy.get_param('powerboard/1')) + self._powerboard_menu.Check(3152, rospy.get_param('powerboard/2')) + + menubar.Append(self._powerboard_menu, "&Powerboard") + + self._host_menu = wx.Menu() + self._host_menu.Append(4001, "Select Test Host\tCTRL+h") + menubar.Append(self._host_menu, "Test &Host") + + self.SetMenuBar(menubar) + self.Bind(wx.EVT_MENU, self.on_menu) + + def on_menu(self, event): + if (event.GetEventObject() == self._file_menu): + if (event.GetId() == wx.ID_EXIT): + self.Close() + return + if (event.GetId() == 1001): + self.login_to_invent() + return + + if (event.GetEventObject() == self._options_menu): + if (event.GetId() == 2001): + self._show_results_always = self._options_menu.IsChecked(2001) + + if (event.GetEventObject() == self._powerboard_menu): + if (event.GetId() == 3101): + while not rospy.is_shutdown(): + # Get powerboard from user + serial = wx.GetTextFromUser('Enter last four digits of power board serial number', 'Select Power Board', rospy.get_param('powerboard/serial')) + if len(serial) == 4 and unicode(serial).isnumeric(): + rospy.set_param('powerboard/serial', serial) + break + are_you_sure = wx.MessageDialog(self, 'Invalid powerboard ID. Retry?', 'Invalid serial', + wx.OK|wx.CANCEL) + if are_you_sure.ShowModal() != wx.ID_OK: + break + + + if (event.GetId() == 3150): + rospy.set_param('powerboard/0', self._powerboard_menu.IsChecked(2150)) + if (event.GetId() == 3151): + rospy.set_param('powerboard/1', self._powerboard_menu.IsChecked(2151)) + if (event.GetId() == 3152): + rospy.set_param('powerboard/2', self._powerboard_menu.IsChecked(2152)) + + if (event.GetEventObject() == self._host_menu): + if (event.GetId() == 4001): + host = wx.GetTextFromUser('Enter test host', 'Test Host', os.environ['ROS_TEST_HOST']) + os.environ['ROS_TEST_HOST'] = host + + def load_wg_test_map(self): + # Load 'Map' of WG test locations to find defaults for this machine + map_xml_path = os.path.join(roslib.packages.get_pkg_dir('qualification'), 'wg_map.xml') + + gui_name = socket.gethostname() + + try: + doc = minidom.parse(map_xml_path) + except IOError: + print >> sys.stderr, "Could not load test map from '%s'"%(map_xml_path) + sys.exit() + + stations = doc.getElementsByTagName('station') + + my_station = None + for station in stations: + if station.attributes['gui'].value == gui_name: + my_station = station + break + + if not my_station: + my_station = stations[0] + + rospy.set_param('powerboard/serial', my_station.attributes['powerboard'].value) + rospy.set_param('powerboard/0', bool(my_station.attributes['breaker0'].value)) + rospy.set_param('powerboard/1', bool(my_station.attributes['breaker1'].value)) + rospy.set_param('powerboard/2', bool(my_station.attributes['breaker2'].value)) + os.environ['ROS_TEST_HOST'] = my_station.attributes['host'].value + + def log(self, msg): + log_msg = datetime.now().strftime("%m/%d/%Y %H:%M:%S: ") + msg + self._test_log[datetime.now()] = msg + self._log.AppendText(log_msg + '\n') + self._log.Refresh() + self._log.Update() + + def set_top_panel(self, panel): + if self._current_panel == panel: + return + + self._current_panel = panel + self._top_sizer.Clear(True) + self._top_sizer.Add(self._current_panel, 1, wx.EXPAND|wx.ALIGN_CENTER_VERTICAL) + self._top_panel.Layout() + + ## Override with inheritance + # def get_loader_panel(self): + # return serial_panel or pr2_qual_panel + + def reset(self): + # + self.set_top_panel(SerialPanel(self._top_panel, self._res, self)) + self._results = None + self._plots_panel = None + self._test_log = {} + + # Called from serial panel + # Rename to something useful at some point + def begin_test(self, test, qual_item): + self._current_test = test + self._current_item = qual_item + + rospy.set_param('qualification/serial', self._current_item.serial) + rospy.set_param('qualification/name', self._current_item.name) + + if (self._current_test.getInstructionsFile() != None): + self.set_top_panel(InstructionsPanel(self._top_panel, self._res, self, self._current_test.getInstructionsFile())) + else: + self.start_qualification() + + # Launches program for either onboard, component conf or test cart tests + def start_qualification(self): + if (len(self._current_test.subtests) == 0): + wx.MessageBox('Test selected has no subtests defined', 'No tests', wx.OK|wx.ICON_ERROR, self) + return + + self._tests_start_date = datetime.now() + + self._results = QualTestResult(self._current_item, self._current_test, self._tests_start_date) + + # Create plots panel to show plots, runtime monitor. + self._plots_panel = PlotsPanel(self._top_panel, self._res, self) + + if (self._result_service != None): + self._result_service.shutdown() + self._result_service = None + + self._result_service = rospy.Service('test_result', TestResult, self.subtest_callback) + + self.run_prestartup_scripts() + + def run_prestartup_scripts(self): + # Run any pre_startup scripts synchronously + if (len(self._current_test.pre_startup_scripts) == 0): + self.log('No prestartup scripts.') + self.test_startup() + return + + self._prestartup_index = 0 + + if (self._prestartup_done_srv != None): + self._prestartup_done_srv.shutdown() + self._prestartup_done_srv = None + + print 'Running prestartup scripts' + self._prestartup_done_srv = rospy.Service('prestartup_done', ScriptDone, self.prestartup_done_callback) + + self.prestartup_call() + + def prestartup_done_callback(self, srv): + wx.CallAfter(self.prestartup_finished, srv) + + return ScriptDoneResponse() + + def prestartup_finished(self, srv): + if self._prestartup_launch != None: + self._prestartup_launch.shutdown() + self._prestartup_launch = None + + result_dict = { 0: 'OK', 1: 'FAIL', 2: 'ERROR' } + self.log('Prestartup script %s finished. Result %s.' % (srv.script, result_dict[srv.result])) + + self._results.add_prestartup_result(self._prestartup_index, srv) + + if srv.result == 0: + # Continue to next test + self._prestartup_index += 1 + if self._prestartup_index >= len(self._current_test.pre_startup_scripts): + + if self._prestartup_done_srv: + self._prestartup_done_srv.shutdown() + self._prestartup_done_srv = None + + self.test_startup() + else: + self.prestartup_call() + else: + if self._prestartup_done_srv: + self._prestartup_done_srv.shutdown() + self._prestartup_done_srv = None + + self.test_finished() + + def prestartup_call(self): + script = self._current_test.pre_startup_scripts[self._prestartup_index].launch_file + name = self._current_test.pre_startup_scripts[self._prestartup_index].get_name() + # update script label in waiting panel + log_message = 'Running pre_startup script [%s]...'%(name) + self.log(log_message) + + wait_html = '<html><H2 align=center>Prestartup Scripts Running</H2>\n' + wait_html += '<H3 align=center>Script: %s</H3>\n</html>' % name + + self._plots_panel.show_waiting(wait_html) + + self.set_top_panel(self._plots_panel) + + self._prestartup_launch = self.launch_script(script, None) + if (self._prestartup_launch == None): + s = 'Could not load roslaunch script "%s"! Press OK to cancel test.' % (os.path.basename(script)) + wx.MessageBox(s, 'Invalid roslaunch file', wx.OK|wx.ICON_ERROR, self) + self.cancel(s) + return + + + def test_startup(self): + # Run the startup script if we have one + startup = self._current_test.getStartupScript() + + if startup: + self.log('Running startup script...') + self._startup_launch = self.launch_script(startup.launch_file, None) + if (self._startup_launch == None): + s = 'Could not load roslaunch script %s, file: "%s"' % (startup.get_name(), os.path.basename(startup.launch_file)) + wx.MessageBox(s, 'Invalid roslaunch file. Press OK to cancel.', wx.OK|wx.ICON_ERROR, self) + self.cancel(s) + return + else: + self.log('No startup script') + + self.start_subtest(0) + + def make_html_waiting_page(self, subtest_name, index, len_subtests): + html = '<html>\n<H2 align=center>Waiting for Subtest to Complete</H2>\n' + html += '<H3 align=center>Test Name: %s</H3>\n' % subtest_name + html += '<H4 align=center>Test %s of %s</H4>\n</html>' % (index + 1, len_subtests) + return html + + def start_subtest(self, index): + subtest = self._current_test.subtests[self._subtest_index] + + self._plots_panel.show_waiting(self.make_html_waiting_page(subtest.get_name(), index, len(self._current_test.subtests))) + self.set_top_panel(self._plots_panel) + + self.launch_pre_subtest() + + script = subtest._test_script + self._subtest_launch = self.launch_script(script, None) + if (self._subtest_launch == None): + s = 'Could not load roslaunch script "%s"'%(os.path.basename(script)) + wx.MessageBox(s, 'Invalid roslaunch file. Press OK to cancel.', wx.OK|wx.ICON_ERROR, self) + self.cancel(s) + return + + def show_results(self): + panel = ResultsPanel(self._top_panel, self._res, self) + self.set_top_panel(panel) + + if self._results is not None: + self._results.write_results_to_file() # Write to temp dir + panel.set_results(self._results) + else: + self.reset() + + def show_plots(self, sub_result): + self._plots_panel.show_plots(sub_result.make_result_page()) + self.set_top_panel(self._plots_panel) + + def login_to_invent(self): + dialog = self._res.LoadDialog(self, 'username_password_dialog') + xrc.XRCCTRL(dialog, 'text').Wrap(300) + dialog.Layout() + dialog.Fit() + username_ctrl = xrc.XRCCTRL(dialog, 'username') + password_ctrl = xrc.XRCCTRL(dialog, 'password') + username_ctrl.SetFocus() + + # These values don't come through in the xrc file + username_ctrl.SetMinSize(wx.Size(200, -1)) + password_ctrl.SetMinSize(wx.Size(200, -1)) + if (dialog.ShowModal() == wx.ID_OK): + username = username_ctrl.GetValue() + password = password_ctrl.GetValue() + + invent = Invent(username, password) + + if (invent.login() == False): + return self.login_to_invent() + + rospy.set_param('invent/username', username) + rospy.set_param('invent/password', password) + return True + else: + return False + + + # TODO: Put in invent client + def get_inventory_object(self): + username = rospy.get_param('invent/username', '') + password = rospy.get_param('invent/password', '') + + if (username != None and password != None): + invent = Invent(username, password) + if (invent.login() == True): + return invent + + rospy.set_param('invent/username', '') + rospy.set_param('invent/password', '') + + if not self.login_to_invent(): + return None + else: + return Invent(username, password) + + + def verify_submit(self): + submit_check = 'Are you sure you want to submit?\n\n' + submit_check += 'Press OK to submit or Cancel to recheck results.\n' + submit_check += 'Be sure to select the correct directory to record your results.\n' + + are_you_sure = wx.MessageDialog(self, submit_check, 'Verify Results Submission', + wx.OK|wx.CANCEL) + return are_you_sure.ShowModal() == wx.ID_OK + + def submit_results(self, notes, dir): + if not self.verify_submit(): + return + + if self._current_item is None: + self.log('Can\'t submit, no item') + self.reset() + return + + if not dir.endswith('/'): + dir += '/' + self._results._results_dir = dir + + invent = self.get_inventory_object() + self._results.set_notes(notes) + self._results.set_operator(rospy.get_param('invent/username', '')) + + self.log('Results logged to %s' % self._results._results_dir) + res, log_str = self._results.log_results(invent) + self.log(log_str) + + print 'Logged results to invent' + + self._results._test_log = self._test_log + + print 'Emailing results' + if not self._results.email_qual_team(): + wx.MessageBox('Unable to email qualification results. Do you have \'sendmail\' installed?', 'Unable to email results', wx.OK|wx.ICON_ERROR, self) + self.log('Unable to email summary.') + else: + self.log('Emailed summary to %s' % self._results.get_qual_team()) + + self.reset() + + + def next_subtest(self): + if (self._subtest_index + 1 >= len(self._current_test.subtests)): + self.test_finished() + else: + self.start_subtest(self._subtest_index + 1) + + + def launch_pre_subtest(self): + subtest = self._current_test.subtests[self._subtest_index] + + if (subtest._pre_script is not None): + script = subtest._pre_script + pre_launcher = self.launch_script(script, None) + if (pre_launcher == None): + s = 'Could not load pre-subtest roslaunch script "%s"'%(os.path.basename(script)) + wx.MessageBox(s, 'Invalid roslaunch file', wx.OK|wx.ICON_ERROR, self) + self.cancel(s) + else: + pre_launcher.spin() + + def launch_post_subtest(self): + subtest = self._current_test.subtests[self._subtest_index] + + if (subtest._post_script is not None): + script = subtest._post_script + post_launcher = self.launch_script(script, None) + if (post_launcher == None): + s = 'Could not load post-subtest roslaunch script "%s"'%(os.path.basename(script)) + wx.MessageBox(s, 'Invalid roslaunch file', wx.OK|wx.ICON_ERROR, self) + self.cancel(s) + else: + post_launcher.spin() + + def retry_subtest(self, notes): + self.log('Retrying subtest "%s"'%(self._current_test.subtests[self._subtest_index].get_name())) + self._results.retry_subresult(self._subtest_index, notes) + self.start_subtest(self._subtest_index) + + + def subtest_result(self, pass_bool, operator_notes): + self.log('Subtest "%s" result: %s'%(self._current_test.subtests[self._subtest_index].get_name(), pass_bool)) + + sub_result = self._results.get_subresult(self._subtest_index) + sub_result.set_note(operator_notes) + sub_result.set_operator_result(pass_bool) + + self.launch_post_subtest() + + if pass_bool: + self.next_subtest() + else: + self.test_finished() # Terminate rest of test + + def subtest_callback(self, msg): + wx.CallAfter(self.subtest_finished, msg) + return TestResultResponse() + + def subtest_finished(self, msg): + # TODO: if subtest_launch is None, cancel + + self._subtest_launch.shutdown() + self._subtest_launch = None + + sub_result = self._results.add_sub_result(self._subtest_index, msg) + + if self._show_results_always: + self.show_plots(sub_result) + else: + if (msg.result == TestResultRequest.RESULT_PASS): + self.subtest_result(True, '') + elif (msg.result == TestResultRequest.RESULT_FAIL): + self.subtest_result(False, "Automated failure") + elif (msg.result == TestResultRequest.RESULT_HUMAN_REQUIRED): + self.log('Subtest "%s" needs human response.'%(self._current_test.subtests[self._subtest_index].get_name())) + self.show_plots(sub_result) + + def launch_script(self, script, process_listener_object = None): + self.log('Launching roslaunch file %s'%(script)) + + f = open(script, 'r') + launch_xml = f.read() + f.close() + + launch = roslaunch_caller.ScriptRoslaunch(launch_xml, process_listener_object) + try: + launch.start() + except: + traceback.print_exc() + self.log('Caught exception launching file:\n%s' % traceback.format_exc()) + return None + + return launch + + def on_spin(self, event): + if (self._subtest_launch != None): + self._subtest_launch.spin_once() + + if (self._startup_launch != None): + self._startup_launch.spin_once() + + if (self._shutdown_launch != None): + self._shutdown_launch.spin_once() + + if (self._prestartup_launch != None): + self._prestartup_launch.spin_once() + + def stop_launches(self): + self.log('Stopping launches') + if (self._subtest_launch != None): + self._subtest_launch.shutdown() + + if (self._startup_launch != None): + self._startup_launch.shutdown() + + if (self._shutdown_launch != None): + self._shutdown_launch.shutdown() + + if (self._prestartup_launch != None): + self._prestartup_launch.shutdown() + + + self._startup_launch = None + self._shutdown_launch = None + self._prestartup_launch = None + self._subtest_launch = None + run_id = rospy.get_param('/run_id') + roslaunch_params = rospy.get_param('/roslaunch', '') + power_board = rospy.get_param('/powerboard', '') + invent_params = rospy.get_param('/invent', '') + # Reset all parameters + rospy.set_param('/', {'run_id': run_id, + 'roslaunch' : roslaunch_params, + 'powerboard' : power_board, + 'invent' : invent_params}) + self.log('Launches stopped.') + + def test_finished(self): + if (self._current_test is not None and self._current_test.getShutdownScript() != None): + self.log('Running shutdown script...') + + if (self._shutdown_done_srv != None): + self._shutdown_done_srv.shutdown() + self._shutdown_done_srv = None + + self._shutdown_done_srv = rospy.Service('shutdown_done', ScriptDone, self.shutdown_callback) + + html = '<html><H2 align=center>Shutting down test and stopping launches</H2></html>' + + self._plots_panel.show_waiting(html, False) + self.set_top_panel(self._plots_panel) + + # Launch given shutdown script + script = self._current_test.getShutdownScript().launch_file + + self._shutdown_launch = self.launch_script(script) + # TODO: display exception to user? + + if self._shutdown_launch == None: + s = 'Could not load roslaunch shutdown script "%s". SHUTDOWN POWER BOARD MANUALLY!'%(os.path.basename(script)) + wx.MessageBox(s, 'Invalid shutdown script!', wx.OK|wx.ICON_ERROR, self) + self.log('No shutdown script: %s' % (s)) + self.log('SHUT DOWN POWER BOARD MANUALLY') + return + else: + self.log('No shutdown script') + self.test_cleanup() + + def shutdown_callback(self, srv): + wx.CallAfter(self.shutdown_finished, srv) + return ScriptDoneResponse() + + def shutdown_finished(self, srv): + self.log('Shutdown finished') + + if self._shutdown_launch: + self._shutdown_launch.shutdown() + self._shutdown_launch = None + + if self._shutdown_done_srv: + self._shutdown_done_srv.shutdown() + self._shutdown_done_srv = None + + shutdown_script = self._current_test.getShutdownScript() + + self._results.add_shutdown_result(srv) + + if srv.result != ScriptDoneRequest.RESULT_OK: + fail_msg = 'Shutdown script failed!' + wx.MessageBox(fail_msg + '\n' + srv.failure_msg, fail_msg, wx.OK|wx.ICON_ERROR, self) + self.log('Shutdown failed for: %s' % srv.failure_msg) + + self.test_cleanup() + + def test_cleanup(self): + self.stop_launches() + + self._current_test = None + self._subtest_index = 0 + + if self._results is not None: + self._results._test_log = self._test_log + + self.show_results() + + def cancel(self, error = False): + if self._results is not None: + if error: + self._results.error() + else: + self._results.cancel() + + self.test_finished() + + def on_close(self, event): + event.Skip() + + self.stop_launches() Modified: pkg/branches/qual_test_2009_07_22/src/qualification/result.py =================================================================== --- pkg/branches/qual_test_2009_07_22/src/qualification/result.py 2009-07-31 23:30:47 UTC (rev 20336) +++ pkg/branches/qual_test_2009_07_22/src/qualification/result.py 2009-07-31 23:43:02 UTC (rev 20337) @@ -40,17 +40,13 @@ import sys, os, time, string, subprocess from xml.dom import minidom - from qualification.msg import * from srv import * from test import * -from result import * -from datetime import datetime from time import strftime from PIL import Image from cStringIO import StringIO -import wx import tarfile import socket @@ -65,18 +61,113 @@ RESULTS_DIR = os.path.join(roslib.packages.get_pkg_dir('qualification'), 'results') TEMP_DIR = os.path.join(roslib.packages.get_pkg_dir('qualification'), 'results/temp/') +## Holds results from pre-startup and shutdown scripts +class TestScriptResult: + ##@param test_script is test/TestScript that we tested + def __init__(self, test_script, srv_result): + self.name = test_script.get_name() + self.launch = test_script.launch_file -ResultType = { 0: "Fail", 1: "Pass", 2: "Manual Failure", 3: "Manual Pass", 4: "Retry", 5: "Error" , 6: "Operator needed" } + self._result = srv_result.result + self.msg = srv_result.failure_msg + + def get_name(self): + return self.name + def get_launch(self): + return os.path.basename(self.launch) + def get_pass_bool(self): + return self._result == 0 + + def has_error(self): + return self._result == 2 + + def get_result_msg(self): + result_dict = { 0: "Pass", 1: "Fail", 2: "Error"} + return result_dict[self._result] + + def get_msg(self): + return self.msg + +## Stores results of subtests in any case. Completely encapsulates +## numeric values of result types from users. +class SubTestResultType: + __result_types = { + 0: "Pass", + 1: "Fail", + 2: "Human required", + 3: "Manual Failure", + 4: "Manual Pass", + 5: "Retry", + # Not currently used + 6: "Error" , + 7: "Canceled" } + + ##@param result TestResultRequest.result : 0 - Pass, 1 - Fail, 2 - Human req'd + def __init__(self, result): + self._result = result + + def cancel(self): + self._result = 7 + + def retry(self): + self._result = 5 + + def manual_pass(self): + # Record as pass if auto-pass + if self._result == 0: + return + self._result = 4 + + def manual_fail(self): + # Record as failure if auto-fail + if self._result == 1: + return + self._result = 3 + + def error(self): + self._result = 6 + + def get_msg(self): + return self.__result_types[self._result] + + def get_html_msg(self): + if self._result == 0: + status_html ='<div class="pass">%s</div>' % self.get_msg() + elif self._result == 3 or self._result == 2 or self._result == 5: + status_html ='<div class="warn">%s</div>' % self.get_msg() + else: + status_html ='<div class="error">%s</div>' % self.get_msg() + + return status_html + + def get_pass_bool(self, manual_ok = True): + if manual_ok: + return self._result == 0 or self._result == 4 + return self._result == 0 + + def is_human_required(self): + return self._result == 2 + + def is_manual(self): + return self._result == 3 or self._result == 4 + + def is_retry(self): + return self._result == 5 + + def is_error(self): + return self._result == 6 + + def is_cancel(self): + return self._result == 7 + class SubTestResult: - def __init__(self, test_name, msg): - self._name = test_name - self._result = 0 - if msg.result == TestResultRequest.RESULT_PASS: - self._result = 1 - elif msg.result == TestResultRequest.RESULT_HUMAN_REQUIRED: - self._result = 6 + ##@param subtest is test/SubTest that we ran + def __init__(self, subtest, msg): + self._subtest = subtest + + self._result = SubTestResultType(msg.result) self._text_result = msg.html_result if msg.text_summary is not None: @@ -84,7 +175,6 @@ else: self._summary = '' - self._msg = msg self._subresult_note = '' self._plots = [] @@ -92,22 +182,38 @@ for plt in msg.plots: self._plots.append(plt) + self._retry_suffix = '' + self._retry_name = '' + self.write_images(TEMP_DIR) - def set_passfail(self, result): - self._result = result - + + + def retry_test(self, count): + self._result.retry() + self._retry_suffix = "_retry%d" % count + self._retry_name = " Retry %d" % count + + def set_operator_result(self, pass_bool): + if pass_bool: + self._result.manual_pass() + else: + self._result.manual_fail() + def get_name(self): - return self._name + return self._subtest.get_name() - def get_passfail(self): - return self._result + def set_name(self, name): + self._subtest._name = name + def get_pass_bool(self): + return self._result.get_pass_bool() + def set_note(self, txt): self._subresult_note = txt def filename_base(self): - return self._name.replace(' ', '_').replace('/', '__') + return self._subtest.get_name().replace(' ', '_').replace('/', '__') + self._retry_suffix def filename(self): return self.filename_base() + '.html' @@ -128,12 +234,8 @@ return html - # Takes test title, status, summary, details and images and makes a - # readable and complete results page. - # Can add a link back to the test index, or next subtest result - # - # TODO: Make failure appear in red text - # + ## Takes test title, status, summary, details and images and makes a + ## readable and complete results page. def make_result_page(self, back_link = False, link_dir = TEMP_DIR, prev = None, next = None): html = "<html><head><title>Qualification Test Results: %s</title>\ <style type=\"text/css\">\ @@ -144,7 +246,7 @@ strong { font-weight: bold; color: red; }\ em { font-style:normal; font-weight: bold; }\ </style>\ -</head><body>\n" % self._name +</head><body>\n" % self._subtest.get_name() html += self.html_header() @@ -152,7 +254,11 @@ # Parses through text and adds image source to file html += self.html_image_result(link_dir) - + + html += '<hr size="3">\n' + html += self.html_test_params() + html += '<hr size="3">\n' + # Add link back to index if applicable # May want to make page "portable" so whole folder can move if back_link: @@ -170,24 +276,41 @@ return html + def html_test_params(self): + html = '<H4 align=center>Subtest Parameters</H4>\n' + + html += '<table border="1" cellpadding="2" cellspacing="0">\n' + html += '<tr><td><b>Parameter</b></td><td><b>Value</b></td></tr>\n' + + if self._subtest._pre_script: + html += '<tr><td>Pre-test</td><td>%s</td></tr>\n' % os.path.basename(self._subtest._pre_script) + else: + html += '<tr><td>Pre-test</td><td>None</td></tr>\n' + + if self._subtest._post_script: + html += '<tr><td>Post-test</td><td>%s</td></tr>\n' % os.path.basename(self._subtest._post_script) + else: + html += '<tr><td>Post-test</td><td>None</td></tr>\n' + + launch_file = self._subtest._test_script + (path, launch_pkg) = roslib.packages.get_dir_pkg(launch_file) + path_idx = launch_file.find(launch_pkg) + len(launch_pkg) + 1 + + + html += '<tr><td>Launch package</td><td>%s</td></tr>\n' % launch_pkg + html += '<tr><td>Launch file... [truncated message content] |