FOC(Field-Oriented Control) 알고리즘의 핵심 부분을 구현한 간단한 C 코드

FOC(Field-Oriented Control) 알고리즘의 핵심 부분을 구현한 간단한 C 코드입니다. 이 코드는 다음의 주요 단계를 포함합니다:

  1. Clarke 변환: 3상 전류를 2축(α-β)으로 변환.
  2. Park 변환: 정지 좌표계(α-β)를 회전 좌표계(d-q)로 변환.
  3. PI 제어기: d축 및 q축 전류를 제어.
  4. 역 Park 변환: 회전 좌표계(d-q)를 정지 좌표계(α-β)로 변환.
  5. 역 Clarke 변환: 정지 좌표계(α-β)를 3상 전압으로 변환.

FOC 알고리즘 C 코드

#include <math.h>
#include <stdint.h>

// PI 제어기 구조체
typedef struct {
    float kp;    // 비례 이득
    float ki;    // 적분 이득
    float integral; // 적분값
    float max;   // 출력 최대값
    float min;   // 출력 최소값
} PIController;

// PI 제어기 함수
float PI_Controller(PIController *controller, float error) {
    controller->integral += error;
    float output = controller->kp * error + controller->ki * controller->integral;

    // 출력 제한
    if (output > controller->max) {
        output = controller->max;
    } else if (output < controller->min) {
        output = controller->min;
    }
    return output;
}

// Clarke 변환: 3상 -> 2축
void ClarkeTransform(float ia, float ib, float *i_alpha, float *i_beta) {
    *i_alpha = ia;
    *i_beta = (1.0f / sqrtf(3.0f)) * (ia + 2.0f * ib);
}

// Park 변환: 2축 -> 회전 좌표계
void ParkTransform(float i_alpha, float i_beta, float theta, float *i_d, float *i_q) {
    *i_d = i_alpha * cosf(theta) + i_beta * sinf(theta);
    *i_q = -i_alpha * sinf(theta) + i_beta * cosf(theta);
}

// 역 Park 변환: 회전 좌표계 -> 2축
void InverseParkTransform(float v_d, float v_q, float theta, float *v_alpha, float *v_beta) {
    *v_alpha = v_d * cosf(theta) - v_q * sinf(theta);
    *v_beta = v_d * sinf(theta) + v_q * cosf(theta);
}

// 역 Clarke 변환: 2축 -> 3상
void InverseClarkeTransform(float v_alpha, float v_beta, float *va, float *vb, float *vc) {
    *va = v_alpha;
    *vb = -0.5f * v_alpha + sqrtf(3.0f) / 2.0f * v_beta;
    *vc = -0.5f * v_alpha - sqrtf(3.0f) / 2.0f * v_beta;
}

// FOC 알고리즘 메인 루프
void FOC(float ia, float ib, float theta, PIController *pi_d, PIController *pi_q,
         float i_d_ref, float i_q_ref, float *va, float *vb, float *vc) {
    // Clarke 변환
    float i_alpha, i_beta;
    ClarkeTransform(ia, ib, &i_alpha, &i_beta);

    // Park 변환
    float i_d, i_q;
    ParkTransform(i_alpha, i_beta, theta, &i_d, &i_q);

    // PI 제어기 적용
    float v_d = PI_Controller(pi_d, i_d_ref - i_d);
    float v_q = PI_Controller(pi_q, i_q_ref - i_q);

    // 역 Park 변환
    float v_alpha, v_beta;
    InverseParkTransform(v_d, v_q, theta, &v_alpha, &v_beta);

    // 역 Clarke 변환
    InverseClarkeTransform(v_alpha, v_beta, va, vb, vc);
}

주요 변수 설명

  1. 입력 변수:
    • ia, ib: 3상 전류 중 A상과 B상의 전류 (C상은 ic=−(ia+ib)i_c = -(i_a + i_b)로 계산 가능).
    • theta: 회전자(로터)의 자속 위치각 (엔코더 또는 센서리스 기법으로 측정).
    • i_d_ref, i_q_ref: 목표 d축과 q축 전류 (예: d축은 자속, q축은 토크 생성).
  2. 출력 변수:
    • va, vb, vc: 3상 전압 출력 (PWM 신호로 변환되어 모터 구동).
  3. PI 제어기 구조체:
    • PIController: d축 및 q축 전류의 오차를 제어하여 안정적인 속도와 토크를 생성.

테스트 코드 예제

#include <stdio.h>

int main() {
    // PI 제어기 초기화
    PIController pi_d = { .kp = 0.1f, .ki = 0.01f, .integral = 0, .max = 1.0f, .min = -1.0f };
    PIController pi_q = { .kp = 0.1f, .ki = 0.01f, .integral = 0, .max = 1.0f, .min = -1.0f };

    // 입력 데이터
    float ia = 1.0f, ib = -0.5f;   // 모터의 3상 전류 중 일부
    float theta = 1.57f;           // 로터 자속의 위치각
    float i_d_ref = 0.0f;          // 목표 d축 전류
    float i_q_ref = 1.0f;          // 목표 q축 전류

    // 출력 데이터
    float va, vb, vc;

    // FOC 호출
    FOC(ia, ib, theta, &pi_d, &pi_q, i_d_ref, i_q_ref, &va, &vb, &vc);

    // 출력 확인
    printf("Output Voltages: Va = %f, Vb = %f, Vc = %f\n", va, vb, vc);
    return 0;
}

요약

위 코드는 FOC 알고리즘의 핵심 흐름을 간단하게 구현한 예제입니다. 실제 시스템에서는 더 정밀한 고속 처리와 하드웨어 인터페이스를 추가해야 하며, 하드웨어 및 소프트웨어 요구사항에 따라 코드를 최적화할 필요가 있습니다.