본문 바로가기

허큘렉스(Herkulex)

버섯돌이의 허큘렉스 다루기 - 4DOF 2족 보행 로봇 제어(단순 제어)


src.zip


 버섯돌이의 허큘렉스 다루기

4DOF 2족 보행 로봇 제어(단순 제어)



Created Date: 2014.08.16
Modified Date: 2014.08.16
revision 1

 

키워드 : 허큘렉스, 2족보행, 4dof, HerkuleX, 로봇 


안녕하세요 버섯돌이 유재성입니다.

임베디드 분야에 조금 더 시간을 할애하려고 큰 맘먹고 몇 달 간 일을 쉬었지만....

개인 사정으로  컴퓨터도 그렇고 이쪽 분야도 그렇고 아무것도 못 한채 시간만 지난 것 같네요.^^;;;

 

많지 않은 여유 시간 속에 이것저것 하고 싶은 것들이 많지만 기존 시리즈 중 일부라도 먼저 마무리 지어보렵니다. 

다만, 거의 4~5개월 만에 다시 시작하려니 머릿속은 백지장이라 아는 내용이 없는데

오랜만에 기존 목차의 흐름을 이어가기 위해 2족 보행으로 진행하려니 기체 준비부터 만만치 않군요.

불행 중 다행인 건 원래부터 아는 내용이 없고 제가 작성하는 글은 많은 지식이 필요하지 않은 수준이라는 게 위안이 됩니다.^^;;

 

저는 보행 알고리즘 등 로봇 제어의 원리 등을 다루기에는 아는 지식과 능력이 안되기에 세부적인 제어와 관련해서는

체험 기간에 작성된 다른 체험단들의 멋진 강좌들이 많으니 해당 강좌를 참고 하시기 바랍니다.

저는 초등학생 수준에서 제가 접근했던 방법들이 취미로 입문하는 분들에게 도움이 될지 모르기에 가이드 정도로만 다룰 예정입니다.

따라서, 질문은 받지 않으며 부딪히는 문제들은 기존 글들과 검색을 통해서 스스로 해결하시기 바랍니다.*^^*

(다만, 많은 분들에게 도움이 되는 정보는 환영합니다.^^)

 

지금까지 허큘렉스 서보(DRS-0101​)에 대한 정보와 라즈베리 파이에서 제어하는 방법을 살펴봤습니다.

오늘은 활용 예제로서 지난 시간에 조립한 2족 보행 로봇을 제어하기 위한 간단한 방법을 살펴보도록 하겠습니다.

 

저처럼 아무런 기초도 없고 문법도 잘 모르는 경우에는 제공되는 라즈베리 파이용 샘플 소스를 활용하는 방법이 가장 쉽습니다.

  버섯돌이의 허큘렉스 다루기 - 서보 모터 제어(Raspberry Pi)

  http://blog.naver.com/dev4unet/120213007666

 

2족 보행 로봇의 경우 4개의 서보가 사용되므로 샘플 중 "Multiple_Servo_Test.cpp" 파일을 참고 합니다.

 

 

  1. #include <iostream>
  2. #include <map>
  3. #include "HerkuleX.h"
  4.  
  5. using namespace std;
  6.  
  7. int main(int argc, char* argv[]) {
  8.     HerkuleX motor;
  9.     std::map<intint> motor_values;
  10.  
  11.     motor.TorqueOn(254);
  12.     cout << "Torque on....." << endl;
  13.  
  14.     motor_values[0] = 320;
  15.     motor_values[1] = 704;
  16.     motor_values[2] = 320;
  17.     motor.movePos(motor_values, 100, HERKULEX_LED_BLUE);
  18.     cout << "Move multiple motors 1....." << endl;
  19.  
  20.     sleep(2);
  21.  
  22.     motor_values[0] = 704;
  23.     motor_values[1] = 320;
  24.     motor_values[2] = 704;
  25.     motor.movePos(motor_values, 100, HERKULEX_LED_GREEN);
  26.     cout << "Move multiple motors 2....." << endl;
  27.  
  28.     sleep(2);
  29.  
  30.     motor.TorqueOff(254);
  31.     cout << "Torque off....." << endl;
  32. }
  33.  

 

허큘렉스 서보를 제어하기 위해 습관적으로 1~5라인은 똑같이 작성해주시면 되겠습니다.

1라인의 #include "HerkuleX.h"​ 부분이 허큘렉스 모터를 제어하기 위해 필요한 부분입니다.

 

8라인은 객체를 선언하는 것으로서 HerkuleX motor;에 의해서 앞으로 motor 객체는 허큘렉스 모터라고 생각하시면 됩니다. 

 

