lego_rip
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
lego_rip [2017/05/19 15:13] – [LQR for gains determination] sangsinpark | lego_rip [2017/06/15 10:10] (current) – [NXC code for LEGO NXT Brick] sangsinpark | ||
---|---|---|---|
Line 8: | Line 8: | ||
**Date:** Last modified on 05/19/2017 | **Date:** Last modified on 05/19/2017 | ||
\\ | \\ | ||
- | **Keywords: | + | **Keywords: |
\\ | \\ | ||
Line 36: | Line 36: | ||
{{ lego_rip_v2: | {{ lego_rip_v2: | ||
\\ | \\ | ||
- | * HW. Derive the kinetic energy. | + | |
And the potential energy of the system is | And the potential energy of the system is | ||
{{ lego_rip_v2: | {{ lego_rip_v2: | ||
Line 53: | Line 53: | ||
{{ lego_rip_v2: | {{ lego_rip_v2: | ||
\\ | \\ | ||
- | * HW. Linearize the above nonlinear equations by Taylor expansion. | + | |
For state-space representation, | For state-space representation, | ||
{{ lego_rip_v2: | {{ lego_rip_v2: | ||
Line 70: | Line 70: | ||
{{ lego_rip_v2: | {{ lego_rip_v2: | ||
\\ | \\ | ||
+ | * **HW.** Derive a transfer function assuming that an output, y, is a α. | ||
===== Full state feedback control ===== | ===== Full state feedback control ===== | ||
Line 87: | Line 87: | ||
===== LQR for the gains ===== | ===== LQR for the gains ===== | ||
+ | ==== Matlab Code ==== | ||
+ | <code java> | ||
+ | clear, clc, close all | ||
+ | |||
+ | mp=((2*0.36335)+(2*1.33192)+0.56)/ | ||
+ | r=140/1000; %Arm Length | ||
+ | L=209/1000; %Pendulum Length | ||
+ | g=9.81; | ||
+ | ma=(0.66556+1.33192)/ | ||
+ | Ja=(1/ | ||
+ | R=9.05; | ||
+ | kt=0.26; | ||
+ | kb=0.26; | ||
+ | |||
+ | A=[0 0 1 0; | ||
+ | 0 0 0 1; | ||
+ | 0 mp*r*g/Ja -kt*kb/Ja/R 0; | ||
+ | 0 -(mp*r^2 + Ja)*g/Ja/L -kt*kb*r/ | ||
+ | |||
+ | B=[0; 0; kt/Ja/R; kt*r/ | ||
+ | |||
+ | q1 = 50; %Weight on motor position | ||
+ | q2 = 50; | ||
+ | q3 = 50; %weight on motor velocity | ||
+ | q4 = 300; | ||
+ | |||
+ | Q = diag([q1 q2 q3 q4]); | ||
+ | |||
+ | R = 1; | ||
+ | |||
+ | K = -lqr(A, | ||
+ | display(K); | ||
+ | </ | ||
+ | < | ||
+ | K = | ||
+ | |||
+ | | ||
+ | </ | ||
+ | |||
+ | ===== NXC code for LEGO NXT Brick ===== | ||
+ | <code java> | ||
+ | #define MOTOR OUT_A | ||
+ | #define PNDLM OUT_C | ||
+ | #define FULL_SPEED 100 | ||
+ | #define D2R 0.0175 // converts degree to radian | ||
+ | #define R2D 57.2958 // converts radian to degree | ||
+ | |||
+ | long prev_tick = 0; | ||
+ | long prev_Mdeg = 0; | ||
+ | long prev_Pdeg = 0; | ||
+ | long Mdeg = 0; | ||
+ | long Pdeg = 0; | ||
+ | long M_diff = 0; | ||
+ | long P_diff = 0; | ||
+ | |||
+ | float dt = 0.0; | ||
+ | float GTime = 0.0; | ||
+ | float Mrad = 0.0; | ||
+ | float Prad = 0.0; | ||
+ | float d_Mrad = 0.0; | ||
+ | float d_Prad = 0.0; | ||
+ | float d_Mdeg = 0.0; | ||
+ | float d_Pdeg = 0.0; | ||
+ | float M_errSum = 0.0; | ||
+ | |||
+ | char controlU = 0; | ||
+ | |||
+ | bool flag_balanceControl = true; | ||
+ | |||
+ | byte fileHandle; | ||
+ | |||
+ | sub MotorPID(float refRad, float PGain, float IGain, float DGain) | ||
+ | { | ||
+ | float error = refRad - Mrad; | ||
+ | float U = PGain*error + IGain*M_errSum - DGain*d_Mrad; | ||
+ | |||
+ | if(U > FULL_SPEED) | ||
+ | { | ||
+ | controlU = FULL_SPEED; | ||
+ | } | ||
+ | else if(U < -FULL_SPEED) | ||
+ | { | ||
+ | controlU = -FULL_SPEED; | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | controlU = U; | ||
+ | } | ||
+ | |||
+ | | ||
+ | |||
+ | | ||
+ | } | ||
+ | |||
+ | sub MotorOpenLoop(float speed) | ||
+ | { | ||
+ | | ||
+ | { | ||
+ | controlU = FULL_SPEED; | ||
+ | } | ||
+ | else if(speed < -FULL_SPEED) | ||
+ | { | ||
+ | controlU = -FULL_SPEED; | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | controlU = speed; | ||
+ | } | ||
+ | |||
+ | | ||
+ | } | ||
+ | |||
+ | task ReadEncoder() | ||
+ | { | ||
+ | const int w = 4; | ||
+ | float M_mov[w] = {0.0,}; | ||
+ | float P_mov[w] = {0.0,}; | ||
+ | float sum_Mmov = 0.0; | ||
+ | float sum_Pmov = 0.0; | ||
+ | int cnt = 0; | ||
+ | |||
+ | | ||
+ | { | ||
+ | dt = (CurrentTick() - prev_tick)*0.001; | ||
+ | Mdeg = MotorRotationCount(MOTOR); | ||
+ | Pdeg = MotorRotationCount(PNDLM); | ||
+ | M_diff = Mdeg - prev_Mdeg; | ||
+ | P_diff = Pdeg - prev_Pdeg; | ||
+ | prev_Mdeg = Mdeg; | ||
+ | prev_Pdeg = Pdeg; | ||
+ | |||
+ | d_Mdeg = M_diff/dt; | ||
+ | d_Pdeg = P_diff/dt; | ||
+ | |||
+ | Mrad = Mdeg*D2R; | ||
+ | Prad = Pdeg*D2R; | ||
+ | |||
+ | d_Mrad = d_Mdeg*D2R; | ||
+ | d_Prad = d_Pdeg*D2R; | ||
+ | |||
+ | prev_tick = CurrentTick(); | ||
+ | GTime += dt; | ||
+ | |||
+ | Wait(MS_20); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | task BalanceControl() | ||
+ | { | ||
+ | // A physical motor rotation direction is reversed as a model' | ||
+ | float Gm_p = -(-7.07106781265702); | ||
+ | float Gp_p = -361.604865668371; | ||
+ | float Gm_v = -(-7.20613568524004); | ||
+ | float Gp_v = -9.15404034187486; | ||
+ | |||
+ | | ||
+ | |||
+ | | ||
+ | { | ||
+ | if(flag_balanceControl == true) | ||
+ | { | ||
+ | | ||
+ | } | ||
+ | Wait(MS_20); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | task Display() | ||
+ | { | ||
+ | | ||
+ | { | ||
+ | TextOut(0, LCD_LINE1, FormatNum(" | ||
+ | TextOut(0, LCD_LINE2, FormatNum(" | ||
+ | TextOut(0, LCD_LINE3, FormatNum(" | ||
+ | TextOut(0, LCD_LINE4, FormatNum(" | ||
+ | TextOut(0, LCD_LINE5, FormatNum(" | ||
+ | TextOut(0, LCD_LINE6, FormatNum(" | ||
+ | Wait(MS_200); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | task WriteData() | ||
+ | { | ||
+ | short bytesWritten; | ||
+ | | ||
+ | long cnt = 0; | ||
+ | |||
+ | | ||
+ | |||
+ | | ||
+ | { | ||
+ | ++cnt; | ||
+ | write = NumToStr(cnt); | ||
+ | write = StrCat(write, | ||
+ | WriteLnString(fileHandle, | ||
+ | Wait(MS_5); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | task main() | ||
+ | { | ||
+ | | ||
+ | |||
+ | | ||
+ | | ||
+ | // | ||
+ | // | ||
+ | // | ||
+ | } | ||
+ | </ | ||
lego_rip.1495232005.txt.gz · Last modified: 2017/05/19 15:13 by sangsinpark