Velocity control using just battery voltage.

The idea of sending a control value to a motor that is proportional to battery voltage keeps coming up. So I decided it was time to see if there is any milage to be had out of this very simple open loop control method. Test subject was my usual three motor flywheel that was build last year and, so far, is a bit pathetic at actually shooting balls (one day I will have time to actually make it work properly). Here is it.

In the background you can see a bench power supply, the experiment involved setting the voltage supplying the flywheel, running the flywheel and adjusting motor control value so as to hit a pre-determined velocity of 100rpm at the motor. By observing the measured velocity and adjusting the control value I was essentially acting as my own proportional controller. The results for several different battery voltages were collected using the ROBOTC datalog functions, these were then brought into excel for analysis.

This graph shows the results. The blue line (sorry, almost hidden) and markers are the raw data. The red line was the result of calculation using the LINEST function in excel that finds the best fit line from a set of data.


X axis is the battery voltage in mV (as returned by the nAvgBatteryLevel function). Y axis is the motor control value. The resultant line equation is.

motor_control = battery voltage x -0.0117904 + 147.22

I put this back into the code and verified that constant velocity was achieved as battery voltage was changed.

This will not be as good as TBH or PID. It does not compensate for balls being shot or anything else, only different battery conditions. I make no claims that it will necessarily make your flywheel better, it was just an interesting experiment I did today as distraction from “work” :slight_smile:

1 Like

So the relationship is actually quite linear then? That’s convenient

With this particular setup, with this power supply, it’s linear. Anyone planning to use this type of control would need to collect their own data set (probably multiple sets if different speeds are required). I did a quick test with a real battery and it did seem to also work, but I’m not going to do much else with the results.

1 Like

I tried to convince my rookie team to try this after they had been struggling with PID coding/tuning. They never took the bait, but good to know it probably would have worked.

We collected some data for this. It was pretty linear too. The nice thing was that adjustment was division by 2,3,4 from full for 3/4,1/2,and1/4 court. That was before, though… I need to collect data again with this rebuild…

1 Like

I would add one thing that everybody need to be cautious about. If you look at the graph from the thread about non-linear control curve of MC29 you will see that there are three segments with kind of linear slope:

Unless you try to do some sort of control remapping you want to stay within a segment for which you tuned your constants.

Both battery scaling and PID coefficients depend on the slope of the motor control curve. In the ideal case all your presets at both fully charged and drained battery levels should fall somewhere between 45 and 75 motor control values for maintaining constant speed (it is ok to have temporary values above that for power boosting).

For example, for full-court, mid-field, and at-the-bar presets our flywheel uses 64, 53, and 42 respectively. Even though we use PID, in addition to battery voltage scaling, when battery is fully charged there is a some degradation of the at the bar accuracy, while full-court shooting is accurate at any voltage.

1 Like

I might try this out on my flywheel once I get the chance. If I could set the motor power to 127 until it reaches the desired rpm, and then set motor power to the exact number that it needs to be based on battery voltage level, that would be amazing.

Alas, this will ensure a constant starting RPM but might not result in a fast recovery time because you’d still be relying on a constant motor power. But it’s definitely better than nothing.

I would assume that setting your motors to 127 until you reach the rpm you need to shoot with would result in the highest possible fire rate. Using battery voltage to set the motor power once it reaches that rpm would result in a velocity control system similar to bang bang, but without any oscillating, excess motor stress, etc.


This weekend my team finally did a proper battery voltage corrections for our P+I loop by collecting motor power levels required to run flywheel at one of the RPMs (row 1: 100, 118, 136, 150) at three battery voltages (Column A: nAvgBatteryLevel):


We want to compute required motor power as a liner function of battery voltage (motorPower = A + B * Battery).

Row 7 - values of B based on the data points are calculated by dividing difference between motorPower levels and battery voltage in rows 2 and 4 for each column. As you can see value of B (slope of the line on the graph) is slightly different for each targetRPM. This must be due to slightly different percentage of the motor power going toward friction losses at various RPM.

Luckily, it could be easily approximated with another linear formula in row 9: B(vel) = -5.6 - (targetRPM-100.0)/10.0, where 100 corresponds to our lowest tested RPM and 10 just happens to work for our launcher.

The final code that went into the program looks like this:

 motorPower = targetPow + (-5.6 - (targetRPM-100.0)/10.0) * (nAvgBatteryLevel/1000.0-8.392) + P + I

where targetRPM is preset velocity (row 1) and targetPower is preset power level (row 4) that we measured at battery voltage = 8.392v.

Row 11 shows results of applying this formula to voltage 7.564v which matches pretty well with experimental data in row 3. It doesn’t have to be perfect, because it just have to get us close to the final answer, while P and I components will do the rest.

However, using only battery voltage instead of PID have several important limitations. First of all, the value of those two coefficients -5.6 and 10.0 depend on particular launcher configuration. If something changes like one of the motor screws turns loose and friction increases, voltage only control will undershoot, while P+I should be able to easily compensate for that.

You are correct, and it appears some teams use this or similar strategy. But I think they are not telling us everything.

The problem is that you need to use some sensors to detect when ball is coming in or leaves the launcher, which all have noise. Also, various balls may take various amounts of energy from the flywheel and you don’t really know what is the exact time to stay at 127. Finally, there are unknown delays between you commanding new power level and motors actually getting it.

So, I would say, if anybody got to the point of doing anything more sophisticated than simple battery voltage correction, then it just makes sense to start investigating PID. And it is easy to avoid oscillations by choosing conservative values for Kp and Ki.

1 Like

More basic question: How do you read battery voltage?

how did you convert the data to an excel graph?

RobotC has a built-in “variable” nAvgBatteryLevel that reports averaged battery voltage.

I am not sure I fully understand the question, but essentially we read values from global variables while running our program under RobotC debugger, then entered it into spreadsheet and graphed A1:E4 area using first row as a series labels.

1 Like

Friday night before the competition our team has replaced 12/49 gears in two of the flywheel motors as well as re-lubricated (with white lithium grease) both motors and geartrain shafts leading up to the flywheel.

Prior to that our code was almost perfectly tuned: all presets, and battery voltage coefficients let it run speed keeping P+I loop with values of “I” well within -0.5…+0.5 power units.

It is good that we have both “I” component of PID as well as potentiometer that let you adjust flywheel preset speed and power level for autonomous. Because when we put the robot on the practice field Saturday morning the LCD displayed values of “I” in the range of -5…-4 power units. Less motor power was needed due to the reduced friction losses.

So the lessons learned is that if you rely on battery voltage scaling for the speed control you need some backup plan that will let you make quick adjustments when physical configuration changes in either bad or good direction.

1 Like

I just used what I called a pulsing system. It was feed forward with some manual readjustment. Basically we tuned the launcher at a median battery level so that under load at about 7.7V the launcher would make full court using the full court button, and subsequently for each other button. Then we had a +10 and -10 power button which allowed us to slow or speed up the flywheel momentarily to either recover or to give the flywheel just a tad more energy to get it in.
Another solution would be something like this, but with a scalar based on the tuned battery voltage divided by the actually battery voltage, so if the voltage is high, the power will be lower.