//
|
// Created by YY on 2020/3/24.
|
//
|
|
#include "stop_car.h"
|
#include "../driver_test.h"
|
#include "../native-lib.h"
|
#include "../jni_log.h"
|
#include "road_exam.h"
|
#include "../utils/xconvert.h"
|
#include "../common/apptimer.h"
|
#include "../test_common/car_sensor.h"
|
#include "../defs.h"
|
|
#define DEBUG(fmt, args...) LOGD("<stop_car> <%s>: " fmt, __func__, ##args)
|
|
static bool inactiveBreakHandbreakTogether, notCloseEngine, inactiveHandBreakAfterOpenDoor, occurOpenDoor, doorNotClose, checkRoadDistance;
|
static int examTtsSeq = 0;
|
static int ttsPlayEnd;
|
static double moveDistance;
|
static double prevSpeed;
|
static struct drive_timer prevPointTime;
|
static int prevMoveDirect;
|
static uint32_t stopTimepoint = 0;
|
static uint32_t openDoorTimepoint;
|
|
const int ENGINE_MIN_ROTATE = 200;
|
|
static const uint32_t STOP_CAR_TIME = D_SEC(2);
|
static const uint32_t OPEN_DOOR_TIMEOUT = D_SEC(15);
|
static const double DISTANCE_TO_ROAD_EDGE_1 = 0.5;
|
static const double DISTANCE_TO_ROAD_EDGE_2 = 0.3;
|
|
static void PlayTTSTimeout(union sigval sig);
|
|
void StartStopCarExam(int index, LIST_ROAD_MAP &RoadMapList) {
|
if (index == -1)
|
return;
|
|
DEBUG("进入靠边停车地图 index = %d id = %d item = %d", index, RoadMapList[index].id, RoadMapList[index].type);
|
|
ttsPlayEnd = 0;
|
moveDistance = 0;
|
prevMoveDirect = 0;
|
inactiveBreakHandbreakTogether = false;
|
notCloseEngine = false;
|
inactiveHandBreakAfterOpenDoor = false;
|
occurOpenDoor = false;
|
doorNotClose = false;
|
checkRoadDistance = false;
|
|
if (!RoadMapList[index].tts.empty()) {
|
examTtsSeq = PlayTTS(RoadMapList[index].tts.c_str());
|
} else {
|
examTtsSeq = PlayTTS("请靠边停车");
|
}
|
|
AppTimer_delete(PlayTTSTimeout);
|
AppTimer_add(PlayTTSTimeout, D_SEC(8));
|
}
|
|
void StopCarTTSDone(int id)
|
{
|
DEBUG("StopCarTTSDone %d", id);
|
// 等语音播报完毕后计时
|
if (id == examTtsSeq) {
|
ttsPlayEnd = 1;
|
}
|
}
|
|
void TerminateStopCarExam(void)
|
{
|
AppTimer_delete(PlayTTSTimeout);
|
}
|
|
int ExecuteStopCarExam(int index, LIST_ROAD_MAP &RoadMapList, const car_model *car,
|
LIST_CAR_MODEL &CarModelList, double speed, int moveDirect, const struct RtkTime *rtkTime) {
|
if (ttsPlayEnd == 1) {
|
ttsPlayEnd = 2;
|
prevSpeed = speed;
|
Rtk2DriveTimer(prevPointTime, rtkTime);
|
}
|
|
if (ttsPlayEnd != 2)
|
return index;
|
|
uint32_t diff = TimeGetDiff(rtkTime->hh, rtkTime->mm, rtkTime->ss,
|
rtkTime->mss * 10,
|
prevPointTime.hour, prevPointTime.min,
|
prevPointTime.sec, prevPointTime.msec * 10);
|
|
moveDistance += (double)diff * (speed + prevSpeed) / 2;
|
prevSpeed = speed;
|
Rtk2DriveTimer(prevPointTime, rtkTime);
|
|
if (moveDistance > 150) {
|
// 150米内未停车,不合格
|
DEBUG("停车距离超标");
|
AddExamFault(33, rtkTime);
|
return -1;
|
}
|
|
if (moveDirect != prevMoveDirect) {
|
if (moveDirect == 0) {
|
stopTimepoint = TimeMakeComposite(rtkTime->hh, rtkTime->mm, rtkTime->ss, rtkTime->mss*10);
|
DEBUG("停车了 %d %d %d %d %d %d %d", rtkTime->YY, rtkTime->MM, rtkTime->DD, rtkTime->hh, rtkTime->mm, rtkTime->ss, rtkTime->mss);
|
}
|
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 && !checkRoadDistance) {
|
// 停车超2秒,开始判断
|
DEBUG("检测和路边的距离");
|
PointF pc;
|
|
checkRoadDistance = true;
|
|
pc.X = (car->carXY[car->right_front_tire[TIRE_OUTSIDE]].X + car->carXY[car->right_rear_tire[TIRE_OUTSIDE]].X) / 2;
|
pc.Y = (car->carXY[car->right_front_tire[TIRE_OUTSIDE]].Y + car->carXY[car->right_rear_tire[TIRE_OUTSIDE]].Y) / 2;
|
|
// 检测道路边缘线
|
for (int i = 0; i < RoadMapList[index].roadEdgeLineNum; ++i) {
|
PointF p1, p2, pv;
|
|
p1 = RoadMapList[index].roadEdgeLine[i].point[0];
|
for (int j = 1; j < RoadMapList[index].roadEdgeLine[i].num; ++j) {
|
p2 = RoadMapList[index].roadEdgeLine[i].point[j];
|
pv = GetVerticalPoint(p1, p2, pc);
|
|
if (isEqual2(pv.X, MIN(p1.X, p2.X)) || isEqual2(pv.X, MAX(p1.X, p2.X)) ||
|
(pv.X > MIN(p1.X, p2.X) && pv.X < MAX(p1.X, p2.X))) {
|
double dis2roadEdge = DistanceOf(pc, pv);
|
|
DEBUG("停车距路边距离 %f", dis2roadEdge);
|
|
if (dis2roadEdge > DISTANCE_TO_ROAD_EDGE_1) {
|
DEBUG("停车超出路边0.5米");
|
// 停车距离超过50厘米,不合格
|
AddExamFault(36, rtkTime);
|
} else if (dis2roadEdge > DISTANCE_TO_ROAD_EDGE_2) {
|
DEBUG("停车超出路边0.3米");
|
// 停车距离超过30厘米,扣10分
|
AddExamFault(37, rtkTime);
|
}
|
}
|
|
p1 = p2;
|
}
|
}
|
}
|
}
|
|
if (!inactiveBreakHandbreakTogether && ReadCarStatus(BREAK) == BREAK_INACTIVE && ReadCarStatus(HAND_BREAK) == BREAK_INACTIVE) {
|
// 拉手刹前,松脚刹,扣10分
|
DEBUG("拉手刹前,松脚刹");
|
AddExamFault(39, rtkTime);
|
inactiveBreakHandbreakTogether = true;
|
}
|
|
if (!notCloseEngine && ReadCarStatus(ENGINE_RPM) < ENGINE_MIN_ROTATE && ReadCarStatus(DOOR) == DOOR_OPEN) {
|
// 下车前,不熄火,扣5分
|
DEBUG("下车前,不熄火");
|
AddExamFault(40, rtkTime);
|
|
notCloseEngine = true;
|
}
|
|
if (!inactiveHandBreakAfterOpenDoor && ReadCarStatus(DOOR) == DOOR_OPEN && ReadCarStatus(HAND_BREAK) == BREAK_INACTIVE) {
|
// 开门前,未拉手刹, 扣10分
|
DEBUG("开门前,未拉手刹");
|
AddExamFault(38, rtkTime);
|
|
inactiveHandBreakAfterOpenDoor = true;
|
}
|
|
if (ReadCarStatus(DOOR) == DOOR_OPEN) {
|
if (!occurOpenDoor) {
|
occurOpenDoor = true;
|
openDoorTimepoint = TimeMakeComposite(rtkTime->hh, rtkTime->mm, rtkTime->ss, rtkTime->mss*10);
|
} else {
|
uint32_t tp = TimeMakeComposite(rtkTime->hh, rtkTime->mm, rtkTime->ss, rtkTime->mss*10);
|
|
if (!doorNotClose && tp - openDoorTimepoint >= OPEN_DOOR_TIMEOUT) {
|
// 开门时间超过15秒,不合格
|
DEBUG("开门时间超过15秒");
|
AddExamFault(35, rtkTime);
|
doorNotClose = true;
|
}
|
}
|
} else if (occurOpenDoor) {
|
return -1;
|
}
|
|
if (occurOpenDoor) {
|
uint32_t tp = TimeMakeComposite(rtkTime->hh, rtkTime->mm, rtkTime->ss, rtkTime->mss*10);
|
|
if (tp - openDoorTimepoint >= OPEN_DOOR_TIMEOUT + D_SEC(5)) {
|
return -1;
|
}
|
}
|
|
return index;
|
}
|
|
static void PlayTTSTimeout(union sigval sig)
|
{
|
AppTimer_delete(PlayTTSTimeout);
|
|
ttsPlayEnd = 1;
|
}
|