/* MOTORS.CC Motor class controls the motors installd on the balancing robot, Ballybot. Alistair Sutherland suthe-aj@ee.uwa.edu.au CIIPS, 2003 */ #include #include "motors.h" CMotors::CMotors() { m_motorLeft = MOTORInit(MOTOR_LEFT); m_motorRight = MOTORInit(MOTOR_RIGHT); if(m_motorLeft == 0 || m_motorRight == 0) { LCDPrintf("Motor Error!\n"); OSWait(200); } // Init QUADS m_quadLeft = QUADInit(QUAD_LEFT); m_quadRight = QUADInit(QUAD_RIGHT); // Reset motor... Reset(); } CMotors::~CMotors() { // Switch motors off... MOTORDrive( m_motorLeft, 0 ); MOTORDrive( m_motorRight, 0); // Release quadrature-decoders QUADRelease( m_quadLeft ); QUADRelease( m_quadRight ); // Release motors MOTORRelease(m_motorLeft); MOTORRelease(m_motorRight); } int CMotors::Reset() { // Turn motor off... MOTORDrive( m_motorLeft, 0 ); MOTORDrive( m_motorRight, 0); // Initialise Quadrature decoders QUADODOReset(QUAD_LEFT); QUADODOReset(QUAD_RIGHT); m_fLastError = 0.0; m_fIntegratedError = 0.0; m_iPIDCounter = 2; m_fCorrection = 0.0; m_fLeftDistance = 0.0; m_fRightDistance = 0.0; return MOTOR_OK; } int CMotors::SetForce(float fForce, float fVelocity) { float fError; float fDiffError; float fForceRight, fForceLeft; float fVoltsRight, fVoltsLeft; // Determine friction float fFriction; if (fVelocity>0.0001) fFriction = -FRICTION_FORCE; if (fVelocity<-0.0001) fFriction = FRICTION_FORCE; fForce -= fFriction; m_iPIDCounter--; if (m_iPIDCounter < 1) { m_iPIDCounter =2; // Determine error in motors: fError = (m_fLeftDistance - m_fRightDistance); m_fIntegratedError += fError; fDiffError = fError - m_fLastError; m_fLastError = fError; m_fCorrection = P_ * fError + I_ * m_fIntegratedError + D_ * fDiffError; } fForceLeft = fForce - m_fCorrection; fForceRight = fForce + m_fCorrection; // Calculate voltage to produce this force... fVoltsLeft = (2.58 * fForceLeft) / (0.0805 - 0.035 * fVelocity); fVoltsRight = (2.58 * fForceRight) / (0.0805 - 0.035 * fVelocity); // Limit fVoltage to +- 100% int iVoltsLeft, iVoltsRight; iVoltsLeft = (int)fVoltsLeft; iVoltsRight = (int)fVoltsRight; if (iVoltsLeft < -100) iVoltsLeft = -100; if (iVoltsLeft > 100) iVoltsLeft = 100; if (iVoltsRight < -100) iVoltsRight = -100; if (iVoltsRight > 100) iVoltsRight = 100; // Apply voltage to motors: MOTORDrive( m_motorLeft, iVoltsLeft ); MOTORDrive( m_motorRight, iVoltsRight ); return MOTOR_OK; } float CMotors::GetDistance() { m_fLeftDistance = QUADODORead( m_quadLeft ); m_fRightDistance = QUADODORead( m_quadRight ); return ( (m_fLeftDistance + m_fRightDistance) / 2.0 ); }