This is a ball follower. It is a robot following a ball like a dog.
Robot uses IR seeker sensor. This sensor detects infrared signal and returns data from five detectors. This data is a basic information we need. It allows us to calculate steering values to motors. To improve behavior this robot I used two PID regulators:
one to set an angle between robot and a ball
the second one to control distance between robot and a ball
Second part of ball follower is a special ball:
This ball generates an infrared signal in all directions, so robot can see this ball and follow it.
#include"hFramework.h"#include"hCloudClient.h"#include"Hitechnic_IRSeeker.h"usingnamespacehFramework;usingnamespacehSensors;//setting default PID valuesfloatKp=1.4;floatKi=0.0;floatKd=0.002;floatKp2=1.0;floatKi2=0.0;floatKd2=0.0;voidstatusTask(){while(1){platform.ui.label("lb_bat").setText("%2f V",sys.getSupplyVoltage());platform.ui.progressBar("pb_bat").setValue(sys.getSupplyVoltageMV()/15);platform.ui.label("l1").setText("hMot1 enc = %d",hMot1.getEncoderCnt());platform.ui.label("l2").setText("hMot3 enc = %d",hMot3.getEncoderCnt());sys.delay(200);}}voidcfgHandler(){autol1=platform.ui.label("l1");autol2=platform.ui.label("l2");autob=platform.ui.button("btn1");platform.ui.loadHtml({Resource::WEBIDE,"/ui.html"});platform.ui.video.enable();}voidonKeyEvent(KeyEventTypetype,KeyCodecode){//steering PID valuesswitch(code){caseKeyCode::Key_T:if(type==KeyEventType::Pressed){platform.ui.console("cl1").printf(" pressed");hServoModule.s2.setWidth(1300);// 1.3 ms width}else{platform.ui.console("cl1").printf(" released");hServoModule.s2.setWidth(2300);// 2.3 ms width}break;//P,L,I,J,D,X changing angle PID valuescaseKeyCode::Key_P:if(type==KeyEventType::Pressed){Kp+=0.1;}break;caseKeyCode::Key_L:if(type==KeyEventType::Pressed){Kp-=0.1;}break;caseKeyCode::Key_I:if(type==KeyEventType::Pressed){Ki+=0.001;}break;caseKeyCode::Key_J:if(type==KeyEventType::Pressed){Ki-=0.001;}break;caseKeyCode::Key_D:if(type==KeyEventType::Pressed){Kd+=0.001;}break;caseKeyCode::Key_X:if(type==KeyEventType::Pressed){Kd-=0.001;}break;//O,K,U,H,S,Z changing distance PID valuescaseKeyCode::Key_O:if(type==KeyEventType::Pressed){Kp2+=0.1;}break;caseKeyCode::Key_K:if(type==KeyEventType::Pressed){Kp2-=0.1;}break;caseKeyCode::Key_U:if(type==KeyEventType::Pressed){Ki2+=0.001;}break;caseKeyCode::Key_H:if(type==KeyEventType::Pressed){Ki2-=0.001;}break;caseKeyCode::Key_S:if(type==KeyEventType::Pressed){Kd2+=0.001;}break;caseKeyCode::Key_Z:if(type==KeyEventType::Pressed){Kd2-=0.001;}break;default:break;}}voidhMain(){platform.begin(&RPi);platform.ui.configHandler=cfgHandler;platform.ui.onKeyEvent=onKeyEvent;platform.ui.setProjectId("b5ec86bafdf797fb");sys.setLogDev(&Serial);sys.disableSyslog();sys.taskCreate(statusTask,2,1000,0);hMot1.setSlewRate(0.1);hMot2.setSlewRate(0.1);hMot3.setSlewRate(0.1);hMot4.setSlewRate(0.1);hServoModule.enablePower();//creating sensor objecthLegoSensor_i2cs(hSens1);Hitechnic_IRSeekersensor(s);//creating PID objectshPIDpidAngle;//angle PIDhPIDpidDistance;//distance PIDfloatv=0;for(;;){intmot1=0;//values steering motorsintmot2=0;sys.delay(50);// 50msLED2.toggle();//geting values from sensorHitechnic_IRSeeker::dataval;if(sensor.read(&val)==Hitechnic_IRSeeker::ERROR_PROTO)continue;LED1.toggle();//summing up signal from all five sensorsfloatsuma=0;floatnowe[5];for(inti=0;i<5;i++){suma+=val.dcValues[i];}//normalizing sensors datafor(inti=0;i<5;i++){nowe[i]=(val.dcValues[i])/suma;}//calculate average signal strengthv=0.65*v+0.35*suma;floatwynik;//calculate average signal from all five sensorswynik=(-2*nowe[0])+(-1*nowe[1])+(1*nowe[3])+(2*nowe[4]);//writing values to PID regulatorspidAngle.setKP(Kp);pidAngle.setKI(Ki);pidAngle.setKD(Kd);pidDistance.setKP(Kp2);pidDistance.setKI(Ki2);pidDistance.setKD(Kd2);//generating steering signal value (angle PID)floatangle=pidAngle.update(wynik,50);//generatinc steering signal value (distance PID)floatdistance=pidDistance.update(v-25,50);//writing steering signals to property variablemot1=angle*300+distance*20;mot2=angle*300+-distance*20;//sendind steering values to motorshMot1.setPower(mot1);hMot2.setPower(mot2);hMot3.setPower(mot1);hMot4.setPower(mot2);//writing in robots concole PID valuesplatform.ui.console("cl1").printf("\r\n odczyty: %d %d %d %d %d",val.dcValues[0],val.dcValues[1],val.dcValues[2],val.dcValues[3],val.dcValues[4]);}}
Comments
Please log in or sign up to comment.