2009年5月17日 星期日

B-spline 曲線

最近有人丟了一個很有趣的文章給我看,他的路徑規劃使用B-spline曲線來做。


似乎很有趣,不知道如果把B-spline曲線丟到老鼠的路徑規劃裡,是不是就可以讓動作可以更平滑一點?


找了一點資料,索性就開起matlab 來求救了,沒想到打 help spline 竟然有範例。


那就改了一下範例:


       x = -4:4; y = [0 15 0 -15 0 15 0 -15  0];
       cs = spline(x,[0 y 0]);
       xx = linspace(-4,4,100);
       plot(x,y,'o--',xx,ppval(cs,xx),'-');



假設動作為1連續V-turn。看B-spline曲線劃出來的似乎還好,不過如果調整頂點的位置,應該就可以讓路徑更短。


       x = -4:4; y = [0 15 0 -15 0 15 0 -15  0];
       x1=-4:4;y1=[0 11 0 -11 0 11 0 -11  0];
       cs = spline(x,[0 y 0]);
       cs1 = spline(x1,[0 y1 0]);      
       xx = linspace(-4,4,100);
       xx1 = linspace(-4,4,100);
       plot(x,y,'o--',xx,ppval(cs,xx),'-',x1,y1,'ro--',xx1,ppval(cs1,xx1),'m-' );



 


 


果然直接看數學模型真的很吃力,還是找找現成的範例比較容易看懂。


至於好不好,還要再討論嚕!
 


2009年5月16日 星期六

malloc

最近想優化電腦鼠的程式,因為最近在製作斜線的時後複製了45度、90度、135度、180度的副程式,還分成左轉、右轉,所以一共有8個類似的副程式,可是裡面的用法其實都一樣,但是就是裡面部分的參數不同而已。


本來想改成副程式,利用return,回傳計算後的參數,但是因為return同一時間只能回傳一個變數,所以就請教黃老師,老師提供一個有趣的方式:動態記憶體的分配方式(allocates memory )。老師是用c++的程式寫給我參考。以下是範例程式:


int* p1()
{
    int *array;
    array = (int*) malloc (sizeof(int));
    *(array+0)=10;  //a[0]
    *(array+1)=11;  //a[1]
    *(array+2)=12;  //a[2]
    return array;    


}
void p2()
{
    int* b;
    b = p1();
    cout<<*(b)<<" "<<*(b+1)<<" "<<*(b+2)< }


查了一下,通常要使用malloc( ) 通常需要配合一個free( )的函式(記憶體有借要有還),可是寫在副程式裡好像rerutn的時後,就把空間還給主程式了。


不過比較困擾我的是,只要用到malloc( ),不管大小,至少都需要一定的時間,才會完成分配動態記憶體的工作。另外我在試float的時後也不是很成功,數值一直傳錯,真的還需要好好研究一下。



這東西還滿有趣的,如果不知道陣列大小的話,用這方式似乎可以節省記憶體空間。不過……不熟悉用法,用起來問題還滿多的;還是別想太多把變數直接宣告成global,這樣也不用管要回傳幾個值,把參數pass進去就好。


不知道如果我需要回多2個以上的變數的話,有沒有其他比較好的方式可以使用。


產生三相弦波的PWM法則

參考"Simple Analytical and Graphical Methods for Carrier-Based PWM-VSI Dirvers"來模擬其他加入不同零序成份的Sinusoidal PWM。除了之前的SPWMSVPWM還有其他的方式可以產生。


零序成份 加入1/6的三次諧波。



零序成份 加入1/4的三次諧波。


以下是幾種都是非連續的PWM,其目的是希望可以在電流最大的時後,以不切換開開以降低切換損。


其概念皆大同小異,只是在不同的角度不做切換而已。






在跑模擬的過程中發現,即使程式寫錯了,反正只要三相同時加入的零序成份一樣的話,2相參考波相減一樣可以得到一個漂亮的弦波,只是說在跑模擬的時後並沒有考慮PWM的波形是否會失真的問題。其實Sinusoidal PWM沒有想像中的複雜,抓到零序成份就可以搞定了。 不過這箇中奧妙可能就不是這麼簡單了。


2009年5月15日 星期五

斜線路徑規劃

假設不做斜線運動的話,在提升轉彎速度是一件非常困難的事情。


所以這次的重心就放在斜線的運動上


繼上一篇座標轉換,將原本的4個絕對方向轉換成8個絕對方向



為了讓程式方向判斷,我讓這8個方向定義成角度,以方便在轉換成相對動作時,比較好思考。


絕對方向轉相對動作我是使用,現在的角度-過去的角度,即可求得相對動作。


不過比較需要注意的就是溢位的問題,所以需要加入一點判斷式


 


if ((現在的角度-過去的角度) >360)  (現在的角度-過去的角度)-360;


else if ((現在的角度-過去的角度) <-360)  (現在的角度-過去的角度)+360;


 


因為得到的都是角度,所以當現在的角度-過去的角度得到為-45度時,即可知道是右轉45度。


反之,現在的角度-過去的角度得到為45度時,即可知道為左轉45度。


在絕對方向轉相對動作大概有這幾種動作需要轉換


90度轉→連續的2個同方向的45度轉,可以視為1個90度轉的動作


 


45度轉


V-turn→斜線運動的90度轉,其實這和正常的90度轉差不多。


J-turn→45度轉+90度轉,可以視為一個135度的動作




U-turn→45度+90度轉+45度轉,可以視為一個180度的動作




以下是我定義的動作。


這是由直線變到斜線的動作


這是由斜線變成直線的動作


另外還2個U-turn的動作


大至上我的斜線動作已經完成,在規劃這些動作時,思考規劃動作是最浪費時間的。如果用以往的if then else 寫的話,可能真的會寫到爆掉,而且在維護上也非常困難。老大提供這個座標轉換的方式確實方便實用。



 



 


看著老鼠可以衝斜線,還滿開心的,接著可以挑戰轉彎的極速了。光增加了斜線運動,最短路徑的轉彎速度至少比以前提升30%~50%之多(我認為)。


或許有些人看到電腦鼠覺得沒什麼,可是當深入其中的時後,卻愈做愈覺得有趣。一直到現在,我心中的疑問老是:「為什麼別人的老鼠的動作可以這麼順暢,怎麼做到的」。等一步一步解開問題的時後,真的會豁然開朗。


下一步需要解惑的是,為何別人的斜線動作很smooth,而我的動作卻很急燥。哈,或許老鼠和主人的個性一樣,暴燥卻不肯安定。