gSOAP+onvif初探(三):PTZ控球

一、获取设备能力集

球机都有自己的能力集,在要对球机发送调用命令前可以先获取设备能力集

 struct _tds__GetCapabilities            Capabilities;
 struct _tds__GetCapabilitiesResponse    CapabilitiesResponse;
 soap_wsse_add_UsernameTokenDigest(soap, NULL, username, password);//依然记得要在这之前加上鉴权操作
 soap_call___tds__GetCapabilities(soap, DeviceXAddr, NULL, &Capabilities, &CapabilitiesResponse);

二、PTZ介绍

简单介绍PTZ表示的是什么:

  • P:Pan水平转动角度
  • T:Tilt垂直转动角度
  • Z:缩放倍数

  我用http的80端口传输时用的是PTZ绝对位置,范围是:P:(0,18000)T:(0,9000)z:(0-200)
  而用onvif控球,其发送的是归一化后的绝对位置,P:(-1,1)T:(-1,1),Z:(0,1)。在发送之前,将PTZ值先归一化即可。
  

三、控球命令

控球用AbsoluteMove(绝对移动)命令
soap_call___tptz__AbsoluteMove(struct soap *soap, const char *soap_endpoint, const char *soap_action, struct _tptz__AbsoluteMove *tptz__AbsoluteMove, struct _tptz__AbsoluteMoveResponse *tptz__AbsoluteMoveResponse)
ContinuousMove(沿某方向持续移动)命令
soap_call___tptz__ContinuousMove(struct soap *soap, const char *soap_endpoint, const char *soap_action, struct _tptz__ContinuousMove *tptz__ContinuousMove, struct _tptz__ContinuousMoveResponse *tptz__ContinuousMoveResponse);
RelativeMove(相对移动)命令
soap_call___tptz__RelativeMove(struct soap *soap, const char *soap_endpoint, const char *soap_action, struct _tptz__RelativeMove *tptz__RelativeMove, struct _tptz__RelativeMoveResponse *tptz__RelativeMoveResponse);

四、结构体描述

绝对位置移动结构体SOAP_TYPE__tptz__AbsoluteMove定义如下:

struct _tptz__AbsoluteMove {
        /** Required element 'ProfileToken' of XSD type 'tt:ReferenceToken' */
        char *ProfileToken;
        /** Required element 'Position' of XSD type 'tt:PTZVector' */
        struct tt__PTZVector *Position;//转动位置结构体成员
        /** Optional element 'Speed' of XSD type 'tt:PTZSpeed' */
        struct tt__PTZSpeed *Speed;//转动速度结构体成员
};

其中ProfileToken是一个标识。可以用获取配置文件函数soap_call___trt__GetProfiles获得,函数定义:

soap_call___trt__GetProfiles(struct soap *soap, const char *soap_endpoint, const char *soap_action, struct _trt__GetProfiles *trt__GetProfiles, struct _trt__GetProfilesResponse *trt__GetProfilesResponse)

tt__PTZVector为转动位置结构体:

struct tt__PTZVector {
        /** Optional element 'tt:PanTilt' of XSD type 'tt:Vector2D' */
        struct tt__Vector2D *PanTilt;//2维坐标结构体
        /** Optional element 'tt:Zoom' of XSD type 'tt:Vector1D' */
        struct tt__Vector1D *Zoom;//1维坐标结构体
};

tt__PTZSpeed为转动速度结构体

struct tt__PTZSpeed {
        /** Optional element 'tt:PanTilt' of XSD type 'tt:Vector2D' */
        struct tt__Vector2D *PanTilt;
        /** Optional element 'tt:Zoom' of XSD type 'tt:Vector1D' */
        struct tt__Vector1D *Zoom;
};

tt__Vector2D 2维坐标:

struct tt__Vector2D {
        /** Required attribute 'x' of XSD type 'xsd:float' */
        float x;   //Pan
        /** Required attribute 'y' of XSD type 'xsd:float' */
        float y;   //Tilt
         /** Optional attribute 'space' of XSD type 'xsd:anyURI' */
        //URI:一般填入"http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace"即可
        char *space;
};

tt__Vector1D 1维坐标:

struct tt__Vector1D {
        /** Required attribute 'x' of XSD type 'xsd:float' */
        float x;
        /** Optional attribute 'space' of XSD type 'xsd:anyURI' */
        char *space;
};

五、简例

1、soap结构初始化
soap_p = soap_new();
soap_set_namespaces(soap_p, namespaces);
2、鉴权(用户认证)
soap_wsse_add_UsernameTokenDigest(soap_p, NULL, "admin", "ADMIN123456");
3、配置文件获取(profiletoken)
struct _trt__GetProfiles            req;
struct _trt__GetProfilesResponse    rep;
soap_call___trt__GetProfiles(soap, MediaXAddr, NULL, &req, &rep);
if (rep.__sizeProfiles > 0) 
{           
     // 分配缓存
      (*profiles) = (struct tagProfile *)malloc(rep.__sizeProfiles * sizeof(struct tagProfile));
      SOAP_ASSERT(NULL != (*profiles));
      memset((*profiles), 0x00, rep.__sizeProfiles * sizeof(struct tagProfile));
}
for(i = 0; i < rep.__sizeProfiles; i++)
 {    
      // 提取所有配置文件信息(我们所关心的)
    struct tt__Profile *ttProfile = &rep.Profiles[i];
    struct tagProfile *plst = &(*profiles)[i];
    if (NULL != ttProfile->token) 
    {                                         
        // 配置文件Token
         strncpy(plst->token, ttProfile->token, sizeof(plst->token) - 1);
    }
 }
