欧美韩国日本桃色,一区二区三区国产私人毛片,精品极品精品,亚洲一区人妻,久久久久久久久亚洲免费,青娱乐91,亚洲情涩,久久久成人毛片,日本欧美不卡二区在线

中國(guó)自動(dòng)化學(xué)會(huì)專家咨詢工作委員會(huì)指定宣傳媒體
文摘詳情
gkongbbs

C#運(yùn)動(dòng)控制開源(三): CAD導(dǎo)圖和小線段速度前瞻優(yōu)化的軟件框架

http://m.henanjusheng.com 2026-07-03 15:42 深圳市正運(yùn)動(dòng)技術(shù)有限公司

01 ZMC432-V2運(yùn)動(dòng)控制器介紹

ZMC432-V2高性能多軸運(yùn)動(dòng)控制器是一款兼容EtherCAT總線和脈沖型的獨(dú)立式運(yùn)動(dòng)控制器,自帶6軸本地差分脈沖軸,最多可擴(kuò)展至32軸,能實(shí)現(xiàn)總線軸+脈沖軸混合插補(bǔ)的多軸運(yùn)動(dòng)控制場(chǎng)合。同時(shí)支持正運(yùn)動(dòng)遠(yuǎn)程顯示功能,能提供網(wǎng)絡(luò)組態(tài)顯示,可實(shí)時(shí)監(jiān)控和調(diào)整參數(shù)配置。

正運(yùn)動(dòng)ZMC432-V2高性能多軸運(yùn)動(dòng)控制器.png

ZMC432-V2硬件功能特性:

(1)支持32軸運(yùn)動(dòng)控制(脈沖+EtherCAT總線),EtherCAT最小通訊周期可達(dá)125us。

(2)24路通用輸入、12路通用輸出,2路模擬量輸出(DA),其中包括2路高速輸入和2路高速輸出。

(3)6路差分脈沖軸輸出,總線軸、脈沖軸可混合插補(bǔ)。

(4)內(nèi)置多項(xiàng)實(shí)時(shí)性運(yùn)動(dòng)控制功能,例如視覺飛拍、多維PSO、高速位置鎖存,多軸同步運(yùn)行等。

(5)可通過EtherCAT擴(kuò)展模塊進(jìn)行IO硬件資源擴(kuò)展,可擴(kuò)展至4096個(gè)隔離輸入口和4096個(gè)隔離輸出口。

(6)具備豐富的運(yùn)動(dòng)控制功能,如點(diǎn)位運(yùn)動(dòng)、電子凸輪、直線插補(bǔ)、圓弧插補(bǔ)、連續(xù)軌跡加工。

(7)支持掉電檢測(cè)、掉電存儲(chǔ),多種程序加密方式,能夠有效防止系統(tǒng)故障,保護(hù)項(xiàng)目工程文件數(shù)據(jù),并提高系統(tǒng)的可靠性。

(8)通過純國(guó)產(chǎn)IDE開發(fā)環(huán)境RTSys進(jìn)行項(xiàng)目開發(fā),可實(shí)時(shí)仿真、在線跟蹤以及診斷與調(diào)試,簡(jiǎn)便易用,支持多種高級(jí)上位機(jī)語(yǔ)言聯(lián)合編程進(jìn)行二次開發(fā)。

正運(yùn)動(dòng)ZMC432-V2高性能多軸運(yùn)動(dòng)控制器架構(gòu)圖.webp

02 內(nèi)容回顧

回顧上兩期推文,我們對(duì)CAD導(dǎo)圖和小線段速度前瞻的C#DEMO中的主要兩個(gè)功能:CAD導(dǎo)圖和運(yùn)動(dòng)前瞻設(shè)置做了詳細(xì)的介紹。這次我們回歸推文本身,對(duì)DEMO軟件框架進(jìn)行介紹。

往期內(nèi)容詳情點(diǎn)擊下方鏈接:

C#運(yùn)動(dòng)控制開源(一):CAD導(dǎo)圖和小線段速度前瞻的優(yōu)化之CAD導(dǎo)圖

C#運(yùn)動(dòng)控制開源(二): CAD導(dǎo)圖和小線段速度前瞻優(yōu)化

03 開發(fā)環(huán)境

?適用場(chǎng)景:需要CAD導(dǎo)圖給XY機(jī)臺(tái)做軌跡運(yùn)動(dòng)的場(chǎng)合都可以使用本DEMO測(cè)試。

?軟件平臺(tái):使用Visual Studio C#(即Visual C#)開發(fā)。‌

