Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: AQM0802A PID Servo mbed
main.cpp
- Committer:
- ryuna
- Date:
- 2015-03-11
- Revision:
- 4:2857f273a7f4
- Parent:
- 3:4a39486ff238
- Child:
- 5:09afcbe0c18f
File content as of revision 4:2857f273a7f4:
/***********************************
*RoboCupJunior Soccer B Open 2015
*Koshinnestu progrum
*
*
* データからロボットの移動やキッカー等のモータの動作を決定する処理を行う
*
* MotorDriverにmaxonに命令
*
* servoにステアリング指示
*
* LCDでデバック
*
* スイッチ4つとスタートスイッチで処理を実行
*
*************************
* Pin Map
*
* p5~p8 >> BusIn >> LineSensor
*
* p9,p10 >> I2C >> LPC1114FN28/102 read & Compass
*
* p13,p14 >> Serial >> Motor
*
* p21 >> PwmOut >> Servo
*
* p22~p26 >> DigitalIn >> DebugSw and StartSw
*
* p27,p28 >> I2C >> DebugLCD
*
* p29 >> DigitalOut >> Kicker
*
* *never use pin number p11,p12,p15,p16,p17,p18,p19,p20,p30
*
*
******************************/
#include "mbed.h"
#include <math.h>
#include <sstream>
#include "Servo.h"
#include "PID.h"
#include "AQM0802A.h"
#include "main.h"
//#include "MultiSerial.h"
/*
void Receive(){
IrData[0] = rx_data[0];
IrData[1] = rx_data[1];
IrData[2] = rx_data[2];
PingData[0] = rx_data[3];
PingData[1] = rx_data[4];
PingData[2] = rx_data[5];
PingData[3] = rx_data[6];
if((IrData[0] == 255)||(IrData[1] == 255)||(IrData[2] == 255)){
IrNum = 12;
return;
}
IrNum = IrData[0]/12;
}
*/
void move(int vr,int vl, double vs ,int Degree){
double pwm[4] = {0};
uint8_t i = 0;
if(vs<0){
pwm[0] = vr - vs;
pwm[1] = 0;
pwm[2] = 0;
pwm[3] = vl + vs;
}else{
pwm[0] = vr + vs;
pwm[1] = 0;
pwm[2] = 0;
pwm[3] = vl - vs;
}
for(i = 0; i < 4; i++){
if(pwm[i] > 100){
pwm[i] = 100;
}else if(pwm[i] < -100){
pwm[i] = -100;
}
speed[i] = pwm[i];
}
if(Degree > 110){
Degree = 110;
}else if(Degree < -110){
Degree = -110;
}
SetDegree = Degree;
S555.position(SetDegree);
wait_ms(10);
}
uint8_t PingChange(uint8_t LineData){
static uint8_t Last_Line;
static uint8_t Last_Ping;
uint8_t LinePing = 0;
if(!LineData){
return 0;
}
if(PingData[0] <40) LinePing = LinePing + 1;
if(PingData[1] <40) LinePing = LinePing + 2;
if(PingData[2] <40) LinePing = LinePing + 4;
if(PingData[3] <40) LinePing = LinePing + 8;
if(LinePing&0x01){
if((LineData&0x01) ||(Last_Line&0x01)||(Last_Ping&0x01)){
Last_Ping = LinePing;
Last_Line = LineData;
return 1;
}
}
if(LinePing&0x02){
if((LineData&0x02) ||(Last_Line&0x02)||(Last_Ping&0x02)){
Last_Ping = LinePing;
Last_Line = LineData;
return 2;
}
}
if(LinePing&0x04){
if((LineData&0x04) ||(Last_Line&0x04)||(Last_Ping&0x04)){
Last_Ping = LinePing;
Last_Line = LineData;
return 4;
}
}
if(LinePing&0x08){
if((LineData&0x08) ||(Last_Line&0x08)||(Last_Ping&0x08)){
Last_Ping = LinePing;
Last_Line = LineData;
return 8;
}
}
Last_Ping = 0;
Last_Line = 0;
return 0;
}
void fool (int *Degree, int *Power){
static int Last_Degree = 0;
static int Last_Vector = 1;
int degree = *Degree;
int Temp;
if((*Degree <0)||(*Degree >=360)){
*Degree = 0;
Last_Degree = 0;
Last_Vector = 1;
return ;
}
Temp = Last_Degree % 180;
if((Temp==90)){
Temp = *Degree % 180;
if((Temp==90)){
Temp = abs(*Degree - Last_Degree);
if(Temp>160){
Last_Vector = -1 * Last_Vector;//正転逆転切り替え
if(*Degree/180){
*Degree = Angle[Last_Degree%180] -(Last_Degree - *Degree%180);
*Power = *Power * Last_Vector;
}else{
*Degree = Angle[Last_Degree%180] -(Last_Degree%180 - *Degree);
*Power = *Power * Last_Vector;
}
Last_Degree = degree;
if((*Degree <= -120)||(*Degree >=120)){
*Degree = 0;
}
return;
}else if((Last_Vector+2) == 1){
/*逆転のまま角度拡張*/
if(*Degree/180){
*Degree = -360 + *Degree ;
}
*Power = *Power * Last_Vector;
Last_Degree = degree;
if((*Degree <= -120)||(*Degree >=120)){
*Degree = 0;
}
return;
}else if((Last_Vector+2) == 3){
/*正転のまま*/
if(*Degree/180){
*Degree = -360 + *Degree ;
}
*Power = *Power * Last_Vector;
Last_Degree = degree;
if((*Degree <= -120)||(*Degree >=120)){
*Degree = 0;
}
return;
}
}
}
/*通常動作*/
if(*Degree == 0){
Last_Vector = DegreeToVector[0];
*Degree = Angle[*Degree%180];
*Power = *Power * Last_Vector;
Last_Degree = degree;
return ;
}
Last_Vector = DegreeToVector[(*Degree-1)/90];
*Degree = Angle[*Degree%180];
*Power = *Power * Last_Vector;
Last_Degree = degree;
if((*Degree <= -120)||(*Degree >=120)){
*Degree = 0;
}
}
int IrDegree(){
/*irの1位の値,2位の場所からirの360へ持っていく*/
uint8_t IrF ,IrS;
unsigned int irdegree = 0;
if(IrNum >=12){
return 0;
}
IrF = IrData[0]/12;
IrS = IrData[0]%12;
if(IrF == 0 ){
if(IrS == 11){
irdegree = 15;
}else if(IrS == 1){
irdegree = 345;
}
return irdegree;
}
irdegree = 360 - IrF*30;
if(IrS&&(abs(IrF-IrS) == 1)){
irdegree = irdegree - (IrF - IrS)*15;
}
if(irdegree>=360){
return 0;
}
return irdegree;
}
void IrFrontAction()//ball 12 or 0 o-clock
{
if(IrData[1]>70){
if(abs(CompassPID)>10){
move(0,0,CompassPID,0);
return;
}
move(30,30,CompassPID,0);
return;
}
if(IrData[1]>60){
move(25,25,CompassPID,0);
return;
}
/*IrData[1]>500*/
if(PingData[0]<50){
if((PingData[1]<60)&&(PingData[1]>40)){
/*右側に居る*/
move(25,40,0,10);
wait_ms(100);
move(30,30,0,0);
return;
}
if((PingData[1]<60)&&(PingData[1]>40)){
/*左側に居る*/
move(40,25,0,-10);
wait_ms(100);
move(30,30,0,0);
return;
}
/*それ以外*/
move(10,10,CompassPID,0);
//Receive();
if(!(IrNum == 0)) return;
move(40,40,CompassPID,0);
return ;
}
move(20,20,CompassPID,0);
}
void IrBackAction()//ball found six o-clock
{
/***
* 6時にボールがある場合の処理.右と左のスペースを確認して広い方から回り込む
*
**/
if(PingData[1]>PingData[3]){
/*右が大きい*/
if(IrData[1]>70){
move(-20,-20,CompassPID,45);
return;
}
if(IrData[1]>60){
move(-20,-20,CompassPID,60);
return;
}
move(-20,-20,CompassPID,80);
return;
}
/*左が大きい*/
if(IrData[1]>70){
move(-20,-20,CompassPID,-45);
return;
}
if(IrData[1]>60){
move(-20,-20,CompassPID,-60);
return;
}
move(-20,-20,CompassPID,-80);
return;
}
void GoHome()//Ball is not found.
{
/*if(PingData[2] >=60){//後ろからの距離60cm
move(-20,-20,CompassPID,0);
return ;
}
*/
move(0,0,CompassPID,0);//stop
}
void PidUpdate()
{
pid.setSetPoint((int)((REFERENCE + SetC) / 1.0));
InputPID = Compass;
pid.setProcessValue(InputPID);
CompassPID = (pid.compute());
}
uint8_t SwRead(){
/******
*retrun : sw_state
*StartS = 0x01;
*Debug2 = 0x02;
*Debug1 = 0x04;
*Debug3 = 0x06;
*Kicker = 0x08;
*Calibration = 0x10;
*
*****/
uint8_t i,temp,temp2;
temp = ~Sw - 224;
if(!(temp == Kicker
||temp == Debug1
||temp == Debug2
||temp == Debug3
||temp == StartS)) return 0;/*スイッチが押されていない*/
if(!(temp == 0x00)){
for(i = 0; i < 50; i++);
temp2 = ~Sw - 224;
if(temp == temp2){
return temp;
}
}
return 0;
}
//通信(モータ用)
void tx_motor(){
array(speed[0],speed[1],speed[3],speed[2]);
Motor.printf("%s",StringFIN.c_str());
}
void SetUp(){
/*初期化*/
Motor.baud(115200); //ボーレート設定
Motor.printf("1F0002F0003F0004F000\r\n"); //モータ停止
Motor.attach(&tx_motor,Serial::TxIrq); //送信空き割り込み(モータ用)
Mbed.attach(&micon_rx,Serial::RxIrq); //送信空き割り込み(センサ用)
S555.calibrate(0.0005, 120.0);
//S555.position(0.0); //初期位置にセット
move(0,0,0,0);//停止
Kick = 0;
Sw.mode(PullUp);
pid.setInputLimits(MINIMUM,MAXIMUM); //pid sed def
pid.setOutputLimits(-OUT_LIMIT, OUT_LIMIT); //pid sed def
pid.setBias(PID_BIAS); //pid sed def
pid.setMode(AUTO_MODE); //pid sed def
pid.setSetPoint(REFERENCE); //pid sed def
pidupdate.attach(&PidUpdate, PID_CYCLE);
}
void StartLoop(){
uint8_t State = 0;
uint8_t LineData = 0;
while(1){
Led[0] = Led[1] = Led[2] = Led[3] = 1;
//Lcd.cls();
State = SwRead();
if(State == 0) continue;
if(State == StartS){
/*loop end & start*/
return;
}
if(State == Debug1){
while((State == Debug1)){
LineData = (~Line+0x00) & 0x0F;
Lcd.printf("%d\n",LineData);
wait_ms(100);
State = SwRead();
}
Lcd.cls();
continue;
}
if(State == Debug2){
while((State == Debug2)){
//Receive();
Lcd.printf("%d\n",IrNum);
wait_ms(100);
State = SwRead();
}
Lcd.cls();
continue;
}
if(State == Debug3){
while((State == Debug3)){
Lcd.printf("%d\n",Compass);
wait_ms(100);
State = SwRead();
}
Lcd.cls();
continue;
}
if(State == Kicker){
Led[0] = Led[1] = Led[2] = 0;
Kick = 1;
wait_ms(500);
Kick = 0;
while((State == Kicker)){
wait_ms(100);
State = SwRead();
}
continue;
}
}
}
int main() {
//uint8_t IrNumOld = 0;//過去値
/*Line*/
uint8_t LineData = 0;
uint8_t LinePing = 0;
/*State */
uint8_t LineIr = 0;
uint8_t IrChange[13] ={0x01,0x01,0x03,0x02,0x02,0x06,
0x04,0x04,0x0B,0x08,0x08,0x09,0x00};
/*行動設定*/
int Power = 0;
int Degree = 0;
/*楽しい変数達*/
int nDegree =0;//基礎角
int addDegree = 0;//追加角
/*関数ポインタ*/
//void (*AnotherAction[3])(uint8_t [],double);
void (*AnotherAction[3])();
AnotherAction[0] = IrFrontAction;
AnotherAction[1] = IrBackAction;
AnotherAction[2] = GoHome;
SetUp();/*set up routine*/
StartLoop(); /*loop strat, switch push end*/
Led[0] = Led[1] = Led[2] = Led[3] = 0;
wait_ms(100);
while(1){
S555.calibrate(0.0005, 120.0);
//Receive();
//Lcd.printf("%d\n",IrNum);
/*白線を読んでいないか確認する*/
LineData = (~Line+0x00) & 0x0F;
if(LineData){
LineIr = LineData & IrChange[IrNum];
LinePing = PingChange(LineData);
if(LineIr){
move(0,0,0,0);
while(LineIr){
Led[1] = Led[2] = Led[3] = 1;
//Receive();
LineData = (~Line+0x00) & 0x0F;
LineIr = LineData & IrChange[IrNum];
wait_ms(10);
}
}else if(LinePing){
move(0,0,0,0);
while(LinePing){
Led[1] = Led[2] = Led[3] = 1;
//Receive();
LineData = (~Line+0x00) & 0x0F;
LinePing = PingChange(LineData);
wait_ms(10);
}
}
Led[1] = Led[2] = Led[3] = 0;
}
Power = 0;
Led[0] = 1;
Degree = 0;
SetC = 0.0;
Led[3] = 1;
//Receive();
Degree = IrDegree();
if((Degree == 0)||(Degree == 180)||(IrNum == 12)){
(AnotherAction[IrNum/6])();
continue;
}
/*
if(IrNum == 12){
move(0,0,0,0);
wait_ms(10);
continue;
}*/
nDegree = wrapDegree[Degree/15];
Power = 20;
Degree = nDegree + addDegree;
if((Degree <0)||(Degree>=360)){
Degree = 0;
}
fool(&Degree,&Power);
move(Power,Power,0,Degree);
//wait_ms(500);
Led[0] =0;
wait_ms(10);
}
while(0){
//デモプログラム
//Receive();
pc.printf("%d %d %d %d %d\n",IrData[0],IrData[1],IrData[2],PingData[0],PingData[1]);
//pc.printf("%d %d %d %d\n",PingData[1],PingData[2],PingData[3],Compass);
//pc.printf("%d\t %d\t %d\t %d\t %d\t %d\t\n",rx_data[3],rx_data[4],rx_data[5],rx_data[6],rx_data[7],rx_data[8]);
//pc.printf("%d\t %d\t %d\t %d\n",speed[0],speed[1],speed[2],speed[3]);
wait(0.1);
}
}