lqr好难调啊草

This commit is contained in:
Robofish 2025-10-25 00:17:56 +08:00
parent f87d2a29a6
commit 22e8029853
9 changed files with 166 additions and 190 deletions

View File

@ -784,11 +784,6 @@
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\User\component\ahrs.c</FilePath> <FilePath>..\User\component\ahrs.c</FilePath>
</File> </File>
<File>
<FileName>cmd.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\component\cmd.c</FilePath>
</File>
<File> <File>
<FileName>filter.c</FileName> <FileName>filter.c</FileName>
<FileType>1</FileType> <FileType>1</FileType>
@ -824,6 +819,21 @@
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\User\component\vmc.c</FilePath> <FilePath>..\User\component\vmc.c</FilePath>
</File> </File>
<File>
<FileName>crc8.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\component\crc8.c</FilePath>
</File>
<File>
<FileName>crc16.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\component\crc16.c</FilePath>
</File>
<File>
<FileName>speed_planner.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\component\speed_planner.c</FilePath>
</File>
</Files> </Files>
</Group> </Group>
<Group> <Group>
@ -859,6 +869,31 @@
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\User\device\motor_lz.c</FilePath> <FilePath>..\User\device\motor_lz.c</FilePath>
</File> </File>
<File>
<FileName>ai.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\device\ai.c</FilePath>
</File>
<File>
<FileName>bmi088.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\device\bmi088.c</FilePath>
</File>
<File>
<FileName>motor_dm.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\device\motor_dm.c</FilePath>
</File>
<File>
<FileName>motor_rm.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\device\motor_rm.c</FilePath>
</File>
<File>
<FileName>virtual_chassis.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\device\virtual_chassis.c</FilePath>
</File>
</Files> </Files>
</Group> </Group>
<Group> <Group>
@ -874,6 +909,21 @@
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\User\module\balance_chassis.c</FilePath> <FilePath>..\User\module\balance_chassis.c</FilePath>
</File> </File>
<File>
<FileName>cmd.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\module\cmd.c</FilePath>
</File>
<File>
<FileName>gimbal.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\module\gimbal.c</FilePath>
</File>
<File>
<FileName>shoot.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\module\shoot.c</FilePath>
</File>
</Files> </Files>
</Group> </Group>
<Group> <Group>
@ -919,6 +969,31 @@
<FileType>1</FileType> <FileType>1</FileType>
<FilePath>..\User\task\ctrl_gimbal.c</FilePath> <FilePath>..\User\task\ctrl_gimbal.c</FilePath>
</File> </File>
<File>
<FileName>ai.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\task\ai.c</FilePath>
</File>
<File>
<FileName>cmd.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\task\cmd.c</FilePath>
</File>
<File>
<FileName>ctrl_shoot.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\task\ctrl_shoot.c</FilePath>
</File>
<File>
<FileName>monitor.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\task\monitor.c</FilePath>
</File>
<File>
<FileName>music.c</FileName>
<FileType>1</FileType>
<FilePath>..\User\task\music.c</FilePath>
</File>
</Files> </Files>
</Group> </Group>
<Group> <Group>

View File

