master
45coll 2021-10-13 15:20:52 +08:00
parent 4cd30344f1
commit b30ccef2c0
6 changed files with 110 additions and 40 deletions

View File

@ -51,13 +51,13 @@ PIDController angle_pid = PIDController(PID_P, PID_I, PID_D, balance_voltage * 0
LowPassFilter lpf_throttle{0.00};
#define FLAG_V 1
//倒立摆参数
float LQR_K1 = 600; //摇摆到平衡
float LQR_K2 = 80; //
float LQR_K3 = -0.30; //
float LQR_K1 = 0; //摇摆到平衡
float LQR_K2 = 0; //
float LQR_K3 = 0; //
float LQR_K1_1 = 200; //平衡态
float LQR_K2_1 = 15; //
float LQR_K3_1 = -0.15; //
float LQR_K1_1 = 0; //平衡态
float LQR_K2_1 = 0; //
float LQR_K3_1 = 0; //
//电机参数
@ -67,19 +67,23 @@ BLDCDriver3PWM driver = BLDCDriver3PWM(32, 33, 25, 22);
//命令设置
Command comm;
double target_velocity = 0;
double target_angle = 89.9;
double target_voltage = 0;
void do_K1(char* cmd) { comm.scalar(&LQR_K1, cmd); }
float target_velocity = 0;
float target_angle = 90;
float target_voltage = 0;
void do_K11(char* cmd) { comm.scalar(&LQR_K1, cmd); }
void do_K12(char* cmd) { comm.scalar(&LQR_K2, cmd); }
void do_K13(char* cmd) { comm.scalar(&LQR_K3, cmd); }
void do_K21(char* cmd) { comm.scalar(&LQR_K1_1, cmd); }
void do_K22(char* cmd) { comm.scalar(&LQR_K2_1, cmd); }
void do_K23(char* cmd) { comm.scalar(&LQR_K3_1, cmd); }
void do_TA(char* cmd) { comm.scalar(&target_angle, cmd); }
void onPacketCallBack(AsyncUDPPacket packet)
{
char* da;
da= (char*)(packet.data());
Serial.println(da);
comm.run(da);
Serial.println(LQR_K1);
digitalWrite(22,LOW);
// target_velocity = atoi();
// Serial.print("数据内容: ");
// Serial.println(target_velocity);
@ -90,8 +94,13 @@ void onPacketCallBack(AsyncUDPPacket packet)
void setup() {
Serial.begin(115200);
//命令设置
comm.add("K1",do_K1);
comm.add("K11",do_K11);
comm.add("K12",do_K12);
comm.add("K13",do_K13);
comm.add("K21",do_K21);
comm.add("K22",do_K22);
comm.add("K23",do_K23);
comm.add("TA",do_TA);
// kalman mpu6050 init
Wire.begin(19, 18,400000);// Set I2C frequency to 400kHz
i2cData[0] = 7; // Set the sample rate to 1000Hz - 8kHz/(7+1) = 1000Hz
@ -183,7 +192,7 @@ void setup() {
Serial.println(F("Motor ready."));
Serial.println(F("Set the target velocity using serial terminal:"));
// digitalWrite(22,LOW);
}
char buf[255];
@ -218,12 +227,12 @@ void loop() {
if (gyroZangle < -180 || gyroZangle > 180)
gyroZangle = kalAngleZ;
float pendulum_angle = constrainAngle((fmod(kalAngleZ * 3, 360.0) / 3.0 - target_angle) / 57.29578);
float pendulum_angle = constrainAngle(fmod(kalAngleZ,120)-target_angle);
// float pendulum_angle = constrainAngle((fmod(kalAngleZ * 3, 360.0) / 3.0 - target_angle) / 57.29578);
#if FLAG_V
if (abs(pendulum_angle) < 0.6) // if angle small enough stabilize 0.5~30°,1.5~90°
if (abs(pendulum_angle) < 18) // if angle small enough stabilize 0.5~30°,1.5~90°
{
target_voltage = controllerLQR(angle_pid(pendulum_angle), gyroZrate / 57.29578, motor.shaftVelocity());
target_voltage = controllerLQR(angle_pid(pendulum_angle), gyroZrate, motor.shaftVelocity());
// limit the voltage set to the motor
if (abs(target_voltage) > motor.voltage_limit * 0.7)
target_voltage = _sign(target_voltage) * motor.voltage_limit * 0.7;
@ -240,13 +249,13 @@ void loop() {
}
else
{
motor.move(lpf_throttle(-target_voltage));
motor.move(lpf_throttle(target_voltage));
}
#else
motor.move(0);
#endif
#if 1
#if 0
//Serial.print(gyroZangle);Serial.print("\t");
Serial.print(kalAngleZ);Serial.print("\t");
@ -255,7 +264,7 @@ Serial.print(kalAngleZ);Serial.print("\t");
// Serial.print(target_velocity);Serial.print("\t");
Serial.print(motor.shaft_velocity);Serial.print("\t");
Serial.print(target_angle);Serial.print("\t");
Serial.print(pendulum_angle+target_angle);Serial.print("\t");
Serial.print(pendulum_angle);Serial.print("\t");
Serial.print(gyroZrate);Serial.print("\t");
Serial.print("\r\n");
#endif
@ -264,7 +273,8 @@ Serial.print(kalAngleZ);Serial.print("\t");
if(wifi_flag)
{
memset(buf, 0, strlen(buf));
wifi_print("p",pendulum_angle+target_angle);
wifi_print("v", motor.shaftVelocity());
wifi_print("p",pendulum_angle);
wifi_print("t",target_angle);
wifi_print("k",kalAngleZ);
wifi_print("g",gyroZrate);
@ -295,13 +305,18 @@ double acc2rotation(double x, double y)
return (atan(x / y) / 1.570796 * 90);
}
}
// function constraining the angle in between -pi and pi, in degrees -180 and 180
float constrainAngle(float x)
{
x = fmod(x + M_PI, _2PI);
if (x < 0)
x += _2PI;
return x - M_PI;
float a = 0;
if(x < 0)
{
a = 120+x;
if(a<abs(x))
return a;
}
return x;
}
// LQR stabilization controller functions
// calculating the voltage that needs to be set to the motor in order to stabilize the pendulum
@ -313,7 +328,7 @@ float controllerLQR(float p_angle, float p_vel, float m_vel)
// - k = [40, 7, 0.3]
// - k = [13.3, 21, 0.3]
// - x = [pendulum angle, pendulum velocity, motor velocity]'
if (abs(p_angle) > 0.05)
if (abs(p_angle) > 1.5)
{
last_unstable_time = millis();
stable = 0;
@ -346,6 +361,6 @@ void wifi_print(char * s,double num)
strcpy(str,s);
strcat(str, n);
strcat(buf+strlen(buf), str);
strcat(buf, ",");
strcat(buf, ",\0");
}

View File

@ -28,7 +28,7 @@ class MyWindow(QMainWindow, Ui_MainWindow):
def CreateSignalSlot(self):
self.velocity_horizontalSlider.valueChanged.connect(self.velocity_horizontalSlider_valueChanged)
self.wifi_config_pushButton.clicked.connect(self.wifi_config_pushButton_clicked)
self.wifi_command_pushButton.clicked.connect(self.wifi_command_pushButton_clicked)
# 设置实例
def CreateItems(self):
# 定时器-绘图刷新
@ -79,6 +79,9 @@ class MyWindow(QMainWindow, Ui_MainWindow):
self.velocity_lineEdit.setText(str(self.target_velocity))
self.udp.send_message(str(self.target_velocity))
print(str(self.target_velocity))
# command命令发送事件
def wifi_command_pushButton_clicked(self):
self.udp.send_message(self.wifi_command_lineEdit.text())
def wifi_config_pushButton_clicked(self):
try:
# self.re_item = ['k','g','l','t']
@ -113,11 +116,10 @@ class MyWindow(QMainWindow, Ui_MainWindow):
# print(recv_data)
for i, data in enumerate(recv_data):
self.re_item.append(''.join(re.split(r'[^A-Za-z]', data)))
data = re.findall(r"\d+\.?\d*", data)
# print(i,data)
data = data.replace(self.re_item[i],'')
self.signalDataArrays[i] = np.roll(self.signalDataArrays[i], -1)
self.signalDataArrays[i][-1] = data[0]
self.signalDataArrays[i][-1] = data
pass
def update_plot(self):
if self.wifi_recv_flag:

View File

@ -80,6 +80,21 @@ class Ui_MainWindow(object):
self.tool_layout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget_4)
self.tool_layout.setContentsMargins(0, 0, 0, 0)
self.tool_layout.setObjectName("tool_layout")
self.groupBox_3 = QtWidgets.QGroupBox(self.centralwidget)
self.groupBox_3.setGeometry(QtCore.QRect(10, 20, 291, 111))
self.groupBox_3.setObjectName("groupBox_3")
self.horizontalLayoutWidget_5 = QtWidgets.QWidget(self.groupBox_3)
self.horizontalLayoutWidget_5.setGeometry(QtCore.QRect(10, 20, 271, 31))
self.horizontalLayoutWidget_5.setObjectName("horizontalLayoutWidget_5")
self.horizontalLayout_4 = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget_5)
self.horizontalLayout_4.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout_4.setObjectName("horizontalLayout_4")
self.wifi_command_lineEdit = QtWidgets.QLineEdit(self.horizontalLayoutWidget_5)
self.wifi_command_lineEdit.setObjectName("wifi_command_lineEdit")
self.horizontalLayout_4.addWidget(self.wifi_command_lineEdit)
self.wifi_command_pushButton = QtWidgets.QPushButton(self.horizontalLayoutWidget_5)
self.wifi_command_pushButton.setObjectName("wifi_command_pushButton")
self.horizontalLayout_4.addWidget(self.wifi_command_pushButton)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 1187, 26))
@ -103,3 +118,5 @@ class Ui_MainWindow(object):
self.label_2.setText(_translate("MainWindow", "目标角度:"))
self.angle_lineEdit.setText(_translate("MainWindow", "149"))
self.groupBox_2.setTitle(_translate("MainWindow", "GroupBox"))
self.groupBox_3.setTitle(_translate("MainWindow", "command命令"))
self.wifi_command_pushButton.setText(_translate("MainWindow", "发送"))

