忍者ブログ

明日の設計図

たまにロボットを考えるブログ・・・。

[PR]

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

コメント

現在、新しいコメントを受け付けない設定になっています。

mbed備忘録7:KONDOシリアルサーボはじめました

ジャイロを買って、サーボも買って、mbedもかって・・・

シリアル用の回路つけてなんにもしてない日々が流れていたので、ちょっとあそびました。

◆まずはじめに、近藤の半2重通信をmbedにどうつなぐかです。
回路図はこんな感じ
mbedからの信号を5Vにしつつ半2重通信をします。
なぜそういうことをしようと思ったのか、それはもう思い出せません。

 
↑は赤がサーボのピン、緑がマイコンのRXD、青がマイコンのTXDそれぞれの電圧です。
マイコンから出た信号がマイコンに入っていますが、まー読まないから関係ないと思います??
ほんとかなぁ。

◆ほんでもって、ICS3.5をさーぼとやるので、シリアルをはいてやる必要があります。
コマンド方式サーボKRS-6003HVの制御 その1
こちらのプログラムを参考にさせていただきました。

また、本家のリファレンスも参考にしました。

ざっくり、こんな感じ
Serial ko(p9,p10);//txrx

void setServoDeg(float deg)//+-135deg
{
    deg=deg+135;
    if(deg>270)deg=270;
    if(deg<0)deg=0;
    targetPosi = 3500 + (int)((deg*800)/27);
}

//↑3500~11500で0~270°動きます。

float getServoDeg(void)
{
    return (((float)(feedbackPosi-3500)*27)/800)-135;
}

/*----------------------------------*/
/* KONDOと角度                      */
/*----------------------------------*/
int set_posi(char id, int pos)
{
  unsigned char tx[3];
  unsigned char rx[6];
  int i;
  int data=0;
 
  tx[0] = 0x80 | id;
  tx[1] = (unsigned char)( (pos >> 7) & 0x7f);
  tx[2] = (unsigned char)(pos &0x7f);
 
  for(i = 0; i<3; i++){
    ko.putc(tx[i]);
  }
  //wait(16);
  for(i = 0; i<6; i++){
    rx[i] = ko.getc();
  }
 
  data = (int)(rx[4] & 0x7f);
  data = (data << 7) + (int)(rx[5] & 0x7f);
 
  return data;
}

int main(){

ko.baud(115200);
ko.format(8, Serial::Even, 1);

setServoDeg(もくひょうかくど);
feedbackPosi=set_posi(1, targetPosi);

↑それっぽいところだけ抜粋。
変数の宣言とか足りないと思う。

◆動かすだけじゃつまらないので、ジャイロとコラボしました。


カメラのジンバルっていうか、そんな感じの動画。
ジャイロの角速度"積分値"を、角度として入力すると、
回路の動いた角度だけ、サーボは逆転動作します。
つまり動いてないかのよう。
今回は5msごとにジャイロ取得、サーボに指令してます。
積分は何にも考えないで、
Σ(現在のジャイロ値×0.005)
です。



ジャイロは角速度を電圧にするんですけれでも、
ドリフトっていって動いてない時の電圧がだんだん増えていく弱点があります。

そこで、ハイパスフィルターとか淹れてみようって準備しました。
けど、動画の通りそこまで必要じゃなかったかっていう。

◆ハイパスフィルター
ゆっくりした変化を無視する方法がハイパスフィルターです。

こちらのプログラムを参考にしました。
簡単なデジタルフィルタの実装

ざっくりこんな感じで真似させていただきました。
// それぞれの変数は下記のとおりとする
// float samplerate … サンプリング周波数
// float freq … カットオフ周波数
// float q    … フィルタのQ値
float omega,alpha,a0,a1,a2,b0,b1,b2;
float freq=.01;
float q=0.7071;
float samplerate=200;
/*----------------------------------*/
/* ハイパスフィルターセット            */
/* Data入力                         */
/*----------------------------------*/
void setHPF(void)

omega = 2.0 * 3.14159 *  freq/samplerate;
alpha = sin(omega) / (2.0* q);
 
a0 =   1.0 + alpha;
a1 =  -2.0 * cos(omega);
a2 =   1.0 - alpha;
b0 =  (1.0 + cos(omega)) / 2.0;
b1 = -(1.0 + cos(omega));
b2 =  (1.0 + cos(omega)) / 2.0;
}
float in1=0,in2=0,out1=0,out2=0;
/*----------------------------------*/
/* ハイパスフィルタ出力            */
/* Data入力                         */
/*----------------------------------*/
float outHPF(float input)
{
// それぞれの変数は下記のとおりとする
//  float input[]  …入力信号の格納されたバッファ。
//  flaot output[] …フィルタ処理した値を書き出す出力信号のバッファ。
//  int   size     …入力信号・出力信号のバッファのサイズ。
//  float in1, in2, out1, out2  …フィルタ計算用のバッファ変数。初期値は0。
//  float a0, a1, a2, b0, b1, b2 …フィルタの係数。 別途算出する。
// 入力信号にフィルタを適用し、出力信号として書き出す。
float output;
output = b0/a0 * input + b1/a0 * in1  + b2/a0 * in2
                             - a1/a0 * out1 - a2/a0 * out2;
 
in2  = in1;       // 2つ前の入力信号を更新
in1  = input;  // 1つ前の入力信号を更新
 
out2 = out1;      // 2つ前の出力信号を更新
out1 = output; // 1つ前の出力信号を更新

return out1;
}

ハイパスフィルターですから動画見たいに、動きが無くなる=高周波成分は0になろうとします。

普通はローパス分を別のセンサーとかを入れて相補するっぽいですが難しいことは・・・。


◆◆◆想像以上に積分値安定してるんで感動した。



拍手[0回]

PR

コメント

お名前
タイトル
文字色
メールアドレス
URL
コメント
パスワード Vodafone絵文字 i-mode絵文字 Ezweb絵文字

プロフィール

HN:
Adel
年齢:
35
性別:
男性
誕生日:
1989/09/17
職業:
会社員
趣味:
モチベーション探し
自己紹介:
ロボットつくるのが夢

ブログ内検索

アクセス解析