第一次提交

This commit is contained in:
2025-08-26 10:53:01 +08:00
commit 7730610c15
59 changed files with 12914 additions and 0 deletions

159
app/app_base.c Normal file
View File

@@ -0,0 +1,159 @@
#include "app_config.h"
#include "app_dependence.h"
#include "interface.h"
#include "app_base.h"
// 使用内联函数
static inline uint8_t setBaseOn(void) { return 1; }
static inline uint8_t setBaseOff(void) { return 0; }
BaseSystem base_data;
// 输出处理函数
static void baseOutput(void *signal_id)
{
(void)signal_id;
// 根据电机状态,填充发送数据结构,发送信号
switch (base_data.base_command)
{
case 1: // 上升状态
un_lifter_output.bit_data.cmd = BASE_UP;
un_h_bridge_output1.bit_data.channel_01 = setBaseOn();
un_h_bridge_output1.bit_data.channel_02 = setBaseOff();
un_h_bridge_output2.bit_data.channel_01 = setBaseOn();
un_h_bridge_output2.bit_data.channel_02 = setBaseOff();
// printf("base: up\n");
break;
case 2: // 下降状态
un_lifter_output.bit_data.cmd = BASE_DOWN;
un_h_bridge_output1.bit_data.channel_01 = setBaseOff();
un_h_bridge_output1.bit_data.channel_02 = setBaseOn();
un_h_bridge_output2.bit_data.channel_01 = setBaseOff();
un_h_bridge_output2.bit_data.channel_02 = setBaseOn();
// printf("base: down\n");
break;
default://停止
un_lifter_output.bit_data.cmd = BASE_STOP;
un_h_bridge_output1.bit_data.channel_01 = setBaseOff();
un_h_bridge_output1.bit_data.channel_02 = setBaseOff();
un_h_bridge_output2.bit_data.channel_01 = setBaseOff();
un_h_bridge_output2.bit_data.channel_02 = setBaseOff();
// printf("base: stop\n");
break;
}
publishMessage(&un_h_bridge_output1, 1);
publishMessage(&un_h_bridge_output2, 1);
publishMessage(&un_lifter_output, 1);
}
//处理开关以及模式状态。还需要保存状态防止重启的问题。
static void baseTimerProcess(void *signal_id)
{
(void)signal_id;
if( (base_data.emergency_stop_switch) || (base_data.remote_emergency_stop) )//急停只要有一个有效就停止
{
base_data.base_command = BASE_STOP;
}
else if(base_data.mode)//自动模式 一直上升就自动
{
if(base_data.input_data > REMOTE_DEADBAND)//上升
{
base_data.base_command = BASE_UP;
}
else if(base_data.input_data < -REMOTE_DEADBAND)//下降
{
base_data.base_command = BASE_DOWN;
}
else//不停止
{
}
}
else//手动模式-
{
if(base_data.input_data > REMOTE_DEADBAND)//上升
{
base_data.base_command = BASE_UP;
}
else if(base_data.input_data < -REMOTE_DEADBAND)//下降
{
base_data.base_command = BASE_DOWN;
}
else
{
base_data.base_command = BASE_STOP;
}
}
baseOutput(signal_id);
}
// 处理所有输入信号的函数
static void baseInput(void *signal_id)
{
// BaseSystem old_data = base_data; // 定义并初始化old_data
// 填充数据
if (signal_id == &un_sw_sample)
{
base_data.emergency_stop_switch = (uint8_t)un_sw_sample.bit_data.emergency_stop_switch;
base_data.Left_switch = (uint8_t)un_sw_sample.bit_data.Left_switch;
base_data.right_switch = (uint8_t)un_sw_sample.bit_data.right_switch;
}
else if ( (signal_id == &un_remote_control_input) && (1 == un_remote_control_input.bit_data.enable) )// 遥控器断线,不更新数据
{
base_data.remote_emergency_stop = ((uint8_t)un_remote_control_input.bit_data.switch_b == 1) ? 0 : 1;
base_data.mode = ((uint8_t)un_remote_control_input.bit_data.switch_c == 1) ? 1 : 0;//
}
else if( (signal_id == &un_remote_control_input1) && (1 == un_remote_control_input.bit_data.enable) )
{
base_data.input_data = (int16_t)(un_remote_control_input1.bit_data.speed) - REMOTE_ZERO;
// printf("un_remote_control_input1: %d\n", base_data.input_data);
}
else if (signal_id == &can_fault_info)
{
// base_data.remote_fault = !can_fault_info.bit_data.remote_state;
// base_data.can_bus_fault = !can_fault_info.bit_data.motor1_state || !can_fault_info.bit_data.motor2_state || !can_fault_info.bit_data.navigator_state;
}
else if (signal_id == &ethernet_fault_Info)
{
// base_data.ethernet_fault = !ethernet_fault_Info.bit_data.auto_state && !ethernet_fault_Info.bit_data.manual_state;
}
baseTimerProcess(signal_id);
}
// 修改APP模块的初始化函数
void baseAppInit(void)
{
// 初始化
memset(&base_data, 0, sizeof(BaseSystem));
// 初始化定时器
timerInit(&base_data.base_timer);
// 订阅输入信号,处理刹车逻辑
subscribe(&un_sw_sample, baseInput);
subscribe(&un_remote_control_input, baseInput);
subscribe(&un_remote_control_input1, baseInput);
printf("app_base: initial OK \n");
}

55
app/app_base.h Normal file
View File

@@ -0,0 +1,55 @@
#ifndef BASE_H
#define BASE_H
#ifdef __cplusplus
extern "C" {
#endif
// <20><><EFBFBD><EFBFBD>ɲ<EFBFBD><C9B2>״̬<D7B4><CCAC>״̬
typedef enum {
BASE_STOP,
BASE_UP,
BASE_DOWN,
} baseState;
typedef struct BaseSystem
{
uint32_t start_time;
Timer base_timer; // <20><>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><E1B9B9>
uint8_t base_command; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>վ<EFBFBD><D5BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0ֹͣ,1<><31><EFBFBD><EFBFBD>,2<>½<EFBFBD>
uint8_t base_state; // <20><>վ״̬<D7B4><CCAC>1<EFBFBD><31>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,2<><32>ʾ<EFBFBD>½<EFBFBD><C2BD>У<EFBFBD>3<EFBFBD><33><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̶<EFBFBD>λ<EFBFBD>ã<EFBFBD>4<EFBFBD><34><EFBFBD>½<EFBFBD><C2BD>̶<EFBFBD>λ<EFBFBD><CEBB>
uint8_t mode; // ң<><D2A3>ģʽ<C4A3><CABD>0<EFBFBD><30>2<EFBFBD>ֶ<EFBFBD><D6B6><EFBFBD>1<EFBFBD>Զ<EFBFBD>
uint8_t Left_switch; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD>
uint8_t right_switch; // <20>Ҳ<EFBFBD><D2B2><EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD>
uint8_t emergency_stop_switch; // <20><>ͣ<EFBFBD><CDA3><EFBFBD>أ<EFBFBD><D8A3><EFBFBD><EFBFBD>¼<EFBFBD>ͣ<EFBFBD><CDA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>½<EFBFBD><C2BD><EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD><CDA3>
uint8_t remote_emergency_stop; // Զ<>̼<EFBFBD>ͣ<EFBFBD><CDA3><EFBFBD>أ<EFBFBD><D8A3><EFBFBD><EFBFBD>¼<EFBFBD>ͣ<EFBFBD><CDA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>½<EFBFBD><C2BD><EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD><CDA3>
int16_t input_data; // <20><><EFBFBD><EFBFBD>ң<EFBFBD><D2A3><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>½<EFBFBD>
} BaseSystem;
#define REMOTE_ZERO 1022
#define REMOTE_DEADBAND 50
void baseAppInit(void);
#ifdef __cplusplus
}
#endif
#endif // BASE_H

236
app/app_brake.c Normal file
View File

@@ -0,0 +1,236 @@
#include "app_config.h"
#include "interface.h"
#include "app_frm_monitor.h"
#include "app_frm_signal.h"
#include "app_frm_timer.h"
#include "app_param_manage.h"
#include "app_power.h"
#include "app_brake.h"
#include "app_differential_drive.h"
// 使用内联函数
static inline uint8_t setBrakeOn(void) { return 1; }
static inline uint8_t setBrakeOff(void){ return 0; }
BrakeSystem brake_data;
// 输出处理函数
static void brakeOutput(void *signal_id)
{
(void)signal_id;
// 根据电机状态,填充发送数据结构,发送信号
switch (brake_data.brake_motor_state)
{
case 1: // 电机前进状态
un_h_bridge_output.bit_data.channel_01 = setBrakeOn();
un_h_bridge_output.bit_data.channel_04 = setBrakeOn();
un_h_bridge_output.bit_data.channel_02 = setBrakeOff();
un_h_bridge_output.bit_data.channel_03 = setBrakeOff();
un_h_bridge_output.bit_data.sleep_01 = setBrakeOn();
un_h_bridge_output.bit_data.sleep_02 = setBrakeOn(); // 正转
printf("Brake: Motor forward\n");
break;
case 2: // 电机后退状态
un_h_bridge_output.bit_data.channel_01 = setBrakeOff();
un_h_bridge_output.bit_data.channel_04 = setBrakeOff();
un_h_bridge_output.bit_data.channel_02 = setBrakeOn();
un_h_bridge_output.bit_data.channel_03 = setBrakeOn();
un_h_bridge_output.bit_data.sleep_01 = setBrakeOn();
un_h_bridge_output.bit_data.sleep_02 = setBrakeOn(); // 反转
printf("Brake: Motor reverse\n");
break;
default:
un_h_bridge_output.bit_data.channel_01 = setBrakeOff();
un_h_bridge_output.bit_data.channel_04 = setBrakeOff();
un_h_bridge_output.bit_data.channel_02 = setBrakeOff();
un_h_bridge_output.bit_data.channel_03 = setBrakeOff();
un_h_bridge_output.bit_data.sleep_01 = setBrakeOff();
un_h_bridge_output.bit_data.sleep_02 = setBrakeOff(); // 关闭
printf("Brake: Motor off\n");
break;
}
publishMessage(&un_h_bridge_output, 1);
}
// 判断是否需要刹车
static uint8_t shouldApplyBrake()
{
return (brake_data.emergency_stop_switch ||
brake_data.remote_emergency_stop ||
(brake_data.mode_signal == 0 && brake_data.remote_fault) ||
(brake_data.mode_signal == 1 && brake_data.can_bus_fault));//20241021 修改不计算以太网故障
// (brake_data.mode_signal == 1 && (brake_data.can_bus_fault || brake_data.ethernet_fault)));
}
// 判断是否需要释放刹车
static uint8_t shouldReleaseBrake()
{
return (!brake_data.emergency_stop_switch &&
!brake_data.remote_emergency_stop &&
((brake_data.mode_signal == 0 && !brake_data.remote_fault) ||
(brake_data.mode_signal == 1 && !brake_data.can_bus_fault)));//20241021 修改不计算以太网故障
// (brake_data.mode_signal == 1 && (!brake_data.can_bus_fault && !brake_data.ethernet_fault))));
}
// 修改刹车定时器处理函数
static void brakeTimerProcess(void *signal_id)
{
(void)signal_id;
switch (brake_data.state)
{
case BRAKE_STATE_IDLE:
if (shouldApplyBrake())
{
brake_data.state = BRAKE_STATE_APPLYING_BRAKE;
if( 0 == brake_data.brake_direction)
{
brake_data.brake_motor_state = 1;
}
else
{
brake_data.brake_motor_state = 2;
}
brakeOutput(NULL);
timerStart(&brake_data.brake_apply_timer, (uint32_t)(getParam("brk_on")), 0);
}
break;
case BRAKE_STATE_BRAKE_ON:
if (shouldReleaseBrake() && power_data.current_state == POWER_WORKING)
{
brake_data.state = BRAKE_STATE_RELEASING_BRAKE;
if( 0 == brake_data.brake_direction)
{
brake_data.brake_motor_state = 2;
}
else
{
brake_data.brake_motor_state = 1;
}
brakeOutput(NULL);
timerStart(&brake_data.brake_release_timer, (uint32_t)(getParam("brk_off")), 0);
}
break;
case BRAKE_STATE_APPLYING_BRAKE:
if (!brake_data.brake_apply_timer.active)
{
brake_data.state = BRAKE_STATE_BRAKE_ON;
brake_data.brake_motor_state = 0;
brakeOutput(NULL);
brake_data.brake_position = 1; // 刹车位置1表示刹车
}
break;
case BRAKE_STATE_RELEASING_BRAKE:
if (!brake_data.brake_release_timer.active)
{
brake_data.state = BRAKE_STATE_IDLE;
brake_data.brake_motor_state = 0;
brakeOutput(NULL);
brake_data.brake_position = 0; // 刹车位置0表示未刹车
}
break;
default:
printf("ERROR: Unknown state\n");
brake_data.state = BRAKE_STATE_IDLE;
break;
}
// 如果刹车位置有变化存入EEPROM
if (brake_data.brake_position != brake_data.old_brake_position)
{
setParam("brk_pos", (float)brake_data.brake_position);
brake_data.old_brake_position = brake_data.brake_position;
}
timerStart(&brake_data.brake_timer, 100, 1); // 周期调用
}
// 处理所有输入信号的函数
static void brakeInput(void *signal_id)
{
// BrakeSystem old_data = brake_data; // 定义并初始化old_data
// 填充数据
if (signal_id == &un_sw_sample)
{
brake_data.emergency_stop_switch = (uint8_t)un_sw_sample.bit_data.emergency_stop_switch;
}
else if ( (signal_id == &un_remote_control_input) && (1 == un_remote_control_input.bit_data.enable) )// 遥控器断线,不更新数据
{
brake_data.remote_emergency_stop = ((uint8_t)un_remote_control_input.bit_data.switch_b == 1) ? 0 : 1;
brake_data.mode_signal = ((uint8_t)un_remote_control_input.bit_data.switch_c == 1) ? 1 : 0;
}
else if (signal_id == &can_fault_info)
{
brake_data.remote_fault = !can_fault_info.bit_data.remote_state;
brake_data.can_bus_fault = !can_fault_info.bit_data.motor1_state || !can_fault_info.bit_data.motor2_state || !can_fault_info.bit_data.navigator_state;
}
else if (signal_id == &ethernet_fault_Info)
{
brake_data.ethernet_fault = !ethernet_fault_Info.bit_data.auto_state && !ethernet_fault_Info.bit_data.manual_state;
}
}
void paramUpdate(void *signal_id)
{
brake_data.brake_direction = (uint8_t)getParam("brk_rev");
timerStart(&brake_data.brake_param_timer, 1000, 1);
}
// 修改APP模块的初始化函数
void brakeAppInit(void)
{
// 初始化
memset(&brake_data, 0, sizeof(BrakeSystem));
brake_data.state = BRAKE_STATE_IDLE;
// 初始化时恢复刹车位置
brake_data.brake_position = (uint8_t)getParam("brk_pos");
brake_data.old_brake_position = brake_data.brake_position;
// 根据刹车位置恢复刹车状态
if (brake_data.brake_position == 1)
{
brake_data.state = BRAKE_STATE_BRAKE_ON;
}
else
{
brake_data.state = BRAKE_STATE_IDLE;
}
// 初始化定时器
timerInit(&brake_data.brake_timer);
timerInit(&brake_data.brake_apply_timer);
timerInit(&brake_data.brake_release_timer);
timerInit(&brake_data.brake_param_timer);
// 订阅输入信号,处理刹车逻辑
subscribe(&un_sw_sample, brakeInput);
subscribe(&un_remote_control_input, brakeInput);
subscribe(&can_fault_info, brakeInput);
subscribe(&ethernet_fault_Info, brakeInput);
// 订阅定时器信号,用于状态机的定时处理
subscribe(&brake_data.brake_timer, brakeTimerProcess);
subscribe(&brake_data.brake_apply_timer, brakeTimerProcess);
subscribe(&brake_data.brake_release_timer, brakeTimerProcess);
subscribe(&brake_data.brake_param_timer, paramUpdate);
// 启动定时器,定期调用 brakeTimerProcess
timerStart(&brake_data.brake_timer, 500, 1);
timerStart(&brake_data.brake_param_timer, 1000, 1);
printf("app_brake: initial OK \n");
}

57
app/app_brake.h Normal file
View File

@@ -0,0 +1,57 @@
#ifndef APP_BRAKE_H
#define APP_BRAKE_H
#ifdef __cplusplus
extern "C" {
#endif
#include "app_config.h"
#include "app_frm_monitor.h"
#include "app_frm_signal.h"
#include "app_frm_timer.h"
// 定义刹车状态机状态
typedef enum {
BRAKE_STATE_IDLE,
BRAKE_STATE_APPLYING_BRAKE,
BRAKE_STATE_RELEASING_BRAKE,
BRAKE_STATE_BRAKE_ON,
} BrakeState;
typedef struct BrakeSystem
{
uint32_t start_time;
Timer brake_timer; // 定时器结构体
uint8_t brake_command; // 刹车命令变量1表示刹车,2表示释放
uint8_t brake_motor_state; // 刹车电机状态变量0停止,1前进,2后退
uint8_t brake_command_in_progress; // 刹车命令执行状态0表示空闲,1表示正在执行
uint8_t brake_direction;
uint8_t emergency_stop_switch; // 急停开关
uint8_t remote_emergency_stop; // 遥控器急停开关
uint8_t remote_fault; // 遥控器故障
uint8_t can_bus_fault; // CAN总线故障
uint8_t ethernet_fault; // 以太网通信故障
uint8_t mode_signal; // 模式信号0表示手动模式,1表示自动模式
BrakeState state; // 刹车状态机
uint8_t brake_position; // 刹车位置0表示未刹车,1表示刹车
uint8_t old_brake_position; // 旧的刹车位置
Timer brake_apply_timer; // 刹车定时器
Timer brake_release_timer; // 释放刹车定时器
Timer brake_param_timer; //参数更新时间
} BrakeSystem;
// 声明外部变量
extern BrakeSystem brake_data;
void brakeAppInit(void);
#ifdef __cplusplus
}
#endif
#endif // APP_BRAKE_H

39
app/app_config.h Normal file
View File

@@ -0,0 +1,39 @@
#ifndef APP_CONFIG_H
#define APP_CONFIG_H
#ifdef __cplusplus
extern "C" {
#endif
// 标准库,每个模块中也会包含
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdint.h>
#include <float.h>
#include <math.h>
#include <stdbool.h>
#include <string.h>
#include <assert.h>
//外部依赖放在这里,方便分层管理,实际代码中也有这个文件,但是没有依赖
//移植的时候,存放依赖的文件不用移植
#include "app_dependence.h"
// 接口,全局变量都放在这里
#include "interface.h"
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
static inline uint8_t app_close(void) { return 1; }
static inline uint8_t app_open(void) { return 0; }
#ifdef __cplusplus
}
#endif
#endif // APP_CONFIG_H

