之前的課程給大家介紹了ZMC432CL-V2硬件接口(詳情點擊→步進的光柵尺全閉環EtherCAT運動控制器ZMC432CL-V2(一):硬件接口介紹)。
本節主要講解如何通過Python編程調試ZMC432CL-V2的脈沖閉環功能。
ZMC432CL-V2產品簡介
ZMC432CL-V2高性能多軸運動控制器是一款兼容EtherCAT總線和脈沖型的獨立式運動控制器,具備高速實時反饋功能,支持脈沖全閉環控制,能夠實現高精度、高響應速度的運動控制。高精度定位,有效消除機械傳動誤差,滿足高精密加工場景應用要求。

ZMC432CL-V2硬件功能特性:
1.豐富的運動控制功能:支持直線、圓弧、空間圓弧、螺旋插補等。
2.硬件接口豐富:支持脈沖軸(帶編碼器反饋)和EtherCAT總線軸,具備24路輸入和12路輸出的通用IO,部分為高速IO,2路模擬量輸出(DA)。
3.EtherCAT刷新周期最快達250us,滿足高速通信需求。
4.支持4通道硬件比較輸出、硬件定時器、運動中精準輸出,適用于多通道視覺飛拍等場合。
5.支持掉電檢測、掉電存儲,多種程序加密方式,能夠有效防止系統故障,保護項目工程文件數據,并提高系統的可靠性。
6.通過純國產IDE開發環境RTSys進行項目開發,可實時仿真、在線跟蹤以及診斷與調試,簡便易用,支持多種高級上位機語言聯合編程進行二次開發。

更多關于ZMC432CL-V2詳情介紹點擊→步進控制的光柵尺全閉環解決方案:32軸EtherCAT總線運動控制器ZMC432CL-V2。
Python語言如何調用ZMotion的動態庫進行項目開發
此案例Python開發環境操作系統環境 :Win11_64位
Python版本:python-3.10.10-amd64.exe
Pycharm版本:pycharm-community-2024.1.3.exe
一.python開發前對環境、解析器進行配置。
1.安裝漢化包:點擊file→setting→plugins,然后搜索Chinese中文包。

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

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

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

二.python+Qt進行項目創建與UI設置、添加ZMotion動態庫。
1.新建項目:文件→新建項目。


2.UI設置界面。
(1)進入項目ui設置界面:工具→Qt→QtDesigner。


(2)設置項目Ui:通過拖動控件到界面設置ui。

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

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


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

fromPySide2.QtCoreimportQFile fromPySide2.QtUiToolsimportQUiLoader classUiInterFace: def__init__(self): # 從文件中加載UI定義 q_state_file = QFile("mainWeiget.ui") q_state_file.open(QFile.ReadOnly) q_state_file.close() # 從 UI 定義中動態 創建一個相應的窗口對象 self.ui = QUiLoader().load(q_state_file)
(3)同步驟(1)添加主運行python文件Main,并添加主入口運行函數。

fromPySide2.QtWidgetsimportQApplication fromUi_WeigetimportUiInterFace if__name__ =="__main__": app = QApplication([]) #加載所有控件 ui_interface = UiInterFace() #創建窗體對象 ui_interface.ui.show() #主窗口的控件,全部顯示在界面上 app.exec_() #進入QApplication的事件處理循環
(4)此時在Main文件點擊運行按鈕,可以運行程序顯示UI界面。

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

b.進入“64位”后打開文件夾“Python64”找到“dll庫文件”與“zmcdll”。

(2)將廠商提供的python的庫文件以及相關文件復制到新建的項目中。
a.進入“dll庫文件”選中zauxdll.dl,zmotion.dll兩個文件復制到項目中。


b.進入“zmcdll”選中zauxdllPython.py文件復制到項目中。


c.把對應的庫文件與封裝的運動Python文件粘貼到項目中后。

(3)進入ui的python文件在文件開頭處導入zauxdllPython文件的ZAUXDLL類,并在界面類中創建ZAUXDLL對象。

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

2.連接控制器。

3.萬能指令之在線命令
有一些使用頻率較低的Basic指令我們沒有封裝到上位機的輔助庫中,如果用戶上位機需要調用對應的Basic指令的話,可以通過在線命令自行進行相關指令封裝。


Python編程調試ZMC432CL-V2的脈沖閉環功能
1.通過在線命令封裝脈沖閉環功能對應的上位機接口。
(1)選中項目右鍵→新建→Python File新建一個MyFullClosedLoop類文件。

