Exemplo n.º 1
0
    nominal_values = {key: 0.7 * limit for key, limit in limit_values.items()}

    # Create the environment
    env = gem.make(
        'emotor-pmsm-cont-v1',
        # Pass a class with extra parameters
        visualization=MotorDashboard,
        visu_period=1,
        load=ConstantSpeedLoad(omega_fixed=1000 * np.pi / 30),
        control_space='dq',
        # Pass a string (with extra parameters)
        ode_solver='scipy.solve_ivp',
        solver_kwargs={},
        # Pass an instance
        reference_generator=rg,
        plotted_variables=['i_sq', 'i_sd', 'u_sq', 'u_sd'],
        reward_weights={
            'i_sq': 1000,
            'i_sd': 1000
        },
        reward_power=0.5,
        observed_states=['i_sq', 'i_sd'],
        dead_time=True,
        u_sup=400,
        motor_parameter=motor_parameter,
        limit_values=limit_values,
        nominal_values=nominal_values,
        state_filter=['i_sq', 'i_sd', 'epsilon'])

    # Due to the dead time in the system, the
    env = AppendLastActionWrapper(env)
from rl.agents import DDPGAgent
from rl.memory import SequentialMemory
from rl.random import GaussianWhiteNoiseProcess
from gym_electric_motor.reference_generators import MultiReferenceGenerator, WienerProcessReferenceGenerator, \
    StepReferenceGenerator, SinusoidalReferenceGenerator
from gym_electric_motor.visualization import MotorDashboard
from gym.wrappers import FlattenObservation

# Create the environment
env = gem.make(
    'emotor-dc-series-cont-v1',
    # Pass a class with extra parameters
    visualization=MotorDashboard,
    visu_period=1,

    # Take standard class and pass parameters (Load)
    load_parameter=dict(a=0, b=.0, c=0.0, j_load=.5),

    # Pass a string (with extra parameters)
    ode_solver='euler',
    solver_kwargs={},
    # Pass an instance
    reference_generator=WienerProcessReferenceGenerator(reference_state='i'))
# Keras-rl DDPG-agent only accepts flat observations
env = FlattenObservation(env)
nb_actions = env.action_space.shape[0]

actor = Sequential()
actor.add(Flatten(input_shape=(1, ) + env.observation_space.shape))
actor.add(Dense(16))
actor.add(Activation('relu'))
actor.add(Dense(16))
Exemplo n.º 3
0
    env = gem.make(
        # Choose the permanent magnet synchronous motor with continuous-control-set
        'PMSMCont-v1',

        # Set the mechanical load to have constant speed
        load=ConstantSpeedLoad(omega_fixed=1000 * np.pi / 30),

        # Set the frame of control inputs, dq is the flux oriented coordinate system
        control_space='dq',

        # Define which numerical solver is to be used for the simulation
        ode_solver='scipy.solve_ivp',
        solver_kwargs={},

        # Pass the previously defined reference generator
        reference_generator=rg,

        # Set weighting of different addends of the reward function
        reward_weights={
            'i_sq': 1000,
            'i_sd': 1000
        },

        # Exponent of the reward function
        # Here we use a square root function
        reward_power=0.5,

        # Define which state variables are to be monitored concerning limit violations
        # Here, only overcurrent will lead to termination
        observed_states=['i_sq', 'i_sd'],

        # Consider converter dead time within the simulation
        # This means that a given action will show effect only with one step delay
        # This is realistic behavior of drive applications
        dead_time=True,

        # Set the DC-link supply voltage
        u_sup=400,

        # Pass the previously defined motor parameters
        motor_parameter=motor_parameter,

        # Pass the updated motor limits and nominal values
        limit_values=limit_values,
        nominal_values=nominal_values,

        # Define which states will be shown in the state observation (what we can "measure")
        state_filter=['i_sd', 'i_sq', 'epsilon'],

        # Defines which variables to plot via the builtin dashboard monitor
        visualization=MotorDashboard(
            plots=['i_sd', 'i_sq', 'action_0', 'action_1', 'mean_reward']),
        visu_period=1,
    )
sys.path.append(os.path.abspath(os.path.join('..')))
import gym_electric_motor as gem
from gym_electric_motor.reference_generators import *
from gym_electric_motor.visualization import MotorDashboard

