▶ 힘든 과정이었다...

PC 개발 환경과 로봇 onboard PC의 설정을 마쳤다. Fedora로 갈아엎는 과정은 순조로웠고, 이제 P3-AT와 PeopleBot은 fedora linux, P3-DX는 windows XP가 설치되어있다.



AmigoBot, 오늘은 이 녀석이 달린다!



1. Advanced Robot interfaces for Application(ARIA)

MobileRobots 사의 로봇들은 모터와 센서 등 다양한 기능들이 임베디드로 구축되어있고, 이 시스템에는 ARCOS라는 펌웨어가 설치되어 있다. ARCOS는 시리얼 포트로 패킷을 받아 로봇 명령으로 해석하고 적절한 기능에 신호를 보내 로봇을 구동시킨다. 따라서 이 시스템은 전형적인 서버/클라이언트 구조를 가지며 굳이 내장된 onboard PC가 아니더라도 일반 데스크탑과 시리얼 포트로 연결하기만 하면 로봇을 구동시킬 수 있다.

ARCOS로 보내야 하는 패킷들을 직접 다루는 것은 매우 저수준 프로그래밍을 요구하므로 일반 어플리케이션이 그것을 다루기란 쉽지 않다. 이러한 문제를 해결하기 위해 나온 것이 ARIA 이다. ARIA는 로봇의 각 기능을 추상화하고 잘 정의된 실행 구조를 갖고 있으며, 개발자가 보다 편하게 로봇을 다룰 수 있도록 인터페이스를 제공한다. 이는 layerd architecture를 따르므로 ARIA 인터페이스를 다루는 개발자에게 ARCOS를 감추며, 따라서 개발자는 ARCOS 펌웨어의 존재를 잊어도 좋다.

ARIA는 http://robots.mobilerobots.com/ARIA/ 에서 다운로드 받을 수 있다.



2. 일단 한 번 굴려 볼까요?

프로그램 언어를 배우다보면 항상 등장하는 것이 Hello World 어플리케이션이다. 몇 줄 안되는 이 어플리케이션은 아마도 지구상에 존재하는 모든 프로그래밍 언어로 포팅되어있을 것이다. 이 프로그램은 소스 코드가 몇 줄 되지도 않을 뿐더러 화면에 고작 Hello World라고 출력할 뿐이지만, 이것이 제대로 출력된다는 것은 개발 환경, 실행 환경, 개발 프로세스가 모두 제대로 동작하고 있음을 확인시켜준다는 점에서 큰 의미를 갖는다. 고로, 구구절절 ARIA의 구조를 설명하기에 앞서 간단한 예제 코드를 작성하고 실행해 보는 것이 좋을 듯 싶다.

#include "Aria.h"

int main(int argc, char** argv) {
	Aria::init();
	ArSimpleConnector conn(&argc, argv);
	ArRobot robot;

	if(!Aria::parseArgs())
	{
		Aria::logOptions();
		return 1;
	}

	if(!conn.connectRobot(&robot))
	{
		ArLog::log(ArLog::Terse, "actionExample: Could not connect to robot! Exiting.");
		return 2;
	}

	ArKeyHandler *keyHandler = Aria::getKeyHandler();
	if (keyHandler == NULL)
	{
		keyHandler = new ArKeyHandler;
		Aria::setKeyHandler(keyHandler);
		robot.attachKeyHandler(keyHandler);
	}

	ArActionGoto action;
	action.setGoal(ArPose(5000, 5000));
	robot.addAction(&action, 100);

	robot.enableMotors();
	robot.run(true);

	Aria::shutdown();
	return 0;
}
이 어플리케이션은 로봇을 5000, 5000 위치로 이동시킨다.


▶ 저는 로봇이 없어요!

MobileRobots 사는 MobileSim 이라 불리는 시뮬레이션 툴을 무료로 배포하고 있다. 시뮬레이터를 실행 시키고나서 로봇 어플리케이션을 실행하면, 시뮬레이션 상에서 로봇이 움직이는 것을 확인할 수 있다.