(2)查詢Basic對應指令的使用說明,封裝一個設置軸比例增益的上位機接口。

defZAux_Direct_SetPGain(self, iaxis, fValue): ''' :Description:設置軸的比例增益 :param iaxis:軸號 :param fValue:比例增益P的值 :return:錯誤碼,返回字符串 ''' # 判斷軸數是否超標 if iaxis > self.MAX_AXIS_AUX: returnself.ERR_AUX_PARAERR # 生成命令 pszCommand ="P_Gain({0}) = {1}".format(iaxis, fValue) # 調用命令執行函數 ret = self.Zmc.ZAux_DirectCommand(pszCommand) returnret[0],ret[1]
(3)查詢Basic對應指令的使用說明,封裝一個獲取軸比例增益的上位機接口。
defZAux_Direct_GetPGain(self,iaxis):
'''
:Description:獲取軸的比例增益
:param iaxis:軸號
:return:錯誤碼,獲取的軸比例增益P的值
'''
# 判斷軸數是否超標
ifiaxis >self.MAX_AXIS_AUX:
returnself.ERR_AUX_PARAERR
#生成命令
pszCommand ="?P_Gain({0})".format(iaxis)
#調用命令執行函數
ret = self.Zmc.ZAux_Execute(pszCommand)
ifself.ERR_OK != ret[0]:
returnret[0]
# 解析返回的字符串
iflen(ret[1]) ==0:
returnself.ERR_NOACK
else:
value =float(ret[1])
returnself.ERR_OK,value
(4)封裝好的脈沖閉環功能相關的上位機接口。

2.Python閉環功能的測試例程編寫案例講解。
(1)【連接】連接控制器。
#連接控制器,一般使用網口連接,控制器默認IP是192.168.0.11,
defon_btn_Connect(self):
ifself.Zmc.handle.valueisnotNone:
self.Zmc.ZAux_Close()
self.Zmc.handle.value =None
self.ui.setWindowTitle("脈沖閉環測試(步進驅動器+編碼器反饋)")
Temptype =2# 2-ETH
TempStr = self.ui.cb_strlist.currentText()
ifself.ui.cb_type.currentText() =="網口":
Temptype =2# 2-ETH
elifself.ui.cb_type.currentText() =="LOCAL":
Temptype =5# MotionRT
elifself.ui.cb_type.currentText() =="PCI":
Temptype =4# PCI
elifself.ui.cb_type.currentText() =="串口":
Temptype =1# COM
iresult = self.Zmc.ZAux_FastOpen(Temptype, TempStr,1000)
(2)【更新PID參數】按鈕如何打開和關閉脈沖閉環功能,如何更新PID參數。
defPidParaSet(self):
TempFloat=0
TempDpos=0
TempMpos=0
TempInt=0
Axis_Num= int(self.ui.edit_AxisId.text()) # 軸號
CloseLoop= MyFullClosedLoop() # 創建 MyFullClosedLoop 控制器對象
CloseLoop.Zmc.handle=self.Zmc.handle #設置控制器句柄為當前連接控制器句柄
CompareStr="閉環已開"
TempStr= self.ui.btn_IsClosedLoop.text()
#打開全閉環去控制軸運動
ifTempStr == CompareStr:
#獲取軸位置,如果DPOS和MPOS相差太大不能打開脈沖閉環
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("規劃位置和反饋位置相差太大,無法啟動閉環功能!!!!")
? ? ? ? ? ??QMessageBox.warning(self.ui,?"提示",?"規劃位置和反饋位置相差太大,無法啟動閉環功能!!!!")
? ? ? ? ? ??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變為4的切換,否則會報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變為4的切換
? ? ? ? ? ??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("閉環參數配置完成, 軸全閉環功能打開成功。");
? ? ? ? ? ??else:
? ? ? ? ? ? ? ??print("軸閉環開關Servo打開失敗, 導致脈沖全閉環開啟失敗");
? ? ? ? ? ? ? ??return?-1;
? ? ? ??else:
? ? ? ? ? ??print("軸編碼器閉環EncoderServo打開失敗, 導致脈沖全閉環開啟失敗!!!");
? ? ? ? ? ??return?-1;
? ??else:
? ? ? ??#關閉全閉環的功能
? ? ? ??#1、關閉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關閉失敗!!!");
? ? ? ? ? ??return?-1;
? ? ? ??# 2、關閉EncoderServo后需要完成ATYPE的切換,保證完全關閉閉環功能
? ? ? ??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,?0);
? ? ? ??time.sleep(0.02)
? ? ? ??TempInt=CloseLoop.ZAux_Direct_GetServo(Axis_Num)[1]
? ? ? ??if?TempInt==1:
? ? ? ? ? ??print("軸Servo關閉失敗!!!");
? ? ? ? ? ??return?-1;
? ??return?0;
(3)【更新軸參數】按鈕如何完成軸參數的更新。
defAxisParaSet(self):
TempFloat =0
TempInt1 =0
TempInt2 =0
Axis_Num =int(self.ui.edit_AxisId.text()) # 軸號
# 設置最大隨動誤差FE_LIMIT
self.Zmc.ZAux_Direct_SetFeLimit(Axis_Num,500)
# 更新編碼器齒輪比 (如果發N個脈沖,實際編碼器反饋M個脈沖,編碼器齒輪比要設置成 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)
# 更新脈沖當量,一般脈沖當量設置成機臺運動1mm需要的脈沖數
TempFloat =float(self.ui.edit_ParaUnits.text())
self.Zmc.ZAux_Direct_SetUnits(Axis_Num, TempFloat);
# 全閉環的功能需要把ATYPE設置成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曲線
ifself.CurveIsSS ==1:
# 啟用SS曲線,VP_MODE模式設置成7即可
# 上位機沒有現場設置VP_MODE的接口,直接在線命令去封裝,在線命令是萬能指令
pszCommand ="VP_MODE({0}) = 7 ".format(Axis_Num)
self.Zmc.ZAux_DirectCommand(pszCommand)
print("啟用SS曲線,VP_MODE模式設置成7!!")
else:
# 啟用S曲線,VP_MODE模式設置成0即可
# 上位機沒有現場設置VP_MODE的接口,直接在線命令去封裝,在線命令是萬能指令
pszCommand ="VP_MODE({0}) = 0 ".format(Axis_Num)
self.Zmc.ZAux_DirectCommand(pszCommand)
# S曲線模式,S曲線時間sramp是有效果的,需要設置一下
TempFloat =float(self.ui.edit_ParaSramp.text())
self.Zmc.ZAux_Direct_SetSramp(Axis_Num, TempFloat);
print("啟用S曲線,VP_MODE模式設置成0!!")
print("軸參數設置完成!!")
通過RTSys的示波器對比開環控制和全閉環控制的情況
示波器的使用可以參考正運動小助手的歷史推文《運動控制看的更清楚細致!RTSys示波器功能簡介 (qq.com)》。
1.開環控制情況分析


