<<前へ
次へ>>
モーション作成用プログラム
サンプルプログラム(four_cr.c)
/*
4足歩行ロボットモーション作成プログラム
プロトタイプ(four_cr.c)
2003/10/06(Mon)
*/
#include<sci.c>
#include<3664.h>
#define MOTOR_NUM 12 /* モータの数 */
#define MOTION_NUM 16 /* モーション数の最大 */
#define MIN_P 600
#define PARA 20
/* パルスを MIN_P+PARA*データ で計算 */
unsigned char n=0; /* PWM出力時に足を指定するためのフラグ */
unsigned char motn=0; /* モーション指定用フラグ */
unsigned char m_num=0; /* モーション数 */
unsigned char ref=1; /* 繰り返し数カウント用 */
unsigned char exec=0; /* モーションをどこまで実行したかカウント */
unsigned char speed=0; /* どこまで補間したかカウント */
unsigned char mode_f=253; /* モード選択フラグ(デフォルト:ポーズ作成) */
int d_flag=0; /* シリアルのデータを区別するためのフラグ */
int r_data=0, r_loop=0, r_motor=0, stend=0;
int flag_se=0; /* 1:start位置から実行して、start位置に戻る */
int dammy1,dammy2;
unsigned char st[MOTOR_NUM]={90,150,120,90,150,120,90,30,60,90,30,60};
/* 初期値 */
unsigned int grbm[MOTOR_NUM];
int rc[MOTOR_NUM][MOTION_NUM]
/*={
{90,65,90,115},{120,150,150,150},{120,120,120,120},
{90,115,90,65},{150,150,120,150},{120,120,120,120},
{90,65,90,115},{30,30,60,30},{60,60,60,60},
{90,115,90,65},{60,30,30,30},{60,60,60,60}}*/
;
/* モーションデータ */
unsigned char speed_d[MOTION_NUM]
/*={3,3,3,3}*/
;
/* 1動作で何回割り込みをするか */
unsigned char exec_d
/*=MOTION_NUM*/
;
/* モーションをどこまで実行するか(データ数で) */
unsigned char ref_d=1;
/* モーションを何回繰り返すか */
int main(void)
{
long i;
int aa;
DI;
SCI3.SMR.BYTE=0x00; /* 調歩同期,8ビット,パリティなし,ストップビット1,クロックφ */
SCI3.SCR3.BYTE=0x00;
SCI3.BRR=12; /* 38400bps */
SCI3.SSR.BIT.OER=0;
SCI3.SSR.BIT.FER=0;
SCI3.SSR.BIT.PER=0;
SCI3.SCR3.BIT.RIE=1; /* シリアル割り込み許可 */
SCI3.SSR.BIT.RDRF=0;
SCI3.SCR3.BIT.TE = 1; // 送信許可
SCI3.SCR3.BIT.RE=1; /* シリアル受信許可 */
TW.TMRW.BYTE=0x48; /* FTIO端子は使用しない */
TW.TCRW.BYTE=0xBF; /* 内部クロックの1/8、割り込みフラグの全て(IMFA-D)の出力を1 */
TW.TIERW.BYTE=0x77; /* D以外の割り込みを可能に */
TW.TSRW.BYTE=0x70; /* 割り込みフラグをクリア */
TW.TCNT=0;
TW.GRA=6000; /* 3mS(18mSの1/6) */
TW.GRB=2400; /* 1.2mS(ニュートラル) */
TW.GRC=2400;
TA.TMA.BYTE=0x1B;
/* B5-7:このプログラムでは関係無い。
B4 :常に1
B3 :0ならインターバルタイマ、1なら時計用タイムベース
B0-2:B3が1の時はオーバーフロー周期の設定
000:1s 001:0.5s 010: 0.25s 011:0.03125s
*/
IRR1.BIT.IRRTA=0;
/* タイマA割込み要求フラグをクリア */
IENR1.BIT.IENTA=0;
/* タイマA割込み要求を不可 */
IO.PCR1=0xFF;
IO.PCR5=0xFF;
IO.PDR1.BYTE=0x00;
IO.PDR5.BYTE=0x00;
TW.TMRW.BIT.CTS=1;
EI;
for(aa=0; aa<MOTOR_NUM; aa++){
grbm[aa]=MIN_P+PARA*st[aa];
}
while(1){
;
}
}
void st_mot(){
int i,j;
for(i=0; i<MOTOR_NUM; i++){
grbm[i]=MIN_P+PARA*((rc[i][0]-st[i])*speed/speed_d[0]+st[i]);
}
speed++;
if(speed > speed_d[0]){
speed=1;
motn++;
}
}
void end_mot(){
int i,j;
for(i=0; i<MOTOR_NUM; i++){
grbm[i]=MIN_P+PARA*((st[i]-rc[i][exec_d-1])*speed/speed_d[exec_d-1]+rc[i][exec_d-1]);
}
speed++;
if(speed > speed_d[0]){
speed=1;
motn++;
}
}
void motion(){
int i,j;
for(i=0; i<MOTOR_NUM; i++){
if(exec==exec_d-1){
if(ref==ref_d-1){
j=exec;
}else{
j=0;
}
}else{
j=exec+1;
}
grbm[i]=MIN_P+PARA*((rc[i][j]-rc[i][exec])*speed/speed_d[exec]+rc[i][exec]);
}
speed++;
if(speed > speed_d[exec]){
speed=1;
exec++;
if(mode_f==249){
IENR1.BIT.IENTA=0;
/* タイマA割込み要求を不可 */
}
if(exec >= exec_d){
exec=0;
ref++;
if(ref >= ref_d){
ref=0;
motn++;
}
}
}
}
/* タイマAを用いて、指定時間ごとに次の足位置データを指定 */
void int_timera(void)
{
IRR1.BIT.IRRTA=0;
switch(motn){
case 0:
if(flag_se==1){
st_mot();
}else{
motn++;
}
break;
case 1:
motion();
break;
case 2:
if(flag_se>0){
end_mot();
}
break;
}
}
void int_timerw(void)
{
if(TW.TSRW.BIT.IMFB==1){
switch(n){
case 0:
IO.PDR5.BIT.B0=0;
break;
case 1:
IO.PDR5.BIT.B1=0;
break;
case 2:
IO.PDR5.BIT.B2=0;
break;
case 3:
IO.PDR5.BIT.B3=0;
break;
case 4:
IO.PDR5.BIT.B4=0;
break;
case 5:
IO.PDR5.BIT.B5=0;
break;
}
TW.TSRW.BIT.IMFB=0;
}
if(TW.TSRW.BIT.IMFC==1){
switch(n){
case 0:
IO.PDR1.BIT.B4=0;
break;
case 1:
IO.PDR1.BIT.B5=0;
break;
case 2:
IO.PDR1.BIT.B6=0;
break;
case 3:
IO.PDR1.BIT.B0=0;
break;
case 4:
IO.PDR1.BIT.B1=0;
break;
case 5:
IO.PDR1.BIT.B2=0;
break;
}
TW.TSRW.BIT.IMFC=0;
}
if(TW.TSRW.BIT.IMFA==1){
switch(n){
case 0:
IO.PDR5.BIT.B1=1;
IO.PDR1.BIT.B5=1;
break;
case 1:
IO.PDR5.BIT.B2=1;
IO.PDR1.BIT.B6=1;
break;
case 2:
IO.PDR5.BIT.B3=1;
IO.PDR1.BIT.B0=1;
break;
case 3:
IO.PDR5.BIT.B4=1;
IO.PDR1.BIT.B1=1;
break;
case 4:
IO.PDR5.BIT.B5=1;
IO.PDR1.BIT.B2=1;
break;
case 5:
IO.PDR5.BIT.B0=1;
IO.PDR1.BIT.B4=1;
break;
}
TW.TSRW.BIT.IMFA=0;
n++;
if(n>5){
n=0;
}
TW.GRB=grbm[n];
TW.GRC=grbm[n+6];
}
}
void int_sci3(void){
int dammy, aa,bb;
while(SCI3.SSR.BIT.RDRF!=1){
;
}
dammy=SCI3.RDR;
if(dammy==254){
r_loop=0;
r_data=0;
r_motor=0;
}else if(dammy==253){
DI;
IENR1.BIT.IENTA=0;
/* タイマA割込み要求を不可 */
TW.TMRW.BIT.CTS=1;
/* タイマW許可 */
EI;
mode_f=253;
}else if(dammy==252){
DI;
IENR1.BIT.IENTA=0;
/* タイマA割込み要求を不可 */
TW.TMRW.BIT.CTS=0;
/* タイマW不可 */
EI;
r_loop=0;
r_data=0;
r_motor=0;
mode_f=252;
}else if(dammy==251){
DI;
IRR1.BIT.IRRTA=0;
/* タイマA割込み要求フラグをクリア */
IENR1.BIT.IENTA=1;
/* タイマA割込み要求を許可 */
TW.TSRW.BYTE=0x70; /* 割り込みフラグをクリア */
TW.TMRW.BIT.CTS=1;
/* タイマW許可 */
EI;
mode_f=251;
motn=0;
ref=0;
exec=0;
speed=0;
}else if(dammy==250){
DI;
IRR1.BIT.IRRTA=0;
/* タイマA割込み要求フラグをクリア */
IENR1.BIT.IENTA=0;
/* タイマA割込み要求を不可 */
TW.TSRW.BYTE=0x70; /* 割り込みフラグをクリア */
TW.TMRW.BIT.CTS=1;
/* タイマW許可 */
EI;
for(aa=0; aa<MOTOR_NUM; aa++){
grbm[aa]=MIN_P+PARA*st[aa];
}
mode_f=250;
}else if(dammy==249){
DI;
IRR1.BIT.IRRTA=0;
/* タイマA割込み要求フラグをクリア */
IENR1.BIT.IENTA=1;
/* タイマA割込み要求を許可 */
TW.TSRW.BYTE=0x70; /* 割り込みフラグをクリア */
TW.TMRW.BIT.CTS=1;
/* タイマW許可 */
EI;
motn=0;
ref=0;
exec=0;
speed=0;
mode_f=249;
}else if(dammy==248){
DI;
IRR1.BIT.IRRTA=0;
/* タイマA割込み要求フラグをクリア */
IENR1.BIT.IENTA=1;
/* タイマA割込み要求を許可 */
EI;
mode_f=249;
}else if(dammy==247){
DI;
IENR1.BIT.IENTA=0;
TW.TMRW.BIT.CTS=0;
EI;
r_loop=0;
mode_f=247;
}else if(dammy<180){
if(mode_f==253){
if(d_flag==0){
dammy1=dammy;
d_flag=1;
}else{
dammy2=dammy;
grbm[dammy1]=dammy2*20+600;
d_flag=0;
}
}else if(mode_f==252){
if(r_data==0){
exec_d=dammy;
m_num=exec_d;
r_data=1;
}else if(r_data==1){
ref_d=dammy;
r_data=2;
r_loop=0;
r_motor=0;
}else if(r_data==2){
if(r_loop==exec_d){
r_loop=0;
r_motor++;
}
rc[r_motor][r_loop]=dammy;
r_loop++;
}
}else if(mode_f==247){
if(r_data==2){
speed_d[r_loop]=dammy;
r_loop++;
if(r_loop==exec_d){
r_loop=0;
r_data=1;
}
}else if(r_data==1){
flag_se=dammy;
}
}
}
}
マイコン側プログラム例(m_check.c)
/*
Windows版シリアル送信(m_check.c)
三点倒立
2003/09/()
*/
#include <windows.h>
#include <stdio.h>
#include <ctype.h>
#define MOTOR_NUM 12
#define MOTION_NUM 14
unsigned char rc[MOTOR_NUM][15]=
{{ 90, 90, 90, 90, 90, 90,100,100,100,100,100,100,100,100,100},
{150,150, 90, 90, 90, 90,100,100,100,130,130,130,130,150,100},
{100,100,100,100,100,100,120,120,120,120,120,120,120,120,120},
{179,179,179, 90, 0, 0, 0, 0, 0, 0, 0, 90,179,179, 90},
{150,179,179,179,179,179,179,150,150,150,170,170, 80, 70,150},
{100,100,100,100,100, 0, 0, 0,100,100,100,100,100,100,100},
{ 90, 90, 90, 90, 90, 90, 80, 80, 80, 80, 80, 80, 80, 80, 80},
{ 30, 30, 90, 90, 90, 90, 80, 80, 80, 50, 50, 50, 50, 30, 80},
{ 80, 80, 80, 80, 80, 80, 50, 50, 50, 50, 50, 50, 50, 50, 50},
{ 0, 0, 0, 90,179,179,179,179,179,179,179, 90, 0, 0, 90},
{ 30, 0, 0, 0, 0, 0, 0, 30, 30, 30, 10, 10,100,110, 30},
{ 80, 80, 80, 80, 80,179,179,179, 80, 80, 80, 80, 80, 80, 80}};
/* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 */
unsigned char inter[15]={15,25, 25, 25, 25, 5, 5, 5, 10, 15, 15, 15, 150, 150, 20};
typedef enum { // ボーレート設定リスト
br2400 = 2400,
br4800 = 4800,
br9600 = 9600,
br19200 = 19200,
br31250 = 31250,
br38400 = 38400,
br57600 = 57600
} BaudRate;
/* シリアルポート初期化関数 */
void InitSer(DCB dcb, HANDLE* hComm, BaudRate baud)
{
*hComm = CreateFile(
"COM1", /* シリアルポートの指定 */
GENERIC_WRITE, /* アクセスモード */
0, /* 共有モード */
NULL, /* セキュリティ属性 */
OPEN_EXISTING, /* 作成フラグ */
FILE_ATTRIBUTE_NORMAL, /* 属性 */
NULL /* テンプレートのハンドル */
);
GetCommState(*hComm, &dcb); /* DCB を取得 */
dcb.BaudRate = baud;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
SetCommState(*hComm, &dcb); /* DCB を設定 */
}
int chop(char* input)
{
int i, c_stat, r_stat=1;
for(i=0; input[i]!='\n'; i++){
c_stat=isdigit(input[i]);
if(c_stat==0){
r_stat=-1;
}
}
input[i]='\0';
return(r_stat);
}
int checkn(int maxn)
{
char input[1024]; /* 入力用 */
int status, status2, value=-1; /* エラー処理,数値格納 */
while(1){
printf("\n送信数値を入力(0-%d)%dで終了:", maxn,maxn+1);
fgets(input, 1024, stdin);
status=sscanf(input, "%d", &value);
status2=chop(input);
if(status!=1 || status2<0){
printf("数値以外が入力されました\n");
printf("入力文字%s\n", input);
}else if(value>=0 && value <=maxn+1){
if(value==maxn+1){
return(-1);
}
return(value);
}else if(status==1){
printf("0-%dの範囲外の数値が入力されました\n",maxn);
printf("入力数値%d\n", value);
}
value=-1;
}
}
int main(void)
{
DCB dcb; /* 通信パラメータ */
HANDLE hComm; /* シリアルポートのハンドル */
DWORD writesize; /* ポートへ書き込んだバイト数 */
BaudRate baud=br38400; /* BaudRate設定用 */
unsigned char sendd1,sendd2; /* 数値格納 */
int echeck1,echeck2;
InitSer(dcb, &hComm, baud);
sendd1=252;
WriteFile(hComm, &sendd1, 1, &writesize, NULL); /* シリアルポートに書き込み */
sendd1=MOTION_NUM;
WriteFile(hComm, &sendd1, 1, &writesize, NULL); /* シリアルポートに書き込み */
sendd1=1;
WriteFile(hComm, &sendd1, 1, &writesize, NULL); /* シリアルポートに書き込み */
for(echeck1=0; echeck1<MOTOR_NUM; echeck1++){
for(echeck2=0; echeck2<MOTION_NUM; echeck2++){
WriteFile(hComm, &rc[echeck1][echeck2], 1, &writesize, NULL); /* シリアルポートに書き込み */
}
}
sendd1=247;
WriteFile(hComm, &sendd1, 1, &writesize, NULL);
for(echeck1=0; echeck1<MOTION_NUM; echeck1++){
WriteFile(hComm, &inter[echeck1], 1, &writesize, NULL);
}
sendd1=254;
WriteFile(hComm, &sendd1, 1, &writesize, NULL); /* シリアルポートに書き込み */
while(1){
echeck1=checkn(253);
sendd1=echeck1;
if(echeck1<0){
break;
}
WriteFile(hComm, &sendd1, 1, &writesize, NULL); /* シリアルポートに書き込み */
}
CloseHandle(hComm);
return(0);
}