本節(jié)主要講解如何通過Python編程調(diào)試ZMC432CL-V2的脈沖閉環(huán)功能。
ZMC432CL-V2高性能多軸運(yùn)動(dòng)控制器是一款兼容EtherCAT總線和脈沖型的獨(dú)立式運(yùn)動(dòng)控制器,具備高速實(shí)時(shí)反饋功能,支持脈沖全閉環(huán)控制,能夠?qū)崿F(xiàn)高精度、高響應(yīng)速度的運(yùn)動(dòng)控制。高精度定位,有效消除機(jī)械傳動(dòng)誤差,滿足高精密加工場(chǎng)景應(yīng)用要求。

ZMC432CL-V2硬件功能特性:
1.豐富的運(yùn)動(dòng)控制功能:支持直線、圓弧、空間圓弧、螺旋插補(bǔ)等。
2.硬件接口豐富:支持脈沖軸(帶編碼器反饋)和EtherCAT總線軸,具備24路輸入和12路輸出的通用IO,部分為高速IO,2路模擬量輸出(DA)。
3.EtherCAT刷新周期最快達(dá)250us,滿足高速通信需求。
4.支持4通道硬件比較輸出、硬件定時(shí)器、運(yùn)動(dòng)中精準(zhǔn)輸出,適用于多通道視覺飛拍等場(chǎng)合。
5.支持掉電檢測(cè)、掉電存儲(chǔ),多種程序加密方式,能夠有效防止系統(tǒng)故障,保護(hù)項(xiàng)目工程文件數(shù)據(jù),并提高系統(tǒng)的可靠性。
6.通過純國(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ā)。

更多關(guān)于ZMC432CL-V2詳情介紹點(diǎn)擊→步進(jìn)控制的光柵尺全閉環(huán)解決方案:32軸EtherCAT總線運(yùn)動(dòng)控制器ZMC432CL-V2。
Python語(yǔ)言如何調(diào)用ZMotion的動(dòng)態(tài)庫(kù)進(jìn)行項(xiàng)目開發(fā)
此案例Python開發(fā)環(huán)境
操作系統(tǒng)環(huán)境 :Win11_64位
Python版本:python-3.10.10-amd64.exe
Pycharm版本:pycharm-community-2024.1.3.exe
一.python開發(fā)前對(duì)環(huán)境、解析器進(jìn)行配置。
1.安裝漢化包:點(diǎn)擊file→setting→plugins,然后搜索Chinese中文包。

2.python解析器安裝Pyside2軟件包(QT庫(kù)):File→Settings→Project pythonProject。

3.配置自定義控件:File→Settings→Tools→External Tools點(diǎn)擊+新增自定義工具。

自定義QtDesigner
目的:用于生成.ui文件
Name:QtDesigner
Group:Qt
Program:PySide2安裝路徑下的 designer.exe 路徑
例如:C:\Python\Python39\Scripts\pyside2-designer.exe
Working directory:$ProjectFileDir$
自定義Pyside2-uic
目的:將制作好的.ui文件轉(zhuǎn)化為.py文件
Name:Pyside2-uic
Group:Qt
Program:Python安裝目錄下Scripts\pyside2-uic.exe
例如:C:\Python\Python39\Scripts\pyside2-uic.exe
Arguments:$FileName$ -o $FileNameWithoutExtension$.py
Working directory:$FileDir$
自定義Pyside2-rcc
目的:將圖片文件轉(zhuǎn)化為.py文件
Name:Pyside2-rcc
Group:Qt
Program:Python安裝目錄下Scripts\pyside2-rcc.exe
例如:C:\Python\Python39\Scripts\pyside2-rcc.exe
Arguments:$FileName$ -o $FileNameWithoutExtension$_rc.py
Working directory:$FileDir$
4.配置好自定義控件后,后續(xù)可以直接在pycharm菜單中使用。

二.python+Qt進(jìn)行項(xiàng)目創(chuàng)建與UI設(shè)置、添加ZMotion動(dòng)態(tài)庫(kù)。
1.新建項(xiàng)目:文件→新建項(xiàng)目。


2.UI設(shè)置界面。
(1)進(jìn)入項(xiàng)目ui設(shè)置界面:工具→Qt→QtDesigner。


(2)設(shè)置項(xiàng)目Ui:通過拖動(dòng)控件到界面設(shè)置ui。

(3)ui設(shè)置完后保存文件:文件→保存。