@ -70,7 +70,6 @@
".\devc\time.o" ".\devc\time.o"
".\devc\uart.o" ".\devc\uart.o"
".\devc\ahrs.o" ".\devc\ahrs.o"
".\devc\cmd.o"
".\devc\filter.o" ".\devc\filter.o"
".\devc\limiter.o" ".\devc\limiter.o"
".\devc\pid.o" ".\devc\pid.o"
@ -78,14 +77,25 @@
".\devc\kinematics.o" ".\devc\kinematics.o"
".\devc\lqr.o" ".\devc\lqr.o"
".\devc\vmc.o" ".\devc\vmc.o"
".\devc\crc8.o"
".\devc\crc16.o"
".\devc\speed_planner.o"
".\devc\buzzer.o" ".\devc\buzzer.o"
".\devc\dm_imu.o" ".\devc\dm_imu.o"
".\devc\dr16.o" ".\devc\dr16.o"
".\devc\motor.o" ".\devc\motor.o"
".\devc\motor_lk.o" ".\devc\motor_lk.o"
".\devc\motor_lz.o" ".\devc\motor_lz.o"
".\devc\ai.o"
".\devc\bmi088.o"
".\devc\motor_dm.o"
".\devc\motor_rm.o"
".\devc\virtual_chassis.o"
".\devc\config.o" ".\devc\config.o"
".\devc\balance_chassis.o" ".\devc\balance_chassis.o"
".\devc\cmd_1.o"
".\devc\gimbal.o"
".\devc\shoot.o"
".\devc\blink.o" ".\devc\blink.o"
".\devc\init.o" ".\devc\init.o"
".\devc\rc.o" ".\devc\rc.o"
@ -93,6 +103,11 @@
".\devc\atti_esti.o" ".\devc\atti_esti.o"
".\devc\ctrl_chassis.o" ".\devc\ctrl_chassis.o"
".\devc\ctrl_gimbal.o" ".\devc\ctrl_gimbal.o"
".\devc\ai_1.o"
".\devc\cmd_1.o"
".\devc\ctrl_shoot.o"
".\devc\monitor.o"
".\devc\music.o"
--strict --scatter ".\DevC\DevC.sct" --strict --scatter ".\DevC\DevC.sct"
--summary_stderr --info summarysizes --map --load_addr_map_info --xref --callgraph --symbols --summary_stderr --info summarysizes --map --load_addr_map_info --xref --callgraph --symbols
--info sizes --info totals --info unused --info veneers --info sizes --info totals --info unused --info veneers

View File

@ -4,7 +4,6 @@
#pragma once #pragma once
#include <sys/cdefs.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif

View File

