스마트 펜: 라즈베리파이와 IMU로 실시간 필기·모션 추적
소개
디지털 시대에 필기 입력을 캡처하려면 보통 정전식 터치스크린이나 스타일러스 펜이 필요합니다. 정밀하지만 이러한 솔루션은 표면 제약이 있고 진정한 공간 자유도가 부족합니다. 우리 스마트 펜은 라즈베리파이와 관성측정장치(IMU)를 결합해 모션을 추적하고 궤적을 즉시 재구성함으로써 이러한 제약을 극복합니다. 시스템은 IMU의 자이로스코프와 가속도계만 활용해 데이터를 무선으로 라즈베리파이에 전송합니다. 맞춤 알고리즘으로 장치의 방향과 위치를 복원하고, 데이터를 저장하며, pygame을 통해 라즈베리파이 TFT 디스플레이에 실시간 렌더링합니다. 단일 푸시 버튼으로 녹화 시작/정지가 가능해 펜, 로봇, 웨어러블 등 다양한 용도로 유연하게 활용할 수 있습니다. 이 방식은 필기 캡처, 모션 분석 등을 위한 다재다능한 표면 비의존적 솔루션을 제공합니다.
목표
핵심 목표는 펜, 로봇, 심지어 인체 사지에도 부착 가능한 모듈형 추적 장치를 개발하는 것입니다. 호스트가 움직이면 모듈은 궤적을 기록하고 화면상의 수평 월드 프레임에 경로를 투영합니다. 기존 스타일러스 시스템과 달리 우리 설계는 미리 정의된 평면에 의존하지 않아 자유 공중이나 불규칙한 표면에서의 움직임을 추적할 수 있습니다. 모듈의 방향 비의존적 성능은 기울기나 배치에 관계없이 일관된 결과를 보장합니다.
IMU 캘리브레이션
제조 공차로 인해 IMU의 가속도계와 자이로스코프 축이 정렬되지 않아 오일러 각도 계산에 오차가 발생합니다. 이를 정량화하고 보정하기 위해 6자세 캘리브레이션 루틴을 사용합니다. 커스텀 캘리브레이션 지그(Figure XX)로 IMU를 각 자세에 고정하고 원시 센서 값을 기록합니다. 이 6개 샘플로부터 도출된 캘리브레이션 행렬을 모든 가속도계 측정에 적용합니다:
\[\mathbf{A}_{\text{cal}} = \begin{bmatrix}A_x\\A_y\\A_z\end{bmatrix}, \quad \mathbf{a}_{\text{raw}} = \begin{bmatrix}a_x\\a_y\\a_z\end{bmatrix}\]
캘리브레이션 후 보정된 가속도 벡터 \(\mathbf{A}_{\text{cal}}\)이 후속 처리를 위한 원시 데이터를 대체합니다.
원시 데이터 센서 퓨전
강건한 자세 추정을 위해 자이로스코프와 가속도계 출력을 쿼터니언 수학으로 융합합니다. 쿼터니언은 특이점 없는 회전 표현과 벡터 변환 단순화 이점을 제공합니다. 쿼터니언 \(q\)와 오일러 각도 \((\alpha,\beta,\gamma)\) 간 변환은 다음과 같습니다:
\[\displaystyle q = \cos\frac{\theta}{2} + \sin\frac{\theta}{2}\bigl(\cos\alpha\,\mathbf{i} + \cos\beta\,\mathbf{j} + \cos\gamma\,\mathbf{k}\bigr)\]
고정 벡터 \(\mathbf{V} = V_x\mathbf{i} + V_y\mathbf{j} + V_z\mathbf{k}\)에 대한 쿼터니언 회전은 \(\mathbf{V}' = q \circ \mathbf{V} \circ q^{-1}\)로 수행됩니다.
자이로스코프만으로는 시간이 지날수록 드리프트가 발생하므로, 가속도계에서 측정된 중력 벡터와 자이로스코프 유도 중력 추정치를 지속적으로 비교해 바이어스를 보정합니다. UpdateIMU 루틴은 센서가 정지 상태일 때 2,000회 반복 실행되며, 비례-적분(PI) 피드백 루프를 구성해 각도 오차를 최소화합니다. 알고리즘 핵심은 다음과 같습니다:
def UpdateIMU(self, Gyr, Acc): if np.linalg.norm(Acc) == 0: warnings.warn("Accelerometer magnitude is zero. Algorithm update aborted.") return Acc = np.array(Acc / np.linalg.norm(Acc)) v = np.array([[2*(self.q[1]*self.q[3] - self.q[0]*self.q[2])], [2*(self.q[0]*self.q[1] + self.q[2]*self.q[3])], [self.q[0]**2 - self.q[1]**2 - self.q[2]**2 + self.q[3]**2]]) error = np.cross(v, np.transpose([Acc]), axis=0) self.IntError += error Ref = Gyr - np.transpose(self.Kp*error + self.Ki*self.IntError) pDot = 0.5 * self.quaternProd_single(self.q, [0, Ref[0,0], Ref[0,1], Ref[0,2]]) self.q += pDot * self.SamplePeriod self.q /= np.linalg.norm(self.q) self.Quaternion = self.quaternConj(self.q)
보정된 자이로스코프 데이터(Ref)가 쿼터니언 업데이트에 입력되어 안정적인 자세 추정을 생성하며, 이는 라즈베리파이에 표시되는 궤적 재구성을 구동합니다.
자세히 보기: 스마트 펜 - ECE5725 최종 프로젝트