USFirst.org
follow us on twitter
like us on facebookMNFTC.org
Bookmark and Share

Thanks

The team members of FRC Team 2220 would like to give a big thanks to all of the Sponsors, Mentors and Parents that make having this team possible.

Thank you!

Team Login



Camera.cpp Create PDF Send to Printer Email this Article
Written by TarinB   
Saturday, February 13 2010 16:13

 

/* BTCamera

* camera-servo hybrid class

* manages camera and servos, including tracking functions

*/

 

#include "BTCamera.h"

#include "WPILib.h"

 

#include "TrackAPI.h"

#include "VisionAPI.h"

#include "AxisCamera.h"

#include "BTRobot.h"

 

BTCamera::BTCamera(void)

{

count = 0;

distance = 0;

// ================================

// ***camera initialization code***

// ================================

int framesPerSecond;

framesPerSecond = 15;

if(StartCameraTask(framesPerSecond, 0, k320x240, ROT_0) == -1)

{

dprintf(LOG_ERROR, "Failed to spawn camera task; exiting. Error code %s",

GetVisionErrorText(GetLastVisionError()) );

}

else

{

dprintf(LOG_INFO, "Camera task started successfully, resolution 160x120");

}

td1 = GetTrackingData(MARIUCCI_GREEN, MARIUCCI_GREEN_LIGHT);

td2 = GetTrackingData(MARIUCCI_PINK, MARIUCCI_PINK_LIGHT);

 

// search variables

foundColor = false;

savedImageTimestamp = 0.0;

staleImage = false;

// ===============================

// ***servo initialization code***

// ===============================

horizontalServo = new Servo(PORTS::CAMERA_SERVO_H); // create horizontal servo

verticalServo = new Servo(PORTS::CAMERA_SERVO_V); // create vertical servo

servoDeadband = 0.01; // move if > this amount

sinStart = 0.0; // control where to start the sine wave for pan

// initialize position and destination variables

// position settings range from -1 to 1

// setServoPositions is a wrapper that handles the conversion to range for servo

horizontalDestination = 0.0; // final destination range -1.0 to +1.0

verticalDestination = 0.0;

 

// pan needs a 1-up number for each call

panIncrement = 0;

// current position range -1.0 to +1.0

horizontalPosition = RangeToNormalized(horizontalServo->Get(),1);

verticalPosition = RangeToNormalized(verticalServo->Get(),1);

// set servos to start at center position

SetServoPositions(horizontalDestination, verticalDestination);

// ===========================

// ***other initializations***

// ===========================

 

// for controlling loop execution time

loopTime = 0.1;

currentTime = GetTime();

lastTime = currentTime;

// allow writing to vxWorks target

Priv_SetWriteFileAllowed(1);

SetDebugFlag(DEBUG_SCREEN_AND_FILE);

}

 

//returns distance between camera and target in inches

float BTCamera::GetCameraDistance(ParticleAnalysisReport* par)

{

float distance;

distance = (log((par->boundingRect.width)/46.872)/(-0.1247));

return distance;

}

 

#if 1

/**

* Set servo positions (0.0 to 1.0) translated from normalized values (-1.0 to 1.0).

*

* @param normalizedHorizontal Pan Position from -1.0 to 1.0.

* @param normalizedVertical Tilt Position from -1.0 to 1.0.

*/

void BTCamera::SetServoPositions(float normalizedHorizontal, float normalizedVertical)

{

float servoH = NormalizeToRange(normalizedHorizontal);

/* narrow vertical range keep vertical servo from going too far */

//float servoV = NormalizeToRange(normalizedVertical, 0.2, 0.8);

float servoV = NormalizeToRange(normalizedVertical);

float currentH = (1 - horizontalServo->Get());

float currentV = (1 - verticalServo->Get());

/* make sure the movement isn't too small */

if ( fabs(servoH - currentH) > servoDeadband ) {

horizontalServo->Set( 1 - servoH );

/* save new normalized horizontal position */

horizontalPosition = RangeToNormalized(servoH, 1);

}

if ( fabs(servoV - currentV) > servoDeadband ) {

verticalServo->Set( 1 - servoV );

verticalPosition = RangeToNormalized(servoV, 1);

}

}

 

/**

* Adjust servo positions (0.0 to 1.0) translated from normalized values (-1.0 to 1.0).

*

* @param normalizedHorizontal Pan adjustment from -1.0 to 1.0.

* @param normalizedVertical Tilt adjustment from -1.0 to 1.0.

*/

void BTCamera::AdjustServoPositions(float normDeltaHorizontal, float normDeltaVertical)

{

/* adjust for the fact that servo overshoots based on image input */

normDeltaHorizontal /= 8.0;

normDeltaVertical /= 4.0;

/* compute horizontal goal */

float currentH = (1 - horizontalServo->Get());

float normCurrentH = RangeToNormalized(currentH, 1);

float normDestH = normCurrentH + normDeltaHorizontal;

/* narrow range keep servo from going too far */

if (normDestH > 1.0) normDestH = 1.0;

if (normDestH < -1.0) normDestH = -1.0;

/* convert input to servo range */

float servoH = NormalizeToRange(normDestH);

 

/* compute vertical goal */

float currentV = (1 - verticalServo->Get());

float normCurrentV = RangeToNormalized(currentV, 1);

float normDestV = normCurrentV + normDeltaVertical;

if (normDestV > 1.0) normDestV = 1.0;

if (normDestV < -1.0) normDestV = -1.0;

/* convert input to servo range */

float servoV = NormalizeToRange(normDestV, 0.2, 0.8);

 

/* make sure the movement isn't too small */

if ( fabs(currentH-servoH) > servoDeadband ) {

horizontalServo->Set( 1 - servoH );

/* save new normalized horizontal position */

horizontalPosition = RangeToNormalized(servoH, 1);

}

if ( fabs(currentV-servoV) > servoDeadband ) {

verticalServo->Set( 1 - servoV );

verticalPosition = RangeToNormalized(servoV, 1);

}

}