if __name__ == '__main__':
    env = gem.make(
        'emotor-dc-series-cont-v1',
        # Pass an instance
        visualization=MotorDashboard(plotted_variables=['all'], visu_period=1),

        # Take standard class and pass parameters (Load)
        load_parameter=dict(a=0.01, b=.1, c=0.1, j_load=.05),

        # Pass a string (with extra parameters)
        ode_solver='euler',
        solver_kwargs={},
        # Pass a Class with extra parameters
        reference_generator=MultiReferenceGenerator(
            sub_generators=[
                SinusoidalReferenceGenerator,
                WienerProcessReferenceGenerator(),
                StepReferenceGenerator()
            ],
            p=[0.1, 0.8, 0.1],
            super_episode_length=(1000, 10000)))
    controller = Controller.make('cascaded_pi', env)
    state, reference = env.reset()
    start = time.time()
    cum_rew = 0
    for i in range(100000):
        env.render()
Exemplo n.º 5
0
import gym_electric_motor as gem
from gym_electric_motor.visualization import MotorDashboard
from gym_electric_motor.reference_generators import WienerProcessReferenceGenerator

if __name__ == '__main__':
    # Run the option parsing
    # Get the environment and extract the number of actions.
    env = gem.make(
        'emotor-dc-series-disc-v1',
        state_filter=['i'],
        # Pass an instance
        visualization=MotorDashboard(visu_period=0.5,
                                     plotted_variables=['omega', 'i', 'u']),
        converter='Disc-4QC',
        # Take standard class and pass parameters (Load)
        a=0,
        b=.1,
        c=1.1,
        j_load=0.4,
        # Pass a string (with extra parameters)
        ode_solver='euler',
        solver_kwargs={},
        # Pass a Class with extra parameters
        reference_generator=WienerProcessReferenceGenerator(
            reference_state='i', sigma_range=(5e-3, 5e-1)))
    nb_actions = env.action_space.n
    env = FlattenObservation(env)
    model = Sequential()
    model.add(Flatten(input_shape=(1, ) + env.observation_space.shape))
    model.add(Dense(4))
    model.add(LeakyReLU(alpha=0.05))
    model.add(Dense(4))
    env = gem.make(
        # Define the series DC motor with continuous-control-set
        'DcSeriesCont-v1',

        # Set the parameters of the motor
        motor_parameter=dict(r_a=2.5, r_e=4.5, l_a=9.7e-3, l_e_prime=9.2e-3, l_e=9.2e-3, j_rotor=0.001),

        # Set the parameters of the mechanical polynomial load (the default load class)
        load_parameter=dict(a=0, b=.0, c=0.01, j_load=.001),

        # Weighting of different addends of the reward function
        # This can be used to assign higher or lower priorities to different states
        # As only one state is weighted here, the value does not make a major difference
        reward_weights={'omega': 1000},

        # Exponent of the reward function
        # Here we use a square root function
        reward_power=0.5,

        # Define which state variables are to be monitored concerning limit violations
        # None means that a limit violation will never trigger an env.reset
        observed_states=None,

        # Define which numerical solver is to be used for the simulation
        ode_solver='scipy.solve_ivp',
        solver_kwargs=dict(method='BDF'),

        # Define and parameterize the reference generator for the speed reference
        reference_generator=WienerProcessReferenceGenerator(reference_state='omega', sigma_range=(5e-3, 1e-2)),

        # Defines which variables to plot via the builtin dashboard monitor
        visualization=MotorDashboard(['omega', 'torque', 'i', 'u', 'u_sup', 'reward']), visu_period=1,
    )
if __name__ == '__main__':
    """
       Continuous mode: The action is the average (normalized) voltage per time step which is assumed to be transferred to a PWM/SVM 
                        converter to generate the switching sequence.

       Discrete mode: The action is the switching state of the power converter i.e., a quantity from a discrete set of
                      switching states which can be generated by the converter.     
    """
    env = gem.make('DcPermExDisc-v1',
                   visualization=MotorDashboard(
                       plots=['omega', 'torque', 'i', 'u', 'u_sup'],
                       visu_period=1),
                   ode_solver='scipy.solve_ivp',
                   solver_kwargs=dict(),
                   reference_generator=rg.SwitchedReferenceGenerator(
                       sub_generators=[
                           rg.SinusoidalReferenceGenerator,
                           rg.WienerProcessReferenceGenerator(),
                           rg.StepReferenceGenerator()
                       ],
                       p=[0.1, 0.8, 0.1],
                       super_episode_length=(1000, 10000)))

    # Assign a simple on/off controller
    controller = Controller.make('on_off', env)
    state, reference = env.reset()
    start = time.time()
    cum_rew = 0
    for i in range(100000):
        env.render()
        action = controller.control(state, reference)
