0%

odriver之svm

源码

SVM函数的alpha和beta的值是经过了标幺化,基准值为 (最大相电压),也就是说alpha和beta的范围是[-1,1]。约束:alpha-beta 向量的大小不得大于 $ $。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// Compute rising edge timings (0.0 - 1.0) as a function of alpha-beta
// as per the magnitude invariant clarke transform
// The magnitude of the alpha-beta vector may not be larger than sqrt(3)/2
// Returns true on success, and false if the input was out of range
std::tuple<float, float, float, bool> SVM(float alpha, float beta) {
float tA, tB, tC;
int Sextant;

if (beta >= 0.0f) {
if (alpha >= 0.0f) {
//quadrant I
if (one_by_sqrt3 * beta > alpha)
Sextant = 2; //sextant v2-v3
else
Sextant = 1; //sextant v1-v2
} else {
//quadrant II
if (-one_by_sqrt3 * beta > alpha)
Sextant = 3; //sextant v3-v4
else
Sextant = 2; //sextant v2-v3
}
} else {
if (alpha >= 0.0f) {
//quadrant IV
if (-one_by_sqrt3 * beta > alpha)
Sextant = 5; //sextant v5-v6
else
Sextant = 6; //sextant v6-v1
} else {
//quadrant III
if (one_by_sqrt3 * beta > alpha)
Sextant = 4; //sextant v4-v5
else
Sextant = 5; //sextant v5-v6
}
}

switch (Sextant) {
// sextant v1-v2
case 1: {
// Vector on-times
float t1 = alpha - one_by_sqrt3 * beta;
float t2 = two_by_sqrt3 * beta;

// PWM timings
tA = (1.0f - t1 - t2) * 0.5f;
tB = tA + t1;
tC = tB + t2;
} break;

// sextant v2-v3
case 2: {
// Vector on-times
float t2 = alpha + one_by_sqrt3 * beta;
float t3 = -alpha + one_by_sqrt3 * beta;

// PWM timings
tB = (1.0f - t2 - t3) * 0.5f;
tA = tB + t3;
tC = tA + t2;
} break;

// sextant v3-v4
case 3: {
// Vector on-times
float t3 = two_by_sqrt3 * beta;
float t4 = -alpha - one_by_sqrt3 * beta;

// PWM timings
tB = (1.0f - t3 - t4) * 0.5f;
tC = tB + t3;
tA = tC + t4;
} break;

// sextant v4-v5
case 4: {
// Vector on-times
float t4 = -alpha + one_by_sqrt3 * beta;
float t5 = -two_by_sqrt3 * beta;

// PWM timings
tC = (1.0f - t4 - t5) * 0.5f;
tB = tC + t5;
tA = tB + t4;
} break;

// sextant v5-v6
case 5: {
// Vector on-times
float t5 = -alpha - one_by_sqrt3 * beta;
float t6 = alpha - one_by_sqrt3 * beta;

// PWM timings
tC = (1.0f - t5 - t6) * 0.5f;
tA = tC + t5;
tB = tA + t6;
} break;

// sextant v6-v1
case 6: {
// Vector on-times
float t6 = -two_by_sqrt3 * beta;
float t1 = alpha + one_by_sqrt3 * beta;

// PWM timings
tA = (1.0f - t6 - t1) * 0.5f;
tC = tA + t1;
tB = tC + t6;
} break;
}

bool result_valid =
tA >= 0.0f && tA <= 1.0f
&& tB >= 0.0f && tB <= 1.0f
&& tC >= 0.0f && tC <= 1.0f;
return {tA, tB, tC, result_valid};
}

函数主体上可以分为2大块,第一大块是个复合的 if 语句,用于判断扇区,第二个则是个 switch 语句,用于计算定时器的比较值,用于产生不同占空比的PWM。

扇区判断

对于第一部分扇区判断,以第1扇区为例说明。

如图1所示,给定的$ \(值使得其合向量蓝色的\)vref\(位于第1扇区。分析一下位于第1扇区的\) \(有什么特点,最明显的就是 ,但这应该是位于第一象限的特点,还有30°的范围不属于第1扇区,继续分析。每个扇区都是60°,因此可以通过三角函数来确定\) \(和\) \(的关系。过110轴上任意点P做100轴的垂线PA,则ΔOPA显然为直角三角形,且∠PAO=90°,∠POA=60°,∠OPA=30°,此时,正好是\) \(的合向量恰好位于110轴的情形,当\)\(的值略小或\)$的值略大时,∠POA都将小于60°,合向量落入第1扇区。从数学上说

\[ \angle POA = arctan \frac{PA}{ OA} = arctan \frac{\beta}{ \alpha} < 60° \]

即可作为1扇区判断条件,坏消息是 arctan 在MCU上计算得慢,所以得换换思路。

\[ tan \angle POA = \frac{\beta}{ \alpha} \] 这是一个显而易见的结论,当合向量恰好位于110轴时$ tan60° = $ ,也就是$ = $ ,如果和程序中的表述一致的话,就是\(\alpha = \frac{1}{ \sqrt{3}} \beta\) 。当\(\beta\)减小\(\alpha\)不变或\(\alpha\)增大\(\beta\)不变时,合向量都将从110轴转向1扇区,反之则转入2扇区。

综上所述得到结论,当$> 0, > 0 $ 且 \(\beta > \sqrt{3} \alpha\) 合向量落在第1扇区; 当$> 0, > 0 $ 且 \(\beta < \sqrt{3} \alpha\),合向量落在第2扇区。

PWM值计算

接下来聊一聊PWM比较值是如何计算的,这次以第2扇区为例,如图2所示。

在第2扇区的合向量是需要借助010和110这两个基本向量合成得到,传入SVM函数的参数alpha和beta的合向量是\(Vref\)。然后考虑将 \(\alpha\)\(\beta\)的值都分解到010和110这两个基本向量上。将\(\alpha\) 在100轴的端点称为A点,\(\beta\)端点称为B点。

先试着分解\(\alpha\)向量,过A点作110(001)轴的平行线交101轴于C点。过A点作010(101)轴平行线交110轴于D点。分析易得$ OAC OAD$ 都是等边三角形。因此,\(\alpha\)向量分解到110轴的长度也是\(\alpha\),分解到010轴的长度是\(- \alpha\)

然后分解\(\beta\)向量,过B点作110轴平行线交010轴于E点,过B点作010轴平行线交110轴于F点。易分析得 \(\bigtriangleup OBE 、 \bigtriangleup OBF\) 为底角为30°的等腰三角形,需求OE和OF长度,且OE=OF=BF=BE。过E点作OB垂线交于G,则 \(\bigtriangleup EGB\)为直角三角形,且\(\angle EBG = 30°\)\(BE = \frac{2}{\sqrt{3}} BG\)\(BG = \frac{1}{2} \beta\)\(BE = \frac{1}{\sqrt{3}} \beta\) 为所求。 可以给结论了,110轴上产生作用力的时间定义为t2,010轴上产生作用力的时间定义为t3。则有:

\[ t3 = - \alpha + \frac{1}{\sqrt{3}} \beta \]

\[ t2 = \alpha + \frac{1}{\sqrt{3}} \beta \]

参考文献

https://zhuanlan.zhihu.com/p/506240030