123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330 |
- /*******************************************************************************************
- * @file wcs.c
- *
- * @brief wcs协议解析
- *
- * (c) Copyright 2021, Shandong Huali electromechanical Co., Ltd..
- * This is protected by international copyright laws. Knowledge of the
- * source code may not be used to write a similar product. This file may
- * only be used in accordance with a license and should not be redistributed
- * in any way. We appreciate your understanding and fairness.
- *
- *
- * @author Simon
- * @date Created: 2021.06.16-T18:02:42+0800
- *
- *******************************************************************************************/
- #include "rtthread.h"
- #include "board.h"
- #include "lwip/netdb.h"
- #include "wcs.h"
- #define DBG_TAG "wcs"
- #define DBG_LVL DBG_INFO
- #include <rtdbg.h>
- enum
- {
- DEV_TYPE_NONE,
- DEV_TYPE_SHUTTLE,
- DEV_TYPE_PALLET,
- DEV_TYPE_OTHER,
- };
- typedef struct
- {
- uint16_t tag;
- uint16_t msg_len;
- uint8_t dev_type;
- uint8_t dev_no;
- uint8_t mode;
- uint8_t map_ver;
- uint8_t task_no;
- uint8_t task_type;
- }wcs_frame_head_t;
- typedef struct
- {
- uint16_t msg_len;
- uint16_t crc;
- uint16_t tag;
- }wcs_frame_tail_t;
- typedef struct __attribute__((__packed__))
- {
- uint8_t seg_no;
- wcs_point_t point[1];
- }wcs_seg_t;
- typedef struct __attribute__((__packed__))
- {
- uint8_t seg_no;
- uint8_t cmd_no;
- uint8_t cmd;
- uint32_t cmd_param;
- uint8_t area_no;
- uint16_t auth;
- }wcs_cmd_req_t;
- typedef struct __attribute__((__packed__))
- {
- uint8_t x;
- uint8_t y;
- uint8_t z;
- // uint8_t action;
- }wcs_location_t;
- typedef struct __attribute__((__packed__))
- {
- uint8_t task_result;
- uint8_t cmd_no;
- uint8_t cmd_exe_result;
- uint32_t cmd_exe_param;
- wcs_location_t location;
- uint8_t seg_no;
- uint16_t seg_target;
- uint32_t barcode;
- uint8_t car_status;
- uint8_t pallet_status;
- uint8_t reserve_status;
- uint8_t dir;
- uint8_t vol;
- uint8_t warning;
- uint8_t res[3];
- }wcs_ack_t;
- const static uint16_t wcs_polynom = 0xA001;
- static uint8_t wcs_clear_ack = 0;
- void ll_get_point(wcs_point_t *point);
- uint8_t ll_get_seg(void);
- uint16_t ll_get_target(void);
- uint8_t ll_get_car_status(void);
- uint8_t ll_get_dtc(void);
- uint8_t ll_get_pallet(void);
- uint8_t ll_get_battery(void);
- uint8_t ll_get_reserve(void);
- uint8_t ll_get_dir(void);
- int cmd_work_result(uint8_t *cmd_no);
- int cmd_parser(uint8_t cmd_no, uint8_t cmd, uint32_t *param);
- void cmd_set_clear_indication(void (*clear_func)(void));
- int sch_trajectory(uint8_t task_id, uint8_t seg_no, wcs_point_t *point);
- int sch_target(uint8_t task_id, uint8_t seg_no);
- int sch_get_status(void);
- void be_send(void *buf, int sz);
- static uint16_t wcs_crc16(uint8_t *ptr, uint16_t len)
- {
- uint8_t i;
- uint16_t crc = 0xffff;
- if (len == 0) {
- len = 1;
- }
- while (len--) {
- crc ^= *ptr;
- for (i = 0; i<8; i++)
- {
- if (crc & 1) {
- crc >>= 1;
- crc ^= wcs_polynom;
- }
- else {
- crc >>= 1;
- }
- }
- ptr++;
- }
- return(crc);
- }
- static __inline wcs_frame_tail_t *wcs_get_tail(void *buf, int sz)
- {
- uint8_t *pbuf = buf;
- return (wcs_frame_tail_t *)&pbuf[sz - sizeof(wcs_frame_tail_t)];
- }
- static __inline uint8_t *wcs_get_body(void *buf, int sz)
- {
- uint8_t *pbuf = buf;
- return &pbuf[sizeof(wcs_frame_head_t)];
- }
- static void wcs_ack_status(wcs_ack_t *pack)
- {
- ll_get_point((wcs_point_t *)&pack->location);
- pack->seg_no = ll_get_seg();
- pack->seg_target = htons(ll_get_target());
- pack->car_status = ll_get_car_status();
- pack->warning = ll_get_dtc();
- pack->pallet_status = ll_get_pallet();
- pack->reserve_status = ll_get_reserve();
- pack->dir = ll_get_dir();
- pack->vol = ll_get_battery();
- // LOG_D("ack");
- }
- static void wcs_ack_clear(void)
- {
- wcs_clear_ack = 1;
- }
- static void wcs_ack(uint8_t result, wcs_frame_head_t *head, wcs_cmd_req_t *cmd)
- {
- static uint8_t buf[sizeof(wcs_ack_t) + sizeof(wcs_frame_head_t) + sizeof(wcs_frame_tail_t)] = {0};
- wcs_frame_tail_t *ptail = wcs_get_tail(buf, sizeof(buf));
- wcs_ack_t *pack = (wcs_ack_t *)wcs_get_body(buf, sizeof(buf));
- wcs_frame_head_t *phead = (wcs_frame_head_t *)buf;
- if(wcs_clear_ack)
- {
- wcs_clear_ack = 0;
- memset(buf, 0, sizeof(buf));
- }
- /* 填充发送信息 */
- phead->tag = htons(0x02fd);
- phead->msg_len = htons(sizeof(buf));
- phead->map_ver = 0;
- if((cmd && cmd->cmd_no) || head->task_no)
- {
- memcpy(&phead->dev_type, &head->dev_type, sizeof(wcs_frame_head_t) - 4);
- }
- if(head->task_no)
- {
- phead->task_type = head->task_type;
- pack->task_result = result;
- pack->cmd_no = 0;
- pack->cmd_exe_result = 0;
- pack->cmd_exe_param = 0;
- }
- else if(cmd)
- {
- pack->task_result = 0;
- pack->cmd_no = cmd->cmd_no;
- pack->cmd_exe_result = result;
- pack->cmd_exe_param = cmd->cmd_param; /* 延时指令不会返回参数 */
- }
- /* 任务执行完毕 */
- else if(phead->task_no && phead->task_type == 2)
- {
- if(ll_get_car_status() == 3)
- {
- pack->task_result = 0;
- }
- }
- else
- {
- int rc;
- uint8_t cmd_exe_no = 0;
- rc = cmd_work_result(&cmd_exe_no);
- if(rc >= 0)
- {
- pack->cmd_no = cmd_exe_no;
- pack->cmd_exe_result = rc;
- }
- }
- wcs_ack_status(pack);
- ptail->tag = htons(0x03fc);
- ptail->msg_len = htons(sizeof(buf));
- ptail->crc = wcs_crc16(buf, sizeof(buf) -4);
- be_send(buf, sizeof(buf));
- if((cmd && cmd->cmd_no) || head->task_no)
- LOG_HEX(DBG_TAG, 16, buf, sizeof(buf));
- }
- /****************************************
- * wcs帧解析
- *函数功能 :
- *参数描述 : 无
- *返回值 : 无
- ****************************************/
- static int wcs_frame_parser(void *buf, int sz)
- {
- wcs_frame_head_t *phead = (wcs_frame_head_t *)buf;
- wcs_frame_tail_t *ptail = wcs_get_tail(buf, sz);
- int rc = 0;
- if(phead->msg_len == ptail->msg_len && ntohs(phead->msg_len) == sz) /* 长度一致 */
- {
- // LOG_D("recv frame");
- uint16_t cal_crc = wcs_crc16(buf, sz -4);
- if(ptail->crc == cal_crc) /* 校验通过 */
- {
- // LOG_D("check ok");
- if(phead->dev_type == DEV_TYPE_SHUTTLE) /* 对象四向车 */
- {
- if(phead->task_no) /* 任务编号 */
- {
- LOG_I("task id[%u]", phead->task_no);
- LOG_HEX(DBG_TAG, 16, buf, sz);
- if(phead->task_type == 1) /* 任务类型 */
- {
- if(ll_get_car_status() != 3)
- {
- rc = 0;
- }
- else //就绪,就获取身体信息
- {
- uint8_t seg_cnt;
- wcs_seg_t *ptask = (wcs_seg_t *)wcs_get_body(buf, sz);
- //LOG_I("add trajectory");
- seg_cnt = (sz - sizeof(wcs_frame_head_t) - sizeof(wcs_cmd_req_t) - sizeof(wcs_frame_tail_t)) / sizeof(wcs_point_t);
- rc = sch_trajectory(phead->task_no, seg_cnt, ptask->point);
- }
- wcs_ack(rc? rc: 1, phead, NULL); /* 回应信息 */
- }
- else if(phead->task_type == 2) //任务类型:1:路径中各段节点; 2:RES能行驶的分段动作序号
- {
- if(ll_get_car_status() != 11) //11:节点待命
- {
- rc = 0;
- }
- else
- {
- wcs_seg_t *ptask = (wcs_seg_t *)wcs_get_body(buf, sz);
- LOG_I("schedule task");
- if(cmd_work_result(NULL) < 0)
- {
- rc = sch_target(phead->task_no, ptask->seg_no);
- }
- else
- {
- rc = ERR_C_RES_TASK_DOING;
- }
- }
- wcs_ack(rc? rc: 1, phead, NULL);
- }
- }
- else
- {
- wcs_cmd_req_t *pcmd = (wcs_cmd_req_t *)wcs_get_body(buf, sz);
- if(pcmd->cmd_no || pcmd->cmd)
- {
- LOG_I("commands[%#x]", pcmd->cmd);
- LOG_HEX(DBG_TAG, 16, buf, sz);
- rc = cmd_parser(pcmd->cmd_no, pcmd->cmd, (uint32_t *)&pcmd->cmd_param);
- wcs_ack(rc, phead, pcmd);
- }
- else
- wcs_ack(rc, phead, NULL);
- }
- }
- }
- }
- return 0;
- }
- static int wcs_init(void)
- {
- extern void be_set_parser(int (*parser_fun)(void *, int));
- be_set_parser(wcs_frame_parser);
- cmd_set_clear_indication(wcs_ack_clear);
- return 0;
- }
- INIT_APP_EXPORT(wcs_init);
|