Is it really likelier that Java source code contains the word "Anteaters" than "Annotators"? You've failed the IDE Turing Test.
I am documenting my learning efforts here, so don't expect any big revelations. But if you see anything useful, you're welcome to drink from the fountain of my wisdom ;-)


public class MyStack
{
private int[] s;
private int top;
private final int MAX_SIZE = 10;
public MyStack()
{
top = 0;
s = new int[MAX_SIZE];
}
public void push(int element)
{
if (top == MAX_SIZE-1)
System.out.println("Stack overflow during push()!");
else
{
s[top] = element;
top = top + 1;
}
}
public int pop()
{
if (isEmpty())
{
System.out.println("Stack underflow during pop()!");
return -1;
}
else
{
top = top - 1;
return s[top+1];
}
}
public int getTop()
{
return top;
}
public boolean isEmpty()
{
return (top == 0);
}
public void printStack()
{
System.out.print("Stack: ");
for (int i = 0; i < top; i++)
System.out.print(s[i] + " ");
System.out.println("\n");
}
}
$ sudo apt-get install ros-groovy-qt-rosThen, to create a ROS package with Qt capabilities, you would do:
$ rosrun qt_create roscreate-qt-pkg PACKAGE_NAMEThe relevant folders in the created package are the following:
$ roscreate-pkg screenshot std_msgs roscpp image_transport $ rosmake screenshotThen create the subscriber (mine is called "cam_listener"), not forgetting to add it to Cmakelists.txt:
$ rosbuild_add_executable(cam_listener src/cam_listener.cpp)The main() function in cam_listener.cpp looks like this:
int main(int argc, char **argv)
{
ros::init(argc, argv, "cam_listener");
ros::NodeHandle n;
image_transport::ImageTransport it(n);
image_transport::Subscriber sub = it.subscribe("camera/rgb/image_color", 1, imageCallback);
while (true)
{
ros::spinOnce();
ros::Duration(15).sleep(); // Take screenshots every 15 seconds
}
return 0;
}
We use image_transport to create a bit more specialized subscriber, in order to get data from the camera. The callback is named "imageCallback", and it looks like this:
void imageCallback(const sensor_msgs::ImageConstPtr& msg)
{
// Writes the raw image data in a PPM formatted file
// We convert the time stamp that comes in the header of the data from the camera to posix time, in order to use it as part of the ppm filename
ros::Time stamp = msg->header.stamp;
boost::posix_time::ptime posix_time = stamp.toBoost();
// We only take part of the posix time
std::string filename = boost::posix_time::to_iso_string(posix_time).substr(0, 14) + ".ppm";
std::ofstream f(filename.c_str());
if (!f)
{
std::cout << "Couldn't open file.\n";
}
std::cout << "Writing data to file " << filename << "\n";
// On the first line, the magic marker for a PPM file -- "P3"
f << "P3\n";
// On the second line, the number of columns and the number of rows
f << msg->width << " " << msg->height << "\n";
// The max colour value
f << "255\n";
// Write the triplets of colour
int row = 0;
int pixel;
while (row < msg->height)
{
pixel = row * msg->step;
while (pixel < (row+1)*msg->step)
{
// B = pixel, G = pixel + 1, R = pixel + 2 -> we need RGB for the PPM format
// Since we are working with unsigned char, cast it to int for writing to the file
f << static_cast< int >(msg->data[pixel+2]) << " ";
f << static_cast< int >(msg->data[pixel+1]) << " ";
f << static_cast< int >(msg->data[pixel]) << " ";
pixel += 3; // Jump to the next bgr triple
}
f << std::endl;
row++;
}
f.close();
}
Basically, we write the header of the ppm file and then the plain text values for the pixels. The only tricky aspect is the order of the rgb pixels. The encoding of the data from the image is bgr8 (check it yourself in msg->encoding!), whereas for the ppm file we need rgb. That's why, on lines 35-37, we take the values in reverse order.$ roslaunch openni_launch openni.launchIn a third terminal, we start our listener:
$ rosrun screenshot cam_listenerEvery 15 seconds, a shot from the camera will be saved in the
$ roslaunch openni_launch openni.launchMake sure the camera has started ok. You should see at the end something like this:
...If it doesn't start ok, it might be because the camera is plugged in a USB3 port. In that case, just switch to a normal USB port.
[ INFO] [1362906100.839021507]: Initializing nodelet with 2 worker threads.
[ INFO] [1362906104.029471453]: Number devices connected: 1
[ INFO] [1362906104.029784696]: 1. device on bus 001:09 is a PrimeSense Device (600) from PrimeSense (1d27) with serial id ''
[ INFO] [1362906104.031251209]: Searching for device with index = 1
[ INFO] [1362906104.065753491]: Opened 'PrimeSense Device' on bus 1:9 with serial number ''
[ INFO] [1362906104.097498307]: rgb_frame_id = '/camera_rgb_optical_frame'
[ INFO] [1362906104.097716391]: depth_frame_id = '/camera_depth_optical_frame'
$ rosrun image_view image_view image:=/camera/rgb/image_colorA window should pop up, showing the normal video output of the camera.