http://www.henanjusheng.com 2026-07-22 12:01 深圳市正運(yùn)動(dòng)技術(shù)有限公司
EtherCAT總線型運(yùn)動(dòng)控制器-ZMC600M
ZMC600M系列高性能多軸運(yùn)動(dòng)控制器是一款EtherCAT總線立式運(yùn)動(dòng)控制器,控制器本身最多支持6-32軸的復(fù)雜的控制需求。
ZMC600M是基于“ARM架構(gòu)+純國產(chǎn)Linux運(yùn)動(dòng)控制實(shí)時(shí)內(nèi)核MotionRT750+ EtherCAT”的總線型運(yùn)動(dòng)控制器,打破平臺(tái)壁壘,實(shí)現(xiàn)了嵌入式系統(tǒng)與運(yùn)動(dòng)控制和實(shí)時(shí)內(nèi)核技術(shù)的無縫銜接。

ZMC600M硬件功能特性:
● 內(nèi)置Linux系統(tǒng),搭載強(qiáng)實(shí)時(shí)內(nèi)核MotionRT750;
● 可選6-32軸運(yùn)動(dòng)控制,EtherCAT總線最快通訊周期可達(dá)250μs;
● 24路高速IO輸入,2路高速鎖存,3路單端編碼器接口;
● 16路高速IO輸出,4路PWM/PSO,4路單端脈沖軸接口;
● 2路AD,2路DA(0-10V,12bit);
● 支持EtherNET、CAN、RS232、RS485通訊;
● 1路MPG手輪接口;
● 支持掉電存儲(chǔ);
● 特殊型號(hào)支持5V/24V推挽輸出功能;
● 支持多文件多任務(wù)編程,可支持PC程序和控制器內(nèi)置程序同時(shí)工作。

更多關(guān)于ZMC600M詳情點(diǎn)擊→基于Linux的強(qiáng)實(shí)時(shí)EtherCAT運(yùn)動(dòng)控制器ZMC600M。
ZMC600M介紹視頻請(qǐng)點(diǎn)擊→基于Linux的強(qiáng)實(shí)時(shí)EtherCAT總線型運(yùn)動(dòng)控制器ZMC600M
基于linux平臺(tái)的ZMotionCadEx和Qt/C++,把CAD文件導(dǎo)入、DXF驗(yàn)證、圖形預(yù)覽、軸參數(shù)配置和運(yùn)動(dòng)控制流程串成一個(gè)可演示、可參考復(fù)用的小型驗(yàn)證DEMO。

一、痛點(diǎn)及工程價(jià)值
在真實(shí)的CAD/CAM或運(yùn)動(dòng)控制項(xiàng)目里,問題通常不是單點(diǎn)出現(xiàn)的,而是出現(xiàn)在一條很長的鏈路中:
CAD文件:
?CAD庫導(dǎo)入
?幾何數(shù)據(jù)解析
?圖形預(yù)覽
?坐標(biāo)和參數(shù)轉(zhuǎn)換
?控制器連接
?運(yùn)動(dòng)執(zhí)行
任何一層出現(xiàn)問題,最后用戶看到的可能是:
?“這個(gè)圖紙跑不了”
?“導(dǎo)入以后沒圖形”
?“圖形看起來對(duì),但設(shè)備動(dòng)作不對(duì)”
?“控制器能連上,但加工效果異常”
所以這個(gè)demo的目標(biāo),不是做一個(gè)簡(jiǎn)單的文件打開工具,而是把“CAD文件→圖形預(yù)覽→參數(shù)配置→控制器執(zhí)行”這條鏈路串起來,方便開發(fā)、聯(lián)調(diào)、演示和現(xiàn)場(chǎng)排障。

