def test_wheels_enslavement(self, dcm, mem, zero_pos, test_wheels_dico,
                                stiff_robot_wheels, test_time,
                                test_wheels_limit):
        """
        Test wheels enslavement.
        Error must be lower than a fixed limit (here test_wheels_limit).
        """
        # Objects creation
        wheel_speed_actuator = test_wheels_dico["wheelActuator"]
        wheel_speed_sensor = test_wheels_dico["wheelSensor"]
        logger = test_wheels_dico["logger"]
        sliding_avg = qha_tools.SlidingAverage(3)

        # Flag initialization
        logger.flag = True

        # Going to initial position
        #subdevice.multiple_set(dcm, mem, zero_pos, wait=True)

        # Behavior of the tested part
        wheel_speed_actuator.trapeze(0.1,
                                     1000.,
                                     2000.,
                                     sens="positive",
                                     second_invert_trapeze=True)

        # Timer creation just before test loop
        timer = qha_tools.Timer(dcm, 4 * test_time)

        # Test loop
        while timer.is_time_not_out():
            speed_actuator = wheel_speed_actuator.value
            speed_sensor = wheel_speed_sensor.value

            # Calculating an averaged sensor value on 3 points. The error can
            # dynamically be high because of the wheel mechanic.
            sliding_avg.point_add(speed_sensor)
            speed_sensor_sa = sliding_avg.calc()

            error = speed_actuator - speed_sensor
            error_sa = speed_actuator - speed_sensor_sa
            actuator = wheel_speed_actuator.value

            # Logging usefull information
            logger.log(("Time", timer.dcm_time() / 1000.),
                       ("Actuator", actuator), ("Sensor", speed_sensor),
                       ("SpeedSA", speed_sensor_sa), ("Error", error),
                       ("ErrorSA", error_sa), ("Eps", test_wheels_limit),
                       ("-Eps", test_wheels_limit * -1.),
                       ("Actuator+Eps", actuator + test_wheels_limit),
                       ("Actuator-Eps", actuator - test_wheels_limit))

            # Checking that enslavement is good
            if abs(error_sa) > test_wheels_limit:
                logger.flag = False

        assert logger.flag
