yy1717
2020-05-22 00c07fb94c6927f3bb8ebfec383a33936f04447b
坐标
7个文件已修改
897 ■■■■■ 已修改文件
lib/src/main/cpp/driver_test.cpp 165 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/driver_test.h 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/master/comm_if.cpp 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/test_items2/road_exam.cpp 512 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/test_items2/road_exam.h 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/test_items2/through_something.cpp 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/test_items2/through_something.h 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/driver_test.cpp
@@ -65,11 +65,7 @@
static LIST_AREA_MAP AreaMapList;
static Polygon RoadMapPoints;
static road_exam_map RoadMap;
static LIST_ROAD_MAP RoadMapList;
static int exam_dummy_light;
@@ -109,10 +105,6 @@
    AreaMapList.clear();
    RoadMapPoints.num = 0;
    RoadMapPoints.point = NULL;
//    RoadMapList.clear();
    RoadMap.roads.clear();
    RoadMap.specialAreas.clear();
    RoadMap.triggerLines.clear();
@@ -210,162 +202,6 @@
    RoadMap.triggerLines.assign(map.triggerLines.begin(), map.triggerLines.end());
    DEBUG("得到新的路考地图 路数量 %d 特殊区域数量 %d 触发线数量 %d", RoadMap.roads.size(), RoadMap.specialAreas.size(), RoadMap.triggerLines.size());
}
void SetRoadMapPoints(vector<double> &mapPoints)
{
    DEBUG("加入路考地图点集合 num = %d", mapPoints.size()/2);
    RoadMapPoints.num = mapPoints.size()/2;
    if (RoadMapPoints.num > 0) {
        RoadMapPoints.point = (PointF *)malloc(sizeof(PointF) * RoadMapPoints.num);
        for (int i = 0; i < RoadMapPoints.num; ++i) {
            RoadMapPoints.point[i].X = mapPoints[i*2];
            RoadMapPoints.point[i].Y = mapPoints[i*2+1];
        }
    }
}
void AddRoadMapParent(int id, int type, string tts, int stopFlag,
        vector<vector<int>> &redLines,
                      vector<vector<int>> &redAreas,
                      vector<vector<int>> &greenLines,
                      vector<vector<int>> &triggerLines,
                      vector<vector<int>> &roadEdgeLines,
                      vector<int> area,
                      vector<int> stopLine)
{
/*    struct road_exam_map newMap;
    newMap.id = id;
    newMap.type = type;
    newMap.tts = tts;
    newMap.flagStop = stopFlag;
    DEBUG("加入路考地图信息 id = %d type = %d", id, type);
    if (!tts.empty()) {
        DEBUG("TTS 信息 = %s", tts.c_str());
    }
    if ((newMap.redLineNum = redLines.size()) > 0) {
        newMap.redLine = (Polygon *) malloc(sizeof(Polygon) * newMap.redLineNum);
        DEBUG("红线 %d 根", newMap.redLineNum);
        for (int i = 0; i < newMap.redLineNum; ++i) {
            newMap.redLine[i].num = redLines[i].size();
            newMap.redLine[i].point = (PointF *) malloc(sizeof(PointF) * newMap.redLine[i].num);
            DEBUG("    结点 %d 个", newMap.redLine[i].num);
            for (int j = 0; j < newMap.redLine[i].num; ++j) {
                newMap.redLine[i].point[j] = RoadMapPoints.point[redLines[i][j]];
            }
        }
    } else {
        newMap.redLine = NULL;
    }
    if ((newMap.redAreaNum = redAreas.size()) > 0) {
        newMap.redArea = (Polygon *) malloc(sizeof(Polygon) * newMap.redAreaNum);
        DEBUG("红区 %d 个", newMap.redAreaNum);
        for (int i = 0; i < newMap.redAreaNum; ++i) {
            newMap.redArea[i].num = redAreas[i].size();
            newMap.redArea[i].point = (PointF *) malloc(sizeof(PointF) * newMap.redLine[i].num);
            DEBUG("    结点 %d 个", newMap.redArea[i].num);
            for (int j = 0; j < newMap.redArea[i].num; ++j) {
                newMap.redArea[i].point[j] = RoadMapPoints.point[redAreas[i][j]];
            }
        }
    } else {
        newMap.redArea = NULL;
    }
    if ((newMap.greenLineNum = greenLines.size()) > 0) {
        newMap.greenLine = (Polygon *) malloc(sizeof(Polygon) * newMap.greenLineNum);
        DEBUG("绿线 %d 根", newMap.greenLineNum);
        for (int i = 0; i < newMap.greenLineNum; ++i) {
            newMap.greenLine[i].num = greenLines[i].size();
            newMap.greenLine[i].point = (PointF *) malloc(sizeof(PointF) * newMap.greenLine[i].num);
            DEBUG("    结点 %d 个", newMap.greenLine[i].num);
            for (int j = 0; j < newMap.greenLine[i].num; ++j) {
                newMap.greenLine[i].point[j] = RoadMapPoints.point[greenLines[i][j]];
            }
        }
    } else {
        newMap.greenLine = NULL;
    }
    if ((newMap.triggerLineNum = triggerLines.size()) > 0) {
        newMap.triggerLine = (struct trigger_line_t *) malloc(sizeof(struct trigger_line_t) * newMap.triggerLineNum);
        DEBUG("触发线 %d 根", newMap.triggerLineNum);
        for (int i = 0; i < newMap.triggerLineNum; ++i) {
            newMap.triggerLine[i].line.num = triggerLines[i].size() - 1;
            newMap.triggerLine[i].line.point = (PointF *) malloc(sizeof(PointF) * newMap.triggerLine[i].line.num);
            DEBUG("    结点 %d 个, 触发 id = %d", newMap.triggerLine[i].line.num, triggerLines[i][0]);
            newMap.triggerLine[i].triggerMapId = triggerLines[i][0];
            for (int j = 0; j < newMap.triggerLine[i].line.num; ++j) {
                newMap.triggerLine[i].line.point[j] = RoadMapPoints.point[triggerLines[i][j+1]];
            }
        }
    } else {
        newMap.triggerLine = NULL;
    }
    if ((newMap.roadEdgeLineNum = roadEdgeLines.size()) > 0) {
        newMap.roadEdgeLine = (Polygon *) malloc(sizeof(Polygon) * newMap.roadEdgeLineNum);
        DEBUG("道路边线 %d 根", newMap.roadEdgeLineNum);
        for (int i = 0; i < newMap.roadEdgeLineNum; ++i) {
            newMap.roadEdgeLine[i].num = roadEdgeLines[i].size();
            newMap.roadEdgeLine[i].point = (PointF *) malloc(sizeof(PointF) * newMap.roadEdgeLine[i].num);
            DEBUG("    结点 %d 个", newMap.roadEdgeLine[i].num);
            for (int j = 0; j < newMap.roadEdgeLine[i].num; ++j) {
                newMap.roadEdgeLine[i].point[j] = RoadMapPoints.point[roadEdgeLines[i][j]];
            }
        }
    } else {
        newMap.roadEdgeLine = NULL;
    }
    if (area.size() > 0) {
        newMap.area.num = area.size();
        newMap.area.point = (PointF *) malloc(sizeof(PointF) * newMap.area.num);
        DEBUG("子项目区域点 %d 个", newMap.area.num);
        for (int i = 0; i < newMap.area.num; ++i) {
            newMap.area.point[i] = RoadMapPoints.point[area[i]];
        }
    } else {
        newMap.area.point = NULL;
        newMap.area.num = 0;
    }
    if (stopLine.size() == 2) {
        newMap.stopLine.X1 = RoadMapPoints.point[stopLine[0]].X;
        newMap.stopLine.Y1 = RoadMapPoints.point[stopLine[0]].Y;
        newMap.stopLine.X2 = RoadMapPoints.point[stopLine[1]].X;
        newMap.stopLine.Y2 = RoadMapPoints.point[stopLine[1]].Y;
        DEBUG("得到停止线 (%f,% f) --- (%f, %f)", newMap.stopLine.X1,
              newMap.stopLine.Y1,
              newMap.stopLine.X2,
              newMap.stopLine.Y2);
    }
    RoadMapList.push_back(newMap);*/
}
void SetCarMeasurePoint(double *basePoint, int *axial, int *left_front_tire,
@@ -784,7 +620,6 @@
    if (ExamType != TEST_TYPE_AREA) {
        if (exam_dummy_light == 2) {
//            TestRoadGeneral(RoadMapList, CarModel, CarModelList, speed, move, rtkTime);
            TestRoadGeneral(RoadMap, CarModel, CarModelList, speed, move, rtkTime);
        }
    } else {
lib/src/main/cpp/driver_test.h
@@ -92,41 +92,6 @@
    int wrong_id;
};
struct trigger_line_tx {
    int triggerMapId;
    Polygon line;
};
struct road_exam_mapx {
    int id;
    int type;
    string tts;
    int redLineNum;
    Polygon *redLine;
    int greenLineNum;
    Polygon *greenLine;
    int redAreaNum;
    Polygon *redArea;
    int triggerLineNum;
    trigger_line_tx *triggerLine;
    int roadEdgeLineNum;    // 道路边线,只有直线驾驶、靠边停车才有
    Polygon *roadEdgeLine;
    Polygon area;           // 子项目的区域
    Line stopLine;         // 诸如人行道、路口等考点的停止线
    int flagStop;           // 到达开始线前,是否需要停车
};
typedef vector<struct road_exam_mapx> LIST_ROAD_MAP;
#define LINE_DOTTED            0
#define LINE_SOLID             1
#define LINE_HALF_SOLID_LEFT        2
@@ -142,6 +107,20 @@
#define SCHOOL_AREA                 1
#define BUS_STATION_AREA            2
#define GRID_AREA                   3
#define ROAD_ITEM_NONE              0
#define ROAD_ITEM_CHANGE_LANE       1
#define ROAD_ITEM_OVERTAKE          2
#define ROAD_ITEM_STRAIGHT          3
#define ROAD_ITEM_OPERATE_GEAR      4
#define ROAD_ITEM_START_CAR         5
enum {
    ROAD_ACTIVE_FORWARD,
    ROAD_ACTIVE_TURN_LEFT,
    ROAD_ACTIVE_TURN_RIGHT,
    ROAD_ACTIVE_TURN_BACKWARD
};
typedef struct {
    int character;                  // 属性(实线、虚线,有些可以掉头的路段)
@@ -165,6 +144,9 @@
    Line startLine;
    Line stopLine;
    int active;         // 到达路口尾部的行进方向
    bool activeBreak;   // 路口刹车减速
    bool activeStop;    // 路口停车瞭望
    bool errorLane;     // 错误车道
    int targetRoad;
    int stopFlag;
    string tts;
@@ -179,6 +161,8 @@
    int id;
    int road;
    int type;
    bool activeBreak;
    bool overSpeed;
    std::vector<PointF> area;       // 人行道等右侧2点,网格线4点
    std::vector<PointF> leftPoints; // 对应到道路左侧的点
} special_area_t;
@@ -190,7 +174,8 @@
    int time;                   // 项目最大完成时间
    int distance;               // 项目最大完成距离
    string tts;
    Line line;
    std::vector<PointF> points;
    std::vector<PointF> leftPoints; // 对应到道路左侧的点
} trigger_line_t;
struct road_exam_map {
@@ -210,8 +195,6 @@
typedef list<car_model *> LIST_CAR_MODEL;
//vector<ExamFault> ExamFaultList;
void DriverTestInit(void);
void ReadDriverExamPrimer(void);
@@ -221,12 +204,6 @@
void CleanRoadMap(void);
void SetRoadMap(road_exam_map &map);
void SetRoadMapPoints(vector<double> &mapPoints);
void AddRoadMapParent(int id, int type, string tts, int stopFlag, vector<vector<int>> &redLines,
                      vector<vector<int>> &redAreas, vector<vector<int>> &greenLines,
                      vector<vector<int>> &triggerLines, vector<vector<int>> &roadEdgeLines,
                      vector<int> area, vector<int> stopLine);
void SetCarMeasurePoint(double *basePoint, int *axial, int *left_front_tire,
                        int *right_front_tire, int *left_rear_tire, int *right_rear_tire,
lib/src/main/cpp/master/comm_if.cpp
@@ -594,7 +594,6 @@
                        mapPoints.push_back((*itr2).GetDouble());
                    }
                    SetRoadMapPoints(mapPoints);
                }
                if (doc.HasMember("maps")) {
@@ -737,7 +736,6 @@
                                tts = s.GetString();
                            }
                            AddRoadMapParent(id, type, tts, stop_flag, redLines, redAreas, greenLines, triggerLines, roadEdgeLines, area, stopLine);
                        }
                    }
                }
