728x90

1. 분할차분법

2. 보간 다항식의 오차

3. 뉴턴의 전향 차분 공식

4. 접촉 보간법

 

 

 

 

 

분할 차분표를 사용하는 이유

- 뉴턴 공식에 있는 모든 분할 차분을 간단하게 구할수 있기 때문

 

 

분할 차분법의 개념

- 서로다른 n+1개의 점 x0, x1, ... xn에 대해서 함수 f(x)와 함수 값이 같은 n차 이하의 다항식 P_n(x)가 다음과 같이 주어질때(뉴턴 형이라 부름)

- x 값에 따라 상수 항들을 순서대로 구할 수 있게 됨

 

 

중복된 계산식(예 : x1-x0)을 줄이기 위해, 분할 차분 기호 사용

 

 

분할 차분표의 일반화

- n차 분할 차분 공식을 이용하여 분할차분표라는 표를 제작

n차 분할 차분 공식

 

분할 차분표를 사용하면?

- 뉴턴 공식에 있는 모든 분할 차분을 간단한 방법으로 구할 수 있음

- 뉴턴 공식을 사용하여 P_n(x)를 구할 때, 분할 차분표의 각 열에서 처음 항들이 그 다항식의 계수가 됨

 

 

 

 

보간 다항식 오차의 발생 원인

- 실제 함수를 알수없는 상황에서 임의의 점에 대한 값을 얻기 위해 사용하는 보간 다항식은 실제 함수와 달라 오차 발생

 

보간 다항식의 오차

- f(x)가 폐구간 [a, b]에서 정의된 함수이고, x0, x1, ... xn을 구간에 있는 n + 1개의 서로 다른 점이라할때

- 차수 n보다 크지않은 다항식 P_n(x)를 점 x0, ... xn에서 f(x)의 보간 다항식이라 한다면

=> 오차 = 실제 함수 - 보간 다항식

 

- bar_x를 주어진 점 x0, x1, ... xn이 아닌 임의의 점이며

- 차수가 n+1보다 크지 않은 다항식 p_(n+1)(x)를 점 x0, x1, ..xn, bar_x 에서 f(x)의 보간 다항식이라 한다면

 

 

뉴턴 공식에 따라 아래와 같이 정리됨.

 

앞에서 나온 식을 통해 bar_x != x0, x1, ... xn 인 경우에 대해

-> 임의의 점 bar_x에 대한 보간 다항식 오차

=> f(bar_x)를 알아야 e_n(bar_x)를 구할 수 있음

 

 

f(bar_x)를 모르면 e_n(bar_x)를 구할수 없는가?

- 함수 f(x)가 구간 [a,b]에서 정의된 함수이고 (a, b)에서 k차 미분 가능하다고 할때, x0, .. xk가 [a,b] 안에 있는 (k+1)개의 서로 다른 점이라면

를 만족하는점 epsilon in (a, b) 가 존재한다.

 

 

 

보간 다항식의 오차 2

- 함수 f가 폐구간 [a, b]에 정의된 함수

- 개구간 (a, b)에서 (n+1)차 미분 가능

-> P_n(x) 차수가 n보다 크지 않고 [a, b] 안에 있는 n+1개의 점 x0, x1 ..., xn에 대해 f(x)의 보간 다항식이라 한다면 [a, b]안의 임의의 점 bar_x에 대해

 

=> epsilon in (a,b) 가 존재

 

 

epsilon은 bar_x에 따라 결정되고 공식을 사용하려면?

- epsilon과 f(x)의 (n+1)차 도함수 f^(n+1) (x)를 일아야함

- epsilon은 구간 (a, b)안에 있는 어떤 점이라는 사실만 알고 실제로는 정확한 epsilon을 알 수 없음.

- f^(n+1) (x)도 모르는 경우가 많음

=> [a, b]에서 |f^(n+1) (x)|의 상계 (upper bound)를 알면 보간 다항식 오차의 한계를 구할 수 있음.

 

 

 

 

 

 

 

 

뉴턴의 전향 차분 공식

- [a, b] 안의 점 x0, ... xn에서 함수 f(x)의 보간 다항식 Pn(x)

