How to get the camera working on the default dashboard

[UPDATED 06-Feb-2011: (a) resolved ambiguity with “top” Ethernet port on cRIO, (b) added information on focusing the video image, and © pointed out that the metal frame on the back of the camera must be electrically isolated from the robot.]

Last year, we used the 2010 Axis 206 camera to display the robot image on our dashboard, and it worked fine. This year, it was no longer working, and it took us quite a while to figure out the problem. We now have it working fine again, but I wanted to document the steps to get the Axis 206 camera working on the dashboard, in case it is useful to other teams.

In the process of researching our camera issues, we read many threads here on Chief Delphi of teams having similar camera problems, so I wanted to pull together all the steps and tips we found into one place.

NOTE: These instructions have only been tested for last year’s 2010 Axis 206 camera. The instructions should be very similar or identical for this year’s 2011 Axis M1011 camera. If a team has the new Axis M1011 camera and tries the steps below, and can point out any differences between the two cameras that we should incorporate, I will update these instructions accordingly.

ALSO: These instructions are for WindRiver C++. The instructions for Java will be slightly different, but should be similar. If someone would like to test and post the differences needed for Java, that would be great, and I will update this posting accordingly.

Here is how to get your Axis 206 camera working with WindRiver C++ so that it will display video from the robot on the default dashboard:

  1. In the Control System section of the 2011 Kit of Parts page, follow the instructions in the most recent versions of the appropriate documents to:
    (a) Configure your cRIO (“How to Configure your cRIO”).
    (b) Set up your driver station (“How to Set Up Your 2011 Driver Station”).
    © Provide 5V power to your Axis camera either by plugging its AC adapter into the wall, or by cutting off the AC adapter on the power cord and connecting the cord wires instead to the 5V connector on the Power Distribution Board (see “How to Set Up Your Robot Control System” or the “Robot Power Distribution Diagram”).

  2. IMPORTANT: Make sure your camera is mounted in such a way that the camera reset button is NOT pressed. It’s very easy for this problem to occur, because the obvious way to mount the camera will end up pressing the reset button. (This was the problem with our camera this year, and this same problem has been reported by at least two other teams here on Chief Delphi. You can lose a lot of time with this problem.) The reset button is a very small black button on the lower back of the Axis 206 camera.

  3. Per 2011 game rule <R36>, you need to make sure your camera is mounted so that it is electrically isolated from the robot frame (just as the frame of the cRIO must be electrically isolated from the robot frame). This is a little tricky. The off-white case on the camera is plastic, so that’s not a problem, but the back of the camera is metal. Even trickier, the mounting bolt and nut on the back of the camera are also metal. If you use the camera mounting bolt, you need to be sure and electrically isolate it from the robot frame. For example, you could make a small plastic plate for the back of the camera (that does not touch the camera reset button), use the camera mounting bolt to mount the camera to the plastic plate, and then attach the plastic plate to your robot. (The plastic would provide the electrical isolation.) You could also conceivably use the plastic base plate that comes with the camera to mount the camera to your robot, but that might be a little ungainly.

  4. Follow the instructions in “How to Configure your Camera.” IMPORANT NOTE: Those instructions imply that you can set up either of two different users on the camera: Username “root” with password “admin” and/or username “FRC” with password “FRC”. However, we found (at least when using the camera with WindRiver C++) that there MUST be a username “FRC” with password “FRC” in order for the Axis camera code to work.

  5. With the cRIO powered off, use an Ethernet **crossover **cable (NOT a regular Ethernet cable) to connect the Axis camera to Ethernet port 2 on the cRIO (the port has a “2” label next to it – it is the “top” Ethernet port on the cRIO when the cRIO is right-side up).

  6. When you power on the robot and camera, the Ethernet activity light next to Ethernet port 2 on the cRIO should light up and possibly blink.

  7. The outer ring around the camera lens is called the Status Indicator. When you first power on the robot and Axis 206 camera, the Status Indicator should be steady amber in color. After 30 seconds or so, the Status Indicator should turn to a steady green color.

  8. Use the default dashboard with the driver station. On the upper left of the dashboard, there should be a large rectangle where the camera video will be displayed. Beneath that rectangle on the screen, there is a small triangular button called “Video Enable.” If that button is NOT lighted green, click on the button with the mouse to turn it on.

  9. Create a new WindRiver C++ project. For this camera test, you only need one file in that project, a very small .CPP file with the following code in it:

