1. 移除计算 3*3 矩阵的逆的函数

2. 优化球机的登陆接口
3. 新增球机的登出接口
This commit is contained in:
kunmeng
2025-02-10 15:57:03 +08:00
parent 0aad52eef1
commit 4974011eee
3 changed files with 139 additions and 116 deletions

View File

@@ -1,155 +1,153 @@
package HikNetSDK package HikNetSDK
import ( import (
"fmt" "errors"
"sync" "fmt"
"unsafe" "sync"
"unsafe"
) )
type HIKBallCamera struct { type HIKBallCamera struct {
core unsafe.Pointer core unsafe.Pointer
State bool State bool
BallCameraCfg BallCamera BallCameraCfg BallCamera
mux sync.RWMutex mux sync.RWMutex
} }
func NewHIKBallCamera(BallCameraCfg BallCamera) *HIKBallCamera { func NewHIKBallCamera(BallCameraCfg BallCamera) *HIKBallCamera {
return &HIKBallCamera{ return &HIKBallCamera{
core: newHIKBallCamera(), core: newHIKBallCamera(),
BallCameraCfg: BallCameraCfg, BallCameraCfg: BallCameraCfg,
State: false, State: false,
mux: sync.RWMutex{}, mux: sync.RWMutex{},
} }
} }
func (hikBC *HIKBallCamera) Login() bool { func (hikBC *HIKBallCamera) Login() (bool, uint, error) {
hikBC.mux.Lock() var ErrorCode uint
hikBC.State = initBallCamera(hikBC.core, hikBC.BallCameraCfg.Ip, hikBC.BallCameraCfg.Port, hikBC.BallCameraCfg.User, hikBC.BallCameraCfg.Password, hikBC.BallCameraCfg.Type) ErrorInfo := make([]byte, 128)
hikBC.mux.Unlock() ErrorInfoPtr := &ErrorInfo[0]
return hikBC.State hikBC.mux.Lock()
hikBC.State = initBallCamera(hikBC.core, hikBC.BallCameraCfg.Ip, hikBC.BallCameraCfg.Port, hikBC.BallCameraCfg.User, hikBC.BallCameraCfg.Password, hikBC.BallCameraCfg.Type, unsafe.Pointer(&ErrorCode), ErrorInfoPtr)
outState := hikBC.State
hikBC.mux.Unlock()
return outState, ErrorCode, errors.New(goString(ErrorInfoPtr))
}
func (hikBC *HIKBallCamera) Logout() (bool, uint, error) {
var ErrorCode uint
ErrorInfo := make([]byte, 128)
ErrorInfoPtr := &ErrorInfo[0]
hikBC.mux.Lock()
hikBC.State = ballCameraLogout(hikBC.core, unsafe.Pointer(&ErrorCode), ErrorInfoPtr)
outState := hikBC.State
hikBC.mux.Unlock()
return outState, ErrorCode, errors.New(goString(ErrorInfoPtr))
}
// goString 将 `char*` 转换为 Go 字符串
func goString(cstr *byte) string {
if cstr == nil {
return ""
}
// 找到 C 字符串的长度(以 null 结尾)
data := unsafe.Slice(cstr, 128) // 假设最大长度 128实际可根据情况调整
for i, b := range data {
if b == 0 { // 遇到 null 终止符
return string(data[:i])
}
}
return string(data) // 如果没有 null 终止符,返回整个 slice
} }
func (hikBC *HIKBallCamera) opt(action func() bool) bool { func (hikBC *HIKBallCamera) opt(action func() bool) bool {
hikBC.mux.RLock() hikBC.mux.RLock()
if hikBC.State { if hikBC.State {
hikBC.mux.RUnlock() hikBC.mux.RUnlock()
hikBC.mux.Lock() hikBC.mux.Lock()
hikBC.State = action() hikBC.State = action()
hikBC.mux.Unlock() hikBC.mux.Unlock()
} else { } else {
hikBC.mux.RUnlock() hikBC.mux.RUnlock()
} }
return hikBC.State return hikBC.State
} }
func (hikBC *HIKBallCamera) PTZGet(P, T, Z *float32) bool { func (hikBC *HIKBallCamera) PTZGet(P, T, Z *float32) bool {
return hikBC.opt(func() bool { return hikBC.opt(func() bool {
return ptzGet(hikBC.core, unsafe.Pointer(P), unsafe.Pointer(T), unsafe.Pointer(Z)) return ptzGet(hikBC.core, unsafe.Pointer(P), unsafe.Pointer(T), unsafe.Pointer(Z))
}) })
} }
func (hikBC *HIKBallCamera) PtzTo(Action int, P, T, Z float32) bool { func (hikBC *HIKBallCamera) PtzTo(Action int, P, T, Z float32) bool {
return hikBC.opt(func() bool { return hikBC.opt(func() bool {
return ptzTo(hikBC.core, Action, P, T, Z) return ptzTo(hikBC.core, Action, P, T, Z)
}) })
} }
func (hikBC *HIKBallCamera) StartBus(Direction, Speed int) bool { func (hikBC *HIKBallCamera) StartBus(Direction, Speed int) bool {
return hikBC.opt(func() bool { return hikBC.opt(func() bool {
return startBus(hikBC.core, Direction, Speed) return startBus(hikBC.core, Direction, Speed)
}) })
} }
func (hikBC *HIKBallCamera) StopBus(Direction int) bool { func (hikBC *HIKBallCamera) StopBus(Direction int) bool {
return hikBC.opt(func() bool { return hikBC.opt(func() bool {
return stopBus(hikBC.core, Direction) return stopBus(hikBC.core, Direction)
}) })
} }
func (hikBC *HIKBallCamera) OneClickToSeeInFullView(point Point) bool { func (hikBC *HIKBallCamera) OneClickToSeeInFullView(point Point) bool {
TransPoint := hikBC.WarpingPtByHomography(hikBC.BallCameraCfg.Matrix.Matrix, point) TransPoint := hikBC.WarpingPtByHomography(hikBC.BallCameraCfg.Matrix.Matrix, point)
return hikBC.PtzTo(5, return hikBC.PtzTo(5,
float32(hikBC.mapping(hikBC.BallCameraCfg.Matrix.PStart, hikBC.BallCameraCfg.Matrix.PMax, TransPoint.X, hikBC.BallCameraCfg.Matrix.PPositiveDirection, "inv")), float32(hikBC.mapping(hikBC.BallCameraCfg.Matrix.PStart, hikBC.BallCameraCfg.Matrix.PMax, TransPoint.X, hikBC.BallCameraCfg.Matrix.PPositiveDirection, "inv")),
float32(hikBC.mapping(hikBC.BallCameraCfg.Matrix.TStart, hikBC.BallCameraCfg.Matrix.TMax, TransPoint.Y, hikBC.BallCameraCfg.Matrix.TPositiveDirection, "inv")), float32(hikBC.mapping(hikBC.BallCameraCfg.Matrix.TStart, hikBC.BallCameraCfg.Matrix.TMax, TransPoint.Y, hikBC.BallCameraCfg.Matrix.TPositiveDirection, "inv")),
0.0, 0.0,
) )
} }
func (hikBC *HIKBallCamera) PTZ2FullView() (Point, error) { func (hikBC *HIKBallCamera) PTZ2FullView() (Point, error) {
var ptz PTZ var ptz PTZ
if !hikBC.PTZGet(&ptz.P, &ptz.T, &ptz.Z) { if !hikBC.PTZGet(&ptz.P, &ptz.T, &ptz.Z) {
return Point{}, fmt.Errorf("PTZ Get Error") return Point{}, fmt.Errorf("PTZ Get Error")
} }
return hikBC.WarpingPtByHomography(hikBC.BallCameraCfg.Matrix.InvMatrix, Point{ return hikBC.WarpingPtByHomography(hikBC.BallCameraCfg.Matrix.InvMatrix, Point{
X: hikBC.mapping(hikBC.BallCameraCfg.Matrix.PStart, hikBC.BallCameraCfg.Matrix.PMax, float64(ptz.P), hikBC.BallCameraCfg.Matrix.PPositiveDirection, ""), X: hikBC.mapping(hikBC.BallCameraCfg.Matrix.PStart, hikBC.BallCameraCfg.Matrix.PMax, float64(ptz.P), hikBC.BallCameraCfg.Matrix.PPositiveDirection, ""),
Y: hikBC.mapping(hikBC.BallCameraCfg.Matrix.TStart, hikBC.BallCameraCfg.Matrix.TMax, float64(ptz.T), hikBC.BallCameraCfg.Matrix.TPositiveDirection, "")}), nil Y: hikBC.mapping(hikBC.BallCameraCfg.Matrix.TStart, hikBC.BallCameraCfg.Matrix.TMax, float64(ptz.T), hikBC.BallCameraCfg.Matrix.TPositiveDirection, "")}), nil
} }
func (hikBC *HIKBallCamera) WarpingPtByHomography(matrix []float64, p Point) Point { func (hikBC *HIKBallCamera) WarpingPtByHomography(matrix []float64, p Point) Point {
var x, y, z float64 var x, y, z float64
x = matrix[0]*p.X + matrix[1]*p.Y + 1.*matrix[2] x = matrix[0]*p.X + matrix[1]*p.Y + 1.*matrix[2]
y = matrix[3]*p.X + matrix[4]*p.Y + 1.*matrix[5] y = matrix[3]*p.X + matrix[4]*p.Y + 1.*matrix[5]
z = matrix[6]*p.X + matrix[7]*p.Y + 1.*matrix[8] z = matrix[6]*p.X + matrix[7]*p.Y + 1.*matrix[8]
x /= z x /= z
y /= z y /= z
return Point{X: x, Y: y} return Point{X: x, Y: y}
}
func (hikBC *HIKBallCamera) Invert3x3() bool {
a := hikBC.BallCameraCfg.Matrix.Matrix[0]
b := hikBC.BallCameraCfg.Matrix.Matrix[1]
c := hikBC.BallCameraCfg.Matrix.Matrix[2]
d := hikBC.BallCameraCfg.Matrix.Matrix[3]
e := hikBC.BallCameraCfg.Matrix.Matrix[4]
f := hikBC.BallCameraCfg.Matrix.Matrix[5]
g := hikBC.BallCameraCfg.Matrix.Matrix[6]
h := hikBC.BallCameraCfg.Matrix.Matrix[7]
i := hikBC.BallCameraCfg.Matrix.Matrix[8]
det := a*(e*i-f*h) - b*(d*i-f*g) + c*(d*h-e*g)
if det == 0 {
return false
}
invDet := 1.0 / det
hikBC.BallCameraCfg.Matrix.InvMatrix = []float64{
(e*i - f*h) * invDet,
(c*h - b*i) * invDet,
(b*f - c*e) * invDet,
(f*g - d*i) * invDet,
(a*i - c*g) * invDet,
(c*d - a*f) * invDet,
(d*h - e*g) * invDet,
(b*g - a*h) * invDet,
(a*e - b*d) * invDet,
}
return true
} }
func (hikBC *HIKBallCamera) mapping(startV float64, max float64, value float64, direction string, method string) float64 { func (hikBC *HIKBallCamera) mapping(startV float64, max float64, value float64, direction string, method string) float64 {
if direction == "+" { if direction == "+" {
if method == "inv" { if method == "inv" {
if value > (max - startV) { if value > (max - startV) {
return value - (max - startV) return value - (max - startV)
} else { } else {
return startV + value // 映射 return startV + value // 映射
} }
} else { } else {
if value > startV { if value > startV {
return value - startV return value - startV
} else { } else {
return (max - startV) + value // 映射 return (max - startV) + value // 映射
} }
} }
} else { } else {
if value > startV { if value > startV {
return startV + max - value return startV + max - value
} else { } else {
return startV - value return startV - value
} }
} }
} }