@@ -959,8 +957,6 @@
                if (doc.HasMember("special_area")) {
                    const Value &a = doc["special_area"];
                    vector<special_area_t> specialAreas;
                    for (Value::ConstValueIterator itr = a.Begin();
                         itr != a.End(); ++itr) {
                        special_area_t specialArea;
@@ -991,7 +987,52 @@
                    }
                }
                if (doc.HasMember("trigger_line")) {
                    const Value &a = doc["trigger_line"];
                    for (Value::ConstValueIterator itr = a.Begin();
                         itr != a.End(); ++itr) {
                        trigger_line_t trigger;
                        if (itr->HasMember("type")) {
                            const Value &s = (*itr)["type"];
                            trigger.active = s.GetInt();
                        }
                        if (itr->HasMember("id")) {
                            const Value &s = (*itr)["id"];
                            trigger.id = s.GetInt();
                        }
                        if (itr->HasMember("road")) {
                            const Value &s = (*itr)["road"];
                            trigger.road = s.GetInt();
                        }
                        if (itr->HasMember("tts")) {
                            const Value &s = (*itr)["tts"];
                            trigger.tts = s.GetString();
                        }
                        if (itr->HasMember("time")) {
                            const Value &s = (*itr)["time"];
                            trigger.time = s.GetInt();
                        } else {
                            trigger.time = 0;
                        }
                        if (itr->HasMember("distance")) {
                            const Value &s = (*itr)["distance"];
                            trigger.distance = s.GetInt();
                        } else {
                            trigger.distance = 0;
                        }
                        if (itr->HasMember("line")) {
                            const Value &a2 = (*itr)["line"];
                            for (Value::ConstValueIterator itr2 = a2.Begin();
                                 itr2 != a2.End(); ++itr2) {
                                trigger.points.push_back(mapPoints[(*itr2).GetInt()]);
                            }
                        }
                        map.triggerLines.push_back(trigger);
                    }
                }
                DEBUG("地图解析完毕");