9라인의 std::map<int, int> motor_values;는 여러 개의 서보모터를 동시에 제어하기 위해 필요한 배열이라고 생각하시면 됩니다.

따라서, 저처럼 C++에 대해서 잘 모르겠다면 1~9라인까지는 필수적으로 사용하세요.^^

 

무엇보다 Multiple_Servo_Test.cpp 예제는 다중 서보 제어를 위한 최소한의 기능을 담고 있기 때문에

샘플 소스에서 모터 값만 적절하게 변경하시면 원하는 기능을 어렵지 않게 구현이 가능합니다.*^^*

 

기존 강좌와 매뉴얼을 보셨으면 아시겠지만 11라인의 motor.TorqueOn(254);에 의해서 모든 모터를 동시에 제어하게 됩니다.

참고로, 토크 On 상태에서만 서보모터가 동작하며 TorqueOn​(ID)의 경우 지정된 ID의 서보모터를

토크 On 하게 됩니다만 254가 지정되면 브로드캐스트로서 연결된 모든 서보모터를 토크 On 하게 됩니다.

 

14~16라인에서 각 모터가 움직여야 할 원하는 절대 위치 값을 설정합니다.

motor_values[0] = 320;

 

위의 경우 모터 ID 값이 0인 서보의 위치를 절대 위치 값이 320인 위치로 이동하라는 의미이며,

다른 부분들은 그대로 사용하면 되지만 2족 보행 로봇을 제어함에 있어 꼭 알아야 할 부분이 위치에 대한 개념입니다.

 

이해를 돕기 위해 기존에 설명드렸던 내용을 다시 살펴보면 아래와 같습니다.



서보모터의 혼(정면)을 바라본 상태에서 양쪽 하단 모서리 꼭짓점의 26.7 도는 사용이 불 가능한 데드 존입니다.

(이해가 쉽도록 하단의 꼭짓점을 빨간색 사각형으로 표시했습니다)

 

서보 혼을 바라본 상태에서 12시 방향인 초록색 숫자 512로 표시된 위치가 0도입니다.

0도를 기준으로 시계 방향은 마이너스 각도, 반 시계 방향은 플러스 각도입니다.

각도는 -166.7도부터 166.7도까지의 333.4도를 제어할 수 있습니다.

다만, 권장되는 각도는 -159.8도부터 159.8도까지의 총 320도입니다.

 

허큘렉스 서보의 경우 분해능이 0.325도라고 했습니다.

따라서, 서보모터 우측 하단 꼭짓점부터 시작해서 반시계 방향으로 좌측 하단 꼭짓점까지를

0.325도 단위로 0부터 1023까지의 절대 위치 값을 부여합니다.

(1024 단계의 위치 값을 편의상 위치라고 하겠습니다.) 

 

위처럼 서보의 위치를 제어할 때에는 절대 위치나 각도 개념이 사용되는데 제공되는 샘플에서는 절대 위치 값을 사용합니다.

motor_values[0] = 320;

따라서, 위처럼 motor_values​ 에 각각 서보가 움직여야 할 원하는 위치 값들을 설정하면 됩니다.

 

최종적으로 17라인의 movePos 명령에 의해서 한 번에 모든 서보들이 각각의 설정된 위치로 이동하게 됩니다.

motor.movePos(motor_values100, HERKULEX_LED_GREEN);

 

100은 Playtime으로서 지정된 절대 위치에 도달하는 시간입니다.

지난 시간에 설명드렸듯이 허큘렉스는 11.2ms가 최소 제어 단위라서

위의 경우 Playtime으로 100이 지정되었으니 320위치로 이동하는데 100*11.2ms(1/1000초)의 시간이 소요됩니다.

 

movePos의 마지막 인자 값은 LED를 제어하며 "HERKULEX_LED_GREEN"은 LED를 초록색으로 만듭니다.

자세한 내용은 허큘렉스 매뉴얼을 참고하시기 바랍니다.

 

끝으로, 모든 사용이 완료되었으면 30라인처럼 모든 서보의 토크를 Off 해줍니다.

motor.TorqueOff(254);

 

지금까지 살펴본 것처럼 일반 모터를 이용해서 PWM 등을 제어하는 게 아니기 때문에 서보의 사용이 상당히 쉽습니다.*^^* 

처음 사용함에도 제 경우 재미있는 모션을 만들기 위해 아래와 같은 형태의 일어서는 동작을 구현해봤습니다.



 

구현 원리를 살펴보면 2족 보행 로봇은 총 4개의 서보가 사용되며 아래와 같이 각각의 ID 값을 부여했습니다.

 

 

