/**
******************************************************************************
* @file phases_transform.c
* @brief Функции для преобразования напряжений/токов в многофазных системах
******************************************************************************
* @details
******************************************************************************/
#include "phases_transform.h"
#define SQRT3 1.7320508

/** 
  * @brief    Рассчитать результирующий вектор трехфазной системы по фазным величинам.
  * @return   Длина вектора (модуль).
  */
float vector_abs_phase_calc(float phase1, float phase2)
{
  /* Двухвазная система координат x-y */
  float x = phase1;
  float y = (-phase1 - 2*phase2)/SQRT3;
  float V = 0;
  arm_status res = arm_sqrt_f32(x*x + y*y, &V);
  
  if(res == ARM_MATH_SUCCESS)
    return V;
  else
    return 0;
}

/** 
  * @brief    Рассчитать результирующий вектор трехфазной системы по линейным величинам.
  * @return   Длина вектора (модуль).
  */
float vector_abs_linear_calc(float phase1, float phase2)
{
  /* Двухвазная система координат x-y */
  float x = (phase1 - phase2)/SQRT3;
  float y = -phase1 - phase2;
  float V = 0;
  arm_status res = arm_sqrt_f32(x*x + y*y, &V);
  
  if(res == ARM_MATH_SUCCESS)
    return V;
  else
    return 0;
}

/**
  * @brief    Рассчитать фазные напряжения из линейных (звезда)
  * @param    Ulin  Линейные напряжения [Uba Uac Ubc]
  * @param    Uph   Фазные напряжения [Ua Ub Uc]
  */
void linear_to_phase_star(float *Ulin, float *Uph)
{
    if(Ulin == NULL || Uph == NULL)
        return;

    // Соответствие макросам: Ulin[0] = UBA, Ulin[1] = UAC, Ulin[2] = UBC
    float Uba = Ulin[0];
    float Uac = Ulin[1];
    float Ubc = Ulin[2];

    // Формулы для звезды (сумма фаз = 0)
    Uph[0] = (Uba - Ubc)/3.0f; // Ua
    Uph[1] = (Ubc - Uac)/3.0f; // Ub
    Uph[2] = (Uac - Uba)/3.0f; // Uc
}

/**
  * @brief    Рассчитать фазные напряжения из линейных (треугольник)
  * @param    Ulin  Линейные напряжения [Uba Uac Ubc]
  * @param    Uph   Фазные напряжения [Ua Ub Uc]
  */
void linear_to_phase_delta(float *Ulin, float *Uph)
{
    if(Ulin == NULL || Uph == NULL)
        return;

    // Соответствие макросам: Ulin[0] = UBA, Ulin[1] = UAC, Ulin[2] = UBC
    // Для треугольника фазные напряжения равны линейным
    Uph[0] = Ulin[0]; // Ua = Uba
    Uph[1] = Ulin[2]; // Ub = Ubc
    Uph[2] = Ulin[1]; // Uc = Uac
}
