Velocity and Voltage Based Control Mechanisms

About Velocity and Voltage Control

Velocity and voltage control provide methods of commanding your Vertiq module to a specified rotational velocity. All Vertiq modules, regardless of firmware style (speed or servo), can be controlled via velocity and voltage commands, though the underlying implementation of control varies depending on the controllers available on your firmware. Both our velocity and position controllers support three methods of setting velocity targets: Control Velocity, Control Voltage, and Control PWM. All modules also support control via standard Analog Hobby Protocols, with options to map inputs to Control Velocity, Control Voltage, and Control PWM. The inputs are mapped by either the ESC Propeller Input Parser or Servo Input Parser. Vertiq’s speed modules larger than our 23XX family can also be driven with DroneCAN.

Throughout this document, we will build up to, and explain our two full controllers in regards to velocity and voltage control. These controllers are the Propeller Motor Controller (left) and Multi Turn Angle Controller (right).

Full Propeller Motor Controller Left and Full Multi Turn Angle Controller Right
../_images/full_propeller_control_system.png
../_images/full_multi_turn_system.png

Velocity and Voltage Control Mechanisms

Control Velocity

Velocity Control Through Propeller Motor Controller v. Multi Turn Angle Controller

All Control Velocity commands use closed loop PID control in order to control either a target velocity or position. The controllers available on each module are firmware dependent. In order to find what controllers are available with your module and firmware, please see your module’s page available on the left-hand side of this page.

Our Propeller Motor Controller, available only while using speed firmware, uses a velocity PID controller in which the input target is a velocity, and error is calculated on the difference between the module’s actual velocity and the target. This is the default controller used when the module receives commands through Analog Hobby Protocols or DroneCAN. An important note is that while Hobby and DroneCAN commands are passed into the Propeller Motor Controller, whether the module uses velocity control depends on the configured mode parameter. Please refer to these linked pages in order to learn more about Hobby and DroneCAN, and the mode parameter.

Propeller Motor Controller PID Loop

Propeller Motor Controller PID Loop

Our Multi Turn Angle Controller (available on all servo firmware and on select speed firmware) is generally meant for angle based control, and is detailed more in our Angle Control Mechanisms documentation. It can, however, also control the module’s velocity, with an important note that it always controls based on a target position. This means that when sent a velocity command, the Multi Turn Angle Controller advances the displacement angle target at the commanded velocity.

Multi Turn Motor Controller PID Loop

Multi Turn Motor Controller PID Loop

Due to each PID controller’s nature, each reacts differently to changes in the proportional, integral, and derivative gains. An important distinction is that even when controlling the Multi Turn Angle Controller with a velocity, the proportional gain relates to a positional error, the integral gain to the positional error multiplied by time, and the derivative gain to velocity error. For the Propeller Motor Controller, proportional gain pertains to velocity error, integral to position, and derivative to acceleration.

Control with Propeller Motor Control

When passed into the Propeller Motor Controller, Control Velocity is a direct target input into the velocity PID control loop. The parameter ctrl_velocity is available through the Propeller Motor Control Client, and is expressed as a value in radians per second. Once set, the module attempts to reach the target velocity. The exact time it takes to reach the setpoint depends on the module’s tuning.

Demo - Basic Velocity Spinning with the Propeller Motor Controller

First, if you have not already, please set up your computer to use Vertiq’s Python API with the instructions found here.

Note

You must set the serial_port parameter to the serial port connected to your module.

Warning

Please remove all propellers from any module you plan on testing. Failure to do so can result in harm to you or others around you. Further, please ensure that your module is secured to a stationary platform or surface before attempting to spin it.

This example illustrates a basic velocity command with the Propeller Motor Controller. We start by setting the module’s timeout period to 5 seconds to ensure that we will continue to spin, even though we are not continuously sending new commands. The module will continue for up to 5 seconds before stopping itself and performing its timeout behavior. Note that the longest sleep period in the script is 4 seconds, so we will not hit a timeout during this test. Then, we set ctrl_velocity to \(25\frac{rad}{s}\) which causes the module to start spinning at \(25\frac{rad}{s}\). After 4 seconds, we halt the module by putting it into Coast, wait another 2 seconds, and perform the same steps, only this time spinning the module at \(-12.5\frac{rad}{s}\). Notice that the module spins in the counterclockwise direction when commanded to a positive velocity, and the clockwise direction when commanded to a negative velocity. This will always be the case as our modules consider counterclockwise movement as positive.

 1import iqmotion as iq
 2import time
 3
 4#Create a SerialCommunicator object for our servo module
 5com = iq.SerialCommunicator("COM3")
 6module = iq.SpeedModule(com)
 7
 8#Set the timeout to a period of 5 seconds
 9module.set("propeller_motor_control", "timeout", 5)
