이전 개발 일지를 작성한지 2주가 지났고 그동안 아래의 실험과 활동을 진행하였다.
이번 개발 일지는 저번 종합설계 일지 #1보다 양적인 면과 질적인 면에서 아쉬움을 느낄 수 있었다. 아마 중간고사의 영향을 받은거 같으며, 이외에도 여러 문제가 발생하여 많은 시간과 설계가 지연된 것 같다.
특히 Raspberry Pi를 사용함에 있어 약간의 어려움을 느꼈는데, 물리적으로 연결할 수 있는 모니터가 없어 상당 기간동안 OpenCV 및 ESP32와의 통신 등의 여러 실험을 진행할 수 없었다.
이전의 개발 일지의 "ESP32 환경에서 MPU6050을 활용한 Servo Motor 제어" 내용을 살펴보면 MPU6050 자이로 센서의 데이터를 활용하여 Servo Motor를 제어하는 것에 대해
위의 두가지의 문제점이 있었다. 이 문제는 Servo Motor 제어에 있어 발생한 문제가 아닌 MPU 6050에서 데이터를 받아오는 과정에서 생긴 문제로 생각된다.
MPU6050 자이로 센서에서 데이터를 읽는 속도와 수직면에 대해 초기화 되는 문제를 해결하기 위해 기존의 실험 코드에서 MPU6050에 대한 검증된 외부 라이브러리 사용함으로써 문제를 해결하는 것으로 진행하였다.
#include <MPU6050_light.h>
#include <ESP32_Servo.h>
#include <Wire.h>
MPU6050 mpu(Wire);
Servo servo1;
Servo servo2;
const int servo_x = 4;
const int servo_Y = 5;
int gryo_X, gryo_Y;
long angle_X, angle_Y;
String gyro_data;
String servo_data;
void setup() {
Serial.begin(115200);
Wire.begin();
byte status = mpu.begin();
mpu.calcOffsets();
servo1.attach(servo_x);
servo2.attach(servo_Y);
}
void loop() {
mpu.update();
angle_X = mpu.getAngleX();
angle_Y = mpu.getAngleY();
gryo_X = map(angle_X, -180, 180, 0, 180);
gryo_Y = map(angle_Y, -90, 90, 180, 0);
gyro_data = "Roll : " + (String)angle_X + " " + "Pitch : " + (String)angle_Y;
servo_data = "Servo_X : " + (String)gryo_X + " " + "Servo_Y : " + (String)gryo_Y;
servo1.write(gryo_X);
servo2.write(gryo_Y);
Serial.println(gyro_data);
Serial.println(servo_data);
delay(10);
}
실험에 사용된 코드는 위와 같으며 "MPU6050_light.h"라는 외부 라이브러리를 사용하여 MPU6050으로부터 자이로센서의 Roll, Pitch 방향으로 회전하는값을 받아왔다.
실험에서 180º 회전 Servo Motor를 사용하였기에 Roll, Pitch의 값을 최대 회전 각도에 맞게 동시화 시켜주기 위해 map 함수를 사용하였다.
2개의 Servo Motor와 두꺼운 철사를 사용하여 Stabilizer의 기능이 구현되는지 확인하는 실험을 진행하였으며 위의 사진처럼 자이로의 움직임을 보완해주는 반대 방향으로 동작하도록 Servo Motor를 동작시켰다.
이외에도 실험에서 발생한 문제 중 하나로, Roll 또는 Pitch 값이 수평면을 넘어 음수 값이 발생하게 되면 알 수 없는 값을 출력하는 문제가 있었다. 이번 실험에서는 이를 보완하였으며 위의 사진에서 볼 수 있듯이 특정 축의 회전 방향이 양수 또는 음수 값이 되어도 동작에 문제 없는 것을 확인할 수 있다.
자이로의 움직임과 반대 방향으로 Servo Motor를 동작하면 항상 Roll, Pitch의 값이 0º로 수평면에 수평한 상태로 유지될 거라고 생각하였지만 단순히 자이로가 움직인 만큼 반대로 움직이는 것을 확인할 수 있었다.
Pitch 값을 기준으로 하나의 Servo Motor를 사용하여 간단한 실험을 해보았는데, float의 크기로 출력되는 Y(Pitch) 값이랑 servo 값을 비교해보면 의도한 대로 작동하는 것을 볼 수 있다.
따라서 항상 Roll, Pitch이 0º으로 유지될 수 있는 기능을 더해야 한다는 것을 알 수 있었다.
AI Turret System에서 사용되는 Servo Motor는 총 6개로 Stabilizer 동작을 위한 Servo 4개, Turret 동작을 위한 Servo 2개로 구성되어 있다.
HS-311 For Stabilizer - DataSheet
FS5113R For Turret - DataSheet
아래의 회로도와 동일하게 용도별로 다른 2 종류의 Servo Motor을 사용하며 12V의 외부전원을 강압하여 병렬로 연결된 모터에 전원을 공급할 계획이다.
정격 전압에 해당하는 6V로 외부 전원(12V)을 강압하여 사용한다고 가정하였을 모터의 정상적인 작동을 위해 필요한 전류의 총량은 "7.2A"로, 이때의 값은 모든 모터가 동작을 하고 있다는 가정하에 계산한 Max 값이다.
외부 전원을 강압하여 System을 구현하는 것에 있어 주의할 점은 "전류"이다. 모터를 병렬 연결하여 구동하기에 전격 전압의 측면에서는 문제가 없다.
외부 전원을 강압하는 방법보다 더 좋은 해결책이 있을 것 같다... 🙈
Raspberry Pi가 Object를 탐지하기 위해 사용하는 카메라의 이미지 센서를 고려하면 해상도 측면에서 높은 성능을 보이지 않을 거라고 판단된다. 따라서 목표로 하는 대상을 적절할 크기를 가진 물체로 선정해야 한다.
가로 약 25cm, 세로 약 40cm의 "산타 인형"을 사용하기로 했다.
YOLO 학습을 위해 학습을 할려는 대상과 그에 대한 Labeling이 된 자료를 수집하여햐 하는데, 해당 자료를 직접 촬영하여 촬영물을 바탕으로 Labeling 작업을 진행하려 한다.
모델의 정확도를 높이기 위해 1000장 이상의 사진을 사용할 것이다. 또한 대상을 촬영할 때, 다양한 변수들을 적용하여 이후 Raspberry Pi 환경에서 Object 탐지를 하였을 때 속도 및 정확도를 개선할 것이다.
다양한 주변 환경, 촬영 구도, 사물의 위치 및 거리감 등의 다양한 요소들을 고려해서 학습 자료를 수집하고 있다.
Labeling 작업을 위해 "Labelimg"라는 툴을 사용하였으며 아래의 글을 참고 하였다.
항상 팀원이 다 모여 실험을 하는 자리에는 물리적으로 연결할 수 있는 모니터가 없었다. 따라서 한동안 Raspberry Pi를 사용하는 것이 불가능했지만, 아무 공유기에 Lan 포트를 Raspberry Pi와 연결하고 해당 공유기의 무선 네트워크로 노트북을 연결하여 "Putty"를 이용한 터미널을 사용할 수 있었다.
그리고 "VNC"를 사용하여 가상 모니터를 사용할 수 있어서 Raspberry Pi를 물리적 모니터 연결 없이 사용할 수 있게 되었다.
이전에 설정한 목표 중 일부만 진행되고 있어 아쉬움이 느껴진다. 특히 Raspberry Pi와 ESP32 간의 Serial 통신을 진행해야 하는데 계속 문제가 발생하여 실험에 어려움을 겪고 있다...