source: cpp/gdk/neuroimpl.h @ 32

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

added the GDK (Genotype Development Kit)

File size: 9.0 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#ifndef _NEUROIMPL_H_
6#define _NEUROIMPL_H_
7
8#include "model.h"
9#include "param.h"
10#include "framsg.h"
11#ifdef NEURO_SIGNALS
12#include "signals.h"
13#endif
14
15class NeuroImpl;
16extern ParamEntry neuroimpl_tab[];
17#ifdef NEURO_SIGNALS
18extern Param neurosignals_param;
19#endif
20
21class Creature;
22
23class NeuroNetConfig
24{
25public:
26NeuroNetConfig();
27
28Param par;
29double randominit;
30double touchrange;
31
32static NeuroNetConfig globalconfig;
33};
34
35#ifdef NEURO_SIGNALS
36class NeuroSignals: public SignalSet
37{
38  protected:
39Creature *cr;
40NeuroImpl *owner;
41Creature *getCreature();
42  public:
43
44NeuroSignals(NeuroImpl *n):owner(n),cr(0) {}
45
46#define STATRICKCLASS NeuroSignals
47PARAMPROCDEF(p_add);
48PARAMPROCDEF(p_get);
49PARAMGETDEF(size);
50PARAMPROCDEF(p_receive);
51PARAMPROCDEF(p_receiveSet);
52PARAMPROCDEF(p_receiveFilter);
53PARAMPROCDEF(p_receiveSingle);
54#undef STATRICKCLASS
55};
56#endif
57
58/// Neuro net implementation
59class NeuroNetImpl
60{
61CallbackNode *cnode;
62Model &mod;
63SList neurons[4];
64NeuroNetConfig& config;
65int isbuilt,errorcount;
66STCALLBACKDEFC(NeuroNetImpl,destroyNN);
67int minorder,maxorder;
68
69  public:
70#ifdef NEURO_SIGNALS
71ChannelSpace *channels;
72#endif
73static int mytags_id;
74static double getStateFromNeuro(Neuro *n);
75int getErrorCount() {return errorcount;}
76NeuroNetImpl(Model& model, NeuroNetConfig& conf = NeuroNetConfig::globalconfig
77#ifdef NEURO_SIGNALS
78, ChannelSpace *ch=0
79#endif
80);
81~NeuroNetImpl();
82void simulateNeuroNet();
83void simulateNeuroPhysics();
84
85static NeuroImpl *getImpl(Neuro* n) {return (NeuroImpl*)n->userdata[mytags_id];}
86};
87
88
89/**
90   Neuro implementation - this object calculates the Neuron's state
91   (Neuro::state) in each simulation step.
92
93SUBCLASSING TUTORIAL
94====================
95
961.Derive your custom neuron from NeuroImpl class. The name must be prefixed with NI_
97
98class NI_MyNeuron: public NeuroImpl
99{ ... };
100
1012.Public parameters
102Create any number of public fields, they will be adjustable from the genotype level.
1033 datatypes are supported: long, double and SString
104
105public:
106  long intParameter;
107  double fpParameter;
108  SString txtParameter;
109
110
1113.Required method: "instantiator".
112It is always the same, just create a new instance of your neuron.
113public:
114  NeuroImpl* makeNew() { return new NI_MyNeuron(); };
115
116
1174.Required method: default constructor
118Set the "paramentries" variable if you need public parameters in your neuron.
119NI_..._tab is created automatically and should be declared as: extern ParamEntry NI_..._tab[];
120At this stage the parameter values are not yet available.
121
122public:
123 NI_MyNeuron() // no parameters!
124 {
125 paramentries=NI_MyNeuron_tab;
126 // you add here: some general initialization
127 }
128
129
1305.Optional method: initialization
131This method is called once before the neuron is actually used in the simulation.
132The parameter values are already initialized (according to the genotype) and the neuron is bound to the creature (i.e. this->neuro is valid).
133Return 0 if the neuron cannot be initialized.
134
135int lateinit()
136 {
137 // you add here: initialization using full neuron context
138 // example: if (!neuro->joint) return 0; //this neuron must be attached to joint
139 return 1;//OK
140 }
141
142
1436.Required method: simulation step
144If it has output: calculate the next neuron state and call setState()
145If it is an effector: do anything else
146
147void go()
148 {
149 // you add here: things called every simulation step
150 }
151
152Note: You can make your neuron fire before or after "regular" neurons by changing its "simorder" property (during initialization). The default value is 1, whereas receptors have simorder=0 and effectors have simorder=2.
153
154
1557.Neuron definition
156In order to incorporate the new neuron into Framsticks you need to provide some additional information (to be added to "f0.def" file).
157
158NEUROCLASS(MyNeuron,MN,This is the name,`Neuron description',-1,1,0)
159NEUROPROP(int,0,0,name of the int,d,,,,intParameter)
160NEUROPROP(fp,0,0,name of the floating point,f,,,,fpParameter)
161NEUROPROP(txt,0,0,name of the text,s,,,,txtParameter)
162ENDNEUROCLASS
163
164NEUROCLASS:
165- MyNeuron: neuron class name (without the NI_ prefix)
166- MN: neuron symbol (used in genotypes)
167- full name and description
168- -1: preferred number of inputs (special case: -1=any)
169- 1: provides output: 1=yes/0=no
170- 0: preferred location: 0=none, 1=part, 2=joint
171
172NEUROPROP:
173- int/fp/txt: parameter names as visible in genotypes and scripting
174- "name of the ...": descriptive name
175- d/f/s: type (int/floating point/string)
176- intParameter/fpParameter/txtParameter: C++ field names
177
178   
179 */
180class NeuroImpl
181{
182protected:
183int simorder;
184int channels;
185SListTempl<double> chstate;
186SListTempl<double> chnewstate;
187Param *fields_param;
188ExtObject *fields_object;
189public:
190static const int ENDDRAWING;
191static const int MAXDRAWINGXY;
192
193enum NeuroImplStats { BeforeInit=0, InitError=1, InitOk=2 };
194NeuroImplStats status;
195/** originating neuron object (from the model) */
196Neuro *neuro;
197/** don't access directly */
198double newstate;
199
200#ifdef NEURO_SIGNALS
201NeuroSignals sigs;
202#endif
203NeuroNetImpl *owner;
204ExtObject sigs_obj;
205
206/** "virtual constructor" - NeuroFactory uses this method to create the proper implementation object.
207    subclasses must return new object here. */
208virtual NeuroImpl* makeNew() {return 0;} //
209/** will be used by readParam() method, if not null  */
210ParamEntry *paramentries; // no extra properties if ==0
211/** read additional properties from "moredata" field of the originating Neuro */
212void readParam();
213/** called when all other neuro objects were already created and "moredata" transferred to
214    object fields.
215    useful for initialization that cannot be performed in the constructor.
216    @return 1=ok  0=failure
217*/
218virtual int lateinit() {return 1;}
219/** calculate 'newstate - implementation dependent */
220virtual void go(){}
221/** for neurons doing some physical actions (called each simulation step when nnspeed!=1.0) */
222virtual void goPhysics(){}
223
224int getSimOrder() {return simorder;}
225virtual int getNeedPhysics() {return 0;}
226
227void setChannelCount(int c);
228int getChannelCount() {return channels;}
229
230int getInputCount() {return neuro->getInputCount();}
231int getInputChannelCount(int i);
232double getInputState(int i,int channel=0);
233double getWeightedInputState(int i,int channel=0);
234double getInputSum(int startwith=0);
235double getWeightedInputSum(int startwith=0);
236double getInputWeight(int i) {return neuro->getInputWeight(i);}
237void setState(double st,int channel);
238void setState(double st) {validateNeuroState(st); newstate=st;}
239double getState(int channel);
240double getState() {return neuro->state;}
241
242virtual int getDrawingCount() {return 0;}
243virtual int* getDrawing(int i) {return 0;}
244
245void commit();
246void validateNeuroState(double& st) {if (st<=-1e10) st=-1e10; else if (st>1e10) st=1e10;}
247
248NeuroImpl():owner(0),neuro(0),newstate(0),paramentries(0),simorder(1),status(BeforeInit),channels(1),fields_param(0),fields_object(0)
249#ifdef NEURO_SIGNALS
250,sigs(this),sigs_obj(&neurosignals_param,&sigs)
251#endif
252 {}
253virtual ~NeuroImpl();
254virtual void createFieldsObject();
255
256/** usually == "newstate" but will obey the "hold state" */
257double getNewState(int channel=0);
258
259/** don't use! */
260void setCurrentState(double st,int channel=0);
261
262bool getPosition(Pt3D &pos);
263Creature* getCreature();
264
265#define STATRICKCLASS NeuroImpl
266PARAMGETDEF(count) {arg1->setInt(getInputCount());}
267PARAMPROCDEF(p_get) {arg2->setDouble(getInputState(arg1->getInt()));}
268PARAMPROCDEF(p_getweight) {arg2->setDouble(getInputWeight(arg1->getInt()));}
269PARAMPROCDEF(p_getw) {arg2->setDouble(getWeightedInputState(arg1->getInt()));}
270PARAMPROCDEF(p_getsum) {arg2->setDouble(getInputSum(arg1->getInt()));}
271PARAMPROCDEF(p_getwsum) {arg2->setDouble(getWeightedInputSum(arg1->getInt()));}
272PARAMGETDEF(sum) {arg1->setDouble(getInputSum(0));}
273PARAMGETDEF(wsum) {arg1->setDouble(getWeightedInputSum(0));}
274PARAMPROCDEF(p_getchancount) {arg2->setInt(getInputChannelCount(arg1->getInt()));}
275PARAMPROCDEF(p_getchan) {arg2->setDouble(getInputState(arg1[1].getInt(),arg1[0].getInt()));}
276PARAMPROCDEF(p_getwchan) {arg2->setDouble(getWeightedInputState(arg1[1].getInt(),arg1[0].getInt()));}
277PARAMGETDEF(state) {arg1->setDouble(getState());}
278PARAMSETDEF(state) {setState(arg1->getDouble()); return 0;}
279PARAMGETDEF(cstate) {arg1->setDouble(neuro->state);}
280PARAMSETDEF(cstate) {setCurrentState(arg1->getDouble()); return 0;}
281PARAMGETDEF(hold) {arg1->setInt((neuro->flags&(Neuro::HoldState))?1:0);}
282PARAMSETDEF(hold) {neuro->flags=(neuro->flags&~Neuro::HoldState)|(arg1->getInt()?Neuro::HoldState:0); return 0;}
283PARAMGETDEF(channels) {arg1->setInt(getChannelCount());}
284PARAMSETDEF(channels) {setChannelCount(arg1->getInt()); return 0;}
285PARAMPROCDEF(p_getstate) {arg2->setDouble(getState(arg1->getInt()));}
286PARAMPROCDEF(p_setstate) {setState(arg1[0].getDouble(),arg1[1].getInt());}
287PARAMPROCDEF(p_setcstate) {setCurrentState(arg1[0].getDouble(),arg1[1].getInt());}
288PARAMGETDEF(creature);
289PARAMGETDEF(part);
290PARAMGETDEF(joint);
291PARAMGETDEF(position_x);
292PARAMGETDEF(position_y);
293PARAMGETDEF(position_z);
294PARAMGETDEF(fields);
295PARAMGETDEF(neurodef);
296#undef STATRICKCLASS
297};
298
299#endif
Note: See TracBrowser for help on using the repository browser.