04 DEMO界面和操作步驟介紹

一、軟件框架流程圖

軟件框架流程圖.webp

二、主界面

打開軟件后首先顯示的是主界面,主要分為3個(gè)部分:

①工具欄提供控制器連接復(fù)位,CAD圖紙導(dǎo)入及編輯,參數(shù)界面跳轉(zhuǎn)等按鈕。

②中間部分用于顯示導(dǎo)入CAD文件后軌跡的顯示。

③右側(cè)操作界面則是用來操作各軸移動(dòng)以及啟動(dòng)加工,切換到BASIC或者G代碼標(biāo)簽則會(huì)顯示軌跡對(duì)應(yīng)的相關(guān)代碼。

1.webp

2.webp

三、工具欄

①連接控制器:點(diǎn)擊控制器→連接控制器彈出控制器連接界面,手動(dòng)輸入控制器IP或者下拉框搜索,點(diǎn)擊連接即可連接對(duì)應(yīng)IP控制器,連接成功軟件標(biāo)題會(huì)顯示連接成功。

3.webp

4.webp

②導(dǎo)入CAD圖紙:點(diǎn)擊文件→打開彈出文件選擇界面,選擇對(duì)應(yīng)格式的CAD文件,成功導(dǎo)入后會(huì)將軌跡顯示出來。

5.webp

6.webp

7.webp

③軌跡操作和優(yōu)化:CAD圖紙軌跡顯示后,可以進(jìn)行一些編輯操作。通過左鍵選取操作對(duì)應(yīng)的軌跡,右鍵進(jìn)行畫面移動(dòng)。對(duì)應(yīng)編輯視圖中進(jìn)行軌跡優(yōu)化以及排序。對(duì)應(yīng)視圖中進(jìn)行顯示元素的選擇。

8.webp

9.webp

10.webp

四、參數(shù)設(shè)置

①打開參數(shù)界面:點(diǎn)擊視圖→參數(shù)設(shè)置可以打開參數(shù)設(shè)置界面。

11.webp

12.webp

②設(shè)置軸參數(shù)和測(cè)試:可以在此頁(yè)面設(shè)置XYZU軸各軸參數(shù),以及進(jìn)行簡(jiǎn)單的手動(dòng)運(yùn)動(dòng)測(cè)試,確保軸運(yùn)動(dòng)沒有問題。

③前瞻參數(shù)設(shè)置:點(diǎn)擊前瞻參數(shù)標(biāo)簽頁(yè),可以進(jìn)行前瞻參數(shù)的設(shè)置。

13.webp

④加工參數(shù)設(shè)置:點(diǎn)擊加工參數(shù)標(biāo)簽頁(yè),可以進(jìn)行加工參數(shù)的設(shè)置。

14.webp

⑤保存參數(shù)設(shè)置:點(diǎn)擊參數(shù)保存按鈕,會(huì)將所有的設(shè)置保存到對(duì)應(yīng)exe所在目錄的para文件夾下,下次打開軟件會(huì)自動(dòng)讀取參數(shù)并設(shè)置上去。

15.webp

五、加工操作面板

①開啟加工:設(shè)置完參數(shù)后,可以在操作面板點(diǎn)擊啟動(dòng)開始加工,同時(shí)記錄加工時(shí)間和目前狀態(tài)。對(duì)應(yīng)各軸坐標(biāo)和速度也會(huì)顯示出來,軌跡顯示視圖中也會(huì)把當(dāng)前末端加工位置顯示出來,方便觀察目前位置。如果加工中需要暫停和停止,點(diǎn)擊對(duì)應(yīng)按鈕即可。

16.webp

②顯示生成代碼:點(diǎn)擊BASIC或者G代碼標(biāo)簽可以顯示當(dāng)前軌跡對(duì)應(yīng)的運(yùn)行代碼,可以用來排查問題,或者復(fù)制到其它軟件中直接運(yùn)行。

17.webp

18.webp

05

DEMO程序介紹

DEMO中把主要用到的重要程序分別放在了:

ZCadFn.cs,ZGCode.cs,ZmotionCard.cs

依次對(duì)應(yīng)CAD導(dǎo)圖,軌跡解析,運(yùn)動(dòng)控制三部分,方便大家使用學(xué)習(xí)。

ZCadFn.cs(CAD導(dǎo)圖解析與繪制)

19.webp

該部分主要提供CAD導(dǎo)圖初始化與導(dǎo)入CAD圖紙獲取軌跡數(shù)據(jù),然后進(jìn)行圖形繪制的函數(shù)。

