| | |
| | | #include "test_items/stop_and_start.h" |
| | | #include "master/comm_if.h" |
| | | #include "utils/xconvert.h" |
| | | #include "test_items/comm_test.h" |
| | | |
| | | #define DEBUG(fmt, args...) LOGD("<driver_test> <%s>: " fmt, __func__, ##args) |
| | | |
| | |
| | | } SensorConfig[32]; |
| | | static int SensorNum = 0; |
| | | |
| | | static int SensorValidLevel; |
| | | |
| | | #define MOV_AVG_SIZE 1 |
| | | #define RTK_BUFFER_SIZE 100 |
| | | #define CAR_MODEL_CACHE_SIZE 10 |
| | | |
| | | static pthread_mutex_t rtk_clock_mutex = PTHREAD_MUTEX_INITIALIZER; |
| | | struct RtkTime rtkClock; |
| | | |
| | | static rtk_info *RtkBuffer = NULL; |
| | | static int RtkBufferNum = 0, RtkBufferIn = 0; |
| | |
| | | |
| | | void DriverTestInit(void) |
| | | { |
| | | pthread_mutex_init(&rtk_clock_mutex, NULL); |
| | | memset(&rtkClock, 0, sizeof(rtkClock)); |
| | | |
| | | TestStart = false; |
| | | memset(&MapList, 0, sizeof(MapList)); |
| | | MapNum = 0; |
| | | CarModel = NULL; |
| | | CarModelPrev = NULL; |
| | | |
| | | CommTestInit(); |
| | | SensorNum = 0; |
| | | memset(SensorConfig, 0, sizeof(SensorConfig)); |
| | | |
| | | SensorValidLevel = 0; |
| | | |
| | | RtkBuffer = (rtk_info *) malloc(RTK_BUFFER_SIZE * sizeof(rtk_info)); |
| | | RtkBufferNum = RtkBufferIn = 0; |
| | |
| | | |
| | | void SetSensorCfg(int (*sensor)[3], int sensorNum) |
| | | { |
| | | DEBUG("SetSensorCfg sensorNum %d", sensorNum); |
| | | DEBUG("加入传感器配置 sensorNum %d", sensorNum); |
| | | SensorValidLevel = 0; |
| | | |
| | | SensorNum = sensorNum; |
| | | for (int i = 0; i < sensorNum; ++i) { |
| | | SensorConfig[i].gpioId = sensor[i][0]; |
| | | SensorConfig[i].funId = sensor[i][1]; |
| | | SensorConfig[i].validLvl = sensor[i][2]; |
| | | |
| | | if (sensor[i][2] != 0) { |
| | | SensorValidLevel |= BV(i); |
| | | } |
| | | } |
| | | } |
| | | |
| | | void GetFuncGpio(int func, int &gpio, int &lvl) |
| | | int GetSensorValidLevel(void) |
| | | { |
| | | return SensorValidLevel; |
| | | } |
| | | |
| | | void GetSensorCfg(int gpio, int &func, bool &lvl) |
| | | { |
| | | for (int i = 0; i < SensorNum; ++i) { |
| | | if (SensorConfig[i].gpioId == gpio) { |
| | | func = SensorConfig[i].funId; |
| | | lvl = SensorConfig[i].validLvl == 0 ? false : true; |
| | | } |
| | | } |
| | | } |
| | | |
| | | void FindSensorCfg(int func, int &gpio, bool &lvl) |
| | | { |
| | | gpio = -1; |
| | | for (int i = 0; i < SensorNum; ++i) { |
| | | if (SensorConfig[i].funId == func) { |
| | | gpio = SensorConfig[i].gpioId; |
| | | lvl = SensorConfig[i].validLvl; |
| | | lvl = SensorConfig[i].validLvl == 0 ? false : true; |
| | | } |
| | | } |
| | | } |
| | |
| | | DEBUG("StartDriverExam %d", start); |
| | | if (start == 0) { |
| | | TestStart = false; |
| | | CommTestStart(false); |
| | | MA_SendExamStatus(0, 0); |
| | | return; |
| | | } |
| | |
| | | examFaultIndex = 0; |
| | | |
| | | TestStart = true; |
| | | CommTestStart(true); |
| | | } |
| | | MA_SendExamStatus(1, 0); |
| | | } |
| | | } |
| | | |
| | | void GetRtkClock(struct RtkTime *s) |
| | | { |
| | | pthread_mutex_lock(&rtk_clock_mutex); |
| | | *s = rtkClock; |
| | | pthread_mutex_unlock(&rtk_clock_mutex); |
| | | } |
| | | |
| | | void UpdateRTKInfo(const rtk_info *s) |
| | | { |
| | | pthread_mutex_lock(&rtk_clock_mutex); |
| | | rtkClock.YY = s->YY; |
| | | rtkClock.MM = s->MM; |
| | | rtkClock.DD = s->DD; |
| | | rtkClock.hh = s->hh; |
| | | rtkClock.mm = s->mm; |
| | | rtkClock.ss = s->ss; |
| | | rtkClock.mss = s->dss; |
| | | pthread_mutex_unlock(&rtk_clock_mutex); |
| | | |
| | | if (s->qf == 3) { |
| | | RtkBuffer[RtkBufferIn] = *s; |
| | | RtkBufferIn = (RtkBufferIn + 1) % RTK_BUFFER_SIZE; |
| | |
| | | RtkBuffer[index].mm, RtkBuffer[index].ss, RtkBuffer[index].dss); |
| | | |
| | | brief.qf = RtkBuffer[index].qf; |
| | | brief.map_id = 866;//GetMapId(CurrExamMapIndex, MapList, MapNum); |
| | | brief.map_id = 863;//GetMapId(CurrExamMapIndex, MapList, MapNum); |
| | | brief.move = move; |
| | | brief.speed = speed * 3.6; |
| | | brief.heading = RtkBuffer[index].heading; |
| | |
| | | DEBUG("进入倒车入库场地"); |
| | | MA_SendDebugInfo("进入倒车入库场地 %d", GetMapId(CurrExamMapIndex, MapList, MapNum)); |
| | | |
| | | StartParkBottom(); |
| | | StartParkBottom(move, &rtkTime); |
| | | CurrExamStatus = 0; |
| | | break; |
| | | case MAP_TYPE_STOP_START: |
| | |
| | | int mtype = GetMapType(CurrExamMapIndex, MapList, MapNum); |
| | | switch (mtype) { |
| | | case MAP_TYPE_PARK_BUTTOM: |
| | | CurrExamStatus = TestParkBottom(ErrorList, &MapList[CurrExamMapIndex].map, |
| | | CurrExamStatus = TestParkBottom(&MapList[CurrExamMapIndex].map, |
| | | CarModel, CarModelPrev, speed, move, &rtkTime); |
| | | break; |
| | | case MAP_TYPE_STOP_START: |
| | |
| | | { |
| | | // 车的最前点是否进入地图 |
| | | for (int i = 0; i < mapNum && car != NULL; ++i) { |
| | | /*if (mapList[i].type == MAP_TYPE_STOP_START) { |
| | | // 构造虚拟的左上角点 |
| | | double x9, y9, xo, yo; |
| | | |
| | | bool enter = false; |
| | | |
| | | xo = (mapList[i].map.point[0].X + mapList[i].map.point[7].X) / 2; |
| | | yo = (mapList[i].map.point[0].Y + mapList[i].map.point[7].Y) / 2; |
| | | |
| | | x9 = 2*xo - mapList[i].map.point[8].X; |
| | | y9 = 2*yo - mapList[i].map.point[8].Y; |
| | | |
| | | Polygon map; |
| | | |
| | | map.num = 4; |
| | | map.point = (PointF *) malloc(map.num * sizeof(PointF)); |
| | | |
| | | map.point[0] = mapList[i].map.point[0]; |
| | | map.point[1] = mapList[i].map.point[8]; |
| | | map.point[2] = mapList[i].map.point[7]; |
| | | map.point[3].X = x9; |
| | | map.point[3].Y = y9; |
| | | |
| | | if (IntersectionOf(car->carXY[ car->axial[AXIAL_FRONT] ], &map) == GM_Containment) { |
| | | Line enterLine1; |
| | | |
| | | MakeLine(&enterLine1, &(map.point[0]), &(map.point[3])); |
| | | |
| | | if (DistanceOf(car->carXY[car->axial[AXIAL_FRONT]], enterLine1) > 0.1) |
| | | enter = true; |
| | | } |
| | | |
| | | free(map.point); |
| | | |
| | | if (enter) return i; |
| | | } else if (mapList[i].type == MAP_TYPE_CURVE) { |
| | | |
| | | } else if (mapList[i].type == MAP_TYPE_PARK_BUTTOM || mapList[i].type == MAP_TYPE_PART_EDGE) { |
| | | // if (mapList[i].type == MAP_TYPE_STOP_START) { |
| | | // // 构造虚拟的左上角点 |
| | | // double x9, y9, xo, yo; |
| | | // |
| | | // bool enter = false; |
| | | // |
| | | // xo = (mapList[i].map.point[0].X + mapList[i].map.point[7].X) / 2; |
| | | // yo = (mapList[i].map.point[0].Y + mapList[i].map.point[7].Y) / 2; |
| | | // |
| | | // x9 = 2*xo - mapList[i].map.point[8].X; |
| | | // y9 = 2*yo - mapList[i].map.point[8].Y; |
| | | // |
| | | // Polygon map; |
| | | // |
| | | // map.num = 4; |
| | | // map.point = (PointF *) malloc(map.num * sizeof(PointF)); |
| | | // |
| | | // map.point[0] = mapList[i].map.point[0]; |
| | | // map.point[1] = mapList[i].map.point[8]; |
| | | // map.point[2] = mapList[i].map.point[7]; |
| | | // map.point[3].X = x9; |
| | | // map.point[3].Y = y9; |
| | | // |
| | | // if (IntersectionOf(car->carXY[ car->axial[AXIAL_FRONT] ], &map) == GM_Containment) { |
| | | // Line enterLine1; |
| | | // |
| | | // MakeLine(&enterLine1, &(map.point[0]), &(map.point[3])); |
| | | // |
| | | // if (DistanceOf(car->carXY[car->axial[AXIAL_FRONT]], enterLine1) > 0.1) |
| | | // enter = true; |
| | | // } |
| | | // |
| | | // free(map.point); |
| | | // |
| | | // if (enter) return i; |
| | | // } |
| | | // if (mapList[i].type == MAP_TYPE_CURVE) { |
| | | // |
| | | // } |
| | | if (mapList[i].type == MAP_TYPE_PARK_BUTTOM /*|| mapList[i].type == MAP_TYPE_PART_EDGE*/) { |
| | | if (IntersectionOf(car->carXY[ car->axial[AXIAL_FRONT] ], &mapList[i].map) == GM_Containment) { |
| | | Line enterLine1, enterLine2; |
| | | |
| | |
| | | DistanceOf(car->carXY[car->axial[AXIAL_FRONT]], enterLine2) > 0.1) |
| | | return i; |
| | | } |
| | | } else */if (mapList[i].type == MAP_TYPE_TURN_90) { |
| | | if (IntersectionOf(car->carXY[ car->axial[AXIAL_FRONT] ], &mapList[i].map) == GM_Containment) { |
| | | Line enterLine1; |
| | | |
| | | MakeLine(&enterLine1, &(mapList[i].map.point[0]), &(mapList[i].map.point[1])); |
| | | |
| | | if (DistanceOf(car->carXY[car->axial[AXIAL_FRONT]], enterLine1) > 0.1) |
| | | return i; |
| | | } |
| | | } |
| | | // if (mapList[i].type == MAP_TYPE_TURN_90) { |
| | | // if (IntersectionOf(car->carXY[ car->axial[AXIAL_FRONT] ], &mapList[i].map) == GM_Containment) { |
| | | // Line enterLine1; |
| | | // |
| | | // MakeLine(&enterLine1, &(mapList[i].map.point[0]), &(mapList[i].map.point[1])); |
| | | // |
| | | // if (DistanceOf(car->carXY[car->axial[AXIAL_FRONT]], enterLine1) > 0.1) |
| | | // return i; |
| | | // } |
| | | // } |
| | | } |
| | | return -1; |
| | | } |
| | |
| | | int *right_front_tire, int *left_rear_tire, int *right_rear_tire, |
| | | int *body, int bodyNum, double (*point)[2], int pointNum); |
| | | void SetSensorCfg(int (*sensor)[3], int sensorNum); |
| | | void GetFuncGpio(int func, int &gpio, int &lvl); |
| | | int GetSensorValidLevel(void); |
| | | void GetSensorCfg(int gpio, int &func, bool &lvl); |
| | | void FindSensorCfg(int func, int &gpio, bool &lvl); |
| | | |
| | | void StartDriverExam(int start); |
| | | void GetRtkClock(struct RtkTime *s); |
| | | void UpdateRTKInfo(const rtk_info *s); |
| | | void AddExamFault(int wrong, const struct RtkTime *rtkTime); |
| | | car_model_cache_t *GetCarModelCache(int node); |
| | |
| | | #define ID_SM_RTCM_IND 0x000F |
| | | #define ID_SM_DEBUG_INFO 0x0010 |
| | | #define ID_MS_FILE 0x8100 |
| | | #define ID_MS_READ_CARD 0x800F |
| | | #define ID_SM_PUT_CARD 0x000F |
| | | |
| | | #define MA_OUT_GPS_BRIEF 0x0001 |
| | | #define MA_OUT_RTK_BRIEF 0x0002 |
| | |
| | | |
| | | void MA_ReadSensor(void) |
| | | { |
| | | |
| | | ReadCard(); |
| | | } |
| | | |
| | | void MA_SendExamStatus(int start, int errorCode) |
| | |
| | | writer.EndObject(); |
| | | |
| | | SendMsgToMainProc(ID_SM_EXAM_STATUS, sb.GetString()); |
| | | } |
| | | |
| | | void MA_SendCardBrief(const struct cardBrief *brief) |
| | | { |
| | | StringBuffer sb; |
| | | Writer<StringBuffer> writer(sb); |
| | | |
| | | writer.StartObject(); |
| | | writer.Key("result"); |
| | | writer.Int(brief->result); |
| | | writer.Key("serialno"); |
| | | writer.String(brief->card); |
| | | writer.EndObject(); |
| | | |
| | | SendMsgToMainProc(ID_SM_PUT_CARD, sb.GetString()); |
| | | } |
| | | |
| | | void MA_SendMcuBrief(const struct mcuBrief *brief) |
| | |
| | | } |
| | | break; |
| | | } |
| | | case ID_MS_READ_CARD : { |
| | | ReadCard(); |
| | | break; |
| | | } |
| | | default:break; |
| | | } |
| | | } |
| | |
| | | char sn[20]; |
| | | }; |
| | | |
| | | struct cardBrief { |
| | | int result; |
| | | char card[32]; |
| | | }; |
| | | |
| | | struct gpsBrief { |
| | | char utc[32]; |
| | | int sat_num; |
| | |
| | | void MA_ReadCar(void); |
| | | void MA_ReadSensor(void); |
| | | void MA_SendExamStatus(int start, int errorCode); |
| | | void MA_SendCardBrief(const struct cardBrief *brief); |
| | | void MA_SendMcuBrief(const struct mcuBrief *brief); |
| | | void MA_SendGpsBrief(const struct gpsBrief *brief); |
| | | void MA_SendRtkBrief(const struct rtkBrief *brief); |
| | |
| | | static void SendDfuFile(int fileLen, int sentLen, int blockLen, const uint8_t *data); |
| | | static void GoNextDfuLater(union sigval sig); |
| | | static void GoNextDfu(void); |
| | | static void ReadCardTimeout(union sigval sig); |
| | | |
| | | void ParseMcuInit(void) |
| | | { |
| | |
| | | break; |
| | | case ID_MC_RFCARD_RSP: |
| | | DEBUG("ID_MC_RFCARD_RSP"); |
| | | AppTimer_delete(ReadCardTimeout); |
| | | |
| | | if (lenth > 0) |
| | | PlatformStatusChanged(CARD_UPDATE_EVT, data, lenth); |
| | | break; |
| | | default: |
| | | break; |
| | |
| | | GoNextDfu(); |
| | | } |
| | | } |
| | | |
| | | static int readCartCnt = 0; |
| | | |
| | | static void ReadCardTimeout(union sigval sig) { |
| | | AppTimer_delete(ReadCardTimeout); |
| | | |
| | | readCartCnt++; |
| | | |
| | | if (readCartCnt < 2) { |
| | | AppTimer_add(ReadCardTimeout, D_SEC(3)); |
| | | SendMcuCommand(ID_CM_READ_RFCARD, NULL, 0); |
| | | } else { |
| | | uint8_t data[8] = {0}; |
| | | PlatformStatusChanged(CARD_UPDATE_EVT, data, sizeof(data)); |
| | | } |
| | | } |
| | | |
| | | void ReadCard(void) |
| | | { |
| | | readCartCnt = 0; |
| | | |
| | | AppTimer_delete(ReadCardTimeout); |
| | | AppTimer_add(ReadCardTimeout, D_SEC(3)); |
| | | SendMcuCommand(ID_CM_READ_RFCARD, NULL, 0); |
| | | } |
| | |
| | | |
| | | void UploadDfuFileEnd(void); |
| | | void UploadDfuFile(const uint8_t *file, int length); |
| | | void ReadCard(void); |
| | | |
| | | #endif //RTKDRIVERTEST_MCU_IF_H |
| | |
| | | }*/ |
| | | |
| | | if (RxBufLen > 0) { |
| | | // const uint8_t *ptr = parseGPS(RxBuf, RxBuf + RxBufLen); |
| | | // if(ptr != RxBuf) { |
| | | // memcpy(RxBuf, ptr, RxBufLen - (ptr - RxBuf)); |
| | | // RxBufLen -= ptr - RxBuf; |
| | | // } else if(RxBufLen == PARSE_BUFF_SIZE) { //填满了,且没有一个\r,都抛弃 |
| | | // DEBUG("Parse GPS error"); |
| | | // RxBufLen = 0; |
| | | // } |
| | | const uint8_t *ptr = parseGPS(RxBuf, RxBuf + RxBufLen); |
| | | if(ptr != RxBuf) { |
| | | memcpy(RxBuf, ptr, RxBufLen - (ptr - RxBuf)); |
| | | RxBufLen -= ptr - RxBuf; |
| | | } else if(RxBufLen == PARSE_BUFF_SIZE) { //填满了,且没有一个\r,都抛弃 |
| | | DEBUG("Parse GPS error"); |
| | | RxBufLen = 0; |
| | | } |
| | | |
| | | |
| | | RxBufLen = 0; ///////////////////////////// |
| | | // RxBufLen = 0; //PC模拟用时 |
| | | } |
| | | } |
| | | if (res == 0) { |
| | |
| | | |
| | | #define DEBUG(fmt, args...) LOGD("<parse_net> <%s>: " fmt, __func__, ##args) |
| | | |
| | | //#define ENABLE_DEBUG_PROTOCOL |
| | | |
| | | using namespace std; |
| | | |
| | | #define PKT_HEAD_CHAR 0x7E |
| | |
| | | } |
| | | |
| | | #ifdef ENABLE_DEBUG_PROTOCOL |
| | | /*{ |
| | | { |
| | | static char buff[16384]; |
| | | |
| | | buff[0] = 0; |
| | |
| | | sprintf(buff + strlen(buff), "%02X ", item->data[i]); |
| | | |
| | | if (strlen(buff) > 800) { |
| | | DEBUG("%s -> %s...", item->access == DATA_ACCESS_MCU ? "UART" : "TCP" , buff); |
| | | DEBUG("DATAOUT: %s -> %s...", item->access == DATA_ACCESS_MCU ? "UART" : "TCP" , buff); |
| | | buff[0] = 0; |
| | | } |
| | | } |
| | | |
| | | if (strlen(buff) > 0) { |
| | | DEBUG("%s -> %s", item->access == DATA_ACCESS_MCU ? "UART" : "TCP", buff); |
| | | DEBUG("DATAOUT: %s -> %s", item->access == DATA_ACCESS_MCU ? "UART" : "TCP", buff); |
| | | } |
| | | }*/ |
| | | } |
| | | #endif |
| | | // 系统层确认发送成功 |
| | | item->curr_cnt += 1; |
| | |
| | | #include "../utils/xconvert.h" |
| | | #include "../utils/num.h" |
| | | #include "../driver_test.h" |
| | | #include "../test_items/comm_test.h" |
| | | |
| | | #define PARSE_BUFF_SIZE 4096 |
| | | |
| | |
| | | pthread_attr_init(&attr); |
| | | pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);//detached |
| | | pthread_create(&pid, &attr, StatusListenThread, NULL); |
| | | |
| | | |
| | | AddEvnet(100, (uint8_t *)"1234567890", 11); |
| | | AddEvnet(101, (uint8_t *)"abcd", 5); |
| | | AddEvnet(102, (uint8_t *)"xyz", 4); |
| | | AddEvnet(104, NULL, 0); |
| | | AddEvnet(105, (uint8_t *)"uio", 4); |
| | | |
| | | while (true) { |
| | | struct event_t *evp = FetchEvent(); |
| | | |
| | | if (evp != NULL) { |
| | | DEBUG("得到event %d %d", evp->id, evp->length); |
| | | |
| | | if (evp->data != NULL) |
| | | DEBUG("数据 %s", evp->data); |
| | | RemoveEvent(); |
| | | } else |
| | | break; |
| | | } |
| | | } |
| | | |
| | | static void ReqRtkPlatformConfigTimeout(union sigval sig) |
| | |
| | | memcpy(brief.sn, data+40, 16); |
| | | |
| | | MA_SendMcuBrief(&brief); |
| | | |
| | | UpdateSensor(brief.gpio, brief.speed, brief.engine); |
| | | } |
| | | if (events & CARD_UPDATE_EVT) { |
| | | DEBUG("CARD_UPDATE_EVT length %d", length); |
| | | |
| | | int ret = -1; |
| | | |
| | | for (int i = 0; i < length; ++i) { |
| | | if (data[i] != 0) { |
| | | ret = 0; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | struct cardBrief brief; |
| | | |
| | | brief.result = ret; |
| | | |
| | | ConvertHex2String(brief.card, data, length); |
| | | |
| | | MA_SendCardBrief(&brief); |
| | | } |
| | | } |
| | | |
| | |
| | | #define RTK_UPDATE_EVT 0x0010 |
| | | #define GPS_UPDATE_EVT 0x0020 |
| | | #define MCU_UPDATE_EVT 0x0040 |
| | | #define CARD_UPDATE_EVT 0x0080 |
| | | |
| | | typedef struct { |
| | | char domain_name[32]; |
| | |
| | | #include "comm_test.h" |
| | | #include "../driver_test.h" |
| | | #include "../defs.h" |
| | | #include "../common/apptimer.h" |
| | | |
| | | static bool seatbeltInsert; |
| | | static bool engineStart; |
| | | |
| | | const int ENGINE_MIN_ROTATE = 200; |
| | | |
| | | static bool commTest = false; |
| | | static uint16_t gpioStore = 0; |
| | | static uint16_t engineStore = 0; |
| | | |
| | | static void SensorChange(int index, bool value); |
| | | static void SensorChange(int gpio, bool value); |
| | | static void EngineStartHold(union sigval sig); |
| | | |
| | | void CommTestStart(void) |
| | | void CommTestInit(void) |
| | | { |
| | | gpioStore = engineStore = 0; |
| | | gpioStore = 0; |
| | | engineStart = true; |
| | | commTest = false; |
| | | } |
| | | |
| | | void CommTestStart(bool start) |
| | | { |
| | | commTest = start; |
| | | if (start) { |
| | | // 检查安全带 |
| | | if (CheckSensorX(SEATBELT) == 0) { |
| | | struct RtkTime rt; |
| | | GetRtkClock(&rt); |
| | | AddExamFault(1, &rt); |
| | | } |
| | | } |
| | | } |
| | | |
| | | void UpdateSensor(uint16_t gpio, uint16_t speed, uint16_t engine) |
| | |
| | | |
| | | uint16_t chg = gpioStore^gpio; |
| | | |
| | | if (chg == 0) |
| | | return; |
| | | gpioStore = gpio; |
| | | |
| | | for (int i = 0; i < 16; ++i) { |
| | | if (chg & BV(i)) { |
| | | SensorChange(i, (bool)(gpio & BV(i))); |
| | | if (commTest) { |
| | | for (int i = 0; i < 16; ++i) { |
| | | if (chg & BV(i)) { |
| | | SensorChange(i, (bool) (gpio & BV(i))); |
| | | } |
| | | } |
| | | } |
| | | |
| | | gpioStore = gpio; |
| | | |
| | | |
| | | |
| | | // 安全带 |
| | | |
| | | // 挡位 |
| | | |
| | | // 启动指示 |
| | | |
| | | // 熄火监控 |
| | | if (engine < ENGINE_MIN_ROTATE) { |
| | | if (engineStart) { |
| | | if (commTest) { |
| | | // 熄火1次,扣10分 |
| | | struct RtkTime rt; |
| | | GetRtkClock(&rt); |
| | | AddExamFault(5, &rt); |
| | | } |
| | | engineStart = false; |
| | | } |
| | | } else { |
| | | engineStart = true; |
| | | } |
| | | } |
| | | |
| | | static void SensorChange(int index, bool value) |
| | | int CheckSensorX(int func) |
| | | { |
| | | int gpio; |
| | | bool level; |
| | | int validLevel = GetSensorValidLevel(); |
| | | |
| | | // 传感器无效,认为通过 |
| | | switch (func) { |
| | | case SEATBELT: |
| | | FindSensorCfg(SENSOR_SEATBELT, gpio, level); |
| | | if (gpio >= 0 && (gpioStore & BV(gpio)) != (validLevel & BV(gpio)) ) { |
| | | return 0; |
| | | } |
| | | return 1; |
| | | case LEFT_TURN_SIGNAL: |
| | | FindSensorCfg(SENSOR_LEFT_TURN_SIGNAL, gpio, level); |
| | | if (gpio == -1 || (gpioStore & BV(gpio)) == (validLevel & BV(gpio)) ) { |
| | | return 1; |
| | | } |
| | | return 0; |
| | | case RIGHT_TURN_SIGNAL: |
| | | FindSensorCfg(SENSOR_RIGHT_TURN_SIGNAL, gpio, level); |
| | | if (gpio == -1 || (gpioStore & BV(gpio)) == (validLevel & BV(gpio)) ) { |
| | | return 1; |
| | | } |
| | | return 0; |
| | | case HANDBREAK: |
| | | FindSensorCfg(SENSOR_HANDBREAK, gpio, level); |
| | | if (gpio == -1 || (gpioStore & BV(gpio)) == (validLevel & BV(gpio)) ) { |
| | | return 1; |
| | | } |
| | | return 0; |
| | | case SHIFT: |
| | | FindSensorCfg(SENSOR_SHIFT_N, gpio, level); |
| | | if (gpio == -1 || (gpioStore & BV(gpio)) == (validLevel & BV(gpio))) { |
| | | return 'N'; |
| | | } |
| | | return 0; |
| | | default: |
| | | break; |
| | | } |
| | | |
| | | return -1; |
| | | } |
| | | |
| | | static void EngineStartHold(union sigval sig) { |
| | | AppTimer_delete(EngineStartHold); |
| | | |
| | | // 不及时松开启动开关,扣10分 |
| | | struct RtkTime rt; |
| | | GetRtkClock(&rt); |
| | | AddExamFault(4, &rt); |
| | | } |
| | | |
| | | static void SensorChange(int gpio, bool value) |
| | | { |
| | | int func; |
| | | bool level; |
| | | |
| | | GetSensorCfg(gpio, func, level); |
| | | |
| | | switch (func) { |
| | | case SENSOR_SEATBELT: |
| | | break; |
| | | case SENSOR_TURNRIGHT: |
| | | break; |
| | | if (level != value) { |
| | | // 不使用安全带,不合格 |
| | | seatbeltInsert = false; |
| | | |
| | | struct RtkTime rt; |
| | | GetRtkClock(&rt); |
| | | AddExamFault(1, &rt); |
| | | } else { |
| | | seatbeltInsert = true; |
| | | } |
| | | break; |
| | | case SENSOR_RIGHT_TURN_SIGNAL: |
| | | break; |
| | | case SENSOR_LEFT_TURN_SIGNAL: |
| | | break; |
| | | case SENSOR_HANDBREAK: |
| | | break; |
| | | case SENSOR_ENGINE_START: |
| | | AppTimer_delete(EngineStartHold); |
| | | if (level == value) { |
| | | AppTimer_add(EngineStartHold, D_SEC(2)); |
| | | |
| | | // 检查是否在空挡 |
| | | if (CheckSensorX(SHIFT) != 'N') { |
| | | // 不是空挡点火,不合格 |
| | | struct RtkTime rt; |
| | | GetRtkClock(&rt); |
| | | AddExamFault(3, &rt); |
| | | } |
| | | } else { |
| | | |
| | | } |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | } |
| | |
| | | #ifndef MYAPPLICATION2_COMM_TEST_H |
| | | #define MYAPPLICATION2_COMM_TEST_H |
| | | |
| | | #define SENSOR_SEATBELT 0 |
| | | #define SENSOR_TURNRIGHT 1 |
| | | #define SENSOR_TURNLEFT 2 |
| | | #define SENSOR_HANDBREAK 3 |
| | | #include <cstdint> |
| | | |
| | | enum { |
| | | SENSOR_SEATBELT, |
| | | SENSOR_LEFT_TURN_SIGNAL, |
| | | SENSOR_RIGHT_TURN_SIGNAL, |
| | | SENSOR_HANDBREAK, |
| | | SENSOR_BREAK, |
| | | SENSOR_LIGHT, |
| | | SENSOR_FAR_LIGHT, |
| | | SENSOR_DOOR, |
| | | SENSOR_SHIFT_N, |
| | | SENSOR_SHIFT_1, |
| | | SENSOR_SHIFT_2, |
| | | SENSOR_SHIFT_3, |
| | | SENSOR_SHIFT_4, |
| | | SENSOR_SHIFT_5, |
| | | SENSOR_SHIFT_R, |
| | | SENSOR_ENGINE_START |
| | | }; |
| | | |
| | | enum { |
| | | SEATBELT, |
| | | LEFT_TURN_SIGNAL, |
| | | RIGHT_TURN_SIGNAL, |
| | | HANDBREAK, |
| | | SHIFT, |
| | | LIGHT, |
| | | FAR_LIGHT, |
| | | DOOR, |
| | | ENGINE_START |
| | | }; |
| | | |
| | | void CommTestInit(void); |
| | | void CommTestStart(bool start); |
| | | void UpdateSensor(uint16_t gpio, uint16_t speed, uint16_t engine); |
| | | int CheckSensorX(int func); |
| | | |
| | | #endif //MYAPPLICATION2_COMM_TEST_H |
| | |
| | | #include "../native-lib.h" |
| | | #include "../jni_log.h" |
| | | #include "../driver_test.h" |
| | | #include "../utils/xconvert.h" |
| | | #include <vector> |
| | | #include <cstdlib> |
| | | |
| | |
| | | THIRD_TOUCH_CTRL_LINE |
| | | }; |
| | | |
| | | const int PARK_TIMEOUT = 210; |
| | | const int PARK_TIMEOUT = D_SEC(210); |
| | | |
| | | static bool PBTesting = false; |
| | | static bool trigLeaveTestAreaDetect = false; |
| | | static bool leaveTestArea = false; |
| | | static bool stopCar2S = false; |
| | | static bool testing = false; |
| | | |
| | | static int currTarget; |
| | | static bool leftTireCrossLeftLine, leftTireCrossRightLine, rightTireCrossLeftLine, rightTireCrossRightLine; |
| | | static char first_ctrl_line_id; |
| | | static bool carStopEvent; // 中途停车标记 |
| | | static bool carParkSuccess; // 是否停在库位 |
| | | static bool parkTimeout; |
| | | const uint32_t STOP_CAR_TIME = D_SEC(2); |
| | | static uint32_t stopTimepoint; |
| | | static int prevMoveDirect, storeMoveDirectBeforeStop; |
| | | static bool occurCrashRedLine; |
| | | static bool checkPartStatus; |
| | | static uint32_t firstReverseTimepoint; |
| | | static bool reportExamTimeout, reportParkFail; |
| | | static bool crossCtrlLineSw; |
| | | static int parkCount; |
| | | static char carray[3]; |
| | | static int darray[3]; |
| | | static int parkStatus[3]; |
| | | |
| | | static void StopCarTimeout(union sigval sig); |
| | | static void LeaveTestAreaLongtime(union sigval sig); |
| | | static void CrossCtrlLine(const Polygon *map, const car_model *car, const car_model *prev_car); |
| | | static char CrossCtrlLine(const Polygon *map, const car_model *car, const car_model *prev_car); |
| | | static bool EnterParking(const Polygon *map, const car_model *car); |
| | | static void ParkBottomTimeout(union sigval sig); |
| | | static bool CrashRedLine(const Polygon *map, const car_model *car); |
| | | static bool ExitParkArea(const Polygon *map, const car_model *car); |
| | | |
| | | void StartParkBottom(void) |
| | | void StartParkBottom(int moveDirect, const struct RtkTime *rtkTime) |
| | | { |
| | | stopCar2S = false; |
| | | trigLeaveTestAreaDetect = false; |
| | | leaveTestArea = false; |
| | | PBTesting = true; |
| | | parkTimeout = false; |
| | | first_ctrl_line_id = 0; |
| | | currTarget = FIRST_TOUCH_CTRL_LINE; |
| | | leftTireCrossLeftLine = leftTireCrossRightLine = rightTireCrossLeftLine = rightTireCrossRightLine = false; |
| | | |
| | | DEBUG("StartParkBottom"); |
| | | testing = true; |
| | | memset(carray, 0, sizeof(carray)); |
| | | memset(darray, 0, sizeof(darray)); |
| | | memset(parkStatus, 0, sizeof(parkStatus)); |
| | | prevMoveDirect = moveDirect; |
| | | |
| | | checkPartStatus = false; |
| | | firstReverseTimepoint = 0; |
| | | reportExamTimeout = false; |
| | | parkCount = 0; |
| | | crossCtrlLineSw = false; |
| | | reportParkFail = false; |
| | | occurCrashRedLine = false; |
| | | } |
| | | |
| | | void StopParkBottom(void) |
| | | int TestParkBottom(const Polygon *map, const car_model *car, const car_model *carPrev, double speed, int moveDirect, const struct RtkTime *rtkTime) |
| | | { |
| | | PBTesting = false; |
| | | AppTimer_delete(StopCarTimeout); |
| | | AppTimer_delete(ParkBottomTimeout); |
| | | AppTimer_delete(LeaveTestAreaLongtime); |
| | | currTarget = NONE; |
| | | char crossCtrlLine = 0; |
| | | uint32_t tp = TimeMakeComposite(rtkTime->hh, rtkTime->mm, rtkTime->ss, rtkTime->mss*10); |
| | | |
| | | DEBUG("ParkBottom End"); |
| | | } |
| | | |
| | | int TestParkBottom(vector<int>&err, const Polygon *map, const car_model *car, const car_model *carPrev, double speed, int run_status, const struct RtkTime *rtkTime) |
| | | { |
| | | int status = 0; |
| | | |
| | | if (!PBTesting) |
| | | return -2; |
| | | |
| | | DEBUG("TestParkBottom speed %f dir %d", speed, run_status); |
| | | |
| | | if (currTarget > FIRST_TOUCH_CTRL_LINE) { |
| | | // 是否超时 |
| | | if (parkTimeout) { |
| | | // 不合格:动作超时 |
| | | DEBUG("不合格:动作超时"); |
| | | err.push_back(10); |
| | | AddExamFault(10, rtkTime); |
| | | status = -1; |
| | | if (ExitParkArea(map, car)) { |
| | | DEBUG("离开场地"); |
| | | // 离开场地 |
| | | testing = false; |
| | | if ((parkStatus[0] != 1 || parkStatus[1] != 1) && !reportParkFail) { |
| | | // 倒库不入,不合格 |
| | | reportParkFail = true; |
| | | AddExamFault(8, rtkTime); |
| | | DEBUG("倒库不入"); |
| | | } |
| | | // 是否压线 |
| | | if (CrashRedLine(map, car)) { |
| | | // 不合格:车身出线 |
| | | DEBUG("不合格:车身出线"); |
| | | err.push_back(7); |
| | | goto TEST_END; |
| | | } |
| | | |
| | | if (CrashRedLine(map, car)) { |
| | | if (!occurCrashRedLine) { |
| | | occurCrashRedLine = true; |
| | | // 车身出线,不合格 |
| | | AddExamFault(7, rtkTime); |
| | | status = -1; |
| | | DEBUG("车轮压线"); |
| | | } |
| | | |
| | | if (trigLeaveTestAreaDetect) { |
| | | if (IntersectionOf(car->carXY[ car->left_front_tire[TIRE_OUTSIDE] ], map) == GM_Containment && |
| | | IntersectionOf(car->carXY[ car->right_front_tire[TIRE_OUTSIDE] ], map) == GM_Containment) { |
| | | trigLeaveTestAreaDetect = false; |
| | | AppTimer_delete(LeaveTestAreaLongtime); |
| | | } |
| | | } |
| | | } else { |
| | | occurCrashRedLine = false; |
| | | } |
| | | |
| | | if (currTarget == FIRST_TOUCH_CTRL_LINE || |
| | | currTarget == SECOND_TOUCH_CTRL_LINE || |
| | | currTarget == THIRD_TOUCH_CTRL_LINE) { |
| | | if (run_status > 0) { |
| | | if (stopCar2S && currTarget != FIRST_TOUCH_CTRL_LINE) { |
| | | // 扣5分:中途停车超过2秒 |
| | | DEBUG("扣5分:中途停车超过2秒"); |
| | | err.push_back(11); |
| | | AddExamFault(11, rtkTime); |
| | | } |
| | | |
| | | if (!((leftTireCrossLeftLine && rightTireCrossLeftLine) || |
| | | (leftTireCrossRightLine && rightTireCrossRightLine))) { |
| | | DEBUG("CrossCtrlLine"); |
| | | CrossCtrlLine(map, car, carPrev); |
| | | } else if (currTarget == FIRST_TOUCH_CTRL_LINE || currTarget == SECOND_TOUCH_CTRL_LINE) { |
| | | // 跨过控制线后,车辆持续向前行驶,处理这些乱搞情况 |
| | | // 整个车都离开测试区后,如果持续15秒,还没回到测试区,就忽略该测试或者淘汰 |
| | | if (leaveTestArea) { |
| | | if (currTarget == FIRST_TOUCH_CTRL_LINE) { |
| | | status = -2; |
| | | DEBUG("来道场玩的"); |
| | | } else { |
| | | // 不合格:未按规定线路行驶(直接跑出测试区了) |
| | | DEBUG("不合格:未按规定线路行驶(直接跑出测试区了)"); |
| | | err.push_back(6); |
| | | AddExamFault(6, rtkTime); |
| | | status = -1; |
| | | DEBUG("直接跑出测试区了"); |
| | | } |
| | | } else if (!trigLeaveTestAreaDetect) { |
| | | Polygon car_body; |
| | | |
| | | car_body.num = car->bodyNum; |
| | | car_body.point = (PointF *) malloc(sizeof(PointF) * car_body.num); |
| | | for (int i = 0; i < car_body.num; ++i) { |
| | | car_body.point[i] = car->carXY[car->body[i]]; |
| | | } |
| | | |
| | | if (IntersectionOf(map, &car_body) == GM_None) { |
| | | trigLeaveTestAreaDetect = true; |
| | | AppTimer_delete(LeaveTestAreaLongtime); |
| | | AppTimer_add(LeaveTestAreaLongtime, D_SEC(15)); |
| | | DEBUG("开始离场计时"); |
| | | } |
| | | |
| | | free(car_body.point); |
| | | } |
| | | } |
| | | |
| | | if (currTarget == THIRD_TOUCH_CTRL_LINE) { |
| | | char the_ctrl_line_crossed = 0; |
| | | |
| | | if (leftTireCrossLeftLine && rightTireCrossLeftLine) { |
| | | the_ctrl_line_crossed = 'L'; |
| | | } else if (leftTireCrossRightLine && rightTireCrossRightLine) { |
| | | the_ctrl_line_crossed = 'R'; |
| | | } |
| | | |
| | | if (the_ctrl_line_crossed != 0 && the_ctrl_line_crossed == first_ctrl_line_id) { |
| | | // 项目完成 |
| | | status = 1; |
| | | } else if (the_ctrl_line_crossed != 0) { |
| | | // 不合格:未按规定线路行驶(未回到起始点) |
| | | DEBUG("不合格:未按规定线路行驶(未回到起始点)"); |
| | | err.push_back(6); |
| | | AddExamFault(6, rtkTime); |
| | | status = -1; |
| | | } |
| | | } |
| | | if (carStopEvent) |
| | | AppTimer_delete(StopCarTimeout); |
| | | carStopEvent = false; |
| | | stopCar2S = false; |
| | | } else if (run_status < 0) { |
| | | // 左右倒库大纲并未要求谁先完成,故以先越过的控制线为准,下次得越过另外一条 |
| | | char the_ctrl_line_crossed = 0; |
| | | |
| | | if (leftTireCrossLeftLine && rightTireCrossLeftLine) { |
| | | the_ctrl_line_crossed = 'L'; |
| | | } else if (leftTireCrossRightLine && rightTireCrossRightLine) { |
| | | the_ctrl_line_crossed = 'R'; |
| | | } |
| | | |
| | | if (first_ctrl_line_id > 0 && first_ctrl_line_id == the_ctrl_line_crossed) { |
| | | // 不合格:未按规定线路行驶(试图做2次同方向的倒库) |
| | | DEBUG("不合格:未按规定线路行驶(试图做2次同方向的倒库)"); |
| | | err.push_back(6); |
| | | crossCtrlLine = CrossCtrlLine(map, car, carPrev); |
| | | if (crossCtrlLine > 0 && !crossCtrlLineSw) { |
| | | crossCtrlLineSw = true; |
| | | if (parkCount == 0) { |
| | | carray[0] = crossCtrlLine; |
| | | } else if (parkCount == 1) { |
| | | if (carray[0] == crossCtrlLine) { |
| | | // 不按规定线路,顺序形式,不合格 |
| | | AddExamFault(6, rtkTime); |
| | | status = -1; |
| | | } else if (the_ctrl_line_crossed > 0 && first_ctrl_line_id == 0) { |
| | | first_ctrl_line_id = the_ctrl_line_crossed; |
| | | // 项目正式开始,210秒内完成 |
| | | AppTimer_delete(ParkBottomTimeout); |
| | | AppTimer_add(ParkBottomTimeout, D_SEC(PARK_TIMEOUT)); |
| | | currTarget = FIRST_PARK; |
| | | carParkSuccess = false; |
| | | parkTimeout = false; |
| | | leftTireCrossLeftLine = leftTireCrossRightLine = rightTireCrossLeftLine = rightTireCrossRightLine = false; |
| | | |
| | | DEBUG("第一次倒库"); |
| | | } else if (the_ctrl_line_crossed > 0) { |
| | | currTarget = SECOND_PARK; |
| | | carParkSuccess = false; |
| | | leftTireCrossLeftLine = leftTireCrossRightLine = rightTireCrossLeftLine = rightTireCrossRightLine = false; |
| | | DEBUG("第二次倒库"); |
| | | } else if (currTarget != THIRD_TOUCH_CTRL_LINE) { |
| | | // 不合格:倒车前,2前轮没驶过控制线 |
| | | DEBUG("不合格:倒车前,2前轮没驶过控制线"); |
| | | err.push_back(9); |
| | | AddExamFault(9, rtkTime); |
| | | status = -1; |
| | | DEBUG("不按规定线路,顺序形式"); |
| | | } |
| | | if (carStopEvent) |
| | | AppTimer_delete(StopCarTimeout); |
| | | carStopEvent = false; |
| | | stopCar2S = false; |
| | | } else { |
| | | if (!carStopEvent) { |
| | | AppTimer_delete(StopCarTimeout); |
| | | AppTimer_add(StopCarTimeout, D_SEC(2)); |
| | | carray[1] = crossCtrlLine; |
| | | } else if (parkCount == 2) { |
| | | if (carray[0] != crossCtrlLine) { |
| | | // 不按规定线路,顺序形式,不合格 |
| | | AddExamFault(6, rtkTime); |
| | | DEBUG("不按规定线路,顺序形式"); |
| | | } else { |
| | | // 离开测试区,停止计时 |
| | | DEBUG("离开测试区,停止计时"); |
| | | testing = false; |
| | | goto TEST_END; |
| | | } |
| | | carStopEvent = true; |
| | | carray[2] = crossCtrlLine; |
| | | } |
| | | } else if (currTarget == FIRST_PARK || currTarget == SECOND_PARK) { |
| | | if (run_status < 0) { |
| | | if (stopCar2S) { |
| | | // 扣5分:中途停车 |
| | | DEBUG("扣5分:中途停车"); |
| | | err.push_back(11); |
| | | AddExamFault(11, rtkTime); |
| | | } |
| | | |
| | | if (testing && darray[0] > 0 && tp - firstReverseTimepoint >= PARK_TIMEOUT) { |
| | | // 完成超时,不合格 |
| | | if (!reportExamTimeout) { |
| | | reportExamTimeout = true; |
| | | AddExamFault(10, rtkTime); |
| | | DEBUG("项目超时"); |
| | | } |
| | | } |
| | | |
| | | if (moveDirect != prevMoveDirect) { |
| | | if (moveDirect == 0) { |
| | | stopTimepoint = tp; |
| | | storeMoveDirectBeforeStop = prevMoveDirect; |
| | | if (prevMoveDirect == -1) { |
| | | checkPartStatus = true; |
| | | } |
| | | |
| | | carStopEvent = false; |
| | | stopCar2S = false; |
| | | } else if (run_status == 0) { |
| | | // 立即检查是否停车到位,也许是中途停车,先不管,待发生前进事件后,再断定是否停车到位 |
| | | if (!carStopEvent) { |
| | | carStopEvent = true; |
| | | carParkSuccess = EnterParking(map, car); |
| | | AppTimer_delete(StopCarTimeout); |
| | | AppTimer_add(StopCarTimeout, D_SEC(2)); |
| | | } |
| | | DEBUG("停车了 %d %d %d %d %d %d %d", rtkTime->YY, rtkTime->MM, rtkTime->DD, rtkTime->hh, rtkTime->mm, rtkTime->ss, rtkTime->mss); |
| | | } else { |
| | | if (carStopEvent) { |
| | | if (!carParkSuccess) { |
| | | // 不合格:倒库不入 |
| | | DEBUG("不合格:倒库不入"); |
| | | err.push_back(8); |
| | | AddExamFault(8, rtkTime); |
| | | status = -1; |
| | | } else if (currTarget == FIRST_PARK) { |
| | | currTarget = SECOND_TOUCH_CTRL_LINE; |
| | | DEBUG("过另一根控制线"); |
| | | } else { |
| | | currTarget = THIRD_TOUCH_CTRL_LINE; |
| | | DEBUG("再过第一根控制线"); |
| | | DEBUG("继续行驶 %d %d %d %d %d %d %d", rtkTime->YY, rtkTime->MM, rtkTime->DD, rtkTime->hh, rtkTime->mm, rtkTime->ss, rtkTime->mss); |
| | | |
| | | DEBUG("停车时间 %ld", tp - stopTimepoint); |
| | | |
| | | if (moveDirect == storeMoveDirectBeforeStop) { |
| | | // 同方向再启动,继续判断是否停车超时 |
| | | if (tp - stopTimepoint >= STOP_CAR_TIME) { |
| | | // 停车超2秒,每次扣5分 |
| | | AddExamFault(11, rtkTime); |
| | | DEBUG("中途停车"); |
| | | } |
| | | } else if (moveDirect == -1) { |
| | | // 切换为倒车 |
| | | if (darray[parkCount] == 0) { |
| | | if (!crossCtrlLineSw) { |
| | | // 倒车前,前轮未驶过控制线 |
| | | AddExamFault(9, rtkTime); |
| | | DEBUG("倒车前,前轮未驶过控制线"); |
| | | } |
| | | darray[parkCount] = 1; |
| | | firstReverseTimepoint = tp; |
| | | } |
| | | } else { |
| | | // 切换为前进 |
| | | if (tp - stopTimepoint >= STOP_CAR_TIME) { |
| | | if (crossCtrlLineSw) { |
| | | if (checkPartStatus) { |
| | | if (EnterParking(map, car)) { |
| | | parkStatus[parkCount] = 1; |
| | | } |
| | | checkPartStatus = false; |
| | | } |
| | | if (parkStatus[parkCount] != 1) { |
| | | // 倒库不入,不合格 |
| | | reportParkFail = true; |
| | | AddExamFault(8, rtkTime); |
| | | DEBUG("倒库不入"); |
| | | } |
| | | } |
| | | |
| | | crossCtrlLineSw = false; |
| | | |
| | | if (parkCount < 2) |
| | | parkCount++; |
| | | } |
| | | } |
| | | carStopEvent = false; |
| | | stopCar2S = false; |
| | | } |
| | | prevMoveDirect = moveDirect; |
| | | } else if (moveDirect == -1) { |
| | | if (darray[parkCount] == 0) { |
| | | // 切换为倒车 |
| | | if (!crossCtrlLineSw) { |
| | | // 倒车前,前轮未驶过控制线 |
| | | AddExamFault(9, rtkTime); |
| | | DEBUG("倒车前,前轮未驶过控制线"); |
| | | } |
| | | darray[parkCount] = 1; |
| | | firstReverseTimepoint = tp; |
| | | } |
| | | } else if (moveDirect == 0 && crossCtrlLineSw) { |
| | | if (tp - stopTimepoint >= STOP_CAR_TIME && checkPartStatus) { |
| | | if (EnterParking(map, car)) { |
| | | parkStatus[parkCount] = 1; |
| | | } |
| | | checkPartStatus = false; |
| | | } |
| | | } |
| | | |
| | | if (status != 0) { |
| | | StopParkBottom(); |
| | | } |
| | | |
| | | return status; |
| | | } |
| | | |
| | | static void StopCarTimeout(union sigval sig) { |
| | | AppTimer_delete(StopCarTimeout); |
| | | |
| | | stopCar2S = true; |
| | | } |
| | | |
| | | static void LeaveTestAreaLongtime(union sigval sig) { |
| | | AppTimer_delete(LeaveTestAreaLongtime); |
| | | leaveTestArea = true; |
| | | trigLeaveTestAreaDetect = false; |
| | | } |
| | | |
| | | static void ParkBottomTimeout(union sigval sig) { |
| | | AppTimer_delete(ParkBottomTimeout); |
| | | parkTimeout = true; |
| | | TEST_END: |
| | | return testing ? 0 : 1; |
| | | } |
| | | |
| | | // 检测2前轮是否正向越过左右控制线 |
| | | static void CrossCtrlLine(const Polygon *map, const car_model *car, const car_model *prev_car) |
| | | static char CrossCtrlLine(const Polygon *map, const car_model *car, const car_model *prev_car) |
| | | { |
| | | Line leftCtrlLine, rightCtrlLine; |
| | | Line track1; |
| | | PointF p1, p2; |
| | | // 过右控制线 |
| | | if ((IntersectionOfLine(map->point[6], map->point[7], car->carXY[car->left_front_tire[TIRE_OUTSIDE]]) == -1) && |
| | | (IntersectionOfLine(map->point[6], map->point[7], car->carXY[car->right_front_tire[TIRE_OUTSIDE]]) == -1) && |
| | | (IntersectionOfLine(map->point[6], map->point[7], car->carXY[car->axial[AXIAL_REAR]]) == 1)) { |
| | | return 'R'; |
| | | } |
| | | |
| | | MakeLine(&leftCtrlLine, &(map->point[0]), &(map->point[1])); |
| | | MakeLine(&rightCtrlLine, &(map->point[6]), &map->point[7]); |
| | | // 左前轮,取轮宽的中点 |
| | | p1.X = (car->carXY[car->left_front_tire[TIRE_OUTSIDE]].X + car->carXY[car->left_front_tire[TIRE_INSIDE]].X) / 2; |
| | | p1.Y = (car->carXY[car->left_front_tire[TIRE_OUTSIDE]].Y + car->carXY[car->left_front_tire[TIRE_INSIDE]].Y) / 2; |
| | | p2.X = (prev_car->carXY[car->left_front_tire[TIRE_OUTSIDE]].X + prev_car->carXY[car->left_front_tire[TIRE_INSIDE]].X) / 2; |
| | | p2.Y = (prev_car->carXY[car->left_front_tire[TIRE_OUTSIDE]].Y + prev_car->carXY[car->left_front_tire[TIRE_INSIDE]].Y) / 2; |
| | | MakeLine(&track1, &p1, &p2); |
| | | if (IntersectionOf(track1, leftCtrlLine) == GM_Intersection && |
| | | IntersectionOfLine(map->point[0], map->point[1], p1) == -1) { |
| | | leftTireCrossLeftLine = true; |
| | | DEBUG("左轮跨越左控制线"); |
| | | // 过左控制线 |
| | | if ((IntersectionOfLine(map->point[1], map->point[0], car->carXY[car->left_front_tire[TIRE_OUTSIDE]]) == 1) && |
| | | (IntersectionOfLine(map->point[1], map->point[0], car->carXY[car->right_front_tire[TIRE_OUTSIDE]]) == 1) && |
| | | (IntersectionOfLine(map->point[1], map->point[0], car->carXY[car->axial[AXIAL_REAR]]) == -1)) { |
| | | return 'L'; |
| | | } |
| | | if (IntersectionOf(track1, rightCtrlLine) == GM_Intersection && |
| | | IntersectionOfLine(map->point[6], map->point[7], p1) == -1) { |
| | | leftTireCrossRightLine = true; |
| | | DEBUG("左轮跨越右控制线"); |
| | | } |
| | | // 右前轮 |
| | | p1.X = (car->carXY[car->right_front_tire[TIRE_OUTSIDE]].X + car->carXY[car->right_front_tire[TIRE_INSIDE]].X) / 2; |
| | | p1.Y = (car->carXY[car->right_front_tire[TIRE_OUTSIDE]].Y + car->carXY[car->right_front_tire[TIRE_INSIDE]].Y) / 2; |
| | | p2.X = (prev_car->carXY[car->right_front_tire[TIRE_OUTSIDE]].X + prev_car->carXY[car->right_front_tire[TIRE_INSIDE]].X) / 2; |
| | | p2.Y = (prev_car->carXY[car->right_front_tire[TIRE_OUTSIDE]].Y + prev_car->carXY[car->right_front_tire[TIRE_INSIDE]].Y) / 2; |
| | | MakeLine(&track1, &p1, &p2); |
| | | if (IntersectionOf(track1, leftCtrlLine) == GM_Intersection && |
| | | IntersectionOfLine(map->point[0], map->point[1], p1) == -1) { |
| | | rightTireCrossLeftLine = true; |
| | | DEBUG("右轮跨越左控制线"); |
| | | } |
| | | if (IntersectionOf(track1, rightCtrlLine) == GM_Intersection && |
| | | IntersectionOfLine(map->point[6], map->point[7], p1) == -1) { |
| | | rightTireCrossRightLine = true; |
| | | DEBUG("右轮跨越右控制线"); |
| | | } |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | static bool EnterParking(const Polygon *map, const car_model *car) { |
| | |
| | | |
| | | CleanPolygon(&parking); |
| | | free(car_body.point); |
| | | |
| | | DEBUG("检查倒库状态 %s", succ ? "成功" : "失败"); |
| | | |
| | | return succ; |
| | | } |
| | |
| | | free(car_body.point); |
| | | return ret; |
| | | } |
| | | |
| | | static bool ExitParkArea(const Polygon *map, const car_model *car) |
| | | { |
| | | // 全车都需不在地图中 |
| | | bool ret = false; |
| | | |
| | | Polygon carBody; |
| | | |
| | | carBody.num = car->bodyNum; |
| | | carBody.point = (PointF *)malloc(carBody.num * sizeof(PointF)); |
| | | for (int i = 0; i < carBody.num; ++i) { |
| | | carBody.point[i] = car->carXY[car->body[i]]; |
| | | } |
| | | |
| | | if (IntersectionOf(&carBody, map) == GM_None) { |
| | | ret = true; |
| | | } |
| | | |
| | | free(carBody.point); |
| | | |
| | | return ret; |
| | | } |
| | |
| | | |
| | | using namespace std; |
| | | |
| | | void StartParkBottom(void); |
| | | void StopParkBottom(void); |
| | | int TestParkBottom(vector<int>&err, const Polygon *map, const car_model *car, const car_model *carPrev, double speed, int run_status, const struct RtkTime *rtkTime); |
| | | void StartParkBottom(int moveStatus, const struct RtkTime *rtkTime); |
| | | int TestParkBottom(const Polygon *map, const car_model *car, const car_model *carPrev, double speed, int moveStatus, const struct RtkTime *rtkTime); |
| | | |
| | | #endif //RTKDRIVERTEST_PARK_BOTTOM_H |
| | |
| | | static int parkStatus; |
| | | static bool occurMoveBack, parkSuccess; |
| | | static uint32_t moveBackTimePoint; |
| | | static bool testing = false; |
| | | |
| | | static bool CrashRedLine1(const Polygon *map, const car_model *car); |
| | | static bool CrashRedLine2(const Polygon *map, const car_model *car); |
| | |
| | | |
| | | void StartParkEdge(int moveStatus, const struct RtkTime *rtkTime) |
| | | { |
| | | DEBUG("进入侧方停车场地"); |
| | | |
| | | testing = true; |
| | | |
| | | occurCrashRedLine1 = occurCrashRedLine2 = false; // 这个科目规定特殊点,发生一次扣10分,而不直接淘汰 |
| | | reportExamTimeout = false; |
| | | |
| | |
| | | occurMoveBack = true; |
| | | moveBackTimePoint = TimeMakeComposite(rtkTime->hh, rtkTime->mm, rtkTime->ss, rtkTime->mss*10); |
| | | } |
| | | |
| | | DEBUG("进入侧方停车场地"); |
| | | } |
| | | |
| | | int TestParkEdge(const Polygon *map, const car_model *car, const car_model *carPrev, double speed, int moveStatus, const struct RtkTime *rtkTime) |
| | | { |
| | | int status = 0; |
| | | |
| | | if (CrashRedLine1(map, car)) { |
| | | if (!occurCrashRedLine1) { |
| | | // 车轮压边线,每次扣10分 |
| | |
| | | AddExamFault(21, rtkTime); |
| | | DEBUG("直接驶离测试区,移库不入"); |
| | | } |
| | | status = 1; |
| | | testing = false; |
| | | goto TEST_END; |
| | | } |
| | | |
| | | if (occurMoveBack) { |
| | |
| | | // 倒车切换到前进 |
| | | if (moveStatus == 1 && tp - stopTimepoint >= STOP_CAR_TIME) { |
| | | if (parkStatus == 0) { |
| | | |
| | | if (EnterParking(map, car)) { |
| | | parkStatus = 1; |
| | | parkSuccess = true; |
| | | } |
| | | } |
| | | |
| | | if (!parkSuccess) { |
| | |
| | | prevMoveStatus = moveStatus; |
| | | } else if (moveStatus == 0 && parkStatus == 0) { |
| | | uint32_t tp = TimeMakeComposite(rtkTime->hh, rtkTime->mm, rtkTime->ss, rtkTime->mss*10); |
| | | tp = tp * 1000 + rtkTime->mss * 10; |
| | | |
| | | if (tp - stopTimepoint >= STOP_CAR_TIME) { |
| | | if (EnterParking(map, car)) { |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | return status; |
| | | TEST_END: |
| | | return testing ? 0 : 1; |
| | | } |
| | | |
| | | // 车轮是否压道路边线 |
| | |
| | | |
| | | const double EPSILON = 1e-3; |
| | | |
| | | static bool SASTesting = false; |
| | | static bool testing = false; |
| | | |
| | | static double slideDistance; |
| | | static PointF stopPoint; |
| | |
| | | void StartSAS(int moveDirect, const struct RtkTime *rtkTime) |
| | | { |
| | | DEBUG("进入坡起项目"); |
| | | SASTesting = true; |
| | | testing = true; |
| | | slideDistance = 0.0; |
| | | |
| | | prevMoveDirect = moveDirect; |
| | |
| | | |
| | | int TestSAS(const Polygon *map, const car_model *car, const car_model *carPrev, double speed, int moveDirect, const struct RtkTime *rtkTime) |
| | | { |
| | | int status = 0; |
| | | |
| | | if (CrashRedLine(map, car)) { |
| | | // 车轮压线,不合格 |
| | | if (!occurCrashRedLine) { |
| | |
| | | |
| | | if (ExitTestArea(map, car)) { |
| | | // 驶离测试区 |
| | | status = 1; |
| | | testing = false; |
| | | } |
| | | |
| | | if (prevMoveDirect != moveDirect) { |
| | |
| | | } |
| | | } |
| | | |
| | | return status; |
| | | return testing ? 0 : 1; |
| | | } |
| | | |
| | | // 车轮是否压边线 |
| | |
| | | |
| | | const uint32_t STOP_CAR_TIME = D_SEC(2); |
| | | |
| | | static bool TA90Testing; |
| | | static bool testing; |
| | | |
| | | static int enterAreaHeading; |
| | | static bool turnLeftFinished; |
| | |
| | | void StartTurnA90(int moveDirect, double heading, const struct RtkTime *rtkTime) |
| | | { |
| | | DEBUG("进入直角转弯场地"); |
| | | testing = true; |
| | | enterAreaHeading = (int) heading; |
| | | prevMoveDirect = moveDirect; |
| | | if (moveDirect == 0) { |
| | |
| | | |
| | | int TestTurnA90(const Polygon *map, const car_model *car, const car_model *carPrev, double heading, double speed, int moveDirect, const struct RtkTime *rtkTime) |
| | | { |
| | | int status = 0; |
| | | int az = (int) heading; |
| | | |
| | | if (ExitTestArea(map, car)) { |
| | | status = 1; |
| | | testing = false; |
| | | goto TEST_END; |
| | | } |
| | | |
| | | if (CrashRedLine(map, car)) { |
| | |
| | | } |
| | | |
| | | // 检查转向状态 |
| | | int az = (int) heading; |
| | | |
| | | if (ABS(az - enterAreaHeading) > 180) { |
| | | az = 360 - ABS(az-enterAreaHeading); |
| | | } else { |
| | | az = ABS(az - enterAreaHeading); |
| | | } |
| | | |
| | | |
| | | |
| | | if (az >= 30) { |
| | | if (!turnLeftFinished) { |
| | |
| | | if (turnLeftFinished) { |
| | | |
| | | } |
| | | |
| | | return status; |
| | | TEST_END: |
| | | return testing?0:1; |
| | | } |
| | | |
| | | // 车轮是否压边线 |