사진처럼 좌측 골반이 1번, 좌측 다리가 3번, 우측 골반이 0번, 우측 다리가 2번입니다.

위와 같이 최초 위치는 정면을 바라본 상태에서 각각의 서보 위치 값은 512 위치가 기본 상태입니다.

 

이때, 영상처럼 일어나는 모습을 구현하기 위해서는 다리를 아래처럼 접어 놓습니다.

 

 

왼발을 먼저 접고, 그 위에 오른발을 접으면 됩니다.

참고로, 서보 ID 0부터 3까지의 서보별 최종 위치 값은 247, 808, 214, 815 입니다.

(즉, 우측 발목을 먼저 접은 뒤에 골반을 안쪽으로 돌려주고 좌측 발도 같은 방법으로 접으면 됩니다.)

 

사진처럼 발을 접었으면 발 바닥면이 마룻바닥을 향하도록 엎어 놓습니다.

이 상태에서 모든 서보들의 위치를 기본 위치인 512로 이동시키면 영상에서처럼 마치 로봇이 일어서는 것처럼 동작합니다.

 

즉, 샘플 소스의 14~28라인을 아래 내용으로 수정하면 됩니다. 

 motor_values[0] = 512;

 motor_values[1] = 512;

 motor_values[2] = 512;

 motor_values[3] = 512;

 motor.movePos(motor_values100, HERKULEX_LED_GREEN);

 

Playtime 값을 100외의 값으로 다양하게 수정하면서 테스트 해 보시기 바랍니다.*^^*

 

일어서기의 경우 배열에 값을 1회만 설정하면 끝이었습니다.

하지만 전진같이 다양한 움직임을 구현하려면 어떻게 해야 할까요?

 

샘플 소스의 20~26라인을 보시면 답을 알 수 있습니다.*^^*

20 라인을 보면 sleep(2);이 사용되었습니다.

sleep​() 함수는 지정된 초동안 실행을 멈추게 됩니다.

따라서, sleep(2)의 경우 2초 동안 멈추는 효과를 갖습니다.

 

그리고 22~25라인에서 다시 motor_values에 값을 설정하고 motor.movePos로 이동합니다.

이런 식으로 움직임과 움직임 사이에 sleep()을 적절히 활용하시면 됩니다.

 

참고로, sleep()의 경우 초 단위의 제어만 가능해서 특정 모션을 구현할 때에는 너무 느린 감이 있습니다.

좀 더 정교한 시간 제어가 필요한 경우에는 usleep() 함수를 이용하시면 됩니다.

usleep()는 1/1000000초까지 제어가 가능합니다.

따라서, 1초간 멈추고 싶다면 usleep(1000000) 하면 1초간 멈추게 됩니다.

 

체험단 활동 시 미션은 전진/후진/회전이었습니다.

이와 관련된 강좌는 다른 분들의 강좌를 참고하셔서 직접 구현해 보시기 바랍니다.

참고로, 운동학이나 기구학 등의 이론을 바탕으로 제어하는 게 아닌 미리 정해진

위치 값을 이용하는 방식이라서 강좌에 사용된 소스를 사용하더라도 마찰면이나 무게중심 등의

환경에 따라 움직임이 다르기 때문에 자신의 환경에 맞는 적당한 값을 찾아보시기 바랍니다.

 

제 경우 일어나기 구현 외에 갖고 다니기 편하도록 아래처럼 드러눕기도 구현했었습니다. 


 

 

위와 같은 여러 단계의 움직임을 구현하기 위해서는 각 단계마다의 서보들의 위치 값을 알아야 합니다.

이때, 각 서보별 현재 위치 값을 찾는 방법은 기존에 설명드렸듯이 HerkuleX Manager를 이용하거나

모션 프로그램 또는 다음에 살펴볼 getPos​() API 등의 여러 방법이 존재합니다.

 

제 경우 초기에는 제공된 전/후진의 모션 데이터 값을 이용하다가 불편해서 getPos()을 활용했었습니다.

편한 방법으로 각 모션 시의 값을 추출해서 별도로 기록한 뒤  sleep()을 이용해서 적절히 제어하시면 됩니다.

 

원래는 더 많은 값이 사용되었으나 강좌를 위해 위 영상에서는 아래의 4단계의 값이 사용되었습니다.

 1단계 511 515 510 513

 2단계 444 808 510 518

 3단계 442 808 214 662

 4단계 383 808 214 815

 

그리고 각 단계마다 0.5초씩 대기하기 위해 usleep(500000);을 사용했으며 Playtime은 30을 사용했습니다.