二、CAD圖形的校驗(yàn)優(yōu)勢(shì)
這個(gè)Demo主要用來驗(yàn)證從圖紙到設(shè)備執(zhí)行之間的關(guān)鍵環(huán)節(jié)。
?對(duì)開發(fā)來說,它可以驗(yàn)證CAD導(dǎo)入邏輯和圖形數(shù)據(jù)處理是否正確。
?對(duì)排障來說,它可以幫助判斷問題到底出在文件、導(dǎo)入庫、參數(shù)還是設(shè)備層。
?對(duì)演示來說,它可以比較完整地展示從CAD文件到運(yùn)動(dòng)控制執(zhí)行的過程。
三、Demo已實(shí)現(xiàn)的功能模塊
當(dāng)前版本已實(shí)現(xiàn)的核心功能如下:
?支持DXF/PLT/AI/EPS等CAD文件導(dǎo)入。
?基于正運(yùn)動(dòng)ZMotionCadEx庫解析CAD文件。
?支持導(dǎo)入后的圖形實(shí)時(shí)預(yù)覽。
?支持X/Y雙軸脈沖當(dāng)量、最大速度、最大加速度、回零速度配置。
?支持控制器IP連接。
?支持回零、開始加工、暫停、停止等運(yùn)動(dòng)控制操作。
?支持系統(tǒng)日志輸出,方便查看導(dǎo)入、連接和運(yùn)動(dòng)控制過程。
?支持加工用紅線覆蓋,顯示加工進(jìn)度。
?額外加入了一個(gè)基于dxflib的DXF驗(yàn)證器,用來排查導(dǎo)圖失敗問題。


四、Demo的實(shí)現(xiàn)流程