3.python運(yùn)行UI。
(1)添加UI運(yùn)行的python文件:選中項(xiàng)目右鍵→新建→Python File。


(2)Ui_Weiget文件里面添加UI處理的類。

from PySide2.QtCore import QFile
from PySide2.QtUiTools import QUiLoader
class UiInterFace:
def __init__(self):
# 從文件中加載UI定義
q_state_file = QFile("mainWeiget.ui")
q_state_file.open(QFile.ReadOnly)
q_state_file.close()
# 從 UI 定義中動(dòng)態(tài) 創(chuàng)建一個(gè)相應(yīng)的窗口對(duì)象
self.ui = QUiLoader().load(q_state_file)
(3)同步驟(1)添加主運(yùn)行python文件Main,并添加主入口運(yùn)行函數(shù)。

from PySide2.QtWidgets import QApplication
from Ui_Weiget import UiInterFace
if __name__ == "__main__":
app = QApplication([]) #加載所有控件
ui_interface = UiInterFace() #創(chuàng)建窗體對(duì)象
ui_interface.ui.show() #主窗口的控件,全部顯示在界面上
app.exec_() #進(jìn)入QApplication的事件處理循環(huán)
(4)此時(shí)在Main文件點(diǎn)擊運(yùn)行按鈕,可以運(yùn)行程序顯示UI界面。

4.添加庫(kù)文件、庫(kù)函數(shù)封裝的Python文件。
(1)找到廠家提供的光盤資料里面的python函數(shù)庫(kù),路徑如下(64位庫(kù)為例)。
a.進(jìn)入廠商提供的光盤資料找到“04PC函數(shù)\01PC函數(shù)庫(kù)V2.1\windows平臺(tái)\Python”文件夾,據(jù)需要選擇對(duì)應(yīng)的函數(shù)庫(kù),這里選擇64位庫(kù)。

b.進(jìn)入“64位”后打開文件夾“Python64”找到“dll庫(kù)文件”與“zmcdll”。

(2)將廠商提供的python的庫(kù)文件以及相關(guān)文件復(fù)制到新建的項(xiàng)目中。
a.進(jìn)入“dll庫(kù)文件”選中zauxdll.dl,zmotion.dll兩個(gè)文件復(fù)制到項(xiàng)目中。

b.進(jìn)入“zmcdll”選中zauxdllPython.py文件復(fù)制到項(xiàng)目中。

c.把對(duì)應(yīng)的庫(kù)文件與封裝的運(yùn)動(dòng)Python文件粘貼到項(xiàng)目中后。

(3)進(jìn)入ui的python文件在文件開頭處導(dǎo)入zauxdllPython文件的ZAUXDLL類,并在界面類中創(chuàng)建ZAUXDLL對(duì)象。

PC函數(shù)介紹
1.PC函數(shù)手冊(cè)可在光盤資料查看,具體路徑如下。

2.連接控制器。

3.萬(wàn)能指令之在線命令
有一些使用頻率較低的Basic指令我們沒有封裝到上位機(jī)的輔助庫(kù)中,如果用戶上位機(jī)需要調(diào)用對(duì)應(yīng)的Basic指令的話,可以通過在線命令自行進(jìn)行相關(guān)指令封裝。


Python編程調(diào)試ZMC432CL-V2的脈沖閉環(huán)功能
1.通過在線命令封裝脈沖閉環(huán)功能對(duì)應(yīng)的上位機(jī)接口。
(1)選中項(xiàng)目右鍵→新建→Python File新建一個(gè)MyFullClosedLoop類文件。

(2)查詢Basic對(duì)應(yīng)指令的使用說明,封裝一個(gè)設(shè)置軸比例增益的上位機(jī)接口。

