장애물 척척 피하는 똑똑한 로봇 만들기 (초보편)
페이지 정보
작성자 관리자 작성일 25-11-20 12:35 조회 344 댓글 0본문
장애물 척척 피하는 똑똑한 로봇 만들기 (초보편)
장애물을 척척 피하는 로봇을 만드는 것은 로봇에게 '눈'을 달아주고 스스로 '생각'해서 '움직이도록' 하는 아주 흥미로운 과정입니다. 초보자분들도 쉽게 따라 할 수 있도록, 가장 기본적인 초음파 센서를 이용한 장애물 회피 로봇 만들기를 자세히 설명해 드릴게요. 라인트레이서 로봇과 비슷한 방식으로 '인지 - 판단 - 행동'의 기본 원리를 다시 한번 익힐 수 있습니다.
1단계: 장애물 회피 로봇의 '원리' 이해하기
장애물 회피 로봇은 다음과 같은 간단한 원리로 움직입니다.
인지 (센서): 로봇 앞쪽에 달린 '초음파 센서'가 주변의 물체까지의 '거리'를 측정합니다.
판단 (컨트롤러/코드): 측정된 거리 값을 아두이노가 읽어들여, 현재 로봇 앞에 '장애물이 있는지', '얼마나 멀리 있는지'를 판단합니다.
장애물이 없을 때 (멀리 있을 때): 계속 앞으로 직진.
장애물이 가까이 있을 때 (위험 거리 이내): 일단 정지. 그리고 다른 방향(예: 왼쪽, 오른쪽)에 장애물이 없는지 확인 후 그쪽으로 회전.
행동 (모터): 아두이노의 판단에 따라 모터를 제어하여 로봇의 움직임(직진, 정지, 회전)을 결정합니다.
2단계: 필수 준비물 확인 및 구매
라인트레이서 로봇과 유사하지만, 라인 센서 대신 초음파 센서가 사용됩니다.
컨트롤러:
아두이노 우노 R3 (Arduino Uno R3) 호환 보드: 1개
USB 케이블: 아두이노와 컴퓨터 연결용.
로봇 섀시:
2WD 로봇 자동차 섀시 키트: 1개 - 모터, 바퀴, 프레임, 캐스터 포함 (라인트레이서와 동일)
액추에이터:
모터 드라이버 (L298N): 1개
SG90 마이크로 서보 모터: 1개 (선택 사항이지만, 센서를 움직여 장애물 감지 시야를 넓히는 데 유용)
센서:
초음파 센서 모듈 (HC-SR04): 1개
전원:
AA 배터리 홀더 (4개용): 1개 (모터 전원용)
AA 배터리: 4개
(선택 사항) 9V 배터리 & 스냅 커넥터: 아두이노 별도 전원용.
연결 재료:
브레드보드: 1개 (선택 사항)
점퍼 케이블 (수-수, 수-암): 넉넉하게
공구:
드라이버 세트, 니퍼, 양면테이프 또는 글루건.
3단계: 로봇의 '몸' 조립하기 (기계적 조립)
라인트레이서 로봇과 거의 동일한 방식으로 조립하되, 초음파 센서의 위치가 다릅니다.
로봇 섀시 조립: 프레임, 모터, 바퀴, 캐스터 등을 조립합니다.
아두이노/모터 드라이버 고정: 아두이노 보드와 모터 드라이버(L298N)를 로봇 프레임에 고정합니다.
초음파 센서 부착:
SG90 서보 모터와 결합: 서보 모터의 축에 초음파 센서를 고정하여, 센서가 좌우로 회전하며 장애물을 감지할 수 있도록 합니다. 이 서보 모터를 로봇 앞쪽에 고정합니다. (센서의 감지 시야를 넓히는 데 큰 도움이 됩니다.)
서보 모터 없이 고정: 서보 모터 없이 로봇 앞쪽에 초음파 센서를 고정할 수도 있습니다. 이 경우 센서는 정면만 감지합니다.
높이: 초음파 센서의 송수신부가 바닥과 수평을 이루도록, 그리고 로봇의 높이 중앙에 위치하도록 고정하는 것이 좋습니다.
4단계: 로봇의 '신경망' 연결하기 (전기 배선 - L298N 모터 드라이버 기준)
라인트레이서 로봇과 대부분 동일합니다.
모터와 L298N 모터 드라이버 연결: (라인트레이서와 동일)
L298N OUT1, OUT2 → 왼쪽 모터
L298N OUT3, OUT4 → 오른쪽 모터
전원부 연결: (라인트레이서와 동일)
AA 배터리 홀더의 + → L298N +12V (또는 VCC)
AA 배터리 홀더의 - → L298N GND
L298N 드라이버와 아두이노 연결: (라인트레이서와 동일)
L298N IN1 → 아두이노 핀 8
L298N IN2 → 아두이노 핀 9
L298N IN3 → 아두이노 핀 10
L298N IN4 → 아두이노 핀 11
L298N ENA → 아두이노 핀 5 (PWM 핀)
L298N ENB → 아두이노 핀 6 (PWM 핀)
L298N GND → 아두이노 GND (가장 중요!)
초음파 센서 (HC-SR04)와 아두이노 연결:
HC-SR04 VCC → 아두이노 5V
HC-SR04 GND → 아두이노 GND
HC-SR04 Trig (트리거 핀) → 아두이노 핀 4 (아무 디지털 핀이나 가능)
HC-SR04 Echo (에코 핀) → 아두이노 핀 7 (아무 디지털 핀이나 가능)
(선택 사항) SG90 서보 모터와 아두이노 연결:
SG90 오렌지/노란색 (Signal) → 아두이노 핀 12 (PWM 핀 중 아무거나 가능)
SG90 빨간색 (VCC) → 아두이노 5V
SG90 갈색/검은색 (GND) → 아두이노 GND
배선 시 주의사항: (라인트레이서와 동일) 모든 배선은 전원이 없는 상태에서 하고, 정확한 연결을 거듭 확인해야 합니다.
5단계: 로봇의 '명령' 프로그래밍하기 (아두이노 코딩)
이제 로봇에게 장애물 회피 방법을 가르쳐 줄 차례입니다. 아두이노 IDE를 사용하여 코드를 업로드합니다.
5.1. 아두이노 IDE 설정 (라인트레이서와 동일)
5.2. 장애물 회피 로봇 기본 코드 (SG90 서보 모터 포함 예시)
cpp
#include <Servo.h> // 서보 모터 라이브러리 포함
// 모터 제어 핀 정의 (L298N 기준)
const int motor1_in1 = 8;
const int motor1_in2 = 9;
const int motor2_in1 = 10;
const int motor2_in2 = 11;
const int motor1_ena = 5; // 왼쪽 모터 속도 (PWM 핀)
const int motor2_enb = 6; // 오른쪽 모터 속도 (PWM 핀)
// 초음파 센서 핀 정의
const int trigPin = 4;
const int echoPin = 7;
// 서보 모터 핀 정의
const int servoPin = 12;
// 모터 속도 (0-255)
const int base_speed = 150; // 기본 전진 속도
const int turn_speed = 100; // 회전 시 모터 속도
// 장애물 감지 거리 임계값 (cm)
const int obstacle_threshold = 20; // 20cm 이내면 장애물로 간주
Servo myservo; // 서보 객체 생성
void setup() {
pinMode(motor1_in1, OUTPUT);
pinMode(motor1_in2, OUTPUT);
pinMode(motor2_in1, OUTPUT);
pinMode(motor2_in2, OUTPUT);
pinMode(motor1_ena, OUTPUT);
pinMode(motor2_enb, OUTPUT);
pinMode(trigPin, OUTPUT); // 초음파 트리거 핀을 출력으로 설정
pinMode(echoPin, INPUT); // 초음파 에코 핀을 입력으로 설정
myservo.attach(servoPin); // 서보 모터를 핀에 연결
myservo.write(90); // 서보 모터를 중앙 (90도)으로 초기화
delay(500);
Serial.begin(9600); // 시리얼 통신 시작 (디버깅용)
}
void loop() {
long duration, distance;
// 1. 초음파 센서로 전방 거리 측정
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH); // 에코 핀으로부터 돌아오는 시간 측정
distance = duration * 0.034 / 2; // 시간을 거리(cm)로 변환 (음속: 340m/s = 0.034cm/us)
Serial.print("Distance: ");
Serial.print(distance);
Serial.println(" cm");
// 2. 측정된 거리에 따른 로봇 행동 판단
if (distance > obstacle_threshold) {
moveForward(); // 장애물이 멀리 있으면 전진
} else {
stopRobot(); // 장애물이 가까우면 일단 정지
delay(300); // 잠시 대기
// 3. 좌우 거리 측정 (서보 모터가 있을 경우)
int leftDistance = measureDistance(160); // 왼쪽으로 센서 돌려 측정
delay(200);
int rightDistance = measureDistance(20); // 오른쪽으로 센서 돌려 측정
delay(200);
myservo.write(90); // 센서 다시 중앙으로
Serial.print("Left Dist: ");
Serial.print(leftDistance);
Serial.print(" Right Dist: ");
Serial.println(rightDistance);
// 4. 장애물이 없는 방향으로 회전
if (leftDistance > rightDistance) {
turnLeft(); // 왼쪽이 더 멀면 왼쪽으로 회전
} else {
turnRight(); // 오른쪽이 더 멀면 오른쪽으로 회전 (같으면 기본값)
}
delay(500); // 충분히 회전
}
}
// 거리 측정 함수 (서보 모터를 사용하여 특정 각도에서 측정)
int measureDistance(int angle) {
myservo.write(angle);
delay(300); // 서보가 해당 각도로 이동할 시간을 줌
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
long duration = pulseIn(echoPin, HIGH);
return duration * 0.034 / 2;
}
// 로봇 제어 함수들 (라인트레이서와 동일)
void moveForward() {
digitalWrite(motor1_in1, HIGH); digitalWrite(motor1_in2, LOW);
analogWrite(motor1_ena, base_speed);
digitalWrite(motor2_in1, HIGH); digitalWrite(motor2_in2, LOW);
analogWrite(motor2_enb, base_speed);
}
void turnLeft() {
digitalWrite(motor1_in1, LOW); digitalWrite(motor1_in2, HIGH); // 왼쪽 모터 후진 (제자리 회전)
analogWrite(motor1_ena, turn_speed);
digitalWrite(motor2_in1, HIGH); digitalWrite(motor2_in2, LOW); // 오른쪽 모터 전진
analogWrite(motor2_enb, turn_speed);
}
void turnRight() {
digitalWrite(motor1_in1, HIGH); digitalWrite(motor1_in2, LOW); // 왼쪽 모터 전진
analogWrite(motor1_ena, turn_speed);
digitalWrite(motor2_in1, LOW); digitalWrite(motor2_in2, HIGH); // 오른쪽 모터 후진 (제자리 회전)
analogWrite(motor2_enb, turn_speed);
}
void stopRobot() {
digitalWrite(motor1_in1, LOW); digitalWrite(motor1_in2, LOW);
analogWrite(motor1_ena, 0);
digitalWrite(motor2_in1, LOW); digitalWrite(motor2_in2, LOW);
analogWrite(motor2_enb, 0);
}
5.3. 코드 업로드 및 테스트
위 코드를 아두이노 IDE에 복사하여 붙여넣기 합니다.
스케치(Sketch) → 컴파일/업로드(Upload)를 클릭하여 코드를 아두이노 보드에 업로드합니다.
툴(Tools) → 시리얼 모니터(Serial Monitor)를 열어 초음파 센서가 정확한 거리를 측정하는지 확인합니다. 로봇 앞에 손을 가져다 대거나 멀리 떨어뜨려가며 값이 변하는지 보세요.
6단계: 로봇 테스트 및 최적화
이제 똑똑한 로봇을 시험할 시간입니다!
테스트 환경 준비: 로봇이 자유롭게 움직일 수 있는 넓은 공간을 확보하고, 다양한 높이와 재질의 장애물(박스, 책 등)을 배치합니다.
시험 운행: 로봇에 전원을 켜고 작동을 시작합니다.
디버깅 및 조정:
장애물 감지 실패: 초음파 센서의 각도나 높이가 적절한지 확인합니다. 너무 높거나 낮으면 장애물을 감지하지 못할 수 있습니다.
거리 임계값: obstacle_threshold 값을 조절하여 로봇이 너무 일찍 멈추거나 너무 가까이 가서 부딪히지 않도록 최적의 거리를 찾습니다.
회전 동작: turn_speed와 delay 값을 조정하여 로봇이 충분히 회전하여 장애물을 피할 수 있도록 합니다.
모터 방향: 로봇이 회전할 때 예상한 방향으로 도는지 확인합니다. 만약 반대로 돌면 turnLeft()나 turnRight() 함수 내의 모터 제어 라인을 수정합니다.
모터 속도: base_speed와 turn_speed 값을 조정하여 로봇의 전반적인 움직임을 부드럽게 하거나 빠르게 만듭니다.
축하합니다! 이제 당신만의 장애물 회피 로봇이 완성되었습니다!
이 로봇은 로봇에게 '공간 인지' 능력을 부여하고 스스로 '생각'해서 위험을 '회피'하는 방법을 가르쳐주는 프로젝트입니다. 이 코드는 가장 기본적인 회피 로직이지만, 여기서 더 나아가 다양한 센서를 추가하거나, AI 알고리즘을 도입하여 더욱 똑똑하고 유연하게 움직이는 로봇을 만들 수 있습니다. 로봇 공학의 세계는 무궁무진합니다!
댓글목록 0
등록된 댓글이 없습니다.
