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:27] – [LQR for the gains] 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 88: | Line 88: | ||
===== LQR for the gains ===== | ===== LQR for the gains ===== | ||
==== Matlab Code ==== | ==== Matlab Code ==== | ||
- | < | + | < |
clear, clc, close all | clear, clc, close all | ||
Line 101: | Line 101: | ||
kb=0.26; | kb=0.26; | ||
- | Am=[0 0 1 0; | + | A=[0 0 1 0; |
0 0 0 1; | 0 0 0 1; | ||
0 mp*r*g/Ja -kt*kb/Ja/R 0; | 0 mp*r*g/Ja -kt*kb/Ja/R 0; | ||
0 -(mp*r^2 + Ja)*g/Ja/L -kt*kb*r/ | 0 -(mp*r^2 + Ja)*g/Ja/L -kt*kb*r/ | ||
- | Bm=[0; 0; kt/Ja/R; kt*r/ | + | B=[0; 0; kt/Ja/R; kt*r/ |
q1 = 50; %Weight on motor position | q1 = 50; %Weight on motor position | ||
Line 117: | Line 117: | ||
R = 1; | R = 1; | ||
- | K = -lqr(Am,Bm,Q,R); | + | K = -lqr(A,B,Q,R); |
+ | display(K); | ||
+ | </ | ||
+ | < | ||
+ | K = | ||
- | Gm_p=K(1, | + | |
- | Gp_p=K(1, | + | |
- | Gm_v=K(1, | + | |
- | Gp_v=K(1, | + | |
</ | </ | ||
+ | |||
+ | ===== 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.1495232867.txt.gz · Last modified: 2017/05/19 15:27 by sangsinpark