HikBallCamera.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. package HikNetSDK
  2. import (
  3. "errors"
  4. "fmt"
  5. "sync"
  6. "unsafe"
  7. )
  8. type HIKBallCamera struct {
  9. core unsafe.Pointer
  10. State bool
  11. BallCameraCfg BallCamera
  12. mux sync.RWMutex
  13. }
  14. func NewHIKBallCamera(BallCameraCfg BallCamera) *HIKBallCamera {
  15. return &HIKBallCamera{
  16. core: newHIKBallCamera(),
  17. BallCameraCfg: BallCameraCfg,
  18. State: false,
  19. mux: sync.RWMutex{},
  20. }
  21. }
  22. func (hikBC *HIKBallCamera) Login() (bool, uint, error) {
  23. var ErrorCode uint
  24. ErrorInfo := make([]byte, 128)
  25. ErrorInfoPtr := &ErrorInfo[0]
  26. hikBC.mux.Lock()
  27. hikBC.State = initBallCamera(hikBC.core, hikBC.BallCameraCfg.Ip, hikBC.BallCameraCfg.Port, hikBC.BallCameraCfg.User, hikBC.BallCameraCfg.Password, hikBC.BallCameraCfg.Type, unsafe.Pointer(&ErrorCode), ErrorInfoPtr)
  28. outState := hikBC.State
  29. hikBC.mux.Unlock()
  30. return outState, ErrorCode, errors.New(goString(ErrorInfoPtr))
  31. }
  32. func (hikBC *HIKBallCamera) Logout() (bool, uint, error) {
  33. var ErrorCode uint
  34. ErrorInfo := make([]byte, 128)
  35. ErrorInfoPtr := &ErrorInfo[0]
  36. hikBC.mux.Lock()
  37. hikBC.State = ballCameraLogout(hikBC.core, unsafe.Pointer(&ErrorCode), ErrorInfoPtr)
  38. outState := hikBC.State
  39. hikBC.mux.Unlock()
  40. return outState, ErrorCode, errors.New(goString(ErrorInfoPtr))
  41. }
  42. // goString 将 `char*` 转换为 Go 字符串
  43. func goString(cstr *byte) string {
  44. if cstr == nil {
  45. return ""
  46. }
  47. // 找到 C 字符串的长度(以 null 结尾)
  48. data := unsafe.Slice(cstr, 128) // 假设最大长度 128,实际可根据情况调整
  49. for i, b := range data {
  50. if b == 0 { // 遇到 null 终止符
  51. return string(data[:i])
  52. }
  53. }
  54. return string(data) // 如果没有 null 终止符,返回整个 slice
  55. }
  56. func (hikBC *HIKBallCamera) opt(action func() bool) bool {
  57. hikBC.mux.RLock()
  58. if hikBC.State {
  59. hikBC.mux.RUnlock()
  60. hikBC.mux.Lock()
  61. hikBC.State = action()
  62. hikBC.mux.Unlock()
  63. } else {
  64. hikBC.mux.RUnlock()
  65. }
  66. return hikBC.State
  67. }
  68. func (hikBC *HIKBallCamera) PTZGet(P, T, Z *float32) bool {
  69. return hikBC.opt(func() bool {
  70. return ptzGet(hikBC.core, unsafe.Pointer(P), unsafe.Pointer(T), unsafe.Pointer(Z))
  71. })
  72. }
  73. func (hikBC *HIKBallCamera) PtzTo(Action int, P, T, Z float32) bool {
  74. return hikBC.opt(func() bool {
  75. return ptzTo(hikBC.core, Action, P, T, Z)
  76. })
  77. }
  78. func (hikBC *HIKBallCamera) StartBus(Direction, Speed int) bool {
  79. return hikBC.opt(func() bool {
  80. return startBus(hikBC.core, Direction, Speed)
  81. })
  82. }
  83. func (hikBC *HIKBallCamera) StopBus(Direction int) bool {
  84. return hikBC.opt(func() bool {
  85. return stopBus(hikBC.core, Direction)
  86. })
  87. }
  88. func (hikBC *HIKBallCamera) OneClickToSeeInFullView(point Point) bool {
  89. TransPoint := hikBC.WarpingPtByHomography(hikBC.BallCameraCfg.Matrix.Matrix, point)
  90. return hikBC.PtzTo(5,
  91. float32(hikBC.mapping(hikBC.BallCameraCfg.Matrix.PStart, hikBC.BallCameraCfg.Matrix.PMax, TransPoint.X, hikBC.BallCameraCfg.Matrix.PPositiveDirection, "inv")),
  92. float32(hikBC.mapping(hikBC.BallCameraCfg.Matrix.TStart, hikBC.BallCameraCfg.Matrix.TMax, TransPoint.Y, hikBC.BallCameraCfg.Matrix.TPositiveDirection, "inv")),
  93. 0.0,
  94. )
  95. }
  96. func (hikBC *HIKBallCamera) PTZ2FullView() (Point, error) {
  97. var ptz PTZ
  98. if !hikBC.PTZGet(&ptz.P, &ptz.T, &ptz.Z) {
  99. return Point{}, fmt.Errorf("PTZ Get Error")
  100. }
  101. return hikBC.WarpingPtByHomography(hikBC.BallCameraCfg.Matrix.InvMatrix, Point{
  102. X: hikBC.mapping(hikBC.BallCameraCfg.Matrix.PStart, hikBC.BallCameraCfg.Matrix.PMax, float64(ptz.P), hikBC.BallCameraCfg.Matrix.PPositiveDirection, ""),
  103. Y: hikBC.mapping(hikBC.BallCameraCfg.Matrix.TStart, hikBC.BallCameraCfg.Matrix.TMax, float64(ptz.T), hikBC.BallCameraCfg.Matrix.TPositiveDirection, "")}), nil
  104. }
  105. func (hikBC *HIKBallCamera) WarpingPtByHomography(matrix []float64, p Point) Point {
  106. var x, y, z float64
  107. x = matrix[0]*p.X + matrix[1]*p.Y + 1.*matrix[2]
  108. y = matrix[3]*p.X + matrix[4]*p.Y + 1.*matrix[5]
  109. z = matrix[6]*p.X + matrix[7]*p.Y + 1.*matrix[8]
  110. x /= z
  111. y /= z
  112. return Point{X: x, Y: y}
  113. }
  114. func (hikBC *HIKBallCamera) mapping(startV float64, max float64, value float64, direction string, method string) float64 {
  115. if direction == "+" {
  116. if method == "inv" {
  117. if value > (max - startV) {
  118. return value - (max - startV)
  119. } else {
  120. return startV + value // 映射
  121. }
  122. } else {
  123. if value > startV {
  124. return value - startV
  125. } else {
  126. return (max - startV) + value // 映射
  127. }
  128. }
  129. } else {
  130. if value > startV {
  131. return startV + max - value
  132. } else {
  133. return startV - value
  134. }
  135. }
  136. }