10
11#Command a velocity of 25 rad/s, then wait for 4 seconds
12module.set("propeller_motor_control", "ctrl_velocity", 25)
13time.sleep(4)
14
15#Set the module to coast, then wait 2 seconds
16module.set("propeller_motor_control", "ctrl_coast")
17time.sleep(2)
18
19#Command a velocity of -12.5 rad/s, then wait for 4 seconds
20module.set("propeller_motor_control", "ctrl_velocity", -12.5)
21time.sleep(4)
22
23#Set the module to coast
24module.set("propeller_motor_control", "ctrl_coast")

Control with Multi Turn Angle Control

Like the Propeller Motor Controller, the Multi Turn Angle Control client offers a ctrl_velocity entry. The Multi Turn Angle Control client also provides a unique velocity command, Control Linear Velocity. Control Linear Velocity provides a mechanism for controlling the velocity of a driven output, for example a belt or lead screw. Information about angular and linear commands can be found here.

Demo - Basic Velocity Spinning with the Multi Turn Angle Controller

First, if you have not already, please set up your computer to use Vertiq’s Python API with the instructions found here.

Note

You must set the serial_port parameter to the serial port connected to your module.

Warning

Please remove all propellers from any module you plan on testing. Failure to do so can result in harm to you or others around you. Further, please ensure that your module is secured to a stationary platform or surface before attempting to spin it.

This example illustrates a basic velocity command with the Multi Turn Angle Controller. First, we set ctrl_velocity to \(25\frac{rad}{s}\) which causes the module to start spinning. After 4 seconds, we halt the module by putting it into Coast, wait another 2 seconds, and perform the same steps, only this time spinning the module at \(-12.5\frac{rad}{s}\). Notice that the module spins in the counterclockwise direction when commanded to a positive velocity, and the clockwise direction when commanded to a negative velocity. This will always be the case. Also, notice that we did not set a new timeout value as we did with the Propeller Motor Controller example. By default, the Multi Turn Angle Controller, has a timeout period much higher than 4 seconds, so we do not worry about setting a new value here.

 1import iqmotion as iq
 2import time
 3
 4#Create a SerialCommunicator object for our servo module
 5com = iq.SerialCommunicator("COM3")
 6module = iq.ServoModule(com)
 7
 8#Command a velocity of 25 rad/s, then wait for 4 seconds
 9module.set("multi_turn_angle_control", "ctrl_velocity", 25)
10time.sleep(4)
11
12#Set the module to coast, then wait 2 seconds
13module.set("multi_turn_angle_control", "ctrl_coast")
14time.sleep(2)
15
16#Command a velocity of -12.5 rad/s, then wait for 4 seconds
17module.set("multi_turn_angle_control", "ctrl_velocity", -12.5)
18time.sleep(4)
19
20#Set the module to coast
21module.set("multi_turn_angle_control", "ctrl_coast")
Demo - Basic Velocity Command with Linear Velocity

This example illustrates how linear velocity commands work with the Meters per Radian parameter. First, we set meter_per_rad to \(\frac{1}{5}\) (every module rotation of one radian results in \(\frac{1}{5}\) meters of output). Then, we send a command to set the output velocity to \(10\frac{m}{s}\). After a coast and wait, we then set the direct Control Velocity to \(-10\frac{rad}{s}\). You’ll see that the two rotational speeds are very different with the first command resulting in motion about 5 times faster than the second.

 1import iqmotion as iq
 2import time
 3
 4#Create a SerialCommunicator object for our servo module
 5com = iq.SerialCommunicator("COM3")
 6module = iq.ServoModule(com)
 7
 8#Set Meters Per Radian to 5
 9module.set("multi_turn_angle_control", "meter_per_rad", 1 / 5)
10
11#Command a velocity of 25 rad/s, then wait for 4 seconds
12module.set("multi_turn_angle_control", "ctrl_linear_velocity", 10)
13time.sleep(4)
14
15#Set the module to coast, then wait 2 seconds
16module.set("multi_turn_angle_control", "ctrl_coast")
17time.sleep(2)
18
19#Command a velocity of -12.5 rad/s, then wait for 4 seconds
20module.set("multi_turn_angle_control", "ctrl_velocity", -10)
21time.sleep(4)
22
23#Set the module to coast
24module.set("multi_turn_angle_control", "ctrl_coast")

