コード例 #1
0
def test_dc_permex_motor():
    motor_state = ['i']  # list of state names
    motor_parameter = test_motor_parameter['DcPermEx']['motor_parameter']
    nominal_values = test_motor_parameter['DcPermEx']['nominal_values']  # dict
    limit_values = test_motor_parameter['DcPermEx']['limit_values']  # dict
    # default initialization without parameters
    motor_1_default = make_module(ElectricMotor, 'DcPermEx')
    motor_2_default = DcPermanentlyExcitedMotor()
    # initialization parameters as dicts
    motor_1 = make_module(ElectricMotor,
                          'DcPermEx',
                          motor_parameter=motor_parameter,
                          nominal_values=nominal_values,
                          limit_values=limit_values)
    motor_2 = DcPermanentlyExcitedMotor(motor_parameter, nominal_values,
                                        limit_values)

    motor_testing(motor_1_default, motor_2_default, motor_1, motor_2,
                  motor_state, limit_values, nominal_values, motor_parameter)

    permex_motor_state_space_testing(motor_1_default, motor_2_default)
    permex_motor_state_space_testing(motor_1, motor_2)

    permex_motor_electrical_ode_testing(motor_1_default)
    permex_motor_electrical_ode_testing(motor_1)
コード例 #2
0
def test_dc_shunt_motor():
    """
    tests the dc shunt motor class
    :return:
    """
    # set up test parameter
    motor_state = ['i_a', 'i_e']  # list of state names
    motor_parameter = test_motor_parameter['DcShunt']['motor_parameter']
    nominal_values = test_motor_parameter['DcShunt']['nominal_values']  # dict
    limit_values = test_motor_parameter['DcShunt']['limit_values']  # dict
    # default initialization of electric motor
    motor_1_default = make_module(ElectricMotor, 'DcShunt')
    motor_2_default = DcShuntMotor()

    motor_1 = make_module(ElectricMotor,
                          'DcShunt',
                          motor_parameter=motor_parameter,
                          nominal_values=nominal_values,
                          limit_values=limit_values)
    motor_2 = DcShuntMotor(motor_parameter, nominal_values, limit_values)
    # test if both initializations work correctly for limits and nominal values
    motor_testing(motor_1_default, motor_2_default, motor_1, motor_2,
                  motor_state, limit_values, nominal_values, motor_parameter)
    shunt_motor_state_space_testing(motor_1_default, motor_2_default)
    shunt_motor_state_space_testing(motor_1, motor_2)
    # test electrical_ode function
    shunt_motor_electrical_ode_testing(motor_1_default)
    shunt_motor_electrical_ode_testing(motor_1)
コード例 #3
0
def test_discrete_single_initializations(convert, convert_class, tau, interlocking_time, dead_time):
    """
    test of both ways of initialization lead to the same result
    :param convert: string name of the converter
    :param convert_class: class name of the converter
    :return:
    """
    # test default initialization
    converter_1 = make_module(PowerElectronicConverter, convert)
    converter_2 = convert_class()
    assert converter_1._tau == converter_2._tau
    # test with different parameters
    interlocking_time *= tau
    # initialize converters
    converter_1 = make_module(PowerElectronicConverter, convert, tau=tau,
                              interlocking_time=interlocking_time, dead_time=dead_time)
    converter_2 = convert_class(
        tau=tau, interlocking_time=interlocking_time, dead_time=dead_time)
    parameter = str(tau) + " " + str(dead_time) + " " + str(interlocking_time)
    # test if they are equal
    assert converter_1.reset() == converter_2.reset()
    assert converter_1.action_space == converter_2.action_space
    assert converter_1._tau == converter_2._tau == tau, "Error (tau): " + parameter
    assert converter_1._dead_time == converter_2._dead_time == dead_time, "Dead time Error"
    assert converter_1._interlocking_time == converter_2._interlocking_time == interlocking_time, \
        "Error (interlocking): " + parameter
コード例 #4
0
def setup_dc_converter(conv, motor_type):
    """
    This function initializes the converter.
    It differentiates between single and double converter and can be used for discrete and continuous converters.
    :param conv: converter name (string)
    :param motor_type: motor name (string)
    :return: initialized converter
    """
    if motor_type == 'DcExtEx':
        # setup double converter
        if 'Disc' in conv:
            double_converter = 'Disc-Double'
        else:
            double_converter = 'Cont-Double'
        converter = make_module(PowerElectronicConverter, double_converter,
                                interlocking_time=converter_parameter['interlocking_time'],
                                dead_time=converter_parameter['dead_time'],
                                subconverters=[make_module(PowerElectronicConverter, conv,
                                                           tau=converter_parameter['tau'],
                                                           dead_time=converter_parameter['dead_time'],
                                                           interlocking_time=converter_parameter['interlocking_time']),
                                               make_module(PowerElectronicConverter, conv,
                                                           tau=converter_parameter['tau'],
                                                           dead_time=converter_parameter['dead_time'],
                                                           interlocking_time=converter_parameter['interlocking_time'])])
    else:
        # setup single converter
        converter = make_module(PowerElectronicConverter, conv,
                                tau=converter_parameter['tau'],
                                dead_time=converter_parameter['dead_time'],
                                interlocking_time=converter_parameter['interlocking_time'])
    return converter