form1.cs中按照:初始化CAD→導(dǎo)入CAD文件→獲得軌跡數(shù)組→繪制軌跡的順序進(jìn)行調(diào)用。比如下方程序:

//導(dǎo)入CAD文件
if (!m_GloFn.m_ZCad.ZcadReadFile(strFilePath))
{
    MessageBox.Show("導(dǎo)入文件失敗");
    return;
}
//計(jì)算比例
if (!m_GloFn.m_ZCad.ZcadPicBoxMath(CadShow.Width, CadShow.Height))
{
    MessageBox.Show("導(dǎo)入文件失敗");
    return;
}
//獲取軌跡數(shù)組
if (!m_GloFn.m_ZCad.ZcadArrayGet())
{
    MessageBox.Show("獲取軌跡失敗");
    return;
}
//繪制一遍CAD
if (!m_GloFn.m_ZCad.ZcadShowPic(CadShow.Width, CadShow.Height, 坐標(biāo)系ToolStripMenuItem.Checked, 順序ToolStripMenuItem.Checked, 空移ToolStripMenuItem.Checked, 起點(diǎn)ToolStripMenuItem.Checked, 方向ToolStripMenuItem.Checked,XCurDpos,YCurDpos, UCurDpos))
{
    MessageBox.Show("繪制失敗");
    return;
}

ZGCode.cs.cs(數(shù)據(jù)轉(zhuǎn)化為G代碼或者BASIC代碼)

該部分主要提供將軌跡數(shù)據(jù)轉(zhuǎn)化成G代碼或者BASIC代碼格式的函數(shù)。

20.webp

主界面上的代碼顯示就是通過該部分轉(zhuǎn)話后顯示到textbox控件中。

if (m_GloFn.m_ZmotionCard.m_bInited && m_GloFn.m_ZCad.m_bInited)
{
    string basicCode = "";
    string gcode = "";
    ZGCode.CadArraytoCode(m_GloFn.m_ZCad.m_ZCad_ArrayInfo, ref basicCode, ref gcode, 僅處理選中圖形toolStripMenuItem.Checked,true, CadShow.Width, CadShow.Height);
    txt_Basic.Text = basicCode;
    txt_GCode.Text = gcode;
}

ZmotionCard.cs(運(yùn)動(dòng)控制測(cè)試和前瞻下發(fā))

該部分主要提供一些封裝好的軸運(yùn)動(dòng)控制函數(shù),以及以三次文件形式或者批量函數(shù)形式下發(fā)軌跡。

21.webp

單軸控制界面時(shí)就是通過按鈕調(diào)用對(duì)應(yīng)的軸控制函數(shù)來實(shí)現(xiàn)JOG,定位,回原等測(cè)試功能。

22.webp

按鈕調(diào)用代碼如下:

?回原:

private void btn_X_SingleHome_Click(object sender, EventArgs e)
{
    SetAxisParaByCtr(); //先控件參數(shù)設(shè)置到實(shí)際軸參數(shù)
    m_GloFn.m_ZmotionCard.AxisParaSet();    //讀取參數(shù)出來之后設(shè)置一遍到軸參數(shù)上
    int axisnum = m_GloFn.m_ZmotionCard.m_nAxis_X;
    int datumtype = m_GloFn.m_ZmotionCard.m_nAxis_X_DatumType;
    float homespeed = (float)m_GloFn.m_ZmotionCard.m_dAxis_X_DatumSpeed;
    float creep = (float)m_GloFn.m_ZmotionCard.m_dAxis_X_Creep;
    bool ifbushome = m_GloFn.m_ZmotionCard.m_bAxis_X_BusDatum;
    float homeoffset = (float)m_GloFn.m_ZmotionCard.m_dAxis_X_DatumOffset;
    m_GloFn.m_ZmotionCard.AxisHome(axisnum,datumtype,homespeed,creep,ifbushome,homeoffset);
}

?定位:

private void btn_X_Move_Click(object sender, EventArgs e)
{
    SetAxisParaByCtr(); //先控件參數(shù)設(shè)置到實(shí)際軸參數(shù)
    m_GloFn.m_ZmotionCard.AxisParaSet();    //讀取參數(shù)出來之后設(shè)置一遍到軸參數(shù)上
    int axisnum = m_GloFn.m_ZmotionCard.m_nAxis_X;
    float movesp = 0;
    if (radio_X_LowSp.Checked) movesp = (float)m_GloFn.m_ZmotionCard.m_dAxis_X_LowSpeed;
    if (radio_X_NomalSp.Checked) movesp = (float)m_GloFn.m_ZmotionCard.m_dAxis_X_NormalSpeed;
    if (radio_X_HighSp.Checked) movesp = (float)m_GloFn.m_ZmotionCard.m_dAxis_X_HighSpeed;
    float movedis = Convert.ToSingle(tb_X_MoveDis.Text);
    bool ifabsmove = cb_X_IfAbs.Checked;
    if(ifabsmove) m_GloFn.m_ZmotionCard.AxisMoveAbs(axisnum,movesp,movedis);
    else m_GloFn.m_ZmotionCard.AxisMove(axisnum, movesp, movedis);
}