@ -42,19 +42,6 @@ static int8_t Chassis_SetMode(Chassis_t *c, Chassis_Mode_t mode) {
if (mode == c->mode) if (mode == c->mode)
return CHASSIS_OK; /* 模式未改变直接返回 */ return CHASSIS_OK; /* 模式未改变直接返回 */
// 特殊处理从JUMP切换到WHELL_LEG_BALANCE时不重置
// 但从WHELL_LEG_BALANCE切换到JUMP时需要重置以触发新的跳跃
if (c->mode == CHASSIS_MODE_JUMP && mode == CHASSIS_MODE_WHELL_LEG_BALANCE) {
c->mode = mode;
return CHASSIS_OK;
}
if (c->mode == CHASSIS_MODE_WHELL_LEG_BALANCE && mode == CHASSIS_MODE_JUMP) {
c->mode = mode;
c->state = 0; // 重置状态,确保每次切换模式时都重新初始化
c->jump_time=0; // 重置跳跃时间切换到JUMP模式时会触发新跳跃
return CHASSIS_OK;
}
Chassis_MotorEnable(c); Chassis_MotorEnable(c);
PID_Reset(&c->pid.leg_length[0]); PID_Reset(&c->pid.leg_length[0]);
@ -101,8 +88,6 @@ static int8_t Chassis_SetMode(Chassis_t *c, Chassis_Mode_t mode) {
LowPassFilter2p_Reset(&c->filter.wheel_out[1], 0.0f); LowPassFilter2p_Reset(&c->filter.wheel_out[1], 0.0f);
c->mode = mode; c->mode = mode;
c->state = 0; // 重置状态,确保每次切换模式时都重新初始化
c->jump_time=0; // 重置跳跃时间切换到JUMP模式时会触发新跳跃
c->wz_multi=0.0f; c->wz_multi=0.0f;
return CHASSIS_OK; return CHASSIS_OK;
@ -132,12 +117,9 @@ static void Chassis_UpdateChassisState(Chassis_t *c) {
c->chassis_state.velocity_x = c->chassis_state.velocity_x =
(left_wheel_linear_vel + right_wheel_linear_vel) / 2.0f; (left_wheel_linear_vel + right_wheel_linear_vel) / 2.0f;
// 在跳跃模式的起跳和收腿阶段暂停位移积分,避免轮子空转导致的位移误差
if (!(c->mode == CHASSIS_MODE_JUMP && (c->state == 2 || c->state == 3))) {
// 积分得到位置 // 积分得到位置
c->chassis_state.position_x += c->chassis_state.velocity_x * c->dt; c->chassis_state.position_x += c->chassis_state.velocity_x * c->dt;
} }
}
@ -289,45 +271,6 @@ int8_t Chassis_Control(Chassis_t *c, const Chassis_CMD_t *c_cmd) {
Chassis_Output(c); // 统一输出 Chassis_Output(c); // 统一输出
} break; } break;
case CHASSIS_MODE_JUMP:
// 跳跃模式状态机
// 状态转换: 0(准备)->1(0.3s)->2(0.2s)->3(0.3s)->0(完成)
// jump_time == 0: 未开始跳跃
// jump_time == 1: 已完成跳跃(不再触发)
// jump_time > 1: 跳跃进行中
// 检测是否需要开始新的跳跃state为0且jump_time为0
if (c->state == 0 && c->jump_time == 0) {
// 开始跳跃进入state 1
c->state = 1;
c->jump_time = BSP_TIME_Get_us();
}
// 只有在跳跃进行中时才处理状态转换jump_time > 1
if (c->jump_time > 1) {
// 计算已经过的时间(微秒)
uint64_t elapsed_us = BSP_TIME_Get_us() - c->jump_time;
// 状态转换逻辑
if (c->state == 1 && elapsed_us >= 300000) {
// state 1 保持0.3s后转到state 2
c->state = 2;
c->jump_time = BSP_TIME_Get_us(); // 重置计时
} else if (c->state == 2 && elapsed_us >= 230000) {
// state 2 保持0.25s后转到state 3确保腿部充分伸展
c->state = 3;
c->jump_time = BSP_TIME_Get_us(); // 重置计时
} else if (c->state == 3 && elapsed_us >= 500000) {
// state 3 保持0.4s后转到state 0确保收腿到最高
c->state = 0;
c->jump_time = 1; // 设置为1表示已完成跳跃不再触发
}
}
// 执行LQR控制包含PID腿长控制
Chassis_LQRControl(c, c_cmd);
Chassis_Output(c); // 统一输出
break;
case CHASSIS_MODE_WHELL_LEG_BALANCE: case CHASSIS_MODE_WHELL_LEG_BALANCE:
case CHASSIS_MODE_ROTOR: case CHASSIS_MODE_ROTOR:
@ -431,17 +374,11 @@ int8_t Chassis_LQRControl(Chassis_t *c, const Chassis_CMD_t *c_cmd) {
/* 构建目标状态 */ /* 构建目标状态 */
LQR_State_t target_state = {0}; LQR_State_t target_state = {0};
// 在跳跃收腿阶段强制摆角目标为0确保落地时腿部竖直 target_state.theta = 0.0f; // 目标摆杆角度
if (c->mode == CHASSIS_MODE_JUMP && c->state == 3) {
target_state.theta = 0.0f; // 强制摆杆角度为0确保腿部竖直
} else {
target_state.theta = 0.00; // 目标摆杆角度
}
target_state.d_theta = 0.0f; // 目标摆杆角速度 target_state.d_theta = 0.0f; // 目标摆杆角速度
target_state.phi = 11.9601*pow((0.16f + c_cmd->height * 0.25f),3) + -11.8715*pow((0.16f + c_cmd->height * 0.25f),2) + 3.87083*(0.16f + c_cmd->height * 0.25f) + -0.4154; // 目标俯仰角 target_state.phi = 0.0f; // 目标俯仰角
target_state.d_phi = 0.0f; // 目标俯仰角速度 target_state.d_phi = 0.0f; // 目标俯仰角速度
target_state.x = c->chassis_state.target_x -2.07411f*(0.16f + c_cmd->height * 0.25f) + 0.41182f; target_state.x = c->chassis_state.target_x;
target_state.d_x = target_dot_x; // 目标速度 target_state.d_x = target_dot_x; // 目标速度
if (c->mode != CHASSIS_MODE_ROTOR){ if (c->mode != CHASSIS_MODE_ROTOR){
@ -494,13 +431,11 @@ int8_t Chassis_LQRControl(Chassis_t *c, const Chassis_CMD_t *c_cmd) {
LQR_SetTargetState(&c->lqr[0], &target_state); LQR_SetTargetState(&c->lqr[0], &target_state);
LQR_Control(&c->lqr[0]); LQR_Control(&c->lqr[0]);
} else { } else {
// 在跳跃收腿阶段强制摆角目标为0其他情况为0.16f target_state.theta = 0.16f; // 非接触时的腿摆角目标
float non_contact_theta = (c->mode == CHASSIS_MODE_JUMP && c->state == 3) ? 0.0f : 0.16f;
target_state.theta = non_contact_theta; // 非接触时的腿摆角目标
LQR_SetTargetState(&c->lqr[0], &target_state); LQR_SetTargetState(&c->lqr[0], &target_state);
c->lqr[0].control_output.T = 0.0f; c->lqr[0].control_output.T = 0.0f;
c->lqr[0].control_output.Tp = c->lqr[0].control_output.Tp =
c->lqr[0].K_matrix[1][0] * (-c->vmc_[0].leg.theta + non_contact_theta) + c->lqr[0].K_matrix[1][0] * (-c->vmc_[0].leg.theta + 0.16f) +
c->lqr[0].K_matrix[1][1] * (-c->vmc_[0].leg.d_theta + 0.0f); c->lqr[0].K_matrix[1][1] * (-c->vmc_[0].leg.d_theta + 0.0f);
c->yaw_control.yaw_force = 0.0f; // 单腿离地时关闭偏航控制 c->yaw_control.yaw_force = 0.0f; // 单腿离地时关闭偏航控制
} }
@ -508,28 +443,20 @@ int8_t Chassis_LQRControl(Chassis_t *c, const Chassis_CMD_t *c_cmd) {
LQR_SetTargetState(&c->lqr[1], &target_state); LQR_SetTargetState(&c->lqr[1], &target_state);
LQR_Control(&c->lqr[1]); LQR_Control(&c->lqr[1]);
}else { }else {
// 在跳跃收腿阶段强制摆角目标为0其他情况为0.16f target_state.theta = 0.16f; // 非接触时的腿摆角目标
float non_contact_theta = (c->mode == CHASSIS_MODE_JUMP && c->state == 3) ? 0.0f : 0.16f;
target_state.theta = non_contact_theta; // 非接触时的腿摆角目标
LQR_SetTargetState(&c->lqr[1], &target_state); LQR_SetTargetState(&c->lqr[1], &target_state);
c->lqr[1].control_output.T = 0.0f; c->lqr[1].control_output.T = 0.0f;
c->lqr[1].control_output.Tp = c->lqr[1].control_output.Tp =
c->lqr[1].K_matrix[1][0] * (-c->vmc_[1].leg.theta + non_contact_theta) + c->lqr[1].K_matrix[1][0] * (-c->vmc_[1].leg.theta + 0.16f) +
c->lqr[1].K_matrix[1][1] * (-c->vmc_[1].leg.d_theta + 0.0f); c->lqr[1].K_matrix[1][1] * (-c->vmc_[1].leg.d_theta + 0.0f);
c->yaw_control.yaw_force = 0.0f; // 单腿离地时关闭偏航控制 c->yaw_control.yaw_force = 0.0f; // 单腿离地时关闭偏航控制
} }
/* 轮毂力矩输出参考C++版本的减速比) */ /* 轮毂力矩输出参考C++版本的减速比) */
// 在跳跃的起跳和收腿阶段强制关闭轮子输出,防止离地时轮子猛转
if (c->mode == CHASSIS_MODE_JUMP && (c->state == 2 || c->state == 3)) {
c->output.wheel[0] = 0.0f;
c->output.wheel[1] = 0.0f;
} else {
c->output.wheel[0] = c->output.wheel[0] =
c->lqr[0].control_output.T / 4.5f + c->yaw_control.yaw_force; c->lqr[0].control_output.T / 4.5f + c->yaw_control.yaw_force;
c->output.wheel[1] = c->output.wheel[1] =
c->lqr[1].control_output.T / 4.5f - c->yaw_control.yaw_force; c->lqr[1].control_output.T / 4.5f - c->yaw_control.yaw_force;
}
/* 腿长控制和VMC逆解算使用PID控制 */ /* 腿长控制和VMC逆解算使用PID控制 */
float virtual_force[2]; float virtual_force[2];
float target_L0[2]; float target_L0[2];
@ -556,39 +483,12 @@ int8_t Chassis_LQRControl(Chassis_t *c, const Chassis_CMD_t *c_cmd) {
} }
// 目标腿长设定(包含横滚角补偿) // 目标腿长设定(包含横滚角补偿)
switch (c->state) {
case 0: // 正常状态,根据高度指令调节腿长
target_L0[0] = 0.16f + c_cmd->height * 0.22f + roll_compensation_length; // 左腿:基础腿长 + 高度调节 + 横滚补偿 target_L0[0] = 0.16f + c_cmd->height * 0.22f + roll_compensation_length; // 左腿:基础腿长 + 高度调节 + 横滚补偿
target_L0[1] = 0.16f + c_cmd->height * 0.22f - roll_compensation_length; // 右腿:基础腿长 + 高度调节 - 横滚补偿 target_L0[1] = 0.16f + c_cmd->height * 0.22f - roll_compensation_length; // 右腿:基础腿长 + 高度调节 - 横滚补偿
break;
case 1: // 准备阶段,腿长收缩
target_L0[0] = 0.14f + roll_compensation_length; // 左腿:收缩到较短腿长 + 横滚补偿
target_L0[1] = 0.14f - roll_compensation_length; // 右腿:收缩到较短腿长 - 横滚补偿
break;
case 2: // 起跳阶段,腿长快速伸展
target_L0[0] = 0.65f; // 左腿:伸展到最大腿长(跳跃时不进行横滚补偿)
target_L0[1] = 0.65f; // 右腿:伸展到最大腿长(跳跃时不进行横滚补偿)
break;
case 3: // 收腿阶段,腿长收缩到最高
target_L0[0] = 0.06f; // 左腿:收缩到最短腿长(确保收腿到最高)
target_L0[1] = 0.06f; // 右腿:收缩到最短腿长(确保收腿到最高)
break;
default:
target_L0[0] = 0.16f + c_cmd->height * 0.22f + roll_compensation_length;
target_L0[1] = 0.16f + c_cmd->height * 0.22f - roll_compensation_length;
break;
}
// 腿长限幅:根据跳跃状态调整限制范围 // 腿长限幅最短0.10最长0.42m
if (c->mode == CHASSIS_MODE_JUMP && c->state == 3) {
// 在跳跃收腿阶段,允许更短的腿长,确保收腿到最高
if (target_L0[0] < 0.06f) target_L0[0] = 0.06f;
if (target_L0[1] < 0.06f) target_L0[1] = 0.06f;
} else {
// 正常情况下的腿长限制最短0.10最长0.42m
if (target_L0[0] < 0.10f) target_L0[0] = 0.10f; if (target_L0[0] < 0.10f) target_L0[0] = 0.10f;
if (target_L0[1] < 0.10f) target_L0[1] = 0.10f; if (target_L0[1] < 0.10f) target_L0[1] = 0.10f;
}
if (target_L0[0] > 0.42f) target_L0[0] = 0.42f; if (target_L0[0] > 0.42f) target_L0[0] = 0.42f;
if (target_L0[1] > 0.42f) target_L0[1] = 0.42f; if (target_L0[1] > 0.42f) target_L0[1] = 0.42f;