Control Voltage

Setting a Control Voltage results in the same behavior in both the Propeller Motor Controller and Multi Turn Angle Controller. Setting a Control Voltage is the same as directly setting the calculated output voltage from the PID controller. An important note here is that commanding a voltage is essentially performing open loop velocity control in which the commanded voltage is multiplied by your module’s Kv producing a velocity target. For example, with a module with a Kv of 150, a voltage command of 2V would result (in the ideal case) in a rotational speed of \(300 \text{rpm}\), or \(31.41\frac{rad}{s}\). In reality, the output velocity will be close to, but not exactly, \(31.41\frac{rad}{s}\). In general, the output velocity will be lower than expected due to drag.

You can find ctrl_volts in either the Propeller Motor Controller or Multi Turn Angle Controller depending on the features supported by your module.

Choosing to control between either a Control Velocity or a Control Voltage is the same as choosing a multiplexed output of the following:

Open v. Closed Loop Control with Control Voltage v. Control Velocity

Open v. Closed Loop Control with Control Voltage v. Control Velocity

Demo - Spinning with Control Voltage

First, if you have not already, please set up your computer to use Vertiq’s Python API with the instructions found here.

Note

If your module only suppports the Multi Turn Angle Controller, this example should work identically as with the Propeller Motor Controller. To test this, simply change “propeller_motor_control” to “multi_turn_angle_control” in each command.

Note

You must set the serial_port parameter to the serial port connected to your module.

Warning

Please remove all propellers from any module you plan on testing. Failure to do so can result in harm to you or others around you. Further, please ensure that your module is secured to a stationary platform or surface before attempting to spin it.

In this demo, you will first see the module rotate counterclockwise for 4 seconds, stop for 1 second, and then rotate clockwise for 4 seconds before stopping again. Note that, like other target commands, counterclockwise is considered the positive direction of rotation. We also set the module’s timeout period to 5 seconds to ensure that it can complete 4 seconds of rotation without interruption.

 1import iqmotion as iq
 2import time
 3
 4#Create a SerialCommunicator object for our servo module
 5com = iq.SerialCommunicator("COM3")
 6
 7# module = iq.SpeedModule(com, extra_clients=clients)
 8module = iq.SpeedModule(com)
 9
10#Set the timeout to a period of 5 seconds
11module.set("propeller_motor_control", "timeout", 5)
12
13#Set our Control Voltage to 1V and hold it for 4 seconds
14module.set("propeller_motor_control", "ctrl_volts", 1)
15time.sleep(4)
16
17#Set the module to coast, and wait 1 second
18module.set("propeller_motor_control", "ctrl_coast")
19time.sleep(1)
20
21#Set our Control Voltage to -1V and hold it for 4 seconds
22module.set("propeller_motor_control", "ctrl_volts", -1)
23time.sleep(4)
24
25#Coast the module
26module.set("propeller_motor_control", "ctrl_coast")

Control PWM

Spinning your module with a Control PWM is very similar in behavior to a Control Voltage. A Control PWM command must be a value [-1, 1], and can be found as ctrl_pwm in either the Propeller Motor Controller or Multi Turn Angle Controller depending on your firmware’s style. The commanded PWM value is multiplied by the supply voltage in order to create the voltage sent to the module’s drive.

For example, if your module is powered by a 15V supply, and you set a Control PWM of 0.1, your module will apply a Control Voltage of 1.5V.

Our system above expands to the following, and represents the entirety of the Multi Turn Angle Control loop:

Open v. Closed Loop Control with Control Voltage v. Control Velocity v. Control PWM

Open v. Closed Loop Control with Control Voltage v. Control Velocity v. Control PWM and Complete Multi Turn Angle Controller PID Loop

Demo - Spinning with Control PWM

First, if you have not already, please set up your computer to use Vertiq’s Python API with the instructions found here.

Note

If your module only suppports the Multi Turn Angle Controller, this example should work identically as with the Propeller Motor Controller. To test this, simply change “propeller_motor_control” to “multi_turn_angle_control” in each command.

Note

You must set the serial_port parameter to the serial port connected to your module.

Warning

Please remove all propellers from any module you plan on testing. Failure to do so can result in harm to you or others around you. Further, please ensure that your module is secured to a stationary platform or surface before attempting to spin it.

