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: mbed QEI biquadFilter
controller.cpp
- Committer:
- ronvbree
- Date:
- 2016-11-03
- Revision:
- 12:8295c02d740f
- Parent:
- 7:a80cb6b06320
- Child:
- 14:551049a798a3
File content as of revision 12:8295c02d740f:
#include "controller.h"
/*
Constructor
*/
RobotController::RobotController():
upperArmController(0.2, 0, 0),
lowerArmController(1.0, 0, 0),
upperXController(6, 0, 0),
// lowerXController(1.9, 0, 0),
lowerXController(1, 0, 0.01),
debug(USBTX, USBRX),
robot() {
// Set initial arm length as reference value
upperArmLengthReference = robot.getUpperArmLength();
lowerArmLengthReference = robot.getLowerArmLength();
// Set initial roller position as reference value
float x,y; // Can't pass volatiles by reference
getRollerPositionForArmLengths(robot.getUpperArmLength(), robot.getLowerArmLength(), x, y);
referenceX = x;
referenceY = y;
// Set movement flags
MOVE_BY_REFERENCE = false;
PAINT_MOVE_UP = false;
PAINT_MOVE_DOWN = false;
// Start ticker
ticker.attach(this, &RobotController::doTick, tick);
}
/*
Private Methods
*/
void RobotController::doTick() {
robot.update();
if (MOVE_BY_REFERENCE) {
float upperOutput = upperArmController.control(upperArmLengthReference - robot.getUpperArmLength(), tick);
float lowerOutput = lowerArmController.control(lowerArmLengthReference - robot.getLowerArmLength(), tick);
robot.setUpperArmVelocity(upperOutput);
robot.setLowerArmVelocity(lowerOutput);
}
if (PAINT_MOVE_UP) {
float x,y;
getRollerPositionForArmLengths(robot.getUpperArmLength(), robot.getLowerArmLength(), x, y);
float xError = referenceX - x;
float yError = topY - y;
float upperOutput = upperXController.control(xError, tick);
float lowerOutput = lowerArmController.control(yError, tick);
robot.setUpperArmVelocity(-1 * upperOutput);
robot.setLowerArmVelocity(lowerOutput);
}
if (PAINT_MOVE_DOWN) {
// Get current roller location and arm lengths
float x,y;
float upperArmLength = robot.getUpperArmLength();
float lowerArmLength = robot.getLowerArmLength();
getRollerPositionForArmLengths(upperArmLength, lowerArmLength, x, y);
// Get controller output for leading arm (upper arm)
float yError = bottomY - y;
float upperOutput = -1 * upperArmController.control(yError, tick);
// Predict influence on x position
float futureUpperArmLength = robot.getUpperArmLength() + robot.getUpperArmEncoderVelocity() * gearRadius * tick;
float futureX, futureY;
getRollerPositionForArmLengths(futureUpperArmLength, robot.getLowerArmLength(), futureX, futureY);
// Calculate lower arm length that is needed to compensate for the leading arm
float upper,lower;
getArmLengthsForRollerPosition(referenceX, futureY, upper, lower);
// Calculate compensating arm velocity based on error
float compensatingArmError = lower - lowerArmLength;
float lowerOutput = lowerXController.control(compensatingArmError, tick);
// float xError = referenceX - futureX;
// float lowerOutput = -1 * lowerXController.control(xError, tick);
robot.setUpperArmVelocity(upperOutput);
robot.setLowerArmVelocity(lowerOutput);
}
}
/*
Public methods
*/
// Set the reference lengths for the arms that correspond to this roller coordinate
void RobotController::moveTo(float x, float y) {
clearFlags();
float upper, lower;
getArmLengthsForRollerPosition(x, y, upper, lower); // Cant pass volatiles by reference
upperArmLengthReference = upper;
lowerArmLengthReference = lower;
MOVE_BY_REFERENCE = true;
}
// Set the arm lengths
void RobotController::setArmLengths(float upper, float lower) {
clearFlags();
upperArmLengthReference = upper;
lowerArmLengthReference = lower;
MOVE_BY_REFERENCE = true;
debug.printf("Set arm length reference to: Upper %f, Lower %f\n\r", upper, lower);
}
// Make a painting movement upwards
void RobotController::paintUp() {
clearFlags();
float x,y;
getRollerPositionForArmLengths(robot.getUpperArmLength(), robot.getLowerArmLength(), x, y);
referenceX = x;
referenceY = y;
PAINT_MOVE_UP = true;
}
// Make a painting movement downwards
void RobotController::paintDown() {
clearFlags();
float x,y;
getRollerPositionForArmLengths(robot.getUpperArmLength(), robot.getLowerArmLength(), x, y);
referenceX = x;
referenceY = y;
PAINT_MOVE_DOWN = true;
}
// Move to max y
void RobotController::goToTop() {
float upper, lower;
getArmLengthsForRollerPosition(topX, topY, upper, lower);
setArmLengths(upper, lower);
}
// Move to min y
void RobotController::goToBottom() {
float upper, lower;
getArmLengthsForRollerPosition(bottomX, bottomY, upper, lower);
setArmLengths(upper, lower);
}
// Set all movement flags to false
void RobotController::clearFlags() {
MOVE_BY_REFERENCE = false;
PAINT_MOVE_UP = false;
PAINT_MOVE_DOWN = false;
}
/*
Robot queries
*/
float RobotController::getUpperArmLength() {
return robot.getUpperArmLength();
}
float RobotController::getLowerArmLength() {
return robot.getLowerArmLength();
}
bool RobotController::isKilled() {
return robot.isKilled();
}
// Get the robot instance
Robot* RobotController::getRobot() {
return &robot;
}