|
|
@ -1,5 +1,14 @@ |
|
|
|
#include "a8k_opt_algo.hpp"
|
|
|
|
|
|
|
|
#include <stdarg.h>
|
|
|
|
|
|
|
|
void zos_log(const char* fmt, ...); |
|
|
|
|
|
|
|
#define ZLOGI(fmt, ...) zos_log("INFO " fmt "\n", ##__VA_ARGS__);
|
|
|
|
#define ZLOGD(fmt, ...) zos_log("DEBU " fmt "\n", ##__VA_ARGS__);
|
|
|
|
#define ZLOGE(fmt, ...) zos_log("ERRO " fmt "\n", ##__VA_ARGS__);
|
|
|
|
#define ZLOGW(fmt, ...) zos_log("WARN " fmt "\n", ##__VA_ARGS__);
|
|
|
|
|
|
|
|
namespace a8k_opt_algo { |
|
|
|
using namespace std; |
|
|
|
|
|
|
@ -8,18 +17,9 @@ typedef enum { |
|
|
|
kfopt, |
|
|
|
} opt_type_t; |
|
|
|
|
|
|
|
class PorcessContext { |
|
|
|
public: |
|
|
|
vector<float> raw; //
|
|
|
|
vector<float> avg; //
|
|
|
|
vector<float> diff; // 一阶斜率
|
|
|
|
vector<float> diffX2; // 二阶斜率
|
|
|
|
float agvline; //
|
|
|
|
}; |
|
|
|
|
|
|
|
static void algo_assert(bool condition, const char* msg) { |
|
|
|
if (!condition) { |
|
|
|
printf("algo_assert:%s\n", msg); |
|
|
|
ZLOGE("algo_assert:%s\n", msg); |
|
|
|
throw std::runtime_error(msg); |
|
|
|
} |
|
|
|
} |
|
|
@ -253,9 +253,16 @@ float computePeakArea(vector<float>& data, int32_t start, int32_t end) { |
|
|
|
|
|
|
|
void findpeak(vector<float>& data, int32_t search_start, int32_t search_end, PeakInfo& retpeak) { |
|
|
|
// find peak
|
|
|
|
ZLOGI("find peak in [%d %d]", search_start, search_end); |
|
|
|
retpeak.find_peak = false; |
|
|
|
retpeak.area = 0; |
|
|
|
retpeak.peak_pos = 0; |
|
|
|
retpeak.peak_start_pos = 0; |
|
|
|
retpeak.peak_end_pos = 0; |
|
|
|
|
|
|
|
float max = 0; |
|
|
|
int peakpos = 0; |
|
|
|
float midpos = (search_end - search_start) / 2; |
|
|
|
float midpos = search_start + (search_end - search_start) / 2; |
|
|
|
for (int i = search_start; i < search_end; i++) { |
|
|
|
if (data[i] > max) { |
|
|
|
max = data[i]; |
|
|
@ -264,12 +271,15 @@ void findpeak(vector<float>& data, int32_t search_start, int32_t search_end, Pea |
|
|
|
} |
|
|
|
|
|
|
|
if (max < m_cxt.agvline) { |
|
|
|
ZLOGI("invalid peak:%f, max < m_cxt.agvline:%f", max, m_cxt.agvline); |
|
|
|
retpeak.find_peak = false; |
|
|
|
return; |
|
|
|
} else if (peakpos > midpos + 10) { |
|
|
|
} else if (peakpos > midpos + 15) { |
|
|
|
ZLOGI("invalid peak:%d, peakpos > midpos + 15:%d", peakpos, midpos + 15); |
|
|
|
retpeak.find_peak = false; |
|
|
|
return; |
|
|
|
} else if (peakpos < midpos - 10) { |
|
|
|
} else if (peakpos < midpos - 15) { |
|
|
|
ZLOGI("invalid peak:%d, peakpos < midpos - 15:%d", peakpos, midpos - 15); |
|
|
|
retpeak.find_peak = false; |
|
|
|
return; |
|
|
|
} |
|
|
@ -277,9 +287,10 @@ void findpeak(vector<float>& data, int32_t search_start, int32_t search_end, Pea |
|
|
|
// find_peak_start
|
|
|
|
// 从pos向前找20个点,从低于均值线的坐标开始找,找到diff2的最大值
|
|
|
|
retpeak.peak_pos = peakpos; |
|
|
|
retpeak.peak_start_pos = findPeakTurnPoint(data, peakpos - 20, peakpos); |
|
|
|
retpeak.peak_end_pos = findPeakTurnPoint(data, peakpos, peakpos + 20); |
|
|
|
retpeak.peak_start_pos = findPeakTurnPoint(data, peakpos - 20, peakpos) - 4;//-4 是经验数值
|
|
|
|
retpeak.peak_end_pos = findPeakTurnPoint(data, peakpos, peakpos + 20) + 4;//+4 是经验数值
|
|
|
|
retpeak.area = computePeakArea(data, retpeak.peak_start_pos, retpeak.peak_end_pos); |
|
|
|
retpeak.find_peak = true; |
|
|
|
|
|
|
|
// find_peak_end
|
|
|
|
// 从pos向后找20个点,找到diff2的最大值
|
|
|
@ -287,15 +298,17 @@ void findpeak(vector<float>& data, int32_t search_start, int32_t search_end, Pea |
|
|
|
|
|
|
|
void a8k_opt_algo_process(vector<float>& ogigin_val, OptAlgoResult& result) { |
|
|
|
//
|
|
|
|
|
|
|
|
vector<float> super = super_sampling(ogigin_val, ogigin_val.size(), 5); |
|
|
|
vector<float> subsample = sub_sampling(ogigin_val, 24); |
|
|
|
vector<float> subsample = sub_sampling(super, 24); |
|
|
|
ZLOGI("subsample size:%d", subsample.size()); |
|
|
|
|
|
|
|
m_cxt.raw = subsample; |
|
|
|
m_cxt.avg = smooth_windows(subsample, 4); |
|
|
|
m_cxt.diff = least_square_method_differentiate(m_cxt.avg, 4); // 最小二乘法求曲线斜率集合
|
|
|
|
m_cxt.diffX2 = least_square_method_differentiate(m_cxt.diff, 4); // 最小二乘法求曲线二次斜率集合
|
|
|
|
m_cxt.avg = subsample; |
|
|
|
m_cxt.diff = least_square_method_differentiate(m_cxt.avg, 5); // 最小二乘法求曲线斜率集合
|
|
|
|
m_cxt.diffX2 = least_square_method_differentiate(m_cxt.diff, 5); // 最小二乘法求曲线二次斜率集合
|
|
|
|
m_cxt.agvline = find_avg_line(subsample); |
|
|
|
result.displayData = m_cxt.avg; |
|
|
|
|
|
|
|
// findPeak
|
|
|
|
|
|
|
|
for (size_t i = 0; i < 5; i++) { |
|
|
@ -307,10 +320,16 @@ void a8k_opt_algo_process(vector<float>& ogigin_val, OptAlgoResult& result) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void A8kOptAlgoProcess(vector<float> ogigin_val, OptAlgoResult& result) { //
|
|
|
|
ecode_t A8kOptAlgoProcess(vector<float> ogigin_val, OptAlgoResult& result) { //
|
|
|
|
if (ogigin_val.size() != 1200) { |
|
|
|
return kOptErr_pointNumError; |
|
|
|
} |
|
|
|
a8k_opt_algo_process(ogigin_val, result); |
|
|
|
return kOptErr_suc; |
|
|
|
} |
|
|
|
|
|
|
|
void A8kOptAlgoGetProcessContext(PorcessContext& context) { context = m_cxt; } |
|
|
|
|
|
|
|
/***********************************************************************************************************************
|
|
|
|
* T_A8kOptAlgoPreProcess * |
|
|
|
***********************************************************************************************************************/ |
|
|
@ -328,7 +347,11 @@ float t_detector_raw_gain_to_gain(int32_t gain) { |
|
|
|
return scan_gain; |
|
|
|
} |
|
|
|
|
|
|
|
void T_A8kOptAlgoPreProcess(vector<float> ogigin_val, int32_t now_scan_gain, int32_t expectResultRangeStart, int32_t expectResultRangeEnd, OptAlgoPreProcessResult& result) { |
|
|
|
ecode_t T_A8kOptAlgoPreProcess(vector<float> ogigin_val, int32_t now_scan_gain, int32_t expectResultRangeStart, int32_t expectResultRangeEnd, OptAlgoPreProcessResult& result) { |
|
|
|
if (ogigin_val.size() != 1200) { |
|
|
|
return kOptErr_pointNumError; |
|
|
|
} |
|
|
|
|
|
|
|
int32_t adcgoal = expectResultRangeEnd; |
|
|
|
int32_t maxadc = ogigin_val[0]; |
|
|
|
|
|
|
@ -343,7 +366,7 @@ void T_A8kOptAlgoPreProcess(vector<float> ogigin_val, int32_t now_scan_gain, int |
|
|
|
|
|
|
|
if (maxadc > expectResultRangeStart) { |
|
|
|
result.scanAgain = false; |
|
|
|
return; |
|
|
|
return kOptErr_suc; |
|
|
|
} |
|
|
|
|
|
|
|
float nowgain = t_detector_raw_gain_to_gain(now_scan_gain); |
|
|
@ -355,9 +378,9 @@ void T_A8kOptAlgoPreProcess(vector<float> ogigin_val, int32_t now_scan_gain, int |
|
|
|
} |
|
|
|
result.suggestScanGain = t_detector_gain_to_raw_gain(gain_adjust); |
|
|
|
result.scanAgain = true; |
|
|
|
return kOptErr_suc; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/***********************************************************************************************************************
|
|
|
|
* F_A8kOptAlgoPreProcess * |
|
|
|
***********************************************************************************************************************/ |
|
|
@ -374,7 +397,11 @@ int32_t f_detector_gain_to_raw_gain(float scan_gain) { |
|
|
|
if (scan_gain_raw > 255) scan_gain_raw = 255; |
|
|
|
return scan_gain_raw; |
|
|
|
} |
|
|
|
void F_A8kOptAlgoPreProcess(vector<float> ogigin_val, int32_t now_scan_gain, int32_t expectResultRangeStart, int32_t expectResultRangeEnd, OptAlgoPreProcessResult& result) { |
|
|
|
ecode_t F_A8kOptAlgoPreProcess(vector<float> ogigin_val, int32_t now_scan_gain, int32_t expectResultRangeStart, int32_t expectResultRangeEnd, OptAlgoPreProcessResult& result) { |
|
|
|
if (ogigin_val.size() != 1200) { |
|
|
|
return kOptErr_pointNumError; |
|
|
|
} |
|
|
|
|
|
|
|
int32_t adcgoal = expectResultRangeEnd; |
|
|
|
int32_t maxadc = ogigin_val[0]; |
|
|
|
|
|
|
@ -389,7 +416,7 @@ void F_A8kOptAlgoPreProcess(vector<float> ogigin_val, int32_t now_scan_gain, int |
|
|
|
|
|
|
|
if (maxadc > expectResultRangeStart) { |
|
|
|
result.scanAgain = false; |
|
|
|
return; |
|
|
|
return kOptErr_suc; |
|
|
|
} |
|
|
|
|
|
|
|
float nowgain = f_detector_raw_gain_to_gain(now_scan_gain); |
|
|
@ -401,6 +428,7 @@ void F_A8kOptAlgoPreProcess(vector<float> ogigin_val, int32_t now_scan_gain, int |
|
|
|
} |
|
|
|
result.suggestScanGain = f_detector_gain_to_raw_gain(gain_adjust); |
|
|
|
result.scanAgain = true; |
|
|
|
return kOptErr_suc; |
|
|
|
} |
|
|
|
|
|
|
|
} // namespace a8k_opt_algo
|