Introduction

ARENA, the adaptable robotic experiment in automation, is a computer program designed to simulate robotic hardware and software. The ARENA program provides an environment to test specific algorithms on varying hardware configurations. To do this, the ARENA program provides a hardware configuration defined in terms of simulated physical devices such as motors and sensors, while the programmer provides the robot’s software in the form of a Lua script file. Both the data that is available to these script files and the quality of that data is determined by the hardware implementation. ARENA currently focuses solely on location finding algorithms by providing the robot with a destination and an unknown set of obstacles in-between.

The ARENA Interface

Display

The ARENA program starts with a visual representation of the “world” (clouds, grass, and buildings) and the “robot” (the funny looking V-shaped object in the center of the screen). ARENA will execute the robot’s script file and keep a real-time visual representation of the robot’s state.

On the right side of the screen is ARENA’s status console. The information here is updated in real time and can be used to debug the current algorithm. The fields for PredictedPosition and ActualPosition indicate where the robot’s software believes itself to be located and where it is actually located respectively. The other parameters follow a similar pattern. The difference between these values is also tallied.

Controls

To begin the simulation, press the ‘P’ button on your keyboard. This is equivalent to switching on the power switch for a real robot. As soon as the robotic agent is “powered on” it will continue running until the software stops itself. To abort the simulation at any point, simply press the escape key.

To control the camera, simply use your mouse. The mouse’s x axis controls the camera’s yaw around the robotic agent, and the y axis controls the pitch. To zoom in press ‘W’ and to zoom out press ‘S’.

The final item to notice is the red line on the screen. The endpoints of this line are the robot’s current position and the robot’s destination. The robot’s destination is fixed and is set internally by the ARENA program. It may be convenient in the future to expand upon this limitation.

The ARENA Programming Environment

ARENA uses four important software packages, all of which need to be properly setup to compile the ARENA source code. It should also be noted that the ARENA program is written in Borland C++ Builder 4, and makes heavy use of the Borland Visual Component Library (VCL). The actual simulation code is not tied to the VCL, however, and should be able to be ported without too much trouble.

The four software packages that ARENA uses are the Just3D Engine, DirectX 8.1, NVidia CG SDK, and Lua 5.1. Just3D is a proprietary 3D engine that uses DirectX and handles models, levels, and collision detection. DirectX 8.1 is a free software development kit distributed by Microsoft that allows programmers to access complex computer hardware from sound cards, Ethernet adapters, video cards, and input devices in a comprehensive interface. NVidia CG is a high level shading language designed to be used with DirectX compatible video cards. The CG interfaces load special CG files and convert them into a format DirectX can use. Finally, Lua is a freely distributed general purpose scripting language with a well supported C interface.

Libraries

The following static libraries must be linked with ARENA:

c_dinput.libDirectX input functions.

dinput.libDirectInput library.

dinput8.lib

d3d8.libDirect3D functions and interfaces.

d3dx8.lib3D math and helper functions.

dsound.libDirectSound interfaces.

dxguid.libDirectX globally unique identifiers.

cg.libCore CG functions and definitions.

cgD3D8.libCG functions specific to DirectX 8.1.

lua.libThe compiled Lua library file.*

* Lua is distributed as ANSI compliant C code. The lua.lib indicated here is a custom library I compiled from the source code specifically for Borland C++ Builder 4. Instructions can be found online explaining how to compile Lua for a specific compiler.

Source Files

The following .cpp files must be included with ARENA:

DebugJU.cppJust3D debugging functions.

fauerby.cppJust3D collision detection.

fauerby_math.cpp

Just3D.cppThe main Just3D source file.

Just3DLua.cppThe Just3D-Lua interface.

Just3DMath.cppJust3D 3D math functions.

Just3DPart2.cppThe second half of the main Just3D source file.

Just3DParticles.cppParticle effects.

Sound.cppJust3D sound engine.

Header Paths

ARENA must have the following header paths in its header file search directory:

-The folder containing the Just3D engine.

-The Fauerby Collision Detection folder, in the Just3D root folder.

-The Lua “src” folder.

-The NVidia CG “include” folder.

-The DirectX “include” folder.

Final Notes

ARENA makes use of the DirectX helper library known as D3DX. Because Microsoft no longer supports Borland compilers, the D3DX libraries could not be directly used. Instead, five dynamic link libraries must be distributed with any application that uses the D3DX functions in a Borland compiler. These five .dll files are:

d3dx8bor.dll

d3dx8d.dll

d3dxbor.dll

d3dxdbor.dll

dxerr8bor.dll

The ARENA Code

The ARENA code can be divided into three main source files. The first is ArenaMain, the next is ArenaAgent, and finally ArenaLua.

