
??? Version

This document's was prepared by Christian L Jacobsen, its current revision is: $Rev: 3085 $, $Date: 2007-12-01 16:27:47 +0000 (Sat, 01 Dec 2007) $


! The \player Library

The \player library is the interface between your \occam robotics code, and your
robots. It provides you with a set of processes, which allow you to communicate
with your robot's sensors and actuators. The \player library currently allows
you to interface with a pioneer style robot, either in the Stage simulator,
Gazebo simulator\footnote{For more detail about the Stage and Gazebo simulators
check out their homepage: http://playerstage.sourceforge.net/} or by
interfacing with a real robot.

!! Using

To use the \player library, you will need the following include statement in
your \occam code:

{{{
#INCLUDE "player.inc"
}}}

You will need to link in the following libraries (-l argument to skroc): ///none///.

You will need the following shared libraries available (.so or .dll):
{{{occ\_player}}}, {{{misc}}}.

!! Connecting to your Robots

Your robotics controllers written using the \player library can connect with
either the Stage simulator, the Gazebo simulator or a real robot. Unless you
explicitly specify a hostname and a port number, your robotics controller
using this library will attempt to connect to a simulator or robot listening
on {{{localhost}}} port {{{6665}}}.

Your simulator or robot must be ready and listening when you run your program,
or it will be unable to connect and will exit with an error message.

!! Symbolic Constants

The following symbolic constants are defined in the \player library.

??? {{{VAL INT num.laser.samples IS ...:}}}

This constant defines the number of sample points returned by the laser
rangefinder.

??? {{{VAL INT num.sonar.samples IS ...:}}}

The number of sample points returned by the sonar ranger.

!! Data Types

??? {{{PROTOCOL MOTORS IS INT ; INT ; INT:}}}

This is the protocol used to control a robot's motors. The motors on a robot are
not controlled directly, but rather as an entity with forward and sideways
velocity, and a rotational speed. Only robots with omni-drive use the sideways
velocity\footnote{The Pioneer3 does not have omni-drive.}, if a sideways
velocity is specified for a robot without omni-drive, the value is ignored.

The robots motors are stateful, once you have sent a movement command to the
robot, it will keep moving/turning as instructed, until a new command is sent to
the motors.

All speeds are defined in the robot coordinate system.

Protocol MOTORS: vx; vy; va
* vx -- Forward speed (cm/s)
* vy -- Sideways speed (cm/s) ///(only used by omni-drive robots)///
* va -- Rotational speed (radians/100/s)

|||note
??? Example: Moving forwards at 0.5 meters per second
{{{
  CHAN MOTORS m:
  m ! 50; 0; 0
}}}
|||

|||note
??? Example: Moving forwards, turning 0.3 radians per second.
{{{
  CHAN MOTORS m:
  m ! 50; 0; 30
}}}
|||


??? {{{DATA TYPE LASER IS [num.laser.samples]INT:}}}

This data type represents data from one full sweep of the laser rangefinder. It
is an array containing integers representing the distance to any obstacle
observed by the laser at a particular sample point, in centimetres.

You are most likely to see a configuration of the laser rangefinder which
has 181 samples, from 0 degrees through 90 to 180 degrees. On the pioneer robot
the laser range finder has a range of 8 meters (800cm).

??? {{{DATA TYPE SONAR IS [num.sonar.samples]INT:}}}

This array represents data from the sonar rangers. Each element in the array
corresponds to one ranger device on the robot. 

The pioneer robot has 16 sonar rangers, numbered:
 * 0, front left
 * 1-6, front
 * 7, front right
 * 8, back right
 * 9-14, back
 * 15, back left
The sonar rangefinders have a range of 5 meters (500cm) on the pioneer robot.

!! Robot Brainstems

The {{{brain.stem}}}s allow you to receive sensor data, and control the
actuators on your robot. You are only allowed to use one of these processes in
your robotics control framework at a time, ///unless/// you use one of the
{{{P}}} versions or the undecorated version.

The decorated versions of {{{brain.stem}}} are purely convenience functions which hide
some of the parameters to {{{brain.stem}}} away. The decorated versions are
intended for use in a classroom setting, where the extra parameters to
{{{brain.stem}}} may be distracting.

??? {{{PROC brain.stem(CHAN MOTORS moto?, CHAN LASER sick!, CHAN SONAR devan!,
VAL []BYTE player.host, VAL INT player.port)}}}

This process controls one robot at player.host:player.port. Motors can be
controlled by sending messages on the moto channel, laser data can be picked up
on the sick channel\stalefoot, and sonar data on the devan channel\stalefoot.
You may use one of the simplified versions listed below, if you do not need
access to all the functionality of the {{{brain.stem}}}.

??? {{{PROC brain.stem.L(CHAN LASER sick!)}}}

This process controls one robot on the default port. It exposes data from the
laser rangefinder on the {{{sick}}} channel. You do not need to service this
channel continuously\stalefoot.

??? {{{PROC brain.stem.ML(CHAN MOTORS motors?, CHAN LASER sick!)}}}

This process controls one robot on the default port. It exposes data from the
laser rangefinder on the {{{sick}}} channel. You do not need to service this
channel continuously\stalefoot. You may control the movement of the robot using
the {{{motors}}} channel.

??? {{{PROC brain.stem.MLP(CHAN MOTORS motors?, CHAN LASER sick!, VAL INT port)}}}

This process is like the {{{robot.brain.ML}}} process, except that it allows
you to specify which robot this brain is going to control using the {{{port}}}
argument. Use this version if you need to control multiple robots.

|||note
??? Example: Controlling 3 robots in one \occam program

This example assumes that three robots have been set up, each listening on port
6665, 6666, 6667 respectively.
{{{
  CHAN MOTORS rob1.m, rob2.m, rob3.m:
  CHAN LASER  rob1.l, rob2.l, rob3.l:
  PAR
    robot.brain.MLP(rob1.m?, rob1.l!, 6665)
    robot.brain.MLP(rob2.m?, rob2.l!, 6666)
    robot.brain.MLP(rob3.m?, rob3.l!, 6667)
    ... Other processes, controlling the robots
:
}}}
|||

??? {{{PROC brain.stem.S(CHAN SONAR devan!)}}}

This process controls one robot on the default port. It exposes data from the
sonar ranger on the {{{devan}}} channel. You do not need to service this
channel continuously\stalefoot.

??? {{{PROC brain.stem.MS(CHAN MOTORS motors?, CHAN SONAR devan!)}}}

This process controls one robot on the default port. It exposes data from the
sonar ranger on the {{{devan}}} channel. You do not need to service this
channel continuously\stalefoot. You may control the movement of the robot using
the {{{motors}}} channel.

??? {{{PROC brain.stem.MSP(CHAN MOTORS motors?, CHAN SONAR devan!, VAL INT
port)}}}

This process is like the {{{robot.brain.MS}}} process, except that it allows
you to specify which robot this brain is going to control using the {{{port}}}
argument. Use this version if you need to control multiple robots.

??? {{{PROC brain.stem.MLS(CHAN MOTORS motors?, CHAN LASER sick!, CHAN SONAR
devan!)}}}

This process controls one robot on the default port. It exposes data from the
sonar ranger on the {{{devan}}} channel and exposes data from the
laser rangefinder on the {{{sick}}} channel. You do not need to service this
channel continuously\stalefoot. You may control the movement of the robot using
the {{{motors}}} channel.


!! Other PROCs

??? {{{PROC simple.motor(CHAN INT simple.in?, CHAN MOTORS motors!)}}}

This process presents a simpler interface to the motors than that exposed by
{{{robot.brain}}}. A range of integer constants sent down the {{{simple.in}}}
channel are used to control the motion of the robot. 

This process is meant for use in early class exercises involving the \player
library, and as a result the values used to set the motor states are not
defined as constants in the \player library, but left as an exercise for the
user. The meaning of the values however, are defined here:
* 1 -- forward
* 0 -- stop
* -1 -- reverse
* 2 -- forward, turning left
* 3 -- forward, turning right
* -2 -- reverse, turning left
* -3 -- reverse, turning right
* 4 -- turn left in place
* 5 -- turn right in place

This process does not allow you to take direct control of the speed or rate of
turning, it simply allows you to set the robot in one of several predefined
movement states. If more control over the movement of the robot is needed, you
should interface directly with the {{{brain.stem}}} using the {{{MOTORS}}}
protocol.

??? {{{PROC get.min.L(CHAN LASER sick.in?, CHAN INT min.out!)}}}

This process consumes laser data on its {{{sick.in}}} channel, and sends out
the minimum value found on the {{{min.out}}} channel. Each laser rangefinder
dataset received on {{{sick.in}}} will produce one INTeger on the {{{min.out}}}
channel.

??? {{{PROC delta.L(CHAN LASER sick.in?, sick.out.1!, sick.out.2!)}}}

This is the laser delta process. It takes laser rangefinder data (of type
{{{LASER}}}) on its input channel, {{{sick.in}}}, and produces verbatim copies
of this data on its {{{sick.out.1}}} and {{{sick.out.2}}} channels.

??? {{{PROC get.min.S(CHAN SONAR devan.in?, CHAN INT min.out!)}}}

This process consumes sonar data on its {{{devan.in}}} channel, and sends out
the minimum value found on the {{{min.out}}} channel. Each sonar rangefinder
dataset received on {{{devan.in}}} will produce one INTeger on the {{{min.out}}}
channel.

??? {{{PROC delta.S(CHAN SONAR devan.in?, devan.out.1!, devan.out.2!)}}}

This is the sonar delta process. It takes sonar rangefinder data (of type
{{{SONAR}}}) on its input channel, {{{devan.in}}}, and produces verbatim copies
of this data on its {{{devan.out.1}}} and {{{devan.out.2}}} channels.


\newpage

! The \pioneerhud Library

The \pioneerhud library allows you to visualise the sensor data from a Pioneer3
style robot. When the appropriate PROCs in the library are used, an OpenGL
\footnote{As the visualisation uses OpenGL, it will use hardware assisted
rendering where possible. Where no 3D hardware is available, software rendering
will be used. This may impose a significant overhead when running your robotics
controller.} window will be appear, containing a heads-up display, with a
top-down view of your Pioneer robot and its sensors.

This display will visualise the sensor data which is passed to it on its input
channels. The heads-up display was made to visualise the unprocessed sensor
data which appears from {{{robot.brain}}} on its various sensor output
channels, and it is therefore advisable to insert the {{{pioneer.hud}}} as the
first component in your network after {{{robot.brain}}}.

There is no graceful way to shut down the {{{pioneer.hud}}} from within your
own code. To stop {{{pioneer.hud}}} you must stop your entire robot controller
using, for example, the \occam {{{STOP}}} process. You may also stop your robot
controller by closing the heads-up display window.

??? The Pioneer Robot

The Pioneer robot is represented as a smallish red rectangle towards the middle
of the screen. The scale of this robot may not match your simulated or real
life robot exactly. 

??? The Laser Rangefinder

The data returned by the laser rangefinder, is displayed in the light blue
half-circle located at the top of the window. It represents the 180 data points
returned by the laser rangefinder, as it performs its 180 degree sweep. The
outer edge of the half-circle represents the three meter limit imposed the
\player library. Obstacles further than three meters away will not be displayed
by the laser rangefinder portion of the heads-up display. Obstacles which are
closer than three meters will be visible on the heads up display, as a dent in
the half-circle.

There is a one and a two meter marker on the laser rangefinder display, (light
blue arcs) denoting approximately one and two meters distance from the front of
your robot.

??? Ultrasonic Rangefinder

This device is not yet supported.

??? Core Reactor Utilisation Dynamics visualiser

In the bottom right hand corner of the heads-up display you will find the
Pioneers Core Reactor Utilisation Dynamics visualiser. This will display, as an
easily readable 10 bar graph, the current utilisation dynamics between the 
different elements in the Pioneers core reactor. (Not displayed in low quality
rendering mode)

|||note
??? Important notes
You may not display more than ///one/// heads-up display window at a time. You
should therefore use at most one of the PROCs defined in \pioneerhud, once!
|||

!! Using

To use the \pioneerhud library you will need the following include statement in
your \occam code:

{{{
#INCLUDE "player_hud.inc"
}}}

The \pioneerhud library depends on the \player library, and you will need to
include that library ///before/// you include {{{pioneer\_hud.inc}}}.

You will need to link in the following libraries (-l argument to skroc): snglmath

You will need the following shared libraries available (.so or .dll): occOPENGL,
occSDL

??? High/Low quality rendering

Low quality rendering is currently the defautl.

If you do not have hardware assisted OpenGL rendering, you may turn on the low
quality rendering mode by including the library as follows:

{{{
#DEFINE HUD.FAST
#INCLUDE "player_hud.inc"
}}}

High quality rendering may be enabled by turned on using the following code:
{{{
#DEFINE HUD.SHINY
#INCLUDE "player_hud.inc"
}}}


!! PROCs

??? {{{PROC pioneer.hud.L(CHAN LASER sick?)}}}

When used, this PROC displays the Pioneer heads-up display. Data from the laser
rangefinder should arrive on the {{{sick}}} channel. All data received on this
channel will be consumed by the {{{pioneer.hud.L}}} process, and it is
therefore most useful when a quick visualisation of the data from
{{{robot.brain}}} is required. If you have other components than
{{{robot.brain}}} in your network, you will likely need one of the other PROCs
defined by this library (which do not consume the data they receive).

??? {{{PROC pioneer.hud.LL(CHAN LASER sick.in?, sick.out!, VAL BOOL enabled)}}}

When used, this PROC displays the Pioneer heads-up display. Data from the laser
rangefinder should arrive on channel {{{sick.in}}} and will come back on channel
{{{sick.out}}}, unaltered. This allows you to insert the {{{pioneer.hud.LL}}}
component in-between the {{{robot.brain}}} process, and your own processes.

To enable you to turn the heads-up display on and off without changing your
network, {{{pioneer.hud.LL}}} requires you to supply an {{{enabled}}} argument,
which when {{{TRUE}}} will display the heads-up display, and when {{{FALSE}}}
will not display the heads-up display.

As a general rule, you will always want to insert the {{{pioneer.hud}}}
processes as the first process receiving data from {{{robot.brain}}}.
