On a recent project with a rushed development schedule, there was a little issue. The workaround of booting the Jetson into a graphics desktop without a monitor attached is worth sharing.
As is the case with a lot of projects that involve visual processing, the example framework for this project was written using a Graphical User Interface, or GUI. In the rush of development, this framework was used as the structure for building a demonstration application.
In this particular demo (Flying Robot Demo), an image stream is acquired from a camera sensor and each image is examined for the presence of a fiducial marker. The fiducial marker in this case is an April Tag, which looks like a big QR code. If a fiducial marker is recognized, then commands are sent out to the robot to control its position corresponding to the markers meaning. For example, a marker recognized as code 20 might tell the robot to move left 2 meters. A very simplistic concept.
Having a graphics program, in this case one written using the framework Qt, is useful for a person to help in the debugging purposes. In this case the camera stream is placed on the monitor, and any markers recognized are highlighted by placing a colored rectangle over the marker on the screen.
Now the computer doesn’t really care about this visual representation, it’s there purely to help the person writing the program. But here’s the thing: as a developer working with a tight deadline you need all the help you can get. The easiest thing to do in this case was to use the example framework and build on that.
Once the program was ready to be tested on the robot standalone, the demo program was marked as a startup application using the Startup Applications app through the desktop. In this case the permissions were fiddled with so that the program could talk to the USB camera. Everything was tested once more, to make sure everything worked on startup as expected.
Now this being a flying robot and all, you probably have guessed that the robot does not carry an attached HDMI monitor on board. So when the program was to the point that it was working on the bench and ready to be tested standalone, the monitor and external peripherals were detached and everything booted up. What happened next? Nothing. The robot sat there like a big fat pig and ignored any attempt at recognizing markers. Of course the natural inclination was to hook everything back up to make sure everything works. It does. Disconnect, startup. Nothing.
What took a little while to realize was that if there is no monitor attached to the Jetson, then the X11 graphics manager does not load, which in turns means that the desktop manager does not load. If the desktop manager does not load, the startup applications do not load. Then what happens? In this case, nothing. It just sits there silently like a big fat pig dog.
For most robot applications, programs are written as console applications. This allows for easy communication with the robot through SSH from another computer. Unfortunately in this case, the framework for controlling the robot is commingled with the graphics user interface. Given the short amount of development time available, it was unlikely that the program could be rewritten as a console app to meet the deadline.
After Googling like a chicken with its head cut off, the solution that was implemented for the demo was based on attaching a HDMI monitor emulator to the Jetson. Here’s the HDMI display Emulator used:
This emulator appears to the Jetson to be a HDMI monitor. X11 and the desktop happily load, none the wiser.
As it turns out after going to GTC 2016 and talking to knowledgeable NVIDIA people, there is a software workaround.
Allow X without HDMI at Boot
Option "AllowEmptyInitialConfiguration" "true"
Which will allow X11 to startup without a monitor attached.
So there you have it. If you wander down the wrong path during development, and find yourself in a similar situation of hopeless despair, you too can tell the developer gods “Not Today!” and snatch victory from the jaws of defeat.