Project Paint / Mbed 2 deprecated arm_control

Dependencies:   mbed QEI biquadFilter

Committer:
Jankoekenpan
Date:
Thu Nov 03 18:23:51 2016 +0000
Revision:
28:09b08753498c
Parent:
27:91dc5174333a
Parent:
25:bdb854127c11
merge rons comments with my demo version

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 25:bdb854127c11 42 /*
ronvbree 25:bdb854127c11 43 MOVE BY REFERENCE
ronvbree 25:bdb854127c11 44
ronvbree 25:bdb854127c11 45 Movement is done based on the upperArmLengthReference and lowerArmLengthReference instance variables. An error between the current (estimated) arm
ronvbree 25:bdb854127c11 46 length and reference arm length is used to generate a proportional velocity to remove the error.
ronvbree 25:bdb854127c11 47 */
ronvbree 7:a80cb6b06320 48 if (MOVE_BY_REFERENCE) {
ronvbree 25:bdb854127c11 49 // Generate control velocities (rad/s)
ronvbree 7:a80cb6b06320 50 float upperOutput = upperArmController.control(upperArmLengthReference - robot.getUpperArmLength(), tick);
ronvbree 7:a80cb6b06320 51 float lowerOutput = lowerArmController.control(lowerArmLengthReference - robot.getLowerArmLength(), tick);
ronvbree 25:bdb854127c11 52 // Instruct motors
ronvbree 7:a80cb6b06320 53 robot.setUpperArmVelocity(upperOutput);
ronvbree 7:a80cb6b06320 54 robot.setLowerArmVelocity(lowerOutput);
ronvbree 7:a80cb6b06320 55 }
ronvbree 25:bdb854127c11 56 /*
ronvbree 25:bdb854127c11 57 PAINT MOVE UP
ronvbree 25:bdb854127c11 58
ronvbree 25:bdb854127c11 59 Painting movement makes a distinction between the two arms. One arm, which is referred to as the leading arm, controls the y value of the roller.
ronvbree 25:bdb854127c11 60 Painting upwards will require an increase in the y-coordinate of the roller. The velocity of the leading arm is proportional to the error in y
ronvbree 25:bdb854127c11 61 values.
ronvbree 25:bdb854127c11 62 The leading arm will, by altering the height of the roller, also influence the x coordinate of the roller. The other arm will compensate for this.
ronvbree 25:bdb854127c11 63 A prediction is made where the other arm will be the next tick (based on the arm's encoder velocity). This is used to make a prediction about the
ronvbree 25:bdb854127c11 64 location of the roller and which arm length is needed to compensate for the error of x. A PD-Controller then outputs a velocity to the compensating
ronvbree 25:bdb854127c11 65 arm, based on the length which is required to set x to its desired value.
ronvbree 25:bdb854127c11 66
ronvbree 25:bdb854127c11 67 */
ronvbree 7:a80cb6b06320 68 if (PAINT_MOVE_UP) {
ronvbree 18:1c9dc6caab9d 69 // Get current roller location and arm lengths
ronvbree 12:8295c02d740f 70 float x,y;
ronvbree 18:1c9dc6caab9d 71 float upperArmLength = robot.getUpperArmLength();
ronvbree 18:1c9dc6caab9d 72 float lowerArmLength = robot.getLowerArmLength();
ronvbree 18:1c9dc6caab9d 73 getRollerPositionForArmLengths(upperArmLength, lowerArmLength, x, y);
ronvbree 12:8295c02d740f 74
ronvbree 18:1c9dc6caab9d 75 // Get controller output for leading arm (lower arm)
ronvbree 12:8295c02d740f 76 float yError = topY - y;
ronvbree 12:8295c02d740f 77 float lowerOutput = lowerArmController.control(yError, tick);
ronvbree 12:8295c02d740f 78
ronvbree 18:1c9dc6caab9d 79 // Predict influence on x position
ronvbree 18:1c9dc6caab9d 80 float futureLowerArmLength = lowerArmLength + robot.getLowerArmEncoderVelocity() * gearRadius * tick;
ronvbree 18:1c9dc6caab9d 81 float futureX, futureY;
ronvbree 18:1c9dc6caab9d 82 getRollerPositionForArmLengths(upperArmLength, futureLowerArmLength, futureX, futureY);
ronvbree 18:1c9dc6caab9d 83
ronvbree 18:1c9dc6caab9d 84 // Calculate upper arm length that is needed to compensate for the leading arm
ronvbree 18:1c9dc6caab9d 85 float upper,lower;
ronvbree 18:1c9dc6caab9d 86 getArmLengthsForRollerPosition(topX, futureY, upper, lower);
ronvbree 18:1c9dc6caab9d 87
ronvbree 18:1c9dc6caab9d 88 // Calculate compensating arm velocity based on error
ronvbree 18:1c9dc6caab9d 89 float compensatingArmError = upper - upperArmLength;
ronvbree 18:1c9dc6caab9d 90 float upperOutput = upperXController.control(compensatingArmError, tick);
ronvbree 18:1c9dc6caab9d 91
Jankoekenpan 28:09b08753498c 92
ronvbree 18:1c9dc6caab9d 93 // Instruct arm motors
ronvbree 18:1c9dc6caab9d 94 robot.setUpperArmVelocity(upperOutput);
ronvbree 12:8295c02d740f 95 robot.setLowerArmVelocity(lowerOutput);
ronvbree 7:a80cb6b06320 96
ronvbree 7:a80cb6b06320 97 }
ronvbree 7:a80cb6b06320 98
ronvbree 25:bdb854127c11 99 /*
ronvbree 25:bdb854127c11 100 PAINT MOVE DOWN
ronvbree 25:bdb854127c11 101
ronvbree 25:bdb854127c11 102 Very similar to paint move up.^
ronvbree 25:bdb854127c11 103 */
ronvbree 7:a80cb6b06320 104 if (PAINT_MOVE_DOWN) {
ronvbree 12:8295c02d740f 105 // Get current roller location and arm lengths
ronvbree 12:8295c02d740f 106 float x,y;
ronvbree 12:8295c02d740f 107 float upperArmLength = robot.getUpperArmLength();
ronvbree 12:8295c02d740f 108 float lowerArmLength = robot.getLowerArmLength();
ronvbree 12:8295c02d740f 109 getRollerPositionForArmLengths(upperArmLength, lowerArmLength, x, y);
ronvbree 12:8295c02d740f 110
ronvbree 12:8295c02d740f 111 // Get controller output for leading arm (upper arm)
ronvbree 12:8295c02d740f 112 float yError = bottomY - y;
ronvbree 12:8295c02d740f 113 float upperOutput = -1 * upperArmController.control(yError, tick);
ronvbree 12:8295c02d740f 114
ronvbree 12:8295c02d740f 115 // Predict influence on x position
ronvbree 18:1c9dc6caab9d 116 float futureUpperArmLength = upperArmLength + robot.getUpperArmEncoderVelocity() * gearRadius * tick;
ronvbree 12:8295c02d740f 117 float futureX, futureY;
ronvbree 18:1c9dc6caab9d 118 getRollerPositionForArmLengths(futureUpperArmLength, lowerArmLength, futureX, futureY);
ronvbree 12:8295c02d740f 119
ronvbree 12:8295c02d740f 120 // Calculate lower arm length that is needed to compensate for the leading arm
ronvbree 12:8295c02d740f 121 float upper,lower;
ronvbree 18:1c9dc6caab9d 122 getArmLengthsForRollerPosition(bottomX, futureY, upper, lower);
ronvbree 12:8295c02d740f 123
ronvbree 12:8295c02d740f 124 // Calculate compensating arm velocity based on error
ronvbree 12:8295c02d740f 125 float compensatingArmError = lower - lowerArmLength;
ronvbree 12:8295c02d740f 126 float lowerOutput = lowerXController.control(compensatingArmError, tick);
ronvbree 12:8295c02d740f 127
ronvbree 18:1c9dc6caab9d 128 // Instruct arm motors
ronvbree 12:8295c02d740f 129 robot.setUpperArmVelocity(upperOutput);
ronvbree 12:8295c02d740f 130 robot.setLowerArmVelocity(lowerOutput);
ronvbree 7:a80cb6b06320 131
ronvbree 0:494acf21d3bc 132 }
ronvbree 0:494acf21d3bc 133 }
ronvbree 0:494acf21d3bc 134
ronvbree 7:a80cb6b06320 135 /*
ronvbree 7:a80cb6b06320 136 Public methods
ronvbree 7:a80cb6b06320 137 */
ronvbree 7:a80cb6b06320 138
ronvbree 7:a80cb6b06320 139
ronvbree 7:a80cb6b06320 140 // Set the reference lengths for the arms that correspond to this roller coordinate
ronvbree 7:a80cb6b06320 141 void RobotController::moveTo(float x, float y) {
ronvbree 12:8295c02d740f 142 clearFlags();
ronvbree 7:a80cb6b06320 143 float upper, lower;
ronvbree 7:a80cb6b06320 144 getArmLengthsForRollerPosition(x, y, upper, lower); // Cant pass volatiles by reference
ronvbree 7:a80cb6b06320 145 upperArmLengthReference = upper;
ronvbree 7:a80cb6b06320 146 lowerArmLengthReference = lower;
ronvbree 12:8295c02d740f 147
ronvbree 7:a80cb6b06320 148 MOVE_BY_REFERENCE = true;
ronvbree 7:a80cb6b06320 149 }
ronvbree 7:a80cb6b06320 150
ronvbree 7:a80cb6b06320 151 // Set the arm lengths
ronvbree 7:a80cb6b06320 152 void RobotController::setArmLengths(float upper, float lower) {
ronvbree 12:8295c02d740f 153 clearFlags();
ronvbree 12:8295c02d740f 154
ronvbree 7:a80cb6b06320 155 upperArmLengthReference = upper;
ronvbree 7:a80cb6b06320 156 lowerArmLengthReference = lower;
ronvbree 7:a80cb6b06320 157
ronvbree 7:a80cb6b06320 158 MOVE_BY_REFERENCE = true;
ronvbree 7:a80cb6b06320 159 }
ronvbree 7:a80cb6b06320 160
ronvbree 12:8295c02d740f 161 // Make a painting movement upwards
ronvbree 12:8295c02d740f 162 void RobotController::paintUp() {
ronvbree 12:8295c02d740f 163 clearFlags();
ronvbree 12:8295c02d740f 164 float x,y;
ronvbree 12:8295c02d740f 165 getRollerPositionForArmLengths(robot.getUpperArmLength(), robot.getLowerArmLength(), x, y);
ronvbree 12:8295c02d740f 166 referenceX = x;
ronvbree 12:8295c02d740f 167 referenceY = y;
ronvbree 0:494acf21d3bc 168
ronvbree 12:8295c02d740f 169 PAINT_MOVE_UP = true;
ronvbree 12:8295c02d740f 170
ronvbree 12:8295c02d740f 171 }
ronvbree 0:494acf21d3bc 172
ronvbree 12:8295c02d740f 173 // Make a painting movement downwards
ronvbree 12:8295c02d740f 174 void RobotController::paintDown() {
ronvbree 12:8295c02d740f 175 clearFlags();
ronvbree 12:8295c02d740f 176 float x,y;
ronvbree 12:8295c02d740f 177 getRollerPositionForArmLengths(robot.getUpperArmLength(), robot.getLowerArmLength(), x, y);
ronvbree 12:8295c02d740f 178 referenceX = x;
ronvbree 12:8295c02d740f 179 referenceY = y;
ronvbree 12:8295c02d740f 180
ronvbree 12:8295c02d740f 181 PAINT_MOVE_DOWN = true;
ronvbree 12:8295c02d740f 182
ronvbree 12:8295c02d740f 183 }
ronvbree 7:a80cb6b06320 184
ronvbree 12:8295c02d740f 185 // Move to max y
ronvbree 12:8295c02d740f 186 void RobotController::goToTop() {
ronvbree 12:8295c02d740f 187 float upper, lower;
ronvbree 12:8295c02d740f 188 getArmLengthsForRollerPosition(topX, topY, upper, lower);
ronvbree 12:8295c02d740f 189 setArmLengths(upper, lower);
ronvbree 12:8295c02d740f 190 }
ronvbree 7:a80cb6b06320 191
ronvbree 12:8295c02d740f 192 // Move to min y
ronvbree 12:8295c02d740f 193 void RobotController::goToBottom() {
ronvbree 12:8295c02d740f 194 float upper, lower;
ronvbree 12:8295c02d740f 195 getArmLengthsForRollerPosition(bottomX, bottomY, upper, lower);
ronvbree 12:8295c02d740f 196 setArmLengths(upper, lower);
ronvbree 12:8295c02d740f 197 }
ronvbree 12:8295c02d740f 198
ronvbree 12:8295c02d740f 199 // Set all movement flags to false
ronvbree 12:8295c02d740f 200 void RobotController::clearFlags() {
ronvbree 12:8295c02d740f 201 MOVE_BY_REFERENCE = false;
ronvbree 12:8295c02d740f 202 PAINT_MOVE_UP = false;
ronvbree 12:8295c02d740f 203 PAINT_MOVE_DOWN = false;
ronvbree 12:8295c02d740f 204 }
ronvbree 7:a80cb6b06320 205
ronvbree 7:a80cb6b06320 206 /*
ronvbree 7:a80cb6b06320 207 Robot queries
ronvbree 7:a80cb6b06320 208 */
ronvbree 7:a80cb6b06320 209
ronvbree 7:a80cb6b06320 210 float RobotController::getUpperArmLength() {
ronvbree 7:a80cb6b06320 211 return robot.getUpperArmLength();
ronvbree 7:a80cb6b06320 212 }
ronvbree 7:a80cb6b06320 213
ronvbree 7:a80cb6b06320 214 float RobotController::getLowerArmLength() {
ronvbree 7:a80cb6b06320 215 return robot.getLowerArmLength();
ronvbree 7:a80cb6b06320 216 }
ronvbree 7:a80cb6b06320 217
ronvbree 7:a80cb6b06320 218 bool RobotController::isKilled() {
ronvbree 7:a80cb6b06320 219 return robot.isKilled();
ronvbree 7:a80cb6b06320 220 }
ronvbree 7:a80cb6b06320 221
ronvbree 12:8295c02d740f 222 // Get the robot instance
ronvbree 7:a80cb6b06320 223 Robot* RobotController::getRobot() {
ronvbree 7:a80cb6b06320 224 return &robot;
ronvbree 7:a80cb6b06320 225 }
ronvbree 7:a80cb6b06320 226
ronvbree 7:a80cb6b06320 227