4、为结构体分配内存并填充结构体

在发送命令之前要为结构体_tptz__AbsoluteMove_tptz__AbsoluteMoveResponse申请内存空间,其成员也需要分配内存:

soap_malloc(struct soap *soap, size_t n)
......//为结构体分配内存

然后填充结构体:

soap_default__tptz__AbsoluteMove(soap_p, &AbsoluteMove);//内存清零
soap_default__tptz__AbsoluteMoveResponse(soap_p, &AbsoluteMoveResponse);

AbsoluteMove.ProfileToken = (char*)soap_malloc(soap_p, 128);
strcpy(AbsoluteMove.ProfileToken, "Profile_1");//profiletoken

AbsoluteMove.Position->PanTilt = (tt__Vector2D*)soap_malloc(soap_p, sizeof(struct tt__Vector2D));
AbsoluteMove.Position->PanTilt->x = -0.9798;//P这里是随便写的几个数
AbsoluteMove.Position->PanTilt->y = 0.6768;//T
AbsoluteMove.Position->PanTilt->xmlns = (char*)soap_malloc(soap_p, 128);
strcpy(AbsoluteMove.Position->PanTilt->xmlns, "http://www.onvif.org/ver10/schema");
AbsoluteMove.Speed->PanTilt = (tt__Vector2D*)soap_malloc(soap_p, sizeof(struct tt__Vector2D));;
AbsoluteMove.Speed->PanTilt->x = 1.0;//P方向转速
AbsoluteMove.Speed->PanTilt->y = 1.0;//T方向转速
AbsoluteMove.Speed->PanTilt->xmlns = (char*)soap_malloc(soap_p, 128);
strcpy(AbsoluteMove.Speed->PanTilt->xmlns, "http://www.onvif.org/ver10/schema");

AbsoluteMove.Position->Zoom =(tt__Vector1D*) soap_malloc(soap_p, sizeof(struct tt__Vector1D));
AbsoluteMove.Position->Zoom->x = 0.7646;//Z
AbsoluteMove.Position->Zoom->xmlns = (char*)soap_malloc(soap_p, 128);
strcpy(AbsoluteMove.Position->Zoom->xmlns, "http://www.onvif.org/ver10/schema");
AbsoluteMove.Speed->Zoom = (tt__Vector1D*)soap_malloc(soap_p, sizeof(struct tt__Vector1D));;
AbsoluteMove.Speed->Zoom->x = 1.0;//Z缩放速度
AbsoluteMove.Speed->Zoom->xmlns = (char*)soap_malloc(soap_p, 128);
strcpy(AbsoluteMove.Speed->Zoom->xmlns, "http://www.onvif.org/ver10/schema");
5、发送调用命令
soap_call___tptz__AbsoluteMove(soap_p, ball_onvifserver, NULL, &AbsoluteMove, &AbsoluteMoveResponse);
6、soap结构清理
    soap_destroy(soap_p);
    soap_end(soap_p);
    soap_done(soap_p);
  • 4
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 20
    评论
gSOAP是一个C/C++的SOAP (Simple Object Access Protocol)开发工具箱,可以用来实现Web Services以及SOAP消息的编解码。通过使用gSOAP,可以方便快捷地实现ONVIF服务。 以下是实现ONVIF服务的步骤: 1. 下载和安装gSOAP工具箱。 2. 生成服务端代码。使用gSOAP提供的命令行工具wsdl2h,将ONVIF的WSDL文件转换为gSOAP的头文件。例如: ``` wsdl2h -o onvif.h http://www.onvif.org/onvif/ver10/device/wsdl/devicemgmt.wsdl ``` 3. 生成客户端代码。使用gSOAP提供的命令行工具soapcpp2,将ONVIF的WSDL文件转换为gSOAP的客户端代码。例如: ``` soapcpp2 -i -C onvif.h ``` 4. 实现服务端程序。在服务端程序中,需要实现ONVIF的各个接口函数,并使用gSOAP提供的API进行SOAP消息的编解码和发送。例如: ```c++ #include "soapH.h" #include "onvif.nsmap" int main(int argc, char** argv) { struct soap soap; soap_init(&soap); // 实现ONVIF的各个接口函数 soap_serve(&soap); soap_destroy(&soap); soap_end(&soap); soap_done(&soap); return 0; } ``` 5. 实现客户端程序。在客户端程序中,需要使用gSOAP提供的API进行SOAP消息的编解码和发送,并调用ONVIF的各个接口函数。例如: ```c++ #include "soapH.h" #include "onvif.nsmap" int main(int argc, char** argv) { struct soap soap; soap_init(&soap); // 调用ONVIF的各个接口函数 soap_destroy(&soap); soap_end(&soap); soap_done(&soap); return 0; } ``` 6. 编译和运行程序。使用gSOAP提供的命令行工具soapcpp2,将生成的客户端和服务端代码编译成可执行程序。例如: ``` soapcpp2 -i -C onvif.h gcc -o onvif_server onvif_server.cpp onvif_serverC.cpp soapC.cpp stdsoap2.cpp gcc -o onvif_client onvif_client.cpp onvif_clientC.cpp soapC.cpp stdsoap2.cpp ``` 7. 测试程序。运行服务端程序,并使用客户端程序调用ONVIF的各个接口函数进行测试。例如: ``` ./onvif_server & ./onvif_client ``` 以上就是使用gSOAP实现ONVIF服务的基本步骤。需要注意的是,gSOAP提供了丰富的API和工具,可以根据具体的需求进行定制和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值