SR7ApiBase.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  1. 
  2. /******************************************************************************
  3. * @file SR7ApiBase.h
  4. * @brief 封装相机图API / Encapsulate camera image API
  5. * @author
  6. * @date 2025-03-17
  7. * @version 1.0.0.0
  8. * @note
  9. *
  10. * 封装取图API,使得调用相机库更简单、直观
  11. * Encapsulate the image acquisition API to make calling the camera library simpler and more intuitive
  12. * -查找相机 / Find camera
  13. * -打开相机 / Open camera
  14. * -初始化相机 / Initialize camera
  15. * -获取数据 / Get data
  16. * -设置相机参数 / Set camera parameters
  17. * -关闭相机 / Turn off camera
  18. *
  19. * @history
  20. * <Date> <Author> <Version> <Description>
  21. * 2025-04-01 GK v1.0.0 初始版本/initial version
  22. *
  23. * @copyright Copyright (c) 2014-2025 SinceVision. All rights reserved.
  24. ******************************************************************************/
  25. using SR7Link;
  26. using System;
  27. using System.Collections.Generic;
  28. using System.Runtime.InteropServices;
  29. using System.Text;
  30. namespace SRAPI
  31. {
  32. public class SRAPIException : Exception
  33. {
  34. public SRAPIException(string message) : base(message) { }
  35. }
  36. // 定义用户数据指针
  37. //using SR7IF_UserData = System.IntPtr;
  38. /// <summary>
  39. /// SR7 API 抽象基类
  40. /// </summary>
  41. public abstract class SR7ApiBase : ISR7Api
  42. {
  43. // 设备控制器ID,默认不可更改
  44. public int ControllerID { get; set; } = 0;
  45. //扫描行数 / Number of scan lines
  46. public int BatchPoints { get; set; } = 0;
  47. //无限循环回调行数 / Infinite loop callback line number
  48. //public int CallBackPoints { get; set; } = 0;
  49. public bool CameraAOnline { get; set; } = false;
  50. public bool CameraBOnline { get; set; } = false;
  51. //数据临时缓存 / Data temporary cache
  52. public IntPtr[] ImgBuff32 = new IntPtr[2];
  53. public IntPtr[] ImgBuff16 = new IntPtr[2];
  54. public IntPtr[] GrayBuff = new IntPtr[2];
  55. public IntPtr[] Encoder = new IntPtr[2];
  56. public SR7IFGetDataCallBack GetDataCallBack;
  57. //method
  58. public abstract int Open(int lDeviceId, string strIP, int timeout, ErrConnectCallBack pfErrCallBack);
  59. /// <summary>
  60. /// 初始化设备
  61. /// </summary>
  62. public abstract int Init(int dwProfileCnt, uint ProfileBits, int nTimeout, SR7IFGetDataCallBack pfGetDataCallBack);
  63. /// <summary>
  64. /// 启动设备
  65. /// </summary>
  66. public abstract int Start(bool bIOTrigger, int timeout);
  67. /// <summary>
  68. /// 停止设备(提供默认参数的重载)
  69. /// </summary>
  70. public int Stop() => Stop(0);
  71. public abstract int Stop(int instantStop);
  72. /// <summary>
  73. /// Close() 断开与相机的连接./Disconnect from the camera.
  74. /// </summary>
  75. /// <returns> <0:失败./Fail. =0:成功./Success</returns>
  76. public virtual int Close()
  77. {
  78. int nRet = Stop();
  79. nRet = SR7LinkFunc.SR7IF_CommClose(ControllerID);
  80. CameraAOnline = false;
  81. CameraBOnline = false;
  82. return nRet;
  83. }
  84. public virtual int GetData(int[] pHighData, byte[] pGrayData, int[] pEncoderData, int nProfileWidth, int nHighlen, int ABCam)
  85. {
  86. if (ABCam < 0 || ABCam >= 2)
  87. return -1;
  88. int totalPoints = nProfileWidth * nHighlen;
  89. if (pHighData != null && ImgBuff32[ABCam] != IntPtr.Zero)
  90. Marshal.Copy(ImgBuff32[ABCam], pHighData, 0, Math.Min(totalPoints, pHighData.Length));
  91. if (pGrayData != null && GrayBuff[ABCam] != IntPtr.Zero)
  92. Marshal.Copy(GrayBuff[ABCam], pGrayData, 0, Math.Min(totalPoints, pGrayData.Length));
  93. if (pEncoderData != null && Encoder[ABCam] != IntPtr.Zero)
  94. Marshal.Copy(Encoder[ABCam], pEncoderData, 0, Math.Min(nHighlen, pEncoderData.Length));
  95. return 0;
  96. }
  97. public virtual int GetData(short[] pHighData, byte[] pGrayData, int[] pEncoderData, int nProfileWidth, int nHighlen, int ABCam)
  98. {
  99. if (ABCam < 0 || ABCam >= 2)
  100. return -1;
  101. int totalPoints = nProfileWidth * nHighlen;
  102. if (pHighData != null && ImgBuff16[ABCam] != IntPtr.Zero)
  103. Marshal.Copy(ImgBuff16[ABCam], pHighData, 0, Math.Min(totalPoints, pHighData.Length));
  104. if (pGrayData != null && GrayBuff[ABCam] != IntPtr.Zero)
  105. Marshal.Copy(GrayBuff[ABCam], pGrayData, 0, Math.Min(totalPoints, pGrayData.Length));
  106. if (pEncoderData != null && Encoder[ABCam] != IntPtr.Zero)
  107. Marshal.Copy(Encoder[ABCam], pEncoderData, 0, Math.Min(nHighlen, pEncoderData.Length));
  108. return 0;
  109. }
  110. /// <summary>
  111. /// 搜索可用摄像头IP(基类提供默认实现,但不强制子类实现)
  112. /// </summary>
  113. public virtual bool SearchCameraIP(out List<string> cameraIPs)
  114. {
  115. cameraIPs = new List<string>();
  116. int[] readNum = new int[1];
  117. try
  118. {
  119. // 使用传统的 using 语法
  120. using (var pin = new PinnedObject(readNum))
  121. {
  122. IntPtr str_Setting = SR7Link.SR7LinkFunc.SR7IF_SearchOnline(pin.Pointer, 3000);
  123. int deviceCount = readNum[0];
  124. if (deviceCount <= 0)
  125. {
  126. return false;
  127. }
  128. byte[][] ipAddressList = new byte[deviceCount][];
  129. for (int i = 0; i < deviceCount; i++)
  130. {
  131. byte[] ip = new byte[4];
  132. Marshal.Copy(str_Setting + 4 * i, ip, 0, 4);
  133. ipAddressList[i] = ip;
  134. cameraIPs.Add(string.Join(".", ip));
  135. }
  136. return true;
  137. }
  138. }
  139. catch (Exception ex)
  140. {
  141. throw new SRAPIException($"Failed to search camera IPs: {ex.Message}");
  142. }
  143. }
  144. public int GetProfileDataWidth()
  145. {
  146. return SR7LinkFunc.SR7IF_ProfileDataWidth(ControllerID, IntPtr.Zero);
  147. }
  148. public int GetProfilePointSetCount()
  149. {
  150. return SR7LinkFunc.SR7IF_ProfilePointSetCount(ControllerID, IntPtr.Zero);
  151. }
  152. public double GetProfileData_XPitch()
  153. {
  154. return SR7LinkFunc.SR7IF_ProfileData_XPitch(ControllerID, IntPtr.Zero);
  155. }
  156. public int SR7IFGet25DSingleProfile(int[] pHighData, uint[] pEncoder)
  157. {
  158. return SR7LinkFunc.SR7IF_GetSingleProfile((uint)ControllerID, pHighData, pEncoder);
  159. }
  160. public int SR7IFGet3DSingleProfile(int[] pHighData)
  161. {
  162. return SR7LinkFunc.SR7IF_GetSingleProfile3DMode((uint)ControllerID, pHighData);
  163. }
  164. ///
  165. /// \brief SetParams SetSetting.
  166. /// \param nAB [in] 相机A为0,B为1 / Camera A is 0, B is 1
  167. /// \param nConfigNum [in] 配方编号 -1:当前配方,0-63指定配方 / Recipe number -1: current recipe, 0-63 specifies the recipe
  168. /// \param nParamItemEnums [in] 参数项枚举,参考SRSettingHeader.h SR7IF_SETTING_ITEM中定义
  169. /// Parameter item enumeration, refer to the definition in SR7IF_SETTING_ITEM in SRSettingHeader.h
  170. /// \param nSetData [in] 设置数据 / Set data
  171. /// \return
  172. /// <0: 失败./Fail.
  173. /// =0: 成功./Success
  174. ///
  175. public int SetParams(int nAB, int nSavePowerOff, int nConfigNum, SR7IF_SETTING_ITEM nParamItemEnums, int nSetData)
  176. {
  177. int nCategory = 0x00;
  178. int nItem = 0x00;
  179. int nDataSize = 1;
  180. if (GetParamsCategory(nParamItemEnums,ref nCategory,ref nItem,ref nDataSize) != 0)
  181. {
  182. return -2;
  183. }
  184. if (nConfigNum != -1)
  185. nConfigNum += 0x10;
  186. //强制小端模式传数据 / Force little-endian mode to transfer data
  187. byte[] pData = new byte[nDataSize];
  188. for (int i = 0; i < nDataSize; i++)
  189. {
  190. pData[i] = (byte)((nSetData >> (i * 8)) & 0xFF);
  191. }
  192. int nRet = 0;
  193. using (PinnedObject pin = new PinnedObject(pData))
  194. {
  195. nRet = SetParams(ControllerID, nSavePowerOff, nConfigNum, nCategory, nItem, nAB, pin, nDataSize);
  196. }
  197. return nRet;
  198. }
  199. ///
  200. /// \brief SetParams 设置参数 SetSetting.
  201. /// \param nDeviceId [in] 控制器ID. / Controller ID
  202. /// \param nDepth [in] 参数是否断电保存,0x01断电不保存,0x02断电保存
  203. /// Whether the parameters are saved when the power is off, 0x01 is not saved when the power is off, 0x02 is saved when the power is off
  204. /// \param nFormulaNum [in] 配方编号 -1:当前配方,0-63指定配方 / Recipe number -1: current recipe, 0-63 specifies the recipe
  205. /// \param nCategory [in] 对应Edgeimage软件中,指定参数页,0:触发设定页面;1:拍摄设定页面;2:轮廓设定页面
  206. /// Corresponding to the Edgeimage software, specify the parameter page, 0: trigger setting page; 1: shooting setting page; 2: contour setting page
  207. /// \param nItem [in] 指定发送 / 接收 nCategory 指定项中的设定项 / Specifies to send/receive the setting items in the specified item of nCategory
  208. /// \param nAB [in] 相机A为0,B为1 / Camera A is 0, B is 1
  209. /// \param pData [in] 写入数据 / Write data
  210. /// \param nDataSize [in] 写入数据的长度 / The length of the written data
  211. /// \return
  212. /// <0: 失败./Fail.
  213. /// =0: 成功./Success
  214. ///
  215. public int SetParams(int nDeviceId, int nSavePowerOff, int nFormulaNum, int nCategory, int nItem, int nAB, PinnedObject pData, int nDataSize)
  216. {
  217. int[] arrayTarget = new int[4] { nAB, 0, 0, 0 };
  218. int nRet = SR7LinkFunc.SR7IF_SetSetting((uint)ControllerID, nSavePowerOff, nFormulaNum, nCategory, nItem, arrayTarget, pData.Pointer, nDataSize);
  219. return nRet;
  220. }
  221. ///
  222. /// \brief GetParams 获取参数 GetSetting.
  223. /// \param nABCamera [in] 相机A为0,B为1 / Camera A is 0, B is 1
  224. /// \param nConfigNum [in] 配方编号 -1:当前配方,0-63指定配方 / Recipe number -1: current recipe, 0-63 specifies the recipe
  225. /// \param nParamItemEnums [in] 参数项枚举,参考SRSettingHeader.h SR7IF_SETTING_ITEM中定义
  226. /// Parameter item enumeration, refer to the definition in SR7IF_SETTING_ITEM in SRSettingHeader.h
  227. /// \param nOutData [out] 获取参数值. / Get parameter value.
  228. /// \return
  229. /// <0: 失败./Fail.
  230. /// =0: 成功./Success
  231. ///
  232. public int GetParams(int nABCamera, int nConfigNum, SR7IF_SETTING_ITEM nParamItemEnums, out int nOutData)
  233. {
  234. nOutData = 0;
  235. int nCategory = 0x00;
  236. int nItem = 0x00;
  237. int nDataSize = 1;
  238. if (GetParamsCategory(nParamItemEnums,ref nCategory,ref nItem,ref nDataSize) != 0)
  239. {
  240. return -3;
  241. }
  242. if (nConfigNum != -1)
  243. nConfigNum += 0x10;
  244. int[] arrayTarget = new int[4] { nABCamera, 0, 0, 0 };
  245. byte[] pData = new byte[nDataSize];
  246. using (PinnedObject pin = new PinnedObject(pData))
  247. {
  248. int nRet = SR7LinkFunc.SR7IF_GetSetting((uint)ControllerID, nConfigNum, nCategory, nItem, arrayTarget, pin.Pointer, nDataSize);
  249. if (0 != nRet)
  250. {
  251. return nRet;
  252. }
  253. //Get Data
  254. for (int i = 0; i < pData.Length; i++)
  255. {
  256. nOutData += pData[i] * (int)Math.Pow(256, i);
  257. }
  258. }
  259. return 0;
  260. }
  261. public int GetParamsCategory(SR7IF_SETTING_ITEM nParamItemEnums, ref int nCategory, ref int nItem, ref int nDataSize)
  262. {
  263. switch (nParamItemEnums)
  264. {
  265. //00
  266. case SR7IF_SETTING_ITEM.TRIG_MODE://触发模式 / Trigger mode
  267. nCategory = 0x00;
  268. nItem = 0x01;
  269. nDataSize = 1;
  270. break;
  271. case SR7IF_SETTING_ITEM.BATCH_OUTPUT://批处理输出 / Batch processing output
  272. nCategory = 0x00;
  273. nItem = 0x21;
  274. nDataSize = 1;
  275. break;
  276. case SR7IF_SETTING_ITEM.SAMPLED_CYCLE://采样周期 / Sampling cycle
  277. nCategory = 0x00;
  278. nItem = 0x02;
  279. nDataSize = 4;
  280. break;
  281. case SR7IF_SETTING_ITEM.BATCH_ON_OFF://批处理开关 / Batch processing switch
  282. nCategory = 0x00;
  283. nItem = 0x03;
  284. nDataSize = 1;
  285. break;
  286. case SR7IF_SETTING_ITEM.ENCODER_TYPE://编码器类型 / Encoder type
  287. nCategory = 0x00;
  288. nItem = 0x0b;
  289. nDataSize = 1;
  290. break;
  291. case SR7IF_SETTING_ITEM.ENCODER_INPUTMODE://编码器输入模式 / Encoder input mode
  292. nCategory = 0x00;
  293. nItem = 0x07;
  294. nDataSize = 1;
  295. break;
  296. case SR7IF_SETTING_ITEM.REFINING_POINTS://细化点数(触发间隔) / Refining points
  297. nCategory = 0x00;
  298. nItem = 0x09;
  299. nDataSize = 2;
  300. break;
  301. case SR7IF_SETTING_ITEM.BATCH_POINT://批处理点数 / Batch processing points
  302. nCategory = 0x00;
  303. nItem = 0x0a;
  304. nDataSize = 2;
  305. break;
  306. case SR7IF_SETTING_ITEM.CYCLICAL_PATTERN://循环模式 0 关闭 1 打开 / Cyclical pattern (0: Off, 1: On)
  307. nCategory = 0x00;
  308. nItem = 0x10;
  309. nDataSize = 1;
  310. break;
  311. case SR7IF_SETTING_ITEM.SEGMENT_BUFER:// 分段存储 0 关闭 1 打开 / Segmented buffer (0: Off, 1: On)
  312. nCategory = 0x00;
  313. nItem = 0x11;
  314. nDataSize = 1;
  315. break;
  316. //01
  317. case SR7IF_SETTING_ITEM.Z_MEASURING_RANGE://Z方向测量范围 / Z-axis measuring range
  318. nCategory = 0x01;
  319. nItem = 0x03;
  320. nDataSize = 1;
  321. break;
  322. case SR7IF_SETTING_ITEM.SENSITIVITY://感光灵敏度 / Sensitivity
  323. nCategory = 0x01;
  324. nItem = 0x05;
  325. nDataSize = 1;
  326. break;
  327. case SR7IF_SETTING_ITEM.EXP_TIME://曝光时间 / Exposure time
  328. nCategory = 0x01;
  329. nItem = 0x06;
  330. nDataSize = 1;
  331. break;
  332. case SR7IF_SETTING_ITEM.LIGHT_CONTROL://光亮控制 / Light control
  333. nCategory = 0x01;
  334. nItem = 0x0B;
  335. nDataSize = 1;
  336. break;
  337. case SR7IF_SETTING_ITEM.LIGHT_MAX://激光亮度上限 / Laser brightness upper limit
  338. nCategory = 0x01;
  339. nItem = 0x0C;
  340. nDataSize = 1;
  341. break;
  342. case SR7IF_SETTING_ITEM.LIGHT_MIN://激光亮度下限 / Laser brightness lower limit
  343. nCategory = 0x01;
  344. nItem = 0x0D;
  345. nDataSize = 1;
  346. break;
  347. case SR7IF_SETTING_ITEM.PEAK_SENSITIVITY://峰值灵敏度 / Peak sensitivity
  348. nCategory = 0x01;
  349. nItem = 0x0F;
  350. nDataSize = 1;
  351. break;
  352. case SR7IF_SETTING_ITEM.PEAK_SELECT://峰值选择 / Peak selection
  353. nCategory = 0x01;
  354. nItem = 0x11;
  355. nDataSize = 1;
  356. break;
  357. //02
  358. case SR7IF_SETTING_ITEM.X_SAMPLING://X轴压缩设定 / X-axis compression setting
  359. nCategory = 0x02;
  360. nItem = 0x02;
  361. nDataSize = 1;
  362. break;
  363. case SR7IF_SETTING_ITEM.FILTER_X_MEDIAN://X轴中位数滤波 / X-axis median filter
  364. nCategory = 0x02;
  365. nItem = 0x0A;
  366. nDataSize = 1;
  367. break;
  368. case SR7IF_SETTING_ITEM.FILTER_Y_MEDIAN://Y轴(时间轴)中位数滤波 / Y-axis (time axis) median filter
  369. nCategory = 0x02;
  370. nItem = 0x0C;
  371. nDataSize = 1;
  372. break;
  373. case SR7IF_SETTING_ITEM.FILTER_X_SMOOTH://X轴平滑滤波 / X-axis smooth filter
  374. nCategory = 0x02;
  375. nItem = 0x0B;
  376. nDataSize = 1;
  377. break;
  378. case SR7IF_SETTING_ITEM.FILTER_Y_SMOOTH://Y轴平滑滤波(平均滤波) / Y-axis smooth filter (mean filter)
  379. nCategory = 0x02;
  380. nItem = 0x0D;
  381. nDataSize = 2;
  382. break;
  383. //30
  384. case SR7IF_SETTING_ITEM.CHANGE_3D_25D://3D/2.5D模式切换 / 3D/2.5D switch (In 2.5D mode, X-axis compression setting changes to default automatically)
  385. nCategory = 0x30;
  386. nItem = 0x00;
  387. nDataSize = 1;
  388. break;
  389. default:
  390. nCategory = 0x00;
  391. nItem = 0x00;
  392. nDataSize = 1;
  393. return -1;
  394. }
  395. return 0;
  396. }
  397. ///
  398. /// \brief SR7IF_Get16BitScale 获取16bit高度数据物理单位 / Get 16-bit height data in physical units
  399. /// \param Scale [out] 16bit高度数据 单位(mm) / 16bit height data Unit (mm)
  400. /// \return
  401. /// <0: 失败./Fail.
  402. /// =0: 成功./Success
  403. ///
  404. public int Get16BitScale(out float Scale)
  405. {
  406. float[] scale1 = new float[1];
  407. int ret = 0;
  408. using (PinnedObject pin_size = new PinnedObject(scale1))
  409. {
  410. ret = SR7LinkFunc.SR7IF_Get16BitScale(0, pin_size.Pointer);
  411. }
  412. Scale = scale1[0];
  413. return ret;
  414. }
  415. }
  416. }