dl-dwd.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535
  1. /*
  2. * dl-dwd.c
  3. *
  4. * Created on: 2019��6��20��
  5. * Author: Eric
  6. */
  7. #include "stdint.h"
  8. #include "stdlib.h"
  9. #include "driver.h"
  10. #include "dl-dwd.h"
  11. #include "obs.h"
  12. #include "guide.h"
  13. #include "mns.h"
  14. #include "senchuang.h"
  15. #include "systick.h"
  16. #include "chassis_bus.h"
  17. #include "kinco.h"
  18. #include "bms.h"
  19. #include "kinco.h"
  20. #define DBG_SECTION_NAME "dwd"
  21. #define DBG_LEVEL DBG_INFO
  22. #include <rtdbg.h>
  23. McWalkInit_t McWalkInit;
  24. McWalkProcess_t McWalkProcess;
  25. McWalkQueryProcess_t McWalkQueryProcess;
  26. //McWalkParse_t McWalkParse;
  27. static struct chassis_bus_parse DRBusParse = {0};
  28. static int DrRecvProcess(void *parser, void *msg, int sz)
  29. {
  30. rt_can_msg_t can_msg = (rt_can_msg_t)msg;
  31. int16_t mgs = 0;
  32. ag_bms_parse(can_msg); //奥冠电池解析
  33. bms_parse(can_msg); //维旭电池解析
  34. motor_msg_parse(can_msg); //步科电机解析
  35. switch(can_msg->id)
  36. {
  37. case 3:
  38. mgs = MnsParseCanHs(can_msg->data, S.Branch, &S.FMgsOnline);
  39. if(mgs != S.FMgsOffset){
  40. S.FMgsOffset = mgs;
  41. //LogDebugCan("[%d]mpf:%d %d", Timer1ms, mgs, S.FMgsOffset);
  42. }
  43. break;
  44. case 4:
  45. mgs = MnsParseCanHs(can_msg->data, S.Branch, &S.BMgsOnline);
  46. if(mgs != S.BMgsOffset){
  47. S.BMgsOffset = mgs;
  48. //LogDebugCan("[%d]mpb:%d %d", Timer1ms, mgs, S.BMgsOffset);
  49. }
  50. break;
  51. case 5:
  52. mgs = MnsParseCanHs(can_msg->data, S.Branch, &S.LMgsOnline);
  53. if(mgs != S.LMgsOffset){
  54. S.LMgsOffset = mgs;
  55. //LogDebugCan("[%d]mpl:%d %d", Timer1ms, mgs, S.LMgsOffset);
  56. }
  57. break;
  58. case 6:
  59. mgs = MnsParseCanHs(can_msg->data, S.Branch, &S.RMgsOnline);
  60. if(mgs != S.RMgsOffset){
  61. S.RMgsOffset = mgs;
  62. //LogDebugCan("[%d]mpr:%d %d", Timer1ms, mgs, S.RMgsOffset);
  63. }
  64. break;
  65. case 0x0671:
  66. case 0x0672:
  67. case 0x0676:
  68. case 0x0677:
  69. case 0x0700:
  70. case 0x067a:
  71. case 0x067b:
  72. McWalkParseSenChuang(can_msg->id, can_msg->data);
  73. default:
  74. return true;
  75. }
  76. return true;
  77. }
  78. rt_inline bool drManualFB(bool positive) {
  79. Set.FWlkRpm = positive?(Set.RpmManual):-Set.RpmManual;
  80. return true;
  81. }
  82. rt_inline bool drManualLR(bool positive) {
  83. Set.FWlkRpm = positive?(-Set.RpmManual):Set.RpmManual;
  84. return true;
  85. }
  86. /* ��ȡ��С��ƫ���� */
  87. rt_inline int16_t getMinOffset(void){
  88. int16_t ret = S.FMgsOffset;
  89. if(S.BMgsOffset < ret){
  90. ret = S.BMgsOffset;
  91. }
  92. if(S.LMgsOffset < ret){
  93. ret = S.LMgsOffset;
  94. }
  95. if(S.RMgsOffset < ret){
  96. ret = S.RMgsOffset;
  97. }
  98. return ret;
  99. }
  100. rt_inline int16_t getMaxOffset(void){
  101. int16_t ret = S.FMgsOffset;
  102. if(S.BMgsOffset > ret){
  103. ret = S.BMgsOffset;
  104. }
  105. if(S.LMgsOffset > ret){
  106. ret = S.LMgsOffset;
  107. }
  108. if(S.RMgsOffset > ret){
  109. ret = S.RMgsOffset;
  110. }
  111. return ret;
  112. }
  113. rt_inline bool drRotate(bool positive, bool stop) {
  114. static volatile uint32_t stopWait = 0;
  115. int16_t offset = 0;
  116. int16_t rpm = Set.RpmRotate;
  117. if(stop){
  118. rpm = 500;
  119. }
  120. Set.FAngle = Cfg.RoteAngle;
  121. Set.BAngle = Cfg.RoteAngle;
  122. if(FAngleReach && BAngleReach){
  123. /* ���ת��ʮ�ּ�����ǰ��ŵ�Ϊ��־����ֹͣ */
  124. if(stop && AGV_ON_CROSS && Set.RotateCnt <= 0){
  125. offset = positive?getMinOffset():getMaxOffset();
  126. LOG_I("Rote:offset=%d", offset);
  127. rpm = positive?offset*2:-offset*2;
  128. //LogLocalPrintf("Rote:Stop X%d-%d = %d\r\n", S.FMgsOffset, S.FMgsOffset, rpm);
  129. }
  130. Set.FWlkRpm = positive?(-rpm):rpm;
  131. Set.BWlkRpm = positive?rpm:(-rpm);
  132. if(Cfg.RoteAngle < 0){
  133. Set.FWlkRpm = -Set.FWlkRpm;
  134. Set.BWlkRpm = -Set.BWlkRpm;
  135. }
  136. if(abs(rpm) < 80){
  137. //LogLocalPrintf("Rote:Stop @X = %d\r\n", S.FMgsOffset, S.FMgsOffset, rpm);
  138. Set.FWlkRpm = 0;
  139. Set.BWlkRpm = 0;
  140. if(rt_tick_timeout(stopWait))
  141. {
  142. S.StopAtCross = true;
  143. return true;
  144. }else{
  145. return false;
  146. }
  147. }
  148. }else{
  149. Set.FWlkRpm = 0;
  150. Set.BWlkRpm = 0;
  151. }
  152. stopWait = rt_tick_timeout_reset(RT_TICK_PER_SECOND);
  153. return false;
  154. }
  155. typedef struct {
  156. int16_t Offset[256];
  157. uint8_t Idx;
  158. int32_t SumOffset;
  159. } Pid_Info_t;
  160. Pid_Info_t pidInfoFA, PidInfoBA;
  161. /* ǰ�󵼺����� */
  162. rt_inline bool drNav(bool positive, bool stop) {
  163. static volatile uint32_t stopWait = 0;
  164. static uint32_t delay_tick = 0,delay_flag = 0;
  165. if(stop)
  166. {
  167. if(S.yOffset < 50 && S.yOffset > -50)
  168. {
  169. Set.FWlkRpm = 0;
  170. if(rt_tick_timeout(stopWait))
  171. {
  172. if (S.Point == S.TgtStation){
  173. S.Station = S.TgtStation;
  174. S.TgtStation = NULL_POINT;
  175. delay_flag = 0;
  176. delay_tick = 0;
  177. DRSetAction(ACT_STOP);
  178. LOG_I("ACT_STOP");
  179. }
  180. S.DirPauseStatus = DIR_STOP_STATUS;
  181. //LogLocalPrintf("nav: @Point\r\n");
  182. return true;
  183. }else{
  184. return false;
  185. }
  186. }
  187. else
  188. {
  189. Set.FWlkRpm = -(S.yOffset)/6; //之前没改,导致车子过冲,前进后退
  190. //LogLocalPrintf("nav: Y rpm=%d\r\n", Set.FWlkRpm);
  191. stopWait = rt_tick_timeout_reset(200);
  192. }
  193. }
  194. else
  195. {
  196. if(S.TgtStation - S.Point == 1 ||
  197. S.Point - S.TgtStation == 1 ||
  198. (S.TgtStationXvalue - S.xValue == 1 && S.TgtStationYvalue == S.yValue) ||
  199. (S.xValue - S.TgtStationXvalue == 1 && S.TgtStationYvalue == S.yValue))
  200. {
  201. if((Set.FWlkRpm == 0) && (S.estop_flag==0))
  202. {
  203. delay_flag = 1;
  204. }
  205. if(Set.FWlkRpm)
  206. {
  207. S.estop_flag=0;
  208. S.reset_flag=0;
  209. }
  210. if(delay_flag)
  211. {
  212. Set.FWlkRpm = positive?(3000):-3000;
  213. delay_tick++;
  214. if(delay_tick > S.near_time_out)
  215. {
  216. delay_flag = 0;
  217. delay_tick = 0;
  218. }
  219. }
  220. else
  221. {
  222. Set.FWlkRpm = positive?(Set.RpmNear):-Set.RpmNear;
  223. }
  224. }else if(S.TgtStationYvalue != S.yValue){
  225. Set.FWlkRpm = positive?(Set.RpmNear):-Set.RpmNear;
  226. }else{
  227. // if(S.cValue == S.TgtCvalue){
  228. Set.FWlkRpm = positive?(Set.DRRpmNav):-Set.DRRpmNav;
  229. // }
  230. }
  231. }
  232. return false;
  233. }
  234. /* ����Ư�� */
  235. rt_inline bool drDrift(bool positive, bool stop) {
  236. static uint32_t delay_tick = 0,delay_flag = 0;
  237. static volatile uint32_t stopWait = 0;
  238. if(stop){
  239. if(S.xOffset < 50 && S.xOffset > -50){
  240. Set.FWlkRpm = 0;
  241. if(rt_tick_timeout(stopWait))
  242. {
  243. if (S.Point == S.TgtStation){
  244. S.Station = S.TgtStation;
  245. S.TgtStation = NULL_POINT;
  246. delay_flag = 0;
  247. delay_tick = 0;
  248. DRSetAction(ACT_STOP);
  249. LOG_I("ACT_STOP");
  250. }
  251. S.DirPauseStatus = DIR_STOP_STATUS;
  252. //LogLocalPrintf("nav: @Point\r\n");
  253. return true;
  254. }else{
  255. return false;
  256. }
  257. }else{
  258. Set.FWlkRpm = -(S.xOffset)/6;
  259. //LogLocalPrintf("nav: X rpm=%d\r\n", Set.FWlkRpm);
  260. stopWait = rt_tick_timeout_reset(200);
  261. }
  262. }else{
  263. if(S.TgtStation - S.Point == 1 || S.Point - S.TgtStation == 1 || S.TgtStationYvalue - S.yValue == 1 || S.yValue - S.TgtStationYvalue == 1)
  264. {
  265. if((Set.FWlkRpm == 0) && (S.estop_flag==0))
  266. {
  267. delay_flag = 1;
  268. }
  269. if(Set.FWlkRpm)
  270. {
  271. S.estop_flag=0;
  272. S.reset_flag=0;
  273. }
  274. if(delay_flag)
  275. {
  276. Set.FWlkRpm = positive?(-3000):3000;
  277. delay_tick++;
  278. if(delay_tick > S.near_time_out)
  279. {
  280. delay_flag = 0;
  281. delay_tick = 0;
  282. }
  283. }
  284. else
  285. {
  286. Set.FWlkRpm = positive?(-Set.RpmNear):Set.RpmNear;
  287. }
  288. }else{
  289. // if(S.cValue != S.TgtCvalue){
  290. Set.FWlkRpm = positive?(-Set.DRRpmNav):Set.DRRpmNav;
  291. // }
  292. }
  293. }
  294. return false;
  295. }
  296. uint8_t drDirFbNav(void){
  297. if (S.Action == ACT_FORWARD){
  298. DRSetAction(ACT_FORWARD_STOP_CROSS);
  299. }
  300. if (S.Action == ACT_BACKWARD){
  301. DRSetAction(ACT_BACKWARD_STOP_CROSS);
  302. }
  303. if (S.DirPauseStatus == DIR_STOP_STATUS){
  304. return 1;
  305. }
  306. return 0;
  307. }
  308. uint8_t drDirLrNav(void){
  309. if (S.Action == ACT_LEFT){
  310. DRSetAction(ACT_LEFT_STOP_CROSS);
  311. }
  312. if (S.Action == ACT_RIGHT){
  313. DRSetAction(ACT_RIGHT_STOP_CROSS);
  314. }
  315. if (S.DirPauseStatus == DIR_STOP_STATUS){
  316. return 1;
  317. }
  318. return 0;
  319. }
  320. rt_inline bool drStop(void) {
  321. //LogLocalPrintf("drStop\n");
  322. Set.FWlkRpm = 0;
  323. return true;
  324. }
  325. char cross[4] = {'O', '-', '|', '+'};
  326. rt_inline void checkCross(void) {
  327. static uint8_t preCross = CROSS_OFF;
  328. if(S.FMgsOnline && S.BMgsOnline && S.LMgsOnline && S.RMgsOnline){
  329. S.CrossType = CROSS_XY;
  330. }else if(S.FMgsOnline && S.BMgsOnline){
  331. S.StopAtCross = false;
  332. S.CrossType = CROSS_FB;
  333. }else if(S.RMgsOnline && S.LMgsOnline){
  334. S.StopAtCross = false;
  335. S.CrossType = CROSS_LR;
  336. }else{
  337. S.StopAtCross = false;
  338. S.CrossType = CROSS_OFF;
  339. }
  340. if(S.CrossType != preCross){
  341. preCross = S.CrossType;
  342. //LogLocalPrintf("CROSS: %c\r\n", cross[S.CrossType]);
  343. }
  344. }
  345. static void DRProcess(void *param) //驱动器进程
  346. {
  347. static uint8_t bms_cnt;
  348. struct rt_can_msg msg;
  349. DRBusParse.parse = DrRecvProcess;
  350. chassis_bus_attach_parse(&DRBusParse);
  351. while(S.DRStatus == DR_STATUS_INIT)
  352. {
  353. //LogLocalPrintf("DR_STATUS_INIT\r\n");
  354. Set.FWlkRpm = 0;
  355. Set.BWlkRpm = 0;
  356. if(McWalkInit())
  357. {
  358. S.DRStatus = DR_STATUS_RUN;
  359. }
  360. rt_thread_mdelay(100);
  361. }
  362. while(1)
  363. {
  364. rt_thread_mdelay(8);
  365. checkCross();
  366. //LogLocalPrintf("DR_Process:%x:%d,%d\n", Set.DRAction, Set.FAngle, Set.BAngle);
  367. S.DRAction = Set.DRAction;
  368. switch(Set.DRAction){
  369. case ACT_FORWARD:
  370. drNav(true, false);
  371. break;
  372. case ACT_FORWARD_STOP_CROSS:
  373. drNav(true, true);
  374. break;
  375. case ACT_FORWARD_LEFT:
  376. if(AGV_ON_LR || S.StopAtCross){
  377. drDrift(true, false);
  378. }else{
  379. drNav(true, true);
  380. }
  381. break;
  382. case ACT_FORWARD_RIGHT:
  383. if(AGV_ON_LR || S.StopAtCross){
  384. drDrift(false, false);
  385. }else{
  386. drNav(true, true);
  387. }
  388. break;
  389. case ACT_BACKWARD:
  390. drNav(false, false);
  391. break;
  392. case ACT_BACKWARD_STOP_CROSS:
  393. drNav(false, true);
  394. break;
  395. case ACT_BACKWARD_LEFT:
  396. if(AGV_ON_LR || S.StopAtCross){
  397. drDrift(true, false);
  398. }else{
  399. drNav(false, true);
  400. }
  401. break;
  402. case ACT_BACKWARD_RIGHT:
  403. if(AGV_ON_LR || S.StopAtCross){
  404. drDrift(false, false);
  405. }else{
  406. drNav(false, true);
  407. }
  408. break;
  409. case ACT_LEFT:
  410. drDrift(true, false);
  411. break;
  412. case ACT_LEFT_STOP_CROSS:
  413. drDrift(true, true);
  414. break;
  415. case ACT_LEFT_FORWARD:
  416. if(AGV_ON_FB || S.StopAtCross){
  417. drNav(true, false);
  418. }else{
  419. drDrift(true, true);
  420. }
  421. break;
  422. case ACT_LEFT_BACKWARD:
  423. if(AGV_ON_FB || S.StopAtCross){
  424. drNav(false, false);
  425. }else{
  426. drDrift(true, true);
  427. }
  428. break;
  429. case ACT_RIGHT:
  430. drDrift(false, false);
  431. break;
  432. case ACT_RIGHT_STOP_CROSS: //有用
  433. drDrift(false, true);
  434. break;
  435. case ACT_RIGHT_FORWARD:
  436. if(AGV_ON_FB || S.StopAtCross){
  437. drNav(true, false);
  438. }else{
  439. drDrift(false, true);
  440. }
  441. break;
  442. case ACT_RIGHT_BACKWARD:
  443. if(AGV_ON_FB || S.StopAtCross){
  444. drNav(false, false);
  445. }else{
  446. drDrift(false, true);
  447. }
  448. break;
  449. case ACT_MANUAL_FORWARD:
  450. drManualFB(true);
  451. break;
  452. case ACT_MANUAL_BACKWARD:
  453. drManualFB(false);
  454. break;
  455. case ACT_MANUAL_DRIFT_LEFT:
  456. drManualLR(true);
  457. break;
  458. case ACT_MANUAL_DRIFT_RIGHT:
  459. drManualLR(false);
  460. break;
  461. case ACT_ROTATE_LEFT:
  462. drRotate(true, true);
  463. break;
  464. case ACT_MANUAL_ROTATE_LEFT:
  465. drRotate(true, false);
  466. break;
  467. case ACT_ROTATE_RIGHT:
  468. drRotate(false, true);
  469. break;
  470. case ACT_MANUAL_ROTATE_RIGHT:
  471. drRotate(false, false);
  472. break;
  473. default:
  474. drStop();
  475. }
  476. // McWalkProcess();
  477. //步科电机
  478. if(motor_init_ok()==0)
  479. {
  480. set_motor_rpm(Set.FWlkRpm); //设置电机转速
  481. msg = send_motor_rpm();
  482. chassis_bus_write(&msg, sizeof(msg));
  483. }
  484. bms_cnt++;
  485. if(bms_cnt>150) //增加奥冠的bms协议发送,每1200ms获取一次容量
  486. {
  487. bms_cnt = 0;
  488. msg = require_ag_bms_msg();
  489. chassis_bus_write(&msg, sizeof(msg));
  490. }
  491. }
  492. }
  493. static int DRInit(void) {
  494. LOG_I("DRInit");
  495. Set.DRAction = ACT_STOP;
  496. S.DRStatus = DR_STATUS_INIT;
  497. switch(Cfg.WlkMcType){
  498. case CFG_WlkMcType_SenChuang:
  499. McWalkInit = McWalkInitSenChuang;
  500. McWalkProcess = McWalkProcessSenChuang;
  501. //McWalkQueryProcess = McWalkProcessSenChuang;
  502. break;
  503. default:
  504. McWalkInit = McWalkInitSenChuang;
  505. McWalkProcess = McWalkProcessSenChuang;
  506. LOG_E("NotSupport WlkMcType %d", Cfg.WlkMcType);
  507. }
  508. // thread
  509. rt_thread_t tid;
  510. tid = rt_thread_create("dr",
  511. DRProcess, RT_NULL,
  512. 2048,
  513. 9, 20);
  514. if (tid != RT_NULL)
  515. {
  516. rt_thread_startup(tid);
  517. }
  518. return 0;
  519. }
  520. INIT_APP_EXPORT(DRInit);