?點(diǎn)動(dòng):

private void btn_X_RVmove_MouseDown(object sender, MouseEventArgs e)
{
    SetAxisParaByCtr(); //先控件參數(shù)設(shè)置到實(shí)際軸參數(shù)
    m_GloFn.m_ZmotionCard.AxisParaSet();    //讀取參數(shù)出來之后設(shè)置一遍到軸參數(shù)上
    int axisnum = m_GloFn.m_ZmotionCard.m_nAxis_X;    float movesp = 0;
    if (radio_X_LowSp.Checked) movesp = (float)m_GloFn.m_ZmotionCard.m_dAxis_X_LowSpeed;
    if (radio_X_NomalSp.Checked) movesp = (float)m_GloFn.m_ZmotionCard.m_dAxis_X_NormalSpeed;
    if (radio_X_HighSp.Checked) movesp = (float)m_GloFn.m_ZmotionCard.m_dAxis_X_HighSpeed;
    m_GloFn.m_ZmotionCard.AxisVmove(axisnum, false, movesp);
}
private void btn_X_RVmove_MouseUp(object sender, MouseEventArgs e)
{
    int axisnum = m_GloFn.m_ZmotionCard.m_nAxis_X;
    m_GloFn.m_ZmotionCard.AxisCancel(axisnum);
}

前瞻功能則是調(diào)用控制器前瞻初始化函數(shù)設(shè)置參數(shù)到控制器中,或者使用平滑函數(shù)前瞻將軌跡數(shù)據(jù)處理成平滑好的數(shù)據(jù)。

?控制器前瞻設(shè)置:

#region
控制器前瞻參數(shù)初始化
public bool RunParaIni()
{
    //判斷控制卡是否初始化成功
    if (!m_bInited)
        return false;  //-1代表初始化未成功
    int iret = 0;
    //控制器前瞻參數(shù)設(shè)置到主軸上
    iret += zmcaux.ZAux_Direct_SetCornerMode(g_handle, m_nAxis_X, m_nCornerMode); CommandHandler("ZAux_Direct_SetCornerMode", iret);   //Corner_Mode
    iret += zmcaux.ZAux_Direct_SetMerge(g_handle, m_nAxis_X, 1); CommandHandler("ZAux_Direct_SetMerge", iret);       //打開連續(xù)插補(bǔ)
    iret += zmcaux.ZAux_Direct_SetFullSpRadius(g_handle, m_nAxis_X, m_fLimitR); CommandHandler("ZAux_Direct_SetFullSpRadius", iret);    //設(shè)置小圓限速半徑
    StringBuilder cmdbuffack = new StringBuilder(2048);
    iret += zmcaux.ZAux_Execute(g_handle, "SPLIMIT_RADIUS(" + m_nAxis_X.ToString() + ") = " + m_fLimitRMinSp.ToString(), cmdbuffack, 2048);  CommandHandler("ZAux_Execute", iret);//小圓限速最小限速
    iret += zmcaux.ZAux_Direct_SetZsmooth(g_handle, m_nAxis_X, m_fZsmooth); CommandHandler("ZAux_Direct_SetZsmooth", iret); //倒角半徑
    iret += zmcaux.ZAux_Direct_SetDecelAngle(g_handle, m_nAxis_X, (float)((m_fDecelAngle / 180) * Math.PI)); CommandHandler("ZAux_Direct_SetDecelAngle", iret);      //減速角
    iret += zmcaux.ZAux_Direct_SetStopAngle(g_handle, m_nAxis_X, (float)((m_fStopAngle / 180) * Math.PI)); CommandHandler("ZAux_Direct_SetStopAngle", iret);    //停止角
    iret += zmcaux.ZAux_Direct_SetStartMoveSpeed(g_handle, m_nAxis_X, m_fXYSpeed); CommandHandler("ZAux_Direct_SetStartMoveSpeed", iret);     //起始速度設(shè)置成加工速度
    iret += zmcaux.ZAux_Direct_SetEndMoveSpeed(g_handle, m_nAxis_X, m_fXYSpeed); CommandHandler("ZAux_Direct_SetEndMoveSpeed", iret);    //結(jié)束速度設(shè)置成加工速度
    if (iret != 0) return false;
    return true;
}
#endregion

