Today
-
Yesterday
-
Total
-
  • 각도로 회전 방향 알아내기
    Soliloquy 2019. 12. 22. 15:23

    ∠θ

     

    주위에서 스마트 암 밴드의 자이로센서를 활용한 로봇 팔 동작 연구를 하시던 형이 있었다. 해당 암 밴드 제조사에서는 밴드에 내장된 자이로센서 값을 라디안 값으로 불러올 수 있었고, 로봇 팔은 각도 값을 기준으로 움직일 수 있어서 실험에는 별 문제가 없는 듯했다.

     

    하지만 처음에는 잘 작동이 되는가 싶더니 로봇 팔이 가끔씩 지나치게 빠른 속도로 회전을 하는 문제가 있었다. 무엇이 문제일까 찾아보던 중 연구실 형은 데모 파일에서 2가지 문제점이 있었음을 발견하였다.

     

    1. 자이로센서 초기 값이 랜덤이어서 스마트 손목 밴드의 각도 값을 그대로 로봇 팔에 사용할 수 없다.
    2. 스마트 손목 밴드의 각도 값이 π 를 넘어가면 각도 값이 음수로 -π가 되는 문제가 발생했다. 이 문제가 로봇팔의 급발진 원인이 되었다.

     

    간단히 초기 값을 뺀 상태의 값을 로봇 팔에 대입을 하면 쉽게 해결되겠지 했는데, 두 번째 문제 때문에 사용하기가 곤란했다. π 값이 -가 될 때를 예외 처리하는 방법이 있긴 했지만, 구현하기에 힘든 점이 많았다. 괜히 복잡하게 구성했다가 나중에 코드가 더 꼬일 것 같은 기분이 들어서 다른 방법을 찾아보기로 하셨다.

     

    어떻게 보면 아주 큰 문제는 아니지만, 금방 해결될 줄로만 알았던 각도 문제가 좀처럼 해결되지 않았고, 옆에 있던 다른 친구와 나도 같이 머리를 맞대어 생각해 보기로 하였다.

     

    그렇게 형과 친구 그리고 나는 2시간이 넘도록 간단명료한 방법을 생각해 내기 위해 이런저런 방법을 생각하고 제시했다. 그러던 중, 극좌표 평면이 갑자기 머릿속에서 스쳐 지나갔다.

     

    극좌표 평면의 사용

     

    극좌표 평면은 한 점을 크기와 위상(각도)으로 나타내는 방법이었는데, 극좌표 평면에서는 각도가 π에서 -π, -0.5π가 되어도 문제없이 차례로 점을 찍을 수 있다는 특징을 이용하려는 시도를 하였다.

     

    스마트 암 밴드에서 전송받은 각도의 라디안 값을 α라 한다면 x1 변수에 cosα, y1 변수에 sinα 를 대입한다. 이후에 다음번에 스마트 암밴드로부터 받은 각도 값을 β이라다면, x2 변수에 cosβ, y2 변수에 sinβ 을 대입한다. 점 (x1, y1), 점 (x2, y2)를 이용하여 각도 문제를 해결을 해보는 시도를 하였다. [각주:1]

     

    좌표를 이용하면 -일 때를 고려하지 않아도 된다는 점이 정말 좋았지만, 컴퓨터가 회전 방향을 판단하는 방법에 대해서 고민을 좀 더 해봐야 했다. 보통 사람들은 극좌표 평면에 찍힌 점을 보고 어디서 어느 쪽으로 이동했다는 것을 직접 생각해서 알 수 있지만, 컴퓨터는 어떻게 판단해야 할까?

     

    첫 번째 방법. 사분면에 따른 움직임 측정

     

     

    가장 먼저 떠오른 것은 사분면에 따라서 어느 방향으로 움직일 것인지 정하는 방법이었다.

     

    (x1, y1)이 1 사분면에 위치하는 경우

    (x2, y2)에서 x1이 x2로 증가하였다면 오른쪽으로 회전한 것이 될 것이고, 반대로 x1이 x2로 감소하였다면 왼쪽으로 회전한 것이 될 것이다.

     

    ...

     

    (x1, y1)이 4사분면에 위치하는 경우

    (x2, y2)에서 x1이 x2로 증가하였다면 왼쪽으로 회전한 것이 될 것이고, 반대로 x1이 x2로 감소하였다면 오른쪽으로 회전한 것이 될 것이다.

     

    이러한 방식으로 1,2,3,4 분면에 대한 경우를 모두 생각하여 코드를 작성하는 방법을 선택을 했었다. 이때 움직인 각도는 간단히 | | arcsin(x1) | - | arcsin(x2) | | 을 하거나 내적을 이용하여 구하였다.

     

    하지만, 여기에는 문제점가 하나 있었는데, 1 사분면과 4 사분면의 경계면에서 갑자기 4 사분면으로 급격히 움직이는 경우 x2가 x1보다 작아져 실제로는 오른쪽으로 회전을 하였음에도 불구하고 계산상으로는 왼쪽으로 움직여질 수 있다는 문제였다.

     

    이러한 문제는 센서로부터 데이터를 받아오는 주기를 줄임으로서 어느 정도 막을 수는 있었지만, 여전히 완벽한 방법이 아니어서 나중에 문제가 될 것만 같았다. 이런 문제 많은 방법을 생각해내고 구현하고 나니 어느덧 3시간이 훌쩍 넘었다. 하는 수 없이 다음에 다시 생각해보기로 했다.

     

    두 번째 방법. 외적을 이용

    분명 첫 번째 방법보다 좀 더 간단명료한 방법이 있을 것만 같았다. 어떻게 하면 좋을지 생각하던 중 내적 말고 외적을 이용하면 어떨까?라는 생각이 들었다. 그리고 외적은 내적과 달리 방향의 차이에 따라서 -값과 +값을 각도로 볼 수 있기 때문에 이 문제를 해결하는데 정말 중요한 열쇠였다.

     

    움직여야 하는 각도는 외적을 이용하여 아래와 같은 수식으로 나타낼 수 있었다. [각주:2][각주:3]

     

    외적의 크기를 나타내는 식

     

    크기를 이용하여 각도(θ)를 구한 식

     

    외적 값(x1y2-x2y1)이 -로 나올 때에는 로봇 팔을 오른쪽으로, +로 나올 때에는 왼쪽으로 해당 θ만큼 움직이게 만들면 되었다.

     

    아니면 좀더 간단히 해서 아래와 같이 표현할 수도 있을 것 같다.[각주:4]

     

    분자를 크기 대신 외적 벡터 부호(각도) 까지 포함한 식

     

    이렇게 하면 외적값이 -가 나오면 각도 arcsin값도 -가 나올태니 이러면 조건문 사용 갯수도 줄일 수 있지 않을까?

     

    이처럼 외적을 이용하면 코드 몇줄로 방향과 각도를 파악할 수 있었다. 외적이 이런데에 사용될 수도 있다니... 놀랍다.

     

    다만 아쉽게도 이 방법도 약간의 문제가 있었다. 바로 센서가 데이터를 보내는 주기보다 더 빠르게 90도 이상 180도 미만의 각을 순간적으로 시계/반시계 방향으로 돌려버리면 계산 상으로는 90도 보다 더 적게 시계/반시계 방향으로 돌린 것으로 된다.

     

    또한 동일하게 180도 이상의 각도를 전송 주기보다 빠르게 회전시키면 반시계/시계 방향으로 돌린 것 처럼 계산이 되는 문제가 있다. 누가 0.01초만에 90도 이상으로 팔을 돌릴수 있긴 하겠냐만은..

     

    만약 그런 경우를 대비한다면 센서가 데이터를 받아오는 속도를 최대한 빠르게 하는 것이 가장 좋을 것이고(데이터 처리속도도 그만큼 빨라야 한다.) 그것도 힘들다면 별도의 센서를 더 추가 해야할 듯 하다.

     

    참... 이게 뭐라고...

     

    [본문 SVG 파일]

     

    Cartesian_coordinates_2D.svg
    0.06MB

     

    [글 대표 이미지 파일]

     

    angle.svg
    0.01MB

     

    1. 이 문단 이후로는 티스토리 에디터가 아래첨자 옵션을 기본으로 지원하지 않아서 아래첨자를 쓰는 대신 x1, y1, x2, y2 로 쓰기로 했다. [본문으로]
    2. |\\overrightarrow { a } \\times \\overrightarrow { b } |=|\\overrightarrow { a } ||\\overrightarrow { b } |sin\\theta [본문으로]
    3. TEX: \\theta = \\arcsin { \\frac { { |x }_{ 1 }{ y }_{ 2 }-{ x }_{ 2 }{ y }_{ 1 }| }{ \\sqrt { { { x }_{ 1 } }^{ 2 }+{ { y }_{ 1 } }^{ 2 } } \\sqrt { { { x }_{ 2 } }^{ 2 }+{ { y }_{ 2 } }^{ 2 } }  }  }  [본문으로]
    4. \\theta =\\arcsin { \\frac { { x }_{ 1 }{ y }_{ 2 }-{ x }_{ 2 }{ y }_{ 1 } }{ \\sqrt { { { x }_{ 1 } }^{ 2 }+{ { y }_{ 1 } }^{ 2 } } \\sqrt { { { x }_{ 2 } }^{ 2 }+{ { y }_{ 2 } }^{ 2 } }  }  } [본문으로]

    댓글

어제는 이곳에 명이 다녀갔습니다.

Powered & Designed by Tistory