agv-control/Plugin/Fast/FastMainDialog.cpp
美食博主 22881ced28 优化角度计算与TCP服务器功能
在 `CDriverMainDlg::ProcessPipeMsg` 中修改了角度计算逻辑,增加了对角度绝对值的判断,并更新了 `CorrectAngle` 函数的调用。调整了 PID 控制器的参数以优化控制效果。

在 `CFastMainDialog` 中实现了 TCP 监听线程,新增了 `StartTCPServer` 和 `StopTCPServer` 函数,并在对话框初始化时启动 TCP 服务器。更新了项目文件以支持新的编译环境。
2025-07-07 08:34:56 +08:00

345 lines
8.1 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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);
}
*/