Go语言实现Onvif客户端:8、摄像头PTZ控制(云台控制)

Go语言实现Onvif客户端:8、摄像头PTZ控制(云台控制)


1、PTZ简单再介绍

之前学习Onvif协议的时候我们已经对PTZ有了基本的了解,这里当我们实现PTZ控制的时候再简单做一下介绍说明,主要针对我们这里实现的PTZ的说明。

PTZ:Pan/Tilt/Zoom,对于枪机的话基本就是固定一个位置或者水平移动,但是球机除了水平移动外,还可以旋转(没有跳跃),此外摄像头还有变焦的功能,目前我们暂时只实现简单的水平移动和旋转,变焦的接口等有需要也可以类似封装。而移动一般包含绝对移动、相对移动和连续移动三种方式,我们暂时使用连续移动,通过移动后调用停止也可以模拟其它两种移动的效果。

连续移动就设置移动或变焦的速度即可。就2d移动坐标来说:以原点坐标(x=0,y=0)进行相对移动控制,那么上(x=0,y=正的相对位置)下(x=0,y=负的相对位置)左(x=负的相对位置,y=0)右(x=正的相对位置,y=0)左上(x=负的相对位置,y=正的相对位置)左下(x=负的相对位置,y=负的相对位置)右上(x=正的相对位置,y=正的相对位置)右下(x=正的相对位置,y=负的相对位置)

2、代码

/**
 * @Description: 摄像头云台控制,包括模式设置和移动方向控制
 * @time: 2021-03-30 11:14:14
 * @receiver client:onvif客户端
 * @param direction:云台移动方向,通过PTZDirection接口传入封装后的方向值进行方向传递
 * @param moveMode:云台移动模式,通过MoveMode接口传入封装后的模式值进行模式控制
 * @return returnInfo:结果Code码和Info信息,Code码为0则成功,否则失败,通过获取Info查看失败原因
 */
func (client *GoOnvifClient) PTZControl(direction PTZDirection, moveMode moveMode) returnInfo {
	if client.localSelectProfileToken == "" {
		return returnInfo{PTZErr, "profile token is nil."}
	}

	if moveMode == CONTINUOUS || moveMode == DISCONTINUOUS {
		client.ptzMoveMode = moveMode
	} else {
		client.ptzMoveMode = DISCONTINUOUS
	}

	switch direction {
	case UP, DOWN, LEFT, RIGHT, UP_LEFT, DOWN_LEFT, UP_RIGHT, DOWN_RIGHT, STOP:
		client.direction = direction
		res := client.ptzControl()
		if res.Code != 0 {
			return res
		}

		if moveMode == DISCONTINUOUS {
			time.Sleep(1 * time.Second)
			res = client.ptzStop()
			if res.Code != 0 {
				return res
			}
		}
	default:
		return returnInfo{PTZErr, "direction err."}
	}

	return returnInfo{OK, "ptz control success!"}
}

/**
 * @Description: 根据输入的Profile token和PTZ速度、方向进行PTZ控制
 * @time: 2021-03-25 14:31:55
 * @receiver client
 * @return returnInfo
 */
func (client *GoOnvifClient) ptzControl() returnInfo {
	ptzContinuousMoveReq := ptz.ContinuousMove{
		ProfileToken: onvif.ReferenceToken(client.localSelectProfileToken),
		Velocity: onvif.PTZSpeed{
			PanTilt: onvif.Vector2D{
				X: 0,
				Y: 0,
			},
		},
	}

	switch client.direction {
	case UP:
		ptzContinuousMoveReq.Velocity.PanTilt.Y = client.ptzSpeed
	case DOWN:
		ptzContinuousMoveReq.Velocity.PanTilt.Y = -client.ptzSpeed
	case LEFT:
		ptzContinuousMoveReq.Velocity.PanTilt.X = -client.ptzSpeed
	case RIGHT:
		ptzContinuousMoveReq.Velocity.PanTilt.X = client.ptzSpeed
	case UP_LEFT:
		ptzContinuousMoveReq.Velocity.PanTilt.X = -client.ptzSpeed
		ptzContinuousMoveReq.Velocity.PanTilt.Y = client.ptzSpeed
	case DOWN_LEFT:
		ptzContinuousMoveReq.Velocity.PanTilt.X = -client.ptzSpeed
		ptzContinuousMoveReq.Velocity.PanTilt.Y = -client.ptzSpeed
	case UP_RIGHT:
		ptzContinuousMoveReq.Velocity.PanTilt.X = client.ptzSpeed
		ptzContinuousMoveReq.Velocity.PanTilt.Y = client.ptzSpeed
	case DOWN_RIGHT:
		ptzContinuousMoveReq.Velocity.PanTilt.X = client.ptzSpeed
		ptzContinuousMoveReq.Velocity.PanTilt.Y = -client.ptzSpeed
	case STOP:
		return client.ptzStop()
	default:
		return returnInfo{PTZErr, "Unknown ptz direction."}
	}

	return client.sendReqGetResp(PTZErr, ptzContinuousMoveReq)
}

/**
 * @Description: 根据输入的Profile token设置PTZ停止
 * @time: 2021-03-25 14:29:43
 * @receiver client
 * @return returnInfo
 */
func (client *GoOnvifClient) ptzStop() returnInfo {
	stopReq := ptz.Stop{
		ProfileToken: onvif.ReferenceToken(client.localSelectProfileToken),
	}

	return client.sendReqGetResp(PTZErr, stopReq)
}

调用,我们可以选择在循环中调用,也可以做一个web服务,从web界面上获取控制参数:

//设置速度后循环进行ptz控制,初始化时设置了默认速度0.2
PTZ:for {
		//断续模式移动一次1s后会调用停止进行停止,连续模式则会绕着指定的方向一直移动
		fmt.Println("选择控制模式,1:连续移动,0:断续移动,2:退出PTZ")
		moveMode := uint(0)
		fmt.Scanln(&moveMode)
		switch moveMode {
		case 2:
			break PTZ
		default:
		}

		direction := uint(0)
		fmt.Println("输入PTZ:1:上;2:下;3:左;4:右;5:左上;6:左下;7:右上;8:右下;9:停")
		fmt.Scanln(&direction)
		switch direction {
		case 1, 2, 3, 4, 5, 6, 7, 8, 9:
			res = client.PTZControl(client.PTZDirection(direction), client.MoveMode(moveMode))
			if res.Code != 0 {
				fmt.Println(res.Info)
				return
			}
		default:
			continue
		}
	}

3、结果

在这里插入图片描述

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

昵称系统有问题

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值