コード例 #5
0
def test_visualization(motor_type, converter_type, plotted_variables,
                       turn_off_windows):
    """
    test initialization and basic functions for all motor and converters
    :param motor_type: motor name (string)
    :param converter_type: converter name (string)
    :param plotted_variables: shown variables (list/True/False)
    :return:
    """
    # set parameters
    update_period = 1E-2
    visu_period = 0.1
    # setup physical system
    physical_system = setup_physical_system(motor_type, converter_type)
    # setup reference generator
    reference_generator = setup_reference_generator('SinusReference',
                                                    physical_system)
    # setup reward function
    reward_function = make_module(RewardFunction, 'WSE')
    reward_function.set_modules(physical_system, reference_generator)
    # initializations of dashboards in different ways
    dashboard_default = MotorDashboard()
    dashboard_make = make_module(ElectricMotorVisualization,
                                 'MotorDashboard',
                                 visu_period=visu_period,
                                 update_period=update_period,
                                 plotted_variables=plotted_variables)
    dashboard_1 = MotorDashboard(visu_period=visu_period,
                                 update_period=update_period,
                                 plotted_variables=plotted_variables)

    # setup state, reference, reward for testing
    len_state = len(physical_system.state_names)
    reference = physical_system.state_space.low
    reward = -0.5
    dashboards = [dashboard_default, dashboard_make, dashboard_1]

    # test references given in each step
    for dashboard in dashboards:
        if plotted_variables == ['none'
                                 ] and dashboard is not dashboard_default:
            with pytest.warns(Warning):
                dashboard.set_modules(physical_system, reference_generator,
                                      reward_function)
                dashboard.reset()
                dashboard.step(physical_system.state_space.sample(),
                               physical_system.state_space.sample(), 0)
        else:
            dashboard.set_modules(physical_system, reference_generator,
                                  reward_function)
            dashboard.reset()
            dashboard.step(physical_system.state_space.sample(),
                           physical_system.state_space.sample(), 0)

        for k in range(2):
            state = np.ones(len_state) * np.sin(k / 1000) / 2 + 0.5
            dashboard.step(state, reference, reward)
        dashboard.close()
コード例 #6
0
def test_visualization_parameter(motor_type, converter_type, plotted_variables,
                                 update_period, visu_period, turn_off_windows):
    """
    test visu period and update period
    :param motor_type: motor name (string)
    :param converter_type: converter name (string)
    :param plotted_variables: shown variables (list/True/False)
    :param update_period: update period from dashboard
    :param visu_period: visu period from dashboard
    :return:
    """
    # setup physical system
    physical_system = setup_physical_system(motor_type, converter_type)
    # setup reference generator
    reference_generator = setup_reference_generator('StepReference',
                                                    physical_system)
    # setup reward function
    reward_function = make_module(RewardFunction, 'WSE')
    reward_function.set_modules(physical_system, reference_generator)
    # initializations of dashboards in different ways
    dashboard = MotorDashboard(plotted_variables=plotted_variables,
                               update_period=update_period,
                               visu_period=visu_period)
    # setup the modules
    dashboard.set_modules(physical_system, reference_generator,
                          reward_function)
    # test for given references in the reset
    dashboard.reset()
    reward = 0
    len_state = len(physical_system.state_names)
    for k in range(150):
        state = np.ones(len_state) * np.sin(k / 1000) / 2 + 0.5
        reference = np.ones(len_state) * np.cos(k / 2000) / 2 + 0.5
        dashboard.step(state, reference, reward)
    dashboard.close()
コード例 #7
0
def test_visualization_plotted_variables(motor_type, converter_type,
                                         plotted_variables, turn_off_windows):
    """
    test initialization and basic functions for all motor and converters
    :param motor_type: motor name (string)
    :param converter_type: converter name (string)
    :param plotted_variables: shown variables (list/True/False)
    :return:
    """
    # setup physical system
    physical_system = setup_physical_system(motor_type, converter_type)
    # setup reference generator
    reference_generator = setup_reference_generator('SinusReference',
                                                    physical_system)
    # setup reward function
    reward_function = make_module(RewardFunction, 'WSE')
    reward_function.set_modules(physical_system, reference_generator)
    # initializations of dashboards in different ways
    dashboard_default = MotorDashboard(plotted_variables=plotted_variables)
    # test for warning
    with pytest.warns(Warning):
        dashboard_default.set_modules(physical_system, reference_generator,
                                      reward_function)
        dashboard_default.reset()
        dashboard_default.step(physical_system.state_space.sample(),
                               physical_system.state_space.sample(), 0)
    dashboard_default.close()
コード例 #8
0
def test_discrete_single_power_electronic_converter(converter_type, action_space_n, actions, i_ins, test_voltages,
                                                    dead_time,
                                                    interlocking_time, tau):
    """
    test the initialization of all single converters for different tau, interlocking times, dead times
    furthermore, test the other functions: reset, convert with different parameters
    :param converter_type: converter name (string)
    :param action_space_n: number of elements in the action space
    :param actions: pre defined actions for testing
    :param i_ins: used input currents for testing
    :param test_voltages: expected voltages for ideal and non ideal behaviour
    :param dead_time: specifies if a dead time is considered or not
    :param interlocking_time: the used interlocking time
    :param tau: sampling time
    :return:
    """
    # test with default initialization
    converter = make_module(PowerElectronicConverter, converter_type)
    g_times = g_times_4qc
    times = g_times * converter._tau
    discrete_converter_functions_testing(converter,
                                         action_space_n,
                                         times,
                                         actions,
                                         i_ins,
                                         test_voltages[0],
                                         test_voltages[1],
                                         test_voltages[2],
                                         test_voltages[3])

    # define various constants for test
    times = g_times * tau
    interlocking_time *= tau
    # setup converter
    # initialize converter with given parameter
    converter = make_module(PowerElectronicConverter, converter_type, tau=tau,
                            interlocking_time=interlocking_time, dead_time=dead_time)
    assert converter.reset() == [0.0]  # test if reset returns 0.0
    # test the conversion function of the converter
    discrete_converter_functions_testing(converter, action_space_n, times,
                                         actions,
                                         i_ins,
                                         test_voltages[0],
                                         test_voltages[1],
                                         test_voltages[2],
                                         test_voltages[3],
                                         interlocking_time=interlocking_time, dead_time=dead_time)
