dsp.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574
  1. /****************************************************************************
  2. * include/dsp.h
  3. *
  4. * Licensed to the Apache Software Foundation (ASF) under one or more
  5. * contributor license agreements. See the NOTICE file distributed with
  6. * this work for additional information regarding copyright ownership. The
  7. * ASF licenses this file to you under the Apache License, Version 2.0 (the
  8. * "License"); you may not use this file except in compliance with the
  9. * License. You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  15. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  16. * License for the specific language governing permissions and limitations
  17. * under the License.
  18. *
  19. ****************************************************************************/
  20. #ifndef __INCLUDE_DSP_H
  21. #define __INCLUDE_DSP_H
  22. /****************************************************************************
  23. * Included Files
  24. ****************************************************************************/
  25. #include <nuttx/compiler.h>
  26. #include <stddef.h>
  27. #include <stdint.h>
  28. #include <string.h>
  29. #include <stdbool.h>
  30. #include <math.h>
  31. #include <assert.h>
  32. /****************************************************************************
  33. * Pre-processor Definitions
  34. ****************************************************************************/
  35. /* Disable DEBUGASSERT macro if LIBDSP debug is not enabled */
  36. #ifdef CONFIG_LIBDSP_DEBUG
  37. # ifndef CONFIG_DEBUG_ASSERTIONS
  38. # warning "Need CONFIG_DEBUG_ASSERTIONS to work properly"
  39. # endif
  40. # define LIBDSP_DEBUGASSERT(x) DEBUGASSERT(x)
  41. #else
  42. # undef LIBDSP_DEBUGASSERT
  43. # define LIBDSP_DEBUGASSERT(x)
  44. #endif
  45. #ifndef CONFIG_LIBDSP_PRECISION
  46. # define CONFIG_LIBDSP_PRECISION 0
  47. #endif
  48. /* Phase rotation direction */
  49. #define DIR_NONE (0.0f)
  50. #define DIR_CW (1.0f)
  51. #define DIR_CCW (-1.0f)
  52. /* Some math constants ******************************************************/
  53. #define SQRT3_BY_TWO_F (0.866025f)
  54. #define SQRT3_BY_THREE_F (0.57735f)
  55. #define ONE_BY_SQRT3_F (0.57735f)
  56. #define TWO_BY_SQRT3_F (1.15470f)
  57. /* Some lib constants *******************************************************/
  58. /* Motor electrical angle is in range 0.0 to 2*PI */
  59. #define MOTOR_ANGLE_E_MAX (2.0f*M_PI_F)
  60. #define MOTOR_ANGLE_E_MIN (0.0f)
  61. #define MOTOR_ANGLE_E_RANGE (MOTOR_ANGLE_E_MAX - MOTOR_ANGLE_E_MIN)
  62. /* Motor mechanical angle is in range 0.0 to 2*PI */
  63. #define MOTOR_ANGLE_M_MAX (2.0f*M_PI_F)
  64. #define MOTOR_ANGLE_M_MIN (0.0f)
  65. #define MOTOR_ANGLE_M_RANGE (MOTOR_ANGLE_M_MAX - MOTOR_ANGLE_M_MIN)
  66. /* Some useful macros *******************************************************/
  67. /****************************************************************************
  68. * Name: LP_FILTER
  69. *
  70. * Description:
  71. * Simple single-pole digital low pass filter:
  72. * Y(n) = (1-beta)*Y(n-1) + beta*X(n) = (beta * (Y(n-1) - X(n)))
  73. *
  74. * filter - (0.0 - 1.0) where 1.0 gives unfiltered values
  75. * filter = T * (2*PI) * f_c
  76. *
  77. * phase shift = -arctan(f_in/f_c)
  78. *
  79. * T - period at which the digital filter is being calculated
  80. * f_in - input frequency of the filter
  81. * f_c - cutoff frequency of the filter
  82. *
  83. * REFERENCE: https://www.embeddedrelated.com/showarticle/779.php
  84. *
  85. ****************************************************************************/
  86. #define LP_FILTER(val, sample, filter) val -= (filter * (val - sample))
  87. /****************************************************************************
  88. * Name: SVM3_BASE_VOLTAGE_GET
  89. *
  90. * Description:
  91. * Get maximum voltage for SVM3 without overmodulation
  92. *
  93. * Notes:
  94. * max possible phase voltage for 3-phase power inverter:
  95. * Vd = (2/3)*Vdc
  96. * max phase reference voltage according to SVM modulation diagram:
  97. * Vrefmax = Vd * cos(30*) = SQRT3_BY_2 * Vd
  98. * which give us:
  99. * Vrefmax = SQRT3_BY_3 * Vdc
  100. *
  101. * Vdc - bus voltage
  102. *
  103. ****************************************************************************/
  104. #define SVM3_BASE_VOLTAGE_GET(vbus) (vbus * SQRT3_BY_THREE_F)
  105. /****************************************************************************
  106. * Public Types
  107. ****************************************************************************/
  108. /* This structure represents phase angle.
  109. * Besides angle value it also stores sine and cosine values for given angle.
  110. */
  111. struct phase_angle_f32_s
  112. {
  113. float angle; /* Phase angle in radians <0, 2PI> */
  114. float sin; /* Phase angle sine */
  115. float cos; /* Phase angle cosine */
  116. };
  117. typedef struct phase_angle_f32_s phase_angle_f32_t;
  118. /* This structure stores motor angles and corresponding sin and cos values
  119. *
  120. * th_el = th_m * pole_pairs
  121. * th_m = th_el/pole_pairs
  122. *
  123. * where:
  124. * th_el - motor electrical angle
  125. * th_m - motor mechanical angle
  126. * pole_pairs - motor pole pairs
  127. *
  128. * NOTE: pole_pairs = poles_total/2
  129. */
  130. struct motor_angle_f32_s
  131. {
  132. phase_angle_f32_t angle_el; /* Electrical angle */
  133. float anglem; /* Mechanical angle in radians <0, 2PI> */
  134. float one_by_p; /* Aux variable */
  135. uint8_t p; /* Number of the motor pole pairs */
  136. int8_t i; /* Pole counter */
  137. };
  138. /* Float number saturaton */
  139. struct float_sat_f32_s
  140. {
  141. float min; /* Lower limit */
  142. float max; /* Upper limit */
  143. };
  144. typedef struct float_sat_f32_s float_sat_f32_t;
  145. /* PI/PID controller state structure */
  146. struct pid_controller_f32_s
  147. {
  148. bool aw_en; /* Integral part decay if saturated */
  149. bool ireset_en; /* Intergral part reset if saturated */
  150. bool pisat_en; /* PI saturation enabled */
  151. bool pidsat_en; /* PID saturation enabled */
  152. bool _res; /* Reserved */
  153. float out; /* Controller output */
  154. float_sat_f32_t sat; /* Output saturation */
  155. float err; /* Current error value */
  156. float err_prev; /* Previous error value */
  157. float KP; /* Proportional coefficient */
  158. float KI; /* Integral coefficient */
  159. float KD; /* Derivative coefficient */
  160. float part[3]; /* 0 - proporitonal part
  161. * 1 - integral part
  162. * 2 - derivative part
  163. */
  164. float KC; /* Integral anti-windup decay coefficient */
  165. float aw; /* Integral anti-windup decay part */
  166. };
  167. typedef struct pid_controller_f32_s pid_controller_f32_t;
  168. /* This structure represents the ABC frame (3 phase vector) */
  169. struct abc_frame_f32_s
  170. {
  171. float a; /* A component */
  172. float b; /* B component */
  173. float c; /* C component */
  174. };
  175. typedef struct abc_frame_f32_s abc_frame_f32_t;
  176. /* This structure represents the alpha-beta frame (2 phase vector) */
  177. struct ab_frame_f32_s
  178. {
  179. float a; /* Alpha component */
  180. float b; /* Beta component */
  181. };
  182. typedef struct ab_frame_f32_s ab_frame_f32_t;
  183. /* This structure represent the direct-quadrature frame */
  184. struct dq_frame_f32_s
  185. {
  186. float d; /* Driect component */
  187. float q; /* Quadrature component */
  188. };
  189. typedef struct dq_frame_f32_s dq_frame_f32_t;
  190. /* Space Vector Modulation data for 3-phase system */
  191. struct svm3_state_f32_s
  192. {
  193. uint8_t sector; /* Current space vector sector */
  194. float d_u; /* Duty cycle for phase U */
  195. float d_v; /* Duty cycle for phase V */
  196. float d_w; /* Duty cycle for phase W */
  197. };
  198. /* Motor open-loop control data */
  199. struct openloop_data_f32_s
  200. {
  201. float angle; /* Open-loop current angle normalized to <0.0, 2PI> */
  202. float per; /* Open-loop control execution period */
  203. };
  204. /* Common motor observer structure */
  205. struct motor_observer_f32_s
  206. {
  207. float angle; /* Estimated observer angle */
  208. float speed; /* Estimated observer speed */
  209. float per; /* Observer execution period */
  210. float angle_err; /* Observer angle error.
  211. * This can be used to gradually eliminate
  212. * error between openloop angle and observer
  213. * angle
  214. */
  215. /* There are different types of motor observers which different
  216. * sets of private data.
  217. */
  218. void *so; /* Speed estimation observer data */
  219. void *ao; /* Angle estimation observer data */
  220. };
  221. /* Speed observer division method data */
  222. struct motor_sobserver_div_f32_s
  223. {
  224. float angle_diff; /* Mechanical angle difference */
  225. float angle_acc; /* Accumulated mechanical angle */
  226. float angle_prev; /* Previous mechanical angle */
  227. float one_by_dt; /* Frequency of observer execution */
  228. float cntr; /* Sample counter */
  229. float samples; /* Number of samples for observer */
  230. float filter; /* Low-pass filter for final omega */
  231. };
  232. /* Speed observer PLL method data */
  233. #if 0
  234. struct motor_sobserver_pll_f32_s
  235. {
  236. /* TODO */
  237. };
  238. #endif
  239. /* Motor Sliding Mode Observer private data */
  240. struct motor_observer_smo_f32_s
  241. {
  242. float k_slide; /* Bang-bang controller gain */
  243. float err_max; /* Linear mode threshold */
  244. float one_by_err_max; /* One by err_max */
  245. float F; /* Current observer F gain (1-Ts*R/L) */
  246. float G; /* Current observer G gain (Ts/L) */
  247. float emf_lp_filter1; /* Adaptive first low pass EMF filter */
  248. float emf_lp_filter2; /* Adaptive second low pass EMF filter */
  249. ab_frame_f32_t emf; /* Estimated back-EMF */
  250. ab_frame_f32_t emf_f; /* Fitlered estimated back-EMF */
  251. ab_frame_f32_t z; /* Correction factor */
  252. ab_frame_f32_t i_est; /* Estimated idq current */
  253. ab_frame_f32_t v_err; /* v_err = v_ab - emf */
  254. ab_frame_f32_t i_err; /* i_err = i_est - i_dq */
  255. ab_frame_f32_t sign; /* Bang-bang controller sign */
  256. };
  257. /* FOC initialize data */
  258. struct foc_initdata_f32_s
  259. {
  260. float id_kp; /* KP for d current */
  261. float id_ki; /* KI for d current */
  262. float iq_kp; /* KP for q current */
  263. float iq_ki; /* KI for q current */
  264. };
  265. /* Field Oriented Control (FOC) data */
  266. struct foc_data_f32_s
  267. {
  268. abc_frame_f32_t v_abc; /* Voltage in ABC frame */
  269. ab_frame_f32_t v_ab; /* Voltage in alpha-beta frame */
  270. dq_frame_f32_t v_dq; /* Requested voltage in dq frame */
  271. ab_frame_f32_t v_ab_mod; /* Modulation voltage normalized to
  272. * magnitude (0.0, 1.0)
  273. */
  274. abc_frame_f32_t i_abc; /* Current in ABC frame */
  275. ab_frame_f32_t i_ab; /* Current in alpha-beta frame */
  276. dq_frame_f32_t i_dq; /* Current in dq frame */
  277. dq_frame_f32_t i_dq_err; /* DQ current error */
  278. dq_frame_f32_t i_dq_ref; /* Requested current for the FOC
  279. * current controller
  280. */
  281. pid_controller_f32_t id_pid; /* Current d-axis component PI controller */
  282. pid_controller_f32_t iq_pid; /* Current q-axis component PI controller */
  283. float vdq_mag_max; /* Maximum dq voltage magnitude */
  284. float vab_mod_scale; /* Voltage alpha-beta modulation scale */
  285. phase_angle_f32_t angle; /* Phase angle */
  286. };
  287. /* Motor physical parameters.
  288. * This data structure was designed to work with BLDC/PMSM motors,
  289. * but probably can be used to describe different types of motors.
  290. */
  291. struct motor_phy_params_f32_s
  292. {
  293. uint8_t p; /* Number of the motor pole pairs */
  294. float res; /* Phase-to-neutral resistance */
  295. float ind; /* Average phase-to-neutral inductance */
  296. float one_by_ind; /* Inverse phase-to-neutral inductance */
  297. };
  298. /* PMSM motor physcial parameters */
  299. struct pmsm_phy_params_f32_s
  300. {
  301. struct motor_phy_params_f32_s motor; /* Motor common PHY */
  302. float iner; /* Rotor inertia */
  303. float flux_link; /* Flux linkage */
  304. float ind_d; /* d-inductance */
  305. float ind_q; /* q-inductance */
  306. float one_by_iner; /* One by intertia */
  307. float one_by_indd; /* One by Ld */
  308. float one_by_indq; /* One by Lq */
  309. };
  310. /* PMSM motor model state */
  311. struct pmsm_model_state_f32_s
  312. {
  313. /* Motor model phase current */
  314. abc_frame_f32_t i_abc;
  315. ab_frame_f32_t i_ab;
  316. dq_frame_f32_t i_dq;
  317. /* Motor model phase voltage */
  318. abc_frame_f32_t v_abc;
  319. ab_frame_f32_t v_ab;
  320. dq_frame_f32_t v_dq;
  321. /* Motor model angle */
  322. struct motor_angle_f32_s angle;
  323. /* Angular speed */
  324. float omega_e;
  325. float omega_m;
  326. };
  327. /* PMSM motor model external conditions */
  328. struct pmsm_model_ext_f32_s
  329. {
  330. float load; /* Motor model load torque */
  331. };
  332. /* PMSM motor model */
  333. struct pmsm_model_f32_s
  334. {
  335. struct pmsm_phy_params_f32_s phy; /* Motor model physical parameters */
  336. struct pmsm_model_state_f32_s state; /* Motor model state */
  337. struct pmsm_model_ext_f32_s ext; /* Motor model external conditions */
  338. float per; /* Control period */
  339. float id_int; /* Id integral part */
  340. float iq_int; /* Iq integral part */
  341. };
  342. /****************************************************************************
  343. * Public Functions Prototypes
  344. ****************************************************************************/
  345. #undef EXTERN
  346. #if defined(__cplusplus)
  347. #define EXTERN extern "C"
  348. extern "C"
  349. {
  350. #else
  351. #define EXTERN extern
  352. #endif
  353. /* Math functions */
  354. float fast_sin(float angle);
  355. float fast_sin2(float angle);
  356. float fast_cos(float angle);
  357. float fast_cos2(float angle);
  358. float fast_atan2(float y, float x);
  359. void f_saturate(FAR float *val, float min, float max);
  360. float vector2d_mag(float x, float y);
  361. void vector2d_saturate(FAR float *x, FAR float *y, float max);
  362. void dq_saturate(FAR dq_frame_f32_t *dq, float max);
  363. float dq_mag(FAR dq_frame_f32_t *dq);
  364. /* PID controller functions */
  365. void pid_controller_init(FAR pid_controller_f32_t *pid,
  366. float KP, float KI, float KD);
  367. void pi_controller_init(FAR pid_controller_f32_t *pid,
  368. float KP, float KI);
  369. void pid_saturation_set(FAR pid_controller_f32_t *pid, float min, float max);
  370. void pi_saturation_set(FAR pid_controller_f32_t *pid, float min, float max);
  371. void pid_integral_reset(FAR pid_controller_f32_t *pid);
  372. void pi_integral_reset(FAR pid_controller_f32_t *pid);
  373. float pi_controller(FAR pid_controller_f32_t *pid, float err);
  374. float pid_controller(FAR pid_controller_f32_t *pid, float err);
  375. void pi_antiwindup_enable(FAR pid_controller_f32_t *pid, float KC,
  376. bool enable);
  377. void pi_ireset_enable(FAR pid_controller_f32_t *pid, bool enable);
  378. /* Transformation functions */
  379. void clarke_transform(FAR abc_frame_f32_t *abc, FAR ab_frame_f32_t *ab);
  380. void inv_clarke_transform(FAR ab_frame_f32_t *ab, FAR abc_frame_f32_t *abc);
  381. void park_transform(FAR phase_angle_f32_t *angle, FAR ab_frame_f32_t *ab,
  382. FAR dq_frame_f32_t *dq);
  383. void inv_park_transform(FAR phase_angle_f32_t *angle, FAR dq_frame_f32_t *dq,
  384. FAR ab_frame_f32_t *ab);
  385. /* Phase angle related functions */
  386. void angle_norm(FAR float *angle, float per, float bottom, float top);
  387. void angle_norm_2pi(FAR float *angle, float bottom, float top);
  388. void phase_angle_update(FAR struct phase_angle_f32_s *angle, float val);
  389. /* 3-phase system space vector modulation */
  390. void svm3_init(FAR struct svm3_state_f32_s *s);
  391. void svm3(FAR struct svm3_state_f32_s *s, FAR ab_frame_f32_t *ab);
  392. void svm3_current_correct(FAR struct svm3_state_f32_s *s,
  393. float *c0, float *c1, float *c2);
  394. /* Field Oriented Control */
  395. void foc_init(FAR struct foc_data_f32_s *foc,
  396. FAR struct foc_initdata_f32_s *init);
  397. void foc_vbase_update(FAR struct foc_data_f32_s *foc, float vbase);
  398. void foc_angle_update(FAR struct foc_data_f32_s *foc,
  399. FAR phase_angle_f32_t *angle);
  400. void foc_iabc_update(FAR struct foc_data_f32_s *foc,
  401. FAR abc_frame_f32_t *i_abc);
  402. void foc_voltage_control(FAR struct foc_data_f32_s *foc,
  403. FAR dq_frame_f32_t *vdq_ref);
  404. void foc_current_control(FAR struct foc_data_f32_s *foc,
  405. FAR dq_frame_f32_t *idq_ref,
  406. FAR dq_frame_f32_t *vdq_comp,
  407. FAR dq_frame_f32_t *v_dq_ref);
  408. void foc_vabmod_get(FAR struct foc_data_f32_s *foc,
  409. FAR ab_frame_f32_t *v_ab_mod);
  410. void foc_vdq_mag_max_get(FAR struct foc_data_f32_s *foc, FAR float *max);
  411. /* BLDC/PMSM motor observers */
  412. void motor_observer_init(FAR struct motor_observer_f32_s *observer,
  413. FAR void *ao, FAR void *so, float per);
  414. float motor_observer_speed_get(FAR struct motor_observer_f32_s *o);
  415. float motor_observer_angle_get(FAR struct motor_observer_f32_s *o);
  416. void motor_observer_smo_init(FAR struct motor_observer_smo_f32_s *smo,
  417. float kslide, float err_max);
  418. void motor_observer_smo(FAR struct motor_observer_f32_s *o,
  419. FAR ab_frame_f32_t *i_ab, FAR ab_frame_f32_t *v_ab,
  420. FAR struct motor_phy_params_f32_s *phy, float dir);
  421. void motor_sobserver_div_init(FAR struct motor_sobserver_div_f32_s *so,
  422. uint8_t samples, float filer, float per);
  423. void motor_sobserver_div(FAR struct motor_observer_f32_s *o,
  424. float angle, float dir);
  425. /* Motor openloop control */
  426. void motor_openloop_init(FAR struct openloop_data_f32_s *op, float per);
  427. void motor_openloop(FAR struct openloop_data_f32_s *op, float speed,
  428. float dir);
  429. float motor_openloop_angle_get(FAR struct openloop_data_f32_s *op);
  430. /* Motor angle */
  431. void motor_angle_init(FAR struct motor_angle_f32_s *angle, uint8_t p);
  432. void motor_angle_e_update(FAR struct motor_angle_f32_s *angle,
  433. float angle_new, float dir);
  434. void motor_angle_m_update(FAR struct motor_angle_f32_s *angle,
  435. float angle_new, float dir);
  436. float motor_angle_m_get(FAR struct motor_angle_f32_s *angle);
  437. float motor_angle_e_get(FAR struct motor_angle_f32_s *angle);
  438. /* Motor physical parameters */
  439. void motor_phy_params_init(FAR struct motor_phy_params_f32_s *phy,
  440. uint8_t poles, float res, float ind);
  441. /* PMSM physical parameters functions */
  442. void pmsm_phy_params_init(FAR struct pmsm_phy_params_f32_s *phy,
  443. uint8_t poles, float res, float ind,
  444. float iner, float flux,
  445. float ind_d, float ind_q);
  446. /* PMSM motor model */
  447. int pmsm_model_initialize(FAR struct pmsm_model_f32_s *model,
  448. FAR struct pmsm_phy_params_f32_s *phy,
  449. float per);
  450. int pmsm_model_elec(FAR struct pmsm_model_f32_s *model,
  451. FAR ab_frame_f32_t *vab);
  452. int pmsm_model_mech(FAR struct pmsm_model_f32_s *model, float load);
  453. #undef EXTERN
  454. #if defined(__cplusplus)
  455. }
  456. #endif
  457. #endif /* __INCLUDE_DSP_H */