一、音圈电机是什么

音圈电机(Voice Coil Motor)是一种特殊形式的直接驱动电机。具有结构简单体积小、高速、高加速响应快等特性。其工作原理是,通电线圈(导体)放在磁场内就会产生力,力的大小与施加在线圈上的电流成比例.基于此原理制造的音圈电机运动形式可以为直线或者圆弧(摘自百度百科)
音圈电机最常见的应用应该就是喇叭了,如下图所示,线圈可以在磁场中跟随电流变化而变化
在这里插入图片描述

二、硬盘音圈电机

在硬盘上,音圈电机根据磁道信息来判断磁头所处的位置,可在极短的时间内精确地定位在由计算机指令指定的磁道上。具体他使用的什么定位算法,笔者也不清楚,但是有一点可以确定的是要定位就需要位置反馈。在这里插入图片描述

三、音圈电机改装

笔者在淘宝十多块买了一个硬盘,音圈电机拆解下来如下图所示。位置反馈使用的是2000线光编码器,使用电位器作为位置反馈也可以,就是效果较差,电位器容易受环境噪音干扰。3D打印了电机与编码器的连接部分。
在这里插入图片描述
组装在一起后如下图所示
在这里插入图片描述

四、控制与代码设计

接下来进入控制设计部分,先简单介绍伺服闭环控制,伺服系统有电流环、速度环、位置环,三个环串联形成串级PID控制系统,最内环为电流环,最外环为位置环,且外环输出作为内环设定值。不管定位还是控制速度,最终控制的都是电流,所以期望电流能自由控制,在伺服系统中需要将三相的电流按照相差120°来产生旋转磁场,可以使用foc方式实现电流模式,也就是力矩模式,那么在音圈电机中情况就简单多了,不需要什么复杂的foc和旋转磁场,直接给电机供直流电就是电流模式,大小和方向可以自由切换,此项目笔者使用TB67H450芯片驱动电机,此芯片可根据输入的电压控制信号来控制电机的电流,内部有比较器,可保证电压与电流的对应关系,即使电机阻抗发生变化,内部比较器会增加电压来实现电流恒定,大概是这么个原理,而直接pwm控制就没有这个效果。可以认为TB67H450芯片做了电流环的控制,程序只需实现速度环和位置环即可

4.1 pid控制对象实现

将pid控制器抽象为TargetPID类,结构体里面的数据是被操作成员变量,外面的接口函数是对变量操作的方法,使用c模仿c++面向对象的思想的简单实现,这样可以方便创建多个pid控制对象,实现速度环、位置环,甚至多个伺服电机

typedef struct
{
    float goal_val;
    float input_val;
    float out_val;
    float last_out_val;
    float integral_i;

    float Kp;
    float Ki;
    float Kd;

    /* interface */
	float (*getFeedbackVal)();
    
}TargetPID;
float PID_Control(TargetPID *target);
void PID_SetGoalVal(TargetPID *target, float goal_val);
void PID_SetPidPara(TargetPID *target, float kp, float ki, float kd);

pid控制器算法,使用绝对式pid算法,输入为被控制的对象

/**
  * @brief  pid控制核心函数
  * @param  target 控制对象
  * @return pid控制输出量 
  */
float PID_Control(TargetPID *target)
{
	float bias = 0;

	target->input_val = target->getFeedbackVal(); //采集输入

	bias = target->goal_val - target->input_val;
	target->integral_i += bias;
	target->out_val = target->Kp * bias + target->Ki * target->integral_i + target->Kd * (bias - target->last_out_val);
	target->last_out_val = bias;

	if (target->integral_i > MAX_INTEGRAL_VAL)  //积分限幅
	{
		target->integral_i = MAX_INTEGRAL_VAL;
	}
	if (target->integral_i < -MAX_INTEGRAL_VAL)
	{
		target->integral_i = -MAX_INTEGRAL_VAL;
	}	

	if (target->out_val > MAX_OUT_VAL)    //输出限幅
	{
		target->out_val = MAX_OUT_VAL;
	}
	if (target->out_val < -MAX_OUT_VAL)
	{
		target->out_val = -MAX_OUT_VAL;
	}		

	return target->out_val;
}

4.2 参数调整

创建速度环和位置环对象后,在主函数循环执行pid控制函数就可以实现位置闭环,麻烦的是参数调整,先给一个居中的位置值作为位置环目标值,先从速度环开始,从很小的数开始慢慢往上加,位置环也是如此,用手触碰电机,其鲁棒性较好即可,实际调整发现参数范围很广都可以稳定运行,根据需要调整位置环比例可得到不同位置环刚度。

4.3 其他应用

为了实现一些比较好玩的功能,在此系统中,我使用的都是纯比例控制。
1、实现阻尼效果:
将位置环比例、积分、微分都设为0,调整速度环比例,慢慢加大阻尼效果增强,因为位置环比例为0时,相当于位置环没有工作,处于速度模式,且速度环的目标值为0,用手拨动电机能感受到明显阻尼,速度越大阻力越大
2、作为体感遥控器使用
使用编码器的位置输出去控制其他执行器,比如机械爪,在机械爪安装力传感器,并将夹持力反馈到音圈电机,人就能感受到机械爪夹到了物体,在工业或娱乐游戏场景可以应用

总结

最后展示下最终的控制效果,正弦位置测试
在这里插入图片描述
对了,项目代码已全部开源GitHub下载地址,上面提到力控机械爪项目后面会陆续更新。
以上就是本篇博客的全部内容,若文中有不足之处,欢迎大家的批评指正!

Logo

鸿蒙生态一站式服务平台。

更多推荐