From ae40434ecf0cc32b29b55e97fabb95c7ae7a1672 Mon Sep 17 00:00:00 2001 From: Robofish <1683502971@qq.com> Date: Sat, 20 Sep 2025 00:44:54 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=94=9F=E6=88=90cmake?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/code_generate_interface.py | 85 +++++++++++++++++++++++++++++- assets/User_code/device/motor_lk.c | 78 +++++++++++++-------------- 2 files changed, 121 insertions(+), 42 deletions(-) diff --git a/app/code_generate_interface.py b/app/code_generate_interface.py index 6a307f1..8154127 100644 --- a/app/code_generate_interface.py +++ b/app/code_generate_interface.py @@ -66,17 +66,23 @@ class CodeGenerateInterface(QWidget): top_layout.addWidget(freertos_label) # 自动生成FreeRTOS任务按钮 - auto_task_btn = PushButton(FluentIcon.SEND, "自动生成FreeRTOS任务") + auto_task_btn = PushButton(FluentIcon.SEND, "配置FreeRTOS") auto_task_btn.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) auto_task_btn.clicked.connect(self.on_freertos_task_btn_clicked) top_layout.addWidget(auto_task_btn, alignment=Qt.AlignRight) # 配置并生成FreeRTOS任务按钮 - freertos_task_btn = PushButton(FluentIcon.SETTING, "配置并生成FreeRTOS任务") + freertos_task_btn = PushButton(FluentIcon.SETTING, "创建任务") freertos_task_btn.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) freertos_task_btn.clicked.connect(self.on_task_code_btn_clicked) top_layout.addWidget(freertos_task_btn, alignment=Qt.AlignRight) + # 配置cmake按钮 + cmake_btn = PushButton(FluentIcon.FOLDER, "配置cmake") + cmake_btn.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) + cmake_btn.clicked.connect(self.on_cmake_config_btn_clicked) + top_layout.addWidget(cmake_btn, alignment=Qt.AlignRight) + # 生成代码按钮 generate_btn = PushButton(FluentIcon.PROJECTOR,"生成代码") generate_btn.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) @@ -154,6 +160,81 @@ class CodeGenerateInterface(QWidget): duration=2000 ) + def on_cmake_config_btn_clicked(self): + """配置cmake,自动更新CMakeLists.txt中的源文件列表""" + try: + from app.tools.update_cmake_sources import find_user_c_files, update_cmake_sources + from pathlib import Path + + # 构建User目录和CMakeLists.txt路径 + user_dir = os.path.join(self.project_path, "User") + cmake_file = os.path.join(self.project_path, "CMakeLists.txt") + + # 检查User目录是否存在 + if not os.path.exists(user_dir): + InfoBar.error( + title="错误", + content=f"User目录不存在: {user_dir}", + parent=self, + duration=3000 + ) + return + + # 检查CMakeLists.txt是否存在 + if not os.path.exists(cmake_file): + InfoBar.error( + title="错误", + content=f"CMakeLists.txt文件不存在: {cmake_file}", + parent=self, + duration=3000 + ) + return + + # 查找User目录下的所有.c文件 + c_files = find_user_c_files(user_dir) + + if not c_files: + InfoBar.warning( + title="警告", + content="在User目录下没有找到.c文件", + parent=self, + duration=3000 + ) + return + + # 更新CMakeLists.txt + success = update_cmake_sources(cmake_file, c_files) + + if success: + InfoBar.success( + title="配置成功", + content=f"已成功更新CMakeLists.txt,共添加了 {len(c_files)} 个源文件", + parent=self, + duration=3000 + ) + else: + InfoBar.error( + title="配置失败", + content="更新CMakeLists.txt失败,请检查文件格式", + parent=self, + duration=3000 + ) + + except ImportError as e: + InfoBar.error( + title="导入错误", + content=f"无法导入cmake配置模块: {str(e)}", + parent=self, + duration=3000 + ) + except Exception as e: + InfoBar.error( + title="配置失败", + content=f"cmake配置过程中出现错误: {str(e)}", + parent=self, + duration=3000 + ) + def generate_code(self): diff --git a/assets/User_code/device/motor_lk.c b/assets/User_code/device/motor_lk.c index 9b34703..d556c3c 100644 --- a/assets/User_code/device/motor_lk.c +++ b/assets/User_code/device/motor_lk.c @@ -92,11 +92,7 @@ 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) { // 如果不是标准反馈命令,可能是其他格式的数据 @@ -106,32 +102,32 @@ static void MOTOR_LK_Decode(MOTOR_LK_t *motor, BSP_CAN_Message_t *msg) { // 解析温度 (DATA[1]) motor->motor.feedback.temp = (int8_t)msg->data[1]; - + // 解析转矩电流值或功率值 (DATA[2], DATA[3]) int16_t raw_current_or_power = (int16_t)((msg->data[3] << 8) | msg->data[2]); - + // 根据电机类型解析电流或功率 switch (motor->param.module) { case MOTOR_LK_MF9025: case MOTOR_LK_MF9035: - // MF/MG电机:转矩电流值 motor->motor.feedback.torque_current = raw_current_or_power * MOTOR_LK_GetCurrentLSB(motor->param.module); break; default: - // MS电机:功率值(范围-1000~1000) - motor->motor.feedback.torque_current = (float)raw_current_or_power; // 将功率存储在torque_current字段中 + motor->motor.feedback.torque_current = (float)raw_current_or_power; break; } - + // 解析转速 (DATA[4], DATA[5]) - 单位:1dps/LSB - motor->motor.feedback.rotor_speed = (int16_t)((msg->data[5] << 8) | msg->data[4]); - + int16_t raw_speed = (int16_t)((msg->data[5] << 8) | msg->data[4]); + motor->motor.feedback.rotor_speed = motor->param.reverse ? -raw_speed : raw_speed; + // 解析编码器值 (DATA[6], DATA[7]) uint16_t raw_encoder = (uint16_t)((msg->data[7] << 8) | msg->data[6]); uint16_t encoder_max = MOTOR_LK_GetEncoderMax(motor->param.module); - + // 将编码器值转换为弧度 (0 ~ 2π) - motor->motor.feedback.rotor_abs_angle = (float)raw_encoder / (float)encoder_max * M_2PI; + float angle = (float)raw_encoder / (float)encoder_max * M_2PI; + motor->motor.feedback.rotor_abs_angle = motor->param.reverse ? (M_2PI - angle) : angle; } /* Exported functions ------------------------------------------------------- */ @@ -163,7 +159,7 @@ int8_t MOTOR_LK_Register(MOTOR_LK_Param_t *param) { // 对于某些LK电机,反馈数据可能通过命令ID发送 // 根据实际测试,使用命令ID接收反馈数据 - uint16_t feedback_id = 0x140 + param->id; // 使用命令ID作为反馈ID + uint16_t feedback_id = param->id; // 使用命令ID作为反馈ID // 注册CAN接收ID if (BSP_CAN_RegisterId(param->can, feedback_id, 3) != BSP_OK) { @@ -186,7 +182,7 @@ int8_t MOTOR_LK_Update(MOTOR_LK_Param_t *param) { MOTOR_LK_t *motor = manager->motors[i]; if (motor && motor->param.id == param->id) { // 对于某些LK电机,反馈数据通过命令ID发送 - uint16_t feedback_id = 0x140 + param->id; + uint16_t feedback_id = param->id; BSP_CAN_Message_t rx_msg; if (BSP_CAN_GetMessage(param->can, feedback_id, &rx_msg, BSP_CAN_TIMEOUT_IMMEDIATE) != BSP_OK) { @@ -227,35 +223,37 @@ int8_t MOTOR_LK_UpdateAll(void) { int8_t MOTOR_LK_SetOutput(MOTOR_LK_Param_t *param, float value) { if (param == NULL) return DEVICE_ERR_NULL; - + MOTOR_LK_CANManager_t *manager = MOTOR_LK_GetCANManager(param->can); if (manager == NULL) return DEVICE_ERR_NO_DEV; - + // 限制输出值范围 if (value > 1.0f) value = 1.0f; if (value < -1.0f) value = -1.0f; - + MOTOR_LK_t *motor = MOTOR_LK_GetMotor(param); if (motor == NULL) return DEVICE_ERR_NO_DEV; - + + // 根据反转参数调整输出 + float output = param->reverse ? -value : value; + // 转矩闭环控制命令 - 将输出值转换为转矩控制值 - int16_t torque_control = (int16_t)(value * (float)LK_TORQUE_RANGE); - - // 构建CAN帧(根据协议:命令报文标识符 = 0x140 + ID) + int16_t torque_control = (int16_t)(output * (float)LK_TORQUE_RANGE); + + // 构建CAN帧 BSP_CAN_StdDataFrame_t tx_frame; - tx_frame.id = 0x140 + param->id; + tx_frame.id = param->id; tx_frame.dlc = MOTOR_TX_BUF_SIZE; - - // 设置转矩闭环控制命令数据 - tx_frame.data[0] = LK_CMD_TORQUE_CTRL; // 命令字节 - tx_frame.data[1] = 0x00; // NULL - tx_frame.data[2] = 0x00; // NULL - tx_frame.data[3] = 0x00; // NULL - tx_frame.data[4] = (uint8_t)(torque_control & 0xFF); // 转矩电流控制值低字节 - tx_frame.data[5] = (uint8_t)((torque_control >> 8) & 0xFF); // 转矩电流控制值高字节 - tx_frame.data[6] = 0x00; // NULL - tx_frame.data[7] = 0x00; // NULL - BSP_CAN_WaitTxMailboxEmpty(param->can, 1); // 等待发送邮箱空闲 + + tx_frame.data[0] = LK_CMD_TORQUE_CTRL; + tx_frame.data[1] = 0x00; + tx_frame.data[2] = 0x00; + tx_frame.data[3] = 0x00; + tx_frame.data[4] = (uint8_t)(torque_control & 0xFF); + tx_frame.data[5] = (uint8_t)((torque_control >> 8) & 0xFF); + tx_frame.data[6] = 0x00; + tx_frame.data[7] = 0x00; + BSP_CAN_WaitForEmptyMailbox(param->can, 1); return BSP_CAN_TransmitStdDataFrame(param->can, &tx_frame) == BSP_OK ? DEVICE_OK : DEVICE_ERR; } @@ -269,7 +267,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 = 0x140 + param->id; + tx_frame.id = param->id; tx_frame.dlc = MOTOR_TX_BUF_SIZE; // 电机运行命令 @@ -281,7 +279,7 @@ int8_t MOTOR_LK_MotorOn(MOTOR_LK_Param_t *param) { tx_frame.data[5] = 0x00; tx_frame.data[6] = 0x00; tx_frame.data[7] = 0x00; - BSP_CAN_WaitTxMailboxEmpty(param->can, 1); // 等待发送邮箱空闲 + return BSP_CAN_TransmitStdDataFrame(param->can, &tx_frame) == BSP_OK ? DEVICE_OK : DEVICE_ERR; } @@ -289,7 +287,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 = 0x140 + param->id; + tx_frame.id = param->id; tx_frame.dlc = MOTOR_TX_BUF_SIZE; // 电机关闭命令 @@ -301,7 +299,7 @@ int8_t MOTOR_LK_MotorOff(MOTOR_LK_Param_t *param) { tx_frame.data[5] = 0x00; tx_frame.data[6] = 0x00; tx_frame.data[7] = 0x00; - BSP_CAN_WaitTxMailboxEmpty(param->can, 1); // 等待发送邮箱空闲 + return BSP_CAN_TransmitStdDataFrame(param->can, &tx_frame) == BSP_OK ? DEVICE_OK : DEVICE_ERR; }