Exemplo n.º 8
0
 def test_make(self):
     if self.key != '':
         env = gem.make(self.key)
         assert type(env) == self.test_class
Exemplo n.º 9
0
           Continuous mode: The action is the average (normalized) voltage per time step which is assumed to be transferred to a PWM 
                            converter to generate the switching sequence.

           Discrete mode: The action is the switching state of the power converter i.e., a quantity from a discrete set of
                          switching states which can be generated by the converter.   


    """

    env = gem.make(
        'DcSeriesCont-v1',  # replace with 'DcSeriesDisc-v1' for discrete controllers
        state_filter=['omega', 'i'],
        # Pass an instance
        visualization=MotorDashboard(plots=['i', 'omega']),
        # Take standard class and pass parameters (Load)
        motor_parameter=dict(r_a=15e-3, r_e=15e-3, l_a=100e-3, l_e=100e-3),
        load_parameter=dict(a=0, b=.1, c=.1, j_load=0.04),
        # Pass a string (with extra parameters)
        ode_solver='scipy.solve_ivp',
        solver_kwargs={},
        # Pass a Class with extra parameters
        reference_generator=rg.WienerProcessReferenceGenerator())

    # Assign a PI-controller to the speed control problem
    controller = Controller.make('pi_controller', env)
    state, reference = env.reset()

    # get the system time to measure program duration
    start = time.time()

    cum_rew = 0
Exemplo n.º 10
0
    ref = 'omega'
    env = gem.make(
        #'DcExtExDisc-v1', visualization=MotorDashboard(plots=['omega', 'torque', 'i_a', 'i_e', 'u_a', 'u_e'], visu_period=1), motor_parameter=dict(j_rotor=0.00005), load_parameter={'a': 0, 'b': 0, 'c': 0, 'j_load': 0},
        #'DcPermExDisc-v1', visualization=MotorDashboard(plots=['omega', 'torque', 'i', 'u'], visu_period=1),
        #'DcSeriesDisc-v1', visualization=MotorDashboard(plots=['omega', 'torque', 'i', 'u'], visu_period=1),
        #'DcShuntDisc-v1', visualization=MotorDashboard(plots=['omega', 'torque', 'i_a', 'i_e', 'u'], visu_period=1), motor_parameter=dict(j_rotor=0.01), load_parameter={'a': 0, 'b': 0, 'c': 0, 'j_load': 0},

        #'DcExtExCont-v1', visualization=MotorDashboard(plots=['omega', 'torque', 'i_a', 'i_e', 'u_a', 'u_e'], visu_period=1), motor_parameter=dict(j_rotor=0.00005), load_parameter={'a': 0, 'b': 0, 'c': 0, 'j_load': 0},
        'DcPermExCont-v1',
        visualization=MotorDashboard(plots=['omega', 'torque', 'i', 'u'],
                                     visu_period=1),
        #'DcSeriesCont-v1', visualization=MotorDashboard(plots=['omega', 'torque', 'i', 'u'], visu_period=1),
        #'DcShuntCont-v1', visualization=MotorDashboard(plots=['omega', 'torque', 'i_a', 'i_e', 'u'], visu_period=1),
        ode_solver='scipy.solve_ivp',
        solver_kwargs=dict(),
        #load=ConstantSpeedLoad(omega_fixed=50 * np.pi / 30),
        reference_generator=rg.SwitchedReferenceGenerator(
            sub_generators=[
                rg.SinusoidalReferenceGenerator(reference_state=ref,
                                                amplitude_range=(0, 0.3),
                                                offset_range=(0, 0.2)),
                rg.WienerProcessReferenceGenerator(reference_state=ref,
                                                   amplitude_range=(0, 0.3),
                                                   offset_range=(0, 0.2)),
                rg.StepReferenceGenerator(reference_state=ref,
                                          amplitude_range=(0, 0.3),
                                          offset_range=(0, 0.2))
            ],
            p=[0.5, 0.25, 0.25],
            super_episode_length=(10000, 100000)),
    )
from gym_electric_motor.reference_generators import WienerProcessReferenceGenerator
from gym_electric_motor.visualization import MotorDashboard

if __name__ == '__main__':

    tf.compat.v1.disable_eager_execution()
    # Create the environment
    env = gem.make(
        'emotor-dc-series-cont-v1',
        # Pass a class with extra parameters
        visualization=MotorDashboard,
        visu_period=1,
        motor_parameter=dict(r_a=1e-1, r_e=1e-1),
        # Take standard class and pass parameters (Load)
        load_parameter=dict(a=0, b=.0, c=0.05, j_load=.05),
        reward_weights={'omega': 1000},
        reward_power=0.5,
        observed_states=None,
        # Pass a string (with extra parameters)
        ode_solver='euler',
        solver_kwargs={},
        # Pass an instance
        reference_generator=WienerProcessReferenceGenerator(
            reference_state='omega', sigma_range=(5e-3, 1e-2)))
    # Keras-rl DDPG-agent accepts flat observations only
    env = FlattenObservation(env)
    nb_actions = env.action_space.shape[0]

    #  CAUTION: Do not use layers that behave differently in training and
    #  testing
    #  (e.g. dropout, batch-normalization, etc..)
sys.path.append(os.path.abspath(os.path.join('..')))
import gym_electric_motor as gem
from gym_electric_motor import reference_generators as rg
from gym_electric_motor.visualization import MotorDashboard

if __name__ == '__main__':
    env = gem.make(
        'emotor-dc-series-cont-v1',
        # Pass an instance
        visualization=MotorDashboard(plotted_variables='all', visu_period=1),
        motor_parameter=dict(r_a=15e-3, r_e=15e-3, l_a=1e-3, l_e=1e-3),
        # Take standard class and pass parameters (Load)
        load_parameter=dict(a=0.01, b=.1, c=0.1, j_load=.06),

        # Pass a string (with extra parameters)
        ode_solver='scipy.solve_ivp',
        solver_kwargs=dict(),
        # Pass a Class with extra parameters
        reference_generator=rg.SwitchedReferenceGenerator(
            sub_generators=[
                rg.SinusoidalReferenceGenerator,
                rg.WienerProcessReferenceGenerator(),
                rg.StepReferenceGenerator()
            ],
            p=[0.1, 0.8, 0.1],
            super_episode_length=(1000, 10000)))
    controller = Controller.make('cascaded_pi', env)
    state, reference = env.reset()
    start = time.time()
    cum_rew = 0
    for i in range(100000):
        env.render()
def set_env(time_limit=True,
            gamma=0.99,
            N=0,
            M=0,
            training=True,
            callbacks=[]):
    # define motor arguments
    motor_parameter = dict(
        p=3,  # [p] = 1, nb of pole pairs
        r_s=17.932e-3,  # [r_s] = Ohm, stator resistance
        l_d=0.37e-3,  # [l_d] = H, d-axis inductance
        l_q=1.2e-3,  # [l_q] = H, q-axis inductance
        psi_p=65.65e-3,
        # [psi_p] = Vs, magnetic flux of the permanent magnet
    )
    u_sup = 350
    nominal_values = dict(omega=4000 * 2 * np.pi / 60, i=230, u=u_sup)
    limit_values = dict(omega=4000 * 2 * np.pi / 60, i=1.5 * 230, u=u_sup)
    q_generator = WienerProcessReferenceGenerator(reference_state='i_sq')
    d_generator = WienerProcessReferenceGenerator(reference_state='i_sd')
    rg = MultipleReferenceGenerator([q_generator, d_generator])
    tau = 1e-5
    max_eps_steps = 10000

    if training:
        motor_initializer = {
            'random_init': 'uniform',
            'interval': [[-230, 230], [-230, 230], [-np.pi, np.pi]]
        }
        # motor_initializer={'random_init': 'gaussian'}
        reward_function = gem.reward_functions.WeightedSumOfErrors(
            observed_states=['i_sq', 'i_sd'],
            reward_weights={
                'i_sq': 10,
                'i_sd': 10
            },
            constraint_monitor=SqdCurrentMonitor(),
            gamma=gamma,
            reward_power=1)
    else:
        motor_initializer = {'random_init': 'gaussian'}
        reward_function = gem.reward_functions.WeightedSumOfErrors(
            observed_states=['i_sq', 'i_sd'],
            reward_weights={
                'i_sq': 0.5,
                'i_sd': 0.5
            },  # comparable reward
            constraint_monitor=SqdCurrentMonitor(),
            gamma=0.99,  # comparable reward
            reward_power=1)

    # creating gem environment
    env = gem.make(  # define a PMSM with discrete action space
        "PMSMDisc-v1",
        # visualize the results
        visualization=MotorDashboard(plots=['i_sq', 'i_sd', 'reward']),
        # parameterize the PMSM and update limitations
        motor_parameter=motor_parameter,
        limit_values=limit_values,
        nominal_values=nominal_values,
        # define the random initialisation for load and motor
        load='ConstSpeedLoad',
        load_initializer={
            'random_init': 'uniform',
        },
        motor_initializer=motor_initializer,
        reward_function=reward_function,

        # define the duration of one sampling step
        tau=tau,
        u_sup=u_sup,
        # turn off terminations via limit violation, parameterize the rew-fct
        reference_generator=rg,
        ode_solver='euler',
        callbacks=callbacks,
    )

    # appling wrappers and modifying environment
    env.action_space = Discrete(7)
    eps_idx = env.physical_system.state_names.index('epsilon')
    i_sd_idx = env.physical_system.state_names.index('i_sd')
    i_sq_idx = env.physical_system.state_names.index('i_sq')

    if time_limit:
        gem_env = TimeLimit(
            AppendNLastActionsWrapper(
                AppendNLastOberservationsWrapper(
                    EpsilonWrapper(FlattenObservation(env), eps_idx, i_sd_idx,
                                   i_sq_idx), N), M), max_eps_steps)
    else:
        gem_env = AppendNLastActionsWrapper(
            AppendNLastOberservationsWrapper(
                EpsilonWrapper(FlattenObservation(env), eps_idx, i_sd_idx,
                               i_sq_idx), N), M)
    return gem_env
            amplitude * np.sin(omega * t + phi_initial + phi)
        ]
        return u_abc

    return grid_voltage


# Create the environment
env = gem.make(
    # Choose the squirrel cage induction motor (SCIM) with continuous-control-set
    "SCIMCont-v1",

    # Define the numerical solver for the simulation
    ode_solver="scipy.ode",

    # Define which state variables are to be monitored concerning limit violations
    # "None" means, that limit violation will not necessitate an env.reset()
    observed_states=None,

    # Parameterize the mechanical load (we set everything to zero such that only j_rotor is significant)
    load_parameter=dict(a=0, b=0, c=0, j_load=0),

    # Set the sampling time
    tau=1e-5)

tau = env._physical_system.tau
limits = env._physical_system.limits

# reset the environment such that the simulation can be started
(state, reference) = env.reset()

# We define these arrays in order to save our simulation results in them
Exemplo n.º 15
0
sys.path.append(os.path.abspath(os.path.join('..')))
import gym_electric_motor as gem
from gym_electric_motor.reward_functions import WeightedSumOfErrors
from gym_electric_motor.visualization import MotorDashboard
from gym_electric_motor.reference_generators import WienerProcessReferenceGenerator


if __name__ == '__main__':
    env = gem.make(
        'emotor-dc-series-disc-v1',
        state_filter=['omega', 'i'],
        # Pass an instance
        reward_function=WeightedSumOfErrors(observed_states='i'),
        visualization=MotorDashboard(update_period=1e-2, visu_period=1e-1, plotted_variables=['omega', 'i', 'u']),
        converter='Disc-1QC',
        # Take standard class and pass parameters (Load)
        motor_parameter=dict(r_a=15e-3, r_e=15e-3, l_a=1e-3, l_e=1e-3),
        load_parameter=dict(a=0, b=.1, c=.1, j_load=0.04),
        # Pass a string (with extra parameters)
        ode_solver='euler', solver_kwargs={},
        # Pass a Class with extra parameters
        reference_generator=WienerProcessReferenceGenerator(reference_state='i', sigma_range=(3e-3, 3e-2))
    )
    env = FlattenObservation(env)

    nb_actions = env.action_space.n
    window_length = 1

    model = Sequential()
    model.add(Flatten(input_shape=(window_length,) + env.observation_space.shape))
    model.add(Dense(16, activation='relu'))
Exemplo n.º 16
0
}

# initializer for a specific speed
load_init = {'states': {'omega': 20}}

if __name__ == '__main__':
    env = gem.make(
        'DcSeriesCont-v1',
        visualization=MotorDashboard(plots=['omega', 'i'], dark_mode=False),
        motor_parameter=dict(j_rotor=0.001),
        load_parameter=dict(a=0, b=0.1, c=0, j_load=0.001),
        ode_solver='scipy.solve_ivp',
        solver_kwargs=dict(),
        reference_generator=rg.SwitchedReferenceGenerator(
            sub_generators=[
                rg.SinusoidalReferenceGenerator(reference_state='omega'),
                rg.WienerProcessReferenceGenerator(reference_state='omega'),
                rg.StepReferenceGenerator(reference_state='omega')
            ],
            p=[0.2, 0.6, 0.2],
            super_episode_length=(1000, 10000)),

        # Pass the predefined initializers
        motor_initializer=gaussian_init,
        load_initializer=uniform_init,
    )

    # After the setup is done, we are ready to simulate the environment
    # We make use of a standard PI speed controller
    controller = Controller.make('pi_controller', env)
    start = time.time()
    cum_rew = 0
    """
       Continuous mode: The action is the average (normalized) voltage per time step which is assumed to be transferred to a PWM/SVM 
                        converter to generate the switching sequence.

       Discrete mode: The action is the switching state of the power converter i.e., a quantity from a discrete set of
                      switching states which can be generated by the converter.     
    """
    env = gem.make(
        'DcPermExDisc-v1',
        visualization=MotorDashboard(
            state_plots=['omega', 'torque', 'i', 'u', 'u_sup']),
        ode_solver='scipy.solve_ivp',
        solver_kwargs=dict(),
        reference_generator=rg.SwitchedReferenceGenerator(
            sub_generators=[
                rg.SinusoidalReferenceGenerator,
                rg.WienerProcessReferenceGenerator(),
                rg.StepReferenceGenerator()
            ],
            p=[0.1, 0.8, 0.1],
            super_episode_length=(1000, 10000)),
        # Override the observation of the current limit of 'i' which is selected per default
        # The 'on_off' Controller cannot comply to any limits.
        constraints=())

    # Assign a simple on/off controller
    controller = Controller.make('on_off', env)
    state, reference = env.reset()
    start = time.time()
    cum_rew = 0
    for i in range(100000):
Exemplo n.º 18
0
    parser.add_argument("--mode", type=str, required=True)
    parser.add_argument("--output", type=str, default='outputs')
    parser.add_argument("--weights", type=str, default=None)
    parser.add_argument("--constrained", type=int, default=1)
    args = parser.parse_args()
    # Create the environment
    # Default DcSeries Motor Parameters are changed to have more dynamic system and to see faster learning results.
    env = gem.make(
        'emotor-dc-series-cont-v1',
        # Pass a class with extra parameters
        visualization=MotorDashboard, visu_period=5,
        motor_parameter=dict(r_a=2.5, r_e=4.5, l_a=9.7e-3, l_e_prime=9.2e-3, l_e=9.2e-3, j_rotor=0.001),
        # Take standard class and pass parameters (Load)
        load_parameter=dict(a=0, b=.0, c=0.01, j_load=.001),
        reward_weights={'omega': 1000},
        reward_power=0.5,
        observed_states=None,  # Constraint violation monitoring is disabled for presentation purpose
        # Pass a string (with extra parameters)
        plotted_variables=['omega', 'i', 'u'],
        ode_solver='scipy.solve_ivp', solver_kwargs=dict(method='BDF'),
        # Pass an instance
        reference_generator=SquareReferenceGenerator(reference_state='omega')
        # reference_generator=WienerProcessReferenceGenerator(reference_state='omega', sigma_range=(5e-3, 1e-2))
    )

    density_max_func = interpolate.interp1d(
        x=[0.15, 0.2, 0.25, 0.3, 1.0],
        y=[120, 80, 10, 10, 10],
        kind='slinear',
        fill_value=10000,
        bounds_error=False,
# External speed profiles can be given by an ExternalSpeedLoad,
# inital value is given by bias of the profile
sampling_time = 1e-4

if __name__ == '__main__':
    # Create the environment
    env = gem.make(
        'DcSeriesCont-v1',
        ode_solver='scipy.solve_ivp', solver_kwargs=dict(),
        tau=sampling_time,
        reference_generator=const_switch_gen,
        visualization=MotorDashboard(state_plots=['omega', 'i'], reward_plot=True),

        # define which load to use, feel free to try these examples:

        # using ExternalSpeedLoad:
        #load=ExternalSpeedLoad(speed_profile=sinus_lambda, tau=sampling_time, amplitude=10, frequency=2, bias=4)
        load=ExternalSpeedLoad(speed_profile=saw_lambda, tau=sampling_time, amplitude=40, frequency=5, bias=40)
        #load=ExternalSpeedLoad(speed_profile=constant_lambda, value=3, load_initializer={'random_init': 'uniform', 'interval': [[20, 80]]})
        #(ExternalSpeedLoad will not use the passed initializer and print a corresponding warning instead)

        # using ConstantSpeedLoad (this class also accepts an initializer):
        #load=ConstantSpeedLoad(omega_fixed=42, load_initializer={'random_init': 'uniform', 'interval': [[20, 80]]})
    )

    # After the setup is done, we are ready to simulate the environment
    # We make use of a standard PI current controller
    controller = Controller.make('pi_controller', env)

    episode_duration = 0.2  # episode duration in seconds
    steps_per_episode = int(episode_duration / sampling_time)
Exemplo n.º 20
0
    env = gem.make(
        # Define the series DC motor with finite-control-set
        'DcSeriesDisc-v1',

        # Set the electric parameters of the motor
        motor_parameter=dict(r_a=15e-3, r_e=15e-3, l_a=1e-3, l_e=1e-3),

        # Set the parameters of the mechanical polynomial load (the default load class)
        load_parameter=dict(a=0, b=.1, c=.1, j_load=0.04),

        # Defines the utilized power converter, which determines the action space
        # 'Disc-1QC' is our notation for a discontinuous one-quadrant converter,
        # which is a one-phase buck converter with available actions 'switch on' and 'switch off'
        converter='Disc-1QC',

        # Define which states will be shown in the state observation (what we can "measure")
        state_filter=['omega', 'i'],

        # Define the reward function and to which state variable it applies
        # Here, we define it for current control
        reward_function=WeightedSumOfErrors(observed_states='i'),

        # Defines which numerical solver is to be used for the simulation
        # euler is fastest but not most precise
        ode_solver='euler',
        solver_kwargs={},

        # Define and parameterize the reference generator for the current reference
        reference_generator=WienerProcessReferenceGenerator(
            reference_state='i', sigma_range=(3e-3, 3e-2)),

        # Defines which variables to plot via the builtin dashboard monitor
        visualization=MotorDashboard(state_plots=['i', 'omega']),
    )
    """
           Continuous mode: The action is the average (normalized) voltage per time step which is assumed to be transferred to a PWM 
                            converter to generate the switching sequence.

           Discrete mode: The action is the switching state of the power converter i.e., a quantity from a discrete set of
                          switching states which can be generated by the converter.   
    """

    env = gem.make(
        'DcSeriesCont-v1',  # replace with 'DcSeriesDisc-v1' for discrete controllers
        state_filter=['omega', 'i'],
        # Pass an instance
        visualization=MotorDashboard(
            state_plots=['i', 'omega'], reward_plot=True, action_plots='all',
            additional_plots=[CumulativeConstraintViolationPlot(), MeanEpisodeRewardPlot()]
        ),
        # Take standard class and pass parameters (Load)
        motor_parameter=dict(r_a=15e-3, r_e=15e-3, l_a=100e-3, l_e=100e-3),
        load_parameter=dict(a=0, b=.1, c=.1, j_load=0.04),
        # Pass a string (with extra parameters)
        ode_solver='euler', solver_kwargs={},
        # Pass a Class with extra parameters
        reference_generator=rg.WienerProcessReferenceGenerator()
    )

    # Assign a PI-controller to the speed control problem
    controller = Controller.make('pi_controller', env)
    state, reference = env.reset()

    # get the system time to measure program duration
    start = time.time()