mind-tech

主にテクノロジーや啓発系、副業などのテーマ中心

アセンブラ言語でDCモータ制御

今迄、Arduinoでモータ制御をしてみたことはあったんですが、分かった気になって実際、内部処理がどうなってるのか全然分からない(笑)





ので、PICマイコンを使ってアセンブラ言語でモータ制御をしてみました。




MOSFETで簡単な電流増幅回路を作り、ライタソフトでプログラムをPICに書き込む。
特にアセンブラで短い命令コードからどのようにレジスタへ情報をやり取りさせるのか等、
良い勉強になった気がします。

LEDチカチカ、モータが動く。

これだけ見るとそれだけじゃないかで終わりますが、
正しく、回路設計や安全な処理(モータへの寄生ダイオードやリセットスイッチ付近のバイパスコンデンサ等)が出来てないと動かない。

問題を解決する際に、ソフトだけでなくハード的にも解決する選択所の多さなどが楽しさを引き出してるのかなーと思ったりします。

サークルのライブでギター弾いてきた

大学の頃、所属していたロバートジョンソン研究会というbluesオタクのライブがあり、久々に御呼ばれしてギターを弾いてきました。

参加者リスト

人の名前ぐらい黒枠で隠そうかと思いましたが、そんな事気にする人達でもないので省略笑
なかなか、研究の合間にギターの練習をするのが難しく、演奏はひどいものでしたが、何はともあれ楽しかった笑
同期がむちゃくちゃギターうまくなってて羨ましかったので、就職決まったらギターの練習頑張りたいと思った。 ライブリハーサル中
皆もノリノリ
そして、誰かがミスったり、ボケても、アホなノリで「ううぇ~い」って盛り上がろうとする雰囲気がとてもあったかくて素敵なサークルだなと思いました。
横浜国立大学の数ある音楽サークルの中で、このサークルにいれた事が良かったと思える1日だった。

ロバートジョンソン研究会

OpenGLを用いてC言語で矢印を描くプログラム

openglC言語を用いて矢印を描く必要があった。

以下の理由で、自分で関数を作成した。

  • 矢印を描く関数はopenglでは標準で用意されてない
  • webに落ちてるものはC++等が多く、Cで書かれているものは自分の望む挙動をしない
  • アニメーションで動作するプログラムがなかった

動作結果

最初に動作結果を載せる。挙動のさせ方は関数への引数で決まる。今回は円上の点を追うようにした。







openglの座標系は以下のようになっている
今回は以下のような設計にした。x,y平面上で動作する2Dモデルとする。

ここで、ちょっと戸惑ったのがopenglでは以下のようなへこみを表現できない問題がある
GL_POLYGONやGL_QUADSを使う場合、図のような内側にへこんだ図形は正しく描くことができない。
このような図形を描くときは、三角形に分割して、GL_TRIANGLE_STRIPなどを使って描く必要がある。
参照

ただ頂点だけを結んでPOLYGON表示させた場合

LINE_LOOPであれば描く事は可能

よって矢印を描く場合は、以下のように三角形と四角形に分けて描写した
以下、ソース。includeするヘッダーファイルが正しく表示されない為、以下のヘッダをincludeして利用してください
#include math.h
#include stdio.h
#include stdlib.h
#include GL/glut.h
#include GL/gl.h
/*  arrow.c   Copyright (c) 2012 by Chikara Morito All rights reserved  */

/*
x1,y1 始点の座標
x2,y2 動かしたい座標
length_arrow 矢全体の長さ
width_arrow 尾の幅
scele 比率...これを帰ると矢印の大きさが変わる
*/



#define KEY_ESC 27

void timer(int value){
glutPostRedisplay();
glutTimerFunc(10,timer,0);
}

void glDrawArrowd(float x1, float y1,float x2, float y2,float length_arrow,float width_arrow,float scale);


void display( void )
{
static float x,y;
static int deg;
glClear( GL_COLOR_BUFFER_BIT );
x = 10*cos(deg*M_PI/180);
y = 10*sin(deg*M_PI/180);
glDrawArrowd(0,0,x,y,8,2,1);

deg++;
if(deg == 360){
deg =0;
}
}


void myKbd( unsigned char key, int x, int y )
{
if ( key == KEY_ESC ) exit( 0 );
}


void myInit ( char *progname )
{
int width = 500, height = 500;

glutInitWindowPosition( 0, 0 );
glutInitWindowSize( width, height );
glutInitDisplayMode( GLUT_RGBA );
glutCreateWindow( progname );

glClearColor ( 0.0, 0.0, 0.0, 1.0 );
glutKeyboardFunc( myKbd );

glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( -20.0, 20.0, -20.0, 20.0, -20.0, 20.0 );
}

