Friday 22 February 2013

IndiGolog Basics

This is a guide on the steps I took set-up a IndiGolog Program.

I prefer to divide up the sections of an IndiGolog program into different files. The different sections of an IndiGolog program are:
  1. Exogenous Actions
    1. Contains the code to handle exogenous actions from then environment.
  2. Fluents
    1. Fluents handle the current state of the environment relative to the agent.
  3. Initial Conditions
    1. The initial conditions of the agent
  4. Primitive Actions
    1. The primitive actions of the agent. These are the lowest level actions that the agent can make
  5. Procedures 
    1. The procedures of the agents. Procedures are sequences of primitive actions that are created from knowledge of the Agent.

The exogenous actions code can be small but will grow depending design. For a basic set of exogenous actions this short list could be used.



/* exog_action(reached(Location)).
    Lets the Agent know when it has fully arived at a location it was navigating
to.
*/
exog_action(reached(_)).

/*
    catch all to make sure system does not crash
*/
exog_action(_).

Fluents are one of the most important parts of the Agents design. fluents are supposed to evolve according to actions that occur. Then these fluents can be used in procedures to make good choices or in any conditions.


% Used to keep track of the state of the Entity
% When the controlled Entity dies this will be set to false.
rel_fluent(alive).
causes_val(died, alive, false, true) :-
    nl, write('Entity died'), nl.


There are different kinds of fluents in IndiGolog rel_fluent and fun_fluent which I believe stand for relational fluent and functional fluent. I am not totally sure what the difference is...


% Will be used to keep track of the inventory of the Entity.
/*    hasItem(item, player)
    Use to keep track of the many game items and players with an
    association of players with items.
*/
rel_fluent(hasItem(_,_)).
causes_val(pickup(Item,Player), hasItem(Item, Player), true, true).
causes_val(drop(Item,Player), hasItem(Item, Player), false, hasItem(Item, Player)).
 
% -- causes_true(action,fluent,cond)
%          when cond holds, doing act causes relational fluent to hold
% doing this because predicate does not exist
% these need to be defined so that the causes_val will work properly because it is
% defined to use these two predicates in ../../Eval/evalbat.pl
% because of relational fluents
causes_true(action,fluent,false).

causes_false(action, fluent, false).


The initial conditions describe the state of the agents world when the program is started. This section can also be use to test the agent by adjusting initial conditions to inspect of the agent still preforms a reasonable set of actions. 

Some predicates can be defined to help solidify the definition of initial conditions



enemies([valerie, will, amy, player]).
friends([glensnemesis, heather, jim, bob, self]).
isEnemy(Player) :- domain(Player, enemies).
isFriend(Player) :- domain(Player, friends).
isPlayer(Player) :- isFriend(Player); isEnemy(Player). 




%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Initial conditions
%% Initial values of fluents
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

initially(alive, true).
initially(hasItem(Item, Player), false) :-
    isItem(Item),
    isPlayer(Player).


initially(name, none).



Primitive actions as said are the lowest actions that an Agent can take. The reason for the primitive actions are to define what is a acceptable action and to define when a particular action is indeed possible in a given situation.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Primitive actions
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


prim_action(die).
 prim_action(look(_)).


prim_action(startgoto(_)).



These are preconditions for the primitive actions. These are very important in a search so the search knows that the actions it selects are valid in the situation thet are selected for.


/*
    Preconditions for primitive actions
*/

poss(check_for_enemy, true).

poss(look(_), true).



poss(startgoto(Location), location(Location)). 



Now procedures are more involved than any of the other pieces of code but they are heavily depandant on them. Some can be as simple as,


proc(defendCapturer,
    pi(teammate, 
        [?(hasItem(enemyflag, teammate)), 
            defend(teammate)
        ]
    )
).


This procedure is to defend the capturer (comes form an agent written to play capture the flag). Essentially it uses pi (pronounced "pick") to choose the teammate of the agent for which the condition hasItem(enemyflag, teammate) is true. Choose the teammate that has the enemyflag and defend that teammate. Pretty awesome for really only 4 lines of code. 

For the functionality of the IndiGolog agent this line needs to be added and is very importand


% THIS IS THE MAIN PROCEDURE FOR INDIGOLOG
proc(main,  mainControl(N)) :- controller(N), !.


When the "main" method is called it will try all of controllers defined for the agent. 

Some examples


/*

    This procedures includes parts of the last. This one will loop while

    the Entity is still alive. It will prioritize these action states

    1. If there is enemyContact engage and attack that enemy.

    2. If an enemy is seen follow that enemy.

    3. Otherwise wonder the map.

*/