ArenaMain.cpp

This source file contains the setup code for the entire ARENA program and maintains the interfaces to the J3D Engine and DirectX. The source file also contains the code that updates the ARENA status console and interprets input (keyboard and mouse). Here are the important functions and their respective purposes:

InitializeArena

This function creates and initializes the Engine, MainCamera, Environment, and Agent objects. The Engine object enables access to all of the Direct3D functions. The MainCamera defines the viewing position and angle of the camera. This is tied to the Engine object by the Engine’s SetCamera function. The Environment object contains all of the data necessary to draw and update the clouds, grass, and buildings. Lastly, the Agent object contains the data to interface with the robotic agent, run its scripts, and draw it on screen. The Agent object is of the ArenaAgent class, which is detailed in the ArenaAgent section.

ArenaMainLoop

This function is called every frame and makes all of the drawing, update, and input calls.

ShutdownArena

This function deletes all of the data, objects, and interfaces created by InitializeArena.

UpdateStatus

This function polls the Agent object for its current position, and rotation. UpdateStatus then compares these values to the values that are used to draw the robot and outputs the comparison. UpdateStatus also checks and reports the distance between the robotic agent’s current position and its destination.

ArenaAgent.cpp

This source file contains all of the functions necessary to maintain the robotic agent. The principle class, ArenaAgent, contains functions to interface with Lua (more information in the ArenaLua section) and maintains the agent’s internal state including its hardware, position, rotation, destination, and collision detection tests. ArenaAgent.cpp (and ArenaAgent.h) also defines the class for the hardware interfaces (ArenaAgentHardware) and the hardware interfaces’ parameters (AgentHardwareParameter).

ArenaAgent::Initialize

The ArenaAgent class must be instantiated for the ARENA program to work. This function also must be called after the object is created to allow the ArenaAgent class to execute additional setup procedures and tie itself to a valid J3D object (Engine, from ArenaMain.cpp).

ArenaAgent::Get*, Set*

ArenaAgent’s various Get and Set functions allow other ARENA classes (such as the AgentLua class) to request and set information internal to ArenaAgent. Two of the more notable functions of this type are GetPredictedPosition and GetPredictedRotation. These functions call back to the Lua script file through the AgentLua interface and query directly what the script thinks those values should be. These functions are used primarily for the UpdateStatus function in ArenaMain.cpp.

ArenaAgentHardware

This class is a container for AgentHardwareParameters that define a common interface for all derived hardware types. In this way, new hardware types can be defined and contain unique data while the access remain invariant. The ArenaAgent’s current hardware must be a pointer to a valid ArenaAgentHardware object. The four functions in this class call their respective functions per each hardware parameter. The ArenaAgentHardware class is also responsible for loading the Lua script file specific to a particular hardware. If the script and hardware class are desynchronized, then the program would not operate properly.

AgentHardwareParameter

This class is the most fundamental unit of the hardware abstraction design. Each hardware parameter can have whatever data it needs, as long as it provides the four functions FromWorld, ToLua, FromLua, and ToWorld. Not all parameters need to a ToWorld call, but the prior three are mandatory and are therefore pure virtual.

The purpose of these four functions is to get information from the “world” as defined by the ARENA interfaces, DirectX calls, and geometric data, to the robot’s software, as defined by the Lua scripts.

The best explanation is an example. One common hardware parameter is the motor parameter. The motor parameter needs no data from the world, so its FromWorld call will be blank. ToLua will send to Lua the motor’s current state, say a floating point value between -1.0 and +1.0. FromLua will then reverse this process so as to keep the Lua stack balanced, and ToWorld will update the ArenaAgent’s position based on the new value. If the motor now indicates full speed ahead (+1.0 in this example), then the ArenaAgent class will move forward as rapidly as it can and its position will be updated. This new position will then be reflected by the various draw calls that are based all the way back to ArenaMain.cpp.

Examples of how the ArenaAgentHardware and AgentHardwareParameter classes might be used can be found in the HardwareProfiles.cpp source file.

ArenaLua.cpp

The primary focus of this source file is the AgentLua class. This class initializes the Lua programming interfaces and provides an easy method for transmitting data to and from Lua script files. The ArenaAgent class contains an AgentLua object that it uses to communicate with Lua.

AgentLua::InitializeAgentLua

This function gets the Lua state (which is initialized at its first access), sets the Lua panic function, and processes the robot’s primary script file, “Agent.lua.” The panic function is called only when Lua encounters an irrecoverable error and allows the program to exit gracefully (usually).

AgentLua::lua_RunAgentScript

