제21회 임베디드 소프트웨어 경진대회 자유공모 부문에 출품한 HYMEC01 프로젝트 저장소입니다.
이 프로젝트는 해당 대회 자유공모 부문에서 장려상을 수상했습니다.
HYMEC01은 Arduino 기반 임베디드 제어 코드와 ROS2 기반 로봇 제어 패키지를 함께 포함하는 프로젝트입니다. 저장소에는 최종 프로토타입 코드, 계산 및 레이저 제어용 Arduino 스케치, 그리고 노트북 컨트롤러와 여러 로봇 노드를 실행하기 위한 ROS2 패키지가 포함되어 있습니다.
.
├── Arduino code/
│ ├── FINAL_ES_Prototype/
│ ├── FINAL_calculations/
│ ├── FINAL_laserCode/
│ └── library/
└── ROS2 Package/
└── HYMEC01/
└── HYMEC01/
Arduino code 디렉터리에는 임베디드 제어용 Arduino 스케치와 커스텀 하드웨어 제어 라이브러리가 포함되어 있습니다.
FINAL_ES_Prototype/FINAL_ES_Prototype.ino: 최종 임베디드 시스템 프로토타입FINAL_calculations/FINAL_calculations.ino: 계산 및 테스트용 스케치FINAL_laserCode/FINAL_laserCode.ino: 레이저 제어용 스케치library/: Hymechan 커스텀 라이브러리
FINAL_ES_Prototype.ino는 로봇의 메인 제어 루프입니다. Raspberry Pi 또는 ROS2 노드에서 들어오는 Serial 명령을 해석하고, UWB 거리 측정값과 레이저 센서값을 이용해 로봇의 이동과 정렬을 수행합니다.
주요 동작 모드는 다음과 같습니다.
0: 사각형 대형 조립1: 세로 대형 조립2: 가로 대형 조립3: 전후 이동4: 좌우 이동5: 분해 및 원위치 복귀6: 제자리 회전
명령 처리는 rxCommand()에서 이루어집니다. 전체 로봇 대상 명령, 특정 로봇 대상 명령, 준비 완료 신호, 강제 정지 및 초기화 명령을 구분해 내부 mode와 목표 이동량을 갱신합니다.
FINAL_calculations.ino는 목표 위치까지의 이동량과 PWM 구동 시간을 계산합니다.
calcCurrentPos(): UWB 거리 데이터가 모두 들어올 때까지 대기한 뒤 현재 위치를 계산합니다.trilateration(): 3개의 앵커 거리값을 이용해 현재 좌표를 추정합니다.calcDelta(): 사각형, 세로, 가로 대형 목표 좌표와 현재 좌표의 차이를 계산합니다.convDtoDelay(): 이동 거리와 회전 각도를 모터 구동 시간으로 변환합니다.
FINAL_laserCode.ino는 전면과 측면 레이저 센서를 이용해 다른 로봇과의 상대 위치를 맞춥니다.
updateLaser(): 전면/측면 레이저 거리값을 갱신합니다.sendLaserData(): 측정된 레이저 값을 디버그 메시지로 전송합니다.isLaserAligned(): 좌우 레이저 값 차이와 거리 임계값을 기준으로 회전, 직선 이동, 전진, 정렬 완료 상태를 판단합니다.
Arduino code/library에는 모터, 자석, 레이저 센서를 제어하는 공통 함수가 들어 있습니다.
MotorControl.cpp: 메카넘 휠 기반 전후 이동, 좌우 이동, 대각 이동, 제자리 회전을 제어합니다.MagnetControl.cpp: 로봇 결합용 전자석 핀을 초기화하고 켜거나 끕니다.LaserControl.cpp: I2C 기반 레이저 거리 센서에서 거리값을 읽습니다.Hymechan.h: 각 제어 함수와 핀 번호, 센서 주소를 정의합니다.
ROS2 패키지는 다음 위치에 있습니다.
ROS2 Package/HYMEC01/HYMEC01패키지에는 노트북 컨트롤러와 4개의 로봇 노드가 포함되어 있습니다.
laptoprobot1robot2robot3robot4
laptop.py는 사용자 입력을 받아 command 토픽으로 명령을 발행하고, 각 로봇의 디버그 토픽을 구독해 상태 메시지를 출력합니다.
각 로봇 노드인 robot1.py부터 robot4.py는 동일한 기본 구조를 가집니다.
command토픽을 구독해 노트북에서 받은 명령을 Arduino로 전달합니다./dev/ttyACM0시리얼 포트를 통해 Arduino와 115200 baud로 통신합니다.- Arduino에서 받은 메시지를 디버그 토픽으로 발행합니다.
- 로봇별 완료 토픽을 사용해 다른 로봇의 진행 상태를 Arduino로 전달합니다.
토픽 흐름은 다음과 같습니다.
laptop
├── publish: command
└── subscribe: debug1_topic, debug2_topic, debug3_topic, debug4_topic
robot1
├── subscribe: command, robot2_complete, robot3_complete, robot4_complete
└── publish: debug1_topic, robot1_complete
robot2
├── subscribe: command, robot1_complete, robot3_complete, robot4_complete
└── publish: debug2_topic, robot2_complete
robot3
├── subscribe: command, robot1_complete, robot2_complete, robot4_complete
└── publish: debug3_topic, robot3_complete
robot4
├── subscribe: command, robot1_complete, robot2_complete, robot3_complete
└── publish: debug4_topic, robot4_complete
ROS2 워크스페이스 디렉터리에서 다음 명령을 실행합니다.
cd "ROS2 Package/HYMEC01/HYMEC01"
colcon build
source install/setup.bash워크스페이스를 source한 뒤 필요한 노드를 실행합니다.
ros2 run HYMEC01 laptop
ros2 run HYMEC01 robot1
ros2 run HYMEC01 robot2
ros2 run HYMEC01 robot3
ros2 run HYMEC01 robot4- ROS2 빌드 생성물인
build/,install/,log/디렉터리는.gitignore로 제외합니다.