Thread: Vision Failing
View Single Post
  #1   Spotlight this post!  
Unread 31-03-2012, 20:33
SoyStuff SoyStuff is offline
Registered User
FRC #1257
 
Join Date: Jan 2012
Location: Brooklyn
Posts: 29
SoyStuff is a jewel in the roughSoyStuff is a jewel in the roughSoyStuff is a jewel in the rough
Vision Failing

Our vision system seems to be terribly unreliable. It works on and off, but never completely. The objective is to have it aim towards the target and then shoot. When it can fine the target, this works quite well. Unfortunately, it cannot seem to find the target most of the time. It is extremely picky. We use a green ring of LEDs from superbrightleds.com to illuminate the targets. We try to find the highest target that is also roughly rectangular (to check that it is rectangular (or at least a parallelogram), we divide the particle area by the lengthxwidth and make sure that it is close to 1.) Here is our function (called aimNFire). Please note that we drive back until the target is around 33 pixels wide because that works out to around 12 feet, which is the only point where we have data on how the shooter needs to be oriented.

Code:
team1257LCD->Printf(DriverStationLCD::kUser_Line2, 1, "Aim n' Fire!");
	team1257LCD->UpdateLCD();
	
	//Threshold threshold(0, 120,  100, 255, 125, 255);
	//Threshold threshold(19, 87, 42, 84, 03, 255);
	//Threshold threshold(0, 75,  100, 255, 0, 60);
	//Threshold threshold(0, 80,  0, 255, 55, 220); // tolerant threshold
	Threshold threshold(0, 80,  0, 220, 55, 220); // competition threshold
	//Threshold threshold(0, 255, 0, 255, 0, 255);
	ParticleFilterCriteria2 criteria[] = {
										{IMAQ_MT_BOUNDING_RECT_WIDTH, 30, 400, false, false},
										{IMAQ_MT_BOUNDING_RECT_HEIGHT, 40, 400, false, false}
	};
	
	AxisCamera& camera = AxisCamera::GetInstance("10.12.57.11");
	camera.WriteResolution(AxisCamera::kResolution_320x240);
	camera.WriteCompression(20);
	camera.WriteBrightness(0);
	//camera.WriteExposureControl(AxisCamera::kExposure_FlickerFree50Hz);
	//camera.WriteExposurePriority(0);
	camera.WriteWhiteBalance(AxisCamera::kWhiteBalance_FixedIndoor);
	
	bool driveBack = false;
	Timer robotTimer2;
	robotTimer2.Start();
	while(true/*IsAutonomous() || IsOperatorControl()*/)
	{
		if(robotTimer2.Get()>= 10)
			break;
		
		ColorImage* image = new RGBImage;
		camera.GetImage(image);            // get the sample image from the cRIO flash
		BinaryImage *thresholdImage = image->ThresholdRGB(threshold);   // get just the red target pixels
		BinaryImage *bigObjectsImage = thresholdImage->RemoveSmallObjects(false, 2);  // remove small objects (noise)
		BinaryImage *convexHullImage = bigObjectsImage->ConvexHull(false);  // fill in partial and full rectangles
		BinaryImage *filteredImage = convexHullImage->ParticleFilter(criteria, 2);  // find the rectangles
		vector<ParticleAnalysisReport>* reports = filteredImage->GetOrderedParticleAnalysisReports();  // get the results
	   
		// Identify the highest rectangle
		ParticleAnalysisReport basket;
		basket.boundingRect.top = 10000;
		basket.center_mass_x = 0;
		for(unsigned int i = 0; i < reports->size(); i++)
		{
			if(reports->at(i).boundingRect.top < basket.boundingRect.top && reports->at(i).particleArea / ((float)reports->at(i).boundingRect.width * (float)reports->at(i).boundingRect.height) > 0.7917011257314159)
			{
				basket = reports->at(i);
			}	
		}
		
		// Now, angle robot towards the target
		if(!driveBack)
		{
			if(basket.center_mass_x != 0 && basket.center_mass_x <= 320) // We have valid data!
			{
				double angle = (abs((double)basket.center_mass_x - ((double)image->GetWidth() / 2)) / ((double)image->GetWidth() / 2)) * 22.5;
	
				if(basket.center_mass_x < image->GetWidth() / 2) // To the right of us
					angle *= -1; // Negate angle
				if(angle < 0)
				{
					team1257Robot.SetLeftRightMotorOutputs(0.35, -0.35);
					Wait(0.001);
				}
				if(angle >= 0)
				{
					team1257Robot.SetLeftRightMotorOutputs(-0.35, 0.35);
					Wait(0.001);
				}
				if(abs(angle) < 1.75)
				{
					//break;
					driveBack = true;
				}
					
				team1257LCD->Printf(DriverStationLCD::kUser_Line4, 1, "Angle: %f", angle);
				team1257LCD->UpdateLCD();
			}
			
			/*else
			{
				team1257Robot.SetLeftRightMotorOutputs(0, 0);
			}*/
		}
		if(driveBack)
		{
			if(basket.center_mass_x != 0 && basket.center_mass_x <= 320) // We have valid data!
			{
				team1257LCD->Printf(DriverStationLCD::kUser_Line6, 1, "Driving back!");
				team1257LCD->UpdateLCD();
				if(basket.boundingRect.height < 32) // We are too far
				{
					team1257Robot.SetLeftRightMotorOutputs(-0.3, -0.3);
				}
				else if(basket.boundingRect.height > 33) // We are too close
				{
					team1257Robot.SetLeftRightMotorOutputs(0.3, 0.3);
				}
				else
				{
					break;
				}
			}
		}
		
		team1257LCD->Printf(DriverStationLCD::kUser_Line5, 1, "Width: %i", basket.boundingRect.height);
		team1257LCD->UpdateLCD();
	   
		// Clean up memory
		delete reports;
		delete filteredImage;
		delete convexHullImage;
		delete bigObjectsImage;
		delete thresholdImage;
		delete image;
		
		if(drivepad.GetRawButton(3) || controlpad.GetRawButton(3))
		{
			team1257LCD->Printf(DriverStationLCD::kUser_Line2, 1, "Aim n' Fire terminated");
			team1257LCD->UpdateLCD();
			break;
		}
	}
	
	team1257LCD->Printf(DriverStationLCD::kUser_Line2, 1, "Aim n' Fire terminated");
	team1257LCD->UpdateLCD();
Reply With Quote