| | |
| | | static double odoPrevSpeed; |
| | | static int odoCnt; |
| | | |
| | | typedef struct { |
| | | int road; |
| | | int sep; |
| | | int lane; |
| | | } lane_t; |
| | | |
| | | typedef struct { |
| | | int edgeIndex; |
| | | int pointIndex; |
| | | PointF point; |
| | | } projection_t; |
| | | |
| | | static const int MAX_ENGINE_RPM = 2500; |
| | | static const double START_CAR_MOVE_DISTANCE = 10.0; |
| | | static const double START_CAR_CHECK_DOOR_DISTANCE = 1.0; |
| | |
| | | static const uint32_t CHANGE_LANE_MIN_INTERVAL = D_SEC(10); |
| | | static const uint32_t CRASH_DOTTED_LINE_TIMEOUT = D_SEC(10); |
| | | static const uint32_t TURN_SIGNAL_LAMP_ADVANCE = D_SEC(3); |
| | | |
| | | |
| | | static const int CRL_NONE = 0; |
| | | static const int CRL_SEP_DOTTED = 1; |
| | |
| | | static bool AllCmp(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); |
| | | |
| | | static PointF CalcProjectionWithRoadEdge(vector<edge_t> &edge, PointF point); |
| | | static int CalcRoadIndex(int currRoadIndex, road_exam_map &RoadMap, const car_model *car); |
| | | |
| | | void InitRoadExam(road_exam_map &RoadMap) |
| | | { |
| | |
| | | |
| | | AppTimer_delete(TurnSignalError13ColdTimer); |
| | | AppTimer_delete(TurnSignalError14ColdTimer); |
| | | } |
| | | |
| | | /********************************************************************* |
| | | * 计算某点到道路边线的投影点 |
| | | * @param edge |
| | | * @param road |
| | | * @param point |
| | | * @return |
| | | */ |
| | | static PointF CalcProjectionWithRoadEdge(vector<edge_t> &edge, PointF point) |
| | | { |
| | | PointF p1, p2; |
| | | PointF proj; |
| | | |
| | | vector<PointF> projArray; |
| | | |
| | | Line line; |
| | | |
| | | // 计算垂点 |
| | | for (int i = 0; i < edge.size(); ++i) { |
| | | p1 = edge[i].points[0]; |
| | | for (int j = 1; j < edge[i].points.size(); ++j) { |
| | | p2 = edge[i].points[j]; |
| | | MakeLine(&line, &p1, &p2); |
| | | |
| | | PointF vp; |
| | | if (VerticalPointOnLine(point, line, vp)) { |
| | | projArray.push_back(vp); |
| | | } |
| | | |
| | | p1 = p2; |
| | | } |
| | | } |
| | | |
| | | if (projArray.size() == 0) { |
| | | // 没有任何垂点,找到最近的点 |
| | | proj = edge[0].points[0]; |
| | | for (int i = 0; i < edge.size(); ++i) { |
| | | for (int j = 1; j < edge[i].points.size(); ++j) { |
| | | if (DistanceOf(point, edge[i].points[j]) < DistanceOf(point, proj)) { |
| | | proj = edge[i].points[j]; |
| | | } |
| | | } |
| | | } |
| | | } else { |
| | | // 最近的垂点 |
| | | proj = projArray[0]; |
| | | for (int i = 1; i < projArray.size(); ++i) { |
| | | if (DistanceOf(point, projArray[i]) < DistanceOf(point, proj)) { |
| | | proj = projArray[i]; |
| | | } |
| | | } |
| | | } |
| | | |
| | | return proj; |
| | | } |
| | | |
| | | static projection_t CalcProjectionWithRoadEdgeEx(vector<edge_t> &edge, PointF point) |
| | | { |
| | | PointF p1, p2; |
| | | Line line; |
| | | projection_t theProj; |
| | | |
| | | vector<projection_t> projSet; |
| | | |
| | | // 计算垂点 |
| | | for (int i = 0; i < edge.size(); ++i) { |
| | | p1 = edge[i].points[0]; |
| | | for (int j = 1; j < edge[i].points.size(); ++j) { |
| | | p2 = edge[i].points[j]; |
| | | MakeLine(&line, &p1, &p2); |
| | | |
| | | PointF vp; |
| | | if (VerticalPointOnLine(point, line, vp)) { |
| | | projection_t proj; |
| | | proj.edgeIndex = i; |
| | | proj.pointIndex = j - 1; |
| | | proj.point = vp; |
| | | projSet.push_back(proj); |
| | | } |
| | | |
| | | p1 = p2; |
| | | } |
| | | } |
| | | |
| | | if (projSet.size() == 0) { |
| | | // 没有任何垂点,找到最近的点 |
| | | theProj.edgeIndex = 0; |
| | | theProj.pointIndex = 0; |
| | | theProj.point = edge[0].points[0]; |
| | | |
| | | for (int i = 0; i < edge.size(); ++i) { |
| | | for (int j = 1; j < edge[i].points.size(); ++j) { |
| | | if (DistanceOf(point, edge[i].points[j]) < DistanceOf(point, theProj.point)) { |
| | | theProj.edgeIndex = i; |
| | | theProj.pointIndex = j - 1; |
| | | theProj.point = edge[i].points[j]; |
| | | } |
| | | } |
| | | } |
| | | } else { |
| | | // 最近的垂点 |
| | | theProj = projSet[0]; |
| | | for (int i = 1; i < projSet.size(); ++i) { |
| | | if (DistanceOf(point, projSet[i].point) < DistanceOf(point, theProj.point)) { |
| | | theProj = projSet[i]; |
| | | } |
| | | } |
| | | } |
| | | |
| | | return theProj; |
| | | } |
| | | |
| | | static double CalcDistanceReference(PointF point, PointF refPoint, vector<edge_t> &edge) |
| | | { |
| | | double distance = 0; |
| | | |
| | | projection_t projection, refProjection; |
| | | |
| | | projection = CalcProjectionWithRoadEdgeEx(edge, point); |
| | | refProjection = CalcProjectionWithRoadEdgeEx(edge, refPoint); |
| | | |
| | | if (projection.edgeIndex != refProjection.edgeIndex || projection.pointIndex != refProjection.pointIndex) { |
| | | bool ahead = false; |
| | | if (projection.edgeIndex != refProjection.edgeIndex) { |
| | | if (projection.edgeIndex > refProjection.edgeIndex) { |
| | | projection_t temp; |
| | | temp = projection; |
| | | projection = refProjection; |
| | | refProjection = temp; |
| | | ahead = true; |
| | | } |
| | | int a = projection.edgeIndex; |
| | | int b = projection.pointIndex + 1; |
| | | |
| | | if (b < edge[a].points.size()) { |
| | | distance += DistanceOf(projection.point, edge[projection.edgeIndex].points[b]); |
| | | } |
| | | |
| | | for (; a < refProjection.edgeIndex; ++a) { |
| | | for (; b < edge[a].points.size() - 1; ++b) { |
| | | distance += DistanceOf(edge[a].points[b], edge[a].points[b+1]); |
| | | } |
| | | b = 0; |
| | | } |
| | | |
| | | for (int i = 0; i < refProjection.pointIndex; i++) { |
| | | distance += DistanceOf(edge[a].points[i], edge[a].points[i+1]); |
| | | } |
| | | |
| | | distance += DistanceOf(refProjection.point, edge[refProjection.edgeIndex].points[refProjection.pointIndex]); |
| | | } else { |
| | | if (projection.pointIndex > refProjection.pointIndex) { |
| | | projection_t temp; |
| | | temp = projection; |
| | | projection = refProjection; |
| | | refProjection = temp; |
| | | ahead = true; |
| | | } |
| | | int a = projection.edgeIndex; |
| | | int b = projection.pointIndex + 1; |
| | | |
| | | if (b < edge[a].points.size()) { |
| | | distance += DistanceOf(projection.point, edge[projection.edgeIndex].points[b]); |
| | | } |
| | | |
| | | for (; b < refProjection.pointIndex; b++) { |
| | | distance += DistanceOf(edge[a].points[b], edge[a].points[b+1]); |
| | | } |
| | | |
| | | distance += DistanceOf(refProjection.point, edge[refProjection.edgeIndex].points[refProjection.pointIndex]); |
| | | } |
| | | if (ahead) { |
| | | distance *= -1.0; |
| | | } |
| | | } else { |
| | | distance = DistanceOf(projection.point, refProjection.point); |
| | | |
| | | if (DistanceOf(projection.point, edge[projection.edgeIndex].points[projection.pointIndex]) > |
| | | DistanceOf(refProjection.point, edge[refProjection.edgeIndex].points[refProjection.pointIndex])) { |
| | | distance *= -1.0; |
| | | } |
| | | } |
| | | |
| | | return distance; |
| | | } |
| | | |
| | | /*************************************************************** |
| | | * 车辆所在道路,根据车辆的中轴前点 |
| | | * @param currRoadIndex |
| | | * @param RoadMap |
| | | * @param car |
| | | * @return |
| | | */ |
| | | static int CalcRoadIndex(int currRoadIndex, road_exam_map &RoadMap, const car_model *car) |
| | | { |
| | | int n = 0; |
| | | int index = currRoadIndex; |
| | | |
| | | if (index < 0) { |
| | | index = 0; |
| | | } |
| | | |
| | | while (n++ < RoadMap.roads.size()) { |
| | | bool changeSegment = false; |
| | | vector<PointF> roadOutLine; |
| | | Polygon area; |
| | | |
| | | for (int i = 0; i < RoadMap.roads[index].leftEdge.size(); ++i) { |
| | | for (int j = 0; j < RoadMap.roads[index].leftEdge[i].points.size(); ++j) { |
| | | if (changeSegment && roadOutLine.size() > 0 && IsSamePoint(roadOutLine.back(), RoadMap.roads[index].leftEdge[i].points[j])) { |
| | | continue; |
| | | } |
| | | changeSegment = false; |
| | | roadOutLine.push_back(RoadMap.roads[index].leftEdge[i].points[j]); |
| | | } |
| | | changeSegment = true; |
| | | } |
| | | |
| | | for (int i = 0; i < RoadMap.roads[index].rightEdge.size(); ++i) { |
| | | for (int j = RoadMap.roads[index].rightEdge[i].points.size() - 1; j >= 0; --j) { |
| | | if (changeSegment && roadOutLine.size() > 0 && IsSamePoint(roadOutLine.back(), RoadMap.roads[index].leftEdge[i].points[j])) { |
| | | continue; |
| | | } |
| | | changeSegment = false; |
| | | roadOutLine.push_back(RoadMap.roads[index].rightEdge[i].points[j]); |
| | | } |
| | | changeSegment = true; |
| | | } |
| | | |
| | | area.num = roadOutLine.size(); |
| | | area.point = (PointF *) malloc(area.num * sizeof(PointF)); |
| | | |
| | | for (int i = 0; i < area.num; ++i) { |
| | | area.point[i] = roadOutLine[i]; |
| | | } |
| | | |
| | | if (IntersectionOf(car->carXY[car->axial[AXIAL_FRONT]], &area) == GM_Containment) { |
| | | free(area.point); |
| | | break; |
| | | } |
| | | |
| | | free(area.point); |
| | | |
| | | index = (index + 1) % RoadMap.roads.size(); |
| | | } |
| | | |
| | | if (n >= RoadMap.roads.size()) { |
| | | index = -1; |
| | | } |
| | | |
| | | return index; |
| | | } |
| | | |
| | | /************************************************ |
| | | * 车轮压实线,前后轴交叉,前后轮迹交叉 |
| | | * @param mode |
| | | * @param RoadMap |
| | | * @param car |
| | | * @param CarModelList |
| | | * @return |
| | | */ |
| | | static bool CrashRedLine(int mode, int roadIndex, road_exam_map &RoadMap, const car_model *car, LIST_CAR_MODEL &CarModelList) |
| | | { |
| | | Line frontTireAxle, rearTireAxle; |
| | | Line frontLeftTireTrack, frontRightTireTrack; |
| | | Line rearLeftTireTrack, rearRightTireTrack; |
| | | bool track = false; |
| | | |
| | | MakeLine(&frontTireAxle, &car->carXY[car->left_front_tire[TIRE_OUTSIDE]], &car->carXY[car->right_front_tire[TIRE_OUTSIDE]]); |
| | | MakeLine(&rearTireAxle, &car->carXY[car->left_rear_tire[TIRE_OUTSIDE]], &car->carXY[car->right_rear_tire[TIRE_OUTSIDE]]); |
| | | |
| | | if (CarModelList.size() >= 2) { |
| | | list<car_model *>::iterator iter = CarModelList.begin(); |
| | | |
| | | PointF p11, p12, p21, p22, p31, p32, p41, p42; |
| | | |
| | | p11 = ((car_model *)(*iter))->carXY[((car_model *)(*iter))->left_front_tire[TIRE_OUTSIDE]]; |
| | | p21 = ((car_model *)(*iter))->carXY[((car_model *)(*iter))->right_front_tire[TIRE_OUTSIDE]]; |
| | | p31 = ((car_model *)(*iter))->carXY[((car_model *)(*iter))->left_rear_tire[TIRE_OUTSIDE]]; |
| | | p41 = ((car_model *)(*iter))->carXY[((car_model *)(*iter))->right_rear_tire[TIRE_OUTSIDE]]; |
| | | |
| | | struct RtkTime time1 = ((car_model *)(*iter))->tm; |
| | | |
| | | ++iter; |
| | | |
| | | p12 = ((car_model *)(*iter))->carXY[((car_model *)(*iter))->left_front_tire[TIRE_OUTSIDE]]; |
| | | p22 = ((car_model *)(*iter))->carXY[((car_model *)(*iter))->right_front_tire[TIRE_OUTSIDE]]; |
| | | p32 = ((car_model *)(*iter))->carXY[((car_model *)(*iter))->left_rear_tire[TIRE_OUTSIDE]]; |
| | | p42 = ((car_model *)(*iter))->carXY[((car_model *)(*iter))->right_rear_tire[TIRE_OUTSIDE]]; |
| | | |
| | | struct RtkTime time2 = ((car_model *)(*iter))->tm; |
| | | |
| | | if (TimeGetDiff(time1.hh, time1.mm, time1.ss, time1.mss, time2.hh, time2.mm, time2.ss, time2.mss) <= D_SEC(1)) { |
| | | MakeLine(&frontLeftTireTrack, &p11, &p12); |
| | | MakeLine(&frontRightTireTrack, &p21, &p22); |
| | | MakeLine(&rearLeftTireTrack, &p31, &p32); |
| | | MakeLine(&rearRightTireTrack, &p41, &p42); |
| | | track = true; |
| | | } |
| | | } |
| | | |
| | | PointF p1, p2; |
| | | Line redLine; |
| | | |
| | | for (int n = 0; n < RoadMap.roads.size(); ++n) { |
| | | for (int m = 0; m < RoadMap.roads[n].leftEdge.size(); ++m) { |
| | | if (RoadMap.roads[n].leftEdge[m].character == LINE_SOLID && RoadMap.roads[n].leftEdge[m].points.size() >= 2) { |
| | | p1 = RoadMap.roads[n].leftEdge[m].points[0]; |
| | | for (int l = 1; l < RoadMap.roads[n].leftEdge[m].points.size(); ++l) { |
| | | p2 = RoadMap.roads[n].leftEdge[m].points[l]; |
| | | |
| | | MakeLine(&redLine, &p1, &p2); |
| | | |
| | | if (IntersectionOf(redLine, frontTireAxle) == GM_Intersection || |
| | | IntersectionOf(redLine, rearTireAxle) == GM_Intersection) { |
| | | return true; |
| | | } |
| | | |
| | | if (track && |
| | | (IntersectionOf(redLine, frontLeftTireTrack) == GM_Intersection || |
| | | IntersectionOf(redLine, frontRightTireTrack) == GM_Intersection || |
| | | IntersectionOf(redLine, rearLeftTireTrack) == GM_Intersection || |
| | | IntersectionOf(redLine, rearRightTireTrack) == GM_Intersection)) { |
| | | return true; |
| | | } |
| | | p1 = p2; |
| | | } |
| | | } |
| | | } |
| | | |
| | | for (int m = 0; m < RoadMap.roads[n].rightEdge.size(); ++m) { |
| | | if (RoadMap.roads[n].rightEdge[m].character == LINE_SOLID && RoadMap.roads[n].rightEdge[m].points.size() >= 2) { |
| | | p1 = RoadMap.roads[n].rightEdge[m].points[0]; |
| | | for (int l = 1; l < RoadMap.roads[n].rightEdge[m].points.size(); ++l) { |
| | | p2 = RoadMap.roads[n].rightEdge[m].points[l]; |
| | | |
| | | MakeLine(&redLine, &p1, &p2); |
| | | |
| | | if (IntersectionOf(redLine, frontTireAxle) == GM_Intersection || |
| | | IntersectionOf(redLine, rearTireAxle) == GM_Intersection) { |
| | | return true; |
| | | } |
| | | |
| | | if (track && |
| | | (IntersectionOf(redLine, frontLeftTireTrack) == GM_Intersection || |
| | | IntersectionOf(redLine, frontRightTireTrack) == GM_Intersection || |
| | | IntersectionOf(redLine, rearLeftTireTrack) == GM_Intersection || |
| | | IntersectionOf(redLine, rearRightTireTrack) == GM_Intersection)) { |
| | | return true; |
| | | } |
| | | p1 = p2; |
| | | } |
| | | } |
| | | } |
| | | |
| | | for (int m = 0; m < RoadMap.roads[n].separate.size(); ++m) { |
| | | // 一组车道 |
| | | for (int l = 0; l < RoadMap.roads[n].separate[m].lines.size(); ++l) { |
| | | // 多根分道线 |
| | | for (int a = 0; a < RoadMap.roads[n].separate[m].lines[l].size(); ++a) { |
| | | // 一根分道线中线型相同的 |
| | | int character = RoadMap.roads[n].separate[m].lines[l][a].character; |
| | | |
| | | if (character == LINE_SOLID && RoadMap.roads[n].separate[m].lines[l][a].points.size() >= 2) { |
| | | p1 = RoadMap.roads[n].separate[m].lines[l][a].points[0]; |
| | | |
| | | for (int b = 1; b < RoadMap.roads[n].separate[m].lines[l][a].points.size(); ++b) { |
| | | p2 = RoadMap.roads[n].separate[m].lines[l][a].points[b]; |
| | | MakeLine(&redLine, &p1, &p2); |
| | | if (IntersectionOf(redLine, frontTireAxle) == GM_Intersection || |
| | | IntersectionOf(redLine, rearTireAxle) == GM_Intersection) { |
| | | return true; |
| | | } |
| | | if (track && |
| | | (IntersectionOf(redLine, frontLeftTireTrack) == GM_Intersection || |
| | | IntersectionOf(redLine, frontRightTireTrack) == GM_Intersection || |
| | | IntersectionOf(redLine, rearLeftTireTrack) == GM_Intersection || |
| | | IntersectionOf(redLine, rearRightTireTrack) == GM_Intersection)) { |
| | | return true; |
| | | } |
| | | p1 = p2; |
| | | } |
| | | } |
| | | // 比较最近的连续的n个左侧点和上一个右侧点 |
| | | if (character == LINE_HALF_SOLID_LEFT) { |
| | | // 不能从左移动到右 |
| | | |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | return false; |
| | | } |
| | | |
| | | /******************************************** |
| | | * 计算某点在哪个车道 |
| | | * @param point |
| | | * @param RoadMap |
| | | * @param roadIndex |
| | | * @return |
| | | */ |
| | | static bool GetLane(lane_t &theLane, PointF point, road_exam_map &RoadMap, int roadIndex) |
| | | { |
| | | Line leftProjLine, rightProjLine; |
| | | Line sep; |
| | | PointF p1, p2; |
| | | |
| | | if (roadIndex < 0 || roadIndex >= RoadMap.roads.size()) |
| | | return false; |
| | | |
| | | p1 = CalcProjectionWithRoadEdge(RoadMap.roads[roadIndex].leftEdge, point); |
| | | p2 = CalcProjectionWithRoadEdge(RoadMap.roads[roadIndex].rightEdge, point); |
| | | |
| | | MakeLine(&leftProjLine, &point, &p1); |
| | | MakeLine(&rightProjLine, &point, &p2); |
| | | |
| | | for (int i = 0; i < RoadMap.roads[roadIndex].separate.size(); ++i) { |
| | | struct car_lane_pos { |
| | | int lane_no; |
| | | char pos; // 点在车道的左右位置 |
| | | |
| | | bool operator == (const int &x) { |
| | | return(this->lane_no == x); |
| | | } |
| | | }; |
| | | |
| | | vector<struct car_lane_pos> CLP; |
| | | bool oneMoreIntersection = false; |
| | | |
| | | for (int j = 0; j < RoadMap.roads[roadIndex].separate[i].lines.size(); ++j) { // 每一根线分组 |
| | | bool intersection = false; |
| | | for (int k = 0; !intersection && k < RoadMap.roads[roadIndex].separate[i].lines[j].size(); ++k) { // 同一线型的线分组 |
| | | |
| | | p1 = RoadMap.roads[roadIndex].separate[i].lines[j][k].points[0]; |
| | | for (int m = 1; m < RoadMap.roads[roadIndex].separate[i].lines[j][k].points.size(); ++m) { |
| | | p2 = RoadMap.roads[roadIndex].separate[i].lines[j][k].points[m]; |
| | | MakeLine(&sep, &p1, &p2); |
| | | |
| | | if (IntersectionOf(sep, leftProjLine) == GM_Intersection) { |
| | | intersection = true; |
| | | struct car_lane_pos temp; |
| | | |
| | | temp.lane_no = j; |
| | | temp.pos = 'R'; |
| | | CLP.push_back(temp); |
| | | break; |
| | | } |
| | | if (IntersectionOf(sep, rightProjLine) == GM_Intersection) { |
| | | intersection = true; |
| | | struct car_lane_pos temp; |
| | | |
| | | temp.lane_no = j; |
| | | temp.pos = 'L'; |
| | | CLP.push_back(temp); |
| | | break; |
| | | } |
| | | p1 = p2; |
| | | } |
| | | } |
| | | if (!intersection) { |
| | | struct car_lane_pos temp; |
| | | temp.lane_no = j; |
| | | temp.pos = 0; |
| | | CLP.push_back(temp); |
| | | } else { |
| | | oneMoreIntersection = true; |
| | | } |
| | | } |
| | | |
| | | if (oneMoreIntersection) { |
| | | // 考虑到采集偏差可能每一根线无法对齐,只要其中一根相交,其它不相交的也参与 |
| | | for (vector<struct car_lane_pos>::iterator it = CLP.begin(); it != CLP.end(); ++it) { |
| | | if ((*it).pos == 0) { |
| | | int m = RoadMap.roads[roadIndex].separate[i].lines[(*it).lane_no].size(); |
| | | int n = RoadMap.roads[roadIndex].separate[i].lines[(*it).lane_no][m-1].points.size(); |
| | | |
| | | if (DistanceOf(RoadMap.roads[roadIndex].separate[i].lines[(*it).lane_no][0].points[0], point) > |
| | | DistanceOf(RoadMap.roads[roadIndex].separate[i].lines[(*it).lane_no][m-1].points[n-1], point)) { |
| | | // 车辆接近车道尾部 |
| | | MakeLine(&sep, &RoadMap.roads[roadIndex].separate[i].lines[(*it).lane_no][m-1].points[n-2], &RoadMap.roads[roadIndex].separate[i].lines[(*it).lane_no][m-1].points[n-1]); |
| | | } else { |
| | | // 车辆接近车道头部 |
| | | MakeLine(&sep, &RoadMap.roads[roadIndex].separate[i].lines[(*it).lane_no][0].points[0], &RoadMap.roads[roadIndex].separate[i].lines[(*it).lane_no][0].points[1]); |
| | | } |
| | | |
| | | struct car_lane_pos temp; |
| | | |
| | | temp.lane_no = (*it).lane_no; |
| | | |
| | | if (IntersectionOfLine(point, sep) == -1) { |
| | | temp.pos = 'R'; |
| | | } else { |
| | | temp.pos = 'L'; |
| | | } |
| | | (*it) = temp; |
| | | } |
| | | } |
| | | |
| | | theLane.road = roadIndex; |
| | | theLane.sep = i; |
| | | theLane.lane = CLP.size(); |
| | | |
| | | for (int x = 0; x < CLP.size(); ++x) { |
| | | if (CLP[x].pos == 'L') { |
| | | theLane.lane = x; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | return true; |
| | | } |
| | | } |
| | | |
| | | return false; |
| | | } |
| | | |
| | | static void TurnSignalError13ColdTimer(union sigval sig) |
| | |
| | | |
| | | void TestRoadGeneral(road_exam_map &RoadMap, const car_model *car, LIST_CAR_MODEL &CarModelList, double speed, int moveDirect, const struct RtkTime *rtkTime) |
| | | { |
| | | uint32_t cts = AppTimer_GetTickCount(); |
| | | int ri = CalcRoadIndex(-1, RoadMap, car); |
| | | bool crash = CrashRedLine(0, RoadMap, car, CarModelList); |
| | | lane_t laneInfo; |
| | | double redist = -1; |
| | | |
| | | laneInfo.road = -1; |
| | | laneInfo.sep = -1; |
| | | laneInfo.lane = -1; |
| | | |
| | | if (ri >= 0) { |
| | | GetLane(laneInfo, car->carXY[car->axial[AXIAL_FRONT]], RoadMap, ri); |
| | | |
| | | int m = RoadMap.roads[ri].rightEdge.size(); |
| | | int n = RoadMap.roads[ri].rightEdge[m-1].points.size(); |
| | | |
| | | PointF base; |
| | | |
| | | base.X = 428922.2985; base.Y = 3292119.5457; |
| | | |
| | | redist = CalcDistanceReference(car->carXY[car->axial[AXIAL_FRONT]], base, |
| | | RoadMap.roads[ri].rightEdge); |
| | | } |
| | | |
| | | DEBUG("当前道路索引 %d, 触发红线 %d lane %d 距离 %f %ld", ri, crash, laneInfo.lane, redist, AppTimer_GetTickCount() - cts); |
| | | |
| | | // 行驶距离,不包含倒车 |
| | | if (odoCnt == 0 && moveDirect == 1) { |
| | | odoPrevSpeed = speed; |
| | |
| | | return false; |
| | | } |
| | | |
| | | /********************************************************************* |
| | | * 计算某点到道路左边线的最近垂点 |
| | | * @param edge |
| | | * @param road |
| | | * @param point |
| | | * @return |
| | | */ |
| | | PointF GetSELine(vector<edge_t> &edge, PointF point) |
| | | { |
| | | PointF p1, p2; |
| | | PointF px; |
| | | |
| | | vector<PointF> vps; |
| | | |
| | | Line line; |
| | | |
| | | for (int i = 0; i < edge.size(); ++i) { |
| | | p1 = edge[i].points[0]; |
| | | for (int j = 1; j < edge[i].points.size(); ++j) { |
| | | p2 = edge[i].points[j]; |
| | | MakeLine(&line, &p1, &p2); |
| | | |
| | | PointF vp; |
| | | if (VerticalPointOnLine(point, line, vp)) { |
| | | vps.push_back(vp); |
| | | } |
| | | |
| | | p1 = p2; |
| | | } |
| | | } |
| | | |
| | | if (vps.size() == 0) { |
| | | if (DistanceOf(point, edge[0].points[0]) < DistanceOf(point, edge[edge.size() - 1].points[edge[edge.size() - 1].points.size() - 1])) { |
| | | px = GetVerticalPoint(edge[0].points[0], edge[0].points[1], point); |
| | | } else { |
| | | px = GetVerticalPoint(edge[edge.size() - 1].points[edge[edge.size() - 1].points.size() - 2], edge[edge.size() - 1].points[edge[edge.size() - 1].points.size() - 1], point); |
| | | } |
| | | } else if (vps.size() == 1) { |
| | | px = vps[0]; |
| | | } else { |
| | | px = vps[0]; |
| | | for (int i = 1; i < vps.size(); ++i) { |
| | | if (DistanceOf(point, vps[i]) < DistanceOf(point, px)) { |
| | | px = vps[i]; |
| | | } |
| | | } |
| | | } |
| | | |
| | | return px; |
| | | } |
| | | |
| | | /*************************************************** |
| | | * 接近路口时,提示下一步怎么走 |
| | |
| | | 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])); |
| | | RoadMap.triggerLines[i].leftPoints.push_back(CalcProjectionWithRoadEdge(RoadMap.roads[index].leftEdge, RoadMap.triggerLines[i].points[j])); |
| | | } |
| | | |
| | | for (int j = 0; j < RoadMap.triggerLines[i].points.size(); ++j) { |
| | |
| | | break; |
| | | } |
| | | |
| | | PointF vPoint = GetSELine(map.roads[road].leftEdge, map.specialAreas[i].area[0]); |
| | | PointF vPoint = CalcProjectionWithRoadEdge(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[1]); |
| | | vPoint = CalcProjectionWithRoadEdge(map.roads[road].leftEdge, map.specialAreas[i].area[1]); |
| | | // DEBUG("计算垂点2 (%f, %f)", vPoint.X, vPoint.Y); |
| | | map.specialAreas[i].leftPoints.push_back(vPoint); |
| | | } |