43
app/app_dependence.cpp Normal file
View File

@@ -0,0 +1,43 @@
#include "app_dependence.h"
#include <QDateTime>
// 添加Qt相关头文件
#include <QDateTime>
UnCanFault can_fault_info;
UnEthernetFault ethernet_fault_Info;
unsigned int wrbyte_24c02(unsigned int addr, unsigned char data)
{
(void)addr;
(void)data;
return 0;
}
unsigned char rdbyte_24c02(unsigned int addr)
{
(void)addr;
return 0;
}
void feedWatchdog(void)
{
}
void udelay(uint32_t t )
{
(void)t;
}
extern "C" {
uint32_t getCurrentTime(void)
{
// 获取当前时间
QDateTime current = QDateTime::currentDateTime();
// 转换为毫秒级时间戳
uint32_t timestamp = static_cast<uint32_t>(current.toMSecsSinceEpoch());
return timestamp;
}
}

90
app/app_dependence.h Normal file
View File

@@ -0,0 +1,90 @@
#ifndef TEST_H
#define TEST_H
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdint.h>
#include <float.h>
#include <math.h>
#include <stdbool.h>
#include <string.h>
#include <assert.h>
#include "irq.h"
#include "udelay\udelay.h"
#define PERIOD_TICK 1000000.0f // 1000000us = 1s
#ifdef __cplusplus
extern "C" {
#endif
//unsigned int wrbyte_24c02(unsigned int addr, unsigned char data);
//unsigned char rdbyte_24c02(unsigned int addr);
//void feedWatchdog(void);
//uint32_t getCurrentTime(void);
//void udelay(uint32_t t );
//
//typedef unsigned int irq_state_t;
//static inline irq_state_t arch_irq_save(void)
//{
// unsigned int cpsr = 0;
// return cpsr;
//}
//
//static inline void arch_irq_restore(irq_state_t flags)
//{
// flags += 1;
//}
//// 故障信息
//typedef struct _StrCanFault
//{
// uint8_t navigator_count; // 导航仪计数器
// uint8_t motor1_count; // 左电机计数器
// uint8_t motor2_count; // 右电机计数器
// uint8_t bms_count; // bms计数器
// uint8_t temperature_count; // 温度计数器
// uint8_t remote_count; // 遥控计数器
//
// uint8_t navigator_state; // 导航仪故障状态
// uint8_t motor1_state; // 电机1故障状态
// uint8_t motor2_state; // 电机2故障状态
// uint8_t bms_state; // bms状态
// uint8_t temperature_state; // 温度计数器
// uint8_t remote_state; // 遥控状态
//} StrCanFault;
//typedef union _UnCanFault
//{
// StrCanFault bit_data; // 使用定义的结构体类型
// uint8_t arr[sizeof(StrCanFault)]; // 通过结构体确定数组大小
//} UnCanFault;
//extern UnCanFault can_fault_info;
//typedef struct _StrEthernetFault
//{
// uint8_t auto_count; // 自动数据计数器
// uint8_t manual_count; // 手动数据计数器
// uint8_t auto_state; // 自动状态 | 0正常 1故障
// uint8_t manual_state; // 手动状态 | 0正常 1故障
//} StrEthernetFault;
//
//typedef union _UnEthernetFault
//{
// StrEthernetFault bit_data; // 使用定义的结构体类型
// uint8_t arr[sizeof(StrEthernetFault)]; // 通过结构体大小确定数组大小
//} UnEthernetFault;
//extern UnEthernetFault ethernet_fault_Info;
#ifdef __cplusplus
}
#endif
#endif // TEST_H

File diff suppressed because it is too large Load Diff

1364
app/app_differential_drive.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,128 @@
#ifndef APP_DIFFERENTIAL_DRIVE_H
#define APP_DIFFERENTIAL_DRIVE_H
#ifdef __cplusplus
extern "C"
{
#endif
#include "app_config.h"
#define SPEED_MODE 0x0C
#define THROTTLE_MODE 0x05
#define TORQUE_MODE 0x0A
#define MOTOR_MODE THROTTLE_MODE
#define SPEED_PID_MODE 0
#define THROTTLE_PID_MODE 1
#define SWITCH_SPEED 20.0f
#define DIFF_SPEED 20.0f
typedef enum
{
STATE_INIT, ///< 初始状态转速为0且等待扭矩方向判定
STATE_FORWARD, ///< 正向旋转状态
STATE_BACKWARD, ///< 反向旋转状态
DEC_FORWARD, ///< 正向减速状态
DEC_FORWARD2, ///< 正向溜坡状态
DEC_BACKWARD, ///< 反向减速状态
DEC_BACKWARD2 ///< 反向溜坡状态
} MotorState;
// 状态机内部状态
typedef enum
{
STATE_CALIB_INIT, // 初始状态:检测方向一致性
STATE_CALIB_JUDGE // 判断状态300ms验证期
} DirState;
typedef enum
{
FORWARD, ///< 正向旋转状态
BACKWARD ///< 反向旋转状态
} MotorDir;
typedef enum
{
MODE_MANUAL, // 手动模式
MODE_AUTO // 自动模式
} ControlMode;
typedef struct DiffData
{
ControlMode mode ; // 控制模式
MotorState state; //当前状态机状态
MotorDir motor_dir; // 当前车辆方向
DirState dir_state;
float desired_speed; // 期望速度
float desired_curvature; // 期望曲率
float left_motor_speed; // 当前左电机速度
float right_motor_speed; // 当前右电机速度
float left_front_motor_speed; // 当前左前电机速度
float right_front_motor_speed; // 当前右前电机速度
float left_rear_motor_speed; // 当前左后电机速度
float right_rear_motor_speed; // 当前右后电机速度
uint8_t out_motor_dir; // 电机状态
float speed_last; // 速度过去值
float torq_last; // 扭矩过去值
uint8_t counter; // 方向判断计数器
float left_speed_diff; // 左侧转速差
float right_speed_diff; // 右侧转速差
float left_diff_touue; // 左侧扭矩差
float right_diff_touue; // 右侧扭矩差
float diff_dead_zone; // 差速速度死区
float out_motor_speed[4];
float speed; // 当前车速
float curvature; // 当前曲率
float yaw_rate; // 当前角速度
float desired_yaw_rate; // 期望角速度
float acceleration; // 当前加速度
float deceleration; // 当前减速度
float max_speed; // 最大速度
float desired_acceleration; // 期望加速度
float desired_deceleration; // 期望减速度
uint8_t emergency_stop_switch; // 急停开关
uint8_t remote_emergency_stop; // 遥控器急停开关
uint8_t emergency_stop_state; // 急停状态
float out_left_motor_speed; // 输出左电机速度
float out_right_motor_speed; // 输出右电机速度
uint16_t max_Torq; // 最大扭矩限制
uint16_t speed_inter;
} DiffData;
// 声明外部变量
extern DiffData diff_data;
void diffAppInit(void);
#ifdef __cplusplus
}
#endif
#endif // APP_DIFFERENTIAL_DRIVE_H

175
app/app_frm_monitor.c Normal file
View File

@@ -0,0 +1,175 @@
#include "app_config.h"
#include "interface.h"
#include "app_frm_monitor.h"
#include "app_frm_signal.h"
#include "app_frm_timer.h"
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdarg.h>
// 全局日志缓冲区实例
LogBuffer log_buffer;
// 打印当前信号队列状态
void printSignalQueueStatus(void)
{
for (uint32_t i = 0; i < PRIORITY_LEVELS; i++)
{
printf("Priority %u Signal Count: %d\n", i,
getSignalCount(i));
}
}
// 打印订阅者信息
void printSubscriberInfo(void)
{
printf("Total Subscribers: %u\n", getSubscriberCount());
}
// 打印定时器状态
void printTimerStatus(void)
{
printf("Current Timer Count: %u / %u\n",
getCurrentTimerCount(), MAX_TIMERS);
}
// 监控函数
void monitorSignalSystem(void)
{
static uint32_t last_print_time = 0;
uint32_t current_print_time = getCurrentTime();
uint32_t time_interval = current_print_time - last_print_time;
printf("---------------------------------------------------\n");
printf("Time since last print: %u us\n", time_interval);
printSignalQueueStatus();
printSubscriberInfo();
printTimerStatus();
printf("---------------------------------------------------\n");
last_print_time = current_print_time;
}
int logBufferWrite(LogBuffer *lb, const char *format, ...)
{
if (format == NULL || lb == NULL)
{
return -1;
}
char temp_buffer[256]; // 临时缓冲区假设单条日志不超过256字节
va_list args;
va_start(args, format);
int length = vsnprintf(temp_buffer, sizeof(temp_buffer), format, args);
va_end(args);
if (length <= 0)
{
return -1;
}
// 进入关键区,保护缓冲区的写操作
irq_state_t saved_state = enter_critical_section();
// 检查缓冲区是否有足够的空间
if (lb->count + length > LOG_BUFFER_SIZE)
{
// 缓冲区满,无法写入
exit_critical_section(saved_state);
return -1;
}
// 写入数据到缓冲区
for (int i = 0; i < length; i++)
{
lb->buffer[lb->tail] = temp_buffer[i];
lb->tail = (lb->tail + 1) % LOG_BUFFER_SIZE;
}
lb->count += length;
exit_critical_section(saved_state);
return 0;
}
int logBufferRead(LogBuffer *lb, char *data, uint32_t max_length)
{
if (max_length == 0 || data == NULL || lb == NULL)
{
return -1;
}
// 进入关键区,保护缓冲区的读操作
irq_state_t saved_state = enter_critical_section();
uint32_t length = lb->count < max_length ? lb->count : max_length;
// 从缓冲区读取数据
for (uint32_t i = 0; i < length; i++)
{
data[i] = lb->buffer[lb->head];
lb->head = (lb->head + 1) % LOG_BUFFER_SIZE;
}
lb->count -= length;
exit_critical_section(saved_state);
return length;
}
// 初始化日志缓冲区
void initLogBuffer(LogBuffer *lb)
{
lb->head = 0;
lb->tail = 0;
lb->count = 0;
memset(lb->buffer, 0, LOG_BUFFER_SIZE);
}
// 日志信号处理函数
void logSignalHandler(void *signal_id)
{
(void)signal_id;
char log_data[256]; // 假设单次读取不超过256字节
int read_length;
// 从缓冲区读取日志信息
read_length = logBufferRead(&log_buffer, log_data, sizeof(log_data) - 1);
if (read_length > 0)
{
log_data[read_length] = '\0'; // 确保字符串以NULL结尾
// 调用printf进行打印
printf("%s", log_data);
}
}
Timer log_timer;
void logTimerHandler(void *timer_id)
{
(void)timer_id;
// monitorSignalSystem();
timerStart(&log_timer, 1000, 1);
}
void appMonitorInit(void)
{
// 初始化日志缓冲区
initLogBuffer(&log_buffer);
// 订阅日志信号
subscribe(&log_buffer, logSignalHandler);
timerInit(&log_timer);
timerStart(&log_timer, 1000, 1);
subscribe(&log_timer, logTimerHandler);
}
// // 使用格式化字符串记录日志
// if (logBufferWrite(&log_buffer, "ISR triggered: IRQ %d\n", irq_number) == 0) {
// // 发送信号,通知主线程有新日志
// publishMessage(&log_buffer, LOG_SIGNAL_PRIORITY);
// }

41
app/app_frm_monitor.h Normal file
View File

@@ -0,0 +1,41 @@
#ifndef APP_FRM_MONITOR_H
#define APP_FRM_MONITOR_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#define LOG_BUFFER_SIZE 1024 // 日志缓冲区的大小
#define LOG_SIGNAL_PRIORITY 1 // 日志信号的优先级
typedef struct
{
char buffer[LOG_BUFFER_SIZE];
uint32_t head; // 读指针
uint32_t tail; // 写指针
uint32_t count; // 缓冲区中的数据量
} LogBuffer;
// 全局日志缓冲区实例
extern LogBuffer log_buffer;
// 函数声明
void printSignalQueueStatus(void);
void printSubscriberInfo(void);
void printTimerStatus(void);
void monitorSignalSystem(void);
// 新增函数接口
int32_t logBufferWrite(LogBuffer *lb, const char *format, ...);
int32_t logBufferRead(LogBuffer *lb, char *data, uint32_t max_length);
void initLogBuffer(LogBuffer *lb);
void logSignalHandler(void *signal_id);
void appMonitorInit(void);
#ifdef __cplusplus
}
#endif
#endif // APP_FRM_MONITOR_H

333
app/app_frm_signal.c Normal file
View File

@@ -0,0 +1,333 @@
#include "app_config.h"
#include "interface.h"
#include "app_frm_signal.h"
typedef struct
{
void *signals[MAX_SIGNALS];
uint32_t head;
uint32_t tail;
uint32_t count;
} SignalQueue;
typedef struct
{
void *signal_id;
CallbackFunc callbacks[MAX_CALLBACKS];
uint32_t callback_count;
} Subscriber;
// 优先级队列
static SignalQueue priority_queues[PRIORITY_LEVELS];
// 订阅者表
static Subscriber subscriber_table[MAX_SUBSCRIBERS] = {{NULL, {NULL}, 0}};
// 初始化队列
static void initQueue(SignalQueue *q)
{
q->head = 0;
q->tail = 0;
q->count = 0;
}
// 将信号请求添加到队列中(按优先级)
static int32_t enqueue(SignalQueue *q, void *signal_id)
{
if (q == NULL)
{
printf("Error: enqueue received NULL queue pointer\n");
return -1;
}
if (signal_id == NULL)
{
printf("Error: Cannot enqueue NULL signal_id\n");
return -1;
}
irq_state_t saved_state = enter_critical_section();
if (q->count >= MAX_SIGNALS)
{
// 队列已满,移除最前面的信号
q->signals[q->head] = NULL;
q->head = (q->head + 1) % MAX_SIGNALS;
q->count--;
printf("Error: Signal queue is full, remove the first signal\n");
}
// 添加新的信号到队列尾部
q->signals[q->tail] = signal_id;
q->tail = (q->tail + 1) % MAX_SIGNALS;
q->count++;
exit_critical_section(saved_state);
return 0;
}
// 从队列中取出信号请求(按优先级)
static int32_t dequeue(SignalQueue *q, void **signal_id)
{
if (q == NULL)
{
printf("Error: dequeue received NULL queue pointer\n");
return -1;
}
if (signal_id == NULL)
{
printf("Error: dequeue received NULL signal pointer\n");
return -1;
}
// 仅在修改共享资源时进入临界区
if (q->count > 0)
{
irq_state_t saved_state = enter_critical_section();
*signal_id = q->signals[q->head];
q->signals[q->head] = NULL; // 清除已取出的信号
q->head = (q->head + 1) % MAX_SIGNALS;
q->count--;
exit_critical_section(saved_state);
return 0;
}
// printf("Warning: dequeue attempted to remove signal from an empty queue\n");
return -1;
}
// 哈希函数
static uint32_t hash(void *ptr)
{
uintptr_t value = (uintptr_t)ptr;
uint32_t hash = 0;
while (value != 0)
{
hash += value & 0xFF;
hash += (hash << 10);
hash ^= (hash >> 6);
value >>= 8;
}
hash += (hash << 3);
hash ^= (hash >> 11);
hash += (hash << 15);
return hash;
}
// 订阅信号, 给每个信号指定回调函数
int32_t subscribe(void *signal_id, CallbackFunc callback)
{
if (signal_id == NULL || callback == NULL)
{
printf("Error: Invalid signal_id or callback\n");
return -1;
}
irq_state_t saved_state = enter_critical_section();
uint32_t index = hash(signal_id) % MAX_SUBSCRIBERS;
uint32_t original_index = index;
do
{
// if(signal_id == &un_remote_control_input)
// {
// printf("remote的地址%p\n", (void*)&un_remote_control_input); // 输出示例0x7ffd9a3c8b40[5](@ref)
// printf("signal_id的地址%p\n", (void*)(subscriber_table[index].signal_id)); // 输出示例0x7ffd9a3c8b40[5](@ref)
// }
//
if (subscriber_table[index].signal_id == NULL ||
subscriber_table[index].signal_id == signal_id)
{
if (subscriber_table[index].signal_id == NULL)
{
subscriber_table[index].signal_id = signal_id;
subscriber_table[index].callback_count = 0;
}
if (subscriber_table[index].callback_count < MAX_CALLBACKS)
{
subscriber_table[index].callbacks[subscriber_table[index].callback_count++] = callback;
exit_critical_section(saved_state);
return 0;
}
else
{
printf("Error: Maximum callbacks reached for this signal\n");
exit_critical_section(saved_state);
return -1;
}
}
index = (index + 1) % MAX_SUBSCRIBERS;
} while (index != original_index);
// printf("remote addrss%p\n", (void*)signal_id); // 输出示例0x7ffd9a3c8b40[5](@ref)
// printf("signal_id addrss%p\n", (void*)(subscriber_table[index].signal_id)); // 输出示例0x7ffd9a3c8b40[5](@ref)
printf("Error: Subscriber table is full\n");
exit_critical_section(saved_state);
return -1;
}
// 检查信号是否有订阅者
static unsigned char hasSubscribers(void *signal_id)
{
irq_state_t saved_state = enter_critical_section();
uint32_t index = hash(signal_id) % MAX_SUBSCRIBERS;
uint32_t original_index = index;
do
{
if (subscriber_table[index].signal_id == signal_id)
{
unsigned char result = subscriber_table[index].callback_count > 0;
exit_critical_section(saved_state);
return result;
}
if (subscriber_table[index].signal_id == NULL)
{
exit_critical_section(saved_state);
return 0; // 没有订阅者
}
index = (index + 1) % MAX_SUBSCRIBERS;
} while (index != original_index);
exit_critical_section(saved_state);
return 0; // 没有订阅者
}
// 内部一致性检查
static void internalConsistencyCheck(void)
{
for (uint32_t i = 0; i < MAX_SUBSCRIBERS; i++)
{
assert(subscriber_table[i].callback_count <= MAX_CALLBACKS);
}
}
// 处理队列中的信号, 调用所有匹配的回调函数
static void processSignals(void)
{
void *signal_id;
for (uint32_t priority = 0; priority < PRIORITY_LEVELS; priority++)
{
SignalQueue *q = &priority_queues[priority];
while (dequeue(q, &signal_id) == 0)
{
// 进入临界区保护 subscriber_table 的读取
irq_state_t saved_state = enter_critical_section();
uint32_t index = hash(signal_id) % MAX_SUBSCRIBERS;
uint32_t original_index = index;
unsigned char found = 0;
do
{
if (subscriber_table[index].signal_id == signal_id)
{
CallbackFunc *callbacks = subscriber_table[index].callbacks;
uint32_t callback_count = subscriber_table[index].callback_count;
// 复制回调函数指针, 避免在临界区外访问共享数据
CallbackFunc local_callbacks[MAX_CALLBACKS];
memcpy(local_callbacks, callbacks, sizeof(CallbackFunc) * callback_count);
exit_critical_section(saved_state);
// 在临界区外调用回调函数
for (uint32_t i = 0; i < callback_count; i++)
{
local_callbacks[i](signal_id);
}
found = 1;
break;
}
if (subscriber_table[index].signal_id == NULL)
{
exit_critical_section(saved_state);
break; // 没有订阅者
}
index = (index + 1) % MAX_SUBSCRIBERS;
} while (index != original_index);
if (!found)
{
printf("Warning: No subscribers found for signal %p\n", signal_id);
}
}
}
internalConsistencyCheck(); // 处理完所有信号后进行一致性检查
}
// 初始化框架
void initFramework(void)
{
irq_state_t saved_state = enter_critical_section();
for (uint32_t i = 0; i < PRIORITY_LEVELS; i++)
{
initQueue(&priority_queues[i]);
}
memset(subscriber_table, 0, sizeof(subscriber_table));
exit_critical_section(saved_state);
}
// 将信号请求添加到指定优先级的队列中
int32_t publishMessage(void *signal_id, uint8_t priority)
{
if ((uint32_t)priority >= PRIORITY_LEVELS)
{
printf("Error: Invalid priority\n");
return -1;
}
if (hasSubscribers(signal_id))
{
return enqueue(&priority_queues[priority], signal_id);
}
else return 1;
}
// 处理所有优先级的信号
void processMessages(void)
{
processSignals();
}
// 获取当前队列中的信号数量
int32_t getSignalCount(uint32_t priority)
{
if (priority >= PRIORITY_LEVELS)
{
printf("Error: Invalid priority\n");
return -1;
}
return priority_queues[priority].count;
}
// 获取订阅者数量
uint32_t getSubscriberCount(void)
{
uint32_t count = 0;
irq_state_t saved_state = enter_critical_section();
for (uint32_t i = 0; i < MAX_SUBSCRIBERS; i++)
{
if (subscriber_table[i].signal_id != NULL)
{
count++;
}
}
exit_critical_section(saved_state);
return count;
}

