C言語でグラフを描こう(gnuplot)

こちらは

adventar.org

14日目の記事です。

 

今日も雑です(すいません)

 

最近ですが、ロボットの軌道シミュレータを作りました。

 

f:id:SmarterThanMonkey:20181213171637p:plain


マイクロマウス界隈では、スラロームシミュレータと呼ばれます。

対抗二輪のロボット(二つのタイヤを、別々のモータで回すロボット)で、カーブする動きを作るために使います。上の画像は、(x:0mm、y:0mm)から(x:90mm,y:90mm)の位置に曲線を描いてロボットが進むところをシミュレーションしているところです。

 

本題はこれではなくて、これをC言語gnuplotというものを使って作ったということです。

 

参考にしたのはコチラ...

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;
}

 

f:id:SmarterThanMonkey:20181213215357p:plain

 

円になってないです。Δ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次元で物理の現象とかシミュレーションできたら面白いだろうなあ...。