void glDrawArrowd(float x1, float y1,float x2, float y2,float length_arrow,float width_arrow,float scale)
{
double deg;
float length,width;
double sn,cs;
float ratio;

length = scale*length_arrow;
width = scale*width_arrow;
deg = atan2(y2-y1,x2-x1);
sn = sin(deg);
cs = cos(deg);
//矢印の傘の部分と棒の部分の長さの比率は1:2とする。
//普通に計算するとintの型変換で0になるのでratio変数へ格納
ratio = (float)2/(float)3;

glColor3f( 0, 1.0, 0 );
glBegin(GL_QUADS);
glVertex3f(x1+width/2*sn,y1-width/2*cs,0);
glVertex3f(x1+width/2*sn+ratio*length*cs,y1-width/2*cs+ratio*length*sn,0);
glVertex3f(x1-width/2*sn+ratio*length*cs,y1+width/2*cs+ratio*length*sn,0);
glVertex3f(x1-width/2*sn,y1+width/2*cs,0);
glEnd();

glBegin(GL_TRIANGLES);
glVertex3f(x1+ratio*length*cs,y1+ratio*length*sn,0);
glVertex3f(x1+width/2*sn+ratio*length*cs+width*sn,y1-width/2*cs+ratio*length*sn-width*cs,0);
glVertex3f(x1+length*cs,y1+length*sn,0);
glEnd();
glBegin(GL_TRIANGLES);
glVertex3f(x1+length*cs,y1+length*sn,0);
glVertex3f(x1-width/2*sn+ratio*length*cs-width*sn,y1+width/2*cs+ratio*length*sn+width*cs,0);
glVertex3f(x1+ratio*length*cs,y1+ratio*length*sn,0);
glEnd();

glFlush();
}


int main( int argc, char** argv )
{

glutInit( &argc, argv );
myInit( argv[0] );
glutDisplayFunc( display );
glutTimerFunc(1,timer,0);
glutMainLoop();

return( 0 );
}

windows7 cygwin環境でOpenGLを動かす

今回は以下の3つの理由でwindows7cygwin環境上でopenglの動作環境を構築した情報を載せる


  1. windows上でopenglを動かす場合、visual studioを用いた情報が多かった
    visual studioは有償&ツールは学習コストが高いので論外→やっぱりunixcygwin
  2. cygwinwindows7openglを動かす情報が少なく感じた
  3. 研究室の皆が同じ環境を再現できるよう備忘録


Cygwin はあらかじめ必用なパッケージを導入しておけば標準で OpenGL 及び GLUT を使ったプログラムがビルド可能
cygwinでGLUTを使うとか、色々なサイトでfreeglut入れないと、って書いてあるけど、無くても動く(確認済み)

ビルドを cygwin で行うか MinGW で行うかで若干の差異がある
普通に cygwin でビルドすると X11 アプリになる。この場合 X server を起こしておかないと実行が出来ない
MinGW (-mno-cygwin オプションを用いる)でビルドすると、通常の Windows アプリになる。この場合は cygwin による UNIX エミュレーションが利用できない
よって、cygwinインストール時に、以下のようにx環境を一緒に入れておく
cygwinのインストールはむちゃくちゃ時間がかかるので注意
Xが入っているかどうかの確認はcygwin起動時に、以下のコマンドでxtermを起動
startxwin
入っていない場合、cygwin本家からsetup.exeをダウンロード



GNU Cコンパイラを用いる場合、通常以下のコマンドでコンパイルを行う
gcc -o @ @.c -lglut -lGLU -lGL -lm
動作環境によっては、-lXmu,-lXi,-lXext,-lX11などのX Windowのライブラリのリンクが必要な場合もある また、ヘッダファイルやライブラリの場所が指定されていない場合には、次のように記述する必要がある
gcc -o @ @.c -I/usr/local/include -L/usr/local/lib -lglut -lGL -lXmu -lXi -lXext -lX11 -lm -lGLU
ここで以下のように怒られた
freeglut(./@.c):failed to open display''
これは、環境変数 DISPLAYが正しく設定できていないから
DISPLAYはXサーバが実際に描画するサーバ名
普通は X clientと X serverは同一のホスト(ローカルホスト)で動いているので、DISPLAY は :0.0 (=localhost:0.0) となっている
ここで、ipconfigで自分のローカルIPを指定してもエラーを吐かれたので、以下のようにして設定
export DISPLAY=:0
動いた実行結果を載せる
毎回、こんなリンクオプションとか書いてるのは疲れるのでmakefileを作成
makefileの暗黙ルールでTABが入るのでコピペ注意

こんな感じ
CC            = gcc
LDFLAGS = -L/usr/local/lib
BUILD_DIR = $(shell pwd)
LIBS = -lglut -lGLU -lGL -lXmu -lXi -lXext -lX11 -lm
OBJS = c4-2.o
PROGRAM = hoge

all: $(PROGRAM)