proc(mainControl(2),

%    [goto(home), sleep]

     prioritized_interrupts(

    [

        interrupt(contactedEnemy=glen, attack( _, [target,glen], _)),

         interrupt(seenEnemy=glen, follow(_, [target,glen])),

         interrupt(true, pi(start, pi(location, [relocate(start,location)])))

     ]) % end of interupts

).


prioritize interrupts chooses the interrupt for which its condition is true first.


% Controller for the Wumpus:

%    1. If agent knows where the wumpus is, she is in line with it and

%       the wumpus may be alive, then aim to wumpus and shoot arrow

%    2. If agent knows that there is gold in the current square, pick it up

%    3. Otherwise: sense everything and take a randomWalk

proc(mainControl(3),

   prioritized_interrupts(

         [interrupt([dir], and(aliveWumpus=true,

                     in_line(locRobot,dir,locWumpus)), [shoot(dir)] ),

      interrupt(isGold(locRobot)=true, [pickGold]),

      interrupt(inDungeon=true, [smell,senseBreeze,senseGold,

                wndet(newRandomWalk, [goto(loc(1,1)),climb])])

         ])  % END OF INTERRUPTS

).





proc(mainControl(4),

    while(alive, searchForEnemy(glen))

).





proc(mainControl(9),

%    [goto(home), sleep]

     prioritized_interrupts( 

    [

        interrupt(and(role=capdef, neg(hasenemyflag=false)), defendCapturer),

        interrupt(and(role=capdef, some([enemy, friend], and(attacking(enemy, friend)=yes, neg(isEnemy(friend))))), 

            pi(enemy, attack( _, [target, enemy], _))),

        interrupt(and(role=capdef, neg(seeEnemy=false)),    pi(enemy, 

            if(bAttackedBy(enemy), 

                attack( _, [target,enemy], _), 

                avoidEnemy))),

        interrupt(role=capdef, startgoto(_, [destination, enemyflag2]))

    ]%,

        %if  % end of if

     )% end of while

).



References:
  1. http://www.cs.toronto.edu/~alexei/ig-oaa/indigolog.htm
  2. http://www.cse.yorku.ca/~lesperan/IndiGolog/
  3. http://sourceforge.net/projects/indigolog/



Thursday 21 February 2013

Install/setup Postgres 9.1 on Ubuntu 12.04

Start by installing Postgres:


sudo apt-get install postgresql


After installing the first thing that needs to be done is adjust the connections postgres will accept. open the file /etc/postgresql/9.1/main/posrgresql.conf and turn on the listen addres


listen_addresses = 'localhost'


Then turn password encryption on


password_encryption = on


Then restart postgresql for these changes to take effect.


/etc/init.d/postgresql restart


Now the server is ready to access. First thing to do is to create a database user to use for all of your work.


sudo -u postgres createuser

Enter name of role to add: username

Shall the new role be a superuser? (y/n) n

Shall the new role be allowed to create databases? (y/n) n

Shall the new role be allowed to create more new roles? (y/n) n


 Then create the database you are going to use:


sudo -u postgres createdb somedb

CREATE DATABASE
After the database has been created a setup a password for that user and grant all privaleges for that user on the database.


sudo -u postgres psql

postgres=# alter user username with encrypted password 'passwd';

ALTER ROLE

postgres=# grant all privileges on database somedb to username;

GRANT




Now it is time to install the postgres client.


sudo apt-get install postgresql-client


Last it might be necessary to change the connection protocol in /etc/postgresql/9.1/main/pg_hba.conf. I was getting an error related to not having the privileges to access the database.

On installation, your pg_hba.conf file will look like this:



# TYPE  DATABASE        USER            ADDRESS                 METHOD 



# "local" is for Unix domain socket connections only 

local   all             all                                     peer 

# IPv4 local connections: 

host    all             all             127.0.0.1/32            ident 

# IPv6 local connections: 

host    all             all             ::1/128                 ident 

# Allow replication connections from localhost, by a user with the 

# replication privilege. 

#local   replication     postgres                                peer 

#host    replication     postgres        127.0.0.1/32            ident 

#host    replication     postgres        ::1/128                 ident  


Change the METHOD to md5 as shown below:


# TYPE  DATABASE        USER            ADDRESS                 METHOD 



# "local" is for Unix domain socket connections only 

local   all             all                                     md5 

# IPv4 local connections: 

host    all             all             127.0.0.1/32            md5 

# IPv6 local connections: 

host    all             all             ::1/128                 md5  


In order for the change to take effect, reload the pg_hba.conf file.

sudo -u postgres psql


posgres=# select pg_reload_conf();  



 pg_reload_conf 

---------------- 

 t 

(1 row) 

 