CAD導(dǎo)入核心邏輯代碼如下:
CadData CadImporter::importFile(const QString& filePath, double unit, double precision)
{
CadData result;
result.success = false;
// option = 0:強(qiáng)制將實(shí)體轉(zhuǎn)換為線段,便于后續(xù)預(yù)覽和運(yùn)動(dòng)控制 int option = 0;
// 原始 precision = 0.1 時(shí),部分 SPLINE 曲線轉(zhuǎn)換效果不穩(wěn)定
// 調(diào)整到 0.01,提高曲線離散和導(dǎo)入成功率
double adjustedPrecision = 0.01;
Struct_ZCad_VectGroup* vectGroup = ZMotionCad3_ImportVectGraph(
filePath.toUtf8().constData(),
unit,
option,
adjustedPrecision,
0
);
if (!vectGroup) {
result.errorMessage = "導(dǎo)入失敗:ZMotionCad3_ImportVectGraph 返回空指針";
return result;
}
double minX = 1e9;
double minY = 1e9;
double maxX = -1e9;
double maxY = -1e9;
int layerIndex = 0;
Struct_ZCad_VectGroup* currentGroup = vectGroup;
while (currentGroup) {
layerIndex++;
Struct_ZCad_Vect* vect = currentGroup->m_pVect;
while (vect) {
CadEntity entity;
entity.layer = layerIndex;
entity.color = currentGroup->m_ColorPen;
entity.isClosed = vect->IfCloseLine;
// 優(yōu)先讀取轉(zhuǎn)換后的線段數(shù)據(jù)
Struct_ZCad_Seg* firstSeg = vect->m_pLineSeg;
// 如果轉(zhuǎn)換后的線段為空,則 fallback 到原始線數(shù)據(jù)
if (!firstSeg) {
firstSeg = vect->m_pLine;
}
if (firstSeg) {
Struct_ZCad_Seg* seg = firstSeg;
int segCount = 0;
do {
QPointF point(seg->x1, seg->y1);
entity.points.append(point);
minX = qMin(minX, seg->x1);
minY = qMin(minY, seg->y1);
maxX = qMax(maxX, seg->x1);
maxY = qMax(maxY, seg->y1);
seg = seg->m_pnext;
segCount++;
// 防止鏈表異常導(dǎo)致死循環(huán)
if (segCount > 10000) {
break;
}
} while (seg && seg != firstSeg);
result.entities.append(entity);
}
Struct_ZCad_Vect* nextVect = (Struct_ZCad_Vect*)vect->m_pnext;
if (nextVect == currentGroup->m_pVect) {
break;
}
vect = nextVect;
}
Struct_ZCad_VectGroup* nextGroup =
(Struct_ZCad_VectGroup*)currentGroup->m_pnext;
if (nextGroup == vectGroup) {
break;
}
currentGroup = nextGroup;
}
if (!result.entities.isEmpty()) {
result.boundingRect = QRectF(QPointF(minX, minY), QPointF(maxX, maxY));
}
ZMotionCad3_DeleteChain((Struct_ZCad_Item*)vectGroup); result.success = true;
return result;
}
這里的關(guān)鍵點(diǎn)有兩個(gè):
1.導(dǎo)入時(shí)使用option=0,強(qiáng)制將CAD實(shí)體轉(zhuǎn)換為線段,方便后續(xù)預(yù)覽和運(yùn)動(dòng)控制。
②讀取數(shù)據(jù)時(shí)不只檢查m_pLineSeg,還有fallback檢查m_pLine,避免庫已經(jīng)返回了原始線數(shù)據(jù),但業(yè)務(wù)代碼沒有讀取到。
這也是后面解決SPLINE樣條曲線導(dǎo)入為空問題的關(guān)鍵。
CAD文件不是簡(jiǎn)單“打開一下”,而是要經(jīng)過導(dǎo)入庫解析、圖層遍歷、矢量對(duì)象讀取、坐標(biāo)提取,最后才能進(jìn)入圖形預(yù)覽和運(yùn)動(dòng)控制流程。
五、DXF驗(yàn)證流程
在實(shí)際調(diào)試中,經(jīng)常會(huì)遇到一種情況:
CAD軟件里能正常打開的DXF文件,導(dǎo)入程序后實(shí)體數(shù)卻是0。
這時(shí)候不能直接判斷文件壞了,也不能直接判斷CAD庫有問題。
更合理的做法是先把問題拆開:
?文件里到底有沒有幾何實(shí)體?
?實(shí)體類型是什么?
?是LINE、CIRCLE、ARC、LWPOLYLINE,還是SPLINE?
?是文件格式問題,還是導(dǎo)入?yún)?shù)問題?
?是CAD庫沒有解析出來,還是業(yè)務(wù)代碼沒有讀取到?
所以這個(gè)demo里額外加了一個(gè)基于dxflib的第三方驗(yàn)證器。
它不參與正式加工流程,只負(fù)責(zé)獨(dú)立檢查DXF文件內(nèi)容。
這樣可以在正運(yùn)動(dòng)CAD庫之外,提供一個(gè)對(duì)照結(jié)果。
驗(yàn)證器可以幫助確認(rèn):
?文件是否能打開。
?是否包含有效幾何實(shí)體。
?各類實(shí)體數(shù)量是多少。
?圖形邊界范圍是否合理。
?文件是否可能是格式或?qū)嶓w類型問題。
DXF_FILE="$1"
if [ ! -f "$DXF_FILE" ]; then
echo "錯(cuò)誤: 文件不存在: $DXF_FILE"
exit 1
fi
if grep -q "ENTITIES" "$DXF_FILE"; then
echo "找到 ENTITIES 段"
else echo "未找到 ENTITIES 段,文件可能不包含幾何實(shí)體"
fi
echo "實(shí)體類型統(tǒng)計(jì):"
for entity_type in LINE CIRCLE ARC LWPOLYLINE SPLINE ELLIPSE TEXT DIMENSION; do
count=$(grep -A1 "^0$" "$DXF_FILE" | grep -c "^${entity_type}$")
if [ $count -gt 0 ]; then
printf " %-15s %d\n" "$entity_type:" $count
fi
done
2.Qt驗(yàn)證器入口。
#include
#include
#include
"dxflibverifier.h"
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
if (argc < 2) {
qDebug() << "用法: ./test_verifier ";
return 1;
}
QString filePath = QString::fromLocal8Bit(argv[1]);
DxflibVerifier verifier;
DxfVerifyResult result = verifier.verifyFile(filePath);
if (result.success && result.entities.size() > 0) {
qDebug() << "驗(yàn)證成功,找到" << result.entities.size() << "個(gè)實(shí)體";
return 0;
}
qDebug() << "驗(yàn)證失敗,未找到有效幾何實(shí)體";
return 1;
}
3.驗(yàn)證結(jié)果數(shù)據(jù)結(jié)構(gòu)。
struct DxfEntity {
QVector points;
bool isClosed;
QString layer;
// 0=LINE, 1=CIRCLE, 2=ARC, 3=LWPOLYLINE, 4=SPLINE
int entityType;
};
struct DxfVerifyResult {
bool success;
QString errorMessage;
QVector entities;
int totalLines;
int totalCircles;
int totalArcs;
int totalPolylines;
int totalSplines;
double minX;
double minY;
double maxX;
double maxY;
};
DxfVerifyResult DxflibVerifier::verifyFile(const QString& filePath)
{
DxfVerifyResult result;
if (!parseDxfFile(filePath, result)) {
result.success = false;
result.errorMessage = "解析失敗或文件不存在";
return result;
}
result.success = true;
printSummary(result);
return result;
}
4.解析DXF實(shí)體類型。
bool DxflibVerifier::parseDxfFile(const QString& filePath, DxfVerifyResult& result)
{
QFile file(filePath);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
return false;
}
QTextStream in(&file);
in.setCodec("UTF-8");
QStringList allCodes;
QStringList allValues;
// DXF 文本格式通常是“組碼 + 值”成對(duì)出現(xiàn)
while (!in.atEnd()) {
QString codeLine = in.readLine().trimmed();
if (in.atEnd()) break;
QString valueLine = in.readLine().trimmed();
if (!codeLine.isEmpty() && !valueLine.isEmpty()) {
allCodes.append(codeLine);
allValues.append(valueLine);
}
}
file.close();
if (allCodes.isEmpty()) {
return false;
}
for (int i = 0; i < allCodes.size(); i++) {
if (allCodes[i] != "0") {
continue;
}
QString entityType = allValues[i].toUpper();
if (entityType == "LINE") {
parseLine(allCodes.mid(i), allValues.mid(i), result);
} else if (entityType == "CIRCLE") {
parseCircle(allCodes.mid(i), allValues.mid(i), result);
} else if (entityType == "ARC") {
parseArc(allCodes.mid(i), allValues.mid(i), result);
} else if (entityType == "LWPOLYLINE") {
parseLWPolyline(allCodes.mid(i), allValues.mid(i), result);
} else if (entityType == "SPLINE") {
parseSpline(allCodes.mid(i), allValues.mid(i), result);
}
}
return true;
}
六、這個(gè)Demo如何幫助排障?
加入DXF驗(yàn)證之后,整個(gè)排障路徑會(huì)清晰很多。
如果第三方驗(yàn)證器能讀到實(shí)體,但正運(yùn)動(dòng)CAD庫導(dǎo)入為空,說明文件本身大概率不是空的。
這時(shí)候應(yīng)該重點(diǎn)檢查:
?導(dǎo)入?yún)?shù)是否合適。
?精度設(shè)置是否過粗。
?是否存在 SPLINE、ELLIPSE等復(fù)雜實(shí)體。
?是否需要將曲線轉(zhuǎn)換成線段。
?程序是否漏讀了某些返回字段。
如果第三方驗(yàn)證器也讀不到實(shí)體,那排查方向就應(yīng)該回到DXF文件本身。比如:
?文件是否為二進(jìn)制DXF。
?是否只有BLOCK定義但沒有實(shí)際插入。
?是否只有文字、標(biāo)注等非幾何實(shí)體。
?是否需要另存為ASCII DXF R12/R14。
?是否需要在CAD軟件里先執(zhí)行炸開或轉(zhuǎn)換。
如果圖形預(yù)覽正常,但設(shè)備執(zhí)行異常,那問題就不應(yīng)該繼續(xù)糾結(jié)在文件層。
這時(shí)候應(yīng)該看:
?X/Y軸脈沖當(dāng)量是否正確。
?最大速度和加速度是否合理。
?回零速度是否匹配當(dāng)前設(shè)備。
?進(jìn)給速度和主軸轉(zhuǎn)速是否符合工藝。
?控制器IP和連接狀態(tài)是否正常。
?運(yùn)動(dòng)控制指令是否正確執(zhí)行(檢查函數(shù)返回值是否為零)。
這樣一來,原本模糊的“跑不了”,就可以被拆成更明確的問題類型。

教學(xué)視頻請(qǐng)點(diǎn)擊→ARM工控機(jī)Linux下從CAD圖紙到運(yùn)動(dòng)加工(一):Qt Demo的CAD導(dǎo)入

正運(yùn)動(dòng)技術(shù)專注于運(yùn)動(dòng)控制技術(shù)研究和通用運(yùn)動(dòng)控制軟硬件產(chǎn)品的研發(fā),是國家級(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)控制卡等等。