实现功能
m3508的串级pid闭环
8路C620电调的can1通讯
使用total anlge的相对编码器
过程要点
pid方面 外环角度环实际上影响了电机转速 内环速度环实际上影响了输出力矩大小 在带负载调试的时候 先调整好外环 让位置环不发散 先pd再i 电机略微震荡的话 调整内环i效果最好 负载震荡的话把外环p适当变小 同时提高d在4倍p左右
total angle 相对于网上一些花里胡哨的过程 我们采用4个象限进行判断 而得出电机转过的总角度
之所以使用总角度 一是方便后续运动学正解的直接调用 二是避免了在位置闭环时电机因为惯性转过8192时圈导致电机震荡
c语言方面 结构体定义 指针调用 函数可读性 数据声明 形参调用 需要注意 避免两组数据寄存在同一个运算函数
can通讯 并非本人负责范围 注意can1通讯有通讯速度上限为6khz 同时多设备挂载can总线应当开路器件避免电气故障
视频效果
演示视频
参考代码
主循环
while (1)
{
for(i = 0;i < MOTOR_COUNT;i++) pos_set [i] = 0;
for(i = 0;i < MOTOR_COUNT;i++) m3508_checkQuadrant(&m3508_arr[i]);
for(i = 0;i < MOTOR_COUNT;i++){
vel_set[i]=pid_calc(&pid3508pos[i],m3508_arr[i].total_angle,pos_set[i]);
iref_inner[i]=pid_calc(&pid3508v[i],m3508_arr[i].m3508_data->speed_rpm,vel_set[i]);
}
CAN_cmd_chassis(1,iref_inner[0], iref_inner[1], iref_inner[2], iref_inner[3]);
CAN_cmd_chassis(2,iref_inner[4], iref_inner[5], iref_inner[6], iref_inner[7]);
HAL_Delay(2);
}
总角度计算
void checkQuadrant()
{
/*
//Quadrants:
4 | 1
---|---
3 | 2
*/
uint16_t read_ecd=m3508->m3508_data->ecd;
int32_t quadrantNumber = 1;
//Quadrant 1
if( read_ecd >= 0 && read_ecd <=2048) quadrantNumber = 1;
//Quadrant 2
if(read_ecd > 2048 && read_ecd<=4096) quadrantNumber = 2;
//Quadrant 3
if(read_ecd > 4096 && read_ecd <=6144) quadrantNumber = 3;
//Quadrant 4
if(read_ecd > 6144 && read_ecd <8192) quadrantNumber = 4;
//Serial.print("Quadrant: ");
//Serial.println(quadrantNumber); //print our position "quadrant-wise"
if(quadrantNumber != m3508->previousquadrantNumber) //if we changed quadrant
{
if(quadrantNumber == 1 && m3508->previousquadrantNumber == 4)
{
m3508->turn_num++; // 4 --> 1 transition: CW rotation
}
if(quadrantNumber == 4 && m3508->previousquadrantNumber == 1)
{
m3508->turn_num--; // 1 --> 4 transition: CCW rotation
}
//this could be done between every quadrants so one can count every 1/4th of transition
m3508->previousquadrantNumber = quadrantNumber; //update to the current quadrant
}
m3508->total_angle=((8192*(m3508->turn_num))+read_ecd);
}