TomoMotionModel.cpp 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913
  1. #include "stdafx.h"
  2. #include "TomoMotionModel.h"
  3. #include "IMachineryManager.h"
  4. #include "MotionStages.h"
  5. #include "TomoMotionStageArgs.h"
  6. #include "ITubeAngleController.h"
  7. #include "ITubeHeightController.h"
  8. #include "ISensorADController.h"
  9. #include "ISensorEncoderController.h"
  10. #include "IExposureController.h"
  11. #include "FeedbackDefine.h"
  12. #include "generatorMove.hpp"
  13. #include "IPositionManager.h"
  14. #include "DigitalTwinLogger.h"
  15. #include "ConfigureExposureDelayTime.h"
  16. #include "TubeLineMotionSwitchController.h"
  17. #include "ConfigurerMotion.h"
  18. #include "ConfigurerWS.h"
  19. #include "ConfigurerTomoMotionLimitation.h"
  20. using namespace DIOS::Dev::Detail::MachineryECOM;
  21. TomoMotionModel::TomoMotionModel()
  22. :m_StageName(""),
  23. m_stageArgs(new TomoMotionStageArgs()),
  24. m_coordinates(nullptr),
  25. m_machineryManager(nullptr),
  26. m_motorTubeAngle(nullptr),
  27. m_motorTubeHeight(nullptr),
  28. m_adDetectorHeight(nullptr),
  29. m_encoderTubeAngle(nullptr),
  30. m_encoderTubeHeight(nullptr),
  31. m_motorTubeHorizontal(nullptr),
  32. m_adTubeHorizontal(nullptr),
  33. m_encoderTubeHorizontal(nullptr),
  34. m_tubeLineMotionSwitch(nullptr),
  35. m_exposure(nullptr),
  36. m_warmAngle(0.0f),
  37. m_anglePerSlice(0.0f),
  38. m_angleSliceCount(0),
  39. m_heightSliceCount(0),
  40. m_heightStartPosition(0.0f),
  41. m_angleStartPosition(0.0f),
  42. m_fps(4.0f)
  43. {
  44. m_heightSlices = new float[TOMO_HEIGHT_SLICE_MAX]{0};
  45. m_anglePeriods = new int[TOMO_HEIGHT_SLICE_MAX]{0};
  46. m_angleSteps = new int[TOMO_HEIGHT_SLICE_MAX]{0};
  47. }
  48. TomoMotionModel::~TomoMotionModel()
  49. {
  50. if (m_stageArgs)
  51. {
  52. delete m_stageArgs;
  53. m_stageArgs = nullptr;
  54. }
  55. if (m_heightSlices)
  56. {
  57. delete[] m_heightSlices;
  58. m_heightSlices = nullptr;
  59. }
  60. if (m_anglePeriods)
  61. {
  62. delete[] m_anglePeriods;
  63. m_anglePeriods = nullptr;
  64. }
  65. if (m_angleSteps)
  66. {
  67. delete[] m_angleSteps;
  68. m_angleSteps = nullptr;
  69. }
  70. }
  71. void TomoMotionModel::ChangeStage(const std::string &stageName)
  72. {
  73. m_StageName = stageName;
  74. OnMotionStage(m_StageName);
  75. }
  76. std::string TomoMotionModel::GetStageName()
  77. {
  78. return m_StageName;
  79. }
  80. IMotionStageArgs *TomoMotionModel::GetStageArgs()
  81. {
  82. return m_stageArgs;
  83. }
  84. void TomoMotionModel::Initialize(IMachineryManager *machineryManager, IPositionManager *coordinates)
  85. {
  86. m_machineryManager = machineryManager;
  87. m_coordinates = coordinates;
  88. m_motorTubeAngle = (ITubeAngleController *)(m_machineryManager->Resove(CONTROLLER_TUBE_ANGLE));
  89. m_motorTubeHeight = (ITubeHeightController *)(m_machineryManager->Resove(CONTROLLER_TUBE_HEIGHT));
  90. m_adDetectorHeight = (ISensorADController *)(m_machineryManager->Resove(CONTROLLER_DETECTOR_HEIGHT_AD));
  91. m_encoderTubeAngle = (ISensorEncoderController *)(m_machineryManager->Resove(CONTROLLER_TUBE_ANGLE_ENCODER));
  92. m_encoderTubeHeight = (ISensorEncoderController *)(m_machineryManager->Resove(CONTROLLER_TUBE_HEIGHT_ENCODER));
  93. m_exposure = (IExposureController *)(m_machineryManager->Resove(CONTROLLER_EXPOSURE));
  94. m_motorTubeHorizontal = (ITubeHeightController*)(machineryManager->Resove(CONTROLLER_TUBE_HORIZONTAL));
  95. m_encoderTubeHorizontal = (ISensorEncoderController*)(machineryManager->Resove(CONTROLLER_TUBE_HORIZONTAL_ENCODER));
  96. m_tubeLineMotionSwitch = (IOutputController*)(machineryManager->Resove(CONTROLLER_TUBE_LINE_MOTION_SWTICH));
  97. assert(m_motorTubeAngle);
  98. assert(m_motorTubeHeight);
  99. assert(m_adDetectorHeight);
  100. assert(m_encoderTubeAngle);
  101. assert(m_encoderTubeHeight);
  102. assert(m_exposure);
  103. assert(m_motorTubeHorizontal);
  104. assert(m_encoderTubeHorizontal);
  105. assert(m_tubeLineMotionSwitch);
  106. }
  107. void TomoMotionModel::LoadMachineryParams(ResDataObject &params)
  108. {
  109. m_MachineryParams = params;
  110. }
  111. void TomoMotionModel::LoadModelParams(ResDataObject &params)
  112. {
  113. m_ModelParams = params;
  114. }
  115. void TomoMotionModel::SetTechnicalParams(ResDataObject &params)
  116. {
  117. m_TechnicalParams = params;
  118. DigitalTwinLogger::Instance()->ReceiveExamMode("TOMO");
  119. }
  120. void TomoMotionModel::OnFeedbackMotionParams(ResDataObject &params)
  121. {
  122. std::string key((const char *)params["key"]);
  123. if (key == TOMO_MODEL_FEEDBACK_KEY_LINEENCODER)
  124. {
  125. m_FeedbackTubeHeightEncoders.push_back((int)params[key.c_str()]);
  126. DigitalTwinLogger::Instance()->ReceiveTomoExposureHeightPosition((int)params[key.c_str()]);
  127. }
  128. else if (key == TOMO_MODEL_FEEDBACK_KEY_ANGLEENCODER)
  129. {
  130. m_FeedbackTubeAngleEncoders.push_back((int)params[key.c_str()]);
  131. DigitalTwinLogger::Instance()->ReceiveTomoExposureAnglePosition((int)params[key.c_str()]);
  132. }
  133. }
  134. BOOL TomoMotionModel::GetMotionParams(ResDataObject &params)
  135. {
  136. std::string key = (const char *)params["key"];
  137. if (key == "AngleResult")
  138. {
  139. params.clear();
  140. int count = 0;
  141. for (auto item : m_FeedbackTubeAngleEncoders)
  142. {
  143. float angle = m_coordinates->ConvertSensorValue(CONTROLLER_TUBE_ANGLE_ENCODER, item);
  144. char buffer[10];
  145. memset(buffer, 0, 10);
  146. sprintf_s(buffer, "%d", count);
  147. params.add(buffer, angle);
  148. ++count;
  149. }
  150. }
  151. else if (key == "HeightResult")
  152. {
  153. params.clear();
  154. int count = 0;
  155. for (auto item : m_FeedbackTubeHeightEncoders)
  156. {
  157. float height = m_coordinates->ConvertSensorValue(CONTROLLER_TUBE_HEIGHT_ENCODER, item);
  158. char buffer[10];
  159. memset(buffer, 0, 10);
  160. sprintf_s(buffer, "%d", count);
  161. params.add(buffer, height * 100);
  162. ++count;
  163. }
  164. }
  165. return TRUE;
  166. }
  167. void TomoMotionModel::OnMotionStage(const std::string &stageName)
  168. {
  169. if (gmotionLog) gmotionLog->Info("[TomoMotionModel][OnMotionStage]->[Enter][{$}]", stageName.c_str());
  170. if (stageName == TOMO_STAGE_CALCULATE_PARAMS)
  171. {
  172. MotionStageCalculateParams();
  173. }
  174. else if (stageName == TOMO_STAGE_SET_TOMO_SLICE)
  175. {
  176. MotionStageSetTomoMotionSlice();
  177. }
  178. else if (stageName == TOMO_STAGE_MOVETO_END_POS)
  179. {
  180. MotionStageMovetoEndPos();
  181. }
  182. else if (stageName == TOMO_STAGE_CLEAR_PARAMS)
  183. {
  184. MotionStageClearParams();
  185. }
  186. else if (stageName == TOMO_STAGE_MOVETO_START_POS_PRE_CENTER_ADJUST)
  187. {
  188. MotionStageCenterAdjust();
  189. }
  190. else if (stageName == TOMO_STAGE_MOVETO_START_POS)
  191. {
  192. MotionStageMovetoStartPos();
  193. }
  194. else if (stageName == TOMO_STAGE_MOTION_ERROR_STOP)
  195. {
  196. MotionStageErrorStop();
  197. }
  198. else if (stageName == TOMO_STAGE_MOTION_ERROR_RECOVER)
  199. {
  200. MotionStageErrorRecover();
  201. }
  202. else if (stageName == TOMO_STAGE_MOTION_CHANGE_PFS)
  203. {
  204. m_fps = m_stageArgs->FPS;
  205. }
  206. else if (stageName == TOMO_STAGE_ADJUST_SID_MOVE)
  207. {
  208. OnMotionStageMove2SID(m_CurWS);
  209. }
  210. if (gmotionLog) gmotionLog->Info("[TomoMotionModel][OnMotionStage]->[Exit][{$}]", stageName.c_str());
  211. }
  212. void TomoMotionModel::DoMotionStageSetTomoMotionSlice(ISensorEncoderController* pEncoder, string encoderControllerName)
  213. {
  214. int effectivePeriod = 50;
  215. //1.设置球管旋转方向
  216. m_motorTubeAngle->SetRotateOrientation(GetTomoRotateDirection());
  217. //2.设置高度编码器触发同步使能
  218. bool useHeightTriggerSync = (bool)atoi((const char*)m_MachineryParams["UseHeightTriggerSyncBox"]);
  219. bool useHeightTriggerAngleRotation = (bool)atoi((const char*)m_MachineryParams["UseHeightTriggerAngleRotation"]);
  220. if (useHeightTriggerSync)
  221. {
  222. auto exposureTriggerID = m_exposure->GetInterfaceID(ID_COMMUNICATE_INTERFACE);
  223. pEncoder->ActiveExposureTrigger(exposureTriggerID);
  224. }
  225. if (useHeightTriggerAngleRotation)
  226. {
  227. auto rotateTriggerID = m_motorTubeAngle->GetInterfaceID(ID_COMMUNICATE_INTERFACE);
  228. pEncoder->ActiveRotateTrigger(rotateTriggerID);
  229. }
  230. //3.依次设置曝光高度点位关联同步信号
  231. if (useHeightTriggerSync)
  232. {
  233. int count = m_heightSliceCount - 2;
  234. if (m_ModelParams.GetFirstOf("TomoNeedExtraTrigger") >= 0 && (int)atoi(m_ModelParams["TomoNeedExtraTrigger"]) != 0)
  235. {
  236. count = m_heightSliceCount - 1;
  237. }
  238. float speed = strtof((const char*)m_TechnicalParams["TomoMotionSpeed"], nullptr);
  239. float systemdelayTime = ConfigureExposureDelayTime::GetExposureDelayTimeInSeconds((const char*)m_TechnicalParams["PositionNumber"]);
  240. int direct = 1;
  241. if (m_heightSlices[0] < m_heightSlices[1])
  242. {
  243. direct = -1;
  244. }
  245. float detaHeight = speed * systemdelayTime * direct;
  246. for (int i = 2; i < count; ++i)
  247. {
  248. if (gbusinessLog) gbusinessLog->Info("[TomoMotionModel][SetExposureTrigger]->[{$:f3} {$:f3} {$:f3}]", m_heightSlices[i] + detaHeight, m_heightSlices[i], detaHeight);
  249. DWORD encoder = m_coordinates->ConvertPhysicsValue(encoderControllerName, m_heightSlices[i] + detaHeight);
  250. pEncoder->SetExposureTrigger(encoder);
  251. }
  252. }
  253. //4.设置起始曝光点位为触发旋转的点
  254. if (useHeightTriggerAngleRotation)
  255. {
  256. DWORD encoder = m_coordinates->ConvertPhysicsValue(encoderControllerName, m_heightSlices[2]);
  257. pEncoder->SetRotateTrigger(encoder);
  258. }
  259. //5.依次设置曝光高度点位关联的旋转周期和步长
  260. for (int i = 0; i < m_angleSliceCount; ++i)
  261. {
  262. int period = m_anglePeriods[i];
  263. int step = m_angleSteps[i];
  264. if (period <= effectivePeriod || period > 0xFFFF)
  265. {
  266. TPRINTA_ERROR("Error At Tomo Calculation.idx:%d,Period:%u,Effective:%u", period, effectivePeriod);
  267. continue;
  268. }
  269. m_motorTubeAngle->AppendPWM(step, period);
  270. }
  271. //6.设置曝光触发角度编码器值回传
  272. auto sensortubeHeightID = pEncoder->GetInterfaceID(ID_COMMUNICATE_INTERFACE);
  273. m_exposure->ActiveExposureTubeHeightPositionAutoNotify(sensortubeHeightID);
  274. auto sensortubeAngleID = m_encoderTubeAngle->GetInterfaceID(ID_COMMUNICATE_INTERFACE);
  275. m_exposure->ActiveExposureTubeAnglePositionAutoNotify(sensortubeAngleID);
  276. }
  277. void TomoMotionModel::MotionStageSetTomoMotionSlice()
  278. {
  279. if (m_CurWS == WS_WALL)
  280. {
  281. DoMotionStageSetTomoMotionSlice(m_encoderTubeHeight, CONTROLLER_TUBE_HEIGHT_ENCODER);
  282. }
  283. else if (m_CurWS == WS_TABLE)
  284. {
  285. DoMotionStageSetTomoMotionSlice(m_encoderTubeHorizontal, CONTROLLER_TUBE_HORIZONTAL_ENCODER);
  286. }
  287. //int effectivePeriod = 50;
  288. ////1.设置球管旋转方向
  289. //m_motorTubeAngle->SetRotateOrientation(GetTomoRotateDirection());
  290. ////2.设置高度编码器触发同步使能
  291. //bool useHeightTriggerSync = (bool)atoi((const char *)m_MachineryParams["UseHeightTriggerSyncBox"]);
  292. //bool useHeightTriggerAngleRotation = (bool)atoi((const char *)m_MachineryParams["UseHeightTriggerAngleRotation"]);
  293. //if (useHeightTriggerSync)
  294. //{
  295. // auto exposureTriggerID = m_exposure->GetInterfaceID(ID_COMMUNICATE_INTERFACE);
  296. // m_encoderTubeHeight->ActiveExposureTrigger(exposureTriggerID);
  297. //}
  298. //if (useHeightTriggerAngleRotation)
  299. //{
  300. // auto rotateTriggerID = m_motorTubeAngle->GetInterfaceID(ID_COMMUNICATE_INTERFACE);
  301. // m_encoderTubeHeight->ActiveRotateTrigger(rotateTriggerID);
  302. //}
  303. ////3.依次设置曝光高度点位关联同步信号
  304. //if (useHeightTriggerSync)
  305. //{
  306. // int count = m_heightSliceCount - 2;
  307. // if (m_ModelParams.GetFirstOf("TomoNeedExtraTrigger") >= 0 && (int)atoi(m_ModelParams["TomoNeedExtraTrigger"]) != 0)
  308. // {
  309. // count = m_heightSliceCount - 1;
  310. // }
  311. // float speed = strtof((const char *)m_TechnicalParams["TomoMotionSpeed"], nullptr);
  312. // float systemdelayTime = ConfigureExposureDelayTime::GetExposureDelayTimeInSeconds((const char *)m_TechnicalParams["PositionNumber"]);
  313. // int direct = 1;
  314. // if (m_heightSlices[0] < m_heightSlices[1])
  315. // {
  316. // direct = -1;
  317. // }
  318. // float detaHeight = speed * systemdelayTime * direct;
  319. // for (int i = 2; i < count; ++i)
  320. // {
  321. // if(gbusinessLog) gbusinessLog->Info("[TomoMotionModel][SetExposureTrigger]->[{$:f3} {$:f3} {$:f3}]", m_heightSlices[i] + detaHeight, m_heightSlices[i], detaHeight);
  322. //
  323. // DWORD encoder = m_coordinates->ConvertPhysicsValue(CONTROLLER_TUBE_HEIGHT_ENCODER, m_heightSlices[i] + detaHeight);
  324. // m_encoderTubeHeight->SetExposureTrigger(encoder);
  325. // }
  326. //}
  327. ////4.设置起始曝光点位为触发旋转的点
  328. //if (useHeightTriggerAngleRotation)
  329. //{
  330. // DWORD encoder = m_coordinates->ConvertPhysicsValue(CONTROLLER_TUBE_HEIGHT_ENCODER, m_heightSlices[2]);
  331. // m_encoderTubeHeight->SetRotateTrigger(encoder);
  332. //}
  333. ////5.依次设置曝光高度点位关联的旋转周期和步长
  334. //for (int i = 0; i < m_angleSliceCount; ++i)
  335. //{
  336. // int period = m_anglePeriods[i];
  337. // int step = m_angleSteps[i];
  338. // if (period <= effectivePeriod || period > 0xFFFF)
  339. // {
  340. // TPRINTA_ERROR("Error At Tomo Calculation.idx:%d,Period:%u,Effective:%u", period, effectivePeriod);
  341. // continue;
  342. // }
  343. // m_motorTubeAngle->AppendPWM(step,period);
  344. //}
  345. ////6.设置曝光触发角度编码器值回传
  346. //auto sensortubeHeightID = m_encoderTubeHeight->GetInterfaceID(ID_COMMUNICATE_INTERFACE);
  347. //m_exposure->ActiveExposureTubeHeightPositionAutoNotify(sensortubeHeightID);
  348. //auto sensortubeAngleID = m_encoderTubeAngle->GetInterfaceID(ID_COMMUNICATE_INTERFACE);
  349. //m_exposure->ActiveExposureTubeAnglePositionAutoNotify(sensortubeAngleID);
  350. }
  351. BOOL TomoMotionModel::GetTomoRotateDirection()
  352. {
  353. auto direction = (int)atoi(m_ModelParams["TomoRotateDirection"]);
  354. return direction != 0;
  355. }
  356. void TomoMotionModel::MotionStageClearParams()
  357. {
  358. m_FeedbackTubeHeightEncoders.clear();
  359. m_FeedbackTubeAngleEncoders.clear();
  360. m_motorTubeAngle->ClearSignal();
  361. m_encoderTubeHeight->ClearTrigger();
  362. if (m_encoderTubeHorizontal)
  363. {
  364. m_encoderTubeHorizontal->ClearTrigger();
  365. }
  366. }
  367. void TomoMotionModel::MotionStageCalculateParams()
  368. {
  369. float detectorHeight = m_coordinates->GetCurrentPhysical(TOMO_DETECTOR_HEIGHT);
  370. float sid = strtof((const char*)m_ModelParams["TomoSID"], nullptr);
  371. if (m_CurWS == WS_WALL)
  372. {
  373. if (m_ModelParams.GetFirstOf("TomoSID_Wall") >= 0)
  374. {
  375. sid = strtof((const char*)m_ModelParams["TomoSID_Wall"], nullptr);
  376. }
  377. }
  378. else if (m_CurWS == WS_TABLE)
  379. {
  380. if (m_ModelParams.GetFirstOf("TomoSID_Table") >= 0)
  381. {
  382. sid = strtof((const char*)m_ModelParams["TomoSID_Table"], nullptr);
  383. }
  384. }
  385. float acc = strtof((const char*)m_ModelParams["TomoAcceleratingDistance"], nullptr);
  386. float lat = strtof((const char*)m_ModelParams["TomoAlignmentDistance"], nullptr);
  387. float sus = strtof((const char*)m_ModelParams["TomoResetDistance"], nullptr);
  388. float brk = strtof((const char*)m_ModelParams["TomoDeceleratingDistance"], nullptr);
  389. float anglePerMot = m_coordinates->GetPhysicalPerMotorPulse(TOMO_TUBE_ANGLE);
  390. float speed = strtof((const char *)m_TechnicalParams["TomoMotionSpeed"],nullptr);
  391. int nproject = (int)m_TechnicalParams["TomoProjectionNumber"];
  392. float scnAngle = strtof((const char *)m_TechnicalParams["TomoScanAngle"],nullptr);
  393. memset(m_heightSlices, 0, TOMO_HEIGHT_SLICE_MAX);
  394. memset(m_anglePeriods, 0, TOMO_HEIGHT_SLICE_MAX);
  395. memset(m_angleSteps, 0, TOMO_HEIGHT_SLICE_MAX);
  396. string strScanAngle = (const char*)m_TechnicalParams["TomoScanAngle"];
  397. int nstatus = IsTomoMotionDetectorPosCorrect(detectorHeight, strScanAngle);
  398. if (nstatus != 0)
  399. {
  400. if (gbusinessLog) gbusinessLog->Warn("[TomoMotionModel][MotionStageCalculateParams]->[Current detector position is out of tomo scan range] ]");
  401. m_coordinates->NotifySystemIsTomoMotionLimitation(nstatus);
  402. return;
  403. }
  404. else
  405. {
  406. if (gbusinessLog) gbusinessLog->Info("[TomoMotionModel][MotionStageCalculateParams]->[Current detector position is in tomo scan range] ]");
  407. m_coordinates->NotifySystemIsTomoMotionLimitation(nstatus);
  408. }
  409. if(gbusinessLog) gbusinessLog->Info("[TomoMotionModel][MotionStageCalculateParams]->[{$:f3} {$:f3} {$:f3} {$:f3} {$:f3} {$:f3} {$:f3} {$:d} {$:f3} ]",
  410. sid, acc, lat, sus, brk, anglePerMot, speed, nproject, scnAngle);
  411. auto err = tomoMotionGeometry(true, detectorHeight, acc, brk, lat, sus, sid, speed,
  412. nproject, scnAngle, anglePerMot, 1.0, m_warmAngle, m_anglePerSlice,
  413. m_heightSlices, m_angleSteps, m_anglePeriods, m_angleSliceCount, m_heightSliceCount);
  414. if (err < 0)
  415. {
  416. if (gmotionLog) gmotionLog->Error("[TomoMotionModel][tomoMotionGeometry]->[Error occurs.]");
  417. }
  418. m_heightStartPosition = m_heightSlices[0];
  419. m_angleStartPosition = -(scnAngle / 2.0f);
  420. FixHeightStartPosition(speed);
  421. //auto period = (DWORD)atoi((const char *)m_MachineryParams["TubeAnglePeriodP0"]);
  422. auto period = ConfigurerMotion::GetTubeRotateNormalPeriod();
  423. DigitalTwinLogger::Instance()->ReceiveTomoScanParam(nproject, scnAngle);
  424. DigitalTwinLogger::Instance()->ReceiveSID(sid);
  425. DigitalTwinLogger::Instance()->ReceiveTomoHeightSpeed(speed);
  426. DigitalTwinLogger::Instance()->ReceiveTomoNormalRotatePeriod(period);
  427. DigitalTwinLogger::Instance()->ReceiveTomoProjectParams(acc, lat, sus, brk);
  428. DigitalTwinLogger::Instance()->ReceiveTomoProjectSliceParams(m_heightSlices, m_heightSliceCount);
  429. DigitalTwinLogger::Instance()->ReceiveTomoSliceRotateSpeeds(m_anglePeriods, m_angleSliceCount);
  430. DigitalTwinLogger::Instance()->ReceiveTomoSliceRotateSteps(m_angleSteps, m_angleSliceCount);
  431. }
  432. void TomoMotionModel::DoMotionStageMovetoEndPosHeight()
  433. {
  434. DigitalTwinLogger::Instance()->ReceiveTimePoint();
  435. auto tubeAngleSensorValue = m_coordinates->GetCurrentSensorValue(TOMO_TUBE_ANGLE);
  436. auto tubeHeightSensorValue = m_coordinates->GetCurrentSensorValue(TOMO_TUBE_HEIGHT);
  437. auto detectorHeight = m_coordinates->GetCurrentPhysical(TOMO_DETECTOR_HEIGHT);
  438. DigitalTwinLogger::Instance()->ReceiveTomoStartPosition(tubeAngleSensorValue, tubeHeightSensorValue);
  439. DigitalTwinLogger::Instance()->ReceiveDetectorHeight(detectorHeight);
  440. float endPosition = m_heightSlices[m_heightSliceCount - 1];
  441. float currentPosition = m_coordinates->GetCurrentPhysical(TOMO_TUBE_HEIGHT);
  442. int direction = JudgeDirectionInTubeHeightAxis(currentPosition, endPosition);
  443. MoveTubeHeight(direction, abs(currentPosition - endPosition));
  444. }
  445. void TomoMotionModel::DoMotionStageMovetoEndPosHorizontal()
  446. {
  447. DigitalTwinLogger::Instance()->ReceiveTimePoint();
  448. auto tubeAngleSensorValue = m_coordinates->GetCurrentSensorValue(TOMO_TUBE_ANGLE);
  449. auto tubeHorizontalSensorValue = m_coordinates->GetCurrentSensorValue(TOMO_TUBE_HORIZONTAL);
  450. auto detectorHorizontal = m_coordinates->GetCurrentPhysical(TOMO_DETECTOR_HORIZONTAL);
  451. DigitalTwinLogger::Instance()->ReceiveTomoStartPosition(tubeAngleSensorValue, tubeHorizontalSensorValue);
  452. DigitalTwinLogger::Instance()->ReceiveDetectorHeight(detectorHorizontal);
  453. float endPosition = m_heightSlices[m_heightSliceCount - 1];
  454. //float currentPosition = m_coordinates->GetCurrentPhysical(TOMO_TUBE_HORIZONTAL);
  455. float currentPosition = m_coordinates->GetCurrentAbsolutePhysical(TOMO_TUBE_HORIZONTAL);
  456. int direction = JudgeDirectionInTubeHorizontalAxis(currentPosition, endPosition);
  457. MoveTubeHorizontal(direction, abs(currentPosition - endPosition));
  458. }
  459. void TomoMotionModel::MotionStageMovetoEndPos()
  460. {
  461. if (m_CurWS == WS_WALL)
  462. {
  463. DoMotionStageMovetoEndPosHeight();
  464. }
  465. else if (m_CurWS == WS_TABLE)
  466. {
  467. DoMotionStageMovetoEndPosHorizontal();
  468. }
  469. //DigitalTwinLogger::Instance()->ReceiveTimePoint();
  470. //auto tubeAngleSensorValue = m_coordinates->GetCurrentSensorValue(TOMO_TUBE_ANGLE);
  471. //auto tubeHeightSensorValue = m_coordinates->GetCurrentSensorValue(TOMO_TUBE_HEIGHT);
  472. //auto detectorHeight = m_coordinates->GetCurrentPhysical(TOMO_DETECTOR_HEIGHT);
  473. //DigitalTwinLogger::Instance()->ReceiveTomoStartPosition(tubeAngleSensorValue, tubeHeightSensorValue);
  474. //DigitalTwinLogger::Instance()->ReceiveDetectorHeight(detectorHeight);
  475. //float endPosition = m_heightSlices[m_heightSliceCount - 1];
  476. //float currentPosition = m_coordinates->GetCurrentPhysical(TOMO_TUBE_HEIGHT);
  477. //int direction = JudgeDirectionInTubeHeightAxis(currentPosition, endPosition);
  478. //MoveTubeHeight(direction, abs(currentPosition - endPosition));
  479. }
  480. void TomoMotionModel::DoMotionStageMovetoStartPosHeight()
  481. {
  482. DigitalTwinLogger::Instance()->ReceiveTimePoint();
  483. auto tubeAngleSensorValue = m_coordinates->GetCurrentSensorValue(TOMO_TUBE_ANGLE);
  484. auto tubeHeightSensorValue = m_coordinates->GetCurrentSensorValue(TOMO_TUBE_HEIGHT);
  485. DigitalTwinLogger::Instance()->ReceiveMotionInitialPosition(tubeAngleSensorValue, tubeHeightSensorValue);
  486. MoveTubeHeightToTomoStartPosiotn();
  487. RotateTubeAngleToTomoStartPostion();
  488. }
  489. void TomoMotionModel::DoMotionStageMovetoStartPosHorizontal()
  490. {
  491. DigitalTwinLogger::Instance()->ReceiveTimePoint();
  492. auto tubeAngleSensorValue = m_coordinates->GetCurrentSensorValue(TOMO_TUBE_ANGLE);
  493. auto tubeHorizontalSensorValue = m_coordinates->GetCurrentSensorValue(TOMO_TUBE_HORIZONTAL);
  494. DigitalTwinLogger::Instance()->ReceiveMotionInitialPosition(tubeAngleSensorValue, tubeHorizontalSensorValue);
  495. MoveTubeHorizontalToTomoStartPosiotn();
  496. RotateTubeAngleToTomoStartPostion();
  497. }
  498. void TomoMotionModel::MotionStageMovetoStartPos()
  499. {
  500. if (m_CurWS == WS_WALL)
  501. {
  502. DoMotionStageMovetoStartPosHeight();
  503. }
  504. else if (m_CurWS == WS_TABLE)
  505. {
  506. DoMotionStageMovetoStartPosHorizontal();
  507. }
  508. /*DigitalTwinLogger::Instance()->ReceiveTimePoint();
  509. auto tubeAngleSensorValue = m_coordinates->GetCurrentSensorValue(TOMO_TUBE_ANGLE);
  510. auto tubeHeightSensorValue = m_coordinates->GetCurrentSensorValue(TOMO_TUBE_HEIGHT);
  511. DigitalTwinLogger::Instance()->ReceiveMotionInitialPosition(tubeAngleSensorValue, tubeHeightSensorValue);
  512. MoveTubeHeightToTomoStartPosiotn();
  513. RotateTubeAngleToTomoStartPostion();*/
  514. }
  515. void TomoMotionModel::MoveTubeHeightToTomoStartPosiotn()
  516. {
  517. float tubeHeight = m_coordinates->GetCurrentPhysical(TOMO_TUBE_HEIGHT);
  518. int direction = JudgeDirectionInTubeHeightAxis(tubeHeight, m_heightStartPosition);
  519. float speed = 0.0f;
  520. if (m_MachineryParams.GetFirstOf("MotionSpeed") > 0)
  521. {
  522. speed = (float)atof((const char *)m_MachineryParams["MotionSpeed"]);
  523. }
  524. MoveTubeHeight(direction, abs(m_heightStartPosition - tubeHeight), speed);
  525. }
  526. void TomoMotionModel::MoveTubeHorizontalToTomoStartPosiotn()
  527. {
  528. float tubeHorizontal = m_coordinates->GetCurrentPhysical(TOMO_TUBE_HORIZONTAL);
  529. int direction = JudgeDirectionInTubeHorizontalAxis(tubeHorizontal, m_heightStartPosition);
  530. float speed = 0.0f;
  531. if (m_MachineryParams.GetFirstOf("MotionSpeed") > 0)
  532. {
  533. speed = (float)atof((const char*)m_MachineryParams["MotionSpeed"]);
  534. }
  535. MoveTubeHorizontal(direction, abs(m_heightStartPosition - tubeHorizontal), speed);
  536. }
  537. void TomoMotionModel::RotateTubeAngleToTomoStartPostion()
  538. {
  539. float tubeAngle = m_coordinates->GetCurrentPhysical(TOMO_TUBE_ANGLE);
  540. int direction = JudgeDirectionInTubeAngleAxis(tubeAngle, m_angleStartPosition);
  541. if(gbusinessLog) gbusinessLog->Info("[TomoMotionModel][RotateTubeAngleToTomoStartPostion]->[{$:f6} {$:f6}]", m_angleStartPosition, tubeAngle);
  542. RotateTubeAngle(direction, abs(m_angleStartPosition - tubeAngle));
  543. }
  544. void TomoMotionModel::MotionStageErrorStop()
  545. {
  546. StopMotion();
  547. }
  548. void TomoMotionModel::MotionStageErrorRecover()
  549. {
  550. StopMotion();
  551. }
  552. void TomoMotionModel::StopMotion()
  553. {
  554. m_motorTubeAngle->StopRotation();
  555. m_motorTubeHeight->StopMove();
  556. m_motorTubeHorizontal->StopMove();
  557. auto tubeAngleSensorValue = m_coordinates->GetCurrentSensorValue(TOMO_TUBE_ANGLE);
  558. auto tubeHeightSensorValue = m_coordinates->GetCurrentSensorValue(TOMO_TUBE_HEIGHT);
  559. DigitalTwinLogger::Instance()->ReceiveMotionStopPosition(tubeAngleSensorValue, tubeHeightSensorValue);
  560. DigitalTwinLogger::Instance()->SaveMotionRecord();
  561. }
  562. void TomoMotionModel::MotionStageCenterAdjust()
  563. {
  564. AlignTubeHeightToDetector();
  565. RotateTubeToHorizontal();
  566. }
  567. void TomoMotionModel::AlignTubeHeightToDetector()
  568. {
  569. float detectorHeight = m_coordinates->GetCurrentPhysical(TOMO_DETECTOR_HEIGHT);
  570. float tubeHeight = m_coordinates->GetCurrentPhysical(TOMO_TUBE_HEIGHT);
  571. int direction = JudgeDirectionInTubeHeightAxis(tubeHeight, detectorHeight);
  572. MoveTubeHeight(direction, abs(detectorHeight - tubeHeight));
  573. }
  574. void TomoMotionModel::RotateTubeToHorizontal()
  575. {
  576. float tubeAngle = m_coordinates->GetCurrentPhysical(TOMO_TUBE_ANGLE);
  577. int direction = JudgeDirectionInTubeAngleAxis(tubeAngle,0.0f);
  578. RotateTubeAngle(direction, tubeAngle);
  579. }
  580. int TomoMotionModel::JudgeDirectionInTubeHeightAxis(float current, float target)
  581. {
  582. //auto positive = (int)atoi((const char *)m_MachineryParams["TubeHeightAxisPositiveDirection"]);
  583. auto positive = ConfigurerMotion::GetTubeHeightAxisPositiveDirection();
  584. auto direction = positive > 0 ? 1 : -1;
  585. if (current > target)
  586. {
  587. return 1 * direction;
  588. }
  589. if (current < target)
  590. {
  591. return -1 * direction;
  592. }
  593. return 0;
  594. }
  595. int TomoMotionModel::JudgeDirectionInTubeAngleAxis(float current, float target)
  596. {
  597. //auto positive = (int)atoi((const char *)m_MachineryParams["TubeRotateAxisPositiveDirection"]);
  598. auto positive = ConfigurerMotion::GetTubeRotateAxisPositiveDirection();
  599. auto direction = positive > 0 ? 1 : -1;
  600. if (current > target)
  601. {
  602. return -1 * direction;
  603. }
  604. if (current < target)
  605. {
  606. return 1 * direction;
  607. }
  608. return 0;
  609. }
  610. void TomoMotionModel::MoveTubeHeight(int direction, float offset, float spd)
  611. {
  612. auto tolerance = ConfigurerMotion::GetMotionToleranceLine();
  613. if (offset < tolerance)
  614. {
  615. if (gmotionLog) gmotionLog->Info("[TomoMotionModel][MoveTubeHeight]->[ Offset is {$:f6}, less than {$:f6}m, no motion]", offset, tolerance);
  616. return;
  617. }
  618. float speed = strtof((const char *)m_TechnicalParams["TomoMotionSpeed"], nullptr);
  619. auto step = m_coordinates->ConvertMotorStepValue(CONTROLLER_TUBE_HEIGHT, offset);
  620. auto period = m_coordinates->ConvertMotorSpeed(CONTROLLER_TUBE_HEIGHT, speed);
  621. if (period < 50 || (period - 50) < 30)
  622. {
  623. period = 50;
  624. }
  625. if (m_tubeLineMotionSwitch)
  626. {
  627. m_tubeLineMotionSwitch->OutputSignal(false);
  628. }
  629. m_motorTubeHeight->Move(direction, step, period);
  630. }
  631. void TomoMotionModel::RotateTubeAngle(int direction, float offset)
  632. {
  633. //auto period = (DWORD)atoi((const char *)m_MachineryParams["TubeAnglePeriodP0"]);
  634. auto period = ConfigurerMotion::GetTubeRotateNormalPeriod();
  635. auto step = m_coordinates->ConvertMotorStepValue(CONTROLLER_TUBE_ANGLE, offset);
  636. m_motorTubeAngle->Rotate(direction, step, period);
  637. }
  638. void TomoMotionModel::UpdateDigitalTwinTomoSliceParams()
  639. {
  640. DigitalTwinLogger::Instance()->ReceiveTomoProjectSliceParams(m_heightSlices, m_heightSliceCount);
  641. }
  642. void TomoMotionModel::FixHeightStartPosition(float speed)
  643. {
  644. //由于曝光系统存在延迟,因此在设置曝光触发点位时需要考虑系统时延
  645. if(gbusinessLog) gbusinessLog->Info("[TomoMotionModel][FixStartPos]->[S][{$:f6} {$:f6} {$:f6}]", m_heightSlices[0], m_heightSlices[1], m_heightSlices[2]);
  646. float systemdelayTime = ConfigureExposureDelayTime::GetExposureDelayTimeInSeconds((const char *)m_TechnicalParams["PositionNumber"]);
  647. int direct = 1;
  648. if (m_heightSlices[0] < m_heightSlices[1])
  649. {
  650. direct = -1;
  651. }
  652. float detaHeight = speed * systemdelayTime * direct;
  653. if (((m_heightSlices[2] + detaHeight) - (m_heightSlices[1])) * direct > 0)
  654. {
  655. m_heightSlices[0] = m_heightSlices[0] + detaHeight;
  656. m_heightSlices[1] = m_heightSlices[1] + detaHeight;
  657. m_heightStartPosition = m_heightSlices[0];
  658. }
  659. if(gbusinessLog) gbusinessLog->Info("[TomoMotionModel][FixStartPos]->[E][{$:f6} {$:f6} {$:f6} [{$:f6}]]", m_heightSlices[0], m_heightSlices[1], m_heightSlices[2], detaHeight);
  660. }
  661. void TomoMotionModel::SwitchScanningComponents(int nSwitch)
  662. {
  663. }
  664. void TomoMotionModel::SwitchWorkstation(string ws)
  665. {
  666. if (gmotionLog) gmotionLog->Info("[TomoMotionModel][SwitchWorkstation]->[{$}]", ws.c_str());
  667. m_CurWS = ws;
  668. }
  669. void TomoMotionModel::OnMotionStageMove2SID(string ws)
  670. {
  671. if (ws == WS_WALL)
  672. {
  673. //float desPos = atof((const char*)m_MachineryParams["SID_Wall"]);
  674. float desPos = ConfigurerWS::GetDefaultSIDWall();
  675. //float tubeHorizontalPos = m_coordinates->GetCurrentPhysical(TOMO_TUBE_HORIZONTAL);
  676. float tubeHorizontalPos = m_coordinates->GetCurrentAbsolutePhysical(TOMO_TUBE_HORIZONTAL);
  677. int direction = JudgeDirectionInTubeHorizontalAxis(tubeHorizontalPos, desPos);
  678. if (gmotionLog) gmotionLog->Info("[TomoMotionModel][OnMotionStageMove2SID]->[{$}][Dafault SID:{$:f6}, Cur Pos:{$:f6}]", ws.c_str(), desPos, tubeHorizontalPos);
  679. MoveTubeHorizontal(direction, abs(tubeHorizontalPos - desPos));
  680. }
  681. else if (ws == WS_TABLE)
  682. {
  683. //float desPos = atof((const char*)m_MachineryParams["SID_Table"]);
  684. float desPos = ConfigurerWS::GetDefaultSIDTable();
  685. float tubeHeightPos = m_coordinates->GetCurrentPhysical(TOMO_TUBE_HEIGHT);
  686. int direction = JudgeDirectionInTubeHeightAxis(tubeHeightPos, desPos);
  687. if (gmotionLog) gmotionLog->Info("[TomoMotionModel][OnMotionStageMove2SID]->[{$}][Dafault SID:{$:f6}, Cur Pos:{$:f6}]", ws.c_str(), desPos, tubeHeightPos);
  688. MoveTubeHeight(direction, abs(tubeHeightPos - desPos));
  689. }
  690. }
  691. int TomoMotionModel::JudgeDirectionInTubeHorizontalAxis(float current, float target)
  692. {
  693. //auto positive = (int)atoi((const char*)m_MachineryParams["TubeHorizontalAxisPositiveDirection"]);
  694. auto positive = ConfigurerMotion::GetTubeHorizontalAxisPositiveDirection();
  695. auto direction = positive > 0 ? 1 : -1;
  696. if (current > target)
  697. {
  698. return 1 * direction;
  699. }
  700. if (current < target)
  701. {
  702. return -1 * direction;
  703. }
  704. return 0;
  705. }
  706. void TomoMotionModel::MoveTubeHorizontal(int direction, float offset, float spd)
  707. {
  708. auto tolerance = ConfigurerMotion::GetMotionToleranceLine();
  709. if (offset < tolerance)
  710. {
  711. if (gmotionLog) gmotionLog->Info("[TomoMotionModel][MoveTubeHorizontal]->[ Offset is {$:f6}, less than {$:f6}m, no motion]", offset, tolerance);
  712. return;
  713. }
  714. float speed = strtof((const char*)m_TechnicalParams["TomoMotionSpeed"], nullptr);
  715. auto step = m_coordinates->ConvertMotorStepValue(CONTROLLER_TUBE_HORIZONTAL, offset);
  716. auto period = m_coordinates->ConvertMotorSpeed(CONTROLLER_TUBE_HORIZONTAL, speed);
  717. if (period < 50 || (period - 50) < 30)
  718. {
  719. period = 50;
  720. }
  721. if (m_tubeLineMotionSwitch)
  722. {
  723. m_tubeLineMotionSwitch->OutputSignal(true);
  724. }
  725. m_motorTubeHorizontal->Move(direction, step, period);
  726. }
  727. int TomoMotionModel::IsTomoMotionDetectorPosCorrect(float fDetectorCurPos, string scanangle)
  728. {
  729. float fDetectorMinPos = 0.0;
  730. float fDetectorMaxPos = 0.0;
  731. if (gmotionLog) gmotionLog->Info("[TomoMotionModel][IsTomoMotionDetectorPosCorrect]->[ WS is {$}, scan angle is {$}, current detector position is {$:f6}]", m_CurWS, scanangle, fDetectorCurPos);
  732. if (m_CurWS == WS_WALL)
  733. {
  734. fDetectorMinPos = ConfigurerTomoMotionLimitation::GetDetectorMinPositionWall(scanangle);
  735. fDetectorMaxPos = ConfigurerTomoMotionLimitation::GetDetectorMaxPositionWall(scanangle);
  736. }
  737. else if (m_CurWS == WS_TABLE)
  738. {
  739. fDetectorMinPos = ConfigurerTomoMotionLimitation::GetDetectorMinPositionTable(scanangle);
  740. fDetectorMaxPos = ConfigurerTomoMotionLimitation::GetDetectorMaxPositionTable(scanangle);
  741. }
  742. int nRes = DET_HIGHT_NORMAL;
  743. if (fDetectorMaxPos > 0.1 && fDetectorMinPos > 0.1 && fDetectorMaxPos > fDetectorMinPos)
  744. {
  745. if (fDetectorCurPos > fDetectorMaxPos)
  746. {
  747. if (gmotionLog) gmotionLog->Warn("[TomoMotionModel][IsTomoMotionDetectorPosCorrect]->[Detector current pos is out of range, max={$:f6}m, current={$:f6}m, no motion]", fDetectorMaxPos, fDetectorCurPos);
  748. nRes = DET_HIGHT_TOOHIGH;
  749. }
  750. else if (fDetectorCurPos < fDetectorMinPos)
  751. {
  752. if (gmotionLog) gmotionLog->Warn("[TomoMotionModel][IsTomoMotionDetectorPosCorrect]->[Detector current pos is out of range, min={$:f6}m, current={$:f6}m, no motion]", fDetectorMinPos, fDetectorCurPos);
  753. nRes = DET_HIGHT_TOOLOW;
  754. }
  755. }
  756. else
  757. {
  758. if (gmotionLog) gmotionLog->Warn("[TomoMotionModel][IsTomoMotionDetectorPosCorrect]->[Detector limitation pos is not correct max={$:f6}m, min={$:f6}m, no motion]", fDetectorMaxPos, fDetectorMinPos);
  759. nRes = DET_HIGHT_TOOHIGH;
  760. }
  761. return nRes;
  762. }