GrpcPrint/PrintS/PLC/CoreCommunication.cpp

440 lines
13 KiB
C++

#include "CoreCommunication.h"
#include "../Communication/S7Command.h"
#include "../config/ConfigManager.h"
#include "../SystemInfo.h"
#include "../ScannerCtrl/BaseCtrl.h"
#include "../include/log/Logger.h"
#include <map>
CoreCommunication::CoreCommunication()
: m_Config(NULL)
, m_ReadThread(INVALID_HANDLE_VALUE)
, m_WriteThread(INVALID_HANDLE_VALUE)
, m_sendTdExitFlag(false)
{
m_IsSmart = true;
m_Invoker = new PLCInvoker();
}
CoreCommunication::~CoreCommunication()
{
Shutdown();
if (m_S7Client) {
if (m_S7Client->Connected)m_S7Client->Disconnect();
delete m_S7Client;
}
m_sendTdExitFlag = true;
if (m_sendTd.joinable()) m_sendTd.join();
}
void CoreCommunication::Startup()
{
Shutdown();
m_RunFlag = true;
m_AssistRunFlag = true;
m_ReadThread = AtlCreateThread(ReadProc, this);
m_AssistThread = AtlCreateThread(AssistProc, this);
m_sendTd = std::thread([this] {SendProc(); });
}
void CoreCommunication::Shutdown()
{
m_RunFlag = false;
m_AssistRunFlag = false;
if (m_ReadThread != INVALID_HANDLE_VALUE) {
if (WaitForSingleObject(m_ReadThread, 2000) == WAIT_TIMEOUT) {
TerminateThread(m_ReadThread, 0);
}
CloseHandle(m_ReadThread);
m_ReadThread = INVALID_HANDLE_VALUE;
}
if (m_WriteThread != INVALID_HANDLE_VALUE) {
if (WaitForSingleObject(m_WriteThread, 2000) == WAIT_TIMEOUT) {
TerminateThread(m_WriteThread, 0);
}
CloseHandle(m_WriteThread);
m_WriteThread = INVALID_HANDLE_VALUE;
}
if (m_AssistThread != INVALID_HANDLE_VALUE)
{
if (WaitForSingleObject(m_AssistThread, 1000) == WAIT_TIMEOUT) {
TerminateThread(m_AssistThread, 0);
}
CloseHandle(m_AssistThread);
m_AssistThread = INVALID_HANDLE_VALUE;
}
m_BaseStat.isConnected = false;
m_S7Client->Disconnect();
std::unique_lock <std::mutex> lck(m_WirteMutex);
while (!m_RTCommands.empty()) {
Command* command = m_RTCommands.front();
if (command->isNeedDel) {
delete command;
command = NULL;
}
m_RTCommands.pop();
}
}
void CoreCommunication::Init()
{
map<string, CommunicationCfg*>* tcpCfgs = ConfigManager::GetInstance()->GetCommunicationCfg();
if (tcpCfgs->find("PLC") != tcpCfgs->end()) {
m_Config = (*tcpCfgs)["PLC"];
ConfigManager::GetInstance()->AddComRefCfg(m_Config, this);
}
m_CoverCfg = ConfigManager::GetInstance()->GetCoverCfg();
m_S7Client = new TSnap7Client();
int sendtimeout = 100;
int readtimeout = 500;
int pdusize = 1200;
if (m_IsSmart)
{
m_S7Client->SetConnectionParams(m_Config->m_IP.c_str(), 0x0200, 0x0200); //ip wxxtest
}
m_S7Client->SetParam(p_i32_PDURequest, &pdusize);
m_S7Client->SetParam(p_i32_SendTimeout, &sendtimeout);
m_S7Client->SetParam(p_i32_RecvTimeout, &readtimeout);
#ifdef _DEBUG
int pingTimeout = 0;
m_S7Client->SetParam(p_i32_PingTimeout, &pingTimeout);
#endif
InitCommand();
//if (m_IOCfgWrapper)
// m_IOCfgWrapper->SetCC(this);
}
void CoreCommunication::InitCommand()
{
vector<S7Command*> vec;
ConfigManager::GetInstance()->GetMachine()->InitPLCCommand(vec);
for (size_t i = 0; i < vec.size();i++) {
m_CycleCommands.push_back(vec[i]);
}
}
Command* CoreCommunication::GetSendCycleCommand()
{
Command* command = NULL;
for (size_t i = 0; i < m_CycleCommands.size(); ++i) {
if (!m_CycleCommands[i]->isFinished)
{
command = m_CycleCommands[i];
break;
}
}
return command;
}
void CoreCommunication::UpdateCycleCommands()
{
bool isAllFinished = true;
for (size_t i = 0; i < m_CycleCommands.size(); ++i) {
if (!m_CycleCommands[i]->isFinished) {
isAllFinished = false;
break;
}
}
if (isAllFinished)
{
for (size_t i = 0; i < m_CycleCommands.size(); ++i) {
m_CycleCommands[i]->isFinished = false;
}
}
}
DWORD WINAPI CoreCommunication::ReadProc(CoreCommunication* _this) {
if (_this) {
_this->ReadRun();
}
return 0;
}
void CoreCommunication::ReadRun()
{
while (m_RunFlag) {
if (!m_S7Client->Connected) {
int rel = 0;
m_BaseStat.isConnected = false;
m_BaseStat.readTimeoutFlag = 0;
if (m_IsSmart) {
m_S7Client->SetConnectionParams(m_Config->m_IP.c_str(), (word)0x0200, (word)0x0200);
rel = m_S7Client->Connect();
}
else {
rel = m_S7Client->ConnectTo(m_Config->m_IP.c_str(), 0, 2);
}
if (rel != 0) {
int counttick = 0;
while (m_RunFlag) {
counttick++;
if (counttick > 20) {
break;
}
Sleep(100);
}
continue;
}
if (m_WriteThread != INVALID_HANDLE_VALUE) {
m_RunFlag = false;
if (WaitForSingleObject(m_WriteThread, 2000) == WAIT_TIMEOUT) {
}
CloseHandle(m_WriteThread);
m_WriteThread = INVALID_HANDLE_VALUE;
m_RunFlag = true;
}
m_WriteThread = AtlCreateThread(WriteProc, this);
}
Command* pCommand = GetSendCycleCommand();
if (pCommand != NULL) {
S7Command* ps7 = (S7Command*)pCommand;
TS7DataItem* items = ps7->getDataItems();
std::unique_lock <std::mutex> lck(m_ReadWriteMutex);
int readlrel = m_S7Client->ReadMultiVars(items, ps7->getItemCount());
lck.unlock();
if (readlrel == 0)
{
m_BaseStat.readTimeoutFlag = 0;
m_BaseStat.isConnected = true;
if (ps7->m_Fun)ps7->m_Fun(ps7->m_Ref, ps7);
}
else {
m_BaseStat.readTimeoutFlag++;
if (m_BaseStat.readTimeoutFlag >= m_Config->m_AlarmTimeoutTimes) {
m_BaseStat.isConnected = false;
m_BaseStat.readTimeoutFlag = 0;
m_S7Client->Disconnect();
if (m_WriteThread != INVALID_HANDLE_VALUE) {
m_RunFlag = false;
if (WaitForSingleObject(m_WriteThread, 2000) == WAIT_TIMEOUT) {
}
CloseHandle(m_WriteThread);
m_WriteThread = INVALID_HANDLE_VALUE;
m_RunFlag = true;
}
}
}
pCommand->isFinished = true;
}
UpdateCycleCommands();
Sleep(10);
}
}
DWORD WINAPI CoreCommunication::WriteProc(CoreCommunication* _this)
{
if (_this) {
_this->WriteRun();
}
return 0;
}
void CoreCommunication::WriteRun()
{
while (m_RunFlag)
{
Command* command = NULL;
unique_lock <std::mutex> lck(m_WirteMutex);
if (!m_RTCommands.empty()) {
command = m_RTCommands.front();
m_RTCommands.pop();
}
lck.unlock();
if (!command) {
Sleep(10);
continue;
}
S7Command* ps7 = (S7Command*)command;
TS7DataItem* items = ps7->getDataItems();
//TS7DataItem item = items[0];
std::unique_lock <std::mutex> wrlck(m_ReadWriteMutex);
int rel=m_S7Client->WriteMultiVars(items, ps7->getItemCount());
wrlck.unlock();
//int rel = m_S7Client->WriteArea(item.Ar0ea, item.DBNumber, item.Start, item.Amount, item.WordLen, item.pdata);
if (rel == 0)
{
if (ps7->m_Fun)ps7->m_Fun(ps7->m_Ref, ps7);
}
if (command->isNeedDel)delete command;
//Sleep(10);
}
}
DWORD WINAPI CoreCommunication::AssistProc(CoreCommunication* _this)
{
if (_this) {
_this->AssistRun();
}
return 0;
}
void CoreCommunication::AssistRun()
{
while (m_AssistRunFlag)
{
if (!m_S7Client->Connected) {
Sleep(200);
continue;
}
uint64_t nowtick = GetTickCount64();
if (nowtick - m_AlarmStateWrapper->m_KeepAliveCommand->m_PrintKeepAliveTimetick >= 500) {
m_AlarmStateWrapper->m_KeepAliveCommand->SetKeepAliveValue();
if (BaseCtrl::IsStandBy()) {
//m_AlarmStateWrapper->m_KeepAliveCommand->SetDeviceStanbyValue(true);
m_AlarmStateWrapper->m_KeepAliveCommand->SetDevicePrintingValue(false);
}
else if (BaseCtrl::IsStart()) {
//m_AlarmStateWrapper->m_KeepAliveCommand->SetDeviceStanbyValue(false);
m_AlarmStateWrapper->m_KeepAliveCommand->SetDevicePrintingValue(true);
}
m_Invoker->SetCommand(m_AlarmStateWrapper->m_KeepAliveCommand);
m_Invoker->Call();
m_AlarmStateWrapper->m_KeepAliveCommand->m_PrintKeepAliveFlag = !m_AlarmStateWrapper->m_KeepAliveCommand->m_PrintKeepAliveFlag;
m_AlarmStateWrapper->m_KeepAliveCommand->m_PrintKeepAliveTimetick = nowtick;
}
if (m_IOCfgWrapper->m_SystemStop->IsActive()) {
vector<ScannerControlCfg*>* laserCfgs = ConfigManager::GetInstance()->GetMatchScannerControlCfg();
for (size_t i = 0; i < laserCfgs->size(); i++) {
ScannerControlCfg* laserCfg = (*laserCfgs)[i];
laserCfg->m_LaserEnable->SetActive(false);
}
if (m_IOCfgWrapper->m_ServoMotor)m_IOCfgWrapper->m_ServoMotor->SetActive(false);
}
bool sysPreClose = false;
if (m_SysParamWrapper->m_PrintPressure->GetValue() > m_SysParamWrapper->m_PrintPressureThrehold->GetValue()
|| m_AlarmStateWrapper->m_PrintPressureOverLimitAlarm->GetValue()) {
m_IOCfgWrapper->m_PressureRelease->SetActive(true);
}
else {
sysPreClose = true;
}
if (m_IOCfgWrapper->IsSystemCtrlPressure()) {
if (sysPreClose && m_IOCfgWrapper->m_PressureRelease->IsActive()) {
m_IOCfgWrapper->m_PressureRelease->SetActive(false);
}
}
m_SysParamWrapper->m_OutsideOxygen->SetValue(g_SystemInfo->GetComOutsideOxygen());
Sleep(100);
}
}
void CoreCommunication::GetAlarmState(SignalState& signalState)
{
std::shared_lock<std::shared_mutex> lock(m_ValueMtx);
//ConfigManager::GetInstance()->GetMachine()->GetAlarmState(signalState);
}
void CoreCommunication::GetEnvState(EnvState& envState)
{
std::shared_lock<std::shared_mutex> lock(m_ValueMtx);
//ConfigManager::GetInstance()->GetMachine()->GetAlarmState(envState);
envState.m_PrintOxygen1Analog=m_SysParamWrapper->m_PrintOxygen1->GetValue();
envState.m_PrintOxygen2Analog =m_SysParamWrapper->m_PrintOxygen2->GetValue();
envState.m_OutsideOxygenAnalog =m_SysParamWrapper->m_OutsideOxygen->GetValue();
envState.m_HighPressureAnalog =m_SysParamWrapper->m_HighPressure->GetValue();
envState.m_ProtectGasPressureAnalog =m_SysParamWrapper->m_ProtectGasPressure->GetValue();
envState.m_PrintPressureAnalog =m_SysParamWrapper->m_PrintPressure->GetValue();
envState.m_MoldMainCurrentPos=m_SysParamWrapper->m_MoldMainCurrentPos->GetValue(); //打印主轴当前位置_R
envState.m_MoldMainCurrentLoad=m_SysParamWrapper->m_MoldMainCurrentLoad->GetValue(); //打印主轴当前扭矩_R
envState.m_MoldSlaveCurrentPos=m_SysParamWrapper->m_MoldSlaveCurrentPos->GetValue(); //打印从轴当前位置_R
envState.m_MoldSlaveCurrentLoad=m_SysParamWrapper->m_MoldSlaveCurrentLoad->GetValue(); //打印从轴当前扭矩_R
envState.m_CleanMainCurrentPos=m_SysParamWrapper->m_CleanMainCurrentPos->GetValue(); //清粉主轴当前位置_R
envState.m_CleanMainCurrentLoad=m_SysParamWrapper->m_CleanMainCurrentLoad->GetValue(); //清粉主轴当前扭矩_R
envState.m_CleanSlaveCurrentPos=m_SysParamWrapper->m_CleanSlaveCurrentPos->GetValue(); //清粉从轴当前位置_R
envState.m_CleanSlaveCurrentLoad=m_SysParamWrapper->m_CleanSlaveCurrentLoad->GetValue(); //清粉从轴当前扭矩_R
envState.m_LoadAxisCurrentPos=m_SysParamWrapper->m_LoadAxisCurrentPos->GetValue(); //移载轴当前位置_R
envState.m_LoadAxisCurrentLoad=m_SysParamWrapper->m_LoadAxisCurrentLoad->GetValue(); //移载轴当前扭矩_R
envState.m_ArmCurrentPos=m_SysParamWrapper->m_ArmCurrentPos->GetValue(); //铺粉轴当前位置_R
envState.m_ArmCurrentLoad=m_SysParamWrapper->m_ArmCurrentLoad->GetValue(); //铺粉轴当前扭矩_R
envState.m_SupplyCurrentPos=m_SysParamWrapper->m_SupplyCurrentPos->GetValue(); //供粉转轴当前位置_R
envState.m_SupplyCurrentLoad=m_SysParamWrapper->m_SupplyCurrentLoad->GetValue(); //供粉转轴当前扭矩_R
envState.m_IsPrintCabinDoorClose = m_IOCfgWrapper->IsSafeDoorClose();
envState.m_PowderJarCabinPressureVoltage=m_SysParamWrapper->m_PowderJarCabinPressureVoltage->GetValue();
envState.m_PowderJarCabinPressure=m_SysParamWrapper->m_PowderJarCabinPressureValue->GetValue();
envState.m_PowderLevelLength = m_SysParamWrapper->m_PowderLevelLength->GetValue();
envState.m_PowderLevelValue = m_SysParamWrapper->m_PowderLevelValue->GetValue();
envState.m_LinearLayerPos = m_SysParamWrapper->m_LinearEncoderPerLayerRealValue->GetValue();
envState.m_MoldTheoryDistance = m_SysParamWrapper->m_MoldTheoryDistance->GetValue();
envState.m_LinearActDistance = m_SysParamWrapper->m_LinearActDistance->GetValue();
envState.m_LinearActPulse = m_SysParamWrapper->m_LinearActPulse->GetValue();
envState.m_LineEncPulseEqu = m_SysParamWrapper->m_LineEncPulseEqu->GetValue();
envState.m_PrintCar1RealWeight = m_SysParamWrapper->m_PrintCar1RealWeight->GetValue();
envState.m_PrintCar2RealWeight = m_SysParamWrapper->m_PrintCar2RealWeight->GetValue();
envState.m_CleanCar1RealWeight = m_SysParamWrapper->m_CleanCar1RealWeight->GetValue();
envState.m_CleanCar2RealWeight = m_SysParamWrapper->m_CleanCar2RealWeight->GetValue();
}
/*void CoreCommunication::AddCmd(Command* cmd)
{
unique_lock <std::mutex> lck(m_WirteMutex);
m_RTCommands.push(cmd);
m_WriteCV.notify_one();
}*/
void CoreCommunication::SendProc() {
string valStr;
DATATYPE dataType;
list<Item> its;
while (!m_sendTdExitFlag) {
std::unique_lock<std::shared_mutex> lock(m_ValueMtx);
valStr = "";
its.clear();
auto param = SysParam::m_sysParamMp.begin();
while (param != SysParam::m_sysParamMp.end()) {
valStr = param->second.GetValue(dataType);
its.emplace_back(Item{ param->first,valStr,dataType});
++param;
}
ClientWrapper::Instance()->PushAllClient(new WriteData(SYSPARAMDATA, its));
valStr = "";
its.clear();
auto ioItem = m_IOCfgWrapper->m_IOCfgMap.begin();
while (ioItem != m_IOCfgWrapper->m_IOCfgMap.end()) {
valStr = to_string(ioItem->second->IsActive());
its.emplace_back(Item{ ioItem->first,valStr,iBOOL });
++param;
}
ClientWrapper::Instance()->PushAllClient(new WriteData(SYSPARAMDATA, its));
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}