#include "stdafx.h" #include #include "Helper.JSON.hpp" #include "DIOS.Dev.Mech.WDMAMMOCAN.hpp" using namespace DIOS::Dev; using namespace DIOS::Dev::Detail::MECH; namespace nsMech = DIOS::Dev::Detail::MECH; #pragma warning (disable:4305) //CAN --------------------------------------------------------------- #if 1 //#include "stdafx.h" //#include "resource.h" //#include "CANPort.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[] = __FILE__; #define new DEBUG_NEW #endif //#include "Table.h" //#include "Aqmodule.h" //#include ".\Generator\GeneratorD100.h" #include "Usbcan\SimulateCan.h" //#include "ReplaceYaoTai.h" //CTable* CCANPort::m_pTable = NULL; //CReplaceYaoTai* CCANPort::m_pReplaceYaoTai = NULL; ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// //----------------------------------------------------- //参数: //chr:要转换的字符 //cint:储存转换过来的数据 //函数功能:字符转换为数据 //----------------------------------------------------- int chartoint(unsigned char chr, unsigned char* cint)//CCANPort:: { unsigned char cTmp; cTmp = chr - 48; //0-9 if (cTmp >= 0 && cTmp <= 9) { *cint = cTmp; return 0; } cTmp = chr - 65;//A-F if (cTmp >= 0 && cTmp <= 5) { *cint = (cTmp + 10); return 0; } cTmp = chr - 97;//a-f if (cTmp >= 0 && cTmp <= 5) { *cint = (cTmp + 10); return 0; } return 1; } //----------------------------------------------------- //参数: //str:要转换的字符串 //data:储存转换过来的数据串 //len:数据长度 //函数功能:字符串转换为数据串 //----------------------------------------------------- int strtodata(unsigned char* str, unsigned char* data, int len, int flag)//CCANPort:: { unsigned char cTmp = 0; int i = 0; for (int j = 0; j < len; j++) { if (chartoint(str[i++], &cTmp)) return 1; data[j] = cTmp; if (chartoint(str[i++], &cTmp)) return 1; data[j] = (data[j] << 4) + cTmp; if (flag == 1) i++; } return 0; } nsMech::CCANPort::CCANPort() { //init_config m_pTableCtrl = nullptr; m_devtype = 0; m_devind = 0; //can number m_cannum = 0; //about thread m_bCANThreadActive = FALSE; m_Thread = NULL; //can start flag m_bCanStart = FALSE; m_hCANWindowHandle = NULL; m_nAngleDirection = 0; m_pCANEx = nullptr; int m_nCANType = 0; switch (m_nCANType) { case 0: m_pCANEx = new CZLG; break; case 1: m_pCANEx = new CPC; break; case 2: m_pCANEx = new CJY; case 9: m_pCANEx = new CSimulateCan; break; default: break; } } nsMech::CCANPort::~CCANPort() { if (m_Thread != NULL) { if (m_bCANThreadActive) m_bCANThreadActive = FALSE; } CAN_Close(); if (m_pCANEx) { delete m_pCANEx; m_pCANEx = NULL; } } BOOL nsMech::CCANPort::CAN_Open(/*int DeviceType,*/DWORD DeviceInd, int Reserved) { // m_devtype = DeviceType; m_devind = DeviceInd; INT nFlag = 0; // while(VCI_OpenDevice(m_devtype,m_devind,Reserved) != STATUS_OK) if (!m_pCANEx->LoadDLL()) { return FALSE; } while (m_pCANEx->OpenDevice(m_devind) != STATUS_OK) { if (2 == nFlag++) { return FALSE; } Sleep(1000); } return TRUE; } bool nsMech::CCANPort::CAN_Start() { //if(VCI_StartCAN(m_devtype,m_devind,m_cannum)==1) if (m_pCANEx->StartCAN(m_devind, m_cannum) == 1) { m_bCanStart = TRUE; return true; } else { return false; } } bool nsMech::CCANPort::CAN_Reset() { //2007.11.19_此函数用来复位CAN //if(VCI_ResetCAN(m_devtype,m_devind,m_cannum) == 1) if (m_pCANEx->ResetCAN(m_devind, m_cannum) == 1) { m_bCanStart = FALSE; return true; } else { //VCI_CloseDevice(m_devtype,m_devind); m_pCANEx->CloseDevice(m_devind); m_bCanStart = FALSE; return false; } } void nsMech::CCANPort::CAN_Close() { if (!m_bCanStart) return; m_bCanStart = FALSE; Sleep(100); m_pCANEx->CloseDevice(m_devind); } BOOL nsMech::CCANPort::CAN_Init(HWND hWnd, DWORD dwAccCode, DWORD dwAccMask, UCHAR ucFilter, UCHAR ucMode, UCHAR ucTiming0, UCHAR ucTiming1, int nCannum) { m_hCANWindowHandle = hWnd; //0 init_config.AccCode = dwAccCode; //0 验收码 init_config.AccMask = dwAccMask; //ffffffff 屏蔽码 init_config.Filter = ucFilter; //1 滤波方式:单滤/双滤0/1 init_config.Mode = ucMode; //0 模式:正常/只听,0/1 init_config.Timing0 = ucTiming0; //TIMING0 定时器1 timing0; init_config.Timing1 = ucTiming1; //TIMING1 m_cannum = nCannum; //nCannum //初始化CAN if (m_pCANEx->InitCAN(m_devind, m_cannum, &init_config) != STATUS_OK) { //VCI_CloseDevice(m_devtype,m_devind); m_pCANEx->CloseDevice(m_devind); return false; } //开启接收线程 DWORD m_HardwareStatusID; m_Thread = CreateThread(0, 0, ReceiveThread, this, 0, (LPDWORD)m_HardwareStatusID); if (m_Thread == NULL) { mLog::Fatal("Start HardwareStatus Thread Failed"); return false; } return TRUE; } bool nsMech::CCANPort::CAN_transmit(string strData, string strFrmID, BYTE RomoteFlag/*= 0*/, BYTE ExternFlag/*= 0*/, BYTE type/*=1*/) { VCI_CAN_OBJ frameinfo; BYTE FrameID[4] = { 0,0,0,0 }; char szFrameID[9]; memset(szFrameID, '0', 9); unsigned char Data[8]; char szData[25]; BYTE datalen = 0; //帧ID占4个字节,用16进制表示:0x21A09878,字符表示长度为8,----------------------here ,maybe not right.because as i know frameID =4. if (strFrmID.length() > 8) { return false; } //if (strFrmID.GetLength() > 8) //{ // return false; //} //发送数据,16进制表示,每个数无空格, 即:"01A1098070000000",最多16个数 //if (strData.GetLength() > 16) if (strData.length() > 16) { return false; } //发送帧类型:标准,扩展 if (ExternFlag == 0)//标准帧 { if (strData.length() % 2 == 1)//。。。? { return false; } } //copy 到低位 memcpy(&szFrameID[8 - strFrmID.length()], strFrmID.c_str(), strFrmID.length()); strtodata((unsigned char*)szFrameID, FrameID, 4, 0); //发送数据是16进制表示,每个数据之间有空格 datalen = (strData.length()) / 2;//实际个数 strcpy(szData, strData.c_str()); strtodata((unsigned char*)szData, Data, datalen, 0); frameinfo.DataLen = datalen; memcpy(&frameinfo.Data, Data, datalen); frameinfo.RemoteFlag = RomoteFlag;//数据帧/远程帧 frameinfo.ExternFlag = ExternFlag; frameinfo.TimeFlag = 0; frameinfo.TimeStamp = 0; //帧类型约束帧ID的实际占有位数 if (frameinfo.ExternFlag == 1) { frameinfo.ID = ((DWORD)FrameID[0] << 24) + ((DWORD)FrameID[1] << 16) + ((DWORD)FrameID[2] << 8) + ((DWORD)FrameID[3]); } else { frameinfo.ID = ((DWORD)FrameID[2] << 8) + ((DWORD)FrameID[3]); } frameinfo.SendType = type;//发送格式:单发。。 CCAN* p = m_pCANEx; if (m_pCANEx->Transmit(m_devind, m_cannum, &frameinfo, 1) == 1) { return true; } else { Sleep(20); if (m_pCANEx->Transmit(m_devind, m_cannum, &frameinfo, 1) == 1) return true; else { return false; } } return false; } DWORD nsMech::CCANPort::ReceiveThread(void* param) { CCANPort* port = (CCANPort*)param; VCI_CAN_OBJ frameinfo[50]; VCI_ERR_INFO errinfo; string strFrmID; int nRecvDataLen = 1; string str; string strData; char recvbuf[10]{ 0,0,0,0,0,0,0,0,0,0 }; port->m_bCANThreadActive = true; while (port->m_bCANThreadActive) { if (port == NULL) { return 0; } Sleep(4); nRecvDataLen = port->m_pCANEx->Receive(port->m_devind, port->m_cannum, frameinfo, 50, 200); if (nRecvDataLen == 0xffffffff) { port->m_pCANEx->ReadErrInfo(port->m_devind, port->m_cannum, &errinfo); } else { //str.Format("frameinfo->ID=%X,frameinfo->DataLen=%d, [%02X,%02X,%02X,%02X,%02X,%02X,%02X,%02X]", recvbuf[0] = frameinfo->ID; recvbuf[1] = frameinfo->DataLen; recvbuf[2] = frameinfo->Data[0]; recvbuf[3] = frameinfo->Data[1]; recvbuf[4] = frameinfo->Data[2]; recvbuf[5] = frameinfo->Data[3]; recvbuf[6] = frameinfo->Data[4]; recvbuf[7] = frameinfo->Data[5]; recvbuf[8] = frameinfo->Data[6]; recvbuf[9] = frameinfo->Data[7]; //port->m_pTableCtrl->m_pLog->WriteLog(str); mLog::Info("CAN recv data:{$}\n", recvbuf); if (frameinfo->ID == 0x405 && frameinfo->DataLen == 8)//立柱板节点 { #pragma region ID405 if (frameinfo->Data[1] == 1) { mLog::Info("recv Column heart beat."); } if (frameinfo->Data[1] == 2) { //配置信息回复 int nPanelType = frameinfo->Data[2];//平板选择 int nAngle = frameinfo->Data[3];//C臂ML0位:角度 mLog::Info("recv : panel type:{$},C臂ML0位:角度={$}", nPanelType, nAngle); //port->m_pTableCtrl->m_pLog->WriteLog(str); } if (frameinfo->Data[1] == 3) { //曝光模式回复 int nExpMode = frameinfo->Data[2]; int nAECfield = frameinfo->Data[3]; int nAECDensity = frameinfo->Data[4]; mLog::Info("recv: exp mode:{$},AEC field={$},AEC density={$}", nExpMode, nAECfield, nAECDensity); } if (frameinfo->Data[1] == 4 && frameinfo->Data[2] == 0x61) { mLog::Info("recv ANRAN panel ready or not."); } if (frameinfo->Data[2] == 0x10) { mLog::Info("recv panel ready status"); } if (frameinfo->Data[2] == 0x20) { mLog::Info("recv gen ready status"); } if (frameinfo->Data[2] == 0x30) { mLog::Info("recv exp start"); } if (frameinfo->Data[2] == 0x40) { mLog::Info("recv exp finished"); } if (frameinfo->Data[2] == 0x50) { mLog::Info("recv workflow finished."); } #if 0 int sid = (int)(frameinfo->Data[2] * 256 + frameinfo->Data[3]); port->m_pTableCtrl->m_nSID = sid; port->m_pTableCtrl->MSGControl(port->m_pTableCtrl->m_pWnd, ECOM_MSG_RFMC_PARAMOUT, ECOM_MECHCOMP_PA_SID, sid, ECOM_MSG_TYPE_SYNC_NO, ECOM_MSG_TARGETHANDLE_RFOC); port->m_pTableCtrl->MSGControl(port->m_pTableCtrl->m_pWnd, ECOM_MSG_RFMC_PARAMOUT, ECOM_MECHCOMP_PA_SID, sid, ECOM_MSG_TYPE_SYNC_NO, ECOM_MSG_TARGETHANDLE_RFHARDWARE); int _collimatorWsize = (int)(frameinfo->Data[4] * 256 + frameinfo->Data[5]); int _collimatorHsize = (int)(frameinfo->Data[6] * 256 + frameinfo->Data[7]); port->m_pTableCtrl->m_nCollRealWSize = _collimatorWsize; port->m_pTableCtrl->m_nCollRealHSize = _collimatorHsize; CString strlog; strlog.Format("feedback collimator real size: id=0x7f0, height=%d mm,width=%d mm, sid=%d cm.", _collimatorHsize, _collimatorWsize, sid); port->m_pTableCtrl->m_pLog->WriteLog(strlog, LOG_INFORMATION); int virtual_Wsize = 1; int virtual_Hsize = 1; if (port->m_pTableCtrl->m_nZoomMode == 0)//17*17 { virtual_Wsize = int(_collimatorWsize / port->m_pTableCtrl->m_fHcoefficient / 10 / port->m_pTableCtrl->m_nFrontPartSID * port->m_pTableCtrl->m_nSID + 0.5); virtual_Hsize = int(_collimatorHsize / port->m_pTableCtrl->m_fVcoefficient / 10 / port->m_pTableCtrl->m_nFrontPartSID * port->m_pTableCtrl->m_nSID + 0.5); } else if (port->m_pTableCtrl->m_nZoomMode == 1)//9*9 { virtual_Wsize = int(_collimatorWsize / port->m_pTableCtrl->m_fHcoefficientZoom1 / 10 / port->m_pTableCtrl->m_nFrontPartSID * port->m_pTableCtrl->m_nSID + 0.5); virtual_Hsize = int(_collimatorHsize / port->m_pTableCtrl->m_fVcoefficientZoom1 / 10 / port->m_pTableCtrl->m_nFrontPartSID * port->m_pTableCtrl->m_nSID + 0.5); } strlog.Format("feedback collimator virtual size: id=0x7f0, height=%d cm,width=%d cm", virtual_Hsize, virtual_Wsize); port->m_pTableCtrl->m_pLog->WriteLog(strlog, LOG_INFORMATION); if (port->m_pTableCtrl->m_pWnd != nullptr) { port->m_pTableCtrl->MSGControl(port->m_pTableCtrl->m_pWnd, ECOM_MSG_RFMC_PARAMOUT, ECOM_MECHCOMP_PA_COLLIMATOR, _collimatorWsize + _collimatorHsize * 100, ECOM_MSG_TYPE_SYNC_NO, ECOM_MSG_TARGETHANDLE_RFOC); port->m_pTableCtrl->MSGControl(port->m_pTableCtrl->m_pWnd, ECOM_MSG_RFMC_PARAMOUT, ECOM_MECHCOMP_PA_COLLIMATOR, _collimatorWsize + _collimatorHsize * 100, ECOM_MSG_TYPE_SYNC_NO, ECOM_MSG_TARGETHANDLE_RFHARDWARE); } else { port->m_pTableCtrl->m_pLog->WriteLog("port->m_pTableCtrl->m_pWnd == nullptr", LOG_INFORMATION); } #endif // 0 #pragma endregion } else if (frameinfo->ID == 0x425)//C臂控制板节点 { #pragma region ID425 if (frameinfo->Data[0] == 0) { if (frameinfo->Data[1] == 0x18) { mLog::Info("recv 双电位器错误 or not.Data[2]决定."); } if (frameinfo->Data[1] == 0x06) { int nAngleSignal = frameinfo->Data[2]; int nAngleValue = frameinfo->Data[3]; if (2 == nAngleSignal)//负 { nAngleValue *= -1; } mLog::Info("recv C 臂旋转角度:{$}", nAngleValue); //port->m_pTableCtrl->MSGControl(port->m_pTableCtrl->m_pWnd, ECOM_MSG_RFMC_PARAMOUT, ECOM_MECHCOMP_PA_COLL_ANGLE, nAngleValue, ECOM_MSG_TYPE_SYNC_NO, ECOM_MSG_TARGETHANDLE_RFOC); //port->m_pTableCtrl->MSGControl(port->m_pTableCtrl->m_pWnd, ECOM_MSG_RFMC_PARAMOUT, ECOM_MECHCOMP_PA_COLL_ANGLE, nAngleValue, ECOM_MSG_TYPE_SYNC_NO, ECOM_MSG_TARGETHANDLE_RFHARDWARE); } } if (frameinfo->Data[1] == 1) { if (frameinfo->Data[1] == 1) { mLog::Info("recv C arm heart beat."); } if (frameinfo->Data[1] == 2) { int nPrePressLimitValue = frameinfo->Data[2]; int nTotalPressLimitValue = frameinfo->Data[3]; mLog::Info("nPrePressLimitValue={$},nTotalPressLimitValue={$}", nPrePressLimitValue, nTotalPressLimitValue); } if (frameinfo->Data[1] == 3) { int nPressType = frameinfo->Data[2]; int nReleaseType = frameinfo->Data[3]; mLog::Info("recv:press type={$},release type={$}", nPressType, nReleaseType); } if (frameinfo->Data[1] == 4) { //振栅模式 int nGridType = frameinfo->Data[2]; mLog::Info("Grid Type={$}", nGridType); } if (frameinfo->Data[1] == 5) { int nPressThickness = frameinfo->Data[2]; int nPressValue = frameinfo->Data[3]; mLog::Info("recv:nPressThickness={$},nPressValue={$}", nPressThickness, nPressValue); if (port->m_pTableCtrl->m_MAMMOMECHUnit.m_Mammo_Thickness->Update(nPressThickness)) { strData = frameinfo->Data[2]; port->m_pTableCtrl->FireNotify(AttrKey::MAMMO_THICKNESS, strData); } if (port->m_pTableCtrl->m_MAMMOMECHUnit.m_Mammo_PressureValue->Update(nPressValue)) { strData = frameinfo->Data[3]; port->m_pTableCtrl->FireNotify(AttrKey::MAMMO_PRESSVAL, strData); } } if (frameinfo->Data[1] == 6) { int nCollLong = frameinfo->Data[2] * 256 + frameinfo->Data[3]; int nCollCross = frameinfo->Data[4] * 256 + frameinfo->Data[5]; mLog::Info("recv:nCollLong={$},nCollCross={$}", nCollLong, nCollCross); //port->m_pTableCtrl->MSGControl(port->m_pTableCtrl->m_pWnd, ECOM_MSG_RFMC_PARAMOUT, ECOM_MECHCOMP_PA_COLLIMATOR, nCollLong*100 + nCollCross, ECOM_MSG_TYPE_SYNC_NO, ECOM_MSG_TARGETHANDLE_RFOC); //port->m_pTableCtrl->MSGControl(port->m_pTableCtrl->m_pWnd, ECOM_MSG_RFMC_PARAMOUT, ECOM_MECHCOMP_PA_COLLIMATOR, nCollLong*100 + nCollCross, ECOM_MSG_TYPE_SYNC_NO, ECOM_MSG_TARGETHANDLE_RFHARDWARE); } if (frameinfo->Data[1] == 7) { int nFilter = frameinfo->Data[2]; //port->m_pTableCtrl->m_nFilterSet = nFilter; mLog::Info("recv:Filter is {$},(1:Mo,2Rh)", nFilter); //port->m_pTableCtrl->MSGControl(port->m_pTableCtrl->m_pWnd, ECOM_MSG_RFMC_PARAMOUT, ECOM_MECHCOMP_PA_FILTER, port->m_pTableCtrl->m_nFilterSet, ECOM_MSG_TYPE_SYNC_NO, ECOM_MSG_TARGETHANDLE_RFOC); //port->m_pTableCtrl->MSGControl(port->m_pTableCtrl->m_pWnd, ECOM_MSG_RFMC_PARAMOUT, ECOM_MECHCOMP_PA_FILTER, port->m_pTableCtrl->m_nFilterSet, ECOM_MSG_TYPE_SYNC_NO, ECOM_MSG_TARGETHANDLE_RFHARDWARE); } if (frameinfo->Data[1] == 12) { if (frameinfo->Data[2] == 0) { mLog::Info("recv 无错误"); } if (frameinfo->Data[2] == 1) { mLog::Info("recv:压迫其初始化未到位 "); } if (frameinfo->Data[2] == 2) { mLog::Info("recv 压迫器上限位错误"); } if (frameinfo->Data[2] == 3) { mLog::Info("recv 过压错误"); } if (frameinfo->Data[2] == 4) { mLog::Info("recv 过流错误"); } if (frameinfo->Data[2] == 5) { mLog::Info("recv 自动释放未完成"); } if (frameinfo->Data[2] == 6) { mLog::Info("recv 限束器初始化成功"); } if (frameinfo->Data[2] == 7) { mLog::Info("recv 压迫释放完成"); } } if (frameinfo->Data[1] == 0x19) { int nPressBoardType = frameinfo->Data[2]; mLog::Info("recv:nPressBoardType={$}", nPressBoardType); } } #pragma endregion } else if (frameinfo->ID == 0x485)//振动栅节点 { #pragma region ID485 //0x485 故障报文 4 3 故障状态:0.正确 ;1.初始化错误; 振栅板发送给图像 if (frameinfo->Data[0] == 4) { if (frameinfo->Data[1] == 3) { int nStatus = frameinfo->Data[2]; mLog::Info("recv:Grid Status={$}", nStatus); } } #pragma endregion } } } return 0; } #endif // 1 //CAN---------------------------------------------------------------**************************************************** //----------------------------------------------------------------------------- // WDMAMMOCANDevice //----------------------------------------------------------------------------- string GetProcessDirectory() { printf("line= %d,%s\n", __LINE__, __FUNCTION__); string ret = ""; char szFilename[MAX_PATH] = { 0 }; DWORD res = GetModuleFileNameA(0, szFilename, MAX_PATH); if (res == 0) { return ret; } string fullpath = szFilename; string::size_type firstHit = fullpath.find_last_of('\\'); if (firstHit == string::npos || firstHit == 0) { return ret; } ret = fullpath.substr(0, firstHit);//kick last \ return ret; } #if 0 bool GetVersion(ResDataObject& config, string& version) { printf("line= %d,%s\n", __LINE__, __FUNCTION__); try { string procdir = ""; char filename[MAX_PATH + 1] = { 0 }; procdir = GetProcessDirectory(); if (procdir.empty()) { if (GetModuleFileName(nullptr, filename, MAX_PATH) == 0) { return false; } } else { string oemdrvpath = (const char*)config["oemdriver"]; { string keystr = "%ROOT%"; string::size_type pos = 0; string::size_type keylen = keystr.size(); string::size_type replen = procdir.size(); while ((pos = oemdrvpath.find(keystr, pos)) != string::npos) { oemdrvpath.replace(pos, keylen, procdir); pos += replen; } } strncpy_s(filename, oemdrvpath.c_str(), MAX_PATH); } ////mLog::Info("get Generator path:{$}\n", filename); DWORD dummy; DWORD size = GetFileVersionInfoSize(filename, &dummy); if (size == 0) { return false; } auto data = make_unique(size); if (!GetFileVersionInfo(filename, 0, size, &data[0])) { return false; } UINT32 len = 0; VS_FIXEDFILEINFO* fixed_file_info = 0; if (!VerQueryValue(&data[0], TEXT("\\"), reinterpret_cast(&fixed_file_info), &len)) { return false; } // version 为版本号 UINT32 vBitNumber = 0; vBitNumber = HIWORD(fixed_file_info->dwProductVersionMS); version += to_string(vBitNumber); version += "."; vBitNumber = LOWORD(fixed_file_info->dwProductVersionMS); version += to_string(vBitNumber); version += "."; vBitNumber = HIWORD(fixed_file_info->dwProductVersionLS); version += to_string(vBitNumber); version += "."; vBitNumber = LOWORD(fixed_file_info->dwProductVersionLS); version += to_string(vBitNumber); return true; } catch (...) { printf("get Generator Mould version failed"); //mLog::Error("get Generator Mould version failed\n"); } return false; } #endif // 0 nsMech::WDMAMMOCANDevice::WDMAMMOCANDevice(std::shared_ptr center, string configfile /*= ""*/):super(center) { printf("line= %d,%s\n", __LINE__, __FUNCTION__); ResDataObject Conftemp; //if (!configfile.empty()) //{ // Conftemp.loadFile(configfile.c_str()); // m_GenConfig = Conftemp["CONFIGURATION"]; // string version; // if (GetVersion(m_GenConfig, version)) // printf("**************version:%s...\n",version.c_str()); // else // printf("**************version 0 0 0 0 ."); //} //else //{ // printf("\n===============log begin : DEMO version:3.0.0.1 ===================\n"); //} } nsMech::WDMAMMOCANDevice::~WDMAMMOCANDevice() { printf("line= %d,%s\n", __LINE__, __FUNCTION__); ////mLog::Info("\n===============log end ===================\n"); } std::string WDMAMMOCANDevice::GetGUID() const { printf("\n===============GetGUID : %s ===================\n", MechanicalUnitType); return MechanicalUnitType; } void nsMech::WDMAMMOCANDevice::FireNotify(std::string key, std::string content) { printf("line= %d,%s\n", __LINE__, __FUNCTION__); EventCenter->OnNotify(1, key, content); } bool WDMAMMOCANDevice::Prepare() { printf("line= %d,%s\n", __LINE__, __FUNCTION__); Register(); return true; } void WDMAMMOCANDevice::Register() { printf("line= %d,%s\n", __LINE__, __FUNCTION__); auto Disp = Dispatch.Lock().As(); superMech::RegisterExamInfo(Disp); superMech::RegisterPostionNumber(Disp); superMech::RegisterGridControl(Disp); superMech::RegisterMotionControl(Disp); superMech::RegisterTOMOControl(Disp); superMech::RegisterMammoInfo(Disp); } RET_STATUS WDMAMMOCANDevice::GetTomoResults(ResDataObject& resultAngle, ResDataObject& resultHeight) { printf("line= %d,%s\n", __LINE__, __FUNCTION__); RET_STATUS ret = RET_STATUS::RET_FAILED; return ret; } RET_STATUS WDMAMMOCANDevice::SetGrid(unsigned int GridType) { printf("line= %d,%s\n", __LINE__, __FUNCTION__); RET_STATUS ret = RET_STATUS::RET_FAILED; //ysj++v1的逻辑是首先获取,如果不同,再set,相同则不做动作。 return ret; } RET_STATUS WDMAMMOCANDevice::SetAutoTracking(unsigned int nAutoTracking) { printf("line= %d,%s\n", __LINE__, __FUNCTION__); RET_STATUS ret = RET_STATUS::RET_FAILED; return ret; } //-------------------------------------------------------------------------------------------// nsMech::WDMAMMOCANDriver::WDMAMMOCANDriver() { printf("line= %d,%s\n", __LINE__, __FUNCTION__); m_bDemoMode = false; m_bDemoConnected = false; m_bDemoInitDataFlag = false; m_pDriGenDev = nullptr; m_pCAN = nullptr; m_pAttribute.reset(new ResDataObject()); m_pDescription.reset(new ResDataObject()); } nsMech::WDMAMMOCANDriver::~WDMAMMOCANDriver() { printf("line= %d,%s\n", __LINE__, __FUNCTION__); } auto nsMech::WDMAMMOCANDriver::CreateDevice(int index) -> std::unique_ptr { printf("line= %d,%s\n", __LINE__, __FUNCTION__); ////mLog::Info("Enter CreateDevice, index={$}", index); printf("**************************************************enter createdevice,config=%s, index=%d************************************************************\n", m_ConfigFileName.c_str(), index); if (index == 0) { m_pDriGenDev = new WDMAMMOCANDevice(EventCenter, m_ConfigFileName); auto dev = std::unique_ptr(new IODevice(m_pDriGenDev)); return dev; } //mLog::Error("unknown index"); unique_ptr dev; return dev; } void nsMech::WDMAMMOCANDriver::FireNotify(int code, std::string key, std::string content) { printf("line= %d,%s\n", __LINE__, __FUNCTION__); EventCenter->OnNotify(code, key, content); } Log4CPP::Logger* mLog::gLogger = nullptr; void nsMech::WDMAMMOCANDriver::Prepare() { printf("line= %d,%s\n", __LINE__, __FUNCTION__); string strLogPath = GetProcessDirectory() + R"(\OEMDrivers\Mechanical\Conf\Log4CPP.Config.MECH.xml)"; Log4CPP::ThreadContext::Map::Set("LogFileName", "MECH.WDMAMMOCAN"); auto rc = Log4CPP::LogManager::LoadConfigFile(strLogPath.c_str()); mLog::gLogger = Log4CPP::LogManager::GetLogger("MECH.WDMAMMOCAN"); ResDataObject r_config; if (r_config.loadFile(m_ConfigFileName.c_str())) { m_bDemoMode = (atoi)(((string)r_config["CONFIGURATION"]["IsDemo"]).c_str()); ResDataObject Connection = r_config["CONFIGURATION"]["connections"][0]; //if ((string)Connection["type"] == "COM") //{ // m_SCFDllName = COM_SCFDllName; //} //else //{ // m_SCFDllName = TCP_SCFDllName; //} } } bool WDMAMMOCANDriver::ResetCommunication() { if (m_pCAN != NULL) { delete m_pCAN; m_pCAN = NULL; } m_pCAN = new CCANPort; //m_pCAN->SetTableCtrl(this); if (!m_pCAN->CAN_Open()) { //this->m_pLog->WriteLog("CAN open failed.", LOG_INFORMATION, LOG_DEBUG, true); return false; } if (!m_pCAN->CAN_Init(0, 0, 0xFFFFFFFF, 1, 0, 0x04, 0x1C)) { //this->m_pLog->WriteLog("CAN init failed.", LOG_INFORMATION, LOG_DEBUG, true); return false; } if (!m_pCAN->CAN_Start())//启动 { //this->m_pLog->WriteLog("CAN start failed.", LOG_INFORMATION, LOG_DEBUG, true); return false; } if (!m_pCAN->m_bCanStart) { //this->m_pLog->WriteLog("CAN start failed 2.", LOG_INFORMATION, LOG_DEBUG, true); return false; } //this->m_pLog->WriteLog("CAN start success.", LOG_INFORMATION, LOG_DEBUG, true); return true; } int nsMech::WDMAMMOCANDriver::Connect() { printf("line= %d,%s\n", __LINE__, __FUNCTION__); if (m_bDemoMode) { m_bDemoConnected = true; return SCF_ERR::SCF_SUCCEED; } ResDataObject r_config; if (!r_config.loadFile(m_ConfigFileName.c_str())) return SCF_ERR::SCF_OPEN_FAILED; //ResDataObject Connection = r_config["CONFIGURATION"]["connections"][0]; //printf("connections:%s \n", Connection.encode()); //mLog::Info("connections:{$} \n", Connection.encode()); //auto erCode = m_SCF.Connect(Connection.encode(), &nsGEN::CPIDriver::callbackPackageProcess, SCF_PACKET_TRANSFER, 3000); //if (erCode != SCF_ERR::SCF_SUCCEED) // return erCode; //auto rc = super::Connect(); //if (!rc) // return 0; bool result = ResetCommunication();//open CAN if (result) { return SCF_ERR::SCF_SUCCEED; } return SCF_ERR::SCF_FAILED; } void nsMech::WDMAMMOCANDriver::Disconnect() { printf("line= %d,%s\n", __LINE__, __FUNCTION__); super::Disconnect(); //m_SCF.Disconnect(); m_bDemoConnected = false; } bool nsMech::WDMAMMOCANDriver::isConnected() const { printf("line= %d,%s\n", __LINE__, __FUNCTION__); return m_bDemoConnected; } std::string nsMech::WDMAMMOCANDriver::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; } bool nsMech::WDMAMMOCANDriver::GetDeviceConfig(std::string& Cfg) { printf("line= %d,%s\n", __LINE__, __FUNCTION__); Cfg = m_DeviceConfigSend.encode(); printf("GetDeviceConfig over , %s", Cfg.c_str()); return true; } bool nsMech::WDMAMMOCANDriver::SetDeviceConfig(std::string Cfg) { printf("line= %d,%s\n", __LINE__, __FUNCTION__); ////mLog::Info("--Func-- SetDeviceConfig {$}\n", Cfg.c_str()); 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::WDMAMMOCANDriver::SaveConfigFile(bool bSendNotify) { printf("line= %d,%s\n", __LINE__, __FUNCTION__); m_ConfigAll["CONFIGURATION"] = m_Configurations; bool bRt = m_ConfigAll.SaveFile(m_ConfigFileName.c_str()); ////mLog::Info("SaveConfigFile over {$}", bRt); return true; } bool nsMech::WDMAMMOCANDriver::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::WDMAMMOCANDriver::SetDeviceConfigValue(ResDataObject& config, const char* pInnerKey, int nPathID, const char* szValue) { printf("line= %d,%s\n", __LINE__, __FUNCTION__); 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; } std::string nsMech::WDMAMMOCANDriver::GetResource() { printf("line= %d,%s\n", __LINE__, __FUNCTION__); 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::WDMAMMOCANDriver::DeviceProbe() { printf("line= %d,%s\n", __LINE__, __FUNCTION__); 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; } void nsMech::WDMAMMOCANDriver::Dequeue(const char* Packet, DWORD Length) { printf("line= %d,%s\n", __LINE__, __FUNCTION__); } PACKET_RET nsMech::WDMAMMOCANDriver::callbackPackageProcess(const char* RecData, DWORD nLength, DWORD& PacketLength) { printf("line= %d,%s\n", __LINE__, __FUNCTION__); return PACKET_NOPACKET; } static nsMech::WDMAMMOCANDriver gIODriver; extern "C" DIOS::Dev::IODriver * __cdecl GetIODriver() // 返回静态对象的引用, 调用者不能删除 ! { return &gIODriver; } extern "C" DIOS::Dev::IODriver * __cdecl CreateIODriver() // 返回新对象, 调用者必须自行删除此对象 ! { return new nsMech::WDMAMMOCANDriver(); }