lib/src/main/cpp/test_items2/road_exam.cpp
@@ -40,6 +40,14 @@
static const int TURN_CHECK_INTERVAL = 500;
const double SLIDE_DISTANCE_THRESHOLD_RED = 0.3;
const double SLIDE_DISTANCE_THRESHOLD_YELLOW = 0.1;
const double CHANGE_LANE_RANGE = 100.0;
const double OVERTAKE_RANGE = 150.0;
const double OVERTAKE_HOLD_RANGE = 30.0;                // 在超车道行驶的一段距离
static const double LASTEST_BREAK_POINT = 30.0;
static const double NEXT_ROAD_TIP = 100.0;                  // 到达路口前提示下一个怎么走
static const double DISTANCE_STOP_CAR_TO_STOP_LINE = 5.0;
static const double PASS_SCHOOL_MAX_SPEED = 30.0;           // kmh
static const int FIND_POSITION = -2;
static const int INVALID_POSITION = -1;
@@ -75,13 +83,15 @@
static int startCar;
static int currExamMapIndex;
static trigger_line_t *currRoadItem;
static int nextRoadId;
static PointF roadItemStartPoint;
static struct drive_timer roadItemStartTime;
static bool overtake = false;
static bool checkDoor = false;
static bool handBreakActive = false;
static bool reportRPMOver = false;
static int currCarOnRoadIndex;
static const uint32_t TURN_ERROR_COLD_TIME = D_SEC(10);
@@ -90,6 +100,8 @@
    int road;
    int separate;
    int lane;
    int direct;         // 车道方向限制
    int type;           // 实线,虚线
} CurrentLane;
static bool laneChanging;
@@ -103,7 +115,6 @@
static const uint32_t CRASH_DOTTED_LINE_TIMEOUT = D_SEC(10);
static const uint32_t TURN_SIGNAL_LAMP_ADVANCE = D_SEC(3);
static const double NEXT_ROAD_TIP = 100.0;                  // 到达路口前提示下一个怎么走
static const int CRL_NONE = 0;
static const int CRL_SEP_DOTTED = 1;
@@ -118,11 +129,6 @@
static char isTurn(int currYaw, int prevYaw, int &ang);
static char CheckCarTurn(LIST_CAR_MODEL &CarModelList);
static bool CrashRedLine(LIST_ROAD_MAP &RoadMapList, const car_model *car);
static bool CrashRedArea(LIST_ROAD_MAP &RoadMapList, const car_model *car);
static bool CrashGreenLine(LIST_ROAD_MAP &RoadMapList, const car_model *car, PointF &p1, PointF &p2);
static int CrashTriggerLine(LIST_ROAD_MAP &RoadMapList, const car_model *car, LIST_CAR_MODEL &CarModelList);
static int FindMapIndexById(int id, LIST_ROAD_MAP &RoadMapList);
static void TurnSignalError13ColdTimer(union sigval sig);
static void TurnSignalError14ColdTimer(union sigval sig);
@@ -132,6 +138,10 @@
static bool LaneIsSame(struct car_on_lane lane1, struct car_on_lane lane2);
static bool LaneIsValid(struct car_on_lane lane);
static void ArrivedRoadEnd(road_t &road, const car_model *car, LIST_CAR_MODEL &CarModelList);
static trigger_line_t * EntryItem(int index, road_exam_map &RoadMap, const car_model *car, LIST_CAR_MODEL &CarModelList);
static void ClearAll(road_exam_map &map);
static void CheckBreakActive(road_exam_map &map, const car_model *car, LIST_CAR_MODEL &CarModelList,
                             double speed, int moveDirect, const struct RtkTime *rtkTime);
