Android2015. 1. 27. 20:40

어플에 바코드나 QR코드 인식 기능을 넣는 방법엔 두가지가 있습니다. 첫번째는 intent로 바코드 인식 기능이 있는 앱(ex.바코드리더기)을 실행시킨 후 결과를 받는거구요, 두번째는 아예 앱 자체에 바코드 인식 기능을 넣어버리는 겁니다.


첫번째 방법은 구현하기 매우 간단하지만 바코드리더기 앱이 없고 인터넷이 안되는 상황이라면 만든 앱이 정상작동을 안하겠죠..


두번째는 라이브러리 구해서 추가하고 매니패스트 수정하고 등등 할게 많지만 독립적으로 운용 가능한 앱을 만들 수 있다는 장점이 있습니다.


이번 포스팅에서는 두번째 방법에 대해 간단히 설명하려 합니다. 자세한 설명은 밑의 출처 링크를 클릭해서 보시구요. 저는 겪은 시행착오에 대해 언급하겠습니다.


먼저, 출처에 소스코드가 있지만 혹시나 해서 여기에도 올리겠습니다.


zxing_exam.zip


먼저 만들어진 앱에 이 부분만 붙이신다면 우선 core.jar를 옮겨야 하구요.


com.google.zxing.client.android

com.google.zxing.client.android.camera

com.google.zxing.client.android.integration

com.google.zxing.client.android.result


그리고 이 네개의 패키지를 모두 옮겨야 사용 가능합니다.


물론 매니페스트나 xml파일은 위 패키지들 안의 소스에 맞게 수정하고 옮기셔야 작동하겠죠


이렇게 해서 바코드 스캐너 기능을 가진 앱을 만들 수 있는데, 약간 꺼림칙한 부분이 있어요. 단말기에 바코드 스캐너 앱이 여러개 설치되어있는 경우, 어떤걸 열건지 물어보는 창이 뜨게되는데 아마 intent 이름이 같아서 선택하라고 뜨는것 같습니다. 우리는 앱 내부에 있는 클래스(CaptureActivity)를 열기 때문에 다른 앱은 필요가 없죠. 이걸 없애는 방법은 다음과 같습니다.


IntentIntegrator 클래스에서

Intent intentScan = new Intent("com.google.zxing.client.android.SCAN"); 부분을

Intent intentScan = new Intent(activity, CaptureActivity.class); 로 바꾸고


CaptureActivity클래스에서

if (intent != null && action != null) 부분의 else 부분에 

source = Source.NONE;

decodeFormats = null;

characterSet = null;

가 있는데 이걸

Source.NATIVE_APP_INTENT;
decodeFormats = DecodeFormatManager.parseDecodeFormats(intent);
characterSet = intent.getStringExtra(Intents.Scan.CHARACTER_SET);

로 바꾸면 됩니다.


여러군데 흩어져 있는 정보를 짜깁기해서 만든 포스팅이라 좀 혼잡하네요.. 



출처 - http://theeye.pe.kr/archives/1339








Posted by 너를위한노래

