*Note: Chrome's 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 suffer from this problem, and can alternatively be used.)

overhead_map.js uses rosjs to listen for messages related to the visualizing overhead localization topics and a canvas element to render these objects in the web browser.

Note: This page depends on jquery and ros.min.js, which should either be available locally or accessible via an internet connection.

If successful, you should see a rendering of the CS148 field with tracked objects on this webpage, appearing with image overlays of recognized objects.

Multi-machine setup

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)

Make sure all computers are connected to the same network. The three tasks at hand are:

Server: A web server to host overhead_map with address [server]. The server hosts the overhead_maps folder, which includes (among other things) html, javascript, and images.

Robot: A robot which is running and publishing information with address [robot]. The robot hosts ROS -- in particular, rosjs -- and exchanges information with the laptop via websockets.

Laptop: A laptop (or any other computer) which you want to view the webpage on. The laptop only needs to have a websockets-compatible browser; no special software is necessary.

Any single machine may take on one or multiple roles.

The interaction between the server, robot, and laptop is, in essence:

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

The laptop establishes a connection with the robot via a WebSocket (where the laptop is the client and the robot is the server), which is then used to send Overhead_Map_Objs messages from the robot to the laptop. (Because WebSockets are bidirectional, it is also possible to send information from the laptop to the robot, but this feature is not used here.)

The server and robot do not interact.

Installation

The server must have some web hosting capability, unless the server and laptop are one machine. (In the latter case, you can simply point the browser at file://...)

Execution (Server-Laptop and Robot)

Example Code

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 to, for instance, create a top-down visualization of a field with objects identifiable by color blobs or AR Tags.

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

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: