`

由云台协议DLL浅谈插件程序的编写(上)

    博客分类:
  • C#
 
阅读更多
前言:本文通过一个简单的工程描述了一种插件设计的思想。复杂设计和模块化分解能力是衡量一个程序员水平的重要标志,欢迎大家和我探讨。
1.我们的目的是在Plug-Ins目录里面查找“ptz*.dll”格式的云台插件的动态链接库。每个库可支持多个协议,通过查找该目录下的合法插件,有此插件创建出某个协议的实例,达到通过该协议操作云台的目的。
2.结构体定义:ComParam为串口通信参数:(定义在include/ComManager/ComParam.h文件中)

class COMPARAMEXT_API ComParam

{

public:

       ComParam(  int nBaudRate,                        // 波特率

                             int nByteSize = 8,                  // 数据位

                             int nParity = 0,                      // 校验位 0 - NOPARITY

                             int nStopBits = 0);                // 停止位 0 - ONESTOPBIT(参考winbase.h中的定义)

};

3.为了达到使用dll的目的,先封装几个简单的类:

CDllLoad类:src/PTZ_Test/controls/DllLoad.h(这个类仅在src/PTZ_Test/controls/PTZDll.h)

// DllLoad.h
#pragma once 

class CDllLoad
{
public:

    CDllLoad()

    {
    }
    virtual ~CDllLoad(void)
    {
         Close();
    }

    void Open(LPCTSTR lpszName) // 加载DLL
    {
         if (m_hModule)
         {
              Close();
         }
         m_hModule = ::LoadLibrary(lpszName);
    }

    void Close()
    {
         ::FreeLibrary(m_hModule);  // 卸载DLL
         m_hModule = NULL;
    }

    operator  HMODULE() { return m_hModule;}

    PROC GetProcAddress(LPCSTR lpProcName)
    {
         return ::GetProcAddress(m_hModule, lpProcName);    // 取得函数入口地址
    }

protected:
    HMODULE m_hModule;
};
CPTZDll类:src/PTZ_Test/controls/DllLoad.h(主要功能:根据插件产生出该DLL的支持的协议对象,然后由该对象的函数调用需要的功能,由于函数调用时实际使用的是dll的类的成员函数,所以对象存在时必须也有一份CPTZDll的实例而且是打开状态的。)
// PTZDll.h
#pragma once 

#include "DllLoad.h" 
#include "PTZInterface.h" 

class CPTZDll
{
    typedef CPTZInterface * (__stdcall* CREATE_PTZ_INSTANCE)(const char * pszProtocolsName);
public:
    CPTZDll()    // 成员初始化
        : m_pDllLoad(0)
        , m_pfnCreatePTZInstance(0)
        , m_ppProtocolsName(0)
    {
    }

    ~CPTZDll()
    {
         Close();

         delete m_pDllLoad;
         m_pDllLoad =0;
    }

    BOOL OpenPlugIn(LPCTSTR lpszName)    // 打开插件,如果是有效的插件返回TRUE,否则FALSE
    {
         if (m_pDllLoad)
              Close();
         else
         {
              m_pDllLoad = new CDllLoad();
              m_pDllLoad->Open(lpszName);
         }

         m_pfnCreatePTZInstance = (CREATE_PTZ_INSTANCE)m_pDllLoad->GetProcAddress("CreatePTZInstance");
         m_ppProtocolsName = (const char **)m_pDllLoad->GetProcAddress("ProtocolNames");

         return (m_ppProtocolsName && m_ppProtocolsName[0]);
    }

    void Close()
    {
         m_pfnCreatePTZInstance = 0;
         m_ppProtocolsName = 0;

        if (m_pDllLoad)
            m_pDllLoad->Close();
    }

    const char ** GetSupportProtocols()
    {
        return m_ppProtocolsName;
    }

    CPTZInterface * CreatePTZInstance(LPCTSTR lpszProtolName)    // 根据该插件内的某个协议产生出一个对象
    {
            if (m_pfnCreatePTZInstance)
        {
            return m_pfnCreatePTZInstance(lpszProtolName);
        }

        return 0;
}

private:
    CDllLoad * m_pDllLoad;

    CREATE_PTZ_INSTANCE m_pfnCreatePTZInstance;

    const char ** m_ppProtocolsName;
};
CPlugInInfo类:src/PTZ_Test/controls/PTZProtocolFind.h和src/PTZ_Test/controls/ptzprotocolfind.cpp

//=========================================================
//

// Copyright (c) 2000-2004  iWise Technologies,Co. Ltd.
// All Rights Reserved.
//
// Product: iW988
// File: PTZProtocolFind.h
// Created: 天衣有缝
// Data :2004.12.22 PM

// Description:
//     ValueAdded main program for iW988.
//                   Contact:
//                       waterpub@mail.csdn.net
//
//=========================================================

#pragma once

 

class CPlugInInfo    // 插件信息类
{
public:
    string szFileName                ; // 文件名
    vector<string>                      Protocols                   ; // 协议列表
    string szFullPath    ; // 文件全路径

public:
    CPlugInInfo(void)
    {
    }
    ~CPlugInInfo(void)
    {
    }
};

class CPTZProtocolFind
{
public:
    CPTZProtocolFind(void);
    ~CPTZProtocolFind(void);

public:
    void EnumPlugIns(vector<CPlugInInfo>& PlugInList); // 枚举Plug-Ins目录的所以ptz文件
};

//=========================================================
//

// Copyright (c) 2000-2004  iWise Technologies,Co. Ltd.
// All Rights Reserved.
//
// Product: iW988
// File: PTZProtocolFind.cpp
// Created: 天衣有缝
// Data :2004.12.22 PM
// Description:
//     ValueAdded main program for iW988.
//                   Contact:
//                       waterpub@mail.csdn.net
//
//=========================================================

#include "StdAfx.h" 
#include "ptzprotocolfind.h" 
#include "PTZDll.h" 

CPTZProtocolFind::CPTZProtocolFind(void)
{
}

CPTZProtocolFind::~CPTZProtocolFind(void)
{
}
// 枚举“Plug-Ins”目录下的所有有效插件
void CPTZProtocolFind::EnumPlugIns(vector<CPlugInInfo>& PlugInList)
{
    char szFilePath[MAX_PATH];
    ::GetModuleFileName(NULL, szFilePath, MAX_PATH);
    char * pFind = strrchr(szFilePath, '//');
    *pFind = '/0';
    strcat(szFilePath, "//Plug-Ins//ptz*.dll"); // 查找的匹配字符串

    CFileFind find;
    BOOL bFind;
    bFind = find.FindFile(szFilePath);
    while (bFind)
    {
        CPTZDll dll;
        bFind = find.FindNextFile();
        if (find.IsArchived()) // 文件而非文件夹
        {
            // 输出这个文件:
            XTRACE("路径:%s/n", find.GetFilePath());
            if ( dll.OpenPlugIn(find.GetFilePath()) ) // 如果是云台插件,则枚举出它的协议
            {
                CPlugInInfo info;
                const char ** ppProtocols = dll.GetSupportProtocols();
                if(!ppProtocols)
                {
                    continue;
                }
                while(0 != *ppProtocols)
                {
                    string _string = *ppProtocols;
                    info.Protocols.push_back(_string);
                    ppProtocols ++;
                }
                info.szFullPath = find.GetFilePath();
                info.szFileName = find.GetFileName();
                PlugInList.push_back(info);
            }
        }
        dll.Close();
    }
    find.Close();
    // 下面是调试代码
    XTRACE("插件数量:%d/n",PlugInList.size());
    vector<CPlugInInfo>::iterator it = PlugInList.begin();
    for(; it != PlugInList.end(); it++)
    {
        XTRACE("文件名:%s----》文件路径:%s/n", (*it).szFileName.c_str(), (*it).szFullPath.c_str());
    }
}
4.在对话框工程的窗体中加入两个成员变量:
CPTZDll         m_PTZdll          ; // dll加载对象
CPTZInterface*  m_PTZInterface    ; // 正在使用的插件协议对象
用户选择一个插件:BOOL bReturn = m_PTZdll.OpenPlugIn(m_strProtocolPath);
然后根据该插件选择一个协议:m_PTZInterface = m_PTZdll.CreatePTZInstance(m_strProtocolName);    // 参数是一个表示协议的字符串
这时我们可以利用这个m_PTZInterface对象来执行各种操作。
说明:m_PTZInterface的类“CPTZInterface”是一个抽象类,由此派生出各种各样的协议。
其定义如下:
//PTZInterface.h
//iWise DVR PTZ Interface define header file.

#pragma once 

#include "PTZDef.h" 
#include "ComParam.h" 

class CPTZInterface
{
public:
	virtual void SetPTZSettings(int nComPort, int nAddrID, const ComParam & param) = 0;
	virtual void Move(MOVEMENT_DIR nDirection) = 0;
	virtual void Action(int nActionID, int param) = 0;
	virtual int SetSpeed(int nSpeedTrgID, int nSpeed) = 0;
	virtual void DeviceSwitch(int nDeviceID, bool bSwitchOn) = 0;
	virtual int SetPreset(int nIndex) = 0;
	virtual int CallPreset(int nIndex) = 0;
	virtual void Reset() = 0;
	virtual int SelfCheck() = 0;
	virtual int GetCaps(int nCapID, void * lParam) = 0;
	virtual int ExtendOp(int nExOpID, void * lParam) = 0;
	virtual void Destroy() = 0;
};

 

 

参考文档:

云台控制协议插件开发文档

本文档描述有关iWise-DVR云台控制协议插件的程序结构、设计原理、插件接口等重要信息,iWisePTZTest为插件的测试程序(插件也可以直接放到iWise-DVR环境中测试)。本文档以下出现的“DVR”均指“iWise-DVR”,本文档适用于使用串口的云台控制设备的基于DVR的云台控制协议插件的开发。

插件工作原理

云台控制有多种不同的控制协议,DVR提供统一的插件接口以支持不同的云台控制协议,通过协议插件来进行对云台的控制操作。DVR启动时会扫描Plug-Ins目录里面的所有文件名以“ptz”开头的动态连接库(DLL),并判断这些DLL是否为有效的云台控制协议插件。DVR定义了一套云台控制的基本操作,插件必须提供这些操作的具体实现,当用户要对云台进行控制时,DRV最终将调用插件的方法来控制云台,插件需要根据协议特征产生相应的指令数据并向串口设备发送这些指令。同时DVR提供向串口发送数据的统一的方法。

云台控制协议插件接口

DVR定义class CPTZInterface作为云台控制协议接口,该类是接口的核心,插件必须使用CPTZInterface派生一个类并实现所有的方法。CPTZInterface类详细定义如下:

class CPTZInterface

{

public:

     virtual void SetPTZSettings(int nComPort, int nAddrID,

const ComParam & param) = 0;

     virtual void Move(MOVEMENT_DIR nDirection) = 0;

     virtual void Action(int nActionID, int param) = 0;

     virtual int SetSpeed(int nSpeedTrgID, int nSpeed) = 0;

     virtual void DeviceSwitch(int nDeviceID, bool bSwitchOn) = 0;

     virtual int SetPreset(int nIndex) = 0;

     virtual int CallPreset(int nIndex) = 0;

     virtual void Reset() = 0;

     virtual int SelfCheck() = 0;

     virtual int GetCaps(int nCapID, void * lParam) = 0;

     virtual int ExtendOp(int nExOpID, void * lParam) = 0;

     virtual void Destroy() = 0;

};

SetPTZSettings函数设置云台设备所在的串口号、地址码及通信参数。

nComPort - 云台设备所在串口号

nAddrID  - 设备地址码

param    - 通信参数,ComParam结构的引用(请参考《iWise-DVR环境串口操作接口使用说明》)。

 

Move函数控制云台在各方向上的运动。

nDirection–运动方向,由MOVEMENT_DIR定义

enum MOVEMENT_DIR

{

      MD_STOP,         // 停止运动

      MD_LEFT,          // 向左

      MD_RIGHT,        // 向右

      MD_UP,            // 向上

      MD_DOWN,          // 向下

      MD_LEFT_UP,       // 左上

      MD_LEFT_DOWN,    // 左下

      MD_RIGHT_UP,     // 右上

      MD_RIGHT_DOWN,    // 右下

};

 

Action函数控制云台摄像机的动作。

nActionID–动作定义

ACTION_ZOOM 缩放,param = 0时为缩小 param = 1时为放大

ACTION_ZOOM_STOP 停止缩放

ACTION_FOCUS 聚焦,param = 0时为往近处聚焦 1为往远处

ACTION_FOCUS_STOP 停止聚焦

ACTION_AUTO_FOCUS 自动聚焦

ACTION_AUTO_FOCUS_STOP 停止自动聚焦

ACTION_AUTO_SCAN 自动扫描

ACTION_AUTO_SCAN_STOP 停止自动扫描

 

SetSpeed设置云台运动或摄像机动作的速度。

nSpeedTrgID–欲设置速度的目标

SPEED_TRG_PAN 水平方向运动

SPEED_TRG_TILT 垂直方向运动

ACTION_AUTO_SCAN 自动扫描

ACTION_AUTO_SCAN_STOP 停止自动扫描

nSpeed     –速度值 (0x00-0x40)

如果成功,该函数返回设置后的速度,否则返回0。

 

DeviceSwitch函数提供打开、关闭某设备的功能。

nDeviceID–设备ID定义

DEVICE_CAMERA照相机

DEVICE_LIGHT灯光

DEVICE_RAINBRUSH 雨刷

DEVICE_IRIS 镜头光圈

bSwitchOn–true为打开设备false为关闭设备

 

SetPreset函数设置预置点。

nIndex–预置点索引号,从1开始,使用GetCaps取得设备可以支持的预置点总数。

返回0为成功,否则失败

 

CallPreset函数调用预置点,将云台摄象机移动到指定预置点位置。

nIndex–预置点索引号,对使用SetPreset设置成功的索引号有效。

返回0为成功,否则失败

 

Reset函数使云台摄象机设备恢复到初始状态。

 

SelfCheck函数使云台摄象机设备自检。

返回0为成功,否则失败

 

GetCaps函数可以取得设备所能提供的能力。

nCapID–欲取得的能力的ID定义,请参考以下值

GC_BASAL 取得基本能力, lParam为指向PTZBasalCaps结构的指针。

lParam–指向特定能力结构的指针。

返回0为成功,否则失败

 

ExtendOp函数对CPTZInterface接口提供扩展功能。

nExOpID–扩展功能ID定义。

lParam–根据不同的nExOpID有不同的意义。

该函数目前未使用

 

Destroy函数负责销毁自身对象。

销毁方式必须和CreatePTZInstance的创建方式一致

 

设备基本能力结构定义:

struct PTZBasalCaps

{

int nSize;                  // PTZBasalCaps结构的大小

int nPresetCount;           // 支持预置点的个数

int nMinSpeed;              // 云台移动速度最小值

int nMaxSpeed;              // 云台移动速度最大值

bool bAutoScanSupported;   // 是否支持自动扫描

}

 

插件DLL接口约定

插件DLL在实现了CPTZInterface的具体实现方法之后,必须提供一致的构建和销毁CPTZInterface对象的方法,因此必须导出如下函数:

        CPTZInterface * __declspec(dllexport) CreatePTZInstance(

const char * pszProtocolsName);

pszProtocolsName – 协议索名称,该名称由GetSupportProtocols函数取得。

该函数构造一个协议接口对象并返回其指针,该函数创建的对象必须由CPTZInterface::Destroy()函数自销毁。为安全起见,插件在卸载时也可以销毁使用者没有销毁的所有对象。

        const char ** __declspec(dllexport) GetSupportProtocols();

nProtocols – 支持的协议数目

该函数返回插件所支持的协议名称列表指针

 

GetSupportProtocols代码示例:

char * szProtocol[] = {

    "PELCO-D",

    "PELCO-P",

    0          // 必须以0表示结束

};

 

const char ** __declspec(dllexport) GetSupportProtocols()

{

    return (const char **)szProtocol;

}

 

以上代码表示该插件支持"PELCO-D"、"PELCO-P"两种协议。

class CPTZInterface声明在ptzInterface.h中。

有关串口指令的发送请参考《iWise-DVR环境串口操作接口使用说明》。

分享到:
评论

相关推荐

    云台程序兼容各种协议主程序用vc++编写

    总结而言,这个云台控制程序是一个使用VC++编写的,具备多协议兼容性的软件,能够有效控制云台和镜头的各种参数,适用于多种应用场景。配合详细的使用手册,用户可以方便地进行设备的调试和操作,提高工作效率。

    不同球机的各种云台协议

    1. Pelco-D 协议:这种协议广泛应用于许多厂商的云台设备,支持基本的上、下、左、右移动,以及连续和点动模式。其命令结构简单,易于实现,但可能不支持复杂的功能,如曲线运动或高速旋转。 2. Pelco-P 协议:与 ...

    云台协议控制软件

    云台协议控制软件是一种专为测试和管理云台设备而设计的应用程序,它允许用户通过电脑或笔记本电脑来远程操作和监控云台的运动和功能。云台在安防监控、无人机、遥感观测等领域广泛应用,因此,理解并掌握云台协议...

    VC编写的云台控制程序

    《VC编写的云台控制程序》 在计算机技术领域,尤其是工业自动化和远程监控系统中,云台控制是一项至关重要的技术。云台是用于安装和调整摄像头方向的设备,广泛应用于监控摄像头、天文观测等领域。VC(Visual C++)...

    中文派尔高D协议(云台控制协议)

    ### 中文派尔高D协议(云台控制协议) #### 一、协议概述 派尔高D协议是一种专为云台摄像机与会议摄像机设计的控制协议,它主要用于实现对这类设备的精确控制,包括但不限于云台的位置调整、摄像头的焦距变化等。...

    三星SCC-641云台协议

    三星SCC-641云台协议是专用于三星SCC-641型号云台摄像机的一种通信协议,主要用于实现远程控制与监控功能。在安防、监控领域,云台摄像机因其可灵活调整视角而备受青睐,而其背后的云台协议则是确保设备正常运行的...

    万能云台测试程序支持大部分解码器协议

    万能云台测试程序是一种专为测试各类云台设备而设计的应用软件,它具有广泛的解码器协议兼容性,能够适应多种不同的云台控制系统。在IT行业中,云台通常用于监控摄像头,允许用户远程操控摄像头的方向,从而实现全...

    视频监控的云台协议(如派高等)

    6. **编程和集成**:为了实现自动化控制或与上位机软件的集成,开发者需要理解并遵循云台协议的规则,编写相应的控制程序。例如,使用Python、C#等语言通过API调用云台控制命令。 7. **安全考虑**:在远程监控系统...

    相机云台-PELCOD协议介绍

    PELCOD(Peltier-Codling Protocol)是由英国Peltier Codling公司开发的一种通信协议,主要用于电动云台的控制。该协议设计的目标是实现简单、高效且可靠的双向通信,使云台能够根据指令精确地移动到指定位置,并...

    云台控制协议PELCO

    掌握PELCO协议后,可以通过编程语言(如C++、Python、C#等)编写程序来控制云台。首先,需要建立与云台设备的串行连接;然后,根据需求构建符合PELCO协议格式的命令字符串;最后,将命令字符串发送到云台,并处理...

    云台控制系统 用VB程序设计

    综上所述,"云台控制系统 用VB程序设计"项目涉及了VB编程、网络通信、逻辑控制、人机交互等多个IT领域的知识点。通过这个项目,不仅可以学习到VB语言的基础知识,还能深入了解安防监控系统的设计与实现。

    云台控制程序,八个方向控制云台,基于VC++编写

    云台控制程序的核心功能是实现八个方向的运动控制,这包括上、下、左、右、顺时针旋转、逆时针旋转、以及两个斜向的移动。这些动作使摄像头能够灵活地覆盖广大的监控区域。除了基本的方向控制,该程序还支持焦距、...

    PELCO云台协议介绍

    综上所述,PELCO-D和PELCO-P协议虽然在结构和细节上存在差异,但都是为了实现对云台设备的有效控制而设计的。理解并掌握这两种协议的原理和应用,对于从事视频监控系统集成和维护的技术人员来说至关重要。

    海康威视有插件版本-vue3集成开发,可云台控制

    在这个特定的项目中,我们关注的是一个基于Vue3框架的有插件版本,特别是针对云台控制功能的实现。 首先,让我们深入理解“Vue3集成开发”。Vue.js 是一个流行的前端JavaScript框架,用于构建用户界面。Vue3是其...

    开源云台算法STM32程序(带注释云台控制.zip

    开源云台算法STM32程序,是针对无人机或摄像设备的稳定系统——云台进行控制的一种软件实现。STM32是一种广泛应用的微控制器,以其高性能、低功耗和丰富的外设接口而闻名,常用于嵌入式系统设计。在这个开源项目中,...

    球机云台控制协议, P_P P_D协议

    球机云台控制协议在IT领域中主要用于智能监控设备,如网络摄像头或监控摄像机,尤其是具有云台功能的设备。这些设备能够通过云台进行水平和垂直移动,以实现广角视野的调整,从而满足不同环境下的监控需求。本文将...

    c# PelcoD 云台控制

    PelcoD协议是一种串行通信协议,主要用于控制云台的上、下、左、右移动,缩放、聚焦、光圈调整等功能。该协议基于RS-485或RS-232通信标准,允许设备之间双向通信,适用于长距离传输。PelcoD协议定义了一系列特定的...

    云台控制协议.ppt

    改文档主要针对工作当中的问题,总结了各个协议的流程,和各个协议的使用字节所对应的关系,并使用伪代码来抽象了各个协议

    高速球云台程序

    高速球云台程序是一种在监控领域广泛使用的设备控制系统,它主要负责驱动和定位摄像头,实现对特定区域的高效、精确监控。在这个项目中,我们拥有的是高速球云台的完整源代码,包括了OSD(On-Screen Display)菜单...

    PelcoD 云台控制协议(完整版).pdf

    网上搜索到的 PelcoD 命令,基本为简单的云台基础版本,只包含云台,Zoom 以及预置位调用设置等简单功能。 此为官方 PelcoD 云台控制协议(完整版),包含查询 Zoom 位置等其他扩展命令

Global site tag (gtag.js) - Google Analytics