?平滑前瞻函數(shù)處理:

#region
ZTrackSmooth函數(shù)平滑下發(fā)
public int SmoothByZTrackDown(double[] originalPos,ref float StartRDpos)
 //public int SmoothByZTrackDown(ref float StartRDpos)
{
    //判斷控制卡是否初始化成功
    if (!m_bInited)
        return -1;  //-1代表初始化未成功
    int iret = 0;
    UInt32 pSmoothPointsNum = 0;
    IntPtr pSmoothPoints = (IntPtr)0;
    IntPtr parryLine = (IntPtr)0;
    IntPtr parryForceSp = (IntPtr)0;
    IntPtr parryLmtSp = (IntPtr)0;
    IntPtr parryR = (IntPtr)0;
    ZTrackSmooth.ZTS_Delete(pSmoothPoints);
    ZTrackSmooth.ZTS_Delete(parryLine);
    ZTrackSmooth.ZTS_Delete(parryForceSp);
    ZTrackSmooth.ZTS_Delete(parryLmtSp);
    ZTrackSmooth.ZTS_Delete(parryR);
    //提出平滑后的軌跡
    double[] SmoothPos = { };
    double[] SmoothSpeed = { };
    double[] SmoothLimSp = { };
    double[] SmoothR = { };
    if (m_dDiserr 0)      //有設(shè)置非線性小圓限速
            iret = ZTrackSmooth.ZTS_ContinueSmoothAndSpeed2(g_handle, originalPos, Convert.ToUInt16(originalPos.Length / 2), 2, m_dDiserr, m_dSplineDis, m_dCornerAccel, m_fXYSpeed, m_dLimitRArray, m_dLimitRSpArray, (uint)m_dLimitRArray.Length, out pSmoothPoints, out parryLine, out parryForceSp, out parryLmtSp, out parryR, ref pSmoothPointsNum);
        else
            iret = ZTrackSmooth.ZTS_ContinueSmoothAndSpeed2(g_handle, originalPos, Convert.ToUInt16(originalPos.Length / 2), 2, m_dDiserr, m_dSplineDis, m_dCornerAccel, m_fXYSpeed, new double[] { 0.1, m_fLimitR }, new double[] { m_fXYSpeed, m_fXYSpeed }, 2, out pSmoothPoints, out parryLine, out parryForceSp, out parryLmtSp, out parryR, ref pSmoothPointsNum);
        //提出平滑后的軌跡
        SmoothPos = new double[pSmoothPointsNum * 2];
        SmoothSpeed = new double[pSmoothPointsNum];
        SmoothLimSp = new double[pSmoothPointsNum];
        SmoothR = new double[pSmoothPointsNum];
        Marshal.Copy(pSmoothPoints, SmoothPos, 0, (int)(pSmoothPointsNum * 2));
        Marshal.Copy(parryForceSp, SmoothSpeed, 0, (int)(pSmoothPointsNum));
        Marshal.Copy(parryLmtSp, SmoothLimSp, 0, (int)(pSmoothPointsNum));
        Marshal.Copy(parryR, SmoothR, 0, (int)(pSmoothPointsNum));
    }
    StringBuilder cmdbuffack = new StringBuilder(2048);
    double rdpos = StartRDpos;
    //下發(fā)平滑軌跡
    for (uint i = 0; i < pSmoothPointsNum; i++)
    {
        float[] targetpos = new float[2];
        targetpos[0] = (float)SmoothPos[i * 2 + 0];
        targetpos[1] = (float)SmoothPos[i * 2 + 1];
        float runspeed = m_fXYSpeed;
        float limitspeed = m_fXYSpeed;
        if (m_dDiserr >= 0)
        {
            runspeed = (float)SmoothSpeed[i];
            limitspeed = (float)SmoothLimSp[i];
        }
        //計(jì)算該點(diǎn)需要轉(zhuǎn)的角度值
        if (i < pSmoothPointsNum - 2 && i >= 0)
        {
            double moveangle = CalculateAngleWithX((float)SmoothPos[(i) * 2 + 0], (float)SmoothPos[(i) * 2 + 1], (float)SmoothPos[(i + 1) * 2 + 0], (float)SmoothPos[(i + 1) * 2 + 1]);
            rdpos = MoveR(moveangle, StartRDpos);
        }
        StartRDpos = (float)rdpos;
        if (m_b3FileDown) Z3pFile_LineString(targetpos[0], targetpos[1], rdpos, runspeed, limitspeed, i);
        else Command_LineString(targetpos[0], targetpos[1], rdpos, runspeed, limitspeed, i);
    } 
   ZTrackSmooth.ZTS_Delete(pSmoothPoints);
    ZTrackSmooth.ZTS_Delete(parryLine); 
   ZTrackSmooth.ZTS_Delete(parryForceSp);
    ZTrackSmooth.ZTS_Delete(parryLmtSp);
    ZTrackSmooth.ZTS_Delete(parryR);
    return iret;
}
#endregion

