/* * Copyright (c) 2014, Texas Instruments Incorporated * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "TurnAngleCommand.h" #include "ZumoMotors.h" #include "IMUManager.h" TurnAngleCommand::TurnAngleCommand(float angle, float timeout) { _angle = angle; spinController = PIDController((float) 6.5, (float) 0.001, (float) 0.0); numSeconds = timeout; initialized = false; targetAngleSet = false; atAngle = false; } void TurnAngleCommand::run(Utilities::MotorInfo &info) { float error; float power; if (!targetAngleSet) { float currHeading = IMUManager::getGyroYaw(); targetAngle = Utilities::wrapAngle(currHeading + _angle); targetAngleSet = true; atAngle = false; } else { error = Utilities::wrapAngle(IMUManager::getGyroYaw() - targetAngle); power = spinController.calculate(fabs(error)); bool done = Utilities::inRange(fabs(error), (float) -10.0, (float) 10.0); if (done) { atAngle = true; } if (atAngle) { power = 0; } if (fabs(power) < 10) { power = 0; } power = Utilities::clip(power); /* Note: this is used because powers higher than 250 result * in a buildup of error in the integrated gyro angle */ if (power > 250) { power = 250; } if (error > 0) { ZumoMotors::setLeftSpeed(power); ZumoMotors::setRightSpeed(-power); } else { ZumoMotors::setLeftSpeed(-power); ZumoMotors::setRightSpeed(power); } info.error = error; info.leftSpeed = power; info.rightSpeed = -power; info.time = (float) millis(); } timedOut = ((millis() - initTime) > ((int) (numSeconds * (float) 1000.0))); } void TurnAngleCommand::initialize() { initTime = millis(); initialized = true; timedOut = false; atAngle = false; targetAngleSet = false; } void TurnAngleCommand::end() { ZumoMotors::setLeftSpeed((int) 0); ZumoMotors::setRightSpeed(0); timedOut = true; initialized = false; } bool TurnAngleCommand::isFinished() { return timedOut || atAngle; } bool TurnAngleCommand::hasBeenInitialized() { return initialized; } bool TurnAngleCommand::isTimedOut() { return timedOut; }