2016년 9월 5일 월요일

GenericServo

GenericServo는 서보(Servo) 모터를 제어하기 위한 ArdunityController입니다.
서보 모터란, 명령한 목표에 근접하기 위해 스스로 제어하는 모터를 의미합니다. 이로 인해서 서보 모터는 스스로 제어하기 위한 방법으로 피드백 제어(Feedback Control)라 불리는 방식을 사용하는데, PID 제어가 대표적인 피드백 제어 방식입니다.
피드백 제어 개념도

일반적으로 서보 모터라 하면 각도(Angle)로 제어할 수 있는 모터를 의미합니다. 각도 제어 모터가 활용되는 대표적 분야는 로봇 분야입니다.

서보 모터 대중화에 가장 크게 공헌한 것은 RC 서보 모터입니다. RC 자동차의 조향 장치로 많이 사용되며 값이 싸고 제어 방법이 간단하다는 것이 특징입니다.

GenericServo는 바로 RC 서보 모터를 제어할 수 있는 기능을 제공합니다.
RC 서보 모터는 PWM 신호로 각도가 제어됩니다.
RC 서보 모터 제어를 위한 PWM 규격

아두이노에서는 RC 서보를 쉽게 사용할 수 있도록 Servo 라이브러리가 존재합니다. GenericServo는 아두이노의 Servo 라이브러리로 RC 서보 모터를 제어합니다.


GenericServo를 사용하기 위해서는 다음과 같은 설정을 해야 합니다.

  • id: ArdunityApp이 ArdunityController를 구분하기 위한 식별자
  • pin: 서보 모터 제어를 위한 PWM 핀
  • Calibrated Angle: Center Angle을 맞추기 위한 보상 각도
  • Min Angle: 회전 최소 각도
  • Max Angle: 회전 최대 각도
  • Angle: 서보 모터의 제어 각도
캘리브레이션(Calibration)
캘리브레이션이란, 오차(Error)를 보상하기 위한 과정을 말합니다. 서보 모터에서 캘리브레이션이란 각도에 대한 오차 보상을 의미합니다.
RC 서보 모터는 가격이 싼 만큼 실제 각도와 제어 각도의 편차가 존재합니다. (정밀도가 높은 서보 모터는 이 작업을 할 필요가 없습니다.)
서보 모터의 실제 각도를 측정하면 차이가 생긴다.
이 오차 각도를 맞춰야 할 필요가 있는 경우 Calibrated Angle을 설정함으로써 맞출 수 있습니다.

제한 각(Angle Limitation)
서보 모터는 0 ~ 180도 제어 범위를 갖습니다. 실제로 서보 모터를 이용해서 구조물을 만들게 되면 이 제어 범위를 다 사용할 경우 구조물이나 모터에 손상이 가는 문제가 발생할 수 있습니다.
서보 모터로 로봇을 만들 경우 각도 제한이 필요합니다.

Min Angle과 Max Angle은 제어 각의 한계 치를 정함으로써 이런 문제가 사전에 발생하지 않도록 만들 수 있습니다.

제어 각도과 실제 각도
GenericServo의 Angle 값을 변경하면 실제 서보 모터의 각도가 변경됩니다. Angle의 값의 범위는 -90 ~ 90이며 0이 가운데(Center) 각도를 의미합니다.

GenericServo를 사용하기 위해서는 Wire Editor에서 다음과 같이 연결하면 되고, 이것을 아두이노 스케치로 생성하여 업로드하면 모든 제어 준비가 끝납니다.

이제 남은 것은 유니티에서 GenericServo를 제어하는 것입니다.
C# Script로 GenericServo의 Angle을 변경할 수 있으며 예제 코드는 다음과 같습니다.
(본 예제는 보드 연결 시 서보 모터 각도를 -90도에서 90도까지 왕복합니다.)

using UnityEngine;
using System.Collections;
using Ardunity;

public class MyComponent : MonoBehaviour
{
 public GenericServo servo;

 private bool _toggle = true;
 private float _angle;
 
 void Start ()
 {
   _angle = servo.angle;
 }

 void Update ()
 {
  if(servo.connected)
  {
    if(_toggle == true)
    {
       _angle += 0.01f;
       if(_angle >= 90f)
       {
         _angle = 90f;
         _toggle = false;
       }
    }
    else
    {
       _angle -= 0.01f;
       if(_angle <= -90f)
       {
         _value = -90f;
         _toggle = true;
       }
    }

    servo.angle = _angle;
  }
 }
}

댓글 없음:

댓글 쓰기