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);

你可能感兴趣的:(onvif入门)