LAPTOP-T815PCOQ\25526
2024-12-10 726f0553fa435809d10c8a33abe46473ee975db1
1. 完善axis细部设定人机交互(数据填充和文件保存)
已修改6个文件
317 ■■■■■ 文件已修改
SourceCode/Bond/BondEq/BondEq.rc 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/FileManager/RecipeManager.cpp 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/FileManager/RecipeManager.h 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/Resource.h 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/View/AxisDetailSettingsDlg.cpp 293 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/View/AxisDetailSettingsDlg.h 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/BondEq/BondEq.rc
Binary files differ
SourceCode/Bond/BondEq/FileManager/RecipeManager.cpp
@@ -37,8 +37,8 @@
        axisInfo.number = axisNode.attribute("number").value();
        axisInfo.description = axisNode.attribute("description").value();
        axisInfo.startAddress = axisNode.attribute("start_address").value();
        axisInfo.maxPositioningSpeed = axisNode.attribute("maxPositioningSpeed").as_double();
        axisInfo.maxManualSpeed = axisNode.attribute("maxManualSpeed").as_double();
        //axisInfo.maxPositioningSpeed = axisNode.attribute("maxPositioningSpeed").as_double();
        //axisInfo.maxManualSpeed = axisNode.attribute("maxManualSpeed").as_double();
        // 加载 ValueRange 值
        axisInfo.jogDistance = ValueRange(
@@ -115,8 +115,8 @@
        axisNode.append_attribute("number") = axisInfo.number.c_str();
        axisNode.append_attribute("description") = axisInfo.description.c_str();
        axisNode.append_attribute("start_address") = axisInfo.startAddress.c_str();
        axisNode.append_attribute("maxPositioningSpeed") = axisInfo.maxPositioningSpeed;
        axisNode.append_attribute("maxManualSpeed") = axisInfo.maxManualSpeed;
        //axisNode.append_attribute("maxPositioningSpeed") = axisInfo.maxPositioningSpeed;
        //axisNode.append_attribute("maxManualSpeed") = axisInfo.maxManualSpeed;
        // 保存 ValueRange 值
        auto jog_distance = axisNode.append_child("jog_distance");
@@ -169,8 +169,8 @@
        AxisInfo axisInfo;
        axisInfo.id = axisId;
        axisInfo.positioningPointCount = 25;
        axisInfo.maxPositioningSpeed = 100.0;
        axisInfo.maxManualSpeed = 100.0;
        //axisInfo.maxPositioningSpeed = 100.0;
        //axisInfo.maxManualSpeed = 100.0;
        axisInfo.number = "M100-M" + std::to_string(axisId);
        axisInfo.description = "Default_Axis" + std::to_string(axisId);
        axisInfo.startAddress = "ZR" + std::to_string(10000 + (axisId - 1) * 300);
@@ -206,7 +206,7 @@
    }
    // 如果没有找到该轴,返回一个默认的无效 AxisInfo
    return AxisInfo{ -1, 0, 0.0, 0.0, "", "", "", ValueRange(), ValueRange(), ValueRange(), ValueRange(), ValueRange(), {} };
    return AxisInfo{ -1, 0, /*0.0, 0.0,*/ "", "", "", ValueRange(), ValueRange(), ValueRange(), ValueRange(), ValueRange(), {} };
}
// 更新轴信息
SourceCode/Bond/BondEq/FileManager/RecipeManager.h
@@ -30,8 +30,8 @@
struct AxisInfo {
    int id;                                    // 轴ID
    int positioningPointCount;                 // 定位点数
    double maxPositioningSpeed;                // 定位速度上限
    double maxManualSpeed;                     // 手动速度上限
    //double maxPositioningSpeed;                // 定位速度上限
    //double maxManualSpeed;                     // 手动速度上限
    std::string number;                        // 轴编号
    std::string description;                   // 轴描述
    std::string startAddress;                  // 起始地址
SourceCode/Bond/BondEq/Resource.h
Binary files differ
SourceCode/Bond/BondEq/View/AxisDetailSettingsDlg.cpp
@@ -5,6 +5,8 @@
#include "BondEq.h"
#include "afxdialogex.h"
#include "AxisDetailSettingsDlg.h"
#include "NewCellTypes/GridCellCheck.h"
#include "NewCellTypes/GridCellNumeric.h"
// CAxisDetailSettingsDlg 对话框
@@ -32,6 +34,126 @@
    m_pPLC = pPLC;
}
void CAxisDetailSettingsDlg::InitAnchorPontManager()
{
    if (m_grid.GetSafeHwnd() == NULL)
        return;
    int nRows = 1;
    int nCols = 6;
    int nFixRows = 1;
    int nFixCols = 0;
    int nRowIdx = 0;
    int nColIdx = 0;
    m_grid.DeleteAllItems();
    m_grid.SetVirtualMode(FALSE);
    m_grid.GetDefaultCell(TRUE, FALSE)->SetBackClr(g_nGridFixCellColor); // 设置固定行背景色
    m_grid.GetDefaultCell(FALSE, TRUE)->SetBackClr(g_nGridFixCellColor); // 设置固定列背景色
    m_grid.GetDefaultCell(FALSE, FALSE)->SetBackClr(g_nGridCellColor);     // 设置单元格背景色
    m_grid.SetFixedTextColor(g_nGridFixFontColor);                         // 设置固定行列字体颜色
    m_grid.SetRowCount(nRows);
    m_grid.SetColumnCount(nCols);
    m_grid.SetFixedRowCount(nFixRows);
    m_grid.SetFixedColumnCount(nFixCols);
    // Col
    m_grid.SetColumnWidth(nColIdx, 10);
    m_grid.SetItemText(nRowIdx, nColIdx++, _T("No."));
    m_grid.SetColumnWidth(nColIdx, 10);
    m_grid.SetItemText(nRowIdx, nColIdx++, _T("激活"));
    m_grid.SetColumnWidth(nColIdx, 50);
    m_grid.SetItemText(nRowIdx, nColIdx++, _T("最小值"));
    m_grid.SetColumnWidth(nColIdx, 50);
    m_grid.SetItemText(nRowIdx, nColIdx++, _T("当前值"));
    m_grid.SetColumnWidth(nColIdx, 50);
    m_grid.SetItemText(nRowIdx, nColIdx++, _T("最大值"));
    m_grid.SetColumnWidth(nColIdx, 120);
    m_grid.SetItemText(nRowIdx, nColIdx++, _T("描述"));
    m_grid.SetFixedRowSelection(FALSE);
    m_grid.SetFixedColumnSelection(FALSE);
    m_grid.SetEditable(TRUE);
    m_grid.SetRowResize(FALSE);
    m_grid.SetColumnResize(TRUE);
    m_grid.ExpandColumnsToFit(TRUE);
    m_grid.SetListMode(TRUE);                // 启用列表模式
    m_grid.EnableSelection(TRUE);            // 启用选择
    m_grid.SetSingleRowSelection(TRUE);        // 自动整行高亮(限制为单行选择)
    m_grid.ExpandLastColumn();                // 最后一列填充网格
    FillAnchorPontManager();
}
void CAxisDetailSettingsDlg::FillAnchorPontManager()
{
    RecipeManager& g_recipeManager = RecipeManager::getInstance();
    auto axisDetails = g_recipeManager.getAxis(m_nAxisNO);
    int nRowIndex = 1;
    int nPositionsSize = (int)axisDetails.positions.size();
    // 清除数据行,保留表头
    for (int i = 1; i < m_grid.GetRowCount(); i++) {
        m_grid.DeleteRow(i);
    }
    // 设置表格行数
    m_grid.SetRowCount(axisDetails.positioningPointCount + 1);
    auto SetCellText = [this](int nRow, int nCol, const CString& strText, UINT nState = GVIS_READONLY) {
        m_grid.SetItemText(nRow, nCol, strText);
        m_grid.SetItemState(nRow, nCol, nState);
    };
    auto FormatFloatToString = [](double dValue) -> CString {
        CString strText;
        strText.Format(_T("%.3f"), dValue);
        return strText;
    };
    for (int nIndex = 0; nIndex < axisDetails.positioningPointCount; nIndex++) {
        m_grid.SetItemState(nIndex, 0, GVIS_READONLY); // 序号列设置只读
        SetCellText(nRowIndex, 0, CString(std::to_string(nRowIndex).c_str()));
        if (nIndex >= nPositionsSize) {
            // 添加新行的默认值
            if (m_grid.SetCellType(nRowIndex, 1, RUNTIME_CLASS(CGridCellCheck))) {
                auto* pCell = static_cast<CGridCellCheck*>(m_grid.GetCell(nRowIndex, 1));
                pCell->SetCheck(TRUE);
            }
            SetCellText(nRowIndex, 2, FormatFloatToString(0.0), GVIS_MODIFIED);
            SetCellText(nRowIndex, 3, FormatFloatToString(1.0), GVIS_MODIFIED);
            SetCellText(nRowIndex, 4, FormatFloatToString(10.0), GVIS_MODIFIED);
            SetCellText(nRowIndex, 5, CString(_T("Position ")) + CString(std::to_string(nIndex + 1).c_str()), GVIS_MODIFIED);
        }
        else {
            const auto& enPosition = axisDetails.positions[nIndex];
            if (m_grid.SetCellType(nRowIndex, 1, RUNTIME_CLASS(CGridCellCheck))) {
                auto* pCell = static_cast<CGridCellCheck*>(m_grid.GetCell(nRowIndex, 1));
                pCell->SetCheck(enPosition.isEnable);
            }
            UINT nCellState = enPosition.isEnable ? GVIS_MODIFIED : GVIS_READONLY;
            SetCellText(nRowIndex, 2, FormatFloatToString(enPosition.range.minValue), nCellState);
            SetCellText(nRowIndex, 3, FormatFloatToString(enPosition.range.currentValue), nCellState);
            SetCellText(nRowIndex, 4, FormatFloatToString(enPosition.range.maxValue), nCellState);
            SetCellText(nRowIndex, 5, CString(enPosition.description.c_str()), nCellState);
        }
        nRowIndex++;
    }
    m_grid.ExpandColumnsToFit(FALSE);
    m_grid.ExpandLastColumn();
    m_grid.Invalidate();
    m_grid.UpdateWindow();
}
void CAxisDetailSettingsDlg::UpdateAxisDetailSettings()
{
    // 获取轴数据
@@ -54,8 +176,8 @@
    m_staticAxisDescription.SetWindowText(CString(axisDetails.description.c_str()));                // 轴描述
    m_staticStartAddress.SetWindowText(CString(axisDetails.startAddress.c_str()));                    // 起始地址
    GetDlgItem(IDC_EDIT_AXIS_POSITIONING_SPEED_LIMIT)->SetWindowText(formatDouble(axisDetails.maxPositioningSpeed));    // 定位速度上限
    GetDlgItem(IDC_EDIT_AXIS_JOG_SPEED_LIMIT)->SetWindowText(formatDouble(axisDetails.maxManualSpeed));                    // 手动速度上限
    //GetDlgItem(IDC_EDIT_AXIS_POSITIONING_SPEED_LIMIT)->SetWindowText(formatDouble(axisDetails.maxPositioningSpeed));    // 定位速度上限
    //GetDlgItem(IDC_EDIT_AXIS_JOG_SPEED_LIMIT)->SetWindowText(formatDouble(axisDetails.maxManualSpeed));                    // 手动速度上限
    GetDlgItem(IDC_EDIT_AXIS_POSITIONING_POINTS)->SetWindowText(formatInt(axisDetails.positioningPointCount));            // 定位点数
    // 微动量
@@ -90,12 +212,14 @@
    DDX_Control(pDX, IDC_STATIC_AXIS_NUMBER, m_staticAxisNO);
    DDX_Control(pDX, IDC_STATIC_AXIS_DESCRIP, m_staticAxisDescription);
    DDX_Control(pDX, IDC_STATIC_START_ADDRESS, m_staticStartAddress);
    DDX_Control(pDX, IDC_CUSTOM_AXIS_ANCHOR_POINT, m_gridAxisDetailSettings);
    DDX_Control(pDX, IDC_CUSTOM_AXIS_ANCHOR_POINT, m_grid);
}
BEGIN_MESSAGE_MAP(CAxisDetailSettingsDlg, CDialogEx)
    ON_NOTIFY(NM_CLICK, IDC_CUSTOM_AXIS_ANCHOR_POINT, &CAxisDetailSettingsDlg::OnGridItemChanged)
    ON_BN_CLICKED(IDC_BUTTON_AXIS_DETAIL_SETTINGS_SAVE, &CAxisDetailSettingsDlg::OnBnClickedButtonAxisDetailSettingsSave)
    ON_BN_CLICKED(IDC_BUTTON_SET_AXIS_POSITIONING_POINTS, &CAxisDetailSettingsDlg::OnBnClickedButtonSetAxisPositioningPoints)