Exemplo n.º 2
0
def sa_objects():
    """
    Returns a dictionnary of sliding average objects with the correct number
    of points for each joint.
    It reads the test configuration file.
    """
    sa_nb_points = qha_tools.read_section(CONFIG_FILE,
                                          "SlidingAverageNbPoints")
    dico_object = dict()
    for joint, nb_points in sa_nb_points.items():
        dico_object[joint] = qha_tools.SlidingAverage(int(nb_points[0]))
    return dico_object
    def test_joint_current_limitation(self, dcm, mem, parameters, joint,
                                      result_base_folder, rest_pos,
                                      stiffness_off, plot, plot_server):
        # logger initialization
        log = logging.getLogger('test_joint_current_limitation')

        # erasing real time plot
        plot_server.curves_erase()

        # flags initialization
        flag_loop = True  # test loop stops when this flag is False
        flag_joint = True  # giving test result
        flag_current_limit_low_exceeded = False

        # checking that ALMemory key MinMaxChange Allowed = 1
        if int(mem.getData("RobotConfig/Head/MinMaxChangeAllowed")) != 1:
            flag_loop = False
            log.error("MinMaxChangeAllowed ALMemory key missing")

        # test parameters
        test_params = parameters
        joint_position_actuator = joint.position.actuator
        joint_position_sensor = joint.position.sensor
        joint_temperature_sensor = joint.temperature
        joint_current_sensor = joint.current
        slav = qha_tools.SlidingAverage(test_params["sa_nb_points"])
        logger = qha_tools.Logger()

        # Going to initial position
        subdevice.multiple_set(dcm, mem, rest_pos, wait=True)
        # unstiffing all the other joints to avoid leg motors overheat
        subdevice.multiple_set(dcm, mem, stiffness_off, wait=False)
        time.sleep(0.1)

        # stiffing the joint we want to test
        joint.hardness.qqvalue = 1.0

        # keeping initial joint min and max
        joint_initial_maximum = joint_position_actuator.maximum
        joint_initial_minimum = joint_position_actuator.minimum

        # put joint to its initial maximum in 3 seconds
        if joint_position_actuator.short_name in\
         ("HipPitch", "RShoulderRoll", "RElbowRoll"):
            joint_position_actuator.qvalue = (joint_initial_minimum, 3000)
        else:
            joint_position_actuator.qvalue = (joint_initial_maximum, 3000)
        qha_tools.wait(dcm, 3000)

        # setting current limitations
        joint_max_current = joint_current_sensor.maximum
        joint_min_current = joint_current_sensor.minimum
        delta_current = joint_max_current - joint_min_current
        k_sup = test_params["limit_factor_sup"]
        k_inf = test_params["limit_factor_inf"]
        current_limit_high = joint_max_current + k_sup * delta_current
        current_limit_low = joint_max_current - k_inf * delta_current

        # setting temperature limitatons
        joint_temperature_min = joint_temperature_sensor.minimum

        # setting new min and max out of the mechanical stop
        joint_new_maximum = \
            joint_initial_maximum + \
            math.radians(test_params["limit_extension"])

        joint_new_minimum = \
            joint_initial_minimum - \
            math.radians(test_params["limit_extension"])

        joint_position_actuator.maximum = [[[
            joint_new_maximum, dcm.getTime(0)
        ]], "Merge"]
        joint_position_actuator.minimum = [[[
            joint_new_minimum, dcm.getTime(0)
        ]], "Merge"]

        if joint_position_actuator.short_name in\
         ("HipPitch", "RShoulderRoll", "RElbowRoll"):
            joint_position_actuator.qvalue = (joint_new_minimum, 1000)
        else:
            joint_position_actuator.qvalue = (joint_new_maximum, 1000)

        timer = qha_tools.Timer(dcm, test_params["test_time"])
        timer_limit = qha_tools.Timer(dcm, test_params["test_time_limit"])

        # test loop
        while flag_loop and timer.is_time_not_out():
            try:
                loop_time = timer.dcm_time() / 1000.
                joint_temperature = joint_temperature_sensor.value
                joint_current = joint_current_sensor.value
                slav.point_add(joint_current)
                joint_current_sa = slav.calc()

                if not flag_current_limit_low_exceeded and\
                    joint_current_sa > current_limit_low:
                    flag_current_limit_low_exceeded = True
                    log.info("Current limit low exceeded")

                if joint_current_sa > current_limit_high:
                    flag_joint = False
                    log.warning("Current limit high overshoot")

                if flag_current_limit_low_exceeded and\
                    joint_current_sa < current_limit_low:
                    flag_joint = False
                    log.warning("Current lower than current limit low")

                if timer_limit.is_time_out() and not \
                    flag_current_limit_low_exceeded:
                    flag_joint = False
                    log.info("Timer limit finished and "+\
                        "current limit low not exceeded")

                # out of test loop if temperature is higher than min temperature
                if joint_temperature >= joint_temperature_min:
                    flag_loop = False
                    log.info("Temperature higher than Min temperature")
                    log.info("Test finished")

                logger.log(("Time", timer.dcm_time() / 1000.),
                           ("Current", joint_current),
                           ("CurrentSA", joint_current_sa),
                           ("CurrentLimitHigh", current_limit_high),
                           ("CurrentLimitLow", current_limit_low),
                           ("MaxAllowedCurrent", joint_max_current),
                           ("Temperature", joint_temperature),
                           ("TemperatureMin", joint_temperature_min),
                           ("Command", joint_position_actuator.value),
                           ("Position", joint_position_sensor.value))

                if plot:
                    plot_server.add_point("Current", loop_time, joint_current)
                    plot_server.add_point("CurrentSA", loop_time,
                                          joint_current_sa)
                    plot_server.add_point("CurrentLimitHigh", loop_time,
                                          current_limit_high)
                    plot_server.add_point("CurrentLimitLow", loop_time,
                                          current_limit_low)
                    plot_server.add_point("MaxAllowedCurrent", loop_time,
                                          joint_max_current)
                    plot_server.add_point("Temperature", loop_time,
                                          joint_temperature)
                    plot_server.add_point("TemperatureMin", loop_time,
                                          joint_temperature_min)

            except KeyboardInterrupt:
                flag_loop = False  # out of test loop
                log.info("KeyboardInterrupt from user")

        log.info("OUT OF TEST LOOP")

        result_file_path = "/".join([
            result_base_folder, joint_position_actuator.subdevice_type,
            joint_position_actuator.short_name + "_" + str(flag_joint)
        ]) + ".csv"
        logger.log_file_write(result_file_path)

        joint_position_actuator.maximum = [[[
            joint_initial_maximum, dcm.getTime(0)
        ]], "Merge"]
        joint_position_actuator.minimum = [[[
            joint_initial_minimum, dcm.getTime(0)
        ]], "Merge"]

        plot_server.curves_erase()

        assert flag_joint
        assert flag_current_limit_low_exceeded
    def test_wheel_temperature_protection(self, dcm, parameters, wheel,
                                          result_base_folder):
        # logger initialization
        log = logging.getLogger('MOTOR_LIMITATION_PERF_HW_002_Wheels')

        # flags initialization
        flag_wheel = True
        flag_loop = True
        flag_max_current_exceeded = False
        flag_max_temperature_exceeded = False
        flag_info = False
        flag_info2 = False
        flag_info3 = False
        flag_info4 = False

        wheel.stiffness.qvalue = (1.0, 5000)
        wheel.speed.actuator.qvalue = (wheel.speed.actuator.maximum, 10000)

        test_params = parameters
        timer = qha_tools.Timer(dcm, test_params["test_time"])
        slav = qha_tools.SlidingAverage(test_params["sa_nb_points"])
        logger = qha_tools.Logger()

        log.info("")
        log.info("*************************************")
        log.info("Testing : " + str(wheel.short_name))
        log.info("*************************************")
        log.info("")

        wheel_temperature_max = wheel.temperature.maximum
        wheel_temperature_min = wheel.temperature.minimum
        wheel_temperature_mid = \
        (wheel_temperature_max + wheel_temperature_min) * 0.5
        wheel_current_max = wheel.current.maximum
        current_limit_high = wheel_current_max * \
        (1.0 + test_params["limit_factor_sup"])
        current_limit_low = wheel_current_max * \
        (1.0 - test_params["limit_factor_inf"])

        while timer.is_time_not_out and flag_loop is True:
            try:
                wheel_temperature = wheel.temperature.value
                wheel_current = wheel.current.value
                slav.point_add(wheel_current)
                wheel_current_sa = slav.calc()
                wheel_speed_command = wheel.speed.actuator.value
                wheel_speed_sensor = wheel.speed.sensor.value
                wheel_stiffness = wheel.stiffness.value
                dcm_time = timer.dcm_time() / 1000.

                logger.log(
                    ("Time", dcm_time),
                    ("Stiffness", wheel_stiffness),
                    ("Current", wheel_current),
                    ("CurrentSA", wheel_current_sa),
                    ("MaxAllowedCurrent", wheel_current_max),
                    ("CurrentLimitHigh", current_limit_high),
                    ("CurrentLimitLow", current_limit_low),
                    ("Temperature", wheel_temperature),
                    ("TemperatureMin", wheel_temperature_min),
                    ("TemperatureMax", wheel_temperature_max),
                    ("SpeedActuator", wheel_speed_command),
                    ("SpeedSensor", wheel_speed_sensor),
                )

                # out of test loop if temperature is higher than MAX + 1 degree
                if wheel_temperature >= wheel_temperature_max + 5:
                    flag_loop = False

                # if joint temperature higher than a limit value,
                # joint current must be null after 100ms.
                if flag_max_temperature_exceeded is False and \
                wheel_temperature >= wheel_temperature_max:
                    flag_max_temperature_exceeded = True
                    timer_max = qha_tools.Timer(dcm, 1000)
                    log.info("max temperature exceeded a first time")

                if flag_max_temperature_exceeded and \
                wheel_temperature <= wheel_temperature_mid:
                    flag_loop = False
                    log.info("Motor windings are cold enough")

                # setting flag to True if 90 percent of max current is exceeded
                if wheel_current_sa > 0.9 * wheel_current_max and not \
                flag_max_current_exceeded and dcm_time > 0.4:
                    flag_max_current_exceeded = True
                    log.info("90 percent of max allowed currend reached")

                # averaged current has not to exceed limit high
                if wheel_current_sa > current_limit_high and not flag_info:
                    flag_wheel = False
                    flag_info = True
                    log.warning("current high limit exceeded")

                # once max current is exceeded, current hasn't to be lower than
                # limit low
                if flag_max_current_exceeded and \
                wheel_current_sa < current_limit_low and not \
                flag_max_temperature_exceeded and not flag_info2:
                    flag_wheel = False
                    flag_info2 = True
                    log.info("current has been lower than low limit")

                if flag_max_temperature_exceeded and\
                timer_max.is_time_out() and wheel_current != 0 and not\
                flag_info3:
                    flag_wheel = False
                    flag_info3 = True
                    log.critical("max temperature exceeded and current "+\
                            "is not null")

                if flag_max_temperature_exceeded and wheel_current == 0.0 and\
                not flag_info4:
                    flag_info4 = True
                    log.info("current null reached")

            except KeyboardInterrupt:
                flag_loop = False
                log.info("KeyboardInterrupt from user")
                wheel.speed.actuator.qvalue = (0.0, 1000)
                wheel.stiffness.qqvalue = 0.0

        # stop and unstiff wheel
        wheel.speed.actuator.qvalue = (0.0, 1000)
        wheel.stiffness.qqvalue = 0.0

        # writing logger results into a csv file
        result_file_path = "/".join([
            result_base_folder, wheel.temperature.subdevice_type,
            wheel.short_name + "_" + str(flag_wheel)
        ]) + ".csv"
        logger.log_file_write(result_file_path)

        assert flag_wheel
    def test_joint_temperature_protection(self, dcm, mem, parameters, joint,
                                          result_base_folder, rest_pos,
                                          stiffness_off, plot_server, plot):
        # logger initialization
        log = logging.getLogger('MOTOR_LIMITATION_PERF_HW_002')

        # flags initialization
        flag_joint = True
        flag_loop = True
        flag_max_current_exceeded = False
        flag_max_temperature_exceeded = False
        flag_low_limit = False
        flag_info = False
        flag_info2 = False
        flag_info3 = False
        flag_info4 = False

        # erasing real time curves
        if plot:
            plot_server.curves_erase()

        # Objects creation
        test_params = parameters
        joint_position_actuator = joint.position.actuator
        joint_position_sensor = joint.position.sensor
        joint_temperature_sensor = joint.temperature
        joint_hardness_actuator = joint.hardness
        joint_current_sensor = joint.current
        slav = qha_tools.SlidingAverage(test_params["sa_nb_points"])
        logger = qha_tools.Logger()

        log.info("")
        log.info("*************************************")
        log.info("Testing : " + str(joint.short_name))
        log.info("*************************************")
        log.info("")

        # Knowing the board, we can know if the motor is a MCC or DC Brushless
        joint_board = joint_position_actuator.device

        # Creating device object to acceed to its error
        joint_board_object = device.Device(dcm, mem, joint_board)

        # Going to initial position
        subdevice.multiple_set(dcm, mem, rest_pos, wait=True)
        # unstiffing all the other joints to avoid leg motors overheat
        subdevice.multiple_set(dcm, mem, stiffness_off, wait=False)
        time.sleep(0.1)

        # stiffing the joint we want to test
        joint.hardness.qqvalue = 1.0

        # keeping initial joint min and max
        joint_initial_maximum = joint_position_actuator.maximum
        joint_initial_minimum = joint_position_actuator.minimum

        # setting current limitations
        joint_current_max = joint_current_sensor.maximum

        # setting temperature limitatons
        joint_temperature_min = joint_temperature_sensor.minimum
        joint_temperature_max = joint_temperature_sensor.maximum
        delta_temperature = joint_temperature_max - joint_temperature_min

        # setting new min and max out of the mechanical stop
        if joint_initial_maximum >= 0.0:
            joint_new_maximum = \
                joint_initial_maximum + \
                math.radians(test_params["limit_extension"])
        else:
            joint_new_maximum = \
                joint_initial_maximum - \
                math.radians(test_params["limit_extension"])

        if joint_initial_minimum <= 0.0:
            joint_new_minimum = \
                joint_initial_minimum - \
                math.radians(test_params["limit_extension"])
        else:
            joint_new_minimum = \
                joint_initial_minimum + \
                math.radians(test_params["limit_extension"])

        joint_position_actuator.maximum = [[[
            joint_new_maximum, dcm.getTime(0)
        ]], "Merge"]
        joint_position_actuator.minimum = [[[
            joint_new_minimum, dcm.getTime(0)
        ]], "Merge"]

        # set timer limit
        timer_limit = qha_tools.Timer(dcm, test_params["test_time_limit"])

        # for Brushless motors, max test time is 60 seconds
        brushless_motors = ("KneePitch", "HipPitch", "HipRoll")
        if joint_position_actuator.short_name in brushless_motors:
            timer = qha_tools.Timer(dcm, 60000)
        else:
            timer = qha_tools.Timer(dcm, test_params["test_time"])

        # set position actuator out of the joint mechanical stop
        # going out of physical mechanical stop in 5 seconds
        if joint_position_actuator.short_name in \
            ("HipPitch", "RShoulderRoll", "HipRoll"):
            joint_position_actuator.qvalue = (joint_new_minimum, 5000)
        else:
            joint_position_actuator.qvalue = (joint_new_maximum, 5000)

        flag_first_iteration = True
        timer_current_decrease = qha_tools.Timer(dcm, 100)
        while flag_loop is True and timer.is_time_not_out():
            try:
                joint_temperature = joint_temperature_sensor.value
                joint_current = joint_current_sensor.value
                slav.point_add(joint_current)
                joint_position_command = joint_position_actuator.value
                joint_position = joint_position_sensor.value
                joint_hardness_value = joint_hardness_actuator.value
                joint_current_sa = slav.calc()
                firmware_error = joint_board_object.error
                dcm_time = timer.dcm_time() / 1000.

                # Max current adaptation if joint temperature higher than Min
                # No lower current for DC Brushless motors
                if joint_board not in \
                    ("HipBoard", "ThighBoard", "BackPlatformBoard"):
                    if joint_temperature > joint_temperature_min:
                        delta_max = joint_temperature_max - joint_temperature
                        max_allowed_current = (
                            (delta_max) / (delta_temperature)) *\
                        joint_current_max
                    else:
                        max_allowed_current = joint_current_max
                else:
                    max_allowed_current = joint_current_max

                # max allowed current can not be lower than 0.
                if max_allowed_current < 0.0:
                    max_allowed_current = 0.0

                # defining old max current as first calculated max current if
                # it is the first loop iteration
                if flag_first_iteration is True:
                    old_mac = max_allowed_current
                    flag_first_iteration = False

                # defining current regulation limits
                current_limit_high = max_allowed_current * \
                (1.0 + test_params["limit_factor_sup"])
                current_limit_low = max_allowed_current *\
                (1.0 - test_params["limit_factor_inf"])

                # setting flag to True if 90 percent of max current is exceeded
                if joint_current_sa > 0.9 * max_allowed_current and not\
                 flag_max_current_exceeded:
                    flag_max_current_exceeded = True
                    log.info("90 percent of max allowed currend reached")

                if max_allowed_current != old_mac:
                    timer_current_decrease = qha_tools.Timer(dcm, 100)

                # averaged current has not to exceed limit high
                if joint_current_sa > current_limit_high and \
                    timer_current_decrease.is_time_out() and not flag_info4:
                    flag_joint = False
                    flag_info4 = True
                    log.warning("current high limit exceeded")

                # once max current is exceeded, current hasn't to be lower than
                # limit low
                if flag_max_current_exceeded and \
                    joint_current_sa < current_limit_low and not \
                    flag_max_temperature_exceeded and not flag_low_limit:
                    flag_joint = False
                    flag_low_limit = True
                    log.info("current has been lower than low limit")

                # after time limit, current has to have exceeded max current
                # if it has not, it is written on time in log file
                if timer_limit.is_time_out() and not\
                 flag_max_current_exceeded and flag_info is False:
                    flag_joint = False
                    flag_info = True
                    log.info("current has not exceeded 90 percent of max "+\
                        "allowed current")

                # hardware protection
                if joint_temperature >= joint_temperature_max + 1:
                    flag_loop = False
                    log.warning("temperature too high (max+1 degree)")

                # if joint temperature higher than a limit value,
                # joint current must be null after 100ms.
                if flag_max_temperature_exceeded is False and \
                    joint_temperature >= joint_temperature_max:
                    flag_max_temperature_exceeded = True
                    timer_max = qha_tools.Timer(dcm, 100)
                    log.info("max temperature exceeded a first time")

                if flag_max_temperature_exceeded and\
                timer_max.is_time_out() and joint_current != 0 and not\
                flag_info2:
                    flag_joint = False
                    flag_info2 = True
                    log.critical("max temperature exceeded and current "+\
                        "is not null")

                if flag_max_temperature_exceeded and joint_current == 0.0 and\
                not flag_info3:
                    flag_info3 = True
                    log.info("current null reached")

                old_mac = max_allowed_current

                logger.log(
                    ("Time", dcm_time), ("Hardness", joint_hardness_value),
                    ("Current", joint_current),
                    ("CurrentSA", joint_current_sa),
                    ("MaxAllowedCurrent", max_allowed_current),
                    ("CurrentLimitHigh", current_limit_high),
                    ("CurrentLimitLow", current_limit_low),
                    ("Temperature", joint_temperature),
                    ("TemperatureMin", joint_temperature_min),
                    ("TemperatureMax", joint_temperature_max),
                    ("Command", joint_position_command),
                    ("Position", joint_position), ("FWError", firmware_error))

                # for real time plot
                if plot:
                    plot_server.add_point("Hardness", dcm_time,
                                          joint_hardness_value)
                    plot_server.add_point("CurrentSA", dcm_time,
                                          joint_current_sa)
                    plot_server.add_point("MaxAllowedCurrent", dcm_time,
                                          max_allowed_current)
                    plot_server.add_point("CurrentLimitHigh", dcm_time,
                                          current_limit_high)
                    plot_server.add_point("CurrentLimitLow", dcm_time,
                                          current_limit_low)
                    plot_server.add_point("Temperature", dcm_time,
                                          joint_temperature)
                    plot_server.add_point("TemperatureMin", dcm_time,
                                          joint_temperature_min)
                    plot_server.add_point("TemperatureMax", dcm_time,
                                          joint_temperature_max)
                    plot_server.add_point("Command", dcm_time,
                                          joint_position_command)
                    plot_server.add_point("Position", dcm_time, joint_position)

            except KeyboardInterrupt:
                flag_loop = False
                log.info("KeyboardInterrupt from user")

        # writing logger results into a csv file
        result_file_path = "/".join([
            result_base_folder, joint_position_actuator.subdevice_type,
            joint_position_actuator.short_name + "_" + str(flag_joint)
        ]) + ".csv"
        logger.log_file_write(result_file_path)

        # seting min and max joint software limits to their original values
        joint_position_actuator.maximum = [[[
            joint_initial_maximum, dcm.getTime(0)
        ]], "Merge"]
        joint_position_actuator.minimum = [[[
            joint_initial_minimum, dcm.getTime(0)
        ]], "Merge"]

        assert flag_joint