control_throttle.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619
  1. #include "control_throttle.h"
  2. #include "auto_pilot.h"
  3. #include "common.h"
  4. #include "control_attitude.h"
  5. #include "control_rate.h"
  6. #include "flight_mode.h"
  7. #include "hard_imu_uart3.h"
  8. #include "helpler_funtions.h"
  9. #include "lowpass_filter.h"
  10. #include "my_crc.h"
  11. #include "my_math.h"
  12. #include "params.h"
  13. #include "pilot_navigation.h"
  14. #include "soft_flash.h"
  15. #include "soft_gps.h"
  16. #include "soft_gs.h"
  17. #include "soft_imu.h"
  18. #include "soft_motor_output.h"
  19. #include "soft_port_uart4.h"
  20. #include "soft_rc_input.h"
  21. #include "soft_sdcard.h"
  22. #include "soft_time.h"
  23. #include "soft_voltage.h"
  24. #include "ver_config.h"
  25. // #include "control_poshold.h"
  26. #include <math.h>
  27. /* 油门控制输出状态 */
  28. ThrCtrolStatusType throttle_pidctrl_status = THROTTLE_OFF;
  29. /* 是否允许调试解锁, 若允许则会禁用部分解锁条件限制 */
  30. bool _enable_unlock_tune = false;
  31. void throttle_enable_unlock_tune(void) { _enable_unlock_tune = true; }
  32. bool throttle_get_enable_unlock_tune(void)
  33. {
  34. return _enable_unlock_tune;
  35. }
  36. /**
  37. * @brief 是否允许地面站指令解锁
  38. *
  39. * @return int
  40. */
  41. int judge_pilot_gsunlock_allow(void)
  42. {
  43. if (thr_lock_status == UNLOCKED)
  44. return UNLOCK_ALLOW;
  45. // imu 数据错误
  46. if (imu_link_status != COMP_NORMAL)
  47. {
  48. return UNLOCK_NOIMU;
  49. }
  50. // imu 通讯错误包
  51. if (dma_iserror == true)
  52. {
  53. return UNLOCK_DMAERR;
  54. }
  55. // 无解算定位
  56. if (ins.insgps_ok != INSGPS)
  57. {
  58. return UNLOCK_NOINSGPS;
  59. }
  60. // GPS 状态标志位异常不允许解锁
  61. if ((raw_gps._gps_status & GPS_STATUS1_ERROR_MASK) ||
  62. (raw_gps._gps_status2 & GPS_STATUS2_ERROR_MASK))
  63. {
  64. return UNLOCK_GPSERR;
  65. }
  66. // IMU 磁状态异常
  67. if (raw_gps._mag_status & MAG_STATUS_ERROR_MASK)
  68. {
  69. return UNLOCK_MAGERROR;
  70. }
  71. // 动力异常
  72. if (Motor_GetFailsafeNum() > 0 && _enable_unlock_tune == false)
  73. {
  74. return UNLOCK_SERVO_FAILSAFE;
  75. }
  76. // IMU 陀螺加速度计异常
  77. if (raw_gps._acc_gyro_status & ACCGYRO_STATUS_ERROR_MASK)
  78. {
  79. return UNLOCK_ACCERR;
  80. }
  81. // 速度超范围不允许解锁
  82. if (thr_lock_status == LOCKED && ins.insgps_ok == INSGPS &&
  83. (fabsf(pid_m_posx.vel_c) > 40.0f || fabsf(pid_m_posy.vel_c) > 40.0f ||
  84. fabsf(pid_m_alt.vel_c) > 40.0f))
  85. {
  86. return UNLOCK_VELERR;
  87. }
  88. // 加计超范围不允许解锁
  89. if (thr_lock_status == LOCKED &&
  90. (fabsf(pid_m_posx.acc_c) > 80.0f || fabsf(pid_m_posy.acc_c) > 80.0f ||
  91. fabsf(pid_m_alt.acc_c) > 80.0f))
  92. {
  93. return UNLOCK_ACCERR;
  94. }
  95. // 陀螺超范围不允许解锁
  96. if (thr_lock_status == LOCKED &&
  97. (fabsf(pid_m_roll.gyro_c) > 10.0f ||
  98. fabsf(pid_m_pitch.gyro_c) > 10.0f || fabsf(pid_m_yaw.gyro_c) > 10.0f))
  99. {
  100. return UNLOCK_GYROERROR;
  101. }
  102. // 姿态倾斜超范围不允许解锁
  103. if (thr_lock_status == LOCKED && (fabsf(pid_m_roll.angle_c) > 30.0f ||
  104. fabsf(pid_m_pitch.angle_c) > 30.0f))
  105. {
  106. return UNLOCK_LEAN_ANGLE;
  107. }
  108. // 温度超范围不允许解锁
  109. if (thr_lock_status == LOCKED && ins.temprature > 80)
  110. {
  111. return UNLOCK_OVER_TEMPRATURE;
  112. }
  113. // 电压低不允许解锁
  114. if (battary_volt_islow)
  115. {
  116. return UNLOCK_VOLT_LOW;
  117. }
  118. // 智能电池故障不允许解锁
  119. const VoltageBms *bms = Voltage_GetBmsInfo();
  120. if (bms->link_status == COMP_NORMAL)
  121. {
  122. if (bms->electricity_percentage < params_get_value(ParamNum_BmsLowCapcityPercentage))
  123. {
  124. return UNLOCK_BMS_LOW_CAPACITY;
  125. }
  126. if (bms->fault_status >= BMS_FAULT_SERIOUS)
  127. {
  128. return UNLOCK_BMS_FAULT;
  129. }
  130. }
  131. else if (bms->link_status == COMP_LOST)
  132. {
  133. return UNLOCK_BMS_LINK_LOST;
  134. }
  135. // sd 卡故障不允许解锁
  136. if (sdcard_initok() == 0)
  137. {
  138. return UNLOCK_SD_FAIL;
  139. }
  140. return UNLOCK_ALLOW;
  141. }
  142. /**
  143. * @brief 是否允许遥控器解锁
  144. *
  145. * @return int
  146. */
  147. int judge_pilot_rcunlock_allow(void)
  148. {
  149. if (thr_lock_status == UNLOCKED)
  150. return UNLOCK_ALLOW;
  151. // 遥控器位置不对
  152. if ((rc_in[RC_CH6] < MAX_S || rc_in[RC_CH6] > MAX_E ||
  153. rc_in[RC_CH7] < MAX_S || rc_in[RC_CH7] > MAX_E) &&
  154. thr_lock_status == LOCKED && comp_rc_status == COMP_NORMAL)
  155. {
  156. return UNLOCK_RCERR;
  157. }
  158. // imu 数据错误
  159. if (imu_link_status != COMP_NORMAL)
  160. {
  161. return UNLOCK_NOIMU;
  162. }
  163. // imu 通讯错误包
  164. if (dma_iserror == true)
  165. {
  166. return UNLOCK_DMAERR;
  167. }
  168. // GPS 状态标志位异常不允许解锁
  169. if (((raw_gps._gps_status & GPS_STATUS1_ERROR_MASK) ||
  170. (raw_gps._gps_status2 & GPS_STATUS2_ERROR_MASK)) &&
  171. _enable_unlock_tune == false)
  172. {
  173. return UNLOCK_GPSERR;
  174. }
  175. // IMU 磁状态异常
  176. if ((raw_gps._mag_status & MAG_STATUS_ERROR_MASK) &&
  177. _enable_unlock_tune == false)
  178. {
  179. return UNLOCK_MAGERROR;
  180. }
  181. if (Motor_GetFailsafeNum() > 0 && _enable_unlock_tune == false)
  182. {
  183. return UNLOCK_SERVO_FAILSAFE;
  184. }
  185. // IMU 陀螺加速度计异常
  186. if (raw_gps._acc_gyro_status & ACCGYRO_STATUS_ERROR_MASK)
  187. {
  188. return UNLOCK_ACCERR;
  189. }
  190. // 速度超范围不允许解锁
  191. if (thr_lock_status == LOCKED && ins.insgps_ok == INSGPS &&
  192. (fabsf(pid_m_posx.vel_c) > 40.0f || fabsf(pid_m_posy.vel_c) > 40.0f ||
  193. fabsf(pid_m_alt.vel_c) > 40.0f) &&
  194. _enable_unlock_tune == false)
  195. {
  196. return UNLOCK_VELERR;
  197. }
  198. // 加计超范围不允许解锁
  199. if (thr_lock_status == LOCKED &&
  200. (fabsf(pid_m_posx.acc_c) > 80.0f || fabsf(pid_m_posy.acc_c) > 80.0f ||
  201. fabsf(pid_m_alt.acc_c) > 80.0f) &&
  202. _enable_unlock_tune == false)
  203. {
  204. return UNLOCK_ACCERR;
  205. }
  206. // 陀螺超范围不允许解锁
  207. if (thr_lock_status == LOCKED &&
  208. (fabsf(pid_m_roll.gyro_c) > 10.0f ||
  209. fabsf(pid_m_pitch.gyro_c) > 10.0f ||
  210. fabsf(pid_m_yaw.gyro_c) > 10.0f) &&
  211. _enable_unlock_tune == false)
  212. {
  213. return UNLOCK_GYROERROR;
  214. }
  215. // 姿态倾斜超范围不允许解锁
  216. if (thr_lock_status == LOCKED && (fabsf(pid_m_roll.angle_c) > 30.0f ||
  217. fabsf(pid_m_pitch.angle_c) > 30.0f))
  218. {
  219. return UNLOCK_LEAN_ANGLE;
  220. }
  221. // 温度超范围不允许解锁
  222. if (thr_lock_status == LOCKED && ins.temprature > 80)
  223. {
  224. return UNLOCK_OVER_TEMPRATURE;
  225. }
  226. // 电压低不允许解锁
  227. if (battary_volt_islow && _enable_unlock_tune == false)
  228. {
  229. return UNLOCK_VOLT_LOW;
  230. }
  231. const VoltageBms *bms = Voltage_GetBmsInfo();
  232. if (bms->link_status == COMP_NORMAL)
  233. {
  234. if (bms->electricity_percentage < params_get_value(ParamNum_BmsLowCapcityPercentage) && _enable_unlock_tune == false)
  235. {
  236. return UNLOCK_BMS_LOW_CAPACITY;
  237. }
  238. if (bms->fault_status >= BMS_FAULT_SERIOUS && _enable_unlock_tune == false)
  239. {
  240. return UNLOCK_BMS_FAULT;
  241. }
  242. }
  243. else if (bms->link_status == COMP_LOST && _enable_unlock_tune == false)
  244. {
  245. return UNLOCK_BMS_LINK_LOST;
  246. }
  247. // sd卡故障不允许解锁
  248. if (sdcard_initok() == 0 && _enable_unlock_tune == false)
  249. {
  250. return UNLOCK_SD_FAIL;
  251. }
  252. return UNLOCK_ALLOW;
  253. }
  254. #define PILOT_RCUNLOCK_PERIOD 200000
  255. unsigned int pilot_rcunlock_time = 0, pilot_rcunlock_delay = 0;
  256. // 上锁方式的标志位
  257. char thr_lock_flag = DEFLOCK;
  258. // 解锁方式的标志位
  259. char thr_unlock_flag = DEFUNLOCK;
  260. // 上锁状态位
  261. char thr_lock_status = LOCKED;
  262. // 起飞状态位
  263. char ground_air_status = ON_GROUND;
  264. void pilot_unlock_decide(void)
  265. {
  266. int rcunlock_allow_flag = judge_pilot_rcunlock_allow();
  267. // 遥控器模式下
  268. if (control_mode == CONTROL_REMOTE && rc_signal_health == RC_SIGNAL_HEALTH)
  269. { // 遥控器解锁
  270. if (thr_lock_status == LOCKED && rcunlock_allow_flag == UNLOCK_ALLOW &&
  271. (rc_in[RC_CH1] > 1950) && (rc_in[RC_CH2] > 1950) &&
  272. (rc_in[RC_CH3] < 1050) && (rc_in[RC_CH4] < 1050))
  273. {
  274. pilot_rcunlock_delay += micros() - pilot_rcunlock_time;
  275. pilot_rcunlock_time = micros();
  276. if (pilot_rcunlock_delay > PILOT_RCUNLOCK_PERIOD)
  277. {
  278. pilot_rcunlock_delay = 0;
  279. set_thr_lock_status(UNLOCKED, RCUNLOCK);
  280. // 解锁成功
  281. if (thr_lock_status == UNLOCKED)
  282. {
  283. pid_m_yaw.angle_t = pid_m_yaw.angle_c;
  284. // 每次解锁清气压,清零气压由控制端来完成,因为给IMU发命令会导致DMA错误
  285. unclock_clear_altitude();
  286. // 初始化定点参数
  287. clear_poshold_i_item(&pid_m_posx);
  288. clear_poshold_i_item(&pid_m_posy);
  289. clear_poshold_i_item(&pid_m_alt);
  290. }
  291. else
  292. {
  293. }
  294. }
  295. }
  296. else
  297. {
  298. pilot_rcunlock_delay = 0;
  299. pilot_rcunlock_time = micros();
  300. }
  301. }
  302. else if (control_mode == CONTROL_GCS)
  303. {
  304. }
  305. }
  306. /*
  307. 飞行器起飞识别
  308. */
  309. // 基础油门
  310. float base_thr = 1000; // HOVER_THR;
  311. void pilot_takeoff_decide(void)
  312. {
  313. // 遥控器 姿态模式/定点模式 下起飞判断
  314. if (control_mode == CONTROL_REMOTE &&
  315. (flight_mode == ATTITUDE || flight_mode == GPS_POSHOLD) &&
  316. thr_lock_status == UNLOCKED && ground_air_status == ON_GROUND)
  317. {
  318. if (rc_in[RC_CH3] <= (1200 + RC_DEAD_ZONE))
  319. {
  320. record_position(&pid_m_posx.loc_t, &pid_m_posy.loc_t,
  321. pid_m_posx.loc_c, pid_m_posy.loc_c);
  322. clear_poshold_i_item(&pid_m_posx);
  323. clear_poshold_i_item(&pid_m_posy);
  324. clear_poshold_i_item(&pid_m_alt);
  325. // 解锁后没有推油门的落锁设置在解锁判断里面
  326. }
  327. else if (rc_in[RC_CH3] > (1200 + RC_DEAD_ZONE))
  328. {
  329. ground_air_status = IN_AIR;
  330. throttle_pidctrl_status = THROTTLE_INAIR_RUNNING;
  331. }
  332. }
  333. }
  334. /**
  335. * @brief 上锁识别 TODO:遥控器上锁识别放到手动飞行模式中去
  336. *
  337. */
  338. void pilot_lock_decide(void)
  339. {
  340. static uint32_t remote_rclock_time = 0, remote_rclock_delay = 0;
  341. // 如果是在遥控器模式下
  342. if (control_mode == CONTROL_REMOTE && rc_signal_health == RC_SIGNAL_HEALTH)
  343. {
  344. // 如果已经解锁
  345. if (thr_lock_status == UNLOCKED)
  346. {
  347. if (flight_mode != GPS_RTH)
  348. {
  349. // 检测遥控器主动操作上锁
  350. if ((rc_in[RC_CH1] < 1050) && (rc_in[RC_CH4] > 1950) &&
  351. (rc_in[RC_CH3] < 1050) && (rc_in[RC_CH2] > 1950))
  352. {
  353. remote_rclock_delay += micros() - remote_rclock_time;
  354. remote_rclock_time = micros();
  355. if (remote_rclock_delay > 0.2f * 1000000)
  356. {
  357. remote_rclock_delay = 0;
  358. set_thr_lock_status(LOCKED, RCLOCK);
  359. }
  360. }
  361. else
  362. {
  363. remote_rclock_delay = 0;
  364. remote_rclock_time = micros();
  365. }
  366. }
  367. }
  368. // 如果已经上锁
  369. else
  370. {
  371. // 清零计时变量
  372. remote_rclock_delay = 0;
  373. remote_rclock_time = micros();
  374. }
  375. }
  376. }
  377. /*
  378. 通过遥控器的值获取期望爬升速度
  379. */
  380. char althold_state = NO_ALT_HOLD;
  381. extern float thr_max;
  382. // 有个±5的余量,避免垂直速度方向有偏差导致小速度时无法正确执行。15太大了。
  383. void get_pilot_desired_climb_rate_fromrc(short thr_in)
  384. {
  385. float desired_rate = 0.0f; // cm/s
  386. static unsigned int stop_time = 0;
  387. // ensure a reasonable throttle value
  388. thr_in = constrain_int16(thr_in, 1000, 2000);
  389. if (rc_in[RC_CH8] < 1500)
  390. {
  391. althold_state = NO_ALT_HOLD;
  392. pid_m_alt.loc_t = pid_m_alt.loc_c;
  393. pid_m_alt.vel_t = 0;
  394. return;
  395. }
  396. // 8通 且遥控器健康
  397. if(rc_in[RC_CH8] > 1500 && comp_rc_status == COMP_NORMAL && rc_signal_health == RC_SIGNAL_HEALTH)
  398. {
  399. pid_m_alt.vel_t = 150; // 期望高度等于当前高度+
  400. althold_state = NO_ALT_HOLD;
  401. thr_max = 1700.0f;
  402. return;
  403. }
  404. // check throttle is above, below or in the deadband
  405. if (thr_in < 1500 - RC_DEAD_ZONE)
  406. {
  407. // below the deadband
  408. desired_rate = -10 + ((parinf._par_maxdownspeed * 10) * (thr_in - (1500 - RC_DEAD_ZONE)) / 450.0f);
  409. althold_state = NO_ALT_HOLD;
  410. pid_m_alt.vel_t = desired_rate;
  411. stop_time = 0;
  412. }
  413. else if (thr_in > 1500 + RC_DEAD_ZONE)
  414. {
  415. // above the deadband
  416. desired_rate = 20 + ((parinf._par_maxupspeed * 10) * (thr_in - (1500 + RC_DEAD_ZONE)) / 450.0f);
  417. althold_state = NO_ALT_HOLD;
  418. pid_m_alt.vel_t = desired_rate;
  419. stop_time = 0;
  420. }
  421. else
  422. {
  423. if (althold_state != ALT_HOLD)
  424. {
  425. pid_m_alt.vel_t = 0.0f;
  426. if (fabsf(pid_m_alt.vel_c) > 30.0f)
  427. stop_time = micros();
  428. if ((unsigned int)(micros() - stop_time > 1500000)) // 1.5s定高
  429. {
  430. althold_state = ALT_HOLD;
  431. pid_m_alt.loc_t = pid_m_alt.loc_c;
  432. }
  433. }
  434. }
  435. }
  436. /**************************实现函数********************************************
  437. *函数原型: void Acc_AltHold_Control()
  438. *功  能: 高度控制
  439. *******************************************************************************/
  440. void Calculate_Target_Az(float dt)
  441. {
  442. // 如果是定高状态,则将高度差计算在内,否则置0
  443. if (althold_state == ALT_HOLD)
  444. {
  445. pid_m_alt.vel_t = cal_tar_vel_z(pid_m_alt.loc_t, pid_m_alt.loc_c, 400, 400);
  446. // 计算垂直速度差
  447. pid_m_alt.vel_e = pid_m_alt.vel_t - pid_m_alt.vel_c;
  448. // 速度的差需要放开,这样从升降速切换到定高时能快速定住
  449. pid_m_alt.vel_e = constrain_float(pid_m_alt.vel_e, -500.0f, 500.0f);
  450. }
  451. else if (althold_state == NO_ALT_HOLD)
  452. {
  453. // 计算垂直速度差
  454. pid_m_alt.vel_e = pid_m_alt.vel_t - pid_m_alt.vel_c;
  455. // 速度的差需要放开,这样从升降速切换到定高时能快速定住
  456. pid_m_alt.vel_e = constrain_float(pid_m_alt.vel_e, -500.0f, 500.0f);
  457. }
  458. pid_m_alt.vel_p_item = pid_m_alt.vel_e * pid_v_alt.speed_p;
  459. pid_m_alt.acc_t = pid_m_alt.vel_p_item;
  460. }
  461. /*
  462. 高度通道加速度pi到油门
  463. */
  464. void rate_pid_acctothrottle_alt(float dt)
  465. {
  466. pid_m_alt.acc_t = constrain_float(pid_m_alt.acc_t, -400.0f, 400.0f);
  467. pid_m_alt.acc_e = pid_m_alt.acc_t - pid_m_alt.acc_c;
  468. pid_m_alt.acc_e = constrain_float(pid_m_alt.acc_e, -500.0f, 500.0f);
  469. //----------P--------------------
  470. // 加速度差转换为电机输出量 ,系数为0.4
  471. pid_m_alt.acc_p_item = pid_m_alt.acc_e * pid_v_alt.acc_p;
  472. //------------------I-----------
  473. // 加速度差的积分,系数为1.5,1m/s^2的加速度差1s积分1500
  474. pid_m_alt.acc_i_item += dt * pid_v_alt.acc_i * constrain_float(pid_m_alt.acc_e, -100.0f, +100.0f) * 10.0f;
  475. pid_m_alt.acc_i_item = constrain_float(pid_m_alt.acc_i_item, 1000 - conf_par.idle_speed, 1650 - base_thr); // -100 300
  476. // 在地上的时候积分不累加
  477. if (ground_air_status != IN_AIR)
  478. {
  479. pid_m_alt.acc_i_item = 0.0f;
  480. }
  481. // 油门输出量
  482. pid_m_alt.pid_out = pid_m_alt.acc_p_item + pid_m_alt.acc_i_item;
  483. // 去掉Z轴声音会变大
  484. pid_m_alt.pid_out = pid_m_alt.pid_out_last + constrain_float((pid_m_alt.pid_out - pid_m_alt.pid_out_last), -10.0f, 10.0f);
  485. pid_m_alt.pid_out_last = pid_m_alt.pid_out;
  486. pid_m_alt.pid_out = constrain_float(pid_m_alt.pid_out, -200.0f, 600.0f);
  487. // pid_m_alt.pid_out = constrain_float(pid_m_alt.pid_out, 0.0f, 600.0f); // 抗冲击必须有
  488. // 如果监测到可能在地面,则油门控制 pid 量清空
  489. if (throttle_pidctrl_status == THROTTLE_OFF ||
  490. throttle_pidctrl_status == THROTTLE_ONGROUND_IDLE)
  491. {
  492. pid_m_alt.pid_out = 0.0f;
  493. pid_m_alt.acc_i_item = 0.0f;
  494. }
  495. if (pid_m_alt.thr_hold == true)
  496. {
  497. pid_m_alt.acc_i_item = 100;
  498. pid_m_alt.pid_out_last = 100;
  499. pid_m_alt.pid_out = 100;
  500. }
  501. }
  502. bool unlock_fail = false;
  503. void set_thr_lock_status(uint8_t lock_status, uint8_t reason)
  504. {
  505. if (lock_status == LOCKED)
  506. {
  507. thr_lock_status = LOCKED;
  508. ground_air_status = ON_GROUND;
  509. throttle_pidctrl_status = THROTTLE_OFF;
  510. notify_imu_lock = true;
  511. thr_lock_flag = reason;
  512. wp_have_cycle_times = 0;
  513. }
  514. else if (lock_status == UNLOCKED)
  515. {
  516. notify_imu_unlock = true;
  517. {
  518. thr_lock_status = UNLOCKED;
  519. ground_air_status = ON_GROUND;
  520. thr_unlock_flag = reason;
  521. throttle_pidctrl_status = THROTTLE_ONGROUND_IDLE;
  522. unlock_fail = false;
  523. }
  524. if (thr_lock_status == LOCKED)
  525. {
  526. unlock_fail = true;
  527. }
  528. }
  529. }
  530. void clear_poshold_i_item(struct pid_method_ap *method)
  531. {
  532. method->acc_i_item = 0.0f;
  533. method->vel_i_item = 0.0f;
  534. }