#include "WPILib.h"
class RobotDemo : public SimpleRobot {
public:
	RobotDemo(void) {
		Wait(8.0);
		AxisCamera &camera = AxisCamera::GetInstance();
	}
};
START_ROBOT_CLASS(RobotDemo)
;
  1. NOTE: The “Wait(8.0);” statement above is to allow the camera to initialize after powering up the robot. That statement is not required, and it will slow down your robot initialization. If you omit the Wait(), you will see “AxisCameraParams: connect: S_errno_ECONNREFUSED” errors on NetConsole when powering up the robot, which is not a big problem. (You won’t see these errors if you do a soft reboot from the driver station; the error only occurs if you power off and power up the robot.) This Wait() is not important, unless you are going to write some code to manipulate the camera images. If you simply want to display the camera image on the dashboard, you can omit the Wait() statement, and you will simply notice that the video on the dashboard won’t update until the camera has fully initialized – not a big deal. ALSO: I have seen Wait() statements for a smaller number of seconds proposed by others. It depends on how many other statements precede the Wait(). But for the simple program above, using a Wait of 7.0 seconds rather than 8.0 seconds still results in a few of the above errors being displayed on NetConsole, so we found that 8.0 seconds is required if you want to avoid all of those errors on NetConsole.

  2. In the above C++ program, the simple act of invoking AxisCamera::GetInstance() causes the camera to initialize and start sending images to the default dashboard. You do NOT need any other code to get images to display on the dashboard. Simply invoking GetInstance() causes the video to start displaying automatically.

  3. When you download and run the above program, you should see that your dashboard displays video from the robot on the default dashboard. Huzzah!

  4. If the video image on the dashboard is out-of-focus, rotate the black “focus” ring that is around the camera lens to bring the image into focus. The black focus ring is fairly stiff, so it might seem like the focus ring doesn’t turn, but it really does.

  5. The camera sends the video as a series of JPEG images. If you would like to perform analysis on the video frames to look for objects in the field of view, see the more advanced C++ code in the video demo program that comes with the FRC version of WindRiver C++ (choose “File | New | Example | VxWorks Downloadable Kernel Module Sample Project | FRC 2010 Vision Demonstration Program” in WindRiver C++). And, of course see the AxisCamera class documentation in the “WPI Robotics Library User’s Guide.pdf” and “WPILib C++ Reference.chm” in the “\WindRiver\docs\extensions\FRC” folder on your development computer.

I hope the step-by-step information above is useful to other teams. If you see any errors or additions that should be added to the above instructions, please let me know, and I will edit the instructions accordingly.

Very ambiguous. Last year we mounted our C-RIO on its side so the top port was port 1 (this year we’re mounting it on the other side, of course)

Good startup guide though, it looks like it’s helpful. You might want to give suggestions for mounting it (just a 1/4 inch hole?)

Very good points. I have updated the post that started this thread to: (a) explain Ethernet port 2 so it is not ambiguous, (b) explain how to focus the camera, and (3) give more concrete suggestions about mounting the camera so that the reset button is not pressed and the camera is electrically isolated (per Rule <R36>).

Everyone: Please let me know if you have any more suggested changes or improvements, and I will make them to my original post.

Nice summary. The reset button was plaguing us since last year.

We had been having much trouble with our robot’s camera system as well, until we came to this thread.

This code worked perfectly in Java.

For testing purposes, we created a new SimpleRobot subclass using the RobotTemplate default method. We imported the wpilibj package and the camera package. And this was what followed it.


public class RobotTemplate extends SimpleRobot
{
   public RobotTemplate()
   {
        Timer.delay(8);
        AxisCamera camera = AxisCamera.getInstance();
   }
   // The other default methods placed here.
}

To prevent waiting 8 seconds before your robot will run, the AxisCamera camera = AxisCamera.getInstance(); line can be put in the teleopInit() method of an IterativeRobot subclass.

Hopes this helps!

If teams are having trouble with the m1011 and C++ they should look at the wpilib tracker: http://firstforge.wpi.edu/sf/go/artf1330

I’m not a Java expert, but could you do something with threading so the camera inits when it’s ready without blocking the rest of the code?

I have two questions, I am getting the warning “warning: unused variable ‘camera’” when I compile it in WindRiver. is that a problem? Second, do I need to put the line of code “AxisCamera &camera = AxisCamera::GetInstance();” in both the constructor and in the teleOp? or just the Constructor? or just TeleOp? Sorry if these are simple questions, this is my first year in C++.

Does anyone happen to know if the C++ code that is embedded in wpilibj (used with Java to implement the AxisCamera class internals) has the fix for bug “Artifact artf1330 : Axis Camera Problems with M1011 in 2011” included in the latest version? We use Java and seem to hit exactly this bug. I would have guessed that this code would be shared (rather than copied), but haven’t had a chance to check for myself yet.

It should be emphasized in these instructions that “The camera comes with a network address of 192.168.0.90”. So if you are connecting camera through to the cRIO you need to leave this address. We accidentally misread the instructions and put 10.xx.yy.11, and it would not work. So we manually set it back to 192.168.0.90 with a subnet mask of 255,0,0,0 and use the l/p “FRC”, “FRC”. This is what works for us.

Also…
When I first read this and saw to use the wait(). I was not sure when this would be called, and was concerned that autonomous would have to wait before it could startup. Fortunately, this code is called only once when the robot is powered on, and the camera comes on (around 15 seconds) before anything is enabled (should come on long before the match starts). So really the wait is not the end of the world. We use a wait of 10 seconds as suggested from the robo-wranglers.

This is a great thread which has been very helpful… Thanks a bunch!!