postgres=# 
Now it should be possible to connect to your database with  psql -d somedb -U username It will ask you for your password. If you want to create a tablespace for your database: I just used the same hard-drive I installed it on, if you computer has more than one hard-drive you might want to distribute databases across table spaces. By default on Ubuntu postgres store the default tablespace in /var/lib/postgresql/9.1/main. You can double check this with the command

$ sudo -u postgres psql

psql (9.1.7)

Type "help" for help.



postgres=# show data_directory;

        data_directory       

------------------------------

 /var/lib/postgresql/9.1/main

(1 row)



postgres=#


This next section gives direction on how to a table_space for postgres to store all of the information for table in a particular directory.

You can just create a new directory in /var/lib/postgresql/9.1


sudo mkdir /var/lib/postgresql/9.1/somedir


This will result in

$ ls -la /var/lib/postgresql/9.1/

total 16

drwxr-xr-x  4 postgres postgres 4096 Feb 21 21:40 .

drwxr-xr-x  3 postgres postgres 4096 Feb  7 12:05 ..

drwx------ 13 postgres postgres 4096 Feb 21 20:43 main

drwxr-xr-x  2 root     root     4096 Feb 21 21:40 somedir


The permissions need to be changed for postgres to be able to access the tablespace store correctly


$ sudo chown postgres /var/lib/postgresql/9.1/somedir

$ sudo chgrp postgres /var/lib/postgresql/9.1/somedir

$ ls -la /var/lib/postgresql/9.1/

total 16

drwxr-xr-x  4 postgres postgres 4096 Feb 21 21:40 .

drwxr-xr-x  3 postgres postgres 4096 Feb  7 12:05 ..

drwx------ 13 postgres postgres 4096 Feb 21 20:43 main

drwxr-xr-x  2 postgres postgres 4096 Feb 21 21:40 somedir


Now your tablespace has a home the postgres has access to. At this point there should be no issue in creating a new tablespace.


$ sudo -u postgres psql

psql (9.1.7)

Type "help" for help.

                                         

postgres=# CREATE TABLESPACE table_store OWNER username  LOCATION '/var/lib/postgresql/9.1/somedir/';

CREATE TABLESPACE

postgres=# 


All Set.

References:
  • http://blog.lodeblomme.be/2008/03/15/move-a-postgresql-database-to-a-different-tablespace/
  • http://www.postgresql.org/docs/9.1/static/sql-commands.html
  • http://linuxpoison.blogspot.ca/2012/01/how-to-install-configure-postgresql.html
  • http://www.davidghedini.com/pg/entry/install_postgresql_9_on_centos

Wednesday 20 February 2013

Python and TCP/IP

TCP/IP in Python

Some notes on how TCP/IP works in Python (2.7).

Basic TCP client



import socket
import sys

# Create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Connect the socket to the port where the server is listening
server_address = ('localhost', 10000)
print >>sys.stderr, 'connecting to %s port %s' % server_address
sock.connect(server_address)

try:
    
    # Send data
    message = 'This is the message.  It will be repeated.'
    print >>sys.stderr, 'sending "%s"' % message
    sock.sendall(message)

    # Look for the response
    amount_received = 0
    amount_expected = len(message)
    
    while amount_received < amount_expected:
        data = sock.recv(16)
        amount_received += len(data)
        print >>sys.stderr, 'received "%s"' % data

finally:
    print >>sys.stderr, 'closing socket'
    sock.close()


This client is simple and easy to use but I need something that would not block at all. To achieve this Python has a feature called select that can be used on stream like object that have a file descriptor. This selector can be used to check if the selector object has data ready for reading, writing or an exceptional condition (exceptional conditions not covered here).


import select
import socket
import sys

service = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Connect the socket to the port where the server is listening
server_address = ('localhost', 10000)
print >> sys.stderr, 'connecting to %s port %s' % server_address
service.connect(server_address)



This beginning stays the same but now the method to receive has changed.


 r, w, e = select.select([service], [], [], 0.0)
    if r: # There is something to read
       data = service.recv(256)
       character = 'ChrBrad0'
       
       bmlMessage = data







Get and Compile Smart Body

This page is linked to another and will outline the steps to get and compile SmartBody.

Current svn command and link


svn co https://smartbody.svn.sourceforge.net/svnroot/smartbody/trunk smartbody 


To Compile for Windows follow the steps in the guide that basically just say to use visual studio to open the solution and build the project.

For Linux it was a little more complicated. I prefer to work on Linux (Ubuntu) for my work so I ventured on writing a script to setup all of the dependencies.

Here is a script I wrote to setup all the dependencies for SmartBody on Ubuntu 12.04.

Thursday 7 February 2013

Ubuntu 12.04 on ASUS n56v

This blog is a collection of solutions to issues or not preferred settings in Ubuntu when installing on ASUS n56v

Press f2 to get into bios

  1. After installing Ubuntu fix Grub to boot Windows 8 again.
    1. So installing Ubuntu 12.04 along with a EFI partition with GRUB will result in a boot error for Windows8 (from /dev/sda[some number]), some thing like: error: unknown command 'drivemap' error: invalid EFI file path. While there are many threads online discussed about this issue. Here is the most elegant solution I found: using the Boot-Repair tool. Here is how: 
       1. After Ubuntu is installed (make sure you can access the internet), open the terminal:

      sudo add-apt-repository ppa:yannubuntu/boot-repair
      sudo apt-get update
       2. Press Enter. 
       3. Then type:
       
       sudo apt-get install -y boot-repair
       boot-repair
       4. Press Enter, let this software figure everything out for you.
      It will automatically generate the GRUB files such that your Windoes8 can boot again.
       
      Best to choose the Recommended option to fix your boot issues in boot-repair

  2. Get the nvidia card working
    1. taken from, http://askubuntu.com/questions/163900/ubuntu-any-version-and-650m-cuda
    2. NOTE: if using Ubuntu 12.04.2 read these first 
      1. http://askubuntu.com/questions/256995/ubuntu-12-04-2-wont-boot-after-bumblebee-instalation 
      2. https://bugs.launchpad.net/ubuntu/+source/cedarview-drm-drivers/+bug/1132584
        1. Yes your integrated graphics will no longer work.
    3. Short story if Ubuntu 12.04:
      
      sudo add-apt-repository ppa:ubuntu-x-swat/x-updates
      sudo add-apt-repository ppa:bumblebee/stable
      sudo apt-get update
       
      sudo apt-get install bumblebee bumblebee-nvidia linux-headers-generic
       
      # If using Ubuntu 12.04.2 with the hardware enablement stack use this to install bumblebee instead
       
      sudo apt-get install bumblebee bumblebee-nvidia linux-headers-generic-lts-quantal 
       
      Log out and log back in to update your user groups
       
      optirun glxspheres
      
      
      Basically to make sure the graphics for the program you want to run is handled by the graphics card run it with optirun. 
    4. 
      
  3. Fixing Eithernet
    1. http://www.linuxfoundation.org/collaborate/workgroups/networking/alx
    2. Worked great
  4. Multi-Touch
    1. http://askubuntu.com/questions/127049/help-trying-to-get-two-finger-scrolling-to-work-on-asus-ul80vt/220299#220299 
  5. Fix computer freezing ever couple of hours
    For whatever reason the computer seem to freeze every so often. Looks to occur whenever I go to save something.

    Apparently it can be easily remedied by enabling the long term service hardware stack like so:

    sudo apt-get install linux-generic-lts-quantal xserver-xorg-lts-quantal
    After this you should have kernel version >= 3.5.0 which is the point of enabling the hardware support.
  6. Fix auto brightness
    You could try adding a line to /etc/rc.local that will set the desired brightness level. To edit the file, run
    gksudo gedit /etc/rc.local
    
    and add the following
    echo X > /sys/class/backlight/intel_backlight/brightness
    
    so that the end result looks like this
    #!/bin/sh -e
    #
    # rc.local
    #
    # This script is executed at the end of each multiuser runlevel.
    # Make sure that the script will "exit 0" on success or any other
    # value on error.
    #
    # In order to enable or disable this script just change the execution
    # bits.
    #
    # By default this script does nothing. 
     
    # Max vlaue seems to be 4882 
     echo X > /sys/class/backlight/intel_backlight/brightness
    
    exit 0
    
    Substitute the X by the desired brightness level.

  7. Sub woofer
    1. Source is http://doc.ubuntu-fr.org/asus_n76vm#son in french
    2. Basically add
      
      echo 0x16 0x99130112 > /sys/class/sound/hwC0D0/user_pin_configs
      echo 1 > /sys/class/sound/hwC0D0/reconfig
      
       
                      To /etc/rc.local                      Before exit 0
                      reboot
                      Might need to change some settings in alsamixer. 



Using PYSdm
http://ubuntuforums.org/showthread.php?t=872197
Use: user,exec,auto,uid=1000,gid=1000,utf8,dmask=027,fmask=007

References
  1. http://askubuntu.com/questions/166263/fn-keys-not-working-on-an-asus-n56v
NOTES:
  1. Kernel 3.5.x will not work with the cedarview GPU on Intel chips. Find the bug here. https://bugs.launchpad.net/ubuntu/+source/cedarview-drm-drivers/+bug/1132584