source: cpp/gdk/neuroimpl.h @ 100

Last change on this file since 100 was 81, checked in by Maciej Komosinski, 12 years ago

improved parsing of properties (e.g. in f0 genotypes)

  • Property svn:eol-style set to native
File size: 9.0 KB
Line 
1// This file is a part of the Framsticks GDK library.
2// Copyright (C) 2002-2011  Szymon Ulatowski.  See LICENSE.txt for details.
3// Refer to http://www.framsticks.com/ 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
18class Creature;
19
20class NeuroNetConfig
21{
22public:
23NeuroNetConfig();
24
25Param par;
26double randominit;
27double nnoise;
28double touchrange;
29
30static NeuroNetConfig& getGlobalConfig();
31};
32
33#ifdef NEURO_SIGNALS
34class NeuroSignals: public SignalSet
35{
36  protected:
37Creature *cr;
38NeuroImpl *owner;
39Creature *getCreature();
40  public:
41
42NeuroSignals(NeuroImpl *n):owner(n),cr(0) {}
43
44#define STATRICKCLASS NeuroSignals
45PARAMPROCDEF(p_add);
46PARAMPROCDEF(p_get);
47PARAMGETDEF(size);
48PARAMPROCDEF(p_receive);
49PARAMPROCDEF(p_receiveSet);
50PARAMPROCDEF(p_receiveFilter);
51PARAMPROCDEF(p_receiveSingle);
52#undef STATRICKCLASS
53
54static Param& getStaticParam();
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::getGlobalConfig()
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;
197NeuroClass *neuroclass;
198/** don't access directly */
199double newstate;
200
201#ifdef NEURO_SIGNALS
202NeuroSignals sigs;
203#endif
204NeuroNetImpl *owner;
205ExtObject sigs_obj;
206
207/** "virtual constructor" - NeuroFactory uses this method to create the proper implementation object.
208    subclasses must return new object here. */
209virtual NeuroImpl* makeNew() {return 0;} //
210/** will be used by readParam() method, if not null  */
211ParamEntry *paramentries; // no extra properties if ==0
212/** read additional properties from "moredata" field of the originating Neuro */
213void readParam();
214/** called when all other neuro objects were already created and "moredata" transferred to
215    object fields.
216    useful for initialization that cannot be performed in the constructor.
217    @return 1=ok  0=failure
218*/
219virtual int lateinit() {return 1;}
220/** calculate 'newstate - implementation dependent */
221virtual void go(){}
222/** for neurons doing some physical actions (called each simulation step when nnspeed!=1.0) */
223virtual void goPhysics(){}
224
225int getSimOrder() {return simorder;}
226virtual int getNeedPhysics() {return 0;}
227
228void setChannelCount(int c);
229int getChannelCount() {return channels;}
230
231int getInputCount() {return neuro->getInputCount();}
232int getInputChannelCount(int i);
233double getInputState(int i,int channel=0);
234double getWeightedInputState(int i,int channel=0);
235double getInputSum(int startwith=0);
236double getWeightedInputSum(int startwith=0);
237double getInputWeight(int i) {return neuro->getInputWeight(i);}
238void setState(double st,int channel);
239void setState(double st) {validateNeuroState(st); newstate=st;}
240double getState(int channel);
241double getState() {return neuro->state;}
242
243virtual int getDrawingCount() {return 0;}
244virtual int* getDrawing(int i) {return 0;}
245
246void commit();
247void validateNeuroState(double& st) {if (st<=-1e10) st=-1e10; else if (st>1e10) st=1e10;}
248
249NeuroImpl():owner(0),neuro(0),newstate(0),paramentries(0),simorder(1),status(BeforeInit),channels(1),fields_param(0),fields_object(0)
250#ifdef NEURO_SIGNALS
251,sigs(this),sigs_obj(&NeuroSignals::getStaticParam(),&sigs)
252#endif
253 {}
254virtual ~NeuroImpl();
255virtual void createFieldsObject();
256
257/** usually == "newstate" but will obey the "hold state" */
258double getNewState(int channel=0);
259
260/** don't use! */
261void setCurrentState(double st,int channel=0);
262
263bool getPosition(Pt3D &pos);
264Creature* getCreature();
265
266#define STATRICKCLASS NeuroImpl
267PARAMGETDEF(count) {arg1->setInt(getInputCount());}
268PARAMPROCDEF(p_get) {arg2->setDouble(getInputState(arg1->getInt()));}
269PARAMPROCDEF(p_getweight) {arg2->setDouble(getInputWeight(arg1->getInt()));}
270PARAMPROCDEF(p_getw) {arg2->setDouble(getWeightedInputState(arg1->getInt()));}
271PARAMPROCDEF(p_getsum) {arg2->setDouble(getInputSum(arg1->getInt()));}
272PARAMPROCDEF(p_getwsum) {arg2->setDouble(getWeightedInputSum(arg1->getInt()));}
273PARAMGETDEF(sum) {arg1->setDouble(getInputSum(0));}
274PARAMGETDEF(wsum) {arg1->setDouble(getWeightedInputSum(0));}
275PARAMPROCDEF(p_getchancount) {arg2->setInt(getInputChannelCount(arg1->getInt()));}
276PARAMPROCDEF(p_getchan) {arg2->setDouble(getInputState(arg1[1].getInt(),arg1[0].getInt()));}
277PARAMPROCDEF(p_getwchan) {arg2->setDouble(getWeightedInputState(arg1[1].getInt(),arg1[0].getInt()));}
278PARAMGETDEF(state) {arg1->setDouble(getState());}
279PARAMSETDEF(state) {setState(arg1->getDouble()); return 0;}
280PARAMGETDEF(cstate) {arg1->setDouble(neuro->state);}
281PARAMSETDEF(cstate) {setCurrentState(arg1->getDouble()); return 0;}
282PARAMGETDEF(hold) {arg1->setInt((neuro->flags&(Neuro::HoldState))?1:0);}
283PARAMSETDEF(hold) {neuro->flags=(neuro->flags&~Neuro::HoldState)|(arg1->getInt()?Neuro::HoldState:0); return 0;}
284PARAMGETDEF(channels) {arg1->setInt(getChannelCount());}
285PARAMSETDEF(channels) {setChannelCount(arg1->getInt()); return 0;}
286PARAMPROCDEF(p_getstate) {arg2->setDouble(getState(arg1->getInt()));}
287PARAMPROCDEF(p_setstate) {setState(arg1[0].getDouble(),arg1[1].getInt());}
288PARAMPROCDEF(p_setcstate) {setCurrentState(arg1[0].getDouble(),arg1[1].getInt());}
289PARAMGETDEF(creature);
290PARAMGETDEF(part);
291PARAMGETDEF(joint);
292PARAMGETDEF(position_x);
293PARAMGETDEF(position_y);
294PARAMGETDEF(position_z);
295PARAMGETDEF(fields);
296PARAMGETDEF(neurodef);
297PARAMGETDEF(classObject);
298#undef STATRICKCLASS
299
300  static Param& getStaticParam();
301};
302
303#endif
Note: See TracBrowser for help on using the repository browser.