MobileSim은 http://robots.mobilerobots.com/MobileSim/ 에서 다운로드 받을 수 있다. 


3. 자세히 살펴보자!

ARIA의 구석 구석을 한 번에 다 살펴보는 것은 매우 기운 빠지는 일이다. 필요할 때마다 조금씩 설명해 나가는 것이 우리네 건강에 좋을 듯 싶다. 앞서 본 예제 코드를 면밀히 살펴보는 것으로 오늘의 강좌를 마칠까 한다.

ARIA는 static 함수인 init()을 통해 로봇에 접속하기 위한 초기화를 수행한다. 그리고 shutdown()을 통해 로봇과의 연결을 해제하게 된다. 따라서 모든 ARIA 어플리케이션은 다음과 같은 형식을 갖춘다.
int main(int argc, char** argv) {
	Aria::init();

	// ...

	Aria::shutdown();
	return 0;
}
로봇과 관련된 모든 제어의 중심은 ArRobot 객체가 담당한다. ArSimpleConnector 객체는 ArRobot 객체를 시뮬레이터(MobileSim) 또는 로봇 시스템과 연결시킨다. connectRobot() 함수가 이러한 기능을 수행한다.
	ArSimpleConnector conn(&argc, argv);
	ArRobot robot;
	if(!conn.connectRobot(&robot))
	{
		ArLog::log(ArLog::Terse, "actionExample: Could not connect to robot! Exiting.");
		return 2;
	}
기본적으로 connectRobot() 함수는 먼저 시뮬레이터로 연결을 시도하고 시뮬레이터가 실행 중이 아니라면 로봇 시스템으로 접속을 시도한다. ArSimpleConnector는 실행 인자를 통해 다양한 옵션을 조절할 수 있는데 일단 오늘은 시뮬레이터로 작업하자. MobileSim을 띄워 놓은 상태라면 아무 실행 인자 없이도 시뮬레이터에 잘 연결될 것이다.

마지막으로 로봇이 어떤 작업을 수행해야 하는가, 그리고 그 수행을 어떻게 시키는가가 남았다. 로봇으로 작업을 전달하는 방법은 저수준 패킷을 전송하는 방법, 직접적인 명령 API 호출, ArAction을 통한 작업 전달 이렇게 세 가지가 있다. 위의 예에서는 ArAction을 통해 작업을 전달했다. 각각의 방법에 대해서는 다음 포스트에서 자세히 설명하겠다.

로봇에게 작업을 주었으면 이제 그 작업을 수행하도록 해야 한다. 먼저 모터를 켜고, ArRobot 객체의 run() 함수를 호출한다. run() 함수의 인자는 로봇과의 연결이 끊어지면 종료하겠는가? 정도의 파라미터이며 생각없이 true를 적어줘도 좋다. run() 함수는 모든 작업이 완료될 때까지 반환되지 않는데, 만약 별도의 스레드를 통해 비동기적으로 로봇 작업을 수행하고자 한다면 runAsync()를 호출하면 된다.
	robot.enableMotors();
	robot.run(true);
자, 여기까지가 Hello World 급의 어플리케이션이다. 실행을 하면 '5000, 5000 위치로 이동한 다음 어플리케이션이 종료되겠지?' 라고 생각했던 당신의 기대를 조금 져버릴 것이고, ESC 키를 누르면 언제든 프로그램은 종료될 것이라는 사실을 설명하지 않았다고 나에게 투덜댈지도 모르겠다. 알아서 찾아보길... 능동적인 인간이 되자. 흥-

다음 시간에는 로봇에게 작업을 전달하는 세 가지 방법에 대해 자세하게 살펴볼 예정이다. 그리고 나서, 로봇 센서를 동작시키는 법, 특정 공간을 시뮬레이션하는 법, Localization과 Path Planning 순으로 포스트를 써 나갈 예정이다.

음, 그런데 관심 갖는 사람이 있으려나?
 
이 글의 트랙백 주소는 http://semix2.tistory.com/trackback/363 입니다