Italiano English
e-nuts.net header

Genetic Arm 2.0

Genetic Arm 2.0 is an application that simulate a mechanical arm driven by a neural network trained using genetic algorithms. The app shows how AI can evolve and execute some actions you provide. In the video below you can see how it evolves: it has to throw a ball as far as possible. Distance is computed after three seconds.

How to use

Once the application is started you must choose a script and an action from first panel. Many actions can be defined for each script. Then on second panel informations about script and application state are shown. If you click on "Train" evolution starts. You can reset effect of evolution clicking on "Reset". The third panel will be filled with a new item every time a new success will be obtained by AI. If you want to see one result just select it from list and click on "Simulate".

Notice: you need to install Ageia Physx system software if you want to use Genetic Arm. You can download it for free here!

How can I define a custom action?

Actions are defined using script. Genetic Arm uses angelscript as scripting language. It has a syntax similar to java and c/c++, by the way angelscript's documentation is available on its own site. Script files must be saved into "script" subfolder of Genetic Arm.

There are two piece of code you really need to write. One is setup() function, the other is the callback function for ON_SCORE event. Let's analyse a simple setup() function:


int ballId;

void setup(Script @s)
{
  Action a;

  // Script info --->
  s.title     = "Ball shots";
  s.author    = "Your Name";
  s.email     = "yourmail@example.com";
  s.website   = "http://www.example.com";

  // Long shot --->
  a.title = "Long shot";

  a.setCallback(ON_LOAD, "on_load");
  a.setCallback(ON_UNLOAD, "on_unload");
  a.setCallback(ON_GROUND_CONTACT,"on_ground_contact");
  a.setCallback(ON_SCORE, "on_score");
  
  a.description = "Here your description!";
  s.addAction(a);
}
                

On first line you can see the function signature. A function declare as void setup(Script @s) is always required on Genetic Arm scripts. It's the main function and it's used by Genetic Arm to get information about script.

The class named Script should be easy to understand. With class Action you can define actions you want to add on your script. The most important method of class Action is setCallback(). This function takes two params. First param must be a constant representing an event you want to handle, second param should be a string: the name of function Genetic Arm has to call when that event occour. Here a list of supported events with its callback signature and a short description:

  • ON_LOADvoid f() – Called when action is loaded.
  • ON_UNLOADvoid f() – Called when action is unloaded.
  • ON_STARTvoid f() – Called every time simulation is started. Objects' position and speed are resetted.
  • ON_STOPvoid f() – Called when action is stopped (e.g. simulation is finished).
  • ON_STEPbool f() – Physic simulation is subdivided in steps. This function is called when a step is performed. If you return false simulation is stopped and ON_SCORE callback will be called.
  • ON_CUSTOM_CONTACTvoid f(int obj1, int obj2, uint type) – A collision occours. obj1 and obj2 are handles of two user-objects. type is a bitfield composed by these constants: CONTACT_START, CONTACT_END, CONTACT_TOUCH
  • ON_MACHINE_CONTACTvoid f(int obj, int part, uint type) – The same as ON_CUSTOM_CONTACT. Here part represent one of machine's parts (MACHINE_BASE, MACHINE_ARM_INNER, MACHINE_ARM_MID, MACHINE_ARM_EXT).
  • ON_GROUND_CONTACTvoid f(int obj, uint type) – The same as ON_CUSTOM_CONTACT. Here an user-object collides with floor.
  • ON_SCOREfloat f() – This is the most important function. It is called when simulation is finished. Here you should return a score. An higher score means that action was performed better.

In previous code snipped we've declared four callbacks for an action called "Long shot". Now let's see how we can implement this callbacks in a simple way:

void on_load() 
{ 
  float y = rand() * 3 + 3.0f;
  Vector3 pos(0.0f, y, 0);
  
  ballId = createBall(0.15f, 1.0f);
  
  setObjectStartingPosition(ballId, pos);
  setTimeout(15); 
}

void on_unload() 
{ 
  destroyObject(ballId); 
}

float on_score() 
{ 
  return getObjectPosition(ballId).z; 
}

bool on_ground_contact(int o1, uint type) 
{
  return false; 
}
								

On line 3 we create a random float number. The function rand() return a float inside 0 and 1. Some other math functions are defined: cos(x), sin(x), tan(x), acos(x), asin(x), atan(x), exp(x), log(x), ceil(x), fabs(x) and floor(x). They are wrappers for functions defined by ANSI C header math.h. On line 4 we use the class Vector3. It is a 3-dimensional vector. It is used for positions and speed. It has three public members: x, y, z. Quaternion (used for orientation) has four public members (x, y, z, w) and one constructor: Quaternion(Vector3 v, w). On line 6 we create a ball. createBall() takes two params: the first is sphere radius, the second is object density (1.0 = water density). A function named createBox exists too. It takes two params: the first is a Vector3 representing sides' lenghts, the second is density. setTimeout sets the max simulation lenght in seconds. In this case after 15 seconds simulation will be stopped and on_score callback will be called.

On line 19 we set the ball "z" as score: in this way neural network can improve its score throwing ball as far as possible.

On lines 22-25 we define our function named "on_ground_contact": it always returns false. In this way when the ball touches ground simulation is stopped and "on_score" is called.

That's not all. You can use some other functions. I think you can use them without any documentation. Here is it a list:

Vector3 getObjectPosition(int objID);
Quaternion getObjectOrientation(int objID);
Vector3 getObjectLinearVelocity(int objID);
Vector3 getObjectAngularVelocity(int objID);

void setObjectPosition(int objID, Vector3 &in v);
void setObjectOrientation(int objID, Quaternion &in q);
void setObjectLinearVelocity(int objID, Vector3 &in v);
void setObjectAngularVelocity(int objID, Vector3 &in v);
void setObjectStartingPosition(int objID, Vector3 &in v);
void setObjectStartingOrientation(int objID, Quaternion &in q);

float getSimulationTime();
                

If you write some funny script don't hesitate: send me them! I'll publish here... Have fun!

Copyright © 2005-2007 e-nuts.net. All right reserved. Bookmark and Share