$(PROGRAM): $(OBJS)
$(CC) $(OBJS) $(LDFLAGS) $(LIBS) -o $(PROGRAM)

clean:; rm -f *.o *~ $(PROGRAM)

load: $(PROGRAM)
./$(PROGRAM) $(BUILD_DIR)
コンパイル
make
実行は
make load

降圧チョッパ回路を作ってみた

降圧チョッパ回路とは

交流の電圧は変圧器を使えば容易に変換できるが、直流では変圧器は使えない。 直流の電圧を変えるには専用の電気回路が必要であり、その回路がチョッパ回路。 昇圧、降圧、昇降圧チョッパのうち、今回は降圧回路を製作した。 最初に完成したものを載せておく。
この回路を用いて今回はモーターを動作させることを、また可変抵抗をいじることでモーターの回転速度を調節することを目標とした。

材料はロボ部屋から調達。
全体の回路図を以下に示す。


動作結果


三角波の確認

可変抵抗による指令値の調節の確認



PWM波の確認

モーターの回転の様子



こいつ、、、、う、、動くぞ!!!

全体図

2リンクマニピュレーターを動かしてみた

今回動かした2リンクマニピュレーターはこれ↓

基本的な理論は記事2リンクマニピュレータの位置制御と一緒。 目標の軌道は円軌道とした。


マニピュレータの関節の回転角はモータに取り付けられたエンコーダにより検出し, モータドライバ内部で速度フィードバックに利用されるとともに, カウンタボードを経由して PC に入力される.

PC は, それぞれのエンコーダからの信号より腕の軌道を計算し, D/A 変換ボードを通し, モータドライバに制御信号を出力する.

結果はこんな感じ。



円軌道を描く前に線が入ってるけど、これは初期位置からの軌道。

指令値と応答値がかなりずれてるけど、これはマニピュレーターがケーブルに引っ張られて慣性が変動してしまうから。
また姿勢の変動により慣性行列の値が変動するため。

位相進み補償器を用いて制御系を設計してみた

以下の図に示す制御系において、直列補償として位相進み補償を用いて制御系の設計を行った



この制御系が以下の仕様を満たすように制御系の設計を行う。



コントローラは以下の進み補償要素のみを用いる。



まず、ざっくりとおおまかな概念や理論についてまとめる。

位相進み補償とは

制御対象に対してあるブロック(補償器)を付加し制御対象の振る舞い(過渡特性)を改善するときに用いられる

位相進み補償の全体的な位置づけ

まず、制御系の特性改善に用いられる補償要素には、制御対象に対して直列に挿入する直列補償と、フィードバック経路に挿入するフィードバック補償がある。



そのうち、位相進み補償とは、直列補償に分類され、直列補償には進み補償と後れ補償がある。

その進み補償である。

位相進み補償の特性

位相進みの主な特性は、共振周波数近くの位相が増加することにより位相余裕が増えることで、安定度が改善される

以下に示す図には遅れ補償と進み補償の効果である。
具体的な理論、設計は置いておいて、つまり位相進み補償を加える事により、位相余裕を増加させる事ができる。

また、遅れ補償の場合、ゲイン余裕を増加させる事が出来る。

位相余裕、ゲイン余裕とは



ゲイン余裕や位相余裕について理解する事で安定性の程度を評価できる。


詳細の理論はここに分かりやすく書いてあるので割愛。要は、位相余裕、ゲイン余裕をコントローラーを設計して調節し、制御系を安定にさせましょうって事。

位相進み補償における設計手順

step1.
性能仕様に対する仕様が満たされるように, ゲイン kの値を決める.
step2.
kを用いて一巡伝達関数 のボード線図を描き, その位相余裕を評価する.
kp(s)の位相余裕と目標位相余裕を比較し 必要な位相進め角φを決定する
step3.
sinφ = (α-1)/(α+1)から, パラメータαの値を決める
step4.
位相進み補償では最も位相が進む角周波数で, ゲインが 10logα[dB]倍上がる。
そこで,位相進み補償後の新たなゲイン交差周波数をωmとおく。ωm = 1/(T√α)から, パラメータ T の値を決める
step5.
設計パラメータK,α,Tが定められたので,位相進み補償器を構成する

設計前と設計後の制御系の比較

ステップ応答を用いてコントローラーの有無による制御系の性能比較を行った。

オーバーシュート、立ち上がり、整定時間は以下のようになった。

位相補償器を設計、挿入する事でオーバーシュートが低減され、立ち上がりも早く、整定時間も早まる事が確認できた。

ボーデ特性の確認

設計したコントローラーを用いて制御対象のボーデ特性、コントローラーのボーデ特性、制御系全体のボーデ特性を確認した。

下の図から、位相余裕が40度程度に出来たことが確認できる。

Copyright ©mind-teck All rights reserved..
🔒プライバシーポリシー