スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

DSP処理速度上がらず

DTC+DSPによるエンコーダ処理の高速化プログラムを作っている.
動作するプログラムはできたが,DSPを使う部分で逆に処理が遅くなってしまっている.

調べてみるとDSPにデータを入れた後の積和演算は目論見どおり劇的に速くなっているが,
その前処理のデータ並び替えに時間がかかり,全体としてのパフォーマンスが下がっていることがわかった.
DTC→【前処理 x DTC転送データ数】→DSP→後処理

 リングバッファの循環アドレスをリニアに展開する処理,Inputキャプチャのタイマカウンタの差分を取る処理,回転方向判別と補正用LUTの並べ替え処理などをForループ内でDTCで転送したデータ数ぶん実行しているが,データ個数が多くなるほど時間がかかり,DSPの足を引っぱっている.
理想的にはこうした変換処理はゼロにしてDTC→DSPとダイレクトにデータを流したい.
しかし,現状のアルゴリズムでは条件分岐が入るためソフトの介在がどうしても必要になる.

今一度アルゴリズムをゼロから見直し,なんとかDSPのメリットが活きる形にもって行きたい.
スポンサーサイト

RXのDSP命令を試す

これまでにDTCを使ってまとまったデータ転送ができるようになった.
次のステップとしてRXのDSP命令を使い高速で積和演算を行わせたい.

そこでまずはDSPの計算時間をLチカ間隔で測定した.
符号付16bit整数の積和演算10回にかかった時間は次のとおり.



DSPを使うと,ソフトウェアで積和した場合に比べ1/5程度の演算時間で済んでいる.
しかし,一番右のグラフにあるように積和を1回ごとにDSP命令で逐次行った場合はソフト(乗算命令)よりも逆に時間がかかる結果となった.
DSP命令はデータロードに一定の計算コストがかかるためか,データ数が多くないと効果を発揮できないことがわかった.

これを見る限り積和したいデータを事前に並び替えて,アドレスが連続したRAMに配置しておくことが重要になりそうだ.

転送三昧

今日は昨日の続きでRXのDTCをいじる.
ルネサスのサンプルプログラムではチェーン転送をうまく使いレジスタを制御している.
この手法にインスパイアされ,MTUの割り込みフラグをDTCからクリアしてみることに.
しかし,なぜか割り込みフラグのあるレジスタに別の変数を介して値を転送しても反映されない.
ここでマニュアルとにらめっこすることしばし,「フラグを読んだ後0を書くとクリア」という文言を発見.
DTCで一度レジスタ値をダミーリードしてから0を書くとちゃんとクリアされることが分かった.

一連の試行錯誤でDTCの使い方にだいぶ慣れてきた.

RXのDTCを使う

フィルタによるサーボ性能改善は一定の効果が確認できたため,フィルタの設計パラメータ入力機能をマイコンに実装した.

さて,ここで前から気になっていた制御周期UPのアイデアを試すことにする.
これを実現するために,RXのDTC機能を使いエンコーダ周りの割り込み処理を完全にCPUと切り離したい.
DTCをInputCapture割り込みで起動してタイマカウンタ値をRAMに自動転送させる.
RAM構造をリングバッファにしておいて,制御のメインルーチンで速度に変換する.

DTCの動作確認まではサンプルプログラムのコピペで問題なく進んだ.
しかし,いざCPUへの割り込みをなくす段で問題発生.
システム側の割り込みフラグIRはDTC転送が終わると自動でクリアされるのに,MTUの割り込みフラグTGFnは自動クリアされずユーザソフトでクリアする必要があるのだ.
これではDTC単体でMTU3からデータを連続転送できないではないか!
なぜこういう仕様になっているのか疑問だが,このままではらちが明かない.
何とか解決策のアイデアを捻り出したい.

振動対策_その2

今日はプロッタアームのブルブル対策その2として,ディジタルフィルタによる振動成分の除去を試してみる.
 ディジタル信号とかフィルタとか言うと小難しいイメージがあるが,難しいのはフィルタ係数を設計する段であり,いったん係数さえ求まればフィルタリング処理自体は数行のプログラムで難なく実装できる.
