loc = numpy.where(particles.ss == k)[0]
    s = 0
    for l in loc:
        s += particles.ws[l]

    switchtrack[k, 0] = s

maxtrack[:, 0] = RBPF.get_max_track(particles, numModels)

# Controller Input
ind = numpy.argmax(maxtrack[:, 0])  # use this model and controller
horizon = 150

params.us[0] = MPC.mpc_lqr(params.rbpfmeans[:, 0] - models[ind].b, horizon,
                           models[ind].A, numpy.matrix(models[ind].B),
                           numpy.matrix(params.QQ), numpy.matrix(params.RR),
                           controllers[ind].x_off,
                           numpy.array([controllers[ind].u_off[0]]))
# Loop through the rest of time

for t in range(1, params.N):
    params.xs[:, t] = params.cstr_model.run_reactor(params.xs[:, t - 1],
                                                    params.us[t - 1], params.h)
    params.xs[:, t] += state_noise_dist.rvs()  # actual plant
    params.ys2[:, t] = params.C2 @ params.xs[:, t] + meas_noise_dist.rvs(
    )  # measured from actual plant
    RBPF.rbpf_filter(particles, params.us[t - 1], params.ys2[:, t], models, A)
    params.rbpfmeans[:,
                     t], params.rbpfcovars[:, :,
                                           t] = RBPF.get_ave_stats(particles)
예제 #2
0
                    params.R2)  # set up the KF object (measuring both states)
state_noise_dist = scipy.stats.multivariate_normal(cov=params.Q)
meas_noise_dist = scipy.stats.multivariate_normal(cov=params.R2)

# First time step of the simulation
params.xs[:,
          0] = init_state - b  # set simulation starting point to the random initial state
params.ys2[:, 0] = params.C2 @ params.xs[:, 0] + meas_noise_dist.rvs(
)  # measure from actual plant
temp = kf_cstr.init_filter(init_state - b, params.init_state_covar,
                           params.ys2[:, 0])  # filter
params.kfmeans[:, 0], params.kfcovars[:, :, 0] = temp

horizon = 150
params.us[0] = MPC.mpc_lqr(params.kfmeans[:, 0], horizon, A, numpy.matrix(B),
                           params.QQ, params.RR, numpy.array([0, 0]),
                           numpy.array([0.0]))  # get the controller input

for t in range(1, params.N):
    params.xs[:, t] = A @ (params.xs[:, t - 1] - b) + B * params.us[
        t - 1] + b + state_noise_dist.rvs()  # actual plant

    params.ys2[:, t] = params.C2 @ params.xs[:, t] + meas_noise_dist.rvs(
    )  # measure from actual plant
    temp = kf_cstr.step_filter(params.kfmeans[:, t - 1],
                               params.kfcovars[:, :, t - 1], params.us[t - 1],
                               params.ys2[:, t] - b)
    params.kfmeans[:, t], params.kfcovars[:, :, t] = temp

    # Compute controller action
    if t % 10 == 0:
