Modelling Equations For A DC Motor
And PV Position Controller
© 2008 Quanser Consulting Inc.
Worksheet Initialization
> | restart: interface( imaginaryunit=j ): |
> | with(inttrans): |
= first load angular position [rad]
> | alias( Theta[1] = laplace( theta[1](t), t, s ) ): |
= Torque produced by the motor at the load gear
> | alias( T[1] = laplace( tq[1](t), t, s ) ): |
> |
DC Motor System Definition - Laplace Representation: G(s)
This section models the motor system to be controlled.
motor transfer function (in the Laplace domain)
> | G[j1] := 'Theta[1] / I[1]'; |
Newton's second law of motion (i.e. equation of motion in the time domain):
> | NEWTON_EQ_DT := J[eq1] * diff( theta[1](t), t$2 ) = tq[1]( t ) - B[eq1] * diff( theta[1](t), t ); |
> | NEWTON_EQ_S := laplace( NEWTON_EQ_DT, t, s ); |
the initial conditions are null
> | IC := { theta[1](0) = 0, D(theta[1])(0) = 0 }: |
> | NEWTON_EQ_S := subs( IC, NEWTON_EQ_S ); |
Torque generated by the DC motor
> | T[1] := K[t] * I[1]; |
Back-ElectroMotive-Force Voltage:
> | E[emf] := 'K[m] * Omega[m]'; |
> | Omega[l] := Theta[1] * s; |
> | NEWTON_EQ_S := collect( NEWTON_EQ_S, { s, Theta[1] } ); |
> | Theta[1] := solve( NEWTON_EQ_S, Theta[1] ); |
> | G[j1] := sort( G[j1], s ); |
and
Open Loop (i.e. SRV02) Transfer Function
> | 'G[j1]' = G[j1]; |
Position Controller Characterisation
PD Position Control
Control Law:
where
> | G[c] := 'K[p] + K[d] * s'; |
unity feedback
> | H := '1'; |
> | T[pd] := G[c] * G[j1] / ( 1 + G[c] * G[j1] * H ); |
> | T[pd] := simplify( T[pd] ); |
> | char_eqn[pd] := collect( denom( T[pd] ), s ); |
Same characteristic equation as with a PV controller (as seen below: char_eqn[pd] == char_eqn[pv]).
However, a PD controller introduces an unaccounted zero in the closed-loop transfer function (see T[pd]).
PV Position Control
and
Determination
Determine the PV controller gains:
and
.
unassign variables
> | G[c] := 'G[c]': H := 'H': K[p] := 'K[p]': |
Controller TF in the forward loop
> | G[c] := 'K[p]'; |
Feedback loop equivalent block (through block reduction)
> | H := 'K[v] / K[p] * s +1'; |
Closed Loop Transfer Function:
> | T[pv] := G[c] * G[j1] / ( 1 + G[c] * G[j1] * H ); |
> | T[pv] := simplify( T[pv] ); |
> | char_eqn[pv] := collect( denom( T[pv] ), s ); |
normalize the characteristic equation
> | char_eqn[pv] := collect( char_eqn[pv] / coeff( char_eqn[pv], s^2), s ); |
> | char_eqn[std] := s^2 + 2 * zeta * omega[n] * s + omega[n]^2; |
> | ID_EQ := char_eqn[pv] = char_eqn[std]; |
solving ID_EQ by identification
> | EQ_KP := coeff( rhs( ID_EQ ), s, 0 ) = coeff( lhs( ID_EQ ), s, 0 ); |
> | K[p] := solve( EQ_KP, K[p] ); |
> | EQ_KV := coeff( rhs( ID_EQ ), s ) = coeff( lhs( ID_EQ ), s ); |
> | K[v] := solve( EQ_KV, K[v] ); |
and
Determination
unassign variables
> | K[p] := 'K[p]': K[v] := 'K[v]': |
assume( J[eq]>0, R[m]>0, eta[g]>0, K[g]>0, eta[m]>0, K[p]>0, omega[n]>0 );
> | solns := [ solve( EQ_KP, omega[n] ) ]; |
however:
> | omega[n] := solns[1]; |
> | zeta := solve( EQ_KV, zeta ); |
> |
and
Standard Calculations for a Second-Order System
Determine the general formula to calculate the gains
and
of a PV controller from the system standard open loop transfer function
.
unassign variables
> | G[c] := 'G[c]': H := 'H': K[p] := 'K[p]': K[v] := 'K[v]': omega[n] := 'omega[n]': zeta := 'zeta': |
Standard form of the system transfer function
> | G[std] := 'G[num0] / ( G[den2] * s^2 + G[den1] * s + G[den0] )'; |
Controller TF in the forward loop
> | G[c] := 'K[p]'; |
Feedback loop equivalent block (through block reduction)
> | H := 'K[v] / K[p] * s +1'; |
Closed Loop Transfer Function (standard form):
> | T[pv_std] := G[c] * G[std] / ( 1 + G[c] * G[std] * H ); |
> | T[pv_std] := simplify( T[pv_std] ); |
> | char_eqn[pv_std] := collect( denom( T[pv_std] ), s ); |
normalize the characteristic equation
> | char_eqn[pv_std] := collect( char_eqn[pv_std] / coeff( char_eqn[pv_std], s^2 ), s ); |
> | ID_EQ_STD := char_eqn[pv_std] = char_eqn[std]; |
solving Eq. ID_EQ_STD by identification
> | EQ_KP_STD := coeff( rhs( ID_EQ_STD ), s, 0 ) = coeff( lhs( ID_EQ_STD ), s, 0 ): |
> | K[p] := solve( EQ_KP_STD, K[p] ); |
> | EQ_KV_STD := coeff( rhs( ID_EQ_STD ), s, 1 ) = coeff( lhs( ID_EQ_STD ), s, 1 ): |
> | K[v] := solve( EQ_KV_STD, K[v] ); |
and
Standard Calculations for a Second-Order System
unassign variables
> | K[p] := 'K[p]': K[v] := 'K[v]': omega[n] := 'omega[n]': zeta := 'zeta': |
> | solns := { solve( EQ_KP_STD, omega[n] ) }; |
assuming:
> | omega[n] := solns[1]; |
> | zeta := solve( EQ_KV_STD, zeta ); |
> |
DC Motor System Definition: State-Space Representation
Xdot_ss = A_ss . X_ss + B_ss . U_ss
Y_ss = C_ss . X_ss + D_ss . U_ss
Y_ss = output vector; U_ss = input vector; X_ss = state vector
unassign variables
> | Theta[1] := 'Theta[1]': theta[1] := 'theta[1]': I[1] := 'I[1]': |
Standard State-Space Representation
Standard Laplace Transfer Function
> | TF_EQ_S := G[std] = Theta[1] / I[1]; |
> | TF_EQ_S := I[1] = solve( TF_EQ_S, I[1] ); |
initial conditions are null
> | TF_EQ_T := I[1] = subs( IC, invlaplace( rhs( TF_EQ_S ), s, t ) ); |
> | TF_EQ_T := diff( theta[1](t), t$2 ) = expand( solve( TF_EQ_T, diff( theta[1](t), t$2 ) ) ); |
state vector
> | X_ss := matrix( 2, 1 ): |
> | X_ss[1,1] := theta[1](t): X_ss[2,1] := diff( theta[1](t), t): |
> | 'X_ss' = evalm( X_ss ); |
> | Xdot_ss := map( diff, X_ss, t ); |
> | U_ss := I[1]; |
according to Eq. TF_EQ_T
> | A_ss := matrix( [ [0, 1], [- G[den0] / G[den2], - G[den1] / G[den2]] ] ); |
> | B_ss := matrix( [ [0], [G[num0] / G[den2]] ] ); |
> | C_ss := Matrix( 2, 2, shape=identity ); D_ss := array( [ [0], [0] ] ); |
> | Y_ss = evalm( C_ss &* X_ss + D_ss * U_ss ); |
> |
DC Motor State-Space Representation
> | G_num0 := numer( G[j1] ): |
> | denom( G[j1] ): |
> | G_den2 := coeff( denom( G[j1] ), s^2 ): |
> | G_den1 := coeff( denom( G[j1] ), s ): |
> | G_den0 := coeff( denom( G[j1] ), s, 0 ): |
> | std_subs := { G[num0] = G_num0, G[den2] = G_den2, G[den1] = G_den1, G[den0] = G_den0 }: |
> | A_J1 := matrix( 2, 2 ): |
> | for i from 1 to 2 do for k from 1 to 2 do A_J1[i,k] := subs( std_subs, A_ss[i,k] ); end do: end do: |
> | 'A_J1' = evalm( A_J1 ); |
> | B_J1 := matrix( [ [0], [subs( std_subs, B_ss[2,1] )] ] ); |
> | C_SRV02 := C_ss; |
> | D_SRV02:= evalm( D_ss ); |
> |