Cソースコードの例:
FIRフィルタ
/*
FIRフィルタの計算を行う
リングバッファを使えば配列の並び替えが不要(読み出し・書き込みが高速化)

x 入力信号
buf[] リングバッファ(配列サイズlength-1)
h[] フィルタ係数の入る配列(配列サイズlength-1)
unsigned int*ix リングバッファ書き込み・読み出しのためのポインタ
unsigned int length フィルタ・タップ長
*/
float fir(float x,float buf[],float h[],unsigned int *ix,unsigned int length)
{
float sum;
unsigned int i;

buf[*ix]=x;
*ix=(*ix+1)%length;
sum=0.0;
for(i=0;i < length; i++){
sum=sum+h[i]*buf[(*ix+i)%length];
}
return sum;
}

IIRフィルタ

float a1,a2;
float b0,b1,b2;
//**********160-240Hz フィルタ係数****************
a1=-0.50796622;
a2=0.5921698;
b0=0.7960849;
b1=-0.50796622;
b2=0.7960849;
float iir(float in,int mode)
{
float out;
static float in_old1,in_old2;
static float out_old1,out_old2;

if(mode==0){
in_old1=0.0;
in_old2=0.0;
out_old1=0.0;
out_old2=0.0;
}

out=b0*in+b1*in_old1+b2*in_old2-a1*out_old1-a2*out_old2;
in_old2=in_old1;
in_old1=in;
out_old2=out_old1;
out_old1=out;

return out;
}

上記のコードのようにフィルタ係数と過去の値を保持するバッファを用意して順番どおりに積和演算を実行するだけである.
(高速・高性能を狙うならDSPやその他専用プロセッサを使う必要があるが・・・)

今回フィルタの係数は こちらのサイト を利用して求めた.
今回は共振周波数らしき200Hz帯のみカットしたいため,BEF(帯域阻止フィルタ)を使う.
FIRフィルタではタップ数が多くなり位相遅れが大きすぎるため,IIRフィルタを使う.

2軸プロッタの速度ゲインを目いっぱい上げ,□を描かせて比較した結果
フィルタ無し

IIR BEF CutOFF=160~240Hz


フィルタが無い場合は途中からブイーンとけたたましい音がして盛大に波形が揺れているが,IIRフィルタで共振周波数をカットしたほうはほとんど振動していない.
いろいろ試してみたが,フィルタ無しに比べ2倍近いゲインまで上げることができ,サーボの追従性が大きく改善した.
また,外乱オブザーバ等の加速度フィードバックとも相性は良いようで,エンコーダ分解能が不足しがちな低速域でも発振しにくくなった.

ただし,デメリットもある.
同じゲインでフィルタ無しに比べると,共振しない部分での応答性は悪くなる.(負荷イナーシャ増大と同様の効果.)
また,ある一定以上ゲインを上げると共振周波数より低い,うなりのような振動が発生する.
そして最大の問題はフィルタ性能のチューニングが難しく時間がかかるということ.
トライアル&エラーをやるたびにWEBでフィルタ係数を計算してプログラムに打ち込むのがめんどくさ過ぎる.

やはりフィルタ係数自体はマイコンに計算させて,ユーザはカットオフ周波数や帯域幅のみ入力するというのが本来あるべき姿だ.

振動制御をいくつか試す

今週末はサーボ振動制御の技術をいろいろ試す.
プロッタの速度ゲインを上げていくとアームがキーンと音を立てて振動を始める場合がある.
そこで周波数を可変したSin波に対する応答で共振周波数を調べてみた.


結果はアームの姿勢によって少しずつ違うが,おおよそ上記のように200Hz付近に共振点がありそうだ.
この振動を抑えるために,加速度入力にフィルタをかけてみる.
制御周波数が1kHzなので,その1/4の250Hあたりをカットすべく4タップの移動平均をかける.

結果,200Hz付近の共振は収まった反面,制御性が大幅に悪化してカクカクの動きになってしまった.
ゲインを調整してみるもフィルタ無しよりも良い結果が得られない.
どうも単純な移動平均ではローパスになるため,共振周波数より上の制御周波数まで減衰させてしまうのがマズイような気がする.

もっと特定の共振周波数だけを急峻に減衰させるフィルタが必要だ.
プロフィール

もやね

Author:もやね
長野県在住の会社員(メカニカル・エンジニア).
ロボットは完全な趣味としてやってます.
E-mail:
mo_ya_ne[a]yahoo.co.jp
[a]⇒@

最近の記事
最近のコメント
最近のトラックバック
月別アーカイブ
カテゴリー
FC2カウンター
ブログ内検索
RSSフィード
リンク
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。