首页 > 其他分享 >foc

foc

时间:2024-08-20 15:04:45浏览次数:11  
标签:double foc Ts beta theta alpha PI

#include <stdio.h>
#include <math.h>

// Constants
#define PI 3.14159265358979323846

// Function prototypes
void smo(double ia, double ib, double v_alpha, double v_beta, double *theta, double *omega, double Ts, double K_slide);
void calculate_voltages(double id, double iq, double Rs, double Ld, double Lq, double lambda_m, double omega_e, double *vd, double *vq);
void inverse_park_transform(double vd, double vq, double theta, double *valpha, double *vbeta);
void svpwm(double valpha, double vbeta, double Vdc, double Ts, double *dutyA, double *dutyB, double *dutyC, int *sector);
double pid_controller(double setpoint, double measured_value, double *prev_error, double *integral, double Kp, double Ki, double Kd, double dt);

int main() {
// Example parameters
double id = 5.0; // d-axis current in amperes
double iq = 10.0; // q-axis current in amperes
double ia = 5.0, ib = 5.0; // Phase currents
double Rs = 0.5; // Stator resistance in ohms
double Ld = 0.001; // d-axis inductance in henries
double Lq = 0.001; // q-axis inductance in henries
double lambda_m = 0.01;// Permanent magnet flux linkage in Wb
double theta = PI/4; // Rotor angle in radians (initial estimate)
double Vdc = 300.0; // DC bus voltage in volts
double Ts = 0.0001; // Sampling time in seconds (100 µs, corresponding to a 10 kHz PWM frequency)

// PID controller parameters
double Kp_pid = 1.0, Ki_pid = 0.1, Kd_pid = 0.01;
double setpoint = 200.0; // Desired speed in rad/s
double prev_error = 0.0, integral_pid = 0.0;

// SMO parameters
double K_slide = 0.1;

// Variables for voltages
double vd, vq, valpha, vbeta;

// Variables for SVPWM duty cycles and sector
double dutyA, dutyB, dutyC;
int sector;

// Main control loop (simplified)
for (int i = 0; i < 1000; i++) {
// SMO to estimate theta and omega
smo(ia, ib, valpha, vbeta, &theta, &omega_e, Ts, K_slide);

// PID controller to regulate speed
double iq_ref = pid_controller(setpoint, omega_e, &prev_error, &integral_pid, Kp_pid, Ki_pid, Kd_pid, Ts);

// Update iq with iq_ref
iq = iq_ref;

// Calculate voltages in d-q frame
calculate_voltages(id, iq, Rs, Ld, Lq, lambda_m, omega_e, &vd, &vq);

// Perform inverse Park transformation to get alpha-beta voltages
inverse_park_transform(vd, vq, theta, &valpha, &vbeta);

// Calculate SVPWM duty cycles and sector
svpwm(valpha, vbeta, Vdc, Ts, &dutyA, &dutyB, &dutyC, &sector);

// Print results
printf("Duty cycles: A = %f, B = %f, C = %f, Sector = %d\n", dutyA, dutyB, dutyC, sector);
printf("Estimated theta: %f, omega: %f\n", theta, omega_e);
}

return 0;
}

void smo(double ia, double ib, double v_alpha, double v_beta, double *theta, double *omega, double Ts, double K_slide) {
static double x_alpha = 0.0, x_beta = 0.0;
static double z_alpha = 0.0, z_beta = 0.0;

// Sliding Mode Observer equations
double x_alpha_dot = v_alpha - K_slide * (x_alpha - z_alpha);
double x_beta_dot = v_beta - K_slide * (x_beta - z_beta);

// Integrate
x_alpha += x_alpha_dot * Ts;
x_beta += x_beta_dot * Ts;

// Calculate z_alpha and z_beta
z_alpha = x_alpha - K_slide * (x_alpha - z_alpha);
z_beta = x_beta - K_slide * (x_beta - z_beta);

// Calculate estimated theta and omega
*theta = atan2(z_beta, z_alpha);
*omega = (*theta - z_alpha) / Ts;

// Keep theta within 0 to 2*PI
if (*theta >= 2 * PI) {
*theta -= 2 * PI;
} else if (*theta < 0) {
*theta += 2 * PI;
}
}

void calculate_voltages(double id, double iq, double Rs, double Ld, double Lq, double lambda_m, double omega_e, double *vd, double *vq) {
*vd = Rs * id - omega_e * Lq * iq;
*vq = Rs * iq + omega_e * (Ld * id + lambda_m);
}

void inverse_park_transform(double vd, double vq, double theta, double *valpha, double *vbeta) {
*valpha = vd * cos(theta) - vq * sin(theta);
*vbeta = vd * sin(theta) + vq * cos(theta);
}

void svpwm(double valpha, double vbeta, double Vdc, double Ts, double *dutyA, double *dutyB, double *dutyC, int *sector) {
double Vref = sqrt(valpha * valpha + vbeta * vbeta);
double angle = atan2(vbeta, valpha);

// Determine sector
if (angle >= 0 && angle < PI/3) {
*sector = 1;
} else if (angle >= PI/3 && angle < 2*PI/3) {
*sector = 2;
} else if (angle >= 2*PI/3 && angle < PI) {
*sector = 3;
} else if (angle >= -PI && angle < -2*PI/3) {
*sector = 4;
} else if (angle >= -2*PI/3 && angle < -PI/3) {
*sector = 5;
} else {
*sector = 6;
}

// Calculate times for switching states
double T1 = (Vref * sin(PI / 3 - angle)) / (sqrt(3) * Vdc);
double T2 = (Vref * sin(angle)) / (sqrt(3) * Vdc);
double T0 = Ts - T1 - T2;

// Calculate duty cycles for each phase
*dutyA = (T1 + T2 + T0 / 2) / Ts;
*dutyB = (T2 + T0 / 2) / Ts;
*dutyC = (T0 / 2) / Ts;
}

