Flat Client (LISP version)

Flat Client is provides the basic functionality needed to create a robot controller. It has a set of functions that interact with Flat and the Flat Display to set robot speed and direction, get sensor information, and display output on the display.

An Example

Suppose that your robot needs to travel down a hallway. A good way to do this is with a wall-following controller, which detects the wall or walls on the side and positions the robot with respect to the walls.

Detecting walls

The simulated laser rangefinders in Flat provide a detailed two-dimensional view of the world:

Flat laser display

You can retrieve either the raw rangefinder scans or the processed scan that is in robot coordinates using these functions:

  (get-laser-scan)     
  (get-robot-centric-laser-scan) 
You may want process the data on your own, but Flat has a function to extract line segments from the laser data (n.b. this is a very complex process - unless you want to spend three months developing your own algorithm, we suggest you use Flat's method).
  (get-laser-segments  min-theta max-theta k-max-distance
                       k-discontinuity-threshold
                       k-squid-window-size
                       k-squid-window-std-deviation
                       k-collinear-range-threshold
                       k-collinear-contiguous-threshold
                       k-min-segment-length
                       k-use-filter
                       k-filter-window-size)

  The parameters are explained elsewhere, but the parameter values
  should be in degrees and millimeters.  Here is a useful set:

  (get-laser-segments -360 360 5000.0 1000.0 5 
                      (/ (degrees->radians 1.0) 1000.0)
                      600.0 (degrees->radians 30.0)
                      1000.0 1000.0 0 7)
Once you get the segments, you can display them on the laser display, overlapping the data points:
  (setq segs (get-laser-segments ...))
  (setq segs (flatten segs))    ;; remove inner lists
  (setq segs (mapcar #'(lambda (val) (* 1000 val)) segs))  ;; convert from m to mm.
  (flat-display-sensor-data "Spot" (length segs) :LASER-LEFT-OBJECTS 
                             "FF3388" segs :SEGMENT)

where (flatten) is defined as:

  (defun flatten (l)
  "Flattens the list by removing all parentheses."

  (cond ((null l) l)
        ((atom l) (list l))
        (T (nconc (flatten (car l))
                  (flatten (cdr l))))
        )
  )
This results in the display shown below, with the two red line segments overlaying the blue laser data on the left side. Different parameters to get-laser-segments will produce different segments for the same data.

Flat laser display with segments

The laser segments are ordered. Your controller then has to figure out which line segment(s) correspond to the hallway wall(s) and then produce commands to follow those walls.


Following is a table of flat-client commands:

List of Flat-Client functions
FunctionArgumentsDescription
flat-stop Sets linear and rotational velocities to zero.
flat-go Sets the robot's linear velocity to *default-speed*.
flat-goto(robot-name x y theta)Notifies the Flat Display and Flat that the robot should be moved to the given coordinates. X and Y are in mm, theta is in degrees.
flat-move-robot-to(robot-name x y)This notifies only the Flat Display. Flat does not know that the robot moved. Do not use this with the robot being simulated by Flat. You may place other robots on the display and move them yourself (but Flat will not see them).
flat-move-robot(robot-name delta-x delta-y)Similar to flat-move-robot-to above, but specifies an incremntal movement.
flat-turn-robot-to(robot-name theta)Like the move actions above, moves a robot on the Flat Display only.
flat-turn-robot(robot-name delta-theta)Like the move actions above, moves a robot on the Flat Display only.
flat-speed Sets the robot's linear speed in mm/sec.
flat-slower Reduces the robot's speed by 10%.
flat-faster  Increases the robot's speed by 10%.
flat-straight  Sets the rotational velocity to zero.
flat-turn-left  Sets the rotational velocity to -10 degrees/second.
flat-turn-right Sets the rotational velocity to 10 degrees/second
get-robot-reckoning-inforobot-name (String)Returns an instance of Reckoning-Info which contains the reckoning information about the given robot. The user will not normally call this function.
add-robot-reckoning-inforobot-name info (String)Replaces the info about the robot with the given info. The user will not normally call this function.
initialize-reckoning-position(robot-name &KEY x y z theta v w time) Sets the position and velocity info about the robot to the given values. Default for all values is zero.
update-reckoning-position-flat(robot-name time x y theta) Given the current position and simulation time supplied by Flat, this routine calculates the current linear and rotational speed of the robot.
update-reckoning-position(robot-name time left right &OPTIONAL up down)This is a stub that should be used with other robots that provide odometry counters for left and right wheels. It currently does nothing.
get-robot-reckoning-vrobot-name (String)Returns the current linear velocity as (TIME velocity), where time is in seconds and velocity is in mm per second.
get-robot-reckoning-wrobot-name (String)Returns the current rotational velocity as (TIME velocity), where time is in seconds and velocity is in degrees per second.
get-robot-reckoning-positionrobot-name (String)Returns the current position of the robot as (TIME X Y Z THETA), where time is in seconds, coordinates are in mm, and theta is degrees. Normally this would be calculated from odometry and would thus be subject to error, but Flat does not have an error model for its odometry, and thus the values are exact.
get-sonar-scan Returns the readings from the sonar. Will return NIL if the sonar is not turned on. You can turn it on in the ".flat" configuration file before starting a run.
get-laser-scan Returns a concatenation of the left and right raw scans. The overlapping region in the middle is removed. You probably want get-robot-centric-laser-scan instead.
get-robot-centric-laser-scan Returns a 270-degree laser scan whose coordinate system is centered on the robot's center.
get-laser-segments Returns line segments derived from the laser data.
get-laser-doorways(min-theta max-theta min-jump-size)Makes a quick check for doorways in the laser data. A doorway is indicated by a jump in the laser data.
get-laser-open-space(min-theta max-theta min-distance min-width)Returns true or false, indicating whether or not the open space in the specified angle range fits the parameters.
get-laser-jumps(min-jump-size)Returns a list of locations in the laser data where a large jump in the readings occurs.
get-laser-blobs(min-inter-blob-distance max-intra-blob-distance max-blob-distance min-blob-size max-blob-size) A blob is a collection of laser points which are near each other but far from other points. Nearness and farness are defined by the parameters. Distances are in mm, sizes indicate number of points in the blob.
change-map(map-filename newX newY newTheta)Tells Flat to use a new environment file (i.e. map) and positions the robot in the new map at the given coordinates.
map-transition(transition-name)Tells Flat to perform a map transition as defined in a world map file.
flat-display-clear(robot-name)Clears the Flat laser displays and all segments, circles and points on them.
flat-display-clear-laser-readings(robot-name which)Clears the left, right or both laser displays of laser readings. Leaves other types of data.
flat-display-clear-laser-segments(robot-name which)Clears one or more laser displays of segment data.
flat-display-clear-laser-points(robot-name which)Clears one or more laser displays of point data.
flat-display-clear-laser-circles(robot-name which)Clears one or more laser displays of circle data.
flat-display-sensor-data(robot-name num-data data-type color data-values) Displays a variety of data on the laser displays. See here for more information
flat-display-what-robots Returns a list of the robots in the Flat Display.
flat-display-robot-mark(robot-name type)Tells a robot to drop a mark at the current location, if the type is :CIRCLE. If the type is :CLEAR it clears all the marks for that robot.
flat-display-use-environment(env-file)Tells the display to display the map given by the file or URL.
flat-display-robot-message(robot-name message)Prints a short message on the fourth line of the Robot Manager panel.
flat-display-quit Tells the display program to exit.
flat-display-set-display-scale(robot-name scale)Sets the display scale to 1x, 2x or 3x.
flat-display-add-robot(&OPTIONAL (robot-class "flat.display.spot.SpotDisplay") (robot-name "Spot") Adds a robot to the display. Note that the Flat simulator does not know about these robots.
flat-display-hide-robot(robot-name)Makes a robot invisible on the display.
flat-display-show-robot(robot-name)Makes a robot visible on the display.
flat-display-perform-robot-action(robot-name &OPTIONAL (parameters nil) (stream *flat-display-connection*)) clicking the middle button (or alt-left-button) performs a robot-specific action. Normally, this opens the sensor display. This function lets you perform the action under program control.
flat-display-set-robot-parameter(robot-name param value) A given robot type may understand certain parameters. This is how you would send the robot the parameter. This is for the display only.
flat-display-get-robot-parameter(robot-name param)Retrieves a parameter value from the robot.
flat-display-remove-robot(robot-name)Removes a robot from the display.