다운로드 교육자료 문제해결 레퍼런스 구입방법

교육 자료 : C 언어 : 여러 대의 햄스터 로봇 제어하기 (선택 사항)

친구 따라가기
하나의 컴퓨터에서 두 대의 햄스터 로봇을 제어하여 지난 시간에 배운 친구 따라가기를 다시 해봅시다.

라인 트레이서 실습판 내려 받기 PDF PPT

하나의 컴퓨터에서 두 대의 햄스터 로봇을 사용하기 위해서는 컴퓨터에 동글을 두 개 꽂고 코드에서 hamster_create() 함수를 두 번 호출하면 됩니다.

Hamster* hamster1 = hamster_create();
Hamster* hamster2 = hamster_create();

여러 대의 햄스터 로봇을 제어하기 위해서는 haster_create() 함수가 반환하는 포인터를 사용하여 각각의 함수를 호출하면 됩니다. 지금까지 사용한 hamster_로 시작하는 함수들은 한 대의 햄스터 로봇(여러 대의 햄스터 로봇인 경우에는 첫 번째 햄스터 로봇)을 제어하기 위한 함수입니다.
hamster_로 시작하는 함수와 포인터를 통해 호출하는 함수는 형태가 같으며 다음 예시들과 같은 규칙을 가집니다.

한 대의 햄스터 로봇을 제어하기 위한 함수 여러 대의 햄스터 로봇 각각을 제어하기 위한 함수
인스턴스 생성 및 통신 연결 hamster_create(); Hamster* robot = hamster_create();
바퀴 제어 hamster_wheels(30, 30); robot->wheels(30, 30);
왼쪽 근접 센서 hamster_left_proximity() robot->left_proximity()
오른쪽 바닥 센서 hamster_right_floor() robot->right_floor()

이 외의 다른 함수들도 같은 규칙으로 함수 이름이 정해져 있습니다.

각각의 햄스터 로봇이 전방을 살펴보면서 검은색 선을 따라 주행하는 코드는 다음과 같이 작성될 수 있습니다.

#include "roboid.h"

int main(int argc, char *argv[]) {
    int diff;

    Hamster* hamster1 = hamster_create();
    Hamster* hamster2 = hamster_create();

    while(1) {
        // 첫 번째 햄스터 로봇
        if(hamster1->left_proximity() > 50 || hamster1->right_proximity() > 50) {
            hamster1->stop();
        } else {
            diff = hamster1->left_floor() - hamster1->right_floor();
            hamster1->wheels(30 + diff * 0.4, 30 - diff * 0.4);
        }

        // 두 번째 햄스터 로봇
        if(hamster2->left_proximity() > 50 || hamster2->right_proximity() > 50) {
            hamster2->stop();
        } else {
            diff = hamster2->left_floor() - hamster2->right_floor();
            hamster2->wheels(30 + diff * 0.4, 30 - diff * 0.4);
        }

        wait(10); // 너무 빨리 반복하지 않도록 한다.
    }

    return 0;
}

같은 코드를 두 번 작성하였기 때문에 뭔가 비효율적으로 보입니다. 햄스터 로봇의 수가 많아지면 어떻게 될까요? 함수로 만드는 것이 좋겠습니다.

#include "roboid.h"

void trace(Hamster* hamster) {
    if(hamster->left_proximity() > 50 || hamster->right_proximity() > 50) {
        hamster->stop();
    } else {
        int diff = hamster->left_floor() - hamster->right_floor();
        hamster->wheels(30 + diff * 0.4, 30 - diff * 0.4);
    }
}

int main(int argc, char *argv[]) {
    Hamster* hamster1 = hamster_create();
    Hamster* hamster2 = hamster_create();

    while(1) {
        trace(hamster1); // 첫 번째 햄스터 로봇
        trace(hamster2); // 두 번째 햄스터 로봇

        wait(10); // 너무 빨리 반복하지 않도록 한다.
    }

    return 0;
}

이제 햄스터 로봇의 수가 많아져도 hamster_create() 함수를 호출하는 부분과 trace() 함수를 호출하는 부분만 추가하면 되기 때문에 훨씬 간단해졌습니다.

첫 번째 햄스터 로봇의 전원만 켜고 코드를 실행한 후 잠시 후에 두 번째 햄스터 로봇의 전원을 켜보도록 합시다. 어떻게 되나요? 첫 번째 햄스터 로봇이 통신으로 연결되었을 때 동작을 먼저 시작하게 됩니다. 두 번째 햄스터 로봇의 전원을 켜서 모든 로봇이 통신으로 연결된 후 동작을 같이 시작하게 하려면 hamster_create() 함수를 호출한 후에 wait_until_ready() 함수를 호출해 주면 됩니다.

#include "roboid.h"

void trace(Hamster* hamster) {
    if(hamster->left_proximity() > 50 || hamster->right_proximity() > 50) {
        hamster->stop();
    } else {
        int diff = hamster->left_floor() - hamster->right_floor();
        hamster->wheels(30 + diff * 0.4, 30 - diff * 0.4);
    }
}

int main(int argc, char *argv[]) {
    Hamster* hamster1 = hamster_create();
    Hamster* hamster2 = hamster_create();

    wait_until_ready();

    while(1) {
        trace(hamster1); // 첫 번째 햄스터 로봇
        trace(hamster2); // 두 번째 햄스터 로봇

        wait(10); // 너무 빨리 반복하지 않도록 한다.
    }

    return 0;
}

참고로, 배열을 사용하여 좀 더 일반적인 형태로 수정하면 다음과 같이 됩니다.

#include "roboid.h"

#define NUM_HAMSTERS 2 // 햄스터의 수를 변경하기 위해서는 숫자 2만 수정하면 된다.

void trace(Hamster* hamster) {
    if(hamster->left_proximity() > 50 || hamster->right_proximity() > 50) {
        hamster->stop();
    } else {
        int diff = hamster->left_floor() - hamster->right_floor();
        hamster->wheels(30 + diff * 0.4, 30 - diff * 0.4);
    }
}

int main(int argc, char *argv[]) {
    Hamster* hamsters[NUM_HAMSTERS];
    int i;

    for(i = 0; i < NUM_HAMSTERS; ++i) {
        hamsters[i] = hamster_create();
    }

    wait_until_ready();

    while(1) {
        for(i = 0; i < NUM_HAMSTERS; ++i) {
            trace(hamsters[i]);
        }

        wait(10); // 너무 빨리 반복하지 않도록 한다.
    }

    return 0;
}
쇼트 트랙 릴레이
마찬가지로 하나의 컴퓨터에서 두 대의 햄스터 로봇을 제어하여 지난 시간에 배운 쇼트 트랙 릴레이를 다시 해봅시다.

라인 트레이서 실습판 내려 받기 PDF PPT

#include "roboid.h"

void trace(Hamster* hamster) {
    if(hamster->left_proximity() > 50 || hamster->right_proximity() > 50) {
        hamster->stop();
    } else {
        int diff = hamster->left_floor() - hamster->right_floor();
        hamster->wheels(30 + diff * 0.4, 30 - diff * 0.4);
    }
}

int calc_speed(int proximity) {
    if(proximity > 60) {
        return 0;
    } else {
        return (int)((60 - proximity) * 0.8);
    }
}

void chase(Hamster* hamster) {
    int left_speed = calc_speed(hamster->left_proximity());
    int right_speed = calc_speed(hamster->right_proximity());

    hamster->wheels(left_speed, right_speed);
}

int main(int argc, char *argv[]) {
    Hamster* hamster1 = hamster_create();
    Hamster* hamster2 = hamster_create();

    wait_until_ready();

    while(1) {
        trace(hamster1); // 첫 번째 햄스터 로봇
        chase(hamster2); // 두 번째 햄스터 로봇

        wait(10); // 너무 빨리 반복하지 않도록 한다.
    }

    return 0;
}

USB 동글을 꽂는 위치에 따라 선두 로봇과 뒤따라가는 로봇의 순서가 바뀔 수 있습니다. 이 경우에는 다음과 같이 선두 로봇과 뒤따라가는 로봇을 서로 바꾸어 주면 됩니다.

