| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486 |
- #include "mode_gcs_tax_launch_run.h"
- #include "auto_pilot.h"
- #include "control_attitude.h"
- #include "control_rate.h"
- #include "control_throttle.h"
- #include "euler.h"
- #include "helpler_funtions.h"
- #include "lowpass_filter.h"
- #include "matrix.h"
- #include "mode_attitude.h"
- #include "my_math.h"
- #include "params.h"
- #include "pilot_navigation.h"
- #include "soft_can_yy.h"
- #include "soft_imu.h"
- #include "soft_time.h"
- #include "soft_voltage.h"
- #include "flight_mode.h"
- #include "soft_motor_output.h"
- #include <math.h>
- #include <stdint.h>
- uint8_t __mode_state = 0; /* 模式运行阶段 */
- uint32_t __time_stamp = 0; /* 定时计数 */
- struct yy_hdw_pos
- {
- uint8_t pos_f; /* m */
- uint8_t pos_r;
- uint8_t pos_d;
- };
- /**
- * @brief 模式初始化
- *
- * @return true-初始化成功
- */
- bool gcs_tax_launch_init(void)
- {
- __mode_state = __STATE_CHECK_ACC_OVERLOAD;
- __time_stamp = micros();
- butter2_filter_init(&_cxy.vt_ff_flt[0], 200, 10);
- butter2_filter_init(&_cxy.vt_ff_flt[1], 200, 10);
- return true;
- }
- /**
- * @brief 检测过载
- *
- * @param dt 运行周期
- */
- static void _check_acc_overload_run(float dt)
- {
- const float acc_overload_thr = 1.0f * 9.8f;
- static uint32_t acc_over_load_count = 0;
- float acc_norm = 0.01f * sqrtf(raw_imu._x_acc * raw_imu._x_acc +
- raw_imu._y_acc * raw_imu._y_acc +
- raw_imu._z_acc * raw_imu._z_acc);
- if (acc_norm > acc_overload_thr)
- {
- if (acc_over_load_count++ >= 2)
- {
- // __mode_state = __STATE_SELF_STABILITY;
- // __time_stamp = micros();
- }
- }
- }
- /**
- * @brief 起飞自稳定
- *
- * @param dt 运行周期
- */
- static void _self_stability_run(float dt)
- {
- if (thr_lock_status == LOCKED)
- {
- if (micros() - __time_stamp > 0.3f * 1e6) /* 延迟 0.3s 后解锁 */
- {
- __mode_state = __STATE_LAUNCH_GO;
- pid_m_alt.thr_hold = true;
- set_thr_lock_status(UNLOCKED, LAUNCHUNLOCK);
- set_automode_target_yaw(pid_m_yaw.angle_c);
- althold_state = NO_ALT_HOLD;
- /* 清除定点积分 */
- clear_poshold_i_item(&pid_m_posx);
- clear_poshold_i_item(&pid_m_posy);
- clear_poshold_i_item(&pid_m_alt);
- /* 清除内环积分 */
- clear_rate_i_item(&pid_m_roll);
- clear_rate_i_item(&pid_m_pitch);
- clear_rate_i_item(&pid_m_yaw);
- ground_air_status = IN_AIR;
- throttle_pidctrl_status = THROTTLE_INAIR_RUNNING;
- pid_m_alt.vel_t = pid_m_alt.vel_c;
- pid_m_roll.angle_t = 0;
- pid_m_pitch.angle_t = 0;
- }
- }
- }
- extern void control_xy(struct controller_xy *cxy, float dt);
- float record_target_alt = 50 * 100; // cm
- float thr_max = 1400.0f; // 限制油门最大为
- uint16_t angle_plan_run_cnt = 0;
- #define _CXY_0_RATIO (-0.8f) // X轴加速度积分结果的比例系数(经验值,需根据实测调整)
- #define _CXY_1_RATIO (-0.8f) // Y轴加速度积分结果的比例系数
- #define _HWD_INT_PERIOD (5.0f) // 以5s为积分周期
- #define _ROLL_THRESHOLD (5.0f) // ROLL角度阈值(度)
- #define _PITCH_THRESHOLD (5.0f) // PITCH角度阈值(度)
- #define _ANGLE_PERIOD (3.0f) // 角度变化阈值时间周期(秒)
- #define _GO_BACK_TIME_PERIOD (5.0f) // 打反向运动时常
- #define _GO_BACK_EULER_ANGLE (15.0f) // 打反向欧拉角阈值(度)
- #define START_UP_STATE1_DURATION (2 * 1e6) // 弹起阶段稳定时长
- #define YAW_DELAY_AFTER_LAUNCH (6.0f * 1e6) // 起飞后航向控制延迟
- #define START_UP_STATE2_THR_RAMP_DURATION (1 * 1e6)
- // 启动阶段1给1450油门 3秒后进入策略
- #define START_UP_STATE0_THR_MAX (1400.0f) // 弹射阶段0 最大油门
- #define START_UP_STATE1_THR_MAX (1430.0f) // 弹起阶段1 最大油门
- #define START_UP_STATE2_THR_MAX (1480.0f) // 弹起阶段2 最大油门
- typedef enum
- {
- HDW_STATE_POSITION = 0, // 互定位位置控制
- HDW_STATE_ACC_INT , // 加速度积分
- HDW_STATE_BACK_EULER, // 打反向欧拉角
- HDW_STATE_RECOVER // 恢复阶段
- } hdw_state_t;
- typedef struct
- {
- hdw_state_t state;
- uint32_t state_enter_t;
- // 加速度积分
- bool acc_int_active;
- uint32_t acc_int_start_t;
- float acc_int_x;
- float acc_int_y;
- // 姿态监控
- bool angle_monitor_triggered;
- uint32_t angle_over_start_t;
- bool roll_triggered;
- bool pitch_triggered;
- // 反向欧拉
- bool euler_dir_set;
- int8_t roll_dir; // -1 / 0 / +1
- int8_t pitch_dir;
- } hdw_ctx_t;
- static hdw_ctx_t hdw_ctx = {
- .state = HDW_STATE_ACC_INT,
- .state_enter_t = 0,
- .acc_int_active = false,
- .acc_int_start_t = 0,
- .acc_int_x = 0.0f,
- .acc_int_y = 0.0f,
- .angle_monitor_triggered = false,
- .angle_over_start_t = 0,
- .roll_triggered = false,
- .pitch_triggered = false,
- .euler_dir_set = false,
- .roll_dir = 0,
- .pitch_dir = 0,
- };
- static inline void no_hdw_reset(hdw_ctx_t *ctx)
- {
- ctx->state = HDW_STATE_ACC_INT;
- ctx->state_enter_t = 0;
- ctx->acc_int_active = false;
- ctx->acc_int_start_t = 0;
- ctx->acc_int_x = 0.0f;
- ctx->acc_int_y = 0.0f;
- ctx->angle_monitor_triggered = false;
- ctx->angle_over_start_t = 0;
- }
- static inline void no_hdw_enter_state(hdw_ctx_t *ctx, hdw_state_t new_state)
- {
- ctx->state = new_state;
- ctx->state_enter_t = micros();
- // 状态切换通用清理
- ctx->angle_monitor_triggered = false;
- ctx->acc_int_active = false;
-
-
- }
- // 无互定位下状态机
- static void hdw_run_no_insgps(hdw_ctx_t *ctx, float dt)
- {
- float ax_cmd = 0.0f;
- float ay_cmd = 0.0f;
- switch (ctx->state)
- {
- case HDW_STATE_POSITION:break;
- /*================ 1. 加速度积分 =================*/
- case HDW_STATE_ACC_INT:
- {
- if (!ctx->acc_int_active)
- {
- ctx->acc_int_x = 0;
- ctx->acc_int_y = 0;
- ctx->acc_int_start_t = micros();
- ctx->acc_int_active = true;
- }
- ctx->acc_int_x += pid_m_posx.acc_c * dt * 0.01f;
- ctx->acc_int_y += pid_m_posy.acc_c * dt * 0.01f;
-
- ax_cmd = constrain_float(ctx->acc_int_x * _CXY_0_RATIO, -3.0f, 3.0f);
- ay_cmd = constrain_float(ctx->acc_int_y * _CXY_1_RATIO, -3.0f, 3.0f);
- // 姿态异常检测
- // if ((fabsf(pid_m_roll.angle_t - pid_m_roll.angle_c) > _ROLL_THRESHOLD ||
- // fabsf(pid_m_pitch.angle_t - pid_m_pitch.angle_c) > _PITCH_THRESHOLD) )
- // {
- // if(ctx->angle_monitor_triggered == false)
- // {
- // ctx->angle_monitor_triggered = true;
- // ctx->angle_over_start_t = micros();
- // }
-
- // if (micros() - ctx->angle_over_start_t > _ANGLE_PERIOD * 1e6)
- // {
- // bool roll_over = fabsf(pid_m_roll.angle_t - pid_m_roll.angle_c) > _ROLL_THRESHOLD;
- // bool pitch_over = fabsf(pid_m_pitch.angle_t - pid_m_pitch.angle_c) > _PITCH_THRESHOLD;
- // ctx->roll_triggered = roll_over;
- // ctx->pitch_triggered = pitch_over;
- // ctx->euler_dir_set = false;
- // angle_plan_run_cnt++;
- // no_hdw_enter_state(ctx, HDW_STATE_BACK_EULER);
- // }
- // }else
- // {
- // ctx->angle_monitor_triggered = false;
- // }
- // 周期性重置积分
- if (micros() - ctx->acc_int_start_t > _HWD_INT_PERIOD * 1e6)
- {
- ctx->acc_int_x = 0;
- ctx->acc_int_y = 0;
- ctx->acc_int_start_t = micros();
- }
- break;
- }
- /*================ 2. 打反向欧拉 =================*/
- case HDW_STATE_BACK_EULER:
- {
- ax_cmd = 0.0f;
- ay_cmd = 0.0f;
-
- if (!ctx->euler_dir_set)
- {
- ctx->roll_dir = (pid_m_roll.angle_c > 0) ? 1 : -1;
- ctx->pitch_dir = (pid_m_pitch.angle_c > 0) ? 1 : -1;
- ctx->euler_dir_set = true;
- }
- if (micros() - ctx->state_enter_t > _GO_BACK_TIME_PERIOD * 1e6)
- {
- no_hdw_enter_state(ctx, HDW_STATE_ACC_INT);
- }
- break;
- }
- /*================ 3. 恢复 =================*/
- case HDW_STATE_RECOVER:
- {
- if (micros() - ctx->state_enter_t > 1.0f * 1e6) // 以0姿态角持续1秒
- {
- no_hdw_enter_state(ctx, HDW_STATE_ACC_INT);
- }
- break;
- }
- default:
- no_hdw_enter_state(ctx, HDW_STATE_ACC_INT);
- break;
- }
- /* 统一输出期望加速度 */
- _cxy.at[0] = ax_cmd; // 只有在加速度积分下有用 反向欧拉直接控制欧拉角覆盖期望加速度
- _cxy.at[1] = ay_cmd;
- }
- // 设置反向欧拉角
- static void no_hdw_apply_back_euler(hdw_ctx_t *ctx)
- {
- if (ctx->state != HDW_STATE_BACK_EULER)
- return;
- if (ctx->roll_triggered)
- pid_m_roll.angle_t = -ctx->roll_dir * _GO_BACK_EULER_ANGLE;
- else
- pid_m_roll.angle_t = 0;
- if (ctx->pitch_triggered)
- pid_m_pitch.angle_t = -ctx->pitch_dir * _GO_BACK_EULER_ANGLE;
- else
- pid_m_pitch.angle_t = 0;
- }
- void __tax_launch_go_run(float dt)
- {
- const struct yy_can_rx_msg_data *yycan_data = yy_can_rx_data_get();
- hdw_ctx_t *hdw_ctx_p = &hdw_ctx;
- // start_up_ctx_t *start_up_ctx_p = &start_up_ctx;
- /**************************************/
- if (pid_m_alt.thr_hold == true)
- {
- thr_max = START_UP_STATE0_THR_MAX;
- if (micros() - __time_stamp > 2.0f * 1e6)
- {
- pid_m_alt.thr_hold = false;
- }
- althold_state = NO_ALT_HOLD;
- t_roll_last = pid_m_roll.angle_t = 0;
- t_pitch_last = pid_m_pitch.angle_t = 0;
- _cxy.reset = true;
- /*弹射后2秒钟,记录当时的高度,作为自动控制时候的目标高度*/
- // record_target_alt = pid_m_alt.loc_c;
- record_target_alt = 50 * 100; // 50m高度
- no_hdw_enter_state(hdw_ctx_p, HDW_STATE_ACC_INT);
- }
- else
- {
- // alt_reached = true;
- thr_max = START_UP_STATE2_THR_MAX; // 油门限制1480
- hdw_run_no_insgps(hdw_ctx_p, dt); // 无互定位状态机
-
- // 大地系下的期望加速度 _cxy.at[0], _cxy.at[1]
- float dcm_z[3] = {_cxy.at[0], _cxy.at[1], GRAVITY_MSS};
- Vector_Normalize(dcm_z, 3);
- float dcm_y[3] = {0, 1, 0};
- dcm_y[2] = -(dcm_z[0] * dcm_y[0] + dcm_z[1] * dcm_y[1]) / dcm_z[2];
- Vector_Normalize(dcm_y, 3);
- float dcm_x[3] = {0, 0, 0};
- Vector_CrossProduct_3D(dcm_y, dcm_z, dcm_x);
- float dcm[3][3];
- for (int i = 0; i < 3; ++i)
- {
- dcm[i][0] = dcm_x[i];
- dcm[i][1] = dcm_y[i];
- dcm[i][2] = dcm_z[i];
- }
- euler_angle_t euler = {0};
- Euler_ByDcm(dcm, &euler);
- pid_m_roll.angle_t = apply(euler.roll * RAD_TO_DEG, t_roll_last, 15.0f, dt);
- pid_m_pitch.angle_t = apply(euler.pitch * RAD_TO_DEG, t_pitch_last, 15.0f, dt);
- // no_hdw_apply_back_euler(hdw_ctx_p); // 打反向欧拉角时 覆盖期望欧拉
- t_roll_last = pid_m_roll.angle_t;
- t_pitch_last = pid_m_pitch.angle_t;
- althold_state = NO_ALT_HOLD;
- /********************优先响应高度****************/
-
- // if (!isnan(yycan_data->txgl_alt_sp) && yycan_data->txgl_alt_sp > 0 && yycan_data->txgl_alt_sp <= 100)
- // {
- // record_target_alt = yycan_data->txgl_alt_sp * 100.0f;
- // if(debug_mode == false)
- // {
- // if (fabsf(yycan_data->txgl_alt_sp * 100 - pid_m_alt.loc_c) < 30.0f)
- // {
- // updata_cmd_status(ALT_EXECUTE, true);
- // updata_cmd_status(ALT_SETTING, false);
- // alt_reached = true;
- // }
- // }
- // else
- // {
- // if(micros() - recv_alt_time > 3 * 1e6 && alt_reached == false)
- // {
- // updata_cmd_status(ALT_EXECUTE, true);
- // updata_cmd_status(ALT_SETTING, false);
- // alt_reached = true;
- // }
- // }
- // }
-
-
- //pid_m_alt.loc_t = record_target_alt;
- //float perror_u = (record_target_alt - pid_m_alt.loc_c);
- // pid_m_alt.vel_t = constrain_float(perror_u * 0.8f, -100.0f, 100.0f); // 期望速度倍做了限制 -100~100cm/s
- // pid_m_alt.vel_t = constrain_float(perror_u * 0.8f, -50.0f, 50.0f); // 期望速度倍做了限制 -50~50cm/s
- pid_m_alt.vel_t = 100.0f; // 期望速度80cm/s 以0.8m/s的速度撞击没有那么大的冲击, 加长高油门时间 减小减速油门时间 2:1
- /********************高度达到后,相应航向****************/
- if(((micros()-__time_stamp) > 6.0f * 1e6))
- {
- alt_reached = true;
- }
- if (alt_reached) // 差不多就是4秒达到最高点
- {
- // 航向到位,更新flag
- if (pid_m_yaw.enable_tyaw)
- {
- set_automode_target_yaw(yycan_data->txgl_yaw_sp);
- if (fabsf(wrap_180(pid_m_yaw.angle_c - yycan_data->txgl_yaw_sp)) < 5.0f)
- {
- updata_cmd_status(YAW_EXECUTE, true);
- updata_cmd_status(YAW_SETTING, false);
- pid_m_yaw.enable_tyaw = false;
- yaw_reached = true;
- }
- }
-
- }
- else
- {
- t_roll_last = pid_m_roll.angle_t = 0;
- t_pitch_last = pid_m_pitch.angle_t = 0;
- hdw_ctx_p->acc_int_x = 0; // 上升到最高点之前不进行加速度积分策略
- hdw_ctx_p->acc_int_y = 0;
- }
- /*所有动作暂停指令 实际台子无该指令*/
- if ((yycan_data->txgl_drone_cmd & CTL_STOP_CMD_MASK) == CTL_STOP_ACTION)
- {
- set_automode_target_yaw(wrap_360(pid_m_yaw.angle_c)); // 航向锁定
- pid_m_alt.vel_t = 0; // 垂速为0
- }
- }
- Calculate_Target_Az(fast_loop_dt);
- }
- void gcs_tax_launch_run(float dt)
- {
- switch (__mode_state)
- {
- case __STATE_CHECK_ACC_OVERLOAD:
- _check_acc_overload_run(dt);
- break;
- case __STATE_SELF_STABILITY:
- _self_stability_run(dt);
- break;
- case __STATE_LAUNCH_GO:
- __tax_launch_go_run(dt);
- break;
- default:
- break;
- }
- }
- void gcs_tax_launch_exit(void)
- {
- pid_m_alt.thr_hold = false;
- }
|