def ZAux_Direct_SetPGain(self, iaxis, fValue):
'''
:Description:設(shè)置軸的比例增益
:param iaxis:軸號(hào)
:param fValue:比例增益P的值
:return:錯(cuò)誤碼,返回字符串
'''
# 判斷軸數(shù)是否超標(biāo)
if iaxis > self.MAX_AXIS_AUX:
return self.ERR_AUX_PARAERR
# 生成命令
pszCommand = "P_Gain({0}) = {1}".format(iaxis, fValue)
# 調(diào)用命令執(zhí)行函數(shù)
ret = self.Zmc.ZAux_DirectCommand(pszCommand)
return ret[0],ret[1]
(3)查詢Basic對(duì)應(yīng)指令的使用說明,封裝一個(gè)獲取軸比例增益的上位機(jī)接口。
#連接控制器,一般使用網(wǎng)口連接,控制器默認(rèn)IP是192.168.0.11,
def ZAux_Direct_GetPGain(self,iaxis):
'''
:Description:獲取軸的比例增益
:param iaxis:軸號(hào)
:return:錯(cuò)誤碼,獲取的軸比例增益P的值
'''
# 判斷軸數(shù)是否超標(biāo)
if iaxis >self.MAX_AXIS_AUX:
return self.ERR_AUX_PARAERR
#生成命令
pszCommand = "?P_Gain({0})".format(iaxis)
#調(diào)用命令執(zhí)行函數(shù)
ret = self.Zmc.ZAux_Execute(pszCommand)
if self.ERR_OK != ret[0]:
return ret[0]
# 解析返回的字符串
if len(ret[1]) == 0:
return self.ERR_NOACK
else:
value = float(ret[1])
return self.ERR_OK,value
(4)封裝好的脈沖閉環(huán)功能相關(guān)的上位機(jī)接口。

