test_ptz.py 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. #!/usr/bin/env python3
  2. """
  3. PTZ 控制测试脚本
  4. 用于验证球机 PTZ 控制是否正常工作
  5. """
  6. import os
  7. import sys
  8. import time
  9. sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
  10. from config import PTZ_CAMERA, SDK_PATH, PTZ_CONFIG
  11. from dahua_sdk import DahuaSDK, PTZCommand
  12. from ptz_camera import PTZCamera
  13. def test_ptz_basic_control(ptz: PTZCamera):
  14. """测试基本 PTZ 控制"""
  15. print("\n" + "=" * 50)
  16. print("测试基本 PTZ 控制")
  17. print("=" * 50)
  18. # 测试向左移动
  19. print("\n[测试1] 向左移动 2 秒...")
  20. ptz.move_left(speed=4)
  21. time.sleep(2)
  22. ptz.stop_move()
  23. print("停止移动")
  24. time.sleep(1)
  25. # 测试向右移动
  26. print("\n[测试2] 向右移动 2 秒...")
  27. ptz.move_right(speed=4)
  28. time.sleep(2)
  29. ptz.stop_move()
  30. print("停止移动")
  31. time.sleep(1)
  32. # 测试放大
  33. print("\n[测试3] 放大 2 秒...")
  34. ptz.zoom_in(speed=4)
  35. time.sleep(2)
  36. ptz.stop_move()
  37. print("停止变倍")
  38. time.sleep(1)
  39. # 测试缩小
  40. print("\n[测试4] 缩小 2 秒...")
  41. ptz.zoom_out(speed=4)
  42. time.sleep(2)
  43. ptz.stop_move()
  44. print("停止变倍")
  45. def test_ptz_exact_goto(ptz: PTZCamera):
  46. """测试精确定位"""
  47. print("\n" + "=" * 50)
  48. print("测试精确定位 (EXACTGOTO)")
  49. print("=" * 50)
  50. # 测试不同的 pan 角度
  51. test_points = [
  52. (0, 0, 1), # pan=0°
  53. (45, 0, 1), # pan=45°
  54. (90, 0, 1), # pan=90°
  55. (135, 0, 1), # pan=135°
  56. (180, 0, 1), # pan=180°
  57. (270, 0, 1), # pan=270°
  58. (0, 0, 1), # 返回 pan=0°
  59. ]
  60. for i, (pan, tilt, zoom) in enumerate(test_points):
  61. print(f"\n[测试点 {i+1}/{len(test_points)}] 移动到 pan={pan}°, tilt={tilt}°, zoom={zoom}")
  62. result = ptz.goto_exact_position(pan, tilt, zoom)
  63. if result:
  64. print(" ✓ 命令成功")
  65. else:
  66. print(" ✗ 命令失败")
  67. time.sleep(3) # 等待球机移动
  68. def test_ptz_fast_goto(ptz: PTZCamera, sdk: DahuaSDK):
  69. """测试快速定位 (FASTGOTO)"""
  70. print("\n" + "=" * 50)
  71. print("测试快速定位 (FASTGOTO)")
  72. print("=" * 50)
  73. print("FASTGOTO 参数格式: 水平(-8191~8191), 垂直(-8191~8191), 变倍(-16~16)")
  74. # FASTGOTO 使用不同的参数格式
  75. # 参数范围: 水平/垂直 -8191~8191, 变倍 -16~16
  76. test_points = [
  77. (0, 0, 0), # 中心
  78. (-4000, 0, 0), # 向左
  79. (4000, 0, 0), # 向右
  80. (0, -2000, 0), # 向上
  81. (0, 2000, 0), # 向下
  82. (0, 0, 0), # 返回中心
  83. ]
  84. for i, (p1, p2, p3) in enumerate(test_points):
  85. print(f"\n[测试点 {i+1}/{len(test_points)}] FASTGOTO: p1={p1}, p2={p2}, p3={p3}")
  86. result = sdk.ptz_control(
  87. ptz.login_handle,
  88. ptz.config['channel'],
  89. PTZCommand.FASTGOTO,
  90. p1, p2, p3, False
  91. )
  92. if result:
  93. print(" ✓ 命令成功")
  94. else:
  95. print(" ✗ 命令失败")
  96. time.sleep(3)
  97. def interactive_test(ptz: PTZCamera, sdk: DahuaSDK):
  98. """交互式测试"""
  99. print("\n" + "=" * 50)
  100. print("交互式测试模式")
  101. print("=" * 50)
  102. print("命令:")
  103. print(" left/right/up/down - 基本移动")
  104. print(" zoomin/zoomout - 变倍")
  105. print(" stop - 停止")
  106. print(" goto <pan> <tilt> [zoom] - 精确定位 (角度)")
  107. print(" fast <p1> <p2> <p3> - 快速定位")
  108. print(" q - 退出")
  109. print("=" * 50)
  110. while True:
  111. try:
  112. cmd = input("\n> ").strip().lower()
  113. if not cmd:
  114. continue
  115. if cmd == 'q':
  116. break
  117. elif cmd == 'left':
  118. ptz.move_left(speed=4)
  119. print("向左移动中... (输入 'stop' 停止)")
  120. elif cmd == 'right':
  121. ptz.move_right(speed=4)
  122. print("向右移动中... (输入 'stop' 停止)")
  123. elif cmd == 'up':
  124. ptz.move_up(speed=4)
  125. print("向上移动中... (输入 'stop' 停止)")
  126. elif cmd == 'down':
  127. ptz.move_down(speed=4)
  128. print("向下移动中... (输入 'stop' 停止)")
  129. elif cmd == 'zoomin':
  130. ptz.zoom_in(speed=4)
  131. print("放大中... (输入 'stop' 停止)")
  132. elif cmd == 'zoomout':
  133. ptz.zoom_out(speed=4)
  134. print("缩小中... (输入 'stop' 停止)")
  135. elif cmd == 'stop':
  136. ptz.stop_move()
  137. print("已停止")
  138. elif cmd.startswith('goto'):
  139. parts = cmd.split()
  140. if len(parts) >= 3:
  141. pan = float(parts[1])
  142. tilt = float(parts[2])
  143. zoom = int(parts[3]) if len(parts) > 3 else 1
  144. print(f"移动到 pan={pan}°, tilt={tilt}°, zoom={zoom}")
  145. ptz.goto_exact_position(pan, tilt, zoom)
  146. else:
  147. print("用法: goto <pan> <tilt> [zoom]")
  148. elif cmd.startswith('fast'):
  149. parts = cmd.split()
  150. if len(parts) >= 4:
  151. p1 = int(parts[1])
  152. p2 = int(parts[2])
  153. p3 = int(parts[3])
  154. print(f"FASTGOTO: p1={p1}, p2={p2}, p3={p3}")
  155. sdk.ptz_control(
  156. ptz.login_handle,
  157. ptz.config['channel'],
  158. PTZCommand.FASTGOTO,
  159. p1, p2, p3, False
  160. )
  161. else:
  162. print("用法: fast <p1> <p2> <p3>")
  163. else:
  164. print("未知命令")
  165. except KeyboardInterrupt:
  166. break
  167. except Exception as e:
  168. print(f"错误: {e}")
  169. def test_channels(sdk: DahuaSDK):
  170. """测试不同通道号的 PTZ 控制"""
  171. print("\n" + "=" * 50)
  172. print("测试不同通道号")
  173. print("=" * 50)
  174. config = PTZ_CAMERA.copy()
  175. # 连接设备
  176. login_handle, error = sdk.login(
  177. config['ip'], config['port'],
  178. config['username'], config['password']
  179. )
  180. if login_handle is None:
  181. print(f"连接失败: 错误码={error}")
  182. return
  183. print(f"连接成功: handle={login_handle}")
  184. # 测试通道 0-3
  185. for channel in range(4):
  186. print(f"\n--- 测试通道 {channel} ---")
  187. # 测试 LEFT 命令
  188. print(f" 测试 LEFT 命令...")
  189. result = sdk.ptz_control(login_handle, channel, PTZCommand.LEFT, 0, 4, 0, False)
  190. if result:
  191. print(f" 通道 {channel}: LEFT 成功 ✓")
  192. time.sleep(1)
  193. # 发送停止
  194. sdk.ptz_control(login_handle, channel, PTZCommand.LEFT, 0, 0, 0, True)
  195. else:
  196. print(f" 通道 {channel}: LEFT 失败 ✗")
  197. time.sleep(0.5)
  198. # 测试 EXACTGOTO
  199. print(f" 测试 EXACTGOTO...")
  200. result = sdk.ptz_control(login_handle, channel, PTZCommand.EXACTGOTO, 900, 0, 1, False)
  201. if result:
  202. print(f" 通道 {channel}: EXACTGOTO 成功 ✓")
  203. else:
  204. print(f" 通道 {channel}: EXACTGOTO 失败 ✗")
  205. time.sleep(1)
  206. sdk.logout(login_handle)
  207. print("\n通道测试完成")
  208. def main():
  209. print("PTZ 控制测试脚本")
  210. print("=" * 50)
  211. # 初始化 SDK
  212. sdk_path = os.path.join(SDK_PATH['lib_path'], SDK_PATH['netsdk'])
  213. print(f"加载 SDK: {sdk_path}")
  214. sdk = DahuaSDK(sdk_path)
  215. if not sdk.init():
  216. print("SDK 初始化失败!")
  217. return 1
  218. print("SDK 初始化成功")
  219. # 询问是否先测试通道
  220. print("\n是否先测试不同通道号? (y/n): ", end="")
  221. if input().strip().lower() == 'y':
  222. test_channels(sdk)
  223. sdk.cleanup()
  224. return 0
  225. # 连接球机
  226. ptz = PTZCamera(sdk, PTZ_CAMERA)
  227. if not ptz.connect():
  228. print("连接球机失败!")
  229. sdk.cleanup()
  230. return 1
  231. print("连接球机成功")
  232. try:
  233. # 运行测试
  234. print("\n选择测试模式:")
  235. print(" 1 - 基本控制测试 (左/右/上/下/变倍)")
  236. print(" 2 - 精确定位测试 (EXACTGOTO)")
  237. print(" 3 - 快速定位测试 (FASTGOTO)")
  238. print(" 4 - 交互式测试")
  239. print(" 5 - 全部测试")
  240. choice = input("\n请选择 (1-5): ").strip()
  241. if choice == '1':
  242. test_ptz_basic_control(ptz)
  243. elif choice == '2':
  244. test_ptz_exact_goto(ptz)
  245. elif choice == '3':
  246. test_ptz_fast_goto(ptz, sdk)
  247. elif choice == '4':
  248. interactive_test(ptz, sdk)
  249. elif choice == '5':
  250. test_ptz_basic_control(ptz)
  251. test_ptz_exact_goto(ptz)
  252. test_ptz_fast_goto(ptz, sdk)
  253. else:
  254. print("无效选择")
  255. finally:
  256. print("\n断开连接...")
  257. ptz.disconnect()
  258. sdk.cleanup()
  259. return 0
  260. if __name__ == '__main__':
  261. sys.exit(main() or 0)