This demonstration is meant to illustrate the similarities between PWM and Voltage control. We are powering our module with a 15V benchtop power supply. Therefore, a PWM Command of 0.1 should result in the same spin velocity as a Voltage Command of 1.5V. You will see this sample prints two statements. First, the observed drive velocity when driven by a Voltage Command of 1.5V, and the second, the observed drive velocity when driven by a PWM Command of 0.1. In the PWM case, you will also see the voltage observed at the module’s input. We also set the module’s timeout period to 5 seconds to ensure that it can complete 4 seconds of rotation without interruption.

 1import iqmotion as iq
 2import time
 3
 4#Create a SerialCommunicator object for our servo module
 5com = iq.SerialCommunicator("COM3")
 6
 7# module = iq.SpeedModule(com, extra_clients=clients)
 8module = iq.SpeedModule(com)
 9
10#Set the timeout to a period of 5 seconds
11module.set("propeller_motor_control", "timeout", 5)
12
13#Set our Control Voltage to 1.5V and hold it for 4 seconds
14module.set("propeller_motor_control", "ctrl_volts", 1.5)
15time.sleep(4)
16
17#Print our observed velocity
18print("Observed velocity with ctrl_volts = 1.5V: ", round(module.get("brushless_drive", "obs_velocity"), 3), "rad/s")
19
20#Set the module to coast, and wait 1 second
21module.set("propeller_motor_control", "ctrl_coast")
22time.sleep(1)
23
24#Set our Control Voltage to -1V and hold it for 4 seconds
25module.set("propeller_motor_control", "ctrl_pwm", 0.1)
26time.sleep(4)
27
28#Print our observed velocity
29print("Observed velocity with observed supply voltage:", round(module.get("brushless_drive", "obs_supply_volts"), 3), "V",  round(module.get("brushless_drive", "obs_velocity"), 3), "rad/s")
30
31#Coast the module
32module.set("propeller_motor_control", "ctrl_coast")
The printed output:
Observed velocity with ctrl_volts = 1.5V: 20.203 rad/s
Observed velocity with observed supply voltage: 14.929 V 20.495 rad/s

As expected, the observed velocities in both cases are practically identical.

Tuning Velocity Gains and Parameters

Propeller Motor Control PID Tuning

As mentioned above, tuning the Propeller Motor Controller and Multi Turn Angle Controller differs due to each controller’s nature. For more information about tuning the Multi Turn Angle Controller please see Position Control Tuning.

Our velocity PID controller found in Propeller Motor Controller can be tuned as any standard PID controller. With this controller, the proportional term acts on a velocity, our integral term on position, and our derivative term on acceleration.

Velocity Kp

The velocity proportional gain. Helps to correct speed errors. Higher gain means smaller errors and faster response, but can lead to oscillations and overheating.

Velocity Ki

The velocity integral gain. Helps to correct steady state speed errors. Higher gain means quicker suppression of steady state errors, but also increased oscillations, overheating, and faster windup. This term is generally not needed.

Velocity Kd

The velocity derivative gain. Helps to reduce overshoot oscillations. Higher gain means less overshoot from Kp and Ki, but can also introduce higher frequency oscillations and overheating.

Velocity Feed Forward Tuning

Feed forward terms are those added to the calculated PID control correction, and are based on the reference velocity. There are 3 available feed forward parameters settable through the Propeller Motor Controller, Feed Forward 0, 1, and 2. Feed Forward 0 is a constant value, Feed Forward 1 is multiplied by the current reference velocity, and Feed Forward 2 is multiplied by the reference velocity squared.

Feed Forward Terms in PID Control

Feed Forward Terms in Velocity PID Control

Velocity Feed Forward 0

The 0th order feedforward for the velocity controller. The constant voltage offset. Generally not needed for propellers. Velocity FF0 has units of volts [\(V\)].

Velocity Feed Forward 1

The 1st order feedforward for the velocity controller. A linear voltage term, which compensates for friction and motor back EMF. We recommend keeping the default value. Velocity FF1 has units of volts per radian per second [\(\frac{V}{(\frac{rad}{s})}\)].

Velocity Feed Forward 2

The 2nd order feedforward of the velocity controller. Typically compensates for propeller drag. Velocity FF2 has units of volts per radian per second squared [\(\frac{V}{(\frac{rad}{s^2})}\)].

Full Propeller Motor Controller

Accounting for all feed forward and control options, our complete velocity controller is summarized by the following:

Full Propeller Motor Controller

Full Propeller Motor Controller