Compare commits

...

5 Commits

Author SHA1 Message Date
20b386a53b 添加发射 2026-01-10 20:48:14 +08:00
5ffc6504b8 测试底盘电机 2026-01-10 04:29:56 +08:00
71466bc61e 添加电机 2026-01-10 02:57:47 +08:00
dd27f0ba8b 添加music 2026-01-10 01:39:42 +08:00
e0dd2ed84a 修改dm 2026-01-08 10:52:20 +08:00
23 changed files with 1221 additions and 55 deletions

View File

@ -75,9 +75,18 @@ target_sources(${CMAKE_PROJECT_NAME} PRIVATE
User/device/motor_lz.c User/device/motor_lz.c
User/device/motor_rm.c User/device/motor_rm.c
# User/module sources
User/module/config.c
User/module/shoot.c
# User/task sources # User/task sources
User/task/atti_esit.c User/task/atti_esit.c
User/task/blink.c
User/task/ctrl_chassis.c
User/task/ctrl_gimbal.c
User/task/ctrl_shoot.c
User/task/init.c User/task/init.c
User/task/monitor.c
User/task/rc.c User/task/rc.c
User/task/user_task.c User/task/user_task.c
) )

View File

@ -67,6 +67,8 @@ void Error_Handler(void);
#define ACCL_CS_GPIO_Port GPIOC #define ACCL_CS_GPIO_Port GPIOC
#define GYRO_CS_Pin GPIO_PIN_3 #define GYRO_CS_Pin GPIO_PIN_3
#define GYRO_CS_GPIO_Port GPIOC #define GYRO_CS_GPIO_Port GPIOC
#define WS2812_Pin GPIO_PIN_7
#define WS2812_GPIO_Port GPIOA
#define DCMI_PWDN_Pin GPIO_PIN_5 #define DCMI_PWDN_Pin GPIO_PIN_5
#define DCMI_PWDN_GPIO_Port GPIOC #define DCMI_PWDN_GPIO_Port GPIOC
#define IMU_HEAT_Pin GPIO_PIN_1 #define IMU_HEAT_Pin GPIO_PIN_1

View File

