#include "stdafx.h" #include "MechnicalMonitor.h" #include "IMotionEventReceiver.h" #include "IPositionManager.h" #include "LogicDriverThreadLocker.h" using namespace DIOS::Dev::Detail::MachineryECOM; MechnicalMonitor *MechnicalMonitor::m_instance = nullptr; MechnicalMonitor::MechnicalMonitor() :m_positionManager(nullptr), m_eventReceiver(nullptr), m_monitorThread(nullptr), m_monitorworkThread(nullptr), m_notifyEventHandleCount(0), m_waitEventHandleCount(0), m_isMonitorStoped(TRUE), m_angleStopedNotifyTime(0), m_heightStopedNotifyTime(0), m_horizontalStopedNotifyTime(0), m_dofTubeAngleAxis(TOMO_TUBE_ANGLE), m_dofTubeHeightAxis(TOMO_TUBE_HEIGHT), m_dofTubeHorizontalAxis(TOMO_TUBE_HORIZONTAL) { for (int i = 0; i < MONITOR_NOTIFY_EVENT_MAX; ++i) { m_waitEventHandles[i] = nullptr; } for (int i = 0; i < MONITOR_NOTIFY_EVENT_MAX; ++i) { m_notifyEventHandles[i] = nullptr; } } MechnicalMonitor::~MechnicalMonitor() { if (m_monitorThread) { m_monitorThread->StopThread(); } if (m_monitorworkThread) { m_monitorworkThread->StopThread(); } } MechnicalMonitor *MechnicalMonitor::Instance() { if (m_instance == nullptr) { m_instance = new MechnicalMonitor(); } return m_instance; } void MechnicalMonitor::Initialize(IPositionManager *coordinates, int dofTubeAngleAxis, int dofTubeHeightAxis) { m_positionManager = coordinates; m_dofTubeAngleAxis = dofTubeAngleAxis; m_dofTubeHeightAxis = dofTubeHeightAxis; HANDLE monitorThreadBeginEvent = CreateEvent(NULL, FALSE, FALSE, NULL); HANDLE monitorThreadEndEvent = CreateEvent(NULL, FALSE, FALSE, NULL); AddThreadWaitEventHandle(MONITOR_EVENT_WAIT_BEGIN_MONITOR,monitorThreadBeginEvent); AddThreadWaitEventHandle(MONITOR_EVENT_WAIT_END_MONITOR,monitorThreadEndEvent); HANDLE tubeAngleMotionStoped = CreateEvent(NULL, FALSE, FALSE, NULL); HANDLE tubeHeightMotionStoped = CreateEvent(NULL, FALSE, FALSE, NULL); HANDLE tubeHorizontalMotionStoped = CreateEvent(NULL, FALSE, FALSE, NULL); AddThreadNotifyEventHandle(MONITOR_EVENT_TUBEANGLE_MOVE_STOP, tubeAngleMotionStoped); AddThreadNotifyEventHandle(MONITOR_EVENT_TUBEHEIGHT_MOVE_STOP, tubeHeightMotionStoped); AddThreadNotifyEventHandle(MONITOR_EVENT_TUBEHORIZONTAL_MOVE_STOP, tubeHorizontalMotionStoped); m_monitorThread = new MotionMonitorThread(); m_monitorThread->Initialize(this); m_monitorThread->StartThread(); m_monitorworkThread = new MotionMonitorWorkThread(); m_monitorworkThread->Initialize(this); m_monitorworkThread->StartThread(); } void MechnicalMonitor::AddThreadNotifyEventHandle(const std::string &name, HANDLE eventHandle) { m_notifyEventsIndexNameMap[m_notifyEventHandleCount] = name; m_notifyEventHandles[m_notifyEventHandleCount++] = eventHandle; } void MechnicalMonitor::AddThreadWaitEventHandle(const std::string &name, HANDLE eventHandle) { m_waitEventsIndexNameMap[m_waitEventHandleCount] = name; m_waitEventHandles[m_waitEventHandleCount++] = eventHandle; } void MechnicalMonitor::BeginMonitor(IMotionEventReceiver *receiver, int offset) { m_eventReceiver = receiver; if (offset == MO_TUBE_ANGLE) { InterlockedIncrement((LONG*)&m_angleStopedNotifyTime); } else if (offset == MO_TUBE_HEIGHT) { InterlockedIncrement((LONG*)&m_heightStopedNotifyTime); } else if (offset == MO_TUBE_HORIZONTAL) { InterlockedIncrement((LONG*)&m_horizontalStopedNotifyTime); } else { InterlockedIncrement((LONG*)&m_angleStopedNotifyTime); InterlockedIncrement((LONG*)&m_heightStopedNotifyTime); InterlockedIncrement((LONG*)&m_horizontalStopedNotifyTime); } if(gbusinessLog) gbusinessLog->Info("[MechnicalMonitor][BeginMonitor]->[{$:d} {$:d} {$:d}]", m_angleStopedNotifyTime, m_heightStopedNotifyTime, m_horizontalStopedNotifyTime); SetEvent(m_waitEventHandles[0]); } void MechnicalMonitor::EndMonitor() { SetEvent(m_waitEventHandles[1]); } void MechnicalMonitor::ReceiveEvent(const std::string &name) { //LogicDriverThreadLocker::Instance()->Lock(); if (m_eventReceiver) { if(gbusinessLog) gbusinessLog->Info("[MechnicalMonitor][ReceiveEvent]->[{$}]", name.c_str()); m_eventReceiver->OnMotionEvent(name); } //LogicDriverThreadLocker::Instance()->UnLock(); } void MechnicalMonitor::OnStartMonitorInThread() { if(gbusinessLog) gbusinessLog->Info("[MechnicalMonitor][OnStartMonitorInThread]"); //轮询球管高度/角度编码器值的变化,直至为 0,并通知work线程 long presionSensor = 2L; InterlockedExchange((LONG *)&m_isMonitorStoped,FALSE); auto lastanglesensor = m_positionManager->GetCurrentSensorValue((DOF_MECH)m_dofTubeAngleAxis); auto lastheightsensor = m_positionManager->GetCurrentSensorValue((DOF_MECH)m_dofTubeHeightAxis); auto lasthorizontalsensor = m_positionManager->GetCurrentSensorValue((DOF_MECH)TOMO_TUBE_HORIZONTAL); while (!m_isMonitorStoped && (m_angleStopedNotifyTime > 0 || m_heightStopedNotifyTime > 0 || m_horizontalStopedNotifyTime > 0)) { Sleep(300); if (!m_notifyEventHandles[0]) { InterlockedDecrement((LONG*)&m_angleStopedNotifyTime); } if (!m_notifyEventHandles[1]) { InterlockedDecrement((LONG*)&m_heightStopedNotifyTime); } if (!m_notifyEventHandles[2]) { InterlockedDecrement((LONG*)&m_horizontalStopedNotifyTime); } auto currentanglesensor = m_positionManager->GetCurrentSensorValue((DOF_MECH)m_dofTubeAngleAxis); if (m_angleStopedNotifyTime > 0 && (abs((long)currentanglesensor - (long)lastanglesensor) < presionSensor)) { InterlockedDecrement((LONG*)&m_angleStopedNotifyTime); if(gbusinessLog) gbusinessLog->Info("[MechnicalMonitor][OnStartMonitorInThread]->[Notify TubeAngle Stop.]"); SetEvent(m_notifyEventHandles[0]); } lastanglesensor = currentanglesensor; auto currentheightsensor = m_positionManager->GetCurrentSensorValue((DOF_MECH)m_dofTubeHeightAxis); if (m_heightStopedNotifyTime > 0 && (abs((long)currentheightsensor - (long)lastheightsensor) < presionSensor)) { InterlockedDecrement((LONG*)&m_heightStopedNotifyTime); if(gbusinessLog) gbusinessLog->Info("[MechnicalMonitor][OnStartMonitorInThread]->[Notify TubeHeight Stop.]"); SetEvent(m_notifyEventHandles[1]); } lastheightsensor = currentheightsensor; long adTolerance = 1L; auto currenthorizontalsensor = m_positionManager->GetCurrentSensorValue((DOF_MECH)m_dofTubeHorizontalAxis); if (m_horizontalStopedNotifyTime > 0 && (abs((long)currenthorizontalsensor - (long)lasthorizontalsensor) < adTolerance)) { InterlockedDecrement((LONG*)&m_horizontalStopedNotifyTime); if (gbusinessLog) gbusinessLog->Info("[MechnicalMonitor][OnStartMonitorInThread]->[Notify TubeHorizontal Stop.]"); SetEvent(m_notifyEventHandles[2]); } lasthorizontalsensor = currenthorizontalsensor; if(gbusinessLog) gbusinessLog->Info("[MechnicalMonitor][CurrentMonitorValues]->[Angle:{$:d}, Height:{$:d}, Horizontal:{$:d}]", currentanglesensor, currentheightsensor, currenthorizontalsensor); } InterlockedExchange((LONG *)&m_isMonitorStoped, TRUE); } void MechnicalMonitor::OnStopMonitorInThread() { //停止轮询球管高度/角度编码器值 InterlockedExchange((LONG *)&m_isMonitorStoped, TRUE); } bool MechnicalMonitor::OnMotionMonitorThreadExecute() { if (m_waitEventHandleCount <= 0 || m_waitEventHandleCount > MONITOR_NOTIFY_EVENT_MAX) { return false; } while (true) { auto waitResult = ::WaitForMultipleObjects(m_waitEventHandleCount, m_waitEventHandles, FALSE, INFINITE); auto eventIndex = waitResult - WAIT_OBJECT_0; if (m_waitEventsIndexNameMap.find(eventIndex) != m_waitEventsIndexNameMap.end()) { auto eventName = m_waitEventsIndexNameMap[eventIndex]; if (eventName == MONITOR_EVENT_WAIT_BEGIN_MONITOR) { if (!m_isMonitorStoped) { continue; } OnStartMonitorInThread(); } else if (eventName == MONITOR_EVENT_WAIT_END_MONITOR) { OnStopMonitorInThread(); } else { } } } return true; } bool MechnicalMonitor::OnMotionMonitorWorkThreadExecute() { if (m_notifyEventHandleCount <= 0 || m_notifyEventHandleCount > MONITOR_NOTIFY_EVENT_MAX) { return false; } while (true) { auto waitResult = ::WaitForMultipleObjects(m_notifyEventHandleCount, m_notifyEventHandles, FALSE, INFINITE); auto eventIndex = waitResult - WAIT_OBJECT_0; if (m_notifyEventsIndexNameMap.find(eventIndex) != m_notifyEventsIndexNameMap.end()) { auto eventName = m_notifyEventsIndexNameMap[eventIndex]; ReceiveEvent(eventName); } } } void MotionMonitorThread::Initialize(MechnicalMonitor *monitor) { m_monitor = monitor; } bool MotionMonitorThread::Exec() { if (!m_monitor) { return false; } std::thread::id this_id = std::this_thread::get_id(); unsigned int t = *(unsigned int*)&this_id;// threadid 转成 unsigned int printf("MotionMonitorThread ID: %d\n", t); return m_monitor->OnMotionMonitorThreadExecute(); } void MotionMonitorWorkThread::Initialize(MechnicalMonitor *monitor) { m_monitor = monitor; } bool MotionMonitorWorkThread::Exec() { if (!m_monitor) { return false; } std::thread::id this_id = std::this_thread::get_id(); unsigned int t = *(unsigned int*)&this_id;// threadid 转成 unsigned int printf("MotionMonitorWorkThread ID: %d\n", t); return m_monitor->OnMotionMonitorWorkThreadExecute(); }