24
HikBallCamera_test.go Normal file
View File

@@ -0,0 +1,24 @@
package HikNetSDK
import "testing"
func TestHIKBallCamera_Login(t *testing.T) {
Init()
if DvrInit() != 0 {
t.Error("Dvr init failed")
}
Camera := NewHIKBallCamera(BallCamera{
Type: "BuKongQiu",
Name: "布控球",
Ip: "192.168.211.44",
Port: "8000",
User: "admin",
Password: "okwy1234",
Channel: 1,
})
State, ErrorCode, ErrorInfo := Camera.Login()
if !State {
t.Error(ErrorCode, ErrorInfo)
return
}
}

View File

@@ -10,10 +10,11 @@ import (
var libc uintptr var libc uintptr
var ( var (
DvrInit func() bool DvrInit func() int
newHIKBallCamera func() unsafe.Pointer newHIKBallCamera func() unsafe.Pointer
initBallCamera func(core unsafe.Pointer, ip string, port string, username string, password string, BallMachineType string) bool initBallCamera func(core unsafe.Pointer, ip string, port string, username string, password string, BallMachineType string, ErrorCode unsafe.Pointer, ErrorInfo *byte) bool
ballCameraLogout func(core unsafe.Pointer, ErrorCode unsafe.Pointer, ErrorInfo *byte) bool
ptzTo func(core unsafe.Pointer, Action int, P float32, T float32, Z float32) bool ptzTo func(core unsafe.Pointer, Action int, P float32, T float32, Z float32) bool
ptzGet func(unsafe.Pointer, unsafe.Pointer, unsafe.Pointer, unsafe.Pointer) bool ptzGet func(unsafe.Pointer, unsafe.Pointer, unsafe.Pointer, unsafe.Pointer) bool
stopBus func(unsafe.Pointer, int) bool stopBus func(unsafe.Pointer, int) bool