2.Python閉環(huán)功能的測(cè)試?yán)叹帉懓咐v解。
(1)【連接】連接控制器。
def on_btn_Connect(self):
if self.Zmc.handle.value is not None:
self.Zmc.ZAux_Close()
self.Zmc.handle.value = None
self.ui.setWindowTitle("脈沖閉環(huán)測(cè)試(步進(jìn)驅(qū)動(dòng)器+編碼器反饋)")
Temptype = 2 # 2-ETH
TempStr = self.ui.cb_strlist.currentText()
if self.ui.cb_type.currentText() == "網(wǎng)口":
Temptype = 2 # 2-ETH
elif self.ui.cb_type.currentText() == "LOCAL":
Temptype = 5 # MotionRT
elif self.ui.cb_type.currentText() == "PCI":
Temptype = 4 # PCI
elif self.ui.cb_type.currentText() == "串口":
Temptype = 1 # COM
iresult = self.Zmc.ZAux_FastOpen(Temptype, TempStr, 1000)
(2)【更新PID參數(shù)】按鈕如何打開和關(guān)閉脈沖閉環(huán)功能,如何更新PID參數(shù)。
def PidParaSet(self):
TempFloat = 0
TempDpos = 0
TempMpos = 0
TempInt = 0
Axis_Num = int(self.ui.edit_AxisId.text()) # 軸號(hào)
CloseLoop = MyFullClosedLoop() # 創(chuàng)建 MyFullClosedLoop 控制器對(duì)象
CloseLoop.Zmc.handle=self.Zmc.handle #設(shè)置控制器句柄為當(dāng)前連接控制器句柄
CompareStr = "閉環(huán)已開"
TempStr = self.ui.btn_IsClosedLoop.text()
#打開全閉環(huán)去控制軸運(yùn)動(dòng)
if TempStr == CompareStr:
#獲取軸位置,如果DPOS和MPOS相差太大不能打開脈沖閉環(huán)
TempDpos = self.Zmc.ZAux_Direct_GetDpos(Axis_Num)[1].value
TempMpos = self.Zmc.ZAux_Direct_GetMpos(Axis_Num)[1].value
if ((TempDpos - TempMpos) > 4 or (TempDpos - TempMpos < -4)):
print("規(guī)劃位置和反饋位置相差太大,無(wú)法啟動(dòng)閉環(huán)功能!。!")
QMessageBox.warning(self.ui, "提示", "規(guī)劃位置和反饋位置相差太大,無(wú)法啟動(dòng)閉環(huán)功能。。。")
return -1
#更新比例增益
TempFloat=self.ui.edit_ParaP.text()
CloseLoop.ZAux_Direct_SetPGain(Axis_Num, TempFloat)
#更新積分增益
TempFloat=self.ui.edit_ParaI.text()
CloseLoop.ZAux_Direct_SetIGain(Axis_Num,TempFloat)
# 更新微分增益
TempFloat=self.ui.edit_ParaD.text()
CloseLoop.ZAux_Direct_SetDGain(Axis_Num,TempFloat)
#更新速度前饋增益
TempFloat = self.ui.edit_ParaVF.text()
CloseLoop.ZAux_Direct_SetVffGain(Axis_Num, TempFloat)
#更新加速度前饋增益
TempFloat = self.ui.edit_ParaAF.text()
CloseLoop.ZAux_Direct_SetAffGain(Axis_Num, TempFloat)
# 更新速度增益
TempFloat = self.ui.edit_ParaOV.text()
CloseLoop.ZAux_Direct_SetOvGain(Axis_Num, TempFloat)
#注意:在打開servo之前打開encoder_servo后要完成一次atype由0變?yōu)?的切換,否則會(huì)報(bào)axis: axis:0 config not support Servo#1、先打開encoder_servo
CloseLoop.ZAux_Direct_SetEncoderServo(Axis_Num, 1)
time.sleep(0.02)
TempInt=CloseLoop.ZAux_Direct_GetEncoderServo(Axis_Num)[1]
if TempInt==1:
#2、完成一次Atype由0變?yōu)?的切換
self.Zmc.ZAux_Direct_SetAtype(Axis_Num, 0);
time.sleep(0.02)
self.Zmc.ZAux_Direct_SetAtype(Axis_Num, 4);
#3、打開Servo
CloseLoop.ZAux_Direct_SetServo(Axis_Num, 1);
time.sleep(0.02)
TempInt=CloseLoop.ZAux_Direct_GetServo(Axis_Num)[1]
if TempInt==1:
print("閉環(huán)參數(shù)配置完成, 軸全閉環(huán)功能打開成功。");
else:
print("軸閉環(huán)開關(guān)Servo打開失敗, 導(dǎo)致脈沖全閉環(huán)開啟失敗");
return -1;
else:
print("軸編碼器閉環(huán)EncoderServo打開失敗, 導(dǎo)致脈沖全閉環(huán)開啟失敗。!");
return -1;
else:
#關(guān)閉全閉環(huán)的功能
#1、關(guān)閉EncoderServo
CloseLoop.ZAux_Direct_SetEncoderServo(Axis_Num, 0);
time.sleep(0.02)
TempInt=CloseLoop.ZAux_Direct_GetEncoderServo(Axis_Num)[1]
if TempInt==1:
Console.WriteLine("軸EncoderServo關(guān)閉失敗。!");
return -1;
# 2、關(guān)閉EncoderServo后需要完成ATYPE的切換,保證完全關(guān)閉閉環(huán)功能
self.Zmc.ZAux_Direct_SetAtype(Axis_Num, 0);
time.sleep(0.02)
self.Zmc.ZAux_Direct_SetAtype(Axis_Num, 4);
# 3、關(guān)閉Servo
CloseLoop.ZAux_Direct_SetServo(Axis_Num, 0);
time.sleep(0.02)
TempInt=CloseLoop.ZAux_Direct_GetServo(Axis_Num)[1]
if TempInt==1:
print("軸Servo關(guān)閉失。。!");
return -1;
return 0;
(3)【更新軸參數(shù)】按鈕如何完成軸參數(shù)的更新。
def AxisParaSet (self):
TempFloat = 0
TempInt1 = 0
TempInt2 = 0
Axis_Num = int(self.ui.edit_AxisId.text()) # 軸號(hào)
# 設(shè)置最大隨動(dòng)誤差FE_LIMIT
self.Zmc.ZAux_Direct_SetFeLimit(Axis_Num, 500)
# 更新編碼器齒輪比 (如果發(fā)N個(gè)脈沖,實(shí)際編碼器反饋M個(gè)脈沖,編碼器齒輪比要設(shè)置成 N/M)
TempInt1 = int(self.ui.edit_EncoderRatioMol.text())
TempInt2 = int(self.ui.edit_EncoderRatioDenom.text())
self.Zmc.ZAux_Direct_EncoderRatio(Axis_Num, TempInt1, TempInt2)
# 更新脈沖當(dāng)量,一般脈沖當(dāng)量設(shè)置成機(jī)臺(tái)運(yùn)動(dòng)1mm需要的脈沖數(shù)
TempFloat = float(self.ui.edit_ParaUnits.text())
self.Zmc.ZAux_Direct_SetUnits(Axis_Num, TempFloat);
# 全閉環(huán)的功能需要把ATYPE設(shè)置成4
self.Zmc.ZAux_Direct_SetAtype(Axis_Num, 4);
# 更新速度
TempFloat = float(self.ui.edit_ParaSpeed.text())
self.Zmc.ZAux_Direct_SetSpeed(Axis_Num, TempFloat);
# 更新加速度、減速度
TempFloat = float(self.ui.edit_ParaAccel.text())
self.Zmc.ZAux_Direct_SetAccel(Axis_Num, TempFloat);
TempFloat = float(self.ui.edit_ParaDecel.text())
self.Zmc.ZAux_Direct_SetDecel(Axis_Num, TempFloat);
# 是否啟用SS曲線
if self.CurveIsSS == 1:
# 啟用SS曲線,VP_MODE模式設(shè)置成7即可
# 上位機(jī)沒有現(xiàn)場(chǎng)設(shè)置VP_MODE的接口,直接在線命令去封裝,在線命令是萬(wàn)能指令
pszCommand = "VP_MODE({0}) = 7 ".format(Axis_Num)
self.Zmc.ZAux_DirectCommand(pszCommand)
print("啟用SS曲線,VP_MODE模式設(shè)置成7!")
else:
# 啟用S曲線,VP_MODE模式設(shè)置成0即可
# 上位機(jī)沒有現(xiàn)場(chǎng)設(shè)置VP_MODE的接口,直接在線命令去封裝,在線命令是萬(wàn)能指令
pszCommand = "VP_MODE({0}) = 0 ".format(Axis_Num)
self.Zmc.ZAux_DirectCommand(pszCommand)
# S曲線模式,S曲線時(shí)間sramp是有效果的,需要設(shè)置一下
TempFloat = float(self.ui.edit_ParaSramp.text())
self.Zmc.ZAux_Direct_SetSramp(Axis_Num, TempFloat);
print("啟用S曲線,VP_MODE模式設(shè)置成0!")
print("軸參數(shù)設(shè)置完成。")
通過RTSys的示波器對(duì)比開環(huán)控制和全閉環(huán)控制的情況
示波器的使用可以參考正運(yùn)動(dòng)小助手的歷史推文《運(yùn)動(dòng)控制看的更清楚細(xì)致!RTSys示波器功能簡(jiǎn)介 (qq.com)》。
1.開環(huán)控制情況分析