댓글을 달아 주세요

  1. ky

    안녕하세요 지나가는 하수 ky라고 합니다.

    QR코드에 대한 정보를 잘 봤습니다.

    올려주신 소스를 다운받아 import시켜 실행한 결과 잘 됩니다.

    하지만 자체 내부의 바코드 기능인식을 넣는 부분이 잘 되지 않아 이렇게 글을 남깁니다.

    위에 말씀하신대로, IntentIntegrator 클래스에서
    Intent intentScan = new Intent("com.google.zxing.client.android.SCAN"); 부분을
    Intent intentScan = new Intent(activity, CaptureActivity.class); 로 바꾸고

    CaptureActivity클래스에서
    if (intent != null && action != null) 부분의 else 부분에
    source = Source.NONE;
    decodeFormats = null;
    characterSet = null;
    가 있는데 이걸
    Source.NATIVE_APP_INTENT;
    decodeFormats = DecodeFormatManager.parseDecodeFormats(intent);
    characterSet = intent.getStringExtra(Intents.Scan.CHARACTER_SET);

    로 변경하였으나, 실행이 되지 않습니다.

    참고로 Source.NATIVE_APP_INTENT; 부분이 오류가 나서 source = Source.NATIVE_APP_INTENT;로 변경하여 돌렸습니다.

    로그는 다음과 같습니다.

    09-09 09:38:42.660: E/AndroidRuntime(31711): FATAL EXCEPTION: main
    09-09 09:38:42.660: E/AndroidRuntime(31711): Process: kr.pe.theeye.qrcode, PID: 31711
    09-09 09:38:42.660: E/AndroidRuntime(31711): java.lang.NoClassDefFoundError: com.google.zxing.ResultMetadataType
    09-09 09:38:42.660: E/AndroidRuntime(31711): at com.google.zxing.client.android.CaptureActivity.<clinit>(CaptureActivity.java:70)
    09-09 09:38:42.660: E/AndroidRuntime(31711): at java.lang.Class.newInstanceImpl(Native Method)
    09-09 09:38:42.660: E/AndroidRuntime(31711): at java.lang.Class.newInstance(Class.java:1208)
    09-09 09:38:42.660: E/AndroidRuntime(31711): at android.app.Instrumentation.newActivity(Instrumentation.java:1066)
    09-09 09:38:42.660: E/AndroidRuntime(31711): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2142)
    09-09 09:38:42.660: E/AndroidRuntime(31711): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2275)
    09-09 09:38:42.660: E/AndroidRuntime(31711): at android.app.ActivityThread.access$800(ActivityThread.java:142)
    09-09 09:38:42.660: E/AndroidRuntime(31711): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1220)
    09-09 09:38:42.660: E/AndroidRuntime(31711): at android.os.Handler.dispatchMessage(Handler.java:102)
    09-09 09:38:42.660: E/AndroidRuntime(31711): at android.os.Looper.loop(Looper.java:136)
    09-09 09:38:42.660: E/AndroidRuntime(31711): at android.app.ActivityThread.main(ActivityThread.java:5091)
    09-09 09:38:42.660: E/AndroidRuntime(31711): at java.lang.reflect.Method.invokeNative(Native Method)
    09-09 09:38:42.660: E/AndroidRuntime(31711): at java.lang.reflect.Method.invoke(Method.java:515)
    09-09 09:38:42.660: E/AndroidRuntime(31711): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:792)
    09-09 09:38:42.660: E/AndroidRuntime(31711): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:608)
    09-09 09:38:42.660: E/AndroidRuntime(31711): at dalvik.system.NativeStart.main(Native Method)

    답변해 주시면 정말 감사하겠습니다.

    그럼 오늘도 좋은 하루 되세요.

    2015.09.09 09:41 [ ADDR : EDIT/ DEL : REPLY ]
    • sss

      저도 똑같이 오류 나는데 혹시 해결 하셨나요?ㅠㅠ

      2015.12.02 11:15 [ ADDR : EDIT/ DEL ]
    • 나그네

      안녕하세요. 지나가는 나그네입니다.
      정의안된클래스다. 라는 에러가 있네요.
      메니페스트에 액티비티로 등록안하셔서 발생하는 에러인것 같네요.

      2016.01.18 09:32 [ ADDR : EDIT/ DEL ]

Quadrotor20132013. 4. 22. 12:18

음... 이번이 두번째네요 보드가 고장난거는..

 

한두푼도 아니고 왜 이러는지... ㅠ

 

첫번째꺼는 쿼드콥터의 BLDC모터랑 전원을 같이 써서 고장 났다고 쳐요, 두번째꺼는 아예 배터리도 따로 쓰고 메뉴얼의 전압대로 맞춰서 썼는데 왜 잘 사용하다가 갑자기 그러냐고요 ㅡㅡ

 

IOIO보드는 좋은 보든데.. 쿼드콥터 하실때는 사지 않으시길 추천드립니다.. ㅠ 두번째도 고장나니까 회로 자체가 불안한게 아닌가 하는 생각도 들고..

 

이왕 이렇게 된 김에 어떻게 할까.. 고민하다가 제가 가지고 있는 아두이노 Mega 2560 보드를 사용할 수 있을거같아서 필요한 케이블 주문해 놨습니다.. 이제 포스팅에 아두이노 글도 올리겠네요 ㅎ

 