- 분할 차분 f([x0, ..., xn]을 계싼하고 뉴턴 공식 사용

- 소구간들의 길이가 같은 경우 분할 차분보다 더 간단한 전향 차분을 사용하여 보간 다항식 P_n(x)를 구하는 방법

=> 점 a = x0 < x1 < x2 ... < xn = b에 의해 만들어 지는 각 소구간의 길이가 같다고 가정

=> 구간 [a, b]를 N등분 하고 h= (b-a)/N으로 놓으면?

 

 

각 점에서 함수 값을 안다고 가정하면

 

 

[a, b]에 있는 임의의 점 x를 x0 + sh로 나타낼수 있으므로

 

 

- 선형 변수 변환 공식을 사용하여, 차수가 n인 x의 다항식 -> 차수 n인 s의 다항식

 

 

 

전향 차분은 다음과 같이 정의

 

전향 차분과 분할 차분의 관계

 

 

P_n(x)를 점 x_k, x_k+1, ..., x_(k+n)에서 f(x)의 보간 다항식 이라면

위 식을 뉴턴 공식에 대입하면

 

 

 

 

아래의 식에 따라

 

 

보간다항식은 다음과 같이 정리가 된다.

 

 

이항 함수 binomial function을 이용

- 임의의 실수 y와 임의의 정수 i >= 0 에 대해 이항함수 (y; i)를 다음과 같이 정의

=> y가 양의 정수면 (y; i)는 이항 계수 binomial coefficient가 됨

 

 

뉴턴의 전향 차분 공식

- 점 x_k + i h (i = 0, 1, ..., n)에서 f(x)의 보간 다항식에 대한 뉴턴의 전향 차분 공식 (Forward difference formula)라 부름.

 

 

 

뉴턴의 전향 차분 공식 예시

- k = 0인경우, 보간 점을 x_0, x_1, ..., x_n일 때

- 위 식의 계수는 전향 차분표로 쉽게 구할 수 있음

 

 

function y = NewtonDiff(xd, yd, x)

  nd = length(xd);
  F = zeros(nd, nd);
  F(:, 1) = yd(:);

  for j = 2:nd
      for i= 1:nd-j+1
			F(i,j) = (F(i+1, j-1) - F(i, j-1))/(xd(i+j-1)-xd(i));
      end
  end


  y = F(1, 1);
  ytemp = 1;

  for j=2:nd
      ytemp = ytemp*(x - xd(j-1));
      y = y + F(1, j)*ytemp;
  end

end
x = [2 3 4 5 6];
y =[4.8 9.4 19.2 36.6 58];

NewtonDiff(x, y, 2.5)

 

 

 

 

 

접촉 보간

- 앞에서 보간 다항식을 구할 떄 구간 [a, b]안에 있는 점 x0, x1, x2 , .. xn이 서로 다른 경우에만 고려

- 점들이 서로 다른점이라 가정하지 않고 보간 다항식을 구하는 방법

- 점 x0, ... xk가 구간 [a, b]에서 서로 다른 점일때 -> f(x)의 k차 분할 차분 f[x0, .. xk]를 차수가 k보다 크지않은 보간 다항식 p_k(x)의 최고차 계수 (x^k의 계수) 계수로 정의

 

 

서로 같은 점들이 있는 경우 P_k(x_i) = f(x_i)의 의미

- 점 x0, ..., xk 중 m번째 나타나는 점 x - f^(j) (x) = g^(j) (x) => j = 0, 1, ..., m-1

- f(x), g(x)는 점 x0, x1, ... xk에서 같다고 정의 

=> 보간 다항식이 한 점 c에서 f(x)와 (m+1)번 접촉(m번 같을 때) 접촉 보간

 

 

 

스플라인

- 매끄러운 곡선을 그리기위해 제도하는 도구에서 유래

- 급격하게 변하는 데이터를 나타내는데 적합한 방법

- 두 점 사이의 각 구간에 대해 스플라인으로 불리는 낮은 차수의 다항식을 이용하여 점들을 연결

 

 

 

 

 

 

 

 

 

 

 

 

300x250
728x90

1. 보간 법

2. 다항식에 의한 보간법

 

 

보간법의 정의

- 아직 측정하지 않거나 할수 없는 값을 구해야하는 경우 사용

-> 존재하지 않는 데이터를 만들어내는 방법

 

 

보간법에 사용되는 함수

- 다항식 : 2개이상의 단항식을 대수의 합으로 연결한 식

 

선형 보간법

- 보간 법 중가장 간단

- 주어진 두 점을 이은 직선의 방정식을 근사 함수로 사용하는 방법

 

선형 보간법 정의

- 함수 f(x)가 폐구간 [a, b]위에 정의되고, 이 구간에 있는 n개의 점 x1, x2, ..., xn에 대해 알면

- (xi, f(xi)) , (xi+1 , f(x+1)) 을 지나는 직선의 방정식

 

선형 보간법 사용법

1. 두개의 점이 주어진 경우

 - 두점을 지나는 함수 f(x)를 직전의 방정식으로 구함

2. p(x) = a0 + a1x가 직선의 방정식인 경우

 

- 데이터 점 들 사이 간격이 작을수록 더 좋은 근사값을 얻게 됨

 -> 간격이 감소함으로써 연속 함수를 직선으로 근사시키기가 좋기 때문

 

 

자연 로그 ln 2를 계산하기

- ln 1 = 0과 ln 6 = 1.7917595 사이에서 다음과 같이 계산

 

- ln 1 = 0 과 ln 4 = 1.3862944 사이에서(점 사이 간격이 작은 경우) 다음과 같이 계산

 

- ln 2의 참 값 : 0.69314718

 

Matlab에서 선형 보간법 사용하기

clc;
clear all;

x = [40 48 56 64 72 80];                  % x 데이터 입력
y = [1.33 1.67 2.08   2.36 2.71 3.19];    % y 데이터 입력
plot(x, y, 'o-')    % 그래프 그려줌
interp1(x, y, 52)   % x값이 52일 때 y에 해당하는 값을 구함

 

 

다항식을 찾기 위한 보간 방법

- 미정 계수법, 라그랑주 보간법, 뉴턴 보간법 등

 

 

다항식에 의한 보간법

- (n+1) 개의 점을 지나는 다항식은 n차 이하의 유일한 다항식으로 표시 가능

 

다항식을 찾아내는 방법

- 미정 계수법

- 라그랑주 보간법

- 뉴턴 보간법

 

 

미정 계수법

- 다항식을 찾아내는 가장 보편적인 방법

- 아래의 보간 다항식이 주어지면

- 위 식을 아래와 같은 행렬로 표현 가능

 

-> 가우스 소거법 등으로 계산하여 a0, a1, ... an을 구하면 됨

 

 

 

가우스 소거법

- n 개의 방정식과 n 개의 미지수로 이루어진 일반적인 선형 연립방정식 Ax = b의 해를 구하는 방법

- 그러나 계산시간이 많이 걸리며 오차가 많이 발생

-> 보간 다항식을 다르게 표현하여 계산 과정을 줄여야함

 

오차를 작게 하는 방법

- 라그랑주 보간법

- 뉴턴 보간법

 

 

 

 

라그랑주 보간법

- 여러 개의 점들을 지나는 곡선으로 연결하는 방법

1. 여러개의 점들이 주어짐

2. 이 점들을 지나는 다항식 구함

3. 이 다항식으로 주어진 점에 대한 보간 값을 구함

 

 

 

- 서로 다른 두점 (x0, y0), (x1, y1)을 지나는 다항식은 많으나 그 중 1차 다항식(직선) y = ax + b, 하나만 존재

- 세 점 (x0, y0), (x1, y1), (x2, y2)를 지나는 2차 다항식 y = ax^2 + bx + c도 단 하나만 존재

-> n + 1개의 점 (xi, yi)를 지나는 n차 다항식

 

- 다항식 g(x)에 (n+1)개의 점들을 대입하여 다음 n+1개의 연립 방정식을 구할 수 있음.

 

연립 방정식을 풀면

- 계수 a0, a1, ..., an을 구할 수 있음

- 다항식 g(x)를 구하여 다른값 x값에 대한 보간 값을 구하는데 사용 가능

=> 라그랑주 보간법은 연립방정식을 풀지 않고 다항식을 결정할 수 있어 정확성을 높일 수 있음

 

 

 

서로 다른 xi, i = 0, 1, ..., n에서 n + 1개의 점 (xi, f(xi))를 지나는 n차 보간 다항식은?

 

여기서 L_i(x)는 다음과 같음

 

 

두 점 (s,1), (t, 0)을 지나는 일차 다항식은 L(x) = (x-t)/(s-t)로 표현 가능

- L_0(x)는 (x0, 1), (x1, 0)을, L_1(x)는 (x0, 0), (x1, 1)을 지나는 1차 다항식은 다음과 같음

1차 라그랑주 다항식

 

두 점 (x0, y0), (x1, y1)을 지나는 1차 다항식

1차 라그랑주 보간 다항식

 

라그랑주 보간 다항식의 일반화

- P_n(x_i) = y_i 를 만족하므로 n + 1개의 점 (x_i, y_i)를 지나는 유일한 n차 다항식

 

 

 

라그랑주 보간법의 문제점

- 차수가 커지면 참값을 기대할 수 없을 정도로 큰 오차가 발생(runge 현상)

-> 차수가 낮은 경우에만 사용

 

 

뉴턴 보간법 필요성

- 라그랑주 보간법의 문제를 보완한 보간법

- 하나의 보간을 위해 필요한 계산량이 필요

- 데이터 수 증가시 바로 직전 결과를 사용하지 못함

-> 에러 계산이 용이하지 않은 문제점을 해결함

 

 

뉴턴 보간법

- 기존 데이터를 기초로 차분표 구성

- 차분표로 보간 공식을 구함

- 새로운 데이터가 추가되어도 그 차수를 늘리기 쉬움

- 라그랑주 보간 다항식과 형태만 다르나 같은 다항식

-> 한점이 추가되는 경우 : 라그랑주 보간 다항식은 처음부터 다시 구해야함. 뉴턴 보간법은 이전 보간 다항식을 유지하고 마지막 계수만 다시 추가

 

1차 다항식 y = ax + b의 경우

- y= a_0 + a_1(x-x_0)로 표현

 

서로 다른 (n+1)개의 점 x_0, ..., x_n에 대해 f(x)와 함수값이 같은 n차 이하 다항식 P_n(x)는 다음과 같음

 

점 (x_0, y_0), (x_1, y_1), (x_2,y_2)를 지나는 다항식은?

 

 

계수 a_0, a_1, a_2를 구하기 위해 P_2(x_0) = y_0, p_2(x_1) = y_1, p_2(x_2) = y_2 이므로 다항식에 대입하면

 

 

 

분할 차분 기호 [ ] 를 이용하여 P_n(x)를 다시 표현하면 ...

뉴턴의 분할 차분 보간 다항식

 

 

보간 다항식의 존재와 유일성 1

- 연속 함수 중 하나가 다항식이고, 이 다항식은 수치해석 거의 모든 분야에서 함수들의 근사값을 구하는데 사용

- 보간법 -> 근사함수로서 다항식을 사용 => 보간 다항식

 

보간 다항식의 존재와 유일성 2

- x0, x1, x2, ... , x0을 구간 [a,b]안에 있는 (n+1)개의 서로 다른 점이라 할 때,

- f(x)가 [a, b]위에서 정의된 함수이고, 각 점에서 함수 값을 알때,

- 주어진 (n+1)개의 점에서 함수 값과 같게되는 차수가 n보다 크지 않는 보간 다항식을 구할 때,

=> 이 조건들을 만족하는 보간 다항식 p(x)는 단 1개만 존재

 

 

다음 데이터가 주어질때 라그랑주 보간다항식을 이용하여 x가 2.5, 3.5일때 y 값을 구하라

 

 

function y = Lagrange(xd, yd, x)

nd = length(xd);
y = 0;
for i=1:nd
	p=1;
    for j=1:nd
    	if(i~=j)
        	p=p*(x-xd(j))/(xd(i)-xd(j));
        end
     end
     y = y+p*yd(i);
end

 

xd=[2 3 45 6];
yd=[4.8 9.4 19.2 36.6 58];

Lagrange(xd, yd, 2.5)

Lagrange(xd, yd, 3.5)

 

 

 

 

300x250
728x90

수의 표기법

- 명수법과 기수법

 

진법

- 2진법, 8진법, 10진법, 16진법

 

수의 표기법

- 명수법 : 하나, 둘, 셋 처럼 수를 말로 나타내는것

- 기수법 : 1, 2, 3 과같이 수를 기호로 나타내는것 -> 10진법, 2진법, 5진법, 12진법 등 존재

 

 

소수점 표시법에 따라 오차가 발생하는 이유

- 컴퓨터에서는 모든 소수를 정규형태로 변환시켜 처리하기 때문. 무한한 소수의 뒷자리를 없앰

 

 

컴퓨터 기억장치나 연산장치는 양(+), 음(-)만을 구별할수있는 비트들로 구성

- >컴퓨터는 2진법 사용

 

컴퓨터에서 수를 표현할 때

- 정수 : 고정 소수점 표시법

- 실수 : 부동 소수점 표시법

 

고정 소수점 표시법

- 소수점을 항상 일정한 위치에 놓는 표시법

- 소수점 위치를 그 수 제일 오른쪽에 있다고 가정하여 정수 계선에서만 사용

 

부동 소수점 표시법

- 소수점 위치를 일정하게 하지 않고 따로 지시해주는 표시법

- 실수 계산에서 주로 이방법 사용

- 32비트를 한단어로 사용하는 경우 -> 0비트는 부호, 1~7비트는 지수, 8 ~31비트는 가수를 나타냄

 

 

정규형태

- 컴퓨터에서 실수를 기억시킬때는 가수부의 제일 높은 자리에 0 이외의 유효숫자가 올때까지 지수값을 변환시켜 기억함

- 이렇게 표시된 수를 정규형태라함.

- 컴퓨터는 모든 숫자를 반드시 정규형태로 처리

- 단정도 표현 : 32비트를 한단어로 사용 -> 가수부 7자리 정도의 10진수를 기억

- 배정도 표현 : 64비트를 한 단어로 사용 -> 가수부에 16자리 정도 10진수를 기억시킴

 

전환 오차

- 컴퓨터에 입력하거나 출력하는 과정에서 생기는 오차

 

 

컴퓨터 프로그래밍 하는 경우 

- 실수를 입력한 다음 그 결과를 출력할 때 값이 변하는 경우가 존재

ex) (단정도 표현) 0.23456789 -> 0.23456790

=> 단정도 표현과 배정도 표현 모두에서 오차 발생 가능

- 일반적으로 배정도 표현에서 오차가 더 적음

 

 

 

(387.620000)_10 가 컴퓨터에 입력되고 출력되는 과정

- 컴퓨터는 387.62를 16 진수로 바꿈

 -> (387.620000)_10

  = (183.9EB851EB851)_16

- 정규 형태로 표시하면

    (0.1839EB851EB851...)x16^3

* 컴퓨터가 16진법 컴퓨터라 가정하면 6자리 미만은 버리게 됨

 -> (0.1839EB) x 16^3

 -> 입력되는 수 387.62는 183.9EB_16로 저장

* 출력하게 되면 10진수로 다시 고쳐서 내보냄

 - 183.9EB_16 = 387.6198730_10