END_MESSAGE_MAP()
@@ -122,13 +246,174 @@
    }
    UpdateAxisDetailSettings();
    InitAnchorPontManager();
    return TRUE;  // return TRUE unless you set the focus to a control
    // 异常: OCX 属性页应返回 FALSE
}
void CAxisDetailSettingsDlg::OnGridItemChanged(NMHDR* pNotifyStruct, LRESULT* pResult)
{
    NM_GRIDVIEW* pItem = (NM_GRIDVIEW*)pNotifyStruct;
    int nRow = pItem->iRow;
    int nCol = pItem->iColumn;
    // 处理复选框状态变化
    if (nCol == 1) {
        // 获取复选框的当前状态
        CGridCellCheck* pCell = static_cast<CGridCellCheck*>(m_grid.GetCell(nRow, nCol));
        BOOL bChecked = pCell->GetCheck();
        // 处理复选框状态变化
        m_grid.SetItemState(nRow, 2, bChecked ? GVIS_MODIFIED : GVIS_READONLY);
        m_grid.SetItemState(nRow, 3, bChecked ? GVIS_MODIFIED : GVIS_READONLY);
        m_grid.SetItemState(nRow, 4, bChecked ? GVIS_MODIFIED : GVIS_READONLY);
        m_grid.SetItemState(nRow, 5, bChecked ? GVIS_MODIFIED : GVIS_READONLY);
    }
    *pResult = 0;
}
void CAxisDetailSettingsDlg::OnBnClickedButtonAxisDetailSettingsSave()
{
    // TODO: 在此添加控件通知处理程序代码
    EndDialog(IDOK);
    // 获取轴数据
    RecipeManager& recipeManager = RecipeManager::getInstance();
    auto& axisDetails = recipeManager.getAxis(m_nAxisNO);
    // 从界面控件获取用户输入的数据并更新到 axisDetails
    // 轴编号、描述和起始地址
    CString strAxisNo, strAxisDesc, strStartAddr;
    m_staticAxisNO.GetWindowText(strAxisNo);
    m_staticAxisDescription.GetWindowText(strAxisDesc);
    m_staticStartAddress.GetWindowText(strStartAddr);
    axisDetails.number = std::string(CT2A(strAxisNo));
    axisDetails.description = std::string(CT2A(strAxisDesc));
    axisDetails.startAddress = std::string(CT2A(strStartAddr));
    // 定位速度上限
    //CString strPosSpeedLimit;
    //GetDlgItem(IDC_EDIT_AXIS_POSITIONING_SPEED_LIMIT)->GetWindowText(strPosSpeedLimit);
    //axisDetails.maxPositioningSpeed = _ttof(strPosSpeedLimit);  // 转换为 double 类型
    // 手动速度上限
    //CString strJogSpeedLimit;
    //GetDlgItem(IDC_EDIT_AXIS_JOG_SPEED_LIMIT)->GetWindowText(strJogSpeedLimit);
    //axisDetails.maxManualSpeed = _ttof(strJogSpeedLimit);
    // 定位点数
    CString strPosCount;
    GetDlgItem(IDC_EDIT_AXIS_POSITIONING_POINTS)->GetWindowText(strPosCount);
    axisDetails.positioningPointCount = _ttoi(strPosCount);   // 转换为 int 类型
    // 微动量
    CString strJogDistanceMin, strJogDistanceCur, strJogDistanceMax;
    GetDlgItem(IDC_EDIT_AXIS_MODITFY_MICROMENTUM_MIN)->GetWindowText(strJogDistanceMin);
    GetDlgItem(IDC_EDIT_AXIS_MODITFY_MICROMENTUM)->GetWindowText(strJogDistanceCur);
    GetDlgItem(IDC_EDIT_AXIS_MODITFY_MICROMENTUM_MAX)->GetWindowText(strJogDistanceMax);
    axisDetails.jogDistance.minValue = _ttof(strJogDistanceMin);
    axisDetails.jogDistance.currentValue = _ttof(strJogDistanceCur);
    axisDetails.jogDistance.maxValue = _ttof(strJogDistanceMax);
    // 手动速度
    CString strManualSpeedMin, strManualSpeedCur, strManualSpeedMax;
    GetDlgItem(IDC_EDIT_AXIS_MODITFY_POS_MIN)->GetWindowText(strManualSpeedMin);
    GetDlgItem(IDC_EDIT_AXIS_MODITFY_POS)->GetWindowText(strManualSpeedCur);
    GetDlgItem(IDC_EDIT_AXIS_MODITFY_POS_MAX)->GetWindowText(strManualSpeedMax);
    axisDetails.manualSpeed.minValue = _ttof(strManualSpeedMin);
    axisDetails.manualSpeed.currentValue = _ttof(strManualSpeedCur);
    axisDetails.manualSpeed.maxValue = _ttof(strManualSpeedMax);
    // 自动速度
    CString strAutoSpeedMin, strAutoSpeedCur, strAutoSpeedMax;
    GetDlgItem(IDC_EDIT_AXIS_MODITFY_AUTO_SPEED_MIN)->GetWindowText(strAutoSpeedMin);
    GetDlgItem(IDC_EDIT_AXIS_MODITFY_AUTO_SPEED)->GetWindowText(strAutoSpeedCur);
    GetDlgItem(IDC_EDIT_AXIS_MODITFY_AUTO_SPEED_MAX)->GetWindowText(strAutoSpeedMax);
    axisDetails.autoSpeed.minValue = _ttof(strAutoSpeedMin);
    axisDetails.autoSpeed.currentValue = _ttof(strAutoSpeedCur);
    axisDetails.autoSpeed.maxValue = _ttof(strAutoSpeedMax);
    // 加速时间
    CString strAcceTimeMin, strAcceTimeCur, strAcceTimeMax;
    GetDlgItem(IDC_EDIT_AXIS_MODITFY_ACCE_TIME_MIN)->GetWindowText(strAcceTimeMin);
    GetDlgItem(IDC_EDIT_AXIS_MODITFY_ACCE_TIME)->GetWindowText(strAcceTimeCur);
    GetDlgItem(IDC_EDIT_AXIS_MODITFY_ACCE_TIME_MAX)->GetWindowText(strAcceTimeMax);
    axisDetails.accelerationTime.minValue = _ttof(strAcceTimeMin);
    axisDetails.accelerationTime.currentValue = _ttof(strAcceTimeCur);
    axisDetails.accelerationTime.maxValue = _ttof(strAcceTimeMax);
    // 减速时间
    CString strDeceTimeMin, strDeceTimeCur, strDeceTimeMax;
    GetDlgItem(IDC_EDIT_AXIS_MODITFY_DECE_TIME_MIN)->GetWindowText(strDeceTimeMin);
    GetDlgItem(IDC_EDIT_AXIS_MODITFY_DECE_TIME)->GetWindowText(strDeceTimeCur);
    GetDlgItem(IDC_EDIT_AXIS_MODITFY_DECE_TIME_MAX)->GetWindowText(strDeceTimeMax);
    axisDetails.decelerationTime.minValue = _ttof(strDeceTimeMin);
    axisDetails.decelerationTime.currentValue = _ttof(strDeceTimeCur);
    axisDetails.decelerationTime.maxValue = _ttof(strDeceTimeMax);
    // 如果 positioningPointCount 和 positions.size() 不同,则调整大小
    if (axisDetails.positioningPointCount != (int)axisDetails.positions.size()) {
        axisDetails.positions.resize(axisDetails.positioningPointCount);
    }
    // 更新表格中的定位点数据
    for (int i = 0; i < axisDetails.positioningPointCount; i++) {
        auto& enPosition = axisDetails.positions[i];
        // 使能状态
        BOOL bIsChecked = ((CGridCellCheck*)m_grid.GetCell(i + 1, 1))->GetCheck();
        enPosition.isEnable = bIsChecked;
        // 最小值、当前值和最大值
        CString strMin, strCur, strMax;
        strMin = m_grid.GetItemText(i + 1, 2);
        strCur = m_grid.GetItemText(i + 1, 3);
        strMax = m_grid.GetItemText(i + 1, 4);
        enPosition.range.minValue = _ttof(strMin);
        enPosition.range.currentValue = _ttof(strCur);
        enPosition.range.maxValue = _ttof(strMax);
        // 描述
        CString strDesc;
        strDesc = m_grid.GetItemText(i + 1, 5);
        enPosition.description = std::string(CT2A(strDesc));
    }
    // 更新 RecipeManager 中的轴数据
    recipeManager.updateAxis(axisDetails);
    // 保存轴数据到文件
    CString cstrMessage;
    if (RecipeManager::getInstance().saveRecipe(std::string(CT2A(m_strRecipeName)))) {
        cstrMessage.Format(_T("保存轴 [%d] 细部参数成功!"), m_nAxisNO);
        SystemLogManager::getInstance().log(SystemLogManager::LogType::Operation, std::string(CT2A(cstrMessage)));
    }
    else {
        cstrMessage.Format(_T("保存轴 [%d] 细部参数失败!"), m_nAxisNO);
        SystemLogManager::getInstance().log(SystemLogManager::LogType::Error, std::string(CT2A(cstrMessage)));
    }
    AfxMessageBox(cstrMessage);
}
void CAxisDetailSettingsDlg::OnBnClickedButtonSetAxisPositioningPoints()
{
    // TODO: 在此添加控件通知处理程序代码
    CString strPosCount;
    GetDlgItem(IDC_EDIT_AXIS_POSITIONING_POINTS)->GetWindowText(strPosCount);
    if (strPosCount.IsEmpty()) {
        AfxMessageBox(_T("请输入定位点数!"));
        return;
    }
    RecipeManager& recipeManager = RecipeManager::getInstance();
    AxisInfo axisDetails = recipeManager.getAxis(m_nAxisNO);
    axisDetails.positioningPointCount = _ttoi(strPosCount);
    // 更新 RecipeManager 中的轴数据
    recipeManager.updateAxis(axisDetails);
    FillAnchorPontManager();
}
SourceCode/Bond/BondEq/View/AxisDetailSettingsDlg.h
@@ -22,6 +22,8 @@
#endif
private:
    void InitAnchorPontManager();
    void FillAnchorPontManager();
    void UpdateAxisDetailSettings();
@@ -36,11 +38,13 @@
    // 控件
    CStatic m_staticAxisNO, m_staticAxisDescription, m_staticStartAddress;
    CGridCtrl m_gridAxisDetailSettings;
    CGridCtrl m_grid;
protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
    virtual BOOL OnInitDialog();
    afx_msg void OnGridItemChanged(NMHDR* pNotifyStruct, LRESULT* pResult);
    afx_msg void OnBnClickedButtonAxisDetailSettingsSave();
    afx_msg void OnBnClickedButtonSetAxisPositioningPoints();
    DECLARE_MESSAGE_MAP()
};