Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Team-1261---C--/Kicker.cpp
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
277 lines (241 sloc)
5.85 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include "Constants.h" | |
| #include "Kicker.h" | |
| #include "Encoder.h" | |
| #include "Solenoid.h" | |
| #include "DigitalInput.h" | |
| #include "Joystick.h" | |
| #include "Math.h" | |
| #include <vxWorks.h> | |
| /** | |
| * Code for the kicker... Yay! | |
| */ | |
| Kicker::Kicker() | |
| { | |
| //Hardware | |
| winchMotor = new Victor(PWM_WINCH); | |
| rollerMotor = new Victor(PWM_ROLLER); | |
| sailClutch_A = new Solenoid(SOLENOID_SAIL_A); | |
| sailClutch_B = new Solenoid(SOLENOID_SAIL_B); | |
| //Sensors | |
| kickerEncoder = new Encoder(DIO_ENCODER_KICKER_A, DIO_ENCODER_KICKER_B); | |
| kickerSwitch = new DigitalInput(DIO_KICKER_SWITCH); | |
| rollerEncoder = new Encoder(DIO_ENCODER_ROLLER_A, DIO_ENCODER_ROLLER_B); | |
| kickerJoystick = new Joystick(JOYSTICK_KICK); | |
| //Other Stuff | |
| rollerOn = true; | |
| kickerMode = KICKER_MODE_ARMED; | |
| kickerHitSwitch = false; | |
| kickerInPosition = false; | |
| kickerEncoder->Start(); | |
| rollerEncoder->Start(); | |
| } | |
| void Kicker::Act() | |
| { | |
| //Arm/Kick depending on the fire button on the kicker joystick | |
| if (kickerJoystick->GetRawButton(joystickKickButton) == 1) | |
| { | |
| //If the kicker is in standby mode, who cares - life is over | |
| //If the kicker is in arm mode, do nothing | |
| //If the kicker is in kicking mode, let it continue | |
| if (kickerMode == KICKER_MODE_ARMED) | |
| { | |
| //It's armed you say? Fire it baby! | |
| kickerMode = KICKER_MODE_KICK; | |
| } | |
| } else { | |
| //If the kicker is in armed mode, do nothing | |
| //If the kicker is in arm mode, it's good to hear that it worked | |
| //If the kicker is in kicking mode, let it continue | |
| if (kickerMode == KICKER_MODE_STANDBY) | |
| { | |
| //If kicker is on standby, arm it | |
| kickerMode = KICKER_MODE_ARM; | |
| } | |
| } | |
| //Emergency armed button for those strange occations when things don't work right | |
| if (kickerJoystick->GetRawButton(joystickEmergencyArmButton) == 1) | |
| { | |
| //Don't care where we are, just do it. I hate you. | |
| kickerMode = KICKER_MODE_ARMED; | |
| } | |
| MoveRoller(rollerOn); | |
| switch(kickerMode) | |
| { | |
| case KICKER_MODE_ARM: | |
| Arm(); | |
| break; | |
| case KICKER_MODE_KICK: | |
| Kick(); | |
| break; | |
| case KICKER_MODE_ARMED: | |
| Armed(); | |
| break; | |
| case KICKER_MODE_STANDBY: | |
| default: | |
| //Waiting for things to happen... | |
| break; | |
| } | |
| } | |
| void Kicker::Arm() | |
| { | |
| rollerOn = true; | |
| //Switch is false when pressed | |
| if (!kickerSwitch->Get()) | |
| { | |
| //Turn the motor off if we haven't already | |
| if (!kickerHitSwitch) | |
| { | |
| winchMotor->Set(0); | |
| } | |
| kickerHitSwitch = true; | |
| } | |
| if (kickerHitSwitch) | |
| { | |
| //Finalize the arming process | |
| if (kickerInPosition) | |
| { | |
| //Backwind the kicker for the actual kicking part | |
| Backwind(); | |
| } else { | |
| //Keep getting into position... | |
| SetPower(); | |
| } | |
| } else { | |
| //Get the kicker into the armed position | |
| EngageSailClutch(true); | |
| winchMotor->Set(winchArmSpeed); | |
| setPoint = fabs(kickerJoystick->GetRawAxis(joystickKickPowerAxis)) * minimumSetPoint; | |
| printf("Set Point: %f", setPoint); | |
| } | |
| } | |
| void Kicker::Kick() | |
| { | |
| rollerOn = false; | |
| //Let the ball roll out a bit | |
| rollerMotor->Set(rollerReleaseBallSpeed); | |
| //In the words of Bethany Sumner, "Fire ze missiles!" | |
| EngageSailClutch(false); | |
| //And reset everything for another kick | |
| Reset(); | |
| } | |
| void Kicker::Armed() | |
| { | |
| //Stop the winch from winching and turn on the roller so we can get balls... | |
| winchMotor->Set(0); | |
| rollerOn = true; | |
| } | |
| void Kicker::Reset() | |
| { | |
| //Reset everything for another run. | |
| kickerMode = KICKER_MODE_STANDBY; | |
| kickerHitSwitch = false; | |
| kickerInPosition = false; | |
| kickerResetEncoder = false; | |
| } | |
| void Kicker::SafeReset() | |
| { | |
| //Do a safe reset (i.e. don't do anything when we're done with this) | |
| Reset(); | |
| kickerMode = KICKER_MODE_ARMED; | |
| } | |
| void Kicker::SetPower() | |
| { | |
| //Reset the encoder if we need to | |
| if (!kickerResetEncoder) | |
| { | |
| kickerEncoder->Reset(); | |
| kickerResetEncoder = true; | |
| } | |
| if (setPoint <= 0) | |
| { | |
| //Stop the kicker, even if we're at zero and supposed to be there (this comment makes no sense) | |
| EngageSailClutch(true); | |
| kickerResetEncoder = false; | |
| winchMotor->Set(0); | |
| kickerInPosition = true; | |
| } else { | |
| //Move the kicker to position (this is accurate enough) | |
| if (kickerEncoder->GetDistance() >= setPoint) | |
| { | |
| //We MIGHT be in position... maybe... ish - lock the clutch and shut everything else off | |
| EngageSailClutch(true); | |
| kickerResetEncoder = false; | |
| winchMotor->Set(0); | |
| kickerInPosition = true; | |
| } else { | |
| //Move to position, sir yes sir! | |
| EngageSailClutch(false); | |
| winchMotor->Set(winchBackwindSpeed); | |
| } | |
| } | |
| } | |
| void Kicker::EngageSailClutch(bool engage) | |
| { | |
| if (engage) | |
| { | |
| //Close the clutch (i.e. grip on the rope) | |
| sailClutch_A->Set(true); | |
| sailClutch_B->Set(false); | |
| } else { | |
| //Open the clutch | |
| sailClutch_A->Set(false); | |
| sailClutch_B->Set(true); | |
| } | |
| } | |
| void Kicker::MoveRoller(bool rollerOn) | |
| { | |
| printf("Roller Encoder: %f",rollerEncoder->GetRate()); | |
| if (rollerOn) | |
| { | |
| //Fix this - the encoder will not very likely equal zero when it stops, it'll just move very slowly. | |
| if (rollerEncoder->GetRate() == 0) | |
| { | |
| rollerMotor->Set(0); | |
| } else { | |
| rollerMotor->Set(rollerOnSpeed); | |
| } | |
| } else { | |
| rollerMotor->Set(0); | |
| } | |
| } | |
| void Kicker::Backwind() | |
| { | |
| EngageSailClutch(true); | |
| //Reset the encoder if we need to | |
| if (!kickerResetEncoder) | |
| { | |
| kickerEncoder->Reset(); | |
| kickerResetEncoder = true; | |
| } | |
| double percentRelativeToLowPower = setPoint / minimumSetPoint; | |
| double newBackwind = ((fullPowerBackwind - lowPowerBackwind) * (1 - percentRelativeToLowPower)) + lowPowerBackwind; | |
| //Backwind by using a PE loop | |
| double processVariable = fabs(kickerEncoder->GetDistance()); | |
| double error = fabs(processVariable - newBackwind) / newBackwind; | |
| if (error <= backwindTolerance) | |
| { | |
| winchMotor->Set(0); | |
| kickerMode = KICKER_MODE_ARMED; | |
| } else { | |
| //Begin backwinding the motor to release tension... | |
| double motorSpeed = error * winchBackwindSpeed; | |
| winchMotor->Set(motorSpeed); | |
| } | |
| } | |
| bool Kicker::HasBall() | |
| { | |
| if (rollerEncoder->GetRate() == 0) | |
| { | |
| return true; | |
| } else { | |
| return false; | |
| } | |
| } | |
| bool Kicker::IsKickerInPosition() | |
| { | |
| return kickerInPosition; | |
| } | |
| void Kicker::SetKickerMode(int mode) | |
| { | |
| kickerMode = mode; | |
| } |