while(1) {
    trace(hamster2); // 첫 번째 햄스터 로봇
    chase(hamster1); // 두 번째 햄스터 로봇

    wait(10); // 너무 빨리 반복하지 않도록 한다.
}

선두 로봇과 뒤따라가는 로봇을 고정시키기 위해서는 다음과 같이 hamster_create_port() 함수를 사용하여 시리얼 포트 이름을 지정해 주어도 됩니다. (클라우드 컴퓨터 환경에서 작업하기 참고)

#include "roboid.h"

void trace(Hamster* hamster) {
    if(hamster->left_proximity() > 50 || hamster->right_proximity() > 50) {
        hamster->stop();
    } else {
        int diff = hamster->left_floor() - hamster->right_floor();
        hamster->wheels(30 + diff * 0.4, 30 - diff * 0.4);
    }
}

int calc_speed(int proximity) {
    if(proximity > 60) {
        return 0;
    } else {
        return (int)((60 - proximity) * 0.8);
    }
}

void chase(Hamster* hamster) {
    int left_speed = calc_speed(hamster->left_proximity());
    int right_speed = calc_speed(hamster->right_proximity());

    hamster->wheels(left_speed, right_speed);
}

int main(int argc, char *argv[]) {
    Hamster* hamster1 = hamster_create_port("COM57");
    Hamster* hamster2 = hamster_create_port("COM70");

    wait_until_ready();

    while(1) {
        trace(hamster1); // 첫 번째 햄스터 로봇
        chase(hamster2); // 두 번째 햄스터 로봇

        wait(10); // 너무 빨리 반복하지 않도록 한다.
    }

    return 0;
}
목차
수업 준비
  1. 하드웨어 살펴보기
  2. 햄스터 · 햄스터S · USB 동글 PDF · PPT
  3. 소프트웨어 설치
  4. PDF · PPT
  5. 로봇과 컴퓨터 연결
  6. PDF · PPT
  7. 예제 프로젝트 실행
  8. PDF · PPT
기초
  1. 새 프로젝트 만들기
  2. 클라우드 컴퓨터 환경에서 작업하기 (선택 사항)
  3. 말판 이동하기 #1 (순차, 횟수 반복)
  4. 이동하고 회전하기
  5. LED 켜고 소리 내기
  6. 순서대로, 반복하여 명령하기
  7. 키보드 이벤트
  8. 근접 센서 사용하기
  9. 말판 이동하기 #2 (~인 동안 반복)
  10. 바닥 센서 사용하기
  11. 밝기 센서와 가속도 센서 사용하기
  12. 브레이튼버그의 로봇
심화
  1. 보드 게임 만들기
  2. 센서 한 개를 사용한 라인 트레이서
  3. 센서 두 개를 사용한 라인 트레이서
  4. 햄스터 친구 따라가기 (2인 1조)
  5. 여러 대의 햄스터 로봇 제어하기 (선택 사항)
  6. 벽 따라가기
  7. 로봇 청소기 흉내 내기
  8. 라인 트레이서 교차로 주행하기
  9. 미로 탈출
확장 키트
  1. 조립하기
  2. 핀/소켓 배치 살펴보기
  3. 디지털 입력 - 버튼을 누르면 삐 소리가 나요
  4. 디지털 출력 - 어두우면 LED 불이 켜져요
  5. 디지털 출력 - 반짝반짝 LED를 깜박여요
  6. 디지털 출력 - 기울이는 방향으로 LED가 켜져요
  7. 아날로그 입력 - 포텐셔미터를 돌리면 음 높이가 달라져요
  8. 아날로그 입력 - 뜨겁지 않게 해주세요
  9. 아날로그 입력 - 빛을 따라 움직여요
  10. PWM 출력 - LED 불이 부드럽게 밝아졌다 어두워져요
  11. PWM 출력 - LED 촛불이 바람에 흔들려요
  12. 아날로그 서보 출력 - 햄스터 로봇에게 꼬리가 생겼어요
고급
  1. 행위 기반의 로봇 제어
  2. 경로 탐색
  3. 자리 바꾸기
Copyright 로봇SW교육원 All rights reserved.
어려운 일이 있으면 광운대학교 로봇학부 박광현 교수(akaii@kw.ac.kr)에게 연락하세요.