搜索
bottom↓
回复: 5

请教,v0.5.3版本的odrive的foc.cpp里,这个乘数0.8是什么原理?

[复制链接]

出20入62汤圆

发表于 2022-6-1 23:50:22 | 显示全部楼层 |阅读模式
float mod_scalefactor = 0.80f * sqrt3_by_2 * 1.0f / std::sqrt(mod_d * mod_d + mod_q * mod_q);
这一行代码。实在不懂这个0.8是啥意思,有大牛指点下我不。。。糊涂了
整个函数如下:
  1. ODriveIntf::MotorIntf::Error FieldOrientedController::get_alpha_beta_output(
  2.         uint32_t output_timestamp, std::optional<float2D>* mod_alpha_beta,
  3.         std::optional<float>* ibus) {

  4.     if (!vbus_voltage_measured_.has_value() || !Ialpha_beta_measured_.has_value()) {
  5.         // FOC didn't receive a current measurement yet.
  6.         return Motor::ERROR_CONTROLLER_INITIALIZING;
  7.     } else if (abs((int32_t)(i_timestamp_ - ctrl_timestamp_)) > MAX_CONTROL_LOOP_UPDATE_TO_CURRENT_UPDATE_DELTA) {
  8.         // Data from control loop and current measurement are too far apart.
  9.         return Motor::ERROR_BAD_TIMING;
  10.     }

  11.     // TODO: improve efficiency in case PWM updates are requested at a higher
  12.     // rate than current sensor updates. In this case we can reuse mod_d and
  13.     // mod_q from a previous iteration.

  14.     if (!Vdq_setpoint_.has_value()) {
  15.         return Motor::ERROR_UNKNOWN_VOLTAGE_COMMAND;
  16.     } else if (!phase_.has_value() || !phase_vel_.has_value()) {
  17.         return Motor::ERROR_UNKNOWN_PHASE_ESTIMATE;
  18.     } else if (!vbus_voltage_measured_.has_value()) {
  19.         return Motor::ERROR_UNKNOWN_VBUS_VOLTAGE;
  20.     }

  21.     auto [Vd, Vq] = *Vdq_setpoint_;
  22.     float phase = *phase_;
  23.     float phase_vel = *phase_vel_;
  24.     float vbus_voltage = *vbus_voltage_measured_;

  25.     std::optional<float2D> Idq;

  26.     // Park transform
  27.     if (Ialpha_beta_measured_.has_value()) {
  28.         auto [Ialpha, Ibeta] = *Ialpha_beta_measured_;
  29.         float I_phase = phase + phase_vel * ((float)(int32_t)(i_timestamp_ - ctrl_timestamp_) / (float)TIM_1_8_CLOCK_HZ);
  30.         float c_I = our_arm_cos_f32(I_phase);
  31.         float s_I = our_arm_sin_f32(I_phase);
  32.         Idq = {
  33.             c_I * Ialpha + s_I * Ibeta,
  34.             c_I * Ibeta - s_I * Ialpha
  35.         };
  36.         Id_measured_ += I_measured_report_filter_k_ * (Idq->first - Id_measured_);
  37.         Iq_measured_ += I_measured_report_filter_k_ * (Idq->second - Iq_measured_);
  38.     } else {
  39.         Id_measured_ = 0.0f;
  40.         Iq_measured_ = 0.0f;
  41.     }


  42.     float mod_to_V = (2.0f / 3.0f) * vbus_voltage;
  43.     float V_to_mod = 1.0f / mod_to_V;
  44.     float mod_d;
  45.     float mod_q;

  46.     if (enable_current_control_) {
  47.         // Current control mode

  48.         if (!pi_gains_.has_value()) {
  49.             return Motor::ERROR_UNKNOWN_GAINS;
  50.         } else if (!Idq.has_value()) {
  51.             return Motor::ERROR_UNKNOWN_CURRENT_MEASUREMENT;
  52.         } else if (!Idq_setpoint_.has_value()) {
  53.             return Motor::ERROR_UNKNOWN_CURRENT_COMMAND;
  54.         }

  55.         auto [p_gain, i_gain] = *pi_gains_;
  56.         auto [Id, Iq] = *Idq;
  57.         auto [Id_setpoint, Iq_setpoint] = *Idq_setpoint_;

  58.         float Ierr_d = Id_setpoint - Id;
  59.         float Ierr_q = Iq_setpoint - Iq;

  60.         // Apply PI control (V{d,q}_setpoint act as feed-forward terms in this mode)
  61.         mod_d = V_to_mod * (Vd + v_current_control_integral_d_ + Ierr_d * p_gain);
  62.         mod_q = V_to_mod * (Vq + v_current_control_integral_q_ + Ierr_q * p_gain);

  63.         // Vector modulation saturation, lock integrator if saturated
  64.         // TODO make maximum modulation configurable
  65.         float mod_scalefactor = 0.80f * sqrt3_by_2 * 1.0f / std::sqrt(mod_d * mod_d + mod_q * mod_q);
  66.         if (mod_scalefactor < 1.0f) {
  67.             mod_d *= mod_scalefactor;
  68.             mod_q *= mod_scalefactor;
  69.             // TODO make decayfactor configurable
  70.             v_current_control_integral_d_ *= 0.99f;
  71.             v_current_control_integral_q_ *= 0.99f;
  72.         } else {
  73.             v_current_control_integral_d_ += Ierr_d * (i_gain * current_meas_period);
  74.             v_current_control_integral_q_ += Ierr_q * (i_gain * current_meas_period);
  75.         }

  76.     } else {
  77.         // Voltage control mode
  78.         mod_d = V_to_mod * Vd;
  79.         mod_q = V_to_mod * Vq;
  80.     }

  81.     // Inverse park transform
  82.     float pwm_phase = phase + phase_vel * ((float)(int32_t)(output_timestamp - ctrl_timestamp_) / (float)TIM_1_8_CLOCK_HZ);
  83.     float c_p = our_arm_cos_f32(pwm_phase);
  84.     float s_p = our_arm_sin_f32(pwm_phase);
  85.     float mod_alpha = c_p * mod_d - s_p * mod_q;
  86.     float mod_beta = c_p * mod_q + s_p * mod_d;

  87.     // Report final applied voltage in stationary frame (for sensorless estimator)
  88.     final_v_alpha_ = mod_to_V * mod_alpha;
  89.     final_v_beta_ = mod_to_V * mod_beta;

  90.     *mod_alpha_beta = {mod_alpha, mod_beta};

  91.     if (Idq.has_value()) {
  92.         auto [Id, Iq] = *Idq;
  93.         *ibus = mod_d * Id + mod_q * Iq;
  94.         power_ = vbus_voltage * (*ibus).value();
  95.     }
  96.    
  97.     return Motor::ERROR_NONE;
  98. }