47
app/app_frm_signal.h Normal file
View File

@@ -0,0 +1,47 @@
#ifndef APP_FRM_SIGNAL_H
#define APP_FRM_SIGNAL_H
#ifdef __cplusplus
extern "C"
{
#endif
#include <stdint.h>
#include "app_dependence.h"
#define MAX_SIGNALS 500u // 每个优先级的最大信号数量
#define MAX_SUBSCRIBERS 100u // 不同信号的订阅者数量 20250519 解决列表满的问题
#define MAX_CALLBACKS 25u // 每个信号最多支持多少订阅者
#define PRIORITY_LEVELS 2u // 优先级层次
// 回调函数类型定义
typedef void (*CallbackFunc)(void *signal_id);
// 函数声明
void initFramework(void);
int32_t subscribe(void *signal_id, CallbackFunc callback);
int32_t publishMessage(void *signal_id, uint8_t priority);
void processMessages(void);
int32_t getSignalCount(uint32_t priority);
uint32_t getSubscriberCount(void);
// 进入临界区,禁用中断,并返回之前的中断状态
static inline irq_state_t enter_critical_section(void)
{
return arch_irq_save();
}
// 退出临界区,恢复之前的中断状态
static inline void exit_critical_section(irq_state_t saved_state)
{
arch_irq_restore(saved_state);
}
#ifdef __cplusplus
}
#endif
#endif // APP_FRM_SIGNAL_H

165
app/app_frm_timer.c Normal file
View File

@@ -0,0 +1,165 @@
#include "app_config.h"
#include "interface.h"
#include "app_frm_timer.h"
#include "app_frm_signal.h"
// 全局计时器列表头指针
static Timer *timer_list = NULL;
// 添加一个静态变量来跟踪当前定时器数量
static uint32_t current_timer_count = 0;
// 初始化定时器
void timerInit(Timer *timer)
{
if (timer == NULL)
{
return;
}
timer->target_time = 0;
timer->elapsed_time = 0;
timer->start_time = 0;
timer->active = 0;
timer->priority = 1; // 默认优先级为1
timer->next = NULL;
}
// 修改 timerStart 函数
void timerStart(Timer *timer, uint32_t target_time, unsigned char priority)
{
if (timer == NULL || target_time == 0)
{
printf("Error: Null timer pointer or invalid target time\n");
return;
}
// 检查定时器是否已经在列表中
Timer *current = timer_list;
while (current != NULL)
{
if (current == timer)
{
// 定时器已在列表中, 只需更新其参数
irq_state_t saved_state = enter_critical_section();
timer->target_time = target_time;
timer->start_time = getCurrentTime();
timer->elapsed_time = 0;
timer->active = 1;
timer->priority = priority;
exit_critical_section(saved_state);
return;
}
current = current->next;
}
// 检查是否达到最大定时器数量
if (current_timer_count >= MAX_TIMERS)
{
printf("Error: Maximum number of timers reached\n");
return;
}
// 初始化新定时器
irq_state_t saved_state = enter_critical_section();
timer->target_time = target_time;
timer->start_time = getCurrentTime();
timer->elapsed_time = 0;
timer->active = 1;
timer->priority = priority;
// 将定时器插入到定时器列表
timer->next = timer_list;
timer_list = timer;
current_timer_count++;
exit_critical_section(saved_state);
}
// 停止定时器
void timerStop(Timer *timer)
{
if (timer == NULL)
{
return;
}
irq_state_t saved_state = enter_critical_section();
Timer *current = timer_list;
Timer *prev = NULL;
while (current != NULL)
{
if (current == timer)
{
// 从链表中移除定时器
if (prev == NULL)
{
timer_list = current->next;
}
else
{
prev->next = current->next;
}
current_timer_count--;
timer->active = 0;
timer->next = NULL; // 断开链接
break;
}
prev = current;
current = current->next;
}
exit_critical_section(saved_state);
}
// 更新所有定时器, 在定时器中断中调用
void timerUpdateAll(void)
{
irq_state_t saved_state = enter_critical_section();
Timer *prev = NULL;
Timer *current = timer_list;
while (current != NULL)
{
if (current->active)
{
current->elapsed_time++;
if (current->elapsed_time >= current->target_time)
{
current->active = 0;
// 发送定时器过期消息
publishMessage((void *)(uintptr_t)current, current->priority);
// 从链表中移除已过期的定时器
if (prev == NULL)
{
timer_list = current->next;
}
else
{
prev->next = current->next;
}
current_timer_count--;
Timer *expired_timer = current;
current = current->next;
expired_timer->next = NULL; // 断开链接
continue; // 跳过前进 prev 指针
}
}
prev = current;
current = current->next;
}
exit_critical_section(saved_state);
}
// 获取当前定时器数量
uint32_t getCurrentTimerCount(void)
{
return current_timer_count;
}

35
app/app_frm_timer.h Normal file
View File

@@ -0,0 +1,35 @@
#ifndef APP_FRM_TIMER_H
#define APP_FRM_TIMER_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define MAX_TIMERS 100 // 定义最大定时器数量
// 定时器结构体定义
typedef struct Timer {
uint32_t target_time;
uint32_t elapsed_time;
uint32_t start_time;
unsigned char active;
unsigned char priority;
struct Timer *next;
} Timer;
// 函数声明
void timerInit(Timer *timer);
void timerStart(Timer *timer, uint32_t target_time, unsigned char priority);
void timerStop(Timer *timer);
void timerUpdateAll(void);
uint32_t getCurrentTimerCount(void);
#ifdef __cplusplus
}
#endif
#endif // APP_FRM_TIMER_H

227
app/app_light.c Normal file
View File

@@ -0,0 +1,227 @@
#include "app_config.h"
#include "interface.h"
#include "app_frm_monitor.h"
#include "app_frm_signal.h"
#include "app_frm_timer.h"
#include "app_param_manage.h"
#include "app_light.h"
#include "app_power.h"
// 声明 light_data 变量
LightSystem light_data;
// ... existing code ...
// 定义灯光按钮状态枚举
typedef enum {
BUTTON_STATE_INITIAL,
BUTTON_STATE_SHORT_PRESS,
BUTTON_STATE_DOUBLE_PRESS_DETECTED,
BUTTON_STATE_SECOND_PRESS_DETECTED
} LightButtonState;
// 定义灯光按钮结构体
typedef struct {
LightButtonState state;
uint32_t press_start_time;
uint32_t release_start_time;
uint8_t is_light_on;
Timer timer;
} LightButton;
// 全局变量
static LightButton light_button = {BUTTON_STATE_INITIAL, 0, 0, 0, {0}};
static uint8_t power_state = 0;
// 灯光按钮处理函数
static void handleLightButton(void)
{
switch (light_button.state)
{
case BUTTON_STATE_INITIAL:
if (light_data.light_switch == app_close())
{
light_button.state = BUTTON_STATE_SHORT_PRESS;
timerStart(&light_button.timer, 300, 0); // 启动短按定时器300ms
}
break;
case BUTTON_STATE_SHORT_PRESS:
if (light_data.light_switch == app_open())
{
if (light_button.timer.active) // 定时器未到期,短按完成,等待双击
{
light_button.state = BUTTON_STATE_DOUBLE_PRESS_DETECTED;
timerStart(&light_button.timer, 300, 0); // 启动双击等待定时器300ms
}
}
else if (!light_button.timer.active) // 短按定时器到期,重置为初始状态
{
light_button.state = BUTTON_STATE_INITIAL;
}
break;
case BUTTON_STATE_DOUBLE_PRESS_DETECTED:
if (light_data.light_switch == app_close())
{
light_button.state = BUTTON_STATE_SECOND_PRESS_DETECTED;
timerStart(&light_button.timer, 300, 0); // 启动第二次按下定时器300ms
}
else if (!light_button.timer.active) // 双击等待定时器到期,重置为初始状态
{
light_button.state = BUTTON_STATE_INITIAL;
}
break;
case BUTTON_STATE_SECOND_PRESS_DETECTED:
if (light_data.light_switch == app_open())
{
if (!light_button.timer.active) // 第二次按下完成,切换灯光状态
{
light_button.is_light_on = !light_button.is_light_on;
printf("LightButton: is_light_on = %d\n", light_button.is_light_on);
light_button.state = BUTTON_STATE_INITIAL;
}
}
else if (!light_button.timer.active) // 第二次按下定时器到期,重置为初始状态
{
light_button.state = BUTTON_STATE_INITIAL;
}
break;
default:
light_button.state = BUTTON_STATE_INITIAL;
break;
}
}
// 灯光输出处理函数
static void lightOutput(void *signal_id)
{
(void)signal_id;
// 根据当前状态,控制各个灯光
for (int32_t i = 0; i < LIGHT_COUNT; i++)
{
uint8_t state_value = (light_data.states[i] == LIGHT_ON) ? setLightOn() : setLightOff();
// 先判断灯光类型并设置状态
switch (i)
{//正常所有灯光熄灭
case LIGHT_HEAD://头灯前面4个灯
un_inf_can_kgf_output2.bit_data.KGF07 = state_value;
un_inf_can_kgf_output2.bit_data.KGF09 = state_value;
break;
case LIGHT_TAIL://尾灯后面4个灯
un_inf_can_kgf_output2.bit_data.KGF11 = state_value;
un_inf_can_kgf_output2.bit_data.KGF13 = state_value;
break;
case LIGHT_LEFT_TURN://左转向左边4个灯
un_inf_can_kgf_output2.bit_data.KGF08 = state_value;
un_inf_can_kgf_output2.bit_data.KGF12 = state_value;
break;
case LIGHT_RIGHT_TURN://右转向灯右边4个灯
un_inf_can_kgf_output2.bit_data.KGF10 = state_value;
un_inf_can_kgf_output2.bit_data.KGF14 = state_value;
break;
case LIGHT_BRAKE://刹车灯,四个黄灯
un_inf_can_kgf_output2.bit_data.KGF11 = state_value;
un_inf_can_kgf_output2.bit_data.KGF13 = state_value;
break;
case LIGHT_ALARM://报警灯,四个红灯
un_inf_can_kgf_output2.bit_data.KGF11 = state_value;
un_inf_can_kgf_output2.bit_data.KGF13 = state_value;
break;
}
}
// 灯的状态有变化就存入参数一个灯对应一位共6位
for (int32_t i = 0; i < LIGHT_COUNT; i++)
{
light_data.light_state |= (light_data.states[i] << i);
}
if (light_data.light_state != light_data.old_light_state)
{
setParam("lightSt", (float)light_data.light_state);
light_data.old_light_state = light_data.light_state;
}
publishMessage(&un_inf_can_kgf_output2, 1);
}
// 灯光状态处理函数
static void lightProcess(void *signal_id)
{
(void)signal_id;
if(0 != power_state)//处于非掉电模式才能打开
{
// 调用按钮处理函数
handleLightButton();
}
else
{
light_button.state = BUTTON_STATE_INITIAL;//一直保持初始化模式
light_button.is_light_on = LIGHT_OFF;//一直关闭
}
// 根据双击标志控制灯光输出,相当于灯光总开关
for (int32_t i = 0; i < LIGHT_COUNT; i++)
{
light_data.states[i] = (LightState)(light_button.is_light_on);
}
lightOutput(NULL);
timerStart(&light_data.timer_function, 100, 1);
}
// 处理输入信号的函数
static void lightInput(void *signal_id)
{
// LightSystem old_data = light_data;
// 填充数据
if ( (signal_id == &un_remote_control_input) && (1 == un_remote_control_input.bit_data.enable) )// 遥控器断线,不更新数据
{
// 保存遥控器输入开关状态
light_data.light_switch = un_remote_control_input.bit_data.switch_d ? LIGHT_ON : LIGHT_OFF;
}
else if(signal_id == &power_data)
{
power_state = power_data.current_state;
}
}
// APP模块的初始化
void lightAppInit(void)
{
// 初始化时恢复灯光状态
light_data.light_state = (uint8_t)getParam("lightSt");
light_data.old_light_state = light_data.light_state;
// 根据灯光状态恢复灯光
for (int32_t i = 0; i < LIGHT_COUNT; i++)
{
light_data.states[i] = (LightState)( (light_data.light_state >> i) & 1 );
}
// 初始化
memset(&light_data, 0, sizeof(LightSystem));
for (int32_t i = 0; i < LIGHT_COUNT; i++)
{
light_data.states[i] = LIGHT_OFF;
light_data.brightness[i] = 255; // 默认最大亮度
light_data.blink_state[i] = 0; // 初始化闪烁状态
light_data.blink_interval[i] = 500; // 默认闪烁间隔500ms
}
// 订阅输入信号,处理灯光逻辑
subscribe(&un_remote_control_input, lightInput);
subscribe(&power_data, lightInput);
// 订阅定时器
subscribe(&light_data.timer_function, lightProcess);
timerStart(&light_data.timer_function, 500, 1);
printf("app_light: initial OK \n");
}

62
app/app_light.h Normal file
View File

@@ -0,0 +1,62 @@
#ifndef APP_LIGHT_H
#define APP_LIGHT_H
#ifdef __cplusplus
extern "C"
{
#endif
// 定义灯光状态枚举
typedef enum
{
LIGHT_OFF,
LIGHT_ON,
LIGHT_BLINK
} LightState;
// 定义灯光类型枚举
typedef enum
{
LIGHT_HEAD,
LIGHT_TAIL,
LIGHT_LEFT_TURN,
LIGHT_RIGHT_TURN,
LIGHT_BRAKE,
LIGHT_ALARM,
LIGHT_COUNT
} LightType;
typedef struct
{
LightState states[LIGHT_COUNT];
uint8_t brightness[LIGHT_COUNT];
uint16_t blink_interval[LIGHT_COUNT]; // 闪烁间隔(毫秒)
uint8_t blink_state[LIGHT_COUNT]; // 闪烁状态
Timer timer;// 设置定时器,定时调用灯光处理函数
uint8_t old_light_state; // 旧的灯光状态
uint8_t light_state; // 当前的灯光状态
Timer timer_function; // 函数定时器
uint8_t light_switch; // 当前的灯光开关状态
uint8_t double_click_flag;//双击标志
} LightSystem;
// 在头文件中声明外部变量
extern LightSystem light_data;
// 使用内联函数
static inline uint8_t setLightOn(void) { return 1; }
static inline uint8_t setLightOff(void) { return 0; }
void lightAppInit(void);
void setLightState(LightType light, LightState state);
void setLightBrightness(LightType light, uint8_t brightness);
void setBlinkInterval(uint16_t interval);
#ifdef __cplusplus
}
#endif
#endif // APP_LIGHT_H

464
app/app_param_manage.c Normal file
View File

