Skip to main content
Version: Next

Modify-the-pid-parameter

Whether it is the current loop, speed loop or position loop, although there is a default pid value in the flash of the actuator control chip, the user can still modify it in real time during use. To modify the pid value, you only need to send the corresponding message after entering any operation mode. For the message content, please refer to the communication protocol introduction.

Current loop pi:

As the name implies, the current loop pi is used to change the current regulation rate (the same parameters may vary in different actuator models, here we take the TA70-101 model as an example), for example:

The default current loop kp and ki values of the actuator are 0.0006 and 0.0001 respectively. At this time, it takes about 1.3s for the current to increase from 0 to 1000mA, as shown in the figure:

After setting the kp and ki values to 0.02 and 0.002 respectively, it takes about 0.2s for the current to increase from 0 to 1000mA, as shown in the figure:

注意:在使用轮廓速度模式或轮廓位置模式时,电流环pi不宜设置过大,否则执行器将发生剧烈抖动

Speed loop pi:

The figure shows the speed change curve when the speed loop kp and ki values are 25 and 0.6 respectively.

The figure shows the speed change curve when the speed loop kp and ki values are 100 and 2.4 respectively.

The velocity loop pi is used to control the speed regulation capability. When the pi value increases, the actual speed overshoot phenomenon is weakened and the speed oscillation amplitude is also reduced. When the pi value decreases, the opposite is true. The speed change rate is determined by acceleration (deceleration) . These two values can also be changed in real time. The modification method is similar to the pid value modification method.

Position loop pd:

The position loop mainly acts on the profile position mode and is used to control the size of the reference speed. When the same position difference is given, the kp value increases, and the actuator rotation speed increases. Kd is used to slow down the rate of change of the reference speed.

The figure shows the speed change curve when kp and kd are 0.004 and 0 respectively:

The figure shows the speed change curve when kp and kd are 0.016 and 0 respectively.

SDK:

Real-time modification of current loop PI

C++:

#include <motor_control.h>
string port_name = "COM3"; // Windows: "COM*" Linux: "/dev/ttyUSB*"
MotorControl motor(port_name, 921600, 0x01); // Params: serial port path (string), baud rate (uint32_t), actuator id (0x05060100)
MotorStatus status;
int main()
{
motor.mode_selection(Mode::CURRENT_MODE, 10, 10, 10);

motor.write_current_pid(0.02, 0.002);
Sleep(300);
motor.write_current(1000);
auto start_time = chrono::steady_clock::now();
while(1)
{
status = motor.get_motor_status({ 0xB1 });
cout << "电流环P:0.02 I:0.002 电流: " << status.current_value << endl;
auto current_time = chrono::steady_clock::now();
double elapsed_time = chrono::duration<double>(current_time - start_time).count();
if (elapsed_time >= 5.0)
{
motor.write_current(0);
break;
}
}

Sleep(1000);

motor.write_current_pid(0.0006, 0.0001);
Sleep(300);
motor.write_current(1000);
start_time = chrono::steady_clock::now();
while (1)
{
status = motor.get_motor_status({ 0xB1 });
cout << " 电流环P:0.0006 I:0.0001 电流: " << status.current_value << endl;
auto current_time = chrono::steady_clock::now();
double elapsed_time = chrono::duration<double>(current_time - start_time).count();
if (elapsed_time >= 5.0)
{
motor.write_current(0);
break;
}
}
Sleep(300);
motor.reset();
}

Python:

import time
import matplotlib.pyplot as plt
from motor_control import *

id = [0x01]
port_name = "COM3"
motor = MotorControl(port_name, id, 921600)
mode_selection(motor, CURRENT_MODE, 10, 10, 10)

current_pid_set(motor, [0.02], [0.002])
time.sleep(0.3)
write_current(motor, [1000])
current_time = time.time()
while True:
results = get_v_p_c_v(motor)
print(f"ID:{results[0][0]}, 电流环P:0.02 I:0.002 电流: {results[0][3]}")
if (time.time() - current_time >= 5):
write_current(motor, [0])
break

time.sleep(1)

current_pid_set(motor, [0.0006], [0.0001])
time.sleep(0.3)
write_current(motor, [1000])
current_time = time.time()
while True:
results = get_v_p_c_v(motor)
print(f"ID:{results[0][0]}, 电流环P:0.0006 I:0.0001 电流: {results[0][3]}")
if (time.time() - current_time >= 5):
write_current(motor, [0])
break

time.sleep(1)
reset(motor)

Real-time modification of speed loop PI

C++:

#include <motor_control.h>
string port_name = "COM3"; // Windows: "COM*" Linux: "/dev/ttyUSB*"
MotorControl motor(port_name, 921600, 0x01); // Params: serial port path (string), baud rate (uint32_t), actuator id (0x05060100)
MotorStatus status;
int main()
{
motor.mode_selection(Mode::PROFILE_VELOCITY_MODE, 10, 10, 10);
motor.write_velocity_pid(25, 0.6);
Sleep(300);
motor.write_profile_velocity(3000, 500);
auto start_time = chrono::steady_clock::now();
while(1)
{
status = motor.get_motor_status({ 0xB1 });
cout << " 速度环P为25 I为0.6 速度: " << status.velocity_value << endl;
auto current_time = chrono::steady_clock::now();
double elapsed_time = chrono::duration<double>(current_time - start_time).count();
if (elapsed_time >= 5.0)
{
motor.write_profile_velocity(3000, 0);
break;
}
}
Sleep(300);
motor.write_velocity_pid(100, 2.4);
Sleep(1000);
motor.write_profile_velocity(3000, 500);
start_time = chrono::steady_clock::now();
while (1)
{
status = motor.get_motor_status({ 0xB1 });
cout << " 速度环P为100 I为2.4 速度: " << status.velocity_value<< endl;
auto current_time = chrono::steady_clock::now();
double elapsed_time = chrono::duration<double>(current_time - start_time).count();
if (elapsed_time >= 5.0)
{
motor.write_profile_velocity(3000, 0);
break;
}
}

Sleep(300);
motor.reset();
}

Python:

import time
import matplotlib.pyplot as plt
from motor_control import *

id = [0x01]
port_name = "COM3"
motor = MotorControl(port_name, id, 921600)
mode_selection(motor, PROFILE_VELOCITY_MODE, 10, 10, 10)

velocity_pid_set(motor, [25], [0.6])
time.sleep(0.3)
write_profile_velocity(motor, [3000], [500])
current_time = time.time()
while True:
results = get_v_p_c_v(motor)
print(f"ID:{results[0][0]}, 速度环P为25 I为0.6 速度: {results[0][4]}")
if (time.time() - current_time >= 5):
write_profile_velocity(motor, [3000], [0])
break

time.sleep(2)
velocity_pid_set(motor, [100], [2.4])
time.sleep(0.3)
write_profile_velocity(motor, [3000], [500])

current_time = time.time()
while True:
results = get_v_p_c_v(motor)
print(f"ID:{results[0][0]}, 速度环P为100 I为2.4 速度: {results[0][4]}")
if (time.time() - current_time >= 5):
write_profile_velocity(motor, [3000], [0])
break

Real-time modification of position loop PD

C++:

#include <motor_control.h>
string port_name = "COM3"; // Windows: "COM*" Linux: "/dev/ttyUSB*"
MotorControl motor(port_name, 921600, 0x01); // Params: serial port path (string), baud rate (uint32_t), actuator id (0x05060100)
MotorStatus status;
int main()
{
motor.mode_selection(Mode::PROFILE_POSITION_MODE, 10, 10, 10);
motor.write_position_pid(0.4, 0.0);
Sleep(300);
motor.write_profile_position(3000, 2000, 65535);
auto start_time = chrono::steady_clock::now();
while(1)
{
status = motor.get_motor_status({ 0xB1 });
cout << "位置环P为0.4 d为0 速度:" << status.velocity_value << endl;
auto current_time = chrono::steady_clock::now();
double elapsed_time = chrono::duration<double>(current_time - start_time).count();
if (elapsed_time >= 8.0)
{
motor.write_profile_position(3000, 2000, 0);
break;
}
}

Sleep(8000);

motor.write_position_pid(1.6, 0.0);
motor.write_profile_position(3000, 2000, 65535);
start_time = chrono::steady_clock::now();
while (1)
{
status = motor.get_motor_status({ 0xB1 });
cout << "位置环P为1.6 d为0 速度:" << status.velocity_value << endl;
auto current_time = chrono::steady_clock::now();
double elapsed_time = chrono::duration<double>(current_time - start_time).count();
if (elapsed_time >= 8.0)
{
motor.write_profile_position(3000, 2000, 0);
break;
}
}
Sleep(8000);
motor.reset();
}

Python:

from motor_control import *
id = [0x01]
port_name = "COM3"
motor = MotorControl(port_name, id, 921600)
mode_selection(motor, PROFILE_POSITION_MODE, 10, 10, 10)

position_pid_set(motor, [0.4], [0])
time.sleep(0.3)
write_profile_position(motor, [3000], [2000], [65535])
current_time = time.time()
while True:
results = get_v_p_c_v(motor)
print(f"ID:{results[0][0]}, 位置环P为0.4 d为0 位置: {results[0][4]}")
if (time.time() - current_time >= 8):
write_profile_position(motor, [3000], [2000], [0])
break

time.sleep(8)

position_pid_set(motor, [1.6], [0])
time.sleep(0.3)
write_profile_position(motor, [3000], [2000], [65535])
current_time = time.time()
while True:
results = get_v_p_c_v(motor)
print(f"ID:{results[0][0]}, 位置环P为1.6 d为0 速度: {results[0][4]}")
if (time.time() - current_time >=8):
write_profile_position(motor, [3000], [2000], [0])
break
time.sleep(8)
reset(motor)