コード例 #9
0
def setup_physical_system(motor_type, converter_type, three_phase=False):
    """
    Function to set up a physical system with test parameters
    :param motor_type: motor name (string)
    :param converter_type: converter name (string)
    :param three_phase: if True, than a synchronous motor system will be instantiated
    :return: instantiated physical system
    """
    # get test parameter
    tau = converter_parameter['tau']
    u_sup = test_motor_parameter[motor_type]['motor_parameter']['u_sup']
    motor_parameter = test_motor_parameter[motor_type]['motor_parameter']  # dict
    nominal_values = test_motor_parameter[motor_type]['nominal_values']  # dict
    limit_values = test_motor_parameter[motor_type]['limit_values']  # dict
    # setup load
    load = PolynomialStaticLoad(load_parameter=load_parameter['parameter'])
    # setup voltage supply
    voltage_supply = IdealVoltageSupply(u_sup)
    # setup converter
    if motor_type == 'DcExtEx':
        if 'Disc' in converter_type:
            double_converter = 'Disc-Double'
        else:
            double_converter = 'Cont-Double'
        converter = make_module(PowerElectronicConverter, double_converter,
                                subconverters=[converter_type, converter_type],
                                tau=converter_parameter['tau'],
                                dead_time=converter_parameter['dead_time'],
                                interlocking_time=converter_parameter['interlocking_time'])
    else:
        converter = make_module(PowerElectronicConverter, converter_type, tau=converter_parameter['tau'],
                                dead_time=converter_parameter['dead_time'],
                                interlocking_time=converter_parameter['interlocking_time'])
    # setup motor
    motor = make_module(ElectricMotor, motor_type, motor_parameter=motor_parameter, nominal_values=nominal_values,
                        limit_values=limit_values)
    # setup solver
    solver = ScipySolveIvpSolver(method='RK45')
    # combine all modules to a physical system
    if three_phase:
        physical_system = SynchronousMotorSystem(converter=converter, motor=motor, ode_solver=solver,
                                                 supply=voltage_supply, load=load, tau=tau)
    else:
        physical_system = DcMotorSystem(converter=converter, motor=motor, ode_solver=solver,
                                        supply=voltage_supply, load=load, tau=tau)
    return physical_system
コード例 #10
0
def setup_reward_function(reward_function_type, physical_system,
                          reference_generator, reward_weights,
                          observed_states):
    reward_function = make_module(RewardFunction,
                                  reward_function_type,
                                  observed_states=observed_states,
                                  reward_weights=reward_weights)
    reward_function.set_modules(physical_system, reference_generator)
    return reward_function
