Project Paint / Mbed 2 deprecated arm_control

Dependencies:   mbed QEI biquadFilter

Committer:
ronvbree
Date:
Thu Nov 03 16:29:31 2016 +0000
Revision:
18:1c9dc6caab9d
Parent:
14:551049a798a3
Child:
25:bdb854127c11
Child:
27:91dc5174333a
final

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ronvbree 0:494acf21d3bc 1 #include "controller.h"
ronvbree 0:494acf21d3bc 2
ronvbree 7:a80cb6b06320 3 /*
ronvbree 7:a80cb6b06320 4 Constructor
ronvbree 7:a80cb6b06320 5 */
ronvbree 7:a80cb6b06320 6
ronvbree 7:a80cb6b06320 7 RobotController::RobotController():
ronvbree 7:a80cb6b06320 8 upperArmController(0.2, 0, 0),
ronvbree 12:8295c02d740f 9 lowerArmController(1.0, 0, 0),
ronvbree 18:1c9dc6caab9d 10 upperXController(1.2, 0, 0.03),
ronvbree 18:1c9dc6caab9d 11 lowerXController(0.6, 0, 0.03),
ronvbree 7:a80cb6b06320 12 debug(USBTX, USBRX),
ronvbree 7:a80cb6b06320 13 robot() {
ronvbree 12:8295c02d740f 14
ronvbree 12:8295c02d740f 15 // Set initial arm length as reference value
ronvbree 12:8295c02d740f 16 upperArmLengthReference = robot.getUpperArmLength();
ronvbree 12:8295c02d740f 17 lowerArmLengthReference = robot.getLowerArmLength();
ronvbree 7:a80cb6b06320 18
ronvbree 12:8295c02d740f 19 // Set initial roller position as reference value
ronvbree 12:8295c02d740f 20 float x,y; // Can't pass volatiles by reference
ronvbree 12:8295c02d740f 21 getRollerPositionForArmLengths(robot.getUpperArmLength(), robot.getLowerArmLength(), x, y);
ronvbree 12:8295c02d740f 22 referenceX = x;
ronvbree 12:8295c02d740f 23 referenceY = y;
ronvbree 12:8295c02d740f 24
ronvbree 12:8295c02d740f 25 // Set movement flags
ronvbree 7:a80cb6b06320 26 MOVE_BY_REFERENCE = false;
ronvbree 7:a80cb6b06320 27 PAINT_MOVE_UP = false;
ronvbree 7:a80cb6b06320 28 PAINT_MOVE_DOWN = false;
ronvbree 7:a80cb6b06320 29
ronvbree 12:8295c02d740f 30 // Start ticker
ronvbree 7:a80cb6b06320 31 ticker.attach(this, &RobotController::doTick, tick);
ronvbree 7:a80cb6b06320 32
ronvbree 7:a80cb6b06320 33 }
ronvbree 7:a80cb6b06320 34
ronvbree 7:a80cb6b06320 35 /*
ronvbree 7:a80cb6b06320 36 Private Methods
ronvbree 7:a80cb6b06320 37 */
ronvbree 7:a80cb6b06320 38
ronvbree 7:a80cb6b06320 39 void RobotController::doTick() {
ronvbree 7:a80cb6b06320 40 robot.update();
ronvbree 7:a80cb6b06320 41
ronvbree 7:a80cb6b06320 42 if (MOVE_BY_REFERENCE) {
ronvbree 7:a80cb6b06320 43 float upperOutput = upperArmController.control(upperArmLengthReference - robot.getUpperArmLength(), tick);
ronvbree 7:a80cb6b06320 44 float lowerOutput = lowerArmController.control(lowerArmLengthReference - robot.getLowerArmLength(), tick);
ronvbree 7:a80cb6b06320 45
ronvbree 7:a80cb6b06320 46 robot.setUpperArmVelocity(upperOutput);
ronvbree 7:a80cb6b06320 47 robot.setLowerArmVelocity(lowerOutput);
ronvbree 7:a80cb6b06320 48 }
ronvbree 0:494acf21d3bc 49
ronvbree 7:a80cb6b06320 50 if (PAINT_MOVE_UP) {
ronvbree 18:1c9dc6caab9d 51 // Get current roller location and arm lengths
ronvbree 12:8295c02d740f 52 float x,y;
ronvbree 18:1c9dc6caab9d 53 float upperArmLength = robot.getUpperArmLength();
ronvbree 18:1c9dc6caab9d 54 float lowerArmLength = robot.getLowerArmLength();
ronvbree 18:1c9dc6caab9d 55 getRollerPositionForArmLengths(upperArmLength, lowerArmLength, x, y);
ronvbree 12:8295c02d740f 56
ronvbree 18:1c9dc6caab9d 57 // Get controller output for leading arm (lower arm)
ronvbree 12:8295c02d740f 58 float yError = topY - y;
ronvbree 12:8295c02d740f 59 float lowerOutput = lowerArmController.control(yError, tick);
ronvbree 12:8295c02d740f 60
ronvbree 18:1c9dc6caab9d 61 // Predict influence on x position
ronvbree 18:1c9dc6caab9d 62 float futureLowerArmLength = lowerArmLength + robot.getLowerArmEncoderVelocity() * gearRadius * tick;
ronvbree 18:1c9dc6caab9d 63 float futureX, futureY;
ronvbree 18:1c9dc6caab9d 64 getRollerPositionForArmLengths(upperArmLength, futureLowerArmLength, futureX, futureY);
ronvbree 18:1c9dc6caab9d 65
ronvbree 18:1c9dc6caab9d 66 // Calculate upper arm length that is needed to compensate for the leading arm
ronvbree 18:1c9dc6caab9d 67 float upper,lower;
ronvbree 18:1c9dc6caab9d 68 getArmLengthsForRollerPosition(topX, futureY, upper, lower);
ronvbree 18:1c9dc6caab9d 69
ronvbree 18:1c9dc6caab9d 70 // Calculate compensating arm velocity based on error
ronvbree 18:1c9dc6caab9d 71 float compensatingArmError = upper - upperArmLength;
ronvbree 18:1c9dc6caab9d 72 debug.printf("Upper Arm error: %f\n\r", compensatingArmError);
ronvbree 18:1c9dc6caab9d 73
ronvbree 18:1c9dc6caab9d 74 float upperOutput = upperXController.control(compensatingArmError, tick);
ronvbree 18:1c9dc6caab9d 75
ronvbree 18:1c9dc6caab9d 76 debug.printf("Resulting reference velocity: %f\n\r", upperOutput);
ronvbree 18:1c9dc6caab9d 77
ronvbree 18:1c9dc6caab9d 78 // Instruct arm motors
ronvbree 18:1c9dc6caab9d 79 robot.setUpperArmVelocity(upperOutput);
ronvbree 12:8295c02d740f 80 robot.setLowerArmVelocity(lowerOutput);
ronvbree 7:a80cb6b06320 81
ronvbree 7:a80cb6b06320 82 }
ronvbree 7:a80cb6b06320 83
ronvbree 7:a80cb6b06320 84 if (PAINT_MOVE_DOWN) {
ronvbree 12:8295c02d740f 85 // Get current roller location and arm lengths
ronvbree 12:8295c02d740f 86 float x,y;
ronvbree 12:8295c02d740f 87 float upperArmLength = robot.getUpperArmLength();
ronvbree 12:8295c02d740f 88 float lowerArmLength = robot.getLowerArmLength();
ronvbree 12:8295c02d740f 89 getRollerPositionForArmLengths(upperArmLength, lowerArmLength, x, y);
ronvbree 12:8295c02d740f 90
ronvbree 12:8295c02d740f 91 // Get controller output for leading arm (upper arm)
ronvbree 12:8295c02d740f 92 float yError = bottomY - y;
ronvbree 12:8295c02d740f 93 float upperOutput = -1 * upperArmController.control(yError, tick);
ronvbree 12:8295c02d740f 94
ronvbree 12:8295c02d740f 95 // Predict influence on x position
ronvbree 18:1c9dc6caab9d 96 float futureUpperArmLength = upperArmLength + robot.getUpperArmEncoderVelocity() * gearRadius * tick;
ronvbree 12:8295c02d740f 97 float futureX, futureY;
ronvbree 18:1c9dc6caab9d 98 getRollerPositionForArmLengths(futureUpperArmLength, lowerArmLength, futureX, futureY);
ronvbree 12:8295c02d740f 99
ronvbree 12:8295c02d740f 100 // Calculate lower arm length that is needed to compensate for the leading arm
ronvbree 12:8295c02d740f 101 float upper,lower;
ronvbree 18:1c9dc6caab9d 102 getArmLengthsForRollerPosition(bottomX, futureY, upper, lower);
ronvbree 12:8295c02d740f 103
ronvbree 12:8295c02d740f 104 // Calculate compensating arm velocity based on error
ronvbree 12:8295c02d740f 105 float compensatingArmError = lower - lowerArmLength;
ronvbree 12:8295c02d740f 106 float lowerOutput = lowerXController.control(compensatingArmError, tick);
ronvbree 12:8295c02d740f 107
ronvbree 18:1c9dc6caab9d 108 // Instruct arm motors
ronvbree 12:8295c02d740f 109 robot.setUpperArmVelocity(upperOutput);
ronvbree 12:8295c02d740f 110 robot.setLowerArmVelocity(lowerOutput);
ronvbree 7:a80cb6b06320 111
ronvbree 0:494acf21d3bc 112 }
ronvbree 0:494acf21d3bc 113 }
ronvbree 0:494acf21d3bc 114
ronvbree 7:a80cb6b06320 115 /*
ronvbree 7:a80cb6b06320 116 Public methods
ronvbree 7:a80cb6b06320 117 */
ronvbree 7:a80cb6b06320 118
ronvbree 7:a80cb6b06320 119
ronvbree 7:a80cb6b06320 120 // Set the reference lengths for the arms that correspond to this roller coordinate
ronvbree 7:a80cb6b06320 121 void RobotController::moveTo(float x, float y) {
ronvbree 12:8295c02d740f 122 clearFlags();
ronvbree 7:a80cb6b06320 123 float upper, lower;
ronvbree 7:a80cb6b06320 124 getArmLengthsForRollerPosition(x, y, upper, lower); // Cant pass volatiles by reference
ronvbree 7:a80cb6b06320 125 upperArmLengthReference = upper;
ronvbree 7:a80cb6b06320 126 lowerArmLengthReference = lower;
ronvbree 12:8295c02d740f 127
ronvbree 7:a80cb6b06320 128 MOVE_BY_REFERENCE = true;
ronvbree 7:a80cb6b06320 129 }
ronvbree 7:a80cb6b06320 130
ronvbree 7:a80cb6b06320 131 // Set the arm lengths
ronvbree 7:a80cb6b06320 132 void RobotController::setArmLengths(float upper, float lower) {
ronvbree 12:8295c02d740f 133 clearFlags();
ronvbree 12:8295c02d740f 134
ronvbree 7:a80cb6b06320 135 upperArmLengthReference = upper;
ronvbree 7:a80cb6b06320 136 lowerArmLengthReference = lower;
ronvbree 7:a80cb6b06320 137
ronvbree 7:a80cb6b06320 138 MOVE_BY_REFERENCE = true;
ronvbree 7:a80cb6b06320 139
ronvbree 7:a80cb6b06320 140 debug.printf("Set arm length reference to: Upper %f, Lower %f\n\r", upper, lower);
ronvbree 7:a80cb6b06320 141 }
ronvbree 7:a80cb6b06320 142
ronvbree 12:8295c02d740f 143 // Make a painting movement upwards
ronvbree 12:8295c02d740f 144 void RobotController::paintUp() {
ronvbree 12:8295c02d740f 145 clearFlags();
ronvbree 12:8295c02d740f 146 float x,y;
ronvbree 12:8295c02d740f 147 getRollerPositionForArmLengths(robot.getUpperArmLength(), robot.getLowerArmLength(), x, y);
ronvbree 12:8295c02d740f 148 referenceX = x;
ronvbree 12:8295c02d740f 149 referenceY = y;
ronvbree 0:494acf21d3bc 150
ronvbree 12:8295c02d740f 151 PAINT_MOVE_UP = true;
ronvbree 12:8295c02d740f 152
ronvbree 12:8295c02d740f 153 }
ronvbree 0:494acf21d3bc 154
ronvbree 12:8295c02d740f 155 // Make a painting movement downwards
ronvbree 12:8295c02d740f 156 void RobotController::paintDown() {
ronvbree 12:8295c02d740f 157 clearFlags();
ronvbree 12:8295c02d740f 158 float x,y;
ronvbree 12:8295c02d740f 159 getRollerPositionForArmLengths(robot.getUpperArmLength(), robot.getLowerArmLength(), x, y);
ronvbree 12:8295c02d740f 160 referenceX = x;
ronvbree 12:8295c02d740f 161 referenceY = y;
ronvbree 12:8295c02d740f 162
ronvbree 12:8295c02d740f 163 PAINT_MOVE_DOWN = true;
ronvbree 12:8295c02d740f 164
ronvbree 12:8295c02d740f 165 }
ronvbree 7:a80cb6b06320 166
ronvbree 12:8295c02d740f 167 // Move to max y
ronvbree 12:8295c02d740f 168 void RobotController::goToTop() {
ronvbree 12:8295c02d740f 169 float upper, lower;
ronvbree 12:8295c02d740f 170 getArmLengthsForRollerPosition(topX, topY, upper, lower);
ronvbree 12:8295c02d740f 171 setArmLengths(upper, lower);
ronvbree 12:8295c02d740f 172 }
ronvbree 7:a80cb6b06320 173
ronvbree 12:8295c02d740f 174 // Move to min y
ronvbree 12:8295c02d740f 175 void RobotController::goToBottom() {
ronvbree 12:8295c02d740f 176 float upper, lower;
ronvbree 12:8295c02d740f 177 getArmLengthsForRollerPosition(bottomX, bottomY, upper, lower);
ronvbree 12:8295c02d740f 178 setArmLengths(upper, lower);
ronvbree 12:8295c02d740f 179 }
ronvbree 12:8295c02d740f 180
ronvbree 12:8295c02d740f 181 // Set all movement flags to false
ronvbree 12:8295c02d740f 182 void RobotController::clearFlags() {
ronvbree 12:8295c02d740f 183 MOVE_BY_REFERENCE = false;
ronvbree 12:8295c02d740f 184 PAINT_MOVE_UP = false;
ronvbree 12:8295c02d740f 185 PAINT_MOVE_DOWN = false;
ronvbree 12:8295c02d740f 186 }
ronvbree 7:a80cb6b06320 187
ronvbree 7:a80cb6b06320 188 /*
ronvbree 7:a80cb6b06320 189 Robot queries
ronvbree 7:a80cb6b06320 190 */
ronvbree 7:a80cb6b06320 191
ronvbree 7:a80cb6b06320 192 float RobotController::getUpperArmLength() {
ronvbree 7:a80cb6b06320 193 return robot.getUpperArmLength();
ronvbree 7:a80cb6b06320 194 }
ronvbree 7:a80cb6b06320 195
ronvbree 7:a80cb6b06320 196 float RobotController::getLowerArmLength() {
ronvbree 7:a80cb6b06320 197 return robot.getLowerArmLength();
ronvbree 7:a80cb6b06320 198 }
ronvbree 7:a80cb6b06320 199
ronvbree 7:a80cb6b06320 200 bool RobotController::isKilled() {
ronvbree 7:a80cb6b06320 201 return robot.isKilled();
ronvbree 7:a80cb6b06320 202 }
ronvbree 7:a80cb6b06320 203
ronvbree 12:8295c02d740f 204 // Get the robot instance
ronvbree 7:a80cb6b06320 205 Robot* RobotController::getRobot() {
ronvbree 7:a80cb6b06320 206 return &robot;
ronvbree 7:a80cb6b06320 207 }
ronvbree 7:a80cb6b06320 208
ronvbree 7:a80cb6b06320 209