前瞻處理好后按照一定格式用三次文件或者批量函數(shù)下發(fā)到控制器中運(yùn)行,流程可以直接參考自動(dòng)線程的程序處理。

#region線程
public void Thread_Run()
{
    WorkStart = DateTime.Now;
    RunStatus = "自動(dòng)運(yùn)行中";
    m_GloFn.m_ZmotionCard.AxisParaSet();
    //讀取參數(shù)出來之后設(shè)置一遍到軸參數(shù)上
    if (!m_GloFn.m_ZmotionCard.RunParaIni())
    {
        MessageBox.Show("前瞻參數(shù)設(shè)置失敗");
        return;
    }
    //獲取軌跡數(shù)組
    if (!m_GloFn.m_ZCad.ZcadArrayGet())
    {
        MessageBox.Show("獲取軌跡失敗");
        return;
    }
    //如果皮帶跟隨
    if (m_GloFn.m_ZmotionCard.m_bSync)
     //開啟皮帶跟隨
    {
        if (m_GloFn.m_ZmotionCard.AxisBeltSync() != 0)
        {
            MessageBox.Show("皮帶跟隨失敗");
            return; 
       }
    }
    //取消U軸插補(bǔ)速度計(jì)算
    int iret = 0;
    iret = zmcaux.ZAux_Direct_SetInterpFactor(m_GloFn.m_ZmotionCard.g_handle, m_GloFn.m_ZmotionCard.m_nAxis_VU, 0); m_GloFn.m_ZmotionCard.CommandHandler("ZAux_Direct_SetInterpFactor", iret);
    //記錄U軸坐標(biāo)    float RDpos = 0;
    iret = zmcaux.ZAux_Direct_GetDpos(m_GloFn.m_ZmotionCard.g_handle, m_GloFn.m_ZmotionCard.m_nAxis_U,ref RDpos); m_GloFn.m_ZmotionCard.CommandHandler("ZAux_Direct_GetDpos", iret);
    //解析軌跡下發(fā)
    if (m_GloFn.m_ZmotionCard.m_b3FileDown) m_GloFn.m_ZmotionCard.Z3pFile_Init(); //三次文件初始化
    else m_GloFn.m_ZmotionCard.CommandIni();
    List OriginalPos = new List();    double Pos_x1, Pos_x2, Pos_z1, Pos_y1, Pos_y2, Pos_z2;
    double Pos_x1_2, Pos_x2_2, Pos_z1_2, Pos_y1_2, Pos_y2_2, Pos_z2_2;
    bool ifsplit = false;
    bool ifdownZ = false;
    for (int i = 0; i < m_GloFn.m_ZCad.m_nZCad_ArrayLen; i++)                //遍歷數(shù)組
    {
        Pos_x1 = m_GloFn.m_ZCad.m_ZCad_ArrayInfo[i].x1;
        Pos_x2 = m_GloFn.m_ZCad.m_ZCad_ArrayInfo[i].x2;
        Pos_z1 = m_GloFn.m_ZCad.m_ZCad_ArrayInfo[i].z1;
        Pos_y1 = m_GloFn.m_ZCad.m_ZCad_ArrayInfo[i].y1;
        Pos_y2 = m_GloFn.m_ZCad.m_ZCad_ArrayInfo[i].y2;
        Pos_z2 = m_GloFn.m_ZCad.m_ZCad_ArrayInfo[i].z2;
        ifsplit = false;
        if ((僅處理選中圖形toolStripMenuItem.Checked == true) && (m_GloFn.m_ZCad.m_ZCad_ArrayInfo[i].m_nChoose == 0)) continue;
        switch (m_GloFn.m_ZCad.m_ZCad_ArrayInfo[i].m_nItemtype)
        {
            case ZmotionCad.ZCAD_ITEMTYPE_VECTLine:    //線型
                if ((m_GloFn.m_ZCad.m_ZCad_ArrayInfo[i].m_nInVectFrist == 1) || (ifdownZ))              //是否軌跡起點(diǎn)起始
                {
                    ifdownZ = false;
                    double StartAngle = m_GloFn.m_ZmotionCard.CalculateAngleWithX(Pos_x1, Pos_y1, Pos_x2, Pos_y2);
                    //下發(fā)空移落刀指令
                    if (m_GloFn.m_ZmotionCard.m_b3FileDown) m_GloFn.m_ZmotionCard.Z3pFile_StartString(Pos_x1, Pos_y1, StartAngle, ref RDpos);
                    else m_GloFn.m_ZmotionCard.Command_StartString(Pos_x1, Pos_y1, StartAngle, ref RDpos);
                    OriginalPos.Clear();
                    //把起點(diǎn)存下來
                    OriginalPos.Add(Pos_x1);
                    OriginalPos.Add(Pos_y1);
                }
                OriginalPos.Add(Pos_x2); //記錄過程點(diǎn)
                OriginalPos.Add(Pos_y2);
                if (i + 1 < m_GloFn.m_ZCad.m_nZCad_ArrayLen)
                {
                    Pos_x1_2 = m_GloFn.m_ZCad.m_ZCad_ArrayInfo[i + 1].x1;
                    Pos_x2_2 = m_GloFn.m_ZCad.m_ZCad_ArrayInfo[i + 1].x2;
                    Pos_z1_2 = m_GloFn.m_ZCad.m_ZCad_ArrayInfo[i + 1].z1;
                    Pos_y1_2 = m_GloFn.m_ZCad.m_ZCad_ArrayInfo[i + 1].y1;
                    Pos_y2_2 = m_GloFn.m_ZCad.m_ZCad_ArrayInfo[i + 1].y2;
                    Pos_z2_2 = m_GloFn.m_ZCad.m_ZCad_ArrayInfo[i + 1].z2;
                    //大于停止角就抬刀
                    if (Math.Abs(m_GloFn.m_ZmotionCard.CalculateAngle(Pos_x1, Pos_y1, Pos_x2, Pos_y2, Pos_x1_2, Pos_y1_2, Pos_x2_2, Pos_y2_2)) > m_GloFn.m_ZmotionCard.m_fStopAngle) ifsplit = true;
                    //判斷下個(gè)點(diǎn)是否空移點(diǎn)
                    if ((m_GloFn.m_ZCad.m_ZCad_ArrayInfo[i + 1].m_nInVectFrist == 1) || (ifsplit))             //下條運(yùn)動(dòng)為空移點(diǎn),需要抬刀
                    {
                        if (ifsplit == false)
                        {
                            OriginalPos.Add(Pos_x2); //記錄過程點(diǎn)
                            OriginalPos.Add(Pos_y2);
                        }
                        //下發(fā)加工軌跡
                        m_GloFn.m_ZmotionCard.SmoothByZTrackDown(OriginalPos.ToArray(), ref RDpos);
                        //m_GloFn.m_ZmotionCard.SmoothByZTrackDown( ref RDpos);
                        //下發(fā)抬刀動(dòng)作
                        if (m_GloFn.m_ZmotionCard.m_b3FileDown) m_GloFn.m_ZmotionCard.Z3pFile_EndString(Pos_x2, Pos_y2);
                        else m_GloFn.m_ZmotionCard.Command_EndString(Pos_x2, Pos_y2);
                        if (ifsplit)
                        {
                            ifdownZ = true;
                            ifsplit = false;
                        }
                    }
                }
                if (i == m_GloFn.m_ZCad.m_nZCad_ArrayLen - 1)
                {
                    //下發(fā)加工軌跡
                    m_GloFn.m_ZmotionCard.SmoothByZTrackDown(OriginalPos.ToArray(), ref RDpos);
                    //m_GloFn.m_ZmotionCard.SmoothByZTrackDown(ref RDpos); 
                   //下發(fā)抬刀動(dòng)作
                    if (m_GloFn.m_ZmotionCard.m_b3FileDown) m_GloFn.m_ZmotionCard.Z3pFile_EndString(Pos_x2, Pos_y2);
                    else m_GloFn.m_ZmotionCard.Command_EndString(Pos_x2, Pos_y2);
                    if (ifsplit)
                    {
                        ifdownZ = true;
                        ifsplit = false;
                    }
                }
                break;
            default:
                break;
        }
    }
    if (m_GloFn.m_ZmotionCard.m_b3FileDown) m_GloFn.m_ZmotionCard.Z3pFile_End(); //三次文件結(jié)束
    //等待3次文件結(jié)束
    while (true)
    {
        int runstatus = 0;
        StringBuilder cmdbuffack = new StringBuilder(2048);
        iret = zmcaux.ZAux_DirectCommand(m_GloFn.m_ZmotionCard.g_handle,$"?PROC_STATUS({m_GloFn.m_ZmotionCard.Z3P_FILE_TASK})", cmdbuffack,2048); m_GloFn.m_ZmotionCard.CommandHandler("ZAux_DirectCommand", iret);
        runstatus = Convert.ToInt16(cmdbuffack.ToString());
        if (runstatus == 0) break;
    }
    //等待運(yùn)動(dòng)結(jié)束
    while (true)
    {
        int idle = 0;
        iret = zmcaux.ZAux_Direct_GetIfIdle(m_GloFn.m_ZmotionCard.g_handle, m_GloFn.m_ZmotionCard.m_nAxis_X, ref idle); m_GloFn.m_ZmotionCard.CommandHandler("ZAux_Direct_GetIfIdle", iret);
        if (idle != 0) break;
    }
    //如果皮帶跟隨
    if (m_GloFn.m_ZmotionCard.m_bSync)   //取消皮帶跟隨綁定
    {
        m_GloFn.m_ZmotionCard.beltsyncend();
    }
    //恢復(fù)U軸插補(bǔ)速度計(jì)算
    iret = zmcaux.ZAux_Direct_SetInterpFactor(m_GloFn.m_ZmotionCard.g_handle, m_GloFn.m_ZmotionCard.m_nAxis_VU, 1); m_GloFn.m_ZmotionCard.CommandHandler("ZAux_Direct_SetInterpFactor", iret);
    RunStatus = "待機(jī)";
}