def fun():
    isDone = True
    init_state = numpy.array([0.55, 450])  # initial state

    # Setup Switching Particle Filter
    A = numpy.array([[0.999, 0.001], [0.001, 0.999]])

    def fun1(x, u, w):
        return params.cstr_model.run_reactor(x, u, params.h) + w

    def fun2(x, u, w):
        return params.cstr_model_broken.run_reactor(x, u, params.h) + w

    def gs(x):
        return params.C2 @ x

    F = [fun1, fun2]
    G = [gs, gs]
    numSwitches = 2

    ydists = numpy.array([
        scipy.stats.multivariate_normal(cov=params.R2),
        scipy.stats.multivariate_normal(cov=params.R2)
    ])
    xdists = numpy.array([
        scipy.stats.multivariate_normal(cov=params.Q),
        scipy.stats.multivariate_normal(cov=params.Q)
    ])
    cstr_filter = SPF.Model(F, G, A, xdists, ydists)

    nP = 500  # number of particles
    xdist = scipy.stats.multivariate_normal(mean=init_state,
                                            cov=params.init_state_covar)
    sdist = [0.9, 0.1]
    particles = SPF.init_spf(xdist, sdist, nP, 2)

    switchtrack = numpy.zeros([2, params.N])
    maxtrack = numpy.zeros([numSwitches, params.N])
    smoothedtrack = numpy.zeros([numSwitches, params.N])

    state_noise_dist = scipy.stats.multivariate_normal(cov=params.Q)
    meas_noise_dist = scipy.stats.multivariate_normal(cov=params.R2)

    # Setup control (use linear control)
    linsystems = params.cstr_model.get_nominal_linear_systems(params.h)
    linsystems_broken = params.cstr_model_broken.get_nominal_linear_systems(
        params.h)
    opoint = 1  # the specific linear model we will use

    lin_models = [None] * 2  # type: typing.List[RBPF.Model]
    lin_models[0] = RBPF.Model(linsystems[opoint].A, linsystems[opoint].B,
                               linsystems[opoint].b, params.C2, params.Q,
                               params.R2)
    lin_models[1] = RBPF.Model(linsystems_broken[opoint].A,
                               linsystems_broken[opoint].B,
                               linsystems_broken[opoint].b, params.C2,
                               params.Q, params.R2)

    H = numpy.matrix([1, 0])  # only attempt to control the concentration
    setpoint = 0.49
    controllers = [None] * 2  # type: typing.List[LQR.Controller]
    for k in range(2):
        ysp = setpoint - lin_models[k].b[0]  # set point is set here
        x_off, u_off = LQR.offset(lin_models[k].A,
                                  numpy.matrix(lin_models[k].B), params.C2, H,
                                  numpy.matrix([ysp]))
        K = LQR.lqr(lin_models[k].A, numpy.matrix(lin_models[k].B), params.QQ,
                    params.RR)
        controllers[k] = LQR.Controller(K, x_off, u_off)

    # Setup simulation
    params.xs[:, 0] = init_state
    params.ys2[:, 0] = params.C2 @ params.xs[:, 0] + meas_noise_dist.rvs(
    )  # measured from actual plant

    SPF.init_filter(particles, params.ys2[:, 0], cstr_filter)

    for k in range(numSwitches):
        switchtrack[k, 0] = numpy.sum(
            particles.w[numpy.where(particles.s == k)[0]])

    maxtrack[:, 0] = SPF.get_max_track(particles, numSwitches)
    smoothedtrack[:, 0] = RBPF.smoothed_track(numSwitches, switchtrack, 1, 10)

    params.spfmeans[:, 0], params.spfcovars[:, :, 0] = SPF.get_stats(particles)

    # Controller Input
    ind = numpy.argmax(maxtrack[:, 0])  # use this model and controller
    horizon = 150
    params.us[0] = MPC.mpc_lqr(params.spfmeans[:, 0] - lin_models[ind].b,
                               horizon, lin_models[ind].A,
                               numpy.matrix(lin_models[ind].B), params.QQ,
                               params.RR, controllers[ind].x_off,
                               controllers[ind].u_off)

    # Loop through the rest of time
    for t in range(1, params.N):
        random_element = state_noise_dist.rvs()
        if params.ts[t] < 100:  # break here
            params.xs[:, t] = params.cstr_model.run_reactor(
                params.xs[:, t - 1], params.us[t - 1],
                params.h) + random_element
        else:
            params.xs[:, t] = params.cstr_model_broken.run_reactor(
                params.xs[:, t - 1], params.us[t - 1], params.h)
            params.xs[:, t] += random_element

        params.ys2[:, t] = params.C2 @ params.xs[:, t] + meas_noise_dist.rvs(
        )  # measured from actual plant

        SPF.spf_filter(particles, params.us[t - 1], params.ys2[:, t],
                       cstr_filter)
        params.spfmeans[:, t], params.spfcovars[:, :,
                                                t] = SPF.get_stats(particles)

        for k in range(numSwitches):
            switchtrack[k, 0] = numpy.sum(
                particles.w[numpy.where(particles.s == k)[0]])

        maxtrack[:, t] = SPF.get_max_track(particles, numSwitches)
        smoothedtrack[:, t] = RBPF.smoothed_track(numSwitches, switchtrack, t,
                                                  40)

        # Controller Input
        if t % 1 == 0:
            ind = numpy.argmax(maxtrack[:, t])  # use this model and controller
            params.us[t] = MPC.mpc_lqr(
                params.spfmeans[:, t] - lin_models[ind].b, horizon,
                lin_models[ind].A, numpy.matrix(lin_models[ind].B), params.QQ,
                params.RR, controllers[ind].x_off, controllers[ind].u_off)
        else:
            params.us[t] = params.us[t - 1]
            if params.us[t] is None or numpy.isnan(params.us[t]):
                isDone = False
                break
    return isDone, setpoint
SPF.init_filter(particles, params.ys2[:, 0], cstr_filter)

for k in range(numSwitches):
    switchtrack[k, 0] = numpy.sum(particles.w[numpy.where(particles.s == k)[0]])

maxtrack[:, 0] = SPF.get_max_track(particles, numSwitches)
smoothedtrack[:, 0] = RBPF.smoothed_track(numSwitches, switchtrack, 1, 10)

params.spfmeans[:, 0], params.spfcovars[:, :, 0] = SPF.get_stats(particles)

# Controller Input
ind = numpy.argmax(maxtrack[:, 0])  # use this model and controller
horizon = 150
params.us[0] = MPC.mpc_lqr(params.spfmeans[:, 0] - lin_models[ind].b, horizon, lin_models[ind].A,
                           numpy.matrix(lin_models[ind].B), params.QQ, params.RR,
                           controllers[ind].x_off, controllers[ind].u_off)

# Loop through the rest of time
for t in range(1, params.N):
    random_element = state_noise_dist.rvs()
    if params.ts[t] < 100:  # break here
        params.xs[:, t] = params.cstr_model.run_reactor(params.xs[:, t-1], params.us[t-1], params.h) + random_element
    else:
        params.xs[:, t] = params.cstr_model_broken.run_reactor(params.xs[:, t-1], params.us[t-1], params.h)
        params.xs[:, t] += random_element

    params.ys2[:, t] = params.C2 @ params.xs[:, t] + meas_noise_dist.rvs()  # measured from actual plant

    SPF.spf_filter(particles, params.us[t-1], params.ys2[:, t], cstr_filter)
    params.spfmeans[:, t], params.spfcovars[:, :, t] = SPF.get_stats(particles)