# Question about CMUCAM servo output

The servo output is the pan and tilt. My question is: what output does it give? I mean, is it outputed in degrees? I’m working with easyC and the output is an unsigned char, so it is only positive numbers. So is the output the number of degrees the servo turned from it’s start point?

The CMU gives PWM outputs from 0 to 255 which on a servo unlike a motor is a commanded posistion not a speed to drive a motor. The units 0 to 255 on a servo are pretty close to a degree but not exactly 1 degree for each unit. 127 is the middle of the servo’s rotation. I’d hook up the servo and check out how it moves in the online window. Then you can drag the slider an observe it in action.

The CMU cam doesn’t have PWM ports any longer so if you wanted to track via the camera. You could write the values the camera returns to a variable “unsigned char” and then grab a SETPWM block and set the speed
to the same variable.

In order to get the pan/tilt angles in degrees based on the PWM values, you need to find what the pan and tilt PWM values are when the camera is centered, and the change in degrees per each PWM step.

Here is an (untested) example of how to calculate the angle in degrees after those values have been obtained:

#define PAN_CENTER *(whatever the pan PWM value is when the camera is centered)*
#define TILT_CENTER *(whatever the tilt PWM value is when the camera is centered)*
#define PAN_RATIO *(ratio of change in pan angle to change in pan PWM value)*
#define TILT_RATIO *(ratio of change in tilt angle to change in tilt PWM value)*

unsigned char pan;
unsigned char tilt;
int panAngle;
int tiltAngle;

CaptureTrackingData(0, 0, 0, 0, 0, 0, 0, 0, &pan, &tilt); // Get the tracking data
panAngle = (pan - PAN_CENTER) * PAN_RATIO; // Calculate the pan angle
tiltAngle = (tilt - TILT_CENTER) * TILT_RATIO; // Calculate the tilt angle

This should give you roughly the number of degrees from the center point, either positive or negative.

Well, it’s not really important for me knowing the degrees. From what I understood from you, the output is the current PWM of the tilt\pan servo?
If it is like that, please tell me if this code is ok:

//This program makes the robot drive after the target that is being targeted by
//the CMU camera.  When the robot is close enough, it stops.

#define CLOSE_TO (a range between 0-255 [PWM])
unsigned char tilt;
unsigned char pan;

while(1)
{
CaptureTrackingData(0, 0, 0, 0, 0, 0, 0, 0, &pan, &tilt);
while(tilt<127)//PWM #127 means center of servo in easyC
{
Drive(40,255); //makes the robot turn left (function I made)
CaptureTrackingData(0, 0, 0, 0, 0, 0, 0, 0, &pan, &tilt);
}
while(tilt>127)//PWM #127 means center of servo in easyC
{
Drive(255,40); //makes the robot turn right (function I made)
CaptureTrackingData(0, 0, 0, 0, 0, 0, 0, 0, &pan, &tilt);
}
if(tilt==0)
{
Drive(0,255); //makes the robot drive forward
}
if(pan>=CLOSE_TO) //if the pan is close
{
stop(); //a function I made that stops the robot
return; //gets out of the function
}
}

Oh, and another question: in this year’s FRC the robot could see multiple targets (seeing 2 green lights on the rack) so it can confuse the robot, so can you give me some ideas on how to make the robot ignore one of the lights?
Sorry for the multiple questions, I’m a rookie in a rookie team.

Download the kickoff demo. It’s a premade program that does exactly what your looking for. Also in the Projects\Sample Files director of Pro has a graphics display window that makes a realtime box around the targets the camera sees. Stick two lights infront of the camera and you will see a huge box. When you goto one light the box will shrink. If you can’t find it let me know.

What do you mean by the realtime box around the targets? When I start the camera does it automatically search for the color I wanted it to search for, or do I have to tell it where to look at first? And how can I tell the camera to keep track with the closest light (with easyC pro)?

The CMUCAM will draw a single big box around any pixels that are within the color range specified. Then it will find the centroid (middle) of the pixels if the camera can see more of a light the centroid will be more towards the center of the light that is closer or in better sight. Has you drive towards the center of the target, the other junk pixes will fall out of the viewing angle of the camera. Then the camera will try to center the only target pixels it can see. Which at that point should be a single light (The green light)

By default easyC has the target values for the green light preloaded.

I’ll post some screen shots in a bit. ( I need to build a second light first)

I haven’t done any coding since the last FRC season so correct me if I am wrong. This is the way I would do it:

#DEFINE pan_allowance 5 //You have to allow for an allowance or your robot will jitter after the position is acquired
#DEFINE tilt_allowance 5 //Same thing as above
#DEFINE desired_tilt 190 //This has to be greater then 127 (which is the center) because if it was 127 then either you'll have to be really far away or the light has to be at the same height as the robot. I just picked 190 :)

unsigned char tilt;
unsigned char pan;

while (1) //Infinite Loop
{
CaptureTrackingData(0, 0, 0, 0, 0, 0, 0, 0, &pan, &tilt); //Get the pan and tilt data back from the camera
if (pan > 127 + pan_allowance) //The camera has to look to the right inorder to look at the center of the box
Drive(255, 40); //Turn the robot to the right
elseif (pan < 127 - pan_allowance) //The camera has to look to the left inorder to look at the center of the box
Drive(40, 255); //Turn the robot to the left
elseif (til > desired_tilt + tilt_allowance) //The camera has to look way too far up inorder to see the light meaning its too close
Drive(0, 0); //Move the robot backwards
elseif (tilt < desired_tilt - tilt_allowance) // The camera has to look below what it should to see the light so its too far away
Drive(255, 255); //Drive forward
else //If everything is right
Drive(127, 127); //Don't drive!
}

Basically what happens is that first it aligns it so that it is parallel to the light and then it either moves forward or backwards to be with the light. I am not sure how you are doing the drive function but I assumed that what you are trying to do is Drive(Left Side, Right Side) and to go forward you would set both sides to a value greater then 127 and to go backwards you would set both sides to a value less then 127 which is what I did. Also you would want an allowance on both the pan and tilt which was discovered through testing that it would be very jittery if you didn’t have it and it makes sense because the center of the rectangle might shift a little bit with each frame. Also you don’t need a bunch of nested while statements unless you have some other piece of code that resets the values for the motors on the left and right side of the robot. Also I set the speed of the motors when going forward and backwards to full speed this is probably not a good idea since it’ll pass it both ways again making it jittery what you want to do is test it and see what speed you can effectively track the green light at!

OK, I understood what you did, but just a little error (that I did too): the tilt is the y axis (up/down) and the pan is the x axis (left/right). But still, I’m not sure about something: let’s say the light that the robot is tracking is really in the side of the rack, so the robot would get to the light on the side of it. According to your code the camera will look up, and that means the robot is way to close to the light, and it would go backwards, but the x axis (left/right) won’t be changed at all. So what could happen is: the robot would go to the light, it would notice that it is to close, but for the robot he is in the right left/right position, and it would go backwards, and eventually put the tube on air.

Sorry about the Pan and Tilt confusion I wrote the code at 2 in the morning while being sick and taking a lot of medication. I have fixed the code above and the way it would work if it was on the left side of the rack would be that it would look to the left in order to put the light in the center and then the robot would turn to the left in order to be parallel to the light and then it would start moving forwards and if the center of the light moved because its getting closer then it’ll adjust the left and right since the whole thing is a loop not just the individual tilts or pans so it checks the order every single loop to make sure that the robot stays parallel to the light. I haven’t tested the code but I am pretty sure that it would do what you are trying to do even if its on the left or right side of the rack!