def main(): # t_psim, Y_psim = mio.read_csv('bldc_startup_psim_1us_resolution.csv') # mp.plot_output(t_psim, Y_psim, '.') freq_sim = 1e6 # simulation frequency compress_factor = 3 time = pl.arange(0.0, 0.01, 1. / freq_sim) # create time slice vector X = np.zeros((time.size, dm.sv_size)) # allocate state vector Xdebug = np.zeros((time.size, dm.dv_size)) # allocate debug data vector Y = np.zeros((time.size, dm.ov_size)) # allocate output vector U = np.zeros((time.size, dm.iv_size)) # allocate input vector X0 = [0, mu.rad_of_deg(0.1), 0, 0, 0] # X[0, :] = X0 W = [0, 1] for i in range(1, time.size): if i == 1: Uim2 = np.zeros(dm.iv_size) else: Uim2 = U[i - 2, :] Y[i - 1, :] = dm.output(X[i - 1, :], Uim2) # get the output for the last step U[i - 1, :] = ctl.run(0, Y[i - 1, :], time[i - 1]) # run the controller for the last step tmp = integrate.odeint(dm.dyn, X[i - 1, :], [time[i - 1], time[i]], args=(U[i - 1, :], W)) # integrate X[i, :] = tmp[1, :] # copy integration output to the current step X[i, dm.sv_theta] = mu.norm_angle( X[i, dm.sv_theta]) # normalize the angle in the state tmp, Xdebug[i, :] = dm.dyn_debug(X[i - 1, :], time[i - 1], U[i - 1, :], W) # get debug data print_simulation_progress(i, time.size) Y[-1, :] = Y[-2, :] U[-1, :] = U[-2, :] if compress_factor > 1: time = compress(time, compress_factor) Y = compress(Y, compress_factor) X = compress(X, compress_factor) U = compress(U, compress_factor) Xdebug = compress(Xdebug, compress_factor) mp.plot_output(time, Y, '-') # pl.show() plt.figure(figsize=(10.24, 5.12)) display_state_and_command(time, X, U) plt.figure(figsize=(10.24, 5.12)) mp.plot_debug(time, Xdebug) pl.show()
def main(): # t_psim, Y_psim = mio.read_csv('bldc_startup_psim_1us_resolution.csv') # mp.plot_output(t_psim, Y_psim, '.') freq_sim = 1e6 # simulation frequency compress_factor = 3 time = pl.arange(0.0, 0.01, 1./freq_sim) # create time slice vector X = np.zeros((time.size, dm.sv_size)) # allocate state vector Xdebug = np.zeros((time.size, dm.dv_size)) # allocate debug data vector Y = np.zeros((time.size, dm.ov_size)) # allocate output vector U = np.zeros((time.size, dm.iv_size)) # allocate input vector X0 = [0, mu.rad_of_deg(0.1), 0, 0, 0] # X[0,:] = X0 W = [0, 1] for i in range(1,time.size): if i==1: Uim2 = np.zeros(dm.iv_size) else: Uim2 = U[i-2,:] Y[i-1,:] = dm.output(X[i-1,:], Uim2) # get the output for the last step U[i-1,:] = ctl.run(0, Y[i-1,:], time[i-1]) # run the controller for the last step tmp = integrate.odeint(dm.dyn, X[i-1,:], [time[i-1], time[i]], args=(U[i-1,:], W)) # integrate X[i,:] = tmp[1,:] # copy integration output to the current step X[i, dm.sv_theta] = mu.norm_angle( X[i, dm.sv_theta]) # normalize the angle in the state tmp, Xdebug[i,:] = dm.dyn_debug(X[i-1,:], time[i-1], U[i-1,:], W) # get debug data print_simulation_progress(i, time.size) Y[-1,:] = Y[-2,:] U[-1,:] = U[-2,:] if compress_factor > 1: time = compress(time, compress_factor) Y = compress(Y, compress_factor) X = compress(X, compress_factor) U = compress(U, compress_factor) Xdebug = compress(Xdebug, compress_factor) mp.plot_output(time, Y, '-') # pl.show() plt.figure(figsize=(10.24, 5.12)) display_state_and_command(time, X, U) plt.figure(figsize=(10.24, 5.12)) mp.plot_debug(time, Xdebug) pl.show()
def backemf(X,thetae_offset): phase_thetae = mu.norm_angle((X[sv_theta] * (NbPoles / 2.)) + thetae_offset) bemf_constant = mu.vpradps_of_rpmpv(Kv) # aka. ke in V/rad/s max_bemf = bemf_constant * X[sv_omega] bemf = 0. if 0. <= phase_thetae <= (math.pi * (1./6.)): bemf = (max_bemf / (math.pi * (1./6.))) * phase_thetae elif (math.pi/6.) < phase_thetae <= (math.pi * (5./6.)): bemf = max_bemf elif (math.pi * (5./6.)) < phase_thetae <= (math.pi * (7./6.)): bemf = -((max_bemf/(math.pi/6.))* (phase_thetae - math.pi)) elif (math.pi * (7./6.)) < phase_thetae <= (math.pi * (11./6.)): bemf = -max_bemf elif (math.pi * (11./6.)) < phase_thetae <= (2.0 * math.pi): bemf = (max_bemf/(math.pi/6.)) * (phase_thetae - (2. * math.pi)) else: print "ERROR: angle out of bounds can not calculate bemf {}".format(phase_thetae) return bemf
def backemf(X, thetae_offset): phase_thetae = mu.norm_angle((X[sv_theta] * (NbPoles / 2.)) + thetae_offset) bemf_constant = mu.vpradps_of_rpmpv(Kv) # aka. ke in V/rad/s max_bemf = bemf_constant * X[sv_omega] bemf = 0. if 0. <= phase_thetae <= (math.pi * (1. / 6.)): bemf = (max_bemf / (math.pi * (1. / 6.))) * phase_thetae elif (math.pi / 6.) < phase_thetae <= (math.pi * (5. / 6.)): bemf = max_bemf elif (math.pi * (5. / 6.)) < phase_thetae <= (math.pi * (7. / 6.)): bemf = -((max_bemf / (math.pi / 6.)) * (phase_thetae - math.pi)) elif (math.pi * (7. / 6.)) < phase_thetae <= (math.pi * (11. / 6.)): bemf = -max_bemf elif (math.pi * (11. / 6.)) < phase_thetae <= (2.0 * math.pi): bemf = (max_bemf / (math.pi / 6.)) * (phase_thetae - (2. * math.pi)) else: print "ERROR: angle out of bounds can not calculate bemf {}".format( phase_thetae) return bemf
def run_hpwm_l_on_bipol(Sp, Y, t): elec_angle = mu.norm_angle(Y[dm.ov_theta] * dm.NbPoles/2) U = np.zeros(dm.iv_size) step = "none" # switching pattern based on the "encoder" # H PWM L ON pattern if 0. <= elec_angle <= (math.pi * (1./6.)): # second half of step 1 # U off # V low # W hpwm hu = 0 lu = 0 hv = 0 lv = 1 if math.fmod(t, PWM_cycle_time) <= PWM_duty_time: hw = 1 else: hw = 0 lw = 0 step = "1b" elif (math.pi * (1.0/6.0)) < elec_angle <= (math.pi * (3.0/6.0)): # step 2 # U hpwm # V low # W off if math.fmod(t, PWM_cycle_time) <= PWM_duty_time: hu = 1 else: hu = 0 lu = 0 hv = 0 lv = 1 hw = 0 lw = 0 step = "2 " elif (math.pi * (3.0/6.0)) < elec_angle <= (math.pi * (5.0/6.0)): # step 3 # U hpwm # V off # W low if math.fmod(t, PWM_cycle_time) <= PWM_duty_time: hu = 1 else: hu = 0 lu = 0 hv = 0 lv = 0 hw = 0 lw = 1 step = "3 " elif (math.pi * (5.0/6.0)) < elec_angle <= (math.pi * (7.0/6.0)): # step 4 # U off # V hpwm # W low hu = 0 lu = 0 if math.fmod(t, PWM_cycle_time) <= PWM_duty_time: hv = 1 else: hv = 0 lv = 0 hw = 0 lw = 1 step = "4 " elif (math.pi * (7.0/6.0)) < elec_angle <= (math.pi * (9.0/6.0)): # step 5 # U low # V hpwm # W off hu = 0 lu = 1 if math.fmod(t, PWM_cycle_time) <= PWM_duty_time: hv = 1 else: hv = 0 lv = 0 hw = 0 lw = 0 step = "5 " elif (math.pi * (9.0/6.0)) < elec_angle <= (math.pi * (11.0/6.0)): # step 6 # U low # V off # W hpwm hu = 0 lu = 1 hv = 0 lv = 0 if math.fmod(t, PWM_cycle_time) <= PWM_duty_time: hw = 1 else: hw = 0 lw = 0 step = "6 " elif (math.pi * (11.0/6.0)) < elec_angle <= (math.pi * (12.0/6.0)): # first half of step 1 # U off # V low # W hpwm hu = 0 lu = 0 hv = 0 lv = 1 if math.fmod(t, PWM_cycle_time) <= PWM_duty_time: hw = 1 else: hw = 0 lw = 0 step = "1a" else: print 'ERROR: The electrical angle is out of range!!!' # Assigning the scheme phase values to the simulator phases # "Connecting the controller wires to the motor" ^^ # This way we can for example decide which direction we want to turn the motor U[dm.iv_hu] = hu U[dm.iv_lu] = lu U[dm.iv_hv] = hw U[dm.iv_lv] = lw U[dm.iv_hw] = hv U[dm.iv_lw] = lv if debug: print 'time {} step {} eangle {} switches {}'.format(t, step, mu.deg_of_rad(elec_angle), U) return U
def run_hpwm_l_on_bipol(Sp, Y, t): elec_angle = mu.norm_angle(Y[dm.ov_theta] * dm.NbPoles / 2) U = np.zeros(dm.iv_size) step = "none" # switching pattern based on the "encoder" # H PWM L ON pattern if 0. <= elec_angle <= (math.pi * (1. / 6.)): # second half of step 1 # U off # V low # W hpwm hu = 0 lu = 0 hv = 0 lv = 1 if math.fmod(t, PWM_cycle_time) <= PWM_duty_time: hw = 1 else: hw = 0 lw = 0 step = "1b" elif (math.pi * (1.0 / 6.0)) < elec_angle <= (math.pi * (3.0 / 6.0)): # step 2 # U hpwm # V low # W off if math.fmod(t, PWM_cycle_time) <= PWM_duty_time: hu = 1 else: hu = 0 lu = 0 hv = 0 lv = 1 hw = 0 lw = 0 step = "2 " elif (math.pi * (3.0 / 6.0)) < elec_angle <= (math.pi * (5.0 / 6.0)): # step 3 # U hpwm # V off # W low if math.fmod(t, PWM_cycle_time) <= PWM_duty_time: hu = 1 else: hu = 0 lu = 0 hv = 0 lv = 0 hw = 0 lw = 1 step = "3 " elif (math.pi * (5.0 / 6.0)) < elec_angle <= (math.pi * (7.0 / 6.0)): # step 4 # U off # V hpwm # W low hu = 0 lu = 0 if math.fmod(t, PWM_cycle_time) <= PWM_duty_time: hv = 1 else: hv = 0 lv = 0 hw = 0 lw = 1 step = "4 " elif (math.pi * (7.0 / 6.0)) < elec_angle <= (math.pi * (9.0 / 6.0)): # step 5 # U low # V hpwm # W off hu = 0 lu = 1 if math.fmod(t, PWM_cycle_time) <= PWM_duty_time: hv = 1 else: hv = 0 lv = 0 hw = 0 lw = 0 step = "5 " elif (math.pi * (9.0 / 6.0)) < elec_angle <= (math.pi * (11.0 / 6.0)): # step 6 # U low # V off # W hpwm hu = 0 lu = 1 hv = 0 lv = 0 if math.fmod(t, PWM_cycle_time) <= PWM_duty_time: hw = 1 else: hw = 0 lw = 0 step = "6 " elif (math.pi * (11.0 / 6.0)) < elec_angle <= (math.pi * (12.0 / 6.0)): # first half of step 1 # U off # V low # W hpwm hu = 0 lu = 0 hv = 0 lv = 1 if math.fmod(t, PWM_cycle_time) <= PWM_duty_time: hw = 1 else: hw = 0 lw = 0 step = "1a" else: print("ERROR: The electrical angle is out of range!!!") # Assigning the scheme phase values to the simulator phases # "Connecting the controller wires to the motor" ^^ # This way we can for example decide which direction we want to turn the motor U[dm.iv_hu] = hu U[dm.iv_lu] = lu U[dm.iv_hv] = hw U[dm.iv_lv] = lw U[dm.iv_hw] = hv U[dm.iv_lw] = lv if debug: print('time {} step {} eangle {} switches {}'.format( t, step, mu.deg_of_rad(elec_angle), U)) return U