#endif

 

/* scans for target and adjusts servos

* call inside autonomous loop

*/

double BTCamera::Track(ControlBoard* controlBoard)

{

ParticleAnalysisReport par; // particle analysis report

SecondColorPosition secondColorPosition = ABOVE; //default to blue alliance

if (controlBoard->ds->GetAlliance() == DriverStation::kRed)

{

secondColorPosition = BELOW;

dprintf(LOG_DEBUG, "SERVO - looking for COLOR %s BELOW %s", td2.name, td1.name);

}

if (controlBoard->ds->GetAlliance() == DriverStation::kBlue)

{

secondColorPosition = ABOVE;

dprintf(LOG_DEBUG, "SERVO - looking for COLOR %s ABOVE %s", td2.name, td1.name);

}

// calculate gimbal position based on colors found

if ( FindTwoColors(td1, td2, secondColorPosition, &par) ){

foundColor = true;

distance = GetCameraDistance(&par);

panIncrement = 0;   // reset pan

if (par.imageTimestamp == savedImageTimestamp) {

// This image has been processed already,

// so don't do anything for this loop

staleImage = true;

dprintf(LOG_DEBUG, "STALE IMAGE");

} else {

// The target was recognized

// save the timestamp

staleImage = false;

savedImageTimestamp = par.imageTimestamp;

dprintf(LOG_DEBUG,"image timestamp: %lf", savedImageTimestamp);

 

// Here is where your game-specific code goes

// when you recognize the target

// get center of target

//horizontalDestination = par.center_mass_x_normalized;

//verticalDestination = par.center_mass_y_normalized;

}

} else {  // need to pan

foundColor = false;

}

if(foundColor && !staleImage) {

/* Move the servo a bit each loop toward the destination.

* Alternative ways to task servos are to move immediately vs.

* incrementally toward the final destination. Incremental method

* reduces the need for calibration of the servo movement while

* moving toward the target.

*/

incrementH = horizontalDestination - horizontalPosition;

// you may need to reverse this based on your vertical servo installation

incrementV = verticalPosition - verticalDestination;

incrementV = verticalDestination - verticalPosition;

AdjustServoPositions( incrementH, incrementV );

//printf("Servo: x: %f\n", horizontalDestination);

} else if (!staleImage) {  // new image, but didn't find two colors

// adjust sine wave for panning based on last movement direction

if(horizontalDestination > 0.0) { sinStart = PI/2.0; }

else { sinStart = -PI/2.0; }

 

/* pan to find color after a short wait to settle servos

* panning must start directly after panInit or timing will be off */

if (panIncrement == 3) {

panInit(4.0); // number of seconds for a pan

}

else if (panIncrement > 3) {

panForTarget(horizontalServo, sinStart);

/* Vertical action: In case the vertical servo is pointed off center,

* center the vertical after several loops searching */

if (panIncrement == 20) { verticalServo->Set( 0.5 ); }

}

panIncrement++;

 

//ShowActivity ("** %s and %s not found                                    ", td1.name, td2.name);

}  // end if found color

if (count > 10)

{

printf("Timestamp = %lf\n", par.imageTimestamp);

count = 0;

}

count++;

// sleep to keep loop at constant rate

// this helps keep pan consistant

// elapsed time can vary significantly due to debug printout

currentTime = GetTime();

lastTime = currentTime;

if ( loopTime > ElapsedTime(lastTime) ) {

Wait( loopTime - ElapsedTime(lastTime) ); // seconds

}

return par.center_mass_x_normalized;

}

 

bool BTCamera::IsTargetInRange(void)

{

// if (GetCameraDistance(&par) <= SHOOTER_RANGE_LIMIT)

return foundColor;

// else

// return false;

}

#if 0

float BTCamera::GetServoValue(int whichServo)

{

float servoValue = 0;

if (whichServo == HORIZ)

{

servoValue = horizontalServo->Get();

}

if (whichServo == VERT)

{

servoValue = verticalServo->Get();

}

return servoValue;

}

#endif

 

#if 1

/** Simple test to see if the color is taking up too much of the image */

bool BTCamera::IsTooClose(ParticleAnalysisReport* par) {

if (par->particleToImagePercent > MAX_PARTICLE_TO_IMAGE_PERCENT)

return true;

return false;

}

 

/** Simple test to see if the color is large enough */

bool BTCamera::IsBigEnough(ParticleAnalysisReport* par) {

if (par->particleToImagePercent < MIN_PARTICLE_TO_IMAGE_PERCENT)

return false;

return true;

}

#endif

 

 

 

 

 

 
Lockheed Martin
Valid XHTML 1.0 Transitional Valid CSS!
Blanda
Blanda
Copyright © 2012 Eagan Robotics. All Rights Reserved.
Joomla! is Free Software released under the GNU/GPL License.