复制代码

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2022-6-2 08:59:59 | 显示全部楼层
只能开到80%的开度?

出20入62汤圆

 楼主| 发表于 2022-6-2 22:57:02 | 显示全部楼层
lonely9391 发表于 2022-6-2 08:59
只能开到80%的开度?
(引用自2楼)

我也觉得是这个意思。但是这个80%是怎么来的,为啥不是81%。。。为啥不是90%。。。

出20入62汤圆

 楼主| 发表于 2023-8-16 21:26:19 | 显示全部楼层
这个问题还是没有答案。
我感觉做了圆周功率限制,就没必要用这个0.8了吧

出105入79汤圆

发表于 2023-8-16 23:10:17 | 显示全部楼层
天下乌鸦一般黑 发表于 2023-8-16 21:26
这个问题还是没有答案。
我感觉做了圆周功率限制,就没必要用这个0.8了吧 ...
(引用自4楼)

看注释就能知道,是用于判断力矩输出较大,Iq较大时,关闭积分计算,是积分抗饱和策略。

出20入62汤圆

 楼主| 发表于 2023-8-16 23:20:49 | 显示全部楼层
qwe2231695 发表于 2023-8-16 23:10
看注释就能知道,是用于判断力矩输出较大,Iq较大时,关闭积分计算,是积分抗饱和策略。 ...
(引用自5楼)

大佬在啊。
抗积分饱和看懂了。
主要是这个0.8。我在学习(抄袭)它代码的时候,主要是看不懂这个0.8~很早的版本也有这个0.8
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-25 06:24

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表