Added context first, for questions/issues go to +++++++++++++++++
TL;DR:
- How to limit current when using powering with a battery (but still have holding torque)?
- Is it possible to read the current accurately even when using voltage control?
- Once voltage control works how to start with foc current control?
Context/Background
I am hoping to move to SimpleFOC based motor controllers for the robot that I am working on. We have a couple of motors that are used in various parts of the system, name this 150kV motor from ODrive and this 350kV Turnigy motor.
Currently, our system uses ODrives, but it would be really nice to be able to make/have/use a board that can drive a single motor and has a better command interface. With these goals in mind, we came across the SimpleFOC PowerShield and immediately had our attention piqued. After reading through the post on the shield it seemed like it fit our use-case well as we generally have gearing so the motors can turn quickly. Decided to take a shot at testing it out using some BTN chips from China, knowing full well they may cause problems. The first round of tests went poorly but figured out it was because we didn’t have a good handle on the software and were using batteries for power which allowed huge current spikes to blow out the chips/traces.
We grabbed an Infineon BLDC_Shield that uses the IFX007 chips as they appeared to be drop-in replacements for the BTN so it should allow us to test some likely working hardware while we got our footing with the software. Further, we switched to a desktop power supply so we could limit the current effectively.
We now have pretty good control over the motors within the TorqueControlType::voltage
regime, both MotionControlType::velocity
and MotionControlType::angle
which are the two that we need for the robot. This is true for both the Infineon and SimpleFOC boards.
+++++++++++++++++
Questions/Problems
-
Voltage/Current/Velocity limits do not seem to behave as I would expect
1.1 I have mostly been setting the phase resistance of the motor so that things can be done in current, but even when using voltage limits the behavior seems the same.
1.2 In order to reach high speeds ~2000RPM (210rad/s
) the limits have to be set very high, yet according to both the readout on the desktop power supply and an amp clamp the chosen limit is never reached. For example, with the settings shown below (1.2 Settings), the motor peaks at ~60 rad/s
and an amp draw of ~0.75A
even when the target velocity is >100. I am fairly sure I need to keep fiddling with PID gains, but my understanding is that should mostly affect how quickly and smoothly desired speeds are reached rather than what the cap is. Upping the current somotor.current_limit = 50
, while changing nothing else, leads to a peak speed of ~90rad/s
and an amp draw of ~0.82A
.
1.3 I am further puzzled because during the encoder index search and pole pair tests the motor moves fairly smoothly but it uses the full5A
that I have allowed it to have on the desktop power supply.
1.4 The goal of these limits in our system is to ensure that the load drawn from the battery and through various wiring harnesses is not too high, but is high enough to allow for holding torque in specific locations. -
Current Sensing - Voltage Control
2.1 In a potentially related issue, that may stem from my lack of deeper knowledge about FOC algorithms, trying to read the current sensor(s) in voltage mode is giving issues. Printing outcurrent_sensor.getDCCurrent()
, when running the same test from 1.2, gives highly volatile readings between6-12A
, with occasional extreme values like1A
or28A
.
2.2 The goal of reading current in this mode is that – as I will outline below, we have not been able to get any control modes using the current working – but we try to monitor what the current draw is in order to predict/optimize battery life on the robot. Plus it seems any oddities here may be the cause of our current control issues. -
TorqueControlType::foc_current
not working at all
3.1 Trying to run infoc_current
mode with the default gains leads to the motor spinning crazily even at torque or velocity targets of 0. And it is using the whole5A
available to it from the power supply.
3.2 Using the gains found in this post (3.2 settings) that are for the ODrive motor we have done testing with, does make it so that the motor doesn’t move with velocity or torque targets of 0, but it still draws the full5A
of the power supply (or more if allowed) to sit still.
3.3. Testing the current sensor on its own by attaching a resistor to the motor phase associated with it, either with the benchtop power supply or with a battery seems to give the right values; both when read directly from the ADC and when read through thecurrent_sensor.getDCCurrent()
function of the SimpleFOC library.
3.4 In searching through the documentation and various issues here I found various tests for how to see if the current sensors and/or foc algorithm is working and none of them seem to behave as desired. One such test is from the getting started doc and says that when the motor is heldcurrent_d
should be 0 (doesn’t seem to be true in my case) andcurrent_q
should increase as the setpoint is increased. Similarly, when a torque target of 0 is sent the motor doesn’t seem to spin freely as is mention here -
Units - Generally speaking it is a bit hard to figure out what units various settings and values are in. Is the whole library in standard units (e.g. V, A, rad/s) or are there times where mA or degrees are used? For all the limits and ramp values in the setup phase? What about the output from the monitor?
1.2 Settings
phase_resistance = 0.047858;
driver.voltage_power_supply = 24;
driver.voltage_limit = 24;
motor.current_limit = 30;
motor.velocity_limit = 220;
3.2 Settings
motor.PID_current_q.P = 0.5;
motor.PID_current_q.I = 0.1;
motor.PID_current_q.D = 0;
motor.PID_current_q.limit = 1;
motor.PID_current_q.output_ramp = 50;
motor.LPF_current_q.Tf = 0.1;
motor.PID_current_d.P = 1;
motor.PID_current_d.I = 0.5;
motor.PID_current_d.D = 0.01;
motor.PID_current_d.limit = 2;
motor.PID_current_d.output_ramp = 100;
motor.LPF_current_d.Tf = 0.0;
Also, I am quite new to the forum and to FOC algorithms in general so please just point me elsewhere if the answers I am seeking already exist. And I am more than happy to answer any questions or give more details about the hardware or software in use or the steps attempted so far.