From 4974011eeea0a7bcb4be238dadf02329388ce117 Mon Sep 17 00:00:00 2001 From: kunmeng Date: Mon, 10 Feb 2025 15:57:03 +0800 Subject: [PATCH] =?UTF-8?q?1.=20=E7=A7=BB=E9=99=A4=E8=AE=A1=E7=AE=97=203*3?= =?UTF-8?q?=20=E7=9F=A9=E9=98=B5=E7=9A=84=E9=80=86=E7=9A=84=E5=87=BD?= =?UTF-8?q?=E6=95=B0=202.=20=E4=BC=98=E5=8C=96=E7=90=83=E6=9C=BA=E7=9A=84?= =?UTF-8?q?=E7=99=BB=E9=99=86=E6=8E=A5=E5=8F=A3=203.=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E7=90=83=E6=9C=BA=E7=9A=84=E7=99=BB=E5=87=BA=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HikBallCamera.go | 226 +++++++++++++++++++++--------------------- HikBallCamera_test.go | 24 +++++ Hikvision.go | 5 +- 3 files changed, 139 insertions(+), 116 deletions(-) create mode 100644 HikBallCamera_test.go diff --git a/HikBallCamera.go b/HikBallCamera.go index 141dd58..ebdaf4f 100644 --- a/HikBallCamera.go +++ b/HikBallCamera.go @@ -1,155 +1,153 @@ package HikNetSDK import ( - "fmt" - "sync" - "unsafe" + "errors" + "fmt" + "sync" + "unsafe" ) type HIKBallCamera struct { - core unsafe.Pointer - State bool - BallCameraCfg BallCamera - mux sync.RWMutex + core unsafe.Pointer + State bool + BallCameraCfg BallCamera + mux sync.RWMutex } func NewHIKBallCamera(BallCameraCfg BallCamera) *HIKBallCamera { - return &HIKBallCamera{ - core: newHIKBallCamera(), - BallCameraCfg: BallCameraCfg, - State: false, - mux: sync.RWMutex{}, - } + return &HIKBallCamera{ + core: newHIKBallCamera(), + BallCameraCfg: BallCameraCfg, + State: false, + mux: sync.RWMutex{}, + } } -func (hikBC *HIKBallCamera) Login() bool { - hikBC.mux.Lock() - hikBC.State = initBallCamera(hikBC.core, hikBC.BallCameraCfg.Ip, hikBC.BallCameraCfg.Port, hikBC.BallCameraCfg.User, hikBC.BallCameraCfg.Password, hikBC.BallCameraCfg.Type) - hikBC.mux.Unlock() - return hikBC.State +func (hikBC *HIKBallCamera) Login() (bool, uint, error) { + var ErrorCode uint + ErrorInfo := make([]byte, 128) + ErrorInfoPtr := &ErrorInfo[0] + 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 { - hikBC.mux.RLock() - if hikBC.State { - hikBC.mux.RUnlock() - hikBC.mux.Lock() - hikBC.State = action() - hikBC.mux.Unlock() - } else { - hikBC.mux.RUnlock() - } - return hikBC.State + hikBC.mux.RLock() + if hikBC.State { + hikBC.mux.RUnlock() + hikBC.mux.Lock() + hikBC.State = action() + hikBC.mux.Unlock() + } else { + hikBC.mux.RUnlock() + } + return hikBC.State } func (hikBC *HIKBallCamera) PTZGet(P, T, Z *float32) bool { - return hikBC.opt(func() bool { - return ptzGet(hikBC.core, unsafe.Pointer(P), unsafe.Pointer(T), unsafe.Pointer(Z)) - }) + return hikBC.opt(func() bool { + return ptzGet(hikBC.core, unsafe.Pointer(P), unsafe.Pointer(T), unsafe.Pointer(Z)) + }) } func (hikBC *HIKBallCamera) PtzTo(Action int, P, T, Z float32) bool { - return hikBC.opt(func() bool { - return ptzTo(hikBC.core, Action, P, T, Z) - }) + return hikBC.opt(func() bool { + return ptzTo(hikBC.core, Action, P, T, Z) + }) } func (hikBC *HIKBallCamera) StartBus(Direction, Speed int) bool { - return hikBC.opt(func() bool { - return startBus(hikBC.core, Direction, Speed) - }) + return hikBC.opt(func() bool { + return startBus(hikBC.core, Direction, Speed) + }) } func (hikBC *HIKBallCamera) StopBus(Direction int) bool { - return hikBC.opt(func() bool { - return stopBus(hikBC.core, Direction) - }) + return hikBC.opt(func() bool { + return stopBus(hikBC.core, Direction) + }) } func (hikBC *HIKBallCamera) OneClickToSeeInFullView(point Point) bool { - TransPoint := hikBC.WarpingPtByHomography(hikBC.BallCameraCfg.Matrix.Matrix, point) - 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.TStart, hikBC.BallCameraCfg.Matrix.TMax, TransPoint.Y, hikBC.BallCameraCfg.Matrix.TPositiveDirection, "inv")), - 0.0, - ) + TransPoint := hikBC.WarpingPtByHomography(hikBC.BallCameraCfg.Matrix.Matrix, point) + 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.TStart, hikBC.BallCameraCfg.Matrix.TMax, TransPoint.Y, hikBC.BallCameraCfg.Matrix.TPositiveDirection, "inv")), + 0.0, + ) } func (hikBC *HIKBallCamera) PTZ2FullView() (Point, error) { - var ptz PTZ - if !hikBC.PTZGet(&ptz.P, &ptz.T, &ptz.Z) { - return Point{}, fmt.Errorf("PTZ Get Error") - } - 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, ""), - Y: hikBC.mapping(hikBC.BallCameraCfg.Matrix.TStart, hikBC.BallCameraCfg.Matrix.TMax, float64(ptz.T), hikBC.BallCameraCfg.Matrix.TPositiveDirection, "")}), nil + var ptz PTZ + if !hikBC.PTZGet(&ptz.P, &ptz.T, &ptz.Z) { + return Point{}, fmt.Errorf("PTZ Get Error") + } + 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, ""), + 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 { - var x, y, z float64 - x = matrix[0]*p.X + matrix[1]*p.Y + 1.*matrix[2] - y = matrix[3]*p.X + matrix[4]*p.Y + 1.*matrix[5] - z = matrix[6]*p.X + matrix[7]*p.Y + 1.*matrix[8] + var x, y, z float64 + x = matrix[0]*p.X + matrix[1]*p.Y + 1.*matrix[2] + y = matrix[3]*p.X + matrix[4]*p.Y + 1.*matrix[5] + z = matrix[6]*p.X + matrix[7]*p.Y + 1.*matrix[8] - x /= z - y /= z - 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 + x /= z + y /= z + return Point{X: x, Y: y} } func (hikBC *HIKBallCamera) mapping(startV float64, max float64, value float64, direction string, method string) float64 { - if direction == "+" { - if method == "inv" { - if value > (max - startV) { - return value - (max - startV) - } else { - return startV + value // 映射 - } - } else { - if value > startV { - return value - startV - } else { - return (max - startV) + value // 映射 - } - } - } else { - if value > startV { - return startV + max - value - } else { - return startV - value - } - } + if direction == "+" { + if method == "inv" { + if value > (max - startV) { + return value - (max - startV) + } else { + return startV + value // 映射 + } + } else { + if value > startV { + return value - startV + } else { + return (max - startV) + value // 映射 + } + } + } else { + if value > startV { + return startV + max - value + } else { + return startV - value + } + } } diff --git a/HikBallCamera_test.go b/HikBallCamera_test.go new file mode 100644 index 0000000..c91524c --- /dev/null +++ b/HikBallCamera_test.go @@ -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 + } +} diff --git a/Hikvision.go b/Hikvision.go index a9b4876..a7a0c7f 100644 --- a/Hikvision.go +++ b/Hikvision.go @@ -10,10 +10,11 @@ import ( var libc uintptr var ( - DvrInit func() bool + DvrInit func() int 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 ptzGet func(unsafe.Pointer, unsafe.Pointer, unsafe.Pointer, unsafe.Pointer) bool stopBus func(unsafe.Pointer, int) bool