測試發現:步進驅動器的開環控制,運動過程中隨動誤差(規劃位置和光柵尺反饋位置的差值)一直維持在0.02個用戶單位左右(這里一個用戶單位即一個UNITS設置的是1mm),當運動結束時光柵尺的反饋位置和指令規劃位置也不相等,大概差了0.0015個用戶單位,折算為脈沖數是0.0015*用戶單位=3個脈沖。
2.閉環控制情況分析


測試發現:步進驅動器的閉環控制,運動過程中隨動誤差(規劃位置和光柵尺反饋位置的差值)除了啟動和停止以外大部分保持在0個脈沖當量左右,相比較開環控制有較大的提升,當運動結束時光柵尺的反饋位置和指令規劃位置也是相等的。
3.教學視頻可點擊→“步進控制的光柵尺全閉環EtherCAT運動控制器ZMC432CL-V2(五):Python編程調試”查看。
完整代碼獲取地址
▼

本次,正運動技術步進控制的光柵尺全閉環EtherCAT運動控制器ZMC432CL-V2(五):Python編程調試,就分享到這里。
本文由正運動技術原創,歡迎大家轉載,共同學習,一起提高中國智能制造水平。文章版權歸正運動技術所有,如有轉載請注明文章來源。
審核編輯 黃宇
-
運動控制
+關注
關注
5文章
821瀏覽量
34536 -
python
+關注
關注
57文章
4876瀏覽量
90025 -
ethercat
+關注
關注
19文章
1508瀏覽量
45183 -
步進控制
+關注
關注
0文章
16瀏覽量
7602
發布評論請先 登錄
如何預防RE74光柵尺性能和作用
如何預防RE74光柵尺污染?
如何判斷光柵尺是否需要清潔?
RE74光柵尺是什么
探索工業自動化核心:ZMC 系列 EtherCAT 主站控制器
直線電機模組中光柵尺和磁柵尺的區別
步進控制的光柵尺全閉環EtherCAT運動控制器ZMC432CL-V2(五):Python編程調試
評論