From eb72df621062cb0fa263d89c0674058d053dd1a3 Mon Sep 17 00:00:00 2001 From: qushuailong Date: Tue, 19 Apr 2022 21:19:38 +0800 Subject: [PATCH] =?UTF-8?q?VisionController=20Version1.0:=201=20=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0Tcp=E6=9C=8D=E5=8A=A1=E5=99=A8=EF=BC=8C=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E4=B8=80=E4=B8=AATcp=E5=AE=A2=E6=88=B7=E7=AB=AF?= =?UTF-8?q?=E8=BF=9E=E6=8E=A5=202=20=E8=83=BD=E5=A4=9F=E6=8E=A5=E6=94=B6?= =?UTF-8?q?=E5=AE=A2=E6=88=B7=E7=AB=AF=E5=8F=91=E9=80=81=E7=9A=84=E4=BF=A1?= =?UTF-8?q?=E6=81=AF=E6=8E=A7=E5=88=B6IO=E5=8F=A3=E8=BE=93=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/tcpServer.json | 6 + runner17/MvIOInterfaceBox.dll | Bin 0 -> 54272 bytes runner17/MvSerial.dll | Bin 0 -> 65536 bytes src/IOController/IOController.cpp | 230 ++++++++++++++ src/IOController/IOController.h | 51 ++++ src/IOController/NewSdkInc/MvErrorDefine.h | 77 +++++ src/IOController/NewSdkInc/MvIOInterfaceBox.h | 231 ++++++++++++++ .../NewSdkInc/MvIOInterfaceBoxDefine.h | 288 ++++++++++++++++++ src/TcpServer/TcpServer.cpp | 98 ++++++ src/TcpServer/TcpServer.h | 72 +++++ src/VisionController/VisionController.cpp | 231 ++++++++++++++ src/VisionController/VisionController.h | 37 +++ src/VisionController/main.cpp | 10 + tpvs17/IOController/IOController.vcxproj | 115 +++++++ .../IOController/IOController.vcxproj.filters | 50 +++ tpvs17/IOController/IOController.vcxproj.user | 12 + tpvs17/TcpServer/TcpServer.vcxproj | 117 +++++++ tpvs17/TcpServer/TcpServer.vcxproj.filters | 38 +++ tpvs17/TcpServer/TcpServer.vcxproj.user | 12 + tpvs17/VisionController.sln | 37 +++ tpvs17/VisionController/VisionController.qrc | 4 + tpvs17/VisionController/VisionController.ui | 214 +++++++++++++ .../VisionController/VisionController.vcxproj | 140 +++++++++ .../VisionController.vcxproj.filters | 55 ++++ .../VisionController.vcxproj.user | 14 + tpvs17/x64/Release/MvIOInterfaceBox.lib | Bin 0 -> 8528 bytes 26 files changed, 2139 insertions(+) create mode 100644 config/tcpServer.json create mode 100644 runner17/MvIOInterfaceBox.dll create mode 100644 runner17/MvSerial.dll create mode 100644 src/IOController/IOController.cpp create mode 100644 src/IOController/IOController.h create mode 100644 src/IOController/NewSdkInc/MvErrorDefine.h create mode 100644 src/IOController/NewSdkInc/MvIOInterfaceBox.h create mode 100644 src/IOController/NewSdkInc/MvIOInterfaceBoxDefine.h create mode 100644 src/TcpServer/TcpServer.cpp create mode 100644 src/TcpServer/TcpServer.h create mode 100644 src/VisionController/VisionController.cpp create mode 100644 src/VisionController/VisionController.h create mode 100644 src/VisionController/main.cpp create mode 100644 tpvs17/IOController/IOController.vcxproj create mode 100644 tpvs17/IOController/IOController.vcxproj.filters create mode 100644 tpvs17/IOController/IOController.vcxproj.user create mode 100644 tpvs17/TcpServer/TcpServer.vcxproj create mode 100644 tpvs17/TcpServer/TcpServer.vcxproj.filters create mode 100644 tpvs17/TcpServer/TcpServer.vcxproj.user create mode 100644 tpvs17/VisionController.sln create mode 100644 tpvs17/VisionController/VisionController.qrc create mode 100644 tpvs17/VisionController/VisionController.ui create mode 100644 tpvs17/VisionController/VisionController.vcxproj create mode 100644 tpvs17/VisionController/VisionController.vcxproj.filters create mode 100644 tpvs17/VisionController/VisionController.vcxproj.user create mode 100644 tpvs17/x64/Release/MvIOInterfaceBox.lib diff --git a/config/tcpServer.json b/config/tcpServer.json new file mode 100644 index 0000000..ccc2e27 --- /dev/null +++ b/config/tcpServer.json @@ -0,0 +1,6 @@ +{ + "address": { + "IP": "127.0.0.1", + "Port": "9900" + } +} diff --git a/runner17/MvIOInterfaceBox.dll b/runner17/MvIOInterfaceBox.dll new file mode 100644 index 0000000000000000000000000000000000000000..63d1e93374931b913be20982d2563b85c3d5695d GIT binary patch literal 54272 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 DPq-2m literal 0 HcmV?d00001 diff --git a/runner17/MvSerial.dll b/runner17/MvSerial.dll new file mode 100644 index 0000000000000000000000000000000000000000..678152d59264e3c358a2a5fb0757f00ce6b0f6c8 GIT binary patch literal 65536 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 a#zts1%tM{Y2049J)QSx7p8H#}!2bo1xNVpK literal 0 HcmV?d00001 diff --git a/src/IOController/IOController.cpp b/src/IOController/IOController.cpp new file mode 100644 index 0000000..a744cc4 --- /dev/null +++ b/src/IOController/IOController.cpp @@ -0,0 +1,230 @@ +#include "IOController.h" + +IOController::IOController() +{ +} +IOController::~IOController() +{ +} +bool IOController::controllerInitialization(unsigned int serialNum) +{ + return controlCom(serialNum, 1); +} +bool IOController::controlCom(unsigned int IONum, unsigned int state) +{ + std::string comName; + switch (IONum) + { + case 1: + comName = "Com1"; + break; + case 2: + comName = "Com2"; + break; + case 3: + comName = "Com3"; + break; + case 4: + comName = "Com4"; + break; + case 5: + comName = "Com5"; + break; + case 6: + comName = "Com6"; + break; + case 7: + comName = "Com7"; + break; + case 8: + comName = "Com8"; + break; + default: + break; + } + m_comName = comName; + m_mpComsState[comName] = false; + void* handle; + int nRet = MV_IO_CreateHandle(&handle); + if (nRet != MV_OK) + { + //throw nRet; + return false; + } + else + { + m_mpComsHandle[comName] = handle; + } + if (state == 1) + { + if (!connectCom(m_mpComsHandle[comName], comName)) + { + return false; + } + } + else if (state == 0) + { + if (!closeCom(m_mpComsHandle[comName], comName)) + { + return false; + } + } + return true; +} +bool IOController::connectCom(void* handle, std::string comName) +{ + MV_IO_SERIAL stSerial; + memset(&stSerial, 0, sizeof(MV_IO_SERIAL)); + strcpy(stSerial.strComName, comName.c_str()); + //m_mpStIOSerial[comName] = stSerial; + int nRet = MV_IO_Open(m_mpComsHandle[comName], &stSerial); + if (nRet != MV_OK) + { + //throw nRet; + return false; + } + m_mpComsState[comName] = true; + return true; +} +bool IOController::closeCom(void* handle, std::string comName) +{ + return true; +} + +bool IOController::controlPort(unsigned int portNum, unsigned int state) +{ + MV_IO_PORT_NUMBER stPortNumber; + switch(portNum) + { + case 1: + stPortNumber = MV_IO_PORT_1; + break; + case2: + stPortNumber = MV_IO_PORT_2; + break; + case 3: + stPortNumber = MV_IO_PORT_3; + break; + case 4: + stPortNumber = MV_IO_PORT_4; + break; + case 5: + stPortNumber = MV_IO_PORT_5; + break; + case 6: + stPortNumber = MV_IO_PORT_6; + break; + case 7: + stPortNumber = MV_IO_PORT_7; + break; + case 8: + stPortNumber = MV_IO_PORT_8; + break; + default: + break; + } + if (state == 1) + { + if (!openPort(m_comName, stPortNumber)) + { + return false; + } + } + else if (state == 0) + { + if (!closePort(m_comName, stPortNumber)) + { + return false; + } + } + return true; +} + +bool IOController::openPort(std::string comName, MV_IO_PORT_NUMBER portNum) +{ + MV_IO_SET_OUTPUT stOutput; + memset(&stOutput, 0, sizeof(MV_IO_SET_OUTPUT)); + stOutput.nPort = portNum; + stOutput.nType = MV_IO_PATTERN_SINGLE; + stOutput.nDurationTime = 0; + stOutput.nValidLevel = 1; //¸ßµçƽ + if ((m_mpComsHandle.find(comName) == m_mpComsHandle.end())|| (!m_mpComsState[comName])) + { + return false; + } + int nRet = MV_IO_SetOutput(m_mpComsHandle[comName], &stOutput); + if (nRet != MV_OK) + { + //throw nRet; + return false; + } + return true; +} + +bool IOController::closePort(std::string comName, MV_IO_PORT_NUMBER portNum) +{ + MV_IO_SET_OUTPUT stOutput; + memset(&stOutput, 0, sizeof(MV_IO_SET_OUTPUT)); + stOutput.nPort = portNum; + stOutput.nType = MV_IO_PATTERN_SINGLE; + // stOutput.nDurationTime = 3000; + stOutput.nValidLevel = 0; //µÍµçƽ + if ((m_mpComsHandle.find(comName) == m_mpComsHandle.end()) || (!m_mpComsState[comName])) + { + return false; + } + int nRet = MV_IO_SetOutput(m_mpComsHandle[comName], &stOutput); + if (nRet != MV_OK) + { + //throw nRet; + return false; + } + return true; +} + +bool IOController::getPortState(unsigned int portNum, unsigned int& state) +{ + MV_IO_PORT_NUMBER stPortNumber; + switch (portNum) + { + case 1: + stPortNumber = MV_IO_PORT_1; + break; + case2: + stPortNumber = MV_IO_PORT_2; + break; + case 3: + stPortNumber = MV_IO_PORT_3; + break; + case 4: + stPortNumber = MV_IO_PORT_4; + break; + case 5: + stPortNumber = MV_IO_PORT_5; + break; + case 6: + stPortNumber = MV_IO_PORT_6; + break; + case 7: + stPortNumber = MV_IO_PORT_7; + break; + case 8: + stPortNumber = MV_IO_PORT_8; + break; + default: + break; + } + if (m_mpComsHandle.find(m_comName) == m_mpComsHandle.end()) + { + return false; + } + MV_IO_SET_OUTPUT stSetOutput; + int nRet = MV_IO_GetPortOutputParam(m_mpComsHandle[m_comName], &stSetOutput); + if (nRet != MV_OK) + { + //throw nRet; + return false; + } + state = stSetOutput.nValidLevel; + return true; +} \ No newline at end of file diff --git a/src/IOController/IOController.h b/src/IOController/IOController.h new file mode 100644 index 0000000..9281c34 --- /dev/null +++ b/src/IOController/IOController.h @@ -0,0 +1,51 @@ +#ifndef _H_IOController_H_ +#define _H_IOController_H_ + +//#define MAX_DEVICE 6 + +#include + +#include +#include +#include +#include + +#include "MvIOInterfaceBox.h" +#include "MvIOInterfaceBoxDefine.h " +#include "MvErrorDefine.h" + +#ifndef BUILD_STATIC +# if defined(IOController_LIB) +# define IOController_EXPORT Q_DECL_EXPORT +# else +# define IOController_EXPORT Q_DECL_IMPORT +# endif +#else +# define IOController_EXPORT +#endif + +class IOController_EXPORT IOController +{ +public: + IOController(); + ~IOController(); + + bool controlCom(unsigned int serialNumber, unsigned int state); + bool controlPort(unsigned int intportNumber, unsigned int state); + bool controllerInitialization(unsigned int serialNum); + bool getPortState(unsigned int portNum, unsigned int& validState); +private: + bool connectCom(void* handle, std::string comName); + bool closeCom(void* handle, std::string comName); + bool openPort(std::string comName, MV_IO_PORT_NUMBER portNum); + bool closePort(std::string comName, MV_IO_PORT_NUMBER portNum); + + //void* m_handleList[MAX_DEVICE]; // ·½±ãÁ¬½Ó¶à¸öÉ豸 + QMap m_mpComsHandle; + //QMap m_mpStIOSerial; + QMap m_mpComsState; + std::string m_comName; +}; + +#endif // !_H_IOController_H_ + diff --git a/src/IOController/NewSdkInc/MvErrorDefine.h b/src/IOController/NewSdkInc/MvErrorDefine.h new file mode 100644 index 0000000..e5bb832 --- /dev/null +++ b/src/IOController/NewSdkInc/MvErrorDefine.h @@ -0,0 +1,77 @@ +/*************************************************************************************************** +* +* °æÈ¨ÐÅÏ¢£º°æÈ¨ËùÓÐ (c) 2015, º¼Öݺ£¿µÍþÊÓÊý×Ö¼¼Êõ¹É·ÝÓÐÏÞ¹«Ë¾, ±£ÁôËùÓÐȨÀû +* +* ÎļþÃû³Æ£ºMvErrorDefine.h +* Õª Òª£º´íÎóÂ붨Òå +* +* µ±Ç°°æ±¾£º1.0.0.0 +* ×÷ Õߣº³Â׿ÎÄ +* ÈÕ ÆÚ£º2015-01-28 +* ±¸ ×¢£ºÐ½¨ +***************************************************************************************************/ + +#ifndef _MV_ERROR_DEFINE_H_ +#define _MV_ERROR_DEFINE_H_ + +//ÕýÈ·Â붨Òå +#define MV_OK 0x00000000 ///< ³É¹¦£¬ÎÞ´íÎó + +//ͨÓôíÎóÂ붨Òå:·¶Î§0x80000000-0x800000FF +#define MV_E_HANDLE 0x80000000 ///< ´íÎó»òÎÞЧµÄ¾ä±ú +#define MV_E_SUPPORT 0x80000001 ///< ²»Ö§³ÖµÄ¹¦ÄÜ +#define MV_E_BUFOVER 0x80000002 ///< »º´æÒÑÂú +#define MV_E_CALLORDER 0x80000003 ///< º¯Êýµ÷ÓÃ˳Ðò´íÎó +#define MV_E_PARAMETER 0x80000004 ///< ´íÎóµÄ²ÎÊý +#define MV_E_RESOURCE 0x80000006 ///< ×ÊÔ´ÉêÇëʧ°Ü +#define MV_E_NODATA 0x80000007 ///< ÎÞÊý¾Ý +#define MV_E_PRECONDITION 0x80000008 ///< ǰÖÃÌõ¼þÓÐÎ󣬻òÔËÐл·¾³ÒÑ·¢Éú±ä»¯ +#define MV_E_VERSION 0x80000009 ///< °æ±¾²»Æ¥Åä +#define MV_E_NOENOUGH_BUF 0x8000000A ///< ´«ÈëµÄÄÚ´æ¿Õ¼ä²»×ã +#define MV_E_MATCH 0x8000000B ///< Æ¥Åä´íÎó£¨Èç·µ»ØµÄÊý¾Ý¸ñʽ´íÎó£© +#define MV_E_UPDATING 0x8000000C ///< ´¦ÓÚÉý¼¶×´Ì¬ +#define MV_E_UNKNOW 0x800000FF ///< δ֪µÄ´íÎó + +//ÍøÂçÏà¹Ø´íÎó: 0x80000100-0x800001FF +#define MV_E_CREAT_SOCKET 0x80000100 // ´´½¨Socketʧ°Ü +#define MV_E_BIND_SOCKET 0x80000101 // °ó¶¨Socketʧ°Ü +#define MV_E_CONNECT_SOCKET 0x80000102 // Á¬½ÓSocketʧ°Ü +#define MV_E_GET_HOSTNAME 0x80000103 // »ñÈ¡Hostnameʧ°Ü +#define MV_E_NET_WRITE 0x80000104 // ÍøÂçдÊý¾Ýʧ°Ü +#define MV_E_NET_READ 0x80000105 // ÍøÂç¶ÁÊý¾Ýʧ°Ü +#define MV_E_NET_SELECT 0x80000106 //ÍøÂçÁ¬½Óʧ°Ü +#define MV_E_NET_TIMEOUT 0x80000107 // ÍøÂ糬ʱ + + +//GigE_STATUS¶ÔÓ¦µÄ´íÎóÂë:·¶Î§0x80000200-0x800002FF +#define MV_E_NOT_IMPLEMENTED 0x80000200 ///< ÃüÁî²»±»É豸֧³Ö +#define MV_E_INVALID_ADDRESS 0x80000201 ///< ·ÃÎʵÄÄ¿±êµØÖ·²»´æÔÚ +#define MV_E_WRITE_PROTECT 0x80000202 ///< Ä¿±êµØÖ·²»¿Éд +#define MV_E_ACCESS_DENIED 0x80000203 ///< ·ÃÎÊÎÞȨÏÞ +#define MV_E_BUSY 0x80000204 ///< É豸棬»òÍøÂç¶Ï¿ª +#define MV_E_PACKET 0x80000205 ///< ÍøÂç°üÊý¾Ý´íÎó +#define MV_E_NETER 0x80000206 ///< ÍøÂçÏà¹Ø´íÎó + + +//USB_STATUS¶ÔÓ¦µÄ´íÎóÂë:·¶Î§0x80000300-0x800003FF +#define MV_E_USB_READ 0x80000300 ///< ¶Áusb³ö´í +#define MV_E_USB_WRITE 0x80000301 ///< дusb³ö´í +#define MV_E_USB_DEVICE 0x80000302 ///< É豸Òì³£ +#define MV_E_USB_GENICAM 0x80000303 ///< GenICamÏà¹Ø´íÎó +#define MV_E_USB_UNKNOW 0x800003FF ///< USBδ֪µÄ´íÎó + +//Éý¼¶Ê±¶ÔÓ¦µÄ´íÎóÂë:·¶Î§0x80000400-0x800004FF +#define MV_E_UPG_FILE_MISMATCH 0x80000400 ///< Éý¼¶¹Ì¼þ²»Æ¥Åä +#define MV_E_UPG_LANGUSGE_MISMATCH 0x80000401 ///< Éý¼¶¹Ì¼þÓïÑÔ²»Æ¥Åä +#define MV_E_UPG_CONFLICT 0x80000402 ///< Éý¼¶³åÍ»£¨É豸ÒѾ­ÔÚÉý¼¶ÁËÔÙ´ÎÇëÇóÉý¼¶¼´·µ»Ø´Ë´íÎó£© +#define MV_E_UPG_INNER_ERR 0x80000403 ///< Éý¼¶Ê±Ïà»úÄÚ²¿³öÏÖ´íÎó +#define MV_E_UPG_UNKNOW 0x800004FF ///< Éý¼¶Ê±Î´Öª´íÎó + +// YModemЭÒé´íÎóÂë + +#define MV_E_YMODEM_C 0x80000500 ///< δÊÕµ½¿ªÆô´«ÊäÃüÁî +#define MV_E_YMODEM_ACK 0x80000501 ///< δÊÕµ½½ÓÊÕÈ·ÈÏ»ØÓ¦ +#define MV_E_YMODEM_NAK 0x80000502 ///< δÊÕµ½½áÊøÈ·ÈÏ»ØÓ¦ + + +#endif //_MV_ERROR_DEFINE_H_ diff --git a/src/IOController/NewSdkInc/MvIOInterfaceBox.h b/src/IOController/NewSdkInc/MvIOInterfaceBox.h new file mode 100644 index 0000000..e60d6f0 --- /dev/null +++ b/src/IOController/NewSdkInc/MvIOInterfaceBox.h @@ -0,0 +1,231 @@ +/*************************************************************************************************** +* +* ÎļþÃû³Æ£ºMvIOInterfaceBox.h +* Õª Òª£º¿ØÖÆÆ÷³£¼ûÍ·Îļþ +* +* µ±Ç°°æ±¾£º1.2.0 +* ±¸ ×¢£ºÐ½¨ +***************************************************************************************************/ + + +/*************************************************************************************************** +* +* File name: MvIOInterfaceBox.h +* Abstract: Common definition header file of Visual controller +* +* Current Version:1.2.0 +* Remarks£º newly build +***************************************************************************************************/ + +#ifndef MV_IO_INTERFACEBOX_CONTROL_H__ +#define MV_IO_INTERFACEBOX_CONTROL_H__ + +#include "MvIOInterfaceBoxDefine.h" + + +/** +* @brief ch:¶¯Ì¬¿âµ¼Èëµ¼³ö¶¨Òå | en:Dynamic library import and export definition +*/ +#ifndef MV_IO_CONTROL_API + + #ifdef WIN32 + #if defined(MVIOINTERFACEBOXCONTROL_EXPORTS) + #define MV_IO_CONTROL_API __declspec(dllexport) + #else + #define MV_IO_CONTROL_API __declspec(dllimport) + #endif + #else + #ifndef __stdcall + #define __stdcall + #endif + + #ifndef MV_IO_CONTROL_API + #define MV_IO_CONTROL_API + #endif + #endif + +#endif + +#ifndef IN + #define IN +#endif + +#ifndef OUT + #define OUT +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** @fn MV_IO_CreateHandle + * @brief ch:´´½¨¾ä±ú | en:Create handle + * @param handle [IN][OUT] ch:É豸¾ä±ú | en:Device handle + * @return ch:³É¹¦£¬·µ»ØMV_OK(0);ʧ°Ü£¬·µ»Ø´íÎóÂë | en:Success,return MV_OK(0);Failed, return error code + * @±¸×¢£º ch:×î¶à¿É´´½¨32¸ö´®¿Ú¾ä±ú | en:A maximum of 32 serial port handles can be created + */ +MV_IO_CONTROL_API int __stdcall MV_IO_CreateHandle(OUT void ** handle); + +/** @fn MV_IO_DestroyHandle + * @brief ch:Ïú»Ù¾ä±ú | en:Destroy handle + * @param handle [IN] ch:É豸¾ä±ú | en:Device handle + * @return ch:³É¹¦£¬·µ»ØMV_OK(0);ʧ°Ü£¬·µ»Ø´íÎóÂë | en:Success,return MV_OK(0);Failed, return error code + */ +MV_IO_CONTROL_API int __stdcall MV_IO_DestroyHandle(IN void * handle); + +/** @fn MV_IO_GetSDKVersion + * @brief ch:»ñÈ¡SDK°æ±¾ºÅ | en:Get SDK version + * @return ch:³É¹¦£¬·µ»ØMV_OK(0);ʧ°Ü£¬·µ»Ø´íÎóÂë | en:Success,return MV_OK(0);Failed, return error code + */ +MV_IO_CONTROL_API int __stdcall MV_IO_GetSDKVersion(OUT MV_IO_VERSION * pstVersion); + +/** @fn MV_IO_Open + * @brief ch:´ò¿ª´®¿Ú | en:Open serial port + * @param handle [IN] ch:É豸¾ä±ú | en: + * @param pstSerial [IN] ch:´®¿Ú²ÎÊý£¬ÏêϸÇë²Î¼ûMV_IO_SERIAL½á¹¹ÌåÒÔ¼°Ïà¹ØÃ¶¾Ù¶¨Òå | en:Serial paranm, reference MV_IO_SERIAL + * @return ch:³É¹¦£¬·µ»ØMV_OK(0);ʧ°Ü£¬·µ»Ø´íÎóÂë | en:Success,return MV_OK(0);Failed, return error code + */ +MV_IO_CONTROL_API int __stdcall MV_IO_Open(IN void* handle, IN MV_IO_SERIAL * pstSerial); + +/** @fn MV_IO_Close + * @brief ch:¹Ø±Õ´®¿Ú | en:Close serial + * @param handle [IN] ch:É豸¾ä±ú | en:Device handle + * @return ch:³É¹¦£¬·µ»ØMV_OK(0);ʧ°Ü£¬·µ»Ø´íÎóÂë | en:Success,return MV_OK(0);Failed, return error code + */ +MV_IO_CONTROL_API int __stdcall MV_IO_Close(IN void* handle); + +/** @fn MV_IO_GetFirmwareVersion + * @brief ch:»ñÈ¡¹Ì¼þ°æ±¾ºÅ | en:Get firmware version + * @param handle [IN] ch:É豸¾ä±ú | en:Device handle + * @param pstVersion [IN] ch:¹Ì¼þ°æ±¾²ÎÊý£¬ÏêϸÇë²Î¼ûMV_IO_VERSION½á¹¹ÌåÒÔ¼°Ïà¹ØÃ¶¾Ù¶¨Òå | en:param,reference MV_IO_VERSION + * @return ch:³É¹¦£¬·µ»ØMV_OK(0);ʧ°Ü£¬·µ»Ø´íÎóÂë | en:Success,return MV_OK(0);Failed, return error code + */ +MV_IO_CONTROL_API int __stdcall MV_IO_GetFirmwareVersion(IN void* handle, OUT MV_IO_VERSION * pstVersion); + +/** @fn MV_IO_LocalUpgrade + * @brief ch:¹Ì¼þÉý¼¶ | en:Local upgrade + * @param handle [IN] ch:É豸¾ä±ú | en:Device handle + * @param pstLocalUpgrade [IN][OUT] ch:Éý¼¶²ÎÊý£¬Ïêϸ²Î¼ûMV_IO_LOCAL_UPGRADE½á¹¹ÌåÒÔ¼°Ïà¹Ø¶¨Òå | en:Upgrade param,reference MV_IO_LOCAL_UPGRADE + * @return ch:³É¹¦£¬·µ»ØMV_OK(0);ʧ°Ü£¬·µ»Ø´íÎóÂë | en:Success,return MV_OK(0);Failed, return error code + */ +MV_IO_CONTROL_API int __stdcall MV_IO_LocalUpgrade(IN void* handle, IN unsigned char* pData, IN unsigned int nLen, IN OUT MV_IO_LOCAL_UPGRADE * pstLocalUpgrade); + +/** @fn MV_IO_SetOutput + * @brief ch:Êä³ö²ÎÊýÉèÖà | en:Output param setting + * @param handle [IN] ch:É豸¾ä±ú | en:Device handle + * @param pstOutput [IN] ch:Êä³ö²ÎÊýÉèÖÃ,ÏêϸÇë²Î¼ûMV_IO_SET_OUTPUT½á¹¹ÌåÒÔ¼°Ïà¹ØÃ¶¾Ù¶¨Òå | en:Output param , reference MV_IO_SET_OUTPUT + * @return ch:³É¹¦£¬·µ»ØMV_OK(0);ʧ°Ü£¬·µ»Ø´íÎóÂë | en:Success,return MV_OK(0);Failed, return error code + */ +MV_IO_CONTROL_API int __stdcall MV_IO_SetOutput(IN void* handle, IN MV_IO_SET_OUTPUT * pstOutput); + +/** @fn MV_IO_SetOutputEnable + * @brief ch:¿ªÆôÊä³öʹÄÜ | en:Turn on output enable + * @param handle [IN] ch:É豸¾ä±ú | en:Device handle + * @param pstEnable [IN] ch:Êä³öʹÄܲÎÊý£¬ÏêϸÇë²Î¼ûMV_IO_OUTPUT_ENABLE½á¹¹ÌåÒÔ¼°Ïà¹ØÃ¶¾Ù¶¨Òå | en:Output enabling parameters, reference MV_IO_OUTPUT_ENABLE + * @return ch:³É¹¦£¬·µ»ØMV_OK(0);ʧ°Ü£¬·µ»Ø´íÎóÂë | en:Success,return MV_OK(0);Failed, return error code + */ +MV_IO_CONTROL_API int __stdcall MV_IO_SetOutputEnable(IN void* handle, IN MV_IO_OUTPUT_ENABLE * pstEnable); + +/** @fn MV_IO_SetInput + * @brief ch:ÊäÈë²ÎÊýÉèÖà + * @param handle [IN] ch:É豸¾ä±ú | en: + * @param pstInput [IN] ch:ÊäÈë²ÎÊý£¬ÏêϸÇë²Î¼ûMV_IO_SET_INPUT½á¹¹ÌåÒÔ¼°Ïà¹ØÃ¶¾Ù¶¨Òå | en: + * @return ch:³É¹¦£¬·µ»ØMV_OK(0);ʧ°Ü£¬·µ»Ø´íÎóÂë | en:Success,return MV_OK(0);Failed, return error code + */ +MV_IO_CONTROL_API int __stdcall MV_IO_SetInput(IN void* handle, IN MV_IO_SET_INPUT * pstInput); + +/** @fn MV_IO_GetPortInputParam + * @brief ch:»ñÈ¡ÊäÈë²ÎÊýÉèÖà | en:Get input parameter settings + * @param handle [IN] ch:É豸¾ä±ú | en:Device handle + * @param pstInput [IN] ch:ÊäÈë²ÎÊý£¬ÏêϸÇë²Î¼ûMV_IO_SET_INPUT½á¹¹ÌåÒÔ¼°Ïà¹ØÃ¶¾Ù¶¨Òå | en:Input param, reference MV_IO_SET_INPUT + * @return ³É¹¦£¬·µ»ØMV_OK(0);ʧ°Ü£¬·µ»Ø´íÎóÂë | en:Success,return MV_OK(0);Failed, return error code + */ +MV_IO_CONTROL_API int __stdcall MV_IO_GetPortInputParam(IN void* handle, IN OUT MV_IO_SET_INPUT * pstInput); + + +/** @fn MV_IO_GetPortOutputParam + * @brief ch:»ñÈ¡Êä³ö²ÎÊýÉèÖà | en:Get output parameter settings + * @param handle [IN] ch:É豸¾ä±ú | en:Device handle + * @param pstInput [IN] ch:ÊäÈë²ÎÊý£¬ÏêϸÇë²Î¼ûMV_IO_SET_OUTPUT½á¹¹ÌåÒÔ¼°Ïà¹ØÃ¶¾Ù¶¨Òå | en:Input param, reference MV_IO_SET_OUTPUT + * @return ch:³É¹¦£¬·µ»ØMV_OK(0);ʧ°Ü£¬·µ»Ø´íÎóÂë | en:Success,return MV_OK(0);Failed, return error code + */ +MV_IO_CONTROL_API int __stdcall MV_IO_GetPortOutputParam(IN void* handle, IN OUT MV_IO_SET_OUTPUT * pstInput); + +/** @fn MV_IO_GetInputLevel + * @brief ch:»ñÈ¡ÊäÈëµçƽÐÅÏ¢,ÔÚÑØ¼ì²â¿ªÆôʱ£¬²»ÄÜʹÓøýӿڻñÈ¡µçƽ | en:Get input level information,When edge detection is on, the interface cannot be used to obtain the level + * @param handle [IN] ch:É豸¾ä±ú | en:Device handle + * @param pstInputLevel [IN] ch:ÊäÈë²ÎÊý£¬ÏêϸÇë²Î¼ûMV_IO_INPUT_LEVEL½á¹¹ÌåÒÔ¼°Ïà¹ØÃ¶¾Ù¶¨Òå | en:Input param, reference MV_IO_INPUT_LEVEL + * @return ch:³É¹¦£¬·µ»ØMV_OK(0);ʧ°Ü£¬·µ»Ø´íÎóÂë | en:Success,return MV_OK(0);Failed, return error code + */ +MV_IO_CONTROL_API int __stdcall MV_IO_GetInputLevel(IN void* handle, OUT MV_IO_INPUT_LEVEL * pstInputLevel); + +/** @fn MV_IO_SetLightParam + * @brief ch:LIGHT(ÁÁ¶È)²ÎÊýÉèÖà | en:Light source setting + * @param handle [IN] ch:É豸¾ä±ú | en:Device handle + * @param pstLightParam [IN] ch:µÆ¹â²ÎÊý£¬ÏêϸÇë²Î¼ûMV_IO_LIGHT_PARAM½á¹¹ÌåÒÔ¼°Ïà¹ØÃ¶¾Ù¶¨Òå | en:Light source param, reference MV_IO_LIGHT_PARAM + * @return ch:³É¹¦£¬·µ»ØMV_OK(0);ʧ°Ü£¬·µ»Ø´íÎóÂë | en:Success,return MV_OK(0);Failed, return error code + */ +MV_IO_CONTROL_API int __stdcall MV_IO_SetLightParam(IN void* handle, IN MV_IO_LIGHT_PARAM * pstLightParam); + +/** @fn MV_IO_GetLightParam + * @brief ch:LIGHT(ÁÁ¶È)²ÎÊý»ñÈ¡ | en:Get light source brightness parameter + * @param handle [IN] ch:É豸¾ä±ú | en:Device handle + * @param pstLightParam [IN] ch:µÆ¹â²ÎÊý£¬ÏêϸÇë²Î¼ûMV_IO_LIGHT_PARAM½á¹¹ÌåÒÔ¼°Ïà¹ØÃ¶¾Ù¶¨Òå | en:light param, reference MV_IO_LIGHT_PARAM + * @return ch:³É¹¦£¬·µ»ØMV_OK(0);ʧ°Ü£¬·µ»Ø´íÎóÂë | en:Success,return MV_OK(0);Failed, return error code + */ +MV_IO_CONTROL_API int __stdcall MV_IO_GetLightParam(IN void* handle, IN MV_IO_LIGHT_PARAM * pstLightParam); + +/** @fn MV_IO_AssociatedOutPort + * @brief ch:ÊäÈë¹ØÁªÊä³ö¶Ë¿Ú | en:Input associated output port + * ch:ÈçÐ迪Æôijһ·ÊäÈëÑØ¼ì²â»òÕ߹رÕÑØ¼ì²â¹¦ÄÜ£¬ÐèÒªÔڸýӿÚÖ®ºóµ÷Óà | en:If you need to open a certain input edge to detect or close the detection function, you need to call it after the interface. + * @param handle [IN] ch:É豸¾ä±ú | en:Device handle + * @param pstAssocParam [IN] ch:¹ØÁª¶Ë¿Ú²ÎÊý£¬ÏêϸÇë²Î¼ûMV_IO_ASSOCIATE_PARAM½á¹¹ÌåÒÔ¼°Ïà¹ØÃ¶¾Ù¶¨Òå | en:Associated port parameters, reference MV_IO_ASSOCIATE_PARAM + * @return ch:³É¹¦£¬·µ»ØMV_OK(0);ʧ°Ü£¬·µ»Ø´íÎóÂë | en:Success,return MV_OK(0);Failed, return error code + */ +MV_IO_CONTROL_API int __stdcall MV_IO_AssociatedOutPort(IN void* handle, IN MV_IO_ASSOCIATEPORT_PARAM * pstAssocParam); + +/*********************************************************************** + * @fn MV_IO_RegisterEdgeDetectionCallBack + * @brief ch:ÑØ¼ì²â»Øµ÷ | en:edge detection callback + * @param handle [IN] ch:É豸¾ä±ú | en:Device handle + * @param cbOutput [IN] ch:»Øµ÷º¯ÊýÖ¸Õë | en:Callback function pointer + * @param pInputLevel [IN] ch:ÑØ¼ì²â²ÎÊý£¬ÏêϸÇë²Î¼ûMV_IO_INPUT_EDGE_TYPE½á¹¹ÌåÒÔ¼°Ïà¹ØÃ¶¾Ù¶¨Òå | en:Edge detection parameters, reference MV_IO_INPUT_EDGE_TYPE + * @param pUser [IN] ch:Óû§×Ô¶¨Òå±äÁ¿ | en: pointer + * @return ch:³É¹¦£¬·µ»ØMV_OK£»´íÎ󣬷µ»Ø´íÎóÂë | en:Success,return MV_OK(0);Failed, return error code + ***********************************************************************/ +MV_IO_CONTROL_API int __stdcall MV_IO_RegisterEdgeDetectionCallBack(IN void* handle, DetectFunType cbOutput,void* pUser); + +/** @fn MV_IO_ResetParam + * @brief ch:ÖØÖòÎÊý | en: + * @param handle [IN] ch:É豸¾ä±ú | en:Device handle + * @return ch:³É¹¦£¬·µ»ØMV_OK(0);ʧ°Ü£¬·µ»Ø´íÎóÂë | en:Success,return MV_OK(0);Failed, return error code + */ +MV_IO_CONTROL_API int __stdcall MV_IO_ResetParam(IN void * handle); + +/** @fn MV_IO_Reboot + * @brief ch:ÖØÆôÉ豸 | en:Reboot device + * @param handle [IN] ch:É豸¾ä±ú | en:Device handle + * @return ch:³É¹¦£¬·µ»ØMV_OK(0);ʧ°Ü£¬·µ»Ø´íÎóÂë | en:Success,return MV_OK(0);Failed, return error code + */ +MV_IO_CONTROL_API int __stdcall MV_IO_Reboot(IN void * handle); + +/** @fn MV_IO_SetDebugView + * @brief ch:´ò¿ªDugview¹¤¾ßµ÷ÊÔ½Ó¿Ú | en:Open the dugview tool debugging interface + * @param nFlag [IN] ch:1±íʾ¿ªÆôDebugview, 0±íʾ¹Ø±Õ | en:1 means DebugView is on, 0 is off + * @return ch: ¿Õ |en: None + */ +MV_IO_CONTROL_API void __stdcall MV_IO_SetDebugView(IN unsigned int nFlag); + + +/** @fn MV_IO_SaveParam + * @brief ch:±£´æ²ÎÊý | en:Save device param + * @param handle [IN] ch:É豸¾ä±ú | en:Device handle + * @return ch:³É¹¦£¬·µ»ØMV_OK(0);ʧ°Ü£¬·µ»Ø´íÎóÂë | en:Success,return MV_OK(0);Failed, return error code + */ +MV_IO_CONTROL_API int __stdcall MV_IO_SaveParam(IN void * handle); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/IOController/NewSdkInc/MvIOInterfaceBoxDefine.h b/src/IOController/NewSdkInc/MvIOInterfaceBoxDefine.h new file mode 100644 index 0000000..63f4354 --- /dev/null +++ b/src/IOController/NewSdkInc/MvIOInterfaceBoxDefine.h @@ -0,0 +1,288 @@ +/*************************************************************************************************** +* +* °æÈ¨ÐÅÏ¢£º°æÈ¨ËùÓÐ (c) 2018±£ÁôËùÓÐȨÀû +* +* ÎļþÃû³Æ£ºMvInterfaceBoxDefine.h +* Õª Òª£ºÊÓ¾õ¿ØÖÆÆ÷³£¼û¶¨ÒåÍ·Îļþ +* +* ±¸ ×¢£ºÎÞ +* +***************************************************************************************************/ + +/*************************************************************************************************** +* +* Copyright: Copyright: Copyright (c) 2018 all rights reserved +* +* File name: MvInterfaceBoxDefine.h +* Abstract: Common definition header file of Visual controller +* +* Remarks: None +* +***************************************************************************************************/ +#ifndef MV_IO_INTERFACE_BOX_DEFINE_H__ +#define MV_IO_INTERFACE_BOX_DEFINE_H__ + +#ifndef IN +#define IN +#endif + +#ifndef OUT +#define OUT +#endif + +#define MV_SERIAL_BUF_LEN 1024 //ch:´®¿Úbuffer³¤¶È | en : Serial buffer length + +#define MV_SERIAL_RECVBUF_MAXLEN (1024*1024) //ch:Ò»´ÎÐÔ½ÓÊÕ´®¿ÚÊý¾ÝµÄ×î´óÖµ | en:Max value of received data at one time + +// ÓÃÓÚÇø·ÖÃüÁîÀàÐÍ +typedef enum MVCL_CTRL_TYPE__ +{ + CTRL_INPUT_LEVEL = 0x00, // ch:»ñÈ¡ÊäÈë¿Ú¸ßµÍµçƽÐÅÏ¢ |en: Get high and low level information of input port + CTRL_RESET_PARAM = 0x01, // ch:»Ö¸´Ä¬ÈϲÎÊýÖµ |en: Restore default parameter values + CTRL_VERSION_INFO = 0x02, // ch:»ñÈ¡°æ±¾ÐÅÏ¢ |en: Get vision information + CTRL_PATTERN_SET_INFO = 0x03, // ch:»ñȡģʽÐÅÏ¢ |en: Get mode information + CTRL_INPUT_SET_INFO = 0x04, // ch:»ñÈ¡IOÊäÈë¿ÚÉèÖÃÐÅÏ¢ |en: Get IO input port setting information + CTRL_OUTPUT_SET_INFO = 0x05, // ch:»ñÈ¡IOÊä³ö¿ÚÉèÖÃÐÅÏ¢ |en: Get IO output port setting information + CTRL_LIGHT_SET_INFO = 0x06, // ch:»ñÈ¡¹âÔ´ÉèÖÃÐÅÏ¢ |en: Get lighting settings information + CTRL_FILTER_SET_INFO = 0x07, // ch:»ñÈ¡Â˲¨ÉèÖÃÐÅÏ¢ |en: Get filter setting information +}MVCL_CTRL_TYPE; + + +/************************************************************************* + *ch:³£¼ûºê¶¨Òå en| Common macro definitions + *************************************************************************/ +const static unsigned int MV_IO_MAX_COM_NAME_LENGTH = 64; // ch:×î´óµÄ´®¿ÚÃû³Æ³¤¶È | en:Max serial port name length +const static unsigned int MV_IO_MAX_PROC_STATE_LEN = 64; // ch:×î´óµÄÉý¼¶½ø¶È״̬³¤¶È | en:Max upgrade state length + +/************************************************************************* + * ö¾Ù¶¨Òå | en: Enumeration definition + *************************************************************************/ + +// ch:¹Ø±Õ´®¿ÚĬÈϳ¬Ê±Ê±¼ä en: Default timeout for closing serial port +#define CLOSE_SERIAL_DEFAULT_TIMEOUT 3000 + +/** @enum MV_IO_PATTERN_OUT + * @brief ch:Êä³öģʽѡÔñ | en: Output mode selection + */ +typedef enum MV_IO_PATTERN_OUT__ +{ + MV_IO_PATTERN_PWM = 0x05, // PWM + MV_IO_PATTERN_SINGLE = 0x06, // SINGLE +} MV_IO_PATTERN_OUT; + +/** @enum MV_IO_PORT_NUMBER + * @brief ch:Port¿Ú¶¨Òå | en: port definition + * ch:ÊäÈëºÍÊä³öµÄ7¸öPort¿Ú¾ùÓÃÕâ7¸öºê¶¨Òå±íʾ | en:The eight port ports of input and output are represented by these seven macro definitions + * ch:ÈôҪͬʱ¿ØÖÆÁ½¸öPort¿ÚÊä³ö£¬¿ÉÒÔ½«Æä»òÔËË㣨ÀýÈç: MV_IO_PORT_1 | MV_IO_PORT_2£© + * en: To enable the output of two port ports at the same time, the or operation can be performed(ex: MV_IO_PORT_1 | MV_IO_PORT_2) + */ +typedef enum MV_IO_PORT_NUMBER__ +{ + MV_IO_PORT_1 = 0x1, // ch:¶Ë¿Ú1 | en: port1 + MV_IO_PORT_2 = 0x2, // ch:¶Ë¿Ú2 | en: port2 + MV_IO_PORT_3 = 0x4, // ch:¶Ë¿Ú3 | en: port3 + MV_IO_PORT_4 = 0x8, // ch:¶Ë¿Ú4 | en: port4 + MV_IO_PORT_5 = 0x10, // ch:¶Ë¿Ú5 | en: port5 + MV_IO_PORT_6 = 0x20, // ch:¶Ë¿Ú6 | en: port6 + MV_IO_PORT_7 = 0x40, // ch:¶Ë¿Ú7 | en: port7 + MV_IO_PORT_8 = 0x80, // ch:¶Ë¿Ú8 | en: port8 +} MV_IO_PORT_NUMBER; + +/** @enum MV_IO_EDGE_TYPE + * @brief ch:ÑØ¶¨Òå,Óû§±íʾÊäÈëÐźŵĴ¥·¢ | en:Edge definition + */ +typedef enum MV_IO_EDGE_TYPE__ +{ + MV_IO_EDGE_UNKNOW = 0x00, // ch:δ֪ | en: Unknow + MV_IO_EDGE_RISING = 0x01, // ch:ÉÏÉýÑØ | en: Rising edge + MV_IO_EDGE_FALLING = 0x02, // ch:ϽµÑØ | en: Falling edge +} MV_IO_EDGE_TYPE; + +/** @enum MV_IO_ENABLE_TYPE + * @brief ch:ʹÄÜÀàÐͶ¨Ò壬ÓÃÓÚ¿ØÖÆ´®¿ÚģʽÇé¿öϵĴ¥·¢ | en: Enable type definition, used to control the trigger in serial mode + */ +typedef enum MV_IO_ENABLE_TYPE__ +{ + MV_IO_ENABLE_START = 0x00, // ch:ʹÄÜ¿ªÊ¼ | en: Enable + MV_IO_ENABLE_END = 0x01, // ch:ʹÄܽáÊø | en: Disable +} MV_IO_ENABLE_TYPE; + +/** @enum MV_IO_LIGHTSTATE + * @brief ch:¹âÔ´³£ÁÁ³£Ãð | en: Light states + */ +typedef enum MV_IO_LIGHTSTATE__ +{ + MV_IO_LIGHTSTATE_ON = 0x0001, // ch:´¥·¢ºó³£ÁÁ | en:Light on after triggering + MV_IO_LIGHTSTATE_OFF = 0x0002, // ch:´¥·¢ºó³£Ãð | en:Light off after triggering +} MV_IO_LIGHTSTATE; + +// ÏûÏ¢ÀàÐÍ +typedef enum MVCL_MSG_TYPE__ +{ + MSG_TYPE_UNKNOW = 0x00, // ch:δ֪ | en:Unknow + MSG_TYPE_NORMAL = 0x02, // ch:¿Éʶ±ðÕý³£ÏûÏ¢ÀàÐÍ | en:Normal +}MVCL_MSG_TYPE; + +/************************************************************************* + * ch:½á¹¹Ì嶨Òå | en:Struct definition + *************************************************************************/ + +/** @struct MV_IO_SERIAL + * @brief ch:´®¿Ú²ÎÊý | en:Serial param + */ +typedef struct MV_IO_SERIAL__ +{ + char strComName[MV_IO_MAX_COM_NAME_LENGTH]; // ch:´®¿ÚÃû³Æ | en:Serial port name + unsigned int nReserved[8]; // ch:±£Áô×Ö¶Î | en:Reserve +} MV_IO_SERIAL; + +/** @struct MV_IO_LIGHT_PARAM + * @brief ch:ÁÁ¶È²ÎÊýÉèÖà | en:Parameter setting of light source module + */ +typedef struct MV_IO_LIGHT_PARAM__ +{ + unsigned char nPortNumber; // ch:ÁÁ¶È¶Ë¿Ú | en:Light port + unsigned short nLightValue; // ch:¹âÔ´ÁÁ¶ÈÖµ(0-100Ö®¼ä) | en:Light value(0-100) + unsigned short nLightState; // ch:´¥·¢ºó³£ÁÁ»¹Êdz£Ãð | en:Light on or off after triggering + unsigned short nLightEdge; // ch:ÉÏÉýÑØ´¥·¢»¹ÊÇϽµÑØ´¥·¢ | en:Rising or falling edge trigger + unsigned int nDurationTime; // ch:³ÖÐøÊ±¼ä | en:Duration Time + unsigned int nReserved[3]; // ch:±£Áô×Ö¶Î | en:Reserved +} MV_IO_LIGHT_PARAM; + +/** @struct MV_IO_ASSOCIATE_PARAM + * @brief ch:ÊäÈë¹ØÁªÊä³ö¶Ë¿Ú²ÎÊýÉèÖà | en:Input associated output port parameter setting + */ +typedef struct MV_IO_ASSOCIATEPORT_PARAM__ +{ + unsigned short nInPortNum; // ch:±»¹ØÁªµÄÊäÈë¶Ë¿Ú | en:Associated input port + unsigned short nOutPortNum; // ch:¹ØÁªµÄÊä³ö¶Ë¿Ú£¬(PORT_1)´ú±í¹ØÁª1ºÅ¿Ú£¬(PORT_1 | PORT_2)´ú±í¹ØÁª1ºÅºÍ2ºÅ¿Ú£¬(ÒÔ´ËÀàÍÆ) + // en:Associated output port, (Port_ 1)For the associated port 1, (Port_ 1 | PORT_ 2) Represents the connection between port 1 and port 2, and so on + unsigned int nReserved[4]; // ch:±£Áô×Ö¶Î | en:Reserved +} MV_IO_ASSOCIATEPORT_PARAM; + + +/** @struct MV_IO_OUTPUT_ENABLE + * @brief ch:ÉèÖÃÊä³öʹÄÜ | en:Set output enable + */ +typedef struct MV_IO_OUTPUT_ENABLE__ +{ + unsigned char nPortNumber; // ʹÄܶ˿Ú,Èô¶à¸ö¶Ë¿ÚͬʱʹÄÜ¿ÉÒÔÖ´ÐлòÔËËã | en:Enable port, if more than one port is enabled at the same time, it can perform or operation + unsigned char nType; // MV_IO_ENABLE_START ±íʾʹÄÜ¿ªÊ¼£¬MV_IO_ENABLE_END±íʾʹÄܽáÊø | en:en:MV_IO_ENABLE_START:start of enabling,MV_IO_ENABLE_END:end of enabling + unsigned int nReserved[4]; // ±£Áô×Ö¶Î | en:Reserved +} MV_IO_OUTPUT_ENABLE; + +/** @struct MV_IO_INPUT_LEVEL + * @brief ch:ÊäÈëµçƽ en: Input level + */ +typedef struct MV_IO_INPUT_LEVEL__ +{ + unsigned char nPortNumber; // ch:¶Ë¿ÚºÅ,²Î¿¼MV_IO_PORT_NUMBER | en: Port number.reference MV_IO_PORT_NUMBER + unsigned char nLevel0; // ch:1ºÅ¿ÚµçƽÐÅÏ¢ |en:Level information of port1 + unsigned char nLevel1; // ch:2ºÅ¿ÚµçƽÐÅÏ¢ |en:Level information of port2 + unsigned char nLevel2; // ch:3ºÅ¿ÚµçƽÐÅÏ¢ |en:Level information of port3 + unsigned char nLevel3; // ch:4ºÅ¿ÚµçƽÐÅÏ¢ |en:Level information of port4 + unsigned char nLevel4; // ch:5ºÅ¿ÚµçƽÐÅÏ¢ |en:Level information of port5 + unsigned char nLevel5; // ch:6ºÅ¿ÚµçƽÐÅÏ¢ |en:Level information of port6 + unsigned char nLevel6; // ch:7ºÅ¿ÚµçƽÐÅÏ¢ |en:Level information of port7 + unsigned char nLevel7; // ch:8ºÅ¿ÚµçƽÐÅÏ¢ |en:Level information of port8 + unsigned int nReserved[8]; // ch:±£Áô×Ö½Ú | en:Reserved +}MV_IO_INPUT_LEVEL; + +/** @struct MV_IO_INPUT_EDGE + * @brief ch:¼ì²âÊäÈëÑØÐÅÏ¢ÀàÐ͵ĽṹÌå | en:Detects the structure of the input along the information type + */ +typedef struct MV_IO_INPUT_EDGE_TYPE__ +{ + unsigned char nPortNumber; // ch:¶Ë¿ÚºÅ | en:Port number + unsigned short nTriggerTimes; // ch:¶ÔÓ¦¶Ë¿Ú´¥·¢´ÎÊý | en:Trigger times of corresponding port + enum MV_IO_EDGE_TYPE enEdgeType; // ch:ÑØÀàÐÍ | en:Trigger edge type + unsigned int nReserved[8]; // ch:±£Áô×Ö½Ú | en:Reserved +}MV_IO_INPUT_EDGE_TYPE; + +/** @struct MV_IO_VERSION + * @brief ch:SDK°æ±¾ºÅ | en:SDK vision + */ +typedef struct MV_IO_VERSION__ +{ + unsigned int nMainVersion; // ch:Ö÷°æ±¾ºÅ | en:Major version + unsigned int nSubVersion; // ch:´Î°æ±¾ºÅ | en:Minor version + unsigned int nModifyVersion; // ch:ÐÞ¶©°æ±¾ºÅ | en:Revision + unsigned int nYear; // ch:Äê | en:Year + unsigned int nMonth; // ch:Ô | en:month + unsigned int nDay; // ch:ÈÕ | en:date + unsigned int nReserved[8]; // ch:±£Áô×Ö½Ú | en:Reserved +}MV_IO_VERSION; + +/** @struct MV_IO_SET_INPUT + * @brief ch:ÊäÈë¶Ë¿ÚÉèÖà | en:Input port setting + */ +typedef struct MV_IO_SET_INPUT__ +{ + unsigned int nPort; // ch:ÊäÈë¶Ë¿Ú | Input port + unsigned int nEnable; // ch:ʹÄÜ״̬£¬1±íʾ¿ªÆô£¬0±íʾ¹Ø±Õ | en:Enable state, 1 is on, 0 is off + unsigned int nEdge; // ch:´¥·¢ÑØ | en:Trigger edge + unsigned int nDelayTime; // ch:´¥·¢ÑÓ³Ù | en:Trigger delay + unsigned int nGlitch; // ch:È¥¶¶Ê±¼ä | en:Debounce time + unsigned int nReserved[8]; // ch:±£Áô×Ö½Ú | en:Reserved +}MV_IO_SET_INPUT; + +/** @struct MV_IO_SET_OUTPUT + * @brief ch:Êä³ö¶Ë¿ÚÉèÖà | en:Output port setting + */ +typedef struct MV_IO_SET_OUTPUT__ +{ + unsigned int nPort; // Êä³ö¶Ë¿Ú | en:Output port + unsigned int nType; // Êä³öģʽ(°üº¬µ¥Âö³åģʽºÍPWMģʽ) | en:Output mode(Single pulse and PWM mode ) + unsigned int nPulseWidth; // Âö³å¿í¶È | en:Pulse width + unsigned int nPulsePeriod; // Âö³åÖÜÆÚ | en:Pulse period + unsigned int nDurationTime; // Âö³å³ÖÐøÊ±¼ä | en:Pulse duration + unsigned int nValidLevel; // ÓÐЧµçƽ£¬1±íʾ¸ßµçƽ£¬0±íʾµÍµçƽ | en:Effective level, 1 is high level, 0 is low level + unsigned int nReserved[8]; // ±£Áô×Ö½Ú | en:Reserved +}MV_IO_SET_OUTPUT; + + +/** @struct MV_IO_LOCAL_UPGRADE + * @brief ch:¹Ì¼þÉý¼¶×´Ì¬ | en:Firmware upgrade status + */ +typedef struct MV_IO_LOCAL_UPGRADE__ +{ + unsigned int nProcPercent; // ch:Éý¼¶½ø¶È | en:Upgrade progress + char chProcState[MV_IO_MAX_PROC_STATE_LEN]; // ch:Éý¼¶×´Ì¬ | en:Upgrade status + + unsigned int nReserved[8]; // ch:±£Áô×Ö½Ú | en:Reserved +}MV_IO_LOCAL_UPGRADE; + + +// ch:¼ì²âµçƽ»Øµ÷º¯Êý | en:Detection level callback function +typedef void (__stdcall* DetectFunType)(void *, MV_IO_INPUT_EDGE_TYPE*, void*); + +/** @struct MV_SERIAL_DEVICE + * @brief ch: ´®¿ÚÉ豸 en: serial device + */ +typedef struct MV_SERIAL_DEVICE_ +{ + void* pMvSerial; // ´®¿Ú¾ä±ú + DetectFunType pCallbackFun; // ÑØ¼ì²âº¯Êý + void* hCallBackThreadHandle; // »Øµ÷¾ä±ú + unsigned int bCallbackRunning; // Åжϻص÷Ïß³ÌÊÇ·ñÕýÔÚÖ´ÐÐ + void* hSerialRecvThreadHandle; // ´®¿Ú½ÓÊÕÊý¾ÝÏ߳̾ä±ú + unsigned int bSerialRecvRunning; // Åжϴ®¿ÚÊÇ·ñÕýÔÚ½ÓÊÕÊý¾Ý + char nReserved[32]; // ±£Áô×Ö½Ú +}MV_SERIAL_DEVICE; + +/** @struct MV_SERIAL_DATA + * @brief ch: ´®¿ÚÊý¾Ý | en: serial Data + */ +typedef struct MV_SERIAL_DATA_ +{ + unsigned int bUsed; // ch:±ê־룬Êý¾ÝÊÇ·ñʹÓà | en:Flag bit, whether the data is used or not + MVCL_MSG_TYPE nType; // ch:Êý¾ÝÀàÐÍ | en: Data type + unsigned int nRecvLen; // ch:½ÓÊÕÊý¾Ý³¤¶È | en:Received data length + double fRecvTime; // ch:½ÓÊÕÊý¾Ýʱ¼ä | en:Received data time + char* pSerialRecvBuf; // ch:½ÓÊÕµÄÊý¾Ý | en:Data received + char* pInitRecvBuf; // ch:³õʼÊý¾Ý | en:Initial data +}MV_SERIAL_DATA; + + +#endif + diff --git a/src/TcpServer/TcpServer.cpp b/src/TcpServer/TcpServer.cpp new file mode 100644 index 0000000..51959ca --- /dev/null +++ b/src/TcpServer/TcpServer.cpp @@ -0,0 +1,98 @@ +#include "Tcpserver.h" +#include +TcpServer::TcpServer(QObject *parent) : + QTcpServer(parent) +{ + m_tcpServerPtr = nullptr; + m_tcpSocketPtr = nullptr; + m_tcpServerPtr = new QTcpServer(this); +} + +TcpServer::~TcpServer() +{ + if (m_tcpServerPtr) + delete m_tcpServerPtr; +} + +bool TcpServer::startConnect(QString address, quint16 port) +{ + if (m_tcpServerPtr == nullptr) + return false; + if (!m_tcpServerPtr->listen(QHostAddress(address), port)) + { + return false; + } + connect(m_tcpServerPtr, &QTcpServer::newConnection, this, &TcpServer::onNewConnection); + return true; +} +bool TcpServer::startConnect() +{ + if (m_tcpServerPtr == nullptr) + return false; + if (!m_tcpServerPtr->listen(QHostAddress(m_serverIP), m_serverPort)) + { + return false; + } + connect(m_tcpServerPtr, &QTcpServer::newConnection, this, &TcpServer::onNewConnection); + return true; +} +void TcpServer::onCloseConnect() +{ + + if (m_tcpServerPtr != nullptr) + { + if (m_tcpSocketPtr != nullptr) + { + m_tcpSocketPtr->disconnectFromHost(); + m_tcpSocketPtr->close(); + m_tcpSocketPtr = nullptr; + } + m_tcpServerPtr->disconnect(); + m_tcpServerPtr->close(); + } + +} +void TcpServer::onNewConnection() +{ + //È¡³ö½¨Á¢ºÃÁ¬½ÓµÄÌ×½Ó×Ö + m_tcpSocketPtr = m_tcpServerPtr->nextPendingConnection(); + + m_clientIp = m_tcpSocketPtr->peerAddress().toString(); + m_clientPort = m_tcpSocketPtr->peerPort(); + emit sgConnected(m_clientIp, m_clientPort); + + connect(m_tcpSocketPtr, &QTcpSocket::readyRead, this, &TcpServer::onReceiveMsg); + //connect(m_tcpSocketPtr, &QTcpSocket::stateChanged, this, &TcpServer::onStateChanged); + //connect(m_tcpSocketPtr, SIGNAL(error(QAbstractSocket::SocketError)), this, &TcpServer::onSocketError); +} + +void TcpServer::onReceiveMsg() +{ + QByteArray dataByte = m_tcpSocketPtr->readAll(); + if (!dataByte.isEmpty()) + { + emit sgReceived(m_clientIp, m_clientPort, dataByte); + } +} + +//void TcpServer::onDisconnected() +//{ +// emit sgDisconnected(m_clientIp, m_clientPort); +//} +//void TcpServer::onStateChanged(QAbstractSocket::SocketState socketState) +//{ +// if (socketState == QAbstractSocket::UnconnectedState) +// { +// emit sgDisconnected(m_clientIp, m_clientPort); +// m_tcpSocketPtr->deleteLater(); +// } +//} +// +//void TcpServer::onSocketError(QAbstractSocket::SocketError socketError) +//{ +// int error = m_tcpSocketPtr->error(); +// if (error == QAbstractSocket::RemoteHostClosedError) +// { +// emit sgDisconnected(m_clientIp, m_clientPort); +// } +//} \ No newline at end of file diff --git a/src/TcpServer/TcpServer.h b/src/TcpServer/TcpServer.h new file mode 100644 index 0000000..1a1adea --- /dev/null +++ b/src/TcpServer/TcpServer.h @@ -0,0 +1,72 @@ +#ifndef _H_TCPSERVER_H_ +#define _H_TCPSERVER_H_ + +#include +#include + +#include +#include +#include + +//#include "tcpsocket.h" + +#include + +#ifndef BUILD_STATIC +# if defined(TCPSERVER_LIB) +# define TCPSERVER_EXPORT Q_DECL_EXPORT +# else +# define TCPSERVER_EXPORT Q_DECL_IMPORT +# endif +#else +# define TCPSERVER_EXPORT +#endif + +class TCPSERVER_EXPORT TcpServer : public QTcpServer +{ + Q_OBJECT + +public: + explicit TcpServer(QObject *parent = 0); + ~TcpServer(); + + bool startConnect(); + bool startConnect(QString address, quint16 port); + void onCloseConnect(); + + void setServerIpPort(QString ip, quint16 port) + { + m_serverIP = ip; + m_serverPort = port; + } +signals: + void sgConnected(QString ip, quint16 port); + void sgReceived(QString ip, quint16 port, const QByteArray &msg); + void sgDisconnected(QString ip, quint16 port); +protected: + void SendHeartHitBack(); + +private: + + QTcpServer *m_tcpServerPtr; //¼àÌýÌ×½Ó×Ö + QTcpSocket *m_tcpSocketPtr; //ͨÐÅÌ×½Ó×Ö + + bool m_bGetHeader{ false }; + int m_goalSize{ 0 }; + int m_nowSize{ 0 }; + + QString m_clientIp; + quint16 m_clientPort; + QString m_serverIP; + quint16 m_serverPort; + QByteArray m_receiveData; + +private slots: + void onNewConnection(); + void onReceiveMsg(); + //void onDisconnected(); + //void onStateChanged(QAbstractSocket::SocketState socketState); + //void onSocketError(QAbstractSocket::SocketError socketError); +}; + +#endif // !_H_TCPSERVER_H_ diff --git a/src/VisionController/VisionController.cpp b/src/VisionController/VisionController.cpp new file mode 100644 index 0000000..fe12660 --- /dev/null +++ b/src/VisionController/VisionController.cpp @@ -0,0 +1,231 @@ +#pragma execution_character_set("utf-8") +#include "VisionController.h" + +VisionController::VisionController(QWidget *parent) + : QMainWindow(parent) +{ + ui.setupUi(this); + + m_tcpServerPtr = nullptr; + m_tcpServerPtr = new TcpServer(this); + QString path = QApplication::applicationDirPath(); + QString serverIP = "127.0.0.1"; + quint16 serverPort = 9900; + readServerConfig(path, serverIP, serverPort); + ui.LineEdit_IP->setText(serverIP); + ui.LineEdit_Port->setText(tr("%1").arg(serverPort)); + ui.LineEdit_IP->setEnabled(false); + if (m_tcpServerPtr->startConnect(serverIP, serverPort)) + { + //QString msg = QString("·þÎñÆ÷£º1%: 2% Æô¶¯³É¹¦").arg(serverIp).arg(port); + QString showMsg = QString("¡¾·þÎñÆ÷£º%1: %2 Æô¶¯³É¹¦¡¿").arg(serverIP).arg(serverPort); + ui.textLog->appendPlainText(showMsg); + ui.ButtonStart->setEnabled(false); + ui.ButtonStop->setEnabled(true); + } + else + { + QString showMsg = QString("¡¾·þÎñÆ÷£º%1: %2 Æô¶¯Ê§°Ü¡¿").arg(serverIP).arg(serverPort); + ui.textLog->appendPlainText(showMsg); + } + connect(ui.ButtonStart, SIGNAL(clicked()), this, SLOT(onButtonClicked())); + connect(ui.ButtonStop, SIGNAL(clicked()), this, SLOT(onButtonClicked())); + connect(ui.ButtonClear, SIGNAL(clicked()), this, SLOT(onButtonClicked())); + + connect(m_tcpServerPtr, &TcpServer::sgConnected, this, &VisionController::newConnected); + connect(m_tcpServerPtr, &TcpServer::sgReceived, this, &VisionController::receivedData); + connect(m_tcpServerPtr, &TcpServer::sgDisconnected, this, &VisionController::onDisconnected); + m_ioControllerPtr = new IOController(); + unsigned int serialNum = 2; + if (!m_ioControllerPtr->controllerInitialization(serialNum)) + { + QString showMsg = QString("´®¿ÚCom%1³õʼ»¯Ê§°Ü").arg(serialNum); + ui.textLog->appendPlainText(showMsg); + } + else + { + QString showMsg = QString("´®¿ÚCom%1³õʼ»¯³É¹¦").arg(serialNum); + ui.textLog->appendPlainText(showMsg); + } +} + +bool VisionController::readServerConfig(QString path, QString& serverIP, quint16& port) +{ + QString filePath = path + "\\..\\config\\tcpServer.json"; + QFile jsonFile(filePath); + if (!jsonFile.exists()) + { + qDebug() << "Îļþ: " << filePath << "²»´æÔÚ£¡"; + return false; + } + if (!jsonFile.open(QIODevice::ReadOnly | QIODevice::Text)) + { + qDebug() << "Îļþ£º" << filePath << "´ò¿ªÊ§°Ü£¡"; + return false; + } + QByteArray dataArray = jsonFile.readAll(); + jsonFile.close(); + QJsonParseError jsonError; + QJsonDocument jsonDocument = QJsonDocument::fromJson(dataArray, &jsonError); + if (jsonError.error != QJsonParseError::NoError) + { + qDebug() << "Îļþ£º" << filePath << "¸ñʽ´íÎó£¡"; + return false; + } + + QJsonObject jsonObject = jsonDocument.object(); + QJsonObject addressObj = jsonObject.value("address").toObject(); + serverIP = addressObj.value("IP").toString(); + port = addressObj.value("Port").toString().toUInt(); + + return true; +} +bool VisionController::writeServerConfig(QString path, QString serverIP, quint16 serverPort) +{ + QString filePath = path + "\\..\\config\\tcpServer.json"; + QFile jsonFile(filePath); + if (!jsonFile.open(QIODevice::WriteOnly)) + { + qDebug() << "´´½¨Îļþ£º" << filePath << "ʧ°Ü£¡"; + return false; + } + QJsonObject addressObj; + QJsonObject subObj; + subObj.insert("IP", serverIP); + subObj.insert("Port", tr("%1").arg(serverPort)); + addressObj.insert("address", QJsonObject(subObj)); + QJsonDocument jsonDoc(addressObj); + QByteArray jsonData = jsonDoc.toJson(); + jsonFile.write(jsonData); + jsonFile.close(); + return true; +} +VisionController::~VisionController() +{ + if (m_ioControllerPtr) + { + delete m_ioControllerPtr; + //m_ioControllerPtr = nullptr; + } + + if (m_tcpServerPtr) + { + delete m_tcpServerPtr; + } +} + +Q_SLOT void VisionController::onButtonClicked() +{ + QString strObj = sender()->objectName(); + if (strObj == "ButtonStart") + { + QString serverIp = ui.LineEdit_IP->text(); + quint16 port = ui.LineEdit_Port->text().toUInt(); + QString path = QApplication::applicationDirPath(); + writeServerConfig(path, serverIp, port); + if (m_tcpServerPtr->startConnect(serverIp, port)) + { + //QString msg = QString("·þÎñÆ÷£º1%: 2% Æô¶¯³É¹¦").arg(serverIp).arg(port); + QString showMsg = QString("¡¾·þÎñÆ÷£º%1: %2 Æô¶¯³É¹¦¡¿").arg(serverIp).arg(port); + ui.textLog->appendPlainText(showMsg); + ui.ButtonStart->setEnabled(false); + ui.ButtonStop->setEnabled(true); + } + else + { + QString showMsg = QString("¡¾·þÎñÆ÷£º%1: %2 Æô¶¯Ê§°Ü¡¿").arg(serverIp).arg(port); + ui.textLog->appendPlainText(showMsg); + } + } + else if (strObj == "ButtonStop") + { + if (m_tcpServerPtr != nullptr) + { + m_tcpServerPtr->onCloseConnect(); + ui.ButtonStart->setEnabled(true); + ui.ButtonStop->setEnabled(false); + //delete m_tcpServerPtr; + } + } + else if (strObj == "ButtonClear") + { + ui.textLog->clear(); + } +} +Q_SLOT void VisionController::newConnected(QString ip, quint16 port) +{ + QString showMsg = QString("¡¾¿Í»§¶ËÉÏÏߣº%1: %2¡¿").arg(ip).arg(port); + ui.textLog->appendPlainText(showMsg); +} +Q_SLOT void VisionController::receivedData(QString ip, quint16 port, const QByteArray& dataByte) +{ + QString showMsg = QString("¡¾¿Í»§¶Ë£º%1: %2¡¿£º").arg(ip).arg(port); + showMsg.append(dataByte); + ui.textLog->appendPlainText(showMsg); + QString msg = QString(dataByte); + + if (msg.startsWith("<") && msg.endsWith(">")) + { + msg.chop(1); + msg.remove(0, 1); + QStringList splitList = msg.split(","); + unsigned int port = splitList[0].toInt(); + unsigned int state = splitList[1].toInt(); + QString mode = splitList[2]; + if (mode == "post") + { + if (!m_ioControllerPtr->controlPort(port, state)) + { + if (state == 0) + { + QString errorMsg = QString("¡¾¶Ë¿ÚPort%1 ¹Ø±Õʧ°Ü£¡¡¿").arg(port); + ui.textLog->appendPlainText(errorMsg); + } + else if (state == 1) + { + QString errorMsg = QString("¡¾¶Ë¿ÚPort%1 ´ò¿ªÊ§°Ü£¡¡¿").arg(port); + ui.textLog->appendPlainText(errorMsg); + } + } + else + { + if (state == 0) + { + QString successMsg = QString("¡¾¶Ë¿Úport%1 ¹Ø±Õ³É¹¦£¡¡¿").arg(port); + ui.textLog->appendPlainText(successMsg); + } + else if (state == 1) + { + QString successMsg = QString("¡¾¶Ë¿Úport%1 ´ò¿ª³É¹¦£¡¡¿").arg(port); + ui.textLog->appendPlainText(successMsg); + } + } + } + else if (mode == "get") + { + unsigned int portState; + if (m_ioControllerPtr->getPortState(port, portState)) + { + QString successMsg = QString("¡¾¶Ë¿Úport%1µÄ״̬Ϊ£º%2¡¿").arg(port).arg(portState); + ui.textLog->appendPlainText(successMsg); + } + else + { + QString errorMsg = QString("¡¾¶Ë¿Úport%1״̬»ñȡʧ°Ü£¡¡¿").arg(port); + ui.textLog->appendPlainText(errorMsg); + } + } + } +} +Q_SLOT void VisionController::onDisconnected(QString ip, quint16 port) +{ + QString msg = QString("¡¾¿Í»§¶Ë£º%1£º%2¶Ï¿ªÁ¬½Ó£¡¡¿").arg(ip).arg(port); + ui.textLog->appendPlainText(msg); +} +void VisionController::closeEvent(QCloseEvent *event) +{ + QString serverIp = ui.LineEdit_IP->text(); + quint16 port = ui.LineEdit_Port->text().toUInt(); + QString path = QApplication::applicationDirPath(); + writeServerConfig(path, serverIp, port); +} \ No newline at end of file diff --git a/src/VisionController/VisionController.h b/src/VisionController/VisionController.h new file mode 100644 index 0000000..5cc5860 --- /dev/null +++ b/src/VisionController/VisionController.h @@ -0,0 +1,37 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include "ui_VisionController.h" +#include "TcpServer.h" +#include "IOController.h" + +class VisionController : public QMainWindow +{ + Q_OBJECT + +public: + VisionController(QWidget *parent = Q_NULLPTR); + ~VisionController(); +protected: + virtual void closeEvent(QCloseEvent *event); + +private: + Ui::VisionControllerClass ui; + + Q_SLOT void onButtonClicked(); + Q_SLOT void newConnected(QString ip, quint16 port); + Q_SLOT void receivedData(QString ip, quint16 port, const QByteArray &dataByte); + Q_SLOT void onDisconnected(QString ip, quint16 port); + bool readServerConfig(QString path, QString& serverIP, quint16& port); + bool writeServerConfig(QString path, QString serverIP, quint16 port); + TcpServer* m_tcpServerPtr; + IOController* m_ioControllerPtr{nullptr}; + //IOInterface* m_ioInterfacePtr{ nullptr }; +}; diff --git a/src/VisionController/main.cpp b/src/VisionController/main.cpp new file mode 100644 index 0000000..f0926b2 --- /dev/null +++ b/src/VisionController/main.cpp @@ -0,0 +1,10 @@ +#include "VisionController.h" +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + VisionController w; + w.show(); + return a.exec(); +} diff --git a/tpvs17/IOController/IOController.vcxproj b/tpvs17/IOController/IOController.vcxproj new file mode 100644 index 0000000..ee9512e --- /dev/null +++ b/tpvs17/IOController/IOController.vcxproj @@ -0,0 +1,115 @@ + + + + + Debug + x64 + + + Release + x64 + + + + {FB680084-3EA6-4ECA-BC68-2644C45CC825} + Qt4VSv1.0 + 10.0.17763.0 + + + + DynamicLibrary + v141 + + + DynamicLibrary + v141 + + + + $(MSBuildProjectDirectory)\QtMsBuild + + + $(SolutionDir)$(Platform)\$(Configuration)\ + + + $(SolutionDir)$(Platform)\$(Configuration)\ + + + + + + + + + + + + + + + + + + + true + UNICODE;_UNICODE;WIN32;WIN64;QT_DLL;QT_CORE_LIB;IOCONTROLLER_LIB;%(PreprocessorDefinitions) + .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;%(AdditionalIncludeDirectories) + Disabled + ProgramDatabase + MultiThreadedDebugDLL + true + + + Windows + $(OutDir)\$(ProjectName).dll + $(QTDIR)\lib;%(AdditionalLibraryDirectories) + true + qtmaind.lib;Qt5Cored.lib;%(AdditionalDependencies) + + + UNICODE;_UNICODE;WIN32;WIN64;QT_DLL;QT_CORE_LIB;IOCONTROLLER_LIB;%(PreprocessorDefinitions) + .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;%(AdditionalIncludeDirectories) + + + + + true + UNICODE;_UNICODE;WIN32;WIN64;QT_DLL;QT_NO_DEBUG;NDEBUG;QT_CORE_LIB;IOCONTROLLER_LIB;%(PreprocessorDefinitions) + .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(SolutionDir)..\src\IOController\NewSdkInc;%(AdditionalIncludeDirectories) + + MultiThreadedDLL + true + + + Windows + $(SolutionDir)..\runner17\$(ProjectName).dll + $(QTDIR)\lib;$(QTDIR);$(OutDir);%(AdditionalLibraryDirectories) + false + qtmain.lib;Qt5Core.lib;MvIOInterfaceBox.lib;%(AdditionalDependencies) + + + UNICODE;_UNICODE;WIN32;WIN64;QT_DLL;QT_NO_DEBUG;NDEBUG;QT_CORE_LIB;IOCONTROLLER_LIB;%(PreprocessorDefinitions) + .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(SolutionDir)..\src\IOController\NewSdkInc;%(AdditionalIncludeDirectories) + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tpvs17/IOController/IOController.vcxproj.filters b/tpvs17/IOController/IOController.vcxproj.filters new file mode 100644 index 0000000..0280666 --- /dev/null +++ b/tpvs17/IOController/IOController.vcxproj.filters @@ -0,0 +1,50 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E} + qrc;* + false + + + {D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E} + qrc;* + false + + + {71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11} + moc;h;cpp + False + + + {549a6910-6555-4b27-a3de-dec5b66aca6a} + + + + + Header Files\NewSdkInc + + + Header Files\NewSdkInc + + + Header Files\NewSdkInc + + + Header Files + + + + + Source Files + + + \ No newline at end of file diff --git a/tpvs17/IOController/IOController.vcxproj.user b/tpvs17/IOController/IOController.vcxproj.user new file mode 100644 index 0000000..4195e6b --- /dev/null +++ b/tpvs17/IOController/IOController.vcxproj.user @@ -0,0 +1,12 @@ + + + + + D:\Qt\Qt5.9.4\5.9.4\msvc2017_64 + PATH=$(QTDIR)\bin%3b$(PATH) + + + D:\Qt\Qt5.9.4\5.9.4\msvc2017_64 + PATH=$(QTDIR)\bin%3b$(PATH) + + \ No newline at end of file diff --git a/tpvs17/TcpServer/TcpServer.vcxproj b/tpvs17/TcpServer/TcpServer.vcxproj new file mode 100644 index 0000000..d817062 --- /dev/null +++ b/tpvs17/TcpServer/TcpServer.vcxproj @@ -0,0 +1,117 @@ + + + + + Debug + x64 + + + Release + x64 + + + + {58DB7028-F0B5-4D49-AE6C-F29CE2942198} + Qt4VSv1.0 + 10.0.17763.0 + + + + DynamicLibrary + v141 + + + DynamicLibrary + v141 + + + + $(MSBuildProjectDirectory)\QtMsBuild + + + $(SolutionDir)$(Platform)\$(Configuration)\ + + + $(SolutionDir)$(Platform)\$(Configuration)\ + + + + + + + + + + + + + + + + + + + true + UNICODE;_UNICODE;WIN32;WIN64;QT_DLL;QT_CORE_LIB;QT_NETWORK_LIB;TCPSERVER_LIB;%(PreprocessorDefinitions) + .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtNetwork;%(AdditionalIncludeDirectories) + Disabled + ProgramDatabase + MultiThreadedDebugDLL + true + + + Windows + $(OutDir)\$(ProjectName).dll + $(QTDIR)\lib;%(AdditionalLibraryDirectories) + true + qtmaind.lib;Qt5Cored.lib;Qt5Networkd.lib;%(AdditionalDependencies) + + + UNICODE;_UNICODE;WIN32;WIN64;QT_DLL;QT_CORE_LIB;QT_NETWORK_LIB;TCPSERVER_LIB;%(PreprocessorDefinitions) + .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtNetwork + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + Moc'ing %(Identity)... + + + + + true + UNICODE;_UNICODE;WIN32;WIN64;QT_DLL;QT_NO_DEBUG;NDEBUG;QT_CORE_LIB;QT_NETWORK_LIB;TCPSERVER_LIB;%(PreprocessorDefinitions) + .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtNetwork;%(AdditionalIncludeDirectories) + None + MultiThreadedDLL + true + MaxSpeed + + + Windows + $(SolutionDir)..\runner17\$(ProjectName).dll + $(QTDIR)\lib;%(AdditionalLibraryDirectories) + false + qtmain.lib;Qt5Core.lib;Qt5Network.lib;%(AdditionalDependencies) + + + UNICODE;_UNICODE;WIN32;WIN64;QT_DLL;QT_NO_DEBUG;NDEBUG;QT_CORE_LIB;QT_NETWORK_LIB;TCPSERVER_LIB;%(PreprocessorDefinitions) + .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtNetwork + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + Moc'ing %(Identity)... + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tpvs17/TcpServer/TcpServer.vcxproj.filters b/tpvs17/TcpServer/TcpServer.vcxproj.filters new file mode 100644 index 0000000..3021139 --- /dev/null +++ b/tpvs17/TcpServer/TcpServer.vcxproj.filters @@ -0,0 +1,38 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E} + qrc;* + false + + + {D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E} + qrc;* + false + + + {71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11} + moc;h;cpp + False + + + + + Source Files + + + + + Header Files + + + \ No newline at end of file diff --git a/tpvs17/TcpServer/TcpServer.vcxproj.user b/tpvs17/TcpServer/TcpServer.vcxproj.user new file mode 100644 index 0000000..4195e6b --- /dev/null +++ b/tpvs17/TcpServer/TcpServer.vcxproj.user @@ -0,0 +1,12 @@ + + + + + D:\Qt\Qt5.9.4\5.9.4\msvc2017_64 + PATH=$(QTDIR)\bin%3b$(PATH) + + + D:\Qt\Qt5.9.4\5.9.4\msvc2017_64 + PATH=$(QTDIR)\bin%3b$(PATH) + + \ No newline at end of file diff --git a/tpvs17/VisionController.sln b/tpvs17/VisionController.sln new file mode 100644 index 0000000..f22d4ee --- /dev/null +++ b/tpvs17/VisionController.sln @@ -0,0 +1,37 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28307.852 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VisionController", "VisionController\VisionController.vcxproj", "{B12702AD-ABFB-343A-A199-8E24837244A3}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "IOController", "IOController\IOController.vcxproj", "{FB680084-3EA6-4ECA-BC68-2644C45CC825}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TcpServer", "TcpServer\TcpServer.vcxproj", "{58DB7028-F0B5-4D49-AE6C-F29CE2942198}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|x64.ActiveCfg = Debug|x64 + {B12702AD-ABFB-343A-A199-8E24837244A3}.Debug|x64.Build.0 = Debug|x64 + {B12702AD-ABFB-343A-A199-8E24837244A3}.Release|x64.ActiveCfg = Release|x64 + {B12702AD-ABFB-343A-A199-8E24837244A3}.Release|x64.Build.0 = Release|x64 + {FB680084-3EA6-4ECA-BC68-2644C45CC825}.Debug|x64.ActiveCfg = Debug|x64 + {FB680084-3EA6-4ECA-BC68-2644C45CC825}.Debug|x64.Build.0 = Debug|x64 + {FB680084-3EA6-4ECA-BC68-2644C45CC825}.Release|x64.ActiveCfg = Release|x64 + {FB680084-3EA6-4ECA-BC68-2644C45CC825}.Release|x64.Build.0 = Release|x64 + {58DB7028-F0B5-4D49-AE6C-F29CE2942198}.Debug|x64.ActiveCfg = Debug|x64 + {58DB7028-F0B5-4D49-AE6C-F29CE2942198}.Debug|x64.Build.0 = Debug|x64 + {58DB7028-F0B5-4D49-AE6C-F29CE2942198}.Release|x64.ActiveCfg = Release|x64 + {58DB7028-F0B5-4D49-AE6C-F29CE2942198}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {62AB1429-5087-41C5-9263-67FBA9A870BB} + EndGlobalSection +EndGlobal diff --git a/tpvs17/VisionController/VisionController.qrc b/tpvs17/VisionController/VisionController.qrc new file mode 100644 index 0000000..771800c --- /dev/null +++ b/tpvs17/VisionController/VisionController.qrc @@ -0,0 +1,4 @@ + + + + diff --git a/tpvs17/VisionController/VisionController.ui b/tpvs17/VisionController/VisionController.ui new file mode 100644 index 0000000..9bed01d --- /dev/null +++ b/tpvs17/VisionController/VisionController.ui @@ -0,0 +1,214 @@ + + + VisionControllerClass + + + + 0 + 0 + 631 + 495 + + + + VisionController + + + + + + 10 + 0 + 611 + 441 + + + + Pannel + + + + + 10 + 20 + 271 + 131 + + + + Server Setting + + + + + 20 + 30 + 231 + 31 + + + + + + + IP: + + + + + + + + + + Port: + + + + + + + + + + + + 40 + 80 + 191 + 31 + + + + + + + Start + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Stop + + + + + + + + + + 320 + 30 + 281 + 191 + + + + Text Log + + + + + 20 + 20 + 251 + 131 + + + + + + + 20 + 160 + 75 + 23 + + + + Clear + + + + + + + 10 + 180 + 281 + 251 + + + + Client List + + + + + 10 + 20 + 261 + 221 + + + + + Num + + + + + IP + + + + + Port + + + + + + + + + + 0 + 0 + 631 + 23 + + + + + + TopToolBarArea + + + false + + + + + + + + + + diff --git a/tpvs17/VisionController/VisionController.vcxproj b/tpvs17/VisionController/VisionController.vcxproj new file mode 100644 index 0000000..6b3cbe3 --- /dev/null +++ b/tpvs17/VisionController/VisionController.vcxproj @@ -0,0 +1,140 @@ + + + + + Debug + x64 + + + Release + x64 + + + + {B12702AD-ABFB-343A-A199-8E24837244A3} + Qt4VSv1.0 + 10.0.17763.0 + + + + Application + v141 + + + Application + v141 + + + + $(MSBuildProjectDirectory)\QtMsBuild + + + $(SolutionDir)$(Platform)\$(Configuration)\ + + + $(SolutionDir)$(Platform)\$(Configuration)\ + + + + + + + + + + + + + + + + + + + true + UNICODE;_UNICODE;WIN32;WIN64;QT_DLL;QT_CORE_LIB;QT_GUI_LIB;QT_NETWORK_LIB;QT_WIDGETS_LIB;%(PreprocessorDefinitions) + .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtNetwork;$(QTDIR)\include\QtWidgets;%(AdditionalIncludeDirectories) + Disabled + ProgramDatabase + MultiThreadedDebugDLL + true + + + Windows + $(OutDir)\$(ProjectName).exe + $(QTDIR)\lib;%(AdditionalLibraryDirectories) + true + qtmaind.lib;Qt5Cored.lib;Qt5Guid.lib;Qt5Networkd.lib;Qt5Widgetsd.lib;%(AdditionalDependencies) + + + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + Moc'ing %(Identity)... + .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtNetwork;$(QTDIR)\include\QtWidgets;%(AdditionalIncludeDirectories) + UNICODE;_UNICODE;WIN32;WIN64;QT_DLL;QT_CORE_LIB;QT_GUI_LIB;QT_NETWORK_LIB;QT_WIDGETS_LIB;%(PreprocessorDefinitions) + + + Uic'ing %(Identity)... + .\GeneratedFiles\ui_%(Filename).h + + + Rcc'ing %(Identity)... + .\GeneratedFiles\qrc_%(Filename).cpp + + + + + true + UNICODE;_UNICODE;WIN32;WIN64;QT_DLL;QT_NO_DEBUG;NDEBUG;QT_CORE_LIB;QT_GUI_LIB;QT_NETWORK_LIB;QT_WIDGETS_LIB;%(PreprocessorDefinitions) + .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtNetwork;$(QTDIR)\include\QtWidgets;$(SolutionDir)..\src\TcpServer;$(SolutionDir)..\src\IOController;$(SolutionDir)..\src\IOController\NewSdkInc;$(SolutionDir)..\src\VisionController;$(OutDir);%(AdditionalIncludeDirectories) + None + MultiThreadedDLL + true + MaxSpeed + + + Windows + $(SolutionDir)..\runner17\$(ProjectName).exe + $(QTDIR)\lib;$(OutDir);%(AdditionalLibraryDirectories) + false + qtmain.lib;Qt5Core.lib;Qt5Gui.lib;Qt5Network.lib;Qt5Widgets.lib;IOController.lib;TcpServer.lib;%(AdditionalDependencies) + + + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + Moc'ing %(Identity)... + .\GeneratedFiles;.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtNetwork;$(QTDIR)\include\QtWidgets;$(SolutionDir)..\src\TcpServer;$(SolutionDir)..\src\IOController;$(SolutionDir)..\src\IOController\NewSdkInc;$(SolutionDir)..\src\VisionController;%(AdditionalIncludeDirectories) + UNICODE;_UNICODE;WIN32;WIN64;QT_DLL;QT_NO_DEBUG;NDEBUG;QT_CORE_LIB;QT_GUI_LIB;QT_NETWORK_LIB;QT_WIDGETS_LIB;%(PreprocessorDefinitions) + + + Uic'ing %(Identity)... + .\GeneratedFiles\ui_%(Filename).h + + + Rcc'ing %(Identity)... + .\GeneratedFiles\qrc_%(Filename).cpp + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tpvs17/VisionController/VisionController.vcxproj.filters b/tpvs17/VisionController/VisionController.vcxproj.filters new file mode 100644 index 0000000..31b1a61 --- /dev/null +++ b/tpvs17/VisionController/VisionController.vcxproj.filters @@ -0,0 +1,55 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E} + qrc;* + false + + + {99349809-55BA-4b9d-BF79-8FDBB0286EB3} + ui + + + {D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E} + qrc;* + false + + + {71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11} + moc;h;cpp + False + + + + + Form Files + + + + + Resource Files + + + + + Source Files + + + Source Files + + + + + Header Files + + + \ No newline at end of file diff --git a/tpvs17/VisionController/VisionController.vcxproj.user b/tpvs17/VisionController/VisionController.vcxproj.user new file mode 100644 index 0000000..2ad395e --- /dev/null +++ b/tpvs17/VisionController/VisionController.vcxproj.user @@ -0,0 +1,14 @@ + + + + + D:\Qt\Qt5.9.4\5.9.4\msvc2017_64 + PATH=$(QTDIR)\bin%3b$(PATH) + + + D:\Qt\Qt5.9.4\5.9.4\msvc2017_64 + $(SolutionDir)..\runner17\$(ProjectName).exe + WindowsLocalDebugger + PATH=$(QTDIR)\bin%3b$(PATH) + + \ No newline at end of file diff --git a/tpvs17/x64/Release/MvIOInterfaceBox.lib b/tpvs17/x64/Release/MvIOInterfaceBox.lib new file mode 100644 index 0000000000000000000000000000000000000000..55387e01a831b8d170d21a6613ac34afe1193bd2 GIT binary patch literal 8528 zcmcIpOLG%P5N>4iumH#S{lp?g0wfh<*_I7e2}rgS5ZIC;8zo| z&8OUQ<-jk<58y;`;=myXiUURE$bnzLfhwnGXLdX@JG<5fu~qHWcK6KJGt-Zm@tN<9 zdhza+@WqJyL}Qny=jNi(sY^0{l6^+!rkP|d3;;g>bXovi&jGqa07EY*jZ6X%>itM* zcpiXI|657}w*d%^c2gR!0uVa=fzlZA2@SraG;{;|MH<_sH1G=BBlSL_)Pp#L`qwB$ z-T>INj&G#F45iZ#v428nI-&9Rl!l+8eMlouD2+ZwyO8?cF+$t=ka}z?6w*t%Y<{JX zOf4_u)47#wzOZyZolRFQvwp`Yn)9_CC=@cc78l)`@Q12O6<4m`%G@j@6DtW=S}mlr zg=?m@oV>Ye)*Izo6}u~MZWVMA%FAwgZ$2>UriWpwn72z;x3;ZC^S)V;EWuF<5~`gyH_8p1%2a8?Oq!Niv~UI%j7nwR zDBhD=`)ktPmQ5?WZ6SE7YOGh}A*wQ^g@na*+4|tOZMmvMnS9*2TAk|UjJmNYDdX4` zsnm*E?b%EebGsMI8+R>t6SP&3a1?>3_?IA|+KEP^RxBHqSwdW5wKNj9^eQ(gX|8W? ztd`9O@%XQaU()g0tfij@ZJgREZd+z9lhdr6Dx)oaE>|&f($%tTp1>CMlBS0y6Hr}T zr6mLV_4HpwN?YNK6Fyxex7%yPQoC!pY$21&NR!OkI3li}UtXwH@02%GWzMIXwwait zl(`YuR4;F?*J|?oF_t55px?TjId5_{)k~TUt6uy4x=}4DQ722N_Cno6=h7%kf~!|& z?A0w)YQ=kvc*82i<3FVmi9{-~IvI^8QuE}s?_$lW2d{#$DOwQM!e_9KSe*dRy8uF1 zvtA4VOpXA2>;;$~26)>KaC-pj<0wFN9N+^Mp6)S#mxBN|P6zTWj=e@Nu1VmmCwa0Ysy8;-y@R<~X_1|4t;2A~tZ zfOa?vBXAf-Aq-=161rdr2H^x8hhgZ4J~#xSPiWl+O|Q(sVed{R%th=nrg0aYzfqn( zOJGDdQ>JJasO(CH?v%iFn@#Avfl%WqPg8bXF)9>yB{uykC+*)AsF+v8nuVXP0V9vt z;7UD&DW*7zfZCL~Un%J~%i~;2$xt*+OUYNr+@H4VqV=t5FJ7aVAQY3WP5@he)P)P>-=`r@>mdwA%(d?R&qSJ_K0T=rd6wTg$V{ z>=W>S2!A>s>>Y=$`H6DLu#B@)jtC1ayhg&qpZ&Dq-#AP@V|ufUjdc;R5YN#g{5V9O zh44LswUs=*x}lzfp01-P{Kr-STeV}Sd#PNk*BZ4uR^)vCLS!+Wxyj_x>jZugiwFVM zZSo7Z7FfHklt~p!@kHX1SS0YY5BSd|8$(ANpG5pU1plZn?klXJ-4kTHUsFqiHt*h z1aF#l_{5w3c0SmfcoUhI&*vr0tT=8gaTPqSAp%F^^yG{%e>58LdIVRSKDznyiN+Xf zW=HdD=YzfD5O<<+#u1UI|JV5t^giD_H#5gyqb05P)l2Mj5y4yvc0`wUN%p&9kGsA3 z-L^Je1kJ;6Lr2|5piSW6bpw3%)}O4q=Y;+JOY}-c^w~^YR23~2QhKqhj@_jqUm3OIH;J|Y{>oLdQBJyF5 ztnPwaggvWY-wDJ%!m%~GY%P2%=lrOME^Okpz`^I-XSI)s$iiN?MaVw!+#w<>hmg;Y z9v0D+Lr#m(eZ1|siY^|awD7I;wi6<{a7NPt2lqCgoOY5UOJ_hWaL^IQ_{A~`6