C言語でグラフを描こう(gnuplot)
こちらは
14日目の記事です。
今日も雑です(すいません)
最近ですが、ロボットの軌道シミュレータを作りました。
マイクロマウス界隈では、スラロームシミュレータと呼ばれます。
対抗二輪のロボット(二つのタイヤを、別々のモータで回すロボット)で、カーブする動きを作るために使います。上の画像は、(x:0mm、y:0mm)から(x:90mm,y:90mm)の位置に曲線を描いてロボットが進むところをシミュレーションしているところです。
本題はこれではなくて、これをC言語とgnuplotというものを使って作ったということです。
参考にしたのはコチラ...
http://www.yamamo10.jp/yamamoto/lecture/2007/5E_comp_app/gnuplot/html/node4.html
そのサイトでは、yの値をsin(x)に入れて求めるだけですが、シミュレータでは円の軌道が描かれています。
やり方としては、機体の向きを示したベクトルに微小時間Δtあたりに進む距離をかけて、機体位置座標(x,y)を足すことでt秒後の位置を求めています。
試しに、微小時間Δtごとにx、y点をプロットし、円を表示してみます。
角速度ωを一定にして機体の向きのベクトルを回転させながら、x、yの値を求めます。
・方向ベクトルはΔtごとにωΔtだけ回転
・円の移動の速さを100とすると、機体の向きのベクトルかけるΔtかける移動の速さ100でΔtのうちに移動する大きさと向きをもったベクトルが得られる。
まあ、試しに動かしてみてください。
雑に貼り付けておきます。
#include <stdio.h>
#include <math.h>
#define NX 3600
#define DELTA_T 0.001
#define OMEGA M_PI/2.0
#define CENTER_SPEED 100
int main(void){
FILE *gp;
int i;
double x=0.0, y=0.0;
double vector_x, vector_y;
double theta = M_PI/2.0;
gp = popen("gnuplot -persist","w");
fprintf(gp, "set xrange [-500:500]\n");
fprintf(gp, "set yrange [-500:500]\n");
fprintf(gp, "set size ratio -1\n");
fprintf(gp, "plot '-' with lines linetype 1 title \"sin\"\n");
for(i=0; i<=NX; i++){
theta += OMEGA*DELTA_T;
x += CENTER_SPEED*DELTA_T * cos(theta);
y += CENTER_SPEED*DELTA_T * sin(theta);
fprintf(gp,"%f\t%f\n", x, y);
}
fprintf(gp,"e\n");
pclose(gp);
return 0;
}
円になってないです。ΔtをNX回繰り返したので、NXΔtの時間だけ進んだらそこでプロットが終了します。今回はΔtを0.001sと考えると、3600回繰り返したので、3.6秒分の移動の軌道がプロットされました。
あ、あと
fprintf(gp, "set size ratio -1\n");
をするとx、yの縦横比が同じになります。円を表示するはずが楕円が表示され、なんでじゃ~っと思っていたら縦横比が違いました。
そんなとこですかね...。
今回は、C言語でグラフ描けるじゃん、というのを紹介したかっただけです。
「シミュレータ作りたいけど、GUIとかよくわからない...。でもC言語でsin波描けたしゴリ押しで作れるかも」という始まりでどうにかなったので、ちょっと知っているというのはまああとで役に立つかもです。
ああ、あとは、gnuplotではアニメーション(gif)を作れるようです。
それ使って3次元で物理の現象とかシミュレーションできたら面白いだろうなあ...。