View File

@ -168,6 +168,41 @@
<layout class="QHBoxLayout" name="tool_layout"/>
</widget>
</widget>
<widget class="QGroupBox" name="groupBox_3">
<property name="geometry">
<rect>
<x>10</x>
<y>20</y>
<width>291</width>
<height>111</height>
</rect>
</property>
<property name="title">
<string>command命令</string>
</property>
<widget class="QWidget" name="horizontalLayoutWidget_5">
<property name="geometry">
<rect>
<x>10</x>
<y>20</y>
<width>271</width>
<height>31</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLineEdit" name="wifi_command_lineEdit"/>
</item>
<item>
<widget class="QPushButton" name="wifi_command_pushButton">
<property name="text">
<string>发送</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">

View File

@ -1,5 +1,6 @@
a = [1,2]
b = [4,5,6,4]
c = [7,8,9,10]
for i,j,k in zip(a,b,c):
print(i,j,k)
import re
a = 'v0.10'
b =''.join(re.split(r'[^A-Za-z]', a))
print(b)
a = a.replace(b,'')
print(a)

View File

@ -16,7 +16,7 @@ def udp_recv(udp_socket):
recv_data = udp_socket.recv(1024)
recv_data = recv_data.decode('utf-8')
udp_data = recv_data
# print('收到信息为:%s'%recv_data)
print('收到信息为:%s'%recv_data)
def main():
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #创建套接字