근데 제가 사용하는 mpu6050안에 LPF가 내장되어있다는데 이거 쓰려면 아두이노가 편하더라구요 LPF써서 잘되면 좋을텐데.. ㅋ

 

위기가 기회가 될지도 모르겠습니다 ㅋㅋ

Posted by 너를위한노래

댓글을 달아 주세요

  1. 안녕하세요.
    사용하신 보드가 안드로이드 IOIO 'OTG' 이신지요?
    저도 장난감 만들고 있는중 보드가 나가버려서 검색해 봤더니 Voltage Regulator에 문제가 있다네요.
    https://groups.google.com/forum/#!searchin/ioio-users/sparkfun/ioio-users/1RCdDQkSJvo/_FIzyDw9Wt8J

    2013.09.01 16:44 [ ADDR : EDIT/ DEL : REPLY ]
    • 아.. 이럴수가.. 저는 그것도 모르고 왜 안되는지 엄청 고생했는데.. 구매한 곳에 문의해 봐야겠습니다.ㅠ 저는 그냥 ioio보드지만 같은 이유일거라 생각됩니다. 정보 감사드려요~

      2013.09.07 17:02 신고 [ ADDR : EDIT/ DEL ]

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. 13. 18:01

 

원래 네이버 블로그에 있는 글을 모두 옮겨오려고 했지만.. 굳이 그럴 필요 없을거 같아서 이 글에 제목과 링크만 올려두겠습니다.

 

네이버 블로그 주요 포스팅:

쿼드콥터 초기 계획안 

재료, 부품 구매 현황

MPU-6050 3축 자이로 + 3축 가속도 센서 구매 

[스크랩]오일러각 

[스크랩] I2C (Inter-Integrated Circuit) 버스 

[스크랩]칼만 필터(Kalman Filter) - Part 1 : Linear Systems | Robotics 

[스크랩]칼만 필터(Kalman Filter) - Part 2 : Kalman Filter & Algorithm | Robotics 

 

 

현재는 가속도, 자이로 센서 값을 이용해서 칼만필터로 융합한 다음, Q행렬, H행렬을 조정하는 단계입니다.

 

 

노랑, 자주 : 가속도

빨강, 초록 : 가속도 + 자이로 using 칼만필터

 

여러가지 상황에 대해 테스트하고 있는데 쿼드콥터 진동이 장난이 아니더라구요.. ㅠ

 

어느 정도는 칼만필터로 보정할 수 있겠거니~ 했는데 이건 너무 심해서 기구적으로 손을 보고 있습니다.

 

그래서 스펀지로도 방진 해보고 고무줄로 진동을 줄여보고자 노력했지만 별로 효과는 없더라구요..

 

   

 

 RPM은 모두 동일

   

 스펀지 장착

 고무줄 장치 장착

 

위의 테스트에서는 RPM이 낮은데 높게하면 +90도~-90도 화이트노이즈수준으로 심하게 감지되더라구요 ㅠ

모터랑 센서가 싸구려라 그런가... ㅠ

 

아예 모터에서 발생하는 진동을 제거하는 방향으로도 해봐야겠습니다.

 

 

안드로이드 소스파일(accel gyro Kalman Filter, PWM generate):

SimpleAnalogInputActivity.java

GraphView.java

Matrix.java

SnowCube.java

SnowRenderer.java

 

 

 

 

Posted by 너를위한노래

댓글을 달아 주세요

  1. GTS

    고무줄을 이용한 방진장치.. 작은 키캠에 사용하기엔 정말 딱일것 같습니다. 고무줄을 조금 느슨하게 하면 조금이라도 진동을 흡수하지않을려나요?ㅎㅎ

    2013.04.01 22:45 [ ADDR : EDIT/ DEL : REPLY ]
    • 아 네이버 블로그에 있던 그 학생이시군요~ 현재 고무줄도 조금 느슨하게 바꿨고 중간 센서 밑에 납으로된 추도 달아 놨는데.. 자잘한 진동에는 효과있을지 몰라도 큰 진동에는 역시 변화가 없네요.. ㅠ 일단 자세제어부터 하고 다시 손 봐야겠습니다. ㅠ

      2013.04.02 13:17 신고 [ ADDR : EDIT/ DEL ]