187d9e58c9
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
493 lines
17 KiB
C
493 lines
17 KiB
C
/****************************************************************************
|
|
* include/dspb16.h
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed with
|
|
* this work for additional information regarding copyright ownership. The
|
|
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
* "License"); you may not use this file except in compliance with the
|
|
* License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
* License for the specific language governing permissions and limitations
|
|
* under the License.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifndef __INCLUDE_DSPB16_H
|
|
#define __INCLUDE_DSPB16_H
|
|
|
|
/****************************************************************************
|
|
* Included Files
|
|
****************************************************************************/
|
|
|
|
#include <nuttx/compiler.h>
|
|
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
#include <fixedmath.h>
|
|
|
|
/****************************************************************************
|
|
* Pre-processor Definitions
|
|
****************************************************************************/
|
|
|
|
/* Disable DEBUGASSERT macro if LIBDSP debug is not enabled */
|
|
|
|
#ifdef CONFIG_LIBDSP_DEBUG
|
|
# ifndef CONFIG_DEBUG_ASSERTIONS
|
|
# warning "Need CONFIG_DEBUG_ASSERTIONS to work properly"
|
|
# endif
|
|
# define LIBDSP_DEBUGASSERT(x) DEBUGASSERT(x)
|
|
#else
|
|
# undef LIBDSP_DEBUGASSERT
|
|
# define LIBDSP_DEBUGASSERT(x)
|
|
#endif
|
|
|
|
#ifndef CONFIG_LIBDSP_PRECISION
|
|
# define CONFIG_LIBDSP_PRECISION 0
|
|
#endif
|
|
|
|
/* Phase rotation direction */
|
|
|
|
#define DIR_NONE_B16 ftob16(0.0f)
|
|
#define DIR_CW_B16 ftob16(1.0f)
|
|
#define DIR_CCW_B16 ftob16(-1.0f)
|
|
|
|
/* Some math constants ******************************************************/
|
|
|
|
#define SQRT3_BY_TWO_B16 ftob16(0.866025f)
|
|
#define SQRT3_BY_THREE_B16 ftob16(0.57735f)
|
|
#define ONE_BY_SQRT3_B16 ftob16(0.57735f)
|
|
#define TWO_BY_SQRT3_B16 ftob16(1.15470f)
|
|
|
|
/* Some lib constants *******************************************************/
|
|
|
|
/* Motor electrical angle is in range 0.0 to 2*PI */
|
|
|
|
#define MOTOR_ANGLE_E_MAX_B16 (b16TWOPI)
|
|
#define MOTOR_ANGLE_E_MIN_B16 (0)
|
|
#define MOTOR_ANGLE_E_RANGE_B16 (MOTOR_ANGLE_E_MAX_B16 - MOTOR_ANGLE_E_MIN_B16)
|
|
|
|
/* Motor mechanical angle is in range 0.0 to 2*PI */
|
|
|
|
#define MOTOR_ANGLE_M_MAX_B16 (b16TWOPI)
|
|
#define MOTOR_ANGLE_M_MIN_B16 (0)
|
|
#define MOTOR_ANGLE_M_RANGE_B16 (MOTOR_ANGLE_M_MAX_B16 - MOTOR_ANGLE_M_MIN_B16)
|
|
|
|
/* Some useful macros *******************************************************/
|
|
|
|
/****************************************************************************
|
|
* Name: LP_FILTER_B16
|
|
*
|
|
* Description:
|
|
* Simple single-pole digital low pass filter:
|
|
* Y(n) = (1-beta)*Y(n-1) + beta*X(n) = (beta * (Y(n-1) - X(n)))
|
|
*
|
|
* filter - (0.0 - 1.0) where 1.0 gives unfiltered values
|
|
* filter = T * (2*PI) * f_c
|
|
*
|
|
* phase shift = -arctan(f_in/f_c)
|
|
*
|
|
* T - period at which the digital filter is being calculated
|
|
* f_in - input frequency of the filter
|
|
* f_c - cutoff frequency of the filter
|
|
*
|
|
* REFERENCE: https://www.embeddedrelated.com/showarticle/779.php
|
|
*
|
|
****************************************************************************/
|
|
|
|
#define LP_FILTER_B16(val, sample, filter) val -= (b16mulb16(filter, (val - sample)))
|
|
|
|
/****************************************************************************
|
|
* Name: SVM3_BASE_VOLTAGE_GET_B16
|
|
*
|
|
* Description:
|
|
* Get maximum voltage for SVM3 without overmodulation
|
|
*
|
|
* Notes:
|
|
* max possible phase voltage for 3-phase power inverter:
|
|
* Vd = (2/3)*Vdc
|
|
* max phase reference voltage according to SVM modulation diagram:
|
|
* Vrefmax = Vd * cos(30*) = SQRT3_BY_2 * Vd
|
|
* which give us:
|
|
* Vrefmax = SQRT3_BY_3 * Vdc
|
|
*
|
|
* Vdc - bus voltage
|
|
*
|
|
****************************************************************************/
|
|
|
|
#define SVM3_BASE_VOLTAGE_GET_B16(vbus) (b16mulb16(vbus, SQRT3_BY_THREE_B16))
|
|
|
|
/****************************************************************************
|
|
* Public Types
|
|
****************************************************************************/
|
|
|
|
/* This structure represents phase angle.
|
|
* Besides angle value it also stores sine and cosine values for given angle.
|
|
*/
|
|
|
|
struct phase_angle_b16_s
|
|
{
|
|
b16_t angle; /* Phase angle in radians <0, 2PI> */
|
|
b16_t sin; /* Phase angle sine */
|
|
b16_t cos; /* Phase angle cosine */
|
|
};
|
|
|
|
typedef struct phase_angle_b16_s phase_angle_b16_t;
|
|
|
|
/* This structure stores motor angles and corresponding sin and cos values
|
|
*
|
|
* th_el = th_m * pole_pairs
|
|
* th_m = th_el/pole_pairs
|
|
*
|
|
* where:
|
|
* th_el - motor electrical angle
|
|
* th_m - motor mechanical angle
|
|
* pole_pairs - motor pole pairs
|
|
*
|
|
* NOTE: pole_pairs = poles_total/2
|
|
*/
|
|
|
|
struct motor_angle_b16_s
|
|
{
|
|
phase_angle_b16_t angle_el; /* Electrical angle */
|
|
b16_t anglem; /* Mechanical angle in radians <0, 2PI> */
|
|
b16_t one_by_p; /* Aux variable */
|
|
uint8_t p; /* Number of the motor pole pairs */
|
|
int8_t i; /* Pole counter */
|
|
};
|
|
|
|
/* Float number saturaton */
|
|
|
|
struct float_sat_b16_s
|
|
{
|
|
b16_t min; /* Lower limit */
|
|
b16_t max; /* Upper limit */
|
|
};
|
|
|
|
typedef struct float_sat_b16_s float_sat_b16_t;
|
|
|
|
/* PI/PID controller state structure */
|
|
|
|
struct pid_controller_b16_s
|
|
{
|
|
bool aw_en; /* Integral part decay if saturated */
|
|
bool ireset_en; /* Intergral part reset if saturated */
|
|
bool pisat_en; /* PI saturation enabled */
|
|
bool pidsat_en; /* PID saturation enabled */
|
|
bool _res; /* Reserved */
|
|
b16_t out; /* Controller output */
|
|
float_sat_b16_t sat; /* Output saturation */
|
|
b16_t err; /* Current error value */
|
|
b16_t err_prev; /* Previous error value */
|
|
b16_t KP; /* Proportional coefficient */
|
|
b16_t KI; /* Integral coefficient */
|
|
b16_t KD; /* Derivative coefficient */
|
|
b16_t part[3]; /* 0 - proporitonal part
|
|
* 1 - integral part
|
|
* 2 - derivative part
|
|
*/
|
|
b16_t KC; /* Integral anti-windup decay coefficient */
|
|
b16_t aw; /* Integral anti-windup decay part */
|
|
};
|
|
|
|
typedef struct pid_controller_b16_s pid_controller_b16_t;
|
|
|
|
/* This structure represents the ABC frame (3 phase vector) */
|
|
|
|
struct abc_frame_b16_s
|
|
{
|
|
b16_t a; /* A component */
|
|
b16_t b; /* B component */
|
|
b16_t c; /* C component */
|
|
};
|
|
|
|
typedef struct abc_frame_b16_s abc_frame_b16_t;
|
|
|
|
/* This structure represents the alpha-beta frame (2 phase vector) */
|
|
|
|
struct ab_frame_b16_s
|
|
{
|
|
b16_t a; /* Alpha component */
|
|
b16_t b; /* Beta component */
|
|
};
|
|
|
|
typedef struct ab_frame_b16_s ab_frame_b16_t;
|
|
|
|
/* This structure represent the direct-quadrature frame */
|
|
|
|
struct dq_frame_b16_s
|
|
{
|
|
b16_t d; /* Driect component */
|
|
b16_t q; /* Quadrature component */
|
|
};
|
|
|
|
typedef struct dq_frame_b16_s dq_frame_b16_t;
|
|
|
|
/* Space Vector Modulation data for 3-phase system */
|
|
|
|
struct svm3_state_b16_s
|
|
{
|
|
uint8_t sector; /* Current space vector sector */
|
|
b16_t d_u; /* Duty cycle for phase U */
|
|
b16_t d_v; /* Duty cycle for phase V */
|
|
b16_t d_w; /* Duty cycle for phase W */
|
|
};
|
|
|
|
/* Motor open-loop control data */
|
|
|
|
struct openloop_data_b16_s
|
|
{
|
|
b16_t angle; /* Open-loop current angle normalized to <0.0, 2PI> */
|
|
b16_t per; /* Open-loop control execution period */
|
|
};
|
|
|
|
/* FOC initialize data */
|
|
|
|
struct foc_initdata_b16_s
|
|
{
|
|
b16_t id_kp; /* KP for d current */
|
|
b16_t id_ki; /* KI for d current */
|
|
b16_t iq_kp; /* KP for q current */
|
|
b16_t iq_ki; /* KI for q current */
|
|
};
|
|
|
|
/* Field Oriented Control (FOC) data */
|
|
|
|
struct foc_data_b16_s
|
|
{
|
|
abc_frame_b16_t v_abc; /* Voltage in ABC frame */
|
|
ab_frame_b16_t v_ab; /* Voltage in alpha-beta frame */
|
|
dq_frame_b16_t v_dq; /* Requested voltage in dq frame */
|
|
ab_frame_b16_t v_ab_mod; /* Modulation voltage normalized to
|
|
* magnitude (0.0, 1.0)
|
|
*/
|
|
|
|
abc_frame_b16_t i_abc; /* Current in ABC frame */
|
|
ab_frame_b16_t i_ab; /* Current in alpha-beta frame */
|
|
dq_frame_b16_t i_dq; /* Current in dq frame */
|
|
dq_frame_b16_t i_dq_err; /* DQ current error */
|
|
|
|
dq_frame_b16_t i_dq_ref; /* Requested current for the FOC
|
|
* current controller
|
|
*/
|
|
|
|
pid_controller_b16_t id_pid; /* Current d-axis component PI controller */
|
|
pid_controller_b16_t iq_pid; /* Current q-axis component PI controller */
|
|
|
|
b16_t vdq_mag_max; /* Maximum dq voltage magnitude */
|
|
b16_t vab_mod_scale; /* Voltage alpha-beta modulation scale */
|
|
|
|
phase_angle_b16_t angle; /* Phase angle */
|
|
};
|
|
|
|
/* Motor physical parameters.
|
|
* This data structure was designed to work with BLDC/PMSM motors,
|
|
* but probably can be used to describe different types of motors.
|
|
*/
|
|
|
|
struct motor_phy_params_b16_s
|
|
{
|
|
uint8_t p; /* Number of the motor pole pairs */
|
|
b16_t res; /* Phase-to-neutral temperature compensated
|
|
* resistance
|
|
*/
|
|
b16_t ind; /* Average phase-to-neutral inductance */
|
|
b16_t one_by_ind; /* Inverse phase-to-neutral inductance */
|
|
};
|
|
|
|
/* PMSM motor physcial parameters */
|
|
|
|
struct pmsm_phy_params_b16_s
|
|
{
|
|
struct motor_phy_params_b16_s motor; /* Motor common PHY */
|
|
b16_t iner; /* Rotor inertia */
|
|
b16_t flux_link; /* Flux linkage */
|
|
b16_t ind_d; /* d-inductance */
|
|
b16_t ind_q; /* q-inductance */
|
|
b16_t one_by_iner; /* One by J */
|
|
b16_t one_by_indd; /* One by Ld */
|
|
b16_t one_by_indq; /* One by Lq */
|
|
};
|
|
|
|
/* PMSM motor model state */
|
|
|
|
struct pmsm_model_state_b16_s
|
|
{
|
|
/* Motor model phase current */
|
|
|
|
abc_frame_b16_t i_abc;
|
|
ab_frame_b16_t i_ab;
|
|
dq_frame_b16_t i_dq;
|
|
|
|
/* Motor model phase voltage */
|
|
|
|
abc_frame_b16_t v_abc;
|
|
ab_frame_b16_t v_ab;
|
|
dq_frame_b16_t v_dq;
|
|
|
|
/* Motor model angle */
|
|
|
|
struct motor_angle_b16_s angle;
|
|
|
|
/* Angular speed */
|
|
|
|
b16_t omega_e;
|
|
b16_t omega_m;
|
|
};
|
|
|
|
/* PMSM motor model external conditions */
|
|
|
|
struct pmsm_model_ext_b16_s
|
|
{
|
|
b16_t load; /* Motor model load torque */
|
|
};
|
|
|
|
/* PMSM motor model */
|
|
|
|
struct pmsm_model_b16_s
|
|
{
|
|
struct pmsm_phy_params_b16_s phy; /* Motor model physical parameters */
|
|
struct pmsm_model_state_b16_s state; /* Motor model state */
|
|
struct pmsm_model_ext_b16_s ext; /* Motor model external conditions */
|
|
b16_t per; /* Control period */
|
|
b16_t id_int; /* Id integral part */
|
|
b16_t iq_int; /* Iq integral part */
|
|
};
|
|
|
|
/****************************************************************************
|
|
* Public Functions Prototypes
|
|
****************************************************************************/
|
|
|
|
#undef EXTERN
|
|
#if defined(__cplusplus)
|
|
#define EXTERN extern "C"
|
|
extern "C"
|
|
{
|
|
#else
|
|
#define EXTERN extern
|
|
#endif
|
|
|
|
/* Math functions */
|
|
|
|
b16_t fast_sin_b16(b16_t angle);
|
|
b16_t fast_sin2_b16(b16_t angle);
|
|
b16_t fast_cos_b16(b16_t angle);
|
|
b16_t fast_cos2_b16(b16_t angle);
|
|
b16_t fast_atan2_b16(b16_t y, b16_t x);
|
|
void f_saturate_b16(FAR b16_t *val, b16_t min, b16_t max);
|
|
b16_t vector2d_mag_b16(b16_t x, b16_t y);
|
|
void vector2d_saturate_b16(FAR b16_t *x, FAR b16_t *y, b16_t max);
|
|
void dq_saturate_b16(FAR dq_frame_b16_t *dq, b16_t max);
|
|
b16_t dq_mag_b16(FAR dq_frame_b16_t *dq);
|
|
|
|
/* PID controller functions */
|
|
|
|
void pid_controller_init_b16(FAR pid_controller_b16_t *pid,
|
|
b16_t KP, b16_t KI, b16_t KD);
|
|
void pi_controller_init_b16(FAR pid_controller_b16_t *pid,
|
|
b16_t KP, b16_t KI);
|
|
void pid_saturation_set_b16(FAR pid_controller_b16_t *pid, b16_t min,
|
|
b16_t max);
|
|
void pi_saturation_set_b16(FAR pid_controller_b16_t *pid, b16_t min,
|
|
b16_t max);
|
|
void pid_integral_reset_b16(FAR pid_controller_b16_t *pid);
|
|
void pi_integral_reset_b16(FAR pid_controller_b16_t *pid);
|
|
b16_t pi_controller_b16(FAR pid_controller_b16_t *pid, b16_t err);
|
|
b16_t pid_controller_b16(FAR pid_controller_b16_t *pid, b16_t err);
|
|
void pi_antiwindup_enable_b16(FAR pid_controller_b16_t *pid, b16_t KC,
|
|
bool enable);
|
|
void pi_ireset_enable_b16(FAR pid_controller_b16_t *pid, bool enable);
|
|
|
|
/* Transformation functions */
|
|
|
|
void clarke_transform_b16(FAR abc_frame_b16_t *abc, FAR ab_frame_b16_t *ab);
|
|
void inv_clarke_transform_b16(FAR ab_frame_b16_t *ab,
|
|
FAR abc_frame_b16_t *abc);
|
|
void park_transform_b16(FAR phase_angle_b16_t *angle, FAR ab_frame_b16_t *ab,
|
|
FAR dq_frame_b16_t *dq);
|
|
void inv_park_transform_b16(FAR phase_angle_b16_t *angle,
|
|
FAR dq_frame_b16_t *dq, FAR ab_frame_b16_t *ab);
|
|
|
|
/* Phase angle related functions */
|
|
|
|
void angle_norm_b16(FAR b16_t *angle, b16_t per, b16_t bottom, b16_t top);
|
|
void angle_norm_2pi_b16(FAR b16_t *angle, b16_t bottom, b16_t top);
|
|
void phase_angle_update_b16(FAR struct phase_angle_b16_s *angle, b16_t val);
|
|
|
|
/* 3-phase system space vector modulation */
|
|
|
|
void svm3_init_b16(FAR struct svm3_state_b16_s *s);
|
|
void svm3_b16(FAR struct svm3_state_b16_s *s, FAR ab_frame_b16_t *ab);
|
|
void svm3_current_correct_b16(FAR struct svm3_state_b16_s *s,
|
|
b16_t *c0, b16_t *c1, b16_t *c2);
|
|
|
|
/* Field Oriented Control */
|
|
|
|
void foc_init_b16(FAR struct foc_data_b16_s *foc,
|
|
FAR struct foc_initdata_b16_s *init);
|
|
void foc_vbase_update_b16(FAR struct foc_data_b16_s *foc, b16_t vbase);
|
|
void foc_angle_update_b16(FAR struct foc_data_b16_s *foc,
|
|
FAR phase_angle_b16_t *angle);
|
|
void foc_iabc_update_b16(FAR struct foc_data_b16_s *foc,
|
|
FAR abc_frame_b16_t *i_abc);
|
|
void foc_voltage_control_b16(FAR struct foc_data_b16_s *foc,
|
|
FAR dq_frame_b16_t *vdq_ref);
|
|
void foc_current_control_b16(FAR struct foc_data_b16_s *foc,
|
|
FAR dq_frame_b16_t *idq_ref,
|
|
FAR dq_frame_b16_t *vdq_comp,
|
|
FAR dq_frame_b16_t *v_dq_ref);
|
|
void foc_vabmod_get_b16(FAR struct foc_data_b16_s *foc,
|
|
FAR ab_frame_b16_t *v_ab_mod);
|
|
void foc_vdq_mag_max_get_b16(FAR struct foc_data_b16_s *foc, FAR b16_t *max);
|
|
|
|
/* Motor openloop control */
|
|
|
|
void motor_openloop_init_b16(FAR struct openloop_data_b16_s *op, b16_t per);
|
|
void motor_openloop_b16(FAR struct openloop_data_b16_s *op, b16_t speed,
|
|
b16_t dir);
|
|
b16_t motor_openloop_angle_get_b16(FAR struct openloop_data_b16_s *op);
|
|
|
|
/* Motor angle */
|
|
|
|
void motor_angle_init_b16(FAR struct motor_angle_b16_s *angle, uint8_t p);
|
|
void motor_angle_e_update_b16(FAR struct motor_angle_b16_s *angle,
|
|
b16_t angle_new, b16_t dir);
|
|
void motor_angle_m_update_b16(FAR struct motor_angle_b16_s *angle,
|
|
b16_t angle_new, b16_t dir);
|
|
b16_t motor_angle_m_get_b16(FAR struct motor_angle_b16_s *angle);
|
|
b16_t motor_angle_e_get_b16(FAR struct motor_angle_b16_s *angle);
|
|
|
|
/* Motor physical parameters */
|
|
|
|
void motor_phy_params_init_b16(FAR struct motor_phy_params_b16_s *phy,
|
|
uint8_t poles, b16_t res, b16_t ind);
|
|
|
|
/* PMSM physical parameters functions */
|
|
|
|
void pmsm_phy_params_init_b16(FAR struct pmsm_phy_params_b16_s *phy,
|
|
uint8_t poles, b16_t res, b16_t ind,
|
|
b16_t iner, b16_t flux,
|
|
b16_t ind_d, b16_t ind_q);
|
|
|
|
/* PMSM motor model */
|
|
|
|
int pmsm_model_initialize_b16(FAR struct pmsm_model_b16_s *model,
|
|
FAR struct pmsm_phy_params_b16_s *phy,
|
|
b16_t per);
|
|
int pmsm_model_elec_b16(FAR struct pmsm_model_b16_s *model,
|
|
FAR ab_frame_b16_t *vab);
|
|
int pmsm_model_mech_b16(FAR struct pmsm_model_b16_s *model, b16_t load);
|
|
|
|
#undef EXTERN
|
|
#if defined(__cplusplus)
|
|
}
|
|
#endif
|
|
|
|
#endif /* __INCLUDE_DSPB16_H */
|