void InitRoadExam(road_exam_map &RoadMap)
{
@@ -141,6 +151,7 @@
    occurCrashRedLine = false;
    occurCrashGreenLine = false;
    occurOverSpeed = false;
    occurSecondBreak = false;
    checkCrashGreenTimeout = 0;
    carIntersectionOfGreenLine = 0;
@@ -161,6 +172,7 @@
    currExamMapIndex = FIND_POSITION;
    startCar = START_CAR_NOT_DO;
    currRoadItem = NULL;
    checkDoor = false;
    handBreakActive = false;
@@ -170,12 +182,11 @@
    turnError13Cold = turnError14Cold = true;
    currCarOnRoadIndex = FIND_POSITION;
    CurrentLane.road = CurrentLane.separate = CurrentLane.lane = -1;
    laneChanging = false;
    InitThroughSomething(RoadMap);
    nextRoadId = -1;
    ClearAll(RoadMap);
}
void TerminateRoadExam(void)
@@ -295,14 +306,12 @@
void TestRoadGeneral(road_exam_map &RoadMap, const car_model *car, LIST_CAR_MODEL &CarModelList, double speed, int moveDirect, const struct RtkTime *rtkTime)
{
    // 起步检测
    TestRoadStartCar(car, speed, moveDirect, rtkTime);
    // 超速检测
    if (moveDirect != 0 && speed > MAX_SPEED) {
        if (!occurOverSpeed) {
            occurOverSpeed = true;
            // 超速,不合格
            DEBUG("超速 %f", speed);
            AddExamFault(10, rtkTime);
        }
    } else {
@@ -470,7 +479,8 @@
    }
    // 检测通过路口、人行道等区域时,释放刹车或减速
    CheckBreakActive(RoadMap, car, CarModelList);
    CheckBreakActive(RoadMap, car, CarModelList,
                                 speed, moveDirect, rtkTime);
    // 检测离开此路段,全车需不在范围内
    if (currExamMapIndex >= 0) {
@@ -579,6 +589,11 @@
            if (IntersectionOf(car->carXY[car->axial[AXIAL_FRONT]], &area) == GM_Containment) {
                currExamMapIndex = i;
                DEBUG("进入道路 id = %d", RoadMap.roads[i].id);
                if (nextRoadId >= 0 && RoadMap.roads[i].id != nextRoadId) {
                    DEBUG("不按规矩行驶,进入错误路段");
                    AddExamFault(3, rtkTime);
                }
                nextRoadId = -1;
                break;
            }
@@ -608,16 +623,16 @@
        if (crl == CRL_NONE) {
//            DEBUG("什么都没压");
        } else if (crl == CRL_SEP_DOTTED) {
//            DEBUG("压分道虚线");
            DEBUG("压分道虚线");
            crashGreenLineNow = true;
        } else if (crl == CRL_SEP_SOLID) {
//            DEBUG("压分道实线");
            DEBUG("压分道实线");
            crashRedLineNow = true;
        } else if (crl == CRL_EDGE_DOTTED) {
//            DEBUG("压边沿虚线");
            DEBUG("压边沿虚线");
            crashGreenLineNow = true;
        } else if (crl == CRL_EDGE_SOLID) {
//            DEBUG("压边沿实线");
            DEBUG("压边沿实线");
            crashRedLineNow = true;
        }
@@ -700,9 +715,23 @@
                } else {
                    // 变道完成
                    DEBUG("变道完成");
                    if (currRoadItem != NULL && currRoadItem->active == ROAD_ITEM_CHANGE_LANE) {
                        DEBUG("变更车道项目完成");
                        currRoadItem = NULL;
                    } else if (currRoadItem != NULL && currRoadItem->active == ROAD_ITEM_OVERTAKE) {
                        if (CurrentLane.lane > lane.lane) {
                            DEBUG("超车变道完成");
                        } else {
                            DEBUG("右道超车,错误");
                            AddExamFault(3, rtkTime);
                            currRoadItem = NULL;
                        }
                    }
                    CurrentLane = lane;
                    laneChanging = false;
                    // 记录本次变道时间点
                    Rtk2DriveTimer(crashGreenCmpTime, rtkTime);
                }
@@ -710,11 +739,20 @@
            if (lane.road != CurrentLane.road || lane.separate != CurrentLane.separate) {
                // 路或段变更,撤销变道跟踪
                DEBUG("============== 路或段变更 CURR %d, %d NEW %d, %d", CurrentLane.road,
                      CurrentLane.separate,
                      lane.road, lane.separate);
                DEBUG("============== 路或段变更 CURR %d, %d dir %d NEW %d, %d, dir %d", CurrentLane.road,
                      CurrentLane.separate, CurrentLane.direct,
                      lane.road, lane.separate, lane.direct);
                CurrentLane = lane;
                laneChanging = false;
            }
            if (CurrentLane.direct != 0 && !(CurrentLane.direct & RoadMap.roads[currExamMapIndex].active)) {
                if (!RoadMap.roads[currExamMapIndex].errorLane) {
                    RoadMap.roads[currExamMapIndex].errorLane = true;
                    DEBUG("不按规定车道标线方向行驶 %d", CurrentLane.direct);
                    AddExamFault(9, rtkTime);
                }
            }
        }
