// // Created by YY on 2020/3/23. // #include "drive_straight.h" #include "../driver_test.h" #include "../native-lib.h" #include "../jni_log.h" #include "road_exam.h" #include "../master/comm_if.h" #include "../common/apptimer.h" #include #define DEBUG(fmt, args...) LOGD(" <%s>: " fmt, __func__, ##args) static const double CHECK_STAGE_DISTANCE = 100.0; static const double MAX_OFFSET_DISTANCE = 0.3; static int ttsPlayEnd; static bool crossStartLine; static bool reportOffsetOver; static double edgeDistance; static double distanceToStartSum; static int examTtsSeq; static double CalcDistance2Edge(road_t &road, const car_model *car); static void PlayTTSTimeout(union sigval sig); void StartDriveStraightExam(std::string tts) { DEBUG("开始直线行驶"); ttsPlayEnd = 0; if (!tts.empty()) { examTtsSeq = PlayTTS(tts.c_str(), NULL); } else { examTtsSeq = PlayTTS("请保持直线行驶", NULL); } distanceToStartSum = 0; reportOffsetOver = false; AppTimer_delete(PlayTTSTimeout); AppTimer_add(PlayTTSTimeout, D_SEC(5)); } int ExecuteDriveStraightExam(road_t &road, const car_model *car, const trigger_line_t *item, const struct RtkTime *rtkTime) { static PointF startPoint; double dis2roadEdge = 0; if (ttsPlayEnd == 1) { ttsPlayEnd = 2; startPoint = car->basePoint; edgeDistance = CalcDistance2Edge(road, car); // 基准边距 DEBUG("当前基准路边间距 %f", edgeDistance); } if (ttsPlayEnd != 2) return 1; double distanceToStart = DistanceOf(car->basePoint, startPoint); dis2roadEdge = CalcDistance2Edge(road, car); DEBUG("路边间距 %f --- %f", dis2roadEdge, edgeDistance); if (!reportOffsetOver && fabs(dis2roadEdge - edgeDistance) > MAX_OFFSET_DISTANCE) { DEBUG("直线偏移大于30厘米"); // 偏移大于30厘米,不合格 AddExamFault(30, rtkTime); reportOffsetOver = true; ////////////////////////////////////////////// // startPoint = car->basePoint; // edgeDistance = dis2roadEdge; // reportOffsetOver = false; } if (distanceToStart > CHECK_STAGE_DISTANCE) { DEBUG("复位边距偏移量"); startPoint = car->basePoint; edgeDistance = dis2roadEdge; reportOffsetOver = false; distanceToStartSum += distanceToStart; distanceToStart = 0; } if (distanceToStart + distanceToStartSum > 105) { DEBUG("离开直线行驶区域"); PlayTTS("直线行驶结束", NULL); return -1; } return 1; } void DriveStraightTTSDone(int id) { // 等语音播报完毕后计时 if (id == examTtsSeq) { DEBUG("StopCarTTSDone %d", id); ttsPlayEnd = 1; AppTimer_delete(PlayTTSTimeout); } } void TerminateDriveStraightExam(void) { AppTimer_delete(PlayTTSTimeout); } static void PlayTTSTimeout(union sigval sig) { AppTimer_delete(PlayTTSTimeout); ttsPlayEnd = 1; } static double CalcDistance2Edge(road_t &road, const car_model *car) { PointF vp; bool get_vp = false; double distance = 0; // 检测道路边缘线 for (int i = 0; i < road.leftEdge.size(); ++i) { PointF p1, p2; Line edge; p1 = road.leftEdge[i].points[0]; for (int j = 1; j < road.leftEdge[i].points.size(); ++j) { p2 = road.leftEdge[i].points[j]; MakeLine(&edge, &p1, &p2); if (VerticalPointOnLine(car->basePoint, edge, vp)) { get_vp = true; goto FIND_VP_END; } p1 = p2; } } FIND_VP_END: if (get_vp) { DEBUG("得到垂点 %d: %f, %f -- %f, %f", road.id, car->basePoint.X, car->basePoint.Y, vp.X, vp.Y); distance = DistanceOf(car->basePoint, vp); } else { // 没有找到匹配线端,按最小距离顶点计算 DEBUG("无垂点"); distance = 100; for (int i = 0; i < road.leftEdge.size(); ++i) { for (int j = 0; j < road.leftEdge[i].points.size(); ++j) { double x; if (distance > (x = DistanceOf(car->basePoint, road.leftEdge[i].points[j]))) { distance = x; } } } } return distance; }