View File

@ -40,17 +40,9 @@ typedef enum {
CHASSIS_MODE_RELAX, /* 放松模式,电机不输出。一般情况底盘初始化之后的模式 */ CHASSIS_MODE_RELAX, /* 放松模式,电机不输出。一般情况底盘初始化之后的模式 */
CHASSIS_MODE_RECOVER, /* 复位模式 */ CHASSIS_MODE_RECOVER, /* 复位模式 */
CHASSIS_MODE_WHELL_LEG_BALANCE, /* 轮子+腿平衡模式,底盘自我平衡 */ CHASSIS_MODE_WHELL_LEG_BALANCE, /* 轮子+腿平衡模式,底盘自我平衡 */
CHASSIS_MODE_JUMP, /* 跳跃模式,底盘跳跃 */
CHASSIS_MODE_ROTOR, /* 小陀螺模式,底盘高速旋转 */ CHASSIS_MODE_ROTOR, /* 小陀螺模式,底盘高速旋转 */
} Chassis_Mode_t; } Chassis_Mode_t;
typedef enum {
CHASSIS_JUMP_STATE_READY, /* 准备跳跃 */
CHASSIS_JUMP_STATE_JUMPING, /* 跳跃中 */
CHASSIS_JUMP_STATE_LANDING, /* 着陆中 */
CHASSIS_JUMP_STATE_END, /* 跳跃结束 */
} Chassis_JumpState_t;
typedef struct { typedef struct {
Chassis_Mode_t mode; /* 底盘模式 */ Chassis_Mode_t mode; /* 底盘模式 */
MoveVector_t move_vec; /* 底盘运动向量 */ MoveVector_t move_vec; /* 底盘运动向量 */
@ -125,10 +117,6 @@ typedef struct {
VMC_t vmc_[2]; /* 两条腿的VMC */ VMC_t vmc_[2]; /* 两条腿的VMC */
LQR_t lqr[2]; /* 两条腿的LQR控制器 */ LQR_t lqr[2]; /* 两条腿的LQR控制器 */
int8_t state;
uint64_t jump_time;
float angle; float angle;
float height; float height;

View File

@ -254,20 +254,19 @@ Config_RobotParam_t robot_config = {
} }
}, },
.lqr_gains = { .lqr_gains = {
.k11_coeff = { -2.299492214443364e+02f, 2.371048664025156e+02f, -1.091592921067477e+02f, -5.004256900558796e+00f }, // theta .k11_coeff = { -2.156343028411120e+02f, 2.257665290023013e+02f, -1.002267208978328e+02f, -2.350184261149268e+00f }, // theta
.k12_coeff = { -5.160496889728024e+00f, 3.062519293243873e+00f, -9.339456933350174e+00f, -4.793280770575950e-01f }, // d_theta .k12_coeff = { -7.743056249446016e+00f, 6.752493325294916e+00f, -8.796808854152014e+00f, -3.119669283951065e-01f }, // d_theta
.k13_coeff = { -5.187383520564029e+01f, 4.899697460241380e+01f, -1.565478588426995e+01f, -2.004694192093775e+00f }, // x .k13_coeff = { -1.118487386616928e+02f, 1.102429207742772e+02f, -3.732715045746770e+01f, -7.925992877328480e-01f }, // x
.k14_coeff = { -5.668796498905875e+01f, 5.377351750824888e+01f, -1.871718521370502e+01f, -2.691170008421150e+00f }, // d_x .k14_coeff = { -6.940658312417929e+01f, 6.823355321869006e+01f, -2.465299412907610e+01f, -1.060847118860617e+00f }, // d_x
.k15_coeff = { -1.449457451875909e+02f, 1.491544007677516e+02f, -5.400783326406858e+01f, 7.212250094701016e+00f }, // phi .k15_coeff = { -4.583141861746078e+01f, 5.818701324121601e+01f, -2.683216623272723e+01f, 4.507357792784873e+00f }, // phi
.k16_coeff = { -9.623232912225313e+01f, 1.012699482439727e+02f, -3.862842162301360e+01f, 6.174165209610019e+00f }, // d_phi .k16_coeff = { -1.544882596273596e+01f, 1.975202028975679e+01f, -9.521615432406449e+00f, 1.862826936219259e+00f }, // d_phi
.k21_coeff = { -1.197720213257983e+02f, 1.432558800683586e+02f, -6.332976803783767e+01f, 1.244403075562354e+01f }, // theta .k21_coeff = { 9.252532546470242e+00f, 4.417889614536075e+01f, -4.710921937977012e+01f, 1.516691345722052e+01f }, // theta
.k22_coeff = { -1.641975451035667e+01f, 1.816373049685376e+01f, -6.825602612420409e+00f, 1.759808519224317e+00f }, // d_theta .k22_coeff = { -1.018276949440906e+00f, 6.140925452791167e+00f, -4.973407169060023e+00f, 2.141324584243587e+00f }, // d_theta
.k23_coeff = { -9.525505626411980e+01f, 9.986545276773818e+01f, -3.780741158172127e+01f, 6.150010121224194e+00f }, // x .k23_coeff = { -1.020910325776861e+02f, 1.292784950839223e+02f, -6.114289602021928e+01f, 1.251012410414232e+01f }, // x
.k24_coeff = { -1.249520841685426e+02f, 1.297949868891588e+02f, -4.847618771898694e+01f, 7.842551207050604e+00f }, // d_x .k24_coeff = { -1.009199238331894e+02f, 1.180052040402144e+02f, -5.140001160311314e+01f, 9.859995261307304e+00f }, // d_x
.k25_coeff = { 1.098971996183004e+02f, -1.028972351169783e+02f, 3.234322461758097e+01f, 1.250515887186789e+01f }, // phi .k25_coeff = { 9.176820525459368e+01f, -9.170665517126247e+01f, 3.124569590587187e+01f, 6.886312255252024e+00f }, // phi
.k26_coeff = { 1.122150774085550e+02f, -1.059683417765082e+02f, 3.379315768085248e+01f, 5.474171975795353e+00f }, // d_phi .k26_coeff = { 4.772624933352569e+01f, -4.722944757834970e+01f, 1.599553913425377e+01f, 1.037598895224650e+00f }, // d_phi
}, },
.theta = 0.0f, .theta = 0.0f,
.x = 0.0f, .x = 0.0f,