@@ -773,6 +811,50 @@
        // 不再压虚线
        occurCrashGreenLine = false;
        checkCrashGreenTimeout = 0;
    }
    TestRoadStartCar(car, speed, moveDirect, rtkTime);
    if (startCar != START_CAR_DONE)
        return;
    // 检测由触发线控制的项目
    if (currRoadItem != NULL) {
        if (currRoadItem->active == ROAD_ITEM_CHANGE_LANE) {
            if (DistanceOf(car->basePoint, roadItemStartPoint) > CHANGE_LANE_RANGE) {
                DEBUG("变道距离超标");
                AddExamFault(3, rtkTime);
                currRoadItem = NULL;
            }
        } else if (currRoadItem->active == ROAD_ITEM_OVERTAKE) {
            if (!overtake && DistanceOf(car->basePoint, roadItemStartPoint) > OVERTAKE_RANGE) {
                DEBUG("超车距离超标");
                AddExamFault(3, rtkTime);
                currRoadItem = NULL;
            } else if (overtake && DistanceOf(car->basePoint, roadItemStartPoint) > OVERTAKE_HOLD_RANGE) {
                DEBUG("回原车道");
                PlayTTS("请返回原车道");
                currRoadItem = NULL;
            }
        } else if (currRoadItem->active == ROAD_ITEM_OPERATE_GEAR) {
            ExecuteOperateGearExam(rtkTime);
        }
    } else if (currExamMapIndex >= 0) {
        currRoadItem = EntryItem(currExamMapIndex, RoadMap, car, CarModelList);
        if (currRoadItem != NULL) {
            if (!currRoadItem->tts.empty())
                PlayTTS(currRoadItem->tts.c_str());
            // 初始时间和距离限制
            roadItemStartPoint = car->basePoint;
            Rtk2DriveTimer(roadItemStartTime, rtkTime);
            if (currRoadItem->active == ROAD_ITEM_OVERTAKE) {
                overtake = false;
            } else if (currRoadItem->active == ROAD_ITEM_OPERATE_GEAR) {
                StartOperateGearExam(rtkTime);
            }
        }
    }
}
@@ -839,7 +921,7 @@
        PointF p1, p2;
        Line sep;
        map<int, int> orthogonal;
        map<int, vector<int>> orthogonal;
        // 一段分道组内,有一条正交,就必须保证同组的全都正交,否则直接退出
        for (int j = 0; j < road.separate[i].lines.size(); ++j) {   // 线组
@@ -853,15 +935,31 @@
                    MakeLine(&sep, &p1, &p2);
                    if (IntersectionOf(leftExtLine, sep) == GM_Intersection) {
                        orthogonal.insert(pair<int, int>(j, 1));
                        vector<int> stor(4);
                        stor[0] = 1;
                        stor[1] = road.separate[i].lines[j][k].character;
                        stor[2] = road.separate[i].lines[j][k].left_lane_direct;
                        stor[3] = road.separate[i].lines[j][k].right_lane_direct;
                        orthogonal.insert(pair<int, vector<int>>(j, stor));
                        orthogonalInSegment = true;
                        intersection = true;
//                        DEBUG("分道线 %d 左正交", j);
                        break;
                    } else if (IntersectionOf(rightExtLine, sep) == GM_Intersection) {
                        orthogonal.insert(pair<int, int>(j, 2));
                        vector<int> stor(4);
                        stor[0] = 2;
                        stor[1] = road.separate[i].lines[j][k].character;
                        stor[2] = road.separate[i].lines[j][k].left_lane_direct;
                        stor[3] = road.separate[i].lines[j][k].right_lane_direct;
                        orthogonal.insert(pair<int, vector<int>>(j, stor));
                        orthogonalInSegment = true;
                        intersection = true;
//                        DEBUG("分道线 %d 右正交", j);
                        break;
                    }
@@ -875,16 +973,26 @@
            if (orthogonal.size() == road.separate[i].lines.size()) {
                // 得到当前在第几个车道
                int x = 0;
                int left_char = LINE_SOLID;               // 道路左边线
                int right_direct = 0;
                for (x = 0; x < orthogonal.size(); ++x) {
                    auto itx = orthogonal.find(x);
                    if (itx != orthogonal.end()) {
                        if (itx->second != 1) {
                        if (itx->second[0] != 1) {          // 在车辆右侧
                            lane.road = road.id;
                            lane.separate = i;
                            lane.lane = itx->first;
                            if ((left_char == LINE_SOLID || left_char == LINE_HALF_SOLID_RIGHT) &&
                                    (itx->second[1] == LINE_SOLID || itx->second[1] == LINE_HALF_SOLID_LEFT))    // 车道左右均是实线
                                lane.direct = itx->second[2];
                            else
                                lane.direct = 0;
//                            DEBUG("路 %d 段 %d 车道 %d", lane.road, lane.separate, lane.lane);
                            break;
                        } else {
                            right_direct = itx->second[3];
                            left_char = itx->second[2];
                        }
                    }
                }
@@ -892,7 +1000,11 @@
                    lane.road = road.id;
                    lane.separate = i;
                    lane.lane = orthogonal.size();
                    // 最后车道的右侧限定
                    if (left_char == LINE_SOLID || left_char == LINE_HALF_SOLID_RIGHT)
                        lane.direct = right_direct;
                    else
                        lane.direct = 0;
//                    DEBUG("路 %d 段 %d 车道 %d", lane.road, lane.separate, lane.lane);
                }
                out = lane;
@@ -1026,6 +1138,7 @@
    return false;
}
#if 0
void TestRoadGeneral(LIST_ROAD_MAP &RoadMapList, const car_model *car, LIST_CAR_MODEL &CarModelList, double speed, int moveDirect, const struct RtkTime *rtkTime)
{
    // 起步检测
@@ -1383,6 +1496,7 @@
    }
}
bool ExitSonArea(int index, LIST_ROAD_MAP &RoadMapList, const car_model *car)
{
    bool ret = false;
@@ -1464,6 +1578,7 @@
    return ret;
}
#endif
void Rtk2DriveTimer(struct drive_timer &tm, const struct RtkTime *rtkTime)
{
@@ -1556,48 +1671,13 @@
    return 0;
}
/*****************************************************
 * CrashRedLine 整个考试区域的道路边缘线,实线等。
 * 按车轮碰触计算,车身不计
 */
static bool CrashRedLine(LIST_ROAD_MAP &RoadMapList, const car_model *car)
{
    Line frontAxle, rearAxle;
    MakeLine(&frontAxle, &car->carXY[car->left_front_tire[TIRE_OUTSIDE]], &car->carXY[car->right_front_tire[TIRE_OUTSIDE]]);
    MakeLine(&rearAxle, &car->carXY[car->left_rear_tire[TIRE_OUTSIDE]], &car->carXY[car->right_rear_tire[TIRE_OUTSIDE]]);
    for (int i = 0; i < RoadMapList.size(); ++i) {
        if (RoadMapList[i].type == GENERAL_MAP) {
            // 每条线都检测
            for (int j = 0; j < RoadMapList[i].redLineNum; ++j) {
                Line red_line;
                int kp = 0;
                for (int k = 1; k < RoadMapList[i].redLine[j].num; ++k) {
                    MakeLine(&red_line, &RoadMapList[i].redLine[j].point[kp], &RoadMapList[i].redLine[j].point[k]);
                    if (IntersectionOf(red_line, frontAxle) == GM_Intersection ||
                        IntersectionOf(red_line, rearAxle) == GM_Intersection) {
                        return true;
                    }
                    kp = k;
                }
            }
            break;
        }
    }
    return false;
}
/**********************************************************
 * 按整个车身是否覆盖计算
 * @param RoadMapList
 * @param car
 * @return
 */
static bool CrashRedArea(LIST_ROAD_MAP &RoadMapList, const car_model *car)
/*static bool CrashRedArea(LIST_ROAD_MAP &RoadMapList, const car_model *car)
{
    bool ret = false;
@@ -1625,119 +1705,7 @@
    free(carBody.point);
    return ret;
}
/**************************************************
 * 车轮触碰道路虚线。检测行驶时间超长;变道情况;
 * @param RoadMapList
 * @param car
 */
