%% DRFOC with PI tuned according to Kessler criteria: %% the modulus optimum method and the symmetrical optimum method (AKA Naslin polynomial method). % % Bartlomiej Ufnalski % Institute of Control and Industrial Electronics % Warsaw University of Technology % 2016.05.26 % % For Extended Luenberger Observer demonstration clear all; rng('shuffle'); Tgraph=1e-3; % sampling period for graphs % Direct rotor field oriented control (DRFOC) scheme is implemented here k_measurement_i = 1/15; tau_measurement_i = 1e-4; % delay k_measurement_omega = 1/100; tau_measurement_omega = 0.005; % delay k_converter = 300; tau_converter = 1.5e-4; % dealy related to digital implementation and PWM out_sat = 1; % saturation level for all PI controllers psir_ref = 0.65; J_tot = 0.15; % Motor parameters Ls = 0.1004; Lr = 0.0969; Lm = 0.0915; sigma = 1-Lm*Lm/Lr/Ls; Rs = 1.54; Rr = 1.294; pb = 3; c_viscosity = 1e-2; Tr = Lr/Rr; Ts = 1e-4; % controller at 10kHz Imax = 15; % to determine noise signal OMEGAmax = 80; % to determine noise signal Umax = k_converter; % to determine noise signal upper_speed = 70; upper_torque = 13; % Modulus Optimum (MO) for current controllers R_MO = Rs + Rr; L_MO = (Ls - Lm) + (Lr - Lm); % the above are from the T-shaped equivalent model of the machine -- the vertical path with Lm neglected (model under short-circuit condition) tau_MO_dominant = L_MO/R_MO; tau_MO_sum_of_small = tau_converter + tau_measurement_i; k_plant_MO = k_converter * 1/R_MO * k_measurement_i; % plant gain T_reg_current_MO = tau_MO_dominant; K_reg_current_MO = 1/2/k_plant_MO/tau_MO_sum_of_small; kp_ix = K_reg_current_MO * T_reg_current_MO; ki_ix = K_reg_current_MO; kp_iy = kp_ix; ki_iy = ki_ix; % Symmetrical Optimum (SO) for speed controller % Plant: 1/(2*tau_MO_sum_of_small*s+1) * (1/k_measurement_i) * 3/2 * Lm/Lr * pb * psir_ref % * (1/c_viscosity)/(s*(J_tot/c_viscosity) + 1) * k_measurement_omega/(s*tau_measurement_omega + 1) k_plant_SO = (1/k_measurement_i) * 3/2 * Lm/Lr * pb * psir_ref * (1/c_viscosity) * k_measurement_omega; tau_SO_dominant = J_tot/c_viscosity; tau_SO_sum_of_small = 2 * tau_MO_sum_of_small + tau_measurement_omega; alpha = 3; % 4 produces critically damped system; 2 is the first hand choice; alpha = 4*zeta^2 T_reg_omega_SO = alpha^2 * tau_SO_sum_of_small; K_reg_omega_SO = tau_SO_dominant/alpha^3/k_plant_SO/tau_SO_sum_of_small/tau_SO_sum_of_small; kp_om = K_reg_omega_SO * T_reg_omega_SO; ki_om = K_reg_omega_SO; % Flux controller plant_PSI = tf([1/k_measurement_i],[2*tau_MO_sum_of_small^2 2*tau_MO_sum_of_small 1]); [z,p,k] = zpkdata(plant_PSI); % this does not comply with SO method step_PSI = stepinfo(plant_PSI); disp(['Stator current rise time: ' num2str(step_PSI.RiseTime)]); disp(['Suggested stator flux rise time: ' num2str(step_PSI.RiseTime*10)]); % Flux controller tuned using PID Tuner -- see flux_controller_PID_Tuner.slx % It is assumed here that the rise time of flux response is increased ca. tenfold in comparison to the current response. % This is a typical approach to cascaded controllers. kp_psi = 3; ki_psi = 100; % Reference speed, disturbance torque and noise generator seeds seed_1 = round(rand*(2^32-1)); seed_2 = round(rand*(2^32-1)); seed_3 = round(rand*(2^32-1)); seed_4 = round(rand*(2^32-1)); seed_5 = round(rand*(2^32-1)); seed_6 = round(rand*(2^32-1)); seed_7 = round(rand*(2^32-1)); seed_8 = round(rand*(2^32-1)); seed_9 = round(rand*(2^32-1)); seed_10 = round(rand*(2^32-1)); seed_11 = round(rand*(2^32-1)); how_many_within = 98; % in percentage erf_inverse = 2.3263 for 98% % erf_inverse = 2.3263; erf_inverse = erfinv(how_many_within/100)*sqrt(2); % inverse Gauss error function noise_psd_OMEGA = (OMEGAmax*0.01/erf_inverse)^2*Ts; % in digital encoders there is no typical noise, but still some non-neglegible inacuracies may be present dpsirmax = 1e2; system_psir_noise_PSD = (dpsirmax*0.005/erf_inverse)^2*Ts; dismax = 2e3; system_is_noise_PSD = (dismax*0.005/erf_inverse)^2*Ts; domegamax = 3e2; system_omega_noise_PSD = (domegamax*0.005/erf_inverse)^2*Ts; noise_psd_I = (Imax*0.03/erf_inverse)^2*Ts; % t_stop = 5; % That's all folks!