-> 이 과정에서 오차 387.60000 - 387.61987 = 0.00013이 발생

-> 이때 상대 오차는 0.00013/387.61987 = 3.35 x 10^-7

 

 

 

버림과 반올림 과정에서 발생하는 오차는 왜 발생하는가

- 컴퓨터가 저장된 소수를 버림이나 반올림하기 위해 읽어올 때 소숫자리 보다 작은 가수를 취하여 읽는 경우

- 버려지는 값이 발생할수 있으므로 버림과 반올림에 의해 오차가 발생

 

 

버림과 반올림 과정에서 생기는 오차

23.4673

- 소수 3째 자리서 반올림 23.47

- 2째 자리 미만 버림 23.46

- 정규형태로 표현하면 0.234673 X 10^2

 

10진법 계산기가 4자리 가수부분만 취한다고 가정하는 경우 0.2346만 취하게 됨.

0.234673 x 10^2 = (0.2346 + 0.000073) x 10^2

                            = (0.2346 + [0.73 x 10^-4]) x 10^2

 

 

 

 

 

 

 

 

 

 

 

 

300x250
728x90

매트랩에서 생성 가능한 그래프

- 선형축 표준 그래프

- 3차원 윤곽 및 망 그래프

- 막대 그래프

- 계단 그래프

- 극좌표 그래프

- 로그 및 세미로그 축 그래프 등

 

그래프

- 정보 표현에 사용도는 유용한 도구

- 여러 유형을 생성하는데 사용할수 있는 많은 명령어가 존재

 

 

2차원 그래프

- 그래프 일련 번호

- 그래프 이름

- 마커

- 텍스트 레이블

- y축 레이블

- x축 레이블

- 범례

- 그래프 제목

 

 

 

x = [10:0.1:22];
y = 95000./x.^2;
xd = [10:2:22];
yd =[950 640 460 340 250 180 140];

plot(x, y, '-', 'LineWidth', 1.);
xlabel('\fontname{돋움} distance(cm)');
ylabel('\fontname{돋움} strength(lux');

axis([8 24 0 1200]);
title('\fontname{바탕} \bf distance function(strength of light)', 'FontSize', 14);
text(14,700, 'compare with theory and experiment','EdgeColor','r','LineWidth',2);
grid on, hold on;

plot(xd, yd, 'ro--', 'LineWidth', 1.0, 'MarkerSize', 10);
legend('theory', 'experiment');
set(gcf, 'Name', 'Fig.5-8') %set( ..., 'NumberTitle', 'off')
hold off

 

plot 명령어

- plot(x, y)

- 2그래프를 생성하는 명령어

- x, y 두벡터로 형성되는 순서쌍을 그래프 상에 점으로 나타내고 점들을 직선으로 연결

ex

x=[1 2 3 5 7 7.5 8 10];
y=[2 6.5 7 7 5.5 4 6 8];
plot(x, y)
grid on;

 

 

그래프 형식 지정

- 선 색이나 종류 등을 지정한다면

- plot 명령어 옵션으로 지정 가능

 

plot(x, y, 'line specifiers', 'propertyName', PropertyValue);

 

 

실습

clc;
clear all;

t = 0:0.4:2*pi;
plot(t, sin(t), '-rs', 'LineWidth', 2);
hold on;
plot(t, sin(t-pi/2), '--mo');
plot(t, sin(t-pi), ':b*');
hold off
axis tight

 

 

 

예제 풀기

y = x^2 + sin(x) 그래프 그리기. 선두께는 1, 빨간선, +- 마커

 

 

데이터를 직관적으로 보기위해 그래프를 만들려면?

1. 주어진 데이터로 행렬 생성

2. 생성한 행렬을 plot 명령어로 그림

 

 

1988 ~ 1994년 매출액 데이터로 그래프 그리기

 

clc;
clear all;

yr=[1988:1994];
sales=[8 12 20 22 18 24 27];
plot(yr,sales, '--r*','LineWidth',2, 'MarkerSize', 12);
grid on;

 

plot 명령어로 y=f(x) 그래프 그리기

1. 함수 정의역 x 벡터 생성

2. x로 f(x) 구하여 백터 y 생성

3. plot으로 작성

 

clc;
clear all;

x=[-2:0.3:4];
y=3.5.^(-0.5*x).*cos(6*x);
plot(x, y);
hold on;
x = [-2:0.01:4];
y=3.5.^(-0.5*x).*cos(6*x);
plot(x, y);
grid on;

 

 

fplot 명령어로 함수 그래프 그리기

fplot('function', limits, 'line specifiers')

- 'function ' : fplot 명령어 안에 문자열로 직접 입력 가능

clc;
clear all;


fplot('x^2+4*sin(2*x)-1',[-3, 3]);
grid on;

 

극좌표 그래프

- 평면상 한점의 위치를 각도 theta와 반경 r로 정의

polar(theta, radius, 'line specifiers');

clc;
clear all;

t = linspace(0, 2*pi, 200);
r = 3*cos(0.5*t).^2 + t
polar(t, r);

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

300x250
728x90

1차원 배열로 나타낼수 있는 것

- 어떤 수들의 집합

-> 연도별 인구 현황

 

 

 

배열이란?

- 매트랩이 데이터를 저장하고 다루기위한 기본 형태

- 행, 열로 정렬 된 수들의 나열

 

1차원 배열 예

- 3차원 공간의 한 점 : p(2,5,6)  -> [2 5 6] or [2, 5, 6]

 

배열 예시

- 어떤 수들의 집합도 배열로 표시 가능

year = [1984 1986 1988 1990 1992 1994 1996]

pop = [127 130 136 145 158 178 211];

-> 연도와 인구수를 벡터로 표시

 

 

 

1차원 배열 생성 방법

- 꺽은괄호 [] 안에 배열 원소 직접 입력

- 외부 데이터 파일로부터 행렬을 읽어드림

- 매트랩 명령이나 m파일로 행렬 생성

 

 

아는 수 집합을 행 벡터로 만들기

- 꺽은 괄호 [] 안에 원소들 기입. 원소와 원소는 공백이나 콤마로 구분

t = [5, 7, 2, 4, 10, 29];

 

 

열 백터 생성 방법

v = [3; 4; 5];

 

v = [3

4

5]

 

v = [3 4 5]'

 

 

 

일정 간격의 벡터 생성

변수명 = [m : q : n]

m : 첫번째 원소

q : 간격

n : 최대값

 

>> x =[1:2:8]

x = 1 3 5 7

 

>> x = 15:-3:8

x=15 12 9

 

 

 

 

2차원 배열 생성 방법

- 행렬이라 불림.

- 다수의 행과 열로 가짐

- 세미콜론이나 엔터로 새로운 행을 만듬

 

>> A = [2 4 10; 16; 3 7; 8 12 35]

A =

 2    4    10

 16  3    7

 8   12  35

 

 

다양한 배열 생성 방법

- 계산 가능한 수식이나, 변수도 가능

- linspace나 콜론으로도 가능

 

 

배열 명령어

- zeros(m, n) : m x n 크기의 0행렬

- ones(m,n) : m x n 크기의 1 행렬

- eye(n) : n 크기의 1 대각 행렬

 

 

전치 연산자

- 행벡터 -> 열백터

- 열백터 -> 행백터

- 행렬의 행과 열을 바꿈

 

 

 

배열 접근하기

- 행렬의 배열에서 하나나 여려 원소의 위치를 찾거나 접근 가능

 

>> v=[12 8 9 6 28]

>> v(1)

12

>> v(1)=30

30

 

 

300x250
728x90

수치해석 소개

- 공학 문제를 수식화하여 이에 대한 해를 수치적으로 구함

- 방정식, 행렬연산, 회귀분석, 미적분 등 수치적 알고리즘 이해

- MATLAB 활용 방법 학습

 

=> 수치해석 알고리즘 이해 및 응용

-> MATLAB 활용능력 향상

 

목적

- 공학 분야 연구, 개발에는 계산기를 이용하여 설계나 수치 시뮬레이션 작업이 많음.

- 수치해석의 영역은 폭이 넓고 동일한 문제에 대해서도 수많은 알고리즘이 있다.

- 기초적인 수치해석법 및 실제로 자주 이용되는 수치해석 알고리즘 학습

 

목표

- 공학문제 수식화하여 해를 수치적으로 구함

- 비선형 방정식, 행렬연산, 회귀분석, 미적분 수치알고리즘 이해

 

 

1. 수치 해석의 역사와 특징

2. 매트랩 개요

 

 

 

수치해석

- 해석학 문제에서 수치적인 근사값을 구하는 알고리즘 연구하는 학문

- 수학적 문제로 표현할수있는 문제들을 컴퓨터로 해결하는 수학 응용분야에 사용

 

 

수치해석

- 해석학 문제에서 수치적인 근사값을 구하는 알고리즘을 연구하는 학문

-> 연속 수학 문제를 해결하기 위한 알고리즘을 연구하는 학문

- 자연과학, 공학, 의학 등 문제들 중 수학적인 문제로 표현될수 있는 문제들을 컴퓨터로 해결하는 학문

 

 

공학적 문제의 접근 방법

1. 실험적 방법

- 실험이나 관찰을 통해 수집한 데이터를 분석하여 인과관계를 규명하는 방법

- 장점 : 신뢰성 높음

- 단점 : 실험 비용, 측정 오차 문제가 발생

 

2. 이론적 방법

- 문제에 대한 가설을 세우고 수학적 증면으로 인과관계를 규명하는 방법

- 장점 : 일반화된 정보를 제공

- 단점 : 보통의 경우 선형 문제에만 국한됨

 

3. 수치해석적 방법

- 주어진 공학적 문제에 해일것으로 추정되는 수치를 차례로 대입하여 가장 작은 오차를 가진 수치를 해라고 판단하는 방법