static bool CrashGreenLine(LIST_ROAD_MAP &RoadMapList, const car_model *car, PointF &p1, PointF &p2)
{
    Line frontAxle, rearAxle;
    MakeLine(&frontAxle, &car->carXY[car->left_front_tire[TIRE_OUTSIDE]], &car->carXY[car->right_front_tire[TIRE_OUTSIDE]]);
    MakeLine(&rearAxle, &car->carXY[car->left_rear_tire[TIRE_OUTSIDE]], &car->carXY[car->right_rear_tire[TIRE_OUTSIDE]]);
    for (int i = 0; i < RoadMapList.size(); ++i) {
        if (RoadMapList[i].type == GENERAL_MAP) {
            // 每条线都检测
            for (int j = 0; j < RoadMapList[i].greenLineNum; ++j) {
                Line green_line;
                int kp = 0;
                for (int k = 1; k < RoadMapList[i].greenLine[j].num; ++k) {
                    MakeLine(&green_line, &RoadMapList[i].greenLine[j].point[kp], &RoadMapList[i].greenLine[j].point[k]);
                    if (IntersectionOf(green_line, frontAxle) == GM_Intersection ||
                        IntersectionOf(green_line, rearAxle) == GM_Intersection) {
                        p1 = RoadMapList[i].greenLine[j].point[kp];
                        p2 = RoadMapList[i].greenLine[j].point[k];
                        return true;
                    }
                    kp = k;
                }
            }
            break;
        }
    }
    return false;
}
/************************************************************
 * 检测车辆是否触发子考项地图
 * @param RoadMapList
 * @param car
 * @param CarModelList
 * @return
 */
static int CrashTriggerLine(LIST_ROAD_MAP &RoadMapList, const car_model *car, LIST_CAR_MODEL &CarModelList)
{
    int map_idx = -1;
    if (CarModelList.size() < 5)
        return map_idx;
    Polygon trace;
    trace.num = 5;
    trace.point = (PointF *) malloc(sizeof(PointF) * trace.num);
    list<car_model *>::iterator iter = CarModelList.begin();
    int pn = 0;
    while (iter != CarModelList.end() && pn < trace.num) {
        trace.point[pn++] = ((car_model *)(*iter))->carXY[((car_model *)(*iter))->left_front_tire[TIRE_OUTSIDE]];
        ++iter;
    }
    for (int i = 0; i < RoadMapList.size(); ++i) {
        if (RoadMapList[i].type == GENERAL_MAP) {
            // 每条线都检测
            for (int j = 0; j < RoadMapList[i].triggerLineNum; ++j) {
                Line trigger_line;
                int kp = 0;
                // 触发线一般应该只有首尾2点(id, p1, p2)
                for (int k = 1; k < RoadMapList[i].triggerLine[j].line.num; ++k) {
                    MakeLine(&trigger_line, &RoadMapList[i].triggerLine[j].line.point[kp], &RoadMapList[i].triggerLine[j].line.point[k]);
                    int pp = 0;
                    for (int p = 1; p < pn; ++p) {
                        Line trace_line;
                        MakeLine(&trace_line, &trace.point[pp], &trace.point[p]);
                        if (IntersectionOf(trace_line, trigger_line) == GM_Intersection &&
                            IntersectionOfLine(RoadMapList[i].triggerLine[j].line.point[kp],
                                    RoadMapList[i].triggerLine[j].line.point[k],
                                    car->carXY[car->left_front_tire[TIRE_OUTSIDE]]) == -1 &&
                            DistanceOf(car->carXY[car->left_front_tire[TIRE_OUTSIDE]], trigger_line) > 0.1) {
                            // 碰到触发线
                            DEBUG("碰撞触发线 引发地图 id = %d", RoadMapList[i].triggerLine[j].triggerMapId);
                            map_idx =  FindMapIndexById(RoadMapList[i].triggerLine[j].triggerMapId, RoadMapList);
                            goto SEARCH_TRIGGER_LINE_END;
                        }
                        pp = p;
                    }
                    kp = k;
                }
            }
            break;
        }
    }
SEARCH_TRIGGER_LINE_END:
    free(trace.point);
    return map_idx;
}
}*/
bool CrashTheLine(Line line, const car_model *car, LIST_CAR_MODEL &CarModelList)
{
@@ -1759,16 +1727,6 @@
        return true;
    }
    return false;
}
static int FindMapIndexById(int id, LIST_ROAD_MAP &RoadMapList)
{
    for (int i = 0; i < RoadMapList.size(); ++i) {
        if (RoadMapList[i].id == id) {
            return i;
        }
    }
    return -1;
}
/*********************************************************************
@@ -1822,6 +1780,12 @@
    return px;
}
/***************************************************
 * 接近路口时,提示下一步怎么走
 * @param road
 * @param car
 * @param CarModelList
 */
static void ArrivedRoadEnd(road_t &road, const car_model *car, LIST_CAR_MODEL &CarModelList)
{
    // 计算车前进轨迹延长线
@@ -1836,6 +1800,7 @@
        IntersectionOfLine(extPoint, road.stopLine) == -1) {
            if (DistanceOf(extPoint, road.stopLine) > 1.0 && !road.arrivedTail) {
                // 接近路口后,要检查车辆是否进入错误车道
                DEBUG("接近路口");
                road.arrivedTail = true;
                if (!road.tts.empty())
                    PlayTTS(road.tts.c_str());
@@ -1845,6 +1810,177 @@
    }
}
static trigger_line_t * EntryItem(int index, road_exam_map &RoadMap, const car_model *car, LIST_CAR_MODEL &CarModelList)
{
    for (int i = 0; i < RoadMap.triggerLines.size(); ++i) {
        if (RoadMap.triggerLines[i].road == RoadMap.roads[index].id) {
            Line triggerLine;
            if (RoadMap.triggerLines[i].leftPoints.size() != RoadMap.triggerLines[i].points.size()) {
                RoadMap.triggerLines[i].leftPoints.clear();
                for (int j = 0; j < RoadMap.triggerLines[i].points.size(); ++j) {
                    RoadMap.triggerLines[i].leftPoints.push_back(GetSELine(RoadMap.roads[index].leftEdge, RoadMap.triggerLines[i].points[j]));
                }
            }
            MakeLine(&triggerLine, &RoadMap.triggerLines[i].points[0], &RoadMap.triggerLines[i].leftPoints[0]);
            if (CrashTheLine(triggerLine, car, CarModelList)) {
                return &RoadMap.triggerLines[i];
            }
        }
    }
    return NULL;
}
/************************************************************************
 * 开始新的考试后,清除地图所有的刹车、停车记录
 * @param map
 */
