美文网首页C++
Vscode mingw下opencv及多线程C++socket

Vscode mingw下opencv及多线程C++socket

作者: applecai | 来源:发表于2019-05-12 22:23 被阅读2次
    目的:由于vslam都是用c++开发的,所以要多练习c++11,所以就自己设计项目来练手
    立项:(适用于0.1版本)
    名称:Display
    功能:一个client将数据集中的png图片读取,通过tcp socket协议传输给server端显示。
    其中特殊控制功能包括如下:
            Server端的按键s是控制socket传输数据的开关,
            按键j是控制是否将当前传输的图片数据实时显示的开关。
    工具链:coding用Vscode,编译用CMake+MinGw8.1(环境搭建可以参考我之前的文章)
    数据集:在client端是读取png的数据集
    

    工程共享路径: https://github.com/AppleCai/Display

    一,0.1版基本设计说明:

    1.1 Server端:

    1.1 Server端:
        1.1.1主进程下有2个线程—一个是key按键扫描
             另一个是server的socket通信传输数据及imshow显示图片。
        1.1.2添加了锁,用于按钮s键暂停socket传输的功能,此时会挂起server线程。
             当再次按s键后,在key线程中可以触发server线程唤醒。
        1.1.3由于有特殊控制功能,所以添加了策略模式的设计。
             可以选择不同的控制显示的方式。
    1.2 client端:
        用作配合server的测试code,忽略设计。
    

    二,后续更新版本说明:

    2.1优化client和server间的通信协议。添加crc校验及各类出错处理。
    2.2 Socket添加心跳包监控及重连接尝试。
    2.3 HMI显示和socket传输分离为2个线程。
    2.4 HMI图片显示添加ROI区域显示张数及叠加特质logo。
    2.5 添加对图片的监视作用,添加弹窗报警及logDTC记录。(目的是使用进程间通信D-bus和共享内存)
    2.6 Server端切换到linux上。
    2.7 添加守护进程。
    2.8 进行性能测试,进行优化。
    

    三,0.1版设计图(详见Design文件夹中的word说明文档)

    3.1 server端的3个对象关于按键的控制说明

    按键时序说明.png

    3.2 socket通信数据的应用协议说明

    socket数据协议.png

    3.3 server端的类图

    类图.png

    四,运行效果图

    运行效果.png

    五,代码片段

    server.hpp文件

        #ifndef SERVER_HPP
        #define SERVER_HPP
        #include "key.hpp"
        #include "head.hpp"
        
        #define BUFFER_SIZE 1024
        
        /* socket通信基类 */
        class baseServer
        {
        public:
          enum status
          {
            E_OK = 0,
            E_NOK = -1
          };
          baseServer();
          ~baseServer(){};
          int socketCreate(int type, int way, int ip, int port);
          int socketBind(void);
          int socketListen(int num);
          int socketAccept(void);
          //virtua void socketDataHandler(void);
          virtual void socketDataHandler() = 0;
          int socketDisconnect(void);
          int socketCloseServer(void);
          int getConnectfd(void);
        
        private:
          int serverfd, connectfd;
          struct sockaddr_in serveraddr;
        };
        
        /* socket通信继承类 */
        class ServerEx : public baseServer
        {
        public:
          ServerEx();
          ~ServerEx(){};
          void socketDataHandler();
          void ReceiveFrame();
          void DisplayFrame();
          void HMIControlStrategy(char cmd);
          cv::Mat &GetImg();
          void server();
        
        private:
          struct _Msg
          {
            int length = 0;
            unsigned char cokstart[1] = {0};
            unsigned char buffer[BUFFER_SIZE];
          } Msg;
          std::vector<uchar> vec;
          cv::Mat img_decode;
        };
        
        /* 策略模式:用于按键对HMI显示的控制策略 */
        class myLock;
        class HMICtrl
        {
        public:
          HMICtrl() : _en(TRUE){};
          ~HMICtrl(){};
          void transmitCtrl();
          void transmitCtrlCfg(bool en);
          bool getTransmitCtrlCfg();
          void FrameTerminal();
          virtual void ActionInterface() = 0;
          ServerEx *myServerEx;
        protected:
          myLock *keylock;
        private:
          bool _en;
        };
        class keysearch;
        class HMICtrlEnable : public HMICtrl
        {
        public:
          HMICtrlEnable(keysearch *keysearch) : _cmd('j'), _keysearch(keysearch){};
          ~HMICtrlEnable(){};
          virtual void ActionInterface();
        
        private:
          char _cmd;
          keysearch *_keysearch;
        };
        
        class HMICtrlDisable : public HMICtrl
        {
        public:
          HMICtrlDisable(){};
          ~HMICtrlDisable(){};
          virtual void ActionInterface();
        };
        
        class Context
        {
        public:
          Context(HMICtrl *hmiCtrl);
          ~Context();
          void HMIcontrol();
        
        private:
          HMICtrl *_HMICtrl;
        };
        
        #endif
    

    key.hpp文件

        #ifndef KEY_HPP
        #define KEY_HPP
        
        #include "head.hpp"
        #include "server.hpp"
        extern std::mutex mtx;
        extern std::condition_variable event;
        
        class myLock
        {
        public:
          myLock(){};
          ~myLock(){};
          void startLock();
          void stopLock();
          void waitEvent();
          void eventTrigger();
        
        private:
        };
        
        class keysearch
        {
        public:
          keysearch();
          ~keysearch(){};
          bool getJumpInfo();
          int KeyDetect();
          bool getTransCmd();
        
        private:
          bool jump;
          bool status;
          myLock *keylock;
        };
        extern keysearch k;
        
        #endif
    

    main.c

        #include "head.hpp"
        #include "key.hpp"
        #include "server.hpp"
        
        /* key=j means stop HMI, but the transmit is keep */
        /* key=s means stop transmit, so the HMI also stop */
        
        int main(void)
        {
          ServerEx ser;
          using namespace std;
          thread t1(&ServerEx::server, ser);
          cout << "start" << endl;
          thread t2(&keysearch::KeyDetect, ref(k));
          t1.join();
          t2.join();
          getchar();
          return 0;
        }
    

    六,历史记录

    历史记录.png

    相关文章

      网友评论

        本文标题:Vscode mingw下opencv及多线程C++socket

        本文链接:https://www.haomeiwen.com/subject/zcwhaqtx.html