在 `CDriverMainDlg::ProcessPipeMsg` 中修改了角度计算逻辑,增加了对角度绝对值的判断,并更新了 `CorrectAngle` 函数的调用。调整了 PID 控制器的参数以优化控制效果。 在 `CFastMainDialog` 中实现了 TCP 监听线程,新增了 `StartTCPServer` 和 `StopTCPServer` 函数,并在对话框初始化时启动 TCP 服务器。更新了项目文件以支持新的编译环境。
345 lines
8.1 KiB
C++
345 lines
8.1 KiB
C++
// WcsMainDialog.cpp : 实现文件
|
||
//
|
||
|
||
#include "stdafx.h"
|
||
#include "afxdialogex.h"
|
||
|
||
#include "Fast.h"
|
||
#include "FastMainDialog.h"
|
||
|
||
|
||
|
||
// CMainDialog 对话框
|
||
|
||
IMPLEMENT_DYNAMIC(CFastMainDialog, CDialogEx)
|
||
|
||
CFastMainDialog::CFastMainDialog(CWnd* pParent /*=NULL*/)
|
||
: CDialogEx(IDD_FAST_MAIN_DIALOG, pParent)
|
||
{
|
||
}
|
||
|
||
CFastMainDialog::~CFastMainDialog()
|
||
{
|
||
|
||
}
|
||
|
||
void CFastMainDialog::DoDataExchange(CDataExchange* pDX)
|
||
{
|
||
CDialogEx::DoDataExchange(pDX);
|
||
DDX_Control(pDX, IDC_STATIC_FAST1, m_FastCam[0]);
|
||
DDX_Control(pDX, IDC_STATIC_FAST2, m_FastCam[1]);
|
||
DDX_Control(pDX, IDC_STATIC_FAST3, m_FastCam[2]);
|
||
DDX_Control(pDX, IDC_STATIC_FAST4, m_FastCam[3]);
|
||
}
|
||
|
||
|
||
BEGIN_MESSAGE_MAP(CFastMainDialog, CDialogEx)
|
||
|
||
ON_WM_TIMER()
|
||
END_MESSAGE_MAP()
|
||
|
||
|
||
// CMainDialog 消息处理程序
|
||
|
||
//和模块进程通讯的管道回调函数:
|
||
void g_PipeCallBack(void* pObj, int lMsgId, WPARAM wparam, LPARAM lparam)
|
||
{
|
||
CFastMainDialog* pModule = (CFastMainDialog*)pObj;
|
||
if (CEXPIPE_CONNECT_OK == lMsgId)
|
||
{
|
||
//连接成功
|
||
//if (FALSE == pModule->PostMessage(WM_PLATFORM_CONNECT_OK, NULL, NULL)) { LogOutToFile("g_PipeCallBack PostMessage error[%d]", lMsgId); }
|
||
LogOutToFile("已连接父进程管道");
|
||
|
||
//向WMS服务器请求设备配置信息
|
||
//theApp.SendMsg2Platform("WMS", DEVICE_CONFIG_REQ, NULL);
|
||
}
|
||
else if (CEXPIPE_DIS_CLIENT == lMsgId)
|
||
{
|
||
//管道断开,结束
|
||
#ifndef _DEBUG
|
||
LogOutToFile("父进程连接管道断开,本模块自动退出");
|
||
//if (FALSE == pModule->PostMessage(WM_CLOSE, NULL, NULL)) { LogOutToFile("g_PipeCallBack PostMessage error[%d]", lMsgId); }
|
||
pModule->PostMessage(WM_COMMAND, MAKEWPARAM(ID_TRAY_EXIT, 0), 0);
|
||
#endif
|
||
}
|
||
else if (CEXPIPE_NEW_DATA == lMsgId)
|
||
{
|
||
pModule->ProcessPipeMsg(lMsgId, (char*)wparam, (int)lparam);
|
||
}
|
||
else
|
||
{
|
||
;
|
||
}
|
||
}
|
||
|
||
|
||
void CFastMainDialog::ProcessPipeMsg(int lMsgId, char* pData, int lLen)
|
||
{
|
||
if (lLen == 0)
|
||
{
|
||
return;
|
||
}
|
||
|
||
PIPE_DATA_STRUCT* pstData = (PIPE_DATA_STRUCT*)pData;
|
||
|
||
//平台转发给插件的消息
|
||
if (pstData->lMsgId == MAIN_2_MODULE_WMS && pstData->lDataLen > 0)
|
||
{
|
||
Json::Reader reader;
|
||
Json::Value root;
|
||
if (reader.parse((char*)pstData->acData, root))
|
||
{
|
||
CString strReceiver = root["receiver"].asString().c_str();
|
||
CString strSender = root["sender"].asString().c_str();
|
||
int nMsgType = root["type"].asInt();
|
||
|
||
|
||
//获取设备配置信息返回
|
||
/*if (nMsgType == DEVICE_CONFIG_RET)
|
||
{
|
||
|
||
}
|
||
else if (nMsgType == SET_TRANS_MODE_REQ && m_bDeviceInit) //设置输送线的工作模式
|
||
{
|
||
|
||
}
|
||
else if (nMsgType == GET_TRANS_STATE_REQ)//请求获取输送线状态
|
||
{
|
||
|
||
}*/
|
||
|
||
}
|
||
}
|
||
else if (pstData->lMsgId == MAIN_2_MODULE_SHOWWINDOW)
|
||
{
|
||
//PostMessage(WM_COMMAND, MAKEWPARAM(ID_TRAY_SHOW, 0), 0);
|
||
AfxGetApp()->m_pMainWnd->ShowWindow(SW_SHOWNORMAL);
|
||
SetForegroundWindow();
|
||
}
|
||
|
||
LogOutToFile("HttpServiceListener::OnRecvRequest End");
|
||
}
|
||
|
||
// TCP服务端线程
|
||
/*UINT CFastMainDialog::TCPListenerThread(LPVOID pParam) {
|
||
CFastMainDialog* pThis = (CFastMainDialog*)pParam;
|
||
SOCKET hServer = pThis->m_hServerSocket;
|
||
|
||
while (true) {
|
||
SOCKET hClient = accept(hServer, NULL, NULL);
|
||
if (hClient == INVALID_SOCKET) continue;
|
||
|
||
char buffer[4096];
|
||
int bytesRecv = recv(hClient, buffer, sizeof(buffer), 0);
|
||
if (bytesRecv > 0) {
|
||
CString strMsg(buffer, bytesRecv);
|
||
pThis->ProcessTCPMessage(strMsg);
|
||
}
|
||
closesocket(hClient);
|
||
}
|
||
return 0;
|
||
}*/
|
||
UINT CFastMainDialog::TCPListenerThread(LPVOID pParam) {
|
||
CFastMainDialog* pThis = (CFastMainDialog*)pParam;
|
||
SOCKET hServer = pThis->m_hServerSocket;
|
||
|
||
while (true) {
|
||
SOCKET hClient = accept(hServer, NULL, NULL);
|
||
if (hClient == INVALID_SOCKET) continue;
|
||
|
||
// 禁用Nagle算法(可选)
|
||
int optval = 1;
|
||
setsockopt(hClient, IPPROTO_TCP, TCP_NODELAY, (char*)&optval, sizeof(optval));
|
||
|
||
// 持续接收数据直到连接关闭
|
||
char buffer[4096];
|
||
while (true) {
|
||
int bytesRecv = recv(hClient, buffer, sizeof(buffer), 0);
|
||
if (bytesRecv <= 0) { // 连接断开或错误
|
||
LogOutToFile("[TCP] Client disconnected or error: %d", WSAGetLastError());
|
||
break;
|
||
}
|
||
|
||
CString strMsg(buffer, bytesRecv);
|
||
pThis->ProcessTCPMessage(strMsg);
|
||
}
|
||
closesocket(hClient); // 最终关闭连接
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
// 处理收到的TCP消息
|
||
void CFastMainDialog::ProcessTCPMessage(const CString& strJson) {
|
||
LogOutToFile("FAST::ProcessTCPMessage Received: %s", strJson);
|
||
|
||
Json::Reader reader;
|
||
Json::Value root;
|
||
if (!reader.parse((LPCTSTR)strJson, root)) {
|
||
LogOutToFile("JSON parse error!");
|
||
return;
|
||
}
|
||
|
||
// 验证必要字段
|
||
if (!root.isMember("receiver") || !root.isMember("type")) {
|
||
LogOutToFile("Invalid message format");
|
||
return;
|
||
}
|
||
|
||
// 通过现有平台接口转发
|
||
CString strReceiver = root["receiver"].asString().c_str();
|
||
int nMsgType = root["type"].asInt();
|
||
Json::Value params = root.get("params", Json::nullValue);
|
||
|
||
theApp.SendMsg2Platform(strReceiver, nMsgType, params);
|
||
}
|
||
|
||
// 启动TCP服务
|
||
void CFastMainDialog::StartTCPServer()
|
||
{
|
||
// 1. 初始化Winsock
|
||
WSADATA wsaData;
|
||
int wsResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
|
||
if (wsResult != 0) {
|
||
LogOutToFile("[TCP] WSAStartup failed: %d", wsResult);
|
||
return;
|
||
}
|
||
|
||
// 2. 创建Socket
|
||
m_hServerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||
if (m_hServerSocket == INVALID_SOCKET) {
|
||
LogOutToFile("[TCP] Socket creation failed: %d", WSAGetLastError());
|
||
WSACleanup();
|
||
return;
|
||
}
|
||
|
||
// 3. 设置端口复用(可选)
|
||
int optval = 1;
|
||
setsockopt(m_hServerSocket, SOL_SOCKET, SO_REUSEADDR, (char*)&optval, sizeof(optval));
|
||
|
||
// 4. 绑定端口
|
||
sockaddr_in service;
|
||
service.sin_family = AF_INET;
|
||
service.sin_addr.s_addr = INADDR_ANY;
|
||
service.sin_port = htons(6000);
|
||
|
||
if (::bind(m_hServerSocket, (SOCKADDR*)&service, sizeof(service)) == SOCKET_ERROR)
|
||
{
|
||
LogOutToFile("[TCP] Bind failed on port 6000: %d", WSAGetLastError());
|
||
closesocket(m_hServerSocket);
|
||
WSACleanup();
|
||
return;
|
||
}
|
||
|
||
// 5. 开始监听
|
||
if (listen(m_hServerSocket, SOMAXCONN) == SOCKET_ERROR)
|
||
{
|
||
LogOutToFile("[TCP] Listen failed: %d", WSAGetLastError());
|
||
closesocket(m_hServerSocket);
|
||
WSACleanup();
|
||
return;
|
||
}
|
||
|
||
// 6. 启动线程
|
||
m_pListenerThread = AfxBeginThread(TCPListenerThread, this);
|
||
if (m_pListenerThread == NULL) {
|
||
LogOutToFile("[TCP] Thread creation failed!");
|
||
closesocket(m_hServerSocket);
|
||
WSACleanup();
|
||
return;
|
||
}
|
||
LogOutToFile("[TCP] Server successfully started on port 6000");
|
||
}
|
||
BOOL CFastMainDialog::OnInitDialog()
|
||
{
|
||
CDialogEx::OnInitDialog();
|
||
|
||
CString strPipe;
|
||
for (int i = 0; i < __argc; i++)
|
||
{
|
||
if (0 == strcmp(__argv[i], "-pipe") && i + 1 < __argc)
|
||
{
|
||
strPipe = __argv[i + 1];
|
||
}
|
||
}
|
||
|
||
if (strPipe.IsEmpty())
|
||
{
|
||
char acPipe[256] = "";
|
||
|
||
CString iniPath = theApp.m_strModulePath.Left(theApp.m_strModulePath.ReverseFind('\\') + 1);
|
||
//m_strModulePath = theApp.m_strModulePath.ReverseFind("\\");
|
||
iniPath = iniPath + "pipe.ini";
|
||
//中文名称,仅显示用
|
||
GetPrivateProfileString("AGV-MODULE", "PIPE_FAST", "", acPipe, 256, iniPath);
|
||
strPipe = acPipe;
|
||
}
|
||
g_pstPipeClient->RegisterCall(g_PipeCallBack, this);
|
||
g_pstPipeClient->Connect(strPipe.GetBuffer());
|
||
|
||
|
||
theApp.m_hMainWnd = m_hWnd;
|
||
//SetTimer(1, 500, NULL);
|
||
|
||
//初始化本地相机
|
||
InitLocalCamera();
|
||
StartTCPServer(); // 新增TCP服务启动
|
||
return TRUE; // return TRUE unless you set the focus to a control
|
||
// 异常: OCX 属性页应返回 FALSE
|
||
}
|
||
|
||
|
||
|
||
|
||
BOOL CFastMainDialog::PreTranslateMessage(MSG* pMsg)
|
||
{
|
||
if (pMsg->message == WM_KEYDOWN&&pMsg->wParam == VK_RETURN)
|
||
return TRUE;
|
||
if (pMsg->message == WM_KEYDOWN&&pMsg->wParam == VK_ESCAPE)
|
||
return TRUE;
|
||
|
||
return CDialog::PreTranslateMessage(pMsg);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
void CFastMainDialog::OnTimer(UINT_PTR nIDEvent)
|
||
{
|
||
// TODO: 在此添加消息处理程序代码和/或调用默认值
|
||
CDialogEx::OnTimer(nIDEvent);
|
||
}
|
||
|
||
void CFastMainDialog::InitLocalCamera()
|
||
{
|
||
m_FastCam[0].SetCameraInfo(0, HIK_RGBD, SNAP_PICTURE);
|
||
m_FastCam[1].SetCameraInfo(1, DAHUA_FISHEYE, SNAP_PICTURE, "192.168.0.124", 37777);
|
||
m_FastCam[2].SetCameraInfo(2, DAHUA_FISHEYE, RT_STREAMING, "192.168.0.124", 37777);
|
||
}
|
||
|
||
/*
|
||
void CFastMainDialog::InitCamereSDK()
|
||
{
|
||
MV3D_RGBD_VERSION_INFO stVersion;
|
||
MV3D_RGBD_GetSDKVersion(&stVersion);
|
||
MV3D_RGBD_Initialize();
|
||
int ret = MV3D_RGBD_Initialize();
|
||
|
||
unsigned int nDevNum = 0;
|
||
ret = MV3D_RGBD_GetDeviceNumber(DeviceType_USB, &nDevNum);
|
||
|
||
if (0 == nDevNum)
|
||
{
|
||
//AfxMessageBox("未检测到相机,请检查相机连接是否正常.");
|
||
return ;
|
||
}
|
||
|
||
MV3D_RGBD_DEVICE_INFO info;
|
||
for (int i = 0; i < nDevNum; i++)
|
||
{
|
||
m_CameraDev.push_back(info);
|
||
}
|
||
ret = MV3D_RGBD_GetDeviceList(DeviceType_USB, &m_CameraDev[0], nDevNum, &nDevNum);
|
||
}
|
||
*/ |