Changeset 1089


Ignore:
Timestamp:
02/20/21 13:32:12 (3 years ago)
Author:
Maciej Komosinski
Message:

Added more examples of using Framsticks in python - building dictionaries, modifying simulator and experiment settings, running simulation, accessing coordinates of MechPart?(s) and the state of Neuron(s) of a simulated Creature

File:
1 edited

Legend:

Unmodified
Added
Removed
  • framspy/frams-test.py

    r1087 r1089  
     1"""Simple examples of using the "frams" module to communicate directly with the Framsticks library (dll/so).
     2
     3For an introduction to Framsticks, its usage and scripting, see https://www.youtube.com/playlist?list=PLkPlXm7pOPatTl3_Gecx8ZaCVGeH4UV1L
     4For a list of available classes, objects, methods and fields, see http://www.framsticks.com/files/classdoc/
     5For a number of examples of scripting, see the "scripts" directory in Framsticks distribution.
     6"""
     7
    18import sys
    29import frams
     
    1320
    1421def extValueDetails(v):
    15         return '"' + str(v) + '"    frams type=' + str(v._type()) + '    frams class=' + str(v._class()) + '    python type=' + str(type(v._value()))
     22        """A helper function to display basic information about a variable of type ExtValue."""
     23        return '\t"' + str(v) + '"    frams type=' + str(v._type()) + '    frams class=' + str(v._class()) + '    python type=' + str(type(v._value()))
    1624
    1725
    18 v = frams.String.deserialize('[100,2.2,"abc",[null,[]],XYZ[9,8,7]]')
     26dic_as_string = '[100,2.2,"abc",[null,[],{}],XYZ[9,8,7]]'
     27print("We have the following string:\n\t'%s'" % dic_as_string)
     28print("Looks like a serialized dictionary, let's ask Framsticks String.deserialize() to do its job.")
     29v = frams.String.deserialize(dic_as_string)
     30print("Framsticks String.deserialize() returned\n\t", type(v))
     31print("More specifically, it is:")
    1932print(extValueDetails(v))
     33print("Even though it is ExtValue (Framsticks' Vector), it supports iteration like a python vector, so let's inspect its elements:")
    2034for e in v:
    2135        print(extValueDetails(e))
    2236
     37print("Now let's play with the Framsticks simulator. Let's create a Genotype object and set fields in its custom 'data' dictionary.")
    2338g = frams.GenePools[0].add('X')
    24 g.name = "py!"
     39g.name = "Snakis Py"
    2540g.data['custom'] = 123.456
    26 g.data['a'] = 'b'
     41g.data['a'] = 'b'  # implicit conversion, looks like python dictionary but still converts '3' and '4' to ExtValue
     42dic = frams.Dictionary.new()  # let's create a Dictionary object from Framsticks
     43dic.set('1', '2')  # calling set() from Framsticks Dictionary
     44dic['3'] = '4'  # implicit conversion, looks like python dictionary but still converts '3' and '4' to ExtValue
     45g.data['d'] = dic
     46print(extValueDetails(g))
    2747
     48print("Let's add a few mutants and display their data:")
    2849for more in range(5):
    2950        frams.GenePools[0].add(frams.GenMan.mutate(g.geno))
    3051
    3152for g in frams.GenePools[0]:
    32         print(str(g.index) + '. "' + str(g.name) + '"  ' + str(g.genotype) + '  data=' + str(g.data))
     53        print("\t%d. name='%s'\tgenotype='%s'\tdata=%s" % (g.index._value(), str(g.name), str(g.genotype), str(g.data)))
     54
     55print("Let's now change some property of the simulation. Current water level is", frams.World.wrldwat)
     56frams.World.wrldwat = 0.5
     57print("Now water level is", frams.World.wrldwat)
     58frams.World.wrldwat = frams.World.wrldwat._value() + 0.7
     59print("Now water level is", frams.World.wrldwat)
     60
     61initial_genotype = 'X(X,RX(X[T],X[G]))'  # simple body with gyroscope and touch sensors
     62print("Let's perform a few simulation steps of the initial genotype:", initial_genotype)
     63frams.ExpProperties.initialgen = initial_genotype
     64frams.ExpProperties.p_mut = 0  # no mutation (the selection procedure will clone our initial genotype)
     65frams.ExpProperties.p_xov = 0  # no crossover (the selection procedure will clone our initial genotype)
     66frams.Populations[0].initial_nn_active = 1  # immediate simulation of neural network - no "waiting for stabilization" period
     67frams.World.wrldg = 5  # gravity=5x default, let it fall quickly
     68
     69frams.Simulator.init()  # adds initial_genotype to gene pool (calls onInit() from standard.expdef)
     70frams.Simulator.start()  # this does not actually start the simulation, just sets the "Simulator.running" status variable
     71step = frams.Simulator.step  # cache reference to avoid repeated lookup in the loop (just for performance)
     72for s in range(15):
     73        step()  # first step performs selection and revives one genotype according to standard.expdef rules
     74        creature = frams.Populations[0][0]  # FramScript Creature object
     75        mechpart0 = creature.getMechPart(0)
     76        print('Step# = %d' % frams.Simulator.stepNumber._value(),
     77              '\tSimulated_creatures =', frams.Populations[0].size._value(),
     78              "\tpart0_xyz = (% .2f,% .2f,% .2f)" % (mechpart0.x._value(), mechpart0.y._value(), mechpart0.z._value()),
     79              "\ttouch = % .3f\tgyro = % .3f" % (creature.getNeuro(0).state._value(), creature.getNeuro(1).state._value()))
     80frams.Simulator.stop()
     81
     82# Note that implementing a complete expdef, especially a complex one, entirely in python may be inconvenient or impractical
     83# because you do not have access to "event handlers" like you have in FramScript - onStep(), onBorn(), onDied(), onCollision() etc.,
     84# so you would have to check various conditions in python in each simulation step to achieve the same effect.
Note: See TracChangeset for help on using the changeset viewer.