@@ -0,0 +1,464 @@
#include "app_config.h"
#include "app_frm_monitor.h"
#include "app_frm_signal.h"
#include "app_frm_timer.h"
#include "app_param_manage.h"
#define E2_RESERVE_COUNT 0x20 //增加IP地址 修改为0x20 20250110
// 待发送的参数请求信号
UnParamRequest un_param_request1 ;
UnParamRequest un_param_request2;
RequestContext request_send ;
RequestContext request_context ;
uint8_t read_write_e2_finished = 0;
// 定义全局信号实例,读写信号现在包括 offset 和 size
ParamSignal param_signal = {
.param_ptr = NULL, // 参数指针初始化为 NULL
.type = READ_OPERATION, // 操作类型设置为读操作
.offset = 0, // 整个数据块的偏移
.size = sizeof(param_manager.arr) // 整个数据块的大小
};
// 全局变量:初始化参数名称结构体
ParamNames param_names = {
#define X(name) .name = #name,
PARAM_LIST
#undef X
};
UnParamManager param_manager ;
static uint8_t is_param_initialized = 0;
// 打印所有参数的名称和值, 每行 4 个参数
void printParams()
{
unsigned int param_count = 0;
#define X(name) \
printf("%-8s: %-8.2f", param_names.name, param_manager.bit_data.name); \
param_count++; \
if (param_count % 4 == 0) { \
printf("\n"); \
} else { \
printf(" "); \
}
PARAM_LIST
#undef X
// 如果最后一行不足 4 个参数, 打印换行
if (param_count % 4 != 0)
{
printf("\n");
}
}
void writeByte24c02(uint16_t addr, uint8_t data)
{
if(0 != wrbyte_24c02(addr,data))
{
printf("E2PROM write error!\n");
}
}
uint8_t readByte24c02(uint16_t addr)
{
return rdbyte_24c02(addr);
}
// 定义一个通用的 EEPROM 访问函数
uint8_t accessEeprom(size_t offset, void *data, size_t size, OperationType type)
{
if (data == NULL || size == 0)
{
return 1; // 返回错误状态,表示无效的参数
}
uint8_t *byte_data = (uint8_t *)data; // 将 void* 转换为 uint8_t*,方便逐字节操作
size_t index;
if (type == WRITE_OPERATION)
{
// 写入操作
for (index = 0; index < size; index++)
{
writeByte24c02((uint16_t)(offset + index + E2_RESERVE_COUNT), byte_data[index]);
udelay(4000);//写入一个字节延时4ms
}
// 校验
for (index = 0; index < size; index++)
{
if (readByte24c02((uint16_t)(offset + index + E2_RESERVE_COUNT)) != byte_data[index])
{
return 2; // 返回错误状态,表示写入验证失败
}
}
}
else
{
// 读取操作
for (index = 0; index < size; index++)
{
byte_data[index] = readByte24c02((uint16_t)(offset + index + E2_RESERVE_COUNT));
}
}
return 0; // 返回状态,表示成功
}
void handleParamOp(void *data)
{
ParamSignal *signal = (ParamSignal *)data;
if (signal->param_ptr == NULL)
{
// 操作整个参数管理器
if (accessEeprom(0, param_manager.arr, sizeof(param_manager.arr), signal->type) == 0)
{
read_write_e2_finished = 1;
publishMessage(&read_write_e2_finished, 1); // 读写成功
}
else
{
read_write_e2_finished = 2;
publishMessage(&read_write_e2_finished, 1); // 读写失败
}
}
else
{
// 根据信号中的偏移和大小操作单个参数
if (accessEeprom(signal->offset, signal->param_ptr, signal->size, signal->type) == 0)
{
read_write_e2_finished = 1;
publishMessage(&read_write_e2_finished, 1); // 读写成功
}
else
{
read_write_e2_finished = 2;
publishMessage(&read_write_e2_finished, 1); // 读写失败
}
}
}
uint8_t calculateCRC(const uint8_t* data, uint32_t length) {
uint8_t crc = 0;
for (uint32_t i = 0; i < length; ++i) {
crc += data[i]; // 简单的校验和,按字节累加
}
return crc;
}
float readParameter(const char *param_name) {
float float_value = 0;
unsigned int offset = 0;
#define X(name) \
if (strcmp(param_name, param_names.name) == 0) { \
accessEeprom(offset, &param_manager.bit_data.name,sizeof(param_manager.bit_data.name), READ_OPERATION);\
memcpy(&float_value, &param_manager.bit_data.name, sizeof(param_manager.bit_data.name)); \
return float_value; \
} \
offset += 4;
PARAM_LIST
#undef X
printf("Parameter not found: %s\n", param_name);
return 0;
}
void writeParameter(const char *param_name, const uint8_t *data) {
unsigned int offset = 0;
#define X(name) \
if (strcmp(param_name, param_names.name) == 0) { \
memcpy(&param_manager.bit_data.name, data, sizeof(param_manager.bit_data.name)); \
accessEeprom(offset, &param_manager.bit_data.name,sizeof(param_manager.bit_data.name), WRITE_OPERATION);\
return; \
} \
offset += 4;
PARAM_LIST
#undef X
printf("Parameter not found: %s\n", param_name);
}
void sendParamRequestResponse(UnParamRequest *paramRequest, uint32_t sender_ip, uint16_t sender_port, uint8_t isWriteOperation) {
// 准备响应帧
paramRequest->bit_data.frame_header = 0xFF80;
paramRequest->bit_data.frame_type = 0x002B;
paramRequest->bit_data.frame_length = sizeof(StrParamRequest);
paramRequest->bit_data.accumulated = 0;
paramRequest->bit_data.request_id = isWriteOperation ? 98 : 99;
paramRequest->bit_data.crc = calculateCRC(paramRequest->arr, sizeof(paramRequest->arr) - 1);
request_send.param_request = paramRequest;
request_send.sender_ip = sender_ip;
request_send.sender_port = sender_port;
// 发送信号从UDP发送
publishMessage(&request_send, 1);
}
void processReadAllParams(UnParamRequest *paramRequest, uint32_t sender_ip, uint16_t sender_port) {
uint8_t allParams[256][4]; // Size based on E2 size
unsigned int i = 0;
float param_value;
uint8_t exceeded_max = 0; // 新增标志变量
// 清零 paramRequest
memset(paramRequest, 0, sizeof(UnParamRequest));
accessEeprom(0, param_manager.arr, sizeof(param_manager.arr), READ_OPERATION);
printf("Sending parameter data:\n");
#define X(name) \
if (!exceeded_max) { \
if (i < 256) { \
strncpy((char *)paramRequest->bit_data.param_name[i], #name, sizeof(paramRequest->bit_data.param_name[i]) - 1); \
paramRequest->bit_data.param_name[i][sizeof(paramRequest->bit_data.param_name[i]) - 1] = '\0'; \
memcpy(allParams[i], &param_manager.bit_data.name, sizeof(param_manager.bit_data.name)); \
memcpy(&param_value, allParams[i], sizeof(float)); \
printf("Parameter name: %-20s Value: %f\n", #name, param_value); \
i++; \
} else { \
printf("Warning: Exceeded maximum number of parameters\n"); \
exceeded_max = 1; \
} \
}
PARAM_LIST
#undef X
// Pack all parameter data into paramRequest
memcpy(paramRequest->bit_data.data, allParams, sizeof(allParams));
printf("Total parameters sent: %d\n", i);
// Send response
sendParamRequestResponse(paramRequest, sender_ip, sender_port, 0);
}
void processWriteRequestFrame(UnParamRequest *paramRequest, uint32_t sender_ip, uint16_t sender_port) {
float value;
printf("Processing write request.\n");
// 先发送信号,然后从结构体读数
for (int i = 0; i < 256; ++i) {
if (strlen((char *)paramRequest->bit_data.param_name[i]) > 0) {
writeParameter(paramRequest->bit_data.param_name[i], paramRequest->bit_data.data[i]);
printf("paramRequest->bit_data.param_name[i]:%s \n",paramRequest->bit_data.param_name[i]);
memcpy(&value, paramRequest->bit_data.data[i], sizeof(float));
printf("paramRequest->bit_data.data[i]:%f \n", value);
}
}
// 发送响应,发送所有参数
processReadAllParams(paramRequest, sender_ip, sender_port);
}
void processReadRequestFrame(UnParamRequest *paramRequest, uint32_t sender_ip, uint16_t sender_port) {
// 处理读请求的逻辑
printf("Processing read request.\n");
// 清零 paramRequest
memset(paramRequest, 0, sizeof(UnParamRequest));
// 先发送信号,然后从结构体读数
for (int i = 0; i < 256; ++i) {
if (strlen((char *)paramRequest->bit_data.param_name[i]) > 0) {
float readData = readParameter(paramRequest->bit_data.param_name[i]);
memcpy(paramRequest->bit_data.data[i], &readData, sizeof(paramRequest->bit_data.data[i]));
}
}
// 发送响应
sendParamRequestResponse(paramRequest, sender_ip, sender_port, 0);
}
void OnParamSignal(void *data)
{
RequestContext *signal = (RequestContext *)data;
uint8_t *datagram = (uint8_t *)signal->param_request->arr;
uint16_t request_id = ((uint16_t)datagram[7] << 8) | (uint16_t)datagram[8];// 大端模式
// 调试输出
printf("Received request ID: 0x%04X\n", request_id);
// 计算CRC
uint8_t calculatedCrc = calculateCRC(datagram, sizeof(UnParamRequest) - 1);
uint8_t receivedCrc = datagram[sizeof(UnParamRequest) - 1];
// 比较CRC
if (calculatedCrc != receivedCrc)
{
printf("CRC check failed, discarding data\n");
printf("Calculated CRC: 0x%02X, Received CRC: 0x%02X\n", calculatedCrc, receivedCrc);
return;
}
printf("CRC check passed\n");
if (request_id == 100)
{ // 读请求
processReadRequestFrame(signal->param_request, signal->sender_ip, signal->sender_port);
}
else if (request_id == 101)
{ // 写请求
processWriteRequestFrame(signal->param_request, signal->sender_ip, signal->sender_port);
}
else if (request_id == 102)
{ // 读取所有参数
processReadAllParams(signal->param_request, signal->sender_ip, signal->sender_port);
}
else
{
printf("Unknown request ID.\n");
return;
}
}
float getParam(const char *param_name)
{
// 检查是否已初始化
if (!is_param_initialized)
{
printf("Parameters not initialized, reinitializing\n");
accessEeprom(0, param_manager.arr, sizeof(param_manager.arr), READ_OPERATION);//Read all parameters from E2
is_param_initialized = 1; // Mark as initialized
printParams();
return 0.0f;
}
// 检查参数名是否为空
if (param_name == NULL)
{
printf("Error: Parameter name is empty\n");
return 0.0f;
}
// 遍历所有参数
#define X(name) \
if (strcmp(param_name, #name) == 0) \
{ \
return param_manager.bit_data.name; \
}
PARAM_LIST
#undef X
// 如果没有找到匹配的参数名
printf("Error: Parameter %s not found\n", param_name);
return 0.0f;
}
// setParam 函数
uint8_t setParam(const char *param_name, float value)
{
// 检查参数名是否为空
if (param_name == NULL)
{
printf("Error: Parameter name is empty\n");
return 2; // 返回错误码
}
// 参数名和值写入EEPROM先转成字节数组
uint8_t data[sizeof(float)];
memcpy(data, &value, sizeof(float));
writeParameter(param_name, data);
// 更新参数
#define X(name) \
if (strcmp(param_name, #name) == 0) \
{ \
memcpy(&param_manager.bit_data.name, data, sizeof(param_manager.bit_data.name)); \
}
PARAM_LIST
#undef X
return 0;
}
void paramAppInit(void)
{
// 初始化全局变量
memset(&un_param_request1, 0, sizeof(UnParamRequest));
memset(&un_param_request2, 0, sizeof(UnParamRequest));
// 正确初始化 RequestContext 结构体
request_send.param_request = &un_param_request1;
request_send.sender_ip = 0;
request_send.sender_port = 0;
request_context.param_request = &un_param_request2;
request_context.sender_ip = 0;
request_context.sender_port = 0;
// 上电读取所有参数
memset(param_manager.arr, 0, sizeof(param_manager.arr));
accessEeprom(0, param_manager.arr, sizeof(param_manager.arr), READ_OPERATION);
// 初始化每个参数
// param_manager.bit_data.whl_bas = 1.5f; // 初始化轮距
// param_manager.bit_data.max_rpm = 5500.0f; // 初始化最大转速
// param_manager.bit_data.whl_dia = 0.6f; // 初始化轮直径
// param_manager.bit_data.max_acc = 1.0f; // 初始化最大加速度
// param_manager.bit_data.spd_kp = 5.0f; // 初始化速度控制 KP
// param_manager.bit_data.spd_ki = 1.0f; // 初始化速度控制 KI
// param_manager.bit_data.spd_kd = 0.0f; // 初始化速度控制 KD
// param_manager.bit_data.spd_il = 5.0f; // 初始化速度控制 IL
// param_manager.bit_data.spd_ol = 5.0f; // 初始化速度控制 OL
// param_manager.bit_data.crv_kp = 1.0f; // 初始化曲线控制 KP
// param_manager.bit_data.crv_ki = 0.0f; // 初始化曲线控制 KI
// param_manager.bit_data.crv_kd = 0.0f; // 初始化曲线控制 KD
// param_manager.bit_data.crv_il = 2.0f; // 初始化曲线控制 IL
// param_manager.bit_data.crv_ol = 2.0f; // 初始化曲线控制 OL
// param_manager.bit_data.brk_on = 1500.0f; // 初始化制动开启参数
// param_manager.bit_data.brk_off = 800.0f; // 初始化制动关闭参数
// param_manager.bit_data.maxTorq = 60.0f; // 初始化最大扭矩
// param_manager.bit_data.feedPwr = 10000.0f; // 初始化馈电功率
// param_manager.bit_data.dispPwr = 10000.0f; // 初始化显示功率
// param_manager.bit_data.VehMass = 700.0f; // 初始化车辆质量
// param_manager.bit_data.gRatio = 28.0f; // 初始化减速比
// param_manager.bit_data.prCTime = 5.0f; // 初始化预充时间
// param_manager.bit_data.brk_pos = 0.0f; // 初始化刹车位置, 0表示未刹车
// param_manager.bit_data.pwr_sta = 0.0f; // 初始化电源状态
// param_manager.bit_data.lightSt = 0.0f; // 初始化灯光状态
// param_manager.bit_data.pwr_btn = 0.0f; // 初始化电源按钮状态
// param_manager.bit_data.test = 0.0f; // 初始化测试参数
// 订阅信号
subscribe(&param_signal, handleParamOp);
subscribe(&request_context, OnParamSignal);// 接收到上位机读写参数信号
printParams();//打印所有参数
is_param_initialized = 1; // 标记初始化完成
printf("paramAPP init OK! %d\n",getCurrentTime());
}

148
app/app_param_manage.h Normal file
View File

@@ -0,0 +1,148 @@
#ifndef APP_PARAM_MANAGE_H
#define APP_PARAM_MANAGE_H
#ifdef __cplusplus
extern "C"
{
#endif
#include "app_config.h"
// 定义参数列表宏
#define PARAM_LIST \
X(whl_bas) \
X(max_rpm) \
X(whl_dia) \
X(max_acc) \
X(spd_kp) \
X(spd_ki) \
X(spd_kd) \
X(spd_il) \
X(spd_ol) \
X(crv_kp) \
X(crv_ki) \
X(crv_kd) \
X(crv_il) \
X(crv_ol) \
X(brk_on) \
X(brk_off) \
X(maxTorq) \
X(feedPwr) \
X(dispPwr) \
X(VehMass) \
X(gRatio) \
X(prCTime) \
X(brk_pos) \
X(pwr_sta) \
X(lightSt) \
X(pwr_btn) \
X(sleepTm) \
X(wakeTm) \
X(R_maxP) \
X(R_minP) \
X(R_zeroP) \
X(R_speed) \
X(L_maxP) \
X(L_minP) \
X(L_zeroP) \
X(L_speed) \
X(brk_rev) \
X(tra_wid) \
X(mot_kp) \
X(mot_ki) \
X(mot_kd) \
X(mot_il) \
X(mot_ol) \
X(diff_sp) \
X(test)
// 定义一个包含所有参数名称的结构体
typedef struct {
#define X(name) const char* name;
PARAM_LIST
#undef X
} ParamNames;
// 参数结构体不能使用位域不要超过E2的大小, 1K byte
typedef struct
{
#define X(name) float name;
PARAM_LIST
#undef X
} ParamData;
typedef union
{
ParamData bit_data; // 使用定义的结构体变量名
uint8_t arr[sizeof(ParamData)]; // 通过结构体类型确定大小
} UnParamManager;
// 定义信号操作类型
typedef enum
{
READ_OPERATION,
WRITE_OPERATION
} OperationType;
// 定义信号数据结构
typedef struct
{
void *param_ptr; // 参数数据的指针
OperationType type; // 操作类型
size_t offset; // 参数在结构体中的偏移
size_t size; // 参数大小
} ParamSignal;
#pragma pack(push, 1)
typedef struct _StrParamRequest {
//--------------------------------------------------
uint16_t frame_header; // 帧头 固定值0xFF80 (16位)
uint16_t frame_type; // 帧类型 固定值0x002A (16位)
uint16_t frame_length; // 帧长 根据参数数据的长度动态设置 (16位)
uint8_t accumulated; // 累加值 按帧累加 (8位)
uint16_t request_id; // 请求帧ID 请求ID 100表示读101 表示写参数 (16位)
char param_name[256][8]; // 参数名称 标识要写入或读出的参数
uint8_t data[256][4]; // 数据 用于写入或读出的参数值一个参数最大4字节 (8位*4)
uint8_t crc; // CRC 按字节累加之和 取低8位 (8位)
} StrParamRequest;
typedef union _UnParamRequest {
StrParamRequest bit_data; // 使用定义的结构体变量名
unsigned char arr[sizeof(StrParamRequest)]; // 通过结构体类型确定大小
} UnParamRequest;
typedef struct {
UnParamRequest *param_request; // 指向 UnParamRequest 的指针
uint32_t sender_ip; // 发送方的 IP 地址使用标准的32位整数表示
uint16_t sender_port; // 发送方的端口号使用标准的16位整数表示
} RequestContext;
#pragma pack(pop)
extern UnParamRequest un_param_request;// 声明用于参数响应的帧实例
extern RequestContext request_context;
// 声明全局信号实例
extern ParamNames param_names;
extern UnParamManager param_manager; // 全局参数管理实例
extern ParamSignal param_signal;
extern uint8_t read_write_e2_finished;
extern RequestContext request_send;// 待发送的参数请求信号
uint8_t access_eeprom(size_t offset, void *data, size_t size, OperationType type);
void paramAppInit(void);
// 在适当的位置添加以下函数声明
float getParam(const char *param_name);
uint8_t setParam(const char *param_name, float value);
void printParams(void);
void handleParamOp(void *data);
void OnParamSignal(void *data);
#ifdef __cplusplus
}
#endif
#endif // APP_PARAM_MANAGE_H

130
app/app_pid.c Normal file
View File

@@ -0,0 +1,130 @@
#include "app_config.h"
#include "app_pid.h"
// PID控制器初始化
void initializePid(PID_t *pid, pid_mode_t mode, float dtMin)
{
pid->mode = mode;
pid->dt_min = dtMin > SIGMA ? dtMin : SIGMA;
pid->kp = 0.0f;
pid->ki = 0.0f;
pid->kd = 0.0f;
pid->integral = 0.0f;
pid->integral_limit = 0.0f;
pid->output_limit = 0.0f;
pid->error_previous = 0.0f;
pid->last_output = 0.0f;
}
// 设置PID参数
int32_t setPidParameters(PID_t *pid, float kp, float ki, float kd, float integralLimit, float outputLimit)
{
int32_t ret = 0;
if (isfinite(kp)) {
pid->kp = kp;
} else {
ret = -1;
}
if (isfinite(ki)) {
pid->ki = ki;
} else {
ret = -2;
}
if (isfinite(kd)) {
pid->kd = kd;
} else {
ret = -3;
}
if (isfinite(integralLimit)) {
pid->integral_limit = integralLimit;
} else {
ret = -4;
}
if (isfinite(outputLimit)) {
pid->output_limit = outputLimit;
} else {
ret = -5;
}
return ret;
}
/**
* @brief 计算PID控制器的输出
*
* @param pid 指向PID_t结构体的指针包含PID控制器的状态和参数
* @param sp 设定值(Setpoint),期望系统达到的目标值
* @param val 当前值(Current Value),系统的实际测量值
* @param val_dot 当前值的导数(Derivative of Current Value),即测量值的变化率(用于微分项计算)
* @param dt 时间增量(Time Increment),两次调用之间的时间间隔,用于计算积分和微分
*
* @return float 返回PID控制器计算出的输出值
*/
float calculatePidOutput(PID_t *pid, float sp, float val, float val_dot, float dt)
{
// 检查输入参数的有效性
if (!isfinite(sp) || !isfinite(val) || !isfinite(val_dot) || !isfinite(dt) || dt < pid->dt_min) {
return pid->last_output;
}
// 计算误差
float error = sp - val;
// 根据模式计算微分项
float derivative = 0.0f;
switch (pid->mode) {
case PID_MODE_DERIVATIVE_CALC:
derivative = (error - pid->error_previous) / dt;
pid->error_previous = error;
break;
case PID_MODE_DERIVATIVE_CALC_NO_SP:
derivative = (-val - pid->error_previous) / dt;
pid->error_previous = -val;
break;
case PID_MODE_DERIVATIVE_SET:
derivative = -val_dot;
break;
default:
derivative = 0.0f;
break;
}
// 计算比例和微分项的输出
float output = (pid->kp * error) + (pid->kd * derivative);
// 计算积分项,并检查积分饱和
if (pid->ki > SIGMA) {
pid->integral += error * dt;
if (pid->integral > pid->integral_limit) {
pid->integral = pid->integral_limit;
} else if (pid->integral < -pid->integral_limit) {
pid->integral = -pid->integral_limit;
}
output += pid->ki * pid->integral;
}
// 限制输出范围
if (output > pid->output_limit) {
output = pid->output_limit;
} else if (output < -pid->output_limit) {
output = -pid->output_limit;
}
pid->last_output = output;
return output;
}
// 重置积分器
void resetPidIntegral(PID_t *pid)
{
pid->integral = 0.0f;
}

46
app/app_pid.h Normal file
View File

@@ -0,0 +1,46 @@
#ifndef PID_H
#define PID_H
#ifdef __cplusplus
extern "C" {
#endif
// 防止除零和其他误差的极小值
#define EPSILON 1e-5f
#define SIGMA EPSILON
#include "app_config.h"
// PID 控制模式
typedef enum {
PID_MODE_DERIVATIVE_NONE = 0, // PI 控制器模式,无微分项
PID_MODE_DERIVATIVE_CALC, // 根据当前误差计算微分项
PID_MODE_DERIVATIVE_CALC_NO_SP, // 根据当前值计算微分项,忽略设定值
PID_MODE_DERIVATIVE_SET // 使用外部提供的微分项值
} pid_mode_t;
// PID 控制器结构体
typedef struct {
pid_mode_t mode; // 控制模式
float dt_min; // 最小时间间隔
float kp; // 比例系数
float ki; // 积分系数
float kd; // 微分系数
float integral; // 积分累积值
float integral_limit; // 积分限幅
float output_limit; // 输出限幅
float error_previous; // 上一次的误差值
float last_output; // 上一次的输出值
} PID_t;
// 函数声明
void initializePid(PID_t *pid, pid_mode_t mode, float dtMin);
int32_t setPidParameters(PID_t *pid, float kp, float ki, float kd, float integralLimit, float outputLimit);
float calculatePidOutput(PID_t *pid, float sp, float val, float val_dot, float dt);
void resetPidIntegral(PID_t *pid);
#ifdef __cplusplus
}
#endif
#endif // PID_H

366
app/app_power.c Normal file
View File

@@ -0,0 +1,366 @@
#include "app_config.h"
#include "interface.h"
#include "app_frm_monitor.h"
#include "app_frm_signal.h"
#include "app_frm_timer.h"
#include "app_param_manage.h"
#include "app_power.h"
// 定义按钮状态枚举
typedef enum {
BUTTON_STATE_INITIAL,
BUTTON_STATE_SHORT_PRESS,
BUTTON_STATE_SHORT_PRESS_DETECTED,
BUTTON_STATE_WAIT_FOR_LONG_PRESS,
BUTTON_STATE_LONG_PRESS,
BUTTON_STATE_LONG_PRESS_WAIT
} ButtonState;
// 定义按钮结构体
typedef struct {
ButtonState state;
uint32_t press_start_time;
uint32_t release_start_time;
uint8_t is_power_on;
Timer timer;
uint8_t old_is_power_on;
Timer timer1;
} PowerButton;
// 全局变量
PowerSystem power_data;
static PowerButton power_button = {BUTTON_STATE_INITIAL, 0, 0, 0, {0},0};
// 电源按钮处理函数
static void handlePowerButton(void)
{
switch (power_button.state)
{
case BUTTON_STATE_INITIAL:
if (power_data.remote_power_switch == app_close())
{
power_button.state = BUTTON_STATE_SHORT_PRESS_DETECTED;
timerStart(&power_button.timer, 500, 0); // 启动短按定时器500ms
}
break;
case BUTTON_STATE_SHORT_PRESS_DETECTED:
if (power_data.remote_power_switch == app_open())
{
if (power_button.timer.active) // 定时器未到期,短按完成,启动等待长按定时器
{
power_button.state = BUTTON_STATE_WAIT_FOR_LONG_PRESS;
timerStart(&power_button.timer, 500, 0); // 启动等待长按定时器500ms
}
}
else if (!power_button.timer.active)// 短按定时器到期,按键仍被按下,视为无效,重置为初始状态
{
power_button.state = BUTTON_STATE_INITIAL;
}
break;
case BUTTON_STATE_WAIT_FOR_LONG_PRESS:
if (power_data.remote_power_switch == app_close())// 检测是否在等待时间内进行长按
{
power_button.state = BUTTON_STATE_LONG_PRESS;
timerStart(&power_button.timer, 1000, 0); // 启动长按定时器1000ms
}
else if (!power_button.timer.active) // 等待长按超时,重置为初始状态
{
power_button.state = BUTTON_STATE_INITIAL;
}
break;
case BUTTON_STATE_LONG_PRESS:
if (!power_button.timer.active)// 长按完成,切换电源状态 20250423 修改不需要判断松开按键就打开控制器
{
power_button.is_power_on = !power_button.is_power_on;
printf("PowerButton: is_power_on = %d\n", power_button.is_power_on);
power_button.state = BUTTON_STATE_LONG_PRESS_WAIT;
}
else if(power_data.remote_power_switch == app_open())
{
power_button.state = BUTTON_STATE_INITIAL;
printf("Long press for short duration");
}
else
break;
case BUTTON_STATE_LONG_PRESS_WAIT:
if (power_data.remote_power_switch == app_open())// 检测按键释放
{
power_button.state = BUTTON_STATE_INITIAL;
printf("Release the button");
}
default:
power_button.state = BUTTON_STATE_INITIAL;
break;
}
}
// 输出处理函数
static void powerOutput(void *signal_id)
{
(void)signal_id;
// 根据当前状态,控制各个设备的电源
switch (power_data.current_state)
{
case POWER_PRE_CHARGE:
publishMessage(&power_data.pre_charge_finish, 1);//发布预充完成信号100ms发送一次直到预充完成
un_inf_can_kgf_output1.bit_data.KGF04 = setPowerOn(); // 预充继电器
un_inf_can_kgf_output1.bit_data.KGF07 = setPowerOff(); // 高压继电器
un_inf_can_kgf_output1.bit_data.KGF08 = setPowerOff(); // 高压继电器
un_inf_can_kgf_output1.bit_data.KGF11 = setPowerOn(); // 低压继电器
un_inf_can_kgf_output1.bit_data.KGF12 = setPowerOn(); // 低压继电器
un_inf_can_kgf_output1.bit_data.KGF13 = setPowerOn(); // 低压充电
un_inf_can_kgf_output2.bit_data.KGF01 = setPowerOn(); // 计算机
un_inf_can_kgf_output2.bit_data.KGF02 = setPowerOn(); // 计算机
un_inf_can_kgf_output2.bit_data.KGF04 = setPowerOn(); // E3
un_inf_can_kgf_output2.bit_data.KGF15 = setPowerOn(); // 计算机
un_inf_can_kgf_output2.bit_data.KGF16 = setPowerOn(); // 计算机
un_inf_can_kgf_output2.bit_data.KGF03 = setPowerOn(); // 遥控器
un_inf_can_kgf_output2.bit_data.KGF05 = setPowerOn(); // 网络交换机
un_inf_can_kgf_output2.bit_data.KGF06 = setPowerOn(); // 网络交换机
break;
case POWER_STANDBY:
// 初始状态,只开启基本设备
un_inf_can_kgf_output1.bit_data.KGF04 = setPowerOff(); // 预充继电器
un_inf_can_kgf_output1.bit_data.KGF07 = setPowerOff(); // 高压继电器
un_inf_can_kgf_output1.bit_data.KGF08 = setPowerOff(); // 高压继电器
un_inf_can_kgf_output1.bit_data.KGF11 = setPowerOff(); // 低压继电器
un_inf_can_kgf_output1.bit_data.KGF12 = setPowerOff(); // 低压继电器
un_inf_can_kgf_output1.bit_data.KGF13 = setPowerOn(); // 低压充电
un_inf_can_kgf_output2.bit_data.KGF01 = setPowerOn(); // 计算机
un_inf_can_kgf_output2.bit_data.KGF02 = setPowerOn(); // 计算机
un_inf_can_kgf_output2.bit_data.KGF04 = setPowerOn(); // E3
un_inf_can_kgf_output2.bit_data.KGF15 = setPowerOn(); // 计算机
un_inf_can_kgf_output2.bit_data.KGF16 = setPowerOn(); // 计算机
un_inf_can_kgf_output2.bit_data.KGF03 = setPowerOn(); // 遥控器
un_inf_can_kgf_output2.bit_data.KGF05 = setPowerOn(); // 网络交换机
un_inf_can_kgf_output2.bit_data.KGF06 = setPowerOn(); // 网络交换机
break;
case POWER_WORKING:
// 工作状态,除预充继电器外所有设备开启
un_inf_can_kgf_output1.bit_data.KGF04 = setPowerOff(); // 预充继电器
un_inf_can_kgf_output1.bit_data.KGF07 = setPowerOn(); // 高压继电器
un_inf_can_kgf_output1.bit_data.KGF08 = setPowerOn(); // 高压继电器
un_inf_can_kgf_output1.bit_data.KGF11 = setPowerOn(); // 低压继电器
un_inf_can_kgf_output1.bit_data.KGF12 = setPowerOn(); // 低压继电器
un_inf_can_kgf_output1.bit_data.KGF13 = setPowerOn(); // 低压充电
un_inf_can_kgf_output2.bit_data.KGF01 = setPowerOn(); // 计算机
un_inf_can_kgf_output2.bit_data.KGF02 = setPowerOn(); // 计算机
un_inf_can_kgf_output2.bit_data.KGF04 = setPowerOn(); // E3
un_inf_can_kgf_output2.bit_data.KGF15 = setPowerOn(); // 计算机
un_inf_can_kgf_output2.bit_data.KGF16 = setPowerOn(); // 计算机
un_inf_can_kgf_output2.bit_data.KGF03 = setPowerOn(); // 遥控器
un_inf_can_kgf_output2.bit_data.KGF05 = setPowerOn(); // 网络交换机
un_inf_can_kgf_output2.bit_data.KGF06 = setPowerOn(); // 网络交换机
break;
case POWER_EMERGENCY:
// 急停状态,断开高压
un_inf_can_kgf_output1.bit_data.KGF04 = setPowerOff(); // 预充继电器
un_inf_can_kgf_output1.bit_data.KGF07 = setPowerOff(); // 高压继电器
un_inf_can_kgf_output1.bit_data.KGF08 = setPowerOff(); // 高压继电器
un_inf_can_kgf_output1.bit_data.KGF11 = setPowerOn(); // 低压继电器
un_inf_can_kgf_output1.bit_data.KGF12 = setPowerOn(); // 低压继电器
un_inf_can_kgf_output1.bit_data.KGF13 = setPowerOn(); // 低压充电
un_inf_can_kgf_output2.bit_data.KGF01 = setPowerOn(); // 计算机
un_inf_can_kgf_output2.bit_data.KGF02 = setPowerOn(); // 计算机
un_inf_can_kgf_output2.bit_data.KGF04 = setPowerOn(); // E3
un_inf_can_kgf_output2.bit_data.KGF15 = setPowerOn(); // 计算机
un_inf_can_kgf_output2.bit_data.KGF16 = setPowerOn(); // 计算机
un_inf_can_kgf_output2.bit_data.KGF03 = setPowerOn(); // 遥控器
un_inf_can_kgf_output2.bit_data.KGF05 = setPowerOn(); // 网络交换机
un_inf_can_kgf_output2.bit_data.KGF06 = setPowerOn(); // 网络交换机
break;
case POWER_SLEEP:
// 休眠状态,关闭所有设备
un_inf_can_kgf_output1.bit_data.KGF04 = setPowerOff(); // 预充继电器
un_inf_can_kgf_output1.bit_data.KGF07 = setPowerOff(); // 高压继电器
un_inf_can_kgf_output1.bit_data.KGF08 = setPowerOff(); // 高压继电器
un_inf_can_kgf_output1.bit_data.KGF11 = setPowerOff(); // 低压继电器
un_inf_can_kgf_output1.bit_data.KGF12 = setPowerOff(); // 低压继电器
un_inf_can_kgf_output1.bit_data.KGF13 = setPowerOn(); // 低压充电
un_inf_can_kgf_output2.bit_data.KGF01 = setPowerOn(); // 计算机
un_inf_can_kgf_output2.bit_data.KGF02 = setPowerOn(); // 计算机
un_inf_can_kgf_output2.bit_data.KGF04 = setPowerOn(); // E3
un_inf_can_kgf_output2.bit_data.KGF15 = setPowerOn(); // 计算机
un_inf_can_kgf_output2.bit_data.KGF16 = setPowerOn(); // 计算机
un_inf_can_kgf_output2.bit_data.KGF03 = setPowerOn(); // 遥控器
un_inf_can_kgf_output2.bit_data.KGF05 = setPowerOn(); // 网络交换机
un_inf_can_kgf_output2.bit_data.KGF06 = setPowerOn(); // 网络交换机
break;
default:
break;
}
publishMessage(&power_data, 1);
publishMessage(&un_inf_can_kgf_output1, 1);
publishMessage(&un_inf_can_kgf_output2, 1);
}
static void wakeupProcess(void *signal_id)
{
(void)signal_id;
un_gather_output.bit_data.sleep_duration = (uint16_t)getParam("sleepTm");
un_gather_output.bit_data.wakeup_interval = (uint16_t)getParam("wakeTm");
if(un_gather_output.bit_data.sleep_duration < 5)//最小值限定
{
un_gather_output.bit_data.sleep_duration = 5;
}
if(un_gather_output.bit_data.wakeup_interval < 5)//最小值限定
{
un_gather_output.bit_data.wakeup_interval = 5;
}
un_gather_output.bit_data.vehicle_mode = power_data.current_state;
publishMessage(&un_gather_output, 1);
timerStart(&power_data.timer1, 500, 1); //周期调用
}
// 定时器处理函数
static void powerTimerProcess(void *signal_id)
{
(void)signal_id;
// 调用电源按钮处理函数
handlePowerButton();
// 电源按钮状态有变化,保存到参数
if (power_button.is_power_on != power_button.old_is_power_on)
{
setParam("pwr_btn", (float)power_button.is_power_on);
power_button.old_is_power_on = power_button.is_power_on;
}
// 状态转换逻辑
switch (power_data.current_state)
{
case POWER_PRE_CHARGE:
if (!power_data.timer_pre_charge.active) // 预充时间到
{
power_data.current_state = POWER_WORKING; // 工作
power_data.pre_charge_finish = 1; // 预充完成
printf("Power: Transitioning from PRE_CHARGE to WORKING state\n");
}
break;
case POWER_STANDBY:
if (power_button.is_power_on == app_close() && power_data.emergency_stop == app_close()) // 遥控器电源开关闭合且急停开关闭合
{
power_data.current_state = POWER_EMERGENCY; // 急停
printf("Power: Transitioning from STANDBY to EMERGENCY state\n");
}
break;
case POWER_WORKING:
if (power_data.emergency_stop == app_close()) // 急停开关闭合
{
power_data.current_state = POWER_EMERGENCY; // 急停
printf("Power: Transitioning from WORKING to EMERGENCY state\n");
}
break;
case POWER_EMERGENCY:
if (power_button.is_power_on == app_open()) // 遥控器电源开关断开
{
power_data.current_state = POWER_STANDBY; // 待机
printf("Power: Transitioning from EMERGENCY to STANDBY state\n");
}
else if (power_data.emergency_stop == app_open()) // 急停断开
{
power_data.current_state = POWER_PRE_CHARGE; // 预充
timerStart(&power_data.timer_pre_charge, (uint32_t)(getParam("prCTime") * 1000), 1); // 启动预充定时器
printf("Power: Transitioning from EMERGENCY to PRE_CHARGE state\n");
}
break;
// case POWER_SLEEP:
// if (power_data.high_voltage_switch == app_close()) // 高压开关闭合
// {
// power_data.current_state = POWER_STANDBY; // 待机
// printf("Power: Transitioning from SLEEP to STANDBY state\n");
// }
// break;
default:
power_data.current_state = POWER_STANDBY; // 待机
break;
}
powerOutput(NULL); // 输出
// 电源状态有变化,记录到参数
if (power_data.old_state != power_data.current_state)
{
power_data.old_state = power_data.current_state;
setParam("pwr_sta", (float)power_data.current_state);
}
timerStart(&power_data.timer, 100, 1); //周期调用
}
// 处理所有输入信号的函数
static void powerInput(void *signal_id)
{
//不能直接赋值用memcpy
PowerSystem old_data;
memcpy(&old_data, &power_data, sizeof(PowerSystem));
// 填充数据
if (signal_id == &un_sw_sample)
{
power_data.emergency_stop_switch = (uint8_t)un_sw_sample.bit_data.emergency_stop_switch;//急停开关
power_data.high_voltage_switch = (uint8_t)un_sw_sample.bit_data.High_voltage_switch;//高压开关
printf("emergency_stop_switch: = %d,high_voltage_switch = %d\n", power_data.emergency_stop_switch,power_data.high_voltage_switch);
}
else if ( (signal_id == &un_remote_control_input) && (1 == un_remote_control_input.bit_data.enable) )// 遥控器断线,不更新数据
{
power_data.remote_power_switch = (uint8_t)un_remote_control_input.bit_data.switch_d; // 遥控器电源开关
power_data.remote_emergency_stop = ((uint8_t)un_remote_control_input.bit_data.switch_b == 1) ? 0 : 1;// 遥控器急停开关
}
// 急停开关
power_data.emergency_stop = (uint8_t)( (power_data.emergency_stop_switch == app_close()) || (power_data.remote_emergency_stop == app_close()) );
}
// APP模块的初始化
void powerAppInit(void)
{
// 初始化变量
memset(&power_data, 0, sizeof(PowerSystem));
power_data.current_state = POWER_STANDBY;
// 初始化时恢复电源状态
power_data.current_state = (PowerState)getParam("pwr_sta");
power_data.old_state = power_data.current_state;
// 恢复电源按钮状态
power_button.is_power_on = (uint8_t)getParam("pwr_btn");
power_button.old_is_power_on = power_button.is_power_on;
// 订阅输入信号
subscribe(&un_sw_sample, powerInput); // 急停开关、高压开关
subscribe(&un_remote_control_input, powerInput); // 遥控器电源开关
// 定时器
timerInit(&power_data.timer);
subscribe(&power_data.timer, powerTimerProcess);
timerStart(&power_data.timer, 500, 1); // 周期调用
//定时器唤醒
timerInit(&power_data.timer1);
subscribe(&power_data.timer1, wakeupProcess);
timerStart(&power_data.timer1, 500, 1); // 周期调用
//预充定时器
timerInit(&power_data.timer_pre_charge);
subscribe(&power_data.timer_pre_charge, powerTimerProcess);
printf("app_power: initial OK\n");
}

53
app/app_power.h Normal file
View File

@@ -0,0 +1,53 @@
#ifndef APP_POWER_H
#define APP_POWER_H
#ifdef __cplusplus
extern "C" {
#endif
#include "app_config.h"
#include "app_frm_monitor.h"
#include "app_frm_signal.h"
#include "app_frm_timer.h"
// 定义电源状态枚举
typedef enum {
POWER_STANDBY,
POWER_WORKING,
POWER_EMERGENCY,
POWER_PRE_CHARGE,
POWER_SLEEP
} PowerState;
// 使用内联函数
static inline uint8_t setPowerOn(void) { return 1; }
static inline uint8_t setPowerOff(void) { return 0; }
// 声明 power_data 变量结构体
typedef struct {
PowerState current_state; // 当前电源状态
uint32_t start_time; // 定时器起始时间
Timer timer; // 定时器
Timer timer1;
Timer timer_pre_charge; // 预充定时器
PowerState last_state; // 上一次状态
uint8_t emergency_stop_switch; // 急停开关
uint8_t high_voltage_switch; // 高压开关
uint8_t remote_power_switch; // 遥控器电源开关
uint8_t remote_emergency_stop; // 遥控器急停开关
uint8_t emergency_stop; // 急停状态
uint8_t pre_charge_finish; // 预充完成标志位
uint8_t old_state; // 上一次状态
} PowerSystem;
// 声明外部变量
extern PowerSystem power_data;
void powerAppInit(void);
#ifdef __cplusplus
}
#endif
#endif // APP_POWER_H

415
app/app_request.c Normal file
View File

@@ -0,0 +1,415 @@
#include "app_config.h"
#include "interface.h"
#include "app_request.h"
#include "app_param_manage.h"
uint16_t request_id = 0;
static void processRequestframe(uint16_t id)
{
uint32_t TempAcc = 0;
uint8_t i = 0;
static uint8_t VehicleStaACC0 = 0;
static uint8_t VehicleStaACC1 = 0;
static uint8_t VehicleStaACC2 = 0;
static uint8_t VehicleStaACC3 = 0;
uint16_t RgExchangeTemp = 0;
uint32_t Rg32ExchangeTemp = 0;
//-----------------------------------------------------------
// printf("request_read_id:%d\n",id);
switch (id)//注意是高位在前,低位在后
{
case 0x2000://状态帧
un_vehicle_Info_output.bit_data.frame_header = 0xCCAA;//帧头
un_vehicle_Info_output.bit_data.frame_type = 0x2000;//帧类型
un_vehicle_Info_output.bit_data.frame_length = 0x2900;//帧长
un_vehicle_Info_output.bit_data.accumulated = VehicleStaACC0++;//累加值
TempAcc = 0;
for (i = 0; i < 40; i++)//累加前40个字节
{
TempAcc = TempAcc + (uint32_t)(un_vehicle_Info_output.arr[i]);
}
un_vehicle_Info_output.bit_data.crc = (uint8_t)TempAcc;//累加值
publishMessage(&un_vehicle_Info_output, 1);
break;
case 0x2100://电机帧
un_motor_status_output.bit_data.frame_header = 0xCCAA;//帧头
un_motor_status_output.bit_data.frame_type = 0x2100;//帧类型
un_motor_status_output.bit_data.frame_length = 0x1E00;//帧长
un_motor_status_output.bit_data.accumulated = VehicleStaACC1++;//累加值
RgExchangeTemp = ( (uint16_t)getParam("maxTorq") + 300 ) *100 ;
// un_motor_status_output.bit_data.left_torque_limit = ((RgExchangeTemp << 8) | (RgExchangeTemp >> 8));//左侧扭矩限制
// un_motor_status_output.bit_data.right_torque_limit = ((RgExchangeTemp << 8) | (RgExchangeTemp >> 8));//右侧扭矩限制
// un_motor_status_output.bit_data.left_power_in = (((uint16_t)getParam("feedPwr") << 8) | ((uint16_t)getParam("feedPwr") >> 8));//左侧馈电功率
// un_motor_status_output.bit_data.right_power_in = (((uint16_t)getParam("feedPwr") << 8) | ((uint16_t)getParam("feedPwr") >> 8));//右侧馈电功率
// un_motor_status_output.bit_data.left_power_out = (((uint16_t)getParam("dispPwr") << 8) | ((uint16_t)getParam("dispPwr") >> 8));//左侧放电功率
// un_motor_status_output.bit_data.right_power_out = (((uint16_t)getParam("dispPwr") << 8) | ((uint16_t)getParam("dispPwr") >> 8));//右侧放电功率
TempAcc = 0;
for (i = 0; i < 31; i++)//累加前31个字节
{
TempAcc = TempAcc + (uint32_t)(un_motor_status_output.arr[i]);
un_motor_status_output.bit_data.checksum = (uint8_t)TempAcc;//累加值
}
publishMessage(&un_motor_status_output, 1);
break;
case 0x2200:
un_pid_output.bit_data.frame_header = 0xCCAA;//帧头
un_pid_output.bit_data.frame_type = 0x2200;//帧类型
un_pid_output.bit_data.frame_length = 0x3800;//帧长
un_pid_output.bit_data.accumulated = VehicleStaACC2++;//累加值
Rg32ExchangeTemp = (uint32_t)(int32_t)(getParam("spd_kp")*1000);
Rg32ExchangeTemp = ( ((Rg32ExchangeTemp >> 24) &0xff ) | ((Rg32ExchangeTemp >> 8) & 0xFF00) | ((Rg32ExchangeTemp << 8) & 0xFF0000) | ((Rg32ExchangeTemp << 24)) );
un_pid_output.bit_data.rc_straight_p = Rg32ExchangeTemp;//遥控直行P参数
Rg32ExchangeTemp = (uint32_t)(int32_t)(getParam("spd_ki")*1000);
Rg32ExchangeTemp = ( ((Rg32ExchangeTemp >> 24) &0xff ) | ((Rg32ExchangeTemp >> 8) & 0xFF00) | ((Rg32ExchangeTemp << 8) & 0xFF0000) | ((Rg32ExchangeTemp << 24)) );
un_pid_output.bit_data.rc_straight_i = Rg32ExchangeTemp;//遥控直行I参数
Rg32ExchangeTemp = (uint32_t)(int32_t)(getParam("spd_kd")*1000);
Rg32ExchangeTemp = ( ((Rg32ExchangeTemp >> 24) &0xff ) | ((Rg32ExchangeTemp >> 8) & 0xFF00) | ((Rg32ExchangeTemp << 8) & 0xFF0000) | ((Rg32ExchangeTemp << 24)) );
un_pid_output.bit_data.rc_straight_d = Rg32ExchangeTemp;//遥控直行D参数
Rg32ExchangeTemp = (uint32_t)(int32_t)(getParam("spd_il")*1000);
Rg32ExchangeTemp = ( ((Rg32ExchangeTemp >> 24) &0xff ) | ((Rg32ExchangeTemp >> 8) & 0xFF00) | ((Rg32ExchangeTemp << 8) & 0xFF0000) | ((Rg32ExchangeTemp << 24)) );
un_pid_output.bit_data.auto_straight_p = Rg32ExchangeTemp;//自主直行P参数
Rg32ExchangeTemp = (uint32_t)(int32_t)(getParam("spd_ol")*1000);
Rg32ExchangeTemp = ( ((Rg32ExchangeTemp >> 24) &0xff ) | ((Rg32ExchangeTemp >> 8) & 0xFF00) | ((Rg32ExchangeTemp << 8) & 0xFF0000) | ((Rg32ExchangeTemp << 24)) );
un_pid_output.bit_data.auto_straight_i = Rg32ExchangeTemp;//自主直行I参数
Rg32ExchangeTemp = (uint32_t)(int32_t)(getParam("spd_kd")*1000);
Rg32ExchangeTemp = ( ((Rg32ExchangeTemp >> 24) &0xff ) | ((Rg32ExchangeTemp >> 8) & 0xFF00) | ((Rg32ExchangeTemp << 8) & 0xFF0000) | ((Rg32ExchangeTemp << 24)) );
un_pid_output.bit_data.auto_straight_d = Rg32ExchangeTemp;//自主直行D参数
Rg32ExchangeTemp = (uint32_t)(int32_t)(getParam("crv_kp")*1000);
Rg32ExchangeTemp = ( ((Rg32ExchangeTemp >> 24) &0xff ) | ((Rg32ExchangeTemp >> 8) & 0xFF00) | ((Rg32ExchangeTemp << 8) & 0xFF0000) | ((Rg32ExchangeTemp << 24)) );
un_pid_output.bit_data.rc_turn_p = Rg32ExchangeTemp;//遥控转弯P参数
Rg32ExchangeTemp = (uint32_t)(int32_t)(getParam("crv_ki")*1000);
Rg32ExchangeTemp = ( ((Rg32ExchangeTemp >> 24) &0xff ) | ((Rg32ExchangeTemp >> 8) & 0xFF00) | ((Rg32ExchangeTemp << 8) & 0xFF0000) | ((Rg32ExchangeTemp << 24)) );
un_pid_output.bit_data.rc_turn_i = Rg32ExchangeTemp;//遥控转弯I参数
Rg32ExchangeTemp = (uint32_t)(int32_t)(getParam("crv_kd")*1000);
Rg32ExchangeTemp = ( ((Rg32ExchangeTemp >> 24) &0xff ) | ((Rg32ExchangeTemp >> 8) & 0xFF00) | ((Rg32ExchangeTemp << 8) & 0xFF0000) | ((Rg32ExchangeTemp << 24)) );
un_pid_output.bit_data.rc_turn_d = Rg32ExchangeTemp;//遥控转弯D参数
Rg32ExchangeTemp = (uint32_t)(int32_t)(getParam("crv_il")*1000);
Rg32ExchangeTemp = ( ((Rg32ExchangeTemp >> 24) &0xff ) | ((Rg32ExchangeTemp >> 8) & 0xFF00) | ((Rg32ExchangeTemp << 8) & 0xFF0000) | ((Rg32ExchangeTemp << 24)) );
un_pid_output.bit_data.auto_turn_p = Rg32ExchangeTemp;//自主转弯P参数
Rg32ExchangeTemp = (uint32_t)(int32_t)(getParam("crv_ol")*1000);
Rg32ExchangeTemp = ( ((Rg32ExchangeTemp >> 24) &0xff ) | ((Rg32ExchangeTemp >> 8) & 0xFF00) | ((Rg32ExchangeTemp << 8) & 0xFF0000) | ((Rg32ExchangeTemp << 24)) );
un_pid_output.bit_data.auto_turn_i = Rg32ExchangeTemp;//自主转弯I参数
Rg32ExchangeTemp = (uint32_t)(int32_t)(getParam("spd_kd")*1000);
Rg32ExchangeTemp = ( ((Rg32ExchangeTemp >> 24) &0xff ) | ((Rg32ExchangeTemp >> 8) & 0xFF00) | ((Rg32ExchangeTemp << 8) & 0xFF0000) | ((Rg32ExchangeTemp << 24)) );
un_pid_output.bit_data.auto_turn_d = Rg32ExchangeTemp;//自主转弯I参数
TempAcc = 0;
for (i = 0; i < 55; i++)//累加前40个字节
{
TempAcc = TempAcc + (uint32_t)(un_pid_output.arr[i]);
}
un_pid_output.bit_data.checksum = (uint8_t)TempAcc;//累加值
publishMessage(&un_pid_output, 1);
break;
case 0x2300:
// ETHTxtempArr[0] = 0xAA;
// ETHTxtempArr[1] = 0xCC;
// ETHTxtempArr[2] = 0x00;
// ETHTxtempArr[3] = 0x23;
// ETHTxtempArr[4] = 0;
// ETHTxtempArr[5] = 27;
// ETHTxtempArr[6] = VehicleStaACC3++;
// //AIAO
// memcpy(&ETHTxtempArr[7],(uint8_t *)&(UnAIAOSignal_1.ArrData.ArrRx[0]),17);//电池数据拷贝
// ETHTxtempArr[24] = (u8)(RgCanToAiAOCnt>>8);
// ETHTxtempArr[25] = (u8)RgCanToAiAOCnt;//累加值
//
// TempAcc = 0;
// for (i = 0; i < 26; i++)//累加前40个字节
// {
// TempAcc = TempAcc + (u32)(ETHTxtempArr[i]);
// }
// ETHTxtempArr[26] = (uint8_t)TempAcc;//累加值
//
// TxLen = 27;
// UdpSendToData(UDPCB_2,(uint8_t *)(&un_analog_signal_output), 27, (uint8_t *)&ethernet_parameter.upper_ip[0], ethernet_parameter.target_upper_port);
break;
case 0x2400:
un_remote_control_output.bit_data.frame_header = 0xCCAA;//帧头
un_remote_control_output.bit_data.frame_type = 0x2400;//帧类型
un_remote_control_output.bit_data.frame_length = 0x1400;//帧长
un_remote_control_output.bit_data.accumulated = VehicleStaACC3++;//累加值
//RCH_3
TempAcc = 0;
for (i = 0; i < 17; i++)//累加前40个字节
{
TempAcc = TempAcc + (uint32_t)(un_remote_control_output.arr[i]);
}
un_remote_control_output.bit_data.crc = (uint8_t)TempAcc;//累加值
publishMessage(&un_remote_control_output, 1);
break;
case 0x2500:
un_manual_control_output.bit_data.frame_type = 0x2500;
TempAcc = 0;
for (i = 0; i < 14; i++)//累加前40个字节
{
TempAcc = TempAcc + (uint32_t)(un_manual_control_output.arr[i]);
}
un_manual_control_output.bit_data.crc_2 = (uint8_t)TempAcc;//累加值
publishMessage(&un_manual_control_output, 1);
break;
case 0x2600:
un_auto_control_output.bit_data.frame_type = 0x2600;
TempAcc = 0;
for (i = 0; i < 27; i++)//累加前40个字节
{
TempAcc = TempAcc + (uint32_t)(un_auto_control_output.arr[i]);
}
un_auto_control_output.bit_data.crc = (uint8_t)TempAcc;//累加值
publishMessage(&un_auto_control_output, 1);
break;
// case 0x2700:
// memcpy(&ETHTxtempArr[0],(uint8_t *)&RemoteControlRoomToVcuBuf,11);//手柄拷贝
// ETHTxtempArr[2] = 0;//修改帧类型为0x0025
// ETHTxtempArr[3] = 0x27;
// ETHTxtempArr[11] = (u8)(RgETHToRemoteControlCnt>>8);
// ETHTxtempArr[12] = (u8)RgETHToRemoteControlCnt;//累加值
// TempAcc = 0;
// for (i = 0; i < 13; i++)//累加前40个字节
// {
// TempAcc = TempAcc + (u32)(ETHTxtempArr[i]);
// }
// ETHTxtempArr[13] = (uint8_t)TempAcc;//累加值
//
// TxLen = 14;
// UdpSendToData(SocketId2,ETHTxtempArr,&TxLen,ip_addr,port);//测试
// break;
// case 0xFFFF:
// memcpy(&ETHTxtempArr[0],(uint8_t *)&RemoteControlRoomToVcuBuf,11);//手柄拷贝
// ETHTxtempArr[2] = 0x27;//修改帧类型为0x0025
// ETHTxtempArr[3] = 0;
// ETHTxtempArr[11] = (u8)RgETHToRemoteControlCnt;
// ETHTxtempArr[12] = (u8)(RgETHToRemoteControlCnt>>8);//累加值
// TempAcc = 0;
// for (i = 0; i < 13; i++)//累加前40个字节
// {
// TempAcc = TempAcc + (u32)(ETHTxtempArr[i]);
// }
// ETHTxtempArr[13] = (uint8_t)TempAcc;//累加值
//
// TxLen = 14;
// UdpSendToData(SocketId2,ETHTxtempArr,&TxLen,ip_addr,port);//测试
// break;
default: break;
}
}
// 处理所有输入信号的函数
static void requestInput(void *signal_id)
{
uint16_t request16_temp = 0;
//--------------------------------------------------------
if (signal_id == &diff_data)
{
request16_temp = (uint16_t)(int16_t)(diff_data.desired_speed * 100.0);
un_vehicle_Info_output.bit_data.desired_speed = ((request16_temp << 8) | (request16_temp >> 8));//当前速度
request16_temp = (uint16_t)(int16_t)(diff_data.left_diff_touue * 10000.0);
un_vehicle_Info_output.bit_data.desired_curvature = ((request16_temp << 8) | (request16_temp >> 8));//当前曲率
request16_temp = (uint16_t)(int16_t)(diff_data.speed * 100.0);
un_vehicle_Info_output.bit_data.speed = ((request16_temp << 8) | (request16_temp >> 8));//当前速度
request16_temp = (uint16_t)(int16_t)(diff_data.right_diff_touue * 10000.0);
un_vehicle_Info_output.bit_data.curvature = ((request16_temp << 8) | (request16_temp >> 8));//当前曲率
request16_temp = (uint16_t)(int16_t)(diff_data.out_motor_speed[0]);//
un_vehicle_Info_output.bit_data.set_left_speed = ((request16_temp << 8) | (request16_temp >> 8));//左前
request16_temp = (uint16_t)(int16_t)(diff_data.out_motor_speed[1]);//out_right_motor_speed
un_vehicle_Info_output.bit_data.set_right_speed = ((request16_temp << 8) | (request16_temp >> 8));//右前
request16_temp = (uint16_t)(int16_t)(diff_data.out_motor_speed[2]);//
un_motor_status_output.bit_data.left_power_in = ((request16_temp << 8) | (request16_temp >> 8));//左后
request16_temp = (uint16_t)(int16_t)(diff_data.out_motor_speed[3]);//out_right_motor_speed
un_motor_status_output.bit_data.right_power_in = ((request16_temp << 8) | (request16_temp >> 8));//右后
un_vehicle_Info_output.bit_data.vehicle_fault_state = diff_data.state;
un_vehicle_Info_output.bit_data.battery_soc = diff_data.motor_dir;
request16_temp = (uint16_t)(int16_t)(diff_data.left_rear_motor_speed + 30000);
un_motor_status_output.bit_data.left_wheel_speed = ((request16_temp << 8) | (request16_temp >> 8));;//左侧后轮速
request16_temp = (uint16_t)(int16_t)(diff_data.right_rear_motor_speed + 30000);
un_motor_status_output.bit_data.right_wheel_speed = ((request16_temp << 8) | (request16_temp >> 8));;//右侧后轮速
request16_temp = (uint16_t)(int16_t)( (diff_data.left_front_motor_speed + 300)*100);
un_motor_status_output.bit_data.left_torque = ((request16_temp << 8) | (request16_temp >> 8));;//左侧前轮速
request16_temp = (uint16_t)(int16_t)( (diff_data.right_front_motor_speed + 300)*100);
un_motor_status_output.bit_data.right_torque = ((request16_temp << 8) | (request16_temp >> 8));;//右侧前轮速
}
else if(signal_id == &un_auto_computer_input)
{
un_vehicle_Info_output.bit_data.longitude = un_auto_computer_input.bit_data.longitude;//经度
un_vehicle_Info_output.bit_data.latitude = un_auto_computer_input.bit_data.latitude;
un_vehicle_Info_output.bit_data.altitude = un_auto_computer_input.bit_data.altitude;
un_vehicle_Info_output.bit_data.heading_angle = un_auto_computer_input.bit_data.heading;//航向
memcpy(&un_auto_control_output.arr[0],&(un_auto_computer_input.arr[0]),25);//手柄拷贝
}
else if(signal_id == &un_bms_input)
{
un_vehicle_Info_output.bit_data.battery_voltage = un_bms_input.bit_data.bus_voltage/10;//电池电压读取得的10mV所以输出的是100mV单位所以缩小10倍
un_vehicle_Info_output.bit_data.battery_soc = un_bms_input.bit_data.soc;//SOC
un_vehicle_Info_output.bit_data.battery_current = un_bms_input.bit_data.bus_current;//电池电流
}
else if(signal_id == &un_motor_input1)
{
// un_motor_status_output.bit_data.left_wheel_speed = ((un_motor_input1.bit_data.speed << 8) | (un_motor_input1.bit_data.speed >> 8));//左侧轮速
// un_motor_status_output.bit_data.left_torque = ((un_motor_input1.bit_data.torque << 8) | (un_motor_input1.bit_data.torque >> 8));//左侧扭矩
// un_motor_status_output.bit_data.left_voltage = ((un_motor_input1.bit_data.bus_voltage << 8) | (un_motor_input1.bit_data.bus_voltage >> 8));//左侧电压
// un_motor_status_output.bit_data.left_fault_code = un_motor_input1.bit_data.fault_code;//左侧故障码
//
}
else if(signal_id == &un_motor_input2)
{
// un_motor_status_output.bit_data.right_wheel_speed = ((un_motor_input2.bit_data.speed << 8) | (un_motor_input2.bit_data.speed >> 8));//右侧轮速
// un_motor_status_output.bit_data.right_torque = ((un_motor_input2.bit_data.torque << 8) | (un_motor_input2.bit_data.torque >> 8));//右侧扭矩
// un_motor_status_output.bit_data.right_fault_code = un_motor_input2.bit_data.fault_code;//右侧故障码
// un_motor_status_output.bit_data.right_voltage = ((un_motor_input2.bit_data.bus_voltage << 8) | (un_motor_input2.bit_data.bus_voltage >> 8));//右侧电压
//
}
else if(signal_id == &un_remote_control_input)
{
//RCH_3
un_remote_control_output.bit_data.speed = ((un_remote_control_input.bit_data.speed << 8) | (un_remote_control_input.bit_data.speed >> 8));//遥控器期望速度
un_remote_control_output.bit_data.curvature = ((un_remote_control_input.bit_data.curvature << 8) | (un_remote_control_input.bit_data.curvature >> 8));//遥控器期望曲率
memcpy(&un_remote_control_output.arr[11],&un_remote_control_input.arr[4],4);//遥控数据拷贝
}
else if(signal_id == &un_manual_computer_input)
{
memcpy(&un_manual_control_output.arr[0],&(un_manual_computer_input.arr[0]),12);//手柄拷贝
}
else if(signal_id == &ethernet_fault_Info)
{
un_auto_control_output.arr[25] = (uint8_t)(ethernet_fault_Info.bit_data.auto_count>>8);
un_auto_control_output.arr[26] = (uint8_t)(ethernet_fault_Info.bit_data.auto_count);//累加值
un_manual_control_output.arr[12] = (uint8_t)(ethernet_fault_Info.bit_data.manual_count>>8);
un_manual_control_output.arr[13] = (uint8_t)(ethernet_fault_Info.bit_data.manual_count);//累加值
}
else if(signal_id == &can_fault_info)
{
un_remote_control_output.arr[15] = (uint8_t)(can_fault_info.bit_data.remote_count>>8);
un_remote_control_output.arr[16] = (uint8_t)(can_fault_info.bit_data.remote_count);//累加值
}
else if(signal_id == &un_request_frame)
{
request_id = REQUEST_READ_ID;
processRequestframe(request_id);
}
else{}
}
// 修改APP模块的初始化函数
void requestAppInit(void)
{
// 订阅消息,使用静态成员函数作为回调 参数回馈
subscribe(&diff_data, requestInput);
subscribe(&un_auto_computer_input, requestInput);
subscribe(&un_bms_input, requestInput);
subscribe(&un_motor_input1, requestInput);
subscribe(&un_motor_input2, requestInput);
subscribe(&un_remote_control_input, requestInput);
subscribe(&can_fault_info, requestInput);
subscribe(&ethernet_fault_Info, requestInput);
// // 订阅消息,使用静态成员函数作为回调 参数回馈
subscribe(&un_request_frame, requestInput);
printf("app_request: initial OK \n");
}

83
app/app_request.h Normal file
View File

@@ -0,0 +1,83 @@
#ifndef APP_REQUEST_H
#define APP_REQUEST_H
#ifdef __cplusplus
extern "C"
{
#endif
#include "app_config.h"
#include "app_differential_drive.h"
//typedef enum
//{
// MODE_MANUAL, // 手动模式
// MODE_AUTO // 自动模式
//} ControlMode;
//
typedef struct RequestData
{
float desired_speed; // 期望速度
float desired_curvature; // 期望曲率
float left_motor_speed; // 当前左电机速度
float right_motor_speed; // 当前右电机速度
float speed; // 当前车速
float curvature; // 当前曲率
float yaw_rate; // 当前角速度
float desired_yaw_rate; // 期望角速度
float acceleration; // 当前加速度
float deceleration; // 当前减速度
float max_speed; // 最大速度
float desired_acceleration; // 期望加速度
float desired_deceleration; // 期望减速度
float out_left_motor_speed; // 输出左电机速度
float out_right_motor_speed; // 输出右电机速度
} RequestData;
// 声明外部变量
extern DiffData diff_data;
void requestAppInit(void);
#ifdef __cplusplus
}
#endif
#endif // APP_DIFFERENTIAL_DRIVE_H

115
app/app_temp.c Normal file
View File

@@ -0,0 +1,115 @@
#include "app_config.h"
#include "interface.h"
#include "app_frm_monitor.h"
#include "app_frm_signal.h"
#include "app_frm_timer.h"
#include "app_param_manage.h"
#include "app_temp.h"
// 声明 temp_data 变量
TempSystem temp_data;
// 温度输出处理函数
static void tempOutput(void *signal_id)
{
(void)signal_id;
// 根据当前状态,控制风扇
switch (temp_data.state)
{
case TEMP_NORMAL:
// un_inf_can_kgf_output1.bit_data.KGF01 = setFanOff();//电机控制器风扇
// un_inf_can_kgf_output1.bit_data.KGF03 = setFanOff();
// un_inf_can_kgf_output1.bit_data.KGF14 = setFanOff();//整车风扇
// un_inf_can_kgf_output2.bit_data.KGF03 = setFanOff();
break;
case TEMP_WARNING:
case TEMP_CRITICAL:
// un_inf_can_kgf_output1.bit_data.KGF01 = setFanOn();
// un_inf_can_kgf_output1.bit_data.KGF03 = setFanOn();
// un_inf_can_kgf_output1.bit_data.KGF14 = setFanOn();
// un_inf_can_kgf_output2.bit_data.KGF03 = setFanOn();
break;
}
// // 设置风扇速度
// temp_data.fan_speed = 0;
// un_inf_can_kgf_output1.bit_data.pwm_01 = temp_data.fan_speed;
publishMessage(&un_inf_can_kgf_output1, 1);
}
// 温度状态处理函数
static void tempProcess(void *signal_id)
{
(void)signal_id;
// 获取当前最高温度
int16_t max_temp = temp_data.current_temp[0];
for (uint8_t i = 1; i < 8; i++)
{
if (temp_data.current_temp[i] > max_temp)
{
max_temp = temp_data.current_temp[i];
}
}
// 根据最高温度设置状态
if (max_temp > 80) // 假设80度为危险温度
{
temp_data.state = TEMP_CRITICAL;
temp_data.fan_speed = 255; // 全速运转
}
else if (max_temp > 60) // 假设60度为警告温度
{
temp_data.state = TEMP_WARNING;
temp_data.fan_speed = 128; // 半速运转
}
else
{
temp_data.state = TEMP_NORMAL;
temp_data.fan_speed = 0; // 停止运转
}
tempOutput(NULL);
}
// 处理输入信号的函数
static void tempInput(void *signal_id)
{
// TempSystem old_data = temp_data;
// 填充数据
if (signal_id == &un_temp_module_input)
{
temp_data.current_temp[0] = (int16_t)un_temp_module_input.bit_data.channel_1;
temp_data.current_temp[1] = (int16_t)un_temp_module_input.bit_data.channel_2;
temp_data.current_temp[2] = (int16_t)un_temp_module_input.bit_data.channel_3;
temp_data.current_temp[3] = (int16_t)un_temp_module_input.bit_data.channel_4;
temp_data.current_temp[4] = (int16_t)un_temp_module_input.bit_data.channel_5;
temp_data.current_temp[5] = (int16_t)un_temp_module_input.bit_data.channel_6;
temp_data.current_temp[6] = (int16_t)un_temp_module_input.bit_data.channel_7;
temp_data.current_temp[7] = (int16_t)un_temp_module_input.bit_data.channel_8;
}
}
// APP模块的初始化
void tempAppInit(void)
{
// 初始化
memset(&temp_data, 0, sizeof(TempSystem));
temp_data.state = TEMP_NORMAL;
temp_data.mode = TEMP_MODE_AUTO;
temp_data.target_temp = 25; // 默认目标温度25度
// 订阅输入信号,处理温度逻辑
subscribe(&un_temp_module_input, tempInput);
// 启动定时器,每秒检查一次温度
subscribe(&temp_data.timer, tempProcess);
timerStart(&temp_data.timer, 1000, 1); //1s
printf("app_temp: initial OK \n");
}

53
app/app_temp.h Normal file
View File

@@ -0,0 +1,53 @@
#ifndef APP_TEMP_H
#define APP_TEMP_H
#ifdef __cplusplus
extern "C"
{
#endif
// 定义温度状态枚举
typedef enum
{
TEMP_NORMAL,
TEMP_WARNING,
TEMP_CRITICAL
} TempState;
// 定义温度控制模式枚举
typedef enum
{
TEMP_MODE_AUTO,
TEMP_MODE_MANUAL
} TempMode;
typedef struct
{
TempState state;
TempMode mode;
int16_t current_temp[8]; // 当前温度,对应8个通道
int16_t target_temp; // 目标温度
uint8_t fan_speed; // 风扇速度
Timer timer; // 定时器
} TempSystem;
// 在头文件中声明外部变量
extern TempSystem temp_data;
// 使用内联函数
static inline uint8_t setFanOn(void) { return 1; }
static inline uint8_t setFanOff(void) { return 0; }
void tempAppInit(void);
void setTempMode(TempMode mode);
void setTargetTemp(int16_t temp);
void setFanSpeed(uint8_t speed);
#ifdef __cplusplus
}
#endif
#endif // APP_TEMP_H

62
app/app_test.c Normal file
View File

@@ -0,0 +1,62 @@
#include "app_config.h"
#include "app_dependence.h"
#include "interface.h"
#include "app_frm_monitor.h"
#include "app_frm_signal.h"
#include "app_frm_timer.h"
#include "sdrv_vic.h"
#include "app_test.h"
#include "app_differential_drive.h"
// 定时器结构体
Timer test_timer;
// 定时器信号处理函数
void testTimerProcess(void *signal_id)
{
(void)signal_id; // 标记变量为已使用,避免编译器警告
// static uint32_t start_time = 0;
// uint32_t test_irq[6] = {0};
// 再次启动定时器,实现周期定时
timerStart(&test_timer, 5000,1);
// printf("speed = %f ",diff_data.desired_speed);
// printf("curvature = %f ",diff_data.desired_curvature);
// printf("mode = %d\n",diff_data.mode);
//
// sdrv_vic_lld_read_all(test_irq);//打印所有中断使能位
// printf("irq state = %#X ",test_irq[0]);
// printf("irq state = %#X ",test_irq[1]);
// printf("irq state = %#X ",test_irq[2]);
// printf("irq state = %#X ",test_irq[3]);
// printf("irq state = %#X ",test_irq[4]);
// printf("irq state = %#X\n",test_irq[5]);
// printf("testAPP: %d us \n",getCurrentTime() - start_time);
// start_time = getCurrentTime();
}
// APP模块的初始化
void testAppInit(void)
{
// 初始化定时器
timerInit(&test_timer);
// 订阅定时器信号,用于停止电机
subscribe(&test_timer, testTimerProcess);
printf("testAPP: initial OK %d\n",getCurrentTime());
timerStart(&test_timer, 5000,1);
}

18
app/app_test.h Normal file
View File

@@ -0,0 +1,18 @@
#ifndef TEST_H
#define TEST_H
#ifdef __cplusplus
extern "C" {
#endif
extern void testAppInit(void);
#ifdef __cplusplus
}
#endif
#endif // TEST_H

372
app/app_turn.c Normal file
View File

@@ -0,0 +1,372 @@
#include "app_config.h"
#include "app_dependence.h"
#include "interface.h"
#include "app_turn.h"
#include "app_differential_drive.h"
#include "app_param_manage.h"
#include <math.h>
#include <stdio.h>
TurnData turn_data;
Timer turn_timer2; // <20><>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><E1B9B9>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>תuint32_t<5F><74><EFBFBD><EFBFBD>С<EFBFBD><D0A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E6B4A2>
void floatToUint32(float num, uint32_t *result)
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD>ֱ<EFBFBD>ӿ<EFBFBD><D3BF><EFBFBD><EFBFBD><EFBFBD>uint32_t<5F><74><EFBFBD><EFBFBD>
memcpy(result, &num, sizeof(num));
}
static void turnOutput(void *signal_id)
{
(void)signal_id;
uint32_t float_temp = 0;
switch(turn_data.direction)
{
case 0:
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
floatToUint32(turn_data.left_zero_position,&float_temp);
un_sdo_output1.bit_data.data = float_temp;
floatToUint32(turn_data.left_speed*2,&float_temp);
un_sdo_output2.bit_data.data = float_temp;
//<2F>ҵ<EFBFBD><D2B5><EFBFBD>
floatToUint32(turn_data.right_zero_position,&float_temp);
un_sdo_output5.bit_data.data = float_temp;
floatToUint32(turn_data.right_speed*2,&float_temp);
un_sdo_output6.bit_data.data = float_temp;
break;
case 1://<2F><>ת
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
floatToUint32(turn_data.inner_rad + turn_data.left_zero_position,&float_temp);
un_sdo_output1.bit_data.data = float_temp;
floatToUint32(turn_data.left_speed,&float_temp);
un_sdo_output2.bit_data.data = float_temp;
//<2F>ҵ<EFBFBD><D2B5><EFBFBD>
floatToUint32(turn_data.outer_rad + turn_data.right_zero_position,&float_temp);
un_sdo_output5.bit_data.data = float_temp;
floatToUint32(turn_data.right_speed,&float_temp);
un_sdo_output6.bit_data.data = float_temp;
break;
case 2://<2F><>ת
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
floatToUint32(turn_data.outer_rad + turn_data.left_zero_position,&float_temp);
un_sdo_output1.bit_data.data = float_temp;
floatToUint32(turn_data.left_speed,&float_temp);
un_sdo_output2.bit_data.data = float_temp;
//<2F>ҵ<EFBFBD><D2B5><EFBFBD>
floatToUint32(turn_data.inner_rad + turn_data.right_zero_position,&float_temp);
un_sdo_output5.bit_data.data = float_temp;
floatToUint32(turn_data.right_speed,&float_temp);
un_sdo_output6.bit_data.data = float_temp;
break;default:;
}
un_sdo_output1.bit_data.index = LOC_REF_INDEX;
un_sdo_output1.bit_data.object_index = 0x0000;
// publishMessage(&un_sdo_output1, 1);//<2F><EFBFBD><E8B6A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>
un_sdo_output2.bit_data.index = LIMIT_SPEED_INDEX;
un_sdo_output2.bit_data.object_index = 0x0000;
// publishMessage(&un_sdo_output2, 1);//<2F><EFBFBD>ҵ<EFBFBD><D2B5><EFBFBD>λ<EFBFBD><CEBB>
un_sdo_output5.bit_data.index = LOC_REF_INDEX;
un_sdo_output5.bit_data.object_index = 0x0000;
// publishMessage(&un_sdo_output5, 1);//<2F><EFBFBD><E8B6A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>
un_sdo_output6.bit_data.index = LIMIT_SPEED_INDEX;
un_sdo_output6.bit_data.object_index = 0x0000;
// publishMessage(&un_sdo_output6, 1);//<2F><EFBFBD>ҵ<EFBFBD><D2B5><EFBFBD>λ<EFBFBD><CEBB>
}
//// Ԥ<><D4A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>Ҫ<EFBFBD>ȷ<EFBFBD>һ<EFBFBD><D2BB>ʧ<EFBFBD>ܣ<EFBFBD><DCA3><EFBFBD>ʹ<EFBFBD><CAB9>
//void turnChargeFinish(uint8_t *stt, uint8_t *cnt)
//{
// switch(stt[0])//<2F>ȷ<EFBFBD><C8B7><EFBFBD><EFBFBD>л<EFBFBD>ģʽ<C4A3>Լ<EFBFBD><D4BC><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD><EFBFBD>ֱ<EFBFBD><D6B1>ʹ<EFBFBD><CAB9>
// {
// case 0:
// if(cnt[0] >= 20)//<2F><><EFBFBD><EFBFBD>50<35><30>
// {
// cnt[0] = 0;
// stt[0] = 1;
// }
// else
// {
// un_sdo_output5.bit_data.cmd = 0x2F;
// un_sdo_output5.bit_data.object_index = 0x6060;
// un_sdo_output5.bit_data.sub_index = 0;
// un_sdo_output5.bit_data.data = 0x01;//<2F>趨λ<E8B6A8><CEBB>ģʽ
// publishMessage(&un_sdo_output5, 1);
//
// un_sdo_output4.bit_data.cmd = 0x2B;
// un_sdo_output4.bit_data.object_index = 0x6040;
// un_sdo_output4.bit_data.sub_index = 0;
// un_sdo_output4.bit_data.data = 0x06;//<2F><><EFBFBD><EFBFBD>ʧ<EFBFBD><CAA7>
// publishMessage(&un_sdo_output4, 1);
// cnt[0] ++;
// stt[0] = 0;
// printf("position! \n");
// }
// break;
//
// case 1:
//
// cnt[0] = 0;
// stt[0] = 1;
// printf("disable! \n");
// break;default:;
// }
//}
/**
* <20><><EFBFBD><EFBFBD><E3B0A2><EFBFBD><EFBFBD>ת<EFBFBD>򼸺<EFBFBD><F2BCB8BA>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><D7AA><EFBFBD>ǣ<EFBFBD><C7A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD>
* @param L <20><><EFBFBD>ࣨǰ<E0A3A8><C7B0><EFBFBD>־<EFBFBD><D6BE><EFBFBD><EBA3AC>λ<EFBFBD><CEBB><EFBFBD>ף<EFBFBD>
* @param W <20>־ࣨ<D6BE><E0A3A8><EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><D6BE><EFBFBD><EBA3AC>λ<EFBFBD><CEBB><EFBFBD>ף<EFBFBD>
* @param inner_rad <20><><EFBFBD><EFBFBD>ת<EFBFBD><D7AA><EFBFBD>ǣ<EFBFBD><C7A3><EFBFBD><EFBFBD>ȣ<EFBFBD>
* @param[out] curvature <20><><EFBFBD><EFBFBD>·<EFBFBD><C2B7><EFBFBD><EFBFBD><EFBFBD>ʣ<EFBFBD><CAA3><EFBFBD>λ<EFBFBD><CEBB>1/<2F>ף<EFBFBD>
* @return <20><><EFBFBD><EFBFBD>ת<EFBFBD><D7AA><EFBFBD>ǣ<EFBFBD><C7A3><EFBFBD><EFBFBD>ȣ<EFBFBD>
*/
float calculate_outer_angle(float L, float W, float inner_rad, float* curvature)
{
// <20><><EFBFBD><EFBFBD>ԭʼ<D4AD><CABC><EFBFBD><EFBFBD>
int sign = (inner_rad < 0) ? -1 : 1;
// ʹ<>þ<EFBFBD><C3BE><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD>м<EFBFBD><D0BC><EFBFBD>
float inner_temp = fabsf(inner_rad);
// <20><><EFBFBD><EFBFBD>ת<EFBFBD><D7AA><EFBFBD><EFBFBD><EBBEB6><EFBFBD><EFBFBD>ؼ<EFBFBD><D8BC>޸ĵ㣩
float R_inner = L / tanf(inner_temp); // <20><><EFBFBD><EFBFBD>ת<EFBFBD><D7AA><EFBFBD>
float R_outer = R_inner + W; // <20><><EFBFBD><EFBFBD>ת<EFBFBD><D7AA><EFBFBD>뾶 = <20><><EFBFBD>ְ뾶 + <20>־<EFBFBD>
float R = R_inner + W / 2; // <20><><EFBFBD><EFBFBD>ת<EFBFBD><D7AA><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʣ<EFBFBD>ע<EFBFBD><D7A2><EFBFBD><EFBFBD><EFBFBD>ţ<EFBFBD>
*curvature = sign / R;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><D7AA><EFBFBD>ǣ<EFBFBD>atan(L/R_outer)
float delta_o = atanf(L / R_outer);
// <20>ָ<EFBFBD>ԭʼ<D4AD><CABC><EFBFBD><EFBFBD>
return sign * delta_o;
}
// ת<><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
static void turnProcess(void *signal_id)
{
static uint8_t turn_process_state = 0;
static uint8_t turn_process_cnt = 0;
(void)signal_id;
if((turn_data.desired_curvature) > 0.01)//<2F><>ת
{
turn_data.direction = 1;
}
else if((turn_data.desired_curvature) < -0.01)//<2F><>ת
{
turn_data.direction = 2;
}
else//<2F><><EFBFBD><EFBFBD>
{
turn_data.direction = 0;
}
turn_data.inner_rad = turn_data.desired_curvature*turn_data.left_max_position/2.0;//<2F><><EFBFBD><EFBFBD><EFBFBD>Ƕȣ<C7B6><C8A3><EFBFBD><EFBFBD>ֽǶ<D6BD> -2-2<><32><EFBFBD><EFBFBD><EFBFBD>ʶ<EFBFBD>Ӧ ת<><D7AA>Ϊ<EFBFBD>޶<EFBFBD><DEB6>Ƕ<EFBFBD>
turn_data.outer_rad = calculate_outer_angle(turn_data.wheel_base, turn_data.track_width, turn_data.inner_rad, &turn_data.curvature);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽǶ<D6BD><C7B6>Լ<EFBFBD><D4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// //<2F><><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD>δ<EFBFBD><CEB4>can<61><6E><EFBFBD><EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD>Ե<EFBFBD><D4B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>բδ<D5A2>򿪵<EFBFBD><F2BFAAB5><EFBFBD><EFBFBD>
// if(power_data.current_state == POWER_WORKING)//<2F><>բ<EFBFBD><D5A2><EFBFBD><EFBFBD>
// {
// un_inf_can_kgf_output1.bit_data.KGF01 = 1;//<2F>򿪱<EFBFBD>բ
// }
// else
// {
// un_inf_can_kgf_output1.bit_data.KGF01 = 0;//<2F><>բ
// }
if ((turn_data.current_state == POWER_WORKING) && (1 == turn_data.motor_sleep))//work<72>ҵ<EFBFBD><D2B5><EFBFBD><EFBFBD>ϵ<EFBFBD><CFB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
switch(turn_process_state)//<2F>ȷ<EFBFBD><C8B7><EFBFBD><EFBFBD>л<EFBFBD>ģʽ<C4A3>Լ<EFBFBD><D4BC><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD><EFBFBD>ֱ<EFBFBD><D6B1>ʹ<EFBFBD><CAB9> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
case 0:
if(turn_process_cnt >= 20)//<2F><><EFBFBD><EFBFBD>50<35><30>
{
turn_process_cnt = 0;
turn_process_state = 1;
}
else
{
turn_process_cnt ++;
un_sdo_output4.bit_data.index = RUM_MODE;
un_sdo_output4.bit_data.object_index = 0x0;
un_sdo_output4.bit_data.data = POSITION_MODE_CSP;//<2F>趨λ<E8B6A8><CEBB>ģʽ
publishMessage(&un_sdo_output4, 1);
un_sdo_output8.bit_data.index = RUM_MODE;
un_sdo_output8.bit_data.object_index = 0x0;
un_sdo_output8.bit_data.data = POSITION_MODE_CSP;//<2F>趨λ<E8B6A8><CEBB>ģʽ
publishMessage(&un_sdo_output8, 1);
}
break;
case 1:
if(turn_process_cnt >= 10)//<2F><><EFBFBD><EFBFBD>50<35><30>
{
turn_process_cnt = 0;
turn_process_state = 2;
}
else
{
turn_process_cnt ++;
un_sdo_output3.bit_data.index = 0x0;
un_sdo_output3.bit_data.object_index = 0x0;
un_sdo_output3.bit_data.data = 0x0;//
publishMessage(&un_sdo_output3, 1);
un_sdo_output7.bit_data.index = 0x0;
un_sdo_output7.bit_data.object_index = 0x0;
un_sdo_output7.bit_data.data = 0x0;//
publishMessage(&un_sdo_output7, 1);
}
break;
case 2:
turnOutput(signal_id);
turn_process_cnt = 0;
turn_process_state = 2;
break;default:;
}
}
else//ÿ<>ε<EFBFBD><CEB5><EFBFBD><E7B6BC><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><C2B7><EFBFBD>ʹ<EFBFBD><CAB9>
{
turn_process_state = 0;
turn_process_cnt = 0;
turn_data.motor_sleep = 0;
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>źŵĺ<C5B5><C4BA><EFBFBD>
static void turnInput(void *signal_id)
{
(void)signal_id;
if (signal_id == &diff_data)
{
turn_data.mode = diff_data.mode;
turn_data.desired_curvature = diff_data.desired_curvature;
}
else if(signal_id == &power_data)//<2F><><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD>
{
turn_data.current_state = power_data.current_state;
}
else{}
turn_data.motor_sleep = 1;
turnProcess(signal_id);//<2F><><EFBFBD><EFBFBD>ӳ<EFBFBD><D3B3>
}
void turnParametersInit(void *signal_id)
{
(void)signal_id; // <20><><EFBFBD>DZ<EFBFBD><C7B1><EFBFBD>Ϊ<EFBFBD><CEAA>ʹ<EFBFBD>ã<EFBFBD><C3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//<2F><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
turn_data.right_max_position = (float)getParam("R_maxP"); // <20><>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>λ<EFBFBD>ã<EFBFBD>rad
turn_data.right_zero_position = (float)getParam("R_zeroP"); // <20><>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>λ<EFBFBD>ã<EFBFBD>rad
turn_data.right_speed = (float)getParam("R_speed"); // <20><>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>λ<EFBFBD>ã<EFBFBD>rad
turn_data.left_max_position = (float)getParam("L_maxP"); // <20><>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>λ<EFBFBD>ã<EFBFBD>rad
turn_data.left_zero_position = (float)getParam("L_zeroP"); // <20><>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>λ<EFBFBD>ã<EFBFBD>rad
turn_data.left_speed = (float)getParam("L_speed"); // <20><>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>λ<EFBFBD>ã<EFBFBD>rad
turn_data.wheel_base = (float)getParam("whl_bas"); //<2F><><EFBFBD><EFBFBD>
turn_data.track_width = (float)getParam("tra_wid"); //<2F>־<EFBFBD>
timerStart(&turn_data.turn_timer,1000,1);//1s<31><73><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>
}
void motorInit(void *signal_id)
{
if(turn_data.current_state == POWER_WORKING)
{
un_sdo_output4.bit_data.index = RUM_MODE;
un_sdo_output4.bit_data.object_index = 0x0;
un_sdo_output4.bit_data.data = POSITION_MODE_CSP;//<2F>趨λ<E8B6A8><CEBB>ģʽ
publishMessage(&un_sdo_output4, 1);
un_sdo_output8.bit_data.index = RUM_MODE;
un_sdo_output8.bit_data.object_index = 0x0;
un_sdo_output8.bit_data.data = POSITION_MODE_CSP;//<2F>趨λ<E8B6A8><CEBB>ģʽ
publishMessage(&un_sdo_output8, 1);
un_sdo_output3.bit_data.index = 0x0;
un_sdo_output3.bit_data.object_index = 0x0;
un_sdo_output3.bit_data.data = 0x0;//
publishMessage(&un_sdo_output3, 1);
un_sdo_output7.bit_data.index = 0x0;
un_sdo_output7.bit_data.object_index = 0x0;
un_sdo_output7.bit_data.data = 0x0;//
publishMessage(&un_sdo_output7, 1);
}
// timerStart(&turn_timer2,1000,1);//1s<31><73><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>
}
// <20>޸<EFBFBD>APPģ<50><C4A3><EFBFBD>ij<EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void turnAppInit(void)
{
// <20><>ʼ<EFBFBD><CABC>
memset(&turn_data, 0, sizeof(TurnData));
timerInit(&turn_data.turn_timer);
timerInit(&turn_timer2);
//<2F><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
turn_data.right_max_position = (float)getParam("R_maxP"); // <20><>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>λ<EFBFBD>ã<EFBFBD>rad
// turn_data.right_min_position = (float)getParam("R_minP"); // <20><>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>λ<EFBFBD>ã<EFBFBD>rad
turn_data.right_zero_position = (float)getParam("R_zeroP"); // <20><>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>λ<EFBFBD>ã<EFBFBD>rad
turn_data.right_speed = (float)getParam("R_speed"); // <20><>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>λ<EFBFBD>ã<EFBFBD>rad
turn_data.left_max_position = (float)getParam("L_maxP"); // <20><>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>λ<EFBFBD>ã<EFBFBD>rad
// turn_data.left_min_position = (float)getParam("L_minP"); // <20><>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>λ<EFBFBD>ã<EFBFBD>rad
turn_data.left_zero_position = (float)getParam("L_zeroP"); // <20><>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>λ<EFBFBD>ã<EFBFBD>rad
turn_data.left_speed = (float)getParam("L_speed"); // <20><>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>λ<EFBFBD>ã<EFBFBD>rad
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ź<EFBFBD>,<2C><><EFBFBD><EFBFBD>ɲ<EFBFBD><C9B2><EFBFBD>߼<EFBFBD>
subscribe(&diff_data, turnInput);
subscribe(&power_data, turnInput);
subscribe(&turn_data.turn_timer, turnParametersInit);
subscribe(&turn_timer2, motorInit);
timerStart(&turn_data.turn_timer,1000,1);//1s<31><73><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>
timerStart(&turn_timer2,1000,1);//1s<31><73><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>
printf("turnApp: initial OK \n");
}

95
app/app_turn.h Normal file
View File

@@ -0,0 +1,95 @@
#ifndef TURN_H
#define TURN_H
#ifdef __cplusplus
extern "C" {
#endif
#include "app_power.h"
#define LIMIT_SPEED_INDEX 0x7017//CSP<53><50><EFBFBD>ٶ<EFBFBD>
#define LOC_REF_INDEX 0x7016//CSP<53><50>λ<EFBFBD><CEBB>
#define RUM_MODE 0x7005//modeģʽ
#define OPERATION_MODE 0 // <20>˿<EFBFBD>ģʽ
#define POSITION_MODE_PP 1 // λ<><CEBB>ģʽ (PP - Profile Position)
#define VELOCITY_MODE 2 // <20>ٶ<EFBFBD>ģʽ
#define CURRENT_MODE 3 // <20><><EFBFBD><EFBFBD>ģʽ
#define POSITION_MODE_CSP 5 // λ<><CEBB>ģʽ (CSP - Cyclic Synchronous Position)
typedef struct TurnData
{
uint8_t mode ; // <20><><EFBFBD><EFBFBD>ģʽ
Timer turn_timer; // <20><>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><E1B9B9>
float desired_curvature; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
float curvature; // <20><>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD>
uint32_t position; // ת<><D7AA>λ<EFBFBD><CEBB>
uint8_t direction; // ת<><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
uint8_t old_direction; // ת<><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
float yaw_rate; // ת<><D7AA><EFBFBD><EFBFBD><EFBFBD>ٶȡ<D9B6>
float inner_rad; //<2F><><EFBFBD>ֽǶ<D6BD>
float outer_rad; //<2F><><EFBFBD>ֽǶ<D6BD>
uint8_t motor_sleep; // <20><><EFBFBD><EFBFBD>״̬ 0δ<30>ϵ磬1<E7A3AC><31><EFBFBD>ϵ<EFBFBD>
uint8_t emergency_stop_switch; // <20><>ͣ<EFBFBD><CDA3><EFBFBD><EFBFBD>
uint8_t remote_emergency_stop; // ң<><D2A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD><CDA3><EFBFBD><EFBFBD>
uint8_t emergency_stop_state; // <20><>ͣ״̬
PowerState current_state; // <20><>ǰ<EFBFBD><C7B0>Դ״̬
float right_max_position; // <20>ұ<EFBFBD><D2B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƕ<EFBFBD> rad
float right_zero_position; // <20>ұ߹<D2B1><DFB9><EFBFBD><EFBFBD>Ƕ<EFBFBD> rad
float right_speed; // <20>ұ<EFBFBD><D2B1>ٶ<EFBFBD> rad/s
float left_max_position; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƕ<EFBFBD> rad
float left_zero_position; // <20><><EFBFBD>߹<EFBFBD><DFB9><EFBFBD><EFBFBD>Ƕ<EFBFBD> rad
float left_speed; // <20><><EFBFBD><EFBFBD><EFBFBD>ٶ<EFBFBD> rad/s
float wheel_base; // <20><><EFBFBD><EFBFBD> m
float track_width; // <20>־<EFBFBD> m
} TurnData;
//<2F>ⲿ<EFBFBD><E2B2BF><EFBFBD><EFBFBD>
void turnAppInit(void);
#ifdef __cplusplus
}
#endif
#endif // TURN_H