教學(xué)視頻請(qǐng)點(diǎn)擊→C#運(yùn)動(dòng)控制開源(三): CAD導(dǎo)圖和小線段速度前瞻優(yōu)化的軟件框架

完整代碼獲取地址

正運(yùn)動(dòng)技術(shù)C#運(yùn)動(dòng)控制開源(三)例程二維碼.jpg

本次,正運(yùn)動(dòng)技術(shù)C#運(yùn)動(dòng)控制開源(三): CAD導(dǎo)圖和小線段速度前瞻優(yōu)化的軟件框架,就分享到這里。

更多精彩內(nèi)容請(qǐng)關(guān)注“正運(yùn)動(dòng)小助手”公眾號(hào),需要相關(guān)開發(fā)環(huán)境與例程代碼,請(qǐng)咨詢正運(yùn)動(dòng)技術(shù)銷售工程師:400-089-8936。

二維碼.webp

正運(yùn)動(dòng)技術(shù)專注于運(yùn)動(dòng)控制技術(shù)研究和通用運(yùn)動(dòng)控制軟硬件產(chǎn)品的研發(fā),是國(guó)家級(jí)高新技術(shù)企業(yè)。正運(yùn)動(dòng)技術(shù)匯集了來自華為、中興等公司的優(yōu)秀人才,在堅(jiān)持自主創(chuàng)新的同時(shí),積極聯(lián)合各大高校協(xié)同運(yùn)動(dòng)控制基礎(chǔ)技術(shù)的研究。主要業(yè)務(wù)有:運(yùn)動(dòng)控制卡_運(yùn)動(dòng)控制器_EtherCAT運(yùn)動(dòng)控制卡_EtherCAT控制器_運(yùn)動(dòng)控制系統(tǒng)_視覺控制器__運(yùn)動(dòng)控制PLC_運(yùn)動(dòng)控制_機(jī)器人控制器_視覺定位_XPCIe/XPCI系列運(yùn)動(dòng)控制卡等等。

版權(quán)所有 工控網(wǎng) Copyright?2026 Gkong.com, All Rights Reserved
缙云县| 阿巴嘎旗| 河北省| 临安市| 荣昌县| 如东县| 广丰县| 通道| 吴川市| 日喀则市| 天等县| 固始县| 霸州市| 怀集县| 西丰县| 聊城市| 全州县| 子洲县| 永寿县| 西丰县| 民权县| 沙河市| 洪湖市| 汝南县| 绥宁县| 凤台县| 黄冈市| 英吉沙县| 苏尼特右旗| 尼玛县| 蕉岭县| 霸州市| 双流县| 突泉县| 井研县| 浦东新区| 承德县| 乌拉特后旗| 永兴县| 岫岩| 东安县|