IVA/app/HxTaskDispatch.cpp
2023-10-20 23:48:21 +08:00

471 lines
16 KiB
C++

#include "HxTaskDispatch.h"
#include "HxVideoDevice.h"
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonDocument>
/* 视频设备 */
VideoDevice adas_video_device, bsd_video_device[6], dsm_video_device;
TaskDispatch *dispatcher = new TaskDispatch();
/* 车辆状态: 1 直行; 2 左转弯; 3 右转弯; 4 倒车 */
static int vehicle_status = 0;
static int detect_channel = 0;
void TaskDispatch::initialization(void)
{
/* 算法模块初始化 */
#if USE_ALGORITHM
/* adas检测配置 */
strcpy(dispatcher->event_detect_config.szAdasDetectConfigPathName, "/opt/algmode/adas_detect.bin");
/* adas跟踪配置 */
strcpy(dispatcher->event_detect_config.szAdasTrackConfigPathName, "/opt/algmode/adas_track.bin");
/* bsd检测配置 */
strcpy(dispatcher->event_detect_config.szBsdDetectConfigPathName, "/opt/algmode/bsd_detect.bin");
// strcpy(dispatcher->event_detect_config.szRightBsdFrontDetectConfigPathName, "/opt/algmode/bsd_detect.bin");
/* dsm人脸检测配置 */
strcpy(dispatcher->event_detect_config.szDsmFaceDetectConfigPathName, "/opt/algmode/dsm_face_detect.bin");
/* dsm人脸特征点检测配置 */
strcpy(dispatcher->event_detect_config.szDsmFaceLandMarksDetectConfigPathName, "/opt/algmode/dsm_face_landmarks_detect.bin");
/* dsm人脸认证检测配置 */
strcpy(dispatcher->event_detect_config.szDsmFaceVerificationDetectConfigPathName, "/opt/algmode/dsm_face_verification_detect.bin");
/* dsm人眼认证检测配置 */
strcpy(dispatcher->event_detect_config.szDsmEyeLandMarksDetectConfigPathName, "/opt/algmode/dsm_eye_landmarks_detect.bin");
/* dsm人脸认证检测配置 */
strcpy(dispatcher->event_detect_config.szDsmSmokeConfPathName, "/opt/algmode/dsm_smoke_detect.bin");
strcpy(dispatcher->event_detect_config.szDsmCallConfPathName, "/opt/algmode/dsm_call_detect.bin");
strcpy(dispatcher->event_detect_config.szDsmFaceFeaturePathName, "/opt/algmode/dsm_face_feature.bin");
strcpy(dispatcher->event_detect_config.szDsmHeadPoseConfPathName, "/opt/algmode/data_68kp");
/* 输出调试信息 */
MvSetPrintf(false);
/* 目标跟踪事件检测初始化 */
auto result = MvObjectEventDetectInit(&dispatcher->event_detect_config, RIGHT_BSD_FRONT_DETECT_CHANNEL |
RIGHT_BSD_REAR_DETECT_CHANNEL |
LEFT_BSD_FRONT_DETECT_CHANNEL |
LEFT_BSD_REAR_DETECT_CHANNEL |
FRONT_BSD_DETECT_CHANNEL |
REAR_BSD_DETECT_CHANNEL |
DMS_DETECT_CHANNEL |
ADAS_DETECT_CHANNEL);
if (result != 0)
return;
#endif
/* ADAS 通道初始化 */
if ((DataBase::algorithm_type & 0x1) == 1)
{
adas_video_device.set(0, DataBase::adas_video_input_source);
}
/* BSD 通道初始化 */
if (((DataBase::algorithm_type >> 1) & 0x1) == 1)
{
/* BSD-前 */
bsd_video_device[0].set(6, DataBase::bsd_video_input_source[0], DataBase::get_bsd_warn_region(0));
/* BSD-后 */
bsd_video_device[1].set(7, DataBase::bsd_video_input_source[1], DataBase::get_bsd_warn_region(1));
/* BSD-左前 */
bsd_video_device[2].set(4, DataBase::bsd_video_input_source[2], DataBase::get_bsd_warn_region(2));
/* BSD-右前 */
bsd_video_device[3].set(1, DataBase::bsd_video_input_source[3], DataBase::get_bsd_warn_region(3));
/* BSD-左后 */
bsd_video_device[4].set(5, DataBase::bsd_video_input_source[4], DataBase::get_bsd_warn_region(4));
/* BSD-右后 */
bsd_video_device[5].set(3, DataBase::bsd_video_input_source[5], DataBase::get_bsd_warn_region(5));
}
/* DSM 通道初始化 */
if (((DataBase::algorithm_type >> 2) & 0x1) == 1)
{
dsm_video_device.set(2, DataBase::dsm_video_input_source);
}
dispatcher->start();
}
void TaskDispatch::listern(uint16_t port)
{
dispatcher->debug_tool = new HxSocketUtils(port);
connect(dispatcher->debug_tool, &HxSocketUtils::data_receive_event, dispatcher, &TaskDispatch::data_receive_event);
connect(dispatcher, &TaskDispatch::data_write_event, dispatcher->debug_tool, &HxSocketUtils::write);
}
void TaskDispatch::connect_to_host(QString address, int port)
{
dispatcher->platform = new HxSocketUtils(address, port);
connect(dispatcher->platform, &HxSocketUtils::data_receive_event, dispatcher, &TaskDispatch::data_receive_event);
connect(dispatcher, &TaskDispatch::data_write_event, dispatcher->platform, &HxSocketUtils::write);
}
void TaskDispatch::algorithm_alarm_event(int channel, int level, int event_type, int detect_type, int left, int top, int right, int bottom, int distance, int speed, QString base64_string, QString filepath)
{
QJsonObject root({{"type", 4}});
QJsonObject msgInfo({{"channel", channel},
{"level", level},
{"event_type", event_type},
{"detect_type", detect_type},
{"left", left},
{"top", top},
{"right", right},
{"bottom", bottom},
{"distance", distance},
{"speed", speed},
{"image", base64_string},
{"filepath", filepath}});
root.insert("msgInfo", msgInfo);
emit dispatcher->data_write_event(QJsonDocument(root).toJson(QJsonDocument::Compact));
// dispatcher->send_can_data(channel, pObjectTrackEventResult->nDangerLevel, pObjectTrackEventResult->objInfo[i].nDetectType);
}
CarInfoInput *TaskDispatch::get_car_info(void) { return &dispatcher->car_info; }
QString TaskDispatch::get_video_frame_data(int type, int channel, int id)
{
Q_UNUSED(channel);
switch (type)
{
case 0:
return adas_video_device.build_image(id);
case 1:
return bsd_video_device[channel].build_image(id);
case 2:
return dsm_video_device.build_image(id);
}
return "";
}
QString TaskDispatch::build_alarm_image(int type, int channel, int frame_id)
{
switch (type)
{
case 0:
return adas_video_device.build_image(frame_id);
case 1:
return bsd_video_device[channel].build_image(frame_id);
case 2:
return dsm_video_device.build_image(frame_id);
}
return "";
}
QString TaskDispatch::build_alarm_video(int type, int channel, int frame_id)
{
switch (type)
{
case 0:
return adas_video_device.build_video(frame_id);
case 1:
return bsd_video_device[channel].build_video(frame_id);
case 2:
return dsm_video_device.build_video(frame_id);
}
return "";
}
void TaskDispatch::update_heartbeat()
{
if (QDateTime::currentDateTime() > heartbeat_timestamp.addSecs(30))
{
heartbeat_timestamp = QDateTime::currentDateTime();
emit data_write_event(QJsonDocument(QJsonObject({{"type", 0}})).toJson(QJsonDocument::Compact));
}
}
void TaskDispatch::updata_vehiclue_status(QJsonObject object)
{
vehicle_status_update_time = QDateTime::currentDateTime();
car_info.fVelocity = object.value("speed").toDouble();
car_info.fAcceleration = object.value("acceleration").toDouble();
car_info.fDeceleration = object.value("deceleration").toDouble();
car_info.nBrake = object.value("brake").toInt();
car_info.nLLight = object.value("left_light").toInt();
car_info.nRLight = object.value("right_light").toInt();
car_info.fAlpha = object.value("steering_angle").toDouble();
car_info.fSteeingWheelAngle = object.value("seeing_wheel_angle").toDouble();
reversing_light = object.value("reversing_light").toInt();
}
void TaskDispatch::parsing_vehiclue_status(void)
{
if (dispatcher->vehicle_status_update_time.secsTo(QDateTime::currentDateTime()) >= 10)
car_info.fVelocity = 0;
if (car_info.fVelocity > 0)
{
auto _detect_channel = 0;
/* ADAS 通道初始化 */
if ((DataBase::algorithm_type & 0x1) == 1)
{
_detect_channel |= ADAS_DETECT_CHANNEL;
}
/* DSM 通道初始化 */
if (((DataBase::algorithm_type >> 2) & 0x1) == 1)
{
_detect_channel |= DMS_DETECT_CHANNEL;
}
/* BSD 类型 */
else if (((DataBase::algorithm_type >> 1) & 0x1) == 1)
{
auto status = 0;
/* 倒车 */
if (reversing_light == 1)
status = 4;
/* 左转弯 */
else if (car_info.nLLight == 1)
status = 2;
/* 右转弯 */
else if (car_info.nRLight == 1)
status = 3;
/* 无左右转弯,车辆直行 */
else
status = 1;
/* 车辆状态发生改变 */
if (status != 0 && vehicle_status != status)
{
qDebug() << "车辆状态发生改变 " << vehicle_status << " => " << status;
vehicle_status = status;
/* 禁止送帧 */
for (int i = 0; i < BSD_MAX_CHANNEL; i++)
bsd_video_device[i].set(false);
switch (status)
{
/* 直线行驶, 检测通道: A C D */
case 1:
/* 允许送帧 */
bsd_video_device[0].set(true);
bsd_video_device[2].set(true);
bsd_video_device[3].set(true);
/* 前侧, 左前, 右前 */
_detect_channel |= (FRONT_BSD_DETECT_CHANNEL | LEFT_BSD_FRONT_DETECT_CHANNEL | RIGHT_BSD_FRONT_DETECT_CHANNEL);
break;
/* 左转弯, 检测通道: C D E */
case 2:
/* 允许送帧 */
bsd_video_device[2].set(true);
bsd_video_device[3].set(true);
bsd_video_device[4].set(true);
/* 左前, 右前, 左后 */
_detect_channel |= (LEFT_BSD_FRONT_DETECT_CHANNEL | RIGHT_BSD_FRONT_DETECT_CHANNEL | LEFT_BSD_REAR_DETECT_CHANNEL);
break;
/* 右转弯, 检测通道: C D F */
case 3:
/* 允许送帧 */
bsd_video_device[2].set(true);
bsd_video_device[3].set(true);
bsd_video_device[5].set(true);
/* 左前, 右前, 右后 */
_detect_channel |= (LEFT_BSD_FRONT_DETECT_CHANNEL | RIGHT_BSD_FRONT_DETECT_CHANNEL | RIGHT_BSD_REAR_DETECT_CHANNEL);
break;
/* 倒车, 检测通道: B C D */
case 4:
/* 允许送帧 */
bsd_video_device[1].set(true);
bsd_video_device[2].set(true);
bsd_video_device[3].set(true);
/* 后侧, 左前, 左后 */
_detect_channel |= (REAR_BSD_DETECT_CHANNEL | LEFT_BSD_FRONT_DETECT_CHANNEL | RIGHT_BSD_FRONT_DETECT_CHANNEL);
break;
}
}
}
/* 确保状态改变后才调用该函数 */
if (detect_channel != _detect_channel)
{
detect_channel = _detect_channel;
#if USE_ALGORITHM
MvSetDetectChannel(detect_channel);
#endif
}
}
}
void TaskDispatch::run()
{
while (true)
{
QCoreApplication::processEvents();
/* 发送心跳数据 */
update_heartbeat();
/* 分析车辆行驶状态 */
parsing_vehiclue_status();
QThread::msleep(10);
}
}
void TaskDispatch::debug_tool_response_event(int type, std::initializer_list<QPair<QString, QJsonValue>> args)
{
QJsonObject root, msginfo;
for (std::initializer_list<QPair<QString, QJsonValue>>::const_iterator i = args.begin(); i != args.end(); ++i)
msginfo.insert(i->first, i->second);
root.insert("type", type);
root.insert("msgInfo", msginfo);
emit data_write_event(QJsonDocument(root).toJson(QJsonDocument::Compact));
}
void TaskDispatch::data_receive_event(QByteArray data)
{
int type = -1;
auto document = QJsonDocument::fromJson(data);
auto root = document.object();
if (root.contains("type"))
{
type = root.value("type").toInt();
}
auto msginfo = root.value("msgInfo").toObject();
switch (type)
{
/* heart */
case 0:
break;
/* 车辆状态 */
case 3:
updata_vehiclue_status(msginfo);
break;
/* 获取算法类型 */
case 0xF0:
debug_tool_response_event(type, {{"mode", DataBase::algorithm_type}});
break;
/* 设置算法类型 */
case 0xF1:
DataBase::algorithm_type = msginfo.value("mode").toInt();
debug_tool_response_event(type, {{"status", DataBase::save_setting()}});
break;
/* 获取ADAS视频输入源 */
case 0xF2:
debug_tool_response_event(type, {{"source", DataBase::adas_video_input_source}});
break;
/* 设置ADAS视频输入源 */
case 0xF3:
DataBase::adas_video_input_source = msginfo.value("source").toString();
debug_tool_response_event(type, {{"status", DataBase::save_setting()}});
break;
/* 抓拍 */
case 0xF4:
debug_tool_response_event(type, {{"data", adas_video_device.snap()}});
break;
/* 获取BSD视频输入源 */
case 0xF5:
debug_tool_response_event(type, {{"source", DataBase::bsd_video_input_source[msginfo.value("channel").toInt()]}});
break;
/* 设置BSD视频输入源 */
case 0xF6:
DataBase::bsd_video_input_source[msginfo.value("channel").toInt()] = msginfo.value("source").toString();
debug_tool_response_event(type, {{"status", DataBase::save_setting()}});
break;
/* 抓拍 */
case 0xF7:
debug_tool_response_event(type, {{"data", bsd_video_device[msginfo.value("channel").toInt()].snap()}});
break;
/* 获取Dsm视频输入源 */
case 0xF8:
debug_tool_response_event(type, {{"source", DataBase::dsm_video_input_source}});
break;
/* 设置Dsm视频输入源 */
case 0xF9:
DataBase::dsm_video_input_source = msginfo.value("source").toString();
debug_tool_response_event(type, {{"status", DataBase::save_setting()}});
break;
/* 抓拍 */
case 0xFA:
debug_tool_response_event(type, {{"data", dsm_video_device.snap()}});
break;
/* 获取BSD报警区域 */
case 0xFB:
debug_tool_response_event(type, {{"data", DataBase::bsd_warn_regions[msginfo.value("channel").toInt()]}});
break;
/* 设置BSD报警区域 */
case 0xFC:
DataBase::bsd_warn_regions[msginfo.value("channel").toInt()] = msginfo.value("data").toString();
debug_tool_response_event(type, {{"status", DataBase::save_setting()}});
break;
/* 获取设备编号及FTP信息 */
case 0xFD:
debug_tool_response_event(type, {{"device_id", DataBase::device_id},
{"ftp_address", DataBase::ftp_address},
{"ftp_username", DataBase::ftp_username},
{"ftp_password", DataBase::ftp_password}});
break;
/* 设置设备编号及FTP信息 */
case 0xFE:
DataBase::device_id = msginfo.value("device_id").toString();
DataBase::ftp_address = msginfo.value("ftp_address").toString();
DataBase::ftp_username = msginfo.value("ftp_username").toString();
DataBase::ftp_password = msginfo.value("ftp_password").toString();
debug_tool_response_event(type, {{"status", DataBase::save_setting()}});
break;
case 0xFFFF:
adas_video_device.test();
break;
}
}