// // Created by YY on 2019/11/4. // #include "driving_curve.h" #include "../jni_log.h" #include "../driver_test.h" #include "../common/apptimer.h" #include "../utils/xconvert.h" #include #include using namespace std; #define DEBUG(fmt, args...) LOGD(" <%s>: " fmt, __func__, ##args) enum { DRIVING_ON_CURVE }; const uint32_t STOP_CAR_TIME = D_SEC(2); static bool testing = false; static uint32_t stopTimepoint = 0; static bool reportStopCarTimeout; static int prevMoveDirect; static bool crashRedLine; static struct calc_zone_t { int leftStart; int leftEnd; int rightStart; int rightEnd; } calcZone; static bool CrashRedLine(const Polygon *map, const Polygon *map2, const car_model *car, struct calc_zone_t *zone); static bool ExitArea(const Polygon *map, const Polygon *map2, const car_model *car); void StartDrivingCurve(int moveDirect, const struct RtkTime *rtkTime) { DEBUG("进入曲线行驶场地"); testing = true; prevMoveDirect = moveDirect; if (moveDirect == 0) { stopTimepoint = TimeMakeComposite(rtkTime->hh, rtkTime->mm, rtkTime->ss, rtkTime->mss*10); } reportStopCarTimeout = false; crashRedLine = false; calcZone.leftStart = calcZone.leftEnd = calcZone.rightStart = calcZone.rightEnd = 0; } int TestDrivingCurve(const Polygon *map, const Polygon *map2, const car_model *car, const car_model *carPrev, double speed, int moveDirect, const struct RtkTime *rtkTime) { Line start, end; Line axial; MakeLine(&axial, &car->carXY[car->axial[AXIAL_FRONT]], &car->carXY[car->axial[AXIAL_REAR]]); // DEBUG("START 线 %d -- %d", calcZone.leftStart, calcZone.rightStart); // DEBUG("END 线 %d -- %d", calcZone.leftEnd, calcZone.rightEnd); MakeLine(&start, &map->point[calcZone.leftStart], &map2->point[calcZone.rightStart]); if (IntersectionOf(start, axial) == GM_None) { // 向起点查找 int tempLeft = calcZone.leftStart, tempRight = calcZone.rightStart; while (calcZone.leftStart > 0 || calcZone.rightStart > 0) { if (calcZone.leftStart > 0) tempLeft = calcZone.leftStart - 1; if (calcZone.rightStart > 0) tempRight = calcZone.rightStart - 1; // DEBUG("START 向起点查找 %d -- %d", tempLeft, tempRight); MakeLine(&start, &map->point[tempLeft], &map2->point[tempRight]); if (IntersectionOf(start, axial) == GM_Intersection) { // 保持之前的线 break; } else { calcZone.leftStart = tempLeft; calcZone.rightStart = tempRight; if (calcZone.leftStart == calcZone.leftEnd && calcZone.rightStart == calcZone.rightEnd) { // 车辆丢失,重新搜索 calcZone.leftStart = calcZone.rightStart = 0; calcZone.leftEnd = calcZone.rightEnd = 0; DEBUG("车辆丢失,重新搜索"); while (calcZone.leftStart < map->num || calcZone.rightStart < map2->num) { MakeLine(&start, &map->point[calcZone.leftStart], &map2->point[calcZone.rightStart]); if (IntersectionOf(start, axial) == GM_Intersection) { while (calcZone.leftStart < map->num || calcZone.rightStart < map2->num) { MakeLine(&start, &map->point[calcZone.leftStart], &map2->point[calcZone.rightStart]); if (IntersectionOf(start, axial) == GM_None) { break; } if (calcZone.leftStart < map->num) calcZone.leftStart++; if (calcZone.rightStart < map2->num) calcZone.rightStart++; } break; } calcZone.leftEnd = calcZone.leftStart; calcZone.rightEnd = calcZone.rightStart; if (calcZone.leftStart < map->num) calcZone.leftStart++; if (calcZone.rightStart < map2->num) calcZone.rightStart++; } if (calcZone.leftStart >= map->num && calcZone.rightStart >= map2->num) { // 离开场地 DEBUG("离开曲线场地"); testing = false; goto TEST_END; } break; } } } } else { // 向终点查找 do { if (calcZone.leftStart >= map->num && calcZone.rightStart >= map2->num) { break; } if (calcZone.leftStart < map->num) calcZone.leftStart++; if (calcZone.rightStart < map2->num) calcZone.rightStart++; // DEBUG("START 向终点查找 %d -- %d", calcZone.leftStart, calcZone.rightStart); MakeLine(&start, &map->point[calcZone.leftStart], &map2->point[calcZone.rightStart]); } while (IntersectionOf(start, axial) == GM_Intersection); } MakeLine(&end, &map->point[calcZone.leftEnd], &map2->point[calcZone.rightEnd]); if (IntersectionOf(end, axial) == GM_None) { // 向终点查找 int tempLeft = calcZone.leftEnd, tempRight = calcZone.rightEnd; while (calcZone.leftEnd < map->num || calcZone.rightEnd < map2->num) { if (calcZone.leftEnd >= map->num && calcZone.rightEnd >= map2->num) { break; } if (calcZone.leftEnd < map->num) tempLeft = calcZone.leftEnd + 1; if (calcZone.rightEnd < map2->num) tempRight = calcZone.rightEnd + 1; // DEBUG("END 向终点查找 %d -- %d", tempLeft, tempRight); MakeLine(&end, &map->point[tempLeft], &map2->point[tempRight]); if (IntersectionOf(end, axial) == GM_Intersection) { // 保持之前的线 break; } else { calcZone.leftEnd = tempLeft; calcZone.rightEnd = tempRight; } } } else { // 向起点查找 do { if (calcZone.leftEnd == 0 && calcZone.rightEnd == 0) { break; } if (calcZone.leftEnd > 0) calcZone.leftEnd--; if (calcZone.rightEnd > 0) calcZone.rightEnd--; // DEBUG("END 向起点查找 %d -- %d", calcZone.leftEnd, calcZone.rightEnd); MakeLine(&end, &map->point[calcZone.leftEnd], &map2->point[calcZone.rightEnd]); } while (IntersectionOf(end, axial) == GM_Intersection); } DEBUG("calcZone leftStart %d leftEnd %d rightStart %d rightEnd %d", calcZone.leftStart, calcZone.leftEnd, calcZone.rightStart, calcZone.rightEnd); if (CrashRedLine(map, map2, car, &calcZone)) { if (!crashRedLine) { crashRedLine = true; // 车轮压边线,不合格 AddExamFault(27, rtkTime); DEBUG("车轮压边线"); } } else { crashRedLine = false; } if (moveDirect != prevMoveDirect) { if (moveDirect == 0) { stopTimepoint = TimeMakeComposite(rtkTime->hh, rtkTime->mm, rtkTime->ss, rtkTime->mss*10); reportStopCarTimeout = false; DEBUG("停车了 %d %d %d %d %d %d %d", rtkTime->YY, rtkTime->MM, rtkTime->DD, rtkTime->hh, rtkTime->mm, rtkTime->ss, rtkTime->mss); } else { } prevMoveDirect = moveDirect; } else if (moveDirect == 0) { uint32_t tp = TimeMakeComposite(rtkTime->hh, rtkTime->mm, rtkTime->ss, rtkTime->mss*10); if (tp - stopTimepoint >= STOP_CAR_TIME && !reportStopCarTimeout) { // 停车超2秒,不合格 AddExamFault(28, rtkTime); DEBUG("中途停车"); reportStopCarTimeout = true; } } TEST_END: return testing ? 1 : 0; } static bool ExitArea(const Polygon *map, const Polygon *map2, const car_model *car) { // 全车都需不在地图中 bool ret = false; Polygon carBody; Polygon bigMap; bigMap.num = map->num + map2->num; bigMap.point = (PointF *) malloc(bigMap.num * sizeof(PointF)); int i = 0; for (; i < map->num; ++i) { bigMap.point[i] = map->point[i]; } for (int j = map2->num; j > 0; --j) { bigMap.point[i++] = map2->point[j-1]; } 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, &bigMap) == GM_None) { ret = true; } free(carBody.point); free(bigMap.point); return ret; } // 车轮是否压边线 static bool CrashRedLine(const Polygon *map, const Polygon *map2, const car_model *car, struct calc_zone_t *zone) { bool ret = false; Line frontTireAxial, rearTireAxial; Line redLine; MakeLine(&frontTireAxial, &car->carXY[car->left_front_tire[TIRE_OUTSIDE]], &car->carXY[car->right_front_tire[TIRE_OUTSIDE]]); MakeLine(&rearTireAxial, &car->carXY[car->left_rear_tire[TIRE_OUTSIDE]], &car->carXY[car->right_rear_tire[TIRE_OUTSIDE]]); int s = zone->leftStart; for (int e = zone->leftStart - 1; e >= zone->leftEnd; --e) { MakeLine(&redLine, &map->point[s], &map->point[e]); if (IntersectionOf(redLine, frontTireAxial) != GM_None) { return true; } if (IntersectionOf(redLine, rearTireAxial) != GM_None) { return true; } s = e; } s = zone->rightStart; for (int e = zone->rightStart - 1; e >= zone->rightEnd; --e) { MakeLine(&redLine, &map2->point[s], &map2->point[e]); if (IntersectionOf(redLine, frontTireAxial) != GM_None) { return true; } if (IntersectionOf(redLine, rearTireAxial) != GM_None) { return true; } s = e; } return ret; }