yy1717
2020-08-20 2d6a9d02c77d7e08d4f18ee87d6e3d337b949f47
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
//
// 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 <cmath>
 
#define DEBUG(fmt, args...)     LOGD("<drive_straight> <%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;
}