|
|
|
![]() |
|
|||||||
|
||||||||
![]() |
|
|
Thread Tools | Rate Thread | Display Modes |
|
|
|
#1
|
|||
|
|||
|
PID Loops using the Camera
Hi all,
We have some code that is untested , and so I thought I would ask if any of you could provide some answers/advice. How feasible would it be to use the camera (involving image processing as similar to that in the sample camera code) in the PID Input value? From what I've heard, it takes some time for it to be calculated, which would cause a delay in the process. |
|
#2
|
||||||
|
||||||
|
Re: PID Loops using the Camera
Quote:
Two things to think about: 1) you might want to change the X position coordinate that you get out of the default camera code to an aim angle. You can do this by multiplying the X coordinate by half of the camera field of view. For example, if the X coordinate from the camera code is 0.5 and your camera field of view is 43 degrees, than your aim is: 0.5 * (43/2) = 10.75 degrees (i.e., you must turn 10.75 degrees to be aimed at the target). Note that your aim is 10.75 from your camera position. If your camera is fixed to a moving turret, you'll need to add 10.75 degrees to your current known turret angle. 2) Your PID will most likely be very unstable due to the time it takes to retrieve the image and process it. What you need to do is delay your known turret angle that I referred to in step 1 above by the same time as your camera lag. Here's an example: PID_setpoint = CurrentTurretAngle_delayed + CameraAim; PID_processVariable = CurrentTurretAngle; In the above example, CurrentTurretAngle_delayed is the turret angle that has been delayed by the same amount of time as your camera lag. So, if you determine that your camera lag is 0.5 seconds, then CurrentTurretAngle_delayed should also lag by 0.5 seconds. CurrentTurretAngle (process variable) should be the real-time turret angle. Last edited by Chris Hibner : 07-03-2012 at 09:48. Reason: Gave some wrong information. |
|
#3
|
||||||
|
||||||
|
Re: PID Loops using the Camera
If you're wondering how to delay your turret angle, you need a circular buffer that covers the time of delay.
Here's an example: Let's say you want to delay measurements by 0.5 sec. Your fast periodic loop (the loop you're running the PID in) runs at 10 msec. In this case, your circular buffer must contain 50 elements (0.5 sec / 0.01 s = 50). Then in your code: in the initialization code, create an array with 50 elements. Set all elements to 0 (or whatever the starting angle of your turret is, if it isn't 0). example: Code:
double turretAngleDelayed[50];
for (int i = 0; i < 50; i++)
{
turretAngleDelayed[i] = 0;
}
Code:
static int currentTurretCount = 0;
double currentTurretAngle_delayed;
currentTurretAngle_delayed = turretAngleDelayed[currentTurretCount]; // this retrieves the value from 50 samples ago (i.e. 0.5 sec ago)
// now overwrite the sample from 50 samples ago with the current sample
turretAngleDelayed[currentTurretCount] = currentTurretAngle; // current turretAngle is the angle measure this loop
// update the counter for the next loop
currentTurretCount++;
if (currentTurretCount >= 50)
{
currentTurretCount = 0;
}
Last edited by Chris Hibner : 07-03-2012 at 10:04. |
|
#4
|
|||
|
|||
|
Re: PID Loops using the Camera
Thanks you so much for your help! In the source code there is a constructor for PIDSubsystem in Java in which you can input the period between calculations- would that work?
|
|
#5
|
||||||
|
||||||
|
Re: PID Loops using the Camera
I really don't know - I've never seen the FIRST Java framework. Hopefully someone that uses Java can help in this area.
|
![]() |
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|