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: biquadFilter FastPWM MODSERIAL QEI mbed
Diff: main.cpp
- Revision:
- 48:1eb0f9ed6cd9
- Parent:
- 47:7919857587f8
- Child:
- 49:0ada5a721686
--- a/main.cpp Thu Nov 01 16:03:01 2018 +0000
+++ b/main.cpp Thu Nov 01 18:46:33 2018 +0000
@@ -156,6 +156,9 @@
int countsCalibratedL;
int countsCalibratedR;
int countsCalibratedF;
+int countsOffsetL;
+int countsOffsetR;
+int countsOffsetF;
float angleCurrentL;
float angleCurrentR;
float angleCurrentF;
@@ -377,255 +380,109 @@
// So, the angleDesired needs to be defined again and the part in which the potmeter value is calculated needs to be commented
// ------------------------ General motor functions ----------------------------
-int countsInputL() // Gets the counts from encoder 1
-{
- int countsL;
- countsL = encoderL.getPulses();
- return countsL;
-}
-int countsInputR() // Gets the counts from encoder 2
-{
- int countsR;
- countsR = encoderR.getPulses();
- return countsR;
-}
-int countsInputF() // Gets the counts from encoder 3
-{
- int countsF;
- countsF = encoderF.getPulses();
- return countsF;
-}
+ int countsInputL() // Gets the counts from encoder 1
+ { countsL = encoderL.getPulses();
+ return countsL;
+ }
+ int countsInputR() // Gets the counts from encoder 2
+ { countsR = encoderR.getPulses();
+ return countsR;
+ }
+ int countsInputF() // Gets the counts from encoder 3
+ { countsF = encoderF.getPulses();
+ return countsF;
+ }
-float angleCurrent(float counts) // Calculates the current angle of the motor (between -2*PI to 2*PI) based on the counts from the encoder
-{
- float angle = ((float)counts*2.0f*PI)/countsRad;
- while (angle > 2.0f*PI) {
- angle = angle-2.0f*PI;
- }
- while (angle < -2.0f*PI) {
- angle = angle+2.0f*PI;
+ float angleCurrent(float counts) // Calculates the current angle of the motor (between -2*PI to 2*PI) based on the counts from the encoder
+ { float angle = ((float)counts*2.0f*PI)/countsRad;
+ while (angle > 2.0f*PI)
+ { angle = angle-2.0f*PI;
+ }
+ while (angle < -2.0f*PI)
+ { angle = angle+2.0f*PI;
+ }
+ return angle;
}
- return angle;
-}
-float errorCalc(float angleReference,float angleCurrent) // Calculates the error of the system, based on the current angle and the reference value
-{
- float error = angleReference - angleCurrent;
- return error;
-}
+ float errorCalc(float angleReference,float angleCurrent) // Calculates the error of the system, based on the current angle and the reference value
+ { float error = angleReference - angleCurrent;
+ return error;
+ }
// ------------------------- MOTOR FUNCTIONS FOR MOTOR LEFT --------------------
-float PIDControllerL(float angleReference,float angleCurrent) // PID controller for the motors, based on the reference value and the current angle of the motor
-{
- float Kp = 19.24f;
- float Ki = 1.02f;
- float Kd = 0.827f;
- float error = errorCalc(angleReference,angleCurrent);
- static float errorIntegralL = 0.0;
- static float errorPreviousL = error; // initialization with this value only done once!
- static BiQuad PIDFilterL(0.0640, 0.1279, 0.0640, -1.1683, 0.4241);
- // Proportional part:
- float u_k = Kp * error;
- // Integral part
- errorIntegralL = errorIntegralL + error * dt;
- float u_i = Ki * errorIntegralL;
- // Derivative part
- float errorDerivative = (error - errorPreviousL)/dt;
- float errorDerivativeFiltered = PIDFilterL.step(errorDerivative);
- float u_d = Kd * errorDerivativeFiltered;
- errorPreviousL = error;
- // Sum all parts and return it
- return u_k + u_i + u_d;
-}
+ float PIDControllerL(float angleReference,float angleCurrent) // PID controller for the motors, based on the reference value and the current angle of the motor
+ { float Kp = 19.24f;
+ float Ki = 1.02f;
+ float Kd = 0.827f;
+ float error = errorCalc(angleReference,angleCurrent);
+ static float errorIntegralL = 0.0;
+ static float errorPreviousL = error; // initialization with this value only done once!
+ static BiQuad PIDFilterL(0.0640, 0.1279, 0.0640, -1.1683, 0.4241);
+ // Proportional part:
+ float u_k = Kp * error;
+ // Integral part
+ errorIntegralL = errorIntegralL + error * dt;
+ float u_i = Ki * errorIntegralL;
+ // Derivative part
+ float errorDerivative = (error - errorPreviousL)/dt;
+ float errorDerivativeFiltered = PIDFilterL.step(errorDerivative);
+ float u_d = Kd * errorDerivativeFiltered;
+ errorPreviousL = error;
+ // Sum all parts and return it
+ return u_k + u_i + u_d;
+ }
-float angleDesiredL() // Sets the desired angle for the controller dependent on the scaled angle of potmeter 1
-{ float angle = (pot1*2.0f*PI)-PI;
- return angle;
-}
-
-float countsCalibrCalcL(int countsOffsetL)
-{
- countsCalibratedL = countsL - countsOffsetL + countsCalibration;
- return countsCalibratedL;
+ float angleDesiredL() // Sets the desired angle for the controller dependent on the scaled angle of potmeter 1
+ { float angle = (pot1*2.0f*PI)-PI;
+ return angle;
+ }
+
+ int countsInputCalibratedL() // Gets the counts from encoder 1
+ { countsL = encoderL.getPulses()- countsOffsetL + countsCalibration;
+ return countsL;
+ }
+
+void motorTurnL() // main function for movement of motor 1, all above functions with an extra tab are called
+{
+ float angleReferenceL = angleDesiredL(); // insert kinematics output here instead of angleDesiredL()
+ angleReferenceL = -angleReferenceL; // different minus sign per motor
+ countsL = countsInputCalibratedL(); // different encoder pins per motor
+ angleCurrentL = angleCurrent(countsL); // different minus sign per motor
+ errorL = errorCalc(angleReferenceL,angleCurrentL); // same for every motor
+
+ float PIDControlL = PIDControllerL(angleReferenceL,angleCurrentL); // same for every motor
+ pin6 = fabs(PIDControlL); // different pins for every motor
+ pin7 = PIDControlL > 0.0f; // different pins for every motor
}
void calibrationL() // Partially the same as motorTurnL, only with potmeter input
// How it works: manually turn motor using potmeters until the robot arm touches the bookholder.
// This program sets the counts from the motor to the reference counts (an angle of PI/4.0)
// Do this for every motor and after calibrated all motors, press a button
-{
- float angleReferenceL = angleDesiredL(); // insert kinematics output here instead of angleDesiredL()
+{ float angleReferenceL = angleDesiredL(); // insert kinematics output here instead of angleDesiredL()
angleReferenceL = -angleReferenceL; // different minus sign per motor
+ countsL = countsInputL(); // different encoder pins per motor
angleCurrentL = angleCurrent(countsL); // different minus sign per motor
errorL = errorCalc(angleReferenceL,angleCurrentL); // same for every motor
-
- if (fabs(errorL) >= 0.01f) {
- float PIDControlL = PIDControllerL(angleReferenceL,angleCurrentL); // same for every motor
+
+ if (fabs(errorL) >= 0.01f)
+ { float PIDControlL = PIDControllerL(angleReferenceL,angleCurrentL); // same for every motor
pin6 = fabs(PIDControlL); // different pins for every motor
pin7 = PIDControlL > 0.0f; // different pins for every motor
- } else if (fabs(errorL) < 0.01f) {
- int countsOffsetL = countsL;
- countsCalibrCalcL(countsOffsetL);
- pin6 = 0.0f;
- // BUTTON PRESS: TO NEXT STATE
}
-}
-
-void motorTurnL() // main function for movement of motor 1, all above functions with an extra tab are called
-{
- float angleReferenceL = theta1; // insert kinematics output here instead of angleDesiredL()
- angleReferenceL = -angleReferenceL; // different minus sign per motor
- int countsL = countsInputL(); // different encoder pins per motor
- angleCurrentL = angleCurrent(countsCalibratedL); // different minus sign per motor
- errorCalibratedL = errorCalc(angleReferenceL,angleCurrentL); // same for every motor
-
- float PIDControlL = PIDControllerL(angleReferenceL,angleCurrentL); // same for every motor
- pin6 = fabs(PIDControlL); // different pins for every motor
- pin7 = PIDControlL > 0.0f; // different pins for every motor
+ else if (fabs(errorL) < 0.01f)
+ { countsOffsetL = countsL;
+ countsL = countsL - countsOffsetL + countsCalibration;
+ //countsL = 0;
+ pin6 = 0.0f;
+ // BUTTON PRESS: NAAR VOLGENDE STATE
+ }
}
// ------------------------ MOTOR FUNCTIONS FOR MOTOR RIGHT --------------------
-float PIDControllerR(float angleReference,float angleCurrent) // PID controller for the motors, based on the reference value and the current angle of the motor
-{
- float Kp = 19.24f;
- float Ki = 1.02f;
- float Kd = 0.827f;
- float error = errorCalc(angleReference,angleCurrent);
- static float errorIntegralR = 0.0;
- static float errorPreviousR = error; // initialization with this value only done once!
- static BiQuad PIDFilterR(0.0640, 0.1279, 0.0640, -1.1683, 0.4241);
- // Proportional part:
- float u_k = Kp * error;
- // Integral part
- errorIntegralR = errorIntegralR + error * dt;
- float u_i = Ki * errorIntegralR;
- // Derivative part
- float errorDerivative = (error - errorPreviousR)/dt;
- float errorDerivativeFiltered = PIDFilterR.step(errorDerivative);
- float u_d = Kd * errorDerivativeFiltered;
- errorPreviousR = error;
- // Sum all parts and return it
- return u_k + u_i + u_d;
-}
-float angleDesiredR() // Sets the desired angle for the controller dependent on the scaled angle of potmeter 1
-{ float angle = (pot2*2.0f*PI)-PI;
- return angle;
-}
-
-float countsCalibrCalcR(int countsOffsetR)
-{
- countsCalibratedR = countsR - countsOffsetR + countsCalibration;
- return countsCalibratedR;
-}
-
-void calibrationR() // Partially the same as motorTurnR, only with potmeter input
-// How it works: manually turn motor using potmeters until the robot arm touches the bookholder.
-// This program sets the counts from the motor to the reference counts (an angle of PI/4.0)
-// Do this for every motor and after calibrated all motors, press a button
-{
- float angleReferenceR = angleDesiredR(); // insert kinematics output here instead of angleDesiredR()
- angleReferenceR = -angleReferenceR; // different minus sign per motor
- angleCurrentR = angleCurrent(countsR); // different minus sign per motor
- errorR = errorCalc(angleReferenceR,angleCurrentR); // same for every motor
-
- if (fabs(errorR) >= 0.01f) {
- float PIDControlR = PIDControllerR(angleReferenceR,angleCurrentR); // same for every motor
- pin6 = fabs(PIDControlR); // different pins for every motor
- pin7 = PIDControlR > 0.0f; // different pins for every motor
- } else if (fabs(errorR) < 0.01f) {
- int countsOffsetR = countsR;
- countsCalibrCalcR(countsOffsetR);
- pin6 = 0.0f;
- // BUTTON PRESS: NAAR VOLGENDE STATE
- }
-}
-
-void motorTurnR() // main function for movement of motor 1, all above functions with an extra tab are called
-{
- float angleReferenceR = theta4; // insert kinematics output here instead of angleDesiredR()
- angleReferenceR = -angleReferenceR; // different minus sign per motor
- int countsR = countsInputR(); // different encoder pins per motor
- angleCurrentR = angleCurrent(countsCalibratedR); // different minus sign per motor
- errorCalibratedR = errorCalc(angleReferenceR,angleCurrentR); // same for every motor
-
- float PIDControlR = PIDControllerR(angleReferenceR,angleCurrentR); // same for every motor
- pin6 = fabs(PIDControlR); // different pins for every motor
- pin7 = PIDControlR > 0.0f; // different pins for every motor
-}
// ------------------------- MOTOR FUNCTIONS FOR MOTOR FLIP --------------------
-float PIDControllerF(float angleReference,float angleCurrent) // PID controller for the motors, based on the reference value and the current angle of the motor
-{
- float Kp = 19.24f;
- float Ki = 1.02f;
- float Kd = 0.827f;
- float error = errorCalc(angleReference,angleCurrent);
- static float errorIntegralF = 0.0;
- static float errorPreviousF = error; // initialization with this value only done once!
- static BiQuad PIDFilterF(0.0640, 0.1279, 0.0640, -1.1683, 0.4241);
- // Proportional part:
- float u_k = Kp * error;
- // Integral part
- errorIntegralF = errorIntegralF + error * dt;
- float u_i = Ki * errorIntegralF;
- // Derivative part
- float errorDerivative = (error - errorPreviousF)/dt;
- float errorDerivativeFiltered = PIDFilterF.step(errorDerivative);
- float u_d = Kd * errorDerivativeFiltered;
- errorPreviousF = error;
- // Sum all parts and return it
- return u_k + u_i + u_d;
-}
-
-float angleDesiredF() // Sets the desired angle for the controller dependent on the scaled angle of potmeter 1
-{
- float angle = (pot1*2.0f*PI)-PI;
- return angle;
-}
-
-float countsCalibrCalcF(int countsOffsetF)
-{
- countsCalibratedF = countsF - countsOffsetF + countsCalibration;
- return countsCalibratedF;
-}
-
-void calibrationF() // Partially the same as motorTurnF, only with potmeter input
-// How it works: manually turn motor using potmeters until the robot arm touches the bookholder.
-// This program sets the counts from the motor to the reference counts (an angle of PI/4.0)
-// Do this for every motor and after calibrated all motors, press a button
- {
- float angleReferenceF = 0.0f;
- //float angleReferenceF = angleDesiredF(); // insert kinematics output here instead of angleDesiredF()
- angleReferenceF = -angleReferenceF; // different minus sign per motor
- angleCurrentF = angleCurrent(countsF); // different minus sign per motor
- errorF = errorCalc(angleReferenceF,angleCurrentF); // same for every motor
-
- if (fabs(errorF) >= 0.01f) {
- float PIDControlF = PIDControllerF(angleReferenceF,angleCurrentF); // same for every motor
- pin6 = fabs(PIDControlF); // different pins for every motor
- pin7 = PIDControlF > 0.0f; // different pins for every motor
- } else if (fabs(errorF) < 0.01f) {
- int countsOffsetF = countsF;
- countsCalibrCalcF(countsOffsetF);
- pin6 = 0.0f;
- // BUTTON PRESS: TO NEXT STATE
- }
- }
-
- void motorTurnF() // main function for movement of motor 1, all above functions with an extra tab are called
- {
- float angleReferenceF = 0.0f;
- //float angleReferenceF = angleDesiredF(); // insert kinematics output here instead of angleDesiredF()
- angleReferenceF = -angleReferenceF; // different minus sign per motor
- int countsF = countsInputF(); // different encoder pins per motor
- angleCurrentF = angleCurrent(countsCalibratedF); // different minus sign per motor
- errorCalibratedF = errorCalc(angleReferenceF,angleCurrentF); // same for every motor
-
- float PIDControlF = PIDControllerF(angleReferenceF,angleCurrentF); // same for every motor
- pin6 = fabs(PIDControlF); // different pins for every motor
- pin7 = PIDControlF > 0.0f; // different pins for every motor
- }
// ≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡ STATE MACHINE ≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡
void stateMachine(void) {
@@ -650,7 +507,7 @@
// Actions for each loop iteration
/* */
calibrationL();
- calibrationR();
+ //calibrationR();
// --------------------------- transition ----------------------------
// Transition condition: when all motor errors smaller than 0.01,
// start calibrating EMG
@@ -839,7 +696,7 @@
ReadUseEMG1(); //Start the use of EMG
kinematics();
motorTurnL();
- motorTurnR();
+ //motorTurnR();
// --------------------------- transition ----------------------------
// Transition condition: with button press, back to homing mode
