# Velocity control loop

This control loop allows you to spin your motor with desired velocity. This mode is enabled by:

// set velocity motion control loop
motor.controller = MotionControlType::velocity;


You can test this algorithm by running the examples in the motion_control/velocity_motion_control/ folder.

## How it works

The velocity control closes the control loop around the torque control, regardless which one it is. If it is the voltage mode without phase resistance set, the velocity motion control will set the the torque command using the voltage Uq::

And if it is any of the current torque control modes (FOC or DC current) or voltage mode with provided phase resistance, the velocity motion control will be setting the target current iq:

The velocity control is created by adding a PID velocity controller to the torque control loop. PID controller reads the motor velocity v, filters it to vf and sets the torque target (uq voltage or iq current) to the torque control loop in a such manner that it reaches and maintains the target velocity vd, set by the user.

## Controller parameters

To tune this control loop you can set the parameters to both angle PID controller and velocity measurement low pass filter.

// controller configuration based on the control type
// velocity PID controller parameters
// default P=0.5 I = 10 D = 0
motor.PID_velocity.P = 0.2;
motor.PID_velocity.I = 20;
motor.PID_velocity.D = 0.001;
// jerk control using voltage voltage ramp
// default value is 300 volts per sec  ~ 0.3V per millisecond
motor.PID_velocity.output_ramp = 1000;

// velocity low pass filtering
// default 5ms - try different values to see what is the best.
// the lower the less filtered
motor.LPF_velocity.Tf = 0.01;

// setting the limits
// either voltage
motor.voltage_limit = 10; // Volts - default driver.voltage_limit
// of current
motor.current_limit = 2; // Amps - default 0.2Amps


The parameters of the PID controller are proportional gain P, integral gain I, derivative gain D and output_ramp.

• In general by raising the proportional gain P your motor controller will be more reactive, but too much will make it unstable. Setting it to 0 will disable the proportional part of the controller.
• The same goes for integral gain I the higher it is the faster motors reaction to disturbance will be, but too large value will make it unstable. Setting it to 0 will disable the integral part of the controller.
• The derivative part of the controller D is usually the hardest to set therefore the recommendation is to set it to 0 and tune the P and I first. Once when they are tuned and if you have an overshoot you add a bit of D component to cancel it.
• The output_ramp value it intended to reduce the maximal change of the voltage value which is sent to the motor. The higher the value the PI controller will be able to change faster the Uq value. The lower the value the smaller the possible change and the less responsive your controller becomes. The value of this parameter is set to be Volts per second[V/s or in other words how many volts can your controller raise the voltage in one time unit. If you set your voltage_ramp value to 10 V/s, and on average your control loop will run each 1ms. Your controller will be able to change the Uq value each time 10[V/s]*0.001[s] = 0.01V what is not a lot.

Additionally, in order to smooth out the velocity measurement Simple FOC library has implemented the velocity low pass filter. Low pass filters are standard form of signal smoothing, and it only has one parameter - filtering time constant Tf.

• The lower the value the less influence the filter has. If you put Tf to 0 you basically remove the filter completely. The exact Tf value for specific implementation is hard guess in advance, but in general the range of values of Tf will be somewhere form 0 to 0.5 seconds.

The voltage_limit parameter is intended if, for some reason, you wish to limit the voltage that can be sent to your motor.

In order to get optimal performance you will have to fiddle a bit with with the parameters. 😁

## Velocity motion control example

Here is one basic example of the velocity motion control with the voltage mode torque control with the complete configuration. The program will set the target velocity of 2 RAD/s and maintain it (resist disturbances) .

#include <SimpleFOC.h>

// motor instance
BLDCMotor motor = BLDCMotor( pole_pairs , phase_resistance );
// driver instance
BLDCDriver3PWM driver = BLDCDriver3PWM(pwmA, pwmB, pwmC, enable);

// Magnetic sensor instance
MagneticSensorSPI AS5x4x = MagneticSensorSPI(chip_select, 14, 0x3FFF);

void setup() {

// initialize magnetic sensor hardware
AS5x4x.init();
// link the motor to the sensor

// driver config
driver.init();

// set motion control loop to be used
motor.controller = MotionControlType::velocity;

// controller configuration
// default parameters in defaults.h

// controller configuration based on the control type
// velocity PID controller parameters
// default P=0.5 I = 10 D =0
motor.PID_velocity.P = 0.2;
motor.PID_velocity.I = 20;
motor.PID_velocity.D = 0.001;
// jerk control using voltage voltage ramp
// default value is 300 volts per sec  ~ 0.3V per millisecond
motor.PID_velocity.output_ramp = 1000;

// velocity low pass filtering
// default 5ms - try different values to see what is the best.
// the lower the less filtered
motor.LPF_velocity.Tf = 0.01;

// since the phase resistance is provided we set the current limit not voltage
// default 0.2
motor.current_limit = 1; // Amps

// use monitoring with serial
Serial.begin(115200);
// comment out if not needed
motor.useMonitoring(Serial);

// initialize motor
motor.init();
// align sensor and start FOC
motor.initFOC();

_delay(1000);
}

// velocity set point variable
float target_velocity = 2; // 2Rad/s ~ 20rpm

void loop() {
// main FOC algorithm function
motor.loopFOC();

// Motion control function
motor.move(target_velocity);
}


## Project examples

Here are two project examples which use velocity motion control and describe the full hardware + software setup needed.

Find more projects in the example projects section.