이전 글을 작성한 이후, 종합설계 시작!에서 정리한 "구현 기능 정리" 내용 중에서 몇 가지 실험도 하였고 이번 프로젝트에 사용할 수 있을 지에 대한 고민도 많이 해보았다.
이번 종합설계의 주제인 "AI Tracking Turret"에 Raspberry Pi Cluster의 사용이 객체 탐지에 기능적으로 효과적인지, 이를 구현하는데에 소요되는 예산이 얼마인지 그리고 소요 예산만큼의 가성비가 있을지에 대한 의문이 들어 여러 자료들을 찾아보았다.
“라즈베리 파이를 이용한 병렬처리 시스템 구축” 논문을 살펴보면 Raspberry Pi를 Cluster로 활용하기 위해 자체 Benchmark를 만들어 노드의 버전 및 개수 별로 수행시 간과 수행속도를 구한 것을 볼 수 있다.
여기서 노드의 개수가 증가함에 따라 전반적인 성능이 선형적으로 늘어나지 않는다는 점을 알 수 있다.
이는 암달의 법칙에 의한 것으로 노드가 늘어남에 따라 선형적으로 성능이 증가하지 않고 한계가 존재한다는 것이다.
강석원.김재윤.이상준.송왕철,「라즈베리 파이를 이용한 병렬 처리 시스템 구축」, 한국콘텐츠학회, 2017, 21-22쪽.
“라즈베리 파이 클러스터 환경에서의 병렬 프로그래밍2)”논문에서 Raspberry Pi Cluster에 MPI를 통해 소수를 구하는 자체 Benchmark를 만들어 Raspberry Pi 하나만 수행한 순차 처리와 다수의 노드를 활용하여 수행한 병렬 처리를 비교한 실험을 찾아볼 수 있다.
위의 여러 실험을 바탕으로 Raspberry Pi의 프로세서를 사용할 때, 순차처리를보다 더욱 상향된 연산 능력을 보여주는 병렬처리를 사용하는 것이 효율적임을 알 수 있었다.
정용재.김동관,「라즈베리 파이 클러스터 환경에서의 병렬 프로그래밍」, 한국컴퓨터정보학회 동계학술대회 논문 집, 제22권 제1호, 2014, 477-478쪽.
AI Turret은 객체를 탐지하기 위해 YOLO 모델을 사용하며, 이는 수많은 Convolution 연산이 필요로 하기에 빠른 연산이 가능한 Raspberry Pi Cluster는 프로젝트 구현에 있어 필수적이라고 느껴진다.
하지만 현실적인 문제로 접근해보면 총 3명인 우리 팀은 최대 30만원의 예산을 지원 받을 수 있다. 그리고 Raspberry Pi Cluster를 구현하기 위해서는 1대의 Master Raspberry Pi와 2 대의 Slave Raspberry Pi가 필요하다.
그러나 2학기 간의 종합 설계 중, Raspberry Pi를 우연히 구할 수 있게 된다면 Cluster를 구현해 볼 것이기에 Raspberry Pi Cluster와 병렬처리에 대해 여러 자료 및 논문을 찾아보았다.
따라서 결론은 Raspberry Pi를 별도로 구하기 전까지는 하나의 Raspberry Pi를 활용하여 프로젝트를 수행한다는 것이다!
MPU6050(Gyro Sensor)를 사용하여 Stabilizer을 구현하기 전, MPU6050의 센싱 데이터를 활용하여 Y축으로 회전하는 Pitch 값을 추출하고 이를 기반으로 서보를 동작해보는 실험을 진행하였다.
#include <ESP32_Servo.h>
#include <Wire.h>
#define mpu_add 0x68 //mpu6050 address
static const int servoPin = 4;
Servo servo1;
long ac_x, ac_y, ac_z, gy_x, gy_y, gy_z;
/***** Pitch Angle + Fliter *****/
double Angle_Pitch = 0, Deg_Pitch; // angle, Deg_Pitch data double dgy_x; //double type acc data
/***** Roll Angle + Fliter *****/
double Angle_Roll = 0, Deg_Roll; // angle, Deg_Pitch data double dgy_y; //double type acc data
void setup() {
Wire.begin();
Wire.beginTransmission(mpu_add);
Wire.write(0x6B);
Wire.write(0);
Wire.endTransmission(true);
Serial.begin(115200);
servo1.attach(servoPin);
}
void loop() {
Deg_Pitch = atan2(ac_x, ac_z) * 180 / PI; //rad to Deg_Pitch
dgy_x = gy_y / 131.; //16-bit data to 250 Deg_Pitch/sec
Angle_Pitch = (0.95 * (Angle_Pitch + (dgy_x * 0.001))) + (0.05 * Deg_Pitch); //complementary filter
Deg_Roll = atan2(ac_y, ac_z) * 180 / PI; //rad to Deg_Roll
dgy_y = gy_x / 131.; //16-bit data to 250 Deg_Roll/sec
Angle_Roll = (0.95 * (Angle_Roll + (dgy_y * 0.001))) + (0.05 * Deg_Roll); //complementary
filter
servo1.write(Angle_Pitch);
Serial.print("Pitch : ");
Serial.println(Angle_Pitch);
delay(20);
}
void getData() {
Wire.beginTransmission(mpu_add); //get acc data Wire.write(0x3B);
Wire.endTransmission(false); Wire.requestFrom(mpu_add, 6, true);
ac_x = Wire.read() << 8 | Wire.read();
ac_y = Wire.read() << 8 | Wire.read();
ac_z = Wire.read() << 8 | Wire.read();
Wire.beginTransmission(mpu_add); //get gyro data Wire.write(0x43);
Wire.endTransmission(false);
Wire.requestFrom(mpu_add, 6, true);
gy_x = Wire.read() << 8 | Wire.read();
gy_y = Wire.read() << 8 | Wire.read();
gy_z = Wire.read() << 8 | Wire.read();
}
위의 코드와 아래의 회로도로 실험을 진행하였으며 MPU6050의 Pitch 각도 값의 변화에 따라 서보모터도 동일하게 동작하는 것을 확인할 수 있었다.
위 실험을 통해 MPU6050를 활용하여 Servo Motor를 동작시키는 것이 가능하다는 것을 알 수 있었지만 몇몇 문제가 발생하였다.
MPU6050의 변화가 생기고 아주 짧은 타이밍이 지난 후에 서보모터가 동작
Pitch 축의 범위 및 수평면에 수직인 축에 대해 0º - 180º으로 초기화
MPU6050를 바닥에 기대에 Pitch 축으로 회전시키면 위 문제가 발생하지 않기에 위의 사진과 같이 실험을 진행하였다.
약간 느린 반응속도지만 별도의 코드 수정 없이 쓸만할지도,,?
ESP32가 제어하는 대상 중 가장 큰 비중을 차지하는 것이 Stabilizer와 Turret이며 Stabilizer는 왼쪽 위의 그림에서 알 수 있듯이 X와 Y 축에 해당되는 Frame을 설계하여 해당 축에 연결된 Servo Motor가 해당 Frame을 지지하고 축 기준으로 회전시키는 역할을 하게 된다.
Turret의 하중을 Servo Motor가 아닌 Stabilizer의 Frame에 부하가 실리도록 설계하였으며 원활한 회전을 위해 볼베어링을 사용할 계획이다.
또한 Turret에 대기어를 부착하여 소기어가 부착된 Servo Motor가 토크 문제없이 회전시킬 수 있도록 설계하는 방향으로 Turret의 동작 구조를 고안하였다.
모형 총 내부의 Gear Box의 크기를 기반으로 Stabilizer와 Turret의 설계가 가능하기에 우선적으로 H/W를 분석해보았다.
Gear Box 내부에 여러 기어가 있고 이를 활용하여 피스톤을 후퇴시켜 격발하는 방식이었다.
단발과 연발 모드가 가능했는데, 이는 별도의 PCB를 통해 모터를 제어하여 동작하는 것이 아닌 기계적인 구조로 이루어진 Selector Switch에 의해 모터의 동작 시간을 제어하는 방식
Gear Box의 트리거에 의해 격발되는 것이 아닌 Gear Box 내부의 스위치에 의해 동작하는 것임을 확인
릴레이 모듈이나 모터 드라이버 모듈을 이용하여 격발을 제어할 수 있을 것을 예상
모터에 인가되는 전원의 시간만 제어해주면 단발과 연발 모두 사용 가능
Raspberry Pi 4 B가 객체를 탐지하고 ESP32가 객체 트레킹 및 Turret의 안정화를 위한 Stabilizer로 기능을 분리하였다. 이는 Raspberry Pi가 객체 탐지를 위한 YOLO 모델의 연산을 수행할 때, 프로세서의 성능이 부족하여 제어까지 담당하기 부담되기에 ESP32가 실시간 제어를 담당하게 되었다.
이외에도 강한 출력을 내는 서보모터를 6개와 6V 모터를 사용하는 Airsoft Gun의 기어박스를 구동하기 위해서는 안정적이고 높은 전압을 요구하는데 ESP32의 출력 전원으로는 동작이 어려울 것 같다.
이 문제를 해결하기 위해 배터리 등의 외부 전원을 별도로 공급할 것
AI Turret의 Proto-Type의 프레임을 제작하기 위해 위의 3 가지 부품을 Google SketchUp을 이용하여 설계하였다.
ESP32
1ch Relay Module
Servo Motor
이는 동작 메커니즘이 잘 구현되는지 또는 부품의 체결 및 위치가 잘 맞는지 확인하기 위한 작업으로 Proto-Type의 프레임 기반으로 문제점을 검증하고 이후, Fusion360으로 더욱 정교한 Main 프레임을 설계하여 3D Printer를 통해 H/W를 구현할 것이다.
이전 글에서 목표했던 향후 계획 중에서 잘 진행된 것도 있었고 아직 접해보지도 못한 것들도 있는 것 같다.