Permalink
Find file
Fetching contributors…
Cannot retrieve contributors at this time
1379 lines (1227 sloc) 40.8 KB
#include "WPILib.h"
//#include "Robot2012.h"
#include "Vision/AxisCamera.h"
#include "nivision.h"
#include "ImageProcessing.h"
#include "customPIDs.h"
#include "AnalogRangeFinder.h"
////////////////////////////////////////////////////////
// Defines and typedefs
////////////////////////////////////////////////////////
#define ANALOG_OUTPUT_CHANNEL 1 //in 2012 this should be in slot 1 (chan 1), or slot 5 (chan 2)
#define DIGITAL_OUTPUT_CHANNEL 1 //in 2012 this should be in slot 2 (chan 1), or slot 7 (chan 2)
#define SOLENOID_OUTPUT_CHANNEL 1 //in 2012 this should be in slot 3 (chan 1), or slot 6 (chan 2)
#define CATAPULT_FIRE_TIME 1.0
#define CATAPULT_REARM_TIME 1.00
#define CATAPULT_RELOAD_TIME_FOUR_BALL 2.00
#define SLOW_PICKUP_DURING_RELOAD_START 0.25
#define CATAPULT_LATCH_TIME 0.2
//Loading from the floor occurs at times: (note: ideally, drop at <1.0 and at 6.25)
//First ball time < 1.0 (CATAPULT_FIRE_TIME) sec or 3.0 (FIRE + REARM + SLOW_PICKUP) < time < 6.75 ( 1 FULL CYCLE + FIRE + REARM)
//Second ball 6.25 < time < 10.0 (previous times + CYCLE_TIME)
//Generically ((CYCLE_TIME * EXTRA_BALL_NUM) - (RELOAD_TIME - SLOW_PICKUP)) < time < ((CYCLE_TIME * EXTRA_BALL_NUM) + FIRE_TIME + REARM_TIME)
//Ball fire times = 4.0 * (ball_num - 1) (0,4,8,12,16,20)
#define AUTONOMOUS_BACKUP_SPEED_SLOW -0.45
#define AUTONOMOUS_BACKUP_SPEED_FAST -0.7
#define AUTONOMOUS_BACKUP_TIME_SLOW (2.1 + AUTONOMOUS_BACKUP_TIME_FAST)
#define AUTONOMOUS_BACKUP_TIME_FAST (1.0 + AUTONOMOUS_BACKUP_TIME_WAIT)
#define AUTONOMOUS_BACKUP_TIME_WAIT 1.0
#define AUTONOMOUS_FENDER_SHOT_FAST (-0.55)
#define AUTONOMOUS_FENDER_SHOT_SLOW (-0.3)
//#define CATAPULT_PRELOAD_TIME_FOUR_BALL 0.1 //How long we turn on the reload roller before the catapult finishes rearming
//Fire 0.0sec
//Rearm start 0.0sec
//preload CATAPULT_REARM_TIME - CATAPULT_PRELOAD_TIME_FOUR_BALL
//reloading CATAPULT_REARM_TIME
//slow ball collect CATAPULT_REARM_TIME + 1.0
//fire again CATAPULT_REARM_TIME + CATAPULT_RELOAD_TIME_FOUR_BALL
#define ANGLE_POSITION_BASE 0.0
#define ANGLE_POSITION_TOLERANCE 0.5
#define DISTANCE_POSITION_BASE 152.0
#define DISTANCE_POSITION_TOLERANCE 1.0
#define CAMERA_MAX_FPS 10
#define CAMERA_BRIGHTNESS_LEVEL 5
#define CAMERA_COLOR_LEVEL 100
#define VERY_SLOW_TURN 0.20F
#define SLOW_TURN 0.30F
#define FAST_TURN 0.40F
#define ELEVATOR_SPEED_BOTTOM 0.8F
#define ELEVATOR_SPEED_BOTTOM_SLOW 0.3F
#define ELEVATOR_SPEED_TOP 1.0F
#define DUMPER_ROLLER_RPM 4100.0F
#define DUMPER_ROLLER_POWER 0.725
#define DUMPER_ROLLER_COUNTS_PER_REVOLUTION (400) //This is a property of the encoder we bought, don't change
#define DUMPER_ROLLER_FILTER_CONSTANT 0.1
#define DUMPER_ROLLER_VOLTAGE_RAMP_RATE 0.19
#define CENTER_OF_IMAGE 160
#define HALF_HORIZONTAL_FIELD_OF_VIEW 24.40828F
#define HORIZONTAL_DEGREES_PER_PIXEL (HALF_HORIZONTAL_FIELD_OF_VIEW/CENTER_OF_IMAGE)
#define HALF_VERTICAL_FIELD_OF_VIEW 19.13711F
#define TANGENT_OF_HALF_VERTICAL_FIELD_OF_VIEW .347007F
#define TARGET_HEIGHT_IN_FEET 1.5F
#define IMAGE_HEIGHT_IN_PIXELS 240
#define IMAGE_HEIGHT_IN_FEET(target_height_pxls) ((TARGET_HEIGHT_IN_FEET * (IMAGE_HEIGHT_IN_PIXELS / 2)) / target_height_pxls)
#define CALCULATE_DISTANCE(target_height_pxls) (IMAGE_HEIGHT_IN_FEET(target_height_pxls)/TANGENT_OF_HALF_VERTICAL_FIELD_OF_VIEW)
#define FPGA_TIME_TO_MINUTES_FACTOR (60 * 1000 * 1000) //FPGA time is in uSec
//Controls defines - for new buttons, add a #define here and use it to get the key you want, that way we can change controls easily
#define BUTTON_CAMERA_ALIGN_SHOT_BUTTON() stickRightDrive.GetTrigger()
#define BUTTON_CAMERA_TAKE_DEBUG_PICTURES() stickRightDrive.GetRawButton(3)
#define BUTTON_ELEVATOR_BOTTOM_UP() (stickShooter.GetRawButton(2) || stickRightDrive.GetTop())
#define BUTTON_ELEVATOR_BOTTOM_DOWN() stickShooter.GetRawButton(3)
#define BUTTON_ELEVATOR_TOP_UP() stickShooter.GetRawButton(4)
#define BUTTON_ELEVATOR_TOP_DOWN() stickShooter.GetRawButton(5)
#define BUTTON_CATAPULT_SHOOT() stickShooter.GetTrigger()
#define BUTTON_CATAPULT_LATCH() stickShooter.GetTrigger()
#define BUTTON_CATAPULT_FORCE_SHOOT() stickShooter.GetRawButton(10)
//#define THROTTLE_TOP_ROLLER() ((stickShooter.GetThrottle() + 1) / 2)
#define BUTTON_DUMPER_RAMP_EXTEND() stickShooter.GetRawButton(9)
#define BUTTON_DUMPER_ROLLER() stickShooter.GetRawButton(11)
#define BUTTON_BRIDGE_RAM_TOGGLE() stickLeftDrive.GetTop()
#define BUTTON_STINGER_TOGGLE() (stickLeftDrive.GetRawButton(5) && stickRightDrive.GetRawButton(4))
//#define BUTTON_COMBO_SWITCH_AUTONOMOUS() (stickShooter.GetTrigger() && stickLeftDrive.GetTrigger() && stickRightDrive.GetTrigger())
#define BUTTON_COMBO_SWITCH_AUTONOMOUS() (stickRightDrive.GetTrigger())
//Kinect defines
#define KINECT_HEAD_RIGHT() kinectLeft.GetRawButton(1)
#define KINECT_HEAD_LEFT() kinectLeft.GetRawButton(2)
#define KINECT_RIGHT_LEG_RIGHT() kinectLeft.GetRawButton(3)
#define KINECT_LEFT_LEG_LEFT() kinectLeft.GetRawButton(4)
#define KINECT_RIGHT_LEG_FORWARD() kinectLeft.GetRawButton(5)
#define KINECT_RIGHT_LEG_BACK() kinectLeft.GetRawButton(6)
#define KINECT_LEFT_LEG_FORWARD() kinectLeft.GetRawButton(7)
#define KINECT_LEFT_LEG_BACK() kinectLeft.GetRawButton(8)
#define KINECT_CONTROL_ENABLED() kinectLeft.GetRawButton(9)
#define KINECT_ELEVATORS_UP() KINECT_RIGHT_LEG_RIGHT()
#define KINECT_ELEVATORS_DOWN() KINECT_LEFT_LEG_LEFT()
#define KINECT_AUTONOMOUS_SHOOT() KINECT_HEAD_RIGHT()
#define KINECT_BRIDGE_RAM_EXTEND() KINECT_HEAD_LEFT()
//PID Parameters
#define ROTATION_PID_PROPORTION 0.26
#define ROTATION_PID_INTEGRAL 0.07
#define ROTATION_PID_DERIVATIVE 0.36
#define ROTATION_PID_MIN_INPUT -30.0
#define ROTATION_PID_MAX_INPUT 30.0
#define ROTATION_PID_MIN_OUTPUT -1.00
#define ROTATION_PID_MAX_OUTPUT 1.00
#define ROTATION_PID_TOLERENCE_FIRST 2.50
#define ROTATION_PID_TOLERENCE_LAST 0.50
#define ROTATION_PID_SETPOINT_OFFSET -1.0 //negative adjusts to the right
#define RANGE_PID_PROPORTION 0.02
#define RANGE_PID_INTEGRAL 0.0005
#define RANGE_PID_DERIVATIVE 0.005
#define RANGE_PID_MIN_INPUT 0.0
#define RANGE_PID_MAX_INPUT 240.0
#define RANGE_PID_MIN_OUTPUT -0.40
#define RANGE_PID_MAX_OUTPUT 0.40
#define RANGE_PID_SETPOINT 150.0
#define RANGE_PID_TOLERENCE 4.0
//Uncomment this to enable the PID tuning section of code that can help tune PIDs
//by running code in debug mode and using breakpoints.
//#define PID_TUNING
//Comment this out to allow range adjusting in autonomous
#define DISABLE_RANGE_ADJUST_IN_AUTONOMOUS
#define ENABLE_FOUR_SHOT_SUPER_AUTONOMOUS
#define DISABLE_RANGE_FINDER
#define LINING_UP_IN_AUTONOMOUS false
//#define TEST_ELEVATOR_TIMING
//Helper Macros
#define STINGER_EXTENDED(isExtended) {FlipSolenoids(isExtended, &solenoidStingerExtend, &solenoidStingerRetract);}
#define BRIDGE_RAM_EXTENDED(isExtended) {FlipSolenoids(isExtended, &solenoidBridgeRamDown, &solenoidBridgeRamUp);}
#define CATAPULT_PUSHER_EXTENDED(isExtended) {FlipSolenoids(isExtended, &solenoidCatapultPusher, &solenoidCatapultPuller);}
#define CATAPULT_LATCH_EXTENDED(isExtended) {FlipSolenoids(isExtended, &solenoidCatapultLatchExtend, &solenoidCatapultLatchRetract);}
#define DISABLE_PID(pid) {if (pid.IsEnabled()){pid.Disable();pid.Reset();}}
typedef enum
{
PWM_CHANNEL_1_JAGUAR_REAR_RIGHT = 1,
PWM_CHANNEL_2_JAGUAR_REAR_LEFT,
PWM_CHANNEL_3_JAGUAR_FRONT_RIGHT,
PWM_CHANNEL_4_JAGUAR_FRONT_LEFT,
PWM_CHANNEL_5_JAGUAR_ELEVATOR_BOTTOM_1,
PWM_CHANNEL_6_JAGUAR_ELEVATOR_BOTTOM_2,
PWM_CHANNEL_7_JAGUAR_ELEVATOR_TOP,
PWM_CHANNEL_8_JAGUAR_DUMPER_ROLLER,
PWM_CHANNEL_9_UNUSED
}PWM_CHANNEL_TYPE;
#define BOTTOM_ROLLERS_SYNC_GROUP 1
typedef enum
{
SOLENOID_CHANNEL_1_CATAPULT_PUSHER = 1,
SOLENOID_CHANNEL_2_CATAPULT_PULLER,
SOLENOID_CHANNEL_3_BRIDGE_RAM_DOWN,
SOLENOID_CHANNEL_4_BRIDGE_RAM_UP,
SOLENOID_CHANNEL_5_STINGER_RETRACT,
SOLENOID_CHANNEL_6_STINGER_EXTEND,
SOLENOID_CHANNEL_7_CATAPULT_LATCH_EXTEND,
SOLENOID_CHANNEL_8_CATAPULT_LATCH_RETRACT
}SOLENOID_CHANNEL_TYPE;
typedef enum
{
ANALOG_CHANNEL_1_GYROSCOPE = 1,
ANALOG_CHANNEL_2_RANGE_FINDER,
ANALOG_CHANNEL_3_UNUSED,
ANALOG_CHANNEL_4_UNUSED,
ANALOG_CHANNEL_5_UNUSED,
ANALOG_CHANNEL_6_UNUSED,
ANALOG_CHANNEL_7_UNUSED,
ANALOG_CHANNEL_8_UNUSED,
ANALOG_CHANNEL_9_UNUSED
}ANALOG_CHANNEL_TYPE;
typedef enum
{
DIGITAL_CHANNEL_1_INPUT_COMPRESSOR_SWITCH = 1,
DIGITAL_CHANNEL_2_DUMPER_COUNTER,
DIGITAL_CHANNEL_3_UNUSED,
DIGITAL_CHANNEL_4_UNUSED,
DIGITAL_CHANNEL_5_UNUSED,
DIGITAL_CHANNEL_6_UNUSED,
DIGITAL_CHANNEL_7_UNUSED,
DIGITAL_CHANNEL_8_UNUSED
}DIGITAL_IO_CHANNEL_TYPE;
typedef enum
{
RELAY_CHANNEL_1_COMPRESSOR_RELAY = 1,
RELAY_CHANNEL_2_UNUSED,
RELAY_CHANNEL_3_UNUSED,
RELAY_CHANNEL_4_UNUSED,
RELAY_CHANNEL_5_UNUSED,
RELAY_CHANNEL_6_UNUSED,
RELAY_CHANNEL_7_UNUSED,
RELAY_CHANNEL_8_UNUSED,
}RELAY_CHANNEL_TYPE;
class Robot2012 : public IterativeRobot
{
Jaguar jaguarFrontLeft;
Jaguar jaguarFrontRight;
Jaguar jaguarRearLeft;
Jaguar jaguarRearRight;
RobotDrive myRobot; // robot drive system
Jaguar jaguarElevatorBottom1;
Jaguar jaguarElevatorBottom2;
Jaguar jaguarElevatorTop;
Victor victorDumperRoller;
Counter counterDumperRoller;
Solenoid solenoidCatapultPusher;
Solenoid solenoidCatapultPuller;
Solenoid solenoidBridgeRamDown;
Solenoid solenoidBridgeRamUp;
Solenoid solenoidStingerExtend;
Solenoid solenoidStingerRetract;
Solenoid solenoidCatapultLatchExtend;
Solenoid solenoidCatapultLatchRetract;
Joystick stickRightDrive; // only joystick
Joystick stickLeftDrive;
Joystick stickShooter;
KinectStick kinectLeft;
KinectStick kinectRight;
Gyro gyroscope;
GyroControlledTurning rotationControl;
PIDController rotationPID;
AnalogRangeFinder rangeFinder;
SonarControlledDriving sonarDriveControl;
PIDController rangePID;
Compressor compressor;
Timer timeInState;
Timer timeSinceBoot;
Timer autonomousStateTimer;
DriverStation *driverStation;
DriverStationLCD *driverStationLCD;
// Local variables to count the number of periodic loops performed
UINT32 m_autoPeriodicLoops;
UINT32 m_disabledPeriodicLoops;
UINT32 m_telePeriodicLoops;
bool cameraInitialized;
float angleToTurn;
float angleAtImage;
float distanceToTarget;
bool targetLocked;
typedef enum
{
AUTONOMOUS_LINING_UP_SHOT,
AUTONOMOUS_FIRING_SHOT,
AUTONOMOUS_SHOT_FIRED,
AUTONOMOUS_REARMING_SHOT,
AUTONOMOUS_RELOADING,
AUTONOMOUS_HITTING_BRIDGE,
AUTONOMOUS_DONE,
}AUTONOMOUS_STATE;
AUTONOMOUS_STATE autonomousState;
typedef enum
{
AUTONOMOUS_MODE_TWO_BALL_AND_TIP,
AUTONOMOUS_MODE_TWO_BALL,
AUTONOMOUS_MODE_FOUR_BALL,
AUTONOMOUS_MODE_SIX_BALL,
AUTONOMOUS_MODE_FEED,
AUTONOMOUS_MODE_FENDER_SHOTS,
AUTONOMOUS_MODE_THREE_BALL
}AUTONOMOUS_MODE_SELECT;
AUTONOMOUS_MODE_SELECT autonomousMode;
typedef enum
{
CATAPULT_COCKING,
CATAPULT_WAITING_LATCH,
CATAPULT_READY,
CATAPULT_FIRING
}CATAPULT_STATE;
CATAPULT_STATE catapultState;
public:
Robot2012(void):
jaguarFrontLeft(DIGITAL_OUTPUT_CHANNEL, PWM_CHANNEL_4_JAGUAR_FRONT_LEFT),
jaguarFrontRight(DIGITAL_OUTPUT_CHANNEL, PWM_CHANNEL_3_JAGUAR_FRONT_RIGHT),
jaguarRearLeft(DIGITAL_OUTPUT_CHANNEL, PWM_CHANNEL_2_JAGUAR_REAR_LEFT),
jaguarRearRight(DIGITAL_OUTPUT_CHANNEL, PWM_CHANNEL_1_JAGUAR_REAR_RIGHT),
myRobot(&jaguarFrontLeft, &jaguarRearLeft, &jaguarFrontRight, &jaguarRearRight),
jaguarElevatorBottom1(DIGITAL_OUTPUT_CHANNEL, PWM_CHANNEL_5_JAGUAR_ELEVATOR_BOTTOM_1),
jaguarElevatorBottom2(DIGITAL_OUTPUT_CHANNEL, PWM_CHANNEL_6_JAGUAR_ELEVATOR_BOTTOM_2),
jaguarElevatorTop(DIGITAL_OUTPUT_CHANNEL, PWM_CHANNEL_7_JAGUAR_ELEVATOR_TOP),
victorDumperRoller(DIGITAL_OUTPUT_CHANNEL, PWM_CHANNEL_8_JAGUAR_DUMPER_ROLLER),
counterDumperRoller(DIGITAL_OUTPUT_CHANNEL, DIGITAL_CHANNEL_2_DUMPER_COUNTER),
solenoidCatapultPusher(SOLENOID_OUTPUT_CHANNEL, SOLENOID_CHANNEL_1_CATAPULT_PUSHER),
solenoidCatapultPuller(SOLENOID_OUTPUT_CHANNEL, SOLENOID_CHANNEL_2_CATAPULT_PULLER),
solenoidBridgeRamDown(SOLENOID_OUTPUT_CHANNEL, SOLENOID_CHANNEL_3_BRIDGE_RAM_DOWN),
solenoidBridgeRamUp(SOLENOID_OUTPUT_CHANNEL, SOLENOID_CHANNEL_4_BRIDGE_RAM_UP),
solenoidStingerExtend(SOLENOID_OUTPUT_CHANNEL, SOLENOID_CHANNEL_6_STINGER_EXTEND),
solenoidStingerRetract(SOLENOID_OUTPUT_CHANNEL, SOLENOID_CHANNEL_5_STINGER_RETRACT),
solenoidCatapultLatchExtend(SOLENOID_OUTPUT_CHANNEL, SOLENOID_CHANNEL_7_CATAPULT_LATCH_EXTEND),
solenoidCatapultLatchRetract(SOLENOID_OUTPUT_CHANNEL, SOLENOID_CHANNEL_8_CATAPULT_LATCH_RETRACT),
stickRightDrive(1),
stickLeftDrive(2),
stickShooter(3),
kinectLeft(1),
kinectRight(2),
gyroscope(ANALOG_OUTPUT_CHANNEL, ANALOG_CHANNEL_1_GYROSCOPE),
rotationControl(&myRobot),
rotationPID(ROTATION_PID_PROPORTION, ROTATION_PID_INTEGRAL, ROTATION_PID_DERIVATIVE, &gyroscope, &rotationControl),
rangeFinder(ANALOG_OUTPUT_CHANNEL, ANALOG_CHANNEL_2_RANGE_FINDER),
sonarDriveControl(&myRobot),
rangePID(RANGE_PID_PROPORTION,RANGE_PID_INTEGRAL,RANGE_PID_DERIVATIVE, &rangeFinder, &sonarDriveControl),
compressor(DIGITAL_CHANNEL_1_INPUT_COMPRESSOR_SWITCH, RELAY_CHANNEL_1_COMPRESSOR_RELAY),
timeInState(),
timeSinceBoot()
{
printf("Robot2012 Constructor Started\n");
cameraInitialized = false;
// Acquire the Driver Station object
driverStation = DriverStation::GetInstance();
driverStationLCD = DriverStationLCD::GetInstance();
myRobot.SetInvertedMotor(myRobot.kRearLeftMotor, true);
myRobot.SetInvertedMotor(myRobot.kRearRightMotor, true);
myRobot.SetInvertedMotor(myRobot.kFrontLeftMotor, true);
myRobot.SetInvertedMotor(myRobot.kFrontRightMotor, true);
// Initialize counters to record the number of loops completed in autonomous and teleop modes
m_autoPeriodicLoops = 0;
m_disabledPeriodicLoops = 0;
m_telePeriodicLoops = 0;
rotationPID.SetInputRange(ROTATION_PID_MIN_INPUT,ROTATION_PID_MAX_INPUT);
rotationPID.SetOutputRange(ROTATION_PID_MIN_OUTPUT,ROTATION_PID_MAX_OUTPUT);
rotationPID.SetTolerance(ROTATION_PID_TOLERENCE_FIRST);
rotationPID.Disable();
rangePID.SetInputRange(RANGE_PID_MIN_INPUT,RANGE_PID_MAX_INPUT);
rangePID.SetOutputRange(RANGE_PID_MIN_OUTPUT, RANGE_PID_MAX_OUTPUT);
rangePID.SetSetpoint(RANGE_PID_SETPOINT);
rangePID.SetTolerance(RANGE_PID_TOLERENCE);
rangePID.Disable();
printf("Robot2012 Constructor Completed\n");
}
/********************************** Init Routines *************************************/
void RobotInit(void)
{
// Actions which would be performed once (and only once) upon initialization of the
// robot would be put here.
catapultState = CATAPULT_READY;
autonomousMode = AUTONOMOUS_MODE_TWO_BALL_AND_TIP;
timeSinceBoot.Start();
myRobot.SetExpiration(1.0);
printf("RobotInit() completed.\n");
}
void DisabledInit(void)
{
m_autoPeriodicLoops = 0;
m_telePeriodicLoops = 0;
m_disabledPeriodicLoops = 0;
timeInState.Reset();
timeInState.Start();
compressor.Stop();
myRobot.SetSafetyEnabled(false);
ManageCatapult(false,false);
autonomousMode = AUTONOMOUS_MODE_TWO_BALL_AND_TIP;
}
void AutonomousInit(void)
{
m_autoPeriodicLoops = 0;
m_telePeriodicLoops = 0;
m_disabledPeriodicLoops = 0;
timeInState.Reset();
timeInState.Start();
compressor.Start();
autonomousState = AUTONOMOUS_LINING_UP_SHOT;
autonomousStateTimer.Reset();
autonomousStateTimer.Start();
myRobot.SetSafetyEnabled(true);
}
void TeleopInit(void)
{
m_autoPeriodicLoops = 0;
m_telePeriodicLoops = 0;
m_disabledPeriodicLoops = 0;
timeInState.Reset();
timeInState.Start();
compressor.Start();
myRobot.SetSafetyEnabled(true);
}
/********************************** Periodic Routines *************************************/
void DisabledPeriodic(void)
{
m_disabledPeriodicLoops++;
CameraInitialize();
AxisCamera &camera = AxisCamera::GetInstance("10.24.74.11");
if (camera.IsFreshImage() == true)
{
ColorImage *colorImage = new ColorImage(IMAQ_IMAGE_HSL);
if (colorImage == (void *)0)
return;
camera.GetImage(colorImage);
//TODO Print to the LCD as well
if (DetermineTargetPosition(colorImage) == 0)
{
if ((angleToTurn > (ANGLE_POSITION_BASE - DISTANCE_POSITION_TOLERANCE)) &&
(angleToTurn < (ANGLE_POSITION_BASE + DISTANCE_POSITION_TOLERANCE)) &&
(distanceToTarget > (DISTANCE_POSITION_BASE - DISTANCE_POSITION_TOLERANCE)) &&
(distanceToTarget < (DISTANCE_POSITION_BASE + DISTANCE_POSITION_TOLERANCE)))
{
SetRIOUserLED(1);
//driverStationLCD->PrintfLine((DriverStationLCD::Line) 0, "Camera is ON target");
}
else
{
SetRIOUserLED(0);
//driverStationLCD->PrintfLine((DriverStationLCD::Line) 0, "Camera is OFF target");
}
}
else
{
SetRIOUserLED(0);
//driverStationLCD->PrintfLine((DriverStationLCD::Line) 0, "Camera is OFF target");
}
delete colorImage;
}
static Timer button_combo_timer;
if (BUTTON_COMBO_SWITCH_AUTONOMOUS() == true)
{
button_combo_timer.Start();
}
else
{
button_combo_timer.Reset();
button_combo_timer.Stop();
}
if (button_combo_timer.Get() > 2.00)
{
button_combo_timer.Reset();
switch (autonomousMode)
{
case AUTONOMOUS_MODE_TWO_BALL_AND_TIP:
autonomousMode = AUTONOMOUS_MODE_TWO_BALL;
break;
case AUTONOMOUS_MODE_TWO_BALL:
autonomousMode = AUTONOMOUS_MODE_THREE_BALL;
break;
case AUTONOMOUS_MODE_THREE_BALL:
autonomousMode = AUTONOMOUS_MODE_FOUR_BALL;
break;
case AUTONOMOUS_MODE_FOUR_BALL:
// autonomousMode = AUTONOMOUS_MODE_SIX_BALL;
// break;
// case AUTONOMOUS_MODE_SIX_BALL:
autonomousMode = AUTONOMOUS_MODE_FEED;
break;
case AUTONOMOUS_MODE_FEED:
autonomousMode = AUTONOMOUS_MODE_FENDER_SHOTS;
break;
default:
case AUTONOMOUS_MODE_FENDER_SHOTS:
autonomousMode = AUTONOMOUS_MODE_TWO_BALL_AND_TIP;
break;
}
}
//TODO look for joystick buttons instead of this switch
switch (autonomousMode)
{
default:
case AUTONOMOUS_MODE_TWO_BALL_AND_TIP:
driverStationLCD->PrintfLine((DriverStationLCD::Line) 1, "Using 2 ball and tip bridge auton");
break;
case AUTONOMOUS_MODE_FOUR_BALL:
driverStationLCD->PrintfLine((DriverStationLCD::Line) 1, "Using 4 ball autonomous");
break;
case AUTONOMOUS_MODE_SIX_BALL:
driverStationLCD->PrintfLine((DriverStationLCD::Line) 1, "Using 6 ball autonomous");
break;
case AUTONOMOUS_MODE_TWO_BALL:
driverStationLCD->PrintfLine((DriverStationLCD::Line) 1, "Using 2 ball NO BRIDGE TIP");
break;
case AUTONOMOUS_MODE_THREE_BALL:
driverStationLCD->PrintfLine((DriverStationLCD::Line) 1, "Using 3 ball NO BRIDGE TIP");
break;
case AUTONOMOUS_MODE_FEED:
driverStationLCD->PrintfLine((DriverStationLCD::Line) 1, "Autonomous Feeding balls");
break;
case AUTONOMOUS_MODE_FENDER_SHOTS:
driverStationLCD->PrintfLine((DriverStationLCD::Line) 1, "Shooting from the fender");
break;
}
driverStationLCD->UpdateLCD();
}
bool CatapultAutonomous(bool hit_bridge, int number_of_shots)
{
bool running_auton = false;
static int shots_fired;
if (m_autoPeriodicLoops < 2)
{
shots_fired = 0;
}
bool use_slow_roller = ((number_of_shots > 2) && (shots_fired < number_of_shots));
if (shots_fired < number_of_shots)
{
running_auton = true;
ManageAppendages(false,false);
PositionForTarget(LINING_UP_IN_AUTONOMOUS);
switch (autonomousState)
{
default:
case AUTONOMOUS_FIRING_SHOT:
ManageCatapult(true, true);
shots_fired++;
case AUTONOMOUS_SHOT_FIRED:
autonomousState = AUTONOMOUS_SHOT_FIRED;
ManageCatapult(false, false);
ManageElevator(false,false,false,false,false,use_slow_roller);
if (catapultState == CATAPULT_COCKING)
{
autonomousState = AUTONOMOUS_REARMING_SHOT;
}
break;
//Cumulative time: 0.01
case AUTONOMOUS_REARMING_SHOT:
ManageAppendages(false,false);
//For the first shot, don't pickup from the floor because it could jam the loading of ball 2
if (shots_fired < 2)
{
ManageElevator(false,false,false,false,false,false);
}
else
{
ManageElevator(true,false,false,false,false,false);
}
PositionForTarget(LINING_UP_IN_AUTONOMOUS);
ManageCatapult(false, false);
if (catapultState != CATAPULT_COCKING)
{
autonomousStateTimer.Reset();
autonomousState = AUTONOMOUS_RELOADING;
}
break;
//Cumulative time: 1.0
//Load a ball after 1.0 seconds and before 4.4 seconds (2.9 ideal)
case AUTONOMOUS_RELOADING:
ManageAppendages(false,false);
if (autonomousStateTimer.Get() > SLOW_PICKUP_DURING_RELOAD_START)
{
ManageElevator(false,false,false,true,false,use_slow_roller);
}
else
{
ManageElevator(false,false,false,true,false,false);
}
PositionForTarget(LINING_UP_IN_AUTONOMOUS);
ManageCatapult(false, false);
if (autonomousStateTimer.Get() > CATAPULT_RELOAD_TIME_FOUR_BALL)
{
ManageCatapult(false, false);
autonomousStateTimer.Reset();
autonomousState = AUTONOMOUS_FIRING_SHOT;
}
break;
}
}
else if (hit_bridge == true)
{
ManageAppendages(true,false);
PositionForTarget(false);
ManageCatapult(false, false);
autonomousState = AUTONOMOUS_HITTING_BRIDGE;
ManageElevator(true,false,false,false,false,false);
if (autonomousStateTimer.Get() < AUTONOMOUS_BACKUP_TIME_WAIT)
{
myRobot.TankDrive(0.0,0.0);
running_auton = true;
}
else if (autonomousStateTimer.Get() < AUTONOMOUS_BACKUP_TIME_FAST)
{
myRobot.TankDrive(AUTONOMOUS_BACKUP_SPEED_FAST,AUTONOMOUS_BACKUP_SPEED_FAST);
running_auton = true;
}
else if (autonomousStateTimer.Get() < AUTONOMOUS_BACKUP_TIME_SLOW)
{
myRobot.TankDrive(AUTONOMOUS_BACKUP_SPEED_SLOW,AUTONOMOUS_BACKUP_SPEED_SLOW);
running_auton = true;
}
else
{
myRobot.TankDrive(0.0,0.0);
}
}
return running_auton;
}
void AutonomousPeriodic(void)
{
m_autoPeriodicLoops++;
CameraInitialize();
if (autonomousMode == AUTONOMOUS_MODE_TWO_BALL_AND_TIP)
{
if (CatapultAutonomous(true,2))
return;
}
else if(autonomousMode == AUTONOMOUS_MODE_TWO_BALL)
{
if (CatapultAutonomous(false,2))
return;
}
else if (autonomousMode == AUTONOMOUS_MODE_THREE_BALL)
{
if (CatapultAutonomous(false, 3))
return;
}
else if (autonomousMode == AUTONOMOUS_MODE_FOUR_BALL)
{
if (CatapultAutonomous(false,4))
return;
}
else if (autonomousMode == AUTONOMOUS_MODE_SIX_BALL)
{
if (CatapultAutonomous(false, 6))
return;
}
else if (autonomousMode == AUTONOMOUS_MODE_FEED)
{
autonomousStateTimer.Start();
if (autonomousStateTimer.Get() > 7.0)
{
ManageElevator(false,true,false,true,false,false);
return;
}
else if (autonomousStateTimer.Get() > 5.0)
{
ManageElevator(false,true,false,false,false,false);
return;
}
else
{
ManageElevator(false,false,false,false,false,false);
}
}
else if (autonomousMode == AUTONOMOUS_MODE_FENDER_SHOTS)
{
autonomousStateTimer.Start();
if (autonomousStateTimer.Get() < 3.5)
{
myRobot.TankDrive(AUTONOMOUS_FENDER_SHOT_FAST,AUTONOMOUS_FENDER_SHOT_FAST);
ManageElevator(false,false,false,false,true,false);
}
else if (autonomousStateTimer.Get() < 4.0)
{
myRobot.TankDrive(AUTONOMOUS_FENDER_SHOT_SLOW,AUTONOMOUS_FENDER_SHOT_SLOW);
ManageElevator(false,false,true,false,true,false);
}
else if (autonomousStateTimer.Get() < 8.0)
{
myRobot.TankDrive(0.0,0.0);
ManageElevator(false,true,true,false,true,false);
}
else if (autonomousStateTimer.Get() < 12.0)
{
myRobot.TankDrive(-AUTONOMOUS_FENDER_SHOT_FAST,-AUTONOMOUS_FENDER_SHOT_FAST);
ManageElevator(false,true,true,false,true,false);
}
}
//If we didn't return above, allow the kinect to function
if (KINECT_CONTROL_ENABLED() == true)
{
myRobot.TankDrive(kinectLeft.GetY() * 0.7, kinectRight.GetY() * 0.7);
//add code to bind each kinectStick button to each action we want to be able to do in autonomous
//ManageAppendages(KINECT_RIGHT_LEG_BACK(),false);
BRIDGE_RAM_EXTENDED(KINECT_BRIDGE_RAM_EXTEND());
ManageElevator((KINECT_ELEVATORS_UP() || KINECT_BRIDGE_RAM_EXTEND()),KINECT_ELEVATORS_DOWN(),
KINECT_ELEVATORS_UP(),KINECT_ELEVATORS_DOWN(),
KINECT_ELEVATORS_UP(),false);
PositionForTarget(false);
ManageCatapult(false, false);
}
}
void TeleopPeriodic(void)
{
// increment the number of teleop periodic loops completed
m_telePeriodicLoops++;
if (!BUTTON_CAMERA_ALIGN_SHOT_BUTTON())
{
DISABLE_PID(rotationPID);
DISABLE_PID(rangePID);
myRobot.TankDrive(stickLeftDrive,stickRightDrive);
myRobot.SetSafetyEnabled(true);
}
CameraInitialize();
ManageAppendages(BUTTON_BRIDGE_RAM_TOGGLE(),BUTTON_STINGER_TOGGLE());
ManageElevator(BUTTON_ELEVATOR_BOTTOM_UP(), BUTTON_ELEVATOR_BOTTOM_DOWN(),
BUTTON_ELEVATOR_TOP_UP(), BUTTON_ELEVATOR_TOP_DOWN(),
BUTTON_DUMPER_ROLLER(), false);
ManageCatapult(BUTTON_CATAPULT_SHOOT(), BUTTON_CATAPULT_FORCE_SHOOT());
PositionForTarget(BUTTON_CAMERA_ALIGN_SHOT_BUTTON());
}
/********************************** Continuous Routines *************************************/
// void DisabledContinuous(void)
// {
// //CameraInitialize();
// }
//
// void AutonomousContinuous(void)
// {
// //AxisCamera &camera = AxisCamera::GetInstance("10.24.74.11");
// //CameraInitialize();
// }
// void TeleopContinuous(void)
// {
// }
//returns 0 if a particle is found
int DetermineTargetPosition(ColorImage *colorImage)
{
int returnVal = -1;
BinaryImage *binaryImage;
Image *imaqImage;
if ((colorImage == (void *) 0) || (colorImage->GetWidth() == 0) || (colorImage->GetHeight() == 0))
{
return returnVal;
}
if (BUTTON_CAMERA_TAKE_DEBUG_PICTURES())
{
colorImage->Write("capturedImage.jpg");
}
//binaryImage = colorImage->ThresholdHSV(0, 255, 0, 255, 255, 0);
//binaryImage = colorImage->ThresholdHSV(56, 125, 55, 255, 255, 150);
binaryImage = colorImage->ThresholdHSL(90, 115,30, 255, 70, 255);
if ((binaryImage == (void *) 0) || (binaryImage->GetWidth() == 0) || (binaryImage->GetHeight() == 0))
return returnVal;
imaqImage = binaryImage->GetImaqImage();
if (imaqImage == (void *) 0)
return returnVal;
if (BUTTON_CAMERA_TAKE_DEBUG_PICTURES())
{
binaryImage->Write("afterCLRThreshold.bmp");
IVA_ProcessImage(imaqImage, binaryImage);
}
else
{
IVA_ProcessImage(imaqImage, (ImageBase *)0);
}
vector<ParticleAnalysisReport> *reports = binaryImage->GetOrderedParticleAnalysisReports();
ParticleAnalysisReport *topParticlePtr = NULL;
for (int particleIndex = 0; particleIndex < reports->size(); particleIndex++)
{
ParticleAnalysisReport &thisReport = reports->at(particleIndex);
//TODO Validate the particle so we don't end up targeting a spec on the wall? (particle filter gets rid fo really small stuff, but we may want this if the arena is noisy)
if ((!topParticlePtr) || (thisReport.center_mass_y < topParticlePtr->center_mass_y) /*&& thisReport.particleQuality > WHATT!!!!*/)
{
topParticlePtr = &thisReport;
}
}
if (topParticlePtr != NULL)
{
returnVal = 0; //indicates success
int centerOfMassX = topParticlePtr->center_mass_x;
angleToTurn = (centerOfMassX - CENTER_OF_IMAGE) * HORIZONTAL_DEGREES_PER_PIXEL;
angleToTurn = ((-angleToTurn) + ROTATION_PID_SETPOINT_OFFSET);
distanceToTarget = 12 * CALCULATE_DISTANCE(topParticlePtr->boundingRect.height);
driverStationLCD->PrintfLine((DriverStationLCD::Line) 2, "Angle to turn: %.5f", -angleToTurn);
driverStationLCD->PrintfLine((DriverStationLCD::Line) 3, "Range to target: %.5f", distanceToTarget);
driverStationLCD->UpdateLCD();
#ifdef PID_TUNING
static float tol_angle = ROTATION_PID_TOLERENCE;
static float set_angle = ROTATION_PID_SETPOINT_OFFSET;
float p = rotationPID.GetP();
float i = rotationPID.GetI();
float d = rotationPID.GetD();
rotationPID.SetPID(p,i,d);
rotationPID.SetTolerance(tol_angle);
rotationPID.SetSetpoint(angleToTurn);
static float tol_range = RANGE_PID_TOLERENCE;
static float set_range = RANGE_PID_SETPOINT;
p = rangePID.GetP();
i = rangePID.GetI();
d = rangePID.GetD();
rangePID.SetPID(p,i,d);
rangePID.SetTolerance(tol_range);
rangePID.SetSetpoint(set_range);
#else
rotationPID.SetSetpoint(angleToTurn);
#endif
}
else
{
jaguarFrontLeft.Set(0.0);
jaguarFrontRight.Set(0.0);
jaguarRearLeft.Set(0.0);
jaguarRearRight.Set(0.0);
}
delete reports;
delete binaryImage;
return returnVal;
}
void ManageAppendages(bool extend_bridge_ram, bool extend_stinger)
{
typedef enum
{
APPENDAGE_IDLE,
APPENDAGE_BRIDGE_RAM_EXTENDED,
APPENDAGE_BRIDGE_RAM_RETRACTING,
APPENDAGE_STINGER_EXTENDED,
APPENDAGE_STINGER_RETRACTING
}APPENDAGE_STATE;
static int retracting_appendage_counter = 0;
static APPENDAGE_STATE appendage_state = APPENDAGE_IDLE;
static bool trigger_released = false;
switch(appendage_state)
{
default:
case APPENDAGE_IDLE:
BRIDGE_RAM_EXTENDED(false);
STINGER_EXTENDED(false);
if (!extend_bridge_ram && !extend_stinger)
{
trigger_released = true;
}
if(trigger_released && extend_bridge_ram)
{
trigger_released = false;
BRIDGE_RAM_EXTENDED(true);
appendage_state = APPENDAGE_BRIDGE_RAM_EXTENDED;
}
else if (trigger_released && extend_stinger)
{
trigger_released = false;
STINGER_EXTENDED(true);
appendage_state = APPENDAGE_STINGER_EXTENDED;
}
break;
case APPENDAGE_BRIDGE_RAM_EXTENDED:
BRIDGE_RAM_EXTENDED(true);
STINGER_EXTENDED(false);
if (!extend_bridge_ram)
{
trigger_released = true;
}
if (trigger_released && extend_bridge_ram)
{
trigger_released = false;
BRIDGE_RAM_EXTENDED(false);
STINGER_EXTENDED(false);
retracting_appendage_counter = 0;
appendage_state = APPENDAGE_STINGER_RETRACTING;
}
break;
case APPENDAGE_BRIDGE_RAM_RETRACTING:
BRIDGE_RAM_EXTENDED(false);
STINGER_EXTENDED(false);
if (!extend_bridge_ram)
{
trigger_released = true;
}
retracting_appendage_counter++;
if (retracting_appendage_counter > 10)
{
appendage_state = APPENDAGE_IDLE;
}
break;
case APPENDAGE_STINGER_EXTENDED:
BRIDGE_RAM_EXTENDED(false);
STINGER_EXTENDED(true);
if (!extend_stinger)
{
trigger_released = true;
}
if (trigger_released && extend_stinger)
{
trigger_released = false;
BRIDGE_RAM_EXTENDED(false);
STINGER_EXTENDED(false);
retracting_appendage_counter = 0;
appendage_state = APPENDAGE_STINGER_RETRACTING;
}
break;
case APPENDAGE_STINGER_RETRACTING:
BRIDGE_RAM_EXTENDED(false);
STINGER_EXTENDED(false);
if (!extend_stinger)
{
trigger_released = true;
}
retracting_appendage_counter++;
if (retracting_appendage_counter > 10)
{
appendage_state = APPENDAGE_IDLE;
}
break;
}
}
void ManageElevator(bool bottom_up, bool bottom_down, bool top_up, bool top_down, bool dumper_roller, bool bottom_elevator_slow_up)
{
static Timer elevatorTimer;
static float dumper_roller_power = 0.0;
#ifdef TEST_ELEVATOR_TIMING
if (!(bottom_up || top_down))
{
elevatorTimer.Reset();
}
#endif
if (bottom_up)
{
#ifdef TEST_ELEVATOR_TIMING
//.75 second minimum
elevatorTimer.Start();
driverStationLCD->PrintfLine((DriverStationLCD::Line) 3, "Bottom Timer: %f", elevatorTimer.Get());
#endif
jaguarElevatorBottom1.Set(-ELEVATOR_SPEED_BOTTOM, BOTTOM_ROLLERS_SYNC_GROUP);
jaguarElevatorBottom2.Set(-ELEVATOR_SPEED_BOTTOM, BOTTOM_ROLLERS_SYNC_GROUP);
}
else if (bottom_down)
{
jaguarElevatorBottom1.Set(ELEVATOR_SPEED_BOTTOM, BOTTOM_ROLLERS_SYNC_GROUP);
jaguarElevatorBottom2.Set(ELEVATOR_SPEED_BOTTOM, BOTTOM_ROLLERS_SYNC_GROUP);
}
else if (bottom_elevator_slow_up)
{
jaguarElevatorBottom1.Set(-ELEVATOR_SPEED_BOTTOM_SLOW, BOTTOM_ROLLERS_SYNC_GROUP);
jaguarElevatorBottom2.Set(-ELEVATOR_SPEED_BOTTOM_SLOW, BOTTOM_ROLLERS_SYNC_GROUP);
}
else
{
jaguarElevatorBottom1.Set(0.0);
jaguarElevatorBottom2.Set(0.0);
}
if (top_up)
{
jaguarElevatorTop.Set(ELEVATOR_SPEED_TOP);
}
else if (top_down)
{
#ifdef TEST_ELEVATOR_TIMING
elevatorTimer.Start();
driverStationLCD->PrintfLine((DriverStationLCD::Line) 3, "Tm:%f spd%f", elevatorTimer.Get(), ELEVATOR_SPEED_TOP);
#endif
jaguarElevatorTop.Set(-ELEVATOR_SPEED_TOP);
}
else
{
jaguarElevatorTop.Set(0.0);
}
float roller_rpm = GetRollerVelocity(dumper_roller);
driverStationLCD->PrintfLine((DriverStationLCD::Line) 3, "Roller RPM: %f", roller_rpm);
driverStationLCD->UpdateLCD();
if (dumper_roller)
{
#ifdef DUMPER_ROLLER_RPM
if (!BUTTON_CATAPULT_FORCE_SHOOT())
{
if (roller_rpm < DUMPER_ROLLER_RPM)
{
if (dumper_roller_power < (1 - DUMPER_ROLLER_VOLTAGE_RAMP_RATE))
{
dumper_roller_power += DUMPER_ROLLER_VOLTAGE_RAMP_RATE;
}
else
{
dumper_roller_power = 1.0F;
}
}
else
{
if (dumper_roller_power > DUMPER_ROLLER_VOLTAGE_RAMP_RATE)
{
dumper_roller_power -= DUMPER_ROLLER_VOLTAGE_RAMP_RATE;
}
else
{
dumper_roller_power = 0.0F;
}
}
}
else
#endif
{
dumper_roller_power = DUMPER_ROLLER_POWER;
}
if (compressor.Enabled() == true)
{
compressor.Stop();
}
}
else
{
dumper_roller_power = 0.0;
if (compressor.Enabled() == false)
{
compressor.Start();
}
}
victorDumperRoller.Set(dumper_roller_power);
}
void ManageCatapult(bool catapult_shoot, bool force_shoot)
{
static bool button_released = true;
static Timer state_timer;
state_timer.Start();//Doesn't do anything unless it's not running
if (!catapult_shoot)button_released = true;
switch (catapultState)
{
case CATAPULT_COCKING:
CATAPULT_PUSHER_EXTENDED(true);
CATAPULT_LATCH_EXTENDED(false);
if (state_timer.Get() >= CATAPULT_REARM_TIME)
{
state_timer.Reset();
catapultState = CATAPULT_WAITING_LATCH;
}
break;
case CATAPULT_WAITING_LATCH:
CATAPULT_PUSHER_EXTENDED(false);
CATAPULT_LATCH_EXTENDED(true);
if (state_timer.Get() > CATAPULT_LATCH_TIME)
{
state_timer.Reset();
catapultState = CATAPULT_READY;
}
break;
case CATAPULT_READY:
if (catapult_shoot && button_released)
{
if ((force_shoot == true) || (targetLocked == true))
{
CATAPULT_LATCH_EXTENDED(false);
state_timer.Reset();
catapultState = CATAPULT_FIRING;
}
}
break;
case CATAPULT_FIRING:
CATAPULT_PUSHER_EXTENDED(false);
CATAPULT_LATCH_EXTENDED(false);
if (state_timer.Get() >= CATAPULT_FIRE_TIME)
{
state_timer.Reset();
//CATAPULT_PUSHER_EXTENDED(true);
catapultState = CATAPULT_COCKING;
}
break;
}
}
void PositionForTarget(bool camera_align_shot)
{
typedef enum
{
TARGETING_IDLE,
TARGETING_ROTATING,
TARGETING_DRIVING_TO_DISTANCE,
TARGETING_ROTATING_FINAL
}TARGETING_STATE;
static TARGETING_STATE state_targeting = TARGETING_IDLE;
driverStationLCD->PrintfLine((DriverStationLCD::Line) 4, "Angle Turned: %f", gyroscope.GetAngle());
//driverStationLCD->PrintfLine((DriverStationLCD::Line) 4, "Range to target: %f", rangeFinder.GetRangeInches());
driverStationLCD->PrintfLine((DriverStationLCD::Line) 5, "Autoposition State: %d", state_targeting);
driverStationLCD->UpdateLCD();
static int on_target_count = 0;
Timer imageRefreshTimer;
AxisCamera &camera = AxisCamera::GetInstance("10.24.74.11");
switch (state_targeting)
{
case TARGETING_IDLE:
targetLocked = false;
DISABLE_PID(rotationPID);
DISABLE_PID(rangePID);
if (camera.IsFreshImage())
{
if (camera_align_shot == true)
{
ColorImage *colorImage = new ColorImage(IMAQ_IMAGE_HSL);
camera.GetImage(colorImage);
imageRefreshTimer.Reset();
imageRefreshTimer.Start();
gyroscope.Reset();
if (DetermineTargetPosition(colorImage) == 0)
{
rotationPID.SetTolerance(ROTATION_PID_TOLERENCE_FIRST);
rotationPID.Enable();
state_targeting = TARGETING_ROTATING;
on_target_count = 0;
}
delete colorImage;
}
}
break;
case TARGETING_ROTATING:
if (camera_align_shot == false)
{
DISABLE_PID(rotationPID);
state_targeting = TARGETING_IDLE;
on_target_count = 0;
}
else if (rotationPID.OnTarget() && (on_target_count > 3))
{
on_target_count = 0;
#ifdef DISABLE_RANGE_FINDER
state_targeting = TARGETING_ROTATING_FINAL;
#else
#ifdef DISABLE_RANGE_ADJUST_IN_AUTONOMOUS
if (m_autoPeriodicLoops != 0)
{
state_targeting = TARGETING_ROTATING_FINAL;
}
else
#endif
{
DISABLE_PID(rotationPID);
rangePID.Enable();
state_targeting = TARGETING_DRIVING_TO_DISTANCE;
}
#endif
}
else if (rotationPID.OnTarget())
{
rotationPID.Enable();
on_target_count++;
}
else
{
rotationPID.Enable();
on_target_count = 0;
}
break;
//TODO need to put in a small delay for autonomous
case TARGETING_DRIVING_TO_DISTANCE:
if (camera_align_shot == false)
{
DISABLE_PID(rangePID);
state_targeting = TARGETING_IDLE;
on_target_count = 0;
}
else if (rangePID.OnTarget() && (on_target_count > 8))
{
DISABLE_PID(rangePID);
state_targeting = TARGETING_ROTATING_FINAL;
rotationPID.SetTolerance(ROTATION_PID_TOLERENCE_LAST);
on_target_count = 0;
}
else if (rangePID.OnTarget())
{
rangePID.Enable();
on_target_count++;
}
else
{
rangePID.Enable();
on_target_count = 0;
}
break;
case TARGETING_ROTATING_FINAL:
if (camera.IsFreshImage() && camera_align_shot && (imageRefreshTimer.HasPeriodPassed(1.0)))
{
ColorImage *colorImage = new ColorImage(IMAQ_IMAGE_HSL);
camera.GetImage(colorImage);
imageRefreshTimer.Reset();
imageRefreshTimer.Start();
if (DetermineTargetPosition(colorImage) == 0)
{
gyroscope.Reset();
}
delete colorImage;
}
DISABLE_PID(rangePID);
if (camera_align_shot == false)
{
DISABLE_PID(rotationPID);
state_targeting = TARGETING_IDLE;
targetLocked = false;
on_target_count = 0;
}
else if (rotationPID.OnTarget() && (on_target_count > 6))
{
targetLocked = true;
rotationPID.Enable();
}
else if (rotationPID.OnTarget())
{
rotationPID.Enable();
on_target_count++;
}
else
{
rotationPID.Enable();
targetLocked = false;
on_target_count = 0;
}
break;
}
}
void CameraInitialize(void)
{
if (cameraInitialized == false)
{
AxisCamera &camera = AxisCamera::GetInstance("10.24.74.11");
if (&camera != (void *)0)
{
camera.WriteBrightness(CAMERA_BRIGHTNESS_LEVEL);
camera.WriteColorLevel(CAMERA_COLOR_LEVEL);
camera.WriteMaxFPS(CAMERA_MAX_FPS);
//camera.WriteResolution(camera.kResolution_320x240);
//camera.WriteWhiteBalance(camera.kWhiteBalance_FixedFlourescent1);
}
}
}
void FlipSolenoids(bool isFirstEna, Solenoid *sol1, Solenoid *sol2)
{
if ((sol1 == NULL) || (sol2 == NULL))
return;
if (isFirstEna)
{
sol2->Set(false);
sol1->Set(true);
}
else
{
sol1->Set(false);
sol2->Set(true);
}
}
float GetRollerVelocity(bool roller_on)
{
static UINT32 prev_time = 0;
static float filtered_rpm = 0;
float return_rpm = 0;
if (prev_time == 0)
{
prev_time = GetFPGATime();
counterDumperRoller.Start();
return return_rpm;
}
if ((filtered_rpm > 100) || (roller_on == true))
{
UINT32 time_difference = GetFPGATime() - prev_time;
INT32 count = counterDumperRoller.Get();
driverStationLCD->PrintfLine((DriverStationLCD::Line) 1, "Roller count: %d", count);
//Filter the incoming speed against previous speed to get a
float current_rpm = ((float)count) / ((float)(((float)DUMPER_ROLLER_COUNTS_PER_REVOLUTION/(float)FPGA_TIME_TO_MINUTES_FACTOR) * time_difference));
filtered_rpm = (current_rpm * (1 - DUMPER_ROLLER_FILTER_CONSTANT)) + (filtered_rpm * DUMPER_ROLLER_FILTER_CONSTANT);
return_rpm = filtered_rpm;
}
counterDumperRoller.Reset();
prev_time = GetFPGATime();
return return_rpm;
}
};
START_ROBOT_CLASS(Robot2012);