[[File:20100927-omclock.png|thumb|omclock is a node that publishes messages for overhead_map, seen above. The time was approximately 12:07:25 when this screenshot was captured.]]

[[File:20100927-omclock.png|thumb|omclock is a node that publishes messages for overhead_map, seen above. The time was approximately 12:07:25 when this screenshot was captured.]]

The overhead_map webpage allows one to display images, lines, points, and arrows on a top-down rendering of a real-world surface.

The overhead_map webpage allows one to display images, lines, points, and arrows on a top-down rendering of a real-world surface.

Line 14:

Line 16:

You will also need a websockets compatible web browser* ([http://www.websockets.org/echo.html check]), such as Chrome 4+, Firefox 4+, or Safari 5+

You will also need a websockets compatible web browser* ([http://www.websockets.org/echo.html check]), such as Chrome 4+, Firefox 4+, or Safari 5+

-

* *Note: Chrome cannot currently handle ajax requests under file://, so if you are using Chrome, the web browser must access overhead_map.html via http. (Other browsers, eg Firefox 4 beta, do not have this problem, and can alternatively be used for this case.)

+

* *Note: As a security feature, Chrome does not handle ajax requests under file:// unless explicitly allowed; if you are using Chrome, the web browser must either access overhead_map.html via http or must be launched with "--allow-file-access-from-files". (Other browsers, eg Firefox 4 beta, do not have this problem, and can alternatively be used for this case.)

Line 64:

Line 66:

* '''Server''': Install a http server, and place the overhead_map folder in a location accessible from other computers via http. (For example, in Apache, this defaults to any files inside of /var/www on Ubuntu machines. ([http://wiki.apache.org/httpd/DistrosDefaultLayout More information])) When we refer to "the overhead_map website" below, we will be referring to:

* '''Server''': Install a http server, and place the overhead_map folder in a location accessible from other computers via http. (For example, in Apache, this defaults to any files inside of /var/www on Ubuntu machines. ([http://wiki.apache.org/httpd/DistrosDefaultLayout More information])) When we refer to "the overhead_map website" below, we will be referring to:

http://[server]/[overhead_map-path]/overhead_map.html?address=[robot]

http://[server]/[overhead_map-path]/overhead_map.html?address=[robot]

+

+

(Note: By default, Apache redirects the "[server]/icons" folder. This is problematic, because overhead_map also has an icons folder. The easy solution is to put overhead_map in its own subdirectory (ie, so that [overhead_map-path] is not ""). The slightly harder solution is to change Apache's default behavior.)

Alternatively, if server and laptop are the same computer, we can look up the website without an http server, in which case when we refer to "the overhead_map website" below, we will be referring to:

Alternatively, if server and laptop are the same computer, we can look up the website without an http server, in which case when we refer to "the overhead_map website" below, we will be referring to:

Line 80:

Line 84:

* Point the laptop's web browser to "the overhead_map website" (as described in the installation section above).

* Point the laptop's web browser to "the overhead_map website" (as described in the installation section above).

-

If successful, you should see a rendering of the CS148 field with a clock.

+

If successful, on the laptop you should see a rendering of the CS148 field with a clock.

[[File:20100927-omclock.png|400px|center|omclock -- Success!]]

[[File:20100927-omclock.png|400px|center|omclock -- Success!]]

+

== Customizing overhead_map ==

+

The overhead_map package was designed to be very flexible with regard to the images, measurements, etc. used. The icons (such as the "irobot-create" picture), backgrounds (such as the soccer field), and logos (such as the center Brown logo and the RLAB logo in the bottom-right) are all customizable without ever touching the Javascript code. <!-- Note: This isn't entirely true, but will be in a few days. -->

+

We will demonstrate how to customize the field by means of example. Robot soccer is fun, but let's supppose you wanted to play robot tennis. We will demonstrate how to completely customize the display to allow this to happen.

A soccer field probably won't do too well, here. Let's make a new background. Navigate to the overhead_map base directory and then to the "backgrounds" subdirectory. Notice that the word "soccer" is present in three of these files:

+

soccer.svg

+

soccer.png

+

soccer.xml

+

+

Of these, only soccer.png and soccer.xml are completely necessary. (soccer.svg was the file used to create the soccer field as a [http://en.wikipedia.org/wiki/Vector_graphics vector graphic], which was then converted into png. We use png files because some browsers (such as the current Firefox 4 Beta) cannot draw svg files inside of html5 canvases, so this increases cross-browser compatibility.)

+

+

Start by making a tennis field image with the name tennis.png:

+

[[File:tennis.png|300px|center|tennis field]]

+

+

For appearance, it is good to keep background files at a reasonably high resolution and at approximately the right proportions; however, the background image will be scaled proportional to the actual dimensions specified in its xml file (below).

+

+

Next, we will add a new xml file for the tennis background. The xml file specifies the "real-world" coordinates of the tennis field, so that we don't need to think of how the field is rendered graphically; we can instead specify where we want things placed in a natural way. In this case, let's do our measurements in feet, since tennis courts are traditionally measured in those units:

+

<field>

+

<width>78</width> <!-- feet -->

+

<height>36</height>

+

<border_color>rgb(241,110,45)</border_color> <!-- "reddish" -->

+

<marker_color>rgb(255,255,0)</marker_color> <!-- yellow -->

+

</field>

+

The border_color field specifies the color to be drawn around the tennis court. The border is drawn so that any objects that are partially off the field will still be drawn fully on the screen. The marker_color field specifies the color of markers (such as points, lines, and arrows) drawn on the field. Here, we've chosen the border to be reddish and the markers to be yellow.

+

+

Now that we've added the tennis background, we would like to see it! We can do this much like the examples above by running rosjs and roscore, and by then pointing our web browser to:

Let's change the logos; we might not be affiliated with [http://www.brown.edu/ Brown University] or [http://code.google.com/p/brown-rlab rlab] and may not want their logos on our tennis court. Let's say, however, that we are associated with [http://www.ros.org/ ROS.org]. We will put the ROS.org logo in the bottom right, and we'll get rid of the center image. (Please note: Brown University, rlab, and the overhead_map project are in no way affiliated with ROS; this choice was made simply for demonstration purposes.)

+

+

First, to get rid of the center image, we'll replace it with a blank image. Conveniently, there's one already available. Navigate to the overhead_map base directory and then to the "logos" subdirectory.

+

> ls

+

blank.png bottom-right.png center.png

+

> mv center.png brown.png

+

> cp blank.png center.png

+

Now, the center logo has been replaced by a transparent pixel.

+

+

Next we will change the bottom-right image to the ROS logo from the top of the main website. To make it fit in better, we'll change the white color to be transparent and shrink it 75% (so that it fits in our picture nicely):

+

+

[[File:ros-logo-transparent-shrunk.png|center|ROS logo, modified for use on tennis court]]

+

+

Name this image "ros-logo-transparent-shrunk.png", and save it in the overhead_maps/logos directory. Then, in the overhead_maps/logos directory:

(For this icon, we will assume rotation does not matter. However, in cases where it does, one should rotate it such that the forward-facing feature of the icon is pointing rightwards (ie, toward theta == 0) as the irobot_create icon does.)

+

+

Put the tennis ball file in the overhead_map/icons directory under the name "tennis-ball.png". Then:

+

> ls

+

ball.png default.png irobot-create.png tennis-ball.png

+

credits.txt icons.xml nxt-brick.png

+

+

The icons.xml file provides overhead_map.js a list of icons to load. So, let's modify this file to include the tennis ball:

+

<icons>

+

<icon>ball.png</icon>

+

<icon>irobot-create.png</icon>

+

<icon>nxt-brick.png</icon>

+

<icon>tennis-ball.png</icon>

+

</icons>

+

+

Finally, to display the tennis ball on the field, users writing Overhead_Map_Objs messages simply need to set the name field of an Overhead_Map_Obj to "tennis-ball" and use it like any other icon. (Note that "line", "point", and "arrow" are keywords which draw said items, so one cannot name icon files any of these names.)

+

As an exercise and a starting point for further development, one can modify omclock to use a tennis ball and display the clock in the center of the field. After completing this, the court will appear as follows:

The example webpage for the om_clock example contains a [http://code.google.com/p/brown-ros-pkg/source/browse/trunk/experimental/overhead_map/overhead_map.js overhead_map JavaScript object], such as [http://code.google.com/p/brown-ros-pkg/source/browse/trunk/experimental/overhead_map/overhead_map.html the one contained in brown-ros-pkg]. overhead_map.js uses rosjs to listen for messages related to the visualizing overhead localization topics and a [http://en.wikipedia.org/wiki/Canvas_element canvas] element to render these objects in the web browser. '''Note:''' This page depends on jQuery, the [http://plugins.jquery.com/project/query-object jQuery query string object plugin], and ros.min.js which are available either locally (as provided in overhead_map/js) or accessible online.

+

The webpage for the overhead_messages system contains a [http://code.google.com/p/brown-ros-pkg/source/browse/trunk/experimental/overhead_map/overhead_map.js overhead_map JavaScript object], such as [http://code.google.com/p/brown-ros-pkg/source/browse/trunk/experimental/overhead_map/overhead_map.html the one contained in brown-ros-pkg]. overhead_map.js uses rosjs to listen for messages related to the visualizing overhead localization topics and a [http://en.wikipedia.org/wiki/Canvas_element canvas] element to render these objects in the web browser. '''Note:''' This page depends on jQuery, the [http://plugins.jquery.com/project/query-object jQuery query string object plugin], and ros.min.js which are available either locally (as provided in overhead_map/js) or accessible online.

Note that the top part (where the field is) is a canvas element named overhead_map_board, and the bottom part (under "Log:") is a textarea named overhead_map_console.

+

=== Message types ===

=== Message types ===

Line 372:

Line 448:

if __name__ == '__main__':

if __name__ == '__main__':

go()

go()

-

-

== Example Code ==

== Example Code ==

Some code was written to test the functionality of overhead_map and may provide a good starting ground for hacking or additional insight.

Some code was written to test the functionality of overhead_map and may provide a good starting ground for hacking or additional insight.

-

'''omclock''': A simple "clock" application to test that all is running well on your system by drawing an analog clock on the overhead_map soccer field. The included launch file (omclock.launch) will launch omclock and rosjs, and it will attempt to launch Google Chrome to display output. (This last step can also be accomplished manually by directing your browser.)

+

* '''omclock''': A simple "clock" application to test that all is running well on your system by drawing an analog clock on the overhead_map soccer field. The included launch file (omclock.launch) will launch omclock and rosjs, and it will attempt to launch Google Chrome to display output. (This last step can also be accomplished manually by directing your browser.)

> roslaunch omclock omclock.launch

> roslaunch omclock omclock.launch

-

'''omdc''': A display controller which takes planar_tracker messages as input and publishes overhead_map messages as output. This can be used to, for instance, create a top-down visualization of a field with objects identifiable by color blobs or AR Tags.

+

* '''omdc''': A display controller which takes planar_tracker messages as input and publishes overhead_map messages as output. This can be used, for instance, to create a top-down visualization of a field with objects identifiable by color blobs or AR Tags in an [[OverheadLocalization|overhead localization system]].

Current revision as of 13:57, 19 November 2010

omclock is a node that publishes messages for overhead_map, seen above. The time was approximately 12:07:25 when this screenshot was captured.

The overhead_map webpage allows one to display images, lines, points, and arrows on a top-down rendering of a real-world surface.

Installation

The overhead visualization system requires a current version of brown-ros-pkg, which includes packages for rosjs (ROS JavaScript interface), om_msgs (ROS overhead map messages), and [1] (overhead_map JavaScript Applet). Assuming brown-ros-pkg is installed, it can be updated by:

The om_msgs package needs to be "compiled" so that the message types Overhead_Map_Obj and Overhead_Map_Objs are available:

> rosmake om_msgs

You will also need a websockets compatible web browser* (check), such as Chrome 4+, Firefox 4+, or Safari 5+

*Note: As a security feature, Chrome does not handle ajax requests under file:// unless explicitly allowed; if you are using Chrome, the web browser must either access overhead_map.html via http or must be launched with "--allow-file-access-from-files". (Other browsers, eg Firefox 4 beta, do not have this problem, and can alternatively be used for this case.)

Introduction: Running omclock example on a single machine

To test that we can get everything up and working, we will use omclock, which draws a clock face with the current time on a soccer field. Once this is up and running, one can easily swap omclock with any other node that publishes Overhead_Map_Objs messages to allow for custom visualizations.

omclock has a built-in launch file, which will start omclock and rosjs:

If successful, you should see a rendering of the CS148 field with a clock.

Running overhead_map with custom code

Graphical illustration of the process explained in this section.

If all overhead_map could do was run clock applications, it would be pretty useless! The good news, though, is that it is a very straightforward process to move away from the demo provided and completely swap it with your code.

Simply put, to publish messages to overhead_map, one needs to publish messages of type Overhead_Map_Objs (defined in om_msgs/msg) to the topic "overhead_map_objs". (In fact, this is exactly what omclock does.) When a web browser is directed to the overhead_map page, overhead_map communicates to rosjs via WebSockets to ask rosjs to subscribe to said topic; rosjs then listens for the topic in ROS and forwards the messages to overhead_map. overhead_map then renders the messages on-screen as they arrive. In each rendering, only the last sent message is rendered.

Details about the publishing format for om_msgs can be found in om_msgs/msg/Overhead_Map_Obj.msg and om_msgs/msg/Overhead_Map_Objs.msg. Below, we will walk step-by-step through omclock's source code to show how to publish this message type.

Using overhead_map on multiple machines

overhead_map is hosted by the server (right computer), rosjs and omclock are running on the "robot" (center computer), and a web browser is running on the laptop (left computer)

One of the perks of the overhead_map system is its modularity; the computer serving webpages, the computer publishing overhead_map information, and the computer viewing the information published can be three completely separate entities! This section will explain the exact division of labor and how to connect the divided laborers together over a local network.

The three tasks at hand are:

Server: A web server (with IP address [server]) which hosts overhead_map. The server hosts the overhead_map folder, which includes (among other things) html, javascript, and images. No special software is needed for this role beyond a traditional web server (such as Apache).

Laptop: A laptop (or other computer) which views the overhead_map webpage. No special software is needed for this role beyond a websockets-compatible browser.

Any single machine may take on one or multiple roles, which interact in the following manner:

The laptop retrieves html, javascript, and image files from the server, like any typical http exchange.

The laptop establishes a connection with the robot via WebSockets. This connection is then used to send Overhead_Map_Objs messages from the robot to the laptop. (Because WebSockets are bidirectional, one may also send information from the laptop to the robot, but this feature is not used by overhead_map.)

The server and robot do not interact.

Installation

Server: Install a http server, and place the overhead_map folder in a location accessible from other computers via http. (For example, in Apache, this defaults to any files inside of /var/www on Ubuntu machines. (More information)) When we refer to "the overhead_map website" below, we will be referring to:

http://[server]/[overhead_map-path]/overhead_map.html?address=[robot]

(Note: By default, Apache redirects the "[server]/icons" folder. This is problematic, because overhead_map also has an icons folder. The easy solution is to put overhead_map in its own subdirectory (ie, so that [overhead_map-path] is not ""). The slightly harder solution is to change Apache's default behavior.)

Alternatively, if server and laptop are the same computer, we can look up the website without an http server, in which case when we refer to "the overhead_map website" below, we will be referring to:

This example will closely follow the single-machine example for running omclock, but it is adapted to use three (or two (or even one)) machines. Like in the single-machine example, after omclock is up and running, it is simple to swap out the omclock node for a custom node on your robot.

Make sure the server is running and available.

On the robot, run the omclock demo:

> roslaunch omclock omclock.launch

Point the laptop's web browser to "the overhead_map website" (as described in the installation section above).

If successful, on the laptop you should see a rendering of the CS148 field with a clock.

Customizing overhead_map

The overhead_map package was designed to be very flexible with regard to the images, measurements, etc. used. The icons (such as the "irobot-create" picture), backgrounds (such as the soccer field), and logos (such as the center Brown logo and the RLAB logo in the bottom-right) are all customizable without ever touching the Javascript code.

We will demonstrate how to customize the field by means of example. Robot soccer is fun, but let's supppose you wanted to play robot tennis. We will demonstrate how to completely customize the display to allow this to happen.

Adding backgrounds

A soccer field probably won't do too well, here. Let's make a new background. Navigate to the overhead_map base directory and then to the "backgrounds" subdirectory. Notice that the word "soccer" is present in three of these files:

soccer.svg
soccer.png
soccer.xml

Of these, only soccer.png and soccer.xml are completely necessary. (soccer.svg was the file used to create the soccer field as a vector graphic, which was then converted into png. We use png files because some browsers (such as the current Firefox 4 Beta) cannot draw svg files inside of html5 canvases, so this increases cross-browser compatibility.)

Start by making a tennis field image with the name tennis.png:

For appearance, it is good to keep background files at a reasonably high resolution and at approximately the right proportions; however, the background image will be scaled proportional to the actual dimensions specified in its xml file (below).

Next, we will add a new xml file for the tennis background. The xml file specifies the "real-world" coordinates of the tennis field, so that we don't need to think of how the field is rendered graphically; we can instead specify where we want things placed in a natural way. In this case, let's do our measurements in feet, since tennis courts are traditionally measured in those units:

The border_color field specifies the color to be drawn around the tennis court. The border is drawn so that any objects that are partially off the field will still be drawn fully on the screen. The marker_color field specifies the color of markers (such as points, lines, and arrows) drawn on the field. Here, we've chosen the border to be reddish and the markers to be yellow.

Now that we've added the tennis background, we would like to see it! We can do this much like the examples above by running rosjs and roscore, and by then pointing our web browser to:

(By adding "map=tennis" to the querystring, we tell overhead_map to draw using the tennis map instead. By default, we use the soccer map.) If all goes well, you should see the tennis court!

Adding/changing logos

Let's change the logos; we might not be affiliated with Brown University or rlab and may not want their logos on our tennis court. Let's say, however, that we are associated with ROS.org. We will put the ROS.org logo in the bottom right, and we'll get rid of the center image. (Please note: Brown University, rlab, and the overhead_map project are in no way affiliated with ROS; this choice was made simply for demonstration purposes.)

First, to get rid of the center image, we'll replace it with a blank image. Conveniently, there's one already available. Navigate to the overhead_map base directory and then to the "logos" subdirectory.

Next we will change the bottom-right image to the ROS logo from the top of the main website. To make it fit in better, we'll change the white color to be transparent and shrink it 75% (so that it fits in our picture nicely):

Name this image "ros-logo-transparent-shrunk.png", and save it in the overhead_maps/logos directory. Then, in the overhead_maps/logos directory:

Adding/changing icons

(For this icon, we will assume rotation does not matter. However, in cases where it does, one should rotate it such that the forward-facing feature of the icon is pointing rightwards (ie, toward theta == 0) as the irobot_create icon does.)

Put the tennis ball file in the overhead_map/icons directory under the name "tennis-ball.png". Then:

Finally, to display the tennis ball on the field, users writing Overhead_Map_Objs messages simply need to set the name field of an Overhead_Map_Obj to "tennis-ball" and use it like any other icon. (Note that "line", "point", and "arrow" are keywords which draw said items, so one cannot name icon files any of these names.)

As an exercise and a starting point for further development, one can modify omclock to use a tennis ball and display the clock in the center of the field. After completing this, the court will appear as follows:

Walkthrough of omclock.py

omclock handles each of the 4 basic types of messages passable by om_msgs, so it will be used to demonstrate how each of these is used. omclock.py can be found by:

> roscd omclock/bin
> gedit omclock.py # or your favorite editor

Breakdown of omclock.launch

In the om_clock example, the launch file starts ROS nodes for rosjs and omclock (to drive the clock behavior):

Note that the top part (where the field is) is a canvas element named overhead_map_board, and the bottom part (under "Log:") is a textarea named overhead_map_console.

Message types

First, let's look at how our messages are specified. For each desired update, we will pass a single message of type Overhead_Map_Objs -- essentially, a list with elements of type Overhead_Map_Obj -- to rosjs. rosjs will then use websockets to send this information to your web browser, resulting in the clock appearing on your screen. The message types the overhead_map system (including but not limited to overhead_map, omclock, and omdc) uses are in the ROS node om_msgs:

> roscd om_msgs/msg

There are two message types specified, namely Overhead_Map_Obj.msg and Overhead_Map_Objs.msg

Basically, we are setting Python up to publish messages of type Overhead_Map_Objs on topic "overhead_map_objs" and to publish the information at about 10 frames per second. (This will let the robot, which represents the second hand, look like it is driving around the clock face.) We also have some helper functions tangential to this walkthrough, which won't be investigated further.

Making the clock

We will now create the clock face by using "Overhead_Map_Obj"s by filling the "Make the clock!" comment.

"Ideal" coordinates overlaid on the soccer background.

Before we can do that, however, we need to know how the coordinate system is set up. All the drawing in overhead_map is performed relative to an "ideal" coordinate frame, which is similar to the one presented in math classes. In our frame, the bottom-left corner of the background is at point (0,0), x points rightward, and y points upward. Theta is measured in radians, is equal to zero when pointing towards +x, and increases as one rotates counterclockwise. The unit is declared arbitrarily, and is meant to be some sort of real-world measure. For example, the "soccer field" in real life is about 4 meters long and 2.5 meters high, so the soccer map is configured to represent the area surrounded by coordinates (0,0), (4,0), (4,2.5), and (0,2.5), and one draws objects by specifying them in ideal coordinates. For instance, if one sees an iRobot Create centered at the real world at coordinates (3,1), one can simply instruct overhead_map to draw a picture of the iRobot Create at (3,1); all the graphics processing and rendering is handled behind-the-scenes by overhead_map.js!

Let's start making the clock by setting up some constants and reading in the time:

Example Code

Some code was written to test the functionality of overhead_map and may provide a good starting ground for hacking or additional insight.

omclock: A simple "clock" application to test that all is running well on your system by drawing an analog clock on the overhead_map soccer field. The included launch file (omclock.launch) will launch omclock and rosjs, and it will attempt to launch Google Chrome to display output. (This last step can also be accomplished manually by directing your browser.)

> roslaunch omclock omclock.launch

omdc: A display controller which takes planar_tracker messages as input and publishes overhead_map messages as output. This can be used, for instance, to create a top-down visualization of a field with objects identifiable by color blobs or AR Tags in an overhead localization system.