지금까지 AI Turret의 Frame을 출력하면서 몇몇 문제들이 있었지만, 출력이 아예 불가능하진 않았다. 이상하게 Pan Module에서 계속 문제가 발생하고 있다... 🥲
이에 대한 원인을 찾고자 여러 시도를 해보았고, 이외에도 PC와 ESP32 간의 통신이 점점 월활히 이루어지고 있는 것 같다!!
지난 실험을 통해 YOLOv5를 이용해 Detect한 Object에 대해 B.Box의 각 모서리의 좌표값을 출력할 수 있었다. 이는 아래의 코드와 동일하며 각 모서리 값을 받아 B.Box(Bounding Box)의 좌표를 확인할 수 있다.
Object B.Box의 각 모서리의 좌표값 출력
for *xyxy, conf, cls in reversed(det):
c = int(cls) # integer class
label = names[c] if hide_conf else f'{names[c]}'
confidence = float(conf)
confidence_str = f'{confidence:.2f}'
# Write bounding box coordinates to console
print(f"Image: {p.name}, Class: {label}, Confidence: {confidence_str}, BBox: {xyxy}")
하지만 Servo Motor를 사용하여 Object Tracking을 하기 위해서는 B.Box의 모서리 좌표값이 아닌 B.Box의 중앙 좌표값이 필요하다.
각 모서리 좌표값을 출력하는 코드를 참고하여 중앙값을 구하는 계산식을 구하였으며, 아래 코드는 기존 B.Box 좌표 출력 코드에서 중앙값을 구하는 계산식을 더한 B.Box의 중앙값 출력 코드이다.
for *xyxy, conf, cls in reversed(det):
c = int(cls) # integer class
label = names[c] if hide_conf else f'{names[c]}'
confidence = float(conf)
confidence_str = f'{confidence:.2f}'
# Calculate central coordinates
x_center = (xyxy[0] + xyxy[2]) / 2
y_center = (xyxy[1] + xyxy[3]) / 2
# Print bounding box information
print(f"Image: {p.name}, Class: {label}, Confidence: {confidence_str}, Center Coordinates: ({x_center:.2f}, {y_center:.2f})\n")
B.Box가 생성되면 가로(x축)와 세로(y축) 각각의 중앙 정확히 절반을 찾아 B.Box의 정중앙값을 Webcam 해상도에 맞게 x,y좌표로 표시한다.
이렇게 출력된 Object에 대한 B.Box의 중앙값을 UART 통신을 활용하여 PC에서 ESP32로 전송하게 되면, Turret에 대한 기능을 동작할 수 있게 된다.
PC와의 UART 통신을 위해 “USB to TTL”모듈을 사용했으며 좌표전송을 확인하기 위한 Serial 통신 실험을 진행한 결과, 원하는 결과를 얻을 수 없었다.
PC에서의 바운딩 박스 검출 결과, 출력은 정상적으로 이루어졌지만 ESP32에서 통신 버퍼에 저장된 데이터가 순차적으로 모니터에 출력하는 것이 아닌 한 번에 값을 출력시키는 것처럼 보였다.
이런 상황이 발생했을 때의 문제점을 크게 2가지로 정리해보았다. 이러한 문제점들을 종합하면 AI Turret은 더 이상 실시간 detection이라는 의미를 잃어버리게 된다.
문제 1) 객체가 탐지되는 동안 전송되는 데이터는 없다.
문제 2) 데이터가 한 번에 전송되면 수많은 데이터를 한 번에 서보모터로 추적할 수 없다.
문제의 원인을 분석하기 위해 Serial통신에 대해 알아보던 중, 데이터 전송의 효율성과 처리 속도를 높이기 위해 한 번에 묶어 전송한다는 것을 알게 되었다.
예상 원인 1) 개별적으로 각 좌표를 전송하게 되면 오버헤드가 크고, 많은 데이터가 전송되어 처리 부하가 발생할 수 있다.
예상 원인 2) PC에서 한 번에 데이터를 전송하면 수신을 받는 쪽의 데이터를 한 번에 처리할 수 있어, 처리 속도 향상을 위해 한 번에 전송되는 것으로 보인다.
하지만 통신의 효율성과 처리속도 보다는 송수신의 좌표 하나하나 전달하는 실시간성이 더 중요하다. 따라서 실시간성을 살리기 위해 detect.py에 “time.sleep” 함수를 사용하여, YOLO의 Detection과 Serial통신의 싱크를 맞추어 주었다.
AI Turret의 목적은 추적과 타격을 목적으로 한다. 따라서 지금까지 추적을 위한 과정만 진행했다면, 이제는 타격을 위한 실험으로 Airsoft Gun의 구동 실험을 실시했다.
Airsoft Gun의 단-연발 Selector Switch는 항상 연발로 고정하여 실험 및 Turret에 배치할 예정이다.
만약 단발에 Switch를 두고 사격을 하게 된다면 해당 재품의 Selector Switch 동작 메커니즘에 의해 한 발만 발사한 후, 안전으로 Switch가 이동하기에 지속적인 수동 조작이 요구된다.
Airsoft Gun은 별도의 전원으로 1.5V 건전지 6개를 사용하여 9V의 전원을 인가할 계획이며, 격발에 대한 지시는 물체인식의 On/Off 신호를 Relay Module을 사용해서 제어할 예정이다.
Airsoft Gun에 건전지를 이용한 전원공급 및 동작 확인을 마친 상태이다.
하나 문제가 있다면, 탄알인 BB탄을 보관 및 공급해줄 탄창이다. 기존 제품에서의 탄창은 사람이 직접 탄을 공급하고 태엽을 돌려 탄을 공급해 줄 수 있는 메커니즘이었다.
하지만 AI Turret은 모두 자동화로 이루어질 것이기에 탄알을 자동으로 공급해줄 방안이 필요하다.
여기에 대해 아직 이상적인 아이디어가 없으며, 현재 이후의 탄창 설계에 대한 확장성을 고려하여 기존 Airsoft Gun - Gear Box Module에 탄창이 배치될만한 공간을 비워두었다.
추후 이 부분을 수정, 보완해야 할 점이며 여러 아이디어를 고안하고 실험해보고 있다.
Tilt Module 설계 형상이 매우 켰음에도 불구하고, 내부 채움(강도)를 대략 90% 정도 까지 높여 3D Printer 출력에 60시간 이상 소요되었다.
지금까지 4 번의 출력 시도 모두 실패했다...
특히, 출력물의 큰 크기에 의해 히팅 배드에 의한 온도의 영향을 덜 받아 룸의 온도가 떨어져 문제가 발생하였거나 또는 긴 출력 시간에 의해 출력 노즐의 과열로 인한 문제로 예상된다.
내부 채움 강도를 75%로 낮춰 출력에 소요되는 시간을 줄여 다시 출력을 시도하였다.
Tilt Module 뿐만 아니라, Pan Module도 Servo Motor, Gyro Sensor 연결부가 설계가 잘 못 되어 다시 설계하여 출력을 시도하였다.
좌 : 기존PanModule설계형상, 우 : Parts연결부재설계형상
기존 Pan Module과 Parts 연결부 재설계 Module과의 측면 형상 비교
위의 그림에서 볼 수 있듯이 Servo Motor를 배치하기 위한 공간이 더욱 확보되었으며, Gyro Sensor가 Servo Motor 바로 옆에 위치하는 것을 볼 수 있다. 이렇게 설계를 수정하면서 이전의 설계보다 더욱 효율적인 동작이 가능하도록 하였다.
또한 Pan Module도 한 번에 출력이 가능하도록 내부 채움 수치를 조정하여 30h가 넘지 않도록 하였다.
기존의 2st Axis Stabilizer Support Module에서 아크릴과 부착할 수 있도록 설계를 수 정하였다. 또한 마지막 Module을 최종적으로 설계함에 따라 AI Turret의 전반적인 크기를 알 수 있었고, 그에 따른 최종 형상을 결정할 수 있었다.
위의 출력물 또한 가급적 30h 내외의 출력 시간을 가질 수 있도록 설정하였다.
이렇게 재설계된 Frame을 바탕으로 AI Turret System 하단부에 배치될 아크릴 판의 크기를 짐작해보았는데, 대략 28.5 X 24(cm)으로 판단되었다.
AI Turret의 무거운 무게에 의해 불안정하기에 2층 구조가 아닌 1층 구조로 설계하기로 하였다. 여기에 배치될 아크릴 판의 크기 대략 28.5 X 40(cm)으로 예상된다. 이는 최종 형상이기에 해당 설계의 크기에 해당되는 아크릴 판과 관련 부품을 주문하였다.
안녕하세요 혹시 바운딩박스의 좌표값을 출력하는 코드는 detect.py를 수정해야 하는건가요?