usleep 값과 Playtime 값을 적절히 변경하시면서 테스트하시면 다양한 차이를 알 수 있을 것입니다.

 

저처럼 운동학이나 기구학 등의 이론을 모르면 이렇게 무식하게라도 적당한 값을 찾아야겠지요.*^^*

개인적으로는 아무것도 모르는 초기에는 허큘렉스 매니저 프로그램에서 값을 찾는 게 더 편하더군요.

코딩이 가능하다면 직접 getPos()를 활용해서 만드시는 게 정신 건강에 좋습니다.^^

 

 

  1. #include <iostream>
  2. #include <map>
  3. #include "HerkuleX.h"
  4.  
  5. using namespace std;
  6.  
  7. int main(int argc, char* argv[]) {
  8.     HerkuleX motor;
  9.     std::map<intint> motor_values;
  10.  
  11.     motor.TorqueOn(254);
  12.     cout << "Torque on....." << endl;
  13.  
  14.     motor_values[0] = 511;
  15.     motor_values[1] = 515;
  16.     motor_values[2] = 510;
  17.     motor_values[3] = 513;
  18.     motor.movePos(motor_values, 30, HERKULEX_LED_BLUE);
  19.     usleep(500000);
  20.  
  21.  
  22.     motor_values[0] = 444;
  23.     motor_values[1] = 808;
  24.     motor_values[2] = 510;
  25.     motor_values[3] = 518;
  26.     motor.movePos(motor_values, 30, HERKULEX_LED_BLUE);
  27.     usleep(500000);
  28.  
  29.     motor_values[0] = 442;
  30.     motor_values[1] = 808;
  31.     motor_values[2] = 214;
  32.     motor_values[3] = 662;
  33.     motor.movePos(motor_values, 30, HERKULEX_LED_BLUE);
  34.     usleep(500000);
  35.  
  36.     motor_values[0] = 383;
  37.     motor_values[1] = 808;
  38.     motor_values[2] = 214;
  39.     motor_values[3] = 815;
  40.     motor.movePos(motor_values, 30, HERKULEX_LED_BLUE);
  41.     usleep(500000);
  42.  
  43.     motor_values[0] = 247;
  44.     motor_values[1] = 808;
  45.     motor_values[2] = 214;
  46.     motor_values[3] = 815;
  47.     motor.movePos(motor_values, 30, HERKULEX_LED_BLUE);
  48.     usleep(500000);
  49.  
  50.  
  51.     motor.TorqueOff(254);
  52.     cout << "Torque off....." << endl;
  53. }
  54.  

역시나 저처럼 C++ 문법을 잘 모르시면 위처럼 무식(?) 하게라도 구현하는 게 속 편합니다.

좀 더 편하게는 각 모션 값을 배열로 저장했다가 루프로 돌리면 되겠지요.^^

좀 더 응용하면 모션 값을 별도의 파일에 기록했다가 불러들여서 처리해도 됩니다.

구현은 자신의 스킬에 맞게 편하게 구현하거나 부족한 부분은 문법을 찾아보시면 되겠습니다.*^^*

 

컴파일 방법은 지난 시간에도 설명드렸듯이 c++ 문법이라서 g++로 컴파일을 하며,

허큘렉스 API를 사용하기 위해서는 파란색의 헤더와 소스 파일은 항상 지정해주시기 바랍니다.

 

g++ -o multiple​_servo_test HerkuleX.h HerkuleX.cpp Multiple_Servo_Test.cpp

 

에러 없이 컴파일이 완료되었으면 multiple​_servo_test ​ 파일을 실행하시면 드러눕기로 동작할 것입니다.

 

> ./multiple​_servo_test

 

간단한 드러눕기 소스를 첨부하며 본 글이 입문하시는 분들에게 조금이라도 도움이 되었길 바래봅니다.*^_^*



[참고자료]
[목차] 버섯돌이의 허큘렉스 다루기 - 목차

버섯돌이의 허큘렉스 다루기 - 준비물편

버섯돌이의 허큘렉스 다루기 - DRS-0101 서보 모터편

http://blog.naver.com/dev4unet/120210588673

 

버섯돌이의 허큘렉스 다루기 - 서보 모터 설정및 테스트(HerkuleX Manager)

http://blog.naver.com/dev4unet/120212995168

 

버섯돌이의 허큘렉스 다루기 - 서보 모터 제어(Raspberry Pi)


버섯돌이의 허큘렉스 다루기 - 4DOF 2족 보행 로봇 조립

End.

written by 버섯돌이(Dev4uNet)

이 저작물은 크리에이티브 커먼즈 저작자표시-비영리 3.0 Unported 라이선스에 따라 이용할 수 있습니다.