写一个比SimpleFOC更好的库
点击观看哔哩哔哩视频
大家好,我是专注传导开源知识的灯哥。
首先,希望这个标题没有震惊到你,为了避免被喷,请容许我先做一下自我介绍,我是SimpleFOC中文资料的官方翻译者,现在官网上的资料就是我翻译的,并且我也是有记录的最早的把SimpleFOC开源项目引入国内的人,甚至基于SimpleFOC我还做了几版的无刷双路硬件并开源,所以其实我很了解SimpleFOC。
那么为何我会起一个这样子看起来很震惊的标题呢?主要是在这一年对SimpleFOC项目的应用中,的确是发现了SimpleFOC的很多不足和短板,这些短板主要分为以下几个方面:
1.SimpleFOC库架构复杂,内存占用大。
这个并不是作者代码水平的问题,而是本身SimpleFOC的结构决定的。SimpleFOC在设计之初就冲着多主控芯片支持的路子走,导致库内有很多针对不同芯片做的特化代码,为了适应这些特化代码,就不得不把很多底层函数进行深度封装以使得这些特化代码可以对接上去,这些过渡封装,就造成了库架构复杂和内存占用大的问题;并且这样的架构也造成了库没办法针对单一芯片的性能进行优化而必须照顾所有的芯片,这就大大的限制了库的发展。
2.SimpleFOC的初衷就是建立一个库,一个能够让人更好的学习FOC算法的库。 但是随着库结构的复杂和封装逐渐的加剧,FOC的过程被封装得越来越死,越来越难以发掘,在库中没有得到足够的“裸露”;官方网站的“理论角”也没有推导过程,对于FOC的学习来说难度其实没有降下来多少。
3.SimpleFOC库只注重FOC功能,没有做很多的软硬件扩展支持,比如Can,双编码器,ROS,无线,OpenMV,Python库,树莓派等,这限制了其在应用领域的进一步发展。
4.似乎还没有纯国人写的、资料完整的FOC开源库。
5.SimpleFOC库没有很好的电机快速应用功能,想要在这个库上运行电机,必须经过复杂的调参,所以,我认为引入自动PID调参在我的库里实际上很有必要。
6.SImpleFOC库没有无感电机驱动的相关算法,限制了其在无感工况条件下的应用。
因此,我决定基于我的DengFOC开源硬件,写一个能够解决以上问题的FOC库,并且借机针对其中的FOC基础实现部分做一个课程,教大家一步步的实现FOC。最终,我希望我的DengFOC能够成为一个真正的国产自主,资料课程全,功能丰富的完整的无刷电机驱动软硬件项目。
理想中我的FOC库在未来会具有以下优势功能:
- 资源占用低:内存占用比SimpleFOC少2/3
- 开放度更广:库把基本的FOC算法接口(如电角度、 、)等以一种及其简单的方式向用户开放,使得用户可以直接接触到 FOC 算法实现的全过程,易于学习和在此基础上更进一步的开发 FOC 算法。
- 外接能力强:支持与OpenMV、树莓派、Python等多种硬件方案和软件语言直接的对接和互相调用,可以以比SimpleFOC更快的方式完成无刷电机应用的开发。
- 即插即用,无需校准:先进的参数自识别功能可以使得用户无需配置任何参数,直接插入电机和编码器即可跑FOC
- 无线控制支持:高速 UDP,ESPNow 通讯,无需信号线即可控制电机 脚本支持:库内建强大的脚本语言 Lua,可以在不编译的情况下快速建立FOC应用
- 强大的工具链支持:支持与 Matlab 、Simulink 、ROS 等系统直接通讯,秒速建立机器人应用
- 高精度减速器应用支持:支持双编码器减速机应用
重要链接
本 FOC 库将与 DengFOC 硬件联合组成一整套完整可用的 FOC 电机驱动方案。资料链接:
1 灯哥开源 淘宝店–一站配齐DengFOC板 您的支持就是我们持续做开源内容和课程的动力,项目收益将用于后续开发DengFOC和做课程~
4 DengFOC官网 包含课程文字版讲义,DengFOC使用文档,库使用方法等。
社区
本FOC板子社区唯四Q群,欢迎加入:开源FOC无刷驱动交流群 灯哥开源 群号 778255240(1群) 735755513(2群)471832283(3群)834835665(4群)
任何使用问题和 DIY 问题 都会在这里做直接的讨论解答
实现一样的功能,DengFOC代码与SimpleFOC代码对比
简单而言,我需要库的结构主要呈这样,让我们来对比一个它与 SimpleFOC 同样实现闭环位置功能时的写法:
DengFOC
#include "DengFOC.h"
int Sensor_DIR=-1; //传感器方向
int Motor_PP=7; //电机极对数
void setup() {
Serial.begin(115200);
DFOC_Vbus(12.6); //设定驱动器供电电压
DFOC_alignSensor(Motor_PP,Sensor_DIR); //校准编码器M0的0电角度
}
void loop()
{
float Kp=0.133;
float Sensor_Angle=DFOC_M0_Angle();
setTorque(Kp*(serial_motor_target()-Sensor_DIR*Sensor_Angle)*180/PI,_electricalAngle()); //位置闭环
serialReceiveUserCommand(); //激活串口数据接收,必须放在Loop中
}
SimpleFOC
#include <SimpleFOC.h>
MagneticSensorI2C sensor = MagneticSensorI2C(AS5600_I2C);
TwoWire I2Cone = TwoWire(0);
//电机参数
BLDCMotor motor = BLDCMotor(14);
BLDCDriver3PWM driver = BLDCDriver3PWM(32,33,25,22);
//命令设置
float target_velocity = 0;
Commander command = Commander(Serial);
void doTarget(char* cmd) { command.scalar(&target_angle, cmd); }
void setup() {
I2Cone.begin(19,18, 400000UL);
sensor.init(&I2Cone);
//连接motor对象与传感器对象
motor.linkSensor(&sensor);
//供电电压设置 [V]
driver.voltage_power_supply = 16.8;
driver.init();
//连接电机和driver对象
motor.linkDriver(&driver);
//FOC模型选择
motor.foc_modulation = FOCModulationType::SpaceVectorPWM;
//运动控制模式设置
motor.controller = MotionControlType::angle;
//速度PI环设置
motor.PID_velocity.P = 0.2;
motor.PID_velocity.I = 20;
//角度P环设置
motor.P_angle.P = 20;
//最大电机限制电机
motor.voltage_limit = 12;
//速度低通滤波时间常数
motor.LPF_velocity.Tf = 0.01;
//设置最大速度限制
motor.velocity_limit = 40;
Serial.begin(115200);
motor.useMonitoring(Serial);
//初始化电机
motor.init();
//初始化 FOC
motor.initFOC();
command.add('T', doTarget, "target velocity");
Serial.println(F("Motor ready."));
Serial.println(F("Set the target velocity using serial terminal:"));
}
void loop() {
Serial.print(sensor.getAngle());
Serial.println();
motor.loopFOC();
motor.move(target_angle);
command.run();
}
可以看到它的结构和SimpleFOC的结构有很大的区别,首先,它的参数设置简洁,不像SimpleFOC一样一次过设置一大堆复杂的东西,并且这样更加容易写代码和二次开发新的功能,实现较好的可读性和可扩展性。
其次,它的FOC过程更裸露,如DengFOC代码中,PID的计算式子是可以直接列在输出式中的,这就使得对FOC过程进行扩增和修改更加方便,FOC整个过程可以变动,更加容易深度开发FOC算法。