Android2013. 4. 1. 15:08

 

칼만필터 적용 과정중에 구현한 행렬 연산 소스입니다.

 

안드로이드에서 만든건데 당연히 자바에서도 되겠네요

 

4x4 행렬의 덧셈, 뺄셈, 곱셈을 이중 for문으로 계산해서 반환해줍니다.

 

행렬 연산하시는분 참고하세요~

 

 함수 정의 부

 // 4x4 행렬 덧셈
  double[][] matrix_plus(double[][] A, double[][]B) {
   double[][] C = new double[4][4];
   for(int i=0; i<4; i++) {
    for(int j=0; j<4; j++) {
      C[i][j] = A[i][j] + B[i][j];
     }
     
    }
   return C;
  }
  // 1x4 행렬 덧셈
  double[] matrix_14plus14(double[] A, double[] B) {
   double[] C = new double[4];
   for(int i=0; i<4; i++) {
      C[i] = A[i] + B[i];
    }
   return C;
  }
  // 4x4 행렬 뺄셈
  double[][] matrix_minus(double[][] A, double[][]B) {
   double[][] C = new double[4][4];
   for(int i=0; i<4; i++) {
    for(int j=0; j<4; j++) {
      C[i][j] = A[i][j] - B[i][j];
     }
     
    }
   return C;
  }
  // 1x4 행렬 뺄셈
  double[] matrix_14minus14(double[] A, double[]B) {
   double[] C = new double[4];
   for(int i=0; i<4; i++) {
      C[i] = A[i] - B[i];
     }
   return C;
  }
  // 4x4 행렬 곱셈
  double[][] matrix_mul(double[][] A, double[][]B) {
   double[][] C = new double[4][4];
   for(int i=0; i<4; i++) {
    for(int j=0; j<4; j++) {
     for(int k=0; k<4; k++) {
      C[i][j] += A[i][k] * B[k][j];
     }
     
    }
   }
   return C;
  }
  // 1x4 * 4x4 행렬 곱셈
  double[] matrix_14mul44(double[] A, double[][]B) {
   double[] C = new double[4];
   for(int i=0; i<4; i++) {
     for(int j=0; j<4; j++) {
      C[i] += A[j] * B[j][i];
     }
   }
   return C;
  }
  // 4x4 행렬 전치
  double[][] matrix_transed(double[][] A) {
   double[][] C = new double[4][4];
   for(int i=0; i<4; i++) {
    for(int j=0; j<4; j++) {
      C[i][j] = A[j][i];
    }
   }
   
   return C;
  }
  // 4x4 행렬 역행렬
  double[][] matrix_inverse(double[][] A) {
   
   double[][] C = new double[4][4];
   
   Matrix mat = new Matrix(4,4);     // Matrix.java는 파일첨부
   for(int i=0; i<4; i++) {
    for(int j=0; j<4; j++) {
     mat.values[i][j] = A[i][j];
    }
   }
   Matrix.Invers inv = mat.new Invers();
   C = inv.Invers(mat);
   
   return C;
  }

 

밑에 소스는 구글링에서 퍼온건데.. 기억이 안나네요 ㅠㅠ (아시는분 댓글 달아주시면 바로 출처 올리겠습니다~)

 

4x4 역행렬 연산에 쓰이는 Matrix 클래스입니다.

 

 Matrix.java

 public class Matrix {
 public int row; // 행 전역변수 선언
 public int col; // 열 전역변수 선언
 public double[][] values; // 2차원 배열 행렬 전역변수 선언

 public Matrix(int row, int col) { // 생성자 Matrix 생성
  this.row = row; // 행의 값을 받는다.
  this.col = col; // 열의 값을 받는다.
  values = new double[row][col];// 전역변수 values에 row값과 col값을 넣어준다.
 }

 class Invers // Invers 메소드
 {
  determi det = new determi(); // 행렬식을 이용하기 위해 불러옴

  public double[][] Invers(Matrix mat) {
   Matrix inv = new Matrix(mat.row, mat.col); // 역행렬을 저장한 행렬 생성
   Matrix cofactor = new Matrix(mat.row, mat.col);
   double de = (double) 1 / det.data(mat);

   if (det.data(mat) == 0) // 행렬식이 0일 경우
   {
    System.out.println("역행렬이  있지 않습니다.");// 메세지 툴력
    System.exit(0); // 그리고 시스템 exit
   }

   for (int i = 0; i < mat.row; i++) { // 0부터 행 값까지 반복
    for (int j = 0; j < mat.col; j++) {// 0부터 열 값까지 반복
     cofactor.values[i][j] = Mino(mat, i, j);
     inv.values[j][i] = de * Math.pow(-1, i + j)
       * cofactor.values[i][j];
    }
   }
   return inv.values;// inv를 리턴한다.
  }
  
  public double Mino(Matrix mat, int r, int c) {// 여인수전개를 위한 메소드
   double cof;
   Matrix minor = new Matrix(mat.row - 1, mat.col - 1);
   int k = 0;
   if (k == r) {
    k++;
   } // C_ij의 소행렬은 i행j열을 제외하므로 이런 if를 쓴다.
   for (int i = 0; i < minor.row; i++) // 0부터 행값까지 반복
   {
    int l = 0; // l은 초기값으로 0
    if (l == c) {
     l++;
    }// l값이 열값과 같다면 l증가
    if (k == r) {
     k++;
    }// k값이 행값과 같다면 k증가
    for (int j = 0; j < minor.col; j++) {
     if (l == c) {
      l++;
     } // 열값과 같아면 l증가
     minor.values[i][j] = mat.values[k][l];
     l++;
    }
    k++;
   }
   cof = det.data(minor);// 소행렬을 구해 반환
   return cof;
  }
 }

 static class determi {
  static int order;
  static double[][] matrix;

  public double data(Matrix mat) // 행렬식을 구할 행렬을 받는다.
  {
   matrix = new double[mat.row][mat.col];
   order = mat.row; // order는 받은 행렬의 행의 수이다.
   for (int i = 0; i < mat.row; i++)// i를 행의수만큼 돌리고
   {
    for (int j = 0; j < mat.col; j++) // j는 열의수만큼 돌려서
    {
     matrix[i][j] = mat.values[i][j]; // matrix에 mat과 같은 값을 넣는다.
    }
   }
   return compute(); // 리턴을 compute함수로 시켜준다.
  }

  public static double compute() // 그럼 여기로 오는데,
  {
   double check[] = new double[20]; // check란 20칸짜리 배열을 만든다.
   double det = 0; // det는 초기화하고
   int row, col = 0; // row와 col도 초기화선언한다.
   for (row = 0; row < order; row++) // row는 받은 행의 수 만큼 돌리고
   {
    check[row] = 1; // 이때 check의 행의수만큼의 index를 1로 지정
   }

   if (order == 1)// 만약 order가 1이면
   {
    det = matrix[0][0]; // det는 a11값이 된다.
   }

   for (row = 0; row < order; row++) // 다시 row를 수만큼 돌림
   {
    check[row] = 0;// row[i]에 0을 집어넣음
    det += matrix[row][0] * Math.pow(-1, row)
      * minor(row, col + 1, check);
    // det를 1열의 수 곱하기 minor함수에서 받은 값으로 온다
    check[row] = 1; // 이렇게 계산 되면 다시 check를 1로 해준다.
   }
   return det; // det 값을 반환
  }

  public static double minor(int Row, int Col, double trans[]) {
   double result = 0;// 결과값으로 초기값을 0을 준다.
   int i = 0;
   if ((order - Col) == 0) {
    return 1;
   }
   for (int row = 0; row < order; row++)// 0부터
   {
    if (trans[row] != 0)// 만약 trans[row]가 0이 아니라면
    {
     trans[row] = 0; // 0을 넣어준다.
     result += matrix[row][Col] * Math.pow(-1, (double) i)
       * minor(row, Col + 1, trans);
     // 여인수전개에 의한 식이다. 재귀함수로 계속 돌리게된다.
     trans[row] = 1; // trans[row]에 1을 넣어준다.
     i++;// i 값 증가
    }
   }
   return result; // result 반환
  }
 }

}


 

 