double pid_controller(double setpoint, double measured_value, double *prev_error, double *integral, double Kp, double Ki, double Kd, double dt) {
double error = setpoint - measured_value;
*integral += error * dt;
double derivative = (error - *prev_error) / dt;
double output = Kp * error + Ki * (*integral) + Kd * derivative;
*prev_error = error;
return output;
}

 

标签:double,foc,Ts,beta,theta,alpha,PI
From: https://www.cnblogs.com/ycpkbql/p/18369446

相关文章

  • Focal Loss详解及其pytorch实现
    FocalLoss详解及其pytorch实现文章目录FocalLoss详解及其pytorch实现引言二分类与多分类的交叉熵损失函数二分类交叉熵损失多分类交叉熵损失FocalLoss基础概念关键点理解什么是难分类样本和易分类样本?超参数......
  • java使用动态链接库读取Fanuc设备,在linux环境部署时报错:FOCAS2 log file is not found
    在linux环境中,使用java调用动态链接库的方式读取Fanuc,报错“FOCAS2logfileisnotfound”解决办法linux环境使用cnc_allclibhndl3之前,需要先使用cnc_startupprocess启用并指定日志文件,否则会报错:"FOCAS2logfileisnotfound"。会包含cnc_startupprocess,windows的dll库......
  • ABC 366E Manhattan Multifocal Ellipse
    题意给你N个在二位平面上的整点(即横纵坐标都为整数的点),以及一个距离阈值D,求有多少个整点(x,y)满足Σ(abs(x-x[i])+abs(y-y[i])),(1≤i≤N)思路题目显然是要要求某个点到给定的N个点的曼哈顿距离之和,但是如果强行枚举点,根据数据范围显然是不可以通过的。那么我们仔细思考一下......
  • docker安装和使用 -- px4-dev-nuttx-focal为例
    安装dockersudoapt-getupdatesudoaptinstalldocker.io镜像源设置1.可scienceInternet开启代理后,还需要设置docker的服务器,参考教程sudomkdir-p/etc/systemd/system/docker.service.dsudovi/etc/systemd/system/docker.service.d/proxy.conf在新建的proxy.co......
  • 中功率FOC驱动器电路分析
    出于对simplefoc的敬佩,所以想自制一个硬件驱动板,目标是能够稳定驱动至少350W的直流无刷电机,电路原理图已经完成,还有一个宗旨是全部元器件国产化。直接上原理图,我把主要的部分以图片的形式贴出来![电源](https://i-blog.csdnimg.cn/direct/48a3ced9bb444f54a5a23b80b......
  • 【花雕学编程】Arduino FOC 之机械臂三维位置跟踪
    Arduino是一个开放源码的电子原型平台,它可以让你用简单的硬件和软件来创建各种互动的项目。Arduino的核心是一个微控制器板,它可以通过一系列的引脚来连接各种传感器、执行器、显示器等外部设备。Arduino的编程是基于C/C++语言的,你可以使用ArduinoIDE(集成开发环境)来编写、......
  • 人工智能深度学习系列—深度学习损失函数中的Focal Loss解析
    文章目录1.背景介绍2.Loss计算公式3.使用场景4.代码样例5.总结1.背景介绍在深度学习的目标检测任务中,类别不平衡问题一直是提升模型性能的拦路虎。FocalLoss损失函数应运而生,专为解决这一难题设计。本文将深入探讨FocalLoss的背景、计算方法、应用场景以及如......
  • Godot聚焦(focus)应用
    首先你需要进行如下配置 指定按钮需要与面板和脚本逻辑顺序一致。模式all代表即可以响应鼠标也可以响应键盘。园哥面板顺序如下 只需要一个脚本脚本挂载在第一个按钮上,其中脚本是必须的,否则即使在编辑器上配置了聚焦也不起作用。脚本如下 点击运行按钮右上角运行结果如下......
  • 【花雕学编程】Arduino FOC 之使用正逆运动学的二轴绘图机器人程序
    Arduino是一个开放源码的电子原型平台,它可以让你用简单的硬件和软件来创建各种互动的项目。Arduino的核心是一个微控制器板,它可以通过一系列的引脚来连接各种传感器、执行器、显示器等外部设备。Arduino的编程是基于C/C++语言的,你可以使用ArduinoIDE(集成开发环境)来编写、......
  • 自制基于simplefoc大功率驱动板想法的由来,同时欢迎有相同兴趣的F友一起来玩。。。
      前一阵子,偶然在B站上看了一个simplefoc的介绍视频,代码简洁、算法精妙让人佩服,更让人佩服的是:开源!遂!搜索之!不搜不知道一搜吓一跳,发现太OUT了,原来玩这个算法的人这么多,让我这个整天沉浸在帕克、反帕克、Ualpha、Ubeta...的开发攻城狮汗颜。  出于好奇和对知识的无限渴求(冒......