|
|
@@ -7,23 +7,66 @@ static foc_observer_t foc_obser;
|
|
|
void foc_observer_init(void) {
|
|
|
foc_obser.smo_enabled = false;
|
|
|
foc_obser.smo_used = false;
|
|
|
+ foc_obser.enc_angle = INVALID_ANGLE;
|
|
|
+ foc_obser.enc_est_angle = INVALID_ANGLE;
|
|
|
+ foc_obser.enc_speed = 0;
|
|
|
+ foc_obser.smo_angle = INVALID_ANGLE;
|
|
|
+ foc_obser.smo_est_angle = INVALID_ANGLE;
|
|
|
+ foc_obser.smo_speed = 0;
|
|
|
+ foc_obser.fusion_ceof = 1.0f;
|
|
|
#ifdef CONFIG_SMO_OBSERVER
|
|
|
smo_observer_init(CONFIG_SMO_PLL_BANDWITH, CONFIG_SMO_LFP_WC, CONFIG_SMO_GAIN_K, CONFIG_SMO_SIGMOID_MAX);
|
|
|
foc_obser.smo_enabled = true;
|
|
|
#endif
|
|
|
}
|
|
|
+
|
|
|
+#define RPM_2_degree(rpm) ((rpm) * 60.0f * nv_get_motor_params()->poles * FOC_CTRL_US)
|
|
|
+
|
|
|
float foc_observer_update(float uAlp, float uBeta, float iAlp, float iBeta){
|
|
|
- if (foc_obser.smo_enabled) {
|
|
|
- foc_obser.smo_angle = smo_observer_update(uAlp, uBeta, iAlp, iBeta);
|
|
|
- foc_obser.smo_speed = smo_observer_est_rpm();
|
|
|
- }
|
|
|
+ float prev_enc_angle = foc_obser.enc_angle;
|
|
|
+ float prev_enc_speed = foc_obser.enc_speed;
|
|
|
foc_obser.enc_angle = motor_encoder_get_angle();
|
|
|
foc_obser.enc_speed = motor_encoder_get_speed();
|
|
|
-
|
|
|
+
|
|
|
+ if (!foc_obser.smo_enabled) {
|
|
|
+ return foc_obser.enc_angle;
|
|
|
+ }
|
|
|
+ float est_enc_delta = RPM_2_degree(prev_enc_speed);
|
|
|
+ float real_enc_delta = foc_obser.enc_angle - prev_enc_angle;
|
|
|
+ if (real_enc_delta < 0) {
|
|
|
+ real_enc_delta += 360.0f;
|
|
|
+ }
|
|
|
+ float est_ration = real_enc_delta/est_enc_delta;
|
|
|
+ if (est_ration >= 1.5f || est_ration <= 0.5f) {
|
|
|
+ foc_obser.fusion_ceof -= 0.1f;
|
|
|
+ if (foc_obser.fusion_ceof < 0.0f) {
|
|
|
+ foc_obser.fusion_ceof = 0.0f;
|
|
|
+ }
|
|
|
+ if (foc_obser.enc_est_angle == INVALID_ANGLE) {
|
|
|
+ foc_obser.enc_est_angle = prev_enc_angle;
|
|
|
+ }else {
|
|
|
+ foc_obser.enc_est_angle += est_enc_delta;
|
|
|
+ rand_angle(foc_obser.enc_est_angle);
|
|
|
+ }
|
|
|
+ }else {
|
|
|
+ foc_obser.fusion_ceof += 0.1f;
|
|
|
+ if (foc_obser.fusion_ceof > 1.0f) {
|
|
|
+ foc_obser.fusion_ceof = 1.0f;
|
|
|
+ }
|
|
|
+ foc_obser.enc_est_angle = foc_obser.enc_angle;
|
|
|
+ }
|
|
|
+ foc_obser.smo_est_angle = foc_obser.smo_angle + RPM_2_degree(foc_obser.smo_speed);
|
|
|
+ foc_obser.smo_angle = smo_observer_update(uAlp, uBeta, iAlp, iBeta);
|
|
|
+ foc_obser.smo_speed = smo_observer_est_rpm();
|
|
|
+
|
|
|
if (foc_obser.smo_used) {
|
|
|
return foc_obser.smo_angle;
|
|
|
}
|
|
|
+#if 0
|
|
|
+ return (foc_obser.enc_est_angle * foc_obser.fusion_ceof + foc_obser.smo_angle * (1.0f - foc_obser.fusion_ceof));
|
|
|
+#else
|
|
|
return foc_obser.enc_angle;
|
|
|
+#endif
|
|
|
}
|
|
|
|
|
|
float foc_observer_speed(void) {
|