//
|
// Created by YY on 2020/3/9.
|
//
|
|
#include <cstdlib>
|
#include "../common/apptimer.h"
|
#include "dummy_light.h"
|
#include "../native-lib.h"
|
#include "../jni_log.h"
|
#include "../test_common/car_sensor.h"
|
|
#define DEBUG(fmt, args...) LOGD("<road_exam dummy_light> <%s>: " fmt, __func__, ##args)
|
|
enum {
|
TTS_NOT_START,
|
TTS_DOING,
|
TTS_DONE,
|
WAIT_OPERATE,
|
CHECK_OPERATE
|
};
|
|
static struct RtkTime currRtkTime;
|
static struct dummy_light_exam *content;
|
static int contentNum;
|
|
static int checkCnt;
|
static bool turn_left_active, flash_beam_active;
|
|
static int examTtsSeq = 0;
|
static bool testing;
|
|
static void DummyLightCheckActive(union sigval sig);
|
static void ExamDummyLight(union sigval sig);
|
|
void StartDummyLightExam(struct dummy_light_exam *ptr, int num, const struct RtkTime* rtkTime)
|
{
|
DEBUG("StartDummyLightExam");
|
content = ptr;
|
contentNum = num;
|
|
if (content != NULL && num > 0) {
|
DEBUG("启动灯光");
|
currRtkTime = *rtkTime;
|
|
for (int i = 0; i < contentNum; ++i) {
|
content[i].itemStatus = TTS_NOT_START;
|
|
DEBUG("灯光项目 <%d> item %d, TTS %s", i, content[i].item, content[i].tts);
|
}
|
testing = true;
|
|
AppTimer_delete(DummyLightCheckActive);
|
AppTimer_delete(ExamDummyLight);
|
AppTimer_add(ExamDummyLight, D_SEC(2));
|
} else {
|
testing = false;
|
}
|
}
|
|
int ExecuteDummyLightExam(const struct RtkTime* rtkTime)
|
{
|
currRtkTime = *rtkTime;
|
return (testing)?1:2;
|
}
|
|
void DummyLightTTSDone(int id)
|
{
|
// 等语音播报完毕后计时
|
if (id == examTtsSeq && testing) {
|
|
for (int i = 0; i < contentNum; ++i) {
|
if (content[i].itemStatus == TTS_DOING) {
|
DEBUG("DummyLightTTSDone item %d", content[i].item);
|
content[i].itemStatus = TTS_DONE;
|
break;
|
}
|
}
|
|
AppTimer_add(ExamDummyLight, 100);
|
}
|
}
|
|
void TerminateDummyLightExam(void)
|
{
|
testing = false;
|
AppTimer_delete(DummyLightCheckActive);
|
AppTimer_delete(ExamDummyLight);
|
}
|
|
static void DummyLightCheckActive(union sigval sig)
|
{
|
int active = sig.sival_int;
|
AppTimer_delete(DummyLightCheckActive);
|
DEBUG("DummyLightCheckActive item = %d", active);
|
|
switch (active) {
|
case DRIVE_AT_NIGHT:
|
case TURN_ON_MAIN_BEAM_LAMP:
|
if (ReadCarStatus(MAIN_BEAM_LAMP) != MAIN_BEAM_LIGHT) {
|
AddExamFault(58, &currRtkTime);
|
}
|
break;
|
case TURN_ON_DIPPED_LAMP:
|
case BRIDGE_MEET_CAR:
|
case FOLLOW_CAR:
|
if (ReadCarStatus(DIPPED_BEAM_LAMP) != DIPPED_BEAM_LIGHT) {
|
AddExamFault(58, &currRtkTime);
|
}
|
break;
|
case DRIVE_IN_FOG:
|
if (ReadCarStatus(FOG_LAMP) != FOG_LIGHT) {
|
AddExamFault(58, &currRtkTime);
|
}
|
break;
|
case THROUGE_CROSSWALK:
|
case THROUGE_CURVE:
|
case THROUGE_CROSSROADS:
|
if (++checkCnt < 5) {
|
if (ReadCarStatus(FLASH_BEAM_LAMP) == FLASH_BEAM_LIGHT) {
|
flash_beam_active = true;
|
}
|
AppTimer_add(DummyLightCheckActive, D_SEC(1), active);
|
return;
|
} else {
|
if (!flash_beam_active) {
|
AddExamFault(58, &currRtkTime);
|
}
|
}
|
break;
|
case OVERTAKE:
|
if (++checkCnt < 5) {
|
if (!flash_beam_active) {
|
if (ReadCarStatus(TURN_SIGNAL_LAMP) == LEFT_TURN_LIGHT) {
|
turn_left_active = true;
|
}
|
}
|
if (turn_left_active) {
|
if (ReadCarStatus(FLASH_BEAM_LAMP) == FLASH_BEAM_LIGHT) {
|
flash_beam_active = true;
|
}
|
}
|
AppTimer_add(DummyLightCheckActive, D_SEC(1), OVERTAKE);
|
return;
|
} else {
|
if (!flash_beam_active || !turn_left_active) {
|
AddExamFault(58, &currRtkTime);
|
}
|
}
|
break;
|
case CAR_FAULT:
|
case PARK_CAR_TEMP:
|
if (ReadCarStatus(TURN_SIGNAL_LAMP) != HAZARD_LIGHTS) {
|
AddExamFault(58, &currRtkTime);
|
}
|
break;
|
default:
|
break;
|
}
|
|
for (int i = 0; i < contentNum; ++i) {
|
if (content[i].item == active) {
|
content[i].itemStatus = CHECK_OPERATE;
|
break;
|
}
|
}
|
|
AppTimer_add(ExamDummyLight, 500);
|
}
|
|
static void ExamDummyLight(union sigval sig)
|
{
|
int i = 0;
|
AppTimer_delete(ExamDummyLight);
|
|
for (; i < contentNum; ++i) {
|
switch (content[i].itemStatus) {
|
case TTS_NOT_START:
|
DEBUG("提示语言 %d: %s", content[i].item, content[i].tts);
|
content[i].itemStatus = TTS_DOING;
|
examTtsSeq = PlayTTS(content[i].tts, DummyLightTTSDone);
|
// 等待TTS播放完毕
|
return;
|
case TTS_DOING:
|
return;
|
case TTS_DONE:
|
content[i].itemStatus = WAIT_OPERATE;
|
|
AppTimer_delete(DummyLightCheckActive);
|
|
DEBUG("提示语言完毕 %d", content[i].item);
|
|
if (content[i].item == OVERTAKE) {
|
checkCnt = 0;
|
turn_left_active = flash_beam_active = false;
|
AppTimer_add(DummyLightCheckActive, D_SEC(1), content[i].item);
|
} else if (content[i].item == THROUGE_CROSSWALK || content[i].item == THROUGE_CURVE || content[i].item == THROUGE_CROSSROADS) {
|
checkCnt = 0;
|
flash_beam_active = false;
|
AppTimer_add(DummyLightCheckActive, D_SEC(1), content[i].item);
|
} else if (content[i].item >= 100)
|
AppTimer_add(DummyLightCheckActive, D_SEC(3), content[i].item);
|
else
|
AppTimer_add(DummyLightCheckActive, D_SEC(5), content[i].item);
|
return;
|
case WAIT_OPERATE:
|
return;
|
case CHECK_OPERATE:
|
default:
|
break;
|
}
|
}
|
|
if (i >= contentNum) {
|
testing = false;
|
}
|
}
|