/***************************************************************************/ /* balanceKN2.c */ /* Balancing robot algorithm */ /* Author: Rich Chi Ooi */ /* Version: 1.3 */ /* Date:14.08.2003 */ /* ------------------------------- */ /* Compilation procedure: */ /* Linux */ /* gcc68 -c XXXXXX.c (to create object file) */ /* gcc68 -o XXXXXX.hex XXXXXX.o ppwa.o */ /***************************************************************************/ /* In this version: */ /***************************************************************************/ #include #include #include "eyebot.h" #include "ppwa.h" #include "sensors.h" #include "kalman.h" #define MAX 5000 /*metre per tick*/ static const float MPT = (M_PI*0.051)/3495; /*Gyro Scaling to rad/s */ static const float GY_SCALE = 0.002798; /*Time step for encoder reading*/ static const float DT = 0.02; MotorHandle motorLeft; MotorHandle motorRight; QuadHandle quadLeft; QuadHandle quadRight; /*Gain values for state control*/ static const float X_K = 0; static const float Xdot_K = -34.3; static const float PHI_K = 1467.6; static const float PHIdot_K = 113.8; static int enc_left_new = 0; static int enc_right_new = 0; static float X = 0; static float Xdot = 0; static float PHI = 0; static float PHIdot = 0; static float command = 0; static float distance_old =0; static float gy_angle = 0; static float in_angle = 0; static int motor_command = 0; /* *Initialize the filter */ void stateInit(){ int gyRaw = 0; gyRaw = gyroRaw(); q_bias =gyRaw*GY_SCALE; angle = incAngle(); } void balance(){ gy_angle = gyroRaw()*GY_SCALE; in_angle = incAngle(); stateUpdate(gy_angle); kalmanUpdate(in_angle); enc_left_new = QUADRead(quadLeft); enc_right_new = QUADRead(quadRight); PHI = in_angle; PHIdot = rate; X = ((enc_left_new+enc_right_new)/2)*MPT; Xdot = (X - distance_old)/DT; distance_old = X; motor_command =(int) (-1*((X*X_K)+(Xdot*Xdot_K)+(PHI*PHI_K)+(PHIdot*PHIdot_K))); if(motor_command>100){ motor_command = 100; } if(motor_command<-100){ motor_command = -100; } MOTORDrive(motorLeft,motor_command); MOTORDrive(motorRight,motor_command); LCDSetPos(1,0); LCDPrintf(" X:%.4f\n XD:%.4f\n",X,Xdot); LCDSetPos(3,0); LCDPrintf(" P:%.4f\n PD:%.4f\n",PHI,PHIdot); LCDSetPos(5,0); LCDPrintf("CMD:%d\n",motor_command); } int main(void) { ServoHandle gyro; TimerHandle balanceTimer; /*initialize ports and sensors*/ tpuInit(); gyroInit(gyro); inclinoInit(); motorLeft = MOTORInit(MOTOR_LEFT); motorRight = MOTORInit(MOTOR_RIGHT); quadLeft = QUADInit(QUAD_LEFT); quadRight = QUADInit(QUAD_RIGHT); QUADReset(quadRight); QUADReset(quadLeft); stateInit(); OSWait(200); LCDPrintf("ROBOT INITIALIZED \n"); LCDClear(); balanceTimer = OSAttachTimer(2,(TimerFnc)balance); while(KEYRead()!=KEY4){ } /*release all handles*/ OSDetachTimer(balanceTimer); SERVORelease(gyro); MOTORRelease(motorLeft); MOTORRelease(motorRight); QUADRelease(quadLeft); QUADRelease(quadRight); }