跳到主要内容
版本:最新版本

pid参数的修改方法

无论是电流环、速度环或者位置环,执行器控制芯片的flash中虽然有一个默认的pid值,但是用户在使用的过程中仍然可以实时地对其进行修改,要修改pd值只需要在进入任意一个操作模式后发送对应的报文即可,报文内容请见通讯协议介绍

电流环pi:

顾名思义,电流环pi用于更改电流的调节速率(相同的参数在不同型号的执行器会有不同的情况,这里以TA70-101型号为例),例如:

执行器默认的电流环kp、ki值分别为0.0006、0.0001,此时电流从0增大到1000mA大约需要1.3s,如图:

将kp、ki值分别设为0.02,0.002后,电流从0增大到1000mA大约需要0.2s,如图:

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

速度环pi:

如图为速度环kp、ki值分别为25,0.6时的速度变化曲线

如图为速度环kp、ki值分别为100、2.4时的速度变化曲线

速度环pi用于控制速度调节的能力,当pi值增大时,实际速度超调现象减弱,速度震荡幅度也有所减小,pi值减小时则相反。速度的变化速率则由加(减)速度决定,这两个值也可以实时更改,修改方法与pid值修改方法类似。

位置环pd:

位置环作用于轮廓位置模式,用于控制参考速度的大小,在给定相同的位置差时,kp值越大,则执行器参考速度越大,kd则用于减缓参考速度的变化速率。

如图为kp、kd分别为0.004、0时的速度变化曲线:

如图为kp、kd分别为0.016、0时的速度变化曲线,

SDK:

实时修改电流环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)

实时修改速度环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

实时修改位置环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)