device_tof3d_b.cpp 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186
  1. #include "device_tof3d_b.h"
  2. Error_manager DeviceTof3D::Init(google::protobuf::RepeatedPtrField<tof3dVzenseEtc> &tof_devices) {
  3. LOG(INFO) << "---------- Init DeviceTof3D ----------";
  4. // 使能tof3d相机SDK
  5. m_vz_status = VZ_Initialize();
  6. if (m_vz_status != VzReturnStatus::VzRetOK && m_vz_status != VzReturnStatus::VzRetReInitialized) {
  7. return {TOF3D_VZENSE_DEVICE_INIT_FAILED, MAJOR_ERROR, "VzInitialize failed status: %d", m_vz_status};
  8. }
  9. // 注册相机列表
  10. // 检索相机
  11. // 配置相机列表配置
  12. // 使能相机列表设备
  13. return {TOF3D_VZENSE_DEVICE_INIT_SUCCESS, NORMAL, "VzInitialize success."};
  14. }
  15. Error_manager DeviceTof3D::Init(const VzEtcMap &tp_tof3d, bool search) {
  16. m_vz_status = VZ_Initialize();
  17. if (m_vz_status != VzReturnStatus::VzRetOK && m_vz_status != VzReturnStatus::VzRetReInitialized) {
  18. return {TOF3D_VZENSE_DEVICE_INIT_FAILED, MAJOR_ERROR, "VzInitialize failed status: %d", m_vz_status};
  19. }
  20. auto t_ip_list = INetInfo::getIpv4List();
  21. for (auto &ip: t_ip_list) {
  22. if (ip != "127.0.0.1") {
  23. // 启动grpc服务
  24. LOG(INFO) << "grpc communication with " << ip;
  25. m_grpc_server.Listenning(ip, 9876);
  26. break;
  27. }
  28. }
  29. #ifdef ENABLE_TENSORRT_DETECT
  30. detector = new TensorrtWheelDetector(ETC_PATH PROJECT_NAME "/model.engine", ETC_PATH PROJECT_NAME "/class.txt");
  31. #else
  32. detector = new TensorrtWheelDetector(ETC_PATH PROJECT_NAME "/model.onnx", ETC_PATH PROJECT_NAME "/class.txt");
  33. #endif
  34. loadEtc(tp_tof3d);
  35. if (search) {
  36. SearchDevice(5);
  37. }
  38. ConnectAllEtcDevices();
  39. VZ_SetHotPlugStatusCallback(DeviceTof3D::HotPlugStateCallback, &mp_device_info);
  40. //启动 线程。
  41. for (auto &info: mp_device_info) {
  42. if (!info.second->etc.enable_device()) {
  43. continue;
  44. }
  45. setTof3dParams(info.second->etc.ip());
  46. getTof3dParams(info.second->etc.ip());
  47. mp_thread_info.insert(std::pair<std::string, ThreadInfo>(
  48. info.first, ThreadInfo(new std::thread(&DeviceTof3D::receiveFrameThread, this, info.first),
  49. new Thread_condition()
  50. )
  51. ));
  52. }
  53. for (auto &t: mp_thread_info) {
  54. t.second.condit->notify_all(true);
  55. }
  56. detect_thread.t = new std::thread(&DeviceTof3D::detectThread, this);
  57. detect_thread.condit = new Thread_condition();
  58. detect_thread.condit->notify_all(true);
  59. return {TOF3D_VZENSE_DEVICE_INIT_SUCCESS, NORMAL, "VzInitialize success."};
  60. }
  61. Error_manager DeviceTof3D::SearchDevice(const double &time) {
  62. uint32_t deviceCount = 0;
  63. auto t = std::chrono::steady_clock::now();
  64. std::chrono::duration<double> cost = std::chrono::steady_clock::now() - t;
  65. while (cost.count() < time) {
  66. m_vz_status = VZ_GetDeviceCount(&deviceCount);
  67. cost = std::chrono::steady_clock::now() - t;
  68. if (m_vz_status != VzReturnStatus::VzRetOK) {
  69. LOG(INFO) << "VzGetDeviceCount failed! make sure the DCAM is connected";
  70. std::this_thread::sleep_for(std::chrono::seconds(1));
  71. continue;
  72. }
  73. std::this_thread::sleep_for(std::chrono::seconds(1));
  74. LOG(INFO) << "Found device count: " << deviceCount;
  75. if (deviceCount == 4) {
  76. break;
  77. }
  78. }
  79. VzDeviceInfo *pDeviceListInfo = new VzDeviceInfo[deviceCount];
  80. m_vz_status = VZ_GetDeviceInfoList(deviceCount, pDeviceListInfo);
  81. if (m_vz_status != VzReturnStatus::VzRetOK) {
  82. LOG(INFO) << "GetDeviceListInfo failed status:" << m_vz_status;
  83. return {}; //TODO
  84. } else {
  85. for (int i = 0; i < deviceCount; i++) {
  86. auto iter = mp_device_info.find(pDeviceListInfo[i].ip);
  87. if (iter == mp_device_info.end()) {
  88. mp_device_info.insert(
  89. std::pair<std::string, tof3dVzenseInfo *>(pDeviceListInfo[i].ip, new tof3dVzenseInfo()));
  90. iter = mp_device_info.find(pDeviceListInfo[i].ip);
  91. }
  92. iter->second->info = pDeviceListInfo[i];
  93. LOG(INFO) << "Found device: " << pDeviceListInfo[i].ip;
  94. }
  95. }
  96. return {};
  97. }
  98. Error_manager DeviceTof3D::ConnectDevice(const std::string &ip, bool open_stream) {
  99. auto iter = mp_device_info.find(ip);
  100. if (iter == mp_device_info.end()) {
  101. LOG(WARNING) << "Can\'t find " << ip << " in mp_device_info";
  102. return {}; //TODO
  103. }
  104. m_vz_status = VZ_OpenDeviceByIP(iter->second->info.ip, &iter->second->handle);
  105. if (m_vz_status != VzReturnStatus::VzRetOK) {
  106. iter->second->is_connect = false;
  107. LOG(WARNING) << "OpenDevice " << ip << " failed status:" << m_vz_status;
  108. return {}; //TODO
  109. } else {
  110. iter->second->is_connect = true;
  111. LOG(INFO) << "OpenDevice " << ip << " success status:" << m_vz_status;
  112. }
  113. if (open_stream) {
  114. m_vz_status = VZ_StartStream(iter->second->handle);
  115. if (m_vz_status != VzReturnStatus::VzRetOK) {
  116. iter->second->is_start_stream = false;
  117. LOG(WARNING) << "VZ_StartStream " << ip << " failed status:" << m_vz_status;
  118. return {};
  119. } else {
  120. iter->second->is_start_stream = true;
  121. LOG(INFO) << "VZ_StartStream " << ip << " success status:" << m_vz_status;
  122. }
  123. }
  124. return {};
  125. }
  126. Error_manager DeviceTof3D::ConnectAllEtcDevices(bool open_stream) {
  127. for (auto &device: mp_device_info) {
  128. if (device.second->etc.enable_device()) {
  129. ConnectDevice(device.first, open_stream);
  130. }
  131. }
  132. return {};
  133. }
  134. Error_manager DeviceTof3D::ConnectAllDevices(bool open_stream) {
  135. for (auto &device: mp_device_info) {
  136. ConnectDevice(device.first, open_stream);
  137. }
  138. return {};
  139. }
  140. Error_manager DeviceTof3D::DisConnectDevice(const std::string &ip) {
  141. auto iter = mp_device_info.find(ip);
  142. if (iter == mp_device_info.end()) {
  143. return {}; //TODO
  144. }
  145. m_vz_status = VZ_StopStream(iter->second->handle);
  146. if (m_vz_status != VzReturnStatus::VzRetOK) {
  147. iter->second->is_start_stream = true;
  148. LOG(WARNING) << "VZ_StopStream failed status:" << m_vz_status;
  149. } else {
  150. iter->second->is_start_stream = false;
  151. LOG(INFO) << "VZ_StopStream success status:" << m_vz_status;
  152. }
  153. m_vz_status = VZ_CloseDevice(&iter->second->handle);
  154. if (m_vz_status != VzReturnStatus::VzRetOK) {
  155. iter->second->is_connect = true;
  156. LOG(WARNING) << "VZ_CloseDevice failed status:" << m_vz_status;
  157. } else {
  158. iter->second->is_connect = false;
  159. LOG(INFO) << "VZ_CloseDevice success status:" << m_vz_status;
  160. }
  161. return {};
  162. }
  163. Error_manager DeviceTof3D::DisConnectAllEtcDevices() {
  164. for (auto &device: mp_device_info) {
  165. if (device.second->etc.enable_device()) {
  166. DisConnectDevice(device.first);
  167. }
  168. }
  169. return {};
  170. }
  171. Error_manager DeviceTof3D::DisConnectAllDevices() {
  172. for (auto &device: mp_device_info) {
  173. DisConnectDevice(device.first);
  174. }
  175. return {};
  176. }
  177. Error_manager DeviceTof3D::getDepthFrame(const std::string &ip, VzFrame &depthFrame) {
  178. auto iter = mp_device_info.find(ip);
  179. if (iter == mp_device_info.end()) {
  180. return {FAILED, NORMAL, "Device %s not in list, can\'t get depth frame.", ip.c_str()}; //TODO
  181. }
  182. if (iter->second->handle == nullptr || !iter->second->is_connect) {
  183. if (ConnectDevice(ip, true) != SUCCESS) {
  184. return {FAILED, NORMAL, "Open device %s failed, stop get depth frame.", ip.c_str()};
  185. }
  186. }
  187. VzFrameReady frameReady = {0};
  188. m_vz_status = VZ_GetFrameReady(iter->second->handle, 200, &frameReady);
  189. if (m_vz_status != VzRetOK) {
  190. LOG(WARNING) << ip << " VZ_GetFrameReady failed status:" << m_vz_status;
  191. return {FAILED, MINOR_ERROR, "%s VZ_GetFrameReady failed status %d!", ip.c_str(), m_vz_status}; //TODO
  192. }
  193. if (1 == frameReady.depth) {
  194. m_vz_status = VZ_GetFrame(iter->second->handle, VzDepthFrame, &depthFrame);
  195. if (m_vz_status == VzRetOK && depthFrame.pFrameData != nullptr) {
  196. // LOG(INFO) << ip << " VZ_GetFrame VzDepthFrame success:" << m_vz_status;
  197. } else {
  198. LOG(INFO) << ip << " VZ_GetFrame VzDepthFrame failed:" << m_vz_status;
  199. }
  200. }
  201. return {};
  202. }
  203. Error_manager DeviceTof3D::getIrFrame(const std::string &ip, VzFrame &irFrame) {
  204. auto iter = mp_device_info.find(ip);
  205. if (iter == mp_device_info.end()) {
  206. return {FAILED, NORMAL, "Device %s not in list, can\'t get ir frame.", ip.c_str()}; //TODO
  207. }
  208. if (iter->second->handle == nullptr || !iter->second->is_connect) {
  209. if (ConnectDevice(ip, true) != SUCCESS) {
  210. return {FAILED, NORMAL, "Open device %s failed, stop get ir frame.", ip.c_str()};
  211. }
  212. }
  213. VzFrameReady frameReady = {0};
  214. m_vz_status = VZ_GetFrameReady(iter->second->handle, 200, &frameReady);
  215. if (m_vz_status != VzRetOK) {
  216. LOG(WARNING) << ip << " VZ_GetFrameReady failed status:" << m_vz_status;
  217. return {}; //TODO
  218. }
  219. if (1 == frameReady.ir) {
  220. m_vz_status = VZ_GetFrame(iter->second->handle, VzIRFrame, &irFrame);
  221. if (m_vz_status == VzRetOK && irFrame.pFrameData != nullptr) {
  222. LOG(INFO) << ip << "VZ_GetFrame VzIrFrame success:" << m_vz_status;
  223. } else {
  224. LOG(INFO) << ip << "VZ_GetFrame VzIrFrame failed:" << m_vz_status;
  225. }
  226. }
  227. return {};
  228. }
  229. Error_manager DeviceTof3D::getDepthAndIrPicture(const std::string &ip, VzFrame &depthFrame, VzFrame &irFrame) {
  230. auto iter = mp_device_info.find(ip);
  231. if (iter == mp_device_info.end()) {
  232. return {FAILED, NORMAL, "Device %s not in list, can\'t get depth and ir frame.", ip.c_str()}; //TODO
  233. }
  234. if (iter->second->handle == nullptr || !iter->second->is_connect) {
  235. if (ConnectDevice(ip, true) != SUCCESS) {
  236. return {FAILED, NORMAL, "Open device %s failed, stop get depth and ir frame.", ip.c_str()};
  237. }
  238. }
  239. Error_manager ret;
  240. VzFrameReady frameReady = {0};
  241. m_vz_status = VZ_GetFrameReady(iter->second->handle, 200, &frameReady);
  242. if (m_vz_status != VzRetOK) {
  243. LOG(WARNING) << ip << " VZ_GetFrameReady failed status:" << m_vz_status;
  244. ret.compare_and_merge_up({FAILED, MINOR_ERROR, "Device %s VZ_GetFrameReady failed status: %d.", ip.c_str(),
  245. m_vz_status}); //TODO
  246. return ret;
  247. }
  248. //Get depth frame, depth frame only output in following data mode
  249. if (1 == frameReady.depth) {
  250. m_vz_status = VZ_GetFrame(iter->second->handle, VzDepthFrame, &depthFrame);
  251. if (m_vz_status == VzRetOK && depthFrame.pFrameData != nullptr) {
  252. // LOG(INFO) << ip << " frameIndex :" << depthFrame.frameIndex;
  253. } else {
  254. ret.compare_and_merge_up(
  255. {FAILED, MINOR_ERROR, "Device %s VZ_GetFrame VzIrFrame failed status: %d.", ip.c_str(),
  256. m_vz_status}); //TODO
  257. LOG(INFO) << ip << "VZ_GetFrame VzIrFrame status:" << m_vz_status;
  258. }
  259. } else {
  260. ret.compare_and_merge_up(
  261. {FAILED, MINOR_ERROR, "Device %s VZ_GetFrameReady depth not ready: %d.", ip.c_str(), frameReady.depth});
  262. }
  263. if (1 == frameReady.ir) {
  264. m_vz_status = VZ_GetFrame(iter->second->handle, VzIRFrame, &irFrame);
  265. if (m_vz_status == VzRetOK && irFrame.pFrameData != nullptr) {
  266. // LOG(INFO) << ip << " frameIndex :" << irFrame.frameIndex;
  267. } else {
  268. ret.compare_and_merge_up(
  269. {FAILED, MINOR_ERROR, "Device %s VZ_GetFrame VzIrFrame failed status: %d.", ip.c_str(),
  270. m_vz_status}); //TODO
  271. LOG(INFO) << ip << "VZ_GetFrame VzIrFrame status:" << m_vz_status;
  272. }
  273. } else {
  274. ret.compare_and_merge_up(
  275. {FAILED, NORMAL, "Device %s VZ_GetFrameReady ir not ready: %d.", ip.c_str(), frameReady.depth});
  276. }
  277. return ret;
  278. }
  279. Error_manager DeviceTof3D::getDepthPointCloud(const std::string &ip, pcl::PointCloud<pcl::PointXYZ>::Ptr &cloud) {
  280. auto iter = mp_device_info.find(ip);
  281. if (iter == mp_device_info.end()) {
  282. return {FAILED, NORMAL, "Device %s not in list, can\'t get point cloud.", ip.c_str()}; //TODO
  283. }
  284. if (iter->second->handle == nullptr || !iter->second->is_connect) {
  285. if (ConnectDevice(ip, true) != SUCCESS) {
  286. return {FAILED, NORMAL, "Open device %s failed, stop get point cloud.", ip.c_str()};
  287. }
  288. }
  289. VzFrameReady frameReady = {0};
  290. m_vz_status = VZ_GetFrameReady(iter->second->handle, 200, &frameReady);
  291. if (m_vz_status != VzRetOK) {
  292. LOG(WARNING) << ip << " VZ_GetFrameReady failed status:" << m_vz_status;
  293. return {}; //TODO
  294. }
  295. //Get depth frame, depth frame only output in following data mode
  296. if (1 == frameReady.depth) {
  297. VzFrame depthFrame = {0};
  298. m_vz_status = VZ_GetFrame(iter->second->handle, VzDepthFrame, &depthFrame);
  299. if (m_vz_status == VzRetOK && depthFrame.pFrameData != nullptr) {
  300. LOG(INFO) << ip << " frameIndex :" << depthFrame.frameIndex;
  301. VzFrame &srcFrame = depthFrame;
  302. const int len = srcFrame.width * srcFrame.height;
  303. VzVector3f *worldV = new VzVector3f[len];
  304. m_vz_status = VZ_ConvertDepthFrameToPointCloudVector(iter->second->handle, &srcFrame,
  305. worldV);
  306. if (m_vz_status == VzRetOK) {
  307. cloud->clear();
  308. for (int i = 0; i < len; i++) {
  309. if (worldV[i].x == 0 && worldV[i].y == 0 && worldV[i].z == 0) {
  310. continue;
  311. }
  312. cloud->points.emplace_back(worldV[i].x, worldV[i].y, worldV[i].z);
  313. }
  314. delete[] worldV;
  315. worldV = nullptr;
  316. LOG(INFO) << "Save point cloud successful to cloud: " << cloud->size();
  317. }
  318. } else {
  319. LOG(INFO) << ip << "VZ_GetFrame VzIrFrame status:" << m_vz_status;
  320. }
  321. }
  322. return {};
  323. }
  324. Error_manager DeviceTof3D::DepthFrame2PointCloud(const std::string &ip, VzFrame &depthFrame,
  325. pcl::PointCloud<pcl::PointXYZ>::Ptr &cloud) {
  326. // if (depthFrame.frameType != VzDepthFrame) {
  327. // return {};
  328. // }
  329. //
  330. // auto handle_iter = mp_devices_handle.find(ip);
  331. // if (handle_iter == mp_devices_handle.end()) {
  332. // return {}; //TODO
  333. // }
  334. //
  335. // cloud->clear();
  336. // if (handle_iter->second) {
  337. //
  338. // VzFrame &srcFrame = depthFrame;
  339. // const int len = srcFrame.width * srcFrame.height;
  340. // VzVector3f *worldV = new VzVector3f[len];
  341. //
  342. // VZ_ConvertDepthFrameToPointCloudVector(handle_iter->second, &depthFrame, worldV);
  343. //
  344. // for (int i = 0; i < len; i++) {
  345. // cloud->points.emplace_back(worldV[i].x, worldV[i].y, worldV[i].z);
  346. // }
  347. // delete[] worldV;
  348. // worldV = nullptr;
  349. // LOG(INFO) << "Save point cloud successful to cloud: " << cloud->size();
  350. // WriteTxtCloud(ETC_PATH"Tof3d/data/cloud.txt", cloud);
  351. // }
  352. return {};
  353. }
  354. Error_manager DeviceTof3D::Frame2Mat(VzFrame &frame, cv::Mat &mat) {
  355. switch (frame.frameType) {
  356. case VzDepthFrame:
  357. return DepthFrame2Mat(frame, mat);
  358. case VzIRFrame:
  359. return IrFrame2Mat(frame, mat);
  360. default:
  361. break;
  362. }
  363. return {};
  364. }
  365. Error_manager DeviceTof3D::DepthFrame2Mat(VzFrame &frame, cv::Mat &mat) {
  366. if (frame.frameType != VzDepthFrame) {
  367. return {};
  368. }
  369. if (mat.type() != CV_16UC1) {
  370. LOG(INFO) << "Mat type " << mat.type() << " not is " << CV_16UC1;
  371. return {};
  372. }
  373. if (mat.rows != 480 || mat.cols != 640) {
  374. LOG(INFO) << "Mat size (" << mat.rows << ", " << mat.cols << ") not is (480, 640)";
  375. return {};
  376. }
  377. memcpy(mat.data, frame.pFrameData, frame.dataLen);
  378. mat.convertTo(mat, CV_8U, 255.0 / 7495);
  379. applyColorMap(mat, mat, cv::COLORMAP_RAINBOW);
  380. return {};
  381. }
  382. Error_manager DeviceTof3D::IrFrame2Mat(VzFrame &frame, cv::Mat &mat) {
  383. if (frame.frameType != VzIRFrame) {
  384. return {};
  385. }
  386. if (mat.type() != CV_8UC1) {
  387. LOG(INFO) << "Mat type " << mat.type() << " not is " << CV_8UC1;
  388. return {};
  389. }
  390. if (mat.rows != 480 || mat.cols != 640) {
  391. LOG(INFO) << "Mat size (" << mat.rows << ", " << mat.cols << ") not is (480, 640)";
  392. return {};
  393. }
  394. memcpy(mat.data, frame.pFrameData, frame.dataLen);
  395. return {};
  396. }
  397. #include <random>
  398. #include "file/pathcreator.h"
  399. void DeviceTof3D::receiveFrameThread(const std::string &ip) {
  400. LOG(INFO) << ip << " in thread " << std::this_thread::get_id();
  401. auto iter = mp_device_info.find(ip);
  402. auto t_iter = mp_thread_info.find(ip);
  403. std::default_random_engine e;
  404. e.seed(time(0));
  405. const std::string path = ETC_PATH PROJECT_NAME "/image/";
  406. Eigen::Matrix3f rotation_matrix3;
  407. rotation_matrix3 =
  408. Eigen::AngleAxisf(iter->second->etc.trans().yaw() * M_PI / 180.f, Eigen::Vector3f::UnitZ()) *
  409. Eigen::AngleAxisf(iter->second->etc.trans().pitch() * M_PI / 180.f, Eigen::Vector3f::UnitY()) *
  410. Eigen::AngleAxisf(iter->second->etc.trans().roll() * M_PI / 180.f, Eigen::Vector3f::UnitX());
  411. Eigen::Matrix4f pcl_transform;
  412. pcl_transform.setIdentity();
  413. pcl_transform.block<3,3>(0,0) = rotation_matrix3;
  414. Eigen::Vector3f move;
  415. move << iter->second->etc.trans().x(), iter->second->etc.trans().y(), iter->second->etc.trans().z();
  416. pcl_transform.topRightCorner<3, 1>() = move;
  417. pcl::PointCloud<pcl::PointXYZ>::Ptr frame_cloud(new pcl::PointCloud<pcl::PointXYZ>);
  418. LOG(INFO) << "\n" << pcl_transform;
  419. while (t_iter->second.condit->is_alive()) {
  420. t_iter->second.condit->wait();
  421. if (t_iter->second.condit->is_alive()) {
  422. Error_manager ret;
  423. if (iter->second->handle) {
  424. DeviceMat depthInfo;
  425. VzFrame depthFrame = {0};
  426. VzFrame irFrame = {0};
  427. frame_cloud->clear();
  428. // 图像获取
  429. if (getDepthAndIrPicture(ip, depthFrame, irFrame) == SUCCESS &&
  430. Frame2Mat(depthFrame, depthInfo.depthMat) == SUCCESS &&
  431. Frame2Mat(irFrame, depthInfo.irMat) == SUCCESS) {
  432. // 点云转换
  433. VzSensorIntrinsicParameters cameraParam = {};
  434. VZ_GetSensorIntrinsicParameters(iter->second->handle, VzToFSensor, &cameraParam);
  435. const uint16_t *pDepthFrameData = (uint16_t *) depthFrame.pFrameData;
  436. for (int cols = 0; cols < depthInfo.pointMat.cols - 0; cols++) {
  437. for (int rows = 0; rows < depthInfo.pointMat.rows - 0; rows++) {
  438. VzDepthVector3 depthPoint = {cols, rows, pDepthFrameData[rows * depthInfo.pointMat.cols + cols]};
  439. VzVector3f worldV = {};
  440. VZ_ConvertDepthToPointCloud(iter->second->handle, &depthPoint, &worldV, 1, &cameraParam);
  441. if (sqrt(worldV.x * worldV.x + worldV.y * worldV.y + worldV.z * worldV.z) * 0.001f > 5) {
  442. continue;
  443. }
  444. frame_cloud->emplace_back(worldV.x * 0.001f, worldV.y * 0.001f, worldV.z * 0.001f);
  445. Eigen::Vector3f trans;
  446. trans << worldV.x * 0.001f, worldV.y * 0.001f, worldV.z * 0.001f;
  447. trans = rotation_matrix3 * trans + move;
  448. if (trans(2) < 0.03 || fabs(trans(0)) > 1.5 || fabs(trans(1)) > 2.7 || trans(2) > 1) {
  449. continue;
  450. }
  451. depthInfo.pointMat.at<cv::Vec4f>(rows, cols)[0] = trans(0);
  452. depthInfo.pointMat.at<cv::Vec4f>(rows, cols)[1] = trans(1);
  453. depthInfo.pointMat.at<cv::Vec4f>(rows, cols)[2] = trans(2);
  454. }
  455. }
  456. // 将图片和点云存储起来
  457. m_device_mat[iter->second->etc.azimuth()].reset(depthInfo, 0.4);
  458. } else {
  459. ret.compare_and_merge_up({FAILED, MINOR_ERROR, "Device %s VZ_GetFrame failed.", ip.c_str()});
  460. }
  461. } else {
  462. LOG_EVERY_N(WARNING, 1000) << ip << " device handle is null.";
  463. }
  464. if (!ret.get_error_description().empty()) {
  465. LOG(INFO) << ret.get_error_description();
  466. }
  467. std::this_thread::sleep_for(std::chrono::milliseconds(1));
  468. }
  469. }
  470. DisConnectDevice(ip);
  471. LOG(INFO) << ip << " thread end " << std::this_thread::get_id();
  472. }
  473. void DeviceTof3D::detectThread() {
  474. LOG(INFO) << "detect thread running in " << std::this_thread::get_id();
  475. pcl::PointCloud<pcl::PointXYZ>::Ptr t_wheel_cloud(new pcl::PointCloud<pcl::PointXYZ>);
  476. std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> vct_wheel_cloud;
  477. for (int i = 0; i < DeviceAzimuth::MAX; i++) {
  478. vct_wheel_cloud.emplace_back(new pcl::PointCloud<pcl::PointXYZ>);
  479. }
  480. auto t_start_time = std::chrono::steady_clock::now();
  481. std::chrono::duration<double> cost = std::chrono::steady_clock::now() - t_start_time;
  482. int index = 0;
  483. const std::string path = ETC_PATH PROJECT_NAME "/image/";
  484. if (PathCreator::IsFolder(path)) {
  485. std::vector<std::string> imagePathList;
  486. cv::glob(path + "/*.jpg", imagePathList);
  487. index = imagePathList.size();
  488. }
  489. DetectResult detect_result;
  490. while (detect_thread.condit->is_alive()) {
  491. detect_thread.condit->wait();
  492. // 参数初始化
  493. t_wheel_cloud->clear();
  494. detect_result.reset();
  495. t_start_time = std::chrono::steady_clock::now();
  496. if (detect_thread.condit->is_alive()) {
  497. ::JetStream::ResFrame frame;
  498. // 获取最新数据
  499. cv::Mat merge_mat = cv::Mat::zeros(480*2, 640*2, CV_8UC1);
  500. DeviceMat t_device_mat[DeviceAzimuth::MAX];
  501. for (int device_index = 0; device_index < DeviceAzimuth::MAX; device_index++) {
  502. if (!m_device_mat[device_index].timeout()) {
  503. detect_result.wheel[device_index].haveCloud = true;
  504. t_device_mat[device_index] = m_device_mat[device_index].Get();
  505. // 拼接图像
  506. cv::Mat merge_mat_lf = merge_mat(cv::Rect(0, 0, 640, 480));
  507. t_device_mat[device_index].irMat.copyTo(
  508. merge_mat(cv::Rect(
  509. (device_index & 0x1) * t_device_mat[device_index].irMat.cols,
  510. ((device_index & 0x2) >> 1) * t_device_mat[device_index].irMat.rows,
  511. t_device_mat[device_index].irMat.cols,
  512. t_device_mat[device_index].irMat.rows)));
  513. grpcVzenseMat(frame, (DeviceAzimuth)device_index, t_device_mat[device_index].irMat);
  514. } else {
  515. DLOG(WARNING) << device_index << " not get data.";
  516. }
  517. }
  518. cost = std::chrono::steady_clock::now() - t_start_time;
  519. LOG(INFO) << "cost time is " << cost.count() * 1000 << " ms";
  520. // 模型识别
  521. std::vector<Object> objs;
  522. cv::Mat mer_mat_rgb;
  523. cv::cvtColor(merge_mat, mer_mat_rgb, cv::COLOR_GRAY2RGB);
  524. detector->detect(mer_mat_rgb, objs, mer_mat_rgb);
  525. cost = std::chrono::steady_clock::now() - t_start_time;
  526. LOG(INFO) << "cost time is " << cost.count() * 1000 << " ms";
  527. // 标记识别点云
  528. bool save_image = false;
  529. for (auto &obj: objs) {
  530. if (obj.prob > 0.9) {
  531. auto seg_points = detector->getPointsFromObj(obj);
  532. int device_index = (int(seg_points[0].x / 640) * 0x01) | (int(seg_points[0].y / 480) << 1);
  533. detect_result.wheel[device_index].detectOk = true;
  534. vct_wheel_cloud[device_index]->clear();
  535. float d = MAX(obj.rect.height, obj.rect.width) / 2;
  536. pcl::PointXYZ point;
  537. int x_alpha = (device_index & 0x1);
  538. int y_alpha = ((device_index & 0x2) >> 1);
  539. for (auto &pt: seg_points) { // use 7.5~9ms
  540. pt.x -= x_alpha * t_device_mat[device_index].irMat.cols;
  541. pt.y -= y_alpha * t_device_mat[device_index].irMat.rows;
  542. t_device_mat[device_index].pointMat.at<cv::Vec4f>(pt)[3] = obj.prob;
  543. point.x = t_device_mat[device_index].pointMat.at<cv::Vec4f>(pt)[0];
  544. point.y = t_device_mat[device_index].pointMat.at<cv::Vec4f>(pt)[1];
  545. point.z = t_device_mat[device_index].pointMat.at<cv::Vec4f>(pt)[2];
  546. vct_wheel_cloud[device_index]->push_back(point);
  547. }
  548. // 自动存图功能
  549. // cv::Point rect_center;
  550. // rect_center.x = obj.rect.x + obj.rect.width * 0.5 - (device_index & 0x1) * t_device_mat[device_index].irMat.cols;
  551. // rect_center.y = obj.rect.y + obj.rect.height * 0.5 - ((device_index & 0x2) >> 1) * t_device_mat[device_index].irMat.rows;
  552. // detect_result.wheel[device_index].center.x = t_device_mat[device_index].pointMat.at<cv::Vec4f>(rect_center)[0];
  553. // detect_result.wheel[device_index].center.y = t_device_mat[device_index].pointMat.at<cv::Vec4f>(rect_center)[1];
  554. // if (fabs(m_detect_result_record.wheel[device_index].center.y - detect_result.wheel[device_index].center.y) > 0.2) {
  555. // save_image = true;
  556. // }
  557. }
  558. }
  559. // if (save_image) {
  560. // std::string file_name = ETC_PATH PROJECT_NAME "/image/merge_" + std::to_string(index++)+ ".jpg";
  561. // cv::imwrite(file_name, merge_mat);
  562. // }
  563. // 提取点云数据
  564. for (int device_index = 0; device_index < DeviceAzimuth::MAX; device_index++) {
  565. if(!detect_result.wheel[device_index].haveCloud) { continue;}
  566. grpcVzensePointMat(frame, (DeviceAzimuth)device_index, t_device_mat[device_index].pointMat); // use 10ms
  567. }
  568. cv::imshow("mergeImage", mer_mat_rgb);
  569. cv::waitKey(1);
  570. cost = std::chrono::steady_clock::now() - t_start_time;
  571. LOG(INFO) << "cost time is " << cost.count() * 1000 << " ms";
  572. // 当没有车辆点云的时候,说明规定区域内没有车辆,将重置测量记录
  573. if (objs.empty()) {
  574. m_detect_result_record.reset();
  575. }
  576. // 点云处理
  577. if (!objs.empty()) {
  578. // CarPoseOptimize(viewer, view_port, t_car_cloud, detect_result);
  579. // cost = std::chrono::steady_clock::now() - t_start_time;
  580. // LOG(INFO) << "cost time is " << cost.count() * 1000 << " ms";
  581. WheelCloudOptimize(vct_wheel_cloud, detect_result);
  582. cost = std::chrono::steady_clock::now() - t_start_time;
  583. LOG(INFO) << "cost time is " << cost.count() * 1000 << " ms";
  584. detect_wheel_ceres detector;
  585. if (m_detect_result_record.car.wheel_width < 1.0 || m_detect_result_record.car.wheel_base < 2.0 ||
  586. objs.size() > 2) {
  587. detect_result.car.wheel_width = 3;
  588. detect_result.car.wheel_base = 2.7;
  589. detector.detect(vct_wheel_cloud[DeviceAzimuth::LF], vct_wheel_cloud[DeviceAzimuth::RF],
  590. vct_wheel_cloud[DeviceAzimuth::LR], vct_wheel_cloud[DeviceAzimuth::RR],
  591. detect_result.car.wheels_center_x, detect_result.car.wheels_center_y,
  592. detect_result.car.theta, detect_result.car.wheel_base,
  593. detect_result.car.wheel_width,detect_result.car.front_wheels_theta);
  594. if ((m_detect_result_record.car.wheel_width < 1.0 && m_detect_result_record.car.wheel_base < 1.0 && objs.size() == 2) || objs.size() < 2) {
  595. detect_result.car.wheel_width = 0;
  596. detect_result.car.wheel_base = 0;
  597. } else if (objs.size() == 2) {
  598. std::vector<int> have_cloud;
  599. for (int device_index = 0; device_index < DeviceAzimuth::MAX; device_index++) {
  600. if (!vct_wheel_cloud[device_index]->empty()) {
  601. have_cloud.push_back(device_index);
  602. }
  603. }
  604. if (have_cloud[0] % 2 == have_cloud[1] %2) {
  605. detect_result.car.wheel_width = 0;
  606. } else {
  607. detect_result.car.wheel_base = 0;
  608. }
  609. }
  610. } else {
  611. detector.detect_dynP(vct_wheel_cloud[DeviceAzimuth::LF], vct_wheel_cloud[DeviceAzimuth::RF],
  612. vct_wheel_cloud[DeviceAzimuth::LR], vct_wheel_cloud[DeviceAzimuth::RR],
  613. detect_result.car.wheels_center_x, detect_result.car.wheels_center_y,
  614. detect_result.car.theta, m_detect_result_record.car.wheel_base,
  615. m_detect_result_record.car.wheel_width,detect_result.car.front_wheels_theta);
  616. detect_result.car.wheel_base = m_detect_result_record.car.wheel_base;
  617. detect_result.car.wheel_width = m_detect_result_record.car.wheel_width;
  618. }
  619. m_detect_result_record = detect_result;
  620. }
  621. cost = std::chrono::steady_clock::now() - t_start_time;
  622. LOG(INFO) << "cost time is " << cost.count() * 1000 << " ms";
  623. // 算法结果处理
  624. static float min_wheel_width = 1e8, max_wheel_width = -1e8, min_wheel_base = 1e8, max_wheel_base = -1e8;
  625. if (m_detect_result_record.car.wheel_width > 1.0) {
  626. min_wheel_width = std::min(min_wheel_width, m_detect_result_record.car.wheel_width);
  627. max_wheel_width = std::max(max_wheel_width, m_detect_result_record.car.wheel_width);
  628. }
  629. if (m_detect_result_record.car.wheel_base > 1.0) {
  630. min_wheel_base = std::min(min_wheel_base, m_detect_result_record.car.wheel_base);
  631. max_wheel_base = std::max(max_wheel_base, m_detect_result_record.car.wheel_base);
  632. }
  633. char debug_info[512];
  634. sprintf(debug_info, "\nwidth: (%0.4f, %0.4f, %0.4f), base: (%0.4f, %0.4f, %0.4f)\n",
  635. min_wheel_width, m_detect_result_record.car.wheel_width, max_wheel_width,
  636. min_wheel_base, m_detect_result_record.car.wheel_base, max_wheel_base);
  637. // grpc数据传出
  638. frame.mutable_measure_info()->set_x(m_detect_result_record.car.wheels_center_x);
  639. frame.mutable_measure_info()->set_y(m_detect_result_record.car.wheels_center_y);
  640. frame.mutable_measure_info()->set_width(m_detect_result_record.car.wheel_width);
  641. frame.mutable_measure_info()->set_wheelbase(m_detect_result_record.car.wheel_base);
  642. frame.mutable_measure_info()->set_theta(m_detect_result_record.car.theta);
  643. frame.mutable_measure_info()->set_ftheta(m_detect_result_record.car.front_wheels_theta);
  644. frame.mutable_measure_info()->set_error(m_detect_result_record.info() + debug_info);
  645. LOG(INFO) << frame.measure_info().error();
  646. m_grpc_server.ResetData(frame);
  647. cost = std::chrono::steady_clock::now() - t_start_time;
  648. m_detect_result_record = detect_result;
  649. DLOG(INFO) << "All cost time is " << cost.count() * 1000 << " ms";
  650. usleep(1000 * 100);
  651. }
  652. }
  653. LOG(INFO) << "detect thread " << std::this_thread::get_id() << " closed.";
  654. }
  655. void DeviceTof3D::HotPlugStateCallback(const VzDeviceInfo *pInfo, int status, void *contex) {
  656. LOG(WARNING) << "uri " << status << " " << pInfo->uri << " " << (status == 0 ? "add" : "remove");
  657. LOG(WARNING) << "alia " << status << " " << pInfo->alias << " " << (status == 0 ? "add" : "remove");
  658. if (contex == nullptr) {
  659. return;
  660. }
  661. tof3dVzenseInfoMap *mp = (tof3dVzenseInfoMap *) contex;
  662. auto iter = mp->find(pInfo->ip);
  663. LOG(INFO) << iter->first;
  664. if (status == 0) {
  665. LOG(WARNING) << "VZ_OpenDevice " << VZ_OpenDeviceByUri(pInfo->uri, &iter->second->handle);
  666. LOG(WARNING) << "VZ_StartStream " << VZ_StartStream(iter->second->handle);
  667. iter->second->is_connect = true;
  668. iter->second->is_start_stream = true;
  669. } else {
  670. LOG(WARNING) << "VZ_StopStream " << VZ_StopStream(iter->second->handle);
  671. LOG(WARNING) << "VZ_CloseDevice " << VZ_CloseDevice(&iter->second->handle);
  672. iter->second->is_connect = false;
  673. iter->second->is_start_stream = false;
  674. }
  675. }
  676. bool DeviceTof3D::drawBox(cv::Mat &mat, cv::Rect &box, cv::Scalar &color, std::string className, float confidence) {
  677. // Detection box
  678. cv::rectangle(mat, box, color, 2);
  679. // Detection box text
  680. std::string classString = className + ' ' + std::to_string(confidence).substr(0, 4);
  681. cv::Size textSize = cv::getTextSize(classString, cv::FONT_HERSHEY_DUPLEX, 1, 2, 0);
  682. cv::Rect textBox(box.x, box.y - 40, textSize.width + 10, textSize.height + 20);
  683. cv::rectangle(mat, textBox, color, cv::FILLED);
  684. cv::putText(mat, classString, cv::Point(box.x + 5, box.y - 10), cv::FONT_HERSHEY_DUPLEX, 1, cv::Scalar(0, 0, 0), 2,
  685. 0);
  686. return true;
  687. }
  688. Error_manager DeviceTof3D::updateTof3dEtc() {
  689. for (auto &info: mp_device_info) {
  690. if (info.second->etc.enable_device()) {
  691. }
  692. }
  693. return Error_manager();
  694. }
  695. Error_manager DeviceTof3D::loadEtc(const DeviceTof3D::VzEtcMap &etc) {
  696. for (auto &iter: etc) {
  697. tof3dVzenseInfo *info = new tof3dVzenseInfo();
  698. info->etc = iter.second;
  699. mp_device_info.insert(std::pair<std::string, tof3dVzenseInfo *>(iter.first, info));
  700. LOG(INFO) << "Get device " << iter.first << " etc: " << iter.second.DebugString();
  701. }
  702. return Error_manager();
  703. }
  704. void DeviceTof3D::stopWorking() {
  705. for (auto &info: mp_device_info) {
  706. auto iter = mp_thread_info.find(info.second->etc.ip());
  707. if (iter != mp_thread_info.end()) {
  708. iter->second.condit->kill_all();
  709. iter->second.t->join();
  710. delete iter->second.t;
  711. iter->second.t = nullptr;
  712. }
  713. }
  714. mp_device_info.clear();
  715. mp_thread_info.clear();
  716. }
  717. Error_manager DeviceTof3D::reInit(const VzEtcMap &etc) {
  718. LOG(INFO) << "================= Reinit Device Tof3D.";
  719. stopWorking();
  720. Error_manager ret = Init(etc, true);
  721. return ret;
  722. }
  723. Error_manager DeviceTof3D::setTof3dParams(const std::string &ip) {
  724. auto iter = mp_device_info.find(ip);
  725. if (iter == mp_device_info.end()) {
  726. LOG(WARNING) << "Can\'t find " << ip << " in mp_device_info";
  727. return {}; //TODO
  728. }
  729. m_vz_status = VZ_SetWorkMode(iter->second->handle, (VzWorkMode) iter->second->etc.bip().work_mode());
  730. if (m_vz_status != VzReturnStatus::VzRetOK) {
  731. LOG(WARNING) << ip << " VZ_SetWorkMode failed status:" << m_vz_status;
  732. return {}; //TODO
  733. }
  734. m_vz_status = VZ_SetIRGMMGain(iter->second->handle, iter->second->etc.bip().irgmmgain());
  735. if (m_vz_status != VzReturnStatus::VzRetOK) {
  736. LOG(WARNING) << ip << " VZ_SetIRGMMGain failed status:" << m_vz_status;
  737. return {}; //TODO
  738. }
  739. m_vz_status = VZ_SetFrameRate(iter->second->handle, iter->second->etc.bip().frame_rate());
  740. if (m_vz_status != VzReturnStatus::VzRetOK) {
  741. LOG(WARNING) << ip << " VZ_SetFrameRate failed status:" << m_vz_status;
  742. return {}; //TODO
  743. }
  744. VzExposureTimeParams exposure_param;
  745. exposure_param.mode = (VzExposureControlMode) iter->second->etc.bip().enable_manual_exposure_time();
  746. exposure_param.exposureTime = iter->second->etc.bip().exposure_time();
  747. m_vz_status = VZ_SetExposureTime(iter->second->handle, VzToFSensor, exposure_param);
  748. if (m_vz_status != VzReturnStatus::VzRetOK) {
  749. LOG(WARNING) << ip << " VZ_SetExposureTime failed status:" << m_vz_status;
  750. return {}; //TODO
  751. }
  752. m_vz_status = VZ_SetFillHoleFilterEnabled(iter->second->handle, iter->second->etc.bip().enable_filter_fill_hole());
  753. if (m_vz_status != VzReturnStatus::VzRetOK) {
  754. LOG(WARNING) << ip << " VZ_SetFillHoleFilterEnabled failed status:" << m_vz_status;
  755. return {}; //TODO
  756. }
  757. m_vz_status = VZ_SetSpatialFilterEnabled(iter->second->handle, iter->second->etc.bip().enable_filter_spatial());
  758. if (m_vz_status != VzReturnStatus::VzRetOK) {
  759. LOG(WARNING) << ip << " VZ_SetSpatialFilterEnabled failed status:" << m_vz_status;
  760. return {}; //TODO
  761. }
  762. VzFlyingPixelFilterParams fly;
  763. fly.enable = iter->second->etc.bip().enable_flying_pixel_filter();
  764. fly.threshold = iter->second->etc.bip().flying_pixel_filter_value();
  765. m_vz_status = VZ_SetFlyingPixelFilterParams(iter->second->handle, fly);
  766. if (m_vz_status != VzReturnStatus::VzRetOK) {
  767. LOG(WARNING) << ip << " VZ_SetFlyingPixelFilterParams failed status:" << m_vz_status;
  768. return {}; //TODO
  769. }
  770. VzConfidenceFilterParams confidence;
  771. confidence.enable = iter->second->etc.bip().enable_confidence_filter();
  772. confidence.threshold = iter->second->etc.bip().confidence_filter_value();
  773. m_vz_status = VZ_SetConfidenceFilterParams(iter->second->handle, confidence);
  774. if (m_vz_status != VzReturnStatus::VzRetOK) {
  775. LOG(WARNING) << ip << " VZ_SetConfidenceFilterParams failed status:" << m_vz_status;
  776. return {}; //TODO
  777. }
  778. VzTimeFilterParams time_filter;
  779. time_filter.enable = iter->second->etc.bip().enable_time_filter();
  780. time_filter.threshold = iter->second->etc.bip().time_filter_value();
  781. m_vz_status = VZ_SetTimeFilterParams(iter->second->handle, time_filter);
  782. if (m_vz_status != VzReturnStatus::VzRetOK) {
  783. LOG(WARNING) << ip << " VZ_SetTimeFilterParams failed status:" << m_vz_status;
  784. return {}; //TODO
  785. }
  786. return Error_manager();
  787. }
  788. Error_manager DeviceTof3D::getTof3dParams(const std::string &ip) {
  789. auto iter = mp_device_info.find(ip);
  790. if (iter == mp_device_info.end()) {
  791. LOG(WARNING) << "Can\'t find " << ip << " in mp_device_info";
  792. return {}; //TODO
  793. }
  794. // 获取参数
  795. VzWorkMode mode;
  796. m_vz_status = VZ_GetWorkMode(iter->second->handle, &mode);
  797. if (m_vz_status != VzReturnStatus::VzRetOK) {
  798. LOG(WARNING) << ip << " VZ_GetWorkMode failed status:" << m_vz_status;
  799. return {}; //TODO
  800. }
  801. iter->second->etc.mutable_bip()->set_work_mode(mode);
  802. uint8_t irgmmgain;
  803. m_vz_status = VZ_GetIRGMMGain(iter->second->handle, &irgmmgain);
  804. if (m_vz_status != VzReturnStatus::VzRetOK) {
  805. LOG(WARNING) << ip << " VZ_GetIRGMMGain failed status:" << m_vz_status;
  806. return {}; //TODO
  807. }
  808. iter->second->etc.mutable_bip()->set_irgmmgain(irgmmgain);
  809. int frame_rate;
  810. m_vz_status = VZ_GetFrameRate(iter->second->handle, &frame_rate);
  811. if (m_vz_status != VzReturnStatus::VzRetOK) {
  812. LOG(WARNING) << ip << " VZ_GetFrameRate failed status:" << m_vz_status;
  813. return {}; //TODO
  814. }
  815. iter->second->etc.mutable_bip()->set_frame_rate(frame_rate);
  816. VzExposureTimeParams exposure_param = {VzExposureControlMode_Manual, 0};
  817. m_vz_status = VZ_GetProperty(iter->second->handle, "Py_ToFExposureTimeMax", &exposure_param,
  818. sizeof(exposure_param));
  819. if (m_vz_status != VzReturnStatus::VzRetOK) {
  820. LOG(WARNING) << ip << " VZ_GetExposureTime failed status:" << m_vz_status;
  821. return {}; //TODO
  822. }
  823. iter->second->etc.mutable_bip()->set_enable_manual_exposure_time(exposure_param.mode);
  824. iter->second->etc.mutable_bip()->set_exposure_time(exposure_param.exposureTime);
  825. bool boolret;
  826. m_vz_status = VZ_GetFillHoleFilterEnabled(iter->second->handle, &boolret);
  827. if (m_vz_status != VzReturnStatus::VzRetOK) {
  828. LOG(WARNING) << ip << " VZ_GetFillHoleFilterEnabled failed status:" << m_vz_status;
  829. return {}; //TODO
  830. }
  831. iter->second->etc.mutable_bip()->set_enable_filter_fill_hole(boolret);
  832. m_vz_status = VZ_GetSpatialFilterEnabled(iter->second->handle, &boolret);
  833. if (m_vz_status != VzReturnStatus::VzRetOK) {
  834. LOG(WARNING) << ip << " VZ_GetSpatialFilterEnabled failed status:" << m_vz_status;
  835. return {}; //TODO
  836. }
  837. iter->second->etc.mutable_bip()->set_enable_filter_spatial(boolret);
  838. VzFlyingPixelFilterParams fly;
  839. m_vz_status = VZ_GetFlyingPixelFilterParams(iter->second->handle, &fly);
  840. if (m_vz_status != VzReturnStatus::VzRetOK) {
  841. LOG(WARNING) << ip << " VZ_GetFlyingPixelFilterParams failed status:" << m_vz_status;
  842. return {}; //TODO
  843. }
  844. iter->second->etc.mutable_bip()->set_enable_flying_pixel_filter(fly.enable);
  845. iter->second->etc.mutable_bip()->set_flying_pixel_filter_value(fly.threshold);
  846. VzConfidenceFilterParams confidence;
  847. m_vz_status = VZ_GetConfidenceFilterParams(iter->second->handle, &confidence);
  848. if (m_vz_status != VzReturnStatus::VzRetOK) {
  849. LOG(WARNING) << ip << " VZ_GetConfidenceFilterParams failed status:" << m_vz_status;
  850. return {}; //TODO
  851. }
  852. iter->second->etc.mutable_bip()->set_enable_confidence_filter(confidence.enable);
  853. iter->second->etc.mutable_bip()->set_confidence_filter_value(confidence.threshold);
  854. VzTimeFilterParams time_filter;
  855. m_vz_status = VZ_GetTimeFilterParams(iter->second->handle, &time_filter);
  856. if (m_vz_status != VzReturnStatus::VzRetOK) {
  857. LOG(WARNING) << ip << " VZ_GetTimeFilterParams failed status:" << m_vz_status;
  858. return {}; //TODO
  859. }
  860. iter->second->etc.mutable_bip()->set_enable_time_filter(time_filter.enable);
  861. iter->second->etc.mutable_bip()->set_time_filter_value(time_filter.threshold);
  862. return Error_manager();
  863. }
  864. Error_manager DeviceTof3D::segFrame2CarAndWheel(VzFrame &depth_frame, std::vector<cv::Point> &wheel_cv_cloud,
  865. pcl::PointCloud<pcl::PointXYZ>::Ptr &car_cloud,
  866. pcl::PointCloud<pcl::PointXYZ>::Ptr &wheel_cloud) {
  867. auto iter = mp_device_info.find("192.168.2.102");
  868. if (iter->second->handle != nullptr) {
  869. VzSensorIntrinsicParameters cameraParam = {};
  870. VZ_GetSensorIntrinsicParameters(iter->second->handle, VzToFSensor, &cameraParam);
  871. const uint16_t *pDepthFrameData = (uint16_t *) depth_frame.pFrameData;
  872. for (auto &pt: wheel_cv_cloud) {
  873. VzDepthVector3 depthPoint = {pt.x, pt.y, pDepthFrameData[pt.y * depth_frame.width + pt.x]};
  874. VzVector3f worldV = {};
  875. VZ_ConvertDepthToPointCloud(iter->second->handle, &depthPoint, &worldV, 1, &cameraParam);
  876. wheel_cloud->emplace_back(worldV.x, worldV.y, worldV.z);
  877. }
  878. // LOG(INFO) << wheel_cloud->size();
  879. VzFrame &srcFrame = depth_frame;
  880. const int len = srcFrame.width * srcFrame.height;
  881. VzVector3f *worldV = new VzVector3f[len];
  882. m_vz_status = VZ_ConvertDepthFrameToPointCloudVector(iter->second->handle, &srcFrame,
  883. worldV);
  884. if (m_vz_status == VzRetOK) {
  885. car_cloud->clear();
  886. for (int i = 0; i < len; i++) {
  887. if (worldV[i].x == 0 && worldV[i].y == 0 && worldV[i].z == 0) {
  888. continue;
  889. }
  890. car_cloud->points.emplace_back(worldV[i].x, worldV[i].y, worldV[i].z);
  891. }
  892. delete[] worldV;
  893. worldV = nullptr;
  894. // LOG(INFO) << "Save point cloud successful to cloud: " << car_cloud->size();
  895. }
  896. // for (int i = (depth_frame.height - WINDOW_SIZE)/2, offset = i * depth_frame.width; i < (depth_frame.height + WINDOW_SIZE)/2; i++)
  897. // {
  898. // for (int j = (depth_frame.width - WINDOW_SIZE)/2; j < (depth_frame.width + WINDOW_SIZE)/2; j++)
  899. // {
  900. // VzDepthVector3 depthPoint = {j, i, pDepthFrameData[offset + j]};
  901. // VzVector3f worldV = {};
  902. // VZ_ConvertDepthToPointCloud(iter->second->handle, &depthPoint, &worldV, 1, &cameraParam);
  903. // if (0 < worldV.z && worldV.z < 0xFFFF)
  904. // {
  905. // LOG(INFO) << worldV.x << "\t" << worldV.y << "\t" << worldV.z << std::endl;
  906. // }
  907. // }
  908. // offset += depth_frame.width;
  909. // }
  910. }
  911. return Error_manager();
  912. }
  913. Error_manager DeviceTof3D::WheelCloudOptimize(std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> &vct_wheel_cloud, DetectResult &result) {
  914. // 1、检测模型识别结果, 如果没有结、只有一个车轮、同侧车轮的结果, 返回无法策略
  915. // char seg_ret = 0;
  916. // for (int i = 0; i < DeviceAzimuth::MAX; i++) {
  917. // seg_ret |= result.wheel[i].segmentOk << i;
  918. // }
  919. // if (seg_ret == 0x1 || seg_ret == 0x2 || seg_ret == 0x4 || seg_ret == 0x8 ||
  920. // seg_ret == 0x0 || seg_ret == 0x5 || seg_ret == 0xa) {
  921. // return {};
  922. // }
  923. //下采样
  924. pcl::VoxelGrid<pcl::PointXYZ> vox; //创建滤波对象
  925. vox.setLeafSize(0.03f, 0.03f, 0.03f); //设置滤波时创建的体素体积为1cm的立方体
  926. //离群点过滤
  927. pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;
  928. sor.setMeanK(10); //K近邻搜索点个数
  929. sor.setStddevMulThresh(2.0); //标准差倍数
  930. sor.setNegative(false); //保留未滤波点(内点)
  931. // 2、
  932. pcl::PointCloud<pcl::PointXYZ>::Ptr filtered_cloud(new pcl::PointCloud<pcl::PointXYZ>);
  933. for (int device_index = 0; device_index < DeviceAzimuth::MAX; device_index++) {
  934. // vct_wheel_cloud[device_index]->clear();
  935. // Point3D_tool::ReadTxtCloud(ETC_PATH PROJECT_NAME "/data/save/wheel_" + std::to_string(device_index) + "_cloud.txt", vct_wheel_cloud[device_index]);
  936. if (vct_wheel_cloud[device_index]->empty()) { continue;}
  937. vox.setInputCloud(vct_wheel_cloud[device_index]); //设置需要过滤的点云给滤波对象
  938. vox.filter(*vct_wheel_cloud[device_index]); //执行滤波处理,存储输出
  939. sor.setInputCloud(vct_wheel_cloud[device_index]);
  940. sor.filter(*vct_wheel_cloud[device_index]); //保存滤波结果到cloud_filter
  941. // filtered_cloud->clear();
  942. // WheelCeresDetector::get_instance_references().detect(vct_wheel_cloud[device_index], filtered_cloud, result.wheel[device_index], device_index % 2);
  943. // vct_wheel_cloud[device_index]->clear();
  944. // vct_wheel_cloud[device_index]->operator+=(*filtered_cloud);
  945. // Point3D_tool::WriteTxtCloud(ETC_PATH PROJECT_NAME "/data/filtered_wheel_" + std::to_string(device_index) + "_cloud.txt", filtered_cloud);
  946. // Point3D_tool::WriteTxtCloud(ETC_PATH PROJECT_NAME "/data/wheel_" + std::to_string(device_index) + "_cloud.txt", vct_wheel_cloud[device_index]);
  947. }
  948. // WheelCeresDetector::get_instance_references().detect(vct_wheel_cloud, filtered_cloud, result.wheel);
  949. // filtered_cloud->clear();
  950. // vct_wheel_cloud[DeviceAzimuth::LR]->clear();
  951. // WheelCeresDetector::get_instance_references().detect(vct_wheel_cloud[DeviceAzimuth::LR], filtered_cloud, result.wheel[DeviceAzimuth::LR],
  952. // vct_wheel_cloud[DeviceAzimuth::RR], filtered_cloud, result.wheel[DeviceAzimuth::RR]);
  953. // Point3D_tool::WriteTxtCloud(ETC_PATH PROJECT_NAME "/data/filtered_wheel_r_cloud.txt", filtered_cloud);
  954. // if (fabs(result.wheel[DeviceAzimuth::RR].theta) > 2.2) {exit(1);}
  955. return Error_manager();
  956. }
  957. Error_manager DeviceTof3D::CarPoseOptimize(pcl::visualization::PCLVisualizer &viewer, int *view_port, pcl::PointCloud<pcl::PointXYZ>::Ptr &car_cloud, DetectResult &result) {
  958. result.car.wheel_width = result.wheel[DeviceAzimuth::RR].center.x - result.wheel[DeviceAzimuth::LR].center.x;
  959. result.car.theta = (result.wheel[DeviceAzimuth::LR].theta + result.wheel[DeviceAzimuth::RR].theta) * 0.5;
  960. result.car.wheels_center_x = (result.wheel[DeviceAzimuth::LF].center.x + result.wheel[DeviceAzimuth::RF].center.x + result.wheel[DeviceAzimuth::LR].center.x + result.wheel[DeviceAzimuth::LR].center.x) * 0.25;
  961. result.car.wheels_center_y = (result.wheel[DeviceAzimuth::LF].center.y + result.wheel[DeviceAzimuth::RF].center.y + result.wheel[DeviceAzimuth::LR].center.y + result.wheel[DeviceAzimuth::LR].center.y) * 0.25;
  962. result.car.front_wheels_theta = (result.wheel[DeviceAzimuth::LF].theta + result.wheel[DeviceAzimuth::RF].theta) * 0.5 - result.car.theta;
  963. result.car.wheel_base = result.wheel[DeviceAzimuth::LF].center.y - result.wheel[DeviceAzimuth::LR].center.y;
  964. LOG(INFO) << result.car.info();
  965. return Error_manager();
  966. }
  967. Error_manager DeviceTof3D::grpcVzenseMat(JetStream::ResFrame &frame, const DeviceAzimuth &azimuth,cv::Mat &mat) {
  968. switch (azimuth) {
  969. case LF:
  970. frame.mutable_images()->mutable_img1()->CopyFrom(StreamRpcServer::cvMat2JetImage(mat));
  971. break;
  972. case RF:
  973. frame.mutable_images()->mutable_img2()->CopyFrom(StreamRpcServer::cvMat2JetImage(mat));
  974. break;
  975. case LR:
  976. frame.mutable_images()->mutable_img3()->CopyFrom(StreamRpcServer::cvMat2JetImage(mat));
  977. break;
  978. case RR:
  979. frame.mutable_images()->mutable_img4()->CopyFrom(StreamRpcServer::cvMat2JetImage(mat));
  980. break;
  981. default:
  982. break;
  983. }
  984. return {};
  985. }
  986. Error_manager DeviceTof3D::grpcVzensePointMat(JetStream::ResFrame &frame, const DeviceAzimuth &azimuth,cv::Mat &mat) {
  987. switch (azimuth) {
  988. case LF:
  989. frame.mutable_clouds()->mutable_cloud1()->CopyFrom(StreamRpcServer::cvPointMat2JetPointCloud(mat));
  990. // LOG(INFO) << "frame.clouds().cloud1().size(): " << frame.clouds().cloud1().size();
  991. break;
  992. case RF:
  993. frame.mutable_clouds()->mutable_cloud2()->CopyFrom(StreamRpcServer::cvPointMat2JetPointCloud(mat));
  994. // LOG(INFO) << "frame.clouds().cloud2().size(): " << frame.clouds().cloud2().size();
  995. break;
  996. case LR:
  997. frame.mutable_clouds()->mutable_cloud3()->CopyFrom(StreamRpcServer::cvPointMat2JetPointCloud(mat));
  998. // LOG(INFO) << "frame.clouds().cloud3().size(): " << frame.clouds().cloud3().size();
  999. break;
  1000. case RR:
  1001. frame.mutable_clouds()->mutable_cloud4()->CopyFrom(StreamRpcServer::cvPointMat2JetPointCloud(mat));
  1002. // LOG(INFO) << "frame.clouds().cloud4().size(): " << frame.clouds().cloud4().size();
  1003. break;
  1004. default:
  1005. break;
  1006. }
  1007. return {};
  1008. }
  1009. Error_manager DeviceTof3D::grpcCloud(JetStream::ResFrame &frame, const DeviceAzimuth &azimuth, pcl::PointCloud<pcl::PointXYZI>::Ptr &cloud) {
  1010. // 传递识别结果
  1011. switch (azimuth) {
  1012. case LF:
  1013. frame.mutable_clouds()->mutable_cloud1()->CopyFrom(StreamRpcServer::pcl2JetPointCloud(cloud));
  1014. break;
  1015. case RF:
  1016. frame.mutable_clouds()->mutable_cloud2()->CopyFrom(StreamRpcServer::pcl2JetPointCloud(cloud));
  1017. break;
  1018. case LR:
  1019. frame.mutable_clouds()->mutable_cloud3()->CopyFrom(StreamRpcServer::pcl2JetPointCloud(cloud));
  1020. break;
  1021. case RR:
  1022. frame.mutable_clouds()->mutable_cloud4()->CopyFrom(StreamRpcServer::pcl2JetPointCloud(cloud));
  1023. break;
  1024. default:
  1025. break;
  1026. }
  1027. return {};
  1028. }