測(cè)試發(fā)現(xiàn):步進(jìn)驅(qū)動(dòng)器的開環(huán)控制,運(yùn)動(dòng)過程中隨動(dòng)誤差(規(guī)劃位置和光柵尺反饋位置的差值)一直維持在0.02個(gè)用戶單位左右(這里一個(gè)用戶單位即一個(gè)UNITS設(shè)置的是1mm),當(dāng)運(yùn)動(dòng)結(jié)束時(shí)光柵尺的反饋位置和指令規(guī)劃位置也不相等,大概差了0.0015個(gè)用戶單位,折算為脈沖數(shù)是0.0015*用戶單位=3個(gè)脈沖。
2.閉環(huán)控制情況分析


測(cè)試發(fā)現(xiàn):步進(jìn)驅(qū)動(dòng)器的閉環(huán)控制,運(yùn)動(dòng)過程中隨動(dòng)誤差(規(guī)劃位置和光柵尺反饋位置的差值)除了啟動(dòng)和停止以外大部分保持在0個(gè)脈沖當(dāng)量左右,相比較開環(huán)控制有較大的提升,當(dāng)運(yùn)動(dòng)結(jié)束時(shí)光柵尺的反饋位置和指令規(guī)劃位置也是相等的。
3.教學(xué)視頻可點(diǎn)擊→“步進(jìn)控制的光柵尺全閉環(huán)EtherCAT運(yùn)動(dòng)控制器ZMC432CL-V2(五):Python編程調(diào)試”查看。
完整代碼獲取地址
▼

本次,正運(yùn)動(dòng)技術(shù)步進(jìn)控制的光柵尺全閉環(huán)EtherCAT運(yùn)動(dòng)控制器ZMC432CL-V2(五):Python編程調(diào)試,就分享到這里。
更多精彩內(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。
本文由正運(yùn)動(dòng)技術(shù)原創(chuàng),歡迎大家轉(zhuǎn)載,共同學(xué)習(xí),一起提高中國(guó)智能制造水平。文章版權(quán)歸正運(yùn)動(dòng)技術(shù)所有,如有轉(zhuǎn)載請(qǐng)注明文章來源。

正運(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ù)的研究,是國(guó)內(nèi)工控領(lǐng)域發(fā)展最快的企業(yè)之一,也是國(guó)內(nèi)少有、完整掌握運(yùn)動(dòng)控制核心技術(shù)和實(shí)時(shí)工控軟件平臺(tái)技術(shù)的企業(yè)。主要業(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)控制卡等等。
|