static void ClearAll(road_exam_map &map)
{
    for (int i = 0; i < map.roads.size(); ++i) {
        map.roads[i].activeStop = map.roads[i].activeBreak = false;
        map.roads[i].arrivedTail = false;
        map.roads[i].errorLane = false;
    }
    for (int i = 0; i < map.specialAreas.size(); i++) {
        map.specialAreas[i].overSpeed = map.specialAreas[i].activeBreak = false;
    }
}
static void CheckBreakActive(road_exam_map &map, const car_model *car, LIST_CAR_MODEL &CarModelList,
                             double speed, int moveDirect, const struct RtkTime *rtkTime)
{
    int BreakDone = ReadCarStatus(BREAK);
    // 计算车前进轨迹延长线
    double yaw = YawOf(car->carXY[ car->axial[AXIAL_FRONT] ], car->carXY[ car->axial[AXIAL_REAR] ]);
    PointF extPoint = PointExtend(car->carXY[ car->axial[AXIAL_FRONT] ], LASTEST_BREAK_POINT, yaw);
    Line extLine;
    MakeLine(&extLine, &car->carXY[ car->axial[AXIAL_FRONT] ], &extPoint);
    // 路口刹车点
    for (int i = 0; i < map.roads.size(); ++i) {
        // 车头和路口距离不足30米
        if (IntersectionOf(extLine, map.roads[i].stopLine) == GM_Intersection &&
            IntersectionOfLine(car->carXY[ car->axial[AXIAL_FRONT] ], map.roads[i].stopLine) == 1 ) {
            DEBUG("进入减速区");
            if (BreakDone == BREAK_ACTIVE) {
                map.roads[i].activeBreak = true;
            }
            if (DistanceOf(car->carXY[car->axial[AXIAL_FRONT]],
                           map.roads[i].stopLine) < DISTANCE_STOP_CAR_TO_STOP_LINE && moveDirect == 0) {
                map.roads[i].activeStop = true;
            }
        }
        // 跨线后,检查刹车动作
        if (CrashTheLine(map.roads[i].stopLine, car, CarModelList)) {
            if (map.roads[i].stopFlag != 0 && !map.roads[i].activeStop) {
                // 不停车瞭望,不合格
                DEBUG("不停车瞭望");
                if (map.roads[i].active == ROAD_ACTIVE_FORWARD) {
                    AddExamFault(42, rtkTime);
                } else if (map.roads[i].active == ROAD_ACTIVE_TURN_LEFT) {
                    AddExamFault(44, rtkTime);
                } else if (map.roads[i].active == ROAD_ACTIVE_TURN_RIGHT) {
                    AddExamFault(47, rtkTime);
                }
            }
            if (!map.roads[i].activeBreak) {
                // 不按规定减速,不合格
                DEBUG("不按规定减速");
                if (map.roads[i].active == ROAD_ACTIVE_FORWARD) {
                    AddExamFault(41, rtkTime);
                } else if (map.roads[i].active == ROAD_ACTIVE_TURN_LEFT) {
                    AddExamFault(43, rtkTime);
                } else if (map.roads[i].active == ROAD_ACTIVE_TURN_RIGHT) {
                    AddExamFault(46, rtkTime);
                }
            }
        }
    }
    // 人行道、公交站刹车点;学校限速区
    for (int i = 0; i < map.specialAreas.size(); i++) {
        if (map.specialAreas[i].type == GRID_AREA)
            continue;
        if (map.specialAreas[i].area.size() == 2 && map.specialAreas[i].leftPoints.size() != 2) {
            // 计算点到左侧路边线的垂点
            int road = 0;
            for (road = 0; road < map.roads.size(); ++road) {
                if (map.roads[road].id == map.specialAreas[i].road)
                    break;
            }
            PointF vPoint = GetSELine(map.roads[road].leftEdge, map.specialAreas[i].area[0]);
            DEBUG("计算垂点1 (%f, %f)", vPoint.X, vPoint.Y);
            map.specialAreas[i].leftPoints.push_back(vPoint);
            vPoint = GetSELine(map.roads[road].leftEdge, map.specialAreas[i].area[0]);
            DEBUG("计算垂点2 (%f, %f)", vPoint.X, vPoint.Y);
            map.specialAreas[i].leftPoints.push_back(vPoint);
        }
        if (map.specialAreas[i].type == ZEBRA_CROSSING || map.specialAreas[i].type == BUS_STATION_AREA) {
            Line startLine;
            MakeLine(&startLine, &map.specialAreas[i].area[0], &map.specialAreas[i].leftPoints[0]);
            // 车头和斑马线距离不足30米
            if (IntersectionOf(extLine, startLine) == GM_Intersection &&
                IntersectionOfLine(car->carXY[ car->axial[AXIAL_FRONT] ], startLine) == 1 ) {
                DEBUG("进入减速区 %d", map.specialAreas[i].type);
                if (BreakDone == BREAK_ACTIVE) {
                    map.specialAreas[i].activeBreak = true;
                }
            }
            // 跨线后,检查刹车动作
            if (CrashTheLine(startLine, car, CarModelList)) {
                if (!map.specialAreas[i].activeBreak) {
                    // 不按规定减速,不合格
                    DEBUG("不按规定减速");
                    if (map.specialAreas[i].type == ZEBRA_CROSSING) {
                        AddExamFault(48, rtkTime);
                    } else {
                        AddExamFault(50, rtkTime);
                    }
                } else {
                    DEBUG("按规定减速");
                }
            }
        } else if (map.specialAreas[i].type == SCHOOL_AREA) {
            Polygon school;
            school.num = 4;
            school.point = (PointF *) malloc(school.num * sizeof(PointF));
            school.point[0] = map.specialAreas[i].area[0];
            school.point[1] = map.specialAreas[i].area[1];
            school.point[2] = map.specialAreas[i].leftPoints[1];
            school.point[3] = map.specialAreas[i].leftPoints[0];
            if (IntersectionOf(car->carXY[ car->axial[AXIAL_FRONT] ], &school) == GM_Containment) {
                if (ConvertMs2KMh(speed) > PASS_SCHOOL_MAX_SPEED) {
                    if (!map.specialAreas[i].overSpeed) {
                        DEBUG("通过学校区域超速");
                        AddExamFault(49, rtkTime);
                        map.specialAreas[i].overSpeed = true;
                    }
                }
            }
            free(school.point);
        }
    }
}
#if 0
typedef struct {
lib/src/main/cpp/test_items2/road_exam.h
@@ -30,9 +30,6 @@
void InitRoadExam(road_exam_map &RoadMap);
void TerminateRoadExam(void);
void TestRoadGeneral(road_exam_map &RoadMap, const car_model *car, LIST_CAR_MODEL &CarModelList, double speed, int moveDirect, const struct RtkTime *rtkTime);
void TestRoadGeneral(LIST_ROAD_MAP &RoadMapList, const car_model *car, LIST_CAR_MODEL &CarModelList, double speed, int moveDirect, const struct RtkTime *rtkTime);
bool ExitSonArea(int index, LIST_ROAD_MAP &RoadMapList, const car_model *car);
bool CrashSonRedLine(int index, LIST_ROAD_MAP &RoadMapList, const car_model *car, LIST_CAR_MODEL &CarModelList);
bool CrashTheLine(Line line, const car_model *car, LIST_CAR_MODEL &CarModelList);
PointF GetSELine(std::vector<edge_t> &edge, PointF point);
lib/src/main/cpp/test_items2/through_something.cpp
@@ -15,6 +15,7 @@
#define DEBUG(fmt, args...)     LOGD("<through_something> <%s>: " fmt, __func__, ##args)
#if 0
using namespace std;
static const double LASTEST_BREAK_POINT = 30.0;
@@ -26,7 +27,7 @@
static int stopActive;
static bool crashRedLine;
static map<int, bool> breakRecord;              // 记录车辆驶过各个停止线前刹车动作
void StartThroughExam(int index, LIST_ROAD_MAP &RoadMapList)
{
@@ -155,101 +156,7 @@
    return index;
}
#endif
void CheckBreakActive(road_exam_map &map, const car_model *car, LIST_CAR_MODEL &CarModelList)
{
    int BreakDone = ReadCarStatus(BREAK);
    // 计算车前进轨迹延长线
    double yaw = YawOf(car->carXY[ car->axial[AXIAL_FRONT] ], car->carXY[ car->axial[AXIAL_REAR] ]);
    PointF extPoint = PointExtend(car->carXY[ car->axial[AXIAL_FRONT] ], LASTEST_BREAK_POINT, yaw);
    PointF extPoint2 = PointExtend(car->carXY[ car->axial[AXIAL_FRONT] ], NEXT_ROAD_TIP, yaw);
    Line extLine, extLine2;
    MakeLine(&extLine, &car->carXY[ car->axial[AXIAL_FRONT] ], &extPoint);
    MakeLine(&extLine2, &car->carXY[ car->axial[AXIAL_FRONT] ], &extPoint2);
    // 路口刹车点
    for (int i = 0; i < map.roads.size(); ++i) {
        // 车头和路口距离不足30米
        if (IntersectionOf(extLine, map.roads[i].stopLine) == GM_Intersection &&
            IntersectionOfLine(car->carXY[ car->axial[AXIAL_FRONT] ], map.roads[i].stopLine) == 1 ) {
            DEBUG("进入减速区");
            if (BreakDone == BREAK_ACTIVE) {
                auto itx = breakRecord.find(map.roads[i].id);
                if (itx != breakRecord.end()) {
                    itx->second = true;
                }
            }
        }
        // 跨线后,检查刹车动作
        if (CrashTheLine(map.roads[i].stopLine, car, CarModelList)) {
            auto itx = breakRecord.find(map.roads[i].id);
            if (itx != breakRecord.end()) {
                if (itx->second == false) {
                    // 不按规定减速,不合格
                    DEBUG("不按规定减速");
                }
                itx->second = false;
            }
        }
    }
    // 人行道、公交站刹车点;学校限速区
    for (int i = 0; i < map.specialAreas.size(); i++) {
        if (map.specialAreas[i].type == GRID_AREA)
            continue;
        if (map.specialAreas[i].area.size() == 2 && map.specialAreas[i].leftPoints.size() != 2) {
            // 计算点到左侧路边线的垂点
            int road = 0;
            for (road = 0; road < map.roads.size(); ++road) {
                if (map.roads[road].id == map.specialAreas[i].road)
                    break;
            }
            PointF vPoint = GetSELine(map.roads[road].leftEdge, map.specialAreas[i].area[0]);
            DEBUG("计算垂点1 (%f, %f)", vPoint.X, vPoint.Y);
            map.specialAreas[i].leftPoints.push_back(vPoint);
            vPoint = GetSELine(map.roads[road].leftEdge, map.specialAreas[i].area[0]);
            DEBUG("计算垂点2 (%f, %f)", vPoint.X, vPoint.Y);
            map.specialAreas[i].leftPoints.push_back(vPoint);
        }
        if (map.specialAreas[i].type == ZEBRA_CROSSING || map.specialAreas[i].type == BUS_STATION_AREA) {
            Line startLine;
            MakeLine(&startLine, &map.specialAreas[i].area[0], &map.specialAreas[i].leftPoints[0]);
            // 车头和斑马线距离不足30米
            if (IntersectionOf(extLine, startLine) == GM_Intersection &&
                    IntersectionOfLine(car->carXY[ car->axial[AXIAL_FRONT] ], startLine) == 1 ) {
                DEBUG("进入减速区");
                if (BreakDone == BREAK_ACTIVE) {
                    auto itx = breakRecord.find(map.specialAreas[i].id);
                    if (itx != breakRecord.end()) {
                        itx->second = true;
                    }
                }
            }
            // 跨线后,检查刹车动作
            if (CrashTheLine(startLine, car, CarModelList)) {
                auto itx = breakRecord.find(map.specialAreas[i].id);
                if (itx != breakRecord.end()) {
                    if (itx->second == false) {
                        // 不按规定减速,不合格
                        DEBUG("不按规定减速");
                    }
                    itx->second = false;
                }
            }
        } else if (map.specialAreas[i].type == SCHOOL_AREA) {
        }
    }
}
lib/src/main/cpp/test_items2/through_something.h
@@ -6,11 +6,11 @@
#define MYAPPLICATION2_THROUGH_SOMETHING_H
#include "../driver_test.h"
/*
void StartThroughExam(int index, LIST_ROAD_MAP &RoadMapList);
void InitThroughSomething(road_exam_map &RoadMap);
void CheckBreakActive(road_exam_map &map, const car_model *car, LIST_CAR_MODEL &CarModelList);
int ExecuteThroughExam(int index, LIST_ROAD_MAP &RoadMapList, const car_model *car,
                       LIST_CAR_MODEL &CarModelList, double speed, int moveDirect, const struct RtkTime *rtkTime);
*/
#endif //MYAPPLICATION2_THROUGH_SOMETHING_H