View File

@ -56,41 +56,41 @@ fprintf('},\n');
fprintf('========================================\n\n'); fprintf('========================================\n\n');
% 线 % 线
x0=leg; %0.1 % x0=leg; %0.1
y11=polyval(a11,x0); %y0x0 % y11=polyval(a11,x0); %y0x0
y12=polyval(a12,x0); %y0x0 % y12=polyval(a12,x0); %y0x0
y13=polyval(a13,x0); %y0x0 % y13=polyval(a13,x0); %y0x0
y14=polyval(a14,x0); %y0x0 % y14=polyval(a14,x0); %y0x0
y15=polyval(a15,x0); %y0x0 % y15=polyval(a15,x0); %y0x0
y16=polyval(a16,x0); %y0x0 % y16=polyval(a16,x0); %y0x0
%
y21=polyval(a21,x0); %y0x0 % y21=polyval(a21,x0); %y0x0
y22=polyval(a22,x0); %y0x0 % y22=polyval(a22,x0); %y0x0
y23=polyval(a23,x0); %y0x0 % y23=polyval(a23,x0); %y0x0
y24=polyval(a24,x0); %y0x0 % y24=polyval(a24,x0); %y0x0
y25=polyval(a25,x0); %y0x0 % y25=polyval(a25,x0); %y0x0
y26=polyval(a26,x0); %y0x0 % y26=polyval(a26,x0); %y0x0
%
figure; % figure;
subplot(3,4,1);plot(leg,k11,'o',x0,y11,'r');xlabel('leg length');ylabel('k11');title('k11'); % subplot(3,4,1);plot(leg,k11,'o',x0,y11,'r');xlabel('leg length');ylabel('k11');title('k11');
subplot(3,4,2);plot(leg,k12,'o',x0,y12,'r');xlabel('leg length');ylabel('k12');title('k12'); % subplot(3,4,2);plot(leg,k12,'o',x0,y12,'r');xlabel('leg length');ylabel('k12');title('k12');
subplot(3,4,3);plot(leg,k13,'o',x0,y13,'r');xlabel('leg length');ylabel('k13');title('k13'); % subplot(3,4,3);plot(leg,k13,'o',x0,y13,'r');xlabel('leg length');ylabel('k13');title('k13');
subplot(3,4,4);plot(leg,k14,'o',x0,y14,'r');xlabel('leg length');ylabel('k14');title('k14'); % subplot(3,4,4);plot(leg,k14,'o',x0,y14,'r');xlabel('leg length');ylabel('k14');title('k14');
subplot(3,4,5);plot(leg,k15,'o',x0,y15,'r');xlabel('leg length');ylabel('k15');title('k15'); % subplot(3,4,5);plot(leg,k15,'o',x0,y15,'r');xlabel('leg length');ylabel('k15');title('k15');
subplot(3,4,6);plot(leg,k16,'o',x0,y16,'r');xlabel('leg length');ylabel('k16');title('k16'); % subplot(3,4,6);plot(leg,k16,'o',x0,y16,'r');xlabel('leg length');ylabel('k16');title('k16');
%
subplot(3,4,7);plot(leg,k21,'o',x0,y21,'r');xlabel('leg length');ylabel('k21');title('k21'); % subplot(3,4,7);plot(leg,k21,'o',x0,y21,'r');xlabel('leg length');ylabel('k21');title('k21');
subplot(3,4,8);plot(leg,k22,'o',x0,y22,'r');xlabel('leg length');ylabel('k22');title('k22'); % subplot(3,4,8);plot(leg,k22,'o',x0,y22,'r');xlabel('leg length');ylabel('k22');title('k22');
subplot(3,4,9);plot(leg,k23,'o',x0,y23,'r');xlabel('leg length');ylabel('k23');title('k23'); % subplot(3,4,9);plot(leg,k23,'o',x0,y23,'r');xlabel('leg length');ylabel('k23');title('k23');
subplot(3,4,10);plot(leg,k24,'o',x0,y24,'r');xlabel('leg length');ylabel('k24');title('k24'); % subplot(3,4,10);plot(leg,k24,'o',x0,y24,'r');xlabel('leg length');ylabel('k24');title('k24');
subplot(3,4,11);plot(leg,k25,'o',x0,y25,'r');xlabel('leg length');ylabel('k25');title('k25'); % subplot(3,4,11);plot(leg,k25,'o',x0,y25,'r');xlabel('leg length');ylabel('k25');title('k25');
subplot(3,4,12);plot(leg,k26,'o',x0,y26,'r');xlabel('leg length');ylabel('k26');title('k26'); % subplot(3,4,12);plot(leg,k26,'o',x0,y26,'r');xlabel('leg length');ylabel('k26');title('k26');
%
for i = 1:12 % for i = 1:12
subplot(3,4,i); % subplot(3,4,i);
grid on; %线 % grid on; %线
set(gca,'GridLineStyle',':','GridColor','k','GridAlpha',0.5); %线线 % set(gca,'GridLineStyle',':','GridColor','k','GridAlpha',0.5); %线线
legend('','线','Location','best'); % legend('','线','Location','best');
end % end
toc toc

