Anybody linearized the motor power yet?

Our students were a big fan of THIS remapping when using v4 the past few years.

Has anybody taken the time to remap the V5 motors? Not trying to have my students reinvent the wheel if it already exists.

1 Like

I don’t see a need to as the motors have built in PID

Pardon me if I’m wrong, but I don’t think this has anything to do with having built-in PID.

I would be inclined to agree with @NightsRosario, the PID and control software should be the same idea. Just set it to percent mode and you should be good.

@littlebro5 It does. The default control method for motors in VCS and RMS (and available in PROS) is to give them target velocities, not specific PWM voltage values. This means if you tell the motor to spin at 5% velocity, it will ramp up the voltage according to its internal PID system to achieve 5% velocity. This is radically different than directly assigning voltage values, as there is no minimum threshold value to get the robot to start moving (in theory). When assigning voltage values, there is some amount of friction that the motor has to overcome before it even starts moving, so a voltage of 5% might not even produce any motion. Good drive code for a voltage-control paradigm would take this into account, as well as take the non-linear speed response of the motors as voltage increased into account. With velocity PID, the PID algorithm takes care of adjusting voltage to produce a target velocity and code doesn’t need to worry about it (unless a later update to VEXos exposes those parameters for us to adjust). The only remapping you would need to do is for driveability’s sake if you have a high acceleration robot to make it more controllable at low speeds.

I personally prefer voltage control for the drive because of the extra control over acceleration it gives me (though it might just be that I’m more used to voltage control), so some kind of voltage linearization would be nice for the V5 motors. I might end up getting some data points and doing the lineraization with a python script if no one else does though.

This is what I’m seeking, controllability at low speeds. Drivers that are excited in the heat of a match have trouble controlling a high speed bot. If it’s already linear (learn something new every day about V5), I’m guessing we either need more driver practice (can you ever have enough?) or we might consider an exponential remapping to provide a wider band of low speed control.

Actually, everybody is correct in some sense… Let me explain why velocity PID driving mode may not feel very natural.

PWM motor controller works by connecting the load to the power source X% of the time.
If the load is purely resistive (i.e. heater) it will result in generating exactly X% of the max power.

However, if there are inductive or capacitive components you will start getting some funny nonlinear results. For example, if in addition to light resistive load, you connect a large capacitor to the output of the PWM controller, it may be able to charge quickly (up to the full voltage of power supply) and then slowly release the energy to the resistive load while the PWM is in the low state. This is exactly what you see in the MC29 power/control curve that was measured with very little load:

Non-lineriarity of the curve depends on the ratio of how much energy output capacitor inside MC29 could store versus how much power the motor needs to overcome internal friction and coil’s electrical resistance at the light loads. As you increase the load and energy demand, capacitor will not be able to keep up (charge speed is limited due to circuit internal resistance) and you will see the curve flattening out and approaching ideal line.

Unlike more sophisticated motor controllers, MC29 has no feedback loop to adjust output voltage to match requested control value (regardless of the actual load).

You may also know that the voltage applied to the motor do not directly translates to output power. When motor rotates at some angular velocity, its back EMF (electromotive force) = voltage it would generate if you used it as generator, and is proportional to the angular velocity. However, torque (force) generated by the motor is proportional to the current (I) flowing through the coils (of resistance R) which, in turn, proportional to the voltage drop between the PWM’s output voltage and back EMF:

I*R = Vbattery * PWMpercentage - BackEMF
TorqueOutput = Vbattery * PWMpercentage * c1 - AngularVelocity * c2

Where c1 and c2 are some coefficients to make units and scale agree.

You could see that, regardless if motor controller had feedback adjusting linear voltage output, it would still control neither only output velocity nor only output torque, but rather a sum of them. And the power it is equal to the product of torque and velocity.

With V5 you have a choice to set output to velocity PID, where feedback loop would exclude toque component, and will simply increase output power until actual velocity matches commanded value.

Human brain is very flexible and drivers could, probably, adapt to the new controls. However, it feels more natural, when pushing harder on the control stick gives you increased torque and not just increases velocity. The old control method seem to combine the best of both worlds for the manual control.

1 Like

One of the most straight-forward ways to do this is to square or cube the value. You just need to be careful about the type of value you’re storing. If you can’t store too large a value and you start cubing values around 100, you can hit the limit. Meanwhile, if you adjust early and use something that only stores integers, you can lose gradation. The basic idea is as follows:

Using rational numbers (like float):

  1. Store the axis value.
  2. Divide by the maximum value to give you a value between -1 and +1.
  3. Square or cube that, still giving between -1 and +1. (If you square, you need to put the sign back on it.)
  4. Multiply by the maximum value.
  5. Assign the new value to the motor.

Using integers (like int), assuming they may not store values around 1,000,000:

  1. Store the axis value.
  2. Square that.
  3. Divide by the maximum axis value.
  4. Multiply again (cubing it).
  5. Divide by the maximum (if you want cubed) or divide by the absolute value of the stored axis value (if you want squared).
  6. Assign the new value to the motor.

It’s not really so many steps in programming since you can lump all that math together in the same line where you assign the value to the motor. But you might to the calculations separately, in the same place where you set a dead band. Even in such a case, though, you’re only looking at the same or nearly the same number of lines of code as setting the dead band in the first place.

If you are using a joystick deadzone to prevent drifting, I would use a piecewise function when defining an exponential drive. Otherwise your deadzone will need to be massive.

I modeled the controller input and voltage output as a piecewise function based on n (power) and d(deadzone size).

If you just define your deadzone normally, you don’t have to worry about making the function piecewise as it already effectively is:

float leftDriveValue;

while(true) {
   leftDriveValue = Controller1.Axis.position(percent);
   if(leftDriveValue < 10) {
      leftDriveValue = 0;
   leftDriveValue = ((leftDriveValue/100)^3)*100;
   leftMotor.spin(directionType::fwd, leftDriveValue, velocityUnits::pct);
1 Like