- 장점 : 복잡한 물리현상도 취급, 선형성과 무관, 실험적 방법보다 간단

- 단점 : 반복 계산의 부담이 존재함.

 

 

 

 

수치 해석의 시작

- 가장 오래된 수치해석은 바빌로니아 사람들이 점토판에 60진법으로 단위길이 사각형의 대각선 길이인 sqrt(2)의 수치적 근사값을 구해놓음

- sqrt(2)의 근사값이 60진법으로 소수점 이하 4자리 까지 계산되어있음

=> 현대의 수치해석도 정확한 해를 구하지 못함. 합리적 수준의 오차를 갖는 근사값을 구하는것이 중요해짐

 

 

 

 

수치해석

- 폰 노이만 이래 현대 컴퓨터의 태동과 발전의 직접적인 견인차 역활

-> 실생활, 국방, 자연현상 등 수치해석은 예측결과를 컴퓨터를 통해 미리알아볼수 있게 함.

 

 

현대 수치해석의 목표

- 현대의 수치해석 역시 정확한 해를 구하지 못하여 하지 않음

-> 합리적인 정도의 오차를 갖는 근사값을 구하는것에 집중함

 

 

 

수치 해석의 응용 분야

1. 공학과 물리학

2. 생명 공학, 예술 분야

-> 상미분 방정식 : 행성들의 움직임과 포트폴리오 관리의 최적화 등에 이용

-> 마르코브 연쇄 : 의약과 생명분야에서 살아있는 세포에 대한 시뮬레이션을 하기 위한 필수 항목으로 자리잡음

 

 

 

 

수치해석 문제 해결 방법

1. 수학적 모형화

 - 해결하고자 하는 문제를 역학, 생물학, 경제학 등 기본 가설이나 법칙들 사용

 - 상/편 미분방정식, 대수 방정식 등의 수학적인 문제로 변형하는 단계

2. 수학적 분석

 - 수학적 모형화 과정을 거쳐 생성된 수학적 문제를 미분방정식, 함수해석학, 기하학 및 대수학 등 가능한 수학 이론들 적용

 - 해의 유일성, 존재성 및 정칙성 등 분석하는 단계

3. 수치적 분석

 - 좁은 의미의 수치해석

 - 수학적 분석에서 다루어진 문제의 해가 존재하면, 이 해를 어떻게 컴퓨터로 구할것인가 수치적 알고리즘 개발

 - 이 알고리즘을 적용하여 이 알고리즘을 적용하여 구한 해의 수렴 성 판정 및 오차 분석 등 하는 단계

4. 수치 실험

 - 실제로 가장 효율적인 수치 알고리즘에 따라 프로그램을 작성하여 원래 문제를 해결하는 단계

 

 

 

 

매트랩 개요

 

매트랩이란?

- 수치해석 분야에 편리한 도구

- 수치해석, 행렬연산, 신호처리 및 간단한 그래픽 기능 통합

- 고성능 수치 계산 및 결과의 시각화 기능 제공

 

 

매트랩

- 수치해석에 편리한도구

- 문법이 간단 : 변수 데이터 타입 지정안해도됨

- 배열 사용이 간단 : 크기 지정안해도됨

- 행렬계산에서 병렬처리가능

- 계싼결과 즉시 확인 가능 : 그래프, 3차원 도형 등

- MATrix LABoratory

- 수치해석, 행렬 연산, 신호 처리 및 간단한 그래픽 기능등을 통합하여 고성능 수치계싼 및 결과의 시각화 기능 제공하는 프로그램

 

 

매트랩 특징

- 인터프리터 방식 언어

- 수학 계싼 및 가시화에 편리

- 선형대수, 데이터 분석, 신호처리, 수치적분 등 많은 과학 계산용 내장함수를 제공

- 사용자에 의한 함수 작성 편리

- 다양한 분야의 광범위한 툴방스 제공

 

 

문제

 

 

 

 

 

 

 

 

 

 

300x250
728x90

 

 이번 장에서는 연속 폐루프를 이용해서 횡방향과 종방향 오토파일럿을 설계하였습니다. 횡방향 오토파일럿은 내부 루프로 롤 자세 유지 루프를 외부 루프로 방위각 유지 루프로 이루어집니다.

 

 종방향 오토파일럿은 고도에 따라 더 복잡하게 구성되는데 피치 자세 유지 루프는 모든 영역에서 사용됩니다. 이륙 영역에서는 비행체는 풀 스로틀 상태가 되며 이륙 피치각을 고정하도록 제어하게 됩니다. 상승 영역에서는 비행체는 풀 스로틀로, 피치, 대기 속도 유지 오토 파일럿 루프로 대기속도를 제어합니다. 하강 영역에서는 상승 영역과 비슷한데 대신 비행체에는 최소 스로틀을 줍니다. 고도 유지 영역에서 고도는 피치를 이용한 고도 오토파일럿 루프로 제어되고, 대기속도는 스로틀을 이용한 대기속도 오토파일럿 루프로 제어됩니다.

 

횡방향 오토파일럿 설계 과정 요약

입력

 - 전달함수 계수 $a_{phi_1}$, $a_{phi_2}$, 명목 대기속도 $V_a$, 에일러론 제한 $\delta_{a}^{max}$

 

튜닝 파라미터

 - 롤 각 제한 $\phi^{max}$, 댐핑 계수 $\zeta_{\phi}$, $\zeta_{\chi}$

 

계산할 고유 주파수

 - 식 (6.8)로 내부 루프의 고유주파수 $\omega_{n_{\phi}}$와 $\omega_{n_{\chi}}$ = $\omega_{n_{\phi}}$ / $W_{\chi}$를 사용해서 외부 루프의 고유 주파수를 계산해야 합니다.

 

계산할 게인

 - 식 (6.7), (6.9), (6.12), (6.13)으로 게인 $k_{p_{\phi}}$, $k_{d_{\phi}}$, $k_{p_{\chi}}$, $k_{i_{\chi}}$을 계산합니다.

 

 

종방향 오토파일럿 설계 과정 요약

입력

 - 전달함수 계수 $a_{\theta_{1}}$, $a_{\theta_{2}}$, $a_{\theta_{3}}$, $a_{V_{1}}$, 명목 대기속도 $V_a$, 엘리베이터 제한 $\delta_{e}^{max}$

 

튜닝 파라미터

 - 피치 각 제한 $e_{\theta}^{max}$, 댐핑 계수 $\zeta_{\theta}$, $\zeta_{h}$, $\zeta_{V}$, $\zeta_{V2}$와 고유 주파수 $\omega_{n_{v}}$, 고도 루프와 피치 이용 대기속도 루프의 분할 주파수  $W_h$, $W_{V_2}$ 

 

계산 고유 주파수들

- 식 (6.21)로 피치 루프 $\omega_{n_{\theta}}$ 고유 주파수 계산. $\omega_{n_{h}}$ = $\omega_{n_{\theta}}$ / $W_h$를 사용하여 고도 루프, $\omega_{n_{V2}}$ = $\omega_{n_{\theta}}$ / $W_{V_2}$를 사용하여 피치 이용 대기속도 루프의 고유 주파수 계산. 

 

계산 게인

- 식 6.22로 게인 $k_{p_{\theta}}$와 $k_{d_{\theta}}$를 계산하고, 식 6.23으로 피치 루프의 DC 게인을 구합니다. 식 6.25와 6.24로 $k_{p_{h}}$, $k_{i_{h}}$를계산하며,식6.28과6.27로 $k_{p v_{2}}$, $k_{i v_{2}}$를 구하고, 식 6.30, 6.29로 $k_{p_v}$, $k_{i_v}$를 구합니다.

 

300x250
728x90

5.2 mavsim_trim.slx복붙하고 동작하도록 파일 수정해라

 

 

% compute trim conditions using 'mavsim_chap5_trim.slx'
% nominal airspeed P.Va0 specified above with aircraft parameters
gamma = 0*pi/180;  % desired flight path angle (radians)
R     = 10000000000;        % desired radius (m) - use (+) for right handed orbit, 
                            %                          (-) for left handed orbit
Va = 25;


% set initial conditions 
x0 = [];
% specify which states to hold equal to the initial conditions
ix = [];

% specify initial inputs 
u0 = [...
    0;... % 1 - delta_e
    0;... % 2 - delta_a
    0;... % 3 - delta_r
    1;... % 4 - delta_t
    ];
% specify which inputs to hold constant
iu = [];

% define constant outputs
y0 = [...
    Va;...       % 1 - Va
    0;...        % 2 - alpha
    0;...        % 3 - beta
    ];
% specify which outputs to hold constant
iy = [1,3];

% define constant derivatives
dx0 = 

if R~=Inf, dx0(9) = Va*cos(gamma)/R; end  % 9 - psidot
% specify which derivaties to hold constant in trim algorithm
idx = [3; 4; 5; 6; 7; 8; 9; 10; 11; 12];

% compute trim conditions
[x_trim,u_trim,y_trim,dx_trim] = trim('mavsim_trim',x0,u0,y0,ix,iu,iy,dx0,idx);

% check to make sure that the linearization worked (should be small)
norm(dx_trim(3:end)-dx0(3:end))

% P.u_trim = u_trim;
% P.x_trim = x_trim;

% set initial conditions to trim conditions
% initial conditions
MAV.pn0    = 0;           % initial North position
MAV.pe0    = 0;           % initial East position
MAV.pd0    = -200;        % initial Down position (negative altitude)
MAV.u0     = x_trim(4);   % initial velocity along body x-axis
MAV.v0     = x_trim(5);   % initial velocity along body y-axis
MAV.w0     = x_trim(6);   % initial velocity along body z-axis
MAV.phi0   = x_trim(7);   % initial roll angle
MAV.theta0 = x_trim(8);   % initial pitch angle
MAV.psi0   = x_trim(9);   % initial yaw angle
MAV.p0     = x_trim(10);  % initial body frame roll rate
MAV.q0     = x_trim(11);  % initial body frame pitch rate
MAV.r0     = x_trim(12);  % initial body frame yaw rate  


 

trim 시뮬링크 모델이랑 트림 계산  파일이 저렇게 주어졌다.

 

xdot은 다음과 같으므로

 

값들은 아래와 같이 대입하면 될거같다

 

 

구현 하긴했는데

 

compute_trim에서 자꾸 dx0이랑 시뮬링크 블록상 연속 상태 크기랑 틀렸다고 에러뜬다.

 

한참 삽질하다보니 mav_dynamics에서 오일러각대신 쿼터니언을 쓰다보니 상태가 13개가 쓰여서 그렇더라

 

다시 챕터 3의 mav_dynamics를 오일러각으로 바꿧다.

 

function [sys,x0,str,ts,simStateCompliance] = mav_dynamics(t,x,u,flag,MAV)

switch flag

  %%%%%%%%%%%%%%%%%%
  % Initialization %
  %%%%%%%%%%%%%%%%%%
  case 0
    [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes(MAV);

  %%%%%%%%%%%%%%%
  % Derivatives %
  %%%%%%%%%%%%%%%
  case 1
    sys=mdlDerivatives(t,x,u,MAV);

  %%%%%%%%%%
  % Update %
  %%%%%%%%%%
  case 2
    sys=mdlUpdate(t,x,u);

  %%%%%%%%%%%
  % Outputs %
  %%%%%%%%%%%
  case 3
    sys=mdlOutputs(t,x);

  %%%%%%%%%%%%%%%%%%%%%%%
  % GetTimeOfNextVarHit %
  %%%%%%%%%%%%%%%%%%%%%%%
  case 4
    sys=mdlGetTimeOfNextVarHit(t,x,u);

  %%%%%%%%%%%%%
  % Terminate %
  %%%%%%%%%%%%%
  case 9
    sys=mdlTerminate(t,x,u);

  %%%%%%%%%%%%%%%%%%%%
  % Unexpected flags %
  %%%%%%%%%%%%%%%%%%%%
  otherwise
    DAStudio.error('Simulink:blocks:unhandledFlag', num2str(flag));

end

% end sfuntmpl

%
%=============================================================================
% mdlInitializeSizes
% Return the sizes, initial conditions, and sample times for the S-function.
%=============================================================================
%
function [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes(MAV)

%
% call simsizes for a sizes structure, fill it in and convert it to a
% sizes array.
%
% Note that in this example, the values are hard coded.  This is not a
% recommended practice as the characteristics of the block are typically
% defined by the S-function parameters.
%
sizes = simsizes;

sizes.NumContStates  = 12;
sizes.NumDiscStates  = 0;
sizes.NumOutputs     = 12;
sizes.NumInputs      = 6;
sizes.DirFeedthrough = 0;
sizes.NumSampleTimes = 1;   % at least one sample time is needed

sys = simsizes(sizes);

%
% initialize the initial conditions
%
x0  = [...
    MAV.pn0;...
    MAV.pe0;...
    MAV.pd0;...
    MAV.u0;...
    MAV.v0;...
    MAV.w0;...
    MAV.phi0;...
    MAV.theta0;...
    MAV.psi0;...
    MAV.p0;...
    MAV.q0;...
    MAV.r0;...
    ];

%
% str is always an empty matrix
%
str = [];

%
% initialize the array of sample times
%
ts  = [0 0];

% Specify the block simStateCompliance. The allowed values are:
%    'UnknownSimState', < The default setting; warn and assume DefaultSimState
%    'DefaultSimState', < Same sim state as a built-in block
%    'HasNoSimState',   < No sim state
%    'DisallowSimState' < Error out when saving or restoring the model sim state
simStateCompliance = 'UnknownSimState';

% end mdlInitializeSizes

%
%=============================================================================
% mdlDerivatives
% Return the derivatives for the continuous states.
%=============================================================================
%
function sys=mdlDerivatives(t,x,uu, MAV)
    pn    = x(1);
    pe    = x(2);
    pd    = x(3);
    u     = x(4);
    v     = x(5);
    w     = x(6);
    phi   = x(7);
    theta= x(8);
    psi   = x(9);
    p     = x(10);
    q     = x(11);
    r     = x(12);
    fx    = uu(1);
    fy    = uu(2);
    fz    = uu(3);
    ell   = uu(4);
    m     = uu(5);
    n     = uu(6);
    
    cphi = cos(phi);
    ctheta = cos(theta);
    cpsi = cos(psi);
    sphi = sin(phi);
    stheta = sin(theta);
    spsi = sin(psi);
    
    
    pndot = u*ctheta*cpsi -v*(sphi*stheta*cpsi - cphi*spsi) +w*(cphi*stheta*cpsi + sphi*spsi);
    
    pedot = u*ctheta*spsi + v*(sphi*stheta*spsi + cphi*cpsi) + w*(cphi*stheta*spsi - sphi*cpsi);
    
    pddot = -stheta*u + v*sphi*ctheta + w*cphi *ctheta;
    
    udot = r*v - q*w + 1/MAV.mass*fx;
    
    vdot = p*w - r*u + 1/MAV.mass*fy;
    
    wdot = q*u - p*v + 1/MAV.mass*fz;
       
    phidot = p + sphi*tan(theta)*q + r*cphi*tan(theta);
    
    thetadot = q*cphi -sphi*r;
    
    psidot = sphi/ctheta*q + cphi/ctheta*r;
    
    pdot = MAV.Gamma1*p*q-MAV.Gamma2*q*r+MAV.Gamma3*ell+MAV.Gamma4*n;
    qdot = MAV.Gamma5*p*r-MAV.Gamma6*(p^2-r^2) +1/MAV.Jy*m;
    rdot = MAV.Gamma7*p*q - MAV.Gamma1*q*r + MAV.Gamma4*ell + MAV.Gamma8*n;
        

sys = [pndot; pedot; pddot; udot; vdot; wdot; phidot; thetadot; psidot; pdot; qdot; rdot];

% end mdlDerivatives

%
%=============================================================================
% mdlUpdate
% Handle discrete state updates, sample time hits, and major time step
% requirements.
%=============================================================================
%
function sys=mdlUpdate(t,x,u)

sys = [];

% end mdlUpdate

%
%=============================================================================
% mdlOutputs
% Return the block outputs.
%=============================================================================
%
function sys=mdlOutputs(t,x)
    y = [...
        x(1);
        x(2);
        x(3);
        x(4);
        x(5);
        x(6);
        x(7);
        x(8);
        x(9);
        x(10);
        x(11);
        x(12);
        ];
sys = y;

% end mdlOutputs

%
%=============================================================================
% mdlGetTimeOfNextVarHit
% Return the time of the next hit for this block.  Note that the result is
% absolute time.  Note that this function is only used when you specify a
% variable discrete-time sample time [-2 0] in the sample time array in
% mdlInitializeSizes.
%=============================================================================
%
function sys=mdlGetTimeOfNextVarHit(t,x,u)

sampleTime = 1;    %  Example, set the next hit to be one second later.
sys = t + sampleTime;

% end mdlGetTimeOfNextVarHit

%
%=============================================================================
% mdlTerminate
% Perform any end of simulation tasks.
%=============================================================================
%
function sys=mdlTerminate(t,x,u)

sys = [];

% end mdlTerminate

 

다음 값이 주어질때

트림 값

 

 

 

아래의 트림 시뮬레이션 모델에서 

 

트림 계산 입력이 아래와 같이 주어질때 

gamma = 2*pi/180;  % desired flight path angle (radians)
R     = 5000;        % desired radius (m) - use (+) for right handed orbit, 
                            %                          (-) for left handed orbit
Va = 100;

 

 

시뮬레이션

 

 

 

 

 

300x250
728x90

시뮬링크에서 트림과 선형화하기

 

F.1 시뮬링크 trim 명령 사용하기

 

 시뮬링크는 트림 상태를 계산하는 루틴을 제공하는데, help trim 으로 사용방법을 확인할 수 있습니다. 5.3장에서 봤던것 처럼 $V_a^*$, $\gamma^*$, $R^*$가 주어지면, $x^*$, $u^*$를 찾는것이 목표가 됩니다. $\dot{x^*}$ = f($x^*$, $u^*$ 로 여기서 x, u는 식 (5.17)과 (5.18)로 정의 됩니다. $\dot{x^*}$는 식 (5.21)에서 주어지며 f(x, u)는 식 (5.1) - (5.12)로 정의됩니다.

 

 트림 명령의 형식은

 

[x, u, y, dx] = trim('sys', x0, u0, y0, ix, iu, uy, dx0, idx);

 

 

 여기서 x는 계산된 트림상태 $x^*$, u는 계산됨 트림 입력 $u^*$, y는 계산된 트림 출력 $y^*$, dx는 계산된 상태의 미분 $\dot{x^*}$, 시뮬링크 모델은 sys.mdl에 명시되는데 모델의 상태들은 서브시스템 내 상태로 되어있고, 입력과 출력은 시뮬링크에서 inports, outports로 정의됩니다.

 

 

 

 그림 F.1은 비행체 트림 계산하는 시뮬링크 모델로 입력은 4개의 inports로 서보 명령인 delta_e, delta_a, delta_r, delta_t 가 있습니다. 이 블록의 상태들은 시뮬링크 상태로 우리는 $\zeta$ = ($p_n$, $p_e$, $p_d$, u, u, w, $\phi$, $\theta$, $\psi$, p, q, r)$^T$가 됩니다. 출력은 세개의 outports이며 대기속도 $V_a$, 받음각 $\alpha$, $\beta$이며 이 아웃풋을 트림 명령에다가 전달하여 $V_a$ = $V_a^*$가 유지되도록 하겠습니다.

 

 

 

 러더도 사용가능하면 $\beta^*$=0으로 유지시키는 트림 명령을 주어 정상선회 하도록 할수 있씁니다. 러더가 없는 경우 0상태로 만들수 없습니다.

 

 

 트림 계산에서 문제는 시스템의 비선형 방정식을 풀어야 하는데, 많은 경우 시뮬링크 트림 명령에는 초기화 추정 값으로 상태 x0, 입력 u0, 출력 y0, 상태 미분 dx0이 필요합니다. 우리가 일부 상태나 입력, 출력 또는 미분 상태같은 시작 상태를 알아서 초기 상태를 쓸수 있으면, 사용가능한 값들을 인덱스 벡터 ix, iu, iy, idx로 전달할 수 있습니다.

 

 

 우리의 상태가 아래와 같다면

 

 

이렇게 작성할 수 있습니다.

 

 

비슷하게 초기 상태, 입력, 출력들을 다음처럼 정의할수 있습니다.

 

 

그림 F.1 트림과 선형 상태 공간 모델 계산을 위한 시뮬링크 다이어그램

 

F.2 트림 수치 계산 Numerical Computation of Trim

 시뮬링크 말고 다른환경에서 시뮬레이션이 개발된다면, 트림 루틴을 따로 작성해야합니다. 이번 장에서는 어떻게 하는지 간단히 설명하고 $V_a^*$, $\gamma^*$, $R^*$ 파라미터들로 상승 선회 트림 제어에 대해 살펴보고, 트림 찾기 알고리즘에서 입력으로 사용하겠습니다. 입력 파라미터 $V_a^*$, $\gamma^*$, $R^*$와  $\alpha$, $\beta$, $\phi$로 트림 상태와 입력 구하는 계산과정을 살펴보겠습니다. 주어진 $V_a^*$, $\gamma^*$, $R^*$값으로 트림값  $\alpha^*$, $\beta^*$, $\phi^*$을 찾아낸다면 이제 트림 상태와 입력같을 구할수 있게됩니다.

 

 첫 단계는 상태 변수들을 $V_a^*$, $\gamma^*$, $R^*$로, 입력을 $\alpha^*$, $\beta^*$, $\phi^*$로 나타내는데 $V_a^*$, $\gamma^*$, $R^*$는 사용자 지정 입력이 되어 알고리즘은 최적의 트림 상태를 구할수 있는 $\alpha^*$, $\beta^*$, $\phi^*$ 계산합니다. 이 값으로 트림 상태 $x^*$, $u^*$를 찾는데 사용됩니다.

 

동체 좌표계 속도 $u^*$, $v^*$, $w^*$

 식 (2.7)에서 동체 좌표계상 속도들은 $V_a^*$, $\alpha^*$, $\beta^*$ 를 이용해서 나타낼 수있습니다.

 

피치각 $\theta^*$

 비행경로각의 정의로 다음과 같이 정리할 수있습니다.

 

각 변화율 p, q, r

 각 변화율은 식 (3.2)로 오일러각으로 나타낼수 있습니다.

 

엘리베이터 $\delta_e$

 $p^*$, $q^*$, $r^*$, $\delta_e^*$에 대해서 식 (5.11)을 풀면

 

에일러론 $\delta_a$과 러더 $\delta_r$

 에일러론과 러더 명령은 식 (5.10), 식(5.12)을 풀어서 구할 수 있습니다.

 

 

F.2.1 트림 알고리즘

 모든 관심변수와 제어입력은 $V_a^*$, $\gamma^*$, $R^*$, $\alpha^*$, $\beta^*$, $\phi^*$입니다. 트림 알고리즘의 입력은 $V^*$, $\gamma^*$, $R^*$이며,  $\alpha^*$, $\beta^*$, $\phi^*$값을 찾기위해 다음의 최적화 알고리즘을 사용합니다.

 

 이는 다음장에서 설명할 경사 하강 알고리즘으로 수치적으로 구할 수있습니다. 트림 알고리즘은 알고리즘 13에서 정리하였습니다.

 

F.2.2 경사하강법 수학적 구현

 이번 장의 목표는 최적화 문제를 풀수있는 단순한 경사 하강 알고리즘을 살펴보겠습니다.

 

 

알고리즘 13 트림

1. 입력 : 희망 대기속도 $V_a^*$, 희망 비행경로각 $\gamma^*$, 희망 선회 반지름 $R_*$

2. 계산 : ($\alpha^*$, $\beta^*$, $\theta^*$) = arg min || $\dot{x^*}$- f($x^*$, $u^*$) $||^2$

3. 트림 상태를 계산합시다.

 

 

4. 트림 입력

 

 

  기본 아이디어는 초기 시작 값 $\xi^{(0)}$에서 음수 기울기 방향으로 따라가는데, 이를 정리하면 다음과 같습니다. 이때 k는 양의 상수 값으로 하강 비율을 나타냅니다.

 

 

식 (F.4)를 이산 추정으로 한다면, 다음과 같고 $k_d$는 이산 스탭 크기를 의미합니다. 

 

 

 트림 계산을 위해서, 편미분 $\frac{\vartheta J} {\vartheta \xi}$는 해석적으로 구하기는 힘들지만 수치적인 방법으로 효율적으로 구할수 있습니다.

 

 이는 수치적으로 추정해서 구하면 다음과 같습니다. 이때 $\epsilon$은 작은 상수값이 됩니다.

 

 

F.3 시뮬링크 linmod 명령을 사용하여 상태공간 모델을 만들기

 시뮬링크는 다이어그램을 이용해서 선형 상태공간을 만들어내는 내장 기능을 제공하고 있습니다. 사용 방법에대해서 매트랩 프롬프트 상에 help linmod로 얻을 수있습니다. linmod 명령의 포맷은 다음과 같습니다.

 

 여기서 X, U는 상태와 입력값으로 선형화 될 값들이며, [A, B, C, D]는 상태공간 모델이 됩니다. 12 상태, 4입력인 F.1 그림에서 linmod 명령을 사용하면 결과 상태공간 모델 방정식은 식 (5.43)의 모델과 식 (5.50)을 포함해서 나오게 됩니다.

 

알고리즘 14. J = || $\dot{x^*}$ - f($x^*$, $u^*$) $||^20$

1. 입력 : $\alpha^*$, $\beta^*$, $\phi^*$, $V_a^*$, $R^*$, $\gamma^*$

2. $\dot{x^*}$계산하기 :

3. 트림 상태 계산 : 

 

 

4. 트림 입력 계산 : 

 

 

5. f($x^*$, $u^*$) 계산  :

 

 

6. J 계산 :

 

 

식 (5.43)을 얻기 위해서 다음 과정을 거치면 됩니다.

 

 

 

 

 

 

 

300x250
728x90

 

 

1. 에일러론, 엘리베이터, 러더, 추진 + 바람에 의한 힘과 모멘트 생성

2. mav_dynamics에 입력 -> 비행체 상태 출력

3. drawAircraft에서 비행체 그리기

 

1. forces_moment.m 파일 중력, 항공역학,  추진 힘과 모멘트 구현하기

 

진행하다보니 aerosonde uav 파라미터를 이미 가지고 있더라

 

% initialize the mav viewer
addpath('../tools');  

% initial conditions
MAV.pn0    = 0;     % initial North position
MAV.pe0    = 0;     % initial East position
MAV.pd0    = -100;  % initial Down position (negative altitude)
MAV.u0     = 25;     % initial velocity along body x-axis
MAV.v0     = 0;     % initial velocity along body y-axis
MAV.w0     = 0;     % initial velocity along body z-axis
MAV.phi0   = 0;     % initial roll angle
MAV.theta0 = 0;     % initial pitch angle
MAV.psi0   = 0;     % initial yaw angle
e = Euler2Quaternion(MAV.phi0, MAV.theta0, MAV.psi0);
MAV.e0     = e(1);  % initial quaternion
MAV.e1     = e(2);
MAV.e2     = e(3);
MAV.e3     = e(4);
MAV.p0     = 0;     % initial body frame roll rate
MAV.q0     = 0;     % initial body frame pitch rate
MAV.r0     = 0;     % initial body frame yaw rate
   
%physical parameters of airframe
MAV.gravity = 9.81;
MAV.mass = 11.0;
MAV.Jx   = 0.824;
MAV.Jy   = 1.135;
MAV.Jz   = 1.759;
MAV.Jxz  = 0.120;
MAV.S_wing        = 0.55;
MAV.b             = 2.90;
MAV.c             = 0.19;
MAV.S_prop        = 0.2027;
MAV.rho           = 1.2682;
MAV.e             = 0.9;
MAV.AR            = MAV.b^2/MAV.S_wing;

% Gamma parameters from uavbook page 36
MAV.Gamma  = MAV.Jx*MAV.Jz-MAV.Jxz^2;
MAV.Gamma1 = (MAV.Jxz*(MAV.Jx-MAV.Jy+MAV.Jz))/MAV.Gamma;
MAV.Gamma2 = (MAV.Jz*(MAV.Jz-MAV.Jy)+MAV.Jxz*MAV.Jxz)/MAV.Gamma;
MAV.Gamma3 = MAV.Jz/MAV.Gamma;
MAV.Gamma4 = MAV.Jxz/MAV.Gamma;
MAV.Gamma5 = (MAV.Jz-MAV.Jx)/MAV.Jy;
MAV.Gamma6 = MAV.Jxz/MAV.Jy;
MAV.Gamma7 = (MAV.Jx*(MAV.Jx-MAV.Jy)+MAV.Jxz*MAV.Jxz)/MAV.Gamma;
MAV.Gamma8 = MAV.Jx/MAV.Gamma;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% aerodynamic coefficients
MAV.C_L_0         = 0.23;
MAV.C_D_0         = 0.043;
MAV.C_m_0         = 0.0135;
MAV.C_L_alpha     = 5.61;
MAV.C_D_alpha     = 0.030;
MAV.C_m_alpha     = -2.74;
MAV.C_L_q         = 7.95;
MAV.C_D_q         = 0.0;
MAV.C_m_q         = -38.21;
MAV.C_L_delta_e   = 0.13;
MAV.C_D_delta_e   = 0.0135;
MAV.C_m_delta_e   = -0.99;
MAV.M             = 50;
MAV.alpha0        = 0.47;
MAV.epsilon       = 0.16;
MAV.C_D_p         = 0.0;

MAV.C_Y_0         = 0.0;
MAV.C_ell_0       = 0.0;
MAV.C_n_0         = 0.0;
MAV.C_Y_beta      = -0.98;
MAV.C_ell_beta    = -0.13;
MAV.C_n_beta      = 0.073;
MAV.C_Y_p         = 0.0;
MAV.C_ell_p       = -0.51;
MAV.C_n_p         = -0.069;
MAV.C_Y_r         = 0.0;
MAV.C_ell_r       = 0.25;
MAV.C_n_r         = -0.095;
MAV.C_Y_delta_a   = 0.075;
MAV.C_ell_delta_a = 0.17;
MAV.C_n_delta_a   = -0.011;
MAV.C_Y_delta_r   = 0.19;
MAV.C_ell_delta_r = 0.0024;
MAV.C_n_delta_r   = -0.069;

% Parameters for propulsion thrust and torque models
MAV.D_prop = 0.508;     % prop diameter in m

% Motor parameters
MAV.K_V = 145;                    % from datasheet RPM/V
MAV.KQ = (1/MAV.K_V)*60/(2*pi);   % KQ in N-m/A, V-s/rad
MAV.R_motor = 0.042;              % ohms
MAV.i0 = 1.5;                     % no-load (zero-torque) current (A)

% Inputs
MAV.ncells = 12;
MAV.V_max = 3.7*MAV.ncells;       % max voltage for specified number of battery cells

% Coeffiecients from prop_data fit
MAV.C_Q2 = -0.01664;
MAV.C_Q1 = 0.004970;
MAV.C_Q0 = 0.005230;

MAV.C_T2 = -0.1079;
MAV.C_T1 = -0.06044;
MAV.C_T0 = 0.09357;



 

그래서 챕터 3의 모델 미분 함수를 위 파라미터를 바로사용하는걸로 고쳤다.

 

%
%=============================================================================
% mdlDerivatives
% Return the derivatives for the continuous states.
%=============================================================================
%
function sys=mdlDerivatives(t,x,uu, MAV)
    pn    = x(1);
    pe    = x(2);
    pd    = x(3);
    u     = x(4);
    v     = x(5);
    w     = x(6);
    e0    = x(7);
    e1    = x(8);
    e2    = x(9);
    e3    = x(10);
    p     = x(11);
    q     = x(12);
    r     = x(13);
    fx    = uu(1);
    fy    = uu(2);
    fz    = uu(3);
    ell   = uu(4);
    m     = uu(5);
    n     = uu(6);
    
    pndot = e1^2+e0^2-e2^2-e3^2*u + 2*v*(e1*e2 - e3*e0) + 2*w*(e1*e3 + e2*e0);
    
    pedot = 2*u*(e1*e2+e3*e0)+v*(e2^2+e0^2-e1^2-e3^2) + w*2*(e2*e3-e1*e0);
    
    pddot = u*2*(e1*e3-e2*e0) + 2*v*(e2*e3 + e1*e0) + w*(e3^2+e0^2 - e1^2 - e2^2);
    
    udot = r*v - q*w + 1/MAV.mass*fx;
    
    vdot = p*w - r*u + 1/MAV.mass*fy;
    
    wdot = q*u - p*v + 1/MAV.mass*fz;
       
    e0dot = 1/2*(-p*e1 -q*e2 -r*e3);
    e1dot = 1/2*(p*e0 + r*e2 -q*e3);
    e2dot = 1/2*(e0*q+e1*-r+e3*p);
    e3dot = 1/2*(r*e0+q*e1-p*e2);
    
    pdot = MAV.Gamma1*p*q-MAV.Gamma2*q*r+MAV.Gamma3*ell+MAV.Gamma4*n;
    qdot = MAV.Gamma5*p*r-MAV.Gamma6*(p^2-r^2) +1/MAV.Jy*m;
    rdot = MAV.Gamma7*p*q - MAV.Gamma1*q*r + MAV.Gamma4*ell + MAV.Gamma8*n;
        

sys = [pndot; pedot; pddot; udot; vdot; wdot; e0dot; e1dot; e2dot; e3dot; pdot; qdot; rdot];

% end mdlDerivatives

 

위 파라미터와 현재 상태값으로  중력, 항공역학적, 추진 힘과 모멘트를 정리한 아래의 식을 구하면 된다.

 

4.2 forces_moments.m 에서 외풍 블록을 수정하고, 대기속도, 받음각, 사이드 슬립각, 바람 백터를 정리하라.

 4.1하는데 우선 대기속도, 받음각 부터 필요하므로 4,2부터 정리하면

 

 

위 식을 계산하는데 $u_r$, $v_r$, $w_r$이 필요하다. 이값들은 

 

 

이며, 동체 좌표계산 바람 속도가 필요한데, steady wind와 gust wind의 합으로 구한다.

 

steady wind와 gust wind는 force moment.m 의 파라미터로 전달되므로 이를 이용하면 되겠다.

 

% forces_moments.m
%   Computes the forces and moments acting on the airframe. 
%
%   Output is
%       F     - forces
%       M     - moments
%       Va    - airspeed
%       alpha - angle of attack
%       beta  - sideslip angle
%       wind  - wind vector in the inertial frame
%

function out = forces_moments(x, delta, wind, P)

    % relabel the inputs
    pn      = x(1);
    pe      = x(2);
    pd      = x(3);
    u       = x(4);
    v       = x(5);
    w       = x(6);
    phi     = x(7);
    theta   = x(8);
    psi     = x(9);
    p       = x(10);
    q       = x(11);
    r       = x(12);
    delta_e = delta(1);
    delta_a = delta(2);
    delta_r = delta(3);
    delta_t = delta(4);
    w_ns    = wind(1); % steady wind - North
    w_es    = wind(2); % steady wind - East
    w_ds    = wind(3); % steady wind - Down
    u_wg    = wind(4); % gust along body x-axis
    v_wg    = wind(5); % gust along body y-axis    
    w_wg    = wind(6); % gust along body z-axis
    
    % compute wind data in NED
    w_n = 0;
    w_e = 0;
    w_d = 0;
    
    % compute air data
    Va = 0;
    alpha = 0;
    beta = 0;
    
    % compute external forces and torques on aircraft
    Force(1) =  0;
    Force(2) =  0;
    Force(3) =  0;
    
    Torque(1) = 0;
    Torque(2) = 0;   
    Torque(3) = 0;
   
    out = [Force'; Torque'; Va; alpha; beta; w_n; w_e; w_d];
end



 

우선 ned축에 대한 바람부터 구해보자.

 

gust_wind는 그대로 써도 되지만

 

steady winid는 기체 좌표계에서 동체 좌표계로 로테이션 시켜주어야 한다.

 

 

chap2 의 drawAircraft 함수에 이 로테이션을 구현한 부분이 있었으니 사용하자

%%%%%%%%%%%%%%%%%%%%%%%
function XYZ=rotate(XYZ,phi,theta,psi)
  % define rotation matrix
  R_roll = [...
          1, 0, 0;...
          0, cos(phi), -sin(phi);...
          0, sin(phi), cos(phi)];
  R_pitch = [...
          cos(theta), 0, sin(theta);...
          0, 1, 0;...
          -sin(theta), 0, cos(theta)];
  R_yaw = [...
          cos(psi), -sin(psi), 0;...
          sin(psi), cos(psi), 0;...
          0, 0, 1];
  R = R_roll*R_pitch*R_yaw;
  % rotate vertices
  XYZ = R*XYZ;
end

 

 

위 함수를 force_moments에 추가하고

 

각 방향에 대한 바람들을 다음과 같이 구하였다.

   w_v = [w_ns; w_es; w_ds];
   w_b = rotate(w_v, phi, theta, psi);
  
    
    % compute wind data in NED
    w_n = w_b(1) + u_wg;
    w_e = w_b(2) + v_wg;
    w_d = w_b(3) + w_wg;
    

 

 

그다음은 대기속도, 받음각, 사이드슬립을 구해보자

 

 

 

여기서 필요한 $u_r$, $v_r$, $w_r$은 동체 좌표계 상에서의 대기속도로 다음과 같이 구한다.

 

 

방금 전에 $u_w$, $v_w$, $w_w$를 구하였으므로, 입력 받은 u, v, w에서 바로 빼주면 되겠다.

 

바로 대기속도, 받음각, 사이드 슬립으로 정리하면

 

    v_ab = [u-w_n; v-w_e; w-w_d];
    
    % compute air data
    Va = sqrt(v_ab(1)^2 + v_ab(2)^2 + v_ab(3)^2);
    alpha = atan(v_ab(3)/ v_ab(1));
    beta = asin(v_ab(2)/Va);

 

 

이렇게 4.2 문제를 끝내고 힘과 모멘트를 구해보면

 

 

위 식에서 중력 요소는 다음과 같으며

 

forces_moments.m 은 MAV 파라미터를 변수 p로 받으므로

 

    % gravity forces
    f_g_x = -p.mass * p.gravity * sin(theta);
    f_g_y = p.mass * p.gravity * cos(theta) * sin(phi);
    f_g_z = p.mass * p.gravity * cos(theta) * cos(phi);
    f_g = [f_g_x; f_g_y; f_g_z];
    

 

 

다음은 항공영학적 힘을 구하려면

 

 

여기서 $C_x$($\alpha$) 같은 값들은

 

다음과 같이 정의된다.

 

비행체 파라미터로 우선 위 값들을 우선 정리하면

 

    % stability coefficients
    c_x_alpha = -P.C_D_alpha * cos(alpha) + P.C_L_alpha * sin(alpha);
    c_x_q_alpha = -P.C_D_q * cos(alpha) + P.C_L_q * sin(alpha);
    c_x_delta_e_alpha = -P.C_D_delta_e * cos(alpha) + P.C_L_delta_e * sin(alpha);
    c_z_alpha = -P.C_D_alpha * sin(alpha) - P.C_L_delta_e*cos(alpha);
    c_z_q_alpha = -P.C_D_q * sin(alpha) - P.C_L_q * cos(alpha);
    c_z_delta_e_alpha = -P.C_D_delta_e * sin(alpha) - P.C_L_delta_e * cos(alpha);

 

다시 돌아와 다음 식을 구하면

 

코드로 구현하면

 

 

    %aerodynamics forces
    tmp = 1/2*P.rho*Va^2*P.S_wing;
    f_a_x = c_x_alpha + c_x_q_alpha*P.c/(2*Va)*q + c_x_delta_e_alpha * delta_e;
    f_a_y = P.C_Y_0 + C_Y_beta * beta + C_Y_p *P.b/(2*Va)*p + C_Y_r*P.b/(2*Va)*r+C_Y_delta_a *delta_a+C_Y_delta_r *delta_r;
    f_a_z = c_z_alpha + c_z_q_alpha * P.c/(2*Va)*q + c_z_delta_e_alpha * delta_e;
    f_a = tmp * [f_a_x; f_a_y; f_a_z];
    

 

마지막으로 구할 힘은 추진 힘으로 x축에 대해서만 작용한다.

 

 

코드 상으로 아래와 같이 구현하면 되나

 

    %propulsion forces
    f_x_p = 1/2 * P.rho *P.S_prop * P.C_prop*( (P.k_motor *delta_t)^2 - Va^2);
    

파라미터 파일에서는 C_prop와 k_motor가 없더라

 

그래서 aerosonde_parameter.m에 다음 코드를 추가했다.

 

MAV.k_motor = 80;
MAV.C_prop  = 1;

 

 

 

힘에 대해서 정리하자면 다음과 같이 코드를 구현하면 된다.

    % compute external forces and torques on aircraft
    Force(1) =  f_g(1) + f_a(1) + f_x_p;
    Force(2) =  f_g(2) + f_a(2);
    Force(3) =  f_g(3) + f_a(3);

 

 

다음으로 각 축방향으로 작용하는 모멘트를 구해보자

 

 

여기서 항공역학적 모멘트 부분만 정리하면 코드상으로 다음과 같다.

 

    %aerodynamics moments
    tmp = 1/2 *P.rho * Va^2 * P.S_wing;
    m_l = P.C_ell_0 + P.C_ell_beta *beta + P.C_ell_p * P.b/(2*Va)*p + P.C.ell_r*b/(2*Va)*r + P.C_ell_delta_a * delta_a + P.C_ell_delta_r * delta_r;
    m_l = tmp *P.b*m_l;
    m_m = P.C_m_0 + P.C_m_alpha * alpha + P.C_m_q * P.c /(2*Va) * q + P.C_m_delta_e * delta_e;
    m_m = tmp*P.c *m_m;
    m_n = P.C_n_0 + P.C_n_beta * beta + P.C_n_p * P.b/(2* Va) *p + P.C_n_r * P.b/(2* Va) * r + P.C_n_delta_a * delta_a + P.C_n_delta_r * delta_r;
    m_n = tmp * P.b *m_n;

 

 

추진력에 의한 x축 모멘트를 구하여야 하나 우리의 경우는 0이므로 추진에 의한 모멘트는 무시하자

 

 

 

 

 

forces_moments.m

전체 코드를 정리하면

 

% forces_moments.m
%   Computes the forces and moments acting on the airframe. 
%
%   Output is
%       F     - forces
%       M     - moments
%       Va    - airspeed
%       alpha - angle of attack
%       beta  - sideslip angle
%       wind  - wind vector in the inertial frame
%

function out = forces_moments(x, delta, wind, P)

    % relabel the inputs
    pn      = x(1);
    pe      = x(2);
    pd      = x(3);
    u       = x(4);
    v       = x(5);
    w       = x(6);
    phi     = x(7);
    theta   = x(8);
    psi     = x(9);
    p       = x(10);
    q       = x(11);
    r       = x(12);
    delta_e = delta(1);
    delta_a = delta(2);
    delta_r = delta(3);
    delta_t = delta(4);
    w_ns    = wind(1); % steady wind - North
    w_es    = wind(2); % steady wind - East
    w_ds    = wind(3); % steady wind - Down
    u_wg    = wind(4); % gust along body x-axis
    v_wg    = wind(5); % gust along body y-axis    
    w_wg    = wind(6); % gust along body z-axis
    
    
   w_v = [w_ns; w_es; w_ds];
   w_b = rotate(w_v, phi, theta, psi);
  
    
    % compute wind data in NED
    w_n = w_b(1) + u_wg;
    w_e = w_b(2) + v_wg;
    w_d = w_b(3) + w_wg;
    
    
    v_ab = [u-w_n; v-w_e; w-w_d];
    
    % compute air data
    Va = sqrt(v_ab(1)^2 + v_ab(2)^2 + v_ab(3)^2);
    alpha = atan(v_ab(3)/ v_ab(1));
    beta = asin(v_ab(2)/Va);
    

    % gravity forces
    f_g_x = -P.mass * P.gravity * sin(theta);
    f_g_y = P.mass * P.gravity * cos(theta) * sin(phi);
    f_g_z = P.mass * P.gravity * cos(theta) * cos(phi);
    f_g = [f_g_x; f_g_y; f_g_z];
    
    
    % stability coefficients
    c_x_alpha = -P.C_D_alpha * cos(alpha) + P.C_L_alpha * sin(alpha);
    c_x_q_alpha = -P.C_D_q * cos(alpha) + P.C_L_q * sin(alpha);
    c_x_delta_e_alpha = -P.C_D_delta_e * cos(alpha) + P.C_L_delta_e * sin(alpha);
    c_z_alpha = -P.C_D_alpha * sin(alpha) - P.C_L_delta_e*cos(alpha);
    c_z_q_alpha = -P.C_D_q * sin(alpha) - P.C_L_q * cos(alpha);
    c_z_delta_e_alpha = -P.C_D_delta_e * sin(alpha) - P.C_L_delta_e * cos(alpha);
    
    %aerodynamics forces
    tmp = 1/2*P.rho*Va^2*P.S_wing;
    f_a_x = c_x_alpha + c_x_q_alpha*P.c/(2*Va)*q + c_x_delta_e_alpha * delta_e;
    f_a_y = P.C_Y_0 + P.C_Y_beta * beta + P.C_Y_p *P.b/(2*Va)*p + P.C_Y_r*P.b/(2*Va)*r+P.C_Y_delta_a *delta_a+P.C_Y_delta_r *delta_r;
    f_a_z = c_z_alpha + c_z_q_alpha * P.c/(2*Va)*q + c_z_delta_e_alpha * delta_e;
    f_a = tmp * [f_a_x; f_a_y; f_a_z];
    
    %propulsion forces
    f_x_p = 1/2 * P.rho *P.S_prop * P.C_prop*( (P.k_motor *delta_t)^2 - Va^2);

    %aerodynamics moments
    tmp = 1/2 *P.rho * Va^2 * P.S_wing;
    m_l = P.C_ell_0 + P.C_ell_beta *beta + P.C_ell_p * P.b/(2*Va)*p + P.C_ell_r*P.b/(2*Va)*r + P.C_ell_delta_a * delta_a + P.C_ell_delta_r * delta_r;
    m_l = tmp *P.b*m_l;
    m_m = P.C_m_0 + P.C_m_alpha * alpha + P.C_m_q * P.c /(2*Va) * q + P.C_m_delta_e * delta_e;
    m_m = tmp*P.c *m_m;
    m_n = P.C_n_0 + P.C_n_beta * beta + P.C_n_p * P.b/(2* Va) *p + P.C_n_r * P.b/(2* Va) * r + P.C_n_delta_a * delta_a + P.C_n_delta_r * delta_r;
    m_n = tmp * P.b *m_n;

    % compute external forces and torques on aircraft
    Force(1) =  f_g(1) + f_a(1) + f_x_p;
    Force(2) =  f_g(2) + f_a(2);
    Force(3) =  f_g(3) + f_a(3);
    
    Torque(1) = m_l;
    Torque(2) = m_m;   
    Torque(3) = m_n;
    out = [Force'; Torque'; Va; alpha; beta; w_n; w_e; w_d];
end


%%%%%%%%%%%%%%%%%%%%%%%
function XYZ=rotate(XYZ,phi,theta,psi)
  % define rotation matrix
  R_roll = [...
          1, 0, 0;...
          0, cos(phi), -sin(phi);...
          0, sin(phi), cos(phi)];
  R_pitch = [...
          cos(theta), 0, sin(theta);...
          0, 1, 0;...
          -sin(theta), 0, cos(theta)];
  R_yaw = [...
          cos(psi), -sin(psi), 0;...
          sin(psi), cos(psi), 0;...
          0, 0, 1];
  R = R_roll*R_pitch*R_yaw;
  % rotate vertices
  XYZ = R*XYZ;
end

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

300x250

+ Recent posts