View File

@ -20,7 +20,7 @@ function K = get_k_length(leg_length)
l1=-0.03; % l1=-0.03; %
mw1=0.60; % mw1=0.60; %
mp1=1.8; % mp1=1.8; %
M1=8.0; % M1=6.0; %
Iw1=mw1*R1^2; % Iw1=mw1*R1^2; %
Ip1=mp1*((L1+LM1)^2+0.05^2)/12.0; % Ip1=mp1*((L1+LM1)^2+0.05^2)/12.0; %
IM1=M1*(0.3^2+0.12^2)/12.0; % IM1=M1*(0.3^2+0.12^2)/12.0; %
@ -48,8 +48,8 @@ function K = get_k_length(leg_length)
B=subs(B,[R,L,LM,l,mw,mp,M,Iw,Ip,IM,g],[R1,L1,LM1,l1,mw1,mp1,M1,Iw1,Ip1,IM1,9.8]); B=subs(B,[R,L,LM,l,mw,mp,M,Iw,Ip,IM,g],[R1,L1,LM1,l1,mw1,mp1,M1,Iw1,Ip1,IM1,9.8]);
B=double(B); B=double(B);
Q=diag([160 160 2000 1500 20000 5000]);%theta d_theta x d_x phi d_phi%700 1 600 200 1000 1 Q=diag([700 150 4000 200 6000 300]);%theta d_theta x d_x phi d_phi%700 1 600 200 1000 1
R=[140 0;0 60]; %T Tp R=[140 0;0 40]; %T Tp
K=lqr(A,B,Q,R); K=lqr(A,B,Q,R);