#include "stdafx.h" #include #include #include "Helper.JSON.hpp" #include "DIOS.Dev.Mech.HanQingNormal.hpp" #include "PacketAnalizer.h" #include "Generator.BasicMoulds.hpp" #define MY_PI 3.14159265358979323846 using namespace DIOS::Dev::Detail::MECH; namespace nsMech = DIOS::Dev::Detail::MECH; namespace nsGEN = DIOS::Dev::Detail::Generator; //关闭无关警告 #pragma warning (disable:4244) // warning C4244: “初始化”: 从“double”转换到“float”,可能丢失数据 #pragma warning (disable:4305) // warning C4305: “参数”: 从“double”到“float”截断 #pragma warning (disable:4267) // warning C4267 : “初始化”: 从“size_t”转换到“int”,可能丢失数据 #pragma warning (disable:4805) // warning C4805: “!=”: 在操作中将类型“bool”与类型“int”混合不安全 //设置相关常量 #define HanQingNormal_TIMEOUTVALUE 100 #define HanQingNormal_LoopDefHBTime 500 static const int msTimeOut_Lock = 200; //通讯接口锁定时间 #define HanQingNormal_Com_NormalLen 128 //#define HanQingNormal_STX 0x02 #define HanQingNormal_ETX 0x03 //DiosV3消息 #define Dios_V3 1 #define HanQingNormal_GenClientName "HanQing_Gen" #define HanQingNormal_ClientTimeOut 5000 Log4CPP::Logger* mLog::gLogger = nullptr; static bool glo_StitchWarningFlag{ false }; /* *串口/以太网通信帧格式: 解释: = 2 ASCII 命令名称 = n ASCII 命令参数 = 1 ASCII 0x03 帧尾 = 校验和 串口通信设置: . 9600 波特率 . No Parity . 8 Data Bits . 1 Stop Bit . 无握手过程 */ //生成命令校验和:cmdData 为 [<,> ]...<,> 其长度要多出3个字符用于存放 CSUM、ETX char ComputeCheckSum(char* cmdData, int& size) { if (size + 2 >= HanQingNormal_Com_NormalLen) { return 0x00; } cmdData[size++] = HanQingNormal_ETX; int AsciiSum = 0; for (int i = 0; i < size; i++) //每字节相加 { AsciiSum += cmdData[i]; } cmdData[size++] = (char)AsciiSum; //mLog::Debug("ComputeCheckSum:[0x{$:x}]", AsciiSum); return (char)AsciiSum; } //指令操作关联结构 nsMech::tFrameMapItem::tFrameMapItem() { m_fFun = NULL; } nsMech::tFrameMapItem::tFrameMapItem(cbFun f) { m_fFun = f; } nsMech::tFrameMapItem& nsMech::tFrameMapItem::operator =(const tFrameMapItem& value) { m_fFun = value.m_fFun; return *this; } //响应操作对照表 auto cmdCmpFun = [](const string& a, const string& b) { int minLengh = a.length() < b.length() ? a.length() : b.length(); return a.compare(0, minLengh, b, 0, minLengh) < 0; }; static std::map arFrame(cmdCmpFun); //查找响应操作对照表执行对应操作 static char CMDData[HanQingNormal_Com_NormalLen] = { 0 }; static bool DecodeFrame(const char* strFrame, int length) { auto found = arFrame.find(strFrame);//此处pr用来在arFrame中找到对于的包头 if (found == arFrame.end()) { return false; } string memset(CMDData, 0, HanQingNormal_Com_NormalLen - 1); int cmdHead = found->first.length(); memcpy(CMDData, strFrame + cmdHead, length - cmdHead - 2); found->second.m_fFun(CMDData, length - cmdHead);//第二个参数 不重要 memcpy(CMDData, strFrame, cmdHead); arFrame["FFF"].m_fFun(CMDData,3); return true; } //指令拆分 void StringSpliTokeyValue(string& strdata, const char* delimiter, string& key, string& value) { std::size_t findPos = strdata.find(delimiter); if (findPos != string::npos) { key = strdata.substr(0, findPos); value = strdata.substr(findPos + 1, strdata.length() - findPos); } } void DataSpliToMap(const char* strdata, const char* delimiter, map& arry) { string strtemp = strdata; string strName = strtemp; std::size_t oldPos = 0; std::size_t findPos = strtemp.find(delimiter); while (findPos != string::npos) { strName = strtemp.substr(oldPos, findPos - oldPos); { string key, value; StringSpliTokeyValue(strName, ":", key, value); arry[key] = value; } if (findPos != strtemp.length()) { oldPos = findPos + 1; findPos = strtemp.find(delimiter, oldPos); if (findPos == string::npos) { strName = strtemp.substr(oldPos, strtemp.length() - oldPos); break; } } else { break; } } strName.erase(strName.length()-2); { string key, value; StringSpliTokeyValue(strName, ":", key, value); arry[key] = value; } } //----------------------------------------------------------------------------- // HanQingNormalDevice //----------------------------------------------------------------------------- int nsMech::HanQingNormalDevice::m_iLoopTime = HanQingNormal_LoopDefHBTime; nsMech::HanQingNormalDevice::HanQingNormalDevice(std::shared_ptr center, nsSCF::SCF SCF, string configfile /*= ""*/):super(center, SCF) { assert(EventCenter); string version; if (GetVersion(version, hMyModule)) mLog::Debug("\n===============log begin : version:{$} ===================\n", version.c_str()); else mLog::Debug("\n===============log begin : version:0.0.0.0 ===================\n"); ResDataObject Conftemp; if (!configfile.empty()) { Conftemp.loadFile(configfile.c_str()); m_MechConfig = Conftemp["CONFIGURATION"]; TransJsonText(m_MechConfig); } //Mechanical m_MECHUnit.m_MechState.reset(new MechStateMould(AttrKey::MACHINE_STATUS_STANDBY, AttrKey::MACHINE_STATUS_SHUTDOWN, AttrKey::MACHINE_STATUS_SERVICE, 1)); m_MECHUnit.m_SID.reset(new SIDMould(123.5, 0, 10000, 1)); m_MECHUnit.m_TubeAngle.reset(new TubeAngleMould(0, -120, 120, 1)); float minHeight = 64.4, maxHeight = 170.2;//标装37.1~174.7,V2配置46.5~170.2,球管中心是最低64.4,最高210.9 if (m_MechConfig.GetKeyCount("MechanicalHeight") > 0) { if (m_MechConfig["MechanicalHeight"].GetKeyCount("min") > 0) minHeight = m_MechConfig["MechanicalHeight"]["min"]; if (m_MechConfig["MechanicalHeight"].GetKeyCount("max") > 0) maxHeight = m_MechConfig["MechanicalHeight"]["max"]; mLog::Debug("config:MechanicalHeight[min:{$},max:{$}]", minHeight, maxHeight); } m_MECHUnit.m_TubeHeight.reset(new TubeHeightMould(0, minHeight, maxHeight, 1)); m_MECHUnit.m_FID.reset(new FIDMould(0, minHeight, maxHeight, 1)); //拼接 m_MECHUnit.m_StitchingState.reset(new StitchingStateMould(AttrKey::STITCHSTATE_INIT, AttrKey::STITCHSTATE_ERR, AttrKey::STITCHSTATE_MAX, 1)); m_MECHUnit.m_StitchHeight.reset(new StitchHeightMould(0, minHeight, maxHeight, 1)); m_MECHUnit.m_StitchLength.reset(new StitchLengthMould(0, 0, 1000, 1)); m_MECHUnit.m_StitchOverLap.reset(new StitchOverLapMould(0, 0, 1000, 1)); m_MECHUnit.m_StitchPID.reset(new StitchPIDMould(0, 0, 1000, 1)); m_MECHUnit.m_StitchDirection.reset(new StitchDirectionMould(AttrKey::STITCHDIR_NULL, AttrKey::STITCHDIR_NULL, AttrKey::STITCHDIR_MAX, 1)); m_MECHUnit.m_StitchType.reset(new StitchTypeMould(AttrKey::STITCHTYPE_NULL, AttrKey::STITCHTYPE_NULL, AttrKey::STITCHTYPE_MAX, 1)); m_MECHUnit.m_StitchStepLength.reset(new StitchStepLengthMould(10, 0, 1000, 1)); m_MECHUnit.m_FPDPosition.reset(new FPDPositionMould(0, 0, 100, 1)); m_MECHUnit.m_TotalImageCount.reset(new TotalImageCountMould(0, 0, 100, 1)); m_MECHUnit.m_CurrentImageNumber.reset(new CurrentImageNumberMould(100, -1, 100, 1)); if (m_MechConfig.GetKeyCount("FPDLengh") > 0) { m_nFPDLengh = m_MechConfig["FPDLengh"]; mLog::Debug("config:FPDLengh[{$}]", m_nFPDLengh); } //上报错误消息 m_MSGUnit.reset(new nsDetail::MSGUnit(center, MechUnitType)); //串口数据处理类初始化 m_tDelivermodule.InitSendModle(this ,&ProcessClientData, WriteLog); m_nCMDType_WaitTime = m_tDelivermodule.SetPriority(false, false, false, true, 100); m_nCMDType_WaitACK = m_tDelivermodule.SetPriority(false, false, 3, false, 0, true, 1000); mLog::Debug("m_nCMDType_WaitTime[{$}] m_nCMDType_WaitACK[{$}]", m_nCMDType_WaitTime, m_nCMDType_WaitACK); //将机架可以对外提供的指令注册集进行补充 Register(); //配置响应操作对照表 OnCallBack(); //设置初始参数 RefreshData(); m_hExitEvent = CreateEvent(NULL, TRUE, FALSE, NULL); m_hMoveBeginEvent = CreateEvent(NULL, FALSE, FALSE, NULL); //启动硬件状态轮询进程 StartLoopThread(); } nsMech::HanQingNormalDevice::~HanQingNormalDevice() { if (m_pGenClient) { if (!m_pGenClient->IsClosed()) { m_pGenClient->Close(); } delete m_pGenClient; m_pGenClient = nullptr; } ResetEvent(m_hMoveBeginEvent); SetEvent(m_hExitEvent); Sleep(m_iLoopTime); m_tDelivermodule.EixtSendModle(); mLog::Debug("\n===============log end ===================\n"); } std::string HanQingNormalDevice::GetGUID() const { mLog::Debug("\n===============GetGUID : {$} ===================\n", StitchMechUnitType); return StitchMechUnitType; } RET_STATUS nsMech::HanQingNormalDevice::RefreshData() { GetUnitStatus(); #if Dios_V3 m_pGenClient = new LogicClient(HanQingNormal_GenClientName, m_strCurTransaction, "NSQ", false); if (m_pGenClient->Open("DIOS/DEVICE/Generator", ACTION + NOTIFY_MSG + NOTIFY_UPDATE,"", HanQingNormal_ClientTimeOut)) { mLog::Debug("Dios_V3 Create {$} Client success", HanQingNormal_GenClientName); m_pGenClient->SubScribeTopic("DIOS/DEVICE/Generator/+/+/+/Notify/KV"); m_pGenClient->SubScribeTopic("DIOS/DEVICE/Generator/+/+/+/Notify/MA"); m_pGenClient->SubScribeTopic("DIOS/DEVICE/Generator/+/+/+/Notify/MS"); m_pGenClient->SubScribeTopic("DIOS/DEVICE/Generator/+/+/+/Notify/MAS"); m_pGenClient->SubScribeTopic("DIOS/DEVICE/Generator/+/+/+/Notify/FOCUS"); m_pGenClient->SubScribeTopic("DIOS/DEVICE/Generator/+/+/+/Notify/TECHMODE"); m_pGenClient->SubScribeTopic("DIOS/DEVICE/Generator/+/+/+/Notify/AECDENSITY"); m_pGenClient->SubScribeTopic("DIOS/DEVICE/Generator/+/+/+/Notify/AECFIELD"); m_pGenClient->SubScribeTopic("DIOS/DEVICE/Generator/+/+/+/Notify/AECFILM"); } else { mLog::Debug("Dios_V3 Create {$} Client failed", HanQingNormal_GenClientName); } #endif return RET_STATUS::RET_SUCCEED; } void nsMech::HanQingNormalDevice::Register() { auto Disp = &Dispatch; superMech::RegisterNormalControl(Disp); superMech::RegisterStitchingControl(Disp); superMech::RegisterExtraScreenControl(Disp); superMech::RegisterExamInfo(Disp); Disp->Get.Push(m_MSGUnit->GetKey().c_str(), [this](std::string& out) { out = m_MSGUnit->JSGet(); return RET_STATUS::RET_SUCCEED; }); auto fun_SendStitchState = [this](auto in, auto& out) { FireNotify(AttrKey::STITCHINGSTATE, m_MECHUnit.m_StitchingState->Get()); return RET_STATUS::RET_SUCCEED; }; Disp->Action.Push("SendStitchState", fun_SendStitchState); } void nsMech::HanQingNormalDevice::FireNotify(std::string key, std::string content) { EventCenter->OnNotify(1, key, content); } void nsMech::HanQingNormalDevice::FireNotify(std::string key, const int content) { std::string str = std::format("{:d}", content); EventCenter->OnNotify(1, key, str); } void nsMech::HanQingNormalDevice::FireNotify(std::string key, const float content) { std::string str = std::format("{:f}", content); EventCenter->OnNotify(1, key, str); } bool nsMech::HanQingNormalDevice::HasErrorMessage() { if (!m_MSGUnit->JSGet().empty()) { return true; } else if (glo_StitchWarningFlag) { return true; } return false; } void nsMech::HanQingNormalDevice::FireErrorMessage(const bool Act, const int Code, const char* ResInfo) { string ErrorCode("Mech_ERR_"); ErrorCode += std::to_string(Code); int level = OTC_MG_REGULATION_LEVEL::REG_ERRO; if (Act) { mLog::Error("add {$}:{$}", ErrorCode.c_str(), ResInfo); m_MSGUnit->AddErrorMessage(ErrorCode.c_str(), level, ResInfo); } else { mLog::Error("del {$}:{$}", ErrorCode.c_str(), ResInfo); if (Code == 0) m_MSGUnit->DelErrorMessage("0", level, ResInfo); else m_MSGUnit->DelErrorMessage(ErrorCode.c_str(), level, ResInfo); } } void nsMech::HanQingNormalDevice::FireWarnMessage(const bool Act, const int Code, const char* ResInfo) { string ErrorCode("Mech_WAR_"); ErrorCode += std::to_string(Code); int level = OTC_MG_REGULATION_LEVEL::REG_WARN; if (Act) { glo_StitchWarningFlag = true; mLog::Error("add {$}:{$}", ErrorCode.c_str(), ResInfo); m_MSGUnit->AddWarnMessage(ErrorCode.c_str(), level, ResInfo); } else { glo_StitchWarningFlag = false; mLog::Error("del {$}:{$}", ErrorCode.c_str(), ResInfo); m_MSGUnit->DelWarnMessage(ErrorCode.c_str(), level, ResInfo); } } RET_STATUS nsMech::HanQingNormalDevice::HWSend(const char* strCommand, int lengh, bool reSend, int nTimeOut) { if (!m_SCF) return RET_STATUS::RET_FAILED; char strSendCommand[HanQingNormal_Com_NormalLen] = { 0 }; int copyCode = memcpy_s(strSendCommand, HanQingNormal_Com_NormalLen, strCommand, lengh); if (copyCode) { mLog::Error("copy cmd[{$}][{$}] error[{$}]", strCommand, lengh, copyCode); return RET_STATUS::RET_FAILED; } ComputeCheckSum(strSendCommand, lengh); if (strncmp(strSendCommand, "TT?", 3) != 0) { if (reSend) { mLog::Debug("==OUT==: [{$}] wait for ACK \n", strSendCommand); } else { mLog::Debug("==OUT==: [{$}] \n", strSendCommand); } } int retLength; m_SCF.Lock(msTimeOut_Lock) .SendPacket(strSendCommand, lengh, nTimeOut, retLength); //Sleep(nTimeOut); return RET_STATUS::RET_SUCCEED; } void HanQingNormalDevice::OnCallBack() { mLog::Debug("Enter OnCallBack"); auto HWNotProcess = [this](const char* value, int length) -> void { //mLog::Warn(" This commands didn't need to process!"); m_tDelivermodule.CheckReceive(value, length); }; auto HW_WS = [this](const char* value, int length) -> void { if (m_pGenClient != NULL) { if (!m_pGenClient->IsClosed()) { ResDataObject Request, Response; Request.add("P0", 0); m_pGenClient->Action(nsGEN::ActionKey::SetValue_WORKSTATION, Request, Response, HanQingNormal_ClientTimeOut); mLog::Debug("execute[{$}:{$}] to GEN", nsGEN::ActionKey::SetValue_WORKSTATION, 0); } else { mLog::Debug("{$} Client is Close", HanQingNormal_GenClientName); } } else { mLog::Debug("{$} Client is NULL", HanQingNormal_GenClientName); } }; auto HW_KV = [this](const char* value, int length) -> void { if (m_pGenClient != NULL) { if (!m_pGenClient->IsClosed()) { ResDataObject Request, Response; if (value[0] == '+') { m_pGenClient->Action(nsGEN::ActionKey::IncParam_KV, Request, Response, HanQingNormal_ClientTimeOut); mLog::Debug("execute[IncParam_KV] to GEN"); } else if (value[0] == '-') { m_pGenClient->Action(nsGEN::ActionKey::DecParam_KV, Request, Response, HanQingNormal_ClientTimeOut); mLog::Debug("execute[DecParam_KV] to GEN"); } } else { mLog::Debug("{$} Client is Close", HanQingNormal_GenClientName); } } else { mLog::Debug("{$} Client is NULL", HanQingNormal_GenClientName); } }; auto HW_MA = [this](const char* value, int length) -> void { if (m_pGenClient != NULL) { if (!m_pGenClient->IsClosed()) { ResDataObject Request, Response; if (value[0] == '+') { m_pGenClient->Action(nsGEN::ActionKey::IncParam_MA, Request, Response, HanQingNormal_ClientTimeOut); mLog::Debug("execute[IncParam_MA] to GEN"); } else if (value[0] == '-') { m_pGenClient->Action(nsGEN::ActionKey::DecParam_MA, Request, Response, HanQingNormal_ClientTimeOut); mLog::Debug("execute[DecParam_MA] to GEN"); } } else { mLog::Debug("{$} Client is Close", HanQingNormal_GenClientName); } } else { mLog::Debug("{$} Client is NULL", HanQingNormal_GenClientName); } }; auto HW_MS = [this](const char* value, int length) -> void { if (m_pGenClient != NULL) { if (!m_pGenClient->IsClosed()) { ResDataObject Request, Response; if (value[0] == '+') { m_pGenClient->Action(nsGEN::ActionKey::IncParam_MS, Request, Response, HanQingNormal_ClientTimeOut); mLog::Debug("execute[IncParam_MS] to GEN"); } else if (value[0] == '-') { m_pGenClient->Action(nsGEN::ActionKey::DecParam_MS, Request, Response, HanQingNormal_ClientTimeOut); mLog::Debug("execute[DecParam_MS] to GEN"); } } else { mLog::Debug("{$} Client is Close", HanQingNormal_GenClientName); } } else { mLog::Debug("{$} Client is NULL", HanQingNormal_GenClientName); } }; auto HW_MAS = [this](const char* value, int length) -> void { if (m_pGenClient != NULL) { if (!m_pGenClient->IsClosed()) { ResDataObject Request, Response; if (value[0] == '+') { m_pGenClient->Action(nsGEN::ActionKey::IncParam_MAS, Request, Response, HanQingNormal_ClientTimeOut); mLog::Debug("execute[IncParam_MAS] to GEN"); } else if (value[0] == '-') { m_pGenClient->Action(nsGEN::ActionKey::DecParam_MAS, Request, Response, HanQingNormal_ClientTimeOut); mLog::Debug("execute[DecParam_MAS] to GEN"); } } else { mLog::Debug("{$} Client is Close", HanQingNormal_GenClientName); } } else { mLog::Debug("{$} Client is NULL", HanQingNormal_GenClientName); } }; auto HW_FO = [this](const char* value, int length) -> void { if (m_pGenClient != NULL) { if (!m_pGenClient->IsClosed()) { ResDataObject Request, Response; Request.add("P0", value); m_pGenClient->Action(nsGEN::ActionKey::SetValue_FOCUS, Request, Response, HanQingNormal_ClientTimeOut); mLog::Debug("execute[{$}:{$}] to GEN", nsGEN::ActionKey::SetValue_FOCUS, value); } else { mLog::Debug("{$} Client is Close", HanQingNormal_GenClientName); } } else { mLog::Debug("{$} Client is NULL", HanQingNormal_GenClientName); } }; auto HW_AECField = [this](const char* value, int length) -> void { if (m_pGenClient != NULL) { if (!m_pGenClient->IsClosed()) { ResDataObject Request, Response; Request.add("P0", value); m_pGenClient->Action(nsGEN::ActionKey::SetValue_AECFIELD, Request, Response, HanQingNormal_ClientTimeOut); mLog::Debug("execute[{$}:{$}] to GEN", nsGEN::ActionKey::SetValue_AECFIELD, value); } else { mLog::Debug("{$} Client is Close", HanQingNormal_GenClientName); } } else { mLog::Debug("{$} Client is NULL", HanQingNormal_GenClientName); } }; auto HW_AECDensity = [this](const char* value, int length) -> void { if (m_pGenClient != NULL) { if (!m_pGenClient->IsClosed()) { ResDataObject Request, Response; Request.add("P0", value); m_pGenClient->Action(nsGEN::ActionKey::SetValue_AECDENSITY, Request, Response, HanQingNormal_ClientTimeOut); mLog::Debug("execute[{$}:{$}] to GEN", nsGEN::ActionKey::SetValue_AECDENSITY, value); } else { mLog::Debug("{$} Client is Close", HanQingNormal_GenClientName); } } else { mLog::Debug("{$} Client is NULL", HanQingNormal_GenClientName); } }; auto HW_Techmode = [this](const char* value, int length) -> void { if (m_pGenClient != NULL) { if (!m_pGenClient->IsClosed()) { ResDataObject Request, Response; Request.add("P0", value); m_pGenClient->Action(nsGEN::ActionKey::SetValue_TECHMODE, Request, Response, HanQingNormal_ClientTimeOut); mLog::Debug("execute[{$}:{$}] to GEN", nsGEN::ActionKey::SetValue_TECHMODE, value); //switch (atoi(value)) //{ // case 0://MA\MS // { // SetMA(m_fMA); // SetMS(m_fMS); // }break; // case 1://MAS // { // SetMAS(m_fMAS); // }break; // case 2://AEC // { // SetMA(m_fMA); // SetMS(m_fMS); // }break; //} } else { mLog::Debug("{$} Client is Close", HanQingNormal_GenClientName); } } else { mLog::Debug("{$} Client is NULL", HanQingNormal_GenClientName); } }; auto HW_PatientSize = [this](const char* value, int length) -> void { string size{"Middle"}; switch (atoi(value)) { case 1: {size = "Small"; }break; case 2: {size = "Middle"; }break; case 3: {size = "Large"; }break; case 4: {size = "Child"; }break; default: break; } FireNotify(AttrKey::PATIENTSIZE, size); }; auto HW_Error = [this](const char* value, int length) -> void { if(length <= 0) FireErrorMessage(true,1, value); else FireErrorMessage(false, 1, value); }; auto HW_Status = [this](const char* value, int length) -> void { map data; DataSpliToMap(value,"|", data); for (auto item : data) { if (item.first == "FP") { int data = atoi(item.second.c_str()); if (m_MECHUnit.m_StitchingState->Get() == AttrKey::STITCHSTATE_REACH_INIT) { //给印度发货的机架不带红外定位,DellWork的带 //if (data == 0) //{ // if (m_MECHUnit.m_StitchingState->Update(AttrKey::STITCHSTATE_START)) // FireNotify(AttrKey::STITCHINGSTATE, AttrKey::STITCHSTATE_START); // m_MECHUnit.m_strInfo = "Stitch Start"; // mLog::Debug("stitching:[{$}]", m_MECHUnit.m_strInfo.c_str()); // FireNotify(AttrKey::UNITINFO, m_MECHUnit.m_strInfo); //} //else //{ // FireErrorMessage(true,3,"The movement of the mechanical system was interrupted, Please EXIT the current stitching and RE-START the stitching exam"); //} } //else //{ // mLog::Error("stitching:not in [Stitch Standby]"); //} } else if (item.first == "FH")//球管的高度值 { float data = atof(item.second.c_str()) / 10.0f; if (m_MECHUnit.m_TubeHeight->Update(data)) { mLog::Debug("update TubeHeight[{$}]", data); FireNotify(AttrKey::TUBEHEIGHT, data); } } else if (item.first == "FG")//球管的角度 { float data = atof(item.second.c_str()); if (m_MECHUnit.m_TubeAngle->Update(data)) { mLog::Debug("update TubeAngle[{$}]", data); FireNotify(AttrKey::TUBEANGLE, data); } } else if (item.first == "FX")//X轴的距离(SID的值) { float data = atof(item.second.c_str())/10.0f; if (m_MECHUnit.m_SID->Update(data)) { mLog::Debug("update SID[{$}]", data); FireNotify(AttrKey::SID, data); } } else if (item.first == "FU")//胸片架Bucky的高度值 { float data = atof(item.second.c_str()) / 10.0f; if (m_MECHUnit.m_FID->Update(data)) { mLog::Debug("update FID[{$}]", data); FireNotify(AttrKey::FID, data); if (m_MECHUnit.m_CurrentImageNumber->Get() == 0) { mLog::Debug("Stitching Check: TubeHeight[current:{$},min:{$},max:{$}]", data, m_MECHUnit.m_StitchHeight->GetLimitMin(), m_MECHUnit.m_StitchHeight->GetLimitMax()); if (m_MECHUnit.m_StitchDirection->Get() == AttrKey::STITCHDIR_TopToBottom) { if (m_MECHUnit.m_StitchLength->Get() > (data - m_MECHUnit.m_StitchHeight->GetLimitMin())) { mLog::Debug("StitchLength[{$}] > CurrentHeight[{$}]-MinHeight[{$}]", m_MECHUnit.m_StitchLength->Get(), data, m_MECHUnit.m_StitchHeight->GetLimitMin()); FireWarnMessage(true, 4, "too low.raise the machine height"); } else if (HasErrorMessage()) { FireWarnMessage(false, 0, "clear all Mech error"); } } else if (m_MECHUnit.m_StitchDirection->Get() == AttrKey::STITCHDIR_BottomToTop) { if (m_MECHUnit.m_StitchLength->Get() > (m_MECHUnit.m_StitchHeight->GetLimitMax() - data)) { mLog::Debug("StitchLength[{$}] > MaxHeight[{$}]-CurrentHeight[{$}]", m_MECHUnit.m_StitchLength->Get(), m_MECHUnit.m_StitchHeight->GetLimitMax(), data); FireWarnMessage(true, 5, "too high,reduce the machine height"); } else if (HasErrorMessage()) { FireWarnMessage(false, 0, "clear all Mech error"); } } } } } else if (item.first == "FV")//Y轴的距离 { float data = atof(item.second.c_str()) / 10.0f; //wxx } } }; auto HW_SM = [this](const char* value, int length) -> void { int status = m_MECHUnit.m_StitchingState->Get(); if (status >= AttrKey::STITCHSTATE_INIT && status < AttrKey::STITCHSTATE_END) { int data = atoi(value); int status = -1; switch (data) { case 1: //启动运动 { status = AttrKey::STITCHSTATE_MOVING; m_MECHUnit.m_strInfo = "Stitch Moving"; }break; case 2: //停止完成 { if (m_MECHUnit.m_CurrentImageNumber->Get() == 0) { if (!m_bIsBeginFlag)//用于拼接计划 { if (m_MECHUnit.m_StitchingState->Update(AttrKey::STITCHSTATE_STANDBY)) FireNotify(AttrKey::STITCHINGSTATE, AttrKey::STITCHSTATE_STANDBY); m_MECHUnit.m_strInfo = "Stitch Standby"; mLog::Debug("stitching:[{$}]", m_MECHUnit.m_strInfo.c_str()); FireNotify(AttrKey::UNITINFO, m_MECHUnit.m_strInfo); } else { switch (m_MECHUnit.m_StitchType->Get()) { case AttrKey::STITCHTYPE_AutomaticTranslation: case AttrKey::STITCHTYPE_ManualTranslation: {}break; case AttrKey::STITCHTYPE_AutomaticAngle: case AttrKey::STITCHTYPE_ManualAngle: { if (m_MECHUnit.m_StitchingState->Update(AttrKey::STITCHSTATE_READY)) { FireNotify(AttrKey::STITCHINGSTATE, AttrKey::STITCHSTATE_READY); } mLog::Debug("stitching:[{$}]", m_MECHUnit.m_strInfo.c_str()); FireNotify(AttrKey::UNITINFO, m_MECHUnit.m_strInfo); }break; } } status = AttrKey::STITCHSTATE_REACH_INIT; m_MECHUnit.m_strInfo = "Stitch Reach to the initial position"; } else { status = AttrKey::STITCHSTATE_REACH_NEXT; m_MECHUnit.m_strInfo = "Stitch Reach to the next position"; } }break; case 3: //退出拼接模式 { status = AttrKey::STITCHSTATE_CANCEL; m_MECHUnit.m_strInfo = "Stitch quit"; }break; case 4: //运动超限停止 { status = AttrKey::STITCHSTATE_ERR; m_MECHUnit.m_strInfo = "get error"; FireErrorMessage(true, 2, "get Mech error"); }break; default: break; } if(m_MECHUnit.m_StitchingState->Update(status)) FireNotify(AttrKey::STITCHINGSTATE, status); mLog::Debug("stitching:[{$}]", m_MECHUnit.m_strInfo.c_str()); FireNotify(AttrKey::UNITINFO, m_MECHUnit.m_strInfo); if (data == 2) { if (m_MECHUnit.m_CurrentImageNumber->Get() != 0) { m_MECHUnit.m_strInfo = "Stitch Ready"; if (m_MECHUnit.m_StitchingState->Update(AttrKey::STITCHSTATE_READY)) { Sleep(2000); FireNotify(AttrKey::STITCHINGSTATE, AttrKey::STITCHSTATE_READY); } mLog::Debug("stitching:[{$}]", m_MECHUnit.m_strInfo.c_str()); FireNotify(AttrKey::UNITINFO, m_MECHUnit.m_strInfo); } } } }; // 有部分前缀是包含关系, 长的包含短的, 因此长的在前面, 短的在后面 // Device 是个短寿命对象, 而 arFrame 是静态变量 !!! // 因此, 在添加到 arFrame 之前, 务必先清零 !!! arFrame.clear(); arFrame["OR"] = tFrameMapItem(HW_WS); arFrame["KV"] = tFrameMapItem(HW_KV); arFrame["MA"] = tFrameMapItem(HW_MA); arFrame["MS"] = tFrameMapItem(HW_MS); arFrame["MX"] = tFrameMapItem(HW_MAS); arFrame["FO"] = tFrameMapItem(HW_FO); arFrame["FI"] = tFrameMapItem(HW_AECField); arFrame["FD"] = tFrameMapItem(HW_AECDensity); arFrame["ET"] = tFrameMapItem(HW_Techmode); arFrame["PS"] = tFrameMapItem(HW_PatientSize); arFrame["ER"] = tFrameMapItem(HW_Error); arFrame[">TT|"] = tFrameMapItem(HW_Status); arFrame["SM"] = tFrameMapItem(HW_SM); arFrame["FFF"] = tFrameMapItem(HWNotProcess);//命令格式:校验和错误 } //串口数据处理类对外接口 void __stdcall nsMech::HanQingNormalDevice::ProcessClientData(const char* pData, unsigned long nDataLength, void* lparam) { HanQingNormalDevice* pCurMech = (HanQingNormalDevice*)lparam; pCurMech->HWSend(pData, nDataLength); } void __stdcall nsMech::HanQingNormalDevice::WriteLog(const char* pData, nsSerialGPM::LOG_V2_LEVEL level) { switch (level) { case nsSerialGPM::LOG_V2_FATAL: case nsSerialGPM::LOG_V2_ERROR: mLog::Error(pData); break; case nsSerialGPM::LOG_V2_WARNING: mLog::Warn(pData); break; case nsSerialGPM::LOG_V2_DEBUG: mLog::Debug(pData); break; case nsSerialGPM::LOG_V2_INFO: mLog::Debug(pData); break; default: break; } } RET_STATUS nsMech::HanQingNormalDevice::HWSendWaittimeCMD(char* strCommand, int lengh, int headLengh) { return m_tDelivermodule.ProcessCommand(strCommand, lengh, m_nCMDType_WaitTime, headLengh); } RET_STATUS nsMech::HanQingNormalDevice::HWSendWaitACKCMD(char* strCommand, int lengh, int headLengh) { return m_tDelivermodule.ProcessCommand(strCommand, lengh, m_nCMDType_WaitACK, headLengh); } bool nsMech::HanQingNormalDevice::StartLoopThread() { mLog::Debug("Enter Start HardwareStatus Thread "); if (m_pHardwareStatusThread == NULL) { DWORD m_HardwareStatusID; m_pHardwareStatusThread = CreateThread(0, 0, HardwareStatusThread, this, 0, &m_HardwareStatusID); if (m_pHardwareStatusThread == NULL) { mLog::Error("Start HardwareStatus Thread Failed"); return false; } } mLog::Debug("Enter Start GenStatus Thread "); if (m_pGenStatusThread == NULL) { DWORD m_GenStatusID; m_pGenStatusThread = CreateThread(0, 0, GenStatusThread, this, 0, &m_GenStatusID); if (m_pGenStatusThread == NULL) { mLog::Error("Start GenStatus Thread Failed"); return false; } } return true; } DWORD nsMech::HanQingNormalDevice::HardwareStatusThread(LPVOID pParam) { HanQingNormalDevice* pCurMech = (HanQingNormalDevice*)pParam; if (pCurMech == NULL) { return false; } mLog::Debug("HardwareStatusThread start"); if ((int)pCurMech->m_MechConfig["loopTime"] >= 0) { pCurMech->m_iLoopTime = (int)pCurMech->m_MechConfig["loopTime"]; } mLog::Debug("loopTime = {$}", pCurMech->m_iLoopTime); while (pCurMech->m_iLoopTime) { DWORD dwResult = WaitForSingleObject(pCurMech->m_hExitEvent, pCurMech->m_iLoopTime); switch (dwResult) { case WAIT_OBJECT_0: { mLog::Debug("get exit event, HardwareStatusThread stop"); return true; }break; case WAIT_TIMEOUT: { if (pCurMech->m_bLoopFlag.load()) { pCurMech->GetUnitStatus(); } }break; } } mLog::Debug("HardwareStatusThread stop"); return true; } DWORD nsMech::HanQingNormalDevice::GenStatusThread(LPVOID pParam) { HanQingNormalDevice* pCurMech = (HanQingNormalDevice*)pParam; if (pCurMech == NULL) { return false; } mLog::Debug("GenStatusThread start"); try { if (!pCurMech->m_pGenClient) { mLog::Error("Cannot find Notify Clinet[{$}]", HanQingNormal_GenClientName); return true; } vector waitList; //事件等待列表 waitList.push_back(pCurMech->m_hExitEvent); waitList.push_back(pCurMech->m_pGenClient->GetNotifyHandle()); while (WaitForSingleObject(pCurMech->m_hExitEvent, 50) != WAIT_OBJECT_0) { DWORD wait_ret = WaitForMultipleObjects((DWORD)waitList.size(), waitList.data(), FALSE, INFINITE); switch (wait_ret) { case WAIT_TIMEOUT: { }break; case WAIT_OBJECT_0://exit thread { mLog::Debug("get exit event, GenStatusThread stop"); return true; }break; case WAIT_OBJECT_0 + 1://pCurMech->m_pGenClient { while (pCurMech->m_pGenClient->IsDataArrived()) { ResDataObject NotifyData; PACKET_CMD notifycmd = pCurMech->m_pGenClient->ReadNotify(NotifyData); switch (notifycmd) { case PACKET_CMD_OPEN: {}break; case PACKET_CMD_CLOSE: {}break; case PACKET_CMD_GET: {}break; case PACKET_CMD_UPDATE://属性更新 { ResDataObject resDevicePath; pCurMech->m_pGenClient->GetFilePath(resDevicePath); string strPath = (string)resDevicePath; string strKey = PacketAnalizer::GetPacketKey(&NotifyData); string strValue = (string)NotifyData["CONTEXT"]; string strTopic = (string)NotifyData["TOPIC"]; if (strTopic.find("demo") == string::npos) { mLog::Debug("get Notify[{$}:{$}] from [{$}]", strKey.c_str(), strValue.c_str(), strPath.c_str()); pCurMech->GenNotify(strKey, strValue); } }break; case PACKET_CMD_ADD://设备上报错误 {}break; case PACKET_CMD_DEL://设备消除错误 {}break; case PACKET_CMD_EXE: {}break; case PACKET_CMD_DATA: {}break; case PACKET_CMD_MSG: {}break; case PACKET_CMD_ONLINE: {}break; case PACKET_CMD_PART_UPDATE: {}break; default: break; } } }break; default: break; } } } catch (...) { mLog::FERROR("ReadForDeviceEvents has crash"); } mLog::Debug("GenStatusThread stop"); return true; } //检查信息接口 RET_STATUS nsMech::HanQingNormalDevice::SetStudyInfo(ResDataObject& pParam) { auto& P0 = pParam[0]; SetPatientInfo(P0); return RET_STATUS::RET_SUCCEED; } RET_STATUS nsMech::HanQingNormalDevice::SetViewInfo(ResDataObject& pParam) { return RET_STATUS::RET_SUCCEED; } RET_STATUS nsMech::HanQingNormalDevice::SetPatientInfo(ResDataObject& pParam) { ECOM_PATIENT Info; Info.strPatientName = (string)pParam["PatientName"]; Info.strSex = (string)pParam["Sex"]; Info.strAge = (string)pParam["Age"]; Info.strPatientID = (string)pParam["PatientID"]; Info.strPatientSize = (string)pParam["PatientSize"]; Info.strStudyDescription = (string)pParam["StudyDescription"]; Info.strAccessionNumber = (string)pParam["AccessionNumber"]; mLog::Debug("Enter SetPatientInfo:[Name:{$}],[Sex:{$}],[Age:{$}],[ID:{$}],[Size:{$}],[Description:{$}],[AccessionNumber:{$}]", Info.strPatientName.c_str(), Info.strSex.c_str(), Info.strAge.c_str(), Info.strPatientID.c_str(), Info.strPatientSize.c_str(), Info.strStudyDescription.c_str(), Info.strAccessionNumber.c_str()); char temp[50] = { 0 }; //PatientName sprintf_s(temp, "PNM%-20s", Info.strPatientName.c_str()); HWSendWaittimeCMD(temp, strlen(temp)); //Sex sprintf_s(temp, "GEM%c", Info.strSex.at(0)); HWSendWaittimeCMD(temp, strlen(temp)); //Age int nAge = atoi(Info.strAge.c_str()); sprintf_s(temp, "AGE%03dY", nAge); HWSendWaittimeCMD(temp, strlen(temp)); //PatientID sprintf_s(temp, "PID%-20s", Info.strPatientID.c_str()); HWSendWaittimeCMD(temp, strlen(temp)); //PatientSizeint int nPS = 2; if (Info.strPatientSize == "Small") { nPS = 1; } else if (Info.strPatientSize == "Middle") { nPS = 2; } else if (Info.strPatientSize == "Large") { nPS = 3; } else if (Info.strPatientSize == "Child") { nPS = 4; } sprintf_s(temp, "PS%1d", nPS); HWSendWaittimeCMD(temp, strlen(temp)); //StudyDescription sprintf_s(temp, "DES%-20s", Info.strStudyDescription.c_str()); HWSendWaittimeCMD(temp, strlen(temp)); //AccessionNumber sprintf_s(temp, "ACC%-20s", Info.strAccessionNumber.c_str()); HWSendWaittimeCMD(temp, strlen(temp)); return RET_STATUS::RET_SUCCEED; } //机架通用接口 RET_STATUS nsMech::HanQingNormalDevice::Reset() { mLog::Debug("Enter Reset"); FireErrorMessage(false, 0, "clear all Mech error"); mLog::Debug("End Reset"); return RET_STATUS::RET_SUCCEED; } RET_STATUS nsMech::HanQingNormalDevice::SetTechParamsInfo(ResDataObject& pParam) { return RET_STATUS::RET_SUCCEED; } RET_STATUS nsMech::HanQingNormalDevice::SetPositionNumber(int pn) { mLog::Debug("Enter SetPositionNumber:[{$}]", pn); char temp[50] = { 0 }; sprintf_s(temp, "PN%03d", pn); return HWSendWaittimeCMD(temp, strlen(temp)); } RET_STATUS nsMech::HanQingNormalDevice::SetSID(float value) { return RET_STATUS::RET_SUCCEED; } RET_STATUS nsMech::HanQingNormalDevice::SetSOD(float value) { return RET_STATUS::RET_SUCCEED; } RET_STATUS nsMech::HanQingNormalDevice::MoveMech(string& value) { return RET_STATUS::RET_SUCCEED; } RET_STATUS nsMech::HanQingNormalDevice::StopMech(string& value) { return RET_STATUS::RET_SUCCEED; } RET_STATUS nsMech::HanQingNormalDevice::SetGrid(AttrKey::MECH_GRIDSTATE GridState) { return RET_STATUS::RET_SUCCEED; } //遮光器 RET_STATUS nsMech::HanQingNormalDevice::SetCollimator(ECOM_COLLIMATOR_INFO& curCollimator) { return RET_STATUS::RET_SUCCEED; } RET_STATUS nsMech::HanQingNormalDevice::SetFilter(int nFilter) { return RET_STATUS::RET_SUCCEED; } //拼接相应接口 RET_STATUS nsMech::HanQingNormalDevice::BeginStitching() { if (m_MECHUnit.m_MechState->Update(AttrKey::MACHINE_STATUS_STITCH)) FireNotify(AttrKey::MACHSTATE, m_MECHUnit.m_MechState->Get()); mLog::Debug("Enter BeginStitching"); char temp[50] = { 0 }; m_bIsBeginFlag = true; switch (m_MECHUnit.m_StitchType->Get()) { case AttrKey::STITCHTYPE_AutomaticTranslation: case AttrKey::STITCHTYPE_ManualTranslation: { sprintf_s(temp, "CM8"); HWSendWaittimeCMD(temp, strlen(temp)); if (m_MECHUnit.m_StitchingState->Get() == AttrKey::STITCHSTATE_REACH_INIT) { m_MECHUnit.m_strInfo = "Stitch Ready"; if (m_MECHUnit.m_StitchingState->Update(AttrKey::STITCHSTATE_READY)) { FireNotify(AttrKey::STITCHINGSTATE, AttrKey::STITCHSTATE_READY); } mLog::Debug("stitching:[{$}]", m_MECHUnit.m_strInfo.c_str()); FireNotify(AttrKey::UNITINFO, m_MECHUnit.m_strInfo); } else { mLog::Error("stitching:[{$}]not in [Stitch Init]", m_MECHUnit.m_StitchingState->Get()); } }break; case AttrKey::STITCHTYPE_AutomaticAngle: case AttrKey::STITCHTYPE_ManualAngle: { sprintf_s(temp, "CM7"); HWSendWaittimeCMD(temp, strlen(temp)); { if (m_MECHUnit.m_TotalImageCount->Get() <= 2) { sprintf_s(temp, "DT1"); } else { sprintf_s(temp, "DT2"); } HWSendWaittimeCMD(temp, strlen(temp)); sprintf_s(temp, "MD%04d", (int)m_MECHUnit.m_StitchStepLength->Get() * 10); HWSendWaittimeCMD(temp, strlen(temp)); } }break; default: return RET_STATUS::RET_FAILED; } return RET_STATUS::RET_SUCCEED; } RET_STATUS nsMech::HanQingNormalDevice::EndStitching() { if (m_MECHUnit.m_MechState->Update(AttrKey::MACHINE_STATUS_STANDBY)) FireNotify(AttrKey::MACHSTATE, m_MECHUnit.m_MechState->Get()); mLog::Debug("Enter EndStitching"); char temp[50] = { 0 }; sprintf_s(temp, "CM0"); HWSendWaittimeCMD(temp, strlen(temp)); //轮询标志 m_bLoopFlag = false; if (m_MECHUnit.m_StitchingState->Update(AttrKey::STITCHSTATE_END)) { FireNotify(AttrKey::STITCHINGSTATE, AttrKey::STITCHSTATE_END); m_MECHUnit.m_strInfo = "Stitch Finish"; mLog::Debug("stitching:[{$}]", m_MECHUnit.m_strInfo.c_str()); FireNotify(AttrKey::UNITINFO, m_MECHUnit.m_strInfo); } return RET_STATUS::RET_SUCCEED; } RET_STATUS nsMech::HanQingNormalDevice::SetupStitching(string& value) { char temp[50] = { 0 }; ResDataObject json, P0; m_bIsBeginFlag = false; json.decode(value.c_str()); if (json.GetKeyCount("P0") > 0) { P0 = json[0]; } else P0 = json; int nInitHeight = atoi(((string)P0[AttrKey::STITCHHEIGHT]).c_str()); int nTargetLength = atoi(((string)P0[AttrKey::STITCHLENGTH]).c_str()); int nOverlap = atoi(((string)P0[AttrKey::STITCHOVERLAP]).c_str()); int nSID = atoi(((string)P0[AttrKey::STITCHSID]).c_str()); int nTID = atoi(((string)P0[AttrKey::STITCHTID]).c_str()); int nPID = atoi(((string)P0[AttrKey::STITCHPID]).c_str()); int nDirection = atoi(((string)P0[AttrKey::STITCHDIRECTION]).c_str()); int nStitchType = atoi(((string)P0[AttrKey::STITCHTYPE]).c_str()); mLog::Debug("Enter SetupStitching:[InitHeight:{$},TotalLength:{$},Overlap:{$},SID:{$},TID:{$},PID:{$},Direction:{$},StitchType:{$}]", nInitHeight, nTargetLength, nOverlap, nSID, nTID, nPID, nDirection, nStitchType); m_MECHUnit.m_StitchHeight->Update(nInitHeight); m_MECHUnit.m_StitchOverLap->Update(nOverlap); m_MECHUnit.m_StitchDirection->Update(nDirection); m_MECHUnit.m_StitchType->Update(nStitchType); if (m_MECHUnit.m_CurrentImageNumber->Update(0)) FireNotify(AttrKey::CURRENTIMAGENUMBER, 0); switch (m_MECHUnit.m_StitchType->Get()) { case AttrKey::STITCHTYPE_AutomaticTranslation: case AttrKey::STITCHTYPE_ManualTranslation: { //总长度校验 int maxLength = m_MECHUnit.m_TubeHeight->GetLimitMax() - m_MECHUnit.m_TubeHeight->GetLimitMin(); if (nTargetLength > (maxLength-5)) { mLog::Warn("StitchingLengh[{$}] too big [height min:{$},height max:{$}],need change to[{$}]", nTargetLength, m_MECHUnit.m_TubeHeight->GetLimitMax(),m_MECHUnit.m_TubeHeight->GetLimitMin(), maxLength - 5); nTargetLength = maxLength - 5; } //总张数计算 int totalImage = std::ceil((float)(nTargetLength - nOverlap) / (float)(m_nFPDLengh - nOverlap)); m_MECHUnit.m_TotalImageCount->Update(totalImage); FireNotify(AttrKey::TOTALIMAGECOUNT, totalImage); //计算步长 float tempStepLength = (float)nTargetLength / (float)totalImage; if (m_MECHUnit.m_StitchStepLength->Update(tempStepLength)) FireNotify(AttrKey::STITCHSTEPLENGTH, tempStepLength); mLog::Debug("compute TransStitching [total ImageCount:{$},StepLength:{$}]", totalImage, tempStepLength); //更新总长 m_MECHUnit.m_StitchLength->Update(nTargetLength); }break; case AttrKey::STITCHTYPE_AutomaticAngle: case AttrKey::STITCHTYPE_ManualAngle: { //手动查询SID GetUnitStatus(true); //总长度校验 int maxLength = m_MECHUnit.m_TubeHeight->GetLimitMax() - m_MECHUnit.m_TubeHeight->GetLimitMin(); float minStitchLenth = m_nFPDLengh * 2 - nOverlap; float maxStitchLenth = m_nFPDLengh * 3 - nOverlap * 2; if (maxStitchLenth > (maxLength - 5)) { mLog::Warn("StitchingLengh[{$}] too big [height min:{$},height max:{$}],need change to[{$}]", maxStitchLenth, m_MECHUnit.m_TubeHeight->GetLimitMax(), m_MECHUnit.m_TubeHeight->GetLimitMin(), maxLength - 5); minStitchLenth = (maxLength - 5) - (maxStitchLenth - minStitchLenth); maxStitchLenth = maxLength - 5; } //2、3张时角度范围 float minStitchAngle = 2 * atan((float)minStitchLenth /2.0f / m_MECHUnit.m_SID->Get()) * 180.0f / MY_PI; float maxStitchAngle = 2 * atan((float)maxStitchLenth /2.0f / m_MECHUnit.m_SID->Get()) * 180.0f / MY_PI; mLog::Debug("compute AngleStitching limit[FPDLengh:{$},OverLap:{$}, SID:{$},minLengh:{$}, maxLengh:{$}]->angle[min:{$},max:{$}]", m_nFPDLengh, nOverlap, m_MECHUnit.m_SID->Get(), minStitchLenth, maxStitchLenth, minStitchAngle, maxStitchAngle); if (maxStitchAngle > 25) { float tempMinAngle = minStitchAngle - (maxStitchAngle - 25); float tempMaxAngle = 25; mLog::Warn("Stitching Angle too big, need change angle[min:{$},max:{$}]",tempMinAngle, tempMaxAngle); minStitchAngle = tempMinAngle; maxStitchAngle = tempMaxAngle; } //设置参数的总角度 if (nTargetLength <= minStitchAngle) { m_MECHUnit.m_StitchLength->Update(minStitchAngle); float tempStepLength = (float)minStitchAngle / 2; if (m_MECHUnit.m_StitchStepLength->Update(tempStepLength)) FireNotify(AttrKey::STITCHSTEPLENGTH, tempStepLength); m_MECHUnit.m_TotalImageCount->Update(2); FireNotify(AttrKey::TOTALIMAGECOUNT, 2); mLog::Debug("compute AngleStitching [total ImageCount:{$},StepLength:{$}]", 2, tempStepLength); } else { m_MECHUnit.m_StitchLength->Update(maxStitchAngle); //计算步长 float tempStepLength = (float)maxStitchAngle / 3; if (m_MECHUnit.m_StitchStepLength->Update(tempStepLength)) FireNotify(AttrKey::STITCHSTEPLENGTH, tempStepLength); m_MECHUnit.m_TotalImageCount->Update(3); FireNotify(AttrKey::TOTALIMAGECOUNT, 3); mLog::Debug("compute AngleStitching [total ImageCount:{$},StepLength:{$}]", 3, tempStepLength); } }break; default: return RET_STATUS::RET_FAILED; } //先退出 { sprintf_s(temp, "CM0"); HWSendWaittimeCMD(temp, strlen(temp)); } //设置对齐位 if (nSID <= 150 && (nStitchType == AttrKey::STITCHTYPE_AutomaticTranslation || nStitchType == AttrKey::STITCHTYPE_ManualTranslation)) { sprintf_s(temp, "CM1"); HWSendWaittimeCMD(temp, strlen(temp)); } else { sprintf_s(temp, "CM2"); HWSendWaittimeCMD(temp, strlen(temp)); } //轮询标志 m_bLoopFlag = true; if (m_MECHUnit.m_StitchingState->Update(AttrKey::STITCHSTATE_INIT)) { FireNotify(AttrKey::STITCHINGSTATE, AttrKey::STITCHSTATE_INIT); m_MECHUnit.m_strInfo = "Stitch Init"; mLog::Debug("stitching:[{$}]", m_MECHUnit.m_strInfo.c_str()); FireNotify(AttrKey::UNITINFO, m_MECHUnit.m_strInfo); } return RET_STATUS::RET_SUCCEED; } //notice the URS that the last acquired image is accepted by host. Move to the next stitching target position. RET_STATUS nsMech::HanQingNormalDevice::AcceptStitchingImage() { mLog::Debug("Enter AcceptStitchingImage"); m_bIsBeginFlag = false; if (m_MECHUnit.m_StitchingState->Update(AttrKey::STITCHSTATE_Accept_Image)) { FireNotify(AttrKey::STITCHINGSTATE, AttrKey::STITCHSTATE_Accept_Image); m_MECHUnit.m_strInfo = "Stitch Accept Current image"; mLog::Debug("stitching:[{$}]", m_MECHUnit.m_strInfo.c_str()); FireNotify(AttrKey::UNITINFO, m_MECHUnit.m_strInfo); } int Currentnum = m_MECHUnit.m_CurrentImageNumber->Get() + 1; if (m_MECHUnit.m_CurrentImageNumber->Update(Currentnum)) { mLog::Debug("stitching current image[{$}:{$}]", m_MECHUnit.m_CurrentImageNumber->Get(), m_MECHUnit.m_TotalImageCount->Get()); FireNotify(AttrKey::CURRENTIMAGENUMBER, Currentnum); } if (m_MECHUnit.m_CurrentImageNumber->Get() >= m_MECHUnit.m_TotalImageCount->Get()) { EndStitching(); } else { char temp[50] = { 0 }; switch (m_MECHUnit.m_StitchType->Get()) { case AttrKey::STITCHTYPE_AutomaticTranslation: case AttrKey::STITCHTYPE_ManualTranslation: { //运动的步距aaaa mm sprintf_s(temp, "MD%04d", (int)m_MECHUnit.m_StitchStepLength->Get() * 10); HWSendWaittimeCMD(temp, strlen(temp)); //移动方向 switch (m_MECHUnit.m_StitchDirection->Get()) { case AttrKey::STITCHDIR_TopToBottom: case AttrKey::STITCHDIR_leftToRight: { sprintf_s(temp, "DT1"); HWSendWaittimeCMD(temp, strlen(temp)); }break; case AttrKey::STITCHDIR_BottomToTop: case AttrKey::STITCHDIR_RightToLeft: { sprintf_s(temp, "DT2"); HWSendWaittimeCMD(temp, strlen(temp)); }break; } //启动运动 sprintf_s(temp, "SM1"); HWSendWaittimeCMD(temp, strlen(temp)); }break; case AttrKey::STITCHTYPE_AutomaticAngle: case AttrKey::STITCHTYPE_ManualAngle: { sprintf_s(temp, "SM1"); HWSendWaittimeCMD(temp, strlen(temp)); }break; default: return RET_STATUS::RET_FAILED; } } return RET_STATUS::RET_SUCCEED; } //notice the URS that the last acquired image is rejected by host. Keep current position. RET_STATUS nsMech::HanQingNormalDevice::RejectStitchingImage() { mLog::Debug("Enter RejectStitchingImage"); if (m_MECHUnit.m_StitchingState->Update(AttrKey::STITCHSTATE_Reject_Image)) { FireNotify(AttrKey::STITCHINGSTATE, AttrKey::STITCHSTATE_Reject_Image); m_MECHUnit.m_strInfo = "Stitch Reject Current Image"; mLog::Debug("stitching:[{$}]", m_MECHUnit.m_strInfo.c_str()); FireNotify(AttrKey::UNITINFO, m_MECHUnit.m_strInfo); } return RET_STATUS::RET_SUCCEED; } //Cancel stitching procedure. RET_STATUS nsMech::HanQingNormalDevice::CancelStitching() { if (m_MECHUnit.m_MechState->Update(AttrKey::MACHINE_STATUS_STANDBY)) FireNotify(AttrKey::MACHSTATE, m_MECHUnit.m_MechState->Get()); mLog::Debug("Enter CancelStitching"); char temp[50] = { 0 }; sprintf_s(temp, "CM0"); HWSendWaittimeCMD(temp, strlen(temp)); //轮询标志 m_bLoopFlag = false; if (m_MECHUnit.m_StitchingState->Update(AttrKey::STITCHSTATE_CANCEL)) { FireNotify(AttrKey::STITCHINGSTATE, AttrKey::STITCHSTATE_CANCEL); m_MECHUnit.m_strInfo = "Stitch Cancel"; mLog::Debug("stitching:[{$}]", m_MECHUnit.m_strInfo.c_str()); FireNotify(AttrKey::UNITINFO, m_MECHUnit.m_strInfo); } return RET_STATUS::RET_SUCCEED; } //Note the URS that stitching is finished. RET_STATUS nsMech::HanQingNormalDevice::CompleteStitching() { if (m_MECHUnit.m_MechState->Update(AttrKey::MACHINE_STATUS_STANDBY)) FireNotify(AttrKey::MACHSTATE, m_MECHUnit.m_MechState->Get()); mLog::Debug("Enter CompleteStitching"); char temp[50] = { 0 }; sprintf_s(temp, "CM0"); HWSendWaittimeCMD(temp, strlen(temp)); //轮询标志 m_bLoopFlag = false; if (m_MECHUnit.m_StitchingState->Update(AttrKey::STITCHSTATE_END)) { FireNotify(AttrKey::STITCHINGSTATE, AttrKey::STITCHSTATE_END); m_MECHUnit.m_strInfo = "Stitch Finish"; mLog::Debug("stitching:[{$}]", m_MECHUnit.m_strInfo.c_str()); FireNotify(AttrKey::UNITINFO, m_MECHUnit.m_strInfo); } return RET_STATUS::RET_SUCCEED; } //New extra view, request the positioner to move to a position to take an extra image. RET_STATUS nsMech::HanQingNormalDevice::NewExtraView() { mLog::Debug("Enter NewExtraView"); return RET_STATUS::RET_SUCCEED; } RET_STATUS nsMech::HanQingNormalDevice::RepeatStitching() { mLog::Debug("Enter RepeatStitching"); return RET_STATUS::RET_SUCCEED; } RET_STATUS nsMech::HanQingNormalDevice::SetAutoPosiitonNo(int nPN) { mLog::Debug("Enter SetAutoPosiitonNo:[{$}]", nPN); return RET_STATUS::RET_SUCCEED; } //牛头 RET_STATUS nsMech::HanQingNormalDevice::SetExpEnable(bool nExpEnabled) { return RET_STATUS::RET_SUCCEED; } RET_STATUS nsMech::HanQingNormalDevice::SetWS(int nWS) { mLog::Debug("Enter SetWS:[{$}]", nWS); if (m_nWS == nWS)return RET_STATUS::RET_SUCCEED; m_nWS = nWS; char temp[50] = { 0 }; sprintf_s(temp, "OR%1d", nWS); return HWSendWaittimeCMD(temp, strlen(temp)); } RET_STATUS nsMech::HanQingNormalDevice::SetKV(int nKV) { mLog::Debug("Enter SetKV:[{$}]", nKV); if(m_nKV == nKV)return RET_STATUS::RET_SUCCEED; m_nKV = nKV; char temp[50] = { 0 }; sprintf_s(temp, "KV%03d", nKV); return HWSendWaittimeCMD(temp, strlen(temp)); } RET_STATUS nsMech::HanQingNormalDevice::SetMA(float fMA) { mLog::Debug("Enter SetMA:[{$}]", fMA); if (m_fMA == fMA)return RET_STATUS::RET_SUCCEED; m_fMA = fMA; char temp[50] = { 0 }; sprintf_s(temp, "MA%05d", (int)(fMA * 10)); return HWSendWaittimeCMD(temp, strlen(temp)); } RET_STATUS nsMech::HanQingNormalDevice::SetMS(float fMS) { mLog::Debug("Enter SetMS:[{$}]", fMS); if (m_fMS == fMS)return RET_STATUS::RET_SUCCEED; m_fMS = fMS; char temp[50] = { 0 }; sprintf_s(temp, "MS%05d", (int)(fMS * 10)); return HWSendWaittimeCMD(temp, strlen(temp)); } RET_STATUS nsMech::HanQingNormalDevice::SetMAS(float fMAS) { mLog::Debug("Enter SetMAS:[{$}]", fMAS); if (m_fMAS == fMAS)return RET_STATUS::RET_SUCCEED; m_fMAS = fMAS; char temp[50] = { 0 }; sprintf_s(temp, "MX%05d", (int)(fMAS * 10)); return HWSendWaittimeCMD(temp, strlen(temp)); } RET_STATUS nsMech::HanQingNormalDevice::SetFO(int nFO) { mLog::Debug("Enter SetFO:[{$}]", nFO); if (m_nFocus == nFO)return RET_STATUS::RET_SUCCEED; m_nFocus = nFO; char temp[50] = { 0 }; sprintf_s(temp, "FO%1d", nFO); return HWSendWaittimeCMD(temp, strlen(temp)); } RET_STATUS nsMech::HanQingNormalDevice::SetTechMode(int nET) { mLog::Debug("Enter SetTechMode:[{$}]", nET); if (m_nET == nET)return RET_STATUS::RET_SUCCEED; m_nET = nET; char temp[50] = { 0 }; sprintf_s(temp, "ET%1d", nET); return HWSendWaittimeCMD(temp, strlen(temp)); } RET_STATUS nsMech::HanQingNormalDevice::SetAECField(int nAECFieldSel) { mLog::Debug("Enter SetAECField:[{$}]", nAECFieldSel); if (m_nAECField == nAECFieldSel)return RET_STATUS::RET_SUCCEED; m_nAECField = nAECFieldSel; char temp[50] = { 0 }; sprintf_s(temp, "FI%03d", nAECFieldSel); return HWSendWaittimeCMD(temp, strlen(temp)); return RET_STATUS::RET_SUCCEED; } RET_STATUS nsMech::HanQingNormalDevice::SetDensity(float nAECDensity) { mLog::Debug("Enter SetDensity:[{$}]", nAECDensity); if (m_nAECDensity == nAECDensity)return RET_STATUS::RET_SUCCEED; m_nAECDensity = nAECDensity; char temp[50] = { 0 }; sprintf_s(temp, "FD%+04d", (int)nAECDensity); return HWSendWaittimeCMD(temp, strlen(temp)); } RET_STATUS nsMech::HanQingNormalDevice::SetBodySize(string strSize) { mLog::Debug("Enter SetBodySize:[{$}]", strSize.c_str()); char temp[50] = { 0 }; int nPS = 2; if (strSize == "Small") { nPS = 1; } else if (strSize == "Middle") { nPS = 2; } else if (strSize == "Large") { nPS = 3; } else if (strSize == "Child") { nPS = 4; } if (m_nBodySize == nPS)return RET_STATUS::RET_SUCCEED; m_nBodySize = nPS; sprintf_s(temp, "PS%1d", m_nBodySize); HWSendWaittimeCMD(temp, strlen(temp)); } //HanQingNormal特有 RET_STATUS nsMech::HanQingNormalDevice::GetUnitStatus(bool sync) { //mLog::Debug("Enter GetUnitStatus"); char temp[50] = { 0 }; sprintf_s(temp, "TT?"); if(sync) return HWSendWaitACKCMD(temp, strlen(temp)); else return HWSendWaittimeCMD(temp, strlen(temp)); } RET_STATUS nsMech::HanQingNormalDevice::GenNotify(string& key, string& value) { if (key == nsGEN::AttrKey::WORKSTATION) { SetWS(atoi(value.c_str())); } else if (key == nsGEN::AttrKey::KV) { SetKV(atoi(value.c_str())); } else if (key == nsGEN::AttrKey::MA) { SetMA(atof(value.c_str())); } else if (key == nsGEN::AttrKey::MS) { SetMS(atof(value.c_str())); } else if (key == nsGEN::AttrKey::MAS) { SetMAS(atof(value.c_str())); } else if (key == nsGEN::AttrKey::FOCUS) { SetFO(atoi(value.c_str())); } else if (key == nsGEN::AttrKey::TECHMODE) { SetTechMode(atoi(value.c_str())); } else if (key == nsGEN::AttrKey::AECDENSITY) { SetDensity(atof(value.c_str())); } else if (key == nsGEN::AttrKey::AECFIELD) { SetAECField(atoi(value.c_str())); } return RET_STATUS::RET_SUCCEED; } //----------------------------------------------------------------------------- // HanQingNormalDriver //----------------------------------------------------------------------------- nsMech::HanQingNormalDriver::HanQingNormalDriver() { m_pAttribute.reset(new ResDataObject()); m_pDescription.reset(new ResDataObject()); } nsMech::HanQingNormalDriver::~HanQingNormalDriver() { } void nsMech::HanQingNormalDriver::FireNotify(int code, std::string key, std::string content) { mLog::Debug("Enter FireNotify"); EventCenter->OnNotify(code, key, content); } void nsMech::HanQingNormalDriver::Dequeue(const char* Packet, DWORD Length) { DecodeFrame(Packet, Length); } static char strRcvTemp[HanQingNormal_Com_NormalLen] = { 0 }; PACKET_RET nsMech::HanQingNormalDriver::callbackPackageProcess(const char* RecData, DWORD nLength, DWORD& PacketLength) { #if 0 if (nLength > 1) { mLog::Error("receive data_len[{$}]", nLength); for (int i = 0; i < nLength; i++) { if (i != nLength - 1) { mLog::Error("receive data[{$}][{$}]", i, RecData[i]); } else { mLog::Error("receive data[{$}][{$}]", i, RecData[i]); } } } #endif if (nLength < 1) { PacketLength = 0; mLog::Error("nLength too small, nLength=={$}", nLength); return PACKET_USELESS; } else if (nLength > HanQingNormal_Com_NormalLen - 1) { PacketLength = nLength; mLog::Error("nLength too big, nLength=={$}", nLength); return PACKET_USELESS; } memset(strRcvTemp, 0, HanQingNormal_Com_NormalLen); for (DWORD i = 0; i < nLength; i++) { //寻找包尾 if (RecData[i] == HanQingNormal_ETX) { PacketLength = i + 2; //because ETX+Checksum if (i >= 3) //正常指令:CMDid(2BYTE) + DATA(1BYTE) + ETX(1BYTE) + Checksum(1BYTE) { memcpy_s(strRcvTemp, HanQingNormal_Com_NormalLen - 1, RecData, i); //长度:-1 排除ETX+Checksum if (strncmp(strRcvTemp, ">TT", 3) != 0) mLog::Info("==IN==:[{$}]", strRcvTemp); return PACKET_ISPACKET; } else //空指令 { memcpy_s(strRcvTemp, HanQingNormal_Com_NormalLen - 1, RecData, PacketLength); //空数据,格式正确但无有效命令 mLog::Error("==IN uselss data==:[{$}]", strRcvTemp); return PACKET_USELESS; } } } return PACKET_NOPACKET; } void nsMech::HanQingNormalDriver::Prepare() { string strLogPath = GetProcessDirectory() + R"(\OEMDrivers\Mechanical\Conf\Log4CPP.Config.MECH.xml)"; //Log4CPP::ThreadContext::Map::Set("LogFileName", "Mech.HanQingNormal"); Log4CPP::GlobalContext::Map::Set(ECOM::Utility::Hash("LogFileName"), "Mech.HanQingNormal"); auto rc = Log4CPP::LogManager::LoadConfigFile(strLogPath.c_str()); mLog::gLogger = Log4CPP::LogManager::GetLogger("Mech.HanQingNormal"); m_SCFDllName = GetConnectDLL(m_ConfigFileName); super::Prepare(); } bool nsMech::HanQingNormalDriver::Connect() { mLog::Debug("Enter Connect"); ResDataObject Connection = GetConnectParam(m_ConfigFileName); mLog::Info("connections:{$} \n", Connection.encode()); auto erCode = m_SCF.Connect(Connection.encode(), &nsMech::HanQingNormalDriver::callbackPackageProcess, SCF_PACKET_TRANSFER, 3000); if (erCode != SCF_ERR::SCF_SUCCEED) return false; //return erCode; auto rc = super::Connect(); if (!rc) return false; //return 0; return true; //return SCF_ERR::SCF_SUCCEED; } void nsMech::HanQingNormalDriver::Disconnect() { mLog::Debug("Enter Disconnect"); super::Disconnect(); m_SCF.Disconnect(); } bool nsMech::HanQingNormalDriver::isConnected() const { return super::isConnected(); } auto nsMech::HanQingNormalDriver::CreateDevice(int index) -> std::unique_ptr { mLog::Debug("Enter CreateDevice[{$}]", index); //mLog::Info("Enter CreateDevice, index={$}", index); if (index == 0) { auto dev = std::unique_ptr(new IODevice(new HanQingNormalDevice(EventCenter, m_SCF, m_ConfigFileName))); return dev; } //mLog::Error("unknown index"); unique_ptr dev; return dev; } std::string nsMech::HanQingNormalDriver::DriverProbe() { printf("line= %d,%s %s\n", __LINE__, __FUNCTION__, m_ConfigFileName.c_str()); ResDataObject r_config, HardwareInfo; if (r_config.loadFile(m_ConfigFileName.c_str())) { HardwareInfo.add("MajorID", r_config["CONFIGURATION"]["MajorID"]); HardwareInfo.add("MinorID", r_config["CONFIGURATION"]["MinorID"]); HardwareInfo.add("VendorID", r_config["CONFIGURATION"]["VendorID"]); HardwareInfo.add("ProductID", r_config["CONFIGURATION"]["ProductID"]); HardwareInfo.add("SerialID", r_config["CONFIGURATION"]["SerialID"]); } else { HardwareInfo.add("MajorID", "Machine"); HardwareInfo.add("MinorID", "Dr"); HardwareInfo.add("VendorID", "ECOM"); HardwareInfo.add("ProductID", "HF"); HardwareInfo.add("SerialID", "1234"); } string ret = HardwareInfo.encode(); printf("line= %d,%s %s\n", __LINE__, __FUNCTION__, m_ConfigFileName.c_str()); return ret; } std::string nsMech::HanQingNormalDriver::GetResource() { ResDataObject r_config, temp; if (!temp.loadFile(m_ConfigFileName.c_str())) { return ""; } m_ConfigAll = temp; r_config = temp["CONFIGURATION"]; m_Configurations = r_config; ResDataObject DescriptionTemp; ResDataObject DescriptionSend; ResDataObject m_DescriptionSend; ResDataObject ListTemp; string strTemp = ""; //用于读取字符串配置信息 string strIndex = ""; //用于读取配置信息中的List项 int nTemp = -1; //用于读取整型配置信息 char sstream[10] = { 0 }; //用于转换值 string strValue = ""; //用于存储配置的值 string strType = ""; //用于存储配置的类型 int/float/string... try { //便利ConfigToolInfo 中 所有的AttributeInfo 属性段 int nConfigInfoCount = (int)m_Configurations["ConfigToolInfo"].GetKeyCount("AttributeInfo"); m_pAttribute->clear(); m_pDescription->clear(); for (int nInfoIndex = 0; nInfoIndex < nConfigInfoCount; nInfoIndex++) { DescriptionTemp.clear(); DescriptionSend.clear(); ListTemp.clear(); //AttributeType strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeDescripition"]["Type"]; DescriptionTemp.add(ConfKey::DiosType, strTemp.c_str());//DiosGeneratorAttribute DescriptionSend.add(ConfKey::DiosType, strTemp.c_str());//DiosGeneratorAttribute strType = strTemp; //记录配置项的类型 //AttributeKey //1. 根据AttributeType,内部key和配置路径,拿到当前的真实值 strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["InnerKey"]; nTemp = (int)m_Configurations["ConfigToolInfo"][nInfoIndex]["PathID"]; GetDeviceConfigValue(r_config, strTemp.c_str(), nTemp, strValue); //得到strValue的值 //2. 赋值 strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeKey"]; if ("int" == strType) { (*m_pAttribute).add(strTemp.c_str(), atoi(strValue.c_str())); } else if ("float" == strType) { (*m_pAttribute).add(strTemp.c_str(), atoi(strValue.c_str())); } else //其它先按string类型处理 { (*m_pAttribute).add(strTemp.c_str(), strValue.c_str()); } //AttributeAccess strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeDescripition"]["Access"]; DescriptionTemp.add(ConfKey::DiosAccess, strTemp.c_str()); DescriptionSend.add(ConfKey::DiosAccess, strTemp.c_str()); //AttributeRangeMin //strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeDescripition"]["RangeMin"]; //if (strTemp != "") //不需要的配置项为空 //{ // DescriptionTemp.add(ConfKey::DiosRangeMin, strTemp.c_str()); //} ////AttributeRangeMax //strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeDescripition"]["RangeMax"]; //if (strTemp != "") //不需要的配置项为空 //{ // DescriptionTemp.add(ConfKey::DiosRangeMax, strTemp.c_str()); //} //AttributeList nTemp = m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeDescripition"]["ListNum"]; if (nTemp > 0) //ListNum不大于0时说明不需要list配置 { for (int nListIndex = 0; nListIndex < nTemp; nListIndex++) { strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeDescripition"]["ListInfo"][nListIndex]; auto temKey = std::to_string(nListIndex); ListTemp.add(temKey.c_str(), strTemp.c_str()); } DescriptionTemp.add(ConfKey::DiosList, ListTemp); DescriptionSend.add(ConfKey::DiosList, ListTemp.encode()); } //AttributeRequired strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeDescripition"]["Required"]; DescriptionTemp.add(ConfKey::DiosRequired, strTemp.c_str()); DescriptionSend.add(ConfKey::DiosRequired, strTemp.c_str()); //AttributeDefaultValue strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeDescripition"]["DefaultValue"]; if (strTemp != "") //不需要的配置项为空 { DescriptionTemp.add(ConfKey::DiosDefaultValue, strTemp.c_str()); DescriptionSend.add(ConfKey::DiosDefaultValue, strTemp.c_str()); } strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeKey"]; (*m_pDescription).add(strTemp.c_str(), DescriptionTemp); m_DescriptionSend.add(strTemp.c_str(), DescriptionSend.encode()); } } catch (ResDataObjectExption& e) { //mLog::Error("Get config error: {$}", e.what()); return ""; } ResDataObject resDeviceResource; resDeviceResource.add(ConfKey::DiosAttribute, (*m_pAttribute)); resDeviceResource.add(ConfKey::DiosDescription, (*m_pDescription)); ResDataObject DescriptionTempEx; DescriptionTempEx.add(ConfKey::DiosConfig, resDeviceResource); m_DeviceConfig.clear(); m_DeviceConfig = DescriptionTempEx; //mLog::Debug("local ************* get resource over {$}", DescriptionTempEx.encode()); printf("local ************* get resource over %s \n", DescriptionTempEx.encode()); resDeviceResource.clear(); resDeviceResource.add(ConfKey::DiosAttribute, (*m_pAttribute)); resDeviceResource.add(ConfKey::DiosDescription, m_DescriptionSend); DescriptionTempEx.clear(); DescriptionTempEx.add(ConfKey::DiosConfig, resDeviceResource); m_DeviceConfigSend.clear(); m_DeviceConfigSend = DescriptionTempEx; string res = m_DeviceConfigSend.encode(); //mLog::Debug("get resource over {$}", DescriptionTempEx.encode()); printf("************* get resource over %s \n", DescriptionTempEx.encode()); return res; } std::string nsMech::HanQingNormalDriver::DeviceProbe() { ResDataObject r_config, HardwareInfo; if (r_config.loadFile(m_ConfigFileName.c_str())) { HardwareInfo.add("MajorID", r_config["CONFIGURATION"]["MajorID"]); HardwareInfo.add("MinorID", r_config["CONFIGURATION"]["MinorID"]); HardwareInfo.add("VendorID", r_config["CONFIGURATION"]["VendorID"]); HardwareInfo.add("ProductID", r_config["CONFIGURATION"]["ProductID"]); HardwareInfo.add("SerialID", r_config["CONFIGURATION"]["SerialID"]); } else { HardwareInfo.add("MajorID", "Machine"); HardwareInfo.add("MinorID", "Dr"); HardwareInfo.add("VendorID", "ECOM"); HardwareInfo.add("ProductID", "HF"); HardwareInfo.add("SerialID", "1234"); } string ret = HardwareInfo.encode(); return ret; } bool nsMech::HanQingNormalDriver::GetDeviceConfig(std::string& Cfg) { Cfg = m_DeviceConfigSend.encode(); printf("GetDeviceConfig over , %s", Cfg.c_str()); return true; } bool nsMech::HanQingNormalDriver::SetDeviceConfig(std::string Cfg) { printf("\n--Func-- SetDeviceConfig %s\n", Cfg.c_str()); ResDataObject DeviceConfig; DeviceConfig.decode(Cfg.c_str()); ResDataObject DescriptionTempEx; DescriptionTempEx = DeviceConfig["DeviceConfig"]["Attribute"]; //mLog::Debug("Attribute:{$}", DescriptionTempEx.encode()); bool bSaveFile = false; //true:重新保存配置文件 string strAccess = ""; for (int i = 0; i < DescriptionTempEx.size(); i++) { string strKey = DescriptionTempEx.GetKey(i); ////mLog::Info("{$}", strKey.c_str()); printf("%s\n", strKey.c_str()); try { if (m_pAttribute->GetFirstOf(strKey.c_str()) >= 0) { strAccess = (string)(*m_pDescription)[strKey.c_str()]["Access"]; if ("RW" == strAccess) { //修改对应配置,在其他单元的配置项要同时调用其修改函数修改真实值 //1. 修改内存中的值,用于给上层发消息 (*m_pAttribute)[strKey.c_str()] = DescriptionTempEx[i]; //2. 拿到Innerkey int nConfigInfoCount = (int)m_Configurations["ConfigToolInfo"].GetKeyCount("AttributeInfo"); ////mLog::Info("nConfigInfoCount {$}", nConfigInfoCount); string strTemp = ""; //存储AttributeKey for (int nInfoIndex = 0; nInfoIndex < nConfigInfoCount; nInfoIndex++) { strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["AttributeKey"]; if (strTemp == strKey) { strTemp = (string)m_Configurations["ConfigToolInfo"][nInfoIndex]["InnerKey"]; break; } } //3. 修改配置文件中的值 if (SetDeviceConfigValue(m_Configurations, strTemp.c_str(), 1, DescriptionTempEx[i])) { //mLog::Debug("SetDeviceConfigValue over"); bSaveFile = true; } } else { ////mLog::Info("{$} is not a RW configuration item", strKey.c_str()); } } else { ////mLog::Info("without this attribute {$}", strKey.c_str()); } } catch (ResDataObjectExption& e) { printf("\nSetDriverConfig crashed: %s\n", e.what()); //mLog::Error("SetDriverConfig crashed: {$}", e.what()); return false; } } if (bSaveFile) { //3. 重新保存配置文件 SaveConfigFile(true); } return true; } bool nsMech::HanQingNormalDriver::SaveConfigFile(bool bSendNotify) { m_ConfigAll["CONFIGURATION"] = m_Configurations; bool bRt = m_ConfigAll.SaveFile(m_ConfigFileName.c_str()); ////mLog::Info("SaveConfigFile over {$}", bRt); return true; } bool nsMech::HanQingNormalDriver::GetDeviceConfigValue(ResDataObject config, const char* pInnerKey, int nPathID, string& strValue) { printf("line= %d,%s,pInnerKey=%s,nPathID=%d\n", __LINE__, __FUNCTION__, pInnerKey, nPathID); strValue = ""; string strTemp = pInnerKey; if (1 == nPathID) //从DriverConfig路径下每个DPC自己的配置文件读取 { int pos = 0; ResDataObject resTemp = config; while ((pos = strTemp.find_first_of(',')) != string::npos) { string Key = strTemp.substr(0, pos); string TempValue = resTemp[Key.c_str()].encode(); //printf("-TempValue=== %s\n", TempValue.c_str()); resTemp.clear(); resTemp.decode(TempValue.c_str()); strTemp = strTemp.substr(pos + 1, strTemp.length() - pos - 1); //printf("-************--%s\n", strTemp.c_str()); } if (strTemp != "") { strValue = (string)resTemp[strTemp.c_str()]; } else { strValue = (string)resTemp; } } //printf("------------%s\n", strValue.c_str()); return true; } bool nsMech::HanQingNormalDriver::SetDeviceConfigValue(ResDataObject& config, const char* pInnerKey, int nPathID, const char* szValue) { string strTemp = pInnerKey; //mLog::Debug("Begin to change {$} item value to {$}", pInnerKey, szValue); printf("\n Begin to change {%s} item value to {%s}\n", pInnerKey, szValue); if (1 == nPathID) //从DriverConfig路径下每个DPC自己的配置文件读取 { try { int pos = 0; ResDataObject* resTemp = &config; while ((pos = strTemp.find_first_of(',')) != string::npos) { string Key = strTemp.substr(0, pos); resTemp = &(*resTemp)[Key.c_str()]; strTemp = strTemp.substr(pos + 1, strTemp.length() - pos - 1); } if (strTemp != "") { (*resTemp)[strTemp.c_str()] = szValue; } else { *resTemp = szValue; } } catch (ResDataObjectExption& e) { //mLog::Error("SetDriverConfigvalue crashed: {$}", e.what()); return false; } } return true; } //模块对外接口 static nsMech::HanQingNormalDriver gIODriver; extern "C" DIOS::Dev::IODriver * __cdecl GetIODriver() // 返回静态对象的引用, 调用者不能删除 ! { return &gIODriver; } extern "C" DIOS::Dev::IODriver * __cdecl CreateIODriver() // 返回新对象, 调用者必须自行删除此对象 ! { return new nsMech::HanQingNormalDriver(); }