大家好,又见面了,我是你们的朋友全栈君。
0.前言
ODrive比较适合大电流的无刷电机使用,对于云台电机(小电流低转速)并没有使用电流环(好像SimpleFOC也没有电流环)。并且网上仅有少数的大电流无刷电机的配置例程,没有小电流无刷电机的配置例程。今天踏了一遍这个坑,遇到了很多错误,最后也逐渐摸索出了解决方法。
主要配置流程 参考博客
1.硬件介绍
1.1.硬件
-
ODrive
硬件版本:ODrive v3.6 56v电压版本
固件版本:fw-v0.5.1。这是目前(2021.04.04)最新版本的固件,也仅仅从0.5版本的固件开始才支持SPI接口的绝对值编码器。 -
云台无刷电机
GB4315云台电机,链接
配置24N28P,因此极对数是14;额定电压24V;额定转速150RPM(注意ODrive中的转速单位是r/s,不是r/min);额定电流0.92A;线电阻16.5欧姆。
-
编码器
AS5048A,SPI接口的绝对值编码器。注意该电机配套两种编码器,还有一个是AS5600,但是不支持SPI接口,因此ODrive不能用。
另外,编码器有Interface和Output两种外接方式:Interface是通信接口,比如SPI、IIC等,ODrive直接通过通信协议读取编码器芯片内部的寄存器值得到数据;而Output属于脉冲输出,比如AB、ABZ、PWM等,ODrive通过定时器的编码器模式读取这些脉冲并计算数据。
-
功率耗散电阻(可选)
50W 2R 黄金壳功率耗散电阻。
1.2.接线
电机直接随意接三相即可。
买来的电机上AS5048A编码器只给焊接了PWM接口的三根线,SPI接口没给焊,需要自己焊接。并且间距比较小,焊接的线要细一点。焊接后,接线注意:
-
将编码器的VCC、GND、MOSI、MISO、CLK连接到ODrive对应的相同的引脚上;
-
编码器的CS引脚接到1-8中的任意一个引脚上(但是默认1/2引脚是串口引脚,所以最好接到3-8上);
-
AS5048A是3.3V和5V电平兼容的,编码器的VCC接到ODrive的3.3V或者5V都可以。但是我最初接了3.3V,好像噪声有点大,又改成了5V(这个我也不确定有没有影响)
-
编码器信号容易受到电机电源线的干扰,所以需要一定的处理。在ODrive官网和社区上,给出了几个方法:
- 避免:尽可能避免编码器线太靠近电机线;尽量减小编码器和ODrive之间的连线长度;尽量不要使用带状电缆
- 使用差分信号传输,但是需要在两端添加RS422收发器,比较麻烦
- 使用屏蔽电缆,如屏蔽双绞线
- 使用铁氧体磁环:铁氧体磁环可减少电容耦合噪声。可以帮助减少耦合回编码器线的噪声,并可以减少EMI辐射。我们建议通过此方法将相线(共)绕3圈,但如果不合适,也可以绕2圈。
- SPI的编码器,请在CLK上串联一个20-50欧姆的电阻,该噪声更容易受到影响。
另外:
- 对于SPI的编码器,可以通过输入命令
odrv0.<axis>.encoder.spi_error_rate
来查看SPI信号的相关特性。如果它是1.0或接近1.0,则可能存在接线或电源问题。如果它是0.0或非常接近,那么您将获得良好的数据。如果介于两者之间,则您的数据断断续续。您可能需要使用示波器或逻辑分析仪,以检查编码器上是否未设置错误标志,以及波形是否正常。 - 最后我使用的是绕铁氧体磁环的方法,因为手头刚好有一个,而且也最简单。没使用磁环之前,输入命令
odrv0.<axis>.encoder.spi_error_rate
,得到的数值是0.6左右;使用磁环之后再输入此命令得到的值就是0.0了。(但是实际使用中电机不同,看位置的曲线,噪声还是比较大,虽然值比较小,但是波动很频繁,但是并没有影响电机的控制)
2.配置参数
注意:进行配置前建议首先执行一遍擦除配置odrv0.erase_configuration()
,然后odrv0.reboot()
重启 ODrive 以确保配置恢复为固件默认配置。
2.1.基本配置
这部分属于整个ODrive板子的配置,和电机无关,所以云台电机和大电流电机配置一样。
-
配置功率耗散电阻阻值,我们使用的的功率耗散电阻阻值为 2 Ohm,如果不接制动电阻或不想使用功率耗散电阻将此项配置为 0 即可
odrv0.config.brake_resistance = 2.0
-
配置电源电压低压保护阈值,当电源电压低于 8V 时将停止电机并报错,注意:8V 为极限值建议根据自己所使用的供电更精确的配置以更好地保护 ODrive 主板
odrv0.config.dc_bus_undervoltage_trip_level = 8
-
配置电源电压过压保护阈值,当电源电压高于 56V 时将停止电机并报错,注意:56V 为极限值建议根据自己所使用的供电更精确的配置以更好地保护 ODrive 主板
odrv0.config.dc_bus_overvoltage_trip_level = 56
-
配置母线电流过流保护阈值,当母线电流高于 80A 时将停止电机并报错,配置为无穷大时禁用此保护
odrv0.config.dc_max_positive_current = 80
-
配置电机制动时在母线上产生的反向电流过流保护阈值,当反向电流高于 5A 时将停止电机并报错,配置为负无穷大时禁用此保护
odrv0.config.dc_max_negative_current = -5
-
配置制动回充电流值为 0A ,由于使用的开关电源进行供电所以不具备电能回收功能,所以配置为 0,如果您使用的电池供电则可以根据电池组可以承受的回充电流大小进行配置,当母线上反向回充电流高于此值时,高出的电流能量将会通过功率耗散电阻进行消耗
odrv0.config.max_regen_current = 0
2.2.电机配置
这里需要注意,虽然说使用的是小电流的云台电机,但是经过我的测试,电机类型如果配置成云台电机的话,编码器校准总是失败。并且电机类型是云台电机,那么运行电机校准指令是没有任何反应的,而去看错误也不会报任何错误,此时就会很迷惑。实际是因为对于云台电机没使用电流环,所以就不用运行电机校准来检测电机的电阻和电感了。所以这里先配置成大电流电机,把电机的限制电流设小一点即可。最后等都配置好了,再把电机类型改成云台电机。
-
配置电机极对数,我们所使用的电机极对数为 14
odrv0.axis1.motor.config.pole_pairs = 14
-
配置所使用的电机类型为云台电机(云台电机数字2,大电流电机数字0)
odrv0.axis1.motor.config.motor_type = MOTOR_TYPE_GIMBAL
-
配置电机运行的最大电流限制。这里注意虽然电机的额定电流是0.92A,但是经过我测试设置成0.92A的话,电机速度始终上不去,位置控制反应很慢,而且电机位置环很软,整个电机就像没劲一样。最后经过测试把额定电流设置为4A,电机就可以达到他的额定转速,位置环也比较硬了。(实际一开始这个地方可以先设置成额定电流,所有的都配置好之后,让电机在速度模式下跑,看能不能跑到额定转速,如果不能那就把这里的限制电流加大,直到可以跑到额定转速)
odrv0.axis1.motor.config.current_lim = 4
-
配置电机参数校准时的电流,此电流值在进行电机参数校准和编码器偏移校准时使用,如果设置的过小在进行编码器偏移校准时电机将没有足够的力量旋转。因为校准的时候电机是空载,所以设置成0.5A即可。
odrv0.axis1.motor.config.calibration_current = 0.5
-
配置电机参数校准时的电压,当电机的相电阻越高此值应该越高,但是如果此值过高会造成电流过大,产生过流保护错误。关于电机校准时的电流和电压,官网说一般满足以下两个关系:
resistance_calib_max_voltage > calibration_current*电机相电阻
resistance_calib_max_voltage < 0.5*电源电压
因为电机的线电阻16.5欧姆,所以相电阻8欧姆左右,所以校准电压要大于0.5*8=4V。电池电压12V,同时校准电压要小于0.5 *12=6V,所以这里设置为5V。
odrv0.axis1.motor.config.resistance_calib_max_voltage = 5
- 配置电机电流采样范围,注意:此值设置后需要重新启动才能生效。
odrv0.axis1.motor.config.requested_current_range = 60
2.3.编码器配置
-
配置编码器为SPI模式
odrv0.axis1.encoder.config.mode = ENCODER_MODE_SPI_ABS_CUI # or ENCODER_MODE_SPI_ABS_AMS
-
关闭编码器的索引信号输入,这一步很重要!因为如果这里配置成True,后面编码器校准的时候就必须进行索引校准,否则无法进行下一步的偏移校准。但是实际上SPI是绝对值编码器,没有索引信号,无须索引校准。
odrv0.axis1.encoder.config.use_index = False
-
设置SPI编码器的CS引脚。不要设置为1/2引脚,那是串口通信用的。
odrv0.axis1.encoder.config.abs_spi_cs_gpio_pin = 4 # or which ever GPIO pin you choose
-
配置编码器分辨率,即电机转动一圈多少个计数值。AS5048A和TLE5012一样都是14位的编码器,所以这里设置为214=16384。这个数值要和最后电机转动一圈输出的数值一样, 可以以此作为检验的方法。
odrv0.axis1.encoder.config.cpr = 16384
-
设置编码器 PLL 带宽,一般对于高分辨率编码器 (> 4000个计数/转) 此值应该越高,这样有助于减少电机振动。
odrv0.axis1.encoder.config.bandwidth = 3000
2.4.控制器配置
-
配置电机控制模式,此处我们设置为位置模式
odrv0.axis1.controller.config.control_mode = CONTROL_MODE_POSITION_CONTROL
-
配置电机最大转速,注意单位为 [turn/s],例如此处我们配置为 60 转/秒。注意这里的转速配置,实际上它和前面的电机运行电流共同决定了电机的转速,哪个先达到哪个先其限幅作用。但是我遇到一个问题,即配置电机进入位置模式的时候,总会报错超速,即如下错误:
controller: Error(s): CONTROLLER_ERROR_OVERSPEED
我怀疑是和编码器的噪声有关,刚启动的时候可能编码器算出来的转速很大,所以总是超速。实际上,超速的判断并不是这个值,而是还有一个参数
odrv0.axis1.controller.config.vel_limit_tolerance
,这个值默认是1.2,也就是速度大于1.2*vel_limit 的时候,电机才进行限速。可以配置这个参数为0,让电机不检查限速。但是经过我的测试这个参数设为0之后还是会出现电机超速的错误。最后没办法了,我就把这个值设置的很大,最后设成了1000,速度限幅设成了60。再进入位置模式的时候就不会报超速的错误了。并且电机还是安全的,因为前面使用电流对其进行了限幅,速度不会很大。最终配置:odrv0.axis1.controller.config.vel_limit = 60 odrv0.axis1.controller.config.vel_limit_tolerance = 1000
-
配置控制器控制增益,pos_gain 为位置环增益,vel_gain 和 vel_integrator_gain 为速度环增益。这些参数需要电机进入闭环后在调节,这里先设置小一点,这样防止电机进入闭环后由于PID参数过大剧烈抖动。
odrv0.axis1.controller.config.pos_gain = 5 odrv0.axis1.controller.config.vel_gain = 0.01 odrv0.axis1.controller.config.vel_integrator_gain = 0.1
2.5.保存配置
保存配置参数并重启 ODrive ,已使某些配置参数生效。
odrv0.save_configuration()
odrv0.reboot()
3.校准工作
注意:进行参数校准前请确保电机转子能够自由旋转而且不能有偏载,即负载均匀和较弱的摩擦负载才行,重载或类似弹簧载荷不行,否则将影响参数自动校准
3.1.校准电机
-
进行电机参数校准,校准过程将测量电机相电阻、电机相电感,并根据相电阻相电感自动生成电流环 PI 增益,当听到电机发出 ‘哔’ 声后表示电机参数测量操作已完成。
这里注意,如果是云台电机,是不进行电机校准的,输入电机校准命令没有任何反应,也不报任何错误。由于经过测试使用云台电机模式无法通过编码器校准,所以之前将电机配置成了大电流电机的模型,但是限制了其最大电流,所以校准的时候还是安全的。
odrv0.axis1.requested_state = AXIS_STATE_MOTOR_CALIBRATION
-
查看状态信息,如果返回状态没有错误则电机校准OK,可以继续进行下面步骤。如果出现错误则要根据错误信息分析原因,然后输入
dump_errors(odrv0, True)
对错误进行清除后重新尝试。注意,有的时候输入这个命令,错误还是存在,这个时候再多输入几次这个命令清楚错误。此时可能错误会被清除,也可能错误仍然不能被清除,这时候就没办法了,之能再去解决错误,或者重启ODrive再次配置。dump_errors(odrv0)
-
将电机 pre_calibrated 设置为 True,表示电机已校准下次重新启动后可以直接使用本次校准的结果
odrv0.axis1.motor.config.pre_calibrated = True
3.2.编码器校准
注意由于使用的AS5048A是绝对编码器,没有索引信号,所以不用进行索引校准,直接进行偏移校准即可。
-
进行电机编码器偏移校准,启动后电机将朝着一个方向开环旋转然后反方向旋转然后停止,开环旋转时的电流大小为 odrv0.axis1.motor.config.calibration_current
odrv0.axis1.requested_state = AXIS_STATE_ENCODER_OFFSET_CALIBRATION
-
列出状态信息,当得到上述返回状态没有错误则表明编码器偏移校准OK,可以继续进行下面步骤,如果出现错误则要根据错误信息分析原因,然后输入
dump_errors(odrv0, True)
对错误进行清除后重新尝试dump_errors(odrv0)
-
将编码器 pre_calibrated 设置为 True,表示编码器已校准下次重新启动后可以直接使用本次校准的结果
odrv0.axis1.encoder.config.pre_calibrated = True
3.3.保存校准结果
将自动检测的电机参数保存并重启,等待 ODrive 重新连接到 odrivetool。
odrv0.save_configuration()
odrv0.reboot()
4.切换电机类型
这一步非常重要。因为之前为了成功进行编码器校准将电机设置成了大电流电机,这个时候如果直接进入闭环控制的话,电机的电流声音特别大,能明显听出来。估计这也是Odrive对云台电机不使用电流环的原因,因为电流的噪声太大了,加上电流环还不如不加。所以此时要把电机类型改为云台电机,然后保存配置,重启。此时再进入闭环,就会发现电机的电流声小了很多。
5.控制电机运行
-
进入闭环运行模式,此时电机将维持在当前位置,如果电机产生震动则说明控制增益设置的过大需要适当调低,当尝试用手转动电机轴时如果电机反应很迟钝反作用力很弱则说明需要适当调高控制增益。
odrv0.axis1.requested_state = AXIS_STATE_CLOSED_LOOP_CONTROL
-
控制电机运行到 1圈位置,因为没有配置梯形加减速模式,所以电机会以最快的速度到达1圈的位置。如果想反方向转动,位置值改为负数即可。此值也可以为小数,如:input_pos = 0.5,则电机正向转动到180°机械角度。如果转2.5圈,则input_pos = 0.5。注意如果电机断电后再上电,不论之前的位置是多少,重新上电后的位置一定是在1圈之内,即pos在0-1之间。
odrv0.axis1.controller.input_pos = 50
-
如果想释放电机,发送此命令即可让 ODrive 进入待机模式,此时电机可以被自由转动
odrv0.axis1.requested_state = AXIS_STATE_IDLE
6.重新启动自动进入闭环控制
注意由于使用的是绝对值编码器,所以每次重新启动后不需要进行编码器的索引校准(即无须寻找零点的位置)。如果使用的是ABZ的增量式编码器,那么每次开机后都需要进行编码器索引校准,就是一直朝着一个方向转直到找到Z相信号。
可以添加自动进入闭环模式的功能,配置 ODrive 启动后自动进入闭环控制模式,然后保存配置,这样每次重新启动后电机自动进入闭环运行模式,我们只需要发送位置控制指令即可。
odrv0.axis1.config.startup_closed_loop_control = True
odrv0.save_configuration()
7.PID参数调节
7.1.官网教程
调整电动机控制器是释放ODrive潜力的必不可少的步骤。通过调整,控制器可以快速响应系统中的干扰或变化(例如施加的外力或设定值的变化)而不会变得不稳定。正确设置三个调整参数(称为增益)可确保ODrive能够以最有效的方式控制电动机。这三个值是:
<axis>.controller.config.pos_gain = 20.0
[(转/秒)/转]<axis>.controller.config.vel_gain = 0.16
[Nm /(转/秒)]<axis>.controller.config.vel_integrator_gain = 0.32
[Nm /(((圈/秒)* s)]
即将推出的功能将启用自动调整。在此之前,这里是一个粗略的调整过程:
- 将
vel_integrator_gain
增益设置为0 - 确保您的系统稳定。如果不是,请减少所有收益,直到获得收益为止。
vel_gain
每次迭代增加约30%,直到电机出现振动。- 退回
vel_gain
至振动值的50%。 pos_gain
每次迭代增加大约30%,直到您看到一些过冲。- 退缩,
pos_gain
直到不再有超调为止。 - 积分器可以设置为
0.5 * bandwidth * vel_gain
,其中bandwidth
是系统的总跟踪带宽。假设您的调整使它以100ms的建立时间(从设定值更改到系统到达新设定值的时间)跟踪命令;这意味着带宽为1 /(100ms)= 1 /(0.1s)= 10hz。在这种情况下,您应该设置vel_integrator_gain = 0.5 * 10 * vel_gain
。
liveplotter工具在拨入这些值时可能会非常有用。要显示绘制位置设定值与测量位置值之间关系的图形,请在ODrive工具中运行以下命令:
start_liveplotter(lambda:[odrv0.axis1.encoder.pos_estimate, odrv0.axis1.controller.pos_setpoint])
7.2.云台电机自己调参总结
- 按照官网步骤,先把速度环Ki设置为0,把位置环的Kp设置成一个比较小的值,比如5。
- 逐渐增大速度环的Kp,直到电机出现震动。实际随着Kp的增大,电流声越来越大,最后会高频震动。
- 将速度环Kp减小,然后按照公式设置速度环的Ki。
- 逐步调大位置环的Kp,直到达到要求。调试中可以给一个Kp,再给一个位置目标,看阶跃响应。
注意:
- 我测试发现电流声的大小和位置环的Kp无关,和速度环的Kp有关,把速度环Kp减小,电流声就会小很多。
- 按理说应该位置环的Kp越大越有超调,可实际发现Kp比较小的时候,电机很软,此时反而有超调。感觉是因为此时电机太软了,到了目标位置有点控制不住。实际此时我把位置环的Kp调的比较大(100左右),电机很硬,位置环的超调反而很小。
8.总结
8.1.遇到的错误
1.MOTOR_ERROR_PHASE_RESISTANCE_OUT_OF_RANGE
电机相电阻超出范围。多数是因为电机的接线有问题,此时可以关闭ODrive,用万用表测量ODrive上的端子的线电阻和电机参数中的是否一致。可以使用以下命令查看电阻和电感:
odrv0.axis1.motor.config.phase_resistance
odrv0.axis1.motor.config.phase_inductance
2.ENCODER_ERROR_CPR_POLEPAIRS_MISMATCH
编码器CPR值和电机极对数匹配错误。这里首先检查设置的编码器值和电机极对数值是否正确。我一开始遇到这个问题,查看后发现这两个值并没有错误。后来发现还是编码器校准没有成功的原因。因为一开始我把电机配成了云台电机,然后进行编码器偏移校准的时候,电机只会左右转很小的范围(几度那样),相当于抖几下。这时候电机其实并没有正确完成编码器的校准。正常的编码器校准,电机会左右转动大概半圈,这样基本上就是完成了编码器校准。
这个时候的解决办法就是如前所述把电机先配置为大电流电机,当所有的校准都完成后,再把电机的类型改成云台电机。
3.CONTROLLER_ERROR_OVERSPEED
电机超速。原因我猜是因为启动时SPI类型的编码器的噪声很大导致的,解决方法前面配置的时候就说过,就是把电机的最大转速设置的非常高,但是最大电流有限制,所以电机也不会转的很快。
4.ENCODER_ERROR_ABS_SPI_COM_FAIL
SPI编码器失败。这个具体什么原因不知道,感觉还是因为SPI的编码器不稳定,因为我时常会出现原来正常,后来突然不能用了,就是报出了这个错误。大体可以从一下几个方面检查:
- 检查SPI编码器接线。因为ODrive上SPI编码器接口不是连在一起的,很容易导致线松动。最好的方式是确认连线无误后就用少量的热熔胶将编码器和ODrive的接线固定住。
- 可以通过输入命令
odrv0.<axis>.encoder.spi_error_rate
来查看SPI信号的相关特性。如果它是1.0或接近1.0,则可能存在接线或电源问题。如果它是0.0或非常接近,那么您将获得良好的数据。如果介于两者之间,则您的数据断断续续。 - 编码器校准原因,重启,再次进行编码器校准。
- 清除错误,重启再试一试
5.ENCODER_ERROR_INDEX_NOT_FOUND_YET
编码器索引信号尚未找到。此错误常在执行编码器偏移校准的时候出现,有两个原因:
1.在编码器校准的时候执行了索引校准命令,然后又去执行偏移校准。实际上由于使用的是绝对值编码器,所以无须进行索引校准,就算进行了也找不到,此时再去进行偏移校准自然会报错。
2.编码器配置中的odrv0.axis1.encoder.config.use_index = True
,这里配置成仍旧使用索引信号,所以后面会出错。将此配置改成False
即可。
6.AXIS_ERROR_INVALID_STATE
电机轴的非法状态。此时通常是因为命令顺序跳跃造成的,比如尚未进行电机校准或者编码器校准,就要进入闭环模式。在ODrive官网的故障排除的地方有讲解。
8.2.注意事项
1.错误解决方式
- 进入ODrive官网,找到故障排除的分类,进去查看对应类型的错误。
- Google搜索出错的类型,这时候通常会出现ODrive社区中的帖子。
2.设置参数后经常save_configuration()
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/127882.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...