@ -180,6 +180,10 @@ void MX_TIM3_Init(void)
sConfigOC.Pulse = 0; sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_4) != HAL_OK) if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
{ {
Error_Handler(); Error_Handler();
@ -336,10 +340,19 @@ void HAL_TIM_MspPostInit(TIM_HandleTypeDef* timHandle)
/* USER CODE END TIM3_MspPostInit 0 */ /* USER CODE END TIM3_MspPostInit 0 */
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE();
/**TIM3 GPIO Configuration /**TIM3 GPIO Configuration
PA7 ------> TIM3_CH2
PB1 ------> TIM3_CH4 PB1 ------> TIM3_CH4
*/ */
GPIO_InitStruct.Pin = WS2812_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF2_TIM3;
HAL_GPIO_Init(WS2812_GPIO_Port, &GPIO_InitStruct);
GPIO_InitStruct.Pin = IMU_HEAT_Pin; GPIO_InitStruct.Pin = IMU_HEAT_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Pull = GPIO_NOPULL;

View File

@ -182,63 +182,64 @@ Mcu.Pin12=PA1
Mcu.Pin13=PA2 Mcu.Pin13=PA2
Mcu.Pin14=PA3 Mcu.Pin14=PA3
Mcu.Pin15=PA5 Mcu.Pin15=PA5
Mcu.Pin16=PC4 Mcu.Pin16=PA7
Mcu.Pin17=PC5 Mcu.Pin17=PC4
Mcu.Pin18=PB0 Mcu.Pin18=PC5
Mcu.Pin19=PB1 Mcu.Pin19=PB0
Mcu.Pin2=PC13 Mcu.Pin2=PC13
Mcu.Pin20=PB2 Mcu.Pin20=PB1
Mcu.Pin21=PE7 Mcu.Pin21=PB2
Mcu.Pin22=PE8 Mcu.Pin22=PE7
Mcu.Pin23=PE9 Mcu.Pin23=PE8
Mcu.Pin24=PE10 Mcu.Pin24=PE9
Mcu.Pin25=PE11 Mcu.Pin25=PE10
Mcu.Pin26=PE12 Mcu.Pin26=PE11
Mcu.Pin27=PE13 Mcu.Pin27=PE12
Mcu.Pin28=PE15 Mcu.Pin28=PE13
Mcu.Pin29=PB10 Mcu.Pin29=PE15
Mcu.Pin3=PC14-OSC32_IN Mcu.Pin3=PC14-OSC32_IN
Mcu.Pin30=PB11 Mcu.Pin30=PB10
Mcu.Pin31=PB12 Mcu.Pin31=PB11
Mcu.Pin32=PB13 Mcu.Pin32=PB12
Mcu.Pin33=PB14 Mcu.Pin33=PB13
Mcu.Pin34=PB15 Mcu.Pin34=PB14
Mcu.Pin35=PD8 Mcu.Pin35=PB15
Mcu.Pin36=PD9 Mcu.Pin36=PD8
Mcu.Pin37=PD10 Mcu.Pin37=PD9
Mcu.Pin38=PD11 Mcu.Pin38=PD10
Mcu.Pin39=PD12 Mcu.Pin39=PD11
Mcu.Pin4=PC15-OSC32_OUT Mcu.Pin4=PC15-OSC32_OUT
Mcu.Pin40=PD13 Mcu.Pin40=PD12
Mcu.Pin41=PA8 Mcu.Pin41=PD13
Mcu.Pin42=PA9 Mcu.Pin42=PA8
Mcu.Pin43=PA10 Mcu.Pin43=PA9
Mcu.Pin44=PA11 Mcu.Pin44=PA10
Mcu.Pin45=PA12 Mcu.Pin45=PA11
Mcu.Pin46=PA13(JTMS/SWDIO) Mcu.Pin46=PA12
Mcu.Pin47=PA14(JTCK/SWCLK) Mcu.Pin47=PA13(JTMS/SWDIO)
Mcu.Pin48=PA15(JTDI) Mcu.Pin48=PA14(JTCK/SWCLK)
Mcu.Pin49=PC12 Mcu.Pin49=PA15(JTDI)
Mcu.Pin5=PH0-OSC_IN Mcu.Pin5=PH0-OSC_IN
Mcu.Pin50=PD0 Mcu.Pin50=PC12
Mcu.Pin51=PD1 Mcu.Pin51=PD0
Mcu.Pin52=PD2 Mcu.Pin52=PD1
Mcu.Pin53=PD4 Mcu.Pin53=PD2
Mcu.Pin54=PD5 Mcu.Pin54=PD4
Mcu.Pin55=PD6 Mcu.Pin55=PD5
Mcu.Pin56=PD7 Mcu.Pin56=PD6
Mcu.Pin57=PB3(JTDO/TRACESWO) Mcu.Pin57=PD7
Mcu.Pin58=PB5 Mcu.Pin58=PB3(JTDO/TRACESWO)
Mcu.Pin59=PB6 Mcu.Pin59=PB5
Mcu.Pin6=PH1-OSC_OUT Mcu.Pin6=PH1-OSC_OUT
Mcu.Pin60=VP_FREERTOS_VS_CMSIS_V2 Mcu.Pin60=PB6
Mcu.Pin61=VP_OCTOSPI1_VS_octo Mcu.Pin61=VP_FREERTOS_VS_CMSIS_V2
Mcu.Pin62=VP_SYS_VS_tim23 Mcu.Pin62=VP_OCTOSPI1_VS_octo
Mcu.Pin63=VP_MEMORYMAP_VS_MEMORYMAP Mcu.Pin63=VP_SYS_VS_tim23
Mcu.Pin64=VP_MEMORYMAP_VS_MEMORYMAP
Mcu.Pin7=PC0 Mcu.Pin7=PC0
Mcu.Pin8=PC1 Mcu.Pin8=PC1
Mcu.Pin9=PC2_C Mcu.Pin9=PC2_C
Mcu.PinsNb=64 Mcu.PinsNb=65
Mcu.ThirdPartyNb=0 Mcu.ThirdPartyNb=0
Mcu.UserConstants= Mcu.UserConstants=
Mcu.UserName=STM32H723VGTx Mcu.UserName=STM32H723VGTx
@ -306,6 +307,10 @@ PA3.Mode=OCTOSPI1_IOL_Port1L
PA3.Signal=OCTOSPIM_P1_IO2 PA3.Signal=OCTOSPIM_P1_IO2
PA5.Locked=true PA5.Locked=true
PA5.Signal=ADCx_INP19 PA5.Signal=ADCx_INP19
PA7.GPIOParameters=GPIO_Label
PA7.GPIO_Label=WS2812
PA7.Locked=true
PA7.Signal=S_TIM3_CH2
PA8.Locked=true PA8.Locked=true
PA8.Mode=Clock-out-1 PA8.Mode=Clock-out-1
PA8.Signal=RCC_MCO_1 PA8.Signal=RCC_MCO_1
@ -609,6 +614,8 @@ SH.S_TIM2_CH1_ETR.0=TIM2_CH1,PWM Generation1 CH1
SH.S_TIM2_CH1_ETR.ConfNb=1 SH.S_TIM2_CH1_ETR.ConfNb=1
SH.S_TIM2_CH3.0=TIM2_CH3,PWM Generation3 CH3 SH.S_TIM2_CH3.0=TIM2_CH3,PWM Generation3 CH3
SH.S_TIM2_CH3.ConfNb=1 SH.S_TIM2_CH3.ConfNb=1
SH.S_TIM3_CH2.0=TIM3_CH2,PWM Generation2 CH2
SH.S_TIM3_CH2.ConfNb=1
SH.S_TIM3_CH4.0=TIM3_CH4,PWM Generation4 CH4 SH.S_TIM3_CH4.0=TIM3_CH4,PWM Generation4 CH4
SH.S_TIM3_CH4.ConfNb=1 SH.S_TIM3_CH4.ConfNb=1
SPI1.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_4 SPI1.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_4
@ -647,8 +654,9 @@ TIM2.Prescaler=24
TIM2.Pulse-PWM\ Generation1\ CH1=5000 TIM2.Pulse-PWM\ Generation1\ CH1=5000
TIM2.Pulse-PWM\ Generation3\ CH3=5000 TIM2.Pulse-PWM\ Generation3\ CH3=5000
TIM3.AutoReloadPreload=TIM_AUTORELOAD_PRELOAD_ENABLE TIM3.AutoReloadPreload=TIM_AUTORELOAD_PRELOAD_ENABLE
TIM3.Channel-PWM\ Generation2\ CH2=TIM_CHANNEL_2
TIM3.Channel-PWM\ Generation4\ CH4=TIM_CHANNEL_4 TIM3.Channel-PWM\ Generation4\ CH4=TIM_CHANNEL_4
TIM3.IPParameters=Channel-PWM Generation4 CH4,Prescaler,Period,AutoReloadPreload TIM3.IPParameters=Channel-PWM Generation4 CH4,Prescaler,Period,AutoReloadPreload,Channel-PWM Generation2 CH2
TIM3.Period=10000-1 TIM3.Period=10000-1
TIM3.Prescaler=24-1 TIM3.Prescaler=24-1
UART5.BaudRate=100000 UART5.BaudRate=100000
@ -683,3 +691,4 @@ VP_OCTOSPI1_VS_octo.Signal=OCTOSPI1_VS_octo
VP_SYS_VS_tim23.Mode=TIM23 VP_SYS_VS_tim23.Mode=TIM23
VP_SYS_VS_tim23.Signal=SYS_VS_tim23 VP_SYS_VS_tim23.Signal=SYS_VS_tim23
board=custom board=custom
rtos.0.ip=FREERTOS

View File

@ -92,6 +92,10 @@ pwm:
custom_name: TIM2_CH3 custom_name: TIM2_CH3
label: TIM2_CH3 label: TIM2_CH3
timer: TIM2 timer: TIM2
- channel: TIM_CHANNEL_2
custom_name: WS2812
label: WS2812
timer: TIM3
- channel: TIM_CHANNEL_4 - channel: TIM_CHANNEL_4
custom_name: IMU_HEAT custom_name: IMU_HEAT
label: IMU_HEAT label: IMU_HEAT

View File

@ -27,6 +27,7 @@ typedef struct {
static const BSP_PWM_Config_t PWM_Map[BSP_PWM_NUM] = { static const BSP_PWM_Config_t PWM_Map[BSP_PWM_NUM] = {
{&htim2, TIM_CHANNEL_1}, {&htim2, TIM_CHANNEL_1},
{&htim2, TIM_CHANNEL_3}, {&htim2, TIM_CHANNEL_3},
{&htim3, TIM_CHANNEL_2},
{&htim3, TIM_CHANNEL_4}, {&htim3, TIM_CHANNEL_4},
{&htim12, TIM_CHANNEL_2}, {&htim12, TIM_CHANNEL_2},
{&htim1, TIM_CHANNEL_3}, {&htim1, TIM_CHANNEL_3},

View File

@ -25,6 +25,7 @@ extern "C" {
typedef enum { typedef enum {
BSP_PWM_TIM2_CH1, BSP_PWM_TIM2_CH1,
BSP_PWM_TIM2_CH3, BSP_PWM_TIM2_CH3,
BSP_PWM_WS2812,
BSP_PWM_IMU_HEAT, BSP_PWM_IMU_HEAT,
BSP_PWM_BUZZER, BSP_PWM_BUZZER,
BSP_PWM_TIM1_CH3, BSP_PWM_TIM1_CH3,

View File

@ -8,7 +8,7 @@ bmi088:
enabled: true enabled: true
buzzer: buzzer:
bsp_config: bsp_config:
BSP_PWM_BUZZER: BSP_PWM_TIM2_CH1 BSP_PWM_BUZZER: BSP_PWM_BUZZER
enabled: true enabled: true
dr16: dr16:
bsp_config: bsp_config:

112
User/module/config.c Normal file
View File

@ -0,0 +1,112 @@
/*
*
*/
/* Includes ----------------------------------------------------------------- */
#include "module/config.h"
/* Private typedef ---------------------------------------------------------- */
/* Private define ----------------------------------------------------------- */
/* Private macro ------------------------------------------------------------ */
/* Private variables -------------------------------------------------------- */
/* Exported variables ------------------------------------------------------- */
/**
* @brief
* @note
*/
Config_RobotParam_t robot_config = {
/* USER CODE BEGIN robot_config */
.shoot_param = {
.trig_step_angle=M_2PI/8,
.shot_delay_time=0.05f,
.shot_burst_num=1,
.fric_motor_param[0] = {
.can = BSP_CAN_2,
.id = 0x201,
.module = MOTOR_M3508,
.reverse = true,
.gear=false,
},
.fric_motor_param[1] = {
.can = BSP_CAN_2,
.id = 0x202,
.module = MOTOR_M3508,
.reverse = false,
.gear=false,
},
.trig_motor_param = {
.can = BSP_CAN_1,
.id = 0x201,
.module = MOTOR_M2006,
.reverse = true,
.gear=true,
},
.fric_follow = {
.k=1.0f,
.p=1.8f,
.i=0.0f,
.d=0.0f,
.i_limit=0.0f,
.out_limit=0.9f,
.d_cutoff_freq=30.0f,
.range=-1.0f,
},
.fric_err = {
.k=1.0f,
.p=4.0f,
.i=0.4f,
.d=0.04f,
.i_limit=0.25f,
.out_limit=0.25f,
.d_cutoff_freq=40.0f,
.range=-1.0f,
},
.trig_omg = {
.k=1.0f,
.p=1.5f,
.i=0.3f,
.d=0.5f,
.i_limit=0.2f,
.out_limit=0.9f,
.d_cutoff_freq=-1.0f,
.range=-1.0f,
},
.trig = {
.k=1.0f,
.p=1.0f,
.i=0.1f,
.d=0.05f,
.i_limit=0.8f,
.out_limit=0.5f,
.d_cutoff_freq=-1.0f,
.range=M_2PI,
},
.filter.fric = {
.in = 30.0f,
.out = 30.0f,
},
.filter.trig = {
.in = 30.0f,
.out = 30.0f,
},
},
/* USER CODE END robot_config */
};
/* Private function prototypes ---------------------------------------------- */
/* Exported functions ------------------------------------------------------- */
/**
* @brief
* @return
*/
Config_RobotParam_t* Config_GetRobotParam(void) {
return &robot_config;
}

35
User/module/config.h Normal file
View File

@ -0,0 +1,35 @@
/*
*
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stdbool.h>
#include "module/shoot.h"
/**
* @brief
* @note
*/
typedef struct {
/* USER CODE BEGIN Config_RobotParam */
Shoot_Params_t shoot_param;
/* USER CODE END Config_RobotParam */
} Config_RobotParam_t;
/* Exported functions prototypes -------------------------------------------- */
/**
* @brief
* @return
*/
Config_RobotParam_t* Config_GetRobotParam(void);
#ifdef __cplusplus
}
#endif

305
User/module/shoot.c Normal file
View File

@ -0,0 +1,305 @@
#include "shoot.h"
#include <string.h>
#include "component/filter.h"
#include "component/user_math.h"
#include <math.h>
#include "bsp/time.h"
static bool last_firecmd;
static inline void ScaleSumTo1(float *a, float *b) {
float sum = *a + *b;
if (sum > 1.0f) {
float scale = 1.0f / sum;
*a *= scale;
*b *= scale;
}
}
int8_t Shoot_SetMode(Shoot_t *s, Shoot_Mode_t mode)
{
if (s == NULL) {
return -1; // 参数错误
}
s->mode=mode;
return 0;
}
int8_t Shoot_ResetIntegral(Shoot_t *s)
{
if (s == NULL) {
return -1; // 参数错误
}
for(int i=0;i<SHOOT_FRIC_NUM;i++)
{
PID_ResetIntegral(&s->pid.fric_follow[i]);
PID_ResetIntegral(&s->pid.fric_err[i]);
}
PID_ResetIntegral(&s->pid.trig);
PID_ResetIntegral(&s->pid.trig_omg);
return 0;
}
int8_t Shoot_ResetCalu(Shoot_t *s)
{
if (s == NULL) {
return -1; // 参数错误
}
for(int i=0;i<SHOOT_FRIC_NUM;i++)
{
PID_Reset(&s->pid.fric_follow[i]);
PID_Reset(&s->pid.fric_err[i]);
LowPassFilter2p_Reset(&s->filter.fric.in[i], 0.0f);
LowPassFilter2p_Reset(&s->filter.fric.out[i], 0.0f);
}
PID_Reset(&s->pid.trig);
PID_Reset(&s->pid.trig_omg);
LowPassFilter2p_Reset(&s->filter.trig.in, 0.0f);
LowPassFilter2p_Reset(&s->filter.trig.out, 0.0f);
return 0;
}
int8_t Shoot_ResetOutput(Shoot_t *s)
{
if (s == NULL) {
return -1; // 参数错误
}
for(int i=0;i<SHOOT_FRIC_NUM;i++)
{
s->output.out_follow[i]=0.0f;
s->output.out_err[i]=0.0f;
s->output.out_fric[i]=0.0f;
s->output.lpfout_fric[i]=0.0f;
}
s->output.outagl_trig=0.0f;
s->output.outomg_trig=0.0f;
s->output.outlpf_trig=0.0f;
return 0;
}
int8_t Shoot_CaluTargetRPM(Shoot_t *s, float target_speed)
{
if (s == NULL) {
return -1; // 参数错误
}
s->target_variable.target_rpm=4000.0f/MAX_FRIC_RPM;
return 0;
}
/**
* \brief
*
* \param s
* \param num
*/
int8_t Shoot_CaluTargetAngle(Shoot_t *s, Shoot_CMD_t *cmd)
{
if (s == NULL || s->shoot_Anglecalu.num_to_shoot == 0) {
return -1;
}
if(s->now - s->shoot_Anglecalu.time_last_shoot >= s->param->shot_delay_time && cmd->firecmd)
{
s->shoot_Anglecalu.time_last_shoot=s->now;
s->target_variable.target_angle += s->param->trig_step_angle;
if(s->target_variable.target_angle>M_PI)s->target_variable.target_angle-=M_2PI;
else if((s->target_variable.target_angle<-M_PI))s->target_variable.target_angle+=M_2PI;
s->shoot_Anglecalu.num_to_shoot--;
}
return 0;
}
int8_t Shoot_Init(Shoot_t *s, Shoot_Params_t *param, float target_freq)
{
if (s == NULL || param == NULL || target_freq <= 0.0f) {
return -1; // 参数错误
}
s->param=param;
BSP_CAN_Init();
for(int i=0;i<SHOOT_FRIC_NUM;i++){
MOTOR_RM_Register(&param->fric_motor_param[i]);
PID_Init(&s->pid.fric_follow[i], KPID_MODE_CALC_D, target_freq,&param->fric_follow);
LowPassFilter2p_Init(&s->filter.fric.in[i], target_freq, s->param->filter.fric.in);
LowPassFilter2p_Init(&s->filter.fric.out[i], target_freq, s->param->filter.fric.out);
}
MOTOR_RM_Register(&param->trig_motor_param);
PID_Init(&s->pid.trig, KPID_MODE_CALC_D, target_freq,&param->trig);
PID_Init(&s->pid.trig_omg, KPID_MODE_CALC_D, target_freq,&param->trig_omg);
LowPassFilter2p_Init(&s->filter.trig.in, target_freq, s->param->filter.trig.in);
LowPassFilter2p_Init(&s->filter.trig.out, target_freq, s->param->filter.trig.out);
memset(&s->shoot_Anglecalu,0,sizeof(s->shoot_Anglecalu));
memset(&s->output,0,sizeof(s->output));
s->target_variable.target_rpm=5000.0f;
return 0;
}
int8_t Shoot_UpdateFeedback(Shoot_t *s)
{
if (s == NULL) {
return -1; // 参数错误
}
float rpm_sum=0.0f;
for(int i = 0; i < SHOOT_FRIC_NUM; i++) {
/* 更新摩擦电机反馈 */
MOTOR_RM_Update(&s->param->fric_motor_param[i]);
MOTOR_RM_t *motor_fed = MOTOR_RM_GetMotor(&s->param->fric_motor_param[i]);
if(motor_fed!=NULL)
{
s->feedback.fric[i]=motor_fed->motor.feedback;
}
/* 滤波反馈rpm */
s->feedback.fil_fric_rpm[i] = LowPassFilter2p_Apply(&s->filter.fric.in[i], s->feedback.fric[i].rotor_speed);
/* 归一化rpm */
s->feedback.fric_rpm[i] = s->feedback.fil_fric_rpm[i] / MAX_FRIC_RPM;
if(s->feedback.fric_rpm[i]>1.0f)s->feedback.fric_rpm[i]=1.0f;
if(s->feedback.fric_rpm[i]<-1.0f)s->feedback.fric_rpm[i]=-1.0f;
/* 计算平均rpm */
rpm_sum+=s->feedback.fric_rpm[i];
}
s->feedback.fric_avgrpm=rpm_sum/SHOOT_FRIC_NUM;
/* 更新拨弹电机反馈 */
MOTOR_RM_Update(&s->param->trig_motor_param);
MOTOR_RM_t *motor_fed = MOTOR_RM_GetMotor(&s->param->trig_motor_param);
if(motor_fed!=NULL)
{
s->feedback.trig=motor_fed->feedback;
}
/* 将多圈角度归化到单圈 (-M_PI, M_PI) */
s->feedback.trig_angle_cicle = s->feedback.trig.rotor_abs_angle;
s->feedback.trig_angle_cicle = fmod(s->feedback.trig_angle_cicle, M_2PI); // 将角度限制在 [-2π, 2π]
if (s->feedback.trig_angle_cicle > M_PI) {
s->feedback.trig_angle_cicle -= M_2PI; // 调整到 [-π, π]
}else if (s->feedback.trig_angle_cicle < -M_PI) {
s->feedback.trig_angle_cicle += M_2PI; // 调整到 [-π, π]
}
s->feedback.fil_trig_rpm = LowPassFilter2p_Apply(&s->filter.trig.in, s->feedback.trig.rotor_speed);
s->feedback.trig_rpm = s->feedback.trig.rotor_speed / MAX_TRIG_RPM;
if(s->feedback.trig_rpm>1.0f)s->feedback.trig_rpm=1.0f; //如果单环效果好就删
if(s->feedback.trig_rpm<-1.0f)s->feedback.trig_rpm=-1.0f;
s->errtosee = s->feedback.fric[0].rotor_speed - s->feedback.fric[1].rotor_speed;
return 0;
}
int8_t Shoot_Control(Shoot_t *s, Shoot_CMD_t *cmd)
{
if (s == NULL || cmd == NULL) {
return -1; // 参数错误
}
s->now = BSP_TIME_Get_us() / 1000000.0f;
s->dt = (BSP_TIME_Get_us() - s->lask_wakeup) / 1000000.0f;
s->lask_wakeup = BSP_TIME_Get_us();
s->online = cmd->online;
if(!s->online /*|| s->mode==SHOOT_MODE_SAFE*/){
for(int i=0;i<SHOOT_FRIC_NUM;i++)
{
MOTOR_RM_Relax(&s->param->fric_motor_param[i]);
}
MOTOR_RM_Relax(&s->param->trig_motor_param);
}
else{
switch(s->running_state)
{
case SHOOT_STATE_IDLE:/*熄火等待*/
for(int i=0;i<SHOOT_FRIC_NUM;i++)
{
PID_ResetIntegral(&s->pid.fric_follow[i]);
s->output.out_follow[i]=PID_Calc(&s->pid.fric_follow[i],0.0f,s->feedback.fric_rpm[i],0,s->dt);
s->output.out_fric[i]=s->output.out_follow[i];
s->output.lpfout_fric[i] = LowPassFilter2p_Apply(&s->filter.fric.out[i], s->output.out_fric[i]);
MOTOR_RM_SetOutput(&s->param->fric_motor_param[i], s->output.lpfout_fric[i]);
}
s->output.outagl_trig =PID_Calc(&s->pid.trig,s->target_variable.target_angle,s->feedback.trig_angle_cicle,0,s->dt);
s->output.outomg_trig =PID_Calc(&s->pid.trig_omg,s->output.outagl_trig,s->feedback.trig_rpm,0,s->dt);
s->output.outlpf_trig =LowPassFilter2p_Apply(&s->filter.trig.out, s->output.outomg_trig);
MOTOR_RM_SetOutput(&s->param->trig_motor_param, s->output.outlpf_trig);
if(cmd->ready)
{
Shoot_ResetCalu(s);
Shoot_ResetIntegral(s);
Shoot_ResetOutput(s);
s->running_state=SHOOT_STATE_READY;
}
break;
case SHOOT_STATE_READY:/*准备射击*/
for(int i=0;i<SHOOT_FRIC_NUM;i++)
{ /* 计算跟随输出、计算修正输出 */
s->output.out_follow[i]=PID_Calc(&s->pid.fric_follow[i],s->target_variable.target_rpm/MAX_FRIC_RPM,s->feedback.fric_rpm[i],0,s->dt);
s->output.out_err[i]=PID_Calc(&s->pid.fric_err[i],s->feedback.fric_avgrpm,s->feedback.fric_rpm[i],0,s->dt);
/* 按比例缩放并加和输出 */
ScaleSumTo1(&s->output.out_follow[i], &s->output.out_err[i]);
s->output.out_fric[i]=s->output.out_follow[i]+s->output.out_err[i];
/* 滤波 */
s->output.lpfout_fric[i] = LowPassFilter2p_Apply(&s->filter.fric.out[i], s->output.out_fric[i]);
/* 输出 */
MOTOR_RM_SetOutput(&s->param->fric_motor_param[i], s->output.lpfout_fric[i]);
}
/* 拨弹电机输出 */
s->output.outagl_trig =PID_Calc(&s->pid.trig,s->target_variable.target_angle,s->feedback.trig_angle_cicle,0,s->dt);
s->output.outomg_trig =PID_Calc(&s->pid.trig_omg,s->output.outagl_trig,s->feedback.trig_rpm,0,s->dt);
s->output.outlpf_trig =LowPassFilter2p_Apply(&s->filter.trig.out, s->output.outomg_trig);
MOTOR_RM_SetOutput(&s->param->trig_motor_param, s->output.outlpf_trig);
/* 检查状态机 */
if(!cmd->ready)
{
Shoot_ResetCalu(s);
Shoot_ResetOutput(s);
s->running_state=SHOOT_STATE_IDLE;
}
else if(last_firecmd==false&&cmd->firecmd==true)
{
Shoot_ResetCalu(s);
Shoot_ResetOutput(s);
s->running_state=SHOOT_STATE_FIRE;
s->shoot_Anglecalu.num_to_shoot+=s->param->shot_burst_num;
}
break;
case SHOOT_STATE_FIRE:
Shoot_CaluTargetAngle(s, cmd);
for(int i=0;i<SHOOT_FRIC_NUM;i++)
{
s->output.out_follow[i]=PID_Calc(&s->pid.fric_follow[i],s->target_variable.target_rpm/MAX_FRIC_RPM,s->feedback.fric_rpm[i],0,s->dt);
s->output.out_err[i]=PID_Calc(&s->pid.fric_err[i],s->feedback.fric_avgrpm,s->feedback.fric_rpm[i],0,s->dt);
ScaleSumTo1(&s->output.out_follow[i], &s->output.out_err[i]);
s->output.out_fric[i]=s->output.out_follow[i]+s->output.out_err[i];
s->output.lpfout_fric[i] = LowPassFilter2p_Apply(&s->filter.fric.out[i], s->output.out_fric[i]);
MOTOR_RM_SetOutput(&s->param->fric_motor_param[i], s->output.lpfout_fric[i]);
}
s->output.outagl_trig =PID_Calc(&s->pid.trig,s->target_variable.target_angle,s->feedback.trig_angle_cicle,0,s->dt);
s->output.outomg_trig =PID_Calc(&s->pid.trig_omg,s->output.outagl_trig,s->feedback.trig_rpm,0,s->dt);
s->output.outlpf_trig =LowPassFilter2p_Apply(&s->filter.trig.out, s->output.outomg_trig);
MOTOR_RM_SetOutput(&s->param->trig_motor_param, s->output.outlpf_trig);
if(!cmd->firecmd)
{
Shoot_ResetCalu(s);
Shoot_ResetOutput(s);
s->running_state=SHOOT_STATE_READY;
}
break;
default:
s->running_state=SHOOT_STATE_IDLE;
break;
}
}
MOTOR_RM_Ctrl(&s->param->fric_motor_param[0]);
MOTOR_RM_Ctrl(&s->param->trig_motor_param);
last_firecmd = cmd->firecmd;
return 0;
}

200
User/module/shoot.h Normal file
View File

@ -0,0 +1,200 @@
/*
* far蛇模组
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include "main.h"
#include <stdbool.h>
#include "component/pid.h"
#include "device/motor_rm.h"
/* Exported constants ------------------------------------------------------- */
#define SHOOT_OK (0) /* 运行正常 */
#define SHOOT_ERR (-1) /* 运行时发现了其他错误 */
#define SHOOT_ERR_NULL (-2) /* 运行时发现NULL指针 */
#define SHOOT_ERR_MODE (-3) /* 运行时配置了错误的CMD_ChassisMode_t */
#define SHOOT_ERR_TYPE (-4) /* 运行时配置了错误的Chassis_Type_t */
#define SHOOT_FRIC_NUM (2) /* 摩擦轮数量 */
#define MAX_FRIC_RPM 7000.0f
#define MAX_TRIG_RPM 5000.0f
/* Exported macro ----------------------------------------------------------- */
/* Exported types ----------------------------------------------------------- */
typedef enum {
SHOOT_STATE_IDLE = 0, // 熄火
SHOOT_STATE_READY, // 准备射击
SHOOT_STATE_FIRE // 射击
} Shoot_State_t;
typedef enum {
SHOOT_MODE_SAFE = 0, // 安全模式
SHOOT_MODE_SINGLE, // 单发模式
SHOOT_MODE_BURST, // 多发模式
SHOOT_MODE_CONTINUE // 连发模式
} Shoot_Mode_t;
typedef struct {
bool online;
bool ready; /* 准备射击 */
bool firecmd; /* 射击指令 */
} Shoot_CMD_t;
typedef struct {
MOTOR_Feedback_t fric[SHOOT_FRIC_NUM]; /* 摩擦轮电机反馈 */
MOTOR_Feedback_t trig; /* 拨弹电机反馈 */
float fil_fric_rpm[SHOOT_FRIC_NUM]; /* 滤波后的摩擦轮转速 */
float fil_trig_rpm; /* 滤波后的拨弹电机转速*/
float trig_angle_cicle; /* 拨弹电机减速输出轴单圈角度0~M_2PI */
float fric_rpm[SHOOT_FRIC_NUM]; /* 归一化摩擦轮转速 */
float fric_avgrpm; /* 归一化摩擦轮平均转速*/
float trig_rpm; /* 归一化拨弹电机转速*/
}Shoot_Feedback_t;
typedef struct{
float time_last_shoot;
uint8_t num_to_shoot;
uint8_t num_shooted;
}Shoot_AngleCalu_t;
typedef struct {
float out_follow[SHOOT_FRIC_NUM];
float out_err[SHOOT_FRIC_NUM];
float out_fric[SHOOT_FRIC_NUM];
float lpfout_fric[SHOOT_FRIC_NUM];
float outagl_trig;
float outomg_trig;
float outlpf_trig;
}Shoot_Output_t;
/* 底盘参数的结构体包含所有初始化用的参数通常是const存好几组 */
typedef struct {
float trig_step_angle; /* 每发弹丸拨弹电机转动的角度 */
float shot_delay_time; /* 射击间隔时间,单位秒 */
uint8_t shot_burst_num; /* 多发模式下一次射击的发数 */
MOTOR_RM_Param_t fric_motor_param[SHOOT_FRIC_NUM];
MOTOR_RM_Param_t trig_motor_param;
KPID_Params_t fric_follow; /* 摩擦轮电机PID控制参数用于跟随目标速度 */
KPID_Params_t fric_err; /* 摩擦轮电机PID控制参数用于消除转速误差 */
KPID_Params_t trig; /* 拨弹电机PID控制参数 */
KPID_Params_t trig_omg; /* 拨弹电机PID控制参数 */
/* 低通滤波器截止频率 */
struct {
struct{
float in; /* 反馈值滤波器 */
float out; /* 输出值滤波器 */
}fric;
struct{
float in; /* 反馈值滤波器 */
float out; /* 输出值滤波器 */
}trig;
} filter;
} Shoot_Params_t;
/*
*
*
*/
typedef struct {
bool online;
float now;
uint64_t lask_wakeup;
float dt;
Shoot_Params_t *param; /* */
/* 模块通用 */
Shoot_State_t running_state; /* 运行状态机 */
Shoot_Mode_t mode;
/* 反馈信息 */
Shoot_Feedback_t feedback;
/* 控制信息*/
Shoot_AngleCalu_t shoot_Anglecalu;
Shoot_Output_t output;
/* 目标控制量 */
struct {
float target_rpm; /* 目标摩擦轮转速 */
float target_angle; /* 目标拨弹位置 */
}target_variable;
/* 反馈控制用的PID */
struct {
KPID_t fric_follow[SHOOT_FRIC_NUM]; /* */
KPID_t fric_err[SHOOT_FRIC_NUM]; /* */
KPID_t trig;
KPID_t trig_omg;
} pid;
/* 滤波器 */
struct {
struct{
LowPassFilter2p_t in[SHOOT_FRIC_NUM]; /* 反馈值滤波器 */
LowPassFilter2p_t out[SHOOT_FRIC_NUM]; /* 输出值滤波器 */
}fric;
struct{
LowPassFilter2p_t in; /* 反馈值滤波器 */
LowPassFilter2p_t out; /* 输出值滤波器 */
}trig;
} filter;
float errtosee; /*调试用*/
} Shoot_t;
/* Exported functions prototypes -------------------------------------------- */
/**
* \brief
*
* \param s
* \param param
* \param target_freq
*
* \return
*/
int8_t Shoot_Init(Shoot_t *s, Shoot_Params_t *param, float target_freq);
/**
* \brief
*
* \param s
*
* \return
*/
int8_t Shoot_UpdateFeedback(Shoot_t *s);
/**
* \brief
*
* \param s
* \param cmd
*
* \return
*/
int8_t Shoot_Control(Shoot_t *s, Shoot_CMD_t *cmd);
#ifdef __cplusplus
}
#endif

View File

@ -49,6 +49,7 @@ static const KPID_Params_t imu_temp_ctrl_pid_param = {
void Task_atti_esit(void *argument) { void Task_atti_esit(void *argument) {
(void)argument; /* 未使用argument消除警告 */ (void)argument; /* 未使用argument消除警告 */
osDelay(ATTI_ESIT_INIT_DELAY); /* 延时一段时间再开启任务 */ osDelay(ATTI_ESIT_INIT_DELAY); /* 延时一段时间再开启任务 */
/* USER CODE INIT BEGIN */ /* USER CODE INIT BEGIN */
@ -86,4 +87,5 @@ void Task_atti_esit(void *argument) {
/* USER CODE END */ /* USER CODE END */
} }
} }

57
User/task/blink.c Normal file
View File

@ -0,0 +1,57 @@
/*
blink Task
*/
/* Includes ----------------------------------------------------------------- */
#include "task/user_task.h"
/* USER INCLUDE BEGIN */
#include "device/buzzer.h"
#include <stdint.h>
/* USER INCLUDE END */
/* Private typedef ---------------------------------------------------------- */
/* Private define ----------------------------------------------------------- */
/* Private macro ------------------------------------------------------------ */
/* Private variables -------------------------------------------------------- */
/* USER STRUCT BEGIN */
BUZZER_t buzzer;
static uint16_t count;
/* USER STRUCT END */
/* Private function --------------------------------------------------------- */
/* Exported functions ------------------------------------------------------- */
void Task_blink(void *argument) {
(void)argument; /* 未使用argument消除警告 */
/* 计算任务运行到指定频率需要等待的tick数 */
const uint32_t delay_tick = osKernelGetTickFreq() / BLINK_FREQ;
osDelay(BLINK_INIT_DELAY); /* 延时一段时间再开启任务 */
uint32_t tick = osKernelGetTickCount(); /* 控制任务运行频率的计时 */
/* USER CODE INIT BEGIN */
/* 播放启动音乐 */
BUZZER_Init(&buzzer, BSP_PWM_BUZZER);
BUZZER_PlayMusic(&buzzer, MUSIC_RM);
/* USER CODE INIT END */
while (1) {
tick += delay_tick; /* 计算下一个唤醒时刻 */
/* USER CODE BEGIN */
count++;
uint16_t phase = count % 1000;
if (phase == 0) {
/* 每秒开始播放C4音符 */
BUZZER_Set(&buzzer, 261.63f, 0.5f); // C4音符频率约261.63Hz
BUZZER_Start(&buzzer);
} else if (phase == 50) {
/* 播放100ms后停止 (50/500Hz = 0.1s) */
BUZZER_Stop(&buzzer);
}
/* USER CODE END */
osDelayUntil(tick); /* 运行结束,等待下一次唤醒 */
}
}

View File

@ -11,3 +11,38 @@
function: Task_atti_esit function: Task_atti_esit
name: atti_esit name: atti_esit
stack: 256 stack: 256
- delay: 0
description: ''
freq_control: true
frequency: 500.0
function: Task_ctrl_chassis
name: ctrl_chassis
stack: 256
- delay: 0
description: ''
freq_control: true
frequency: 500.0
function: Task_ctrl_gimbal
name: ctrl_gimbal
stack: 256
- delay: 0
description: ''
freq_control: true
frequency: 500.0
function: Task_monitor
name: monitor
stack: 256
- delay: 0
description: ''
freq_control: true
frequency: 500.0
function: Task_blink
name: blink
stack: 256
- delay: 0
description: ''
freq_control: true
frequency: 500.0
function: Task_ctrl_shoot
name: ctrl_shoot
stack: 256

60
User/task/ctrl_chassis.c Normal file
View File

@ -0,0 +1,60 @@
/*
ctrl_chassis Task
*/
/* Includes ----------------------------------------------------------------- */
#include "task/user_task.h"
/* USER INCLUDE BEGIN */
#include "bsp/can.h"
#include "device/motor.h"
#include "device/motor_lk.h"
#include "device/motor_lz.h"
/* USER INCLUDE END */
/* Private typedef ---------------------------------------------------------- */
/* Private define ----------------------------------------------------------- */
/* Private macro ------------------------------------------------------------ */
/* Private variables -------------------------------------------------------- */
/* USER STRUCT BEGIN */
MOTOR_LZ_Param_t motor_lz_param = {
.can = BSP_CAN_3,
.motor_id = 125,
.host_id = 0xFF,
.module = MOTOR_LZ_RSO3,
.reverse = false,
.mode = MOTOR_LZ_MODE_MOTION,
};
float out = 0.0f;
/* USER STRUCT END */
/* Private function --------------------------------------------------------- */
/* Exported functions ------------------------------------------------------- */
void Task_ctrl_chassis(void *argument) {
(void)argument; /* 未使用argument消除警告 */
/* 计算任务运行到指定频率需要等待的tick数 */
const uint32_t delay_tick = osKernelGetTickFreq() / CTRL_CHASSIS_FREQ;
osDelay(CTRL_CHASSIS_INIT_DELAY); /* 延时一段时间再开启任务 */
uint32_t tick = osKernelGetTickCount(); /* 控制任务运行频率的计时 */
/* USER CODE INIT BEGIN */
BSP_CAN_Init();
MOTOR_LZ_Init();
MOTOR_LZ_Register(&motor_lz_param);
/* USER CODE INIT END */
while (1) {
tick += delay_tick; /* 计算下一个唤醒时刻 */
/* USER CODE BEGIN */
MOTOR_LZ_Enable(&motor_lz_param);
/* USER CODE END */
osDelayUntil(tick); /* 运行结束,等待下一次唤醒 */
}
}

53
User/task/ctrl_gimbal.c Normal file
View File

@ -0,0 +1,53 @@
/*
ctrl_gimbal Task
*/
/* Includes ----------------------------------------------------------------- */
#include "task/user_task.h"
/* USER INCLUDE BEGIN */
#include "bsp/can.h"
#include "device/motor.h"
#include "device/motor_dm.h"
/* USER INCLUDE END */
/* Private typedef ---------------------------------------------------------- */
/* Private define ----------------------------------------------------------- */
/* Private macro ------------------------------------------------------------ */
/* Private variables -------------------------------------------------------- */
/* USER STRUCT BEGIN */
MOTOR_DM_Param_t motor_dm_yaw = {
.can = BSP_CAN_1,
.can_id = 0x1,
.master_id = 0x11,
.module = MOTOR_DM_J4310,
.reverse = false,
};
/* USER STRUCT END */
/* Private function --------------------------------------------------------- */
/* Exported functions ------------------------------------------------------- */
void Task_ctrl_gimbal(void *argument) {
(void)argument; /* 未使用argument消除警告 */
/* 计算任务运行到指定频率需要等待的tick数 */
const uint32_t delay_tick = osKernelGetTickFreq() / CTRL_GIMBAL_FREQ;
osDelay(CTRL_GIMBAL_INIT_DELAY); /* 延时一段时间再开启任务 */
uint32_t tick = osKernelGetTickCount(); /* 控制任务运行频率的计时 */
/* USER CODE INIT BEGIN */
BSP_CAN_Init();
MOTOR_DM_Register(&motor_dm_yaw);
/* USER CODE INIT END */
while (1) {
tick += delay_tick; /* 计算下一个唤醒时刻 */
/* USER CODE BEGIN */
MOTOR_DM_Enable(&motor_dm_yaw);
/* USER CODE END */
osDelayUntil(tick); /* 运行结束,等待下一次唤醒 */
}
}

51
User/task/ctrl_shoot.c Normal file
View File

@ -0,0 +1,51 @@
/*
ctrl_shoot Task
*/
/* Includes ----------------------------------------------------------------- */
#include "device/motor_rm.h"
#include "task/user_task.h"
/* USER INCLUDE BEGIN */
#include "module/shoot.h"
#include "module/config.h"
/* USER INCLUDE END */
/* Private typedef ---------------------------------------------------------- */
/* Private define ----------------------------------------------------------- */
/* Private macro ------------------------------------------------------------ */
/* Private variables -------------------------------------------------------- */
/* USER STRUCT BEGIN */
Shoot_t shoot;
Shoot_CMD_t shoot_cmd;
/* USER STRUCT END */
/* Private function --------------------------------------------------------- */
/* Exported functions ------------------------------------------------------- */
void Task_ctrl_shoot(void *argument) {
(void)argument; /* 未使用argument消除警告 */
/* 计算任务运行到指定频率需要等待的tick数 */
const uint32_t delay_tick = osKernelGetTickFreq() / CTRL_SHOOT_FREQ;
osDelay(CTRL_SHOOT_INIT_DELAY); /* 延时一段时间再开启任务 */
uint32_t tick = osKernelGetTickCount(); /* 控制任务运行频率的计时 */
/* USER CODE INIT BEGIN */
Shoot_Init(&shoot,&Config_GetRobotParam()->shoot_param,CTRL_SHOOT_FREQ);
/* USER CODE INIT END */
while (1) {
tick += delay_tick; /* 计算下一个唤醒时刻 */
/* USER CODE BEGIN */
osMessageQueueGet(task_runtime.msgq.shoot.shoot_cmd, &shoot_cmd, NULL, 0);
Shoot_UpdateFeedback(&shoot);
// Shoot_Test(&shoot);
Shoot_Control(&shoot,&shoot_cmd);
/* USER CODE END */
osDelayUntil(tick); /* 运行结束,等待下一次唤醒 */
}
}

View File

@ -7,7 +7,7 @@
#include "task/user_task.h" #include "task/user_task.h"
/* USER INCLUDE BEGIN */ /* USER INCLUDE BEGIN */
#include "module/shoot.h"
/* USER INCLUDE END */ /* USER INCLUDE END */
/* Private typedef ---------------------------------------------------------- */ /* Private typedef ---------------------------------------------------------- */
@ -32,10 +32,16 @@ void Task_Init(void *argument) {
/* 创建任务线程 */ /* 创建任务线程 */
task_runtime.thread.rc = osThreadNew(Task_rc, NULL, &attr_rc); task_runtime.thread.rc = osThreadNew(Task_rc, NULL, &attr_rc);
task_runtime.thread.atti_esit = osThreadNew(Task_atti_esit, NULL, &attr_atti_esit); task_runtime.thread.atti_esit = osThreadNew(Task_atti_esit, NULL, &attr_atti_esit);
task_runtime.thread.ctrl_chassis = osThreadNew(Task_ctrl_chassis, NULL, &attr_ctrl_chassis);
task_runtime.thread.ctrl_gimbal = osThreadNew(Task_ctrl_gimbal, NULL, &attr_ctrl_gimbal);
task_runtime.thread.monitor = osThreadNew(Task_monitor, NULL, &attr_monitor);
task_runtime.thread.blink = osThreadNew(Task_blink, NULL, &attr_blink);
task_runtime.thread.ctrl_shoot = osThreadNew(Task_ctrl_shoot, NULL, &attr_ctrl_shoot);
// 创建消息队列 // 创建消息队列
/* USER MESSAGE BEGIN */ /* USER MESSAGE BEGIN */
task_runtime.msgq.user_msg= osMessageQueueNew(2u, 10, NULL); task_runtime.msgq.user_msg= osMessageQueueNew(2u, 10, NULL);
task_runtime.msgq.shoot.shoot_cmd = osMessageQueueNew(2u, sizeof(Shoot_CMD_t), NULL);
/* USER MESSAGE END */ /* USER MESSAGE END */
osKernelUnlock(); // 解锁内核 osKernelUnlock(); // 解锁内核

44
User/task/monitor.c Normal file
View File

@ -0,0 +1,44 @@
/*
monitor Task
*/
/* Includes ----------------------------------------------------------------- */
#include "task/user_task.h"
/* USER INCLUDE BEGIN */
/* USER INCLUDE END */
/* Private typedef ---------------------------------------------------------- */
/* Private define ----------------------------------------------------------- */
/* Private macro ------------------------------------------------------------ */
/* Private variables -------------------------------------------------------- */
/* USER STRUCT BEGIN */
/* USER STRUCT END */
/* Private function --------------------------------------------------------- */
/* Exported functions ------------------------------------------------------- */
void Task_monitor(void *argument) {
(void)argument; /* 未使用argument消除警告 */
/* 计算任务运行到指定频率需要等待的tick数 */
const uint32_t delay_tick = osKernelGetTickFreq() / MONITOR_FREQ;
osDelay(MONITOR_INIT_DELAY); /* 延时一段时间再开启任务 */
uint32_t tick = osKernelGetTickCount(); /* 控制任务运行频率的计时 */
/* USER CODE INIT BEGIN */
/* USER CODE INIT END */
while (1) {
tick += delay_tick; /* 计算下一个唤醒时刻 */
/* USER CODE BEGIN */
/* USER CODE END */
osDelayUntil(tick); /* 运行结束,等待下一次唤醒 */
}
}

View File

@ -4,10 +4,10 @@
*/ */
/* Includes ----------------------------------------------------------------- */ /* Includes ----------------------------------------------------------------- */
#include "device/dr16.h"
#include "task/user_task.h" #include "task/user_task.h"
/* USER INCLUDE BEGIN */ /* USER INCLUDE BEGIN */
#include "device/dr16.h" #include "device/dr16.h"
#include "module/shoot.h"
/* USER INCLUDE END */ /* USER INCLUDE END */
/* Private typedef ---------------------------------------------------------- */ /* Private typedef ---------------------------------------------------------- */
@ -16,6 +16,8 @@
/* Private variables -------------------------------------------------------- */ /* Private variables -------------------------------------------------------- */
/* USER STRUCT BEGIN */ /* USER STRUCT BEGIN */
DR16_t dr16; DR16_t dr16;
Shoot_CMD_t for_shoot;
/* USER STRUCT END */ /* USER STRUCT END */
/* Private function --------------------------------------------------------- */ /* Private function --------------------------------------------------------- */
@ -40,9 +42,86 @@ void Task_rc(void *argument) {
DR16_StartDmaRecv(&dr16); DR16_StartDmaRecv(&dr16);
if (DR16_WaitDmaCplt(20)) { if (DR16_WaitDmaCplt(20)) {
DR16_ParseData(&dr16); DR16_ParseData(&dr16);
} else { } else {
DR16_Offline(&dr16); DR16_Offline(&dr16);
} }
// switch (dr16.data.sw_l) {
// case DR16_SW_UP:
// cmd_for_chassis.mode = CHASSIS_MODE_RELAX;
// break;
// case DR16_SW_MID:
// // cmd_for_chassis.mode = CHASSIS_MODE_RECOVER;
// cmd_for_chassis.mode = CHASSIS_MODE_WHELL_LEG_BALANCE;
// break;
// case DR16_SW_DOWN:
// // cmd_for_chassis.mode = CHASSIS_MODE_ROTOR;
// // cmd_for_chassis.mode = CHASSIS_MODE_WHELL_LEG_BALANCE;
// cmd_for_chassis.mode = CHASSIS_MODE_JUMP;
// break;
// default:
// cmd_for_chassis.mode = CHASSIS_MODE_RELAX;
// break;
// }
// cmd_for_chassis.move_vec.vx = dr16.data.ch_l_y;
// cmd_for_chassis.move_vec.vy = dr16.data.ch_l_x;
// cmd_for_chassis.move_vec.wz = dr16.data.ch_r_x;
// cmd_for_chassis.height = dr16.data.ch_res;
// osMessageQueueReset(
// task_runtime.msgq.chassis.cmd); // 重置消息队列,防止阻塞
// osMessageQueuePut(task_runtime.msgq.chassis.cmd, &cmd_for_chassis, 0,
// 0); // 非阻塞发送底盘控制命令
// switch (dr16.data.sw_l) {
// case DR16_SW_UP:
// cmd_for_gimbal.mode = GIMBAL_MODE_RELAX;
// cmd_for_gimbal.delta_yaw = 0.0f;
// cmd_for_gimbal.delta_pit = 0.0f;
// break;
// case DR16_SW_MID:
// cmd_for_gimbal.mode = GIMBAL_MODE_ABSOLUTE;
// cmd_for_gimbal.delta_yaw = -dr16.data.ch_r_x * 5.0f;
// cmd_for_gimbal.delta_pit = dr16.data.ch_r_y * 5.0f;
// break;
// case DR16_SW_DOWN:
// cmd_for_gimbal.mode = GIMBAL_MODE_ABSOLUTE;
// cmd_for_gimbal.delta_yaw = -dr16.data.ch_r_x * 5.0f;
// cmd_for_gimbal.delta_pit = dr16.data.ch_r_y * 5.0f;
// break;
// default:
// cmd_for_gimbal.mode = GIMBAL_MODE_RELAX;
// cmd_for_gimbal.delta_yaw = 0.0f;
// cmd_for_gimbal.delta_pit = 0.0f;
// break;
// }
// osMessageQueueReset(task_runtime.msgq.gimbal.cmd);
// osMessageQueuePut(task_runtime.msgq.gimbal.cmd, &cmd_for_gimbal, 0, 0);
for_shoot.online = dr16.header.online;
switch (dr16.data.sw_r) {
case DR16_SW_UP:
for_shoot.ready = false;
for_shoot.firecmd = false;
break;
case DR16_SW_MID:
for_shoot.ready = true;
for_shoot.firecmd = false;
break;
case DR16_SW_DOWN:
for_shoot.ready = true;
for_shoot.firecmd = true;
break;
default:
for_shoot.ready = false;
for_shoot.firecmd = false;
break;
}
osMessageQueueReset(task_runtime.msgq.shoot.shoot_cmd);
osMessageQueuePut(task_runtime.msgq.shoot.shoot_cmd, &for_shoot, 0, 0);
/* USER CODE END */ /* USER CODE END */
osDelayUntil(tick); /* 运行结束,等待下一次唤醒 */ osDelayUntil(tick); /* 运行结束,等待下一次唤醒 */
} }

View File

@ -19,3 +19,28 @@ const osThreadAttr_t attr_atti_esit = {
.priority = osPriorityNormal, .priority = osPriorityNormal,
.stack_size = 256 * 4, .stack_size = 256 * 4,
}; };
const osThreadAttr_t attr_ctrl_chassis = {
.name = "ctrl_chassis",
.priority = osPriorityNormal,
.stack_size = 256 * 4,
};
const osThreadAttr_t attr_ctrl_gimbal = {
.name = "ctrl_gimbal",
.priority = osPriorityNormal,
.stack_size = 256 * 4,
};
const osThreadAttr_t attr_monitor = {
.name = "monitor",
.priority = osPriorityNormal,
.stack_size = 256 * 4,
};
const osThreadAttr_t attr_blink = {
.name = "blink",
.priority = osPriorityNormal,
.stack_size = 256 * 4,
};
const osThreadAttr_t attr_ctrl_shoot = {
.name = "ctrl_shoot",
.priority = osPriorityNormal,
.stack_size = 256 * 4,
};

View File

@ -14,11 +14,21 @@ extern "C" {
/* Exported constants ------------------------------------------------------- */ /* Exported constants ------------------------------------------------------- */
/* 任务运行频率 */ /* 任务运行频率 */
#define RC_FREQ (500.0) #define RC_FREQ (500.0)
#define CTRL_CHASSIS_FREQ (500.0)
#define CTRL_GIMBAL_FREQ (500.0)
#define MONITOR_FREQ (500.0)
#define BLINK_FREQ (500.0)
#define CTRL_SHOOT_FREQ (500.0)
/* 任务初始化延时ms */ /* 任务初始化延时ms */
#define TASK_INIT_DELAY (100u) #define TASK_INIT_DELAY (100u)
#define RC_INIT_DELAY (0) #define RC_INIT_DELAY (0)
#define ATTI_ESIT_INIT_DELAY (0) #define ATTI_ESIT_INIT_DELAY (0)
#define CTRL_CHASSIS_INIT_DELAY (0)
#define CTRL_GIMBAL_INIT_DELAY (0)
#define MONITOR_INIT_DELAY (0)
#define BLINK_INIT_DELAY (0)
#define CTRL_SHOOT_INIT_DELAY (0)
/* Exported defines --------------------------------------------------------- */ /* Exported defines --------------------------------------------------------- */
/* Exported macro ----------------------------------------------------------- */ /* Exported macro ----------------------------------------------------------- */
@ -30,11 +40,39 @@ typedef struct {
struct { struct {
osThreadId_t rc; osThreadId_t rc;
osThreadId_t atti_esit; osThreadId_t atti_esit;
osThreadId_t ctrl_chassis;
osThreadId_t ctrl_gimbal;
osThreadId_t monitor;
osThreadId_t blink;
osThreadId_t ctrl_shoot;
} thread; } thread;
/* USER MESSAGE BEGIN */ /* USER MESSAGE BEGIN */
struct { struct {
osMessageQueueId_t user_msg; /* 用户自定义任务消息队列 */ osMessageQueueId_t user_msg; /* 用户自定义任务消息队列 */
struct {
osMessageQueueId_t imu;
osMessageQueueId_t cmd;
osMessageQueueId_t yaw;
}chassis;
struct {
osMessageQueueId_t imu;
osMessageQueueId_t cmd;
}gimbal;
struct {
osMessageQueueId_t shoot_cmd; /* 发射命令队列 */
}shoot;
struct {
osMessageQueueId_t rc;
osMessageQueueId_t ref;
osMessageQueueId_t ai;
}cmd;
struct {
osMessageQueueId_t quat;
osMessageQueueId_t move_vec;
osMessageQueueId_t eulr;
osMessageQueueId_t fire;
}ai;
} msgq; } msgq;
/* USER MESSAGE END */ /* USER MESSAGE END */
@ -53,16 +91,31 @@ typedef struct {
struct { struct {
UBaseType_t rc; UBaseType_t rc;
UBaseType_t atti_esit; UBaseType_t atti_esit;
UBaseType_t ctrl_chassis;
UBaseType_t ctrl_gimbal;
UBaseType_t monitor;
UBaseType_t blink;
UBaseType_t ctrl_shoot;
} stack_water_mark; } stack_water_mark;
/* 各任务运行频率 */ /* 各任务运行频率 */
struct { struct {
float rc; float rc;
float ctrl_chassis;
float ctrl_gimbal;
float monitor;
float blink;
float ctrl_shoot;
} freq; } freq;
/* 任务最近运行时间 */ /* 任务最近运行时间 */
struct { struct {
float rc; float rc;
float ctrl_chassis;
float ctrl_gimbal;
float monitor;
float blink;
float ctrl_shoot;
} last_up_time; } last_up_time;
} Task_Runtime_t; } Task_Runtime_t;
@ -74,11 +127,21 @@ extern Task_Runtime_t task_runtime;
extern const osThreadAttr_t attr_init; extern const osThreadAttr_t attr_init;
extern const osThreadAttr_t attr_rc; extern const osThreadAttr_t attr_rc;
extern const osThreadAttr_t attr_atti_esit; extern const osThreadAttr_t attr_atti_esit;
extern const osThreadAttr_t attr_ctrl_chassis;
extern const osThreadAttr_t attr_ctrl_gimbal;
extern const osThreadAttr_t attr_monitor;
extern const osThreadAttr_t attr_blink;
extern const osThreadAttr_t attr_ctrl_shoot;
/* 任务函数声明 */ /* 任务函数声明 */
void Task_Init(void *argument); void Task_Init(void *argument);
void Task_rc(void *argument); void Task_rc(void *argument);
void Task_atti_esit(void *argument); void Task_atti_esit(void *argument);
void Task_ctrl_chassis(void *argument);
void Task_ctrl_gimbal(void *argument);
void Task_monitor(void *argument);
void Task_blink(void *argument);
void Task_ctrl_shoot(void *argument);
#ifdef __cplusplus #ifdef __cplusplus
} }