差一个电机

This commit is contained in:
Robofish 2025-08-31 22:25:15 +08:00
parent e75094a41d
commit 9574929545
13 changed files with 217 additions and 115 deletions

View File

@ -76,9 +76,16 @@ static int8_t MOTOR_LK_CreateCANManager(BSP_CAN_t can) {
}
static void MOTOR_LK_Decode(MOTOR_LK_t *motor, BSP_CAN_Message_t *msg) {
// 调试信息:打印接收到的数据
// printf("LK Motor ID:%d, CMD:0x%02X, Data: %02X %02X %02X %02X %02X %02X %02X %02X\n",
// motor->param.id, msg->data[0], msg->data[0], msg->data[1], msg->data[2],
// msg->data[3], msg->data[4], msg->data[5], msg->data[6], msg->data[7]);
// 检查命令字节是否为反馈命令
if (msg->data[0] != LK_CMD_FEEDBACK) {
return;
// 如果不是标准反馈命令,可能是其他格式的数据
// 临时跳过命令字节检查,直接解析数据
// return;
}
// 解析温度 (DATA[1])
@ -138,8 +145,9 @@ int8_t MOTOR_LK_Register(MOTOR_LK_Param_t *param) {
memset(&new_motor->motor, 0, sizeof(MOTOR_t));
new_motor->motor.reverse = param->reverse;
// 计算反馈ID假设为控制ID + 0x40
uint16_t feedback_id = param->id + 0x40;
// 对于某些LK电机反馈数据可能通过命令ID发送
// 根据实际测试使用命令ID接收反馈数据
uint16_t feedback_id = 0x140 + param->id; // 使用命令ID作为反馈ID
// 注册CAN接收ID
if (BSP_CAN_RegisterId(param->can, feedback_id, 3) != BSP_OK) {
@ -161,8 +169,8 @@ int8_t MOTOR_LK_Update(MOTOR_LK_Param_t *param) {
for (int i = 0; i < manager->motor_count; i++) {
MOTOR_LK_t *motor = manager->motors[i];
if (motor && motor->param.id == param->id) {
// 计算反馈ID
uint16_t feedback_id = param->id + 0x100;
// 对于某些LK电机反馈数据通过命令ID发送
uint16_t feedback_id = 0x140 + param->id;
BSP_CAN_Message_t rx_msg;
if (BSP_CAN_GetMessage(param->can, feedback_id, &rx_msg, BSP_CAN_TIMEOUT_IMMEDIATE) != BSP_OK) {
@ -217,9 +225,9 @@ int8_t MOTOR_LK_SetOutput(MOTOR_LK_Param_t *param, float value) {
// 转矩闭环控制命令 - 将输出值转换为转矩控制值
int16_t torque_control = (int16_t)(value * (float)LK_TORQUE_RANGE);
// 构建CAN帧
// 构建CAN帧(根据协议:命令报文标识符 = 0x140 + ID
BSP_CAN_StdDataFrame_t tx_frame;
tx_frame.id = param->id;
tx_frame.id = 0x140 + param->id;
tx_frame.dlc = MOTOR_TX_BUF_SIZE;
// 设置转矩闭环控制命令数据
@ -245,7 +253,7 @@ int8_t MOTOR_LK_MotorOn(MOTOR_LK_Param_t *param) {
if (param == NULL) return DEVICE_ERR_NULL;
BSP_CAN_StdDataFrame_t tx_frame;
tx_frame.id = param->id;
tx_frame.id = 0x140 + param->id;
tx_frame.dlc = MOTOR_TX_BUF_SIZE;
// 电机运行命令
@ -265,7 +273,7 @@ int8_t MOTOR_LK_MotorOff(MOTOR_LK_Param_t *param) {
if (param == NULL) return DEVICE_ERR_NULL;
BSP_CAN_StdDataFrame_t tx_frame;
tx_frame.id = param->id;
tx_frame.id = 0x140 + param->id;
tx_frame.dlc = MOTOR_TX_BUF_SIZE;
// 电机关闭命令
@ -297,7 +305,7 @@ MOTOR_LK_t* MOTOR_LK_GetMotor(MOTOR_LK_Param_t *param) {
}
int8_t MOTOR_LK_Relax(MOTOR_LK_Param_t *param) {
return MOTOR_LK_SetOutput(param, 0.0f);
return MOTOR_LK_SetOutput(param, 0.01f);
}
int8_t MOTOR_LK_Offine(MOTOR_LK_Param_t *param) {

View File

@ -36,7 +36,7 @@
MOTOR_LZ_MotionParam_t lz_recover_param = {
.target_angle = 0.0f,
.target_velocity = 0.0f,
.kp = 10.0f,
.kp = 5.0f,
.kd = 1.0f,
.torque = 0.0f,
};

View File

@ -4,16 +4,15 @@
#include <math.h>
static int8_t Chassis_SetMode(Chassis_t *c, Chassis_Mode_t mode, Chassis_Action_t action) {
static int8_t Chassis_SetMode(Chassis_t *c, Chassis_Mode_t mode) {
if (c == NULL) return CHASSIS_ERR_NULL; /* 主结构体不能为空 */
if (mode == c->mode && action == c->action) return CHASSIS_OK; /* 模式未改变直接返回 */
if (mode == c->mode) return CHASSIS_OK; /* 模式未改变直接返回 */
PID_Reset(&c->pid.left_wheel);
PID_Reset(&c->pid.right_wheel);
PID_Reset(&c->pid.follow);
PID_Reset(&c->pid.balance);
c->mode = mode;
c->action = action;
c->state = 0;
return CHASSIS_OK;
@ -54,9 +53,8 @@ int8_t Chassis_UpdateFeedback(Chassis_t *c){
for (int i = 0; i < 4; i++) {
MOTOR_LZ_Update(&c->param->joint_motors[i]);
}
for (int i = 0; i < 2; i++) {
MOTOR_LK_Update(&c->param->wheel_motors[i]);
}
MOTOR_LK_Update(&c->param->wheel_motors[0]);
MOTOR_LK_Update(&c->param->wheel_motors[1]);
/*将电机反馈数据赋值到标准反馈结构体,并检查是否离线*/
// 更新关节电机反馈并检查离线状态
@ -64,13 +62,7 @@ int8_t Chassis_UpdateFeedback(Chassis_t *c){
MOTOR_LZ_t *joint_motor = MOTOR_LZ_GetMotor(&c->param->joint_motors[i]);
if (joint_motor != NULL) {
c->feedback.joint[i] = joint_motor->motor.feedback;
// 检查关节电机是否离线
if (!joint_motor->motor.header.online) {
return CHASSIS_ERR; // 有关节电机离线,返回错误
}
} else {
return CHASSIS_ERR; // 无法获取关节电机实例,返回错误
}
}
}
// 更新轮子电机反馈并检查离线状态
@ -78,25 +70,16 @@ int8_t Chassis_UpdateFeedback(Chassis_t *c){
MOTOR_LK_t *wheel_motor = MOTOR_LK_GetMotor(&c->param->wheel_motors[i]);
if (wheel_motor != NULL) {
c->feedback.wheel[i] = wheel_motor->motor.feedback;
// 检查轮子电机是否离线
if (!wheel_motor->motor.header.online) {
return CHASSIS_ERR; // 有轮子电机离线,返回错误
}
} else {
return CHASSIS_ERR; // 无法获取轮子电机实例,返回错误
}
}
return 0;
}
int8_t Chassis_UpdateIMU(Chassis_t *c, const AHRS_Eulr_t *euler, const AHRS_Gyro_t *gyro, const AHRS_Accl_t *accl){
if (c == NULL || euler == NULL || gyro == NULL || accl == NULL) {
int8_t Chassis_UpdateIMU(Chassis_t *c, const Chassis_IMU_t imu){
if (c == NULL) {
return -1; // 参数错误
}
c->feedback.imu_euler = *euler;
c->feedback.imu_gyro = *gyro;
c->feedback.imu_accl = *accl;
c->feedback.imu = imu;
return 0;
}
@ -108,7 +91,7 @@ int8_t Chassis_Control(Chassis_t *c, const Chassis_CMD_t *c_cmd){
c->lask_wakeup = BSP_TIME_Get_us();
/*设置底盘模式*/
if (Chassis_SetMode(c, c_cmd->mode, c_cmd->action) != CHASSIS_OK) {
if (Chassis_SetMode(c, c_cmd->mode) != CHASSIS_OK) {
return CHASSIS_ERR_MODE; // 设置模式失败
}
@ -120,7 +103,7 @@ int8_t Chassis_Control(Chassis_t *c, const Chassis_CMD_t *c_cmd){
MOTOR_LZ_Relax(&c->param->joint_motors[i]);
}
for (int i = 0; i < 2; i++) {
MOTOR_LK_MotorOff(&c->param->wheel_motors[i]);
MOTOR_LK_Relax(&c->param->wheel_motors[i]); // 改为Relax以保持反馈
}
break;
@ -139,26 +122,27 @@ int8_t Chassis_Control(Chassis_t *c, const Chassis_CMD_t *c_cmd){
case 1:
// 关节电机复位轮电机输出0
for (int i = 0; i < 4; i++) {
MOTOR_LZ_PositionControl(&c->param->joint_motors[i], 0.0f, 1.0f); // 回到零位最大速度1.0 rad/s
MOTOR_LZ_RecoverToZero(&c->param->joint_motors[i]);
}
for (int i = 0; i < 2; i++) {
MOTOR_LK_SetOutput(&c->param->wheel_motors[i], 0.0f); // 设置轮子速度为0
MOTOR_LK_Relax(&c->param->wheel_motors[i]);
}
break;
}
break;
case CHASSIS_MODE_WHELL_BALANCE:
{
// 只靠两轮平衡关节电机锁死通过pid实现倒立摆
// 锁定关节电机到固定位置(比如直立状态)
for (int i = 0; i < 4; i++) {
MOTOR_LZ_PositionControl(&c->param->joint_motors[i], 0.0f, 0.5f); // 目标位置0最大速度0.5 rad/s
}
// for (int i = 0; i < 4; i++) {
// MOTOR_LZ_PositionControl(&c->param->joint_motors[i], 0.0f, 0.5f); // 目标位置0最大速度0.5 rad/s
// }
// 双轮平衡控制
// 获取IMU pitch角度和角速度作为平衡反馈
float pitch_angle = c->feedback.imu_euler.pit; // pitch角度
float pitch_rate = c->feedback.imu_gyro.y; // pitch角速度
float pitch_angle = c->feedback.imu.euler.pit;
float pitch_rate = c->feedback.imu.gyro.y; // pitch角速度
// 平衡PID计算 - 以直立为目标0度
float balance_output = PID_Calc(&c->pid.balance, 0.0f, pitch_angle, pitch_rate, c->dt);
@ -197,6 +181,7 @@ int8_t Chassis_Control(Chassis_t *c, const Chassis_CMD_t *c_cmd){
MOTOR_LK_SetOutput(&c->param->wheel_motors[0], left_output);
MOTOR_LK_SetOutput(&c->param->wheel_motors[1], right_output);
break;
}
case CHASSIS_MODE_WHELL_LEG_BALANCE:
// 轮子+腿平衡模式(暂时留空,后续实现)

View File

@ -40,25 +40,22 @@ typedef enum {
CHASSIS_MODE_WHELL_LEG_BALANCE, /* 轮子+腿平衡模式,底盘自我平衡 */
} Chassis_Mode_t;
typedef enum {
CHASSIS_ACTION_JUMP,
CHASSIS_ACTION_STAND,
}Chassis_Action_t;
typedef struct {
Chassis_Mode_t mode; /* 底盘模式 */
Chassis_Action_t action; /* 底盘动作 */
MoveVector_t move_vec; /* 底盘运动向量 */
float height; /* 目标高度 */
} Chassis_CMD_t;
typedef struct {
AHRS_Accl_t accl; /* IMU加速度计 */
AHRS_Gyro_t gyro; /* IMU陀螺仪 */
AHRS_Eulr_t euler; /* IMU欧拉角 */
}Chassis_IMU_t;
typedef struct {
MOTOR_Feedback_t joint[4]; /* 四个关节电机反馈 */
MOTOR_Feedback_t wheel[2]; /* 两个轮子电机反馈 */
AHRS_Accl_t imu_accl; /* IMU加速度计 */
AHRS_Gyro_t imu_gyro; /* IMU陀螺仪 */
AHRS_Eulr_t imu_euler; /* IMU欧拉角 */
Chassis_IMU_t imu; /* IMU数据 */
MOTOR_Feedback_t yaw; /* 云台Yaw轴电机反馈 */
}Chassis_Feedback_t;
@ -90,7 +87,7 @@ typedef struct {
*
*/
typedef struct {
uint32_t lask_wakeup;
uint64_t lask_wakeup;
float dt;
Chassis_Params_t *param; /* 底盘的参数用Chassis_Init设定 */
@ -98,7 +95,6 @@ typedef struct {
/* 模块通用 */
Chassis_Mode_t mode; /* 底盘模式 */
Chassis_Action_t action; /* 底盘动作 */
/* 反馈信息 */
Chassis_Feedback_t feedback;
@ -152,7 +148,7 @@ int8_t Chassis_Init(Chassis_t *c, Chassis_Params_t *param, float target_freq);
int8_t Chassis_UpdateFeedback(Chassis_t *c);
int8_t Chassis_UpdateIMU(Chassis_t *c, const AHRS_Eulr_t *euler, const AHRS_Gyro_t *gyro, const AHRS_Accl_t *accl);
int8_t Chassis_UpdateIMU(Chassis_t *c, const Chassis_IMU_t imu);
/**
* \brief
*

View File

@ -55,16 +55,92 @@ Config_RobotParam_t robot_config = {
},
.wheel_motors[0] = { // 左轮电机
.can = BSP_CAN_1,
.id = 0x141,
.id = 1, // 电机ID为1对应命令ID=0x141反馈ID=0x181
.module = MOTOR_LK_MF9025,
.reverse = false,
},
.wheel_motors[1] = { // 右轮电机
.can = BSP_CAN_1,
.id = 0x142,
.id = 2, // 电机ID为2对应命令ID=0x142反馈ID=0x182
.module = MOTOR_LK_MF9025,
.reverse = true,
},
.chassis_param = {
.follow_pid_param = {
.k = 1.0f,
.p = 20.0f,
.i = 0.0f,
.d = 0.0f,
.i_limit = 0.0f,
.out_limit = 500.0f,
.d_cutoff_freq = 30.0f,
.range = 0.0f,
},
.motor_pid_param = {
.k = 1.0f,
.p = 0.5f,
.i = 0.0f,
.d = 0.0f,
.i_limit = 0.0f,
.out_limit = 12.0f,
.d_cutoff_freq = 30.0f,
.range = 0.0f,
},
.low_pass_cutoff_freq = {
.in = 30.0f,
.out = 30.0f,
},
.joint_motors = {
{ // 左髋关节
.can = BSP_CAN_1,
.motor_id = 124,
.host_id = 130,
.module = MOTOR_LZ_RSO3,
.reverse = false,
.mode = MOTOR_LZ_MODE_MOTION,
},
{ // 左膝关节
.can = BSP_CAN_1,
.motor_id = 125,
.host_id = 130,
.module = MOTOR_LZ_RSO3,
.reverse = false,
.mode = MOTOR_LZ_MODE_MOTION,
},
{ // 右膝关节
.can = BSP_CAN_1,
.motor_id = 126,
.host_id = 130,
.module = MOTOR_LZ_RSO3,
.reverse = false,
.mode = MOTOR_LZ_MODE_MOTION,
},
{ // 右髋关节
.can = BSP_CAN_1,
.motor_id = 127,
.host_id = 130,
.module = MOTOR_LZ_RSO3,
.reverse = false,
.mode = MOTOR_LZ_MODE_MOTION,
},
},
.wheel_motors = {
{ // 左轮电机
.can = BSP_CAN_1,
.id = 1,
.module = MOTOR_LK_MF9025,
.reverse = false,
},
{ // 右轮电机
.can = BSP_CAN_1,
.id = 2,
.module = MOTOR_LK_MF9025,
.reverse = true,
},
},
.mech_zero_yaw = 0.0f,
}
};
/* Private function prototypes ---------------------------------------------- */

View File

@ -12,12 +12,14 @@ extern "C" {
#include "device/dm_imu.h"
#include "device/motor_lz.h"
#include "device/motor_lk.h"
#include "module/balance_chassis.h"
typedef struct {
DM_IMU_Param_t imu_param;
MOTOR_LZ_Param_t joint_motors[4];
MOTOR_LK_Param_t wheel_motors[2];
Chassis_Params_t chassis_param;
} Config_RobotParam_t;
/* Exported functions prototypes -------------------------------------------- */

View File

@ -9,6 +9,7 @@
#include "bsp/can.h"
#include "device/dm_imu.h"
#include "module/config.h"
#include "module/balance_chassis.h"
/* USER INCLUDE END */
/* Private typedef ---------------------------------------------------------- */
@ -17,6 +18,7 @@
/* Private variables -------------------------------------------------------- */
/* USER STRUCT BEGIN */
DM_IMU_t dm_imu;
Chassis_IMU_t chassis_imu_send;
/* USER STRUCT END */
/* Private function --------------------------------------------------------- */
@ -42,7 +44,11 @@ void Task_atti_esti(void *argument) {
/* USER CODE BEGIN */
if (DM_IMU_AutoUpdateAll(&dm_imu) == DEVICE_OK) {
osMessageQueueReset(task_runtime.msgq.chassis_imu); // 重置消息队列,防止阻塞
chassis_imu_send.accl = dm_imu.data.accl;
chassis_imu_send.gyro = dm_imu.data.gyro;
chassis_imu_send.euler = dm_imu.data.euler;
osMessageQueuePut(task_runtime.msgq.chassis_imu, &chassis_imu_send, 0, 0); // 非阻塞发送IMU数据
}
/* USER CODE END */
osDelayUntil(tick); /* 运行结束,等待下一次唤醒 */

View File

@ -25,4 +25,4 @@
frequency: 500.0
function: Task_ctrl_chassis
name: ctrl_chassis
stack: 256
stack: 512

View File

@ -10,6 +10,8 @@
#include "device/motor_lk.h"
#include "device/motor_lz.h"
#include "module/config.h"
#include "module/balance_chassis.h"
/* USER INCLUDE END */
/* Private typedef ---------------------------------------------------------- */
@ -17,25 +19,20 @@
/* Private macro ------------------------------------------------------------ */
/* Private variables -------------------------------------------------------- */
/* USER STRUCT BEGIN */
MOTOR_LZ_MotionParam_t joint0_motion_params = {
.target_angle = 0.0f,
.target_velocity = 0.0f,
.kp = 1.0f,
.kd = 1.0f,
.torque = 0.0f,
Chassis_t chassis;
Chassis_CMD_t chassis_cmd = {
.mode = CHASSIS_MODE_RECOVER, // 改为RECOVER模式让电机先启动
.move_vec = {
.vx = 0.0f,
.vy = 0.0f,
.wz = 0.0f,
},
.height = 0.0f,
};
Chassis_IMU_t chassis_imu;
MOTOR_LZ_MotionParam_t joint1_motion_params = {
.target_angle = 0.0f,
.target_velocity = 0.0f,
.kp = 1.0f,
.kd = 1.0f,
.torque = 0.0f,
};
bool motor_free = false;
MOTOR_t joint0;
MOTOR_t joint1;
// MOTOR_LZ_Feedback_t lz_feedback;
MOTOR_Feedback_t left_wheel_fb;
MOTOR_Feedback_t right_wheel_fb;
/* USER STRUCT END */
/* Private function --------------------------------------------------------- */
@ -51,47 +48,26 @@ void Task_ctrl_chassis(void *argument) {
uint32_t tick = osKernelGetTickCount(); /* 控制任务运行频率的计时 */
/* USER CODE INIT BEGIN */
BSP_CAN_Init();
// 初始化电机
MOTOR_LZ_Init();
for (int i = 0; i < 4; i++) {
MOTOR_LZ_Register(&Config_GetRobotParam()->joint_motors[i]);
MOTOR_LZ_Enable(&Config_GetRobotParam()->joint_motors[i]);
}
for (int i = 0; i < 2; i++) {
MOTOR_LK_Register(&Config_GetRobotParam()->wheel_motors[i]);
MOTOR_LK_MotorOn(&Config_GetRobotParam()->wheel_motors[i]);
}
Chassis_Init(&chassis, &Config_GetRobotParam()->chassis_param, CTRL_CHASSIS_FREQ);
/* USER CODE INIT END */
while (1) {
tick += delay_tick; /* 计算下一个唤醒时刻 */
/* USER CODE BEGIN */
MOTOR_LZ_Update(&Config_GetRobotParam()->joint_motors[0]);
MOTOR_LZ_Update(&Config_GetRobotParam()->joint_motors[1]);
// 实时获取电机数据并更新 joint0 和 joint1
MOTOR_LZ_t* joint0_instance = MOTOR_LZ_GetMotor(&Config_GetRobotParam()->joint_motors[0]);
MOTOR_LZ_t* joint1_instance = MOTOR_LZ_GetMotor(&Config_GetRobotParam()->joint_motors[1]);
if (joint0_instance != NULL) {
joint0 = joint0_instance->motor;
if (osMessageQueueGet(task_runtime.msgq.chassis_imu, &chassis_imu, NULL, 0) == osOK) {
chassis.feedback.imu = chassis_imu;
}
if (joint1_instance != NULL) {
joint1 = joint1_instance->motor;
if (osMessageQueueGet(task_runtime.msgq.Chassis_cmd, &chassis_cmd, NULL, 0) == osOK) {
// 成功接收到命令,更新底盘命令
}
Chassis_UpdateFeedback(&chassis);
Chassis_Control(&chassis, &chassis_cmd);
if (motor_free) {
// MOTOR_LZ_Relax(&Config_GetRobotParam()->joint_motors[0]);
// MOTOR_LZ_Relax(&Config_GetRobotParam()->joint_motors[1]);
MOTOR_LZ_RecoverToZero(&Config_GetRobotParam()->joint_motors[0]);
MOTOR_LZ_RecoverToZero(&Config_GetRobotParam()->joint_motors[1]);
} else {
MOTOR_LZ_MotionControl(&Config_GetRobotParam()->joint_motors[0], &joint0_motion_params);
MOTOR_LZ_MotionControl(&Config_GetRobotParam()->joint_motors[1], &joint1_motion_params);
}
/* USER CODE END */
osDelayUntil(tick); /* 运行结束,等待下一次唤醒 */
}}

View File

@ -7,7 +7,9 @@
#include "task/user_task.h"
/* USER INCLUDE BEGIN */
#include "component/ahrs.h"
#include "module/config.h"
#include "module/balance_chassis.h"
/* USER INCLUDE BEGIN */
/* Private typedef ---------------------------------------------------------- */
@ -38,6 +40,8 @@ void Task_Init(void *argument) {
// 创建消息队列
/* USER MESSAGE BEGIN */
task_runtime.msgq.user_msg= osMessageQueueNew(2u, 10, NULL);
task_runtime.msgq.chassis_imu = osMessageQueueNew(2u, sizeof(Chassis_IMU_t), NULL);
task_runtime.msgq.Chassis_cmd = osMessageQueueNew(2u, sizeof(Chassis_CMD_t), NULL);
/* USER MESSAGE END */
osKernelUnlock(); // 解锁内核

View File

@ -7,6 +7,7 @@
#include "task/user_task.h"
/* USER INCLUDE BEGIN */
#include "device/dr16.h"
#include "module/balance_chassis.h"
/* USER INCLUDE END */
/* Private typedef ---------------------------------------------------------- */
@ -15,6 +16,7 @@
/* Private variables -------------------------------------------------------- */
/* USER STRUCT BEGIN */
DR16_t dr16;
Chassis_CMD_t cmd_to_chassis;
/* USER STRUCT END */
/* Private function --------------------------------------------------------- */
@ -37,7 +39,50 @@ void Task_rc(void *argument) {
tick += delay_tick; /* 计算下一个唤醒时刻 */
/* USER CODE BEGIN */
DR16_StartDmaRecv(&dr16);
if (DR16_WaitDmaCplt(20)) {
// 根据左拨杆设置底盘模式
switch (dr16.data.sw_l) {
case 1: // 上位
cmd_to_chassis.mode = CHASSIS_MODE_RELAX;
break;
case 3: // 中位
cmd_to_chassis.mode = CHASSIS_MODE_RECOVER;
break;
case 2: // 下位
cmd_to_chassis.mode = CHASSIS_MODE_WHELL_BALANCE;
break;
default:
cmd_to_chassis.mode = CHASSIS_MODE_RELAX;
break;
}
// 解析遥控器摇杆数据为运动向量
// 将遥控器通道值从[364, 1684]映射到[-1.0, 1.0]
float ch_l_y_norm = (float)(dr16.data.ch_l_y - 1024) / 660.0f; // 前后
float ch_l_x_norm = (float)(dr16.data.ch_l_x - 1024) / 660.0f; // 左右
float ch_r_x_norm = (float)(dr16.data.ch_r_x - 1024) / 660.0f; // 旋转
// 设置运动向量(根据需要调整增益)
cmd_to_chassis.move_vec.vx = ch_l_y_norm * 2.0f; // 前后运动,增益可调
cmd_to_chassis.move_vec.vy = ch_l_x_norm * 2.0f; // 左右运动,增益可调
cmd_to_chassis.move_vec.wz = ch_r_x_norm * 3.0f; // 旋转运动,增益可调
// 设置目标高度(可根据右拨杆或其他输入调整)
cmd_to_chassis.height = 0.0f;
// 发送命令到底盘控制任务
osMessageQueuePut(task_runtime.msgq.Chassis_cmd, &cmd_to_chassis, 0, 0);
} else {
// 超时处理,发送安全命令
cmd_to_chassis.mode = CHASSIS_MODE_RELAX;
cmd_to_chassis.move_vec.vx = 0.0f;
cmd_to_chassis.move_vec.vy = 0.0f;
cmd_to_chassis.move_vec.wz = 0.0f;
cmd_to_chassis.height = 0.0f;
osMessageQueuePut(task_runtime.msgq.Chassis_cmd, &cmd_to_chassis, 0, 0);
}
/* USER CODE END */
osDelayUntil(tick); /* 运行结束,等待下一次唤醒 */
}

View File

@ -27,5 +27,5 @@ const osThreadAttr_t attr_atti_esti = {
const osThreadAttr_t attr_ctrl_chassis = {
.name = "ctrl_chassis",
.priority = osPriorityNormal,
.stack_size = 256 * 4,
.stack_size = 512 * 8,
};

View File

@ -42,6 +42,10 @@ typedef struct {
/* USER MESSAGE BEGIN */
struct {
osMessageQueueId_t user_msg; /* 用户自定义任务消息队列 */
osMessageQueueId_t chassis_imu;
osMessageQueueId_t Chassis_cmd;
} msgq;
/* USER MESSAGE END */