from dunnan-400, complete base flow of scanning

This commit is contained in:
gb 2023-04-23 11:50:17 +08:00
parent 7fdeb2d0ee
commit 2fe046b857
94 changed files with 6910 additions and 1167 deletions

View File

@ -0,0 +1,75 @@
#include "CImageMerge.h"
CImageMerge::CImageMerge()
{
}
CImageMerge::~CImageMerge()
{
}
cv::Mat CImageMerge::MergeImage(cv::Mat &srcMat, int dstwidth, int dstheight)
{
cv::Mat retMat(dstheight, dstwidth, CV_8UC3);
if (!srcMat.empty())
{
std::vector<cv::Mat> ch_mats;
int blockcnt = 12;
int spitWidth = srcMat.cols / blockcnt;
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 3; j++)
{
std::cout << " index " << (i * 3 + j) << " x " << spitWidth * (i * 3 + j) << " y " << 0 << " width " << spitWidth << " height " << dstheight << std::endl;
ch_mats.push_back(srcMat(cv::Rect(spitWidth * (i * 3 + j), 0, spitWidth, dstheight)));
}
cv::merge(ch_mats, retMat(cv::Rect(spitWidth * i, 0, spitWidth, dstheight)));
ch_mats.clear();
}
return retMat;
}
}
cv::Mat CImageMerge::MergeImage(bool iscolor, cv::Mat &srcMat, int dstwidth, int dstheight,std::uint32_t fpga_vs)
{
int blockcnt = 12;
int spitWidth = srcMat.cols / blockcnt;
int abortwidth; // = spitWidth == 3888 ? 432 : (spitWidth == 2592 ? 216 : 144);
if (!iscolor) //灰度
{
abortwidth = spitWidth == 1296 ? 432 : (spitWidth == 648 ? 216 : 144);
}
else
{
abortwidth = spitWidth == 3888 ? 432 : (spitWidth == 1944 ? 216 : 144);
}
cv::Mat dst(dstheight, dstwidth - abortwidth * 2, CV_8UC(iscolor ? 3 : 1));
if (!iscolor)
{
for (int i = 0; i < 2; i++)
{
srcMat(cv::Rect((dstwidth / 2 + abortwidth) * i, 0, dstwidth / 2 - abortwidth, dstheight)).copyTo(dst(cv::Rect(dst.cols / 2 * i, 0, dst.cols / 2, dstheight)));
}
srcMat.release();
}
else
{
std::vector<cv::Mat> m_splits;
std::vector<int> m_index = {0, 3, 8, 11, 2, 5, 6, 9, 1, 4, 7, 10};
for (int i = 0; i < 3; i++)
{
int startindex = i == 0 ? 0 : (i == 1 ? 4 : 8);
cv::Mat t_mat(dstheight, dstwidth - abortwidth * 2, CV_8UC1);
srcMat(cv::Rect(spitWidth * m_index[startindex + 0], 0, spitWidth, dstheight)).copyTo(t_mat(cv::Rect(0, 0, spitWidth, dstheight)));
srcMat(cv::Rect(spitWidth * m_index[startindex + 1], 0, spitWidth - abortwidth, dstheight)).copyTo(t_mat(cv::Rect(spitWidth, 0, spitWidth - abortwidth, dstheight)));
srcMat(cv::Rect(spitWidth * m_index[startindex + 2] + abortwidth, 0, spitWidth - abortwidth, dstheight)).copyTo(t_mat(cv::Rect(spitWidth * 2 - abortwidth, 0, spitWidth - abortwidth, dstheight)));
srcMat(cv::Rect(spitWidth * m_index[startindex + 3], 0, spitWidth, dstheight)).copyTo(t_mat(cv::Rect(spitWidth * 3 - abortwidth * 2, 0, spitWidth, dstheight)));
m_splits.push_back(t_mat);
}
cv::merge(m_splits, dst);
m_splits.clear();
}
srcMat.release();
return dst;
}

View File

@ -0,0 +1,14 @@
#pragma once
#include <opencv2/opencv.hpp>
class CImageMerge
{
private:
/* data */
public:
CImageMerge(/* args */);
~CImageMerge();
public:
cv::Mat MergeImage(cv::Mat& srcMat,int dstwidth,int dstheight);
cv::Mat MergeImage(bool iscolor,cv::Mat& srcMat,int dstwidth,int dstheight,std::uint32_t fpga_vs);
};

View File

@ -0,0 +1,40 @@
#pragma once
#include <sstream>
#define LIGHT_DIFF(maxthre, x) ((maxthre)-x)
#define BLACK_DIFF(x) (8 - x)
#define FMT_STEP(x) \
do \
{ \
if (x < 1 && x > 0) \
{ \
x = 1; \
} \
if (step < 0 && step > -1) \
{ \
x = -1; \
} \
} while (0)
struct FPGAConfigParam
{
unsigned int ExposureF[3]; //RGB
unsigned int GainF[6]; //123456
unsigned int OffsetF[6]; //123456
unsigned int ExposureB[3]; //RGB
unsigned int GainB[6]; //123456
unsigned int OffsetB[6]; //123456
unsigned int DpiMode;
unsigned int ColorMode;
unsigned int MaxBright;
unsigned int MaxExp;
unsigned int Sp;
unsigned int HRatio;
unsigned int VRatio;
std::string LutPath;
std::string TextLutPath;
std::string Flat_BwPath;
std::string Flat_WhitePath;
};

View File

@ -14,6 +14,8 @@
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/types_c.h>
#include "filetools.h"
#include "CameraParam.h"
#include "correct_ultis.h"
using namespace std;
#define LOG_PATH "/usr/local/correct.log"
@ -22,65 +24,14 @@ FileTools ft(LOG_PATH);
static std::string loggername = "Capturer";
bool isAutoCorrect = true;
int offsetStep[12];
int expStep[2][3];
double radio = 1;
double Radio = 1;
cv::Mat mBuffMat;
cv::Mat out;
#define LIGHT_DIFF(maxthre, x) ((maxthre)-x)
#define BLACK_DIFF(x) (10 - x)
#define FMT_STEP(x) \
do \
{ \
if (x < 1 && x > 0) \
{ \
x = 1; \
} \
if (step < 0 && step > -1) \
{ \
x = -1; \
} \
} while (0)
void initStep()
{
for (int i = 0; i < 12; i++)
{
offsetStep[i] = 256;
}
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
expStep[i][j] = 1200;
}
}
}
//设置一面的offset值
void setOffset(int *config, int step)
{
for (int i = 0; i < 6; i++)
{
int *offset = config + i;
*offset += step;
if (*offset < 0)
*offset = 1;
if (*offset > 255)
*offset = 255;
}
}
Capturer::Capturer()
: vdd_cis_3voff_pin(new GpioOut(CIS_3v3_Off)),
vdd_vis_5ven_pin(new GpioOut(CIS_5v_En)),
reset_pin(new GpioOut(Fpga_Reset)),
image_in_transfer_pin(new Gpio(Image_In_Transfer)),
initDone_pin(new Gpio(Fpga_InitDone)),
fpgaLoad(new Gpio(70)),
fpga_conf_done(new Gpio(69)),//gpio init 导出 scanservice 仅操作IO
fpga_conf_initn(new Gpio(71)),//gpio init 导出 scanservice 仅操作IO
: reset_pin(new GpioOut(Fpga_Reset)),
initDone_pin(new Gpio(71)),
fpgaLoad(new GpioOut(70)),
bcorrecting(false)
{
LOG_INIT();
@ -94,12 +45,6 @@ Capturer::Capturer()
Capturer::~Capturer()
{
}
void Capturer::Fpga_regsAccess_reset(bool enable){
if(fpgaComm.get())
fpgaComm->regsAccess_reset(enable);
}
void Capturer::open()
@ -144,7 +89,7 @@ void Capturer::open()
}
static int val = 0;
static double exp_ratio = 0.1;
void Capturer::open(HGScanConfig config)
void Capturer::open(HGScanConfig config,FPGAConfigParam fpgaparam)
{
if (val > 4000)
val = 0;
@ -152,8 +97,7 @@ void Capturer::open(HGScanConfig config)
if (exp_ratio > 2.0)
exp_ratio = 0.1;
cisconfigs = getcisparams();
auto hgsize = papersMap[(PaperSize)config.g200params.paper];
int height = hgsize.height;
int height = 1632;
fpgaComm->setColorMode(config.g200params.color ? 1 : 0);
auto info = jsonconfig().getscannerinfo();
//set_sp(config.g200params.color ? cisconfigs.color.sp : cisconfigs.gray.sp); //0x03fa : 0x0bf0
@ -176,11 +120,10 @@ void Capturer::open(HGScanConfig config)
clrsp=info.color_sp;
graysp = info.gray_sp;
set_sp(config.g200params.color ? clrsp : graysp);
HG_LOG("\n capture color sp =%d, gray sp =%d",clrsp,graysp);
printf("\n capture color sp =%d, gray sp =%d",clrsp,graysp);
//set_sp(config.g200params.color ? 0x335 : 0x99f); //G100 0x438 0xca8 60 ppm 0x335 : 0x99f 100ppm
//G200 SP极限值205 0x27c 0x775 140ppm
//fpgaComm->setDpi(config.g200params.dpi); //0 300dpi 1 200dpi
fpgaComm->setDpi(1);
fpgaComm->setDpi(config.g200params.dpi); //0 300dpi 1 200dpi
fpgaComm->setSample(256);
fpgaComm->enableLed(true);
//设置曝光值等
@ -209,7 +152,6 @@ void Capturer::close()
{
video->close();
}
fpga_reload();
}
void Capturer::start()
{
@ -256,15 +198,15 @@ void Capturer::fpga_reset()
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
// void Capturer::fpga_reload()
// {
// //fpga 代码重载
// fpgaLoad->setValue(Gpio::Low);
// std::this_thread::sleep_for(std::chrono::milliseconds(15));
// fpgaLoad->setValue(Gpio::High);
// std::this_thread::sleep_for(std::chrono::milliseconds(15));
// fpgaComm->resetADC();
// }
void Capturer::fpga_reload()
{
//fpga 代码重载
fpgaLoad->setValue(Gpio::Low);
std::this_thread::sleep_for(std::chrono::milliseconds(15));
fpgaLoad->setValue(Gpio::High);
std::this_thread::sleep_for(std::chrono::milliseconds(15));
fpgaComm->resetADC();
}
void Capturer::set_expo(int ix, int val)
{
@ -358,11 +300,12 @@ void Capturer::configFPGAParam(bool iscorrect, int mode)
// val+=step;
// exp_ratio += 0.1;
// printf("\n\n\n----------------\n");
// for (int i = 0; i < 2; i++)
// {
// for (int j = 0; j < 6; j++)
// {
// offsets[i][j]=j==4?200:0;
// printf("gains[%d][%d] = %d \r\n", i, j, gains[i][j]);
// printf("offsets[%d][%d] = %d \r\n", i, j, offsets[i][j]);
// if (j < 3)
@ -472,7 +415,7 @@ void Capturer::autocorrect(int colormode)
m_captureCallback(4, colormode ? "------彩色校正完成------\r\n" : "------灰度校正完成------\r\n");
reset();
bcorrecting = false;
HG_LOG("init_autocorrect exit \n");
printf("init_autocorrect exit \n");
}
void Capturer::creatcorrectconfig(int mode)
@ -515,7 +458,7 @@ void Capturer::creatcorrectconfig(int mode)
ft.append_log(log);
std::this_thread::sleep_for(std::chrono::milliseconds(100));
fpgaComm->enableLed(true);
fpgaComm->update();
//fpgaComm->update();
std::this_thread::sleep_for(std::chrono::milliseconds(200));
fpgaComm->capture();
std::this_thread::sleep_for(std::chrono::milliseconds(500));
@ -567,7 +510,7 @@ bool Capturer::saveLutImg(int mode, int index)
void *data = video->read_frame(1500);
if (data == NULL)
{
log = "图像采集失败\r\n";
log = "图像采集失败!\r\n";
ft.append_log(log);
isNeedSave = false;
if (m_captureCallback)
@ -631,7 +574,7 @@ bool Capturer::saveLutImg(int mode, int index)
int diff = LIGHT_DIFF(scannerinfo.clr_maxbright, *((double *)values + k));
log += " 明场:" + std::to_string(k) + ";diff" + std::to_string(diff) + "\r\n";
double step = diff * radio;
double step = diff * Radio;
int preStep = *((int *)expStep + k);
if (step * preStep < 0)
{
@ -643,7 +586,7 @@ bool Capturer::saveLutImg(int mode, int index)
isOutBounds |= exposures[x] <= 0 && step < 0;
if (isOutBounds)
log += "" + to_string(x) + "个明场校正异常 \r\n";
else if (abs(diff) >= 2 || isMinStep)
else if (abs(diff) >= 1 || isMinStep)
{
*((int *)expStep + k) = (int)(step);
exposures[x] += step;
@ -677,7 +620,7 @@ bool Capturer::saveLutImg(int mode, int index)
{
int k = s * 6 + j;
double diff = BLACK_DIFF(offValues[k]);
double step = radio * diff;
double step = Radio * diff;
int preStep = offsetStep[k];
if (step * preStep < 0)
{
@ -685,7 +628,7 @@ bool Capturer::saveLutImg(int mode, int index)
}
else
{
radio = 1;
Radio = 1;
}
FMT_STEP(step);
bool isMinStep = abs(step) == 1 && step == offsetStep[k];
@ -787,7 +730,7 @@ bool Capturer::saveLutImg(int mode, int index)
{
int *exposures = (int *)(s == 0 ? cisconfigs.grayCorrect.expF : cisconfigs.grayCorrect.expB);
int diff = LIGHT_DIFF(scannerinfo.gray_maxbright, values[s]);
double step = diff * radio;
double step = diff * Radio;
log += " 明场:" + to_string(s) + ";diff" + to_string(diff) + "\r\n";
int preStep = expStep[s][0];
if (step * preStep < 0)
@ -796,7 +739,7 @@ bool Capturer::saveLutImg(int mode, int index)
}
else
{
radio = 1;
Radio = 1;
}
FMT_STEP(step);
@ -808,7 +751,7 @@ bool Capturer::saveLutImg(int mode, int index)
isOutBounds |= exp <= 0 && step < 0;
if (isOutBounds)
log += "" + to_string(s) + "个明场校正异常 \r\n";
else if (abs(diff) > 2 || isMinStep)
else if (abs(diff) > 1 || isMinStep)
{
exp += step;
if (exp < 0)
@ -843,7 +786,7 @@ bool Capturer::saveLutImg(int mode, int index)
{
int k = s * 6 + j;
double diff = BLACK_DIFF(offValues[k]);
double step = radio * diff;
double step = Radio * diff;
int preStep = offsetStep[k];
if (step * preStep < 0)
{
@ -851,7 +794,7 @@ bool Capturer::saveLutImg(int mode, int index)
}
else
{
radio = 1;
Radio = 1;
}
FMT_STEP(step);
bool isMinStep = abs(step) == 1 && step == offsetStep[k];
@ -892,25 +835,4 @@ bool Capturer::saveLutImg(int mode, int index)
}
}
return isNeedSave;
}
void Capturer::fpga_reload()
{
// fpga 代码重载
fpgaLoad->setValue(Gpio::Low);
std::this_thread::sleep_for(std::chrono::milliseconds(15));
fpga_conf_initn->setValue(Gpio::Low);
std::this_thread::sleep_for(std::chrono::milliseconds(15));
printf("\n fpga_conf_done value %d",fpga_conf_done->getValue());
fpgaLoad->setValue(Gpio::High);
std::this_thread::sleep_for(std::chrono::milliseconds(15));
fpga_conf_initn->setValue(Gpio::High);
//std::this_thread::sleep_for(std::chrono::milliseconds(5));
printf("\n fpga_conf_done value %d",fpga_conf_done->getValue());
// while(fpga_conf_done->getValue() == Gpio::GpioLevel::Low)
// std::this_thread::sleep_for(std::chrono::milliseconds(5));
std::this_thread::sleep_for(std::chrono::seconds(3));
printf("\n fpga_conf_done value %d",fpga_conf_done->getValue());
fpgaComm->resetADC();
fpgaComm->update();
}

View File

@ -1,58 +1,26 @@
#pragma once
#include <functional>
#include <thread>
#include <string>
#include "regsaccess.h"
#include "commondef.h"
#include <ICapturer.h>
#include "hgutils.h"
class FpgaComm;
class gVideo;
class Gpio;
class ICapturer
{
public:
virtual ~ICapturer() {}
virtual void open() = 0;
virtual void Fpga_regsAccess_reset(bool enable) = 0 ;
virtual void open(HGScanConfig config) = 0;
virtual void close() = 0;
virtual void start() = 0;
virtual void stop() = 0;
virtual bool is_runing() = 0;
virtual void snap() = 0;
virtual void set_size(int width, int height) = 0;
virtual void* readFrame(int timeout) = 0;
virtual void set_gain(int ix, int val) = 0;
virtual void set_offset(int ix, int val) = 0;
virtual void set_expo(int ix, int val) = 0;
virtual std::shared_ptr<IRegsAccess> regs() = 0;
virtual void reset() = 0;
virtual int width() = 0;
virtual int height() = 0;
virtual int color() = 0;
virtual void init_autocorrect(int colormode) = 0;
virtual void setcapturecall(std::function<void(int,std::string)> callback) = 0;
};
class Capturer : public ICapturer
{
public:
Capturer();
virtual ~Capturer();
virtual void Fpga_regsAccess_reset(bool enable);
virtual void open();
virtual void open(HGScanConfig config);
virtual void open(HGScanConfig config,FPGAConfigParam fpgaparam);
virtual void close();
virtual void start();
virtual void stop();
virtual bool is_runing();
virtual void snap();
virtual void stopsnap(){}
virtual int getautosizeheight(){return 0;}
virtual void set_size(int width, int height);
virtual void set_sp(int sp);
@ -89,8 +57,6 @@ private:
std::shared_ptr<Gpio> image_in_transfer_pin;
std::shared_ptr<Gpio> initDone_pin;
std::shared_ptr<Gpio> fpgaLoad;
std::shared_ptr<Gpio> fpga_conf_initn;
std::shared_ptr<Gpio> fpga_conf_done;
std::shared_ptr<FpgaComm> fpgaComm;
std::shared_ptr<gVideo> video;

View File

@ -0,0 +1,279 @@
#include "CorrectParam.h"
#include <iostream>
#include <fstream>
#include <sys/stat.h>
#include <sstream>
#include <iomanip>
#include "commondef.h"
using namespace std;
#define JSONPATH "/usr/local/huago/cameraparam.json"
#define TEXTLUT200COLORPATH "/usr/local/huago/Textlut200clr.bmp"
#define LUT200COLORPATH "/usr/local/huago/lut200clr.bmp"
#define LUT200_COLOR_BLACKPATH "/usr/local/huago/lut200clrbw.bmp"
#define LUT200_COLOR_WHITEPATH "/usr/local/huago/lut200clrwhite.bmp"
#define TEXTLUT200GRAYPATH "/usr/local/huago/Textlut200gray.bmp"
#define LUT200GRAYPATH "/usr/local/huago/lut200gray.bmp"
#define LUT200_GRAY_BLACKPATH "/usr/local/huago/lut200graybw.bmp"
#define LUT200_GRAY_WHITEPATH "/usr/local/huago/lut200graywhite.bmp"
#define TEXTLUT300COLORPATH "/usr/local/huago/Textlut300clr.bmp"
#define LUT300COLORPATH "/usr/local/huago/lut300clr.bmp"
#define LUT300_COLOR_BLACKPATH "/usr/local/huago/lut300clrbw.bmp"
#define LUT300_COLOR_WHITEPATH "/usr/local/huago/lut300clrwhite.bmp"
#define TEXTLUT300GRAYPATH "/usr/local/huago/Textlut300gray.bmp"
#define LUT300GRAYPATH "/usr/local/huago/lut300gray.bmp"
#define LUT300_GRAY_BLACKPATH "/usr/local/huago/lut300graybw.bmp"
#define LUT300_GRAY_WHITEPATH "/usr/local/huago/lut300graywhite.bmp"
#define LUT600COLORPATH "/usr/local/huago/lut600clr.bmp"
#define TEXTLUT600COLORPATH "/usr/local/huago/Textlut600clr.bmp"
#define LUT600_COLOR_BLACKPATH "/usr/local/huago/lut600clrbw.bmp"
#define LUT600_COLOR_WHITEPATH "/usr/local/huago/lut600clrwhite.bmp"
#define LUT600GRAYPATH "/usr/local/huago/lut600gray.bmp"
#define TEXTLUT600GRAYPATH "/usr/local/huago/Textlut600gray.bmp"
#define LUT600_GRAY_BLACKPATH "/usr/local/huago/lut600graybw.bmp"
#define LUT600_GRAY_WHITEPATH "/usr/local/huago/lut600graywhite.bmp"
CorrectParam::CorrectParam()
{
initdefaultpapram();
}
CorrectParam::~CorrectParam()
{
}
std::vector<FPGAConfigParam> CorrectParam::GetCorrectParams()
{
std::ifstream i(JSONPATH);
json j;
i >> j;
std::vector<FPGAConfigParam> vct_param;
for (json::iterator it = j.begin(); it != j.end(); ++it)
{
auto tmv = it.value();
FPGAConfigParam param;
from_json(tmv, param);
vct_param.push_back(param);
}
return vct_param;
}
FPGAConfigParam CorrectParam::GetFpgaparam(int dpi,int mode)
{
FPGAConfigParam param;
auto filejson = GetCorrectParams();
for (size_t i = 0; i < filejson.size(); i++)
{
if ((filejson[i].ColorMode == mode) &&
(filejson[i].DpiMode == dpi))
{
param = filejson[i];
break;
}
}
return param;
}
void CorrectParam::SaveCorrectParam(FPGAConfigParam& parms)
{
auto filejson = GetCorrectParams();
for (size_t i = 0; i < filejson.size(); i++)
{
if ((filejson[i].ColorMode == parms.ColorMode) &&
(filejson[i].DpiMode == parms.DpiMode))
{
memcpy(filejson[i].ExposureB, parms.ExposureB, sizeof(parms.ExposureB));
memcpy(filejson[i].ExposureF, parms.ExposureF, sizeof(parms.ExposureF));
memcpy(filejson[i].GainB, parms.GainB, sizeof(parms.GainB));
memcpy(filejson[i].GainF, parms.GainF, sizeof(parms.GainF));
memcpy(filejson[i].OffsetB, parms.OffsetB, sizeof(parms.OffsetB));
memcpy(filejson[i].OffsetF, parms.OffsetF, sizeof(parms.OffsetF));
filejson[i].LutPath = parms.LutPath;
filejson[i].TextLutPath = parms.TextLutPath;
filejson[i].Flat_BwPath = parms.Flat_BwPath;
filejson[i].Flat_WhitePath = parms.Flat_WhitePath;
filejson[i].Sp = parms.Sp;
filejson[i].HRatio = parms.HRatio;
filejson[i].VRatio = parms.VRatio;
break;
}
}
json j = json::array();
for (size_t i = 0; i < filejson.size(); i++)
{
json t_j;
to_json(t_j, filejson[i]);
j.push_back(t_j);
}
ofstream ofs(JSONPATH);
ofs << std::setw(4) << j << std::endl;
}
void CorrectParam::initdefaultpapram()
{
struct stat buff;
if (stat(JSONPATH, &buff) != 0)//存在
{
json js = json::array();
{
FPGAConfigParam param;
json t_j;
//彩色 300 dpi
param.ColorMode = 1;//彩色
param.DpiMode = 2;//300 dpi
#ifdef G200
param.MaxBright = 190;
#else
param.MaxBright = 200;
#endif
param.MaxExp = 1100;
param.HRatio = 1065353216;
param.VRatio = 1065353216;
param.LutPath = LUT300COLORPATH;
param.TextLutPath = TEXTLUT300COLORPATH;
param.Flat_BwPath = LUT300_COLOR_BLACKPATH;
param.Flat_WhitePath = LUT300_COLOR_WHITEPATH;
param.Sp = 1200;
for (size_t i = 0; i < 6; i++)
{
if(i<3)
param.ExposureB[i] = param.ExposureF[i] = 700;//1500
param.GainF[i] = param.GainB[i] = 170;
param.OffsetF[i] = param.OffsetB[i] = 125;
}
to_json(t_j, param);
js.push_back(t_j);
//灰度 300 dpi
param.ColorMode = 0;//灰度
param.MaxBright = 200;
param.LutPath = LUT300GRAYPATH;
param.TextLutPath = TEXTLUT300GRAYPATH;
param.Flat_BwPath = LUT300_GRAY_BLACKPATH;
param.Flat_WhitePath = LUT300_GRAY_WHITEPATH;
to_json(t_j, param);
js.push_back(t_j);
//彩色 200 dpi
#ifdef G200
param.MaxBright = 190;
#else
param.MaxBright = 200;
#endif
param.ColorMode = 1;//彩色
param.DpiMode = 1;//200 dpi
param.LutPath = LUT200COLORPATH;
param.TextLutPath = TEXTLUT200COLORPATH;
param.Flat_BwPath = LUT200_COLOR_BLACKPATH;
param.Flat_WhitePath = LUT200_COLOR_WHITEPATH;
for (size_t i = 0; i < 6; i++)
{
if(i<3)
param.ExposureB[i] = param.ExposureF[i] = 650;//1500
param.GainF[i] = param.GainB[i] = 170;
param.OffsetF[i] = param.OffsetB[i] = 125;
}
to_json(t_j, param);
js.push_back(t_j);
//灰度 200dpi
param.MaxBright = 200;
param.ColorMode = 0;//灰度
param.LutPath = LUT200GRAYPATH;
param.TextLutPath = TEXTLUT200GRAYPATH;
param.Flat_BwPath = LUT200_GRAY_BLACKPATH;
param.Flat_WhitePath = LUT200_GRAY_WHITEPATH;
to_json(t_j, param);
js.push_back(t_j);
//彩色 600 dpi
#ifdef G200
param.MaxBright = 190;
#else
param.MaxBright = 200;
#endif
param.ColorMode = 1;//彩色
param.DpiMode = 0x03;//200 dpi
param.LutPath = LUT600COLORPATH;
param.TextLutPath = TEXTLUT600COLORPATH;
param.Flat_BwPath = LUT600_COLOR_BLACKPATH;
param.Flat_WhitePath = LUT600_COLOR_WHITEPATH;
for (size_t i = 0; i < 6; i++)
{
if(i<3)
param.ExposureB[i] = param.ExposureF[i] = 1350;//1500
param.GainF[i] = param.GainB[i] = 170;
param.OffsetF[i] = param.OffsetB[i] = 125;
}
to_json(t_j, param);
js.push_back(t_j);
//灰度 600dpi
param.MaxBright = 200;
param.ColorMode = 0;//灰度
param.LutPath = LUT600GRAYPATH;
param.TextLutPath = TEXTLUT600GRAYPATH;
param.Flat_BwPath = LUT600_GRAY_BLACKPATH;
param.Flat_WhitePath = LUT600_GRAY_WHITEPATH;
to_json(t_j, param);
js.push_back(t_j);
std::ofstream ofs(JSONPATH);
ofs << std::setw(4) << js << std::endl;
}
}
}
void CorrectParam::to_json(json& j, FPGAConfigParam& param)
{
j = json{ {"ExposureF",param.ExposureF},
{"GainF",param.GainF},
{"OffsetF",param.OffsetF},
{"ExposureB",param.ExposureB},
{"GainB",param.GainB},
{"OffsetB",param.OffsetB},
{"DpiMode",param.DpiMode},
{"ColorMode",param.ColorMode},
{"MaxBright",param.MaxBright},
{"MaxExp",param.MaxExp},
{"Sp",param.Sp},
{"HRatio",param.HRatio},
{"VRatio",param.VRatio},
{"LutPath",param.LutPath},
{"TextLutPath",param.TextLutPath},
{"FlatBlackPath",param.Flat_BwPath},
{"FlatWhitePath",param.Flat_WhitePath}
};
}
void CorrectParam::from_json(json& j, FPGAConfigParam& param)
{
j.at("ExposureF").get_to(param.ExposureF);
j.at("GainF").get_to(param.GainF);
j.at("OffsetF").get_to(param.OffsetF);
j.at("ExposureB").get_to(param.ExposureB);
j.at("GainB").get_to(param.GainB);
j.at("OffsetB").get_to(param.OffsetB);
j.at("DpiMode").get_to(param.DpiMode);
j.at("ColorMode").get_to(param.ColorMode);
j.at("MaxBright").get_to(param.MaxBright);
j.at("MaxExp").get_to(param.MaxExp);
j.at("Sp").get_to(param.Sp);
j.at("HRatio").get_to(param.HRatio);
j.at("VRatio").get_to(param.VRatio);
j.at("LutPath").get_to(param.LutPath);
j.at("TextLutPath").get_to(param.TextLutPath);
j.at("FlatBlackPath").get_to(param.Flat_BwPath);
j.at("FlatWhitePath").get_to(param.Flat_WhitePath);
}

View File

@ -0,0 +1,21 @@
#pragma once
#include "json.hpp"
#include <vector>
#include <memory>
#include "CameraParam.h"
using json = nlohmann::json;
class CorrectParam
{
public:
CorrectParam(/* args */);
~CorrectParam();
FPGAConfigParam GetFpgaparam(int dpi,int mode);
void SaveCorrectParam(FPGAConfigParam& parms);
private:
void initdefaultpapram();
std::vector<FPGAConfigParam> GetCorrectParams();
void to_json(json& j, FPGAConfigParam& param);
void from_json(json& j, FPGAConfigParam& param);
};

View File

@ -17,13 +17,26 @@
FpgaComm::FpgaComm()
{
m_regsAccess.reset(new UartRegsAccess(FPGA_UART, 921600, 0x03, 0x83));
update();
m_regsAccess.reset(new UartRegsAccess(MOTOR_UART, 921600, 0x03, 0x83));
update(0);
Reg(AledR).sample = 256;
WR_Reg(AledR);
}
void FpgaComm::regsAccess_reset(bool enable){
if(enable)
{
if(!m_regsAccess.get())
m_regsAccess.reset(new UartRegsAccess(MOTOR_UART, 921600, 0x03, 0x83));
update(0);
return;
}
if(m_regsAccess.get())
m_regsAccess.reset();
}
bool FpgaComm::read(unsigned int addr, unsigned int& val) {
return m_regsAccess->read(addr, val);
}
@ -32,18 +45,6 @@ bool FpgaComm::write(unsigned int addr, unsigned int val) {
return m_regsAccess->write(addr, val);
}
void FpgaComm::regsAccess_reset(bool enable){
if(enable)
{
if(!m_regsAccess.get())
m_regsAccess.reset(new UartRegsAccess(FPGA_UART, 921600, 0x03, 0x83));
update();
return;
}
if(m_regsAccess.get())
m_regsAccess.reset();
}
void FpgaComm::setFrameHeight(int height){
Reg(frame).height = height;
WR_Reg(frame);
@ -66,7 +67,7 @@ void FpgaComm::enableLed(bool bEnable) {
Reg(BledR).ledEnable = bEnable;
WR_Reg(BledR);
#else
Reg(BledR).ledEnable = bEnable;
Reg(BledR).ledEnable = !bEnable;
WR_Reg(BledR);
#endif
}
@ -275,12 +276,13 @@ void FpgaComm::setDelayTime(int value) {
WR_Reg(DelayTime);
}
void FpgaComm::update()
void FpgaComm::update(int times)
{
for(int i = 0; i < MAX_REGS; i++)
std::uint32_t tmp_reg = 0;
for(int i = 0; i < 16; i++)
{
read(i, fpgaParams.regs[i]);
printf("reg[%d] = 0x%08x \n",i,fpgaParams.regs[i]);
read(i, tmp_reg);
printf("times[%d] reg[%d] = 0x%08x \n",times,i,tmp_reg);
}
}
@ -358,4 +360,31 @@ void FpgaComm::resetADC() {
WR_Reg(mode);
fpgaParams.mode.adcB = 0;
WR_Reg(mode);
}
void FpgaComm::setEnTestCol(bool en)
{
Reg(AledR).en_test_color = en?1:0;
WR_Reg(AledR);
}
void FpgaComm::setEnTestBit(bool en)
{
Reg(AledR).en_test = en?1:0;
WR_Reg(AledR);
}
void FpgaComm::setVsp(unsigned int Aside,unsigned int BSide)
{
unsigned int regv;
CISVSP vsp;
read(13,regv);
vsp.value = regv;
vsp.bits.ASide_VSP = Aside;
vsp.bits.BSide_VSP = BSide;
vsp.bits.reserved=0;
printf("setVsp A side =%d B side=%d vspint=%08x \n", vsp.bits.ASide_VSP, vsp.bits.BSide_VSP,vsp.value);
write(13,vsp.value);
WR_Reg(AledR);
}

View File

@ -6,7 +6,7 @@
#ifdef HAS_UV
#define MAX_REGS 0x0e
#else
#define MAX_REGS 0x0d
#define MAX_REGS 0x0e
#endif
typedef struct Frame_FPGA
@ -75,7 +75,9 @@ typedef struct CIS_LED_R
{
unsigned short int ledEnable : 1;
unsigned short int sample : 9;
unsigned short int reserved : 6;
unsigned short int en_test_color :1;
unsigned short int en_test : 1;
unsigned short int reserved : 4;
unsigned short int ledR;
} CisLedR;
@ -91,6 +93,8 @@ typedef struct CIS_LED_UV
unsigned short int ledBSide;
} CisLedUv;
typedef union Fpga_Params
{
struct
@ -118,6 +122,17 @@ typedef union Fpga_Params
} FpgaParams;
typedef union CIS_VSP
{
struct
{
unsigned int ASide_VSP:8;
unsigned int BSide_VSP:8;
unsigned int reserved : 16;
} bits;
int value;
} CISVSP;
class FpgaComm : public IRegsAccess
{
public:
@ -149,6 +164,9 @@ public:
void setBExposureB(int value);
void setBExpousreUV(int value);
void setEnTestCol(bool en);
void setEnTestBit(bool en);
void setSp(int value);
int getSp();
@ -168,9 +186,10 @@ public:
void setDelayTime(int value);
void setTrigMode(bool isArmMode);
void update();
void update(int times);
void enableJamCheck(bool b);
void resetADC();
void setVsp(unsigned int Aside,unsigned int BSide);
virtual bool write(unsigned int addr, unsigned int val);
virtual bool read(unsigned int addr, unsigned int& val);

View File

@ -0,0 +1,39 @@
#pragma once
#include <memory>
#include <functional>
#include <thread>
#include <string>
#include "regsaccess.h"
#include "commondef.h"
#include "CorrectParam.h"
class ICapturer
{
public:
virtual ~ICapturer() {}
virtual void open() = 0;
virtual void open(HGScanConfig config,FPGAConfigParam fpgaparam) = 0;
virtual void close() = 0;
virtual void start() = 0;
virtual void stop() = 0;
virtual bool is_runing() = 0;
virtual void snap() = 0;
virtual void stopsnap() = 0;
virtual int getautosizeheight() = 0;
virtual void set_size(int width, int height) = 0;
virtual void* readFrame(int timeout) = 0;
virtual void set_gain(int ix, int val) = 0;
virtual void set_offset(int ix, int val) = 0;
virtual void set_expo(int ix, int val) = 0;
virtual std::shared_ptr<IRegsAccess> regs() = 0;
virtual void reset() = 0;
virtual int width() = 0;
virtual int height() = 0;
virtual int color() = 0;
virtual void init_autocorrect(int colormode=0) = 0;
virtual void setcapturecall(std::function<void(int,std::string)> callback) = 0;
};

View File

@ -0,0 +1,924 @@
#include "MonoCapturer.h"
#include "config.h"
#include "applog.h"
#include "gvideoisp1.h"
#include "Gpio.h"
#include "DevUtil.h"
#include "FpgaComm.h"
#include "CorrectParam.h"
#include "correct_ultis.h"
#include "stringex.hpp"
#include "filetools.h"
#include "CImageMerge.h"
#include "commondef.h"
#include "hgutils.h"
#include "dailex.hpp"
#include "jsonconfig.h"
#include "ThreadPool.h"
using namespace std;
using namespace cv;
#define LOG_PATH "/usr/local/correct.log"
FileTools ft_log(LOG_PATH);
static std::string loggername = "MonoCapturer";
static double radio = 1.0;
static int offsetStep1[12];
static int expStep1[2][3];
void initStep1()
{
printf("initStep aaaaaaaaaaa \n");
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
expStep1[i][j] = 600;
}
}
for (int i = 0; i < 12; i++)
{
offsetStep1[i] = 256;
printf("offsetStep[%d]=%d \n",i,offsetStep1[i]);
}
}
MonoCapturer::MonoCapturer() : vdd_cis_3voff_pin(new GpioOut(CIS_3v3_Off)),
vdd_vis_5ven_pin(new GpioOut(CIS_5v_En)),
reset_pin(new GpioOut(50)),
image_in_transfer_pin(new Gpio(Image_In_Transfer)),
initDone_pin(new Gpio(Fpga_InitDone)),
fpgaLoad(new Gpio(70)),
fpga_conf_done(new Gpio(69)),//gpio init 导出 scanservice 仅操作IO
fpga_conf_initn(new Gpio(71)),//gpio init 导出 scanservice 仅操作IO
bcorrecting(false)
{
LOG_INIT();
fpga_conf_done->setDirection(Gpio::in);
fpgaComm.reset(new FpgaComm());
fpga_reset();
fpgaComm->resetADC();
fpgaComm->setDelayTime(0X3e8);
// fpgaComm->update();
video.reset(new VIDEO_CLASS());
// GetFpgaparam(0x01,0);
}
MonoCapturer::~MonoCapturer()
{
if (video.get())
video.reset();
printf("Exit ~MonoCapturer() \n");
}
void MonoCapturer::open()
{
}
void MonoCapturer::open(HGScanConfig config,FPGAConfigParam fpgaparam)
{
fpgaComm->update(1);
// reset_pin->setValue(Gpio::Low);
// std::this_thread::sleep_for(std::chrono::milliseconds(50));
// reset_pin->setValue(Gpio::High);
bool dunnancis = true;
int dpi;
if (dunnancis)
dpi = config.g200params.dpi == 0x02 ? 2 : (config.g200params.dpi == 0x03 ? 3 : 2);
else
dpi = config.g200params.dpi;
int mode = config.g200params.color;
int channelwidth = dpi == 0x02 ? 1296 : (dpi == 0x03 ? 2592 : 864);
int channels = mode == 0x01 ? 3 : 1;
int width = channelwidth * channels;
auto phyHeight = paperHeight[(PaperSize)config.g200params.paper];
int pixheight; // = ((int)((phyHeight / 25.4 * (dpi == 0x02 ? 300 : (dpi == 0x03 ? 600 : 200)) + 2) / 3)) * 3 * 2;
if (dunnancis)
{
int tdpi = config.g200params.dpi == 0x02 ? 300 : (config.g200params.dpi == 0x03 ? 600 : 200);
//int tdpi = config.g200params.dpi == 0x02 ? 285 : (config.g200params.dpi == 0x03 ? 570 : 190);
pixheight = ((int)((phyHeight / 25.4 * tdpi + 2) / 3)) * 3 * 2;
}
else
pixheight = ((int)((phyHeight / 25.4 * (config.g200params.dpi == 0x02 ? 300 : (config.g200params.dpi == 0x03 ? 600 : 200)) + 2) / 3) * 3) * 2;
if (config.g200params.paper == (unsigned int)(PaperSize::G400_AUTO)||pixheight > 16380) // isp sup max height config 16383
pixheight = 16380;
int dstheight = pixheight;
int fpgaheight = mode == 0x1 ? dstheight / 2 * 3 : dstheight / 2; //彩色配置fpga 高度要为目标图像高度的3倍
//FPGAConfigParam fpgaparam = GetFpgaparam(config.g200params.dpi, mode);// == 0x02 ? 2 : (config.g200params.dpi == 0x03 ? 3 : 2)
// FPGAConfigParam fpgaparam = GetFpgaparam(dpi, mode);
printf("dpi = %d fpgaparam.sp=%d exp=%d gain=%d offset=%d LUT=%s \n", dpi, fpgaparam.Sp, fpgaparam.ExposureB[0], fpgaparam.GainB[0], fpgaparam.OffsetB[0], fpgaparam.LutPath.c_str());
// int startsample= cistype.GetCisType()==CISVendor::DUNNAN_CIS_V0?205:262;
#ifdef G300
int startsample = 202;
dpi = 0;
width = 1728;
if (papersMap.count((PaperSize)config.g200params.paper) > 0)
{
dstheight = papersMap[(PaperSize)config.g200params.paper].height;
}
else
{
dstheight = papersMap[PaperSize::G400_A4].height; //不区分G300 G400
}
dstheight = config.g200params.color ? dstheight : dstheight /3;
if(config.g200params.dpi != 1)
dstheight = std::min(16002,dstheight*3/2);
fpgaheight = dstheight;
#else
int startsample = 208;
std::uint32_t m_fpgaversion = 0;
fpgaComm->read(15,m_fpgaversion);
if(Dail().GetValue().dails.in_voltage3 == 0)
startsample = 262;
else
startsample = m_fpgaversion == 0x90002? 205 : 208;
#endif
float v_ratio = *((float*)(&fpgaparam.VRatio));
fpgaparam.Sp /= v_ratio;
printf("\n apply sp = %d, v_ratio =%f",fpgaparam.Sp,v_ratio);
ModeFpga fpgamod = {
.colorMode = mode,
.dpi = dpi,
.led = 1,
.sample = startsample, // 256+39
.adcA = 0,
.adcB = 0,
.selftest = 0,
.sp = fpgaparam.Sp}; // 600DPI 0x1450 300DPI 0xe10
fpgaComm->setRegs(0x01, *((int *)(&fpgamod)));
fpgaComm->setSample(startsample);
fpgaComm->enableLed(true);
fpgaComm->setEnTestCol(false);
fpgaComm->setEnTestBit(false);
auto vsp_value = jsonconfig().getscannerinfo();
if(vsp_value.clr_maxbright > 20 || vsp_value.clr_maxbright < 1)
vsp_value.clr_maxbright = 2;
if(vsp_value.gray_maxbright > 20 || vsp_value.gray_maxbright < 1)
vsp_value.gray_maxbright = 2;
fpgaComm->setVsp(vsp_value.clr_maxbright,vsp_value.gray_maxbright);
// fpgaComm->update(2);
configFPGAParam(mode, config.g200params.dpi);
// fpgaComm->update(3);
// fpgaComm->setFrameHeight(12);
// fpgaComm->capture();
// auto data = video->read_frame(100);
// fpgaComm->enableLed(false);
video->open(width, dstheight); // 300dpi 7344/2 600dpi 7344
printf("opened video with width = %d height = %d \n", width, dstheight);
fpgaComm->setFrameHeight(12);
for (int i = 0; i < 1; i++)
{
fpgaComm->capture(); // abort first frame
video->read_frame(100);
std::this_thread::sleep_for(std::chrono::milliseconds(20));
printf("abort first frame \n");
}
fpgaComm->setFrameHeight(fpgaheight);
printf("fpgaComm set height = %d \n", fpgaheight);
fpgaComm->update(3);
//initLut(fpgaparam.LutPath, config.g200params.color);
initLut(config.g200params.is_textcorrect?fpgaparam.LutPath:fpgaparam.TextLutPath,config.g200params.color);
}
void MonoCapturer::close()
{
if (video.get())
video->close();
//fpga_reload();
}
void MonoCapturer::Fpga_regsAccess_reset(bool enable){
if(fpgaComm.get())
fpgaComm->regsAccess_reset(enable);
}
void MonoCapturer::start()
{
if (video.get())
video->start();
}
void MonoCapturer::MonoCapturer::stop()
{
if (video.get())
video->stop();
}
bool MonoCapturer::is_runing()
{
return false;
}
void MonoCapturer::snap()
{
fpgaComm->capture();
}
void MonoCapturer::stopsnap()
{
}
int MonoCapturer::getautosizeheight()
{
unsigned int val;
unsigned int reg8 = 0;
fpgaComm->read(8, reg8);
// std::cout << "1 reg[8]:" << string_format("0x%08x", reg8) << std::endl;
// fpgaComm->update(4);
fpgaComm->read(14, val);
int regv = val;
val &= 0x0000ffff;
// std::cout << string_format("ONE height = %d reg[14] = %d \n", val, regv);
// fpgaComm->update(5);
fpgaComm->write(8, reg8 & 0xfffffff7);
// std::cout << string_format("ONE reg[8] = %d \n", reg8 & 0xfffffff7);
std::this_thread::sleep_for(std::chrono::milliseconds(5));
// fpgaComm->update(6);
fpgaComm->read(14, val);
regv = val;
val &= 0x0000ffff;
fpgaComm->read(8, reg8);
// std::cout << "2 reg[8]:" << string_format("0x%08x", reg8) << std::endl;
std::cout << string_format("TWO height = %d reg[14] = %d \n", val, regv);
std::this_thread::sleep_for(std::chrono::milliseconds(5));
fpgaComm->write(8, reg8 | 0x8);
// fpgaComm->write(8,0x02260008);
// fpgaComm->update(7);
// fpgaComm->read(8, reg8);
// std::cout << "2 reg[8]:" << string_format("0x%08x", reg8) << std::endl;
return val;
// return fpgaComm->getFrameHeight();
}
void MonoCapturer::set_size(int width, int height)
{
if (video.get())
video->set_size(width, height);
}
void MonoCapturer::set_sp(int sp)
{
fpgaComm->setSp(sp);
}
void *MonoCapturer::readFrame(int timeout)
{
return video->read_frame(timeout);
}
void MonoCapturer::set_gain(int ix, int val)
{
for (int i = 0; i < 6; i++)
{
if (ix)
fpgaComm->setAGain(i, val);
else
fpgaComm->setBGain(i, val);
}
}
void MonoCapturer::set_offset(int ix, int val)
{
for (int i = 0; i < 6; i++)
{
if (ix)
fpgaComm->setAOffset(i, val);
else
fpgaComm->setBOffset(i, val);
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
}
void MonoCapturer::set_expo(int ix, int val)
{
switch (ix)
{
case 0:
fpgaComm->setAExposureR(val);
break;
case 1:
fpgaComm->setAExposureG(val);
break;
case 2:
fpgaComm->setAExposureB(val);
break;
case 3:
fpgaComm->setBExposureR(val);
break;
case 4:
fpgaComm->setBExposureG(val);
break;
case 5:
fpgaComm->setBExposureB(val);
break;
default:
break;
}
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
std::shared_ptr<IRegsAccess> MonoCapturer::regs()
{
return fpgaComm;
}
void MonoCapturer::reset()
{
fpga_reset();
// fpgaComm->resetADC();
// fpgaComm->setDelayTime(0X3e8);
// fpgaComm->setRegs(0x00, fpgaComm->getRegs(0x00));
// fpgaComm->setRegs(0x01, fpgaComm->getRegs(0x01));
}
int MonoCapturer::width()
{
#ifdef G300
return 1728;
#else
int dpi = fpgaComm->getDpi();
int channel = 1;
int width = dpi == 0x02 ? 1296 * channel : (dpi == 0x03 ? (2592 * channel) : (864 * channel));
// printf("get width = %d \n", width);
return width;
#endif
}
int MonoCapturer::height()
{
return fpgaComm->getFrameHeight();
}
int MonoCapturer::color()
{
return fpgaComm->getColorMode() ? 16 : 0;
}
void MonoCapturer::init_autocorrect(int colormode)
{
std::thread t_correctthread = std::thread(&MonoCapturer::correctcolor, this);
t_correctthread.detach();
}
void MonoCapturer::configFPGAParam(int mode, int dpi)
{
printf("dpi = %d mode = %d \n", dpi, mode);
//fpgaComm->resetADC();
FPGAConfigParam fpgaparam = GetFpgaparam(dpi, mode);
// int offF[6]={0,0,0,0,0,200};
// int offB[6]={0,0,0,0,0,0};
for (int i = 0; i < 6; i++)
{
if (i < 3)
{
set_expo(i, fpgaparam.ExposureF[i]);
printf("fpgaparam.ExposureF[%d] = %d \n", i, fpgaparam.ExposureF[i]);
}
else
{
set_expo(i, fpgaparam.ExposureB[i % 3]);
printf("fpgaparam.ExposureB[%d] = %d \n", i, fpgaparam.ExposureB[i % 3]);
}
std::this_thread::sleep_for(std::chrono::milliseconds(3));
fpgaComm->setAOffset(i, fpgaparam.OffsetF[i]);
// fpgaComm->setAOffset(i,offF[i]);
printf("fpgaparam.setAOffset[%d] = %d \n", i, fpgaparam.OffsetF[i]);
std::this_thread::sleep_for(std::chrono::milliseconds(3));
fpgaComm->setBOffset(i, fpgaparam.OffsetB[i]);
// fpgaComm->setBOffset(i, offB[i]);
printf("fpgaparam.OffsetB[%d] = %d \n", i, fpgaparam.OffsetB[i]);
std::this_thread::sleep_for(std::chrono::milliseconds(3));
fpgaComm->setAGain(i, fpgaparam.GainF[i]);
printf("fpgaparam.GainF[%d] = %d \n", i, fpgaparam.GainF[i]);
std::this_thread::sleep_for(std::chrono::milliseconds(3));
fpgaComm->setBGain(i, fpgaparam.GainB[i]);
printf("fpgaparam.GainB[%d] = %d \n", i, fpgaparam.GainB[i]);
std::this_thread::sleep_for(std::chrono::milliseconds(3));
}
}
void MonoCapturer::openDevice(int dpi, int mode)
{
// reset_pin->setValue(Gpio::Low);
// std::this_thread::sleep_for(std::chrono::milliseconds(50));
// reset_pin->setValue(Gpio::High);
int config_dpi = dpi == 1 ? 2 : dpi;
int channelwidth = config_dpi == 0x02 ? 1296 : (config_dpi == 0x03 ? 2592 : 864);
int channels = mode == 0x01 ? 3 : 1;
int width = channelwidth * channels;
int dstheight = 200;
int fpgaheight = mode == 0x1 ? dstheight / 2 * 3 : dstheight; //彩色配置fpga 高度要为目标图像高度的3倍
FPGAConfigParam fpgaparam = GetFpgaparam(dpi, mode);
#ifdef G300
int startsample = 202;
config_dpi = 0;
width = 1728;
dstheight = mode ? 6000 : 2000;
fpgaheight = dstheight;
#else
int startsample = 208;
std::uint32_t m_fpgaversion = 0;
fpgaComm->read(15,m_fpgaversion);
if(Dail().GetValue().dails.in_voltage3 == 0)
startsample = 262;
else
startsample = m_fpgaversion == 0x90002? 205 : 208;
#endif
printf("fpgaparam.sp=%d exp=%d gain=%d offset=%d LUT=%s", fpgaparam.Sp, fpgaparam.ExposureB[0], fpgaparam.GainB[0], fpgaparam.OffsetB[0], fpgaparam.LutPath.c_str());
// int startsample= cistype.GetCisType()==CISVendor::DUNNAN_CIS_V0?205:262;
float v_ratio = *((float*)(&fpgaparam.VRatio));
fpgaparam.Sp *= v_ratio;
printf("\n openDevice apply sp = %d, v_ratio =%f",fpgaparam.Sp,v_ratio);
ModeFpga fpgamod = {
.colorMode = mode,
.dpi = config_dpi,
.led = 1,
.sample = startsample, // 256+39
.adcA = 0,
.adcB = 0,
.selftest = 0,
.sp = fpgaparam.Sp}; // 600DPI 0x1450 300DPI 0xe10
fpgaComm->setRegs(0x01, *((int *)(&fpgamod)));
fpgaComm->setSample(startsample);
fpgaComm->enableLed(true);
fpgaComm->setEnTestCol(false);
fpgaComm->setEnTestBit(false);
auto vsp_value = jsonconfig().getscannerinfo();
if(vsp_value.clr_maxbright > 20 || vsp_value.clr_maxbright < 1)
vsp_value.clr_maxbright = 2;
if(vsp_value.gray_maxbright > 20 || vsp_value.gray_maxbright < 1)
vsp_value.gray_maxbright = 2;
fpgaComm->setVsp(vsp_value.clr_maxbright,vsp_value.gray_maxbright);
configFPGAParam(mode, dpi);
video->open(width, dstheight); // 300dpi 7344/2 600dpi 7344
printf("opened video with width = %d height = %d \n", width, dstheight);
fpgaComm->setFrameHeight(12);
for (int i = 0; i < 1; i++)
{
fpgaComm->capture(); // abort first frame
video->read_frame(100);
std::this_thread::sleep_for(std::chrono::milliseconds(20));
printf("abort first frame \n");
}
fpgaComm->setFrameHeight(fpgaheight);
}
void MonoCapturer::creatcorrectconfig(int dpi, int mode)
{
printf(" opendevice");
openDevice(dpi, mode);
printf(" opendevice end ");
bool isDone = false;
int i = 1;
initStep1();
while (!isDone) //先暗场
{
string log = "==============================第" + to_string(i) + "次===============================";
ft_log.append_log(log);
configFPGAParam(mode, dpi);
ft_log.append_log(log);
fpgaComm->enableLed(false);
std::this_thread::sleep_for(std::chrono::milliseconds(3));
fpgaComm->capture();
std::this_thread::sleep_for(std::chrono::milliseconds(3));
isDone = saveLutImg(dpi, mode, true); // 0 color_black 1 color_white 2 gray_balck 3 gray_white
i++;
}
i = 1;
isDone = false;
initStep1();
while (!isDone) //后明场
{
configFPGAParam(mode, dpi);
string log = "==============================第" + to_string(i) + "次===============================";
ft_log.append_log(log);
fpgaComm->enableLed(true);
std::this_thread::sleep_for(std::chrono::milliseconds(3));
fpgaComm->capture();
std::this_thread::sleep_for(std::chrono::milliseconds(3));
isDone = saveLutImg(dpi, mode, false);
i++;
}
printf("creatcorrectconfig %s \n", (mode == IMAGE_COLOR ? " Color" : " Gray"));
//creatLUTData(dpi, mode);
video->close();
}
static int savelutindex = 0;
bool MonoCapturer::saveLutImg(int dpi, int mode, bool black)
{
int config_dpi = dpi == 1 ? 2 : dpi;
#ifdef G300
int offset_indexs[] = {3, 4, 5, 2, 1, 0, 0, 1, 2, 5, 4, 3};
#else
int offset_indexs[] = {0, 1, 2, 5, 4, 3, 3, 4, 5, 2, 1, 0};
#endif
int channels = mode == IMAGE_COLOR ? 3 : 1;
int height = 100;
int width = config_dpi == 0x02 ? 1296 : (config_dpi == 0x03 ? 2592 : 864);
int orgimgwidth = width * 2 * 3 * channels;
int dstwidth = width * 2 * 3;
#ifdef G300
orgimgwidth = 1728 * channels * 3;
height = 6000 / 9 *3 ;
#endif
bool isNeedSave = true;
string log;
void *data = video->read_frame(10000);
if (data == NULL)
{
isNeedSave = false;
log = "WARNNING WARNNING WARNNING FAILDED TO READ IMAGE DATA !!!!!!!!!!!!!!!!!!!\r\n";
ft_log.append_log(log);
if (m_captureCallback)
m_captureCallback(mode, log);
return isNeedSave;
}
cv::Mat src(height, orgimgwidth, CV_8UC1, data);
//cv::imwrite(std::to_string(savelutindex++) + ".jpg", src);
#ifdef G300
cv::Mat mrgmat = GetStitchMat(mode ==1?1:0,orgimgwidth,height,src);
#else
CImageMerge t_marge;
cv::Mat mrgmat = t_marge.MergeImage(mode == 0x01, src, dstwidth, height,0x90001);
#endif
mrgmat = mrgmat(cv::Rect(0,20,mrgmat.cols,mrgmat.rows-20));
// return false;
FPGAConfigParam param = GetFpgaparam(dpi, mode);
if (black) //暗场
{
double offValues[12];
std::vector<bool> bflags;
for (volatile int n = 0; n < 2; n++)
{
cv::Mat img = mrgmat(cv::Rect(mrgmat.cols * n / 2, 10, mrgmat.cols / 2, mrgmat.rows - 10)).clone();
int offset_total = 0;
for (volatile int s = 0; s < 6; s++) //
{
int k = n * 6 + s;
int offset_wdth;
if ((k == 5) || (k == 6))
{
offset_wdth = config_dpi == 0x03 ? 864 : (config_dpi == 0x02 ? 432 : 288);
}
else
{
offset_wdth = config_dpi == 0x03 ? 1296 : (config_dpi == 0x02 ? 648 : 432);
}
#ifdef G300
offset_wdth =432;
#endif
double min,max;
//auto t_mat= img(cv::Rect(offset_total, 10, offset_wdth, img.rows - 10));
//cv::minMaxLoc(t_mat,&min,&max);
cv::Scalar mean = cv::mean(img(cv::Rect(offset_total, 10, offset_wdth, img.rows - 10)));
//printf("AAAAAAAAAAAAAAAAAAAAAAAAAAA min = %.2f max= %.2f mean = %0.2f \n",min,max);
offset_total += offset_wdth;
offValues[k] = mean.val[0];
printf("\noffValues[%d] = %f",k,mean.val[0]);
bflags.push_back(false);
//offValues[k] = min;
}
}
// std::string clrmode = (mode == 0x01 ? "彩色" : " 灰度");
// log = "开始" + clrmode + "暗场校正 \n";
for (volatile int s = 0; s < 2; s++)
{
int offsets[6]; // = (int *)(s == 0 ? &param.OffsetF[0] : &param.OffsetB[0]);
memcpy(offsets, (s == 0 ? &param.OffsetF[0] : &param.OffsetB[0]), sizeof(param.OffsetF));
for (volatile int j = 0; j < 6; j++)
{
int k = s * 6 + j;
double diff = BLACK_DIFF(offValues[k]);
//double diff = 3-offValues[k];
double step = radio * diff;
int preStep = offsetStep1[k];
printf("offsetStep1[%d]=%d \n",k,offsetStep1[k]);
if (step * preStep < 0)
{
step = 0 - preStep / 2;
}
else
{
radio = 1;
}
if (step < 1 && step > 0)
step = 1;
if (step < 0 && step > -1)
step = -1;
// FMT_STEP(step);
bool isMinStep = abs(step) == 1 && step == offsetStep1[k];
bool isOutBounds = offsets[j] >= 255 && step > 0;
isOutBounds |= offsets[j] <= 0 && step < 0;
log += " 暗场校正 :" + std::to_string(k) + ";diff:" + std::to_string(diff) + ";light:" + std::to_string(offValues[k]) + ";offset:" + std::to_string(offsets[j]) + ";step:" + std::to_string(step) + "\r\n";
if (isOutBounds)
log += "" + std::to_string(k) + "条带暗场校正异常,暗场值无法降低 \r\n";
else if (abs(step) > 1 || isMinStep)
{
offsetStep1[k] = (int)(step);
offsets[offset_indexs[k]] += step;
log += "offsetStep1" + std::to_string(k) + " = " + std::to_string(offsetStep1[k]) + ", offset_indexs" + std::to_string(k) + " =" + std::to_string(offset_indexs[k]) + "\r\n";
if (offsets[offset_indexs[k]] < 1)
offsets[offset_indexs[k]] = 1;
if (offsets[offset_indexs[k]] > 255)
offsets[offset_indexs[k]] = 255;
//isNeedSave = false;
bflags[k] = false;
}
else
{
bflags[k] = true;
printf("channel[%d] black correct done\n",k);
}
log += (s == 0 ? "彩色正面" : "彩色背面");
log += "偏移值:" + std::to_string(offsets[0]) + "," + std::to_string(offsets[1]) + "," + std::to_string(offsets[2]) + "," + std::to_string(offsets[3]) + "," + std::to_string(offsets[4]) + "," + std::to_string(offsets[5]) + "\r\n";
// log += (s == 0 ? "彩色正面暗场校正完成 \r\n" : "彩色背面暗场校正完成 \r\n");
ft_log.append_log(log);
if (m_captureCallback)
m_captureCallback(mode, log);
log = "";
}
auto siez = sizeof(param.OffsetF);
memcpy((s == 0 ? &param.OffsetF[0] : &param.OffsetB[0]), offsets, sizeof(param.OffsetF));
}
for(int i = 0;i<bflags.size();i++)
{
if(!bflags[i])
isNeedSave=false;
}
if (isNeedSave)
{
printf("Save LUT image path :%s \n", param.Flat_BwPath.c_str());
log = "暗场校正完成 \r\n";
if (m_captureCallback)
m_captureCallback(mode, log);
// log ="";
imwrite(param.Flat_BwPath, mrgmat);
}
}
else //明场
{
if (mode == IMAGE_COLOR)
{
double values[2][3];
cv::Scalar a = mean(mrgmat(Rect(0, 0, mrgmat.cols / 2, mrgmat.rows)));
cv::Scalar b = mean(mrgmat(Rect(mrgmat.cols / 2, 0, mrgmat.cols / 2, mrgmat.rows)));
for (int j = 0; j < 3; j++)
{
values[0][j] = a.val[2 - j];
values[1][j] = b.val[2 - j];
}
log = "开始彩色明场校正 \r\n";
if (m_captureCallback)
m_captureCallback(mode, log);
for (int s = 0; s < 2; s++)
{
int exposures[3]; // = (int *)(s == 0 ? param.ExposureF : param.ExposureB);
memcpy(exposures, (s == 0 ? &param.ExposureF[0] : &param.ExposureB[0]), sizeof(param.ExposureB));
for (int x = 0; x < 3; x++)
{
int k = (3 * s + x);
int diff = LIGHT_DIFF(param.MaxBright, *((double *)values + k));
log += " 明场:" + std::to_string(k) + ";diff" + std::to_string(diff) + "\r\n";
if(abs(diff) > 30)
radio = 2;
else
radio = 1;
double step = diff * radio;
int preStep = *((int *)expStep + k);
if (step * preStep < 0)
{
step = 0 - preStep / 2;
}
if (step < 1 && step > 0)
step = 1;
if (step < 0 && step > -1)
step = -1;
bool isMinStep = abs(step) == 1 && step == *((int *)expStep + k);
bool isOutBounds = exposures[x] >= (param.Sp -5) && step > 0;
isOutBounds |= exposures[x] <= 0 && step < 0;
if (isOutBounds)
log += "" + to_string(x) + "个明场校正异常 \r\n";
else if (abs(diff) >= 1 || isMinStep)
{
*((int *)expStep + k) = (int)(step);
exposures[x] += step;
if (exposures[x] > (param.Sp -5))
{
exposures[x] = (param.Sp -5);
}
if (exposures[x] < 0)
exposures[x] = 0;
isNeedSave = false;
}
log += " 曝光值:" + to_string(exposures[x]) + "\r\n";
log += " 调整步长:" + to_string(*((int *)expStep + k)) + "\r\n";
}
memcpy((s == 0 ? &param.ExposureF[0] : &param.ExposureB[0]), exposures, sizeof(param.ExposureB));
}
ft_log.append_log(log);
if (m_captureCallback)
m_captureCallback(mode, log);
if (isNeedSave)
{
log = "彩色明场校正完成\r\n";
if (m_captureCallback)
m_captureCallback(mode, log);
// log ="";
imwrite(param.Flat_WhitePath, mrgmat);
}
}
else
{
double values[2];
values[0] = cv::mean(mrgmat(cv::Rect(0, 0, mrgmat.cols / 2, mrgmat.rows))).val[0];
values[1] = cv::mean(mrgmat(cv::Rect(mrgmat.cols / 2, 0, mrgmat.cols / 2, mrgmat.rows))).val[0];
log = "-----开始灰色明场校正-----\r\n";
log += " 灰色扫描灰度明场均值:" + to_string(values[0]) + "," + to_string(values[1]) + "\r\n";
if (m_captureCallback)
m_captureCallback(mode, log);
for (int s = 0; s < 2; s++)
{
int *exposures = (int *)(s == 0 ? param.ExposureF : param.ExposureB);
int diff = LIGHT_DIFF(param.MaxBright, values[s]);
if(abs(diff) > 30)
radio = 2;
else
radio = 1;
double step = diff * radio;
log += " 明场:" + to_string(s) + ";diff" + to_string(diff) + "\r\n";
int preStep = expStep[s][0];
if (step * preStep < 0)
{
step = 0 - preStep / 2;
}
else
{
radio = 1;
}
if (step < 1 && step > 0)
step = 1;
if (step < 0 && step > -1)
step = -1;
int exp = *(exposures + 1);
// std::string ss1(string_format("exp[%d] = %d step = %.3f \r\n", s, exp, step));
// log += ss1;
bool isMinStep = abs(step) == 1 && step == expStep[s][0];
bool isOutBounds = exp >= (param.Sp -5) && step > 0;
isOutBounds |= exp <= 0 && step < 0;
if (isOutBounds)
log += "" + to_string(s) + "个明场校正异常 \r\n";
else if (abs(diff) > 1 || isMinStep)
{
exp += step;
if (exp < 0)
exp = 0;
if (exp >(param.Sp -5))
exp = (param.Sp -5);
float coffe[3] = {1, 1, 1}; // 0.2, 1,0.51
for (int k = 0; k < 3; k++)
{
*(exposures + k) = (int)(exp * coffe[k]);
expStep[s][k] = (int)(step);
std::string exps(string_format("expStep[%d][%d] = %.3f\r\n", s, k, step));
log += exps;
std::string ss(string_format("exposures[%d] = %0.3f \r\n", k, exposures[k]));
log += ss;
}
isNeedSave = false;
}
}
ft_log.append_log(log);
if (m_captureCallback)
m_captureCallback(mode, log);
if (isNeedSave)
{
printf("Save LUT image path :%s \n", param.Flat_WhitePath.c_str());
log = "灰度明场校正完成\r\n";
if (m_captureCallback)
m_captureCallback(mode, log);
log = "";
imwrite(param.Flat_WhitePath, mrgmat);
}
}
}
SaveFpgaparam(param);
printf("exit Save_lut \n");
return isNeedSave;
}
void MonoCapturer::correctcolor()
{
printf(" correctcolor start \n");
auto _start = std::chrono::steady_clock::now();
ThreadPool pool(2);
std::queue<std::future<void>> fu_correct;
std::string loginfo = "Start Correctcolor 200DPI COLOR \r\n";
// if (m_captureCallback)
// m_captureCallback(0x01, loginfo);
creatcorrectconfig(0x01, IMAGE_COLOR);
auto param = GetFpgaparam(0x01,IMAGE_COLOR);
fu_correct.emplace(pool.enqueue([param](){creatLUTData(0x01,IMAGE_COLOR,param);}));
loginfo = "-----------200DPI COLOR Correct Done----------- \r\n\r\n Start Correctcolor 200DPI GRAY \r\n";
if (m_captureCallback)
m_captureCallback(0x01, loginfo);
creatcorrectconfig(0x01, IMAGE_GRAY);
param = GetFpgaparam(0x01,IMAGE_GRAY);
fu_correct.emplace(pool.enqueue([param](){creatLUTData(0x01,IMAGE_GRAY,param);}));
loginfo = "-----------200DPI Gray Correct Done----------- \r\n\r\n Start Correctcolor 200DPI COLOR \r\n";
if (m_captureCallback)
m_captureCallback(0x02, loginfo);
creatcorrectconfig(0x02, IMAGE_COLOR);
param = GetFpgaparam(0x02,IMAGE_COLOR);
fu_correct.emplace(pool.enqueue([param](){creatLUTData(0x02,IMAGE_COLOR,param);}));
loginfo = "-----------300DPI COLOR Correct Done----------- \r\n\r\n Start Correctcolor 300DPI GRAY \r\n";
if (m_captureCallback)
m_captureCallback(0x02, loginfo);
creatcorrectconfig(0x02, IMAGE_GRAY);
param = GetFpgaparam(0x02,IMAGE_GRAY);
fu_correct.emplace(pool.enqueue([param](){creatLUTData(0x02,IMAGE_GRAY,param);}));
loginfo = "-----------300DPI Gray Correct Done----------- \r\n\r\n Start Correctcolor 600DPI COLOR \r\n";
#ifndef G300
if (m_captureCallback)
m_captureCallback(0x03, loginfo);
creatcorrectconfig(0x03, IMAGE_COLOR);
param = GetFpgaparam(0x03,IMAGE_COLOR);
fu_correct.emplace(pool.enqueue([param](){creatLUTData(0x03,IMAGE_COLOR,param);}));
loginfo = "-----------600DPI COLOR Correct Done----------- \r\n\r\n Start Correctcolor 600DPI GRAY \r\n";
if (m_captureCallback)
m_captureCallback(0x03, loginfo);
creatcorrectconfig(0x03, IMAGE_GRAY);
param = GetFpgaparam(0x03,IMAGE_GRAY);
fu_correct.emplace(pool.enqueue([param](){creatLUTData(0x03,IMAGE_GRAY,param);}));
loginfo = "-----------600DPI Gray Correct Done----------- \r\n\r\n ";
if (m_captureCallback)
m_captureCallback(0x03, loginfo);
#endif
while(fu_correct.size())
{
fu_correct.front().get();
fu_correct.pop();
}
loginfo = "******Correct Done****** time " + std::to_string(std::chrono::duration<double>(std::chrono::steady_clock::now() - _start).count())+"s";
if (m_captureCallback)
m_captureCallback(0x03, loginfo);
}
void MonoCapturer::fpga_reset()
{
reset_pin->setValue(Gpio::Low);
std::this_thread::sleep_for(std::chrono::milliseconds(50));
reset_pin->setValue(Gpio::High);
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
void MonoCapturer::fpga_reload()
{
// fpga 代码重载
fpgaLoad->setValue(Gpio::Low);
std::this_thread::sleep_for(std::chrono::milliseconds(15));
fpga_conf_initn->setValue(Gpio::Low);
std::this_thread::sleep_for(std::chrono::milliseconds(15));
printf("\n fpga_conf_done value %d",fpga_conf_done->getValue());
fpgaLoad->setValue(Gpio::High);
std::this_thread::sleep_for(std::chrono::milliseconds(15));
fpga_conf_initn->setValue(Gpio::High);
//std::this_thread::sleep_for(std::chrono::milliseconds(5));
printf("\n fpga_conf_done value %d",fpga_conf_done->getValue());
// while(fpga_conf_done->getValue() == Gpio::GpioLevel::Low)
// std::this_thread::sleep_for(std::chrono::milliseconds(5));
std::this_thread::sleep_for(std::chrono::seconds(3));
printf("\n fpga_conf_done value %d",fpga_conf_done->getValue());
fpgaComm->resetADC();
fpgaComm->update(0);
}

View File

@ -0,0 +1,67 @@
#pragma once
#include "ICapturer.h"
class FpgaComm;
class gVideo;
class Gpio;
class MonoCapturer : public ICapturer
{
private:
/* data */
public:
MonoCapturer(/* args */);
virtual ~MonoCapturer();
virtual void open();
virtual void open(HGScanConfig config,FPGAConfigParam fpgaparam);
virtual void close();
virtual void start();
virtual void stop();
virtual bool is_runing();
virtual void snap();
virtual void stopsnap();
virtual int getautosizeheight();
virtual void set_size(int width, int height);
virtual void set_sp(int sp);
virtual void *readFrame(int timeout);
virtual void set_gain(int ix, int val);
virtual void set_offset(int ix, int val);
virtual void set_expo(int ix, int val);
virtual std::shared_ptr<IRegsAccess> regs();
virtual void reset();
virtual int width();
virtual int height();
virtual int color();
virtual void init_autocorrect(int colormode);
virtual void setcapturecall(std::function<void(int, std::string)> callback)
{
m_captureCallback = callback;
};
virtual void Fpga_regsAccess_reset(bool enable);
private:
void configFPGAParam(int mode, int dpi);
void openDevice(int dpi, int mode);
void creatcorrectconfig(int dpi, int mode);
bool saveLutImg(int dpi, int mode, bool black);
void correctcolor();
void fpga_reset();
void fpga_reload();
private:
std::function<void(int, std::string)> m_captureCallback;
std::shared_ptr<gVideo> video;
std::shared_ptr<Gpio> vdd_cis_3voff_pin;
std::shared_ptr<Gpio> vdd_vis_5ven_pin;
std::shared_ptr<Gpio> reset_pin;
std::shared_ptr<Gpio> image_in_transfer_pin;
std::shared_ptr<Gpio> initDone_pin;
std::shared_ptr<Gpio> fpgaLoad;
std::shared_ptr<FpgaComm> fpgaComm;
std::shared_ptr<Gpio> fpga_conf_initn;
std::shared_ptr<Gpio> fpga_conf_done;
bool bcorrecting;
std::thread m_correctthread;
};

View File

@ -0,0 +1,183 @@
#pragma once
#include "SysInforTool.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/vfs.h>
#include <sys/types.h>
#include <sys/sysinfo.h>
#include <sys/utsname.h>
#include <errno.h>
#include <fstream>
#include <iostream>
#include <iomanip>
extern int errno;
static void get_system_output(char *cmd, char *output, int size)
{
FILE *fp = NULL;
fp = popen(cmd, "r");
if (fp)
{
if (fgets(output, size, fp) != NULL)
{
if (output[strlen(output) - 1] == '\n')
output[strlen(output) - 1] = '\0';
}
pclose(fp);
}
}
/*block to kbyte*/
static unsigned long kscale(unsigned long m_block, unsigned long m_kbyte)
{
return ((unsigned long long) m_block * m_kbyte + 1024 / 2 ) /1024;
}
/*convert size to GB MB KB*/
static void convert_size(float m_size, int *dest)
{
if((((m_size / 1024.0) / 1024.0)) >= 1.0)
{
*dest = (int)((m_size/1024.0)/1024.0);
}
else if((m_size / 1024.0) >= 1.0)
{
*dest = (int)(m_size/1024);
}
}
SysInforTool::SysInforTool(ScannerSysInfo tinfo)
{
m_sysinfo = tinfo;
}
SysInforTool::~SysInforTool()
{
}
/*获取文件系统信息*/
int SysInforTool::get_fileSystem_info(const char *fileSystem_name,struct fileSystem_info *fi)
{
struct statfs buf;
float fileSystem_total_size = 0;
float fileSystem_free_size = 0;
if(statfs(fileSystem_name,&buf))
{
fprintf(stderr,"statfs %s\n",strerror(errno));
return -1;
}
switch(buf.f_type)
{
case 0xEF51:
case 0xEF53:
sprintf(fi->fileSystem_format,"EXT");
break;
case 0x4d44:
sprintf(fi->fileSystem_format,"FAT");
break;
case 0x5346544e:
sprintf(fi->fileSystem_format,"NIFS");
break;
default:
sprintf(fi->fileSystem_format,"unknown");
break;
}
//bzero(&fi->fileSystem_total_capacity,sizeof(fi->fileSystem_total_capacity));
//bzero(&fi->fileSystem_free_capacity,sizeof(fi->fileSystem_free_capacity));
printf("blocks %ld\n",buf.f_blocks);
printf("bfree %ld\n",buf.f_bfree);
printf("bsize %ld\n",buf.f_bsize);
fileSystem_total_size =
(float)(kscale(buf.f_blocks, buf.f_bsize));
fileSystem_free_size =
(float)(kscale(buf.f_bfree, buf.f_bsize));
printf("total %f\n",fileSystem_total_size);
printf("free %f\n",fileSystem_free_size);
fi->fileSystem_total_capacity = fileSystem_total_size;
fi->fileSystem_free_capacity = fileSystem_free_size;
//convert_size(fileSystem_total_size,(int*)(&fi->fileSystem_total_capacity));
//convert_size(fileSystem_free_size,(int*)(&fi->fileSystem_free_capacity));
bzero(fi->fileSystem_permissions,sizeof(fi->fileSystem_permissions));
sprintf(fi->fileSystem_permissions,"rw");
return 0;
}
std::string SysInforTool::GetSysInfo()
{
struct sysinfo memInfo;
sysinfo(&memInfo);
m_sysinfo.MemTotal = memInfo.totalram;
fileSystem_info fileinfo;
get_fileSystem_info("/",&fileinfo);
m_sysinfo.DiskTotal = fileinfo.fileSystem_total_capacity;//KB
m_sysinfo.DiskUsed = fileinfo.fileSystem_free_capacity;//KB
struct utsname t_uname;
if(uname(&t_uname)!=0)
perror("uname doesn't return 0, so there is an error");
printf("System Name = %s\n", t_uname.sysname);
printf("Node Name = %s\n", t_uname.nodename);
printf("Version = %s\n", t_uname.version);
printf("Release = %s\n", t_uname.release);
printf("Machine = %s\n", t_uname.machine);
if(strcmp(t_uname.nodename,"linaro-alip")==0 && strcmp(t_uname.machine,"armv7l")==0)
{
m_sysinfo.Systype=SysType::Sys_Linux_Debian;
m_sysinfo.CPU = SCPU::CPU_3288;
printf("Machine = %s CPU = %s \n", "Sys_Linux_Debian","CPU_3288");
}
else if(strcmp(t_uname.nodename,"linaro-alip")==0 && strcmp(t_uname.machine,"aarch64")==0)
{
m_sysinfo.Systype = SysType::Sys_Linux_Debian;
m_sysinfo.CPU = SCPU::CPU_3399;
printf("Machine = %s CPU = %s \n", "Sys_Linux_Debian","CPU_3399");
}
m_sysinfo.MtType = SMBType::MB_DRV_8825;
m_sysinfo.Cistype = HGCISType::CIS_DUNNAN_MONO_V0;
char output[512];
get_system_output("uname -a",output,sizeof(output));
std::string ver(output);
m_sysinfo.KernelVersion = ver;
printf("system version = %s \n",ver.c_str());
json j;
struct2json(j,m_sysinfo);
std::ofstream o("/usr/local/huago/sysinfo.json");
o << std::setw(4) << j << std::endl;
return j.dump();
}
void SysInforTool::struct2json(json& j,ScannerSysInfo& info)
{
j["CPU"]=info.CPU;
j["Systype"]=info.Systype;
j["Screentype"] = info.Screentype;
j["MtBoardVersion"] = info.MtBoardVersion;
j["MtType"] = info.MtType;
j["FPGAVersion"] = info.FPGAVersion;
j["Cistype"] = info.Cistype;
j["MaxRes"] = info.ResSup;
j["MemTotal"] = info.MemTotal;
j["DiskTotal"] = info.DiskTotal;
j["DiskUsed"] = info.DiskUsed;
j["KernelVersion"] = info.KernelVersion;
j["Have_EthernPort"] = info.Have_EthernPort;
j["ServiceVersion"] = info.ServiceVersion;
j["UsbProtocol"] = info.UsbProtocol;
}

View File

@ -0,0 +1,26 @@
#pragma once
#include "scannersysinfo.h"
#include "json.hpp"
using json=nlohmann::json;
struct fileSystem_info{
char fileSystem_format[8];
unsigned int fileSystem_total_capacity;
unsigned int fileSystem_free_capacity;
char fileSystem_permissions[3];
};
class SysInforTool
{
public:
SysInforTool(ScannerSysInfo tinfo);
~SysInforTool();
std::string GetSysInfo();
private:
int get_fileSystem_info(const char *fileSystem_name,struct fileSystem_info *fi);
void struct2json(json& j,ScannerSysInfo& info);
private:
ScannerSysInfo m_sysinfo;
};

View File

@ -0,0 +1,427 @@
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "correct_ultis.h"
#include "CorrectParam.h"
#include "commondef.h"
#define USE_NEWFLAT
using namespace cv;
void initStep()
{
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
expStep[i][j] = 600;
}
}
for (int i = 0; i < 12; i++)
{
offsetStep[i] = 256;
printf("offsetStep[%d]=%d \n",i,offsetStep[i]);
}
}
cv::Mat extractRepresentRow2(const cv::Mat &src)
{
cv::Mat BWbalenceSrc(1, src.cols * src.channels(), CV_8UC1);
cv::Mat temp_imageBW(src.rows, src.cols * src.channels(), CV_8UC1, src.data);
for (size_t i = 0; i < BWbalenceSrc.cols; i++)
BWbalenceSrc.at<uchar>(0, i) = cv::mean(temp_imageBW(cv::Rect(i, 0, 1, temp_imageBW.rows)))[0];
return BWbalenceSrc;
}
#ifdef G300
#define CHANNEL 432
#else
#define CHANNEL 408
#endif
cv::Mat loadLUT(const std::string& file)
{
cv::Mat dataFile = cv::imread(file, cv::IMREAD_ANYCOLOR);
long total = dataFile.total();
int step = total / 256;
int channel = 1;
#ifndef USE_NEWFLAT
if (step == 4896 || step == 7344 )
channel = 408;
else if (step == 14688 ||step== 22032 || step == 44064)
channel = 432; //486
#else
channel = CHANNEL;
#endif
cv::Mat lut(step / channel, 256, CV_8UC(channel));
memcpy(lut.data, dataFile.data, total);
return lut;
}
void initLut(const std::string lutpath,bool iscolor)
{
printf("\n-----------------------------");
lutColorMat.release();
lutGrayMat.release();
if (!lutpath.empty() && (access(lutpath.c_str(), F_OK) == 0))
{
printf("\n %s",lutpath.c_str());
if(iscolor)
lutColorMat = loadLUT(lutpath); //彩色校正值
else
lutGrayMat = loadLUT(lutpath); //灰色校正值
}
}
void correctColor(cv::Mat& src, int dpi, int mode,bool isText)
{
Mat lutMat;
FPGAConfigParam param = GetFpgaparam(dpi, mode);
std::string path = isText?param.TextLutPath : param.LutPath;
printf("\n %s",path.c_str());
if (src.type() == CV_8UC3)
{
if (lutColorMat.empty())
{
if (access(path.c_str(), F_OK) != -1)
{
lutColorMat = loadLUT(path);
}
else
{
printf("error error error %s NOT FOUND \n",path.c_str());
return;
}
}
lutMat = lutColorMat;
}
else
{
if (lutGrayMat.empty())
{
if (access(path.c_str(), F_OK) != -1)
{
lutGrayMat = loadLUT(path);
}
else
{
printf("error error error %s NOT FOUND", path.c_str());
return;
}
}
lutMat = lutGrayMat;
}
if (lutMat.empty())
{
return;
}
cv::Mat image_temp(src.rows, src.cols * src.channels() / lutMat.channels(), CV_8UC(lutMat.channels()), src.data);
for (size_t i = 0; i < image_temp.cols; i++)
cv::LUT(image_temp(cv::Rect(i, 0, 1, image_temp.rows)), lutMat(cv::Rect(0, i, 256, 1)), image_temp(cv::Rect(i, 0, 1, image_temp.rows)));
}
void creatLUTData(int dpi , int mode,FPGAConfigParam param)
{
printf("eneter creatLUTData \n");
auto colormode = mode == 1 ? IMREAD_COLOR : IMREAD_GRAYSCALE;
std::string blackPath = param.Flat_BwPath;
std::string whitePath = param.Flat_WhitePath;
std::string lutsavePath = param.LutPath;
printf("\n blackPath =%s \
whitePath =%s \
lutsavePath =%s \n",param.Flat_BwPath.c_str(),param.Flat_WhitePath.c_str(),param.LutPath.c_str());
cv::Mat lut;
cv::Mat twMat = cv::imread(whitePath, IMREAD_ANYCOLOR);
cv::Mat tbMat = cv::imread(blackPath, IMREAD_ANYCOLOR);
cv::Mat wMat, bMat;
if (mode == 1)
{
wMat = cv::Mat(twMat.rows, twMat.cols * 3, CV_8UC1, twMat.data);
bMat = cv::Mat(twMat.rows, twMat.cols * 3, CV_8UC1, tbMat.data);
}
else
{
wMat = twMat;
bMat = tbMat;
}
//lut = create_lut(extractRepresentRow2(bMat), extractRepresentRow2(wMat), dpi, mode); // add by liuyong: 刘丁维提供 2019/4/12
lut = calcLUT(extractRepresentRow2(bMat), extractRepresentRow2(wMat),false);
// Mat dst(bMat.cols * bMat.channels(), 256, CV_8UC1);
// memcpy(dst.data, lut.data, bMat.cols * bMat.channels() * 256);
cv::imwrite(param.LutPath, lut);
lut = calcLUT(extractRepresentRow2(bMat), extractRepresentRow2(wMat),true);
cv::imwrite(param.TextLutPath, lut);
printf("exit creatLUTData \n");
}
void creatLUTData(int dpi, int mode)
{
printf("eneter creatLUTData \n");
auto param = GetFpgaparam(dpi, mode);
auto colormode = mode == 1 ? IMREAD_COLOR : IMREAD_GRAYSCALE;
std::string blackPath = param.Flat_BwPath;
std::string whitePath = param.Flat_WhitePath;
std::string lutsavePath = param.LutPath;
cv::Mat lut;
cv::Mat twMat = cv::imread(whitePath, IMREAD_ANYCOLOR);
cv::Mat tbMat = cv::imread(blackPath, IMREAD_ANYCOLOR);
cv::Mat wMat, bMat;
if (mode == 1)
{
wMat = cv::Mat(twMat.rows, twMat.cols * 3, CV_8UC1, twMat.data);
bMat = cv::Mat(twMat.rows, twMat.cols * 3, CV_8UC1, tbMat.data);
}
else
{
wMat = twMat;
bMat = tbMat;
}
//lut = create_lut(extractRepresentRow2(bMat), extractRepresentRow2(wMat), dpi, mode); // add by liuyong: 刘丁维提供 2019/4/12
lut = calcLUT(extractRepresentRow2(bMat), extractRepresentRow2(wMat),false);
// Mat dst(bMat.cols * bMat.channels(), 256, CV_8UC1);
// memcpy(dst.data, lut.data, bMat.cols * bMat.channels() * 256);
cv::imwrite(param.LutPath, lut);
lut = calcLUT(extractRepresentRow2(bMat), extractRepresentRow2(wMat),true);
cv::imwrite(param.TextLutPath, lut);
printf("exit creatLUTData \n");
}
FPGAConfigParam GetFpgaparam(int dpi, int mode)
{
FPGAConfigParam param = CorrectParam().GetFpgaparam(dpi, mode);
return param;
}
void SaveFpgaparam(FPGAConfigParam &param)
{
CorrectParam().SaveCorrectParam(param);
}
cv::Mat colMean(const cv::Mat& image)
{
cv::Mat meanMat(1, image.step, CV_8UC1);
cv::Mat tempMat(image.rows, image.step, CV_8UC1, image.data);
for (int i = 0; i < tempMat.step; i++)
meanMat.data[i] = cv::mean(tempMat(cv::Rect(i, 0, 1, tempMat.rows)))[0];
return meanMat;
}
float gamma(float value, float ex)
{
return cv::pow(value / 255.0f, 1.0f / ex) * 255.0f + 0.5f;
}
#define GAMMA_EX 1.7f
#define BLACK_OFFSET 5
void fittingLUT(const std::vector<uchar>& points, uchar min_value, uchar max_value, uchar* data)
{
float step = max_value - min_value + 1;
memset(data, min_value, 127);
memset(data + 127, max_value, 129);
int b = points[0];
int w = points[1];
int tb = min_value;
int tw = max_value;
step = cv::max((float)(tw - tb + 1) / (float)(w - b + 1), 0.0f);
float temp;
for (int j = 0, length = (255 - b + 1); j < length; j++)
{
temp = gamma(tb + step * j, GAMMA_EX) - BLACK_OFFSET;
data[j + b] = cv::min(255, cv::max(0, static_cast<int>(temp)));
}
}
cv::Mat calcLUT(const cv::Mat& black, const cv::Mat& white, bool isTextCorrection)
{
std::vector<cv::Mat> w;
w.push_back(colMean(black));
w.push_back(colMean(white));
cv::Mat lut = createLUT(w, isTextCorrection);
for (size_t i = 0, block = lut.rows / CHANNEL; i < block; i++)
{
cv::Mat lutROI = lut(cv::Rect(0, i * CHANNEL, 256, CHANNEL));
cv::Mat tran;
cv::transpose(lutROI, tran);
memcpy(lutROI.data, tran.data, tran.total());
}
return lut;
}
cv::Mat create_lut(const cv::Mat &black, const cv::Mat &white, int dpi, bool colormode)
{
#ifndef USE_NEWFLAT
if (black.empty() || white.empty() || black.channels() != 1 || white.channels() != 1 || black.step != white.step)
return cv::Mat();
int channel = 1;
if (black.step == 4896 || black.step == 7344)
channel = 408;
else if (black.step == 14688 || black.step == 22032 ||black.step == 44064)
channel = 432; //486
if (channel == 1)
return cv::Mat();
const int rows = black.cols / channel;
const int cols = 256;
auto cc = CV_8UC(channel);
Mat lut(rows, cols, CV_8UC(channel));
const double gain = 255.0/((double)CorrectParam().GetFpgaparam(dpi,colormode).MaxBright);
for (size_t i = 0; i < rows; i++)
{
Mat lut_row = lut(cv::Rect(0, i, cols, 1));
unsigned char *ptr_buffer = lut_row.data;
unsigned char *ptr_black = black.data + i * channel;
unsigned char *ptr_white = white.data + i * channel;
for (size_t j = 0; j < cols; j++)
for (size_t k = 0; k < channel; k++)
{
if (ptr_black[k] >= ptr_white[k])
{
ptr_buffer[j * channel + k] = 0;
continue;
}
if (j <= ptr_black[k])
ptr_buffer[j * channel + k] = 0;
else if (j >= ptr_white[k])
ptr_buffer[j * channel + k] = 255;
else
{
float val = 255.0f * (j - ptr_black[k]) / (ptr_white[k] - ptr_black[k]) * gain;
ptr_buffer[j * channel + k] = (unsigned char)cv::max(0.0f, cv::min(val, 255.0f));
}
}
}
cv::Mat saveMat(black.step, 256, CV_8UC1, lut.data);
return saveMat.clone();
#else
return calcLUT(black,white,false);
#endif
}
std::vector<double> caculate(const std::vector<double>& points_x, const std::vector<double>& points_y)
{
int MaxElement = points_x.size() - 1;
//计算常数f
double f = points_y[0];
//求解
int n, m;
//double a[MaxElement][MaxElement+1];
std::vector<std::vector<double>> a;
//a.resize(MaxElement);
for (int i = 0; i < MaxElement; i++)
{
std::vector<double> b;
b.resize(MaxElement + 1);
a.push_back(b);
}
for (int i = 0; i < MaxElement; i++)
{
for (int j = 0; j < MaxElement; j++)
a[i][j] = cv::pow(points_x[i + 1], MaxElement - j);
a[i][MaxElement] = points_y[i + 1] - f;
}
int i, j;
n = MaxElement;
for (j = 0; j < n; j++)
{
double max = 0;
double imax = 0;
for (i = j; i < n; i++)
{
if (imax < cv::abs(a[i][j])) {
imax = cv::abs(a[i][j]);
max = a[i][j];//得到各行中所在列最大元素
m = i;
}
}
if (cv::abs(a[j][j]) != max)
{
double b = 0;
for (int k = j; k < n + 1; k++) {
b = a[j][k];
a[j][k] = a[m][k];
a[m][k] = b;
}
}
for (int r = j; r < n + 1; r++)
{
a[j][r] = a[j][r] / max;//让该行的所在列除以所在列的第一个元素目的是让首元素为1
}
for (i = j + 1; i < n; i++)
{
double c = a[i][j];
if (c == 0.0) continue;
for (int s = j; s < n + 1; s++) {
a[i][s] = a[i][s] - a[j][s] * c;//前后行数相减使下一行或者上一行的首元素为0
}
}
}
for (i = n - 2; i >= 0; i--)
{
for (j = i + 1; j < n; j++)
{
a[i][n] = a[i][n] - a[j][n] * a[i][j];
}
}
std::vector<double> result;
for (int k = 0; k < n; k++)
result.push_back(a[k][n]);
result.push_back(f);
return result;
}
cv::Mat createLUT(const std::vector<cv::Mat>& mats, bool isTextCorrect)
{
int rows = mats[0].cols;
cv::Mat lut(rows, 256, CV_8UC1);
double max_val, min_val;
cv::minMaxIdx(mats[0], &min_val, nullptr);
cv::minMaxIdx(mats[1], nullptr, &max_val);
for (size_t i = 0; i < rows; i++)
{
std::vector<uchar> grayPoints;
for (size_t j = 0; j < mats.size(); j++)
grayPoints.push_back(mats[j].data[i]);
fittingLUT(grayPoints, static_cast<uchar>(min_val), static_cast<uchar>(max_val), lut.data + i * 256);
}
if (isTextCorrect)
{
std::vector<double> points_x = { 0, 25, 230, 255 }, points_y = { 0, 0, 255, 255 };
std::vector<double> coefficient = caculate(points_x, points_y);
uchar buffer[256];
for (int i = 0; i < 256; i++)
{
int temp = coefficient[0] * i * i * i + coefficient[1] * i * i + coefficient[2] * i + coefficient[3];
buffer[i] = static_cast<uchar>(cv::min(255, cv::max(0, temp)));
}
cv::Mat lut_lut(256, 1, CV_8UC1, buffer);
cv::LUT(lut, lut_lut, lut);
}
return lut;
}

View File

@ -0,0 +1,33 @@
#pragma once
#include <sstream>
#include <opencv2/opencv.hpp>
#include "CameraParam.h"
static cv::Mat lutGrayMat; //灰色校正值
static cv::Mat lutColorMat; //彩色校正值
static int offsetStep[12];
static int expStep[2][3];
void initStep();
cv::Mat calcLUT(const cv::Mat& black, const cv::Mat& white, bool isTextCorrection);
cv::Mat extractRepresentRow2(const cv::Mat& src);
void initLut(const std::string lutpath,bool iscolor);
cv::Mat createLUT(const std::vector<cv::Mat>& mats, bool isTextCorrect);
void correctColor(cv::Mat& src, int dpi,int mode,bool isText);
void creatLUTData(int dpi , int mode);
void creatLUTData(int dpi , int mode,FPGAConfigParam param);
FPGAConfigParam GetFpgaparam(int dpi,int mode);
void SaveFpgaparam(FPGAConfigParam& param);
cv::Mat create_lut(const cv::Mat& black, const cv::Mat& white,int dpi, bool colormode);
void correctColor(cv::Mat& src, int dpi, int mode,bool isText);

View File

@ -38,7 +38,7 @@ protected:
size_t length;
};
const int v4l_buffer_count = 5;
const int v4l_buffer_count = 3;
int v4l_width = 3100;
int v4l_height = 3100;
std::string dev_name;

View File

@ -172,6 +172,7 @@ void* GVideoISP1::read_frame(int timeout) {
LOG_TRACE(string_format("VIDIOC_QBUF sucess"));
}
LOG_TRACE(string_format("buf.index = %d,buf.addr = %p\n",buf.index,buffers[buf.index].start));
printf("\n readframe size = %d ",buffers[buf.index].length);
return buffers[buf.index].start;
}

View File

@ -3,10 +3,11 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <iostream>
#include "CImageMerge.h"
using namespace cv;
cv::Mat extractRepresentRow2(const cv::Mat &src)
cv::Mat extractRepresentRow(const cv::Mat &src)
{
printf("extractRepresentRow2 enter \n");
Mat src_temp(src.rows, src.step, CV_8UC1, src.data);
@ -137,9 +138,9 @@ cv::Mat create_lut(const cv::Mat &black, const cv::Mat &white, bool colormode, C
void initLut()
{
if(access(LUT_GRAY_LUT_PATH, F_OK) != -1)
lutGrayMat = cv::imread(LUT_GRAY_LUT_PATH, IMREAD_GRAYSCALE); //灰色校正值
lutGrayMat_old = cv::imread(LUT_GRAY_LUT_PATH, IMREAD_GRAYSCALE); //灰色校正值
if(access(LUT_COLOR_LUT_PATH, F_OK) != -1)
lutColorMat = cv::imread(LUT_COLOR_LUT_PATH, IMREAD_GRAYSCALE); //彩色校正值
lutColorMat_old = cv::imread(LUT_COLOR_LUT_PATH, IMREAD_GRAYSCALE); //彩色校正值
}
void correctColor(cv::Mat src, bool enhance)
@ -153,11 +154,11 @@ void correctColor(cv::Mat src, bool enhance)
if (src.type() == CV_8UC3)
{
patch = (src.cols * 3) / SIZE;
if (lutColorMat.empty())
if (lutColorMat_old.empty())
{
if (access(LUT_COLOR_LUT_PATH, F_OK) != -1)
{
lutColorMat = imread(LUT_COLOR_LUT_PATH, IMREAD_GRAYSCALE);
lutColorMat_old = imread(LUT_COLOR_LUT_PATH, IMREAD_GRAYSCALE);
}
else
{
@ -165,16 +166,16 @@ void correctColor(cv::Mat src, bool enhance)
return;
}
}
lutMat = lutColorMat;
lutMat = lutColorMat_old;
}
else
{
patch = (src.cols) / SIZE;
if (lutGrayMat.empty())
if (lutGrayMat_old.empty())
{
if (access(LUT_GRAY_LUT_PATH, F_OK) != -1)
{
lutGrayMat = imread(LUT_GRAY_LUT_PATH, IMREAD_GRAYSCALE);
lutGrayMat_old = imread(LUT_GRAY_LUT_PATH, IMREAD_GRAYSCALE);
}
else
{
@ -182,7 +183,7 @@ void correctColor(cv::Mat src, bool enhance)
return;
}
}
lutMat = lutGrayMat;
lutMat = lutGrayMat_old;
}
if (lutMat.empty())
{
@ -218,7 +219,7 @@ void creatLUTData(int mode, CISVendor vendor)
bMat = tbMat;
}
lut = create_lut(extractRepresentRow2(bMat), extractRepresentRow2(wMat), mode, vendor); // add by liuyong: 刘丁维提供 2019/4/12
lut = create_lut(extractRepresentRow(bMat), extractRepresentRow(wMat), mode, vendor); // add by liuyong: 刘丁维提供 2019/4/12
Mat dst(bMat.cols * bMat.channels(), 256, CV_8UC1);
memcpy(dst.data, lut.data, bMat.cols * bMat.channels() * 256);
cv::imwrite(lutsavePath, dst);
@ -261,7 +262,7 @@ cv::Mat GetMergeMat(void *data, int width, int height, int type)
return saveMat.clone();
}
//3399 旧版本 华凌cis拼接算法
cv::Mat GetMergeMat(cv::Mat& mat, int width, int height, int type)
{
if (mat.empty())
@ -288,6 +289,38 @@ cv::Mat GetMergeMat(cv::Mat& mat, int width, int height, int type)
return mat;
}
cv::Mat GetStitchMat(int pixtype,int width,int height,cv::Mat& mat){
cv::Mat dst;
cv::Mat ch_mats[3];
int dstwidth, dstheight;
width = width /3 /(pixtype == 1? 3:1);
height *=3;
dstwidth = width * 3;
dstheight = height / 3;
if (pixtype == IMAGE_COLOR)
{
//mat = cv::Mat(m_height / 3, m_width * 9, CV_8UC1, imgdata);
dst = cv::Mat(dstheight, dstwidth, CV_8UC3);
ch_mats[2] = mat(cv::Rect(width * 3 * 1, 0, width * 3, height / 3)); //R 对应红通道
ch_mats[1] = mat(cv::Rect(width * 3 * 2, 0, width * 3, height / 3)); //G 对应绿通道
ch_mats[0] = mat(cv::Rect(width * 3 * 0, 0, width * 3, height / 3)); //B 对应蓝通道
cv::merge(ch_mats, 3, dst);
for (int i = 0; i < 3; i++)
ch_mats[i].release();
return dst.clone();
}
else
{ //gray
return mat;
}
}
//3399 敦南cis 300 600 拼接算法
cv::Mat GetMergeMat(int dstwidth ,int dstheight,int type,cv::Mat& mat,std::uint32_t fpga_vs)
{
return CImageMerge().MergeImage(type==CV_8UC3,mat,dstwidth,dstheight,0x90001);
}
void savescannerinfo(ScannerNativeParam params)
{
jsonconfig().savescannerinfo(params);

View File

@ -4,10 +4,10 @@
#include "commondef.h"
static cv::Mat lutGrayMat; //灰色校正值
static cv::Mat lutColorMat; //彩色校正值
static cv::Mat lutGrayMat_old; //灰色校正值
static cv::Mat lutColorMat_old; //彩色校正值
cv::Mat extractRepresentRow2(const cv::Mat& src);
cv::Mat extractRepresentRow(const cv::Mat& src);
cv::Mat create_lut(const cv::Mat& black, const cv::Mat& white,bool colormode,CISVendor vendor);
@ -19,8 +19,13 @@ cv::Mat GetMergeMat(void* data,int width ,int height,int type);
cv::Mat GetMergeMat(cv::Mat& mat,int width ,int height,int type);
cv::Mat GetMergeMat(int dstwidth ,int dstheight,int type,cv::Mat& mat,std::uint32_t fpga_vs);
cv::Mat GetStitchMat(int pixtype,int width,int height,cv::Mat& mat);
void correctColor(cv::Mat src, bool enhance);
void creatLUTData(int mode,CISVendor vendor);
void savescannerinfo(ScannerNativeParam params);

View File

@ -9,6 +9,7 @@
#define SP_COLOR_DEFAULT 0x438
#define SP_GRAY_DEFAULT 0xca8
jsonconfig::jsonconfig()
{
}
@ -24,7 +25,7 @@ void jsonconfig::savecisconfig(HGCorrectConfigs configs)
auto ret = mkdir(JSON_CORRECTDIR_PATH, 0777);
if (ret != 0)
{
HG_LOG("make dir failed .path=%s \n", JSON_CORRECTDIR_PATH);
printf("make dir failed .path=%s \n", JSON_CORRECTDIR_PATH);
}
}
json m_json;
@ -100,6 +101,7 @@ HGCorrectConfigs jsonconfig::getcorrectconfigs()
std::ifstream i(JSON_CORRECTFILE_PATH);
auto pos = i.tellg();
i.seekg(0, std::ios::end);
//printf("file length =%d ", i.tellg());
if (i.tellg() <= 2)
{
cfs = getdefaultconfigs();
@ -226,17 +228,19 @@ void jsonconfig::savescannerinfo(ScannerNativeParam param)
m_json[S_INFO_PID] = (param.Pid);
std::ofstream o(JSON_SCANNER_INFO_FILE);
o << std::setw(4) << m_json << std::endl;
//printf("\n %s speedmode value = %d",JSON_SCANNER_INFO_FILE,param.speedmode);
}
ScannerNativeParam jsonconfig::getscannerinfo()
{
std::lock_guard<std::mutex> lc(mtx);
ScannerNativeParam snp;
if (access(JSON_SCANNER_INFO_DIR, 0) == -1)
{
auto ret = mkdir(JSON_SCANNER_INFO_DIR, 0777);
if (ret != 0)
{
HG_LOG("make dir failed .path=%s \n", JSON_SCANNER_INFO_DIR);
printf("make dir failed .path=%s \n", JSON_SCANNER_INFO_DIR);
}
}
@ -253,6 +257,7 @@ ScannerNativeParam jsonconfig::getscannerinfo()
i.seekg(0, std::ios::end);
//printf("file length =%d ", i.tellg());
if (i.tellg() <= 2)
{
snp = getdefaultscannerinfo();
@ -333,7 +338,7 @@ ScannerNativeParam jsonconfig::getscannerinfo()
if(!m_json[S_INFO_SLEEPTIME].is_null())
m_json[S_INFO_SLEEPTIME].get_to(snp.sleeptime);
else
snp.sleeptime = 900;
snp.sleeptime = 10800;
if(!m_json[S_INFO_CLR_MAXBRT].is_null())
m_json[S_INFO_CLR_MAXBRT].get_to(snp.clr_maxbright);
@ -357,8 +362,12 @@ ScannerNativeParam jsonconfig::getscannerinfo()
{
#ifdef G100
snp.Pid = 0x139;
#else
#elif defined G200
snp.Pid = 0x239;
#elif defined G300
snp.Pid = 0x339;
#else
snp.Pid = 0x439;
#endif
}
@ -366,6 +375,8 @@ ScannerNativeParam jsonconfig::getscannerinfo()
m_json[S_INFO_VID].get_to(snp.Vid);
else
snp.Vid = 0x3072;
//printf("vid = %d pid =%d \n",snp.Vid,snp.Pid );
return snp;
}
@ -385,14 +396,24 @@ ScannerNativeParam jsonconfig::getdefaultscannerinfo()
param.color_sp=0x27C;
param.speedmode = 100;
param.Pid = 0x0239;
#else
#elif defined G100
param.gray_sp=0x822; //G200 140 ppm 0x27c 0x781 G100 100 ppm 0x2B6 0x822
param.color_sp=0x2B6;
param.speedmode = 70;
param.Pid = 0x0139;
#elif defined G300
param.gray_sp=0x822;
param.color_sp=0x2B6;
param.speedmode = 40;
param.Pid = 0x0339;
#else
param.gray_sp=0x822;
param.color_sp=0x2B6;
param.speedmode = 50;
param.Pid = 0x0439;
#endif
param.Vid = 0x3072;
param.sleeptime=3600;
param.sleeptime=10800;
param.clr_maxbright = param.gray_maxbright = 200;
return param;

View File

@ -1,6 +1,7 @@
#pragma once
#include "json.hpp"
#include "commondef.h"
#include <mutex>
using json = nlohmann::json;
@ -18,4 +19,5 @@ public:
ScannerNativeParam getscannerinfo();
HGCorrectConfigs getdefaultconfigs();
ScannerNativeParam getdefaultscannerinfo();
std::mutex mtx;
};

View File

@ -0,0 +1,69 @@
#pragma once
#include <sstream>
enum class SysType
{
Sys_Linux_Debian=1,
Sys_Linux_Uos,
Sys_Android
};
enum class Scanner_Serial{
S_G100=1,
S_G200,
S_G300,
S_G300_UV,
S_G400
};
enum class SCPU
{
CPU_3288=1,
CPU_3399
};
enum class SMBType
{
MB_DRV_UNKNOWUN,
MB_DRV_8825,
MB_DRV_TMC216,
MB_DRV_ANLU,
MB_DRV_LATIACE
};
enum class HGCISType
{
CIS_UNKOWNUN,
CIS_HUALIN_MONO_V0,
CIS_DUNNAN_MONO_V0,
CIS_DUNNAN_COLOR_V0
};
enum class ScreenType
{
ST_None=1,
ST_SmallLcd,
ST_BigLcd,
ST_8Inch,
ST_7Inch
};
typedef struct Scanner_SysInfo
{
SCPU CPU;//3288 3399
SysType Systype;
ScreenType Screentype;
unsigned int MtBoardVersion;
SMBType MtType;
unsigned int FPGAVersion;
HGCISType Cistype;
unsigned int ResSup[3];//分辨率支持
unsigned int MemTotal;//单位 MB
unsigned int DiskTotal;//单位 MB
unsigned int DiskUsed;//已使用空间
std::string KernelVersion;
unsigned int Have_EthernPort;
std::string ServiceVersion;
float UsbProtocol;//1.0 2.0 2.xx
}ScannerSysInfo;

View File

@ -5,6 +5,6 @@ target("capimage")
add_files("*.cpp")
add_deps("regs", "deviceio", "conf", "applog", {public = true})
add_includedirs(".", { public = true})
add_links("opencv_core", "opencv_highgui", "opencv_imgproc", { public = true })
add_links("opencv_core", "opencv_imgcodecs", "opencv_highgui", "opencv_imgproc", { public = true })
add_syslinks("pthread")
add_packages("common")

View File

@ -3,7 +3,6 @@
#include <fstream>
#include <memory>
#define G300
template <typename T>
void write_dev(std::string path, T value)

View File

@ -3,35 +3,30 @@
#include <unistd.h>
#include <fcntl.h>
#include <poll.h>
#include <sys/epoll.h>
#include <thread>
#include <iostream>
#include "StopWatch.h"
#include <errno.h>
#include <stdlib.h>
#include "applog.h"
#include "stringex.hpp"
static const std::string loggername = "PinMonitor";
PinMonitor::PinMonitor(unsigned int pinNum, std::function<void(int)> call_back)
: pin(pinNum)
: pin(pinNum)
{
LOG_INIT();
pin.setDirection(Gpio::in);
pin.setEdge(Gpio::falling);
this->call_back = call_back;
thread_monitor = std::thread(&PinMonitor::monitor, this);
//printf("PinMonitor threadid = %d \n",thread_monitor.get_id());
// int priority=sched_get_priority_max(SCHED_FIFO);
// if(priority==-1)
// {
// printf("sched_get_priority_max error \n");
// }
// thparm.sched_priority = priority;
// if(pthread_setschedparam(thread_monitor.native_handle(),SCHED_FIFO,&thparm))
// {
// printf("failed to error set pthread_setschedparam \n");
// }
sched_param thparm;
int priority=sched_get_priority_max(SCHED_FIFO);
if(priority==-1)
{
printf("sched_get_priority_max error \n");
}
thparm.sched_priority = priority;
if(pthread_setschedparam(thread_monitor.native_handle(),SCHED_FIFO,&thparm))
{
printf("failed to error set pthread_setschedparam \n");
}
}
PinMonitor::~PinMonitor()
@ -66,20 +61,15 @@ void PinMonitor::monitor()
{
lseek(pfd.fd, 0, SEEK_SET);
num = read(pfd.fd, buf, 8);
buf[num - 1] = '\0';
ret = atoi(buf);
//LOG_TRACE("poll call");
if (call_back)
{
sw.reset();
call_back(pin.getPort());
LOG_TRACE(string_format("poll call times = %.2f \n",sw.elapsed_ms()));
}
if (call_back)
call_back(pin.getPort());
sw.reset();
while(sw.elapsed_ms() < 10)
while(sw.elapsed_ms() < 30)
{
ret = poll(&pfd, 1, 1);
if (ret > 0)
@ -88,43 +78,11 @@ void PinMonitor::monitor()
buf[num - 1] = '\0';
ret = atoi(buf);
//printf("pMonitor nread = %d ret val = %d \n",num,ret);
}
}
}
}
}
}
close(pfd.fd);
// int n;
// int epfd = epoll_create(1);
// int fd = open(pin.getValuePath().c_str(), O_RDONLY);
// char buf[8];
// //printf("open returned %d: %s\n", fd, strerror(errno));
// if (fd > 0)
// {
// struct epoll_event ev;
// struct epoll_event events;
// ev.events = EPOLLPRI;
// ev.data.fd = fd;
// n = epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev);
// while (bMonitor)
// {
// n = epoll_wait(epfd, &events, 1, 1000);
// if (n > 0)
// {
// n = lseek(fd, 0, SEEK_SET);
// n = read(fd, buf, 8);
// buf[n - 1] = '\0';
// auto ret = atoi(buf);
// if (call_back)
// call_back(pin.getPort());
// }
// }
// }
// close(fd);
}

View File

@ -22,18 +22,22 @@ MemoryPtr BmpImageEncode::encode(cv::Mat &image)
return mem;
}
JpegImageEncode::JpegImageEncode(bool bwimg)
JpegImageEncode::JpegImageEncode(bool bwimg, int dpi)
{
// if (!bwimg)
// {
// compression_params.push_back(cv::IMWRITE_JPEG_QUALITY);
// compression_params.push_back(100);
// }
// else{
// compression_params.push_back(/*CV_IMWRITE_PNG_STRATEGY*/17);
// compression_params.push_back(cv::IMWRITE_PNG_STRATEGY_FIXED);
// }
// m_bwimg = bwimg;
if (!bwimg)
{
compression_params.push_back(cv::IMWRITE_JPEG_QUALITY);
compression_params.push_back(100);
compression_params.push_back(/*cv::CV_IMWRITE_JPEG_RESOLUTION_X*/7);
compression_params.push_back(dpi);
compression_params.push_back(/*cv::CV_IMWRITE_JPEG_RESOLUTION_Y*/8);
compression_params.push_back(dpi);
}
else{
compression_params.push_back(/*CV_IMWRITE_PNG_STRATEGY*/17);
compression_params.push_back(cv::IMWRITE_PNG_STRATEGY_FIXED);
}
m_bwimg = bwimg;
}
JpegImageEncode::~JpegImageEncode()
@ -42,11 +46,11 @@ JpegImageEncode::~JpegImageEncode()
MemoryPtr JpegImageEncode::encode(cv::Mat &image)
{
VectorMemroyPtr mem = VectorMemroyPtr(new VectorMemroy());
StopWatch sw;
// StopWatch sw;
printf("encode image(%d * %d): %p - %p\n", image.cols, image.rows, image.data, image.dataend);
// cv::imwrite("beforcompress.jpg",image);
// cv::imencode(m_bwimg ? ".png" : ".jpg", image, mem->buf(), compression_params);
cv::imencode(".png", image, mem->buf(), compression_params);
cv::imencode(".jpg", image, mem->buf(), compression_params);
//printf("encode time = %0.2f \n", sw.elapsed_ms());
return mem;

View File

@ -21,7 +21,7 @@ public:
class JpegImageEncode : public IImageEncode
{
public:
JpegImageEncode(bool bwimg);
JpegImageEncode(bool bwimg, int dpi);
virtual ~JpegImageEncode();
virtual MemoryPtr encode(cv::Mat& image);

View File

@ -0,0 +1,64 @@
#include "CuoZhiMotor.h"
#include <iostream>
CuoZhiMotor::CuoZhiMotor() : Motor(motorPorts_Cuozhi)
{
m_cfg.GetParams(0,MotorConfig::MTBDType::MT_DRV);
if(Dail().GetValue().dails.in_voltage4 == 0)
m_mttype = MotorConfig::MTBDType::MT_DRV;
else
m_mttype = MotorConfig::MTBDType::MT_TMC;
speedChange(0,1,1);
printf("\nCuo speed = %d ",m_mttype);
}
CuoZhiMotor::~CuoZhiMotor()
{
std::cout << "CuoZhiMotor::~CuoZhiMotor()" << std::endl;
}
void CuoZhiMotor::speedChange(int speed,int dpi ,int iscolor)
{
printf("\nCuo speed = %d dpi = %d iscolor = %d",speed,dpi,iscolor);
if(speed == 0xff)
{
if(m_mttype == MotorConfig::MTBDType::MT_DRV)
mspCuozhiForward = { .finalPeriod = 1427500,.Fmin = 2027500 ,.stepnum = 30 ,.a = 100 ,
.offset = 4 ,.finalDelay = 3000 };
else
mspCuozhiForward = { .finalPeriod = 1427500/4,.Fmin = 2027500/4 ,.stepnum = 30 ,.a = 100 ,
.offset = 4 ,.finalDelay = 3000 };
}
else{
auto params = m_cfg.GetMotorSpeedParams(false,m_mttype);
m_speedmode = speed;
for (int i = 0; i < params.size(); i++)
{
if (params[i].dpi == dpi &&
params[i].colormode == iscolor &&
params[i].speed == (speed+1))
{
mspCuozhiForward = { .finalPeriod = params[i].mt_param.finalPeriod,.Fmin = params[i].mt_param.Fmin,.stepnum = params[i].mt_param.stepnum,.a = params[i].mt_param.a,
.offset = params[i].mt_param.offset,.finalDelay = params[i].mt_param.finalDelay };
}
}
}
printf("\n mspCuozhiForward.finalPeriod %d, mspCuozhiForward.Fmin %d, mspCuozhiForward.stepnum %f , mspCuozhiForward.a %f, mspCuozhiForward.offset %f , mspCuozhiForward.finalDelay %f",
mspCuozhiForward.finalPeriod, mspCuozhiForward.Fmin, mspCuozhiForward.stepnum, mspCuozhiForward.a, mspCuozhiForward.offset, mspCuozhiForward.finalDelay);
delays_forward = speedup_cfg(mspCuozhiForward.finalPeriod, mspCuozhiForward.Fmin, mspCuozhiForward.stepnum, mspCuozhiForward.a, mspCuozhiForward.offset, mspCuozhiForward.finalDelay);
// if(cuoZhiForwardFinalPeriod.find(dpi) == cuoZhiForwardFinalPeriod.end())
// dpi = 1;
// mspCuozhiForward = { .finalPeriod = cuoZhiForwardFinalPeriod.at(dpi)[m_speedmode],.Fmin = cuoZhiFmin.at(dpi)[m_speedmode],
// .stepnum = cuoZhiStepNum.at(dpi)[m_speedmode],.a = cuoZhiA.at(dpi)[m_speedmode],.offset = cuoZhiOffset.at(dpi)[m_speedmode],
// .finalDelay = cuoZhiFinalDelay.at(dpi)[m_speedmode] };
mspCuozhiBackward = { .finalPeriod = cuoZhiBackwardFinalPeriod.at(dpi)[m_speedmode],.Fmin = cuoZhiFmin.at(dpi)[m_speedmode],
.stepnum = cuoZhiStepNum.at(dpi)[m_speedmode],.a = cuoZhiA.at(dpi)[m_speedmode],.offset = cuoZhiOffset.at(dpi)[m_speedmode],
.finalDelay = cuoZhiFinalDelay.at(dpi)[m_speedmode] };
// delays_forward = speedup_cfg(mspCuozhiForward.finalPeriod, mspCuozhiForward.Fmin, mspCuozhiForward.stepnum, mspCuozhiForward.a,
// mspCuozhiForward.offset, mspCuozhiForward.finalDelay);
delays_backward = speedup_cfg(mspCuozhiBackward.finalPeriod, mspCuozhiBackward.Fmin, mspCuozhiBackward.stepnum, mspCuozhiBackward.a,
mspCuozhiBackward.offset, mspCuozhiBackward.finalDelay);
}

View File

@ -0,0 +1,92 @@
#pragma once
#include "Motor.h"
#include <thread>
class CuoZhiMotor : public Motor
{
public:
CuoZhiMotor();
~CuoZhiMotor();
void speedChange(int speed,int dpi ,int iscolor);
void reset() {
mspCuozhiBackward = {.finalPeriod = 827500, .Fmin = 1407750, .stepnum = 25, .a = 150, .offset = 8, .finalDelay = 3000};
mspCuozhiForward = {.finalPeriod = 627500, .Fmin = 1407750, .stepnum = 25, .a = 150, .offset = 8, .finalDelay = 3000};
if(m_mttype == MotorConfig::MTBDType::MT_TMC)
{
mspCuozhiBackward.finalPeriod /= 4;
mspCuozhiBackward.Fmin /= 4;
mspCuozhiForward.finalPeriod /= 4;
mspCuozhiForward.Fmin /= 4;
}
delays_forward = speedup_cfg(mspCuozhiForward.finalPeriod, mspCuozhiForward.Fmin, mspCuozhiForward.stepnum, mspCuozhiForward.a,
mspCuozhiForward.offset, mspCuozhiForward.finalDelay);
forward();
std::this_thread::sleep_for(std::chrono::milliseconds(300));
stop();
delays_backward = speedup_cfg(mspCuozhiBackward.finalPeriod, mspCuozhiBackward.Fmin, mspCuozhiBackward.stepnum, mspCuozhiBackward.a,
mspCuozhiBackward.offset, mspCuozhiBackward.finalDelay);
backward();
std::this_thread::sleep_for(std::chrono::milliseconds(20));
stop();
}
virtual void start() {
forward();
}
void forward() {
setDirection(1);
Motor::start(delays_forward, mspCuozhiForward);
}
void backward() {
setDirection(0);
Motor::start(delays_backward, mspCuozhiBackward);
}
private:
MotorConfig m_cfg;
const std::map<int,std::vector<int>> cuoZhiStepNum = {
{1,{23,25,30,30,30 }},
{2,{23,25,30,30,30 }},
{3,{23,25,30,30,30 }},
};
const std::map<int,std::vector<int>> cuoZhiForwardFinalPeriod = {
{1,{607500,537500,477500,435500,435500}},
{2,{607500,537500,517500,497500,477500}},
{3,{607500,537500,527500,477500,307500}},
};//627500,607500,587500,567500,547500,527500
const std::map<int,std::vector<int>> cuoZhiBackwardFinalPeriod = {
{1,{607500,537500,477500,395500,307500}},
{2,{607500,587500,527500,477500,307500}},
{3,{607500,587500,527500,477500,307500}},
};//707500,607500,587500,567500,547500,527500
const std::map<int,std::vector<int>> cuoZhiFmin = {
{1,{ 1407750,1407750,1407750,1407750,1407750 }},
{2,{ 1407750,1407750,1407750,1407750,1407750 }},
{3,{ 1407750,1407750,1407750,1407750,1407750 }},
};
const std::map<int,std::vector<int>> cuoZhiA = {
{1,{ 180,150,150,130,130 }},
{2,{ 180,150,150,130,130 }},
{3,{ 180,150,150,150,150 }},
};
const std::map<int,std::vector<int>> cuoZhiOffset = {
{1,{ 7,7,7,12,12 }},
{2,{ 7,7,7,7,7 }},
{3,{ 7,7,7,7,7 }},
};
const std::map<int,std::vector<int>> cuoZhiFinalDelay = {
{1,{ 3000,3000,3000,3000,3000 }},
{2,{ 3000,3000,3000,3000,3000 }},
{3,{ 3000,3000,3000,3000,3000 }},
};
MotorSpeedParam mspCuozhiForward;
MotorSpeedParam mspCuozhiBackward;
std::vector<int> delays_forward;
std::vector<int> delays_backward;
int m_speedmode;
};

View File

@ -0,0 +1,30 @@
#include "DevUtil.h"
#include <fstream>
#define IOEXPORTPATH "/sys/class/gpio/export"
#define PWMEXPORTPATH "/sys/class/pwm/pwmchip%d/export"
int read_dev_i(std::string path) {
int val = -1;
std::ifstream ifin(path.c_str());
ifin >> val;
return val;
}
std::string read_dev_s(std::string path) {
std::string val;
std::ifstream ifin(path.c_str());
ifin >> val;
return val;
}
DeviceExport::DeviceExport()
{
int num = sizeof(ports) / sizeof(ports[0]);
for (int i = 0; i < num; i++)
write_dev(IOEXPORTPATH, ports[i]);
num = sizeof(pwms) / sizeof(pwms[0]);
for (int i = 0; i < num; i++)
write_dev(string_format(PWMEXPORTPATH, pwms[i]), 0);
printf("DeviceExport::DeviceExport().\n");
}

View File

@ -0,0 +1,57 @@
#pragma once
#include <string>
#include <fstream>
#include <memory>
#include "stringex.hpp"
template<typename T>
void write_dev(std::string path, T value) {
std::ofstream ofout(path);
ofout << value;
ofout.close();
}
extern int read_dev_i(std::string path);
extern std::string read_dev_s(std::string path);
enum PORTS
{
/* //RK3288 Motor GPIO
CuoZhiMotor_Reset = 56, // GPIO2_A0 MOTO_BOT_RESET_N
CuoZhiMotor_Sleep = 57, // GPIO2_A1 MOTO_BOT_SLEEP_N
CuoZhiMotor_Enable = 58, // GPIO2_A2 MOTO_BOT_ENBL_N
CuoZhiMotor_Direction = 62, // GPIO2_A6 MOTO_BOT_DIR
CuoZhiMotor_Home = 184, // GPIO6_A0 MOTO_BOT_HOME_N
CuoZhiMotor_Fault = 185, // GPIO6_A1 MOTO_BOT_FAULT_N
ZouZhiMotor_Reset = 64, // GPIO2_B0 MOTO_TOP_RESET_N
ZouZhiMotor_Sleep = 65, // GPIO2_B1 MOTO_TOP_SLEEP_N
ZouZhiMotor_Enable = 66, // GPIO2_B2 MOTO_TOP_ENBL_N
ZouZhiMotor_Direction = 70, // GPIO2_B6 MOTO_TOP_DIR
ZouZhiMotor_Home = 186, // GPIO6_A2
ZouZhiMotor_Fault = 187, // GPIO6_A3
*/
//RK3399 Motor GPIO
MotorPower = 157, // GPIO4_D5 motor power
CuoZhiMotor_Reset = 151, // GPIO4_C7 BOT
CuoZhiMotor_Enable = 153, // GPIO4_D1 BOT
CuoZhiMotor_Direction = 152, // GPIO4_D0 BOT
ZouZhiMotor_Reset = 155, // GPIO4_D3 TOP
ZouZhiMotor_Enable = 154, // GPIO4_D2 TOP
ZouZhiMotor_Direction = 52, // GPIO1_C4 TOP
};
class DeviceExport {
public:
DeviceExport();
private:
const int ports[7] = { MotorPower, CuoZhiMotor_Reset, CuoZhiMotor_Enable, CuoZhiMotor_Direction,
ZouZhiMotor_Reset, ZouZhiMotor_Enable, ZouZhiMotor_Direction,
};
const int pwms[2] = { 1, 2 };
};

View File

@ -0,0 +1,79 @@
#include <iostream>
#include "Gpio.h"
#include "DevUtil.h"
#define IOPATH "%s/gpio%d/%s"
const std::string Gpio::falling = "falling";
const std::string Gpio::rising = "rising";
const std::string Gpio::both = "both";
const std::string Gpio::none = "none";
const std::string Gpio::in = "in";
const std::string Gpio::out = "out";
Gpio::Gpio(int port)
{
this->port = port;
path_value = string_format(IOPATH, path_gpiobase.c_str(), port, path_value.c_str());
path_edge = string_format(IOPATH, path_gpiobase.c_str(), port, path_edge.c_str());
path_direction = string_format(IOPATH, path_gpiobase.c_str(), port, path_direction.c_str());
path_active_low = string_format(IOPATH, path_gpiobase.c_str(), port, path_active_low.c_str());
printf("Gpio::Gpio(int port = %d) \n",port);
}
Gpio::~Gpio()
{
std::cout << "Gpio::~Gpio()" << std::endl;
}
int Gpio::getPort()
{
return port;
}
void Gpio::setValue(GpioLevel level)
{
write_dev(path_value, level);
}
Gpio::GpioLevel Gpio::getValue() {
return (Gpio::GpioLevel)read_dev_i(path_value);
}
std::string Gpio::getDirection()
{
return read_dev_s(path_direction);
}
void Gpio::setDirection(std::string direction)
{
write_dev(path_direction, direction);
}
void Gpio::setActive(GpioLevel level)
{
write_dev(path_active_low, level);
}
Gpio::GpioLevel Gpio::getActive()
{
return (GpioLevel)read_dev_i(path_active_low);
}
void Gpio::setEdge(std::string edge)
{
write_dev(path_edge, edge);
}
std::string Gpio::getEdge()
{
return read_dev_s(path_edge);
}
GpioOut::GpioOut(int port) : Gpio(port)
{
setDirection(out);
}

View File

@ -0,0 +1,53 @@
#pragma once
#include <string>
class Gpio {
public:
enum GpioLevel {
Low,
High
};
public:
static const std::string falling;
static const std::string rising;
static const std::string both;
static const std::string none;
static const std::string in;
static const std::string out;
public:
Gpio(int port);
~Gpio();
int getPort();
void setValue(GpioLevel level);
GpioLevel getValue();
std::string getDirection();
void setDirection(std::string direction);
void setActive(GpioLevel level);
GpioLevel getActive();
void setEdge(std::string edge);
std::string getEdge();
std::string getValuePath() {
return path_value;
}
private:
const std::string path_gpiobase = "/sys/class/gpio";
int port;
std::string path_value = "value";
std::string path_edge = "edge";
std::string path_direction = "direction";
std::string path_active_low = "active_low";
};
class GpioOut : public Gpio
{
public:
GpioOut(int port);
};

View File

@ -0,0 +1,69 @@
#include "Motor.h"
#include "DevUtil.h"
#include <vector>
#include <cmath>
#include <iostream>
const MotorPorts motorPorts_Zouzhi = { .reset = ZouZhiMotor_Reset, .enable = ZouZhiMotor_Enable, .dir = ZouZhiMotor_Direction,
.pwm = 1};
const MotorPorts motorPorts_Cuozhi = {.reset = CuoZhiMotor_Reset, .enable = CuoZhiMotor_Enable, .dir = CuoZhiMotor_Direction,
.pwm = 2 };
std::vector<int> speedup_cfg(int finalPeriod, int Fmin, int stepnum, int a, int offset, int finalDelay) {
std::vector<int> freqs;
int period = 0;
double delay = ((double)finalDelay) / 1000000.0;
double b = stepnum * delay;
for (int i = 0; i < stepnum; i++) {
b = b - delay;
period = (int)(finalPeriod + (Fmin - finalPeriod) / (1 + exp(-a * b + offset)));
freqs.push_back(period);
//printf("\n period %d",period);
}
return freqs;
}
Motor::Motor(MotorPorts motorPorts)
: powerpin(MotorPower),resetPin(motorPorts.reset),enablePin(motorPorts.enable),dirPin(motorPorts.dir),pwm(motorPorts.pwm)
{
powerpin.setDirection(Gpio::out);
resetPin.setDirection(Gpio::out);
enablePin.setDirection(Gpio::out);
dirPin.setDirection(Gpio::out);
powerpin.setValue(Gpio::High);
resetPin.setValue(Gpio::High);
enablePin.setValue(Gpio::High);
std::cout << "Motor::Motor(MotorPorts motorPorts)" << std::endl;
}
Motor:: ~Motor()
{
stop();
std::cout << "Motor::~Motor()" << std::endl;
}
void Motor::start() {
enablePin.setValue(Gpio::Low);
pwm.enable(true);
}
void Motor::stop() {
enablePin.setValue(Gpio::High);
pwm.enable(false);
}
void Motor::pause() {
enablePin.setValue(Gpio::Low);
pwm.enable(false);
}
void Motor::setDirection(int dir) {
dirPin.setValue((Gpio::GpioLevel)dir);
}
void Motor::setSpeed(int value) {
pwm.setFreq(value);
}

View File

@ -0,0 +1,72 @@
#pragma once
#include <vector>
#include <thread>
#include <map>
#include "Gpio.h"
#include "Pwm.h"
#include "MotorConfig.h"
#include "commondef.h"
#include "dailex.hpp"
struct MotorPorts
{
int reset;
int enable;
int dir;
int pwm;
};
extern const MotorPorts motorPorts_Zouzhi;
extern const MotorPorts motorPorts_Cuozhi;
class Motor
{
public:
Motor(MotorPorts motorPorts);
virtual ~Motor();
protected:
Gpio powerpin;
Gpio resetPin;
//Gpio sleepPin;
Gpio enablePin;
Gpio dirPin;
//Gpio homePin;
//Gpio faultPin;
Pwm pwm;
MotorConfig::MTBDType m_mttype;
void start(std::vector<int>& delay_s, const MotorSpeedParam& msp)
{
if (!delay_s.empty()) {
std::vector<int>::iterator iter = delay_s.begin();
enablePin.setValue(Gpio::Low);
pwm.setFreq(PWM_PERIOD / (*iter));
pwm.enable(true);
std::this_thread::sleep_for(std::chrono::microseconds((int)msp.finalDelay));
while (++iter != delay_s.end()) {
pwm.setFreq(PWM_PERIOD / (*iter));
std::this_thread::sleep_for(std::chrono::microseconds((int)msp.finalDelay));
}
}
pwm.setFreq(PWM_PERIOD / msp.finalPeriod);
}
public:
virtual void start();
void stop();
void pause();
void setDirection(int dir);
void setSpeed(int value);
static void enablePower(bool bEnable);
};
extern std::vector<int> speedup_cfg(int finalPeriod, int Fmin, int stepnum, int a, int offset, int finalDelay);

View File

@ -0,0 +1,195 @@
#include "MotorConfig.h"
#include <sys/stat.h>
#include <fstream>
#include <iostream>
#include <iomanip>
using namespace std;
MotorConfig::MotorConfig()
{
initconfigfile();
}
MotorConfig::~MotorConfig()
{
}
std::string MotorConfig::GetParams(bool bzouzhi, MTBDType mttype)
{
std::string j_str;
json j;
if (mttype == MTBDType::MT_TMC)
{
std::ifstream i(bzouzhi ? MT_TMC216_ZOU_PATH : MT_TMC216_CUO_PATH);
i >> j;
j_str = j.dump();
}
else
{
std::ifstream i(bzouzhi ? MT_DRV888_ZOU_PATH : MT_DRV888_CUO_PATH);
i >> j;
j_str = j.dump();
}
return j_str;
}
void MotorConfig::SetParams(bool bzouzhi, MTBDType mttype, MotorSpeedParamEx &param)
{
std::string path;
auto params = GetMotorSpeedParams(bzouzhi, mttype);
for (int i = 0; i < params.size(); i++)
{
if (params[i].dpi == param.dpi &&
params[i].colormode == param.colormode &&
params[i].speed == param.speed)
{
params[i] = param;
}
}
json j = json::array();
for (int i = 0; i < params.size(); i++)
{
json t_j;
to_json(params[i], t_j);
j.push_back(t_j);
}
if (mttype == MTBDType::MT_TMC)
path = bzouzhi?MT_TMC216_ZOU_PATH:MT_TMC216_CUO_PATH;
else
path = bzouzhi?MT_DRV888_ZOU_PATH:MT_DRV888_CUO_PATH;
ofstream ofs(path);
ofs << std::setw(4) << j << std::endl;
}
std::vector<MotorSpeedParamEx> MotorConfig::GetMotorSpeedParams(bool bzouzhi, MTBDType mttype)
{
std::vector<MotorSpeedParamEx> ret;
if (mttype == MTBDType::MT_TMC)
{
std::ifstream i(bzouzhi ? MT_TMC216_ZOU_PATH : MT_TMC216_CUO_PATH);
json j;
i >> j;
for (json::iterator it = j.begin(); it != j.end(); ++it)
{
auto tmv = it.value();
MotorSpeedParamEx param;
from_json(tmv, param);
ret.push_back(param);
}
}
else
{
std::ifstream i(bzouzhi ? MT_DRV888_ZOU_PATH : MT_DRV888_CUO_PATH);
json j;
i >> j;
for (json::iterator it = j.begin(); it != j.end(); ++it)
{
auto tmv = it.value();
MotorSpeedParamEx param;
from_json(tmv, param);
ret.push_back(param);
}
}
return ret;
}
void MotorConfig::initconfigfile()
{
struct stat buff;
for (int s = 0; s < m_jsonpaths.size(); s++)
{
if (stat(m_jsonpaths[s].c_str(), &buff) != 0) //不存在
{
{
json j = json::array();
for (int i = 1; i < 6; i++)
{
MotorSpeedParamEx param;
for (int k = 1; k < 4; k++)
{
// //float ratio = k == 1 ? 1 : (k == 2 ? 1.51 : 2.81);
// param.mt_param.finalPeriod = s >= 2 ? 586500 / 4 : 586500; // s < 2 drv888
// //param.mt_param.finalPeriod = s >= 2 ? 2000 / 4 : 2000; // s < 2 drv888
// param.mt_param.Fmin = s >= 2 ? 1607750 / 4 : 1607750;
// param.mt_param.stepnum = 30;
// param.mt_param.a = 200;
// param.mt_param.offset = 7;
// param.mt_param.finalDelay = 2500;
// param.mt_param.acceleration_time = 2;
// param.speed = i; // 0 gray 1 color
// param.dpi = k; // 1 200dpi 2 300dpi 3 600dpi
// param.sp = 1200;
for(int t = 0;t<2;t++)
{
//param.colormode = t;
param = m_motor_params[s*30+(i-1)*6+(k-1)*2+t];
json t_j;
to_json(param, t_j);
j.push_back(t_j);
}
}
}
ofstream ofs(m_jsonpaths[s]);
ofs << std::setw(4) << j << std::endl;
}
}
}
}
void MotorConfig::reset_json(){
// for(int i =0;i<m_jsonpaths.size();i++)
// remove(m_jsonpaths[i].c_str());
initconfigfile();
}
std::vector<MotorSpeedParamEx> MotorConfig::GetMotorSpeedParams(const std::string& json_str)
{
std::vector<MotorSpeedParamEx> ret;
if(json_str.length())
{
json j = json::parse(json_str);
for (json::iterator it = j.begin(); it != j.end(); ++it)
{
auto tmv = it.value();
MotorSpeedParamEx param;
from_json(tmv, param);
ret.push_back(param);
}
}
return ret;
}
void MotorConfig::to_json(MotorSpeedParamEx &param, json &j)
{
j = json{
{"A", param.mt_param.a},
{"FINALDELAY", param.mt_param.finalDelay},
{"FINALPERIOD", param.mt_param.finalPeriod},
{"FMIN", param.mt_param.Fmin},
{"OFFSET", param.mt_param.offset},
{"STEPNUM", param.mt_param.stepnum},
{"DPI", param.dpi},
{"COLORMODE", param.colormode},
{"ACCELERATIONTIME",param.mt_param.acceleration_time},
{"SPEED", param.speed},
{"SP",param.sp}};
}
void MotorConfig::from_json(json &j, MotorSpeedParamEx &param)
{
j.at("A").get_to(param.mt_param.a);
j.at("FINALDELAY").get_to(param.mt_param.finalDelay);
j.at("FINALPERIOD").get_to(param.mt_param.finalPeriod);
j.at("FMIN").get_to(param.mt_param.Fmin);
j.at("OFFSET").get_to(param.mt_param.offset);
j.at("STEPNUM").get_to(param.mt_param.stepnum);
j.at("DPI").get_to(param.dpi);
j.at("ACCELERATIONTIME").get_to(param.mt_param.acceleration_time);
j.at("COLORMODE").get_to(param.colormode);
j.at("SPEED").get_to(param.speed),
j.at("SP").get_to(param.sp);
}

View File

@ -0,0 +1,367 @@
#pragma once
#include <vector>
#include "json.hpp"
#include <tuple>
#include <commondef.h>
using json= nlohmann::json;
struct MotorSpeedParam
{
int finalPeriod;
int Fmin;
float stepnum;
float a;
float offset;
float finalDelay;
float acceleration_time;
};
struct MotorSpeedParamEx
{
MotorSpeedParam mt_param;
int speed;
int colormode;
int dpi;
int sp;
};
#ifndef WIN32
#define MT_DRV888_CUO_PATH "/usr/local/huago/drv888_cuo.json"
#define MT_DRV888_ZOU_PATH "/usr/local/huago/drv888_zou.json"
#define MT_TMC216_CUO_PATH "/usr/local/huago/tmc216_cuo.json"
#define MT_TMC216_ZOU_PATH "/usr/local/huago/tmc216_zou.json"
#else
#define MT_DRV888_CUO_PATH "drv888_cuo.json"
#define MT_DRV888_ZOU_PATH "drv888_zou.json"
#define MT_TMC216_CUO_PATH "tmc216_cuo.json"
#define MT_TMC216_ZOU_PATH "tmc216_zou.json"
#endif
#ifdef G300
static std::vector<MotorSpeedParamEx> m_motor_params{
//drv_888
{{.finalPeriod = 754200, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 1,.sp = 5910},//40 ppm 搓纸
{{.finalPeriod = 754200, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 1,.sp = 1970},
{{.finalPeriod = 804300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 2,.sp = 3942},
{{.finalPeriod = 804300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 2,.sp = 1314},
{{.finalPeriod = 804300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 3,.sp = 3942},
{{.finalPeriod = 804300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 3,.sp = 1314},
{{.finalPeriod = 705300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 1,.sp = 4509},//50 ppm 搓纸
{{.finalPeriod = 705300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 1,.sp = 1503},
{{.finalPeriod = 705300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 2,.sp = 3009},
{{.finalPeriod = 705300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 2,.sp = 1003},
{{.finalPeriod = 705300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 3,.sp = 3009},
{{.finalPeriod = 705300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 3,.sp = 1003},
{{.finalPeriod = 656200, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 1,.sp = 3702},//60 ppm 搓纸
{{.finalPeriod = 656200, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 1,.sp = 1234},
{{.finalPeriod = 656300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 2,.sp = 2446},
{{.finalPeriod = 656300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 2,.sp = 822},
{{.finalPeriod = 656300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 3,.sp = 2446},
{{.finalPeriod = 656300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 3,.sp = 822},
{{.finalPeriod = 527200, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 1,.sp = 3129},//70 ppm 搓纸
{{.finalPeriod = 527200, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 1,.sp = 1043},
{{.finalPeriod = 527300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 2,.sp = 2446},
{{.finalPeriod = 527300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 2,.sp = 859},
{{.finalPeriod = 527300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 3,.sp = 2446},
{{.finalPeriod = 527300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 3,.sp = 859},
{{.finalPeriod = 527200, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 1,.sp = 3129},//80 ppm 搓纸
{{.finalPeriod = 527200, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 1,.sp = 1043},
{{.finalPeriod = 527300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 2,.sp = 2446},
{{.finalPeriod = 527300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 2,.sp = 859},
{{.finalPeriod = 527300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 3,.sp = 2446},
{{.finalPeriod = 527300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 3,.sp = 859},
{{.finalPeriod = 504200, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 1,.sp = 5910},//40 ppm 走纸
{{.finalPeriod = 504200, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 1,.sp = 1970},
{{.finalPeriod = 504300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 2,.sp = 3942},
{{.finalPeriod = 504300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 2,.sp = 1314},
{{.finalPeriod = 504300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 3,.sp = 3942},
{{.finalPeriod = 504300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 3,.sp = 1314},
{{.finalPeriod = 385300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 1,.sp = 4509},//50 ppm 走纸
{{.finalPeriod = 385300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 1,.sp = 1503},
{{.finalPeriod = 385300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 2,.sp = 3009},
{{.finalPeriod = 385300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 2,.sp = 1003},
{{.finalPeriod = 385300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 3,.sp = 3009},
{{.finalPeriod = 385300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 3,.sp = 1003},
{{.finalPeriod = 316200, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 1,.sp = 3702},//60 ppm 走纸
{{.finalPeriod = 316200, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 1,.sp = 1234},
{{.finalPeriod = 316300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 2,.sp = 2466},
{{.finalPeriod = 316300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 2,.sp = 822},
{{.finalPeriod = 316300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 3,.sp = 2466},
{{.finalPeriod = 316300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 3,.sp = 822},
{{.finalPeriod = 267200, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 1,.sp = 3129},//70 ppm 走纸
{{.finalPeriod = 267200, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 1,.sp = 1043},
{{.finalPeriod = 316300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 2,.sp = 2466},
{{.finalPeriod = 316300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 2,.sp = 822},
{{.finalPeriod = 316300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 3,.sp = 2466},
{{.finalPeriod = 316300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 3,.sp = 822},
{{.finalPeriod = 267200, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 1,.sp = 3129},//80 ppm 走纸
{{.finalPeriod = 267200, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 1,.sp = 1043},
{{.finalPeriod = 316300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 2,.sp = 2466},
{{.finalPeriod = 316300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 2,.sp = 822},
{{.finalPeriod = 316300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 3,.sp = 2466},
{{.finalPeriod = 316300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 3,.sp = 822},
//tmc
{{.finalPeriod = 184200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 1,.sp = 5814},//40 ppm 搓纸
{{.finalPeriod = 184200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 1,.sp = 1938},
{{.finalPeriod = 204300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 2,.sp = 3879},
{{.finalPeriod = 204300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 2,.sp = 1293},
{{.finalPeriod = 204300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 3,.sp = 3879},
{{.finalPeriod = 204300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 3,.sp = 1293},
{{.finalPeriod = 185200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 1,.sp = 4455},//50 ppm 搓纸
{{.finalPeriod = 185200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 1,.sp = 1485},
{{.finalPeriod = 185200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 2,.sp = 2975},
{{.finalPeriod = 185200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 2,.sp = 991},
{{.finalPeriod = 185200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 3,.sp = 2972},
{{.finalPeriod = 185200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 3,.sp = 991},
{{.finalPeriod = 166200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 1,.sp = 3570},//60 ppm 搓纸
{{.finalPeriod = 166200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 1,.sp = 1190},
{{.finalPeriod = 166300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 2,.sp = 2445},
{{.finalPeriod = 166300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 2,.sp = 815},
{{.finalPeriod = 166300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 3,.sp = 2445},
{{.finalPeriod = 166300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 3,.sp = 815},
{{.finalPeriod = 137200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 1,.sp = 3126},//70 ppm 搓纸
{{.finalPeriod = 137200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 1,.sp = 1042},
{{.finalPeriod = 166300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 2,.sp = 2445},
{{.finalPeriod = 166300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 2,.sp = 815},
{{.finalPeriod = 166300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 3,.sp = 2445},
{{.finalPeriod = 166300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 3,.sp = 815},
{{.finalPeriod = 137200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 1,.sp = 3126},//80 ppm 搓纸
{{.finalPeriod = 137200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 1,.sp = 1042},
{{.finalPeriod = 166300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 2,.sp = 2445},
{{.finalPeriod = 166300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 2,.sp = 815},
{{.finalPeriod = 166300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 3,.sp = 2445},
{{.finalPeriod = 166300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 3,.sp = 815},
{{.finalPeriod = 124200, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 1,.sp = 5814},//40 ppm 走纸
{{.finalPeriod = 124200, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 1,.sp = 1938},
{{.finalPeriod = 124300, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 2,.sp = 3879},
{{.finalPeriod = 124300, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 2,.sp = 1293},
{{.finalPeriod = 124300, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 3,.sp = 3879},
{{.finalPeriod = 124300, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 3,.sp = 1293},
{{.finalPeriod = 95200, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 1,.sp = 4455},//50 ppm 走纸
{{.finalPeriod = 95200, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 1,.sp = 1485},
{{.finalPeriod = 95200, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 2,.sp = 2975},
{{.finalPeriod = 95200, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 2,.sp = 991},
{{.finalPeriod = 95200, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 3,.sp = 2975},
{{.finalPeriod = 95200, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 3,.sp = 991},
{{.finalPeriod = 76200, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 1,.sp = 3570},//60 ppm 走纸
{{.finalPeriod = 76200, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 1,.sp = 1190},
{{.finalPeriod = 78300, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 2,.sp = 2445},
{{.finalPeriod = 78300, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 2,.sp = 815},
{{.finalPeriod = 78300, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 3,.sp = 2445},
{{.finalPeriod = 78300, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 3,.sp = 815},
{{.finalPeriod = 66720, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 1,.sp = 3126},//70 ppm 走纸
{{.finalPeriod = 66720, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 1,.sp = 1042},
{{.finalPeriod = 78300, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 2,.sp = 2445},
{{.finalPeriod = 78300, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 2,.sp = 815},
{{.finalPeriod = 78300, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 3,.sp = 2445},
{{.finalPeriod = 78300, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 3,.sp = 815},
{{.finalPeriod = 66720, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 1,.sp = 3126},//80 ppm 走纸
{{.finalPeriod = 66720, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 1,.sp = 1042},
{{.finalPeriod = 78300, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 2,.sp = 2445},
{{.finalPeriod = 78300, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 2,.sp = 815},
{{.finalPeriod = 78300, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 3,.sp = 2445},
{{.finalPeriod = 78300, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 3,.sp = 815},
};
#else
static std::vector<MotorSpeedParamEx> m_motor_params{
//drv_888
{{.finalPeriod = 754200, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 1,.sp = 7290},//40 ppm 搓纸
{{.finalPeriod = 754200, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 1,.sp = 2430},
{{.finalPeriod = 804300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 2,.sp = 4869},
{{.finalPeriod = 804300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 2,.sp = 1623},
{{.finalPeriod = 1006000, .Fmin = 1407500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 3000, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 3,.sp = 4749},
{{.finalPeriod = 1006000, .Fmin = 1407500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 3000, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 3,.sp = 1583},
{{.finalPeriod = 735200, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 1,.sp = 5870},//50 ppm 搓纸
{{.finalPeriod = 735200, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 1,.sp = 1950},
{{.finalPeriod = 735300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 2,.sp = 3909},
{{.finalPeriod = 735300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 2,.sp = 1303},
{{.finalPeriod = 1006000, .Fmin = 1407500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 3000, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 3,.sp = 4749},
{{.finalPeriod = 1006000, .Fmin = 1407500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 3000, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 3,.sp = 1583},
{{.finalPeriod = 686200, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 1,.sp = 5004},//60 ppm 搓纸
{{.finalPeriod = 686200, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 1,.sp = 1688},
{{.finalPeriod = 706300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 2,.sp = 3248},
{{.finalPeriod = 706300, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 2,.sp = 1080},
{{.finalPeriod = 1006000, .Fmin = 1407500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 3000, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 3,.sp = 4749},
{{.finalPeriod = 1006000, .Fmin = 1407500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 3000, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 3,.sp = 1583},
{{.finalPeriod = 527200, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 1,.sp = 3864},//70 ppm 搓纸
{{.finalPeriod = 527200, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 1,.sp = 1287},
{{.finalPeriod = 527200, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 2,.sp = 2580},
{{.finalPeriod = 527200, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 2,.sp = 859},
{{.finalPeriod = 1006000, .Fmin = 1407500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 3000, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 3,.sp = 4749},
{{.finalPeriod = 1006000, .Fmin = 1407500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 3000, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 3,.sp = 1583},
{{.finalPeriod = 508200, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 1,.sp = 3735},//80 ppm 搓纸
{{.finalPeriod = 508200, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 1,.sp = 1245},
{{.finalPeriod = 508200, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 2,.sp = 2490},
{{.finalPeriod = 508200, .Fmin = 1407500, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 2,.sp = 830},
{{.finalPeriod = 1006000, .Fmin = 1407500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 3000, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 3,.sp = 4749},
{{.finalPeriod = 1006000, .Fmin = 1407500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 3000, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 3,.sp = 1583},
{{.finalPeriod = 504200, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 1,.sp = 7290},//40 ppm 走纸
{{.finalPeriod = 504200, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 1,.sp = 2430},
{{.finalPeriod = 504300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 2,.sp = 4869},
{{.finalPeriod = 504300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 2,.sp = 1623},
{{.finalPeriod = 656000, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 7, .finalDelay = 3000, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 3,.sp = 4749},
{{.finalPeriod = 656000, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 7, .finalDelay = 3000, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 3,.sp = 1583},
{{.finalPeriod = 385200, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 1,.sp = 6050},//50 ppm 走纸
{{.finalPeriod = 405200, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 1,.sp = 1950},
{{.finalPeriod = 405300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 2,.sp = 3909},
{{.finalPeriod = 405300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 2,.sp = 1303},
{{.finalPeriod = 656000, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 7, .finalDelay = 3000, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 3,.sp = 4749},
{{.finalPeriod = 656000, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 7, .finalDelay = 3000, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 3,.sp = 1583},
{{.finalPeriod = 346200, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 1,.sp = 5004},//60 ppm 走纸
{{.finalPeriod = 346200, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 1,.sp = 1688},
{{.finalPeriod = 336300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 2,.sp = 3248},
{{.finalPeriod = 336300, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 2,.sp = 1080},
{{.finalPeriod = 656000, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 7, .finalDelay = 3000, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 3,.sp = 4749},
{{.finalPeriod = 656000, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 7, .finalDelay = 3000, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 3,.sp = 1583},
{{.finalPeriod = 267200, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 1,.sp = 3864},//70 ppm 走纸
{{.finalPeriod = 267200, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 1,.sp = 1287},
{{.finalPeriod = 267200, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 2,.sp = 2580},
{{.finalPeriod = 267200, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 2,.sp = 859},
{{.finalPeriod = 656000, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 7, .finalDelay = 3000, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 3,.sp = 4749},
{{.finalPeriod = 656000, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 7, .finalDelay = 3000, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 3,.sp = 1583},
{{.finalPeriod = 258200, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 1,.sp = 3735},//80 ppm 走纸
{{.finalPeriod = 258200, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 1,.sp = 1245},
{{.finalPeriod = 258200, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 2,.sp = 2490},
{{.finalPeriod = 258200, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2000, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 2,.sp = 830},
{{.finalPeriod = 656000, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 7, .finalDelay = 3000, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 3,.sp = 4749},
{{.finalPeriod = 656000, .Fmin = 1607500, .stepnum = 30, .a = 200, .offset = 7, .finalDelay = 3000, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 3,.sp = 1583},
//tmc
{{.finalPeriod = 184200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 1,.sp = 7200},//40 ppm 搓纸
{{.finalPeriod = 184200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 1,.sp = 2400},
{{.finalPeriod = 204300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 2,.sp = 4800},
{{.finalPeriod = 204300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 2,.sp = 1598},
{{.finalPeriod = 251600, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 3,.sp = 4760},
{{.finalPeriod = 251600, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 3,.sp = 1586},
{{.finalPeriod = 185200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 1,.sp = 6050},//50 ppm 搓纸
{{.finalPeriod = 185200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 1,.sp = 2026},
{{.finalPeriod = 185200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 2,.sp = 4053},
{{.finalPeriod = 185200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 2,.sp = 1350},
{{.finalPeriod = 251600, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 3,.sp = 4760},
{{.finalPeriod = 251600, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 3,.sp = 1586},
{{.finalPeriod = 176200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 1,.sp = 4978},//60 ppm 搓纸
{{.finalPeriod = 176200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 1,.sp = 1659},
{{.finalPeriod = 176300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 2,.sp = 3330},
{{.finalPeriod = 176300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 2,.sp = 1110},
{{.finalPeriod = 251600, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 3,.sp = 4760},
{{.finalPeriod = 251600, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 3,.sp = 1586},
{{.finalPeriod = 137200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 1,.sp = 3858},//70 ppm 搓纸
{{.finalPeriod = 137200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 1,.sp = 1286},
{{.finalPeriod = 137300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 2,.sp = 2570},
{{.finalPeriod = 137300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 2,.sp = 857},
{{.finalPeriod = 251600, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 3,.sp = 4760},
{{.finalPeriod = 251600, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 3,.sp = 1586},
{{.finalPeriod = 128200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 1,.sp = 3750},//80 ppm 搓纸
{{.finalPeriod = 128200, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 1,.sp = 1250},
{{.finalPeriod = 128300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 2,.sp = 2498},
{{.finalPeriod = 128300, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 2,.sp = 832},
{{.finalPeriod = 251600, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 3,.sp = 4760},
{{.finalPeriod = 251600, .Fmin = 351875, .stepnum = 30, .a = 150, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 3,.sp = 1586},
{{.finalPeriod = 124200, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 1,.sp = 7200},//40 ppm 走纸
{{.finalPeriod = 124200, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 1,.sp = 2400},
{{.finalPeriod = 124300, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 2,.sp = 4800},
{{.finalPeriod = 124300, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 2,.sp = 1598},
{{.finalPeriod = 164600, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 0,.dpi = 3,.sp = 4760},
{{.finalPeriod = 164600, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 1,.colormode = 1,.dpi = 3,.sp = 1586},
{{.finalPeriod = 105200, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 1,.sp = 6050},//50 ppm 走纸
{{.finalPeriod = 105200, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 1,.sp = 2026},
{{.finalPeriod = 105200, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 2,.sp = 4053},
{{.finalPeriod = 105200, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 2,.sp = 1350},
{{.finalPeriod = 164600, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 0,.dpi = 3,.sp = 4760},
{{.finalPeriod = 164600, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 2,.colormode = 1,.dpi = 3,.sp = 1586},
{{.finalPeriod = 86200, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 1,.sp = 4978},//60 ppm 走纸
{{.finalPeriod = 86200, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 1,.sp = 1659},
{{.finalPeriod = 86300, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 2,.sp = 3330},
{{.finalPeriod = 86300, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 2,.sp = 1110},
{{.finalPeriod = 164600, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 0,.dpi = 3,.sp = 4760},
{{.finalPeriod = 164600, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 3,.colormode = 1,.dpi = 3,.sp = 1586},
{{.finalPeriod = 66720, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 1,.sp = 3858},//70 ppm 走纸
{{.finalPeriod = 66720, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 1,.sp = 1286},
{{.finalPeriod = 66730, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 2,.sp = 2572},
{{.finalPeriod = 66730, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 2,.sp = 857},
{{.finalPeriod = 164600, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 0,.dpi = 3,.sp = 4760},
{{.finalPeriod = 164600, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 4,.colormode = 1,.dpi = 3,.sp = 1586},
{{.finalPeriod = 64820, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 1,.sp = 3750},//80 ppm 走纸
{{.finalPeriod = 64820, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 1,.sp = 1250},
{{.finalPeriod = 64830, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 2,.sp = 2498},
{{.finalPeriod = 64830, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 2,.sp = 832},
{{.finalPeriod = 164600, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 0,.dpi = 3,.sp = 4760},
{{.finalPeriod = 164600, .Fmin = 401875, .stepnum = 30, .a = 200, .offset = 9, .finalDelay = 2500, .acceleration_time =2},.speed = 5,.colormode = 1,.dpi = 3,.sp = 1586},
};
#endif
class MotorConfig
{
private:
std::vector<MotorSpeedParamEx> m_cuoParams;
std::vector<MotorSpeedParamEx> m_zouParams;
const std::vector<std::string> m_jsonpaths={
MT_DRV888_CUO_PATH,
MT_DRV888_ZOU_PATH,
MT_TMC216_CUO_PATH,
MT_TMC216_ZOU_PATH
};
public:
enum class MTBDType
{
MT_TMC,
MT_DRV
};
MotorConfig(/* args */);
~MotorConfig();
std::string GetParams(bool bzouzhi,MTBDType mttype);
void SetParams(bool bzouzhi,MTBDType mttype,MotorSpeedParamEx& param);
std::vector<MotorSpeedParamEx> GetMotorSpeedParams(bool bzouzhi,MTBDType mttype);
std::vector<MotorSpeedParamEx> GetMotorSpeedParams(const std::string& json_str);
void to_json(MotorSpeedParamEx& param,json& j);
void from_json(json& j,MotorSpeedParamEx& param);
void reset_json();
private:
void initconfigfile();
};

View File

@ -0,0 +1,60 @@
#pragma once
#include "CuoZhiMotor.h"
#include "ZouZhiMotor.h"
#include "MotorControl.h"
MotorControl::MotorControl()
{
m_zzm.reset(new ZouZhiMotor());
m_czm.reset(new CuoZhiMotor());
//m_czm->reset();
}
MotorControl::~MotorControl()
{
m_zzm->stop();
m_czm->stop();
m_czm.reset();
m_zzm.reset();
}
void MotorControl::MotorRun(MotorOption option)
{
switch (option)
{
case MotorOption::CZ_Reset :
m_czm->reset();
break;
case MotorOption::CZ_Forward :
m_czm->forward();
break;
case MotorOption::CZ_Backward :
m_czm->backward();
break;
case MotorOption::CZ_Pause:
m_czm->pause();
break;
case MotorOption::CZ_Stop :
m_czm->stop();
break;
case MotorOption::ZZ_Backward :
m_zzm->setDirection(1);
m_zzm->start();
break;
case MotorOption::ZZ_Forward :
m_zzm->setDirection(0);
m_zzm->start();
break;
case MotorOption::ZZ_Stop :
m_zzm->stop();
break;
default:
break;
}
}
void MotorControl::setzzspeed(int zuo_spmode,int dpi,int iscolor){
m_zzm->speedChange(zuo_spmode,dpi,iscolor);
}
void MotorControl::setczspeed(int cuo_spmode,int dpi,int iscolor){
m_czm->speedChange(cuo_spmode,dpi,iscolor);
}

View File

@ -0,0 +1,28 @@
#pragma once
class CuoZhiMotor;
class ZouZhiMotor;
struct MotorSpeedParam;
class MotorControl
{
public:
enum MotorOption : int{
CZ_Reset,
CZ_Forward,
CZ_Backward,
CZ_Pause,
CZ_Stop,
ZZ_Forward,
ZZ_Backward,
ZZ_Stop,
};
MotorControl();
~MotorControl();
void setzzspeed(int zuo_spmode,int dpi,int iscolor);
void setczspeed(int cuo_spmode,int dpi,int iscolor);
void MotorRun(MotorOption option);
private:
std::unique_ptr<CuoZhiMotor> m_czm;
std::unique_ptr<ZouZhiMotor> m_zzm;
};

View File

@ -0,0 +1,40 @@
#include "Pwm.h"
#include "DevUtil.h"
#include <iostream>
#define PWMPATH "%s%d/pwm0/%s"
Pwm::Pwm(int port)
{
path_enable = string_format(PWMPATH, path_base.c_str(), port, path_enable.c_str());
path_duty_cycle = string_format(PWMPATH, path_base.c_str(), port, path_duty_cycle.c_str());
path_period = string_format(PWMPATH, path_base.c_str(), port, path_period.c_str());
printf("Pwm::Pwm(int port = %d)\n",port);
}
Pwm::~Pwm()
{
std::cout << "Pwm::~Pwm()" << std::endl;
}
void Pwm::setFreq(int freq)
{
int value = PWM_PERIOD / freq;
write_dev(path_period, value);
write_dev(path_duty_cycle, value / 2);
}
int Pwm::getFreq()
{
return PWM_PERIOD/read_dev_i(path_period);
}
void Pwm::enable(bool bEnable)
{
write_dev(path_enable, bEnable);
}
bool Pwm::isEnable()
{
return (bool)read_dev_i(path_enable);
}

View File

@ -0,0 +1,22 @@
#pragma once
#include <string>
#define PWM_PERIOD 1000000000
class Pwm
{
public:
Pwm(int port);
~Pwm();
void setFreq(int freq);
int getFreq();
void enable(bool bEnable);
bool isEnable();
private:
const std::string path_base = "/sys/class/pwm/pwmchip";
std::string path_enable = "enable";
std::string path_duty_cycle = "duty_cycle";
std::string path_period = "period";
};

View File

@ -0,0 +1,48 @@
#include "ZouZhiMotor.h"
#include <thread>
#include <iostream>
ZouZhiMotor::ZouZhiMotor() : Motor(motorPorts_Zouzhi)
{
speedChange(0,1,1);
if(Dail().GetValue().dails.in_voltage4 == 0)
m_mttype = MotorConfig::MTBDType::MT_DRV;
else
m_mttype = MotorConfig::MTBDType::MT_TMC;
}
ZouZhiMotor::~ZouZhiMotor()
{
std::cout << "ZouZhiMotor::~ZouZhiMotor()" << std::endl;
}
void ZouZhiMotor::start()
{
Motor::start(delays, mspZhouzhi);
}
void ZouZhiMotor::speedChange(int speed,int dpi ,int iscolor)
{
// if(zouZhiFinalDelay.find(dpi)==zouZhiFinalDelay.end())
// dpi = 1;
// m_speedmode = speed;
// printf(" \n speed %d",speed);
// mspZhouzhi = { .finalPeriod = zouZhiFinalPeriod.at(dpi)[m_speedmode],.Fmin = zouZhiFmin.at(dpi)[m_speedmode],.stepnum = zouZhiStepNum.at(dpi)[m_speedmode],.a = zouZhiA.at(dpi)[m_speedmode],
// .offset = zouZhiOffset.at(dpi)[m_speedmode],.finalDelay = zouZhiFinalDelay.at(dpi)[m_speedmode] };
// std::cout<< ".finalPeriod = "<<zouZhiFinalPeriod.at(dpi)[m_speedmode]<<",.Fmin = "<<zouZhiFmin.at(dpi)[m_speedmode]<<",.stepnum = "<<zouZhiStepNum.at(dpi)[m_speedmode]<<",.a = "<<zouZhiA.at(dpi)[m_speedmode]<<
// ",.offset = "<< zouZhiOffset.at(dpi)[m_speedmode] <<",.finalDelay = "<<zouZhiFinalDelay.at(dpi)[m_speedmode]<<std::endl;
// printf("\nZuo speed = %d dpi = %d iscolor = %d",speed,dpi,iscolor);
auto params = m_cfg.GetMotorSpeedParams(true,m_mttype);
m_speedmode = speed;
for (int i = 0; i < params.size(); i++)
{
if (params[i].dpi == dpi &&
params[i].colormode == iscolor &&
params[i].speed == (speed+1))
{
mspZhouzhi = { .finalPeriod = params[i].mt_param.finalPeriod,.Fmin = params[i].mt_param.Fmin,.stepnum = params[i].mt_param.stepnum,.a = params[i].mt_param.a,
.offset = params[i].mt_param.offset,.finalDelay = params[i].mt_param.finalDelay };
}
}
delays = speedup_cfg(mspZhouzhi.finalPeriod, mspZhouzhi.Fmin, mspZhouzhi.stepnum, mspZhouzhi.a, mspZhouzhi.offset, mspZhouzhi.finalDelay);
}

View File

@ -0,0 +1,51 @@
#pragma once
#include "Motor.h"
class ZouZhiMotor : public Motor
{
public:
ZouZhiMotor();
virtual ~ZouZhiMotor();
virtual void start();
void speedChange(int speed,int dpi ,int iscolor);
private:
std::vector<int> delays;
MotorSpeedParam mspZhouzhi;
MotorConfig m_cfg;
int m_speedmode;
const std::map<int,std::vector<int>> zouZhiFinalPeriod ={
{1,{ 586500,420500,330000,245000,205000 }},
{2,{ 916500,656500,530500,386500,347000 }},
{3,{ 756500,756500,756500,756500,756500 }},
};//756500,556500,426500,336500,286500,230500 //265000
const std::map<int,std::vector<int>> zouZhiFmin ={
{1,{ 1607750,1607750,1607750,1607750,1607750 }},
{2,{ 1607750,1607750,1607750,1607750,1607750 }},
{3,{ 1607750,1607750,1607750,1607750,1607750 }},
};//1607750,1607750,1607750,1607750,1607750,1607750
const std::map<int,std::vector<int>> zouZhiStepNum ={
{ 1, { 23,23,30,30,30 }},
{ 2, { 30,30,30,30,30 }},
{ 3, { 30,30,30,30,30 }},
};
const std::map<int,std::vector<int>> zouZhiA = {
{1,{ 200,200,200,200,200 }},
{2,{ 200,200,200,200,200 }},
{3,{ 200,200,200,200,200 }},
};
const std::map<int,std::vector<int>> zouZhiOffset = {
{1,{ 7,7,7,7,9 }},
{2,{ 7,7,7,7,7 }},
{3,{ 7,7,7,7,7 }},
};
const std::map<int,std::vector<int>> zouZhiFinalDelay = {
{1,{ 2500,2500,2500,2500,2500 }},
{2,{ 2500,2500,2500,2500,2500 }},
{3,{ 2500,2500,2500,2500,2500 }},
};
};

View File

@ -0,0 +1,56 @@
#include <cstdio>
#include <iostream>
#include <thread>
#include <string>
#include <sstream>
#include <stdio.h>
#include <stdlib.h>
#include "DevUtil.h"
#include "Pwm.h"
#include "ZouZhiMotor.h"
#include "CuoZhiMotor.h"
int main(int argc,char **argv) {
//DeviceExport(); /*类里面的构造函数可以直接调用*/
DeviceExport d1;
ZouZhiMotor zzm;
CuoZhiMotor czm;
std::string instring;
do {
printf("1.cuozhi motor reset\n");
printf("2.cuozhi motor forward\n");
printf("3.cuozhi motor reverse\n");
printf("4.cuozhi motor stop\n");
printf("5.zouzhi motor forward\n");
printf("6.zouzhi motor reverse\n");
printf("7.zouzhi motor stop\n");
printf(":");
std::getline(std::cin, instring);
if (instring == "1") {
czm.reset();
}
if (instring == "2") {
czm.forward();
}
if (instring == "3") {
czm.backward();
}
if (instring == "4") {
czm.stop();
}
if (instring == "5") {
zzm.setDirection(0);
zzm.start();
}
if (instring == "6") {
zzm.setDirection(1);
zzm.start();
}
if (instring == "7") {
zzm.stop();
}
}while(1);
return 0;
}

View File

@ -0,0 +1,89 @@
add_rules("mode.debug", "mode.release")
target("motor_run")
set_kind("static")
add_files("Motor.cpp")
add_files("DevUtil.cpp")
add_files("ZouZhiMotor.cpp")
add_files("CuoZhiMotor.cpp")
add_files("Gpio.cpp")
add_files("Pwm.cpp")
add_files("MotorControl.cpp")
add_files("MotorConfig.cpp")
add_includedirs(".", { public = true})
add_includedirs("../packages/common.pkg/include", { public = true})
--add_packages("common")
target("main")
set_kind("binary")
add_files("main.cpp")
add_deps("motor_run")
--
-- If you want to known more usage about xmake, please see https://xmake.io
--
-- ## FAQ
--
-- You can enter the project directory firstly before building project.
--
-- $ cd projectdir
--
-- 1. How to build project?
--
-- $ xmake
--
-- 2. How to configure project?
--
-- $ xmake f -p [macosx|linux|iphoneos ..] -a [x86_64|i386|arm64 ..] -m [debug|release]
--
-- 3. Where is the build output directory?
--
-- The default output directory is `./build` and you can configure the output directory.
--
-- $ xmake f -o outputdir
-- $ xmake
--
-- 4. How to run and debug target after building project?
--
-- $ xmake run [targetname]
-- $ xmake run -d [targetname]
--
-- 5. How to install target to the system directory or other output directory?
--
-- $ xmake install
-- $ xmake install -o installdir
--
-- 6. Add some frequently-used compilation flags in xmake.lua
--
-- @code
-- -- add debug and release modes
-- add_rules("mode.debug", "mode.release")
--
-- -- add macro defination
-- add_defines("NDEBUG", "_GNU_SOURCE=1")
--
-- -- set warning all as error
-- set_warnings("all", "error")
--
-- -- set language: c99, c++11
-- set_languages("c99", "c++11")
--
-- -- set optimization: none, faster, fastest, smallest
-- set_optimize("fastest")
--
-- -- add include search directories
-- add_includedirs("/usr/include", "/usr/local/include")
--
-- -- add link libraries and search directories
-- add_links("tbox")
-- add_linkdirs("/usr/local/lib", "/usr/lib")
--
-- -- add system link libraries
-- add_syslinks("z", "pthread")
--
-- -- add compilation and link flags
-- add_cxflags("-stdnolib", "-fno-strict-aliasing")
-- add_ldflags("-L/usr/local/lib", "-lpthread", {force = true})
--
-- @endcode
--

View File

@ -0,0 +1,16 @@
#include <iostream>
#include "Imotorboard.h"
#include "PinMonitor.h"
#include "uartregsaccess.h"
#include <iomanip>
#include "stringex.hpp"
#include "config.h"
#include "StopWatch.h"
#include "applog.h"
#include "Capturer.h"
IMotorBoard::IMotorBoard() : mb_ev_cb_(std::function<void(uint32_t)>())
{}
IMotorBoard::~IMotorBoard(){
}

View File

@ -0,0 +1,98 @@
#pragma once
#include <string>
#include <memory>
#include <condition_variable>
#include <functional>
#include "autoevent.hpp"
#include "commondef.h"
#include "Led.h"
#include "StopWatch.h"
#include "ThreadPool.h"
class IRegsAccess;
class PinMonitor;
class Gpio;
class ICapturer;
#include "../usb/src/common/packet.h"
class IMotorBoard{
public:
IMotorBoard();
virtual ~IMotorBoard();
virtual void start() = 0;
virtual void stop() = 0;
virtual void clear_error() = 0;
virtual void pick_paper() = 0;
virtual void stop_pick_paper() = 0;
virtual int os_mode() = 0;
virtual bool paper_ready() = 0;
virtual bool is_converopen() = 0;
virtual bool is_scanning() = 0;
virtual bool is_jam() = 0;
virtual int paper_counter() = 0;
virtual bool set_long_paper(bool enable) = 0;
virtual bool set_double_inpect(bool enable) = 0;
virtual bool set_staple_inpect(bool enable) = 0;
virtual bool set_auto_paper(bool enable) = 0;
virtual bool set_color_mode(int mode) = 0;
virtual int get_speed_mode() = 0;
virtual bool set_speed_mode(int mode,int dpi,int iscolor) = 0;
virtual bool set_screw_inpect(bool enable) = 0;
virtual bool get_screw_inpect() = 0;
virtual bool set_screw_level(int level) = 0;
virtual int get_screw_level() = 0;
virtual bool wait_paper_out(int timeout_ms) = 0;
virtual bool wait_paper_in(int timeout_ms) = 0;
virtual bool read(unsigned int addr, unsigned int &val) = 0;
virtual bool write(unsigned int addr, unsigned int val) = 0;
virtual bool set_cuospeed(unsigned int speed,uint dpi,uint iscolor) = 0;
virtual void set_callbacks(MotorBoardGlue glue) = 0;
virtual bool get_keeplastpaper() = 0;
virtual std::shared_ptr<IRegsAccess> regs() = 0;
virtual void set_capture(std::shared_ptr<ICapturer> cap) = 0;
virtual void motor_reset() = 0;
virtual void LedControlOption(HG_LedOption option,uint32_t time) = 0;
virtual void clean_paper_road() = 0;
void set_error(int value){
mb_error = value;
}
void set_scancap(GScanCap cap)
{
m_scancap = cap;
}
void set_motorboard_event_callback(std::function<void(uint32_t)> cb)
{
mb_ev_cb_ = cb;
}
static scanner_status scanner_status_from_raw(int raw)
{
switch(raw)
{
case 1:
return SCANNER_STATUS_PAPER_JAMMED;
case 2:
return SCANNER_STATUS_NO_PAPER;
case 4:
return SCANNER_STATUS_COVER_OPENNED;
case 0x20:
return SCANNER_STATUS_DOUBLE_FEEDED;
case 0x2000000:
return SCANNER_STATUS_PAPER_ON;
case 0x4000000:
return SCANNER_STATUS_COVER_CLOSED;
case 0:
default:
return SCANNER_STATUS_READY; // jam has resolved
}
}
protected:
volatile int mb_error = 0;
GScanCap m_scancap;
std::function<void(uint32_t)> mb_ev_cb_;
};

View File

@ -0,0 +1,95 @@
#include "Led.h"
#define LEDPATH "%s/%s/%s"
std::string Led::timer = "timer";
std::string Led::none = "none";
Led::Led(std::string name) {
path_brightness = string_format(LEDPATH, path_base.c_str(), name.c_str(), path_brightness.c_str());
path_trigger = string_format(LEDPATH, path_base.c_str(), name.c_str(), path_trigger.c_str());
path_delay_off = string_format(LEDPATH, path_base.c_str(), name.c_str(), path_delay_off.c_str());
path_delay_on = string_format(LEDPATH, path_base.c_str(), name.c_str(), path_delay_on.c_str());
}
Led::~Led() {
}
void Led::on(int time_ms) {
if (time_ms != 0) {
write_dev(path_trigger, timer);
write_dev(path_delay_off, time_ms);
write_dev(path_delay_on, time_ms);
} else {
//if (read_dev_s(path_trigger).find(none) == std::string::npos)
write_dev(path_trigger, none);
}
write_dev(path_brightness, 1);
}
void Led::off() {
write_dev(path_brightness, 0);
}
bool Led::isOn() {
return (bool)read_dev_i(path_brightness);
}
LedControl::LedControl():m_led_green(Led("green")),m_led_red(Led("red")),m_led_white(Led("white")){
}
LedControl::~LedControl(){
option(HG_LedOption::HG_OFF_ALL,0);
}
HG_LedOption LedControl::get_state(){
return m_state;
}
void LedControl::option(HG_LedOption option,uint32_t time){
m_state = option;
switch (option)
{
case HG_LedOption::HG_OFF_ALL:
m_led_red.off();
m_led_green.off();
m_led_white.off();
break;
case HG_LedOption::HG_ON_ALL:
m_led_green.on(time);
m_led_red.on(time);
m_led_white.on(time);
break;
case HG_LedOption::HG_RED_ON:
m_led_red.on(time);
m_led_green.off();
m_led_white.off();
break;
case HG_LedOption::HG_GREEN_ON:
m_led_green.on(time);
m_led_red.off();
m_led_white.off();
break;
case HG_LedOption::HG_WHITE_ON:
m_led_red.off();
m_led_green.off();
m_led_white.on(time);
break;
case HG_LedOption::HG_RED_WHITR_ON:
m_led_green.off();
m_led_red.on(time);
m_led_white.on(time);
break;
case HG_LedOption::HG_RED_GREEN_ON:
m_led_red.on(time);
m_led_green.on(time);
m_led_white.off();
break;
case HG_LedOption::HG_GREEN_WHITR_ON:
m_led_green.on(time);
m_led_red.off();
m_led_white.on(time);
break;
default:
break;
}
}

View File

@ -0,0 +1,50 @@
#pragma once
#include "DevUtil.h"
#include "stringex.hpp"
enum HG_LedOption : uint8_t{
HG_OFF_ALL = 0,
HG_RED_ON,
HG_GREEN_ON,
HG_WHITE_ON,
HG_RED_GREEN_ON,
HG_RED_WHITR_ON,
HG_GREEN_WHITR_ON,
HG_ON_ALL,
};
class Led
{
public:
static std::string timer;
static std::string none;
public:
Led(std::string name);
~Led();
void on(int time_ms = 0);
void off();
bool isOn();
private:
const std::string path_base = "/sys/class/leds";
std::string path_brightness = "brightness";
std::string path_trigger = "trigger";
std::string path_delay_off = "delay_off";
std::string path_delay_on = "delay_on";
};
class LedControl{
public:
LedControl();
~LedControl();
void option(HG_LedOption option,uint32_t time = 0);
HG_LedOption get_state();
private:
Led m_led_red;
Led m_led_green;
Led m_led_white;
HG_LedOption m_state;
};

View File

@ -8,7 +8,6 @@
#include "StopWatch.h"
#include "applog.h"
#include "Capturer.h"
static const std::string loggername = "MotorBoard";
@ -87,15 +86,6 @@ bool MotorBoard::wait_paper_out(int timeout_ms)
return cv_paper_out.wait(timeout_ms);
}
bool MotorBoard::wait_error(int timeout_ms)
{
return cv_error.wait(timeout_ms);
}
bool MotorBoard::wait_done(int timeout_ms)
{
return cv_scan_done.wait(timeout_ms);
}
int MotorBoard::os_mode()
{
@ -112,7 +102,13 @@ bool MotorBoard::paper_ready()
SMB_MODE *smb_mode = (SMB_MODE *)&val;
return smb_mode->feeding_paper_ready;
}
bool MotorBoard::is_converopen()
{
unsigned int val;
read(0x02, val);
SMBSTATUS *smb_mode = (SMBSTATUS *)&val;
return smb_mode->open_machine;
}
bool MotorBoard::is_scanning()
{
unsigned int val;
@ -121,6 +117,31 @@ bool MotorBoard::is_scanning()
return smb_mode->work_status;
}
bool MotorBoard::is_jam()
{
return false;
}
void MotorBoard::motor_reset(){
}
void MotorBoard::clean_paper_road()
{
unsigned int val;
SMB_FUNC *smbc = (SMB_FUNC *)(&val);
read(6, val);
if(smbc->param.work_mode == 0)
{
smbc->param.func_clean_passthro = 1;
write(6, val);
smbc->param.func_clean_passthro = 0;
write(6, val);
}
else{
printf("\n 非空闲模式不允许清理纸道!!!!");
}
}
int MotorBoard::paper_counter()
{
unsigned int val;
@ -129,39 +150,11 @@ int MotorBoard::paper_counter()
return smb_mode->scan_num;
}
bool MotorBoard::set_paper_inspect_param(unsigned int value /* = 1000 */)
{
unsigned int val;
if (!read(0x04, val))
return false;
SMBCONFIGEXT *smb_config_ext = (SMBCONFIGEXT *)&val;
smb_config_ext->error_range_set = value;
return write(0x04, val);
}
bool MotorBoard::get_keeplastpaper(){
return keep_last_paper;
}
bool MotorBoard::set_paper_inpect_info(unsigned int value)
{
unsigned int val;
if (!read(0x04, val))
return false;
SMBCONFIGEXT *smb_config_ext = (SMBCONFIGEXT *)&val;
smb_config_ext->paper_infor = value;
return write(0x04, val);
}
bool MotorBoard::set_paper_inspect(bool enable /* = true */)
{
unsigned int val;
if (!read(0x04, val))
return false;
SMBCONFIGEXT *smb_config_ext = (SMBCONFIGEXT *)&val;
smb_config_ext->paper_size_check_en = enable;
return write(0x04, val);
}
bool MotorBoard::set_double_inpect(bool enable)
{
@ -172,16 +165,13 @@ bool MotorBoard::set_double_inpect(bool enable)
smb_config->double_paper = enable;
return write(0x00, val);
}
bool MotorBoard::get_doublle_inpect()
{
}
bool MotorBoard::set_auto_paper(bool enable){
unsigned int val;
if (!read(0x00, val))
return false;
SMBCONFIG *smb_config = (SMBCONFIG *)&val;
smb_config->paper_auto_module = enable;
smb_config->autofeed_mode = enable;
return write(0x00, val);
}
@ -195,9 +185,7 @@ bool MotorBoard::set_staple_inpect(bool enable)
return write(0x00, val);
}
bool MotorBoard::get_staple_inpect()
{
}
bool MotorBoard::set_color_mode(int mode)
{
unsigned int val;
@ -207,11 +195,8 @@ bool MotorBoard::set_color_mode(int mode)
smb_config->color_mode = mode;
return write(0x00, val);
}
int MotorBoard::get_color_mode()
{
}
bool MotorBoard::set_speed_mode(int mode)
bool MotorBoard::set_speed_mode(int mode,int dpi,int iscolor)
{
unsigned int val;
if (!read(0x00, val))
@ -234,7 +219,7 @@ int MotorBoard::get_speed_mode()
return smb_config->v_setting;
}
bool MotorBoard::set_cuospeed(unsigned int speed)
bool MotorBoard::set_cuospeed(unsigned int speed,uint dpi,uint iscolor)
{
unsigned int val;
if (!read(0x04, val))
@ -259,7 +244,6 @@ void MotorBoard::pin_call(unsigned int pinNum)
if (m_os_mode != os_m)
{
m_os_mode = os_m;
cv_os_mode.notify_all();
if (m_glue.m_os_mode_call)
m_glue.m_os_mode_call(m_os_mode);
}
@ -290,14 +274,13 @@ void MotorBoard::pin_call(unsigned int pinNum)
if(m_glue.m_mltop_call)
m_glue.m_mltop_call(val);
}
if(smb_status->paper_auto)
if(smb_status->auto_feed)
{
if(m_glue.m_auto_paper)
m_glue.m_auto_paper(1);
}
if (val & 0xAFE)
{
cv_error.notify_all();
if (m_glue.m_error_call)
m_glue.m_error_call(val & 0x30efe); //0xefe index of 16:aquireimage error index of bit 17 :size check error
@ -323,7 +306,6 @@ void MotorBoard::pin_call(unsigned int pinNum)
if (val & 0x400)
{
LOG_TRACE("done");
cv_scan_done.notify_all();
if (m_glue.m_scan_done_call)
m_glue.m_scan_done_call();
}
@ -403,30 +385,3 @@ int MotorBoard::get_screw_level()
SMBCONFIG *smb_mode = (SMBCONFIG *)&val;
return smb_mode->skew_parameter;
}
bool MotorBoard::en_testbit(bool en)
{
unsigned int val;
auto ret= read(0x00, val);
if(!ret)
return -1;
SMBCONFIG *smb_mode = (SMBCONFIG *)&val;
smb_mode->testbit = en?1:0;
return write(0x00,val);
}
void MotorBoard::release_statecontrol()
{
set_auto_paper(false);
m_regsAccess.reset();
m_intPinMonitor.reset();
}
void MotorBoard::init_statecontrol()
{
m_regsAccess.reset(new UartRegsAccess(devPort, bauds, 0x07, 0x87));
m_intPinMonitor.reset(new PinMonitor(intport, std::bind(&MotorBoard::pin_call, this, std::placeholders::_1)));
std::this_thread::sleep_for(std::chrono::milliseconds(10));
m_os_mode = os_mode();
}

View File

@ -1,15 +1,6 @@
#pragma once
#include <string>
#include <memory>
#include <condition_variable>
#include <functional>
#include "autoevent.hpp"
#include "commondef.h"
#include "Imotorboard.h"
class IRegsAccess;
class PinMonitor;
class Gpio;
class ICapturer;
typedef struct SMB_CONFIG
{
@ -17,23 +8,23 @@ typedef struct SMB_CONFIG
unsigned int color_mode : 1;
unsigned int paper : 1;
unsigned int double_paper : 1;
unsigned int staple_enable : 1; // 5
unsigned int staple_enable : 1;//5
unsigned int error_clean : 1;
unsigned int status_init : 1;
unsigned int pick_paper : 1;
unsigned int skew_enable : 1;
unsigned int skew_parameter : 3; // 7
unsigned int key_staple_enable : 1;
unsigned int skew_parameter : 3;
unsigned int key_staple_enable : 1;//8
unsigned int iic_config_addr : 7;
unsigned int iic_config : 1;
unsigned int v_setting : 2; // 11
unsigned int v_setting : 2;//10
unsigned int speed_set_enable : 1;
unsigned int scan_busy_motor_stop : 1;
unsigned int sleep_state : 1;
unsigned int sleep_parameter : 3; // 6
unsigned int _600dpi : 1;
unsigned int paper_auto_module : 1; // 2
unsigned int testbit : 1;
unsigned int dpi_mode : 2;
unsigned int sleep_parameter : 2;//6
unsigned int dpi600:1;
unsigned int autofeed_mode:1;
unsigned int lifter_en:1;
} SMBCONFIG;
typedef struct SMB_STATUS
@ -54,10 +45,10 @@ typedef struct SMB_STATUS
unsigned int sleep_conf : 3;
unsigned int dsp_get_paper_error : 1;
unsigned int paper_check_result : 1;
unsigned int top_wuzhi : 1;
unsigned int ml_top_sin : 1; // 10
unsigned int paper_auto : 1;
unsigned int paper_left : 1;
unsigned int arrival_top:1;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ
unsigned int arrival_top_int:1;//<2F><><EFBFBD><EFBFBD><EFB6A5><EFBFBD>ж<EFBFBD>
unsigned int auto_feed:1;//4
unsigned int paper_left:1;
} SMBSTATUS;
typedef struct SMB_MODE
@ -76,50 +67,74 @@ typedef struct SMB_CONFIG_EXT
unsigned int cuo_speed : 7;
} SMBCONFIGEXT;
class MotorBoard
typedef struct SMB_CONFIG_TIME
{
unsigned int error_time_set : 7;
} SMBCONFIGTIME;
//Reg 6
typedef union SMB_FUNC
{
struct{
unsigned int work_mode : 3;
unsigned int func_clean_passthro : 1;
unsigned int func_feed_low : 1;
unsigned int func_feed_mid : 1;
unsigned int func_feed_high : 1;
unsigned int key_sound : 1;
unsigned int key_endouble_feed : 1;
unsigned int func_encount : 1;
unsigned int func_clear_count : 1;
unsigned int motor_choose : 2;
unsigned int wr_en : 1;
unsigned int motor_addr : 8;
unsigned int key_stop_enable : 1;
unsigned int lift_init_set: 2;
}param;
unsigned int value;
} SMBFUNC;
class MotorBoard : public IMotorBoard
{
public:
MotorBoard();
void start();
void stop();
void clear_error();
void pick_paper();
int os_mode();
bool paper_ready();
bool is_scanning();
int paper_counter();
bool set_long_paper(bool enable);
bool set_double_inpect(bool enable);
bool get_doublle_inpect();
bool set_staple_inpect(bool enable);
bool set_auto_paper(bool enable);
bool get_staple_inpect();
bool set_color_mode(int mode);
int get_color_mode();
int get_speed_mode();
bool set_speed_mode(int mode);
bool set_screw_inpect(bool enable);
bool get_screw_inpect();
bool set_screw_level(int level);
int get_screw_level();
bool wait_paper_out(int timeout_ms);
bool wait_paper_in(int timeout_ms);
bool wait_error(int timeout_ms);
bool wait_done(int timeout_ms);
bool read(unsigned int addr, unsigned int &val);
bool write(unsigned int addr, unsigned int val);
bool set_paper_inspect_param(unsigned int value = 1000);
bool set_paper_inpect_info(unsigned int value);
bool set_paper_inspect(bool enable = true);
bool set_cuospeed(unsigned int speed);
void set_callbacks(MotorBoardGlue glue);
bool get_keeplastpaper();
bool en_testbit(bool en);
std::shared_ptr<IRegsAccess> regs();
void set_capture(std::shared_ptr<ICapturer> cap);
void release_statecontrol();
void init_statecontrol();
void start() override;
void stop() override;
void clear_error() override;
void pick_paper() override;
void stop_pick_paper() override{};
int os_mode() override;
bool paper_ready() override;
bool is_scanning() override;
bool is_jam() override;
int paper_counter() override;
bool is_converopen() override;
bool set_long_paper(bool enable) override;
bool set_double_inpect(bool enable) override;
bool set_staple_inpect(bool enable) override;
bool set_auto_paper(bool enable) override;
bool set_color_mode(int mode) override;
int get_speed_mode() override;
bool set_speed_mode(int mode,int dpi,int iscolor) override;
bool set_screw_inpect(bool enable) override;
bool get_screw_inpect() override;
bool set_screw_level(int level) override;
int get_screw_level() override;
bool wait_paper_out(int timeout_ms) override;
bool wait_paper_in(int timeout_ms) override;
bool read(unsigned int addr, unsigned int &val) override;
bool write(unsigned int addr, unsigned int val) override;
bool set_cuospeed(unsigned int speed,uint dpi = 0,uint iscolor = 1) override;
void set_callbacks(MotorBoardGlue glue) override;
bool get_keeplastpaper() override;
std::shared_ptr<IRegsAccess> regs() override;
void set_capture(std::shared_ptr<ICapturer> cap) override;
void motor_reset() override;
void LedControlOption(HG_LedOption option,uint32_t time) override{};
void clean_paper_road() override;
private:
void pin_call(unsigned int pinNum);
void scansensor_call(unsigned int pinNum);
@ -133,9 +148,6 @@ private:
std::shared_ptr<Gpio> m_uartEnable;
AutoSemaphore cv_paper_out;
AutoSemaphore cv_paper_in;
AutoSemaphore cv_error;
AutoSemaphore cv_scan_done;
AutoSemaphore cv_os_mode;
unsigned int m_os_mode;
volatile bool keep_last_paper;
MotorBoardGlue m_glue;

View File

@ -0,0 +1,320 @@
#include "motormanager.h"
#include "MotorControl.h"
#include "sensormonitor.h"
#include <future>
#include "Led.h"
MotorManager::MotorManager():m_motorcontrol(new MotorControl()),
m_ledcontrol(new LedControl()),
is_usb_connect(false),
is_sleeping(false),
is_autopaper(false),
is_motor_run(false),
autopaper_state_change(false),
autopaperthread(1),
m_glue({nullptr,nullptr,nullptr,nullptr,nullptr,nullptr})
{
GetorSetSysClassValue(false,HG_PWM_FAN,false);
GetorSetSysClassValue(false,HG_MOTOR_FAN,false);
m_sensormonitor.reset(new SensorMonitor([&](int value){pincall(value);}));
m_ledcontrol->option(HG_WHITE_ON,300);
}
MotorManager::~MotorManager()
{
}
bool MotorManager::GetOrSetUsbConnectFlag(bool isGet,bool value){
if(isGet)
return is_usb_connect;
if(value == false)
m_ledcontrol->option(HG_LedOption::HG_WHITE_ON,300);
return is_usb_connect = value;
}
bool MotorManager::GetOrSetSleepFlag(bool isGet,bool value){
if(isGet)
return is_sleeping;
if(value == false)
{
if(!(m_sensormonitor->Is_ConverOpen()||m_sensormonitor->Is_Jam()))
{
if(!m_sensormonitor->Is_PaperOn())
m_motorcontrol->MotorRun(MotorControl::MotorOption::CZ_Reset);
m_ledcontrol->option(HG_WHITE_ON,0);
}
else{
if(m_sensormonitor->Is_ConverOpen())
m_ledcontrol->option(HG_RED_ON,300);
else
m_ledcontrol->option(HG_RED_ON,0);
}
}
else
is_autopaper = false;
if(mb_ev_cb_)
mb_ev_cb_(value ? SCANNER_STATUS_SLEEPING : SCANNER_STATUS_WAKED_UP);
return is_sleeping = value;
}
void MotorManager::set_capture(std::shared_ptr<ICapturer> cap)
{
m_cap = cap;
}
std::shared_ptr<IRegsAccess> MotorManager::regs()
{
return nullptr;
}
int MotorManager::os_mode(){
return 0;
}
bool MotorManager::paper_ready(){
return m_sensormonitor->Is_PaperOn();
}
void MotorManager::clear_error(){
mb_error = 0;
}
void MotorManager::start(){
is_motor_run = true;
m_papperout_time = std::chrono::steady_clock::now();
m_motorcontrol->MotorRun(MotorControl::MotorOption::ZZ_Forward);
m_motorcontrol->MotorRun(MotorControl::MotorOption::CZ_Forward);
GetorSetSysClassValue(false,HG_PWM_FAN,true);
GetorSetSysClassValue(false,HG_MOTOR_FAN,true);
m_ledcontrol->option(HG_WHITE_ON,0);
}
void MotorManager::stop(){
is_motor_run = false;
m_motorcontrol->MotorRun(MotorControl::MotorOption::CZ_Stop);
m_motorcontrol->MotorRun(MotorControl::MotorOption::ZZ_Stop);
GetorSetSysClassValue(false,HG_PWM_FAN,false);
GetorSetSysClassValue(false,HG_MOTOR_FAN,false);
}
bool MotorManager::wait_paper_out(int timeout_ms){
return cv_paperout.wait(timeout_ms);
}
bool MotorManager::wait_paper_in(int timeout_ms){
bool ret = cv_paperin.wait(timeout_ms);
std::cout<<"wait_paper_in timeout:"<<timeout_ms <<"ret :"<<ret<<std::endl;
if(ret)
m_motorcontrol->MotorRun(MotorControl::MotorOption::CZ_Pause);
return ret;
}
void MotorManager::pick_paper(){
m_motorcontrol->MotorRun(MotorControl::MotorOption::CZ_Forward);
}
void MotorManager::stop_pick_paper(){
m_motorcontrol->MotorRun(MotorControl::MotorOption::CZ_Pause);
}
bool MotorManager::is_scanning(){
return false;
}
bool MotorManager::is_jam(){
return GetorSetSysClassValue(true,"/sys/class/gpio/gpio54/value",true);
}
int MotorManager::paper_counter(){
return -1;
}
bool MotorManager::set_long_paper(bool enable){
return false;
}
bool MotorManager::set_double_inpect(bool enable){
if(enable)
//system("echo 1 > /sys/class/gpio/gpio139/value");
GetorSetSysClassValue(false,"/sys/class/gpio/gpio139/value",true);
else
//system("echo 0 > /sys/class/gpio/gpio139/value");
GetorSetSysClassValue(false,"/sys/class/gpio/gpio139/value",false);
return true;
}
bool MotorManager::set_staple_inpect(bool enable){
return false;
}
bool MotorManager::set_auto_paper(bool enable){
is_autopaper = enable;
return false;
}
bool MotorManager::set_color_mode(int mode){
return false;
}
int MotorManager::get_speed_mode(){
return -1;
}
bool MotorManager::set_speed_mode(int mode,int dpi,int iscolor){
m_motorcontrol->setczspeed(mode,dpi,iscolor);
m_motorcontrol->setzzspeed(mode,dpi,iscolor);
return true;
}
bool MotorManager::set_screw_inpect(bool enable){
return false;
}
bool MotorManager::get_screw_inpect(){
return false;
}
bool MotorManager::set_screw_level(int level){
return false;
}
int MotorManager::get_screw_level(){
return -1;
}
bool MotorManager::read(unsigned int addr, unsigned int &val){
return false;
}
bool MotorManager::write(unsigned int addr, unsigned int val){
return false;
}
bool MotorManager::set_cuospeed(unsigned int speed,uint dpi,uint iscolor){
m_motorcontrol->setczspeed(speed,dpi,iscolor);
return true;
}
void MotorManager::set_callbacks(MotorBoardGlue glue){
m_glue = glue;
}
bool MotorManager::get_keeplastpaper(){
return false;
}
void MotorManager::motor_reset(){
m_motorcontrol->MotorRun(MotorControl::CZ_Reset);
}
void MotorManager::pincall(int value){
if(mb_ev_cb_)
{
mb_ev_cb_(IMotorBoard::scanner_status_from_raw(value));
}
if(is_sleeping || !is_usb_connect)
return;
printf("\npin call value %d",value);
if(value == 1){
cv_paperin.notify_all();
if(std::chrono::duration<double,std::milli>(std::chrono::steady_clock::now() - m_papperout_time).count() < 60)
m_glue.m_error_call?m_glue.m_error_call(0x40000):void(0);
printf("\n-------------- paper out time %f ---------------------------",std::chrono::duration<double,std::milli>(std::chrono::steady_clock::now() - m_papperout_time).count());
m_papperout_time = std::chrono::steady_clock::now();
}
else if(value == 0){
cv_paperout.notify_all();
m_papperout_time = std::chrono::steady_clock::now();
}
if(value &0x24)
{
if(m_glue.m_error_call)
m_glue.m_error_call(value);
cv_paperin.notify_all();
cv_paperout.notify_all();
}
if(value == 0x20)
{
this->stop();
set_double_inpect(false);
}
if(value == 4 && is_converopen())
m_ledcontrol->option(HG_RED_ON,300);
if(value ==0x4000000 && !is_motor_run)
{
f_motorreset = std::async(std::launch::async,[&](){
std::this_thread::sleep_for(std::chrono::milliseconds(200));
if(is_usb_connect && !is_converopen() && (!paper_ready()))
motor_reset(),printf("\n conver reset");
});
printf("\n conver ******************************");
if(is_jam())
m_ledcontrol->option(HG_RED_ON,0);
else if(!is_usb_connect)
m_ledcontrol->option(HG_WHITE_ON,500);
else
m_ledcontrol->option(HG_WHITE_ON,0);
}
if(is_autopaper && value == 0x2000000 && !is_motor_run)
{
printf("\n ---------------------------------------------------");
autopaper_state_change = true;
autopaperthread.enqueue([&]{
StopWatch sw;
while (sw.elapsed_ms()<1000)
{
std::this_thread::sleep_for(std::chrono::milliseconds(1));
if(!autopaper_state_change)
return;
}
m_glue.m_auto_paper(true);
printf("\n -----------------m_glue.m_auto_paper(true);----------------------------------");
});
}
if(is_autopaper && value == 2 && !is_motor_run)
{
autopaper_state_change = false;
}
if(value == 2){
if(is_motor_run == false && is_converopen() == false && is_jam() == false && m_ledcontrol->get_state() == HG_LedOption::HG_RED_ON)
{
m_ledcontrol->option(HG_WHITE_ON,0);
if(mb_error == 8 || mb_error == 79 || mb_error == 82)
motor_reset(),mb_error = 0;
}
}
}
bool MotorManager::is_converopen()
{
return m_sensormonitor->Is_ConverOpen();
}
void MotorManager::LedControlOption(HG_LedOption option,uint32_t time){
m_ledcontrol?m_ledcontrol->option(option,time):void(1);
}
void MotorManager::clean_paper_road(){
set_speed_mode(1,2,0);
StopWatch sw;
m_motorcontrol->MotorRun(MotorControl::MotorOption::ZZ_Forward);
std::this_thread::sleep_for(std::chrono::milliseconds(1500));
bool b_clean_ = false;
while(sw.elapsed_s() < 5)
{
if(!is_jam())
{
b_clean_ = true;
break;
}
std::this_thread::sleep_for(std::chrono::milliseconds(700));
}
m_motorcontrol->MotorRun(MotorControl::MotorOption::ZZ_Stop);
if(is_sleeping || !is_usb_connect)
return;
if(is_motor_run == false && is_converopen() == false && is_jam() == false && m_ledcontrol->get_state() == HG_LedOption::HG_RED_ON || b_clean_)
{
m_ledcontrol->option(HG_WHITE_ON,0);
}
}
bool MotorManager::GetorSetSysClassValue(bool isGet,std::string path,bool value){
if(isGet)
{
FILE *fp = fopen(path.c_str(),"r");
if(fp != NULL)
{
fscanf(fp,"%d",&value);
fclose(fp);
return value;
}
return false;
}
else{
FILE *fp = fopen(path.c_str(),"w");
if(fp != NULL)
{
fprintf(fp,"%d",value);
fclose(fp);
return true;
}
return false;
}
}

View File

@ -0,0 +1,72 @@
#pragma once
#include "Imotorboard.h"
#include "autoevent.hpp"
const std::string HG_PWM_FAN = "/sys/class/fv_en_class/fv_en/pwm_fan";
const std::string HG_MOTOR_FAN = "/sys/class/fv_en_class/fv_en/motor_fan";
class MotorControl;
class SensorMonitor;
class LedControl;
enum HG_LedOption : uint8_t;
class MotorManager : public IMotorBoard
{
public:
MotorManager();
virtual ~MotorManager();
void start() override;
void stop() override;
void clear_error() override;
void pick_paper() override;
void stop_pick_paper() override;
int os_mode() override;
bool paper_ready() override;
bool is_converopen() override;
bool is_scanning() override;
bool is_jam() override;
int paper_counter() override;
bool set_long_paper(bool enable) override;
bool set_double_inpect(bool enable) override;
bool set_staple_inpect(bool enable) override;
bool set_auto_paper(bool enable) override;
bool set_color_mode(int mode) override;
int get_speed_mode() override;
bool set_speed_mode(int mode,int dpi,int iscolor) override;
bool set_screw_inpect(bool enable) override;
bool get_screw_inpect() override;
bool set_screw_level(int level) override;
int get_screw_level() override;
bool wait_paper_out(int timeout_ms) override;
bool wait_paper_in(int timeout_ms) override;
bool read(unsigned int addr, unsigned int &val) override;
bool write(unsigned int addr, unsigned int val) override;
bool set_cuospeed(unsigned int speed,uint dpi,uint iscolor) override;
void set_callbacks(MotorBoardGlue glue) override;
bool get_keeplastpaper() override;
std::shared_ptr<IRegsAccess> regs() override;
void set_capture(std::shared_ptr<ICapturer> cap) override;
void motor_reset() override;
bool GetOrSetUsbConnectFlag(bool isGet,bool value);
bool GetOrSetSleepFlag(bool isGet,bool value);
void LedControlOption(HG_LedOption option,uint32_t time) override;
void clean_paper_road() override;
private:
void pincall(int value);
bool GetorSetSysClassValue(bool isGet,std::string path,bool value);
std::unique_ptr<MotorControl> m_motorcontrol;
std::unique_ptr<SensorMonitor> m_sensormonitor;
std::unique_ptr<LedControl> m_ledcontrol;
MotorBoardGlue m_glue;
volatile bool is_usb_connect;
volatile bool is_sleeping;
volatile bool is_autopaper;
volatile bool is_motor_run;
volatile bool autopaper_state_change;
std::shared_ptr<ICapturer> m_cap;
ThreadPool autopaperthread;
AutoSemaphore cv_paperin;
AutoSemaphore cv_paperout;
std::future<void> f_motorreset;
std::chrono::steady_clock::time_point m_papperout_time;
};

View File

@ -0,0 +1,127 @@
#include "sensormonitor.h"
#include <iostream>
#include <poll.h>
#include <unistd.h>
#include <fcntl.h>
#include <poll.h>
#include <sys/epoll.h>
#include <thread>
#include <iostream>
#include <errno.h>
#include <stdlib.h>
SensorMonitor::SensorMonitor(std::function<void(int)> callback):m_callback(callback),
_C6(54),//扫描传感器
_A4(36),//有无纸传感器
_C7(55),//开盖传感器
Double_out0(137)//超声波传感器
{
_C6.setDirection(Gpio::in);
_A4.setDirection(Gpio::in);
_C7.setDirection(Gpio::in);
Double_out0.setDirection(Gpio::in);
_C7.setEdge(Gpio::both);
_A4.setEdge(Gpio::both);
_C6.setEdge(Gpio::both);
Double_out0.setEdge(Gpio::rising);
is_paperon = _A4.getValue() == Gpio::GpioLevel::High ? false : true;
is_converopen = _C7.getValue() == Gpio::GpioLevel::High ? false : true;
is_jam = _C6.getValue() == Gpio::GpioLevel::High? true : false;
b_monitor = true;
m_monitor = std::thread(&SensorMonitor::monitor,this);
}
SensorMonitor::~SensorMonitor()
{
b_monitor =false;
if(m_monitor.joinable())
m_monitor.join();
}
bool SensorMonitor::Is_PaperOn()
{
return is_paperon;
}
bool SensorMonitor::Is_ConverOpen()
{
return is_converopen;
}
bool SensorMonitor::Is_Jam()
{
return is_jam;
}
void SensorMonitor::monitor(){
pollfd fds[4]{};
fds[0].fd = open(_C6.getValuePath().c_str(),O_RDONLY);
fds[1].fd = open(_A4.getValuePath().c_str(),O_RDONLY);
fds[2].fd = open(_C7.getValuePath().c_str(),O_RDONLY);
fds[3].fd = open(Double_out0.getValuePath().c_str(),O_RDONLY);
int ret=0;
char buf[8]{};
int num =0;
num = read(fds[0].fd, buf, 8);
num = read(fds[1].fd, buf, 8);
num = read(fds[2].fd, buf, 8);
num = read(fds[3].fd, buf, 8);
while(b_monitor)
{
ret = poll(fds,4,1000);
if(ret>0)
{
if(fds[0].revents)
{
if(ret = readfile(fds[0].fd,num,buf)){
if(m_callback)
m_callback(true);
is_jam = true;
}
else{
if(m_callback)
m_callback(false);
is_jam = false;
}
printf("\n 扫描传感器 %d ",ret);
}
if(fds[1].revents)
{
if(readfile(fds[1].fd,num,buf)){
is_paperon = false;
m_callback(2);
}
else{
is_paperon = true;
m_callback(0x2000000);
}
printf("\n 有无纸传感器 %d ",!is_paperon);
}
if(fds[2].revents)
{
if(readfile(fds[2].fd,num,buf)){
is_converopen = false;
m_callback(0x4000000);
}
else{
is_converopen = true;
m_callback(4);
}
printf("\n 开盖传感器 %d ",!is_converopen);
}
if(fds[3].revents)
{
if(ret = readfile(fds[3].fd,num,buf)){
m_callback(0x20);
}
printf("\n 双张 %d ",ret);
}
}
}
}
int SensorMonitor::readfile(int fd,int num , char* buf){
lseek(fd, 0, SEEK_SET);
num = read(fd, buf, 8);
buf[num - 1] = '\0';
return atoi(buf);
}

View File

@ -0,0 +1,29 @@
#pragma once
#include "Gpio.h"
#include <thread>
#include <condition_variable>
#include <functional>
class SensorMonitor
{
public:
SensorMonitor(std::function<void(int)> callback);
~SensorMonitor();
bool Is_PaperOn();
bool Is_ConverOpen();
bool Is_Jam();
private:
void monitor();
int readfile(int fd,int num , char* buf);
Gpio _C6;
Gpio _A4;
Gpio _C7;
Gpio Double_out0;
std::thread m_monitor;
std::function<void(int)> m_callback;
volatile bool b_monitor;
volatile bool is_converopen;
volatile bool is_paperon;
volatile bool is_jam;
};

View File

@ -4,6 +4,6 @@ target("motorboard")
set_kind("static")
add_syslinks("pthread")
add_files("*.cpp")
add_deps("regs", "deviceio", "conf", "applog", "capimage",{public = true})
add_deps("regs", "motor_run" ,"deviceio", "conf", "applog", "capimage",{public = true})
add_includedirs(".", { public = true})
add_packages("common")

View File

@ -61,11 +61,8 @@ json DeviceConfig::getdefaultjson()
void DeviceConfig::savejson(json js)
{
//std::lock_guard<std::mutex> lc(m_lock);
std::ofstream o(ParamPath);
o << std::setw(4) << js <<std::endl;
o.flush();
o.close();
}
@ -97,6 +94,5 @@ json DeviceConfig::getjson()
i.seekg(pos);
json m_json;
i >> m_json;
i.close();
return m_json;
}

View File

@ -1,7 +1,7 @@
#include "fsmstate.h"
#include "scanner.h"
#include "iscanner.h"
Scanner *FsmState::scanner = NULL;
IScanner *FsmState::scanner = NULL;
#ifndef LOG
#define LOG printf
#endif

View File

@ -4,7 +4,7 @@
#include <typeinfo>
#include <string>
class Scanner;
class IScanner;
enum ScanEvent {
@ -47,12 +47,12 @@ public:
virtual FsmState* on_event(ScanEvent event) = 0;
virtual void initial() {}
static void setScanner(Scanner* scan) {
static void setScanner(IScanner* scan) {
scanner = scan;
}
std::string typeName = "FsmState";
protected:
static Scanner* scanner;
static IScanner* scanner;
};

View File

@ -2,6 +2,7 @@
#include "commondef.h"
#include "ImageApplyHeaders.h"
#include "CSizedetect.h"
#include "CorrectParam.h"
#include <vector>
#include <map>
#include <memory>
@ -15,8 +16,13 @@ static std::map<TwSS, Size> papersize{
{B4, Size{250, 353}},
{B5, Size{176, 250}},
{B6, Size{125, 176}},
{MaxSize, Size{297, 420 * 2}},
#ifdef G300
{MaxSize, Size{210, (long)(420 * 1.5)}},
{USStatement, Size{210, (long)(420 * 1.5)}},
#else
{MaxSize, Size{297, 1040}},
{USStatement, Size{297, (long)(420 * 1.5)}},
#endif
{USLetter, Size{216, 279}},
{USLegal, Size{216, 356}},
{USLedger, Size{279, 432}},
@ -31,11 +37,12 @@ class IImageHandler
{
public:
virtual ~IImageHandler() {}
virtual void add_image(void *data, int width, int height, int type,int scannnum) = 0;
virtual void add_image(void *data, int width, int height, int type,int scannnum,std::uint32_t fpga_vs,CISVendor cistype) = 0;
virtual void config_procparams(HGImgProcParms params) = 0;
virtual void add_scanevent(HGIntInfo status) = 0;
virtual void clear() = 0;
virtual bool done() = 0;
virtual bool is_limit() = 0;
virtual void Set_ratio(u32 h_ratio,u32 v_ratio) = 0;
ImgStatus getimgstatus() { return m_imgstatus;}
void resetimgstatus() { m_imgstatus={.status=NO_error,.sannum=0};}
@ -64,25 +71,47 @@ public:
{
m_scanconfig = config;
}
bool set_config(GScanCap config) {
m_hgimgconfig = config;
if(config.resolution_dst<300.0f)
m_hgimgconfig.resolution_native = 200.0f;
#ifdef G300
else
m_hgimgconfig.resolution_native = 300.0f;
#else
else if(config.resolution_dst <500.0f)
m_hgimgconfig.resolution_native = 300.0f;
else
m_hgimgconfig.resolution_native = 600.0f;
#endif
m_ials.clear();
if(m_dog.get())
{
if(m_hgimgconfig.dogeardistabce>=10 && m_hgimgconfig.dogeardistabce <=300)
m_dog->setDistance(m_hgimgconfig.dogeardistabce);
else
m_dog->setDistance(50);
m_dog->setDistance(70);
}
if(config.fillhole.is_fillhole)
{
float ratio=config.fillhole.fillholeratio/100.0;
m_ials.push_back(std::shared_ptr<CImageApply>(new CImageApplyOutHole(200.0f,ratio,50.0)));
if((config.fillholeratio_down+config.fillholeratio_up+config.fillholeratio_left+config.fillholeratio_right)>0)
{
m_ials.push_back(std::shared_ptr<CImageApply>(new CImageApplyOutHole(
25.0f,
{config.fillholeratio_up/100.0f,config.fillholeratio_down/100.0f,config.fillholeratio_left/100.0f,config.fillholeratio_right/100.0f},
50.0)));
}
else if(config.fillhole.fillholeratio > 0){
float ratio=config.fillhole.fillholeratio/100.0;
m_ials.push_back(std::shared_ptr<CImageApply>(new CImageApplyOutHole(25.0f,{ratio,ratio,ratio,ratio},50.0)));
}
}
bool islongcustomcrop = config.papertype == 52;
bool islongcustomcrop = config.papertype == 52 || config.papertype == 0;
//bool isautocrop = config.papertype == TwSS::None;
Size fixedSize;
printf(" \nconfig.dogeardistabce=%d", config.dogeardistabce);
printf(" \nconfig.papertype=%d", config.papertype);
printf(" \nconfig.AutoCrop_threshold=%d", config.AutoCrop_threshold);
printf(" \nconfig.autodescrew=%d", config.autodescrew);
@ -100,6 +129,7 @@ public:
printf(" \nconfig.hardwarecaps.capturepixtype=%d", config.hardwarecaps.capturepixtype);
printf(" \nconfig.hardwarecaps.en_doublefeed=%d", config.hardwarecaps.en_doublefeed);
printf(" \nconfig.hsvcorrect=%d", config.hsvcorrect);
printf(" \nconfig.HsvFilterType=%d", config.HsvFilterType);
printf(" \nconfig.imageRotateDegree=%d", config.imageRotateDegree);
printf(" \nconfig.indent=%d", config.indent);
printf(" \nconfig.is_autocontrast=%d", config.is_autocontrast);
@ -116,77 +146,28 @@ public:
printf(" \nconfig.noise=%d", config.noise);
printf(" \nconfig.hardwarecaps.paperAlign=%d", config.paperAlign);
printf(" \nconfig.hardwarecaps.pixtype=%d", config.pixtype);
printf(" \nconfig.resolution_dst=%d", config.resolution_dst);
printf(" \nconfig.resolution_native=%d", config.resolution_native);
printf(" \nconfig.resolution_dst=%f", config.resolution_dst);
printf(" \nconfig.resolution_native=%f", config.resolution_native);
printf(" \nconfig.scannum=%d", config.scannum);
printf(" \nconfig.sharpen=%d", config.sharpen);
printf(" \nconfig.sharpen=%d",config.sharpen);
printf(" \nconfig.is_dogeardetection=%d", config.is_dogeardetection);
fixedSize = GetPaperSize(config.papertype, 200.0f, config.paperAlign);
// m_ials.push_back(shared_ptr<CImageApply>(new CImageApplyAutoCrop(islongcustomcrop ? islongcustomcrop : config.is_autocrop,
// config.autodescrew, config.fillbackground, cv::Size(fixedSize.x, fixedSize.y), config.is_convex,false,config.AutoCrop_threshold,config.noise,config.indent)));
fixedSize = GetPaperSize(config.papertype, m_hgimgconfig.resolution_native, config.paperAlign);
printf( " \n fixedSize x %d fixedSize y %d ",fixedSize.x,fixedSize.y);
config.is_autocrop = 1;
islongcustomcrop = false;
m_ials.push_back(shared_ptr<CImageApply>(new CImageApplyAutoCrop(islongcustomcrop ? islongcustomcrop : config.is_autocrop,
config.autodescrew, config.fillbackground, cv::Size(fixedSize.x, fixedSize.y), config.is_convex,false,config.AutoCrop_threshold,config.noise,config.indent)));
if (config.is_autodiscradblank_normal || config.is_autodiscradblank_vince)
{
//m_ials.push_back(shared_ptr<CImageApply>(new CImageApplyDiscardBlank()));
CImageApplyDiscardBlank *disBlank = new CImageApplyDiscardBlank();
//跳过空白页阈值
int area = 200;
int intensity = 15;
int maxHeight = 3307; //A3 height
//页面最大高度获取
if (config.papertype == 54)
maxHeight = 6614;
//阈值参数赋值
if (config.discardblank_percent < 10)
{
area = 70 + (int)((config.discardblank_percent - 1) * 13.33);
intensity = 8 + config.discardblank_percent / 2;
}
else if (config.discardblank_percent < 20)
{
area = 190 + (config.discardblank_percent - 10) * 14;
intensity = 15;
}
else if (config.discardblank_percent < 40)
{
area = 400 + (config.discardblank_percent - 20) * 10;
intensity = 20;
}
else if (config.discardblank_percent < 60)
{
area = 600 + (config.discardblank_percent - 40) * 20;
intensity = 20;
}
else if (config.discardblank_percent < 80)
{
area = 1000 + (config.discardblank_percent - 60) * 55;
intensity = 30;
}
if (config.is_autodiscradblank_normal)
m_ials.push_back(shared_ptr<CImageApply>(new CImageApplyDiscardBlank(40, 30, config.discardblank_percent, 200)));
else
{
area = 2100 + (config.discardblank_percent - 80) * (maxHeight - 2100) / 20;
intensity = 40;
}
//判断是否为跳过空白页发票
if (config.is_autodiscradblank_vince)
{
area *= 1.5;
intensity *= 1.5;
}
//设置参数阈值
// disBlank->setMinArea(area);
// disBlank->setIntensity(intensity);
printf("\n area =%d,intensity =%d ",area,intensity);
m_ials.push_back(shared_ptr<CImageApply>(disBlank));
//m_ials.push_back(shared_ptr<CImageApply>(new CImageApplyDiscardBlank(config.areanum,config.devnmax)));
m_ials.push_back(shared_ptr<CImageApply>(new CImageApplyDiscardBlank(40, 30, config.discardblank_percent * 15 / 10, 150)));
}
m_ials.push_back(shared_ptr<CImageApply>(new CImageApplyAutoCrop(islongcustomcrop ? islongcustomcrop : config.is_autocrop,
config.autodescrew, config.fillbackground, cv::Size(fixedSize.x, fixedSize.y), config.is_convex,false,config.AutoCrop_threshold,config.noise,config.indent)));
//除底色
if(config.fadeback && config.pixtype == 2)
m_ials.push_back(shared_ptr<CImageApply>(new CImageApplyFadeBackGroudColor(100,0,config.fadebackrange)));
config.autodescrew, config.fillbackground, cv::Size(fixedSize.x, fixedSize.y), config.is_convex,config.isfillcolor,config.AutoCrop_threshold,config.noise,config.indent,config.normalCrop,config.HsvFilterType == 0)));
//自定义裁切
if(config.cropRect.enable &&!config.is_autocrop)
@ -194,7 +175,19 @@ public:
printf("\n 自定义裁切");
m_ials.push_back(shared_ptr<CImageApply>(new CImageApplyCustomCrop(cv::Rect(config.cropRect.x,config.cropRect.y,config.cropRect.width,config.cropRect.height))));
}
m_hgimgconfig.is_colorcast = 0;
// if((config.pixtype == 2)&&(config.is_colorcast))
// {
// printf("\n 色偏");
// m_ials.push_back(m_colorcast);
// }
// if (config.fadeback && config.pixtype > 0)// && config.pixtype == 2
{
printf("\n 除底色");
m_ials.push_back(shared_ptr<CImageApply>(new CImageApplyFadeBackGroudColor(50,0,config.fadebackrange)));
}
// if (config.customGamma.enable)
// {
// m_iaList.push_back(shared_ptr<CImageApply>(new CImageApplyCustomGamma(imgparams.customGamma.table, imgparams.customGamma.tableLength)));
@ -228,10 +221,16 @@ public:
m_ials.push_back(shared_ptr<CImageApply>(new CImageApplyAdjustColors(bright, contrast, config.gamma)));
}
//答题卡除红
if (config.hsvcorrect && config.pixtype==2)
if ((config.hsvcorrect|| config.HsvFilterType!=0)&& config.pixtype==2)
{
printf("\n 答题卡除红");
m_ials.push_back(shared_ptr<CImageApplyHSVCorrect>(new CImageApplyHSVCorrect(CImageApplyHSVCorrect::CorrectOption::Red_Removal)));
CImageApplyHSVCorrect::CorrectOption hsv;//= config.hsvcorrect?CImageApplyHSVCorrect::CorrectOption::Red_Removal:
if(config.hsvcorrect)
hsv = CImageApplyHSVCorrect::CorrectOption::Red_Removal;
else
hsv = CImageApplyHSVCorrect::CorrectOption::FXB_Color_Cast;
m_ials.push_back(shared_ptr<CImageApplyHSVCorrect>(new CImageApplyHSVCorrect(hsv)));
}
//防止渗透
if (config.refuseInflow)
@ -269,7 +268,7 @@ public:
islongcustomcrop = true;
if (config.is_autocrop || islongcustomcrop)
{
double ratio = config.resolution_dst / 200.0; //
double ratio = config.resolution_dst /m_hgimgconfig.resolution_native; //
apply = new CImageApplyResize(CImageApplyResize::ResizeType::RATIO, cv::Size(0, 0), ratio, ratio);
}
else
@ -300,24 +299,29 @@ public:
if (config.en_fold)
{
m_ials.push_back(shared_ptr<CImageApply>(new CImageApplyConcatenation(CImageApplyConcatenation::horizontal, cv::Scalar(255, 255, 255))));
if(!(config.fold_concatmode >=0 && config.fold_concatmode <3))
config.fold_concatmode = 0;
m_ials.push_back(shared_ptr<CImageApply>(new CImageApplyConcatenation(CImageApplyConcatenation::ConcatMode(config.fold_concatmode), cv::Scalar(255, 255, 255))));
}
if (config.imageRotateDegree != 0.0 || config.is_backrotate180)
{
CImageApplyRotation::RotationType type;
if (config.imageRotateDegree > 89.0f && config.imageRotateDegree < 91.0f)
type = CImageApplyRotation::RotationType::Rotate_90_clockwise;
else if (config.imageRotateDegree > 269.0f && config.imageRotateDegree < 271.0f)
type = CImageApplyRotation::RotationType::Rotate_90_anti_clockwise;
else if (config.imageRotateDegree > 179.0f && config.imageRotateDegree < 181.0f)
type = CImageApplyRotation::RotationType::Rotate_180;
else
type = CImageApplyRotation::RotationType::Invalid;
// CImageApplyRotation::RotationType type;
// if (config.imageRotateDegree > 89.0f && config.imageRotateDegree < 91.0f)
// type = CImageApplyRotation::RotationType::Rotate_90_clockwise;
// else if (config.imageRotateDegree > 269.0f && config.imageRotateDegree < 271.0f)
// type = CImageApplyRotation::RotationType::Rotate_90_anti_clockwise;
// else if (config.imageRotateDegree > 179.0f && config.imageRotateDegree < 181.0f)
// type = CImageApplyRotation::RotationType::Rotate_180;
// else
// type = CImageApplyRotation::RotationType::Invalid;
m_ials.push_back(shared_ptr<CImageApply>(new CImageApplyRotation(type, config.is_backrotate180, config.resolution_dst, NULL)));
// m_ials.push_back(shared_ptr<CImageApply>(new CImageApplyRotation(type, config.is_backrotate180, config.resolution_dst, NULL)));
}
printf("Image processors: %d\n", m_ials.size());
return true;
}
@ -328,4 +332,5 @@ protected:
std::vector<std::shared_ptr<CImageApply>> m_ials;
std::shared_ptr<CImageApplyDogEarDetection> m_dog;
std::shared_ptr<CSizedetect> m_sizedetect;
// std::shared_ptr<CImageApplyColorCastCorrect> m_colorcast;
};

View File

@ -14,7 +14,7 @@ ImageSaveHandler::~ImageSaveHandler()
}
void ImageSaveHandler::add_image(void *data, int width, int height, int type, int scannnum)
void ImageSaveHandler::add_image(void *data, int width, int height, int type, int scannnum,std::uint32_t fpga_vs,CISVendor cistype)
{
static int indexx = 0;
std::string path = std::to_string(++indexx) + ".png";

View File

@ -8,7 +8,7 @@ class ImageSaveHandler : public IImageHandler
public:
ImageSaveHandler();
virtual ~ImageSaveHandler();
virtual void add_image(void* data, int width, int height, int type ,int scannnum);
virtual void add_image(void* data, int width, int height, int type ,int scannnum,std::uint32_t fpga_vs,CISVendor cistype);
virtual bool done();
private:

View File

@ -12,122 +12,161 @@
#include "ImageApplyAutoCrop.h"
#include "hgutils.h"
#include "correct_ultis.h"
#include <unistd.h>
#include "../usb/src/common/packet.h"
#include "../usb/src/common/sys_util.h"
namespace bmp
{
#pragma pack(push)
#pragma pack(1)
typedef struct BITMAPFILEHEADER
{
u_int16_t bfType;
u_int32_t bfSize;
u_int16_t bfReserved1;
u_int16_t bfReserved2;
u_int32_t bfOffBits;
} BITMAPFILEHEADER;
typedef struct BITMAPINFOHEADER
{
u_int32_t biSize;
u_int32_t biWidth;
u_int32_t biHeight;
u_int16_t biPlanes;
u_int16_t biBitCount;
u_int32_t biCompression;
u_int32_t biSizeImage;
u_int32_t biXPelsPerMeter;
u_int32_t biYPelsPerMeter;
u_int32_t biClrUsed;
u_int32_t biClrImportant;
} BITMAPINFODEADER;
#pragma pack(pop)
int save_2_bmp_file(const char *bmp_file, void *buf, int w, int h, int resolution)
{
BITMAPINFOHEADER bih = {0};
BITMAPFILEHEADER fh = {0};
int pal_size = 0, line_len = (w * 24 + 31) / 32 * 4;
FILE *dst = fopen(bmp_file, "wb");
if (!dst)
return errno;
bih.biSize = sizeof(bih);
bih.biWidth = w;
bih.biBitCount = 24;
bih.biSizeImage = h * line_len;
bih.biPlanes = 1;
bih.biHeight = h;
bih.biCompression = 0;
bih.biXPelsPerMeter = bih.biYPelsPerMeter = resolution * 39.37f + .5f;
fh.bfType = 'B' | ('M' << 8);
fh.bfOffBits = sizeof(fh) + sizeof(bih) + pal_size;
fh.bfSize = fh.bfOffBits + bih.biSizeImage;
fwrite(&fh, 1, sizeof(fh), dst);
fflush(dst);
printf("width * 3 = %d, line bytes = %d\n", w * 3, line_len);
unsigned char *ptr = (unsigned char *)buf;
unsigned int pad = 0;
int pad_l = 4 - ((w * 3) % 4), step = w * 3;
if (0)
{
ptr += w * 3 * (h - 1);
step *= -1;
}
if (line_len == w * 3)
{
bih.biHeight *= -1;
fwrite(&bih, 1, sizeof(bih), dst);
fwrite(buf, 1, bih.biSizeImage, dst);
}
else
{
fwrite(&bih, 1, sizeof(bih), dst);
for (int i = 0; i < h; ++i)
{
fwrite(ptr, w * 3, 1, dst);
fwrite(&pad, 1, pad_l, dst);
ptr += step;
}
}
fclose(dst);
return 0;
}
}
static const std::string loggername = "imageusbhandler";
ImageUsbHandler::ImageUsbHandler(std::shared_ptr<UsbImageProcQueue> images)
: pool(1), encodepools(6),pushpool(1), que_len_(0)
: pool(1), encodepools(6), pushpool(1), que_len_(0)
{
LOG_INIT();
this->images = images;
m_dog.reset(new CImageApplyDogEarDetection(40,1.0,50));
m_dog.reset(new CImageApplyDogEarDetection(40, 1.0, 50));
// m_colorcast.reset(new CImageApplyColorCastCorrect());
m_sizedetect.reset(new CSizedetect(1));
initLut();
auto info= jsonconfig().getscannerinfo();
H_ratio =*((float*)(&info.H_ratio));
V_ratio =*((float*)(&info.V_ratio));
auto info = jsonconfig().getscannerinfo();
H_ratio = *((float *)(&info.H_ratio));
V_ratio = *((float *)(&info.V_ratio));
}
ImageUsbHandler::~ImageUsbHandler()
{
}
static int push_img_data_times = 0;
static int take_img_data_times = 0;
static int num = 0;
void ImageUsbHandler::add_image(void *data, int width, int height, int type, int scannnum,std::uint32_t fpga_vs,CISVendor cistype)
void ImageUsbHandler::add_image(void *data, int width, int height, int type, int scannnum, std::uint32_t fpga_vs, CISVendor cistype)
{
printf("add_image(%u * %u)\n", width, height);
printf("\nadd_image(%u * %u), memory usage = %s\n", width, height, sys_util::format_readable_bytes(sys_util::get_memory_usage("scan")).c_str());
images->push(nullptr, false);
// bmp::save_2_bmp_file((std::string("/root/.scanner/log/cap_") + std::to_string(scannnum) + ".bmp").c_str(), data, width / 3, height, 200);
PACKIMAGE pkimg;
memset(&pkimg, 0, sizeof(pkimg));
pkimg.pos.paper_ind = scannnum;
pkimg.pos.status = IMG_STATUS_OK;
pkimg.pos.paper_side = PAPER_SIDE_LEFT;
std::string ext = ".jpg";
{
if (m_imgstatus.status != NO_error)
return;
cv::Mat mat;
if(m_scanconfig.g200params.dpi == 3)
if (m_scanconfig.g200params.dpi == 3)
mat = cv::Mat(height, width, CV_8UC1, data);
else
mat = cv::Mat(height, width, CV_8UC1, data).clone();
mat = cv::Mat(height, width, CV_8UC1, data).clone();
printf("Image %d parameters: %d * %d * %d\n", scannnum, mat.cols, mat.rows, mat.channels() * 8);
capture_data.Put(mat);
StopWatch checktime;
if (m_hgimgconfig.is_dogeardetection || m_hgimgconfig.en_sizecheck)
{
cv::Mat tmp = cv::Mat(height, width, CV_8UC1, data);
if (tmp.empty())
return;
m_imgstatus.status = Img_Detecting;
#ifdef G300
auto mergemat = GetStitchMat(type == 16?1:0,width,height,tmp);
#else
auto mergemat = GetMergeMat(type == CV_8UC1 ? width : width / 3, height, type, tmp,0x90001);
#endif
if (m_scanconfig.g200params.dpi == 1)
cv::resize(mergemat, mergemat, cv::Size(0, 0), 200.0 / 300.0, 1.0);
else if (m_scanconfig.g200params.dpi == 2)
cv::resize(mergemat, mergemat, cv::Size(0, 0), 200.0 / 300.0, 200.0 / 300.0);
else
{
#ifdef G200
cv::resize(mergemat,mergemat,cv::Size(0,0),200.0 / 600.0,1.43434/3); // 600 dpi <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ600<30>ɼ<EFBFBD>
#elif defined G300
cv::resize(mergemat,mergemat,cv::Size(0,0),200.0 / 600.0,1.432323/3);
#elif defined G400
cv::resize(mergemat,mergemat,cv::Size(0,0),200.0 / 600.0,1.5/3);
#else
cv::resize(mergemat,mergemat,cv::Size(0,0),200.0 / 600.0,1.432323/3);
#endif
}
if (m_hgimgconfig.is_dogeardetection)
{
printf("\n is_dogeardetection");
if(!m_scanconfig.g200params.pc_correct)
correctColor(mergemat, false);
auto dogmat=mergemat(cv::Rect(mergemat.cols/2, 0, mergemat.cols/2, mergemat.rows));
m_dog->apply(dogmat,0);
if(m_dog->getResult())
{
m_imgstatus.status=Dog_error;
m_imgstatus.sannum=scannnum;
add_scanevent({.From=IMG,.Code=m_imgstatus.status,.Img_Index=m_imgstatus.sannum});
return;
}
}
if(m_hgimgconfig.en_sizecheck)
{
auto sizemat=mergemat(cv::Rect(mergemat.cols/2, 0, mergemat.cols/2, mergemat.rows));
printf("\n en_sizecheck %d",m_scanconfig.g200params.paper);
m_sizedetect->SetPapertype(m_scanconfig.g200params.paper);
if(m_sizedetect->preprocess(sizemat,NULL))
{
m_imgstatus.status=Size_error;
m_imgstatus.sannum=scannnum;
add_scanevent({.From=IMG,.Code=m_imgstatus.status,.Img_Index=m_imgstatus.sannum});
return;
}
}
m_imgstatus.status = NO_error;
}
//tmp.release();
//std::lock_guard<std::mutex> guard(mtx);
add_que_count();
results.emplace(
pool.enqueue([this, width, height, type, ext, scannnum, data,cistype]
pool.enqueue([this, width, height, type, ext, scannnum, data, cistype]
{
printf("enqueue image index %d \n",scannnum);
StopWatch sw;
cv::Mat mat = capture_data.Take();
if(m_scanconfig.g200params.dpi == 3)
mat = cv::Mat(height, width, CV_8UC1, data);
else
mat = cv::Mat(height, width, CV_8UC1, data).clone();
capture_data.Put(mat);
printf("\nenqueue image index %d \n",scannnum);
StopWatch sw;
cv::Mat mat = capture_data.Take();
#ifdef G300
cv::Mat saveMat = GetStitchMat(type == 16?1:0,width,height,mat);
#else
int dstwidth = type==CV_8UC1?width:width/3;
cv::Mat saveMat =GetMergeMat(dstwidth, height, type,mat,0x90001);
#endif
printf("\n GetMergeMat time %f \n",sw.elapsed_ms());
printf("Merged image: %d * %d * %d\n", saveMat.cols, saveMat.rows, saveMat.channels() * 8);
//printf("\n GetMergeMat time %f \n",sw.elapsed_ms());
//cv::imwrite("/home/"+to_string(scannnum)+".png",saveMat);
int dpi = saveMat.cols==7344?2:3;
if(!m_scanconfig.g200params.pc_correct)
@ -137,7 +176,7 @@ void ImageUsbHandler::add_image(void *data, int width, int height, int type, int
add_que_count();
encodeimgs.push(encodepools.enqueue([this,width,height,type,cistype]() -> std::vector<MemoryPtr>
{
auto saveMat = encode_data.Take();
auto saveMat = encode_data.Take();
if(H_ratio>1.2f ||H_ratio<0.8f)
H_ratio=1.0f;
if(V_ratio>1.2f || V_ratio <0.8f)
@ -152,15 +191,17 @@ void ImageUsbHandler::add_image(void *data, int width, int height, int type, int
cv::resize(saveMat,saveMat,cv::Size(),H_ratio,V_ratio);
}
if(m_scanconfig.g200params.dpi == 3)
#ifdef G200
cv::resize(saveMat,saveMat,cv::Size(0,0),1.0*H_ratio,1.43434*V_ratio); // 600 dpi <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ600<30>ɼ<EFBFBD>
#elif defined G300
#ifdef G200
cv::resize(saveMat,saveMat,cv::Size(0,0),1.0*H_ratio,1.43434*V_ratio); // 600 dpi <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ600<30>ɼ<EFBFBD>
#elif defined G300
cv::resize(saveMat,saveMat,cv::Size(0,0),1.0*H_ratio,1.432323*V_ratio);
#elif defined G400
#elif defined G400
cv::resize(saveMat,saveMat,cv::Size(0,0),1.0*H_ratio,1.5*V_ratio);
#else
#else
cv::resize(saveMat,saveMat,cv::Size(0,0),1.0*H_ratio,1.432323*V_ratio);
#endif
#endif
printf("dpi = %d, image = %d * %d * %d\n", m_scanconfig.g200params.dpi, saveMat.cols, saveMat.rows, saveMat.channels() * 8);
cv::Mat imageMat;
std::vector<cv::Mat> imgs;
int actwidth = saveMat.cols / 2;
@ -173,13 +214,12 @@ void ImageUsbHandler::add_image(void *data, int width, int height, int type, int
imgs.push_back(imageMat);
}
}
// cv::imwrite("/home/proc.jpg",saveMat);
imgs.push_back(saveMat);
std::shared_ptr<IImageEncode> imageencode; //(new BmpImageEncode());
std::vector<MemoryPtr> encodedata;
bool iscorrect_mode =true;
if(!iscorrect_mode)
//if (!m_scanconfig.g200params.iscorrect_mode)
// imgs.push_back(saveMat);
std::shared_ptr<IImageEncode> imageencode; //(new BmpImageEncode());
std::vector<MemoryPtr> encodedata;
//bool iscorrect_mode =true;
//if(!iscorrect_mode)
if (!m_scanconfig.g200params.iscorrect_mode)
{
if (!m_hgimgconfig.is_switchfrontback && (imgs.size() > 1))
std::swap(imgs[0], imgs[1]);
@ -213,9 +253,10 @@ void ImageUsbHandler::add_image(void *data, int width, int height, int type, int
cv::cvtColor(enMat,enMat,cv::COLOR_BGR2GRAY);
}
if(m_scanconfig.g200params.iscorrect_mode)
imageencode.reset(new JpegImageEncode(false));
imageencode.reset(new JpegImageEncode(false, m_hgimgconfig.resolution_dst));
else
imageencode.reset(new JpegImageEncode(false));
imageencode.reset(new JpegImageEncode(m_scanconfig.g200params.color?false:true, m_hgimgconfig.resolution_dst));
encodedata.push_back(imageencode->encode(enMat));
}
}
@ -229,20 +270,28 @@ void ImageUsbHandler::add_image(void *data, int width, int height, int type, int
for (auto &data : mem)
{
if (data.get())
images->push(data, true);
{
images->push(data, true);
}
else
add_scanevent({.From = V4L2, .Code = 1});
}
}
else
printf("!!!!!!!!! mem proc = empty vector \n");
add_que_count(-1);
});
printf("imgproce time = %f \n", sw.elapsed_ms());
LOG_TRACE(string_format("imgproce time = %f\n", sw.elapsed_ms())); }));
add_que_count(-1);
//printf("imgproce time = %f \n", sw.elapsed_ms());
//LOG_TRACE(string_format("imgproce time = %f\n", sw.elapsed_ms()));
}));
add_que_count(-1);
}
}
bool ImageUsbHandler::is_limit(){
bool ImageUsbHandler::is_limit()
{
if (m_hgimgconfig.resolution_dst > 200.0 || m_hgimgconfig.papertype == 52 || m_hgimgconfig.papertype == 54 ||
m_hgimgconfig.papertype == 131)
{
@ -250,7 +299,7 @@ bool ImageUsbHandler::is_limit(){
{
results.front().get();
{
//std::lock_guard<std::mutex> guard(mtx);
// std::lock_guard<std::mutex> guard(mtx);
results.pop();
}
}
@ -265,7 +314,7 @@ bool ImageUsbHandler::is_limit(){
{
results.front().get();
{
//std::lock_guard<std::mutex> guard(mtx);
// std::lock_guard<std::mutex> guard(mtx);
results.pop();
}
}
@ -277,11 +326,10 @@ bool ImageUsbHandler::is_limit(){
return false;
}
void ImageUsbHandler::thread_push_stop_event(HGIntInfo ev)
{
printf("Received STOPSCAN event, but image-process is busying, wait real stop in thread ...\n");
while(!done())
while (!done())
{
std::this_thread::sleep_for(std::chrono::milliseconds(3));
}
@ -307,9 +355,9 @@ int32_t ImageUsbHandler::add_que_count(int adden)
void ImageUsbHandler::add_scanevent(HGIntInfo status)
{
printf("add_scanevent(%d)\n", status.From);
if(status.From == STOPSCAN && !done())
if (status.From == STOPSCAN && !done())
{
if(stop_event_thread_.get() && stop_event_thread_->joinable())
if (stop_event_thread_.get() && stop_event_thread_->joinable())
stop_event_thread_->join();
stop_event_thread_.reset(new std::thread(&ImageUsbHandler::thread_push_stop_event, this, status));
}
@ -330,39 +378,58 @@ void ImageUsbHandler::clear()
capture_data.Clear();
}
void ImageUsbHandler::Set_ratio(u32 h_ratio,u32 v_ratio)
void ImageUsbHandler::Set_ratio(u32 h_ratio, u32 v_ratio)
{
H_ratio =*((float*)(&h_ratio));
//V_ratio =*((float*)(&v_ratio));
H_ratio = *((float *)(&h_ratio));
// V_ratio =*((float*)(&v_ratio));
V_ratio = 1.0f;
}
bool ImageUsbHandler::done()
{
return add_que_count(0) == 0;
// return add_que_count(0) == 0;
bool over = true;
{
std::lock_guard<std::mutex> guard(mtx);
if(results.size() >= 1){
auto &fu_run = results.back();
if((fu_run.valid() && (fu_run.wait_for(std::chrono::seconds(0)) != std::future_status::ready)))
over = false;
}
if(over && encodeimgs.size()>=1)
{
auto &fu_encode = encodeimgs.back();
over = !fu_encode.valid() || encodeimgs.size() == 0;
// if((!fu_encode.valid()) && encodeimgs.size() == 1)
// over = true;
// else
// over = false;
// return !(fu_encode.wait_for(std::chrono::seconds(0)) != std::future_status::ready);
//return (!(fu_run.wait_for(std::chrono::seconds(0)) != std::future_status::ready))&&(!(fu_encode.wait_for(std::chrono::seconds(0)) != std::future_status::ready));
}
// bool over = true;
// {
// std::lock_guard<std::mutex> guard(mtx);
// if (results.size() >= 1)
// {
// auto &fu_run = results.back();
// if ((fu_run.valid() && (fu_run.wait_for(std::chrono::seconds(0)) != std::future_status::ready)))
// over = false;
// }
// if (over && encodeimgs.size() >= 1)
// {
// auto &fu_encode = encodeimgs.back();
// over = !fu_encode.valid() || encodeimgs.size() == 0;
// // if((!fu_encode.valid()) && encodeimgs.size() == 1)
// // over = true;
// // else
// // over = false;
// // return !(fu_encode.wait_for(std::chrono::seconds(0)) != std::future_status::ready);
// // return (!(fu_run.wait_for(std::chrono::seconds(0)) != std::future_status::ready))&&(!(fu_encode.wait_for(std::chrono::seconds(0)) != std::future_status::ready));
// }
// }
// return over;
std::lock_guard<std::mutex> guard(mtx);
if(results.size() >= 1){
auto &fu_run = results.back();
if((fu_run.valid() && (fu_run.wait_for(std::chrono::seconds(0)) != std::future_status::ready)))
return false;
}
if(encodeimgs.size()>=1)
{
auto &fu_encode = encodeimgs.back();
if((!fu_encode.valid()) && encodeimgs.size() == 1)
return true;
else
return false;
return !(fu_encode.wait_for(std::chrono::seconds(0)) != std::future_status::ready);
//return (!(fu_run.wait_for(std::chrono::seconds(0)) != std::future_status::ready))&&(!(fu_encode.wait_for(std::chrono::seconds(0)) != std::future_status::ready));
return over;
}
return true;
}
void ImageUsbHandler::config_procparams(HGImgProcParms params)
@ -376,3 +443,61 @@ void ImageUsbHandler::config_procparams(HGImgProcParms params)
LOG_TRACE(string_format("HGImgProcParms.fillhole = %d \n", params.imgprocparams.fillhole));
m_procparams = params;
}
//{
// "montage": {
// "category": "base",
// "readonly" : false,
// "affect" : 0,
// "group" : "base",
// "visible" : false,
// "field" : "cis",
// "pos" : 10,
// "unit" : "None",
// "title" : "图像拼接",
// "desc" : "将CIS采集的原始数据恢复为正常的图像",
// "type" : "bool",
// "cur" : true,
// "default" : true,
// "size" : 4,
// },
// "fb-split": {
// "category": "base",
// "readonly" : false,
// "affect" : 0,
// "group" : "base",
// "visible" : false,
// "field" : "cis",
// "pos" : 20,
// "unit" : "None",
// "title" : "拆分正反面",
// "desc" : "将正反面合成的一张图片,拆分成正面和反面图片",
// "type" : "bool",
// "cur" : true,
// "default" : true,
// "size" : 4,
// "depend_and": ["montage==true"]
// }
//}
//
//
//
//{
// "compress": {
// "category": "base",
// "readonly" : false,
// "affect" : 0,
// "group" : "base",
// "visible" : false,
// "field" : "imgproc",
// "pos" : 9999,
// "unit" : "None",
// "title" : "图像压缩",
// "desc" : "图片压缩成指定文件格式",
// "type" : "string",
// "cur" : "jpeg",
// "default" : "jpeg",
// "size" : 32,
// "range": ["none", "zip", "jpeg", "png", "bmp"] // none & zip 方式的数据为PACKIMAGE + 图像点阵数据
// }
//}

View File

@ -14,7 +14,7 @@ ImageUsbTestHandler::ImageUsbTestHandler(std::shared_ptr<UsbImageProcQueue> imag
{
}
void ImageUsbTestHandler::add_image(void* data, int width, int height, int type ,int scannnum)
void ImageUsbTestHandler::add_image(void* data, int width, int height, int type ,int scannnum,std::uint32_t fpga_vs,CISVendor cistype)
{
// results.emplace_back(
// pool.enqueue([this, data, width, height, type]

View File

@ -6,5 +6,5 @@ class ImageUsbTestHandler : public ImageUsbHandler
{
public:
ImageUsbTestHandler(std::shared_ptr<UsbImageProcQueue> images = nullptr);
virtual void add_image(void* data, int width, int height, int type,int scannnum);
virtual void add_image(void* data, int width, int height, int type,int scannnum,std::uint32_t fpga_vs,CISVendor cistype);
};

View File

@ -0,0 +1,344 @@
#include "iscanner.h"
#include <iostream>
#include "Imotorboard.h"
#include "Capturer.h"
#include <opencv2/opencv.hpp>
#include "StopWatch.h"
#include "iimagehandler.h"
#include "correct_ultis.h"
#include "applog.h"
#include "stringex.hpp"
#include "fpgacontrol.h"
#include "scannerregs.h"
#include "fpgacontrol.h"
#include "Gpio.h"
#include "deviceconfig.h"
#include <openssl/md5.h>
#include <openssl/aes.h>
#include <random>
#include <stdlib.h>
static const std::string loggername = "IScanner";
IScanner::IScanner(std::shared_ptr<ICapturer> capturer, std::shared_ptr<IMotorBoard> mb, std::shared_ptr<WakeUp> wake)
: bMsgLoop(true),
scancount(1024)
// testGpio(new Gpio(153))
{
LOG_INIT();
this->wake = wake;
this->mb = mb;
this->capturer = capturer;
mb->set_capture(capturer);
scannerinfo = getscannerinfo();
auto capturecallback = [&](int cap_call_code, std::string s_info)
{
HGIntInfo info = {.From = AutoCorrect, .Code = cap_call_code, .Img_Index = s_info.length()};
imagehandler->add_scanevent(info);
if (s_info.length() > 0)
((ScannerRegAccess *)m_parent)->write_info(s_info);
};
this->capturer->setcapturecall(capturecallback);
}
IScanner::~IScanner()
{
bMsgLoop = false;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
sysEvent.Put(ScanEvent::S_EVT_STOP_SCAN);
if (threadRunMessageLoop.joinable())
threadRunMessageLoop.join();
}
bool IScanner::check_scan(std::string encodehexstr){
bool is_scan = true;
if(DeviceConfig().GetParam().is_lock)
{
auto tmp_token = DeviceConfig().GetParam().token;
if((encodehexstr.length() != 32) || (tmp_token.length() !=32))
is_scan = false;
else{
AES_KEY aes_key;
std::uint8_t key[16] ={0};
//tmp_token = "C34E58CD5F3F2FF703E1AA24892FBD69";
printf("tmp_token %s",tmp_token);
for(int i =0;i<16;i++)
{
key[i] = std::strtol(tmp_token.substr(i*2,2).c_str(),nullptr,16);
}
if(AES_set_decrypt_key(key,128,&aes_key)< 0)
{
is_scan = false;
}
std::uint8_t cipher[16] ={0};
std::uint8_t decode[16] ={0};
for(int i =0;i<16;i++)
{
cipher[i] = std::strtol(encodehexstr.substr(i*2,2).c_str(),nullptr,16);
}
AES_ecb_encrypt(cipher,decode,&aes_key,AES_DECRYPT);
for(int i =0;i<scannerinfo.SerialNum.length();i++)
{
if(decode[i]!= scannerinfo.SerialNum[i])
{
is_scan = false;
break;
}
if(i == (scannerinfo.SerialNum.length() - 1 ))
is_scan = true;
}
printf("\n decode %s",(char*)decode);
}
}
if(!is_scan)
{
imagehandler->add_scanevent({.From = MtBoard, 0x100});
if (m_config.g200params.is_autopaper)
imagehandler->add_scanevent({.From = STOPSCAN, 1});
imagehandler->add_scanevent({.From = STOPSCAN, 0});
}
return is_scan;
}
std::string IScanner::getmbversion()
{
return mbversion;
}
void IScanner::add_scansever(HGIntInfo event)
{
if (imagehandler.get())
imagehandler->add_scanevent(event);
}
bool IScanner::set_hgimgconfig(GScanCap config)
{
printf("enter config set_hgimgconfig \n");
scancount = config.is_duplex ? config.scannum / 2 : config.scannum;
m_cap = config;
mb->set_scancap(config);
if(config.resolution_dst < 300)
m_config.g200params.dpi = 1;
#ifdef G300
else
m_config.g200params.dpi = 2;
#else
else if ((config.resolution_dst >= 300) &&(config.resolution_dst < 500))
m_config.g200params.dpi = 2;
else
m_config.g200params.dpi = 3;
#endif
if(config.HsvFilterType!=0 || config.filter!=3 ||config.fadeback!=0)
m_config.g200params.color = 1;
printf("\n m_config.g200params.dpi =%d",m_config.g200params.dpi);
imagehandler->set_scanconfig(m_config);
if (config.is_autocrop && (config.papertype == 0)&&m_config.g200params.en_autosize)
m_config.g200params.paper = 16;
if(config.papertype == 54)
m_config.g200params.paper = m_config.g200params.en_autosize? 16 : 17;
if(config.papertype == 52 || config.papertype == 131)
m_config.g200params.paper = m_config.g200params.en_autosize? 16 : 18;
if (imagehandler.get())
{
imagehandler->clear();
return imagehandler->set_config(config);
}
return false;
}
void IScanner::configparam(HGScanConfig config)
{
LOG_TRACE(string_format("******HGScanConfig******\n config.g200params.color = %d \n config.g200params.dpi = %d \n config.g200params.paper =%d \n config.g200params.double_feed_enbale = %d \n config.g200params.stable_enbale = %d \n config.g200params.iscorrect_mode = %d \n config.g200params.pc_correct = %d\n ",
config.g200params.color,
config.g200params.dpi,
config.g200params.paper,
config.g200params.double_feed_enbale,
config.g200params.stable_enbale,
config.g200params.iscorrect_mode,
config.g200params.pc_correct));
printf("******HGScanConfig******\n config.g200params.color = %d \n config.g200params.dpi = %d \n config.g200params.paper =%d \n config.g200params.double_feed_enbale = %d \n config.g200params.stable_enbale = %d \n config.g200params.iscorrect_mode = %d \n config.g200params.pc_correct = %d\n ",
config.g200params.color,
config.g200params.dpi,
config.g200params.paper,
config.g200params.double_feed_enbale,
config.g200params.stable_enbale,
config.g200params.iscorrect_mode,
config.g200params.pc_correct);
imagehandler->set_scanconfig(config);
m_config = config;
if (config.g200params.iscorrect_mode)
{
scancount = 65535;
}
}
int IScanner::getimageprocedone()
{
if (imagehandler.get())
return imagehandler->done();
return true;
}
void IScanner::test_autocorrect(int colormode)
{
printf("color mode =%s \n", colormode == 1 ? "COLOR" : "GRAY");
capturer->init_autocorrect(colormode);
}
bool IScanner::is_runscan()
{
return (fu_runscan && fu_runscan->is_runing()) || (imagehandler && !imagehandler->done());
}
void IScanner::set_imagehandler(std::shared_ptr<IImageHandler> handler)
{
imagehandler = handler;
}
void IScanner::clear_error()
{
mb->clear_error();
}
void IScanner::runMessageLoop()
{
FsmState *fsmState = FsmStateManagerEx<InitState>::GetState();
FsmState::setScanner(this);
do
{
ScanEvent evt = sysEvent.Take();
fsmState = fsmState->on_event(evt);
} while (bMsgLoop);
}
bool IScanner::paper_ready()
{
return mb->paper_ready();
}
bool IScanner::get_keeplastpaper()
{
return mb->get_keeplastpaper();
}
void IScanner::startcapimage()
{
FILE * fp =fopen("/sys/class/tty/ttyUSB0/device/huagao_scanner","w");
if (fp == NULL)
perror("startcapimage open filed");
else
fprintf(fp,"%d",1);
fclose(fp);
}
void IScanner::set_motorboardcallback(MotorBoardGlue glue)
{
mb->set_callbacks(glue);
}
void IScanner::set_imgprocparams(HGImgProcParms params)
{
imagehandler->config_procparams(params);
}
void IScanner::test_cap(HGScanConfig config)
{
printf("capturer openning \n");
FPGAConfigParam fpgaparam = GetFpgaparam(m_config.g200params.dpi, m_config.g200params.color);
capturer->open(config,fpgaparam);
capturer->snap();
void *data;
if (data = capturer->readFrame(2000))
{
int imtype = capturer->color() ? CV_8UC3 : CV_8UC1;
cv::Mat mat;
cv::Mat saveMat;
std::vector<cv::Mat> ch_mats;
int dstwidth, dstheight;
int width = capturer->width();
int height = capturer->height();
dstwidth = width * 3;
dstheight = height / 3;
if (imtype == CV_8UC3)
{
mat = cv::Mat(height / 3, width * 9, CV_8UC1, data);
saveMat = cv::Mat(dstheight, dstwidth, CV_8UC3);
}
else
{ // gray
saveMat = cv::Mat(height, width * 3, CV_8UC1, data);
}
static int savenum;
if (imtype == CV_8UC3)
{
for (int i = 0; i < 3; i++)
{ // B G R
cv::Mat mattemp = mat(cv::Rect(dstwidth * i, 0, dstwidth, dstheight));
ch_mats.push_back(mattemp);
}
swap(ch_mats[1], ch_mats[2]);
cv::merge(ch_mats, saveMat);
}
//cv::imwrite(std::to_string(++savenum) + ".jpg", saveMat);
}
else
{
printf("LOST Image \n");
}
capturer->close();
printf("capturer closed \n");
}
void IScanner::set_sleeptime(int val)
{
if (wake.get())
wake->settime(val);
}
int IScanner::get_sleeptime()
{
if (wake.get())
return wake->gettime();
return 0;
}
void IScanner::resettime()
{
if (wake.get())
wake->resettime();
}
int IScanner::get_sleepstatus()
{
if (wake.get())
return wake->get_status();
return 0;
}
void IScanner::set_paprent(void *parent)
{
if (parent)
m_parent = parent;
}
void IScanner::set_sleepstatus(bool off)
{
if (wake.get())
{
if (off)
wake->power_on();
else
wake->power_off();
}
}
void IScanner::clean_paper_road(){
if(mb.get())
mb->clean_paper_road();
}

View File

@ -0,0 +1,71 @@
#pragma once
#include <memory>
#include <thread>
#include "BlockingQueue.h"
#include "fsmstate.h"
#include <threadex.h>
#include "commondef.h"
#include "wakeup.hpp"
#include <future>
class IMotorBoard;
class ICapturer;
class IImageHandler;
class Gpio;
class IScanner
{
public:
IScanner(std::shared_ptr<ICapturer> capturer, std::shared_ptr<IMotorBoard> mb, std::shared_ptr<WakeUp> wake);
virtual ~IScanner();
virtual void start_scan() = 0;
virtual void stop_scan() = 0;
virtual int count() = 0;
virtual int mode() = 0;
virtual int getmbstatus() = 0;
virtual bool getpaperon() = 0;
virtual void runScan() = 0;
void clean_paper_road();
bool check_scan(std::string encodehexstr);
void configparam(HGScanConfig config);
void put(ScanEvent evt) { sysEvent.Put(evt); }
bool is_runscan();
void set_imagehandler(std::shared_ptr<IImageHandler> handler = nullptr);
void clear_error();
bool paper_ready();
bool get_keeplastpaper();
void set_motorboardcallback(MotorBoardGlue glue);
void set_imgprocparams(HGImgProcParms parmas);
void test_autocorrect(int colormode);
void test_cap(HGScanConfig config);
bool set_hgimgconfig(GScanCap config);
void add_scansever(HGIntInfo event);
void set_sleeptime(int val);
int get_sleeptime();
void resettime();
int get_sleepstatus();
void set_sleepstatus(bool off);
int getimageprocedone();
void set_paprent(void* parent);
std::string getmbversion();
void runMessageLoop();
void startcapimage();
protected:
std::thread threadRunMessageLoop;
volatile bool bMsgLoop = true;
BlockingQueue<ScanEvent> sysEvent;
std::shared_ptr<IMotorBoard> mb;
std::shared_ptr<ICapturer> capturer;
std::shared_ptr<WakeUp> wake;
std::shared_ptr<ThreadEx> fu_runscan;
std::shared_ptr<ThreadEx> m_capturereload;
std::shared_ptr<IImageHandler> imagehandler;
std::function<void(int)> m_mtcallback;
int scancount=0;
HGScanConfig m_config;
GScanCap m_cap;
ScannerNativeParam scannerinfo;
void* m_parent;
std::string mbversion;
};

View File

@ -1,6 +1,6 @@
#include "scanner.h"
#include <iostream>
#include "motorboard.h"
#include "Imotorboard.h"
#include "Capturer.h"
#include <opencv2/opencv.hpp>
#include "StopWatch.h"
@ -11,24 +11,13 @@
#include "scannerregs.h"
#include "fpgacontrol.h"
#include "Gpio.h"
#include "deviceconfig.h"
#include <openssl/md5.h>
#include <openssl/aes.h>
#include <random>
#include <stdlib.h>
#include "correct_ultis.h"
static const std::string loggername = "Scanner";
Scanner::Scanner(std::shared_ptr<ICapturer> capturer, std::shared_ptr<MotorBoard> mb, std::shared_ptr<WakeUp> wake)
: bMsgLoop(true),
scancount(1024)
// testGpio(new Gpio(153))
Scanner::Scanner(std::shared_ptr<ICapturer> capturer, std::shared_ptr<IMotorBoard> mb, std::shared_ptr<WakeUp> wake):IScanner(capturer,mb,wake)
{
LOG_INIT();
this->wake = wake;
this->mb = mb;
this->capturer = capturer;
// threadRunMessageLoop = std::move(std::thread(&Scanner::runMessageLoop, this));
auto mb_error_call = [&](unsigned int error_code)
{
int code = 0;
@ -140,7 +129,7 @@ Scanner::Scanner(std::shared_ptr<ICapturer> capturer, std::shared_ptr<MotorBoard
auto mb_mltop_call = [&](unsigned int value)
{
if (value & 0x00080000)
is_ml_top = true; //升降台到<EFBFBD>?
is_ml_top = true; //升降台到
};
auto mb_auto_paper = [&](unsigned int value)
{
@ -151,20 +140,10 @@ Scanner::Scanner(std::shared_ptr<ICapturer> capturer, std::shared_ptr<MotorBoard
};
MotorBoardGlue mb_glue = {mb_error_call, mb_scandone_call, mb_osmode_call, mb_set_sleeptime_call, mb_mltop_call, mb_auto_paper};
mb->set_callbacks(mb_glue);
mb->set_capture(capturer);
scannerinfo = getscannerinfo();
auto capturecallback = [&](int cap_call_code, std::string s_info)
{
HGIntInfo info = {.From = AutoCorrect, .Code = cap_call_code, .Img_Index = s_info.length()};
imagehandler->add_scanevent(info);
if (s_info.length() > 0)
((ScannerRegAccess *)m_parent)->write_info(s_info);
};
this->capturer->setcapturecall(capturecallback);
mb->set_auto_paper(m_config.g200params.is_autopaper); //防止程序异常死掉后未关闭连续扫描导致升降台抬升扫<E58D87>?
mb->set_auto_paper(m_config.g200params.is_autopaper); //防止程序异常死掉后未关闭连续扫描导致升降台抬升扫描
u32 value;
mb->read(0x00, value);
printf("mb reg[0] = 0x%x \n", value);
printf("mb reg[0] = %d \n", value);
value = 0;
mb->read(0x03, value);
if (value >= 35211210)
@ -174,143 +153,12 @@ Scanner::Scanner(std::shared_ptr<ICapturer> capturer, std::shared_ptr<MotorBoard
else
m_mbver = MotorVersion::Motor_old;
mbversion = std::to_string(value);
printf("mb reg[3] = 0x%x \n", value);
// capturer->open();
printf("mb reg[0] = %d \n", value);
}
Scanner::~Scanner()
{
bMsgLoop = false;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
sysEvent.Put(ScanEvent::S_EVT_STOP_SCAN);
if (threadRunMessageLoop.joinable())
threadRunMessageLoop.join();
}
void Scanner::try_scan(const std::string encodehexstr)
{
bool is_scan = true;
printf("\n encodehexstr = ");
for(int i =0;i<encodehexstr.length();i++)
printf(" %x",encodehexstr[i]);
if(DeviceConfig().GetParam().is_lock)
{
auto tmp_token = DeviceConfig().GetParam().token;
if((encodehexstr.length() != 32) || (tmp_token.length() !=32))
is_scan = false;
else{
AES_KEY aes_key;
std::uint8_t key[16] ={0};
//tmp_token = "C34E58CD5F3F2FF703E1AA24892FBD69";
printf("tmp_token %s",tmp_token);
for(int i =0;i<16;i++)
{
key[i] = std::strtol(tmp_token.substr(i*2,2).c_str(),nullptr,16);
}
if(AES_set_decrypt_key(key,128,&aes_key)< 0)
{
is_scan = false;
}
std::uint8_t cipher[16] ={0};
std::uint8_t decode[16] ={0};
for(int i =0;i<16;i++)
{
cipher[i] = std::strtol(encodehexstr.substr(i*2,2).c_str(),nullptr,16);
}
AES_ecb_encrypt(cipher,decode,&aes_key,AES_DECRYPT);
for(int i =0;i<scannerinfo.SerialNum.length();i++)
{
if(decode[i]!= scannerinfo.SerialNum[i])
{
is_scan = false;
break;
}
if(i == (scannerinfo.SerialNum.length() - 1 ))
is_scan = true;
}
printf("\n decode %s",(char*)decode);
}
// tmp += scannerinfo.SerialNum;
// uchar md5[MD5_DIGEST_LENGTH];
// MD5_CTX ctx;
// MD5_Init(&ctx);
// MD5_Update(&ctx,tmp.c_str(),tmp.size());
// MD5_Final(md5,&ctx);
// printf("\n md5 = %s",md5);
// std::string md5_hex;
// const char map[]="0123456789abcdef";
// for(size_t i=0;i < MD5_DIGEST_LENGTH; i++)
// {
// md5_hex+=map[md5[i] /16];
// md5_hex+=map[md5[i] %16];
// }
// if(md5_hex.compare(encodehexstr.c_str()) != 0)
// is_scan = false;
//printf("\naes hex= %s",decode);
}
if(is_scan)
start_scan();
else
{
imagehandler->add_scanevent({.From = MtBoard, 0x100});
if (m_config.g200params.is_autopaper)
imagehandler->add_scanevent({.From = STOPSCAN, 1});
imagehandler->add_scanevent({.From = STOPSCAN, 0});
}
}
std::string Scanner::getmbversion()
{
return mbversion;
}
void Scanner::add_scansever(HGIntInfo event)
{
if (imagehandler.get())
imagehandler->add_scanevent(event);
}
bool Scanner::set_hgimgconfig(GScanCap config)
{
printf("enter config set_hgimgconfig \n");
scancount = config.is_duplex ? config.scannum / 2 : config.scannum;
m_cap = config;
if (imagehandler.get())
{
imagehandler->clear();
return imagehandler->set_config(config);
}
return false;
}
void Scanner::configparam(HGScanConfig config)
{
LOG_TRACE(string_format("******HGScanConfig******\n config.g200params.color = %d \n config.g200params.dpi = %d \n config.g200params.paper =%d \n config.g200params.double_feed_enbale = %d \n config.g200params.stable_enbale = %d \n config.g200params.iscorrect_mode = %d \n config.g200params.pc_correct = %d\n ",
config.g200params.color,
config.g200params.dpi,
config.g200params.paper,
config.g200params.double_feed_enbale,
config.g200params.stable_enbale,
config.g200params.iscorrect_mode,
config.g200params.pc_correct));
printf("******HGScanConfig******\n config.g200params.color = %d \n config.g200params.dpi = %d \n config.g200params.paper =%d \n config.g200params.double_feed_enbale = %d \n config.g200params.stable_enbale = %d \n config.g200params.iscorrect_mode = %d \n config.g200params.pc_correct = %d\n ",
config.g200params.color,
config.g200params.dpi,
config.g200params.paper,
config.g200params.double_feed_enbale,
config.g200params.stable_enbale,
config.g200params.iscorrect_mode,
config.g200params.pc_correct);
imagehandler->set_scanconfig(config);
m_config = config;
if (config.g200params.iscorrect_mode)
{
scancount = 65535;
}
}
void Scanner::start_scan()
@ -321,7 +169,8 @@ void Scanner::start_scan()
if (wake.get())
wake->setsleepfalg(true);
mb_error_code = is_ml_top = handstop = false;
capturer->open(m_config);
FPGAConfigParam fpgaparam = GetFpgaparam(m_config.g200params.dpi, m_config.g200params.color);
capturer->open(m_config,fpgaparam);
scannerinfo = getscannerinfo();
int spdmode = 0;
if (scannerSp.count((SpeedMode)scannerinfo.speedmode) <= 0)
@ -336,10 +185,8 @@ void Scanner::start_scan()
{
spdmode = scannerSp[(SpeedMode)scannerinfo.speedmode].motorSpeed;
}
mb->set_speed_mode(spdmode);
imagehandler->Set_ratio(scannerinfo.H_ratio,scannerinfo.V_ratio);
mb->set_speed_mode(spdmode,1,1);
printf("\n set speedmode %d read speedmode %d", spdmode, mb->get_speed_mode());
// capturer->open();
imagehandler->resetimgstatus();
mb->clear_error();
fu_runscan.reset(new ThreadEx(&Scanner::runScan, this));
@ -362,14 +209,6 @@ int Scanner::mode()
{
return mb->os_mode();
}
int Scanner::getimageprocedone()
{
if (imagehandler.get())
return imagehandler->done();
return true;
}
int Scanner::getmbstatus()
{
mb->clear_error();
@ -379,57 +218,6 @@ int Scanner::getmbstatus()
return val & 0x700fe;
}
void Scanner::test_autocorrect(int colormode)
{
printf("color mode =%s \n", colormode == 1 ? "COLOR" : "GRAY");
capturer->init_autocorrect(colormode);
}
bool Scanner::is_runscan()
{
return (fu_runscan && fu_runscan->is_runing()) || (imagehandler && !imagehandler->done());
}
void Scanner::set_imagehandler(std::shared_ptr<IImageHandler> handler)
{
imagehandler = handler;
}
void Scanner::clear_error()
{
mb->clear_error();
}
void Scanner::runMessageLoop()
{
FsmState *fsmState = FsmStateManagerEx<InitState>::GetState();
FsmState::setScanner(this);
do
{
ScanEvent evt = sysEvent.Take();
fsmState = fsmState->on_event(evt);
} while (bMsgLoop);
}
bool Scanner::paper_ready()
{
return mb->paper_ready();
}
bool Scanner::get_keeplastpaper()
{
return mb->get_keeplastpaper();
}
void Scanner::startcapimage()
{
FILE * fp =fopen("/sys/class/tty/ttyUSB0/device/huagao_scanner","w");
if (fp == NULL)
perror("startcapimage open filed");
else
fprintf(fp,"%d",1);
fclose(fp);
}
static int pickpapernum = 0;
void Scanner::runScan()
@ -457,11 +245,9 @@ void Scanner::runScan()
imagehandler->add_scanevent({.From = MtBoard, .Code = 4});
LOG_TRACE("\nCover Open status");
imagehandler->add_scanevent({.From = STOPSCAN, 0});
}
if (m_config.g200params.is_autopaper)
{
imagehandler->add_scanevent({.From = STOPSCAN, 1});
mb->set_auto_paper(false);
if (mb_error_code != 0 && m_config.g200params.is_autopaper)
mb->set_auto_paper(false);
return;
}
imagehandler->add_scanevent({.From = MtBoard, .Code = val & 0x700fe});
printf("\n scan stop code =%d ", val & 0x700fe);
@ -480,14 +266,8 @@ void Scanner::runScan()
}
if (!is_ml_top || mb_error_code || handstop)
{
if (mb_error_code == 0 && handstop == 0) // 无其他异常时发送升降台未到达指定位置异<E7BDAE>?
{
if (mb_error_code == 0 && handstop == 0) // 无其他异常时,发送升降台未到达指定位置异常
imagehandler->add_scanevent({.From = MtBoard, 0x80000});
if (m_config.g200params.is_autopaper)
mb->set_auto_paper(false);
}
capturer->stop();
capturer->close();
capturer->reset();
this_thread::sleep_for(chrono::milliseconds(20));
imagehandler->add_scanevent({.From = STOPSCAN, 0});
@ -509,126 +289,25 @@ void Scanner::runScan()
wake->resettime();
wake->setsleepfalg(false);
}
capturer->reset();
imagehandler->add_scanevent({.From = STOPSCAN, 0});
if ((mb_error_code != 0 || imagehandler->getimgstatus().status != NO_error ) && m_config.g200params.is_autopaper)
capturer->reset();
if (mb_error_code != 0 && m_config.g200params.is_autopaper)
mb->set_auto_paper(false);
printf("\n-------scanner done-------\n");
}
void Scanner::set_motorboardcallback(MotorBoardGlue glue)
{
mb->set_callbacks(glue);
}
void Scanner::set_imgprocparams(HGImgProcParms params)
{
imagehandler->config_procparams(params);
}
void Scanner::test_cap(HGScanConfig config)
{
printf("capturer openning \n");
capturer->open(config);
capturer->snap();
void *data;
if (data = capturer->readFrame(2000))
{
int imtype = capturer->color() ? CV_8UC3 : CV_8UC1;
cv::Mat mat;
cv::Mat saveMat;
std::vector<cv::Mat> ch_mats;
int dstwidth, dstheight;
int width = capturer->width();
int height = capturer->height();
dstwidth = width * 3;
dstheight = height / 3;
if (imtype == CV_8UC3)
{
mat = cv::Mat(height / 3, width * 9, CV_8UC1, data);
saveMat = cv::Mat(dstheight, dstwidth, CV_8UC3);
}
else
{ // gray
saveMat = cv::Mat(height, width * 3, CV_8UC1, data);
}
static int savenum;
if (imtype == CV_8UC3)
{
for (int i = 0; i < 3; i++)
{ // B G R
cv::Mat mattemp = mat(cv::Rect(dstwidth * i, 0, dstwidth, dstheight));
ch_mats.push_back(mattemp);
}
swap(ch_mats[1], ch_mats[2]);
cv::merge(ch_mats, saveMat);
}
cv::imwrite(std::to_string(++savenum) + ".jpg", saveMat);
}
else
{
printf("LOST Image \n");
}
capturer->close();
printf("capturer closed \n");
}
void Scanner::set_sleeptime(int val)
{
if (wake.get())
wake->settime(val);
}
int Scanner::get_sleeptime()
{
if (wake.get())
return wake->gettime();
return 0;
}
void Scanner::resettime()
{
if (wake.get())
wake->resettime();
}
int Scanner::get_sleepstatus()
{
if (wake.get())
return wake->get_status();
return 0;
}
void Scanner::set_paprent(void *parent)
{
if (parent)
m_parent = parent;
}
void Scanner::set_sleepstatus(bool off)
{
if (wake.get())
{
if (off)
wake->power_on();
else
wake->power_off();
}
}
bool Scanner::getpaperon()
{
#ifdef G200
if (mb.get())
{
uint val = 0;
mb->read(2, val);
if ((val & 0x10000) && m_config.g200params.is_autopaper)
mb->set_auto_paper(false);
return val & 0x10000;
}
return 0;
#endif
return 1;
}
void Scanner::scanpaperout()
{
@ -648,7 +327,7 @@ void Scanner::scanpaperout()
//LOG_TRACE(string_format("+++++paper on:%fms+++++++++++ ", swCap.elapsed_ms()));
if (mb->wait_paper_out(3000))
{
HG_LOG("wait_paper_out time =%f \n",sw.elapsed_ms());
printf("wait_paper_out time =%f \n",sw.elapsed_ms());
sw.reset();
swCap.reset();
if (data = capturer->readFrame(2000))
@ -656,13 +335,11 @@ void Scanner::scanpaperout()
printf("\n readFrame time =%f pickpapernum = %d",swCap.elapsed_ms(),pickpapernum++);
if (imagehandler)
{
imagehandler->add_image(data, capturer->width(), capturer->height() / 3 * 3, capturer->color(), scannum++);
imagehandler->add_image(data, capturer->width(), capturer->height() / 3 * 3, capturer->color(), scannum++,0x90001,CISVendor::DUNNAN_CIS_V0);
data = NULL;
}
//std::this_thread::sleep_for(std::chrono::milliseconds(100));
swCap.reset();
scannerinfo.RollerNum++;
scannerinfo.TotalScanned++;
LOG_TRACE(string_format("capture one=%fms", swCap.elapsed_ms()));
}
else
@ -755,7 +432,7 @@ void Scanner::scanold()
swCap.reset();
if (imagehandler)
{
imagehandler->add_image(data, capturer->width(), capturer->height() / 3 * 3, capturer->color(), scannum++);
imagehandler->add_image(data, capturer->width(), capturer->height() / 3 * 3, capturer->color(), scannum++,0x90001,CISVendor::DUNNAN_CIS_V0);
data = NULL;
}
LOG_TRACE(string_format("readFrame time =%f ",swCap.elapsed_ms()));

View File

@ -1,11 +1,5 @@
#pragma once
#include <memory>
#include <thread>
#include "BlockingQueue.h"
#include "fsmstate.h"
#include <threadex.h>
#include "commondef.h"
#include "wakeup.hpp"
#include "iscanner.h"
enum MotorVersion : uint{
Motor_old,
@ -13,72 +7,25 @@ enum MotorVersion : uint{
Motor_paperout,
};
class MotorBoard;
class ICapturer;
class IImageHandler;
class Gpio;
class Scanner
class Scanner : public IScanner
{
public:
Scanner(std::shared_ptr<ICapturer> capturer, std::shared_ptr<MotorBoard> mb, std::shared_ptr<WakeUp> wake);
~Scanner();
void try_scan(const std::string encodehexstr);
void configparam(HGScanConfig config);
void start_scan();
void stop_scan();
int count();
int mode();
void put(ScanEvent evt) { sysEvent.Put(evt); }
bool is_runscan();
void set_imagehandler(std::shared_ptr<IImageHandler> handler = nullptr);
void clear_error();
bool paper_ready();
bool get_keeplastpaper();
void set_motorboardcallback(MotorBoardGlue glue);
void set_imgprocparams(HGImgProcParms parmas);
void test_autocorrect(int colormode);
void test_cap(HGScanConfig config);
bool set_hgimgconfig(GScanCap config);
void add_scansever(HGIntInfo event);
void set_sleeptime(int val);
int get_sleeptime();
void resettime();
int get_sleepstatus();
void set_sleepstatus(bool off);
int getimageprocedone();
void set_paprent(void* parent);
bool getpaperon();
int getmbstatus();
std::string getmbversion();
Scanner(std::shared_ptr<ICapturer> capturer, std::shared_ptr<IMotorBoard> mb, std::shared_ptr<WakeUp> wake);
virtual ~Scanner();
virtual void start_scan() override;
virtual void stop_scan() override;
virtual int count() override;
virtual int mode() override;
virtual int getmbstatus() override;
virtual bool getpaperon() override;
virtual void runScan() override;
private:
void runMessageLoop();
void runScan();
void startcapimage();
void scanold();
void scanpaperout();
//std::shared_ptr<Gpio> testGpio;
std::thread threadRunMessageLoop;
volatile bool bMsgLoop = true;
BlockingQueue<ScanEvent> sysEvent;
std::shared_ptr<MotorBoard> mb;
std::shared_ptr<ICapturer> capturer;
std::shared_ptr<WakeUp> wake;
std::shared_ptr<ThreadEx> fu_runscan;
std::shared_ptr<IImageHandler> imagehandler;
std::function<void(int)> m_mtcallback;
volatile int done_scan = 0;
volatile bool is_ml_top = 0;
volatile bool handstop = 0;
int scancount=0;
volatile unsigned int mb_error_code;
volatile int mb_error_code = 0;
MotorVersion m_mbver;
HGScanConfig m_config;
GScanCap m_cap;
ScannerNativeParam scannerinfo;
void* m_parent;
std::string mbversion;
};

View File

@ -0,0 +1,293 @@
#include <iostream>
#include "Imotorboard.h"
#include "Capturer.h"
#include <opencv2/opencv.hpp>
#include "StopWatch.h"
#include "iimagehandler.h"
#include "applog.h"
#include "stringex.hpp"
#include "fpgacontrol.h"
#include "scannerregs.h"
#include "fpgacontrol.h"
#include "Gpio.h"
#include "scannero300.h"
#include "SysInforTool.h"
#include "correct_ultis.h"
#include "dailex.hpp"
static const std::string loggername = "ScannerO300";
ScannerO300::ScannerO300(std::shared_ptr<ICapturer> capturer, std::shared_ptr<IMotorBoard> mb, std::shared_ptr<WakeUp> wake) : IScanner(capturer, mb, wake), mfpgaversion(0x90001)
{
LOG_INIT();
capturer->regs()->read(15, mfpgaversion);
SysInforTool(ScannerSysInfo()).GetSysInfo();
auto mb_error_call = [&](std::uint32_t code)
{
if (done_scan)
return;
if (code == 0x40000 && m_config.g200params.paper != 16)
return;
if (code != 0)
{
imagehandler->add_scanevent({.From = MtBoard, .Code = code});
mb_error = code;
if (code == 0x20)
scannerinfo.DoubleFeedTimes++;
done_scan = true;
}
printf("\n scan done 1 code = %d ", code);
};
auto mb_scandone_call = [&]()
{
printf("\n scan done 2");
done_scan = true;
};
auto mb_auto_paper = [&](unsigned int value)
{
printf("连续扫描模式检测到有纸");
if (fu_runscan && fu_runscan->is_runing())
return;
start_scan();
};
mb->set_callbacks({mb_error_call, mb_scandone_call, nullptr, nullptr, nullptr, mb_auto_paper});
scannerinfo = getscannerinfo();
auto mb_ev_cb = [&](uint32_t ev) -> void
{
if(imagehandler)
imagehandler->add_scanevent({.From = MBEvent, .Code = ev});
};
mb->set_motorboard_event_callback(mb_ev_cb);
}
ScannerO300::~ScannerO300()
{
}
void ScannerO300::start_scan()
{
printf("m_config.g200params.color= %d ,m_config.g200params.dpi = %d ,m_config.g200params.paper = %d ", m_config.g200params.color, m_config.g200params.dpi, m_config.g200params.paper);
mb->clear_error();
capturer->regs()->read(15, mfpgaversion);
if (m_capturereload && m_capturereload->is_runing())
{
while (m_capturereload->is_runing())
std::this_thread::sleep_for(std::chrono::milliseconds(10));
m_capturereload.reset();
}
if (fu_runscan && fu_runscan->is_runing())
return;
if (wake.get())
wake->setsleepfalg(true);
m_cistype = Dail().GetValue().dails.in_voltage3 == 1 ? CISVendor::DUNNAN_CIS_V0 : CISVendor::HUALIN_CIS_V0;
FPGAConfigParam fpgaparam = GetFpgaparam(m_config.g200params.dpi, m_config.g200params.color);
capturer->open(m_config, fpgaparam);
scannerinfo = getscannerinfo();
imagehandler->Set_ratio(fpgaparam.HRatio, fpgaparam.VRatio);
imagehandler->resetimgstatus();
mb->clear_error();
mb_error = 0;
scancount = 0;
fu_runscan.reset(new ThreadEx(&ScannerO300::runScan, this));
}
void ScannerO300::stop_scan()
{
done_scan = true;
mb->set_auto_paper(false);
}
int ScannerO300::count()
{
return scannerinfo.RollerNum;
}
int ScannerO300::mode()
{
return 0;
}
int ScannerO300::getmbstatus()
{
return 0;
}
bool ScannerO300::getpaperon()
{
return mb->paper_ready();
}
void ScannerO300::runScan()
{
int spdmode = 0;
if (scannerSp.find((SpeedMode)scannerinfo.speedmode) != scannerSp.end())
spdmode = scannerSp.at((SpeedMode)scannerinfo.speedmode).motorSpeed;
mb->set_speed_mode(spdmode, m_config.g200params.dpi, m_config.g200params.color);
system("echo performance > /sys/devices/system/cpu/cpu5/cpufreq/scaling_governor");
mb->set_double_inpect(m_config.g200params.double_feed_enbale);
mb->set_auto_paper(m_config.g200params.is_autopaper);
StopWatch sw;
if (mb->is_converopen())
{
imagehandler->add_scanevent({.From = MtBoard, .Code = 4});
mb_error = 4;
printf("\n------------------converopen-------------------");
}
else if (mb->is_jam())
{
imagehandler->add_scanevent({.From = MtBoard, .Code = 16});
mb_error = 16;
printf("\n------------------jam-------------------");
}
else if (!mb->paper_ready())
{
imagehandler->add_scanevent({.From = MtBoard, .Code = 2});
mb_error = 2;
printf("\n-------------------no paper---------------");
}
else
{
done_scan = false;
printf("\n------------------motor run ------------------- %f ", sw.elapsed_ms());
std::thread m_startthread([this, spdmode]
{
std::this_thread::sleep_for(std::chrono::milliseconds(20));//20ms再启动 保证到达 wait paper in 之后才有传感器信号
mb->set_cuospeed(0xff,m_config.g200params.dpi,m_config.g200params.color);
mb->start();
std::this_thread::sleep_for(std::chrono::milliseconds(90));
mb->stop_pick_paper();
mb->set_cuospeed(spdmode,m_config.g200params.dpi,m_config.g200params.color);
std::this_thread::sleep_for(std::chrono::milliseconds(500));
mb->pick_paper(); });
void *data = NULL;
while (!done_scan)
{
if (mb->wait_paper_in(5000))
{
printf("\n------------------wait_paper_in------------------- %f ", sw.elapsed_ms());
if (mb_error != 0)
break;
capturer->snap();
if (mb->wait_paper_out(7000))
{
printf("\n------------------wait_paper_out------------------- %f ", sw.elapsed_ms());
if (mb_error != 0)
break;
scannerinfo.RollerNum++;
scannerinfo.TotalScanned++;
#ifdef G300
HGSize size;
size = papersMap[(PaperSize)m_config.g200params.paper];
size.width = size.width == 0 ? papersMap[PaperSize::G400_A4].width : size.width;
size.height = size.height == 0 ? papersMap[PaperSize::G400_A4].height : size.height;
if (m_config.g200params.dpi != 1)
size.height = std::min((unsigned int)16002, size.height * 3 / 2);
int channels = m_config.g200params.color ? 3 : 1;
int dstwith = size.width * channels * 3;
int dstHeight = size.height / 9 * 3;
#else
int height; //
if (m_config.g200params.paper == (unsigned int)PaperSize::G400_AUTO)
{
int delaytime = m_config.g200params.dpi == 0x02 ? 150 : (m_config.g200params.dpi == 0x03 ? 250 : 100);
this_thread::sleep_for(chrono::milliseconds(delaytime)); // 纸张过了 多采集几张
height = capturer->getautosizeheight();
}
else
height = capturer->height();
int channel = capturer->color() == 16 ? 3 : 1;
int dstwith = capturer->width() * 2 * 3 * channel;
int dstHeight = m_config.g200params.paper == (unsigned int)PaperSize::G400_AUTO ? height : height / channel;
#endif
printf("\n------------------readFrame------------------- %f", sw.elapsed_ms());
if (data = capturer->readFrame(7000))
{
printf("\n addimage %f ", sw.elapsed_ms());
while (imagehandler->is_limit())
{
this_thread::sleep_for(chrono::milliseconds(10));
continue;
}
printf("\n dstwith = %d ,dstHeight = %d color type = %d", dstwith, dstHeight, capturer->color());
imagehandler->add_image(data, dstwith, dstHeight, capturer->color(), ++scancount, mfpgaversion, m_cistype);
}
else
{
imagehandler->add_scanevent({.From = V4L2, .Code = 0});
done_scan = true;
mb_error = 79; // 79异常取图失败
printf("capture error \n");
break;
}
if (imagehandler->getimgstatus().status != Error_Status::NO_error && (m_cap.is_dogeardetection || m_cap.en_sizecheck))
{
done_scan = true;
mb_error = 82;
break;
}
if ((!mb->paper_ready()) || (scancount >= (m_cap.is_duplex ? m_cap.scannum / 2 : m_cap.scannum)))
{
done_scan = true;
break;
}
printf("\n scancount =%d m_cap.scannum =%d addimage %f", scancount, m_cap.scannum, sw.elapsed_ms());
if (!done_scan)
mb->pick_paper();
else
{
done_scan = true;
break;
}
printf("\n pick paper done %f ", sw.elapsed_ms());
}
else
{
printf("\n scan done 16");
if (mb_error == 0)
{
scannerinfo.JamTimes++;
imagehandler->add_scanevent({.From = MtBoard, .Code = 16});
mb_error = 16;
}
break;
}
}
else
{
printf("\n scan done 8");
imagehandler->add_scanevent({.From = MtBoard, .Code = 8});
mb_error = 8;
scannerinfo.FeedErrorTimes++;
break;
}
}
printf("\n scan done 5");
if (m_startthread.joinable())
m_startthread.join();
if ((mb_error == 0) || (mb_error == 82))
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
mb->stop();
}
mb->set_double_inpect(false);
m_capturereload.reset(new ThreadEx([&]
{
capturer->stop();
capturer->close();
capturer->reset(); }));
while (!imagehandler->done())
this_thread::sleep_for(chrono::milliseconds(10));
printf("-------scanner done------- %f \n", sw.elapsed_ms());
imagehandler->add_scanevent({.From = STOPSCAN, 0});
system("sudo cpufreq-set -g ondemand");
if (wake.get())
{
wake->resettime();
wake->setsleepfalg(false);
}
savescannerinfo(scannerinfo);
done_scan = true;
if (mb_error && mb_error != 2)
{
mb->LedControlOption(HG_LedOption::HG_RED_ON, 0);
}
if (mb_error)
{
mb->set_auto_paper(false);
}
mb->set_error(mb_error);
if (!mb->paper_ready() && (mb_error == 0 || (mb->is_converopen() == false && mb->is_jam() == false && mb_error != 2)))
mb->motor_reset();
}

View File

@ -0,0 +1,23 @@
#pragma once
#include "iscanner.h"
class ScannerO300 : public IScanner
{
public:
ScannerO300(std::shared_ptr<ICapturer> capturer, std::shared_ptr<IMotorBoard> mb, std::shared_ptr<WakeUp> wake);
virtual ~ScannerO300();
virtual void start_scan() override;
virtual void stop_scan() override;
virtual int count() override;
virtual int mode() override;
virtual int getmbstatus() override;
virtual bool getpaperon() override;
virtual void runScan() override;
private:
volatile bool done_scan = true;
volatile int mb_error = 0;
std::uint32_t mfpgaversion;
CISVendor m_cistype;
//std::future<void> m_addimg_future;
};

View File

@ -188,7 +188,8 @@ bool ScannerRegAccess::write(unsigned int addr, const unsigned int val)
std::string cfg(load_mini_file("/root/.scanner/log/cfg_4308.bin"));
GScanCap cap = *(GScanCap*)&cfg[0];
cap.resolution_dst = cap.resolution_native = scan_dpi;
cap.resolution_dst = scan_dpi;
cap.resolution_native = 200;
cap.scannum = scan_cnt;
printf("DPI: %d, Count: %d\n", scan_dpi, scan_cnt);
#else

View File

@ -23,8 +23,7 @@ public:
WakeUp()
{
b_run=true;
if(get_status()==0)
power_on();
update_state();
m_thread.reset(new std::thread(&WakeUp::input,this));
m_time =std::chrono::steady_clock::now();
sleeptime = jsonconfig().getscannerinfo().sleeptime;
@ -46,7 +45,7 @@ public:
return;
char buf=0x55;
if((m_status == 1)&&releasecallback)
releasecallback();
releasecallback();
write(fd,&buf,1);
close(fd);
m_status=0;
@ -54,17 +53,23 @@ public:
void power_on(){
int fd=open(dev_name,O_RDWR);
resettime();
if(fd == -1)
return;
char buf=0xaa;
write(fd,&buf,1);
close(fd);
if((m_status == 0)&&initcallback)
if((m_status == 0)&&initcallback)
initcallback();
m_status=1;
}
int get_status()
{
return m_status;
}
int update_state()
{
int fd= open(dev_name,O_RDWR);
if(fd == -1)
@ -88,14 +93,14 @@ public:
sleeptime= val;
auto var = jsonconfig().getscannerinfo();
var.sleeptime = val;
printf("\nwakeup time %d",val);
jsonconfig().savescannerinfo(var);
resettime();
}
void setinitcallback(std::function<void()> init,std::function<void()> release){
this->initcallback = init;
this->releasecallback = release;
}
}
int gettime() {return sleeptime;}
@ -137,21 +142,33 @@ private:
while (read(fd, &event, sizeof(event)) == sizeof(event))
{
printf("get event: type = 0x%x, code = 0x%x, value = 0x%x\n", event.type, event.code, event.value);
if(event.type == 0x01 && event.code == 0x3e && event.value == 0x00)
if(event.type == 0x01 && event.code == 0x3e && event.value == 0x01)
{
int val= get_status();
if(val == 1) {
printf("system in sleep.\n");
power_off();
}
else if(val == 0) {
printf("system wakeup.\n");
power_on();
resettime();
}
else {
printf("error sleep index.\n");
}
pressed_time = std::chrono::steady_clock::now();
}
if(event.type == 0x01 && event.code == 0x3e && event.value == 0x00)
{
if(std::chrono::duration<double, std::milli>(std::chrono::steady_clock::now() - pressed_time).count() > 5000){
printf("wake up poweroff .\n");
system("poweroff");
}
if(std::chrono::duration<double, std::milli>(std::chrono::steady_clock::now() - pressed_time).count() > 2000)
{
int val= update_state();
if(val == 1) {
printf("system in sleep.\n");
power_off();
}
else if(val == 0) {
printf("system wakeup.\n");
power_on();
resettime();
}
else {
printf("error sleep index.\n");
}
}
}
}
}
@ -164,12 +181,13 @@ private:
{
printf("wakeup_process.c::poll err...\n");
}
if((sleeptime!=-1) && std::chrono::duration<double>(std::chrono::steady_clock::now()-m_time).count()>sleeptime && m_status==1 && !sleep_falg )
if((sleeptime!=-1) && (std::chrono::duration<double>(std::chrono::steady_clock::now()-m_time).count()>sleeptime) && (m_status==1) && (!sleep_falg) )
{
if(get_status()==1)
if(update_state()==1)
power_off();
printf("\nwakeup_process sleep...\n");
}
//printf("\n wake up time ----- %f sleep_flag =%d sleeptime %d",std::chrono::duration<double>(std::chrono::steady_clock::now()-m_time).count(),sleep_falg,sleeptime);
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
@ -177,9 +195,10 @@ private:
bool b_run;
int sleeptime;
bool sleep_falg;
std::atomic<bool> m_status;
volatile bool m_status;
std::function<void()> initcallback;
std::function<void()> releasecallback;
std::shared_ptr<std::thread> m_thread;
std::chrono::steady_clock::time_point m_time;
std::chrono::steady_clock::time_point pressed_time;
};

View File

@ -4,8 +4,8 @@ target("gscanner")
set_kind("static")
add_files("*.cpp")
add_syslinks("pthread")
-- add_links("turbojpeg")
add_links("ssl","crypto")
-- add_links("turbojpeg")
add_deps("motorboard", "capimage", "gusb", "gimgproc", "applog","fpgaupdate")
add_packages("common")
add_includedirs(".", { public = true})

View File

@ -1,3 +1,239 @@
// #include <iostream>
// #include <iomanip>
// #include <memory>
// #include <thread>
// #include <chrono>
// #include <stdio.h>
// #include <stdlib.h>
// #include <signal.h>
// #include <errno.h>
// #include <unistd.h>
// #include <sys/file.h>
// #include "filetools.h"
// #include "stringex.hpp"
// #include <functional>
// #include "usbservice.h"
// #include "Capturer.h"
// #include "motorboard.h"
// #include "itransmit.h"
// #include "scannerregs.h"
// #include "scanner.h"
// #include "inotify.h"
// #include "memoryex.h"
// #include "usbimageprocqueue.h"
// #include "imageusbtesthandler.h"
// #include "applog.h"
// #include "jsonconfig.h"
// #include "wakeup.hpp"
// using namespace std;
// #define MY_PID_FILE "/tmp/scanservice_pid"
// #define BUF_LEN_FOR_PID 64
// static int write_pid_into_fd(int fd, pid_t pid)
// {
// int ret = -1;
// char buf[BUF_LEN_FOR_PID] = {0};
// /* Move cursor to the start of file. */
// lseek(fd, 0, SEEK_SET);
// sprintf(buf, "%d", pid);
// ret = write(fd, buf, strlen(buf));
// if (ret <= 0)
// { /* Write fail or write 0 byte */
// if (ret == -1)
// perror("Write " MY_PID_FILE " fail\n");
// ret = -1;
// }
// else
// {
// printf("Create " MY_PID_FILE " ok, pid=%d\n", pid);
// ret = 0;
// }
// return ret;
// }
// static int create_pid_file(pid_t pid)
// {
// int fd, ret;
// char buf[BUF_LEN_FOR_PID] = {0};
// fd = open(MY_PID_FILE, O_WRONLY | O_CREAT | O_EXCL, 0666); /* rw-rw-rw- */
// if (fd == -1)
// {
// perror("Create " MY_PID_FILE " fail\n");
// return -1;
// }
// ret = flock(fd, LOCK_EX);
// if (ret == -1)
// {
// perror("flock " MY_PID_FILE " fail\n");
// close(fd);
// return -1;
// }
// ret = write_pid_into_fd(fd, pid);
// flock(fd, LOCK_UN);
// close(fd);
// return ret;
// }
// static int check_pid_file(int fd, pid_t pid)
// {
// int ret = -1;
// pid_t old_pid;
// char buf[BUF_LEN_FOR_PID] = {0};
// ret = flock(fd, LOCK_EX);
// if (ret == -1)
// {
// perror("flock " MY_PID_FILE " fail\n");
// return -1;
// }
// ret = read(fd, buf, sizeof(buf) - 1);
// if (ret < 0)
// { /* read error */
// perror("read from " MY_PID_FILE " fail\n");
// ret = -1;
// }
// else if (ret > 0)
// { /* read ok */
// old_pid = atol(buf);
// /* Check if old_pid is running */
// ret = kill(old_pid, 0);
// if (ret < 0)
// {
// if (errno == ESRCH)
// { /* old_pid is not running. */
// ret = write_pid_into_fd(fd, pid);
// }
// else
// {
// perror("send signal fail\n");
// ret = -1;
// }
// }
// else
// { /* running */
// printf("Program already exists, pid=%d\n", old_pid);
// ret = -1;
// }
// }
// else if (ret == 0)
// { /* read 0 byte from file */
// ret = write_pid_into_fd(fd, pid);
// }
// flock(fd, LOCK_UN);
// return ret;
// }
// static int init_pid_file()
// {
// pid_t pid;
// int fd, ret;
// pid = getpid();
// fd = open(MY_PID_FILE, O_RDWR);
// if (fd == -1)
// { /* open file fail */
// if (errno == ENOENT)
// { /* No such file. Create one for this program. */
// ret = create_pid_file(pid);
// }
// else
// {
// perror("open " MY_PID_FILE " fail\n");
// ret = -1;
// }
// }
// else
// { /* pid file already exists */
// ret = check_pid_file(fd, pid);
// close(fd);
// }
// return ret;
// }
// static void sigHandler(int sig)
// {
// if (sig == SIGINT || sig == SIGTERM)
// remove(MY_PID_FILE);
// printf("exit now \n");
// _exit(0);
// }
// int main()
// {
// if (-1 == init_pid_file())
// {
// exit(-1);
// }
// /* Ctrl + C */
// if (signal(SIGINT, sigHandler) == SIG_ERR)
// {
// exit(-1);
// }
// /* kill pid / killall name */
// if (signal(SIGTERM, sigHandler) == SIG_ERR)
// {
// exit(-1);
// }
// auto wake = std::shared_ptr<WakeUp>(new WakeUp());
// auto cap = std::shared_ptr<Capturer>(new Capturer());
// auto mt = std::shared_ptr<MotorBoard>(new MotorBoard());
// wake->setinitcallback([&mt,&cap]{
// std::this_thread::sleep_for(std::chrono::milliseconds(5000));
// cap->Fpga_regsAccess_reset(true);
// mt->init_statecontrol();
// },[&mt,&cap]{
// cap->Fpga_regsAccess_reset(false);
// mt->release_statecontrol();
// });
// auto scanner = std::shared_ptr<Scanner>(new Scanner(cap, mt,wake));
// UsbService us(cap->regs(), mt->regs());
// auto usbhotplugcall = [&](bool connect){
// if(connect){
// printf("USB Connect\n");
// }else
// {
// scanner->stop_scan();
// printf("USB Disconnect Scanner STOP SCAN\n");
// exit(0);
// }
// };
// us.set_onconnect_call(usbhotplugcall);
// auto notify = us.notify();
// std::shared_ptr<UsbImageProcQueue> usbImage(new UsbImageProcQueue(notify));
// auto transfer = us.transmiter();
// auto receiver = us.receiver();
// std::shared_ptr<IRegsAccess> regs = std::shared_ptr<IRegsAccess>(new ScannerRegAccess(scanner, usbImage, transfer,receiver));
// scanner->set_imagehandler(std::shared_ptr<IImageHandler>(new ImageUsbHandler(usbImage)));
// us.set_scannerregs(regs);
// while(1) {std::this_thread::sleep_for(std::chrono::milliseconds(2));}
// return 0;
// }
#include <iostream>
#include <iomanip>
#include <memory>
@ -10,10 +246,14 @@
#include <unistd.h>
#include <sys/file.h>
#include "filetools.h"
#include "stringex.hpp"
#include <functional>
#include "usbservice.h"
#include "Capturer.h"
#include "Imotorboard.h"
#include "motormanager.h"
#include "iscanner.h"
#include "scannero300.h"
#include "MonoCapturer.h"
#include "motorboard.h"
#include "itransmit.h"
#include "scannerregs.h"
@ -25,6 +265,8 @@
#include "applog.h"
#include "jsonconfig.h"
#include "wakeup.hpp"
#include "Led.h"
#include "dailex.hpp"
using namespace std;
#define MY_PID_FILE "/tmp/scanservice_pid"
@ -196,35 +438,59 @@ int main()
{
exit(-1);
}
//auto deviceinfo = jsonconfig().getdeviceinfo();
auto wake = std::shared_ptr<WakeUp>(new WakeUp());
auto cap = std::shared_ptr<Capturer>(new Capturer());
auto mt = std::shared_ptr<MotorBoard>(new MotorBoard());
wake->setinitcallback([&mt,&cap]{
std::this_thread::sleep_for(std::chrono::milliseconds(5000));
cap->Fpga_regsAccess_reset(true);
mt->init_statecontrol();
},[&mt,&cap]{
cap->Fpga_regsAccess_reset(false);
mt->release_statecontrol();
});
auto scanner = std::shared_ptr<Scanner>(new Scanner(cap, mt,wake));
//auto cap = std::shared_ptr<ICapturer>(new Capturer());
auto cap = std::shared_ptr<MonoCapturer>(new MonoCapturer());
std::shared_ptr<MotorManager> mt;
std::shared_ptr<IScanner> scanner;
mt = std::shared_ptr<MotorManager>(new MotorManager());
scanner = std::shared_ptr<IScanner>(new ScannerO300(cap, mt,wake));
mt->GetOrSetSleepFlag(false,wake->get_status() == 0 ?true : false);
printf("\n Scan_G300");
printf("\n 鎷ㄧ爜寮€鍏?%d",Dail().GetValue().value);
UsbService us(cap->regs(), mt->regs());
auto usbhotplugcall = [&](bool connect){
if(connect){
printf("USB Connect\n");
mt->GetOrSetUsbConnectFlag(false,true);
}else
{
scanner->stop_scan();
StopWatch sw;
while(scanner->is_runscan() || sw.elapsed_s() < 10)
{
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
mt->GetOrSetUsbConnectFlag(false,false);
printf("USB Disconnect Scanner STOP SCAN\n");
exit(0);
}
};
us.set_onconnect_call(usbhotplugcall);
auto notify = us.notify();
std::shared_ptr<UsbImageProcQueue> usbImage(new UsbImageProcQueue(notify));
wake->setinitcallback([&cap,&mt]{
std::this_thread::sleep_for(std::chrono::milliseconds(5000));
cap->Fpga_regsAccess_reset(true);
mt->LedControlOption(HG_LedOption::HG_WHITE_ON,0);
mt->GetOrSetSleepFlag(false,false);
},[&mt,&cap,&usbImage,&scanner]{
scanner->stop_scan();
scanner->add_scansever({.From = STOPSCAN , .Code = 1});
cap->Fpga_regsAccess_reset(false);
mt->LedControlOption(HG_LedOption::HG_GREEN_ON,0);
mt->GetOrSetSleepFlag(false,true);
});
if(wake->get_status() == 0)
{
cap->Fpga_regsAccess_reset(false);
mt->LedControlOption(HG_LedOption::HG_GREEN_ON,0);
mt->GetOrSetSleepFlag(false,true);
}
auto transfer = us.transmiter();
auto receiver = us.receiver();
std::shared_ptr<IRegsAccess> regs = std::shared_ptr<IRegsAccess>(new ScannerRegAccess(scanner, usbImage, transfer,receiver));

View File

@ -121,7 +121,8 @@ int main()
config.g200params.dpi=1;
config.g200params.paper=(unsigned int)PaperSize::G400_A4;
void *data;
cap->open(config);
// cap->open(config);
cap->open();
int ch = 0;
int ixx = 0;

View File

@ -26,9 +26,16 @@ int main()
//std::string straa = read_all_from("/mnt/d/3.tif");
//fipMemoryIO mio((unsigned char*)straa.c_str(), straa.size());
//auto filet = mio.getFileType();
std::string imgpath = "/home/linaro/gxx-linux/2.jpg";
cv::Mat mat=cv::imread(imgpath,cv::IMREAD_GRAYSCALE);
ImageEncodePtr encoder(new BmpImageEncode());
encoder->encode(mat);
std::string imgpath = "/root/.scanner/log/raw.bmp";
cv::Mat mat=cv::imread(imgpath,cv::IMREAD_COLOR);
if(mat.empty())
{
std::cout<<" empty image "<<mat.rows<<std::endl;
return 0;
}
// JpegImageEncode *encoder=new JpegImageEncode(false, 200);
std::vector<unsigned char> buffer;
cv::imencode(".jpg", mat,buffer);
std::cout<<" imencode image done"<<std::endl;
return 0;
}

View File

@ -114,7 +114,7 @@ int main()
mb.set_callbacks(mb_glue);
done_scan = 0;
mb.start();
mb.set_speed_mode(1);
mb.set_speed_mode(1, 200, 1);
StopWatch sw;
for (;;)
{

View File

@ -21,6 +21,7 @@ public:
HGIntInfo info;
if(containsimg)
{
printf("UsbImageProcQueue::push\n");
images.push(image);
//images.Put(image);
info.From = IMG;
@ -49,6 +50,7 @@ public:
std::lock_guard<std::mutex> lck(mx);
if(images.size()>0)
{
printf("UsbImageProcQueue::pop\n");
auto front = images.front();
images.pop();
//auto front=images.Take();

View File

@ -82,6 +82,7 @@ enum packet_cmd
PACK_CMD_SCAN_BASE = 200,
PAIR_COMMAND(PACK_CMD_SCAN_START), // start scanning, [in]: PACK_BASE, [out]: PACK_BASE
PAIR_COMMAND(PACK_CMD_SCAN_IMG), // device -> host, PACK_BASE::payload - LPPACKIMAGE
PAIR_COMMAND(PACK_CMD_SCAN_PAPER), // device -> host, ONE paper has passed through the CIS. PACK_BASE::data - status of this paper
PACK_CMD_SCAN_FINISHED_ROGER, // device -> host, PACK_BASE::data is scanner_status
PAIR_COMMAND(PACK_CMD_SCAN_STOP), // stop scanning, [in]: PACK_BASE, [out]: PACK_BASE
//PAIR_COMMAND(PACK_CMD_SCAN_IMAGE_REQ), // get image request, [in]: PACK_BASE, [out] PACK_BASE on error, or PACK_BASE::payload - LPPACKIMAGE
@ -155,12 +156,13 @@ enum img_compression
};
enum img_status
{
IMG_STATUS_OK = 0,
IMG_STATUS_DOUBLE,
IMG_STATUS_JAM,
IMG_STATUS_OK = 0, // normal
IMG_STATUS_DOUBLE, // double-feeded paper
IMG_STATUS_JAM, // jammed paper
IMG_STATUS_STAPLE, // staples on the paper
IMG_STATUS_SIZE_ERR, // size check failed
IMG_STATUS_DOGEAR, // paper has dogear
IMG_STATUS_BLANK, // blank image
};
enum data_type
{
@ -190,6 +192,16 @@ enum rot_angle
ROT_ANGLE_180,
ROT_ANGLE_270,
};
enum clr_channel
{
COLOR_CHANNEL_RGB = 0,
COLOR_CHANNEL_RGBA,
COLOR_CHANNEL_GRAY,
COLOR_CHANNEL_RED,
COLOR_CHANNEL_GREEN,
COLOR_CHANNEL_BLUE,
COLOR_CHANNEL_ALPHA,
};
#pragma pack(push)
#pragma pack(1)
@ -251,7 +263,7 @@ typedef struct _img_pos
uint64_t img_over : 1; // 0 - has data yet; 1 - END for the image. (image-collector set)
uint64_t paper_side : 3; // enum paper_side. front of paper(When scanning multiple sheets, the paper feeding side is the front side). (image-collector set)
uint64_t back_rot : 2; // back rotation angle, enum rot_angle. (image-collector set)
uint64_t channel_ind : 4; // index of color channel, based ZERO, 0x0f for all channels. (image-collector set)
uint64_t channel_ind : 4; // index of color channel, enum clr_channel. (image-collector set)
uint64_t status : 4; // img_status. (image-collector set)
uint64_t split_ind : 7; // splitting order, from left to right and then top to bottom, based ZERO
uint64_t multiout_ind : 4; // index of multi-out
@ -274,7 +286,7 @@ typedef struct _pack_img
uint32_t reserve : 2; // unused now
uint32_t info_size; // image information size in bytes, information part is used for quality of JPEG, pallete of BMP .... (image-collector set)
uint64_t data_size; // image data size in 'data' with bytes. (image-collector set)
char data[0]; // two parts: image info (info_size) + image data (data_size)
// char data[0]; // two parts: image info (info_size) + image data (data_size)
STRUCT_CONSTRUCTOR(_pack_img)
}PACKIMAGE, * LPPACKIMAGE;

View File

@ -102,7 +102,44 @@ bool sane_cfg_provider::sane_option_value_set(json* jsn, void* data, const char*
return ret;
}
int32_t sane_cfg_provider::inner_get_config(json* root, void* buf, size_t* len, const char* cfg_name, std::string* strval)
{
int ret = 0;
std::string val("");
if (!len)
return EINVAL;
if (cfg_name)
{
json* child = nullptr;
if (root->get_value(cfg_name, child) && child)
{
val = sane_cfg_provider::sane_option_value_get(child, "cur", strval);
child->release();
}
}
else
{
val = root->to_string();
}
if (ret == 0)
{
if (*len < val.length())
{
*len = val.length() + 4;
ret = ENOMEM;
}
else
{
memcpy(buf, val.c_str(), val.length());
*len = val.length();
}
}
return ret;
}

View File

@ -46,6 +46,9 @@ public:
static std::string sane_option_value_get(json* jsn, const char* key = "cur"/*cur, default*/, std::string* strval = nullptr/*convert value into string*/);
static bool sane_option_value_set(json* jsn, void* data, const char* key = "cur"/*cur, default*/);
protected:
int32_t inner_get_config(json* root, void* buf, size_t* len, const char* cfg_name, std::string* strval);
public:
// Function: get all or given name configuration value
//
@ -116,19 +119,6 @@ public:
int32_t set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo);
};
class hardware : public sane_cfg_provider
{
public:
hardware();
protected:
~hardware();
public:
virtual int32_t get_config(void* buf, size_t* len, const char* cfg_name = nullptr, std::string* str = nullptr) override;
virtual int32_t set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) override;
};
class img_processor : public sane_cfg_provider

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,56 @@
#pragma once
// image process interface classes
//
// created on 2023-04-19
//
#include <referer.h>
#include <packet.h>
#include <sane_cfg.h>
#include <functional>
class json;
#define CIS_API std::function<int(int*)> // return error code, set real value to parameter if in-value was not exact
typedef struct _cis_api
{
CIS_API set_color_mode;
CIS_API set_dpi;
CIS_API set_sample;
CIS_API set_frame_height;
CIS_API set_gain_front;
CIS_API set_gain_back;
CIS_API set_offset_front;
CIS_API set_offset_back;
CIS_API set_exposure_front_red;
CIS_API set_exposure_front_green;
CIS_API set_exposure_front_blue;
CIS_API set_exposure_back_red;
CIS_API set_exposure_back_green;
CIS_API set_exposure_back_blue;
}CISAPI, *LPCISAPI;
class hardware : public sane_cfg_provider
{
json* cfg_;
CISAPI api_;
int32_t set(const char* name, void* data, size_t* len);
public:
hardware();
protected:
~hardware();
// sane_cfg_provider
public:
virtual int32_t get_config(void* buf, size_t* len, const char* cfg_name = nullptr, std::string* strval = nullptr) override;
virtual int32_t set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) override;
public:
void set_api(LPCISAPI api);
};

View File

@ -15,6 +15,7 @@
#ifdef ASYNC_EP
#include "common/sys_util.h"
#include "common/json/json.h"
#include "hardware/hardware.h"
#include "commondef.h"
#endif
@ -1558,6 +1559,7 @@ protected:
virtual ~image_packet()
{
uint32_t size = img_->size();
head_->release();
img_.reset();
log_cls::log(LOG_LEVEL_ALL, "Image-%04u sending complete: %u/%u, memory usage %s\n", ind_, offset_, size, sys_util::format_readable_bytes(sys_util::get_memory_usage("scan")).c_str());
@ -1726,7 +1728,7 @@ dyn_mem_ptr UsbDevice::handle_bulk_cmd(LPPACK_BASE pack, uint32_t* used, packet_
cfg->val_off = 0;
cfg->name_off = val.length() + 1;
pk->payload_len = sizeof(CFGVAL) + strlen(pack->payload) + 1 + val.length() + 1;
strcpy(cfg->data, val.c_str());
memcpy(cfg->data, val.c_str(), val.length());
strcpy(cfg->data + cfg->name_off, pack->payload);
reply->set_len(base_head_size + pk->payload_len);
*used = base_head_size + pack->payload_len;
@ -1903,6 +1905,8 @@ void UsbDevice::do_system_command(const char* cmd)
void UsbDevice::init(void)
{
readonly_cfg* r = new readonly_cfg();
hardware *hrd = new hardware();
size_t l = sizeof(dpi_);
cfg_text_ = "{\"resolution\":{\"category\":\"base\",\"readonly\":false,\"affect\":2,\"ver\":1,\"group\":\"base\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u5206\\u8fa8\\u7387\",\"desc\":\"\\u8bbe\\u7f6e\\u626b\\u63cf\\u56fe\\u50cf\\u7684\\u5206\\u8fa8\\u7387\",\"type\":\"int\",\"cur\":200,\"default\":200,\"size\":4,\"range\":[100,150,200,300,600]},\"count\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"ver\":1,\"group\":\"base\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u626b\\u63cf\\u5f20\\u6570\",\"desc\":\"\\u8bbe\\u7f6e\\u626b\\u63cf\\u7684\\u7eb8\\u5f20\\u6570\\u91cf\",\"type\":\"int\",\"cur\":-1,\"default\":-1,\"size\":4,\"range\":[-1,1]}}";
@ -1912,6 +1916,8 @@ void UsbDevice::init(void)
cfg_ = new sane_cfg_mgr();
cfg_->reg_sane_provider(dynamic_cast<sane_cfg_provider*>(r));
l = cfg_->reg_sane_provider(dynamic_cast<sane_cfg_provider*>(this));
l = cfg_->reg_sane_provider(dynamic_cast<sane_cfg_provider*>(hrd));
hrd->release();
r->release();
}
void UsbDevice::save_image(MemoryPtr data, bool img)
@ -1942,7 +1948,7 @@ void UsbDevice::save_image(MemoryPtr data, bool img)
}
}
}
else
else if(data)
{
HGIntInfo* info = (HGIntInfo*)data->data();
dyn_mem_ptr reply = dyn_mem::memory(sizeof(PACK_BASE));
@ -2035,6 +2041,15 @@ void UsbDevice::save_image(MemoryPtr data, bool img)
}
reply->release();
}
else
{
// paper count ...
dyn_mem_ptr reply = dyn_mem::memory(sizeof(PACK_BASE));
BASE_PACKET_REPLY(*((LPPACK_BASE)reply->ptr()), PACK_CMD_SCAN_PAPER_ROGER, 0, 0);
reply->set_len(sizeof(PACK_BASE));
usb_->write_bulk(reply);
reply->release();
}
}
int32_t UsbDevice::get_config(void* buf, size_t* len, const char* cfg_name, std::string* strval)
@ -2049,25 +2064,26 @@ int32_t UsbDevice::get_config(void* buf, size_t* len, const char* cfg_name, std:
json *jsn = new json();
if(jsn->attach_text(&cfg_text_[0]))
{
json* child = nullptr;
ret = inner_get_config(jsn, buf, len, cfg_name, strval);
// json* child = nullptr;
ret = ENOENT;
if(jsn->get_value(cfg_name, child) && child)
{
std::string val(sane_cfg_provider::sane_option_value_get(child, "cur", strval));
child->release();
// ret = ENOENT;
// if(jsn->get_value(cfg_name, child) && child)
// {
// std::string val(sane_cfg_provider::sane_option_value_get(child, "cur", strval));
// child->release();
if(*len < val.length())
{
*len = val.length();
ret = ENOMEM;
}
else
{
memcpy(buf, val.c_str(), val.length());
*len = val.length();
}
}
// if(*len < val.length())
// {
// *len = val.length();
// ret = ENOMEM;
// }
// else
// {
// memcpy(buf, val.c_str(), val.length());
// *len = val.length();
// }
// }
jsn->release();
}
}

View File

@ -3,7 +3,7 @@ add_rules("mode.debug", "mode.release")
target("gusb")
set_kind("static")
add_syslinks("pthread")
add_files("*.cpp", "src/*.cpp", "src/common/*.cpp", "src/common/json/*.c*")
add_files("*.cpp", "src/*.cpp", "src/common/*.cpp", "src/common/json/*.c*", "src/hardware/*.cpp")
add_includedirs("inc")
add_includedirs("src/common")
add_includedirs(".", { public = true})

View File

@ -66,7 +66,7 @@ target("conf")
add_includedirs("$(buildir)/config/header", { public = true })
target_end("conf")
includes("regs", "deviceio", "motorboard", "capimage", "usb", "service", "scanner", "imgproc", "applog","scanservice","fpgaupdate")
includes("regs", "deviceio", "motor_run", "motorboard", "capimage", "usb", "service", "scanner", "imgproc", "applog","scanservice","fpgaupdate")
add_includedirs("/usr/local/include/opencv4", "imgproc/ImageProcess")
add_linkdirs("/usr/local/lib/")

View File

@ -102,7 +102,7 @@
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;HGSCANNER_EXPORT;CUSTOM_USBVIEW;_DIRECT_BUILD;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>WIN32;OEM_NONE;HGSCANNER_EXPORT;CUSTOM_USBVIEW;_DIRECT_BUILD;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<DisableSpecificWarnings>4996</DisableSpecificWarnings>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>

View File

@ -630,7 +630,7 @@ IMPLEMENT_DYNAMIC(CDlgScanner, CDialogEx)
CDlgScanner::CDlgScanner(CWnd* pParent /*=nullptr*/)
: CDialogEx(IDD_SCANNER, pParent)
, scanner_(NULL), auto_tx_file_(-1), auto_tx_(false)
, setting_ui_(NULL), img_cnt_(0)
, setting_ui_(NULL), img_cnt_(0), paper_cnt_(0)
{
g_my_inst = GetModuleHandle(NULL);
@ -695,10 +695,10 @@ void CDlgScanner::set_device(usb::LPUSBPNP pnp)
if (err)
//::SetDlgItemTextW(m_hWnd, IDC_EDIT_COUNT, (L"Receive image " + std::to_wstring(img_cnt_) + L" error: " + std::to_wstring(err)).c_str());
dlg->set_text(IDC_EDIT_COUNT, (L"Receive image " + std::to_wstring(img_cnt_) + L" error: " + std::to_wstring(err)).c_str());
dlg->set_text(IDC_EDIT_COUNT, (L"Receive image " + (std::to_wstring(dlg->img_cnt_) + L"/" + std::to_wstring(dlg->paper_cnt_)) + L" error: " + std::to_wstring(err)).c_str());
else if (cur >= total)
{
dlg->set_text(IDC_EDIT_COUNT, std::to_wstring(dlg->img_cnt_).c_str());
dlg->set_text(IDC_EDIT_COUNT, (std::to_wstring(dlg->img_cnt_) + L"/" + std::to_wstring(dlg->paper_cnt_)).c_str());
if (dlg->is_checked(IDC_CHECK_AUTO_OPEN_IMG))
ShellExecuteA(dlg->m_hWnd, "Open", cur_img_file.c_str(), NULL, NULL, SW_SHOWNORMAL);
@ -708,7 +708,33 @@ void CDlgScanner::set_device(usb::LPUSBPNP pnp)
};
auto img_keeper = [&](LPPACKIMAGE img, uint64_t size) -> data_holder_ptr
{
if (img)
if (img == IMG_RECEIVER_FINISHED)
{
// scan stopped ...
wchar_t buf[40] = { 0 };
HWND wnd = GetDlgItem(IDC_EDIT_COUNT)->m_hWnd;
HDC dc = ::GetDC(wnd);
set_text(IDC_BUTTON_SCAN, L"Scan");
::SetTextColor(dc, size ? RGB(255, 0, 0) : RGB(0, 0, 0));
::ReleaseDC(wnd, dc);
log_cls::log(LOG_LEVEL_DEBUG, "Scan stopped with error %s\r\n", usb::u2a(scanner_status(size, buf)).c_str());
set_text(IDC_EDIT_COUNT, (std::to_wstring(img_cnt_) + L"/" + std::to_wstring(paper_cnt_)).c_str());
if (size == 0)
size = SCANNER_STATUS_READY;
::PostMessage(m_hWnd, WM_DEVICE_STATTUS, 0, (LPARAM)size);
return NULL;
}
else if (img == IMG_RECEIVER_PAPER_CNT)
{
set_text(IDC_EDIT_COUNT, (std::to_wstring(img_cnt_) + L"/" + std::to_wstring(++paper_cnt_)).c_str());
return NULL;
}
else
{
file_saver* saver = new file_saver();
std::string root(usb::u2a(img_root_.c_str()));
@ -731,26 +757,6 @@ void CDlgScanner::set_device(usb::LPUSBPNP pnp)
return dynamic_cast<data_holder_ptr>(saver);
}
else
{
// scan stopped ...
wchar_t buf[40] = { 0 };
HWND wnd = GetDlgItem(IDC_EDIT_COUNT)->m_hWnd;
HDC dc = ::GetDC(wnd);
set_text(IDC_BUTTON_SCAN, L"Scan");
::SetTextColor(dc, size ? RGB(255, 0, 0) : RGB(0, 0, 0));
::ReleaseDC(wnd, dc);
log_cls::log(LOG_LEVEL_DEBUG, "Scan stopped with error %s\r\n", usb::u2a(scanner_status(size, buf)).c_str());
set_text(IDC_EDIT_COUNT, std::to_wstring(img_cnt_).c_str());
if (size == 0)
size = SCANNER_STATUS_READY;
::PostMessage(m_hWnd, WM_DEVICE_STATTUS, 0, (LPARAM)size);
return NULL;
}
};
auto status_cb = [&](uint32_t status) -> void
{
@ -1198,6 +1204,7 @@ void CDlgScanner::OnBnClickedButtonScan()
if (wcsicmp(title, L"Scan") == 0)
{
img_cnt_ = 0;
paper_cnt_ = 0;
SetDlgItemInt(IDC_EDIT_COUNT, img_cnt_);
if (scanner_)
{

View File

@ -59,6 +59,7 @@ class CDlgScanner : public CDialogEx
SANEAPI sane_api_;
std::wstring img_root_;
uint32_t img_cnt_;
uint32_t paper_cnt_;
public:
CDlgScanner(CWnd* pParent = nullptr); // 标准构造函数

View File

@ -191,11 +191,21 @@ scanner_handler::scanner_handler(void) : usb_(nullptr), status_(SCANNER_STATUS_N
*more = dynamic_cast<packet_data_base_ptr>(receiver);
}
}
else if (pack->cmd == PACK_CMD_SCAN_PAPER_ROGER)
{
if (img_receiver_)
{
data_holder_ptr receiver = img_receiver_(IMG_RECEIVER_PAPER_CNT, pack->data);
if (receiver)
receiver->release();
}
*used = sizeof(PACK_BASE);
}
else if (pack->cmd == PACK_CMD_SCAN_FINISHED_ROGER)
{
if (img_receiver_)
{
data_holder_ptr receiver = img_receiver_(NULL, pack->data);
data_holder_ptr receiver = img_receiver_(IMG_RECEIVER_FINISHED, pack->data);
if (receiver)
receiver->release();
}

View File

@ -14,6 +14,9 @@
#include <algorithm>
#include <map>
#define IMG_RECEIVER_FINISHED ((LPPACKIMAGE)NULL)
#define IMG_RECEIVER_PAPER_CNT ((LPPACKIMAGE)1)
class async_usb_host;
struct libusb_device;