一、 直線/圓弧插補(bǔ)與矢量速度
直線插補(bǔ)的矢量速度,本人在《如何正確計(jì)算及設(shè)置DMC1000插補(bǔ)的矢量速度》中有介紹,雖然DMC3000通過改進(jìn),解決了矢量速度的問題,但實(shí)際編程應(yīng)用時(shí),由于參與插補(bǔ)運(yùn)動(dòng)的多軸驅(qū)動(dòng)軸脈沖當(dāng)量不一致,使用戶在設(shè)定速度時(shí),不知如何選擇恰當(dāng)?shù)拿}沖當(dāng)量進(jìn)行計(jì)算和設(shè)定。此問題的解決亦可參照《如何正確計(jì)算及設(shè)置DMC1000插補(bǔ)的矢量速度》的思路及算法,從而可以解決矢量速度的計(jì)算問題。只是程序員務(wù)必考慮大數(shù)的平方溢出的問題,此問題在《四個(gè)編程問題,請(qǐng)稍加留意》一文中得到解決,請(qǐng)參考之。
對(duì)于圓弧插補(bǔ),從原則上必須是兩軸脈沖當(dāng)量一致,否則作出的圓弧為橢圓。解決它的矢量速度其計(jì)算方式較復(fù)雜,大量的計(jì)算會(huì)耽誤較多的CPU運(yùn)算時(shí)間,為此,大連理工的曾工提出一簡(jiǎn)單可行的方法,增加一系數(shù)參數(shù)供外部設(shè)置,具有較好的靈活性,我們?cè)诖私ㄗh也這樣作。
在此,非常感謝曾工的積極參與和支持。
二、 圓弧插補(bǔ)的兩個(gè)問題
這兩上問題都是由于脈沖當(dāng)量的計(jì)算引起的誤差造成的,一般用戶在編程應(yīng)用時(shí),都設(shè)有一個(gè)脈沖當(dāng)量的設(shè)置,以方便把用戶慣習(xí)單位轉(zhuǎn)成脈沖單位,常見的諸如:毫米單位通過每毫米脈沖數(shù)轉(zhuǎn)成脈沖,如下所示:
long CCtrlCard::M2P( int nAxis, double fMM ) //毫米轉(zhuǎn)脈沖
{
return long( fMM * m_axis[ nAxis ].fUnitPM );
// fUnitPM為指定軸的脈沖當(dāng)量(每毫米脈沖數(shù))
}
如此以來,對(duì)于封裝類所有成員函數(shù)的參數(shù)都可以由毫米作為單位,像tag_ARC、tag_SPEED(圓弧/速度)結(jié)構(gòu),都可以用毫米作單位。
但是,由于計(jì)算精度的問題,由浮點(diǎn)數(shù)計(jì)算完成后再取整,往往會(huì)產(chǎn)生誤差,此誤差對(duì)于圓弧插補(bǔ)的情況會(huì)出現(xiàn)意想不到的情況,待會(huì)兒一一列出,但對(duì)于浮點(diǎn)取整的誤差可簡(jiǎn)單處理之:
long CCtrlCard::M2P( int nAxis, double fMM ) //毫米轉(zhuǎn)脈沖
{
return long( fMM * m_axis[ nAxis ].fUnitPM +(fMM>0?0.5:-0.5));
}
通過以上方法,對(duì)于下面所示情況就有明顯改善了:
double pk = 1.99999-1.00000;//誤差幾乎接近一個(gè)脈沖了
int( pk ) = 0;//直接取整,會(huì)導(dǎo)致脈沖缺失
int( pk + (pk > 0?0.5:-0.5 ) ) = int( pk+0.5) = 1;//取得最小的誤差
以上取整方法我們暫命名為0.5取整法(呵呵,臨時(shí)想的,臨時(shí)用麻)
1、 360度整圓情況
圓弧往一個(gè)方向可以作整圓,換一個(gè)方向一下子就運(yùn)動(dòng)結(jié)束了,則現(xiàn)像正是由于圓弧起點(diǎn)和終點(diǎn)不重合而引起的,若以上0.5取整法不能解決,請(qǐng)用下面的方法解決。
void CCtrlCard::Arc( short nAxis1, short nAxis2,//圓弧插補(bǔ)
const tag_ARC &arc, const tag_SPEED &speed,
double dt)
{
short axisArray[]={ nAxis1, nAxis2 };
long ex = d3000_get_command_pos( axisArray[0] );//取得當(dāng)前位置
long ey = d3000_get_command_pos( axisArray[1] );
if( (arc.dir&0x02) )//若為整圓,在arc.dir的第1位上置1,if( 整圓 ) arc.dir |= 0x02;
;
else{//非整圓
ex = M2P(nAxis1, arc.ex);
ey = M2P(nAxis2, arc.ey);
}
d3000_start_ta_arc( axisArray,
M2P(nAxis1, arc.ox),
M2P(nAxis2, arc.oy),
ex,
ey,
(arc.dir&0x01),//只保留第0位作方向判斷
M2P(nAxis1, speed.start),
M2P(nAxis1, speed.speed),
speed.accel,
speed.accel);
return ;
}
ARC和SPEED結(jié)構(gòu)在《一個(gè)DMC3000控制卡類的完全源代碼》一文中有聲明。
2、 非整圓情況下
由于起點(diǎn)到圓心的距離R1與終點(diǎn)到圓心的距離R2不相等(哪怕只相差一個(gè)脈沖),此圓弧插補(bǔ)行為不可預(yù)定(可能會(huì)不運(yùn)動(dòng),可能會(huì)連續(xù)走)。此問題若用0.5取整法不可解決,則用下面方法解決:
//計(jì)算起點(diǎn)到圓心的半徑
double R1 = sqrt( (startX-orginX) * (startX-orginX)+(startY-orginY)*(startY-orginY) );
//注意這樣的運(yùn)算易引起溢出,在此僅為演示,解決方法已有介紹
double pi = atan2( endY-orginY, endX-orginX );//計(jì)算終點(diǎn)到圓心的斜率
endX = orginX + R1 * cos( pi );//計(jì)算得到新的終點(diǎn)位置
endY = orginY + R1 * cos( pi );
//計(jì)算新的終點(diǎn)位置不會(huì)與原點(diǎn)的相差太多,不用擔(dān)心,因?yàn)槲覀兊哪繕?biāo)就是控制1個(gè)脈沖誤差。當(dāng)然,以上的計(jì)算是建立在脈沖為單位的基礎(chǔ)上,不要以毫米數(shù)為單位,否則就沒有效果了(呵呵)。
補(bǔ)充一個(gè)小問題,若脈沖模式設(shè)定不正確,圓弧插補(bǔ)將會(huì)在每個(gè)90度位置發(fā)生很明顯的軌跡平移。
|