Posted by 너를위한노래
Quadrotor20132013. 3. 29. 19:36

 

쿼드콥터 제어에 대해 찾다가 동역학에 대해 찾게 되고 현재 동역학에 대해 공부를 하고 있습니다.

 

학교에서 일반물리학 수업을 듣는데 열심히 들어야겠어요 ㅠ 관성좌표계니 모멘트니 하는거를 하나도 모르면 어쩔뻔 했나 싶네요.

 

지금 제가 따로 구축한 개념은 없고 지금 보고 있는 자료를 포스팅 하려고합니다.

 

구글링 하다가 양광웅님의 블로그에 들어갔는데.. 이 분은 천재신듯.. ㅋ 대단하신분 같아요

 

밑에 링크 걸어놓을테니 로봇, 제어등에 관심있으신 분은 들어가 보시길 권합니다.

 

양광웅님의 블로그에 게시되어있는 PDF파일입니다.

 

 

1. 쿼드 로터 무인항공기 동역학 모델링  -

               쿼드콥터_-_동역학_해석.pdf

 

2. 쿼드 로터 무인항공기 제어 및 시뮬레이션 -

               쿼드콥터_-_제어기_설계.pdf

 

좀 더 보다가 얻는게 있으면 또다시 포스팅 하기로 하겠습니다~

 

출처 : 양광웅님의 블로그 - Open Robotics

Posted by 너를위한노래
Quadrotor20132013. 3. 27. 13:20

쿼드콥터의 자세를 추정할 수 있다고 치고.. ㅠ

 

떠있으려면 피드백 받은 자세에 따른 새로운 자세를 만들어 내야겠죠? 각 모터 회전수의 변화로 말이죠

 

이번 글에서는 기본적인 쿼드콥터 작동 원리에 대해 적어 보겠습니다.

 

자, 쿼드콥터를 위에서 바라보면 아래 그림과 같습니다.

 

 

 

 

 

 

이웃한 로터끼리는 반대방향으로 돌아서 각 로터에서 생성되는 반토크를 상쇄시킨다

 

라고 되어있는데.. 로켓 추진체의 작용반작용처럼 직관적으로 확 와닿지는 않네요.

 

각 로터가 100%똑같은 추력을 발생시킨다고 가정하면 쿼드콥터는 지상에 평행하게 뜨게 됩니다.

 

그리고 공중에 떠서 정지해있는 상태일 때는 아래 그림에 따라 움직입니다.

 

 

 

 

 

 

화살표가 굵은 부분 얇은 부분 주의해서 보시길 바랍니다. (각 모터의 상대적 회전수를 나타냄)

 

Roll, Pitch, Yaw는 아래의 그림을 보시면 이해하실 수 있을겁니다~

 

 

(클릭하시면 확대됩니다)

 

 

내용이 추상적이라 거의 그림이네요.. ㅋ

 

이정도면 특정 자세를 만들기위해 어떻게 모터를 조작해야되는지 대충 감이 올거같네요.

 

다음에는 좀더 심도있는 내용을 다뤄보도록 하겠습니다.

 

요새 개강도하고 과제도 슬슬 나올때라 진도가 늦네요 ㅠㅜ

 

 

 

 

Posted by 너를위한노래