コード例 #11
0
def test_discrete_double_power_electronic_converter(tau, interlocking_time, dead_time):
    """
    setup all combinations of single converters and test the convert function if no error is raised
    :return:
    """
    # define all converter
    all_single_disc_converter = ['Disc-1QC', 'Disc-2QC', 'Disc-4QC']
    interlocking_time *= tau

    for conv_1 in all_single_disc_converter:
        for conv_2 in all_single_disc_converter:
            converter = make_module(
                PowerElectronicConverter, 'Disc-Double', tau=tau,
                interlocking_time=interlocking_time, dead_time=dead_time,
                subconverters=[conv_1, conv_2]
            )
            comparable_converter_1 = make_module(PowerElectronicConverter, conv_1, tau=tau,
                                                 interlocking_time=interlocking_time, dead_time=dead_time)
            comparable_converter_2 = make_module(PowerElectronicConverter, conv_2, tau=tau,
                                                 interlocking_time=interlocking_time, dead_time=dead_time)
            action_space_n = converter.action_space.n
            assert converter.reset() == [0.0, 0.0]  # test if reset returns 0.0
            actions = [randint(0, action_space_n) for _ in range(100)]
            times = np.arange(100) * tau
            action_space_1_n = comparable_converter_1.action_space.n
            action_space_2_n = comparable_converter_2.action_space.n
            for action, t in zip(actions, times):
                time_steps = converter.set_action(action, t)
                time_steps_1 = comparable_converter_1.set_action(action % action_space_1_n, t)
                time_steps_2 = comparable_converter_2.set_action((action // action_space_1_n) % action_space_2_n, t)
                for time_step in time_steps_1 + time_steps_2:
                    assert time_step in time_steps
                for time_step in time_steps:
                    i_in_1 = uniform(-1, 1)
                    i_in_2 = uniform(-1, 1)
                    i_in = [i_in_1, i_in_2]
                    voltage = converter.convert(i_in, time_step)
                    voltage_1 = comparable_converter_1.convert([i_in_1], time_step)
                    voltage_2 = comparable_converter_2.convert([i_in_2], time_step)
                    converter.i_sup(i_in)
                    assert voltage[0] == voltage_1[0], "First converter is wrong"
                    assert voltage[1] == voltage_2[0], "Second converter is wrong"
コード例 #12
0
def setup_reference_generator(reference_type, physical_system, reference_state='omega'):
    """
    Function to setup the reference generator
    :param reference_type: name of reference generator
    :param physical_system: instantiated physical system
    :param reference_state: referenced state name (string)
    :return: instantiated reference generator
    """
    reference_generator = make_module(ReferenceGenerator, reference_type, reference_state=reference_state)
    reference_generator.set_modules(physical_system)
    reference_generator.reset()
    return reference_generator
コード例 #13
0
def test_visualization_reset(motor_type, converter_type, plotted_variables,
                             update_period, visu_period, turn_off_windows):
    """
    test reset with given references
    :param motor_type: motor name (string)
    :param converter_type: converter name (string)
    :param plotted_variables: shown variables (list/True/False)
    :param update_period: update period from dashboard
    :param visu_period: visu period from dashboard
    :return:
    """
    # setup physical system
    physical_system = setup_physical_system(motor_type, converter_type)
    # setup reference generator
    reference_generator = setup_reference_generator('WienerProcessReference',
                                                    physical_system)
    # setup reward function
    reward_function = make_module(RewardFunction, 'WSE')
    reward_function.set_modules(physical_system, reference_generator)
    # initializations of dashboards in different ways
    dashboard = MotorDashboard(plotted_variables=plotted_variables,
                               update_period=update_period,
                               visu_period=visu_period)
    # setup the modules
    dashboard.set_modules(physical_system, reference_generator,
                          reward_function)
    # test for given references in the reset
    len_state = len(physical_system.state_names)
    # setup different pre defined references
    len_reference = 1000
    reference_basic = np.ones((len_state, len_reference))
    references_1 = reference_basic
    references_1[0, :] *= physical_system.limits[0] * 0.8
    references_1[1, :] = None
    references_2 = reference_basic[:len_state, :] * 0.5
    references_2[2, :] = None
    references_3 = reference_basic
    reset_args = [references_1, references_2, references_3, None]

    # test for given references in the reset
    for reset_arg in reset_args:
        dashboard.reset(reset_arg)
        for k in range(50):
            state = np.ones(len_state) * np.sin(k / 1000) / 2 + 0.5
            dashboard.step(state, None, None)
    # test reset() and step function with step reference
    dashboard.reset()
    for k in range(50):
        state = np.ones(len_state) * np.sin(k / 1000) / 2 + 0.5
        reference_generator.get_reference_observation()
        reference = reference_generator.get_reference()
        dashboard.step(state, reference, None)
    dashboard.close()
コード例 #14
0
def test_dc_series_motor():
    motor_state = ['i', 'i']  # list of state names
    motor_parameter = test_motor_parameter['DcSeries']['motor_parameter']
    nominal_values = test_motor_parameter['DcSeries']['nominal_values']  # dict
    limit_values = test_motor_parameter['DcSeries']['limit_values']  # dict
    # default initialization
    motor_1_default = make_module(ElectricMotor, 'DcSeries')
    motor_2_default = DcSeriesMotor()
    # initialization parameters as dicts
    motor_1 = make_module(ElectricMotor,
                          'DcSeries',
                          motor_parameter=motor_parameter,
                          nominal_values=nominal_values,
                          limit_values=limit_values)
    motor_2 = DcSeriesMotor(motor_parameter, nominal_values, limit_values)
    motor_testing(motor_1_default, motor_2_default, motor_1, motor_2,
                  motor_state, limit_values, nominal_values, motor_parameter)

    series_motor_state_space_testing(motor_1_default, motor_2_default)
    series_motor_state_space_testing(motor_1, motor_2)

    series_motor_electrical_ode_testing(motor_1_default)
    series_motor_electrical_ode_testing(motor_1)
コード例 #15
0
def test_make_module(monkeypatch):
    registry = {}
    monkeypatch.setattr(utils, "_registry", registry)
    utils.register_superclass(core.PhysicalSystem)
    utils.register_class(dummies.DummyPhysicalSystem, core.PhysicalSystem,
                         'DummySystem')
    kwargs = dict(a=0, b=5)
    dummy_sys = utils.make_module(core.PhysicalSystem, 'DummySystem', **kwargs)
    assert isinstance(dummy_sys, dummies.DummyPhysicalSystem)
    assert dummy_sys.kwargs == kwargs

    with pytest.raises(Exception):
        _ = registry[core.ReferenceGenerator]['DummySystem']

    with pytest.raises(Exception):
        _ = registry[core.PhysicalSystem]['NonExistingKey']
コード例 #16
0
def test_shifted_weighted_sum_of_errors(normed, reward_power, motor_type, converter_type, number_reward_weights):
    """
    Test the ShiftedWeightedSumOfErrors Class
    :param normed: specifies if the reward is normed (True/False)
    :param reward_power: specifies the used power order (int)
    :param motor_type: motor name (string)
    :param converter_type: converter name (string
    :param number_reward_weights: specifies how many states are considered for the reward
    :return:
    """
    # setup physical system and reference generator
    physical_system = setup_physical_system(motor_type, converter_type)
    reference_generator = setup_reference_generator('SinusReference', physical_system)
    reference_generator.reset()
    len_state = len(physical_system.state_names)
    state = np.ones(len_state) # * physical_system.limits
    reference = physical_system.state_space.low # * physical_system.limits
    # set parameter
    gamma = 0.99
    observed_states = physical_system.state_names
    reward_weights_dict = test_motor_parameter[motor_type]['reward_weights']
    # setup reward functions
    reward_fct_default = ShiftedWeightedSumOfErrors()
    reward_fct_1 = ShiftedWeightedSumOfErrors(reward_weights_dict, normed, observed_states, gamma, reward_power)
    reward_fct_2 = ShiftedWeightedSumOfErrors(reward_weights=reward_weights_dict, normed=normed,
                                              observed_states=observed_states, gamma=gamma, reward_power=reward_power)
    reward_fct_3 = make_module(RewardFunction, 'SWSE', observed_states=observed_states,
                               reward_weights=reward_weights_dict)
    reward_fct_list = [reward_fct_default, reward_fct_1, reward_fct_2, reward_fct_3]
    # test reset, reward, close function
    for index, reward_fct in enumerate(reward_fct_list):
        reward_fct.set_modules(physical_system, reference_generator)
        reward_fct.reset()
        assert reward_fct.reward_range[0] == 0, 'Wrong reward range lower limit'
        assert reward_fct.reward_range[1] > 0, 'Wrong reward range upper limit '
        rew, done = reward_fct.reward(state, reference)
        assert done == 0
        assert reward_fct.reward_range[0] <= rew <= reward_fct.reward_range[1], "Reward out of range"
        # test limit violation
        exceeding_state = 1.2 * state
        rew, done = reward_fct.reward(exceeding_state, reference)
        if index > 0:
            assert done == 1
            assert rew == 0
        else:
            assert done == 0
        reward_fct.close()
コード例 #17
0
def test_continuous_power_electronic_converter(converter_type, tau, interlocking_time, dead_time):
    """
    test the functions and especially the conversion of continuous single converter
    :param converter_type:
    :return:
    """
    interlocking_time *= tau
    # setup converter
    converter = make_module(PowerElectronicConverter, converter_type, tau=tau,
                            interlocking_time=interlocking_time, dead_time=dead_time)
    assert converter.reset() == [0.0], "Error reset function"
    action_space = converter.action_space
    # take 100 random actions
    seed(123)
    actions = [[uniform(action_space.low, action_space.high)] for _ in range(len(g_times_cont))]
    times = g_times_cont * tau

    continuous_converter_functions_testing(converter, times, interlocking_time, dead_time, actions, converter_type)
コード例 #18
0
def test_discrete_double_converter_initializations(tau, interlocking_time, dead_time):
    """
    tests different initializations of the converters
    :return:
    """
    # define all converter
    all_single_disc_converter = ['Disc-1QC', 'Disc-2QC', 'Disc-4QC']
    interlocking_time *= tau
    # chose every combination of single converters
    for conv_1 in all_single_disc_converter:
        for conv_2 in all_single_disc_converter:
            converter = make_module(
                PowerElectronicConverter, 'Disc-Double', tau=tau,
                interlocking_time=interlocking_time, dead_time=dead_time,
                subconverters=[conv_1, conv_2]
            )
            # test if both converter have the same parameter
            assert converter._subconverters[0]._tau == converter._subconverters[1]._tau == tau
            assert converter._subconverters[0]._interlocking_time == converter._subconverters[1]._interlocking_time \
                   == interlocking_time
            assert converter._subconverters[0]._dead_time == converter._subconverters[1]._dead_time == dead_time
コード例 #19
0
def test_continuous_double_power_electronic_converter(tau, interlocking_time, dead_time):
    """
    test functions of continuous double converter
    :return:
    """
    # define all converter
    all_single_cont_converter = ['Cont-1QC', 'Cont-2QC', 'Cont-4QC']
    interlocking_time *= tau
    times = g_times_cont * tau
    for conv_1 in all_single_cont_converter:
        for conv_2 in all_single_cont_converter:
            # setup converter with all possible combinations
            converter = make_module(PowerElectronicConverter, 'Cont-Double', tau=tau,
                                    interlocking_time=interlocking_time, dead_time=dead_time,
                                    subconverters=[conv_1, conv_2])
            assert all(converter.reset() == np.zeros(2))
            action_space = converter.action_space
            seed(123)
            actions = [uniform(action_space.low, action_space.high) for _ in range(0, 100)]
            continuous_double_converter_functions_testing(converter, times, interlocking_time, dead_time, actions,
                                                          [conv_1, conv_2])
コード例 #20
0
def test_discrete_b6_bridge():
    """
    test discrete b6 bridge
    :return:
    """

    tau = converter_parameter['tau']
    # test default initializations
    converter_default_init_1 = make_module(PowerElectronicConverter, 'Disc-B6C')
    converter_default_init_2 = DiscB6BridgeConverter()
    assert converter_default_init_1._tau == 1E-5
    for subconverter in converter_default_init_1._subconverters:
        assert subconverter._tau == 1E-5
        assert subconverter._interlocking_time == 0
        assert subconverter._dead_time is False

    # test default initialized converter
    converters_default = [converter_default_init_1, converter_default_init_2]
    for converter in converters_default:
        assert all(converter.reset() == -0.5 * np.ones(3))
        assert converter._subconverters[0].action_space.n == 3
        assert converter.action_space.n == 8

        # 1  1  1  1  2  2  2  1  2  1  # Action for the converter
        actions_1 = [4, 5, 6, 7, 0, 1, 2, 5, 3, 6]
        actions_2 = [2, 3, 6, 7, 0, 1, 4, 2, 5, 6]
        actions_3 = [1, 3, 5, 7, 0, 2, 4, 3, 6, 5]
        actions = [actions_1, actions_2, actions_3]
        times = np.arange(len(actions[0])) * tau
        i_ins = [0.5, 0, -0.5, 0.5, 0.5, 0, -0.5, -0.5, 0.5, 0.5]
        u_out = np.array([1, 1, 1, 1, -1, -1, -1, 1, -1, 1])
        # test each subconverter individually
        for k in range(3):
            converter.reset()
            step_counter = 0
            i_in = [[0.5], [0], [-0.5]]
            for time, action, i_in_ in zip(times, actions[k], i_ins):
                time_steps = converter.set_action(action, time)
                for time_step in time_steps:
                    i_in[k] = [i_in_]
                    voltage = converter.convert(i_in, time_step)
                    assert voltage[k] == 0.5 * u_out[step_counter], "Wrong action without dead time " + str(
                        step_counter)
                    step_counter += 1

    # test parametrized converter
    converter_init_1 = make_module(PowerElectronicConverter, 'Disc-B6C', **converter_parameter)
    converter_init_2 = DiscB6BridgeConverter(**converter_parameter)
    assert converter_init_1._tau == converter_parameter['tau']
    for subconverter in converter_init_1._subconverters:
        assert subconverter._tau == converter_parameter['tau']
        assert subconverter._interlocking_time == converter_parameter['interlocking_time']
        assert subconverter._dead_time == converter_parameter['dead_time']
    # set parameter
    actions = [6, 6, 4, 5, 1, 2, 3, 7, 0, 4]
    i_ins = [[[0.5], [0.5], [-0.5]],
             [[0], [0.5], [0]],
             [[-0.5], [0.5], [-0.5]],
             [[0.5], [0.5], [0.5]],
             [[0.5], [0.5], [-0.5]],
             [[0], [-0.5], [0]],
             [[-0.5], [-0.5], [0.5]],
             [[-0.5], [-0.5], [-0.5]],
             [[0.5], [-0.5], [0]],
             [[0.5], [-0.5], [0.5]]]

    expected_voltage = np.array([[-1, -1, 1],
                                 [1, 1, -1],
                                 [1, 1, -1],
                                 [1, -1, -1],
                                 [1, -1, -1],
                                 [1, -1, 1],
                                 [1, -1, 1],
                                 [-1, -1, 1],
                                 [-1, -1, 1],
                                 [-1, 1, -1],
                                 [-1, 1, -1],
                                 [-1, 1, 1],
                                 [-1, 1, 1],
                                 [-1, 1, 1],
                                 [1, 1, 1],
                                 [-1, 1, -1],
                                 [-1, -1, -1]]) / 2

    times = np.arange(len(actions)) * tau
    converters_init = [converter_init_1, converter_init_2]
    # test every initialized converter for a given action sequence
    for converter in converters_init:
        converter.reset()
        step_counter = 0
        for time, action, i_in in zip(times, actions, i_ins):
            time_steps = converter.set_action(action, time)
            i_in = np.array(i_in)
            for time_step in time_steps:
                voltage = np.array(converter.convert(i_in, time_step))
                converter.i_sup(i_in)
                assert all(voltage == expected_voltage[step_counter]), "Wrong voltage calculated " + str(step_counter)
                step_counter += 1
コード例 #21
0
def test_continuous_b6_bridge():
    converter_default_init_1 = ContB6BridgeConverter()
    converter_default_init_2 = make_module(PowerElectronicConverter, 'Cont-B6C')
    converters_default = [converter_default_init_1, converter_default_init_2]
    actions = np.array([[1, -1, 0.65],
                        [0.75, -0.95, -0.3],
                        [-0.25, 0.98, -1],
                        [0.65, 0.5, -0.95],
                        [-0.3, 0.5, 0.98],
                        [-1, 1, 0.5],
                        [-0.95, 0.75, 0.5],
                        [0.98, -0.25, 1],
                        [0.5, 0.65, 0.75],
                        [0.5, -0.3, -0.25]])
    i_ins = [[[0.5], [-0.2], [1]],
             [[-0.6], [-0.5], [0.8]],
             [[0.3], [0.4], [0.9]],
             [[-0.2], [0.7], [0.5]],
             [[-0.5], [1], [-0.6]],
             [[0.4], [0.8], [0.3]],
             [[0.7], [0.9], [-0.2]],
             [[1], [0.5], [-0.5]],
             [[0.8], [-0.6], [0.4]],
             [[0.9], [0.75], [0.7]]]

    times = np.arange(len(actions)) * 1E-4
    for converter in converters_default:
        # parameter testing
        assert converter._tau == 1E-4
        assert converter._dead_time is False
        assert converter._interlocking_time == 0
        assert all(converter.reset() == -0.5 * np.ones(3))
        assert converter.action_space.shape == (3,)
        assert all(converter.action_space.low == -1 * np.ones(3))
        assert all(converter.action_space.high == 1 * np.ones(3))
        for subconverter in converter._subconverters:
            assert subconverter._tau == 1E-4
            assert subconverter._dead_time is False
            assert subconverter._interlocking_time == 0
        # conversion testing
        for time, action, i_in in zip(times, actions, i_ins):
            i_in = np.array(i_in)
            i_sup = converter.i_sup(i_in)
            time_step = converter.set_action(action, time)
            voltages = converter.convert(i_in, time_step)
            for voltage, single_action in zip(voltages, action):
                assert abs(voltage[0] - single_action / 2) < 1E-9

    # testing parametrized converter
    expected_voltages = np.array([[-5, -4.95, -5],
                                  [5, -4.95, 3.2],
                                  [3.7, -4.8, -1.55],
                                  [-1.2, 4.85, -5],
                                  [3.3, 2.45, -4.7],
                                  [-1.55, 2.45, 4.85],
                                  [-5, 4.95, 2.55],
                                  [-4.8, 3.7, 2.55],
                                  [4.85, -1.2, 4.95],
                                  [2.45, 3.2, 3.7]]) / 10

    converter_init_1 = ContB6BridgeConverter(**converter_parameter)
    converter_init_2 = make_module(PowerElectronicConverter, 'Cont-B6C', **converter_parameter)
    converters = [converter_init_1, converter_init_2]
    for converter in converters:
        # parameter testing
        assert converter._tau == converter_parameter['tau']
        assert converter._dead_time == converter_parameter['dead_time']
        assert converter._interlocking_time == converter_parameter['interlocking_time']
        assert all(converter.reset() == -0.5 * np.ones(3))
        assert converter.action_space.shape == (3,)
        assert all(converter.action_space.low == -1 * np.ones(3))
        assert all(converter.action_space.high == 1 * np.ones(3))
        for subconverter in converter._subconverters:
            assert subconverter._tau == converter_parameter['tau']
            assert subconverter._dead_time == converter_parameter['dead_time']
            assert subconverter._interlocking_time == converter_parameter['interlocking_time']
        # conversion testing
        for time, action, i_in, expected_voltage in zip(times, actions, i_ins, expected_voltages):
            i_in = np.array(i_in)
            time_step = converter.set_action(action.tolist(), time)
            voltages = converter.convert(i_in, time_step)
            for voltage, test_voltage in zip(voltages, expected_voltage):
                assert abs(voltage - test_voltage) < 1E-9
コード例 #22
0
def setup_sub_generator(generator, **kwargs):
    return make_module(ReferenceGenerator, generator, **kwargs)
コード例 #23
0
def test_synchronous_motor_testing(motor_type, motor_class):
    """
    testing the synrm and pmsm
    consider that it uses dq coordinates and the state is [i_q, i_d, epsilon]!!.
    The same goes with the voltages u_qd and not as usual dq!!
    :return:
    """
    parameter = test_motor_parameter[motor_type]
    # use this values for testing
    state = np.array([0.5, 0.3, 0.68])  # i_q, i_d, epsilon
    u_qd = np.array([200, 50])
    omega = 25
    # test default initialization first
    default_init_1 = make_module(ElectricMotor, motor_type)
    default_init_2 = motor_class()
    # test parameters
    assert default_init_1.motor_parameter == default_init_2.motor_parameter
    assert default_init_1.nominal_values == default_init_2.nominal_values
    assert default_init_1.limits == default_init_2.limits
    # test functions
    mp = default_init_1.motor_parameter
    if motor_type == 'SynRM':
        mp.update({'psi_p': 0})
    for motor in [default_init_1, default_init_2]:
        assert motor.torque(state) == torque_testing(state, mp)
        assert all(motor.i_in(state) == state[0:2])
        ode = motor.electrical_ode(state, u_qd, omega)
        test_ode = synchronous_motor_ode_testing(state, u_qd, omega, mp)
        assert sum(abs(ode - test_ode)) < 1E-8, "Motor ode is wrong: " + str(
            [ode, test_ode])
    # test parametrized motors
    motor_init_1 = make_module(ElectricMotor,
                               motor_type,
                               motor_parameter=parameter['motor_parameter'],
                               nominal_values=parameter['nominal_values'],
                               limit_values=parameter['limit_values'])

    motor_init_2 = motor_class(motor_parameter=parameter['motor_parameter'],
                               nominal_values=parameter['nominal_values'],
                               limit_values=parameter['limit_values'])
    for motor in [motor_init_1, motor_init_2]:
        # test motor parameter

        assert motor.motor_parameter == parameter['motor_parameter'], "Different Parameter: " + \
                                                                      str([motor.motor_parameter,
                                                                           parameter['motor_parameter']])
        mp = motor.motor_parameter
        if motor_type == 'SynRM':
            mp.update({'psi_p': 0})
        # test limits
        factor_abc_to_alpha_beta = 1
        for limit_key in motor_init_1.limits.keys():
            if 'i_' in limit_key:
                assert motor_init_1.limits[limit_key] == parameter['limit_values']['i'] or \
                       motor_init_1.limits[limit_key] == factor_abc_to_alpha_beta * parameter['limit_values']['i']
            if 'u_' in limit_key:
                assert motor_init_1.limits[limit_key] == parameter['limit_values']['u'] or \
                       motor_init_1.limits[limit_key] == .5 * factor_abc_to_alpha_beta * parameter['limit_values']['u']\
                       or motor_init_1.limits[limit_key] == .5 * parameter['limit_values']['u']

            if limit_key in parameter['limit_values'].keys():
                assert motor_init_1.limits[limit_key] == parameter[
                    'limit_values'][limit_key]

            if 'i_' in limit_key:
                assert motor_init_1.nominal_values[limit_key] == parameter['nominal_values']['i'] or \
                       motor_init_1.nominal_values[limit_key] == factor_abc_to_alpha_beta\
                       * parameter['nominal_values']['i']
            if 'u_' in limit_key:
                assert motor_init_1.nominal_values[limit_key] == 0.5 * factor_abc_to_alpha_beta * \
                       parameter['nominal_values']['u'] or \
                       motor_init_1.nominal_values[limit_key] == parameter['nominal_values']['u'] \
                       or motor_init_1.nominal_values[limit_key] == .5 * parameter['nominal_values']['u']
            if limit_key in parameter['nominal_values'].keys():
                assert motor_init_1.nominal_values[limit_key] == parameter[
                    'nominal_values'][limit_key]
        # test functions
        assert motor.torque(state) == torque_testing(state, mp)
        assert all(motor.i_in(state) == state[0:2])
        ode = motor.electrical_ode(state, u_qd, omega)
        test_ode = synchronous_motor_ode_testing(state, u_qd, omega, mp)
        assert sum(abs(ode - test_ode)) < 1E-8, "Motor ode is wrong: " + str(
            [ode, test_ode])
コード例 #24
0
def test_initialization_weighted_sum_of_errors(normed, reward_power,
                                               motor_type, converter_type,
                                               number_reward_weights):
    """
    Function to test the basic methods and functions ot the WeightedSumOfErrors class

    :param normed: specifies if the reward is normed (True/False)
    :param reward_power: specifies the used power order (int)
    :param motor_type: motor name (string)
    :param converter_type: converter name (string
    :param number_reward_weights: specifies how many states are considered for the reward
    :return:
    """
    # setup physical system and reference generator
    physical_system = setup_physical_system(motor_type, converter_type)
    reference_generator = setup_reference_generator('SinusReference',
                                                    physical_system)
    reference_generator.reset()
    len_state = len(physical_system.state_names)
    state = np.ones(len_state)
    reference = physical_system.state_space.low
    # set parameters
    gamma = 0.99
    # observe the limits for all state variables
    observed_states = physical_system.state_names

    # set different types of reward weights
    reward_weights_dict = test_motor_parameter[motor_type]['reward_weights']
    # test different numbers of reward weights
    if number_reward_weights == 1:
        reward_weights_dict['torque'] = 0
    elif number_reward_weights == 3:
        reward_weights_dict['u_sup'] = 1

    reward_weights_list = list(reward_weights_dict.values())
    reward_weights_array = np.array(reward_weights_list)
    # initialize the reward function with different types of reward weights
    reward_fct_default = WeightedSumOfErrors(observed_states=None)
    reward_fct_initial_dict = WeightedSumOfErrors(reward_weights_dict,
                                                  observed_states=None)
    reward_fct_initial_list = WeightedSumOfErrors(reward_weights_list,
                                                  observed_states=None)
    reward_fct_initial_array = WeightedSumOfErrors(reward_weights_array,
                                                   observed_states=None)
    reward_fct_make = make_module(RewardFunction,
                                  'WSE',
                                  reward_weights=reward_weights_dict,
                                  observed_states=None)
    # initialize a reward function where all parameters are set
    reward_fct_test = WeightedSumOfErrors(reward_weights_dict,
                                          normed,
                                          gamma,
                                          reward_power,
                                          observed_states=observed_states)
    reward_fcts = [
        reward_fct_default, reward_fct_initial_dict, reward_fct_initial_list,
        reward_fct_initial_array, reward_fct_make, reward_fct_test
    ]
    for reward_fct in reward_fcts:
        reward_fct.set_modules(physical_system, reference_generator)

    # test if reward weights of default initialization are different to the parametrized initialization
    assert reward_fct_default._reward_weights is not reward_fct_initial_dict._reward_weights
    # test if all parametrized initializations result in the same reward weights
    assert all(reward_fct_initial_dict._reward_weights == reward_fct_initial_list._reward_weights) \
        and all(reward_fct_initial_dict._reward_weights == reward_fct_initial_array._reward_weights)

    # test the reward range, it should be negative and therefore, the upper limit is always zero
    assert reward_fct_test.reward_range[1] == 0
    # if the reward is normalized the minimum reward should be -1
    if normed:
        assert reward_fct_test.reward_range[0] == -1

    # test the reset, reward and close function as well as the limit violation in a basic test scenario
    for index, reward_fct in enumerate(reward_fcts):
        reward_fct.reset()
        reward_fct.close()
        rew, done = reward_fct.reward(state, reference)
        # test if reward is in the expected range
        assert reward_fct.reward_range[0] <= rew <= reward_fct.reward_range[1], "Reward out of reward range" +\
                                                                                str(reward_fct.reward_range) + " " +\
                                                                                str(reward_fct._normed) + " " +\
                                                                                str(reward_fct._reward_weights) + " " +\
                                                                                str(state) + " " + \
                                                                                str(reference) + " " + \
                                                                                str(index)
        assert done == 0
        # test if limit check does work
        exceeding_state = state * 1.2
        rew, done = reward_fct.reward(exceeding_state, reference)
        if index < 5:
            assert done == 0, "Limit violation recognized " + str(
                [exceeding_state, physical_system.limits])
        else:
            assert done == 1, "Limit violation is not recognized " + str(
                [exceeding_state, physical_system.limits])
            # test if the punishment is correct
            assert rew == reward_fct.reward_range[0] / (
                1 - gamma), "Wrong punishment"
コード例 #25
0
def test_cont_three_phase(motor_type):
    """
    test the physical system for continuous-time three phase motors
    :param motor_type: motor name (string)
    :return:
    """
    converter_type = 'Cont-B6C'
    actions = [[1, 1, 1], [0, 0, 0], [-1, -1, -1], [0.5, -0.5, 0.3],
               [-0.6, 0.5, 0.3]]
    # test default initializations
    default_motor = make_module(ElectricMotor, motor_type)
    default_converter = make_module(PowerElectronicConverter, converter_type)
    default_mechanical_load = make_module(MechanicalLoad, 'PolyStaticLoad')
    default_supply = make_module(VoltageSupply, 'IdealVoltageSupply')
    default_solver = make_module(OdeSolver, 'scipy.solve_ivp')

    default_scml_1 = SynchronousMotorSystem(converter=converter_type,
                                            motor=motor_type)

    default_scml_2 = SynchronousMotorSystem(motor=default_motor,
                                            converter=default_converter,
                                            load=default_mechanical_load,
                                            supply=default_supply,
                                            ode_solver=default_solver)

    default_scml_3 = SynchronousMotorSystem(motor=motor_type,
                                            converter=converter_type,
                                            load='PolyStaticLoad',
                                            supply='IdealVoltageSupply',
                                            ode_solver='scipy.solve_ivp')
    # test parameters for different default initializations
    assert all(default_scml_2.limits ==
               default_scml_3.limits), "Different default limits"
    assert all(default_scml_2.nominal_state == default_scml_3.nominal_state
               ), "Different default nominal values"
    assert default_scml_2.tau == default_scml_3.tau == default_scml_1.tau, "Different sampling times"
    assert default_scml_1.state_names == default_scml_2.state_names == default_scml_3.state_names
    assert default_scml_1.state_positions == default_scml_2.state_positions == default_scml_3.state_positions == \
           dict(omega=0, torque=1, i_a=2, i_b=3, i_c=4, u_a=5, u_b=6, u_c=7, epsilon=8, u_sup=9)

    assert default_scml_1.state_space.shape == default_scml_2.state_space.shape == \
           default_scml_2.state_space.shape == (10,)

    # test functions as reset, simulate, close
    for scml in [default_scml_1, default_scml_2, default_scml_3]:
        assert all(scml.reset() == np.array([0, 0, 0, 0, 0, -1, -1, -1, 0, 1]))

        assert all(default_scml_1.action_space.low == -1 *
                   np.ones(3)) and all(scml.action_space.high == np.ones(3))

        for action in actions:
            state = scml.simulate(action)
            assert all(scml.state_space.low <= state / scml.limits) and all(
                state / scml.limits <= scml.state_space.high)
        scml.close()

    # test parametrized initializations
    mp = test_motor_parameter[motor_type]['motor_parameter']
    cp = converter_parameter
    lp = load_parameter['parameter']
    u_sup = mp['u_sup']
    tau = cp['tau']
    # set up instantiated modules
    motor = make_module(ElectricMotor, motor_type, motor_parameter=mp)
    converter = make_module(PowerElectronicConverter,
                            converter_type,
                            converter_parameter=cp)
    mechanical_load = make_module(MechanicalLoad,
                                  'PolyStaticLoad',
                                  load_parameter=lp)
    supply = make_module(VoltageSupply,
                         'IdealVoltageSupply',
                         u_nominal=u_sup,
                         tau=tau)
    solver = make_module(OdeSolver, 'scipy.solve_ivp')
    # initialize parametrized SCML systems
    scml_1 = SynchronousMotorSystem(motor=motor,
                                    converter=converter,
                                    load=mechanical_load,
                                    supply=supply,
                                    ode_solver=solver,
                                    tau=tau)

    scml_2 = SynchronousMotorSystem(motor=motor_type,
                                    converter=converter_type,
                                    load='PolyStaticLoad',
                                    supply='IdealVoltageSupply',
                                    ode_solver='scipy.solve_ivp',
                                    motor_parameter=mp,
                                    converter_parameter=cp,
                                    load_parameter=lp,
                                    tau=tau,
                                    u_sup=u_sup)
    # test parameter
    assert all(scml_1.limits == scml_2.limits), "Different default limits"
    assert all(scml_1.nominal_state ==
               scml_2.nominal_state), "Different default nominal values"
    assert scml_1.tau == scml_2.tau == tau, "Different sampling times"
    assert scml_1.state_names == scml_2.state_names
    assert scml_1.state_positions == scml_2.state_positions == \
           dict(omega=0, torque=1, i_a=2, i_b=3, i_c=4, u_a=5, u_b=6, u_c=7, epsilon=8, u_sup=9)
    assert scml_1.state_space.shape == scml_2.state_space.shape == (10, )

    # test functions reset, simulate, close
    for scml in [scml_1, scml_2]:
        assert all(
            scml.reset() == np.array([0, 0, 0, 0, 0, -.75, -.75, -.75, 0, 1]))
        assert all(default_scml_1.action_space.low == -1 *
                   np.ones(3)) and all(scml.action_space.high == np.ones(3))

        assert all(scml.state_space.high == np.ones(10))
        assert all(scml.state_space.low == np.array(
            [-1, -1, -1, -1, -1, -1, -1, -1, -1, 0])), "Wrong state space"

    for index, action in enumerate(actions):
        state_1 = scml_1.simulate(action)
        state_2 = scml_2.simulate(action)
        assert all(state_1 == state_2)
        assert all(scml.state_space.low <= state_1 / scml.limits) and all(
            state_1 / scml.limits <= scml.state_space.high)
        assert scml.k == index + 1

    scml_1.close()
    scml_2.close()