File tree 8 files changed +1022
-0
lines changed
8 files changed +1022
-0
lines changed Original file line number Diff line number Diff line change
1
+
2
+ .vscode
3
+ .pyenv
4
+
5
+ target
6
+ build
7
+ target
8
+ Core
9
+ Drivers
10
+ FATFS
11
+ Middlewares
12
+ USB_Device
13
+ HTML
14
+
15
+ ! * .c
16
+ ! * .h
17
+ ! * .cpp
18
+ ! * .hpp
19
+
20
+ ! Makefile
21
+
22
+ ! * .a
23
+
24
+ ! * .s
25
+ ! * .ld
26
+
27
+ ! Doxyfile
Load Diff Large diffs are not rendered by default.
Original file line number Diff line number Diff line change
1
+ SOGI-PLL
2
+ ========
3
+
4
+ Phase-Locked Loop Based Second Order Generalized Integrator for power electric application.
5
+
6
+
Original file line number Diff line number Diff line change
1
+ // SPDX-License-Identifier: LGPL-2.1
2
+
3
+ /* *
4
+ * @file mc_config.h
5
+ * @brief 控制系统配置
6
+
7
+ * @date 2022-07-27
8
+ *
9
+ * @copyright Copyright (C) 向阳 2022
10
+ */
11
+ #if !defined(__INCLUDE_CONTROL_MC_CONFIG_H__)
12
+ #define __INCLUDE_CONTROL_MC_CONFIG_H__
13
+ #include < float.h>
14
+ namespace control
15
+ {
16
+ // ! 运算的值类型
17
+ using value_t = float ;
18
+
19
+ // ! 控制周期
20
+ constexpr value_t T = 1 / 12800 .0f ;
21
+
22
+ // ! 常量值表
23
+ template <typename T>
24
+ struct constant_value ;
25
+
26
+
27
+ template <>
28
+ struct constant_value <value_t >
29
+ {
30
+ // ! 零
31
+ static constexpr value_t ZERO = 0 ;
32
+
33
+ // ! 圆周率
34
+ static constexpr value_t PI = 3 .14159265358979323f ;
35
+
36
+ // ! 1/2 * 圆周率
37
+ static constexpr value_t HALF_PI = PI / 2 ;
38
+
39
+ // ! 2 * 圆周率
40
+ static constexpr value_t TAU = PI * 2 ;
41
+
42
+ // ! 最大值
43
+ static constexpr value_t MAX = FLT_MAX;
44
+
45
+ // ! 最小
46
+ static constexpr value_t MIN = FLT_MIN;
47
+ };
48
+
49
+ }
50
+ #endif // __INCLUDE_CONTROL_MC_SPLL_H__
Original file line number Diff line number Diff line change
1
+ // SPDX-License-Identifier: LGPL-2.1
2
+
3
+ /* *
4
+ * @file ma_pid.h
5
+ * @brief 数字PID控制器
6
+
7
+ * @date 2022-07-16
8
+ *
9
+ * @copyright Copyright (C) 向阳 2022
10
+ */
11
+ #if !defined(__INCLUDE_CONTROL_MC_PID_H__)
12
+ #define __INCLUDE_CONTROL_MC_PID_H__
13
+ #include " mc_config.h"
14
+ namespace control
15
+ {
16
+ /* *
17
+ * @brief 带退饱和反馈和积分限幅的PID控制器(float32)
18
+ *
19
+ */
20
+ class PID final
21
+ {
22
+ public:
23
+ /* *
24
+ * @brief 控制器参数
25
+ *
26
+ */
27
+ struct Factors
28
+ {
29
+ // ! 比例系数
30
+ value_t kp;
31
+
32
+ // ! 积分系数
33
+ value_t ki;
34
+
35
+ // ! 微分系数
36
+ value_t kd;
37
+
38
+ // ! 微分增益
39
+ value_t kg;
40
+
41
+ // ! 饱和系数
42
+ value_t kc;
43
+
44
+ // ! 积分器限幅(min)
45
+ value_t i_min;
46
+
47
+ // ! 积分器限幅(max)
48
+ value_t i_max;
49
+ };
50
+
51
+ PID () = default ;
52
+ ~PID () = default ;
53
+
54
+ PID (const PID &) = delete ;
55
+ PID &operator =(const PID &) = delete ;
56
+
57
+ PID (PID &&) = delete ;
58
+ PID &operator =(PID &&) = delete ;
59
+
60
+ // ! @get
61
+ // ! @set
62
+ // ! 控制器参数
63
+ Factors param = {0 };
64
+
65
+ /* *
66
+ * @brief 重置调节器状态
67
+ *
68
+ */
69
+ void reset () noexcept ;
70
+
71
+ /* *
72
+ * @brief 数字P
73
+ *
74
+ * @param [in] e: 输入, error
75
+ *
76
+ * @return value_t: 输出
77
+ *
78
+ */
79
+ value_t p_transfer (value_t e) noexcept ;
80
+
81
+ /* *
82
+ * @brief 数字PI
83
+ *
84
+ * @param [in] e: 输入, error
85
+ *
86
+ * @return value_t: 输出
87
+ *
88
+ */
89
+ value_t pi_transfer (value_t e) noexcept ;
90
+
91
+ /* *
92
+ * @brief 数字PD
93
+ *
94
+ * @param [in] e: 输入, error
95
+ *
96
+ * @return value_t: 输出
97
+ *
98
+ */
99
+ value_t pd_transfer (value_t e) noexcept ;
100
+
101
+ /* *
102
+ * @brief 数字PID
103
+ *
104
+ * @param [in] e: 输入, error
105
+ *
106
+ * @return value_t: 输出
107
+ *
108
+ */
109
+ value_t pid_transfer (value_t e) noexcept ;
110
+
111
+ private:
112
+ // ! 饱和误差
113
+ value_t sat_err = 0 ;
114
+
115
+ // ! 积分值
116
+ value_t i_sum = 0 ;
117
+ };
118
+ }
119
+ #endif // __INCLUDE_CONTROL_MC_PID_H__
Original file line number Diff line number Diff line change
1
+ // SPDX-License-Identifier: LGPL-2.1
2
+
3
+ /* *
4
+ * @file mc_spll.h
5
+ * @brief 数字锁相环
6
+
7
+ * @date 2022-07-27
8
+ *
9
+ * @copyright Copyright (C) 向阳 2022
10
+ */
11
+ #if !defined(__INCLUDE_CONTROL_MC_SPLL_H__)
12
+ #define __INCLUDE_CONTROL_MC_SPLL_H__
13
+ #include < tuple>
14
+ #include " mc_pid.h"
15
+ #include < stddef.h>
16
+ #include < stdint.h>
17
+ #include " mc_config.h"
18
+ namespace control
19
+ {
20
+ class SPLL final
21
+ {
22
+ public:
23
+ // ! SPLL工作周期
24
+ static constexpr value_t Ti = T;
25
+
26
+ // ! SPLL期望频率(Hz)
27
+ static constexpr value_t TARGET_FREQ = 50 ;
28
+
29
+ // ! 计算1个周期有多少个点
30
+ static constexpr size_t N_SAMPLE = static_cast <size_t >((1 / Ti) / TARGET_FREQ);
31
+
32
+ SPLL ();
33
+ ~SPLL () = default ;
34
+
35
+ SPLL (SPLL&&) = delete ;
36
+ SPLL& operator =(SPLL&&) = delete ;
37
+
38
+ SPLL (const SPLL &) = delete ;
39
+ SPLL& operator =(const SPLL &) = delete ;
40
+
41
+ /* *
42
+ * @brief 复位
43
+ *
44
+ */
45
+ void reset ();
46
+
47
+ /* *
48
+ * @brief 进行一次计算
49
+ *
50
+ * @note 按照Ti等间隔调用本方法, 实现PLL
51
+ *
52
+ */
53
+ void transfer_1phase (value_t val);
54
+
55
+ /* *
56
+ * @brief 判断PLL是否已经锁定
57
+ *
58
+ * @param [in] th: 比较阈值
59
+ *
60
+ */
61
+ bool is_lock (value_t th = 1e-2f ) const ;
62
+
63
+ /* *
64
+ * @brief 取得当前信号的频率
65
+ *
66
+ * @return value_t: 频率
67
+ *
68
+ */
69
+ inline value_t freq () const noexcept
70
+ {
71
+ return omega / constant_value<value_t >::TAU;
72
+ }
73
+
74
+ /* *
75
+ * @brief 取得当前信号的相位
76
+ *
77
+ * @return value_t: 相位
78
+ *
79
+ */
80
+ inline value_t phase () const noexcept
81
+ {
82
+ return cur_phase;
83
+ }
84
+ private:
85
+ // ! PI
86
+ PID pid;
87
+
88
+ // ! 是否启动环路
89
+ bool launch_loop;
90
+
91
+ // ! 采样点索引, 最大到N_SAMPLE / 4
92
+ uint16_t sample_index;
93
+
94
+ // ! 角速度
95
+ value_t omega;
96
+
97
+ // ! 角度积分值, 作为相位wt
98
+ value_t cur_phase;
99
+
100
+ // ! 自动归零: 最大值和最小值
101
+ value_t auto_offset_min;
102
+ value_t auto_offset_max;
103
+
104
+ // ! SOGI的积分值
105
+ value_t sogi_s1;
106
+ value_t sogi_s2;
107
+
108
+
109
+ // ! 上次的环路error
110
+ value_t last_error;
111
+
112
+ /* *
113
+ * @brief 按照历史最大值和最小值进行归中
114
+ * @param [in] inp: 输入
115
+ *
116
+ * @return value_t: 归中后的值
117
+ *
118
+ */
119
+ value_t auto_offset (value_t inp);
120
+ };
121
+ }
122
+ #endif // __INCLUDE_CONTROL_MC_SPLL_H__
Original file line number Diff line number Diff line change
1
+ // SPDX-License-Identifier: LGPL-2.1
2
+
3
+ /* *
4
+ * @file mc_pid.cpp
5
+ * @brief 数字PID控制器
6
+
7
+ * @date 2022-07-16
8
+ *
9
+ * @copyright Copyright (C) 向阳 2022
10
+ */
11
+ #include " mc_pid.h"
12
+
13
+ using namespace control ;
14
+
15
+ void PID::reset () noexcept
16
+ {
17
+ i_sum = 0 ;
18
+ sat_err = 0 ;
19
+ }
20
+
21
+ value_t PID::p_transfer (value_t e) noexcept
22
+ {
23
+ value_t m = param.kp * e;
24
+ value_t out
25
+ = m > param.i_max ? param.i_max
26
+ : m < param.i_min ? param.i_min
27
+ : m;
28
+ return out;
29
+ }
30
+
31
+ value_t PID::pi_transfer (value_t e) noexcept
32
+ {
33
+ value_t sat = param.kp * e + i_sum;
34
+ // PI输出
35
+ // U(s) = kp * E(s) + ki * E(s) / s
36
+ value_t out
37
+ = sat > param.i_max ? param.i_max
38
+ : sat < param.i_min ? param.i_min
39
+ : sat;
40
+ // 饱和误差
41
+ value_t sat_err = out - sat;
42
+ // 累积积分, 加上饱和误差
43
+ i_sum += param.ki * e + param.kc * sat_err;
44
+ // 积分限幅, clamp
45
+ if (i_sum > param.i_max )
46
+ {
47
+ i_sum = param.i_max ;
48
+ }
49
+ else if (i_sum < param.i_min )
50
+ {
51
+ i_sum = param.i_min ;
52
+ }
53
+ //
54
+ return out;
55
+ }
56
+
57
+ value_t PID::pd_transfer (value_t e) noexcept
58
+ {
59
+ return 0 ;
60
+ }
61
+
62
+ value_t PID::pid_transfer (value_t e) noexcept
63
+ {
64
+ return 0 ;
65
+ }
You can’t perform that action at this time.
0 commit comments