下記プログラムについてご教授をお願いいたします
お世話になります。
すいません。下記のプログラムにおいてお聞きしたいことがあります。(プログラムの記述の順は無視してください。)
void int_tim_b1(void)がタイマーによって10ms毎に呼ばれ、void control_pid(void)の
関数処理が始まり、float TBL_target(float sec, tbl_target *tbl)にテーブル値を引数として
渡すようなのですが、float TBL_target関数において府に落ちない点があります。
例えば、10ms経ち、引数secに0.01が入り、if(sec > tbl[i].time)の条件においてi = 0なので、
tbl[i].time == 0なので、次のif(0 > tbl[i].time)が判定されますが、これは「偽」ですので、
処理はされず、次のelse if(i == 1)もまだi == 0なので、実行されず、elseの中が処理されると
思うのですが、tbl[i-1].target、tbl[i-2].target等の処理は配列の要素の中身が負となってしまうと思うのですが、
違いますでしょうか?
又、else if(i == 1)の処理もtbl[i-1].target == 0となってしまい、次の割り算処理において
「0/0」の0割り処理となってしまう気がいたします。
自分の理解が間違っていると思うのですが、何分わからず、大変困っております。
何卒ご教授のほどよろしくお願いいたします。
typedef struct {
float time;
float target;
} tbl_target;
void control_pid(void);
float TBL_target(float sec, tbl_target *tbl);
const tbl_target tbl_target_angle[ ] = {
/* time[sec], target_angle[m/sec] */
0, 0,
4.99f, 0,
5, PI/2,
10, PI/2,
15, 0,
20, 0,
-1, -1,
};
#pragma interrupt(INT_TimerB1)
void int_tim_b1(void)
{
IRR2.BIT.IRRTB1 = 0; /* 割り込み要求フラグクリア*/
if(c_start)
{
control_pid(); c_time += 10;
}
}
void control_pid(void)
{
theta_ref = TBL_target((float)c_time / 1000, tbl_target_angle); /* 目標値*/
}
float TBL_target(float sec, tbl_target *tbl)
{
int i;
float a, b;
i = 0;
while(1){
if(sec > tbl[i].time){
if(0 > tbl[i].time){
/* -1:テーブル終端の場合 */
if(i == 0){
/* テーブルデータなし */
return 0;
}
else if(i == 1){
/* 初期値は0として直線補間 */
a = tbl[i-1].target / tbl[i-1].time;
b = 0;
return a * sec + b;
}
else{
/* 前2点で直線補間 */
a = (tbl[i-1].target - tbl[i-2].target) /
(tbl[i-1].time - tbl[i-2].time);
b = tbl[i-1].target - a * tbl[i-1].time;
return a * sec + b;
}
}
i++; /* 次のデータへ */
}
else if(sec == tbl[i].time){
/* テーブルデータと同じ場合 */
return tbl[i].target;
}
else{
if(i > 0){
/* 前1点で直線補間 */
a = (tbl[i].target - tbl[i-1].target) /
(tbl[i].time - tbl[i-1].time);
b = tbl[i].target - a * tbl[i].time;
return a * sec + b;
}
else{
/* 前1点は0として直線補間 */
a = tbl[i].target / tbl[i].time;
b = 0;
return a * sec + b;
}
}
}
}
お礼
回答ありがとうございます! 助かりました! 重ねて質問ですが、3重ループにしようと思ったら またAFTER~とすればいいのでしょうか?