source: cpp/gdk/gdktest.cpp @ 50

Last change on this file since 50 was 5, checked in by sz, 16 years ago

added the GDK (Genotype Development Kit)

File size: 11.9 KB
Line 
1// This file is a part of Framsticks GDK library.
2// Copyright (C) 2002-2006  Szymon Ulatowski.  See LICENSE.txt for details.
3// Refer to http://www.frams.alife.pl/ for further information.
4
5#include <stdlib.h>
6#include <stdio.h>
7#include <time.h>
8
9#include "model.h"
10#include "defgenoconv.h"
11#include "stdouterr.h"
12
13/**
14 @file
15 Sample code: Accessing model elements
16*/
17
18StdoutErrorHandler err; //redirect model-related errors to stdout
19DefaultGenoConvManager gcm; //without this object the application would only handle "format 0" genotypes
20
21void printNiceBanner(const char* title)
22{
23printf("    ########################################\n"
24       "   ##                                      ##\n"
25       "  ##    %-32s    ##\n"
26       "   ##                                      ##\n"
27       "    ########################################\n",title);
28}
29void printProperties(ParamInterface &pi)
30{
31printf(" #        id                      type  name        group (%d properties)\n",pi.getPropCount());
32for (int i=0;i<pi.getPropCount();i++)
33        {
34        printf("%2d. %8s = %-20s %-3s %-10s  %-10s\n",i,pi.id(i),(const char*)pi.get(i),pi.type(i),pi.name(i),pi.grname(pi.group(i)));
35        }
36}
37
38void changeOneProperty(ParamInterface &pi)
39{
40if (pi.getPropCount()<=0) return;
41int i=rand() % pi.getPropCount();
42double maxprop=1,minprop=0,def;
43pi.getMinMax(i,minprop,maxprop,def);
44printf("      Change property #%d to random value from range [%g..%g]\n",i,minprop,maxprop);
45printf("      Current value of '%s' (%s) is '%s'\n",pi.id(i),pi.name(i),(const char*)pi.get(i));
46char t[100];
47sprintf(t,"%g",minprop+(rnd01)*(maxprop-minprop));
48printf("      Setting new value... [ using ParamInterface::set() ]\n");
49pi.set(i,t);
50printf("      The value is now '%s'\n",(const char*)pi.get(i));
51}
52
53void moreAboutPart(Part* p)
54{
55printf("Here is the full listing of properties as they are printed in f0\n"
56       " (please compare with f0 genotype).\n"
57       "Some properties have special meaning (eg. geometry and connections groups)\n"
58       "and should be handled with care, because they influence other elements of the model.\n\n"
59       " [this data is provided by Part::properties() ]\n");
60printProperties(p->properties());
61printf("\nHowever, there is a subset of properties which may be modified more freely.\n"
62       "Properties on this list are related only to this part and can be changed\n"
63       "without much consideration. They are guaranteed to be always valid; any inconsistencies\n"
64       "will be silently repaired.\n"
65       "\n [this data is provided by Part::extraProperties() ]\n");
66printProperties(p->extraProperties());
67printf("\nThis set of properties can vary from release to release,\n"
68       "but can be safely accessed by using extraProperties() call.\n"
69           "This method accesses the full set of properies (even those\n"
70           "which appear in future releases).\n"
71       "Now we will try to change some of properties:\n\n");
72p->getModel().open();
73changeOneProperty(p->extraProperties());
74p->getModel().close();
75printf("\nLet's see f0... (check out part #%d !)\n\n%s\n", p->refno, (const char*)p->getModel().getF0Geno().getGene());
76}
77
78void playWithAbsolute(Joint *j)
79{
80printf("\nAbsolute Joints adapt to its Parts' positions.\n"
81       "We can move a Part, and it does not influence the second part, nor the Joint.\n"
82       "Let's move the first Part along y axis by -0.1...\n");
83j->getModel().open();
84j->part1->p.y-=0.1;
85j->getModel().close();
86printf("The Part's position is changed, but everything else stays intact:\n\n%s\n",
87       (const char*)j->getModel().getF0Geno().getGene());
88}
89
90void playWithDelta(Joint *j)
91{
92printf("\nDelta fields (dx,dy,dz) describe relative location of the second part.\n"
93       "This joint will change the second Part's positions to preserve delta distance.\n"
94       "Let's move the first Part (#%d) along y axis (+0.1) and change delta.z (dz) by 0.1.\n",j->part1->refno);
95j->getModel().open();
96j->part1->p.y+=0.1;
97j->d.z+=0.1;
98j->getModel().close();
99printf("Position of the second Part referenced by this joint (part #%d) is now changed:\n\n%s\n",
100       j->part2->refno, (const char*)j->getModel().getF0Geno().getGene());
101printf("If no delta fields are defined, they will be computed automatically.\n"
102       "You can always delete existing delta values by using Joint::resetDelta().\n"
103       "Now we will change the second Part's z position by -0.2 and call resetDelta()...\n");
104j->getModel().open();
105j->part2->p.z-=0.2;
106j->resetDelta();
107j->getModel().close();
108printf("As you can see, Joint's delta fields have altered:\n\n%s\n", (const char*)j->getModel().getF0Geno().getGene());
109}
110
111void switchDelta(Joint *j)
112{
113int option=! j->isDelta();
114printf("How would this joint look like with delta option %s?\n[ by calling Joint::useDelta(%d) ]\n",option?"enabled":"disabled",option);
115j->getModel().open();
116j->useDelta( ! j->isDelta() );
117j->getModel().close();
118printf("f0 is now:\n\n%s\n...so this is %s joint.\n",
119       (const char*)j->getModel().getF0Geno().getGene(), option?"a delta":"an absolute");
120
121}
122
123void moreAboutJoint(Joint* j)
124{
125printf("Similarly as with Part, the full list of properties comes first:\n\n");
126printProperties(j->properties());
127printf("\nActually, there are two kinds of Joints: delta and absolute.\n"
128       "For this object, Joint::isDelta() returns %d, so this is the %s Joint.\n",
129       j->isDelta(),j->isDelta()?"delta":"absolute");
130if (j->isDelta())
131        {
132        playWithDelta(j);
133        switchDelta(j);
134        playWithAbsolute(j);
135        }
136else
137        {
138        playWithAbsolute(j);
139        switchDelta(j);
140        playWithDelta(j);
141        }
142
143printf("Part references and delta fields are the 'core' properties of the Joint.\n"
144       "The other properties are available from Joint::extraProperties()\n"
145       "and at the moment are defined as follows:\n\n");
146printProperties(j->extraProperties());
147printf("\nThey can be changed just like Part's extra properties:\n");
148j->getModel().open();
149changeOneProperty(j->extraProperties());
150j->getModel().close();
151printf("And after that we have this genotype:\n\n%s\n", (const char*)j->getModel().getF0Geno().getGene());
152}
153
154
155
156void moreAboutNeuro(Neuro* n)
157{
158printf("Basic features of Neuro object are similar to those of Part and Joint.\n"
159       "We can request a property list:\n\n");
160printProperties(n->properties());
161printf("\n...and extra properties (which are designed to be always valid and easy to change):\n\n");
162printProperties(n->extraProperties());
163printf("\nAs usual, we will change something:\n");
164n->getModel().open();
165changeOneProperty(n->extraProperties());
166n->getModel().close();
167printf("Each neuron can have any number of inputs = weighted connections\n with other neurons.\n"
168       "According to Neuro::getInputCount(), this one has %d inputs.\n",n->getInputCount());
169printf("Standard API is provided for accessing those inputs (getInput(int)),\n"
170       "adding inputs (addInput(Neuro*)) and removing them (removeInput(int)).\n\n");
171
172printf("\nThe most unusual thing is 'item details' field (d).\n"
173       "It is something like separate object with its own set of properties.\n"
174       "Currently the value of 'd' is '%s'.\n",(const char*)n->getDetails());
175
176{
177NeuroClass* cl=n->getClass();
178if (!cl)
179        printf("It should contain the class name but the meaning of '%s' is unknown\n",(const char*)n->getDetails());
180else
181{
182
183printf("'%s' is the class name (NeuroItem::getClassName() == '%s') and means '%s'.\n",
184       (const char*)cl->getName(),(const char*)cl->getName(),(const char*)cl->getLongName());
185printf("Neuro::getClass() gives you information about basic characteristic\n"
186       "of the class, that can be analyzed automatically.\n");
187printf("For the current object we can get know, that this object likes to have ");
188if (cl->getPreferredInputs()<0) printf("any number of inputs");
189  else if (cl->getPreferredInputs()==0) printf("no inputs");
190  else printf("%d inputs",cl->getPreferredInputs());
191printf(" (getPreferredInputs()) ");
192printf(cl->getPreferredOutput()?"and provides meaningful output signal (getPreferredOutput==1).\n":"and doesn't provide useful output signal (getPreferredOutput==0).\n");
193
194SyntParam p=n->classProperties();
195if (p.getPropCount()>0)
196        {
197        printf("The class defines its own properties:\n\n [ data provided by Neuro::classProperties() ]\n");
198        printProperties(p);
199        printf("and they can be changed:\n");
200        n->getModel().open();
201        changeOneProperty(p);
202        p.update();
203        n->getModel().close();
204        printf("After that, 'item details' contains the new object: '%s'.\n",(const char*)n->getDetails());
205        }
206else
207        printf("(This class does not have its own properties\n"
208               " - Neuro::classProperties().getPropCount()==0)\n");
209}
210}
211
212printf("The class of this object can be changed using Neuro::setClassName()\n"
213       "The following classes are available:\n"
214       " [ data provided by Neuro::getClassInfo()->getProperties() ]\n\n");
215printf(" #  class  description       properties\n");
216for (int i=0;i<n->getClassCount();i++)
217        {
218        NeuroClass* cl=n->getClass(i);
219        Param p=cl->getProperties();
220        printf("%2d.%6s  %-20s  %2d\n",i,(const char*)cl->getName(),(const char*)cl->getLongName(),p.getPropCount());
221        }
222int cl=rand() % n->getClassCount();
223printf("\nLet's change the NeuroItem's class to '%s'...\n",(const char*)n->getClassName(cl));
224n->getModel().open();
225n->setClass(n->getClass(cl));
226{
227SyntParam p=n->classProperties();
228if (p.getPropCount()>0)
229        {
230        printProperties(p);
231        changeOneProperty(p);
232        p.update();
233        }
234}
235
236if (n->getInputCount()>0)
237{
238printf("input info 0 = \"%s\"\n",(const char*)n->getInputInfo(0));
239printf("input info 0 abc = \"%s\"\n",(const char*)n->getInputInfo(0,"abc"));
240        n->setInputInfo(0,"test",44);
241        n->setInputInfo(0,"abc","yeah");
242}
243
244n->getModel().close();
245printf("The final object description will be then: '%s'\nAnd the full f0 genotype:\n\n%s\n",
246       (const char*)n->getDetails(), (const char*)n->getModel().getF0Geno().getGene());
247
248
249}
250
251int main(int argc,char*argv[])
252{
253srand(time(0));
254printNiceBanner("Welcome to GDK test application!");
255
256//Geno g(argc>1?argv[1]:"X[|G:1.23]");
257Geno g(argc>1?argv[1]:"//0\np:\nn:\nc:0,0,i=\"abc=7\"\n");
258printf("\nSource genotype: '%s'\n",(const char*)g.getGene());
259printf("                  ( format %c %s)\n",
260       g.getFormat(), (const char*)g.getComment());
261
262Model m(g);//.getConverted('0'));
263
264if (!m.isValid())
265        {
266        printf("Cannot build Model from this genotype!\n");
267        return 2;       
268        }
269printf("Converted to f0:\n%s\n",(const char*)m.getF0Geno().getGene());
270
271printf("Model contains: %d part(s)\n"
272       "                %d joint(s)\n"
273       "                %d neuron(s)\n",m.getPartCount(),m.getJointCount(),m.getNeuroCount());
274
275printf("\nInvestigating details...\n");
276
277if (m.getPartCount()>0)
278        {
279        int p=rand()%m.getPartCount();
280        printNiceBanner("P A R T    O B J E C T");
281        printf("            (part # %d)\n",p);
282        moreAboutPart(m.getPart(p));
283        }
284
285if (m.getJointCount()>0)
286        {
287        int j=rand()%m.getJointCount();
288        printNiceBanner("J O I N T    O B J E C T");
289        printf("            (joint # %d)\n",j);
290        moreAboutJoint(m.getJoint(j));
291        }
292
293if (m.getNeuroCount()>0)
294        {
295        int n=rand()%m.getNeuroCount();
296        printNiceBanner("N E U R O    O B J E C T");
297        printf("            (neuro # %d)\n",n);
298        moreAboutNeuro(m.getNeuro(n));
299        }
300
301#ifdef MODEL_V1_COMPATIBLE
302printNiceBanner("Old Neuro/NeuroItem view");
303int nc=m.old_getNeuroCount();
304printf("Model::old_getNeuroCount() = %d\n",nc);
305for (int i=0;i<nc;i++)
306        {
307        Neuro *n=m.old_getNeuro(i);
308        printf("neuron #%d: p=%d, j=%d, force=%g, inertia=%g, sigmoid=%g\n",
309               i,n->part_refno,n->joint_refno,
310               n->force,n->inertia,n->sigmo);
311        int nicount=n->getItemCount();
312        printf("    %d items\n",nicount);
313        for (int j=0;j<nicount;j++)
314                {
315                NeuroItem *ni=n->getNeuroItem(j);
316                printf("        item #%d - '%s', conn=%d, weight=%g\n",
317                       j,(const char*)ni->getDetails(),ni->conn_refno,ni->weight);
318                }
319        }
320printf("end.\n");
321#endif
322
323printf("\n######### THE END ###########\n\n"
324       "Hints:\n"
325       "  1. You can redirect output: gdktest >filename.txt\n"
326       "  2. Each run can yield different results because some\n"
327       "     values are randomly generated.\n"
328       "  3. Application will use custom genotype passed as\n"
329       "     a commandline parameter: gdktest X\n"
330       "\n");
331return 0;
332}
Note: See TracBrowser for help on using the repository browser.