This function takes a ArenaAgentHardware pointer and a destination and calls one frame of the robot’s script. This function first updates Lua’s global variables of time elapsed and the destination. The function then pushes all of the function parameters that Lua needs, calls the Lua script’s “RobotMain” function, and pops the return value. Most of the work is done by the pushing and popping commands, detailed below:

AgentLua::lua_PushAgentState, …Pop…

These functions push onto or pop from the Lua stack all of the robot’s state that is necessary for the “RobotMain” call. These functions rely on the hardware objects that are passed to them to detmerine what is or is not pushed or popped. It could be a simple x, y, z position state, or a complicated thirty-variable mess, it just depends on the ArenaAgentHardware passed to them.

The ARENA Lua Code

The Lua scripting language is a very significant part of the total ARENA system. The focus of the whole system is the software location finding algorithm that the particular robotic hardware will be running. This algorithm is defined in the script file “Agent.lua.” Likewise, all hardware must have an accompanying Lua script file to define its interactions with this main Lua file. Here are the details of these two concepts:

Algorithm Script File (Agent.lua)

The main Lua script file contains the function RobotMain that is called every frame of the simulation. Passed to Lua is a State table of unknown size and variable type (only the ARENA program and the hardware specific Lua file knowsthe specifics of this table). Because State is unknown, RobotMain operates strictly abstractly through the global Robot table. The Robot table holds function pointers that will refer to the hardware specific function in the respective hardware script, but RobotMain does not know or care about which hardware is currently installed.

The global Robot table contains four movement functions: MoveForward, MoveBackward, TurnLeft, TurnRight, and three information functions: GetPosition, GetRotation, and DetectObstruction. Robot also contains a StateFunction variable that is a pointer to the current state function. The movement functions define instantaneous actions. It is up to the RobotMain function to get data from the data functions and call its movement functions. This is accomplished by transitioning between different states until the robot reaches its destination. The DetectObstruction function raises a special case by causing an interrupt to the current state. When the obstruction code is finished, the previous state is restored. The algorithm will work the same on all hardware types, where the deciding factor is the accuracy of the three information functions.

Hardware Script File (hardware_*.lua)

There is one hardware script file for each hardware implementation in ARENA. It is up to the main ARENA program to ensure that the correct hardware script is properly loaded and initialized. The purpose of the hardware script files is to provide hardware-specific logic for the global Robot table’s four movement and three information functions (see the section on the algorithm script file above).

Each function is passed a State table. The table’s elements are defined by the current ArenaAgentHardware’s various ToLua functions further define by its constituent AgentHardwareParameter classes. All seven of the Robot table’s functions must be valid, though the accuracy of their results will depend on the quality of the simulated hardware.

Take for example a GPS system. The data coming in to the system would be perfect everyframe. Therefore, the GetPosition function could be defined in such a way as to exactly reflect the GPS data. However, if no GPS hardware was being simulated, the hardware script would have to maintain an internal position, update that position whenever MoveForward or MoveBackward was called, and report this value back for any call to GetPosition. For this second example, GetPosition would return a guess, while the first example would be correct every time.

The hardware systems currently defined are hardware_gps, hardware_twomotors, and hardware_bumper. Hardware_gps simulates a GPS hardware component and digital compass. Its position and rotation are always correct, though it cannot detect obstructions. For hardware_twomotors, there is no facility for tracking position or rotation, so these values must be guessed at. There is also to obstacle detection. Finally, hardware_bumper is an exact copy of the hardware_twomotors system, but with an added “bumper” simulator that will detect an obstruction within a very close proximity to the robot. Each of these systems have their advantages and disadvantages and all perform uniquely.

A Higher Level View of ARENA

ARENA is designed to be simple, powerful, and extensible. This philosophy is incorporated into the ARENA C++ source files as well as the Lua functions and structures, and the overall ARENA design.

The main class in ARENA, the ArenaAgent class, encapsulates all of the functionality of loading and executing an ARENA script and loading and drawing the 3D model associated with it. The class self contained in that the main program only needs to see one instance of this class to access all of ARENA’s functionality.

The Lua implementation uses a singleton class that initializes when it is first called. This allows ARENA and other J3D functions to use Lua in a global manner, whilw maintaining control on its access and construction.

The main Lua algorithm script file uses a state design pattern with each state defined as a function pointer, allowing an unlimited number of potential states. Each individual state refers to robot-based functions through a common structure that provides virtual functions to the robot’s hardware. This allows new hardware definitions to be dynamically dropped in to the Lua script file as well as decoupling the Lua movement algorithm from its hardware implementation.

Whenever possible, in